diff --git a/api/current.txt b/api/current.txt
index 3c681d21a6831..4e5e59720fe46 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -12725,6 +12725,7 @@ package android.hardware.camera2 {
field public static final int CONTROL_AE_MODE_ON_ALWAYS_FLASH = 3; // 0x3
field public static final int CONTROL_AE_MODE_ON_AUTO_FLASH = 2; // 0x2
field public static final int CONTROL_AE_MODE_ON_AUTO_FLASH_REDEYE = 4; // 0x4
+ field public static final int CONTROL_AE_PRECAPTURE_TRIGGER_CANCEL = 2; // 0x2
field public static final int CONTROL_AE_PRECAPTURE_TRIGGER_IDLE = 0; // 0x0
field public static final int CONTROL_AE_PRECAPTURE_TRIGGER_START = 1; // 0x1
field public static final int CONTROL_AE_STATE_CONVERGED = 2; // 0x2
diff --git a/api/system-current.txt b/api/system-current.txt
index 290d81dcc88d6..61463c0796601 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -13031,6 +13031,7 @@ package android.hardware.camera2 {
field public static final int CONTROL_AE_MODE_ON_ALWAYS_FLASH = 3; // 0x3
field public static final int CONTROL_AE_MODE_ON_AUTO_FLASH = 2; // 0x2
field public static final int CONTROL_AE_MODE_ON_AUTO_FLASH_REDEYE = 4; // 0x4
+ field public static final int CONTROL_AE_PRECAPTURE_TRIGGER_CANCEL = 2; // 0x2
field public static final int CONTROL_AE_PRECAPTURE_TRIGGER_IDLE = 0; // 0x0
field public static final int CONTROL_AE_PRECAPTURE_TRIGGER_START = 1; // 0x1
field public static final int CONTROL_AE_STATE_CONVERGED = 2; // 0x2
diff --git a/core/java/android/hardware/camera2/CameraMetadata.java b/core/java/android/hardware/camera2/CameraMetadata.java
index 44e97306f6a21..3674a268b7fb0 100644
--- a/core/java/android/hardware/camera2/CameraMetadata.java
+++ b/core/java/android/hardware/camera2/CameraMetadata.java
@@ -974,6 +974,14 @@ public abstract class CameraMetadata The camera device will cancel any currently active or completed
+ * precapture metering sequence, the auto-exposure routine will return to its
+ * initial state. AE has been asked to do a precapture sequence
* and is currently executing it. Precapture can be triggered through setting
- * {@link CaptureRequest#CONTROL_AE_PRECAPTURE_TRIGGER android.control.aePrecaptureTrigger} to START.
Once PRECAPTURE completes, AE will transition to CONVERGED
* or FLASH_REQUIRED as appropriate. This is a transient
* state, the camera device may skip reporting this state in
diff --git a/core/java/android/hardware/camera2/CaptureRequest.java b/core/java/android/hardware/camera2/CaptureRequest.java
index 3499966cafde0..caa1cd33387b8 100644
--- a/core/java/android/hardware/camera2/CaptureRequest.java
+++ b/core/java/android/hardware/camera2/CaptureRequest.java
@@ -724,7 +724,14 @@ public final class CaptureRequest extends CameraMetadata
When an AE precapture sequence is triggered, AE unlock will not be able to unlock
+ * the AE if AE is locked by the camera device internally during precapture metering
+ * sequence In other words, submitting requests with AE unlock has no effect for an
+ * ongoing precapture metering sequence. Otherwise, the precapture metering sequence
+ * will never succeed in a sequence of preview requests where AE lock is always set
+ * to false.
Since the camera device has a pipeline of in-flight requests, the settings that
* get locked do not necessarily correspond to the settings that were present in the
* latest capture result received from the camera device, since additional captures
@@ -869,6 +876,11 @@ public final class CaptureRequest extends CameraMetadata
When set to CANCEL, the camera device will cancel any active + * precapture metering trigger, and return to its initial AE state. + * If a precapture metering sequence is already completed, and the camera + * device has implicitly locked the AE for subsequent still capture, the + * CANCEL trigger will unlock the AE and return to its initial AE state.
*The precapture sequence should be triggered before starting a
* high-quality still capture for final metering decisions to
* be made, and for firing pre-capture flash pulses to estimate
@@ -884,7 +896,11 @@ public final class CaptureRequest extends CameraMetadata{@link CaptureRequest#CONTROL_AE_LOCK android.control.aeLock} == true, followed by a request
* with {@link CaptureRequest#CONTROL_AE_LOCK android.control.aeLock} == false, if the application decides not to submit a
- * still capture request after the precapture sequence completes.
The exact effect of auto-exposure (AE) precapture trigger
* depends on the current AE mode and state; see
* {@link CaptureResult#CONTROL_AE_STATE android.control.aeState} for AE precapture state transition
@@ -897,6 +913,7 @@ public final class CaptureRequest extends CameraMetadata
*
Optional - This value may be {@code null} on some devices.
*Limited capability -
@@ -909,6 +926,7 @@ public final class CaptureRequest extends CameraMetadata
When an AE precapture sequence is triggered, AE unlock will not be able to unlock
+ * the AE if AE is locked by the camera device internally during precapture metering
+ * sequence In other words, submitting requests with AE unlock has no effect for an
+ * ongoing precapture metering sequence. Otherwise, the precapture metering sequence
+ * will never succeed in a sequence of preview requests where AE lock is always set
+ * to false.
Since the camera device has a pipeline of in-flight requests, the settings that
* get locked do not necessarily correspond to the settings that were present in the
* latest capture result received from the camera device, since additional captures
@@ -720,6 +727,11 @@ public class CaptureResult extends CameraMetadata
When set to CANCEL, the camera device will cancel any active + * precapture metering trigger, and return to its initial AE state. + * If a precapture metering sequence is already completed, and the camera + * device has implicitly locked the AE for subsequent still capture, the + * CANCEL trigger will unlock the AE and return to its initial AE state.
*The precapture sequence should be triggered before starting a
* high-quality still capture for final metering decisions to
* be made, and for firing pre-capture flash pulses to estimate
@@ -735,7 +747,11 @@ public class CaptureResult extends CameraMetadata{@link CaptureRequest#CONTROL_AE_LOCK android.control.aeLock} == true, followed by a request
* with {@link CaptureRequest#CONTROL_AE_LOCK android.control.aeLock} == false, if the application decides not to submit a
- * still capture request after the precapture sequence completes.
The exact effect of auto-exposure (AE) precapture trigger
* depends on the current AE mode and state; see
* {@link CaptureResult#CONTROL_AE_STATE android.control.aeState} for AE precapture state transition
@@ -748,6 +764,7 @@ public class CaptureResult extends CameraMetadata
*
Optional - This value may be {@code null} on some devices.
*Limited capability -
@@ -760,6 +777,7 @@ public class CaptureResult extends CameraMetadata For the above table, the camera device may skip reporting any state changes that happen
@@ -922,18 +958,30 @@ public class CaptureResult extends CameraMetadataReady for high-quality capture
*
*
- *
+ * Any state
+ * LOCKED
+ * aeLock is ON and aePrecaptureTrigger is START
+ * LOCKED
+ * Precapture trigger is ignored when AE is already locked
+ *
+ *
+ * LOCKED
+ * aeLock is ON and aePrecaptureTrigger is CANCEL
+ * LOCKED
+ * Precapture trigger is ignored when AE is already locked
+ *
+ *
+ * Any state (excluding LOCKED)
* {@link CaptureRequest#CONTROL_AE_PRECAPTURE_TRIGGER android.control.aePrecaptureTrigger} is START
* PRECAPTURE
* Start AE precapture metering sequence
*
+ *
*
*
* Any state (excluding LOCKED)
+ * {@link CaptureRequest#CONTROL_AE_PRECAPTURE_TRIGGER android.control.aePrecaptureTrigger} is CANCEL
+ * INACTIVE
+ * Currently active precapture metering sequence is canceled
+ * Values are already good, transient states are skipped by camera device.
*
*
- *
* Any state
+ * Any state (excluding LOCKED)
* {@link CaptureRequest#CONTROL_AE_PRECAPTURE_TRIGGER android.control.aePrecaptureTrigger} is START, sequence done
* FLASH_REQUIRED
* Converged but too dark w/o flash after a precapture sequence, transient states are skipped by camera device.
*
- *
* Any state
+ * Any state (excluding LOCKED)
* {@link CaptureRequest#CONTROL_AE_PRECAPTURE_TRIGGER android.control.aePrecaptureTrigger} is START, sequence done
* CONVERGED
* Converged after a precapture sequence, transient states are skipped by camera device.
*
+ *
+ * Any state (excluding LOCKED)
+ * {@link CaptureRequest#CONTROL_AE_PRECAPTURE_TRIGGER android.control.aePrecaptureTrigger} is CANCEL, converged
+ * FLASH_REQUIRED
+ * Converged but too dark w/o flash after a precapture sequence is canceled, transient states are skipped by camera device.
+ *
+ *
+ * Any state (excluding LOCKED)
+ * {@link CaptureRequest#CONTROL_AE_PRECAPTURE_TRIGGER android.control.aePrecaptureTrigger} is CANCEL, converged
+ * CONVERGED
+ * Converged after a precapture sequenceis canceled, transient states are skipped by camera device.
+ *
* CONVERGED
* Camera device finished AE scan
* FLASH_REQUIRED