Merge branch 'issue/94051_navigation_delegate_typedefs' into intf_nav_update
diff --git a/.ci/flutter_master.version b/.ci/flutter_master.version
index 20cb21b..a9baeda 100644
--- a/.ci/flutter_master.version
+++ b/.ci/flutter_master.version
@@ -1 +1 @@
-4e8a28d29db7c26988c58ecaa692cb79f5e71394
+99475b1b0bee6ab09d0282b255c6b8c7e01ca4fe
diff --git a/.cirrus.yml b/.cirrus.yml
index 7a8e31d..01de99c 100644
--- a/.cirrus.yml
+++ b/.cirrus.yml
@@ -64,7 +64,7 @@
macos_arm_template: &MACOS_ARM_TEMPLATE
<< : *MACOS_TEMPLATE
macos_instance:
- image: ghcr.io/cirruslabs/macos-monterey-xcode:13.4
+ image: ghcr.io/cirruslabs/macos-ventura-xcode:14
# Light-workload Linux tasks.
# These use default machines, with fewer CPUs, to reduce pressure on the
diff --git a/packages/image_picker/image_picker_ios/CHANGELOG.md b/packages/image_picker/image_picker_ios/CHANGELOG.md
index 33e2b61..986f5c0 100644
--- a/packages/image_picker/image_picker_ios/CHANGELOG.md
+++ b/packages/image_picker/image_picker_ios/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 0.8.6+1
+
+* Fixes issue with crashing the app when picking images with PHPicker without providing `Photo Library Usage` permission.
+
## 0.8.6
* Adds `requestFullMetadata` option to `pickImage`, so images on iOS can be picked without `Photo Library Usage` permission.
diff --git a/packages/image_picker/image_picker_ios/example/ios/RunnerTests/PickerSaveImageToPathOperationTests.m b/packages/image_picker/image_picker_ios/example/ios/RunnerTests/PickerSaveImageToPathOperationTests.m
index 688f5fb..e04c4f2 100644
--- a/packages/image_picker/image_picker_ios/example/ios/RunnerTests/PickerSaveImageToPathOperationTests.m
+++ b/packages/image_picker/image_picker_ios/example/ios/RunnerTests/PickerSaveImageToPathOperationTests.m
@@ -22,7 +22,7 @@
PHPickerResult *result = [self createPickerResultWithProvider:itemProvider
withIdentifier:UTTypeWebP.identifier];
- [self verifySavingImageWithPickerResult:result];
+ [self verifySavingImageWithPickerResult:result fullMetadata:YES];
}
- (void)testSavePNGImage API_AVAILABLE(ios(14)) {
@@ -32,7 +32,7 @@
PHPickerResult *result = [self createPickerResultWithProvider:itemProvider
withIdentifier:UTTypeWebP.identifier];
- [self verifySavingImageWithPickerResult:result];
+ [self verifySavingImageWithPickerResult:result fullMetadata:YES];
}
- (void)testSaveJPGImage API_AVAILABLE(ios(14)) {
@@ -42,7 +42,7 @@
PHPickerResult *result = [self createPickerResultWithProvider:itemProvider
withIdentifier:UTTypeWebP.identifier];
- [self verifySavingImageWithPickerResult:result];
+ [self verifySavingImageWithPickerResult:result fullMetadata:YES];
}
- (void)testSaveGIFImage API_AVAILABLE(ios(14)) {
@@ -52,7 +52,21 @@
PHPickerResult *result = [self createPickerResultWithProvider:itemProvider
withIdentifier:UTTypeWebP.identifier];
- [self verifySavingImageWithPickerResult:result];
+ [self verifySavingImageWithPickerResult:result fullMetadata:YES];
+}
+
+- (void)testSavePNGImageWithoutFullMetadata API_AVAILABLE(ios(14)) {
+ id photoAssetUtil = OCMClassMock([PHAsset class]);
+
+ NSURL *imageURL = [[NSBundle bundleForClass:[self class]] URLForResource:@"pngImage"
+ withExtension:@"png"];
+ NSItemProvider *itemProvider = [[NSItemProvider alloc] initWithContentsOfURL:imageURL];
+ PHPickerResult *result = [self createPickerResultWithProvider:itemProvider
+ withIdentifier:UTTypeWebP.identifier];
+
+ [self verifySavingImageWithPickerResult:result fullMetadata:NO];
+ OCMVerify(times(0), [photoAssetUtil fetchAssetsWithLocalIdentifiers:[OCMArg any]
+ options:[OCMArg any]]);
}
/**
@@ -79,7 +93,8 @@
*
* @param result the picker result
*/
-- (void)verifySavingImageWithPickerResult:(PHPickerResult *)result API_AVAILABLE(ios(14)) {
+- (void)verifySavingImageWithPickerResult:(PHPickerResult *)result
+ fullMetadata:(BOOL)fullMetadata API_AVAILABLE(ios(14)) {
XCTestExpectation *pathExpectation = [self expectationWithDescription:@"Path was created"];
FLTPHPickerSaveImageToPathOperation *operation = [[FLTPHPickerSaveImageToPathOperation alloc]
@@ -87,6 +102,7 @@
maxHeight:@100
maxWidth:@100
desiredImageQuality:@100
+ fullMetadata:fullMetadata
savedPathBlock:^(NSString *savedPath) {
if ([[NSFileManager defaultManager] fileExistsAtPath:savedPath]) {
[pathExpectation fulfill];
diff --git a/packages/image_picker/image_picker_ios/example/lib/main.dart b/packages/image_picker/image_picker_ios/example/lib/main.dart
index c5372b8..440f2f1 100755
--- a/packages/image_picker/image_picker_ios/example/lib/main.dart
+++ b/packages/image_picker/image_picker_ios/example/lib/main.dart
@@ -93,10 +93,15 @@
await _displayPickImageDialog(context!,
(double? maxWidth, double? maxHeight, int? quality) async {
try {
- final List<XFile>? pickedFileList = await _picker.getMultiImage(
- maxWidth: maxWidth,
- maxHeight: maxHeight,
- imageQuality: quality,
+ final List<XFile> pickedFileList =
+ await _picker.getMultiImageWithOptions(
+ options: MultiImagePickerOptions(
+ imageOptions: ImageOptions(
+ maxWidth: maxWidth,
+ maxHeight: maxHeight,
+ imageQuality: quality,
+ ),
+ ),
);
setState(() {
_imageFileList = pickedFileList;
@@ -111,11 +116,13 @@
await _displayPickImageDialog(context!,
(double? maxWidth, double? maxHeight, int? quality) async {
try {
- final XFile? pickedFile = await _picker.getImage(
+ final XFile? pickedFile = await _picker.getImageFromSource(
source: source,
- maxWidth: maxWidth,
- maxHeight: maxHeight,
- imageQuality: quality,
+ options: ImagePickerOptions(
+ maxWidth: maxWidth,
+ maxHeight: maxHeight,
+ imageQuality: quality,
+ ),
);
setState(() {
_setImageFileListFromFile(pickedFile);
diff --git a/packages/image_picker/image_picker_ios/ios/Classes/FLTImagePickerPlugin.m b/packages/image_picker/image_picker_ios/ios/Classes/FLTImagePickerPlugin.m
index fa1bb66..27b06ba 100644
--- a/packages/image_picker/image_picker_ios/ios/Classes/FLTImagePickerPlugin.m
+++ b/packages/image_picker/image_picker_ios/ios/Classes/FLTImagePickerPlugin.m
@@ -490,14 +490,15 @@
for (int i = 0; i < results.count; i++) {
PHPickerResult *result = results[i];
- FLTPHPickerSaveImageToPathOperation *operation =
- [[FLTPHPickerSaveImageToPathOperation alloc] initWithResult:result
- maxHeight:maxHeight
- maxWidth:maxWidth
- desiredImageQuality:desiredImageQuality
- savedPathBlock:^(NSString *savedPath) {
- pathList[i] = savedPath;
- }];
+ FLTPHPickerSaveImageToPathOperation *operation = [[FLTPHPickerSaveImageToPathOperation alloc]
+ initWithResult:result
+ maxHeight:maxHeight
+ maxWidth:maxWidth
+ desiredImageQuality:desiredImageQuality
+ fullMetadata:self.callContext.requestFullMetadata
+ savedPathBlock:^(NSString *savedPath) {
+ pathList[i] = savedPath;
+ }];
[operationQueue addOperation:operation];
}
[operationQueue waitUntilAllOperationsAreFinished];
diff --git a/packages/image_picker/image_picker_ios/ios/Classes/FLTPHPickerSaveImageToPathOperation.h b/packages/image_picker/image_picker_ios/ios/Classes/FLTPHPickerSaveImageToPathOperation.h
index 7ba3d28..8e097072 100644
--- a/packages/image_picker/image_picker_ios/ios/Classes/FLTPHPickerSaveImageToPathOperation.h
+++ b/packages/image_picker/image_picker_ios/ios/Classes/FLTPHPickerSaveImageToPathOperation.h
@@ -26,6 +26,7 @@
maxHeight:(NSNumber *)maxHeight
maxWidth:(NSNumber *)maxWidth
desiredImageQuality:(NSNumber *)desiredImageQuality
+ fullMetadata:(BOOL)fullMetadata
savedPathBlock:(void (^)(NSString *))savedPathBlock API_AVAILABLE(ios(14));
@end
diff --git a/packages/image_picker/image_picker_ios/ios/Classes/FLTPHPickerSaveImageToPathOperation.m b/packages/image_picker/image_picker_ios/ios/Classes/FLTPHPickerSaveImageToPathOperation.m
index a81c95f..7c8fbc9 100644
--- a/packages/image_picker/image_picker_ios/ios/Classes/FLTPHPickerSaveImageToPathOperation.m
+++ b/packages/image_picker/image_picker_ios/ios/Classes/FLTPHPickerSaveImageToPathOperation.m
@@ -13,6 +13,7 @@
@property(assign, nonatomic) NSNumber *maxHeight;
@property(assign, nonatomic) NSNumber *maxWidth;
@property(assign, nonatomic) NSNumber *desiredImageQuality;
+@property(assign, nonatomic) BOOL requestFullMetadata;
@end
@@ -28,6 +29,7 @@
maxHeight:(NSNumber *)maxHeight
maxWidth:(NSNumber *)maxWidth
desiredImageQuality:(NSNumber *)desiredImageQuality
+ fullMetadata:(BOOL)fullMetadata
savedPathBlock:(GetSavedPath)savedPathBlock API_AVAILABLE(ios(14)) {
if (self = [super init]) {
if (result) {
@@ -35,6 +37,7 @@
self.maxHeight = maxHeight;
self.maxWidth = maxWidth;
self.desiredImageQuality = desiredImageQuality;
+ self.requestFullMetadata = fullMetadata;
getSavedPath = savedPathBlock;
executing = NO;
finished = NO;
@@ -113,7 +116,12 @@
* Processes the image.
*/
- (void)processImage:(UIImage *)localImage API_AVAILABLE(ios(14)) {
- PHAsset *originalAsset = [FLTImagePickerPhotoAssetUtil getAssetFromPHPickerResult:self.result];
+ PHAsset *originalAsset;
+ // Only if requested, fetch the full "PHAsset" metadata, which requires "Photo Library Usage"
+ // permissions.
+ if (self.requestFullMetadata) {
+ originalAsset = [FLTImagePickerPhotoAssetUtil getAssetFromPHPickerResult:self.result];
+ }
if (self.maxWidth != nil || self.maxHeight != nil) {
localImage = [FLTImagePickerImageUtil scaledImage:localImage
diff --git a/packages/image_picker/image_picker_ios/pubspec.yaml b/packages/image_picker/image_picker_ios/pubspec.yaml
index 5c30bf9..6c78b23 100755
--- a/packages/image_picker/image_picker_ios/pubspec.yaml
+++ b/packages/image_picker/image_picker_ios/pubspec.yaml
@@ -2,7 +2,7 @@
description: iOS implementation of the image_picker plugin.
repository: https://github.com/flutter/plugins/tree/main/packages/image_picker/image_picker_ios
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+image_picker%22
-version: 0.8.6
+version: 0.8.6+1
environment:
sdk: ">=2.14.0 <3.0.0"
diff --git a/packages/in_app_purchase/in_app_purchase_storekit/CHANGELOG.md b/packages/in_app_purchase/in_app_purchase_storekit/CHANGELOG.md
index 1982a45..2952c4b 100644
--- a/packages/in_app_purchase/in_app_purchase_storekit/CHANGELOG.md
+++ b/packages/in_app_purchase/in_app_purchase_storekit/CHANGELOG.md
@@ -1,6 +1,7 @@
-## NEXT
+## 0.3.2+1
* Updates minimum Flutter version to 2.10.
+* Replaces deprecated ThemeData.primaryColor.
## 0.3.2
diff --git a/packages/in_app_purchase/in_app_purchase_storekit/example/lib/main.dart b/packages/in_app_purchase/in_app_purchase_storekit/example/lib/main.dart
index 72086ee..aa03190 100644
--- a/packages/in_app_purchase/in_app_purchase_storekit/example/lib/main.dart
+++ b/packages/in_app_purchase/in_app_purchase_storekit/example/lib/main.dart
@@ -336,7 +336,7 @@
children: <Widget>[
TextButton(
style: TextButton.styleFrom(
- backgroundColor: Theme.of(context).primaryColor,
+ backgroundColor: Theme.of(context).colorScheme.primary,
// TODO(darrenaustin): Migrate to new API once it lands in stable: https://github.com/flutter/flutter/issues/105724
// ignore: deprecated_member_use
primary: Colors.white,
diff --git a/packages/in_app_purchase/in_app_purchase_storekit/pubspec.yaml b/packages/in_app_purchase/in_app_purchase_storekit/pubspec.yaml
index 69bc6c6..0768371 100644
--- a/packages/in_app_purchase/in_app_purchase_storekit/pubspec.yaml
+++ b/packages/in_app_purchase/in_app_purchase_storekit/pubspec.yaml
@@ -2,7 +2,7 @@
description: An implementation for the iOS platform of the Flutter `in_app_purchase` plugin. This uses the StoreKit Framework.
repository: https://github.com/flutter/plugins/tree/main/packages/in_app_purchase/in_app_purchase_storekit
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+in_app_purchase%22
-version: 0.3.2
+version: 0.3.2+1
environment:
sdk: ">=2.14.0 <3.0.0"
diff --git a/packages/plugin_platform_interface/CHANGELOG.md b/packages/plugin_platform_interface/CHANGELOG.md
index 0e9b701..0b5a6b6 100644
--- a/packages/plugin_platform_interface/CHANGELOG.md
+++ b/packages/plugin_platform_interface/CHANGELOG.md
@@ -1,7 +1,11 @@
-## NEXT
+## 2.1.3
* Minor fixes for new analysis options.
* Adds additional tests for `PlatformInterface` and `MockPlatformInterfaceMixin`.
+* Modifies `PlatformInterface` to use an expando for detecting if a customer
+ tries to implement PlatformInterface using `implements` rather than `extends`.
+ This ensures that `verify` will continue to work as advertized after
+ https://github.com/dart-lang/language/issues/2020 is implemented.
## 2.1.2
diff --git a/packages/plugin_platform_interface/lib/plugin_platform_interface.dart b/packages/plugin_platform_interface/lib/plugin_platform_interface.dart
index a03c9ce..6733b29 100644
--- a/packages/plugin_platform_interface/lib/plugin_platform_interface.dart
+++ b/packages/plugin_platform_interface/lib/plugin_platform_interface.dart
@@ -44,9 +44,20 @@
/// derived classes.
///
/// @param token The same, non-`const` `Object` that will be passed to `verify`.
- PlatformInterface({required Object token}) : _instanceToken = token;
+ PlatformInterface({required Object token}) {
+ _instanceTokens[this] = token;
+ }
- final Object? _instanceToken;
+ /// Expando mapping instances of PlatformInterface to their associated tokens.
+ /// The reason this is not simply a private field of type `Object?` is because
+ /// as of the implementation of field promotion in Dart
+ /// (https://github.com/dart-lang/language/issues/2020), it is a runtime error
+ /// to invoke a private member that is mocked in another library. The expando
+ /// approach prevents [_verify] from triggering this runtime exception when
+ /// encountering an implementation that uses `implements` rather than
+ /// `extends`. This in turn allows [_verify] to throw an [AssertionError] (as
+ /// documented).
+ static final Expando<Object> _instanceTokens = Expando<Object>();
/// Ensures that the platform instance was constructed with a non-`const` token
/// that matches the provided token and throws [AssertionError] if not.
@@ -89,10 +100,10 @@
return;
}
if (preventConstObject &&
- identical(instance._instanceToken, const Object())) {
+ identical(_instanceTokens[instance], const Object())) {
throw AssertionError('`const Object()` cannot be used as the token.');
}
- if (!identical(token, instance._instanceToken)) {
+ if (!identical(token, _instanceTokens[instance])) {
throw AssertionError(
'Platform interfaces must not be implemented with `implements`');
}
diff --git a/packages/plugin_platform_interface/pubspec.yaml b/packages/plugin_platform_interface/pubspec.yaml
index f4800d4..6a4bc48 100644
--- a/packages/plugin_platform_interface/pubspec.yaml
+++ b/packages/plugin_platform_interface/pubspec.yaml
@@ -15,7 +15,7 @@
# be done when absolutely necessary and after the ecosystem has already migrated to 2.X.Y version
# that is forward compatible with 3.0.0 (ideally the ecosystem have migrated to depend on:
# `plugin_platform_interface: >=2.X.Y <4.0.0`).
-version: 2.1.2
+version: 2.1.3
environment:
sdk: ">=2.12.0 <3.0.0"
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 329cecb..869017c 100644
--- a/packages/plugin_platform_interface/test/plugin_platform_interface_test.dart
+++ b/packages/plugin_platform_interface/test/plugin_platform_interface_test.dart
@@ -21,6 +21,12 @@
class ImplementsSamplePluginPlatform extends Mock
implements SamplePluginPlatform {}
+class ImplementsSamplePluginPlatformUsingNoSuchMethod
+ implements SamplePluginPlatform {
+ @override
+ dynamic noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+}
+
class ImplementsSamplePluginPlatformUsingMockPlatformInterfaceMixin extends Mock
with MockPlatformInterfaceMixin
implements SamplePluginPlatform {}
@@ -98,6 +104,13 @@
}, throwsA(isA<AssertionError>()));
});
+ test('prevents implmentation with `implements` and `noSuchMethod`', () {
+ expect(() {
+ SamplePluginPlatform.instance =
+ ImplementsSamplePluginPlatformUsingNoSuchMethod();
+ }, throwsA(isA<AssertionError>()));
+ });
+
test('allows mocking with `implements`', () {
final SamplePluginPlatform mock =
ImplementsSamplePluginPlatformUsingMockPlatformInterfaceMixin();