Skip to content
Open
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions packages/camera/camera_android/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 0.10.10+17

* Reset AE and AF triggers to idle after capture to fix camera flash remaining issue #97501.

## 0.10.10+16

* Updates build files from Groovy to Kotlin.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import android.graphics.SurfaceTexture;
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraCaptureSession;
import android.hardware.camera2.CaptureFailure;
import android.hardware.camera2.CameraDevice;
import android.hardware.camera2.CameraManager;
import android.hardware.camera2.CameraMetadata;
Expand Down Expand Up @@ -675,13 +676,39 @@ private void runPrecaptureSequence() {

// Trigger one capture to start AE sequence.
captureSession.capture(
previewRequestBuilder.build(), cameraCaptureCallback, backgroundHandler);
previewRequestBuilder.build(),
createTriggerResetCallback(
CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER,
CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER_IDLE),
backgroundHandler);

} catch (CameraAccessException e) {
e.printStackTrace();
}
}

@VisibleForTesting
CameraCaptureSession.CaptureCallback createTriggerResetCallback(
final CaptureRequest.Key<Integer> triggerKey, final int triggerIdleValue) {
return new CameraCaptureSession.CaptureCallback() {
@Override
public void onCaptureCompleted(
@NonNull CameraCaptureSession session,
@NonNull CaptureRequest request,
@NonNull TotalCaptureResult result) {
previewRequestBuilder.set(triggerKey, triggerIdleValue);
}

@Override
public void onCaptureFailed(
@NonNull CameraCaptureSession session,
@NonNull CaptureRequest request,
@NonNull CaptureFailure failure) {
previewRequestBuilder.set(triggerKey, triggerIdleValue);
}
};
}

/**
* Capture a still picture. This method should be called when a response is received {@link
* #cameraCaptureCallback} from both lockFocus().
Expand Down Expand Up @@ -788,7 +815,11 @@ private void lockAutoFocus() {
CaptureRequest.CONTROL_AF_TRIGGER, CaptureRequest.CONTROL_AF_TRIGGER_START);

try {
captureSession.capture(previewRequestBuilder.build(), null, backgroundHandler);
captureSession.capture(
previewRequestBuilder.build(),
createTriggerResetCallback(
CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF_TRIGGER_IDLE),
backgroundHandler);
} catch (CameraAccessException e) {
String message =
(e.getMessage() == null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -976,6 +976,62 @@ public void setFocusMode_shouldSendErrorEventOnLockAutoFocusCameraAccessExceptio
verify(mockDartMessenger, times(1)).sendCameraErrorEvent(any());
}

@Test
public void createTriggerResetCallback_shouldResetTriggerOnCaptureCompleted() {
CaptureRequest.Key<Integer> triggerKey = CaptureRequest.CONTROL_AF_TRIGGER;
int idleValue = CameraMetadata.CONTROL_AF_TRIGGER_IDLE;

CameraCaptureSession.CaptureCallback callback =
camera.createTriggerResetCallback(triggerKey, idleValue);

callback.onCaptureCompleted(
mock(CameraCaptureSession.class), mock(CaptureRequest.class), mock(TotalCaptureResult.class));

verify(mockPreviewRequestBuilder, times(1)).set(triggerKey, idleValue);
}

@Test
public void createTriggerResetCallback_shouldResetTriggerOnCaptureFailed() {
CaptureRequest.Key<Integer> triggerKey = CaptureRequest.CONTROL_AF_TRIGGER;
int idleValue = CameraMetadata.CONTROL_AF_TRIGGER_IDLE;

CameraCaptureSession.CaptureCallback callback =
camera.createTriggerResetCallback(triggerKey, idleValue);

callback.onCaptureFailed(
mock(CameraCaptureSession.class), mock(CaptureRequest.class), mock(CaptureFailure.class));

verify(mockPreviewRequestBuilder, times(1)).set(triggerKey, idleValue);
}

@Test
public void createTriggerResetCallback_shouldResetAEPrecaptureTriggerOnCaptureCompleted() {
CaptureRequest.Key<Integer> triggerKey = CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER;
int idleValue = CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER_IDLE;

CameraCaptureSession.CaptureCallback callback =
camera.createTriggerResetCallback(triggerKey, idleValue);

callback.onCaptureCompleted(
mock(CameraCaptureSession.class), mock(CaptureRequest.class), mock(TotalCaptureResult.class));

verify(mockPreviewRequestBuilder, times(1)).set(triggerKey, idleValue);
}

@Test
public void createTriggerResetCallback_shouldResetAEPrecaptureTriggerOnCaptureFailed() {
CaptureRequest.Key<Integer> triggerKey = CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER;
int idleValue = CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER_IDLE;

CameraCaptureSession.CaptureCallback callback =
camera.createTriggerResetCallback(triggerKey, idleValue);

callback.onCaptureFailed(
mock(CameraCaptureSession.class), mock(CaptureRequest.class), mock(CaptureFailure.class));

verify(mockPreviewRequestBuilder, times(1)).set(triggerKey, idleValue);
}

@Test
public void setFocusMode_shouldCallErrorOnResultOnCameraAccessException()
throws CameraAccessException {
Expand Down
2 changes: 1 addition & 1 deletion packages/camera/camera_android/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ description: Android implementation of the camera plugin.
repository: https://github.com/flutter/packages/tree/main/packages/camera/camera_android
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+camera%22

version: 0.10.10+16
version: 0.10.10+17

environment:
sdk: ^3.9.0
Expand Down