Add an auto-exposure lock feature to the Camera API.

Adds a new camera parameter for locking auto-exposure to its current
value. Also adds a function for checking if auto-exposure lock is
supported by the current platform.

Hidden for now.

Change-Id: Id452371191ab220318ce2cb98b8ee91bdde9aab6
diff --git a/core/java/android/hardware/Camera.java b/core/java/android/hardware/Camera.java
index 49db72b..9011f73 100644
--- a/core/java/android/hardware/Camera.java
+++ b/core/java/android/hardware/Camera.java
@@ -1179,6 +1179,8 @@
         private static final String KEY_MAX_EXPOSURE_COMPENSATION = "max-exposure-compensation";
         private static final String KEY_MIN_EXPOSURE_COMPENSATION = "min-exposure-compensation";
         private static final String KEY_EXPOSURE_COMPENSATION_STEP = "exposure-compensation-step";
+        private static final String KEY_AUTO_EXPOSURE_LOCK = "auto-exposure-lock";
+        private static final String KEY_AUTO_EXPOSURE_LOCK_SUPPORTED = "auto-exposure-lock-supported";
         private static final String KEY_METERING_AREAS = "metering-areas";
         private static final String KEY_MAX_NUM_METERING_AREAS = "max-num-metering-areas";
         private static final String KEY_ZOOM = "zoom";
@@ -1195,6 +1197,7 @@
         private static final String SUPPORTED_VALUES_SUFFIX = "-values";
 
         private static final String TRUE = "true";
+        private static final String FALSE = "false";
 
         // Values for white balance settings.
         public static final String WHITE_BALANCE_AUTO = "auto";
