Skip to content

Conversation

@dasyad00
Copy link
Contributor

@dasyad00 dasyad00 commented Oct 25, 2025

Implements MediaSettings::fps in camera_android_camerax for image preview, image streaming, and video recording.

  • Resolves #167719: implements the feature instead of adding documentation that it does not work.
  • Partially resolves #176148: only implements for camera_android_camerax, and uses the existing MediaSettings::fps instead of adding parameters to CameraImageStreamOptions

Pre-Review Checklist

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-assist bot 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

  1. 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 3

@dasyad00 dasyad00 force-pushed the androix_camerax/control_fps branch from 6707def to 3404a0b Compare October 25, 2025 13:40
@dasyad00 dasyad00 marked this pull request as ready for review October 25, 2025 13:40
@dasyad00 dasyad00 requested a review from camsim99 as a code owner October 25, 2025 13:40
Copy link
Contributor

@camsim99 camsim99 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks great! Thank you so much for taking this on. This will be a huge improvement to the plugin!

I think we need to add a Dart test, but otherwise LGTM. Let's get a second review.


@RunWith(RobolectricTestRunner.class)
public class ImageAnalysisTest {
@SuppressWarnings({"unchecked", "rawtypes"})
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: where you added this annotation, can you leave a comment as to why this is safe?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let me know whether I should try upgrading Mockito, or just leave a comment about it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Upgrading mockito if possible would be great!

If you run into issues, though, feel free to open an issue andwe can take a look. Though, I just meant to leave a comment in the code so we remember why we added the suppression, so if you don't upgrade mockito, can you do that?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've just added a comment for the rationale behind the warning suppression: c954355.

Apparently it's a limitation of Java and not Mockito.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should add a test to make sure that if the fps media setting is passed, we actually set it as expected. I know these test are a bit daunting to write so let me know if you need help 😅

Just in case you need help getting started: The hardest part is mocking the pigeon calls. There are several other createCamera tests you can copy or modify to handle the mocks, though. But there are some helper methods at the top of the file that can help with that. I think you could end up doing something like

newCameraSelector:
({
LensFacing? requireLensFacing,
CameraInfo? cameraInfoForFilter,
// ignore: non_constant_identifier_names
BinaryMessenger? pigeon_binaryMessenger,
// ignore: non_constant_identifier_names
PigeonInstanceManager? pigeon_instanceManager,
}) {
if (cameraInfoForFilter == mockFrontCameraInfo) {
return mockFrontCameraSelector;
}
return mockBackCameraSelector;
},
where can check the fps and return a mock object then check that the use case (like camera.videoCapture) equals your mock object.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've added a unit test in 4abed18. Was this what you had in mind?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great thanks! This looks good to me.

Copy link
Contributor

@bparrishMines bparrishMines left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM pending unit tests and updating the lint-baseline.xml.

class ImageAnalysisProxyApi extends PigeonApiImageAnalysis {
static final long CLEAR_FINALIZED_WEAK_REFERENCES_INTERVAL_FOR_IMAGE_ANALYSIS = 1000;

@OptIn(markerClass = ExperimentalCamera2Interop.class)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This plugin updates [lint-baseline.xml] (https://github.com/flutter/packages/blob/main/packages/camera/camera_android_camerax/android/lint-baseline.xml) to handle this specific warning.

This should be updateable by following https://developer.android.com/studio/write/lint#snapshot in the example app. But this can be updated after getting both LGTMs.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just tried to run this (./gradlew lintDebug -Dlint.baselines.continue=true) inside of the camera_android_camerax/example/android directory, but I see that lint-baseline.xml only contains references to src/main/java/io/flutter/plugins/camerax/CameraXLibrary.g.kt.

I also see @OptIn(markerClass = ExperimentalCamera2Interop.class) already used in Camera2CameraControlProxyApi.java and Camera2CameraInfoProxyApi.java

Is this to be expected?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, good catch! @camsim99 was baseline intended to only be used for the CameraXLibrary.g.kt?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ideally, the baseline should only handles lints caused by generated code since we can't control it, though I'm open to it in certain cases. I think keeping this annotation could be nice so we can easily identify experimental CameraX features.

@camsim99 camsim99 self-requested a review November 4, 2025 16:28
Copy link
Contributor

@camsim99 camsim99 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks for the fixes :)


@RunWith(RobolectricTestRunner.class)
public class ImageAnalysisTest {
@SuppressWarnings({"unchecked", "rawtypes"})
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Upgrading mockito if possible would be great!

If you run into issues, though, feel free to open an issue andwe can take a look. Though, I just meant to leave a comment in the code so we remember why we added the suppression, so if you don't upgrade mockito, can you do that?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great thanks! This looks good to me.

@dasyad00 dasyad00 force-pushed the androix_camerax/control_fps branch from c954355 to 9ec4f0a Compare November 11, 2025 09:14
@stuartmorgan-g
Copy link
Collaborator

From triage: @bparrishMines It looks like this had your preliminary LGTM, but needs a final re-review and approval.

)
abstract class Preview extends UseCase {
Preview(int? targetRotation);
Preview(int? targetRotation, int? targetFps);
Copy link
Contributor

@bparrishMines bparrishMines Nov 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like this takes a range in the Java code. This should use CameraIntegerRange defined in this file instead. Same for the other classes.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've reworked it so that we pass CameraIntegerRange instead of int

Copy link
Contributor

@bparrishMines bparrishMines left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks mostly good to me. Just a comment on the type passed for the fps.

@dasyad00 dasyad00 force-pushed the androix_camerax/control_fps branch from 9ec4f0a to 9439f17 Compare November 23, 2025 18:04
@dasyad00 dasyad00 force-pushed the androix_camerax/control_fps branch from 7545acf to d13436c Compare November 23, 2025 19:25
Copy link
Contributor

@bparrishMines bparrishMines left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@bparrishMines bparrishMines added the autosubmit Merge PR when tree becomes green via auto submit App label Nov 26, 2025
@auto-submit auto-submit bot merged commit b505d41 into flutter:main Nov 26, 2025
80 checks passed
engine-flutter-autoroll added a commit to engine-flutter-autoroll/flutter that referenced this pull request Nov 27, 2025
github-merge-queue bot pushed a commit to flutter/flutter that referenced this pull request Nov 27, 2025
flutter/packages@5d8d954...b505d41

2025-11-26 dasyad00@gmail.com [camera_android_camerax] use
MediaSettings::fps for image preview, streaming, and video recording
(flutter/packages#10301)
2025-11-26 stuartmorgan@google.com [various] Update READMEs to reflect
current OS support (flutter/packages#10470)
2025-11-26 engine-flutter-autoroll@skia.org Roll Flutter from
3f553f6 to 7b98d50 (30 revisions) (flutter/packages#10523)
2025-11-26 alex@swipelab.co [camera] fix RECORD_AUDIO permission on
Android when there is no permission (flutter/packages#10424)

If this roll has caused a breakage, revert this CL and stop the roller
using the controls here:
https://autoroll.skia.org/r/flutter-packages-flutter-autoroll
Please CC flutter-ecosystem@google.com 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
mboetger pushed a commit to mboetger/flutter that referenced this pull request Dec 2, 2025
…r#179188)

flutter/packages@5d8d954...b505d41

2025-11-26 dasyad00@gmail.com [camera_android_camerax] use
MediaSettings::fps for image preview, streaming, and video recording
(flutter/packages#10301)
2025-11-26 stuartmorgan@google.com [various] Update READMEs to reflect
current OS support (flutter/packages#10470)
2025-11-26 engine-flutter-autoroll@skia.org Roll Flutter from
3f553f6 to 7b98d50 (30 revisions) (flutter/packages#10523)
2025-11-26 alex@swipelab.co [camera] fix RECORD_AUDIO permission on
Android when there is no permission (flutter/packages#10424)

If this roll has caused a breakage, revert this CL and stop the roller
using the controls here:
https://autoroll.skia.org/r/flutter-packages-flutter-autoroll
Please CC flutter-ecosystem@google.com 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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

autosubmit Merge PR when tree becomes green via auto submit App p: camera platform-android

Projects

None yet

4 participants