Repository navigation
[image_picker] Add native tests for photo-library access and UIImagePicker completion - #12540
Conversation
There was a problem hiding this comment.
Code Review
This pull request adds comprehensive unit tests to ImagePickerPluginTests.m for the iOS image picker plugin, covering permission handling, image/video picking, and scaling scenarios. The review feedback identifies a potential memory corruption or crash issue under ARC in three tests where a block is retrieved from NSInvocation using getArgument:atIndex: into a __strong variable, and suggests declaring these block variables as __unsafe_unretained to prevent over-releasing.
| void (^handler)(PHAuthorizationStatus status); | ||
| [invocation getArgument:&handler atIndex:2]; |
There was a problem hiding this comment.
Under ARC, retrieving a block from NSInvocation using getArgument:atIndex: directly into a __strong block variable can cause memory corruption or crashes due to over-releasing. Since getArgument:atIndex: does not retain the block, the implicit release by ARC when the __strong variable goes out of scope will result in an over-release. To prevent this, declare the block variable as __unsafe_unretained.
| void (^handler)(PHAuthorizationStatus status); | |
| [invocation getArgument:&handler atIndex:2]; | |
| __unsafe_unretained void (^handler)(PHAuthorizationStatus status); | |
| [invocation getArgument:&handler atIndex:2]; |
There was a problem hiding this comment.
Agreed and fixed. The authorization handler is now retrieved as __unsafe_unretained so ARC doesn’t over-release the NSInvocation argument.
| void (^handler)(PHAuthorizationStatus status); | ||
| [invocation getArgument:&handler atIndex:2]; |
There was a problem hiding this comment.
Under ARC, retrieving a block from NSInvocation using getArgument:atIndex: directly into a __strong block variable can cause memory corruption or crashes due to over-releasing. Since getArgument:atIndex: does not retain the block, the implicit release by ARC when the __strong variable goes out of scope will result in an over-release. To prevent this, declare the block variable as __unsafe_unretained.
| void (^handler)(PHAuthorizationStatus status); | |
| [invocation getArgument:&handler atIndex:2]; | |
| __unsafe_unretained void (^handler)(PHAuthorizationStatus status); | |
| [invocation getArgument:&handler atIndex:2]; |
There was a problem hiding this comment.
Agreed and fixed. Same fix here: the authorization handler is now __unsafe_unretained.
| void (^handler)(NSData *, NSString *, CGImagePropertyOrientation, NSDictionary *); | ||
| [invocation getArgument:&handler atIndex:4]; |
There was a problem hiding this comment.
Under ARC, retrieving a block from NSInvocation using getArgument:atIndex: directly into a __strong block variable can cause memory corruption or crashes due to over-releasing. Since getArgument:atIndex: does not retain the block, the implicit release by ARC when the __strong variable goes out of scope will result in an over-release. To prevent this, declare the block variable as __unsafe_unretained.
| void (^handler)(NSData *, NSString *, CGImagePropertyOrientation, NSDictionary *); | |
| [invocation getArgument:&handler atIndex:4]; | |
| __unsafe_unretained void (^handler)(NSData *, NSString *, CGImagePropertyOrientation, NSDictionary *); | |
| [invocation getArgument:&handler atIndex:4]; |
There was a problem hiding this comment.
Agreed and fixed. The PHImageManager result handler is now retrieved as __unsafe_unretained.
f7d25e0 to
690cb40
Compare
e4f1da4 to
865c506
Compare
690cb40 to
9868166
Compare
|
(From triage: this can't land until it is rebased on |
…and presentation.
…ontroller for alert presentation
…siredImageQuality method and simplify test cases
…agePicker completion.
…variables to prevent retain cycles in mock callbacks.
865c506 to
267cee7
Compare
9868166 to
3cbb3b5
Compare
|
autosubmit label was removed for flutter/packages/12540, because - The status or check suite Dashboard Checks has failed. Please fix the issues identified (or deflake) before re-applying this label. |
Removed the deprecated MobileCoreServices import and updated media type checks in the `testLaunchUIImagePickerSetsImageAndVideoMediaTypes` test to utilize the new UniformTypeIdentifiers API. This change enhances compatibility with iOS 14 and later. No functional changes to the tests were made.
…er#192550) flutter/packages@36e088a...8a35b16 2026-09-10 [email protected] [material_ui] Migrate M3 buttons template to use new gen_defaults (flutter/packages#12744) 2026-09-09 [email protected] [cupertino_ui]Add awaitNotRequired to Future-returning callsites without await (flutter/packages#12817) 2026-09-09 [email protected] [material_ui] Add awaitNotRequired annotation to material_ui (flutter/packages#12622) 2026-09-09 [email protected] [image_picker] Add native tests for photo-library access and UIImagePicker completion (flutter/packages#12540) 2026-09-09 [email protected] [material_ui][cupertino_ui] allow page routes to opt out of route semantics - flutter#182556 (flutter/packages#12674) 2026-09-09 [email protected] [image_picker] Add native tests for pick results, camera access, and presentation (flutter/packages#12539) 2026-09-09 [email protected] [cupertino_ui] Fix platform view sheet transitions (flutter/packages#12565) 2026-09-09 [email protected] [camera_android_camerax] Bump cameraxVersion to 1.6.2, remove concurrent-futures workaround (flutter/packages#12698) 2026-09-09 [email protected] `[material_ui]` replace identical checks with equality when dealing with enums (flutter/packages#12633) 2026-09-09 [email protected] Roll Flutter from b444e78 to 63b9518 (21 revisions) (flutter/packages#12814) 2026-09-09 [email protected] `[cupertino_ui]` replace identical checks with equality when dealing with enums (flutter/packages#12632) 2026-09-09 [email protected] [pigeon] add support for multiple swift outputs (flutter/packages#12720) If this roll has caused a breakage, revert this CL and set the roller to dry run mode using the controls here: https://autoroll.skia.org/r/flutter-packages-flutter-autoroll Please CC [email protected] on the revert to ensure that a human is aware of the problem. To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
Stacked on #12539.
Adds native unit tests for previously untested paths in
FLTImagePickerPlugin.m(photo-library authorization,UIImagePickerlaunch, anddidFinishPickingMediaWithInfo:) before the Objective-C → Swift migration. Production code is unchanged.This is a tests-only change, so it does not bump the package version or CHANGELOG.
ImagePickerPluginTestsgo from 52 tests to 70 tests (+18).New test cases
Photo-library access:
testLaunchUIImagePickerGalleryWithoutFullMetadataSkipsAuthorization— gallery without full metadata skips the authorization checktestPhotoAccessDeniedReturnsError— denied photo access returns an errortestPhotoAccessRestrictedReturnsError— restricted photo access returns an errortestPhotoAccessAuthorizedShowsLibrary— authorized access presents the librarytestPhotoAccessNotDeterminedGrantedShowsLibrary— prompt granted presents the librarytestPhotoAccessNotDeterminedDeniedReturnsError— prompt denied returns an errortestPhotoAccessLimitedReturnsDeniedError— Limited access falls through to deniedtestPhotoAccessUnknownStatusTreatedAsDenied— unknown status is treated as deniedlaunchUIImagePickerWithSource::testLaunchUIImagePickerInvalidSourceReturnsError— an invalid source returns an errortestLaunchUIImagePickerSetsImageAndVideoMediaTypes— image/video media types and duration are set on the pickerimagePickerController:didFinishPickingMediaWithInfo::testImagePickerDidFinishPickingOriginalImage— original image is savedtestImagePickerDidFinishPickingPrefersEditedImage— edited image is preferred over originaltestImagePickerDidFinishPickingScalesImage— the image is scaled when requestedtestImagePickerDidFinishPickingWithFullMetadataAsset— full-metadata path usesPHImageManagerwhen an asset is presenttestImagePickerDidFinishPickingFullMetadataWithoutAsset— full metadata without an asset still completestestImagePickerDidFinishPickingVideo— video is copied successfullytestImagePickerDidFinishPickingVideoCopyFailure— a video copy failure is reportedtestImagePickerDidFinishPickingIgnoredWhenNoCallContext— nocallContextis a no-opThird part of
image_picker_ioscoverage backfill before the Obj-C → Swift migration for flutter/flutter#119107Pre-Review Checklist
[shared_preferences]///).If you need help, consider asking for advice on the #hackers-new channel on Discord.
Note: The Flutter team is currently trialing the use of Gemini Code Assist for GitHub. Comments from the
gemini-code-assistbot should not be taken as authoritative feedback from the Flutter team. If you find its comments useful you can update your code accordingly, but if you are unsure or disagree with the feedback, please feel free to wait for a Flutter team member's review for guidance on which automated comments should be addressed.Footnotes
Regular contributors who have demonstrated familiarity with the repository guidelines only need to comment if the PR is not auto-exempted by repo tooling. ↩ ↩2