Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[camera_avfoundation] fix race condition when starting image stream on iOS #8733

Open
wants to merge 7 commits into
base: main
Choose a base branch
from

Conversation

js2702
Copy link

@js2702 js2702 commented Feb 27, 2025

Fixes flutter/flutter#147702

It's not easy to reproduce this with the example application (as shown in the linked issue). We've been able to reproduce it in our own application which makes heavy usage of Platform channels and different native plugins. After digging into the code we notice that:

The Dart code that starts listening to the event channel was being executed before initializing the stream in the native side.

I don't have much experience with Objective-C, so not sure how to create unit tests for that if necessary but I believe this would be an adecuate solution. I've seen other methods in the plugin that use the same strategy passing the completion object.

Pre-launch Checklist

If you need help, consider asking for advice on the #hackers-new channel on Discord.

@js2702 js2702 requested a review from hellohuanlin as a code owner February 27, 2025 17:24
@flutter-dashboard
Copy link

It looks like this pull request may not have tests. Please make sure to add tests before merging. If you need an exemption, contact "@test-exemption-reviewer" in the #hackers channel in Discord (don't just cc them here, they won't see it!).

If you are not sure if you need tests, consider this rule of thumb: the purpose of a test is to make sure someone doesn't accidentally revert the fix. Ask yourself, is there anything in your PR that you feel it is important we not accidentally revert back to how it was before your fix?

Reviewers: Read the Tree Hygiene page and make sure this patch meets those guidelines before LGTMing. The test exemption team is a small volunteer group, so all reviewers should feel empowered to ask for tests, without delegating that responsibility entirely to the test exemption group.

Copy link

google-cla bot commented Feb 27, 2025

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

@js2702 js2702 force-pushed the fix_startstream_race_condition branch from 89cc825 to e902881 Compare February 27, 2025 17:37
@js2702
Copy link
Author

js2702 commented Feb 27, 2025

I'm not sure why but I'm getting a 400 error when signing the CLA (Which I thought I had already signed for other PR)

@hellohuanlin
Copy link
Contributor

This will require unit test in order to land.

@js2702
Copy link
Author

js2702 commented Feb 27, 2025

I'm looking for any example test but I don't see anything. As this doesn't affect the Dart part I don't see how to make a test for this, wouldn't this be test exempt?

Additionally, this bug in particular manifests as a race condition in the communication with Dart and native, requiring an end to end test, which I'm not seeing either.

@stuartmorgan
Copy link
Contributor

stuartmorgan commented Feb 27, 2025

As this doesn't affect the Dart part I don't see how to make a test for this, wouldn't this be test exempt?

There is no blanket test exemption for native code; if there were, almost nothing in plugins would be tested. Please see https://github.com/flutter/flutter/blob/master/docs/ecosystem/testing/Plugin-Tests.md

js2702 added 3 commits March 1, 2025 15:06
# Conflicts:
#	packages/camera/camera_avfoundation/example/ios/Runner.xcodeproj/project.pbxproj
#	packages/camera/camera_avfoundation/example/ios/RunnerTests/StreamingTest.m
@js2702
Copy link
Author

js2702 commented Mar 2, 2025

I added a test for the issue. Everything was working before this last Swift refactor. A few things:

  1. Now these tests that were just changed in StreamingTests.swift (I did not change this file in the PR, as I'm not sure why this is needed now) fail because they are not async/await. Not sure why this happens as I don't see anything that would need async. These are the calls that fail:

https://github.com/SkillDevs/flutter_packages/blob/423c038bdb06ee8d75a2e6523e1ce688e0b555a0/packages/camera/camera_avfoundation/example/ios/RunnerTests/StreamingTests.swift#L74

  1. In my tests, I'm not sure if there is a better way to expect the streamHandler is initialized instead of checking the boolean flag.
  2. Also, in this completion call
    https://github.com/SkillDevs/flutter_packages/blob/423c038bdb06ee8d75a2e6523e1ce688e0b555a0/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/FLTCam.m#L1206
    Should the completion be at the beginning, on each early return, or it's fine where it is?

Again, not an expert in Swift/Objective-C.

Also, the test was developed in Master and it failed unless you added a delay before the expect.

@js2702
Copy link
Author

js2702 commented Mar 2, 2025

Ended up adding the async/await because the tests pass with that, I guess it's because of the callback added to the function?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[camera] regression: startImageStream throws MissingPluginException on iOS
3 participants