@@ -2463,6 +2466,80 @@
         }
 
         /**
+         * Sets the auto-exposure lock state. Applications should check
+         * {@link #isAutoExposureLockSupported} before using this method.
+         *
+         * If set to true, the camera auto-exposure routine will pause until the
+         * lock is set to false. Exposure compensation settings changes will
+         * still take effect while auto-exposure is locked. Stopping preview
+         * with {@link #stopPreview()}, or triggering still image capture with
+         * {@link #takePicture(Camera.ShutterCallback, Camera.PictureCallback,
+         * Camera.PictureCallback)}, will automatically set the lock to
+         * false. However, the lock can be re-enabled before preview is
+         * re-started to keep the same AE parameters. Exposure compensation, in
+         * conjunction with re-enabling the AE lock after each still capture,
+         * can be used to capture an exposure-bracketed burst of images, for
+         * example. Auto-exposure state, including the lock state, will not be
+         * maintained after camera {@link #release()} is called.  Locking
+         * auto-exposure after {@link #open()} but before the first call to
+         * {@link #startPreview()} will not allow the auto-exposure routine to
+         * run at all, and may result in severely over- or under-exposed images.
+         *
+         * The driver may also independently lock auto-exposure after auto-focus
+         * completes. If this is undesirable, be sure to always set the
+         * auto-exposure lock to false after the
+         * {@link AutoFocusCallback#onAutoFocus(boolean, Camera)} callback is
+         * received. The {@link #getAutoExposureLock()} method can be used after
+         * the callback to determine if the camera has locked auto-exposure
+         * independently.
+         *
+         * @param toggle new state of the auto-exposure lock. True means that
+         *        auto-exposure is locked, false means that the auto-exposure
+         *        routine is free to run normally.
+         *
+         * @hide
+         */
+        public void setAutoExposureLock(boolean toggle) {
+            set(KEY_AUTO_EXPOSURE_LOCK, toggle ? TRUE : FALSE);
+        }
+
+        /**
+         * Gets the state of the auto-exposure lock. Applications should check
+         * {@link #isAutoExposureLockSupported} before using this method. See
+         * {@link #setAutoExposureLock} for details about the lock.
+         *
+         * @return State of the auto-exposure lock. Returns true if
+         *         auto-exposure is currently locked, and false otherwise. The
+         *         auto-exposure lock may be independently enabled by the camera
+         *         subsystem when auto-focus has completed. This method can be
+         *         used after the {@link AutoFocusCallback#onAutoFocus(boolean,
+         *         Camera)} callback to determine if the camera has locked AE.
+         *
+         * @see #setAutoExposureLock(boolean)
+         *
+         * @hide
+         */
+        public boolean getAutoExposureLock() {
+            String str = get(KEY_AUTO_EXPOSURE_LOCK);
+            return TRUE.equals(str);
+        }
+
+        /**
+         * Returns true if auto-exposure locking is supported. Applications
+         * should call this before trying to lock auto-exposure. See
+         * {@link #setAutoExposureLock} for details about the lock.
+         *
+         * @return true if auto-exposure lock is supported.
+         * @see #setAutoExposureLock(boolean)
+         *
+         * @hide
+         */
+        public boolean isAutoExposureLockSupported() {
+            String str = get(KEY_AUTO_EXPOSURE_LOCK_SUPPORTED);
+            return TRUE.equals(str);
+        }
+
+        /**
          * Gets current zoom value. This also works when smooth zoom is in
          * progress. Applications should check {@link #isZoomSupported} before
          * using this method.
diff --git a/include/camera/CameraParameters.h b/include/camera/CameraParameters.h
index db81721..513239f 100644
--- a/include/camera/CameraParameters.h
+++ b/include/camera/CameraParameters.h
@@ -309,6 +309,25 @@
     // 0.3333, EV is -2.
     // Example value: "0.333333333" or "0.5". Read only.
     static const char KEY_EXPOSURE_COMPENSATION_STEP[];
+    // The state of the auto-exposure lock. "true" means that auto-exposure is
+    // locked to its current value and will not change. "false" means the
+    // auto-exposure routine is free to change exposure settings. Changing
+    // exposure compensation settings will still affect the exposure settings
+    // while auto-exposure is locked. Stopping preview or taking a still image
+    // will release the lock. However, the lock can be re-enabled prior to
+    // preview being re-started, to keep the exposure values from the previous
+    // lock. In conjunction with exposure compensation, this allows for
+    // capturing multi-exposure brackets with known relative exposure
+    // values. Locking auto-exposure after open but before the first cal to
+    // startPreview may result in severly over- or under-exposed images.  The
+    // driver may independently enable the AE lock after auto-focus
+    // completes. If it does so, this key must have its value updated to reflect
+    // the lock's existence. Applications are free to release such a lock, to
+    // re-enable AE without restarting preview.
+    static const char KEY_AUTO_EXPOSURE_LOCK[];
+    // Whether locking the auto-exposure is supported. "true" means it is, and
+    // "false" or this key not existing means it is not supported.
+    static const char KEY_AUTO_EXPOSURE_LOCK_SUPPORTED[];
     // The maximum number of metering areas supported. This is the maximum
     // length of KEY_METERING_AREAS.
     // Example value: "0" or "2". Read only.
@@ -428,6 +447,7 @@
 
     // Value for KEY_ZOOM_SUPPORTED or KEY_SMOOTH_ZOOM_SUPPORTED.
     static const char TRUE[];
+    static const char FALSE[];
 
     // Value for KEY_FOCUS_DISTANCES.
     static const char FOCUS_DISTANCE_INFINITY[];
diff --git a/libs/camera/CameraParameters.cpp b/libs/camera/CameraParameters.cpp
index 214cd4d..4f3da40 100644
--- a/libs/camera/CameraParameters.cpp
+++ b/libs/camera/CameraParameters.cpp
@@ -68,6 +68,8 @@
 const char CameraParameters::KEY_MAX_EXPOSURE_COMPENSATION[] = "max-exposure-compensation";
 const char CameraParameters::KEY_MIN_EXPOSURE_COMPENSATION[] = "min-exposure-compensation";
 const char CameraParameters::KEY_EXPOSURE_COMPENSATION_STEP[] = "exposure-compensation-step";
+const char CameraParameters::KEY_AUTO_EXPOSURE_LOCK[] = "auto-exposure-lock";
+const char CameraParameters::KEY_AUTO_EXPOSURE_LOCK_SUPPORTED[] = "auto-exposure-lock-supported";
 const char CameraParameters::KEY_MAX_NUM_METERING_AREAS[] = "max-num-metering-areas";
 const char CameraParameters::KEY_METERING_AREAS[] = "metering-areas";
 const char CameraParameters::KEY_ZOOM[] = "zoom";
@@ -82,6 +84,7 @@
 const char CameraParameters::KEY_PREFERRED_PREVIEW_SIZE_FOR_VIDEO[] = "preferred-preview-size-for-video";
 
 const char CameraParameters::TRUE[] = "true";
+const char CameraParameters::FALSE[] = "false";
 const char CameraParameters::FOCUS_DISTANCE_INFINITY[] = "Infinity";
 
 // Values for white balance settings.