[camera_android_camerax] Restore torch state between camera switches#11541
[camera_android_camerax] Restore torch state between camera switches#11541camsim99 wants to merge 12 commits intoflutter:mainfrom
Conversation
…really a timing issue
631b962 to
b33f6ae
Compare
| > - **Option B (Ideal)**: Expose `hasFlashUnit()` via Pigeon and check it before attempting to restore torch. | ||
| > |
There was a problem hiding this comment.
I think this is an indication that we have not given the agent sufficient context to understand the design principles for where we put what layer of logic. That said, our goal is to one-shot package changes not one shot plans. Let's see if there is also evidence that it does not understand where to put logic when it implements code.
There was a problem hiding this comment.
I think A is the right approach for fixing the issue. B wouldn't fix it on its own but I do think it identified a good improvement for the plugin which is checking hasFlashUnit before trying to turn on the torch and giving back a helpful error if so.
|
|
||
| --- | ||
|
|
||
| #### [MODIFY] [android_camera_camerax.dart](file:///Users/camillesimon/packages/packages/camera/camera_android_camerax/lib/src/android_camera_camerax.dart) |
There was a problem hiding this comment.
Agents can wander across the files they have access to. I think running this under the camera_android_camerax package is probably sufficient to keep the changes scoped there. My one worry is that it tries to modify the root federated api surface.
Maybe we say "Changes must be backwards compatible and should stay in camera_android_camerax"
There was a problem hiding this comment.
Also if this was a relative path I think in code review we could click it and read the file it was suggesting modifications to.
|
|
||
| #### [MODIFY] [android_camera_camerax.dart](file:///Users/camillesimon/packages/packages/camera/camera_android_camerax/lib/src/android_camera_camerax.dart) | ||
|
|
||
| - Add `_currentCameraDescription` instance variable to track active camera. |
There was a problem hiding this comment.
I do not understand why this needs a new variable. Why cant one of camera, cameraInfo or liveCameraState track which camera is "current"
There was a problem hiding this comment.
I think the key to the map should be Camera2CameraInfo.from(cameraInfo).cameraId in java. Not sure what the dart equivalent is.
There was a problem hiding this comment.
We need it to track the last torch state per camera. The suggested _currentCameraDescription.name is the equivalent of Camera2CameraInfo.from(cameraInfo).cameraId
| - Update `_currentCameraDescription` in `createCameraWithSettings` and `setDescriptionWhileRecording`. | ||
| - Replace `torchEnabled` boolean with `Map<String, bool> _torchEnabledPerCamera = {};`. | ||
| - Update `setFlashMode` to use `_torchEnabledPerCamera` keyed by `_currentCameraDescription.name`. | ||
| - Modify `_enableTorchMode` to accept an optional `isRestore` boolean parameter (defaulting to `false`). If `isRestore` is true and the operation fails, the error should not be added to `cameraErrorStreamController`. `isRestore` is true when called during automatic restoration. |
There was a problem hiding this comment.
Reading the implementation of _enableTorchMode I dont think the input should be isRestore because in the context of that method the only thing it would decide is if an error should be thrown. The variable in _enableTorchMode should be "shouldThrowOnFailure" or something similar.
Then in the places where we call _enableTorchMode(<bool>. shouldThrowOnFailure=isRestore)
|
|
||
| Run tests using: | ||
| ```bash | ||
| dart test test/android_camera_camerax_test.dart |
There was a problem hiding this comment.
I think this should be dart run ../../../script/tool/bin/flutter_plugin_tools.dart dart-test --package=camera_android_camerax and we should remove it from below.
|
|
||
| ### Automated Tests | ||
|
|
||
| I will add unit tests in `android_camera_camerax_test.dart` to verify: |
There was a problem hiding this comment.
There should be a test for restoring a torch mode to off in addition to restoring to on.
| ``` | ||
|
|
||
| Additionally, run the following commands to ensure codebase health: | ||
| ```bash |
There was a problem hiding this comment.
@camsim99 do you think we should ask/tell the agent to make the tool call an alias to make the below commands easier to read.
|
|
||
| Additionally, run the following commands to ensure codebase health: | ||
| ```bash | ||
| # Format and Analyze |
There was a problem hiding this comment.
I suggest we give some guidance to the prompt on when to run each of these tools.
Here is my suggestion.
- Run format and analyze after every code edit.
- Run fix if errors are found in analyze before attempting any other mitigations.
- Run tests after each test case added and after finishing a unit of code work.
- Run gradle check after touching build.gradle.kts files
- Run license check after getting new files to their final state.
- When you think you are completely done run readme, version, pubspec checks.
- finally run publish check.
| dart run ../../../script/tool/bin/flutter_plugin_tools.dart pubspec-check --packages=camera_android_camerax | ||
| dart run ../../../script/tool/bin/flutter_plugin_tools.dart readme-check --packages=camera_android_camerax | ||
| dart run ../../../script/tool/bin/flutter_plugin_tools.dart version-check --packages=camera_android_camerax | ||
| ``` |
There was a problem hiding this comment.
The automated test need to include building the example app.
There was a problem hiding this comment.
Not sure when you want to add this in but we can also point it to the integration tests, making sure those all pass (and thus, the example app builds). Of course, it ideally also adds an integration test.
| dart run ../../../script/tool/bin/flutter_plugin_tools.dart version-check --packages=camera_android_camerax | ||
| ``` | ||
|
|
||
| ### Manual Verification |
There was a problem hiding this comment.
This needs to expanded to let the agent build the example app against an emulator.
Give the agent a command to start an emulator you have installed locally, We can worry about portability later. I also recommend we install the skill android-adb it is mit licensed.
adb shell dumpsys media.camera | grep -i "torch" can find the state of the torch.
There was a problem hiding this comment.
2 considerations we might consider including in the manual verification section since I hope to run the plan from more than just your host machine.
Hardware Emulation: In the AVD Manager, ensure your emulator's camera setting is set to something other than None. If it is set to Emulated or Webcam, the system image may or may not support torch operations depending on the API level and emulator build.
Unsupported State: If the emulator simply does not support the torch, CameraCharacteristics.FLASH_INFO_AVAILABLE will return false. You can verify this by checking the dumpsys output for "flash" availability. If it is unavailable, the plugin's attempts to toggle the torch will be ignored by the system, which is a common reason for the "silent failure" you might be seeing in the issue you linked.
camsim99
left a comment
There was a problem hiding this comment.
High level thoughts on the plan % the manual verification section (which will require an entirely new draft from me looks like)
| > - **Option B (Ideal)**: Expose `hasFlashUnit()` via Pigeon and check it before attempting to restore torch. | ||
| > |
There was a problem hiding this comment.
I think A is the right approach for fixing the issue. B wouldn't fix it on its own but I do think it identified a good improvement for the plugin which is checking hasFlashUnit before trying to turn on the torch and giving back a helpful error if so.
| - Update `_currentCameraDescription` in `createCameraWithSettings` and `setDescriptionWhileRecording`. | ||
| - Replace `torchEnabled` boolean with `Map<String, bool> _torchEnabledPerCamera = {};`. | ||
| - Update `setFlashMode` to use `_torchEnabledPerCamera` keyed by `_currentCameraDescription.name`. | ||
| - Modify `_enableTorchMode` to accept an optional `isRestore` boolean parameter (defaulting to `false`). If `isRestore` is true and the operation fails, the error should not be added to `cameraErrorStreamController`. `isRestore` is true when called during automatic restoration. |
|
|
||
| #### [MODIFY] [android_camera_camerax.dart](file:///Users/camillesimon/packages/packages/camera/camera_android_camerax/lib/src/android_camera_camerax.dart) | ||
|
|
||
| - Add `_currentCameraDescription` instance variable to track active camera. |
There was a problem hiding this comment.
We need it to track the last torch state per camera. The suggested _currentCameraDescription.name is the equivalent of Camera2CameraInfo.from(cameraInfo).cameraId
| ``` | ||
|
|
||
| Additionally, run the following commands to ensure codebase health: | ||
| ```bash |
| dart run ../../../script/tool/bin/flutter_plugin_tools.dart pubspec-check --packages=camera_android_camerax | ||
| dart run ../../../script/tool/bin/flutter_plugin_tools.dart readme-check --packages=camera_android_camerax | ||
| dart run ../../../script/tool/bin/flutter_plugin_tools.dart version-check --packages=camera_android_camerax | ||
| ``` |
There was a problem hiding this comment.
Not sure when you want to add this in but we can also point it to the integration tests, making sure those all pass (and thus, the example app builds). Of course, it ideally also adds an integration test.
|
Despite me being at next I am available to review this so we can make forward progress this week. Just ping me when it is ready for another review. |
| #### [MODIFY] [pigeons/camerax_library.dart](file:///Users/camillesimon/packages/packages/camera/camera_android_camerax/pigeons/camerax_library.dart) | ||
|
|
||
| - Add `bool hasFlashUnit();` to `abstract class CameraInfo`. | ||
| - Run the Pigeon generator to update generated files. |
There was a problem hiding this comment.
I don't think we have to modify the plan here but I am wondering if the agents know how to use this library. I do think we should probably make sure that one of the automated verification steps will ensure that the generated files have been updated correctly and not by the agent.
| - Add `bool hasFlashUnit();` to `abstract class CameraInfo`. | ||
| - Run the Pigeon generator to update generated files. | ||
|
|
||
| #### [MODIFY] [android/src/main/java/io/flutter/plugins/camerax/CameraInfoProxyApi.java](file:///Users/camillesimon/packages/packages/camera/camera_android_camerax/android/src/main/java/io/flutter/plugins/camerax/CameraInfoProxyApi.java) |
There was a problem hiding this comment.
Can you remove all global paths and replace them with relative paths? Or is this the result of having strong file selectors in your ide?
|
I think this plan is good enough for a first attempt. @kevmoo has a concept he called when the agent is "tired" I am curious if this plan will max out the context window and need to be picked upbon another session mid way through. Check out his "rules" here. https://github.com/kevmoo/sdk/blob/socket2/conductor%2Fcheat_sheet_for_the_agent.md Depending on how the first prompt goes we may want to incorporate some of those. |
It's basically just "context window is full" – but it is fun to talk to the agent about it. I EXPLICITLY say "DO NOT be passive aggressive about 'are we ready to call it a day on this project?' – just tell me your context window is getting full" |
WIP towards fixing flutter/flutter#160956.
Normal pull request information above the line.
This pull request is an attempt to "oneshot" fixing flutter/flutter#160956. Using antigravity to execute a plan that is collaboratively worked on. The "rules" are to not allow human authored code to camera_android_camerax and to not rely on human code review feedback for code iteration.
We can add documentation, skills, mcp servers, presubmit test etc. Basically any "support infrastructure" for development is allowed but the package changes must be generated as a single pass.
When we discover that the plan is not good enough we will blow the package changes away and either modify the plan or add more support infrastructure and try again.
For more information see the working doc in go/flutter-project-one-shot-torch