Merge "Stagefright: Add HDRStaticInfo support for encoder." into nyc-dev
diff --git a/camera/aidl/android/hardware/camera2/ICameraDeviceCallbacks.aidl b/camera/aidl/android/hardware/camera2/ICameraDeviceCallbacks.aidl
index ab57db5..755ec8e 100644
--- a/camera/aidl/android/hardware/camera2/ICameraDeviceCallbacks.aidl
+++ b/camera/aidl/android/hardware/camera2/ICameraDeviceCallbacks.aidl
@@ -37,4 +37,11 @@
     oneway void onResultReceived(in CameraMetadataNative result,
                                  in CaptureResultExtras resultExtras);
     oneway void onPrepared(int streamId);
+
+    /**
+     * Repeating request encountered an error and was stopped.
+     *
+     * @param lastFrameNumber Frame number of the last frame of the streaming request.
+     */
+    oneway void onRepeatingRequestError(in long lastFrameNumber);
 }
diff --git a/camera/aidl/android/hardware/camera2/ICameraDeviceUser.aidl b/camera/aidl/android/hardware/camera2/ICameraDeviceUser.aidl
index 250f15e..1e8744b 100644
--- a/camera/aidl/android/hardware/camera2/ICameraDeviceUser.aidl
+++ b/camera/aidl/android/hardware/camera2/ICameraDeviceUser.aidl
@@ -36,7 +36,10 @@
      * Cancel the repeating request specified by requestId
      * Returns the frame number of the last frame that will be produced from this
      * repeating request, or NO_IN_FLIGHT_REPEATING_FRAMES if no frames were produced
-     * by this repeating request
+     * by this repeating request.
+     *
+     * Repeating request may be stopped by camera device due to an error. Canceling a stopped
+     * repeating request will trigger ERROR_ILLEGAL_ARGUMENT.
      */
     long cancelRequest(int requestId);
 
diff --git a/camera/ndk/impl/ACameraDevice.cpp b/camera/ndk/impl/ACameraDevice.cpp
index 0b758b6..bff5547 100644
--- a/camera/ndk/impl/ACameraDevice.cpp
+++ b/camera/ndk/impl/ACameraDevice.cpp
@@ -380,7 +380,11 @@
 
         int64_t lastFrameNumber;
         binder::Status remoteRet = mRemote->cancelRequest(repeatingSequenceId, &lastFrameNumber);
-        if (!remoteRet.isOk()) {
+        if (remoteRet.serviceSpecificErrorCode() ==
+                hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT) {
+            ALOGV("Repeating request is already stopped.");
+            return ACAMERA_OK;
+        } else if (!remoteRet.isOk()) {
             ALOGE("Stop repeating request fails in remote: %s", remoteRet.toString8().string());
             return ACAMERA_ERROR_UNKNOWN;
         }
@@ -1342,4 +1346,24 @@
     return binder::Status::ok();
 }
 
+binder::Status
+CameraDevice::ServiceCallback::onRepeatingRequestError(int64_t lastFrameNumber) {
+    binder::Status ret = binder::Status::ok();
+
+    sp<CameraDevice> dev = mDevice.promote();
+    if (dev == nullptr) {
+        return ret; // device has been closed
+    }
+
+    Mutex::Autolock _l(dev->mDeviceLock);
+
+    int repeatingSequenceId = dev->mRepeatingSequenceId;
+    dev->mRepeatingSequenceId = REQUEST_ID_NONE;
+
+    dev->checkRepeatingSequenceCompleteLocked(repeatingSequenceId, lastFrameNumber);
+
+    return ret;
+}
+
+
 } // namespace android
diff --git a/camera/ndk/impl/ACameraDevice.h b/camera/ndk/impl/ACameraDevice.h
index 3ccf95a..71e364d 100644
--- a/camera/ndk/impl/ACameraDevice.h
+++ b/camera/ndk/impl/ACameraDevice.h
@@ -74,6 +74,7 @@
         binder::Status onResultReceived(const CameraMetadata& metadata,
                               const CaptureResultExtras& resultExtras) override;
         binder::Status onPrepared(int streamId) override;
+        binder::Status onRepeatingRequestError(int64_t lastFrameNumber) override;
       private:
         const wp<CameraDevice> mDevice;
     };
diff --git a/camera/tests/CameraBinderTests.cpp b/camera/tests/CameraBinderTests.cpp
index 0b687b4..828a758 100644
--- a/camera/tests/CameraBinderTests.cpp
+++ b/camera/tests/CameraBinderTests.cpp
@@ -149,7 +149,8 @@
         PREPARED,
         RUNNING,
         SENT_RESULT,
-        UNINITIALIZED
+        UNINITIALIZED,
+        REPEATING_REQUEST_ERROR,
     };
 
 protected:
@@ -215,6 +216,15 @@
         return binder::Status::ok();
     }
 
+    virtual binder::Status onRepeatingRequestError(int64_t lastFrameNumber) {
+        (void) lastFrameNumber;
+        Mutex::Autolock l(mLock);
+        mLastStatus = REPEATING_REQUEST_ERROR;
+        mStatusesHit.push_back(mLastStatus);
+        mStatusCondition.broadcast();
+        return binder::Status::ok();
+    }
+
     // Test helper functions:
 
     bool hadError() const {
diff --git a/include/camera/ndk/NdkCameraMetadataTags.h b/include/camera/ndk/NdkCameraMetadataTags.h
index 3ec164c..155f221 100644
--- a/include/camera/ndk/NdkCameraMetadataTags.h
+++ b/include/camera/ndk/NdkCameraMetadataTags.h
@@ -96,372 +96,5243 @@
  * Main enum for camera metadata tags.
  */
 typedef enum acamera_metadata_tag {
+    /**
+     * <p>The mode control selects how the image data is converted from the
+     * sensor's native color into linear sRGB color.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraCaptureSession_captureCallback_result callbacks</li>
+     *   <li>ACaptureRequest</li>
+     * </ul>
+     *
+     * <p>When auto-white balance (AWB) is enabled with ACAMERA_CONTROL_AWB_MODE, this
+     * control is overridden by the AWB routine. When AWB is disabled, the
+     * application controls how the color mapping is performed.</p>
+     * <p>We define the expected processing pipeline below. For consistency
+     * across devices, this is always the case with TRANSFORM_MATRIX.</p>
+     * <p>When either FULL or HIGH_QUALITY is used, the camera device may
+     * do additional processing but ACAMERA_COLOR_CORRECTION_GAINS and
+     * ACAMERA_COLOR_CORRECTION_TRANSFORM will still be provided by the
+     * camera device (in the results) and be roughly correct.</p>
+     * <p>Switching to TRANSFORM_MATRIX and using the data provided from
+     * FAST or HIGH_QUALITY will yield a picture with the same white point
+     * as what was produced by the camera device in the earlier frame.</p>
+     * <p>The expected processing pipeline is as follows:</p>
+     * <p><img alt="White balance processing pipeline" src="../../../../images/camera2/metadata/android.colorCorrection.mode/processing_pipeline.png" /></p>
+     * <p>The white balance is encoded by two values, a 4-channel white-balance
+     * gain vector (applied in the Bayer domain), and a 3x3 color transform
+     * matrix (applied after demosaic).</p>
+     * <p>The 4-channel white-balance gains are defined as:</p>
+     * <pre><code>ACAMERA_COLOR_CORRECTION_GAINS = [ R G_even G_odd B ]
+     * </code></pre>
+     * <p>where <code>G_even</code> is the gain for green pixels on even rows of the
+     * output, and <code>G_odd</code> is the gain for green pixels on the odd rows.
+     * These may be identical for a given camera device implementation; if
+     * the camera device does not support a separate gain for even/odd green
+     * channels, it will use the <code>G_even</code> value, and write <code>G_odd</code> equal to
+     * <code>G_even</code> in the output result metadata.</p>
+     * <p>The matrices for color transforms are defined as a 9-entry vector:</p>
+     * <pre><code>ACAMERA_COLOR_CORRECTION_TRANSFORM = [ I0 I1 I2 I3 I4 I5 I6 I7 I8 ]
+     * </code></pre>
+     * <p>which define a transform from input sensor colors, <code>P_in = [ r g b ]</code>,
+     * to output linear sRGB, <code>P_out = [ r' g' b' ]</code>,</p>
+     * <p>with colors as follows:</p>
+     * <pre><code>r' = I0r + I1g + I2b
+     * g' = I3r + I4g + I5b
+     * b' = I6r + I7g + I8b
+     * </code></pre>
+     * <p>Both the input and output value ranges must match. Overflow/underflow
+     * values are clipped to fit within the range.</p>
+     *
+     * @see ACAMERA_COLOR_CORRECTION_GAINS
+     * @see ACAMERA_COLOR_CORRECTION_TRANSFORM
+     * @see ACAMERA_CONTROL_AWB_MODE
+     */
     ACAMERA_COLOR_CORRECTION_MODE =                             // byte (enum)
             ACAMERA_COLOR_CORRECTION_START,
+    /**
+     * <p>A color transform matrix to use to transform
+     * from sensor RGB color space to output linear sRGB color space.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraCaptureSession_captureCallback_result callbacks</li>
+     *   <li>ACaptureRequest</li>
+     * </ul>
+     *
+     * <p>This matrix is either set by the camera device when the request
+     * ACAMERA_COLOR_CORRECTION_MODE is not TRANSFORM_MATRIX, or
+     * directly by the application in the request when the
+     * ACAMERA_COLOR_CORRECTION_MODE is TRANSFORM_MATRIX.</p>
+     * <p>In the latter case, the camera device may round the matrix to account
+     * for precision issues; the final rounded matrix should be reported back
+     * in this matrix result metadata. The transform should keep the magnitude
+     * of the output color values within <code>[0, 1.0]</code> (assuming input color
+     * values is within the normalized range <code>[0, 1.0]</code>), or clipping may occur.</p>
+     * <p>The valid range of each matrix element varies on different devices, but
+     * values within [-1.5, 3.0] are guaranteed not to be clipped.</p>
+     *
+     * @see ACAMERA_COLOR_CORRECTION_MODE
+     */
     ACAMERA_COLOR_CORRECTION_TRANSFORM =                        // rational[3*3]
             ACAMERA_COLOR_CORRECTION_START + 1,
+    /**
+     * <p>Gains applying to Bayer raw color channels for
+     * white-balance.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraCaptureSession_captureCallback_result callbacks</li>
+     *   <li>ACaptureRequest</li>
+     * </ul>
+     *
+     * <p>These per-channel gains are either set by the camera device
+     * when the request ACAMERA_COLOR_CORRECTION_MODE is not
+     * TRANSFORM_MATRIX, or directly by the application in the
+     * request when the ACAMERA_COLOR_CORRECTION_MODE is
+     * TRANSFORM_MATRIX.</p>
+     * <p>The gains in the result metadata are the gains actually
+     * applied by the camera device to the current frame.</p>
+     * <p>The valid range of gains varies on different devices, but gains
+     * between [1.0, 3.0] are guaranteed not to be clipped. Even if a given
+     * device allows gains below 1.0, this is usually not recommended because
+     * this can create color artifacts.</p>
+     *
+     * @see ACAMERA_COLOR_CORRECTION_MODE
+     */
     ACAMERA_COLOR_CORRECTION_GAINS =                            // float[4]
             ACAMERA_COLOR_CORRECTION_START + 2,
+    /**
+     * <p>Mode of operation for the chromatic aberration correction algorithm.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraCaptureSession_captureCallback_result callbacks</li>
+     *   <li>ACaptureRequest</li>
+     * </ul>
+     *
+     * <p>Chromatic (color) aberration is caused by the fact that different wavelengths of light
+     * can not focus on the same point after exiting from the lens. This metadata defines
+     * the high level control of chromatic aberration correction algorithm, which aims to
+     * minimize the chromatic artifacts that may occur along the object boundaries in an
+     * image.</p>
+     * <p>FAST/HIGH_QUALITY both mean that camera device determined aberration
+     * correction will be applied. HIGH_QUALITY mode indicates that the camera device will
+     * use the highest-quality aberration correction algorithms, even if it slows down
+     * capture rate. FAST means the camera device will not slow down capture rate when
+     * applying aberration correction.</p>
+     * <p>LEGACY devices will always be in FAST mode.</p>
+     */
     ACAMERA_COLOR_CORRECTION_ABERRATION_MODE =                  // byte (enum)
             ACAMERA_COLOR_CORRECTION_START + 3,
+    /**
+     * <p>List of aberration correction modes for ACAMERA_COLOR_CORRECTION_ABERRATION_MODE that are
+     * supported by this camera device.</p>
+     *
+     * @see ACAMERA_COLOR_CORRECTION_ABERRATION_MODE
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraManager_getCameraCharacteristics</li>
+     * </ul>
+     *
+     * <p>This key lists the valid modes for ACAMERA_COLOR_CORRECTION_ABERRATION_MODE.  If no
+     * aberration correction modes are available for a device, this list will solely include
+     * OFF mode. All camera devices will support either OFF or FAST mode.</p>
+     * <p>Camera devices that support the MANUAL_POST_PROCESSING capability will always list
+     * OFF mode. This includes all FULL level devices.</p>
+     * <p>LEGACY devices will always only support FAST mode.</p>
+     *
+     * @see ACAMERA_COLOR_CORRECTION_ABERRATION_MODE
+     */
     ACAMERA_COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES =       // byte[n]
             ACAMERA_COLOR_CORRECTION_START + 4,
     ACAMERA_COLOR_CORRECTION_END,
 
+    /**
+     * <p>The desired setting for the camera device's auto-exposure
+     * algorithm's antibanding compensation.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraCaptureSession_captureCallback_result callbacks</li>
+     *   <li>ACaptureRequest</li>
+     * </ul>
+     *
+     * <p>Some kinds of lighting fixtures, such as some fluorescent
+     * lights, flicker at the rate of the power supply frequency
+     * (60Hz or 50Hz, depending on country). While this is
+     * typically not noticeable to a person, it can be visible to
+     * a camera device. If a camera sets its exposure time to the
+     * wrong value, the flicker may become visible in the
+     * viewfinder as flicker or in a final captured image, as a
+     * set of variable-brightness bands across the image.</p>
+     * <p>Therefore, the auto-exposure routines of camera devices
+     * include antibanding routines that ensure that the chosen
+     * exposure value will not cause such banding. The choice of
+     * exposure time depends on the rate of flicker, which the
+     * camera device can detect automatically, or the expected
+     * rate can be selected by the application using this
+     * control.</p>
+     * <p>A given camera device may not support all of the possible
+     * options for the antibanding mode. The
+     * ACAMERA_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES key contains
+     * the available modes for a given camera device.</p>
+     * <p>AUTO mode is the default if it is available on given
+     * camera device. When AUTO mode is not available, the
+     * default will be either 50HZ or 60HZ, and both 50HZ
+     * and 60HZ will be available.</p>
+     * <p>If manual exposure control is enabled (by setting
+     * ACAMERA_CONTROL_AE_MODE or ACAMERA_CONTROL_MODE to OFF),
+     * then this setting has no effect, and the application must
+     * ensure it selects exposure times that do not cause banding
+     * issues. The ACAMERA_STATISTICS_SCENE_FLICKER key can assist
+     * the application in this.</p>
+     *
+     * @see ACAMERA_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES
+     * @see ACAMERA_CONTROL_AE_MODE
+     * @see ACAMERA_CONTROL_MODE
+     * @see ACAMERA_STATISTICS_SCENE_FLICKER
+     */
     ACAMERA_CONTROL_AE_ANTIBANDING_MODE =                       // byte (enum)
             ACAMERA_CONTROL_START,
+    /**
+     * <p>Adjustment to auto-exposure (AE) target image
+     * brightness.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraCaptureSession_captureCallback_result callbacks</li>
+     *   <li>ACaptureRequest</li>
+     * </ul>
+     *
+     * <p>The adjustment is measured as a count of steps, with the
+     * step size defined by ACAMERA_CONTROL_AE_COMPENSATION_STEP and the
+     * allowed range by ACAMERA_CONTROL_AE_COMPENSATION_RANGE.</p>
+     * <p>For example, if the exposure value (EV) step is 0.333, '6'
+     * will mean an exposure compensation of +2 EV; -3 will mean an
+     * exposure compensation of -1 EV. One EV represents a doubling
+     * of image brightness. Note that this control will only be
+     * effective if ACAMERA_CONTROL_AE_MODE <code>!=</code> OFF. This control
+     * will take effect even when ACAMERA_CONTROL_AE_LOCK <code>== true</code>.</p>
+     * <p>In the event of exposure compensation value being changed, camera device
+     * may take several frames to reach the newly requested exposure target.
+     * During that time, ACAMERA_CONTROL_AE_STATE field will be in the SEARCHING
+     * state. Once the new exposure target is reached, ACAMERA_CONTROL_AE_STATE will
+     * change from SEARCHING to either CONVERGED, LOCKED (if AE lock is enabled), or
+     * FLASH_REQUIRED (if the scene is too dark for still capture).</p>
+     *
+     * @see ACAMERA_CONTROL_AE_COMPENSATION_RANGE
+     * @see ACAMERA_CONTROL_AE_COMPENSATION_STEP
+     * @see ACAMERA_CONTROL_AE_LOCK
+     * @see ACAMERA_CONTROL_AE_MODE
+     * @see ACAMERA_CONTROL_AE_STATE
+     */
     ACAMERA_CONTROL_AE_EXPOSURE_COMPENSATION =                  // int32
             ACAMERA_CONTROL_START + 1,
+    /**
+     * <p>Whether auto-exposure (AE) is currently locked to its latest
+     * calculated values.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraCaptureSession_captureCallback_result callbacks</li>
+     *   <li>ACaptureRequest</li>
+     * </ul>
+     *
+     * <p>When set to <code>true</code> (ON), the AE algorithm is locked to its latest parameters,
+     * and will not change exposure settings until the lock is set to <code>false</code> (OFF).</p>
+     * <p>Note that even when AE is locked, the flash may be fired if
+     * the ACAMERA_CONTROL_AE_MODE is ON_AUTO_FLASH /
+     * ON_ALWAYS_FLASH / ON_AUTO_FLASH_REDEYE.</p>
+     * <p>When ACAMERA_CONTROL_AE_EXPOSURE_COMPENSATION is changed, even if the AE lock
+     * is ON, the camera device will still adjust its exposure value.</p>
+     * <p>If AE precapture is triggered (see ACAMERA_CONTROL_AE_PRECAPTURE_TRIGGER)
+     * when AE is already locked, the camera device will not change the exposure time
+     * (ACAMERA_SENSOR_EXPOSURE_TIME) and sensitivity (ACAMERA_SENSOR_SENSITIVITY)
+     * parameters. The flash may be fired if the ACAMERA_CONTROL_AE_MODE
+     * is ON_AUTO_FLASH/ON_AUTO_FLASH_REDEYE and the scene is too dark. If the
+     * ACAMERA_CONTROL_AE_MODE is ON_ALWAYS_FLASH, the scene may become overexposed.
+     * Similarly, AE precapture trigger CANCEL has no effect when AE is already locked.</p>
+     * <p>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 <code>false</code>.</p>
+     * <p>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
+     * and AE updates may have occurred even before the result was sent out. If an
+     * application is switching between automatic and manual control and wishes to eliminate
+     * any flicker during the switch, the following procedure is recommended:</p>
+     * <ol>
+     * <li>Starting in auto-AE mode:</li>
+     * <li>Lock AE</li>
+     * <li>Wait for the first result to be output that has the AE locked</li>
+     * <li>Copy exposure settings from that result into a request, set the request to manual AE</li>
+     * <li>Submit the capture request, proceed to run manual AE as desired.</li>
+     * </ol>
+     * <p>See ACAMERA_CONTROL_AE_STATE for AE lock related state transition details.</p>
+     *
+     * @see ACAMERA_CONTROL_AE_EXPOSURE_COMPENSATION
+     * @see ACAMERA_CONTROL_AE_MODE
+     * @see ACAMERA_CONTROL_AE_PRECAPTURE_TRIGGER
+     * @see ACAMERA_CONTROL_AE_STATE
+     * @see ACAMERA_SENSOR_EXPOSURE_TIME
+     * @see ACAMERA_SENSOR_SENSITIVITY
+     */
     ACAMERA_CONTROL_AE_LOCK =                                   // byte (enum)
             ACAMERA_CONTROL_START + 2,
+    /**
+     * <p>The desired mode for the camera device's
+     * auto-exposure routine.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraCaptureSession_captureCallback_result callbacks</li>
+     *   <li>ACaptureRequest</li>
+     * </ul>
+     *
+     * <p>This control is only effective if ACAMERA_CONTROL_MODE is
+     * AUTO.</p>
+     * <p>When set to any of the ON modes, the camera device's
+     * auto-exposure routine is enabled, overriding the
+     * application's selected exposure time, sensor sensitivity,
+     * and frame duration (ACAMERA_SENSOR_EXPOSURE_TIME,
+     * ACAMERA_SENSOR_SENSITIVITY, and
+     * ACAMERA_SENSOR_FRAME_DURATION). If one of the FLASH modes
+     * is selected, the camera device's flash unit controls are
+     * also overridden.</p>
+     * <p>The FLASH modes are only available if the camera device
+     * has a flash unit (ACAMERA_FLASH_INFO_AVAILABLE is <code>true</code>).</p>
+     * <p>If flash TORCH mode is desired, this field must be set to
+     * ON or OFF, and ACAMERA_FLASH_MODE set to TORCH.</p>
+     * <p>When set to any of the ON modes, the values chosen by the
+     * camera device auto-exposure routine for the overridden
+     * fields for a given capture will be available in its
+     * CaptureResult.</p>
+     *
+     * @see ACAMERA_CONTROL_MODE
+     * @see ACAMERA_FLASH_INFO_AVAILABLE
+     * @see ACAMERA_FLASH_MODE
+     * @see ACAMERA_SENSOR_EXPOSURE_TIME
+     * @see ACAMERA_SENSOR_FRAME_DURATION
+     * @see ACAMERA_SENSOR_SENSITIVITY
+     */
     ACAMERA_CONTROL_AE_MODE =                                   // byte (enum)
             ACAMERA_CONTROL_START + 3,
+    /**
+     * <p>List of metering areas to use for auto-exposure adjustment.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraCaptureSession_captureCallback_result callbacks</li>
+     *   <li>ACaptureRequest</li>
+     * </ul>
+     *
+     * <p>Not available if android.control.maxRegionsAe is 0.
+     * Otherwise will always be present.</p>
+     * <p>The maximum number of regions supported by the device is determined by the value
+     * of android.control.maxRegionsAe.</p>
+     * <p>The coordinate system is based on the active pixel array,
+     * with (0,0) being the top-left pixel in the active pixel array, and
+     * (ACAMERA_SENSOR_INFO_ACTIVE_ARRAY_SIZE.width - 1,
+     * ACAMERA_SENSOR_INFO_ACTIVE_ARRAY_SIZE.height - 1) being the
+     * bottom-right pixel in the active pixel array.</p>
+     * <p>The weight must be within <code>[0, 1000]</code>, and represents a weight
+     * for every pixel in the area. This means that a large metering area
+     * with the same weight as a smaller area will have more effect in
+     * the metering result. Metering areas can partially overlap and the
+     * camera device will add the weights in the overlap region.</p>
+     * <p>The weights are relative to weights of other exposure metering regions, so if only one
+     * region is used, all non-zero weights will have the same effect. A region with 0
+     * weight is ignored.</p>
+     * <p>If all regions have 0 weight, then no specific metering area needs to be used by the
+     * camera device.</p>
+     * <p>If the metering region is outside the used ACAMERA_SCALER_CROP_REGION returned in
+     * capture result metadata, the camera device will ignore the sections outside the crop
+     * region and output only the intersection rectangle as the metering region in the result
+     * metadata.  If the region is entirely outside the crop region, it will be ignored and
+     * not reported in the result metadata.</p>
+     *
+     * @see ACAMERA_SCALER_CROP_REGION
+     * @see ACAMERA_SENSOR_INFO_ACTIVE_ARRAY_SIZE
+     */
     ACAMERA_CONTROL_AE_REGIONS =                                // int32[5*area_count]
             ACAMERA_CONTROL_START + 4,
+    /**
+     * <p>Range over which the auto-exposure routine can
+     * adjust the capture frame rate to maintain good
+     * exposure.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraCaptureSession_captureCallback_result callbacks</li>
+     *   <li>ACaptureRequest</li>
+     * </ul>
+     *
+     * <p>Only constrains auto-exposure (AE) algorithm, not
+     * manual control of ACAMERA_SENSOR_EXPOSURE_TIME and
+     * ACAMERA_SENSOR_FRAME_DURATION.</p>
+     *
+     * @see ACAMERA_SENSOR_EXPOSURE_TIME
+     * @see ACAMERA_SENSOR_FRAME_DURATION
+     */
     ACAMERA_CONTROL_AE_TARGET_FPS_RANGE =                       // int32[2]
             ACAMERA_CONTROL_START + 5,
+    /**
+     * <p>Whether the camera device will trigger a precapture
+     * metering sequence when it processes this request.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraCaptureSession_captureCallback_result callbacks</li>
+     *   <li>ACaptureRequest</li>
+     * </ul>
+     *
+     * <p>This entry is normally set to IDLE, or is not
+     * included at all in the request settings. When included and
+     * set to START, the camera device will trigger the auto-exposure (AE)
+     * precapture metering sequence.</p>
+     * <p>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.</p>
+     * <p>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
+     * scene brightness and required final capture flash power, when
+     * the flash is enabled.</p>
+     * <p>Normally, this entry should be set to START for only a
+     * single request, and the application should wait until the
+     * sequence completes before starting a new one.</p>
+     * <p>When a precapture metering sequence is finished, the camera device
+     * may lock the auto-exposure routine internally to be able to accurately expose the
+     * subsequent still capture image (<code>ACAMERA_CONTROL_CAPTURE_INTENT == STILL_CAPTURE</code>).
+     * For this case, the AE may not resume normal scan if no subsequent still capture is
+     * submitted. To ensure that the AE routine restarts normal scan, the application should
+     * submit a request with <code>ACAMERA_CONTROL_AE_LOCK == true</code>, followed by a request
+     * with <code>ACAMERA_CONTROL_AE_LOCK == false</code>, if the application decides not to submit a
+     * still capture request after the precapture sequence completes. Alternatively, for
+     * API level 23 or newer devices, the CANCEL can be used to unlock the camera device
+     * internally locked AE if the application doesn't submit a still capture request after
+     * the AE precapture trigger. Note that, the CANCEL was added in API level 23, and must not
+     * be used in devices that have earlier API levels.</p>
+     * <p>The exact effect of auto-exposure (AE) precapture trigger
+     * depends on the current AE mode and state; see
+     * ACAMERA_CONTROL_AE_STATE for AE precapture state transition
+     * details.</p>
+     * <p>On LEGACY-level devices, the precapture trigger is not supported;
+     * capturing a high-resolution JPEG image will automatically trigger a
+     * precapture sequence before the high-resolution capture, including
+     * potentially firing a pre-capture flash.</p>
+     * <p>Using the precapture trigger and the auto-focus trigger ACAMERA_CONTROL_AF_TRIGGER
+     * simultaneously is allowed. However, since these triggers often require cooperation between
+     * the auto-focus and auto-exposure routines (for example, the may need to be enabled for a
+     * focus sweep), the camera device may delay acting on a later trigger until the previous
+     * trigger has been fully handled. This may lead to longer intervals between the trigger and
+     * changes to ACAMERA_CONTROL_AE_STATE indicating the start of the precapture sequence, for
+     * example.</p>
+     * <p>If both the precapture and the auto-focus trigger are activated on the same request, then
+     * the camera device will complete them in the optimal order for that device.</p>
+     *
+     * @see ACAMERA_CONTROL_AE_LOCK
+     * @see ACAMERA_CONTROL_AE_STATE
+     * @see ACAMERA_CONTROL_AF_TRIGGER
+     * @see ACAMERA_CONTROL_CAPTURE_INTENT
+     */
     ACAMERA_CONTROL_AE_PRECAPTURE_TRIGGER =                     // byte (enum)
             ACAMERA_CONTROL_START + 6,
+    /**
+     * <p>Whether auto-focus (AF) is currently enabled, and what
+     * mode it is set to.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraCaptureSession_captureCallback_result callbacks</li>
+     *   <li>ACaptureRequest</li>
+     * </ul>
+     *
+     * <p>Only effective if ACAMERA_CONTROL_MODE = AUTO and the lens is not fixed focus
+     * (i.e. <code>ACAMERA_LENS_INFO_MINIMUM_FOCUS_DISTANCE &gt; 0</code>). Also note that
+     * when ACAMERA_CONTROL_AE_MODE is OFF, the behavior of AF is device
+     * dependent. It is recommended to lock AF by using ACAMERA_CONTROL_AF_TRIGGER before
+     * setting ACAMERA_CONTROL_AE_MODE to OFF, or set AF mode to OFF when AE is OFF.</p>
+     * <p>If the lens is controlled by the camera device auto-focus algorithm,
+     * the camera device will report the current AF status in ACAMERA_CONTROL_AF_STATE
+     * in result metadata.</p>
+     *
+     * @see ACAMERA_CONTROL_AE_MODE
+     * @see ACAMERA_CONTROL_AF_STATE
+     * @see ACAMERA_CONTROL_AF_TRIGGER
+     * @see ACAMERA_CONTROL_MODE
+     * @see ACAMERA_LENS_INFO_MINIMUM_FOCUS_DISTANCE
+     */
     ACAMERA_CONTROL_AF_MODE =                                   // byte (enum)
             ACAMERA_CONTROL_START + 7,
+    /**
+     * <p>List of metering areas to use for auto-focus.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraCaptureSession_captureCallback_result callbacks</li>
+     *   <li>ACaptureRequest</li>
+     * </ul>
+     *
+     * <p>Not available if android.control.maxRegionsAf is 0.
+     * Otherwise will always be present.</p>
+     * <p>The maximum number of focus areas supported by the device is determined by the value
+     * of android.control.maxRegionsAf.</p>
+     * <p>The coordinate system is based on the active pixel array,
+     * with (0,0) being the top-left pixel in the active pixel array, and
+     * (ACAMERA_SENSOR_INFO_ACTIVE_ARRAY_SIZE.width - 1,
+     * ACAMERA_SENSOR_INFO_ACTIVE_ARRAY_SIZE.height - 1) being the
+     * bottom-right pixel in the active pixel array.</p>
+     * <p>The weight must be within <code>[0, 1000]</code>, and represents a weight
+     * for every pixel in the area. This means that a large metering area
+     * with the same weight as a smaller area will have more effect in
+     * the metering result. Metering areas can partially overlap and the
+     * camera device will add the weights in the overlap region.</p>
+     * <p>The weights are relative to weights of other metering regions, so if only one region
+     * is used, all non-zero weights will have the same effect. A region with 0 weight is
+     * ignored.</p>
+     * <p>If all regions have 0 weight, then no specific metering area needs to be used by the
+     * camera device.</p>
+     * <p>If the metering region is outside the used ACAMERA_SCALER_CROP_REGION returned in
+     * capture result metadata, the camera device will ignore the sections outside the crop
+     * region and output only the intersection rectangle as the metering region in the result
+     * metadata. If the region is entirely outside the crop region, it will be ignored and
+     * not reported in the result metadata.</p>
+     *
+     * @see ACAMERA_SCALER_CROP_REGION
+     * @see ACAMERA_SENSOR_INFO_ACTIVE_ARRAY_SIZE
+     */
     ACAMERA_CONTROL_AF_REGIONS =                                // int32[5*area_count]
             ACAMERA_CONTROL_START + 8,
+    /**
+     * <p>Whether the camera device will trigger autofocus for this request.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraCaptureSession_captureCallback_result callbacks</li>
+     *   <li>ACaptureRequest</li>
+     * </ul>
+     *
+     * <p>This entry is normally set to IDLE, or is not
+     * included at all in the request settings.</p>
+     * <p>When included and set to START, the camera device will trigger the
+     * autofocus algorithm. If autofocus is disabled, this trigger has no effect.</p>
+     * <p>When set to CANCEL, the camera device will cancel any active trigger,
+     * and return to its initial AF state.</p>
+     * <p>Generally, applications should set this entry to START or CANCEL for only a
+     * single capture, and then return it to IDLE (or not set at all). Specifying
+     * START for multiple captures in a row means restarting the AF operation over
+     * and over again.</p>
+     * <p>See ACAMERA_CONTROL_AF_STATE for what the trigger means for each AF mode.</p>
+     * <p>Using the autofocus trigger and the precapture trigger ACAMERA_CONTROL_AE_PRECAPTURE_TRIGGER
+     * simultaneously is allowed. However, since these triggers often require cooperation between
+     * the auto-focus and auto-exposure routines (for example, the may need to be enabled for a
+     * focus sweep), the camera device may delay acting on a later trigger until the previous
+     * trigger has been fully handled. This may lead to longer intervals between the trigger and
+     * changes to ACAMERA_CONTROL_AF_STATE, for example.</p>
+     *
+     * @see ACAMERA_CONTROL_AE_PRECAPTURE_TRIGGER
+     * @see ACAMERA_CONTROL_AF_STATE
+     */
     ACAMERA_CONTROL_AF_TRIGGER =                                // byte (enum)
             ACAMERA_CONTROL_START + 9,
+    /**
+     * <p>Whether auto-white balance (AWB) is currently locked to its
+     * latest calculated values.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraCaptureSession_captureCallback_result callbacks</li>
+     *   <li>ACaptureRequest</li>
+     * </ul>
+     *
+     * <p>When set to <code>true</code> (ON), the AWB algorithm is locked to its latest parameters,
+     * and will not change color balance settings until the lock is set to <code>false</code> (OFF).</p>
+     * <p>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
+     * and AWB updates may have occurred even before the result was sent out. If an
+     * application is switching between automatic and manual control and wishes to eliminate
+     * any flicker during the switch, the following procedure is recommended:</p>
+     * <ol>
+     * <li>Starting in auto-AWB mode:</li>
+     * <li>Lock AWB</li>
+     * <li>Wait for the first result to be output that has the AWB locked</li>
+     * <li>Copy AWB settings from that result into a request, set the request to manual AWB</li>
+     * <li>Submit the capture request, proceed to run manual AWB as desired.</li>
+     * </ol>
+     * <p>Note that AWB lock is only meaningful when
+     * ACAMERA_CONTROL_AWB_MODE is in the AUTO mode; in other modes,
+     * AWB is already fixed to a specific setting.</p>
+     * <p>Some LEGACY devices may not support ON; the value is then overridden to OFF.</p>
+     *
+     * @see ACAMERA_CONTROL_AWB_MODE
+     */
     ACAMERA_CONTROL_AWB_LOCK =                                  // byte (enum)
             ACAMERA_CONTROL_START + 10,
+    /**
+     * <p>Whether auto-white balance (AWB) is currently setting the color
+     * transform fields, and what its illumination target
+     * is.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraCaptureSession_captureCallback_result callbacks</li>
+     *   <li>ACaptureRequest</li>
+     * </ul>
+     *
+     * <p>This control is only effective if ACAMERA_CONTROL_MODE is AUTO.</p>
+     * <p>When set to the ON mode, the camera device's auto-white balance
+     * routine is enabled, overriding the application's selected
+     * ACAMERA_COLOR_CORRECTION_TRANSFORM, ACAMERA_COLOR_CORRECTION_GAINS and
+     * ACAMERA_COLOR_CORRECTION_MODE. Note that when ACAMERA_CONTROL_AE_MODE
+     * is OFF, the behavior of AWB is device dependent. It is recommened to
+     * also set AWB mode to OFF or lock AWB by using ACAMERA_CONTROL_AWB_LOCK before
+     * setting AE mode to OFF.</p>
+     * <p>When set to the OFF mode, the camera device's auto-white balance
+     * routine is disabled. The application manually controls the white
+     * balance by ACAMERA_COLOR_CORRECTION_TRANSFORM, ACAMERA_COLOR_CORRECTION_GAINS
+     * and ACAMERA_COLOR_CORRECTION_MODE.</p>
+     * <p>When set to any other modes, the camera device's auto-white
+     * balance routine is disabled. The camera device uses each
+     * particular illumination target for white balance
+     * adjustment. The application's values for
+     * ACAMERA_COLOR_CORRECTION_TRANSFORM,
+     * ACAMERA_COLOR_CORRECTION_GAINS and
+     * ACAMERA_COLOR_CORRECTION_MODE are ignored.</p>
+     *
+     * @see ACAMERA_COLOR_CORRECTION_GAINS
+     * @see ACAMERA_COLOR_CORRECTION_MODE
+     * @see ACAMERA_COLOR_CORRECTION_TRANSFORM
+     * @see ACAMERA_CONTROL_AE_MODE
+     * @see ACAMERA_CONTROL_AWB_LOCK
+     * @see ACAMERA_CONTROL_MODE
+     */
     ACAMERA_CONTROL_AWB_MODE =                                  // byte (enum)
             ACAMERA_CONTROL_START + 11,
+    /**
+     * <p>List of metering areas to use for auto-white-balance illuminant
+     * estimation.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraCaptureSession_captureCallback_result callbacks</li>
+     *   <li>ACaptureRequest</li>
+     * </ul>
+     *
+     * <p>Not available if android.control.maxRegionsAwb is 0.
+     * Otherwise will always be present.</p>
+     * <p>The maximum number of regions supported by the device is determined by the value
+     * of android.control.maxRegionsAwb.</p>
+     * <p>The coordinate system is based on the active pixel array,
+     * with (0,0) being the top-left pixel in the active pixel array, and
+     * (ACAMERA_SENSOR_INFO_ACTIVE_ARRAY_SIZE.width - 1,
+     * ACAMERA_SENSOR_INFO_ACTIVE_ARRAY_SIZE.height - 1) being the
+     * bottom-right pixel in the active pixel array.</p>
+     * <p>The weight must range from 0 to 1000, and represents a weight
+     * for every pixel in the area. This means that a large metering area
+     * with the same weight as a smaller area will have more effect in
+     * the metering result. Metering areas can partially overlap and the
+     * camera device will add the weights in the overlap region.</p>
+     * <p>The weights are relative to weights of other white balance metering regions, so if
+     * only one region is used, all non-zero weights will have the same effect. A region with
+     * 0 weight is ignored.</p>
+     * <p>If all regions have 0 weight, then no specific metering area needs to be used by the
+     * camera device.</p>
+     * <p>If the metering region is outside the used ACAMERA_SCALER_CROP_REGION returned in
+     * capture result metadata, the camera device will ignore the sections outside the crop
+     * region and output only the intersection rectangle as the metering region in the result
+     * metadata.  If the region is entirely outside the crop region, it will be ignored and
+     * not reported in the result metadata.</p>
+     *
+     * @see ACAMERA_SCALER_CROP_REGION
+     * @see ACAMERA_SENSOR_INFO_ACTIVE_ARRAY_SIZE
+     */
     ACAMERA_CONTROL_AWB_REGIONS =                               // int32[5*area_count]
             ACAMERA_CONTROL_START + 12,
+    /**
+     * <p>Information to the camera device 3A (auto-exposure,
+     * auto-focus, auto-white balance) routines about the purpose
+     * of this capture, to help the camera device to decide optimal 3A
+     * strategy.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraCaptureSession_captureCallback_result callbacks</li>
+     *   <li>ACaptureRequest</li>
+     * </ul>
+     *
+     * <p>This control (except for MANUAL) is only effective if
+     * <code>ACAMERA_CONTROL_MODE != OFF</code> and any 3A routine is active.</p>
+     * <p>ZERO_SHUTTER_LAG will be supported if ACAMERA_REQUEST_AVAILABLE_CAPABILITIES
+     * contains PRIVATE_REPROCESSING or YUV_REPROCESSING. MANUAL will be supported if
+     * ACAMERA_REQUEST_AVAILABLE_CAPABILITIES contains MANUAL_SENSOR. Other intent values are
+     * always supported.</p>
+     *
+     * @see ACAMERA_CONTROL_MODE
+     * @see ACAMERA_REQUEST_AVAILABLE_CAPABILITIES
+     */
     ACAMERA_CONTROL_CAPTURE_INTENT =                            // byte (enum)
             ACAMERA_CONTROL_START + 13,
+    /**
+     * <p>A special color effect to apply.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraCaptureSession_captureCallback_result callbacks</li>
+     *   <li>ACaptureRequest</li>
+     * </ul>
+     *
+     * <p>When this mode is set, a color effect will be applied
+     * to images produced by the camera device. The interpretation
+     * and implementation of these color effects is left to the
+     * implementor of the camera device, and should not be
+     * depended on to be consistent (or present) across all
+     * devices.</p>
+     */
     ACAMERA_CONTROL_EFFECT_MODE =                               // byte (enum)
             ACAMERA_CONTROL_START + 14,
+    /**
+     * <p>Overall mode of 3A (auto-exposure, auto-white-balance, auto-focus) control
+     * routines.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraCaptureSession_captureCallback_result callbacks</li>
+     *   <li>ACaptureRequest</li>
+     * </ul>
+     *
+     * <p>This is a top-level 3A control switch. When set to OFF, all 3A control
+     * by the camera device is disabled. The application must set the fields for
+     * capture parameters itself.</p>
+     * <p>When set to AUTO, the individual algorithm controls in
+     * ACAMERA_CONTROL_* are in effect, such as ACAMERA_CONTROL_AF_MODE.</p>
+     * <p>When set to USE_SCENE_MODE, the individual controls in
+     * ACAMERA_CONTROL_* are mostly disabled, and the camera device implements
+     * one of the scene mode settings (such as ACTION, SUNSET, or PARTY)
+     * as it wishes. The camera device scene mode 3A settings are provided by
+     * {@link android.hardware.camera2.CaptureResult capture results}.</p>
+     * <p>When set to OFF_KEEP_STATE, it is similar to OFF mode, the only difference
+     * is that this frame will not be used by camera device background 3A statistics
+     * update, as if this frame is never captured. This mode can be used in the scenario
+     * where the application doesn't want a 3A manual control capture to affect
+     * the subsequent auto 3A capture results.</p>
+     *
+     * @see ACAMERA_CONTROL_AF_MODE
+     */
     ACAMERA_CONTROL_MODE =                                      // byte (enum)
             ACAMERA_CONTROL_START + 15,
+    /**
+     * <p>Control for which scene mode is currently active.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraCaptureSession_captureCallback_result callbacks</li>
+     *   <li>ACaptureRequest</li>
+     * </ul>
+     *
+     * <p>Scene modes are custom camera modes optimized for a certain set of conditions and
+     * capture settings.</p>
+     * <p>This is the mode that that is active when
+     * <code>ACAMERA_CONTROL_MODE == USE_SCENE_MODE</code>. Aside from FACE_PRIORITY, these modes will
+     * disable ACAMERA_CONTROL_AE_MODE, ACAMERA_CONTROL_AWB_MODE, and ACAMERA_CONTROL_AF_MODE
+     * while in use.</p>
+     * <p>The interpretation and implementation of these scene modes is left
+     * to the implementor of the camera device. Their behavior will not be
+     * consistent across all devices, and any given device may only implement
+     * a subset of these modes.</p>
+     *
+     * @see ACAMERA_CONTROL_AE_MODE
+     * @see ACAMERA_CONTROL_AF_MODE
+     * @see ACAMERA_CONTROL_AWB_MODE
+     * @see ACAMERA_CONTROL_MODE
+     */
     ACAMERA_CONTROL_SCENE_MODE =                                // byte (enum)
             ACAMERA_CONTROL_START + 16,
+    /**
+     * <p>Whether video stabilization is
+     * active.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraCaptureSession_captureCallback_result callbacks</li>
+     *   <li>ACaptureRequest</li>
+     * </ul>
+     *
+     * <p>Video stabilization automatically warps images from
+     * the camera in order to stabilize motion between consecutive frames.</p>
+     * <p>If enabled, video stabilization can modify the
+     * ACAMERA_SCALER_CROP_REGION to keep the video stream stabilized.</p>
+     * <p>Switching between different video stabilization modes may take several
+     * frames to initialize, the camera device will report the current mode
+     * in capture result metadata. For example, When "ON" mode is requested,
+     * the video stabilization modes in the first several capture results may
+     * still be "OFF", and it will become "ON" when the initialization is
+     * done.</p>
+     * <p>In addition, not all recording sizes or frame rates may be supported for
+     * stabilization by a device that reports stabilization support. It is guaranteed
+     * that an output targeting a MediaRecorder or MediaCodec will be stabilized if
+     * the recording resolution is less than or equal to 1920 x 1080 (width less than
+     * or equal to 1920, height less than or equal to 1080), and the recording
+     * frame rate is less than or equal to 30fps.  At other sizes, the CaptureResult
+     * ACAMERA_CONTROL_VIDEO_STABILIZATION_MODE field will return
+     * OFF if the recording output is not stabilized, or if there are no output
+     * Surface types that can be stabilized.</p>
+     * <p>If a camera device supports both this mode and OIS
+     * (ACAMERA_LENS_OPTICAL_STABILIZATION_MODE), turning both modes on may
+     * produce undesirable interaction, so it is recommended not to enable
+     * both at the same time.</p>
+     *
+     * @see ACAMERA_CONTROL_VIDEO_STABILIZATION_MODE
+     * @see ACAMERA_LENS_OPTICAL_STABILIZATION_MODE
+     * @see ACAMERA_SCALER_CROP_REGION
+     */
     ACAMERA_CONTROL_VIDEO_STABILIZATION_MODE =                  // byte (enum)
             ACAMERA_CONTROL_START + 17,
+    /**
+     * <p>List of auto-exposure antibanding modes for ACAMERA_CONTROL_AE_ANTIBANDING_MODE that are
+     * supported by this camera device.</p>
+     *
+     * @see ACAMERA_CONTROL_AE_ANTIBANDING_MODE
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraManager_getCameraCharacteristics</li>
+     * </ul>
+     *
+     * <p>Not all of the auto-exposure anti-banding modes may be
+     * supported by a given camera device. This field lists the
+     * valid anti-banding modes that the application may request
+     * for this camera device with the
+     * ACAMERA_CONTROL_AE_ANTIBANDING_MODE control.</p>
+     *
+     * @see ACAMERA_CONTROL_AE_ANTIBANDING_MODE
+     */
     ACAMERA_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES =            // byte[n]
             ACAMERA_CONTROL_START + 18,
+    /**
+     * <p>List of auto-exposure modes for ACAMERA_CONTROL_AE_MODE that are supported by this camera
+     * device.</p>
+     *
+     * @see ACAMERA_CONTROL_AE_MODE
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraManager_getCameraCharacteristics</li>
+     * </ul>
+     *
+     * <p>Not all the auto-exposure modes may be supported by a
+     * given camera device, especially if no flash unit is
+     * available. This entry lists the valid modes for
+     * ACAMERA_CONTROL_AE_MODE for this camera device.</p>
+     * <p>All camera devices support ON, and all camera devices with flash
+     * units support ON_AUTO_FLASH and ON_ALWAYS_FLASH.</p>
+     * <p>FULL mode camera devices always support OFF mode,
+     * which enables application control of camera exposure time,
+     * sensitivity, and frame duration.</p>
+     * <p>LEGACY mode camera devices never support OFF mode.
+     * LIMITED mode devices support OFF if they support the MANUAL_SENSOR
+     * capability.</p>
+     *
+     * @see ACAMERA_CONTROL_AE_MODE
+     */
     ACAMERA_CONTROL_AE_AVAILABLE_MODES =                        // byte[n]
             ACAMERA_CONTROL_START + 19,
+    /**
+     * <p>List of frame rate ranges for ACAMERA_CONTROL_AE_TARGET_FPS_RANGE supported by
+     * this camera device.</p>
+     *
+     * @see ACAMERA_CONTROL_AE_TARGET_FPS_RANGE
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraManager_getCameraCharacteristics</li>
+     * </ul>
+     *
+     * <p>For devices at the LEGACY level or above:</p>
+     * <ul>
+     * <li>
+     * <p>For constant-framerate recording, for each normal
+     * {@link android.media.CamcorderProfile CamcorderProfile}, that is, a
+     * {@link android.media.CamcorderProfile CamcorderProfile} that has
+     * {@link android.media.CamcorderProfile#quality quality} in
+     * the range [{@link android.media.CamcorderProfile#QUALITY_LOW QUALITY_LOW},
+     * {@link android.media.CamcorderProfile#QUALITY_2160P QUALITY_2160P}], if the profile is
+     * supported by the device and has
+     * {@link android.media.CamcorderProfile#videoFrameRate videoFrameRate} <code>x</code>, this list will
+     * always include (<code>x</code>,<code>x</code>).</p>
+     * </li>
+     * <li>
+     * <p>Also, a camera device must either not support any
+     * {@link android.media.CamcorderProfile CamcorderProfile},
+     * or support at least one
+     * normal {@link android.media.CamcorderProfile CamcorderProfile} that has
+     * {@link android.media.CamcorderProfile#videoFrameRate videoFrameRate} <code>x</code> &gt;= 24.</p>
+     * </li>
+     * </ul>
+     * <p>For devices at the LIMITED level or above:</p>
+     * <ul>
+     * <li>For YUV_420_888 burst capture use case, this list will always include (<code>min</code>, <code>max</code>)
+     * and (<code>max</code>, <code>max</code>) where <code>min</code> &lt;= 15 and <code>max</code> = the maximum output frame rate of the
+     * maximum YUV_420_888 output size.</li>
+     * </ul>
+     */
     ACAMERA_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES =            // int32[2*n]
             ACAMERA_CONTROL_START + 20,
+    /**
+     * <p>Maximum and minimum exposure compensation values for
+     * ACAMERA_CONTROL_AE_EXPOSURE_COMPENSATION, in counts of ACAMERA_CONTROL_AE_COMPENSATION_STEP,
+     * that are supported by this camera device.</p>
+     *
+     * @see ACAMERA_CONTROL_AE_COMPENSATION_STEP
+     * @see ACAMERA_CONTROL_AE_EXPOSURE_COMPENSATION
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraManager_getCameraCharacteristics</li>
+     * </ul>
+     *
+     * <p>None</p>
+     */
     ACAMERA_CONTROL_AE_COMPENSATION_RANGE =                     // int32[2]
             ACAMERA_CONTROL_START + 21,
+    /**
+     * <p>Smallest step by which the exposure compensation
+     * can be changed.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraManager_getCameraCharacteristics</li>
+     * </ul>
+     *
+     * <p>This is the unit for ACAMERA_CONTROL_AE_EXPOSURE_COMPENSATION. For example, if this key has
+     * a value of <code>1/2</code>, then a setting of <code>-2</code> for ACAMERA_CONTROL_AE_EXPOSURE_COMPENSATION means
+     * that the target EV offset for the auto-exposure routine is -1 EV.</p>
+     * <p>One unit of EV compensation changes the brightness of the captured image by a factor
+     * of two. +1 EV doubles the image brightness, while -1 EV halves the image brightness.</p>
+     *
+     * @see ACAMERA_CONTROL_AE_EXPOSURE_COMPENSATION
+     */
     ACAMERA_CONTROL_AE_COMPENSATION_STEP =                      // rational
             ACAMERA_CONTROL_START + 22,
+    /**
+     * <p>List of auto-focus (AF) modes for ACAMERA_CONTROL_AF_MODE that are
+     * supported by this camera device.</p>
+     *
+     * @see ACAMERA_CONTROL_AF_MODE
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraManager_getCameraCharacteristics</li>
+     * </ul>
+     *
+     * <p>Not all the auto-focus modes may be supported by a
+     * given camera device. This entry lists the valid modes for
+     * ACAMERA_CONTROL_AF_MODE for this camera device.</p>
+     * <p>All LIMITED and FULL mode camera devices will support OFF mode, and all
+     * camera devices with adjustable focuser units
+     * (<code>ACAMERA_LENS_INFO_MINIMUM_FOCUS_DISTANCE &gt; 0</code>) will support AUTO mode.</p>
+     * <p>LEGACY devices will support OFF mode only if they support
+     * focusing to infinity (by also setting ACAMERA_LENS_FOCUS_DISTANCE to
+     * <code>0.0f</code>).</p>
+     *
+     * @see ACAMERA_CONTROL_AF_MODE
+     * @see ACAMERA_LENS_FOCUS_DISTANCE
+     * @see ACAMERA_LENS_INFO_MINIMUM_FOCUS_DISTANCE
+     */
     ACAMERA_CONTROL_AF_AVAILABLE_MODES =                        // byte[n]
             ACAMERA_CONTROL_START + 23,
+    /**
+     * <p>List of color effects for ACAMERA_CONTROL_EFFECT_MODE that are supported by this camera
+     * device.</p>
+     *
+     * @see ACAMERA_CONTROL_EFFECT_MODE
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraManager_getCameraCharacteristics</li>
+     * </ul>
+     *
+     * <p>This list contains the color effect modes that can be applied to
+     * images produced by the camera device.
+     * Implementations are not expected to be consistent across all devices.
+     * If no color effect modes are available for a device, this will only list
+     * OFF.</p>
+     * <p>A color effect will only be applied if
+     * ACAMERA_CONTROL_MODE != OFF.  OFF is always included in this list.</p>
+     * <p>This control has no effect on the operation of other control routines such
+     * as auto-exposure, white balance, or focus.</p>
+     *
+     * @see ACAMERA_CONTROL_MODE
+     */
     ACAMERA_CONTROL_AVAILABLE_EFFECTS =                         // byte[n]
             ACAMERA_CONTROL_START + 24,
+    /**
+     * <p>List of scene modes for ACAMERA_CONTROL_SCENE_MODE that are supported by this camera
+     * device.</p>
+     *
+     * @see ACAMERA_CONTROL_SCENE_MODE
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraManager_getCameraCharacteristics</li>
+     * </ul>
+     *
+     * <p>This list contains scene modes that can be set for the camera device.
+     * Only scene modes that have been fully implemented for the
+     * camera device may be included here. Implementations are not expected
+     * to be consistent across all devices.</p>
+     * <p>If no scene modes are supported by the camera device, this
+     * will be set to DISABLED. Otherwise DISABLED will not be listed.</p>
+     * <p>FACE_PRIORITY is always listed if face detection is
+     * supported (i.e.<code>ACAMERA_STATISTICS_INFO_MAX_FACE_COUNT &gt;
+     * 0</code>).</p>
+     *
+     * @see ACAMERA_STATISTICS_INFO_MAX_FACE_COUNT
+     */
     ACAMERA_CONTROL_AVAILABLE_SCENE_MODES =                     // byte[n]
             ACAMERA_CONTROL_START + 25,
+    /**
+     * <p>List of video stabilization modes for ACAMERA_CONTROL_VIDEO_STABILIZATION_MODE
+     * that are supported by this camera device.</p>
+     *
+     * @see ACAMERA_CONTROL_VIDEO_STABILIZATION_MODE
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraManager_getCameraCharacteristics</li>
+     * </ul>
+     *
+     * <p>OFF will always be listed.</p>
+     */
     ACAMERA_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES =       // byte[n]
             ACAMERA_CONTROL_START + 26,
+    /**
+     * <p>List of auto-white-balance modes for ACAMERA_CONTROL_AWB_MODE that are supported by this
+     * camera device.</p>
+     *
+     * @see ACAMERA_CONTROL_AWB_MODE
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraManager_getCameraCharacteristics</li>
+     * </ul>
+     *
+     * <p>Not all the auto-white-balance modes may be supported by a
+     * given camera device. This entry lists the valid modes for
+     * ACAMERA_CONTROL_AWB_MODE for this camera device.</p>
+     * <p>All camera devices will support ON mode.</p>
+     * <p>Camera devices that support the MANUAL_POST_PROCESSING capability will always support OFF
+     * mode, which enables application control of white balance, by using
+     * ACAMERA_COLOR_CORRECTION_TRANSFORM and ACAMERA_COLOR_CORRECTION_GAINS(ACAMERA_COLOR_CORRECTION_MODE must be set to TRANSFORM_MATRIX). This includes all FULL
+     * mode camera devices.</p>
+     *
+     * @see ACAMERA_COLOR_CORRECTION_GAINS
+     * @see ACAMERA_COLOR_CORRECTION_MODE
+     * @see ACAMERA_COLOR_CORRECTION_TRANSFORM
+     * @see ACAMERA_CONTROL_AWB_MODE
+     */
     ACAMERA_CONTROL_AWB_AVAILABLE_MODES =                       // byte[n]
             ACAMERA_CONTROL_START + 27,
+    /**
+     * <p>List of the maximum number of regions that can be used for metering in
+     * auto-exposure (AE), auto-white balance (AWB), and auto-focus (AF);
+     * this corresponds to the the maximum number of elements in
+     * ACAMERA_CONTROL_AE_REGIONS, ACAMERA_CONTROL_AWB_REGIONS,
+     * and ACAMERA_CONTROL_AF_REGIONS.</p>
+     *
+     * @see ACAMERA_CONTROL_AE_REGIONS
+     * @see ACAMERA_CONTROL_AF_REGIONS
+     * @see ACAMERA_CONTROL_AWB_REGIONS
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraManager_getCameraCharacteristics</li>
+     * </ul>
+     *
+     * <p>None</p>
+     */
     ACAMERA_CONTROL_MAX_REGIONS =                               // int32[3]
             ACAMERA_CONTROL_START + 28,
+    /**
+     * <p>Current state of the auto-exposure (AE) algorithm.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraCaptureSession_captureCallback_result callbacks</li>
+     * </ul>
+     *
+     * <p>Switching between or enabling AE modes (ACAMERA_CONTROL_AE_MODE) always
+     * resets the AE state to INACTIVE. Similarly, switching between ACAMERA_CONTROL_MODE,
+     * or ACAMERA_CONTROL_SCENE_MODE if <code>ACAMERA_CONTROL_MODE == USE_SCENE_MODE</code> resets all
+     * the algorithm states to INACTIVE.</p>
+     * <p>The camera device can do several state transitions between two results, if it is
+     * allowed by the state transition table. For example: INACTIVE may never actually be
+     * seen in a result.</p>
+     * <p>The state in the result is the state for this image (in sync with this image): if
+     * AE state becomes CONVERGED, then the image data associated with this result should
+     * be good to use.</p>
+     * <p>Below are state transition tables for different AE modes.</p>
+     * <table>
+     * <thead>
+     * <tr>
+     * <th align="center">State</th>
+     * <th align="center">Transition Cause</th>
+     * <th align="center">New State</th>
+     * <th align="center">Notes</th>
+     * </tr>
+     * </thead>
+     * <tbody>
+     * <tr>
+     * <td align="center">INACTIVE</td>
+     * <td align="center"></td>
+     * <td align="center">INACTIVE</td>
+     * <td align="center">Camera device auto exposure algorithm is disabled</td>
+     * </tr>
+     * </tbody>
+     * </table>
+     * <p>When ACAMERA_CONTROL_AE_MODE is AE_MODE_ON_*:</p>
+     * <table>
+     * <thead>
+     * <tr>
+     * <th align="center">State</th>
+     * <th align="center">Transition Cause</th>
+     * <th align="center">New State</th>
+     * <th align="center">Notes</th>
+     * </tr>
+     * </thead>
+     * <tbody>
+     * <tr>
+     * <td align="center">INACTIVE</td>
+     * <td align="center">Camera device initiates AE scan</td>
+     * <td align="center">SEARCHING</td>
+     * <td align="center">Values changing</td>
+     * </tr>
+     * <tr>
+     * <td align="center">INACTIVE</td>
+     * <td align="center">ACAMERA_CONTROL_AE_LOCK is ON</td>
+     * <td align="center">LOCKED</td>
+     * <td align="center">Values locked</td>
+     * </tr>
+     * <tr>
+     * <td align="center">SEARCHING</td>
+     * <td align="center">Camera device finishes AE scan</td>
+     * <td align="center">CONVERGED</td>
+     * <td align="center">Good values, not changing</td>
+     * </tr>
+     * <tr>
+     * <td align="center">SEARCHING</td>
+     * <td align="center">Camera device finishes AE scan</td>
+     * <td align="center">FLASH_REQUIRED</td>
+     * <td align="center">Converged but too dark w/o flash</td>
+     * </tr>
+     * <tr>
+     * <td align="center">SEARCHING</td>
+     * <td align="center">ACAMERA_CONTROL_AE_LOCK is ON</td>
+     * <td align="center">LOCKED</td>
+     * <td align="center">Values locked</td>
+     * </tr>
+     * <tr>
+     * <td align="center">CONVERGED</td>
+     * <td align="center">Camera device initiates AE scan</td>
+     * <td align="center">SEARCHING</td>
+     * <td align="center">Values changing</td>
+     * </tr>
+     * <tr>
+     * <td align="center">CONVERGED</td>
+     * <td align="center">ACAMERA_CONTROL_AE_LOCK is ON</td>
+     * <td align="center">LOCKED</td>
+     * <td align="center">Values locked</td>
+     * </tr>
+     * <tr>
+     * <td align="center">FLASH_REQUIRED</td>
+     * <td align="center">Camera device initiates AE scan</td>
+     * <td align="center">SEARCHING</td>
+     * <td align="center">Values changing</td>
+     * </tr>
+     * <tr>
+     * <td align="center">FLASH_REQUIRED</td>
+     * <td align="center">ACAMERA_CONTROL_AE_LOCK is ON</td>
+     * <td align="center">LOCKED</td>
+     * <td align="center">Values locked</td>
+     * </tr>
+     * <tr>
+     * <td align="center">LOCKED</td>
+     * <td align="center">ACAMERA_CONTROL_AE_LOCK is OFF</td>
+     * <td align="center">SEARCHING</td>
+     * <td align="center">Values not good after unlock</td>
+     * </tr>
+     * <tr>
+     * <td align="center">LOCKED</td>
+     * <td align="center">ACAMERA_CONTROL_AE_LOCK is OFF</td>
+     * <td align="center">CONVERGED</td>
+     * <td align="center">Values good after unlock</td>
+     * </tr>
+     * <tr>
+     * <td align="center">LOCKED</td>
+     * <td align="center">ACAMERA_CONTROL_AE_LOCK is OFF</td>
+     * <td align="center">FLASH_REQUIRED</td>
+     * <td align="center">Exposure good, but too dark</td>
+     * </tr>
+     * <tr>
+     * <td align="center">PRECAPTURE</td>
+     * <td align="center">Sequence done. ACAMERA_CONTROL_AE_LOCK is OFF</td>
+     * <td align="center">CONVERGED</td>
+     * <td align="center">Ready for high-quality capture</td>
+     * </tr>
+     * <tr>
+     * <td align="center">PRECAPTURE</td>
+     * <td align="center">Sequence done. ACAMERA_CONTROL_AE_LOCK is ON</td>
+     * <td align="center">LOCKED</td>
+     * <td align="center">Ready for high-quality capture</td>
+     * </tr>
+     * <tr>
+     * <td align="center">LOCKED</td>
+     * <td align="center">aeLock is ON and aePrecaptureTrigger is START</td>
+     * <td align="center">LOCKED</td>
+     * <td align="center">Precapture trigger is ignored when AE is already locked</td>
+     * </tr>
+     * <tr>
+     * <td align="center">LOCKED</td>
+     * <td align="center">aeLock is ON and aePrecaptureTrigger is CANCEL</td>
+     * <td align="center">LOCKED</td>
+     * <td align="center">Precapture trigger is ignored when AE is already locked</td>
+     * </tr>
+     * <tr>
+     * <td align="center">Any state (excluding LOCKED)</td>
+     * <td align="center">ACAMERA_CONTROL_AE_PRECAPTURE_TRIGGER is START</td>
+     * <td align="center">PRECAPTURE</td>
+     * <td align="center">Start AE precapture metering sequence</td>
+     * </tr>
+     * <tr>
+     * <td align="center">Any state (excluding LOCKED)</td>
+     * <td align="center">ACAMERA_CONTROL_AE_PRECAPTURE_TRIGGER is CANCEL</td>
+     * <td align="center">INACTIVE</td>
+     * <td align="center">Currently active precapture metering sequence is canceled</td>
+     * </tr>
+     * </tbody>
+     * </table>
+     * <p>For the above table, the camera device may skip reporting any state changes that happen
+     * without application intervention (i.e. mode switch, trigger, locking). Any state that
+     * can be skipped in that manner is called a transient state.</p>
+     * <p>For example, for above AE modes (AE_MODE_ON_*), in addition to the state transitions
+     * listed in above table, it is also legal for the camera device to skip one or more
+     * transient states between two results. See below table for examples:</p>
+     * <table>
+     * <thead>
+     * <tr>
+     * <th align="center">State</th>
+     * <th align="center">Transition Cause</th>
+     * <th align="center">New State</th>
+     * <th align="center">Notes</th>
+     * </tr>
+     * </thead>
+     * <tbody>
+     * <tr>
+     * <td align="center">INACTIVE</td>
+     * <td align="center">Camera device finished AE scan</td>
+     * <td align="center">CONVERGED</td>
+     * <td align="center">Values are already good, transient states are skipped by camera device.</td>
+     * </tr>
+     * <tr>
+     * <td align="center">Any state (excluding LOCKED)</td>
+     * <td align="center">ACAMERA_CONTROL_AE_PRECAPTURE_TRIGGER is START, sequence done</td>
+     * <td align="center">FLASH_REQUIRED</td>
+     * <td align="center">Converged but too dark w/o flash after a precapture sequence, transient states are skipped by camera device.</td>
+     * </tr>
+     * <tr>
+     * <td align="center">Any state (excluding LOCKED)</td>
+     * <td align="center">ACAMERA_CONTROL_AE_PRECAPTURE_TRIGGER is START, sequence done</td>
+     * <td align="center">CONVERGED</td>
+     * <td align="center">Converged after a precapture sequence, transient states are skipped by camera device.</td>
+     * </tr>
+     * <tr>
+     * <td align="center">Any state (excluding LOCKED)</td>
+     * <td align="center">ACAMERA_CONTROL_AE_PRECAPTURE_TRIGGER is CANCEL, converged</td>
+     * <td align="center">FLASH_REQUIRED</td>
+     * <td align="center">Converged but too dark w/o flash after a precapture sequence is canceled, transient states are skipped by camera device.</td>
+     * </tr>
+     * <tr>
+     * <td align="center">Any state (excluding LOCKED)</td>
+     * <td align="center">ACAMERA_CONTROL_AE_PRECAPTURE_TRIGGER is CANCEL, converged</td>
+     * <td align="center">CONVERGED</td>
+     * <td align="center">Converged after a precapture sequenceis canceled, transient states are skipped by camera device.</td>
+     * </tr>
+     * <tr>
+     * <td align="center">CONVERGED</td>
+     * <td align="center">Camera device finished AE scan</td>
+     * <td align="center">FLASH_REQUIRED</td>
+     * <td align="center">Converged but too dark w/o flash after a new scan, transient states are skipped by camera device.</td>
+     * </tr>
+     * <tr>
+     * <td align="center">FLASH_REQUIRED</td>
+     * <td align="center">Camera device finished AE scan</td>
+     * <td align="center">CONVERGED</td>
+     * <td align="center">Converged after a new scan, transient states are skipped by camera device.</td>
+     * </tr>
+     * </tbody>
+     * </table>
+     *
+     * @see ACAMERA_CONTROL_AE_LOCK
+     * @see ACAMERA_CONTROL_AE_MODE
+     * @see ACAMERA_CONTROL_AE_PRECAPTURE_TRIGGER
+     * @see ACAMERA_CONTROL_MODE
+     * @see ACAMERA_CONTROL_SCENE_MODE
+     */
     ACAMERA_CONTROL_AE_STATE =                                  // byte (enum)
             ACAMERA_CONTROL_START + 31,
+    /**
+     * <p>Current state of auto-focus (AF) algorithm.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraCaptureSession_captureCallback_result callbacks</li>
+     * </ul>
+     *
+     * <p>Switching between or enabling AF modes (ACAMERA_CONTROL_AF_MODE) always
+     * resets the AF state to INACTIVE. Similarly, switching between ACAMERA_CONTROL_MODE,
+     * or ACAMERA_CONTROL_SCENE_MODE if <code>ACAMERA_CONTROL_MODE == USE_SCENE_MODE</code> resets all
+     * the algorithm states to INACTIVE.</p>
+     * <p>The camera device can do several state transitions between two results, if it is
+     * allowed by the state transition table. For example: INACTIVE may never actually be
+     * seen in a result.</p>
+     * <p>The state in the result is the state for this image (in sync with this image): if
+     * AF state becomes FOCUSED, then the image data associated with this result should
+     * be sharp.</p>
+     * <p>Below are state transition tables for different AF modes.</p>
+     * <p>When ACAMERA_CONTROL_AF_MODE is AF_MODE_OFF or AF_MODE_EDOF:</p>
+     * <table>
+     * <thead>
+     * <tr>
+     * <th align="center">State</th>
+     * <th align="center">Transition Cause</th>
+     * <th align="center">New State</th>
+     * <th align="center">Notes</th>
+     * </tr>
+     * </thead>
+     * <tbody>
+     * <tr>
+     * <td align="center">INACTIVE</td>
+     * <td align="center"></td>
+     * <td align="center">INACTIVE</td>
+     * <td align="center">Never changes</td>
+     * </tr>
+     * </tbody>
+     * </table>
+     * <p>When ACAMERA_CONTROL_AF_MODE is AF_MODE_AUTO or AF_MODE_MACRO:</p>
+     * <table>
+     * <thead>
+     * <tr>
+     * <th align="center">State</th>
+     * <th align="center">Transition Cause</th>
+     * <th align="center">New State</th>
+     * <th align="center">Notes</th>
+     * </tr>
+     * </thead>
+     * <tbody>
+     * <tr>
+     * <td align="center">INACTIVE</td>
+     * <td align="center">AF_TRIGGER</td>
+     * <td align="center">ACTIVE_SCAN</td>
+     * <td align="center">Start AF sweep, Lens now moving</td>
+     * </tr>
+     * <tr>
+     * <td align="center">ACTIVE_SCAN</td>
+     * <td align="center">AF sweep done</td>
+     * <td align="center">FOCUSED_LOCKED</td>
+     * <td align="center">Focused, Lens now locked</td>
+     * </tr>
+     * <tr>
+     * <td align="center">ACTIVE_SCAN</td>
+     * <td align="center">AF sweep done</td>
+     * <td align="center">NOT_FOCUSED_LOCKED</td>
+     * <td align="center">Not focused, Lens now locked</td>
+     * </tr>
+     * <tr>
+     * <td align="center">ACTIVE_SCAN</td>
+     * <td align="center">AF_CANCEL</td>
+     * <td align="center">INACTIVE</td>
+     * <td align="center">Cancel/reset AF, Lens now locked</td>
+     * </tr>
+     * <tr>
+     * <td align="center">FOCUSED_LOCKED</td>
+     * <td align="center">AF_CANCEL</td>
+     * <td align="center">INACTIVE</td>
+     * <td align="center">Cancel/reset AF</td>
+     * </tr>
+     * <tr>
+     * <td align="center">FOCUSED_LOCKED</td>
+     * <td align="center">AF_TRIGGER</td>
+     * <td align="center">ACTIVE_SCAN</td>
+     * <td align="center">Start new sweep, Lens now moving</td>
+     * </tr>
+     * <tr>
+     * <td align="center">NOT_FOCUSED_LOCKED</td>
+     * <td align="center">AF_CANCEL</td>
+     * <td align="center">INACTIVE</td>
+     * <td align="center">Cancel/reset AF</td>
+     * </tr>
+     * <tr>
+     * <td align="center">NOT_FOCUSED_LOCKED</td>
+     * <td align="center">AF_TRIGGER</td>
+     * <td align="center">ACTIVE_SCAN</td>
+     * <td align="center">Start new sweep, Lens now moving</td>
+     * </tr>
+     * <tr>
+     * <td align="center">Any state</td>
+     * <td align="center">Mode change</td>
+     * <td align="center">INACTIVE</td>
+     * <td align="center"></td>
+     * </tr>
+     * </tbody>
+     * </table>
+     * <p>For the above table, the camera device may skip reporting any state changes that happen
+     * without application intervention (i.e. mode switch, trigger, locking). Any state that
+     * can be skipped in that manner is called a transient state.</p>
+     * <p>For example, for these AF modes (AF_MODE_AUTO and AF_MODE_MACRO), in addition to the
+     * state transitions listed in above table, it is also legal for the camera device to skip
+     * one or more transient states between two results. See below table for examples:</p>
+     * <table>
+     * <thead>
+     * <tr>
+     * <th align="center">State</th>
+     * <th align="center">Transition Cause</th>
+     * <th align="center">New State</th>
+     * <th align="center">Notes</th>
+     * </tr>
+     * </thead>
+     * <tbody>
+     * <tr>
+     * <td align="center">INACTIVE</td>
+     * <td align="center">AF_TRIGGER</td>
+     * <td align="center">FOCUSED_LOCKED</td>
+     * <td align="center">Focus is already good or good after a scan, lens is now locked.</td>
+     * </tr>
+     * <tr>
+     * <td align="center">INACTIVE</td>
+     * <td align="center">AF_TRIGGER</td>
+     * <td align="center">NOT_FOCUSED_LOCKED</td>
+     * <td align="center">Focus failed after a scan, lens is now locked.</td>
+     * </tr>
+     * <tr>
+     * <td align="center">FOCUSED_LOCKED</td>
+     * <td align="center">AF_TRIGGER</td>
+     * <td align="center">FOCUSED_LOCKED</td>
+     * <td align="center">Focus is already good or good after a scan, lens is now locked.</td>
+     * </tr>
+     * <tr>
+     * <td align="center">NOT_FOCUSED_LOCKED</td>
+     * <td align="center">AF_TRIGGER</td>
+     * <td align="center">FOCUSED_LOCKED</td>
+     * <td align="center">Focus is good after a scan, lens is not locked.</td>
+     * </tr>
+     * </tbody>
+     * </table>
+     * <p>When ACAMERA_CONTROL_AF_MODE is AF_MODE_CONTINUOUS_VIDEO:</p>
+     * <table>
+     * <thead>
+     * <tr>
+     * <th align="center">State</th>
+     * <th align="center">Transition Cause</th>
+     * <th align="center">New State</th>
+     * <th align="center">Notes</th>
+     * </tr>
+     * </thead>
+     * <tbody>
+     * <tr>
+     * <td align="center">INACTIVE</td>
+     * <td align="center">Camera device initiates new scan</td>
+     * <td align="center">PASSIVE_SCAN</td>
+     * <td align="center">Start AF scan, Lens now moving</td>
+     * </tr>
+     * <tr>
+     * <td align="center">INACTIVE</td>
+     * <td align="center">AF_TRIGGER</td>
+     * <td align="center">NOT_FOCUSED_LOCKED</td>
+     * <td align="center">AF state query, Lens now locked</td>
+     * </tr>
+     * <tr>
+     * <td align="center">PASSIVE_SCAN</td>
+     * <td align="center">Camera device completes current scan</td>
+     * <td align="center">PASSIVE_FOCUSED</td>
+     * <td align="center">End AF scan, Lens now locked</td>
+     * </tr>
+     * <tr>
+     * <td align="center">PASSIVE_SCAN</td>
+     * <td align="center">Camera device fails current scan</td>
+     * <td align="center">PASSIVE_UNFOCUSED</td>
+     * <td align="center">End AF scan, Lens now locked</td>
+     * </tr>
+     * <tr>
+     * <td align="center">PASSIVE_SCAN</td>
+     * <td align="center">AF_TRIGGER</td>
+     * <td align="center">FOCUSED_LOCKED</td>
+     * <td align="center">Immediate transition, if focus is good. Lens now locked</td>
+     * </tr>
+     * <tr>
+     * <td align="center">PASSIVE_SCAN</td>
+     * <td align="center">AF_TRIGGER</td>
+     * <td align="center">NOT_FOCUSED_LOCKED</td>
+     * <td align="center">Immediate transition, if focus is bad. Lens now locked</td>
+     * </tr>
+     * <tr>
+     * <td align="center">PASSIVE_SCAN</td>
+     * <td align="center">AF_CANCEL</td>
+     * <td align="center">INACTIVE</td>
+     * <td align="center">Reset lens position, Lens now locked</td>
+     * </tr>
+     * <tr>
+     * <td align="center">PASSIVE_FOCUSED</td>
+     * <td align="center">Camera device initiates new scan</td>
+     * <td align="center">PASSIVE_SCAN</td>
+     * <td align="center">Start AF scan, Lens now moving</td>
+     * </tr>
+     * <tr>
+     * <td align="center">PASSIVE_UNFOCUSED</td>
+     * <td align="center">Camera device initiates new scan</td>
+     * <td align="center">PASSIVE_SCAN</td>
+     * <td align="center">Start AF scan, Lens now moving</td>
+     * </tr>
+     * <tr>
+     * <td align="center">PASSIVE_FOCUSED</td>
+     * <td align="center">AF_TRIGGER</td>
+     * <td align="center">FOCUSED_LOCKED</td>
+     * <td align="center">Immediate transition, lens now locked</td>
+     * </tr>
+     * <tr>
+     * <td align="center">PASSIVE_UNFOCUSED</td>
+     * <td align="center">AF_TRIGGER</td>
+     * <td align="center">NOT_FOCUSED_LOCKED</td>
+     * <td align="center">Immediate transition, lens now locked</td>
+     * </tr>
+     * <tr>
+     * <td align="center">FOCUSED_LOCKED</td>
+     * <td align="center">AF_TRIGGER</td>
+     * <td align="center">FOCUSED_LOCKED</td>
+     * <td align="center">No effect</td>
+     * </tr>
+     * <tr>
+     * <td align="center">FOCUSED_LOCKED</td>
+     * <td align="center">AF_CANCEL</td>
+     * <td align="center">INACTIVE</td>
+     * <td align="center">Restart AF scan</td>
+     * </tr>
+     * <tr>
+     * <td align="center">NOT_FOCUSED_LOCKED</td>
+     * <td align="center">AF_TRIGGER</td>
+     * <td align="center">NOT_FOCUSED_LOCKED</td>
+     * <td align="center">No effect</td>
+     * </tr>
+     * <tr>
+     * <td align="center">NOT_FOCUSED_LOCKED</td>
+     * <td align="center">AF_CANCEL</td>
+     * <td align="center">INACTIVE</td>
+     * <td align="center">Restart AF scan</td>
+     * </tr>
+     * </tbody>
+     * </table>
+     * <p>When ACAMERA_CONTROL_AF_MODE is AF_MODE_CONTINUOUS_PICTURE:</p>
+     * <table>
+     * <thead>
+     * <tr>
+     * <th align="center">State</th>
+     * <th align="center">Transition Cause</th>
+     * <th align="center">New State</th>
+     * <th align="center">Notes</th>
+     * </tr>
+     * </thead>
+     * <tbody>
+     * <tr>
+     * <td align="center">INACTIVE</td>
+     * <td align="center">Camera device initiates new scan</td>
+     * <td align="center">PASSIVE_SCAN</td>
+     * <td align="center">Start AF scan, Lens now moving</td>
+     * </tr>
+     * <tr>
+     * <td align="center">INACTIVE</td>
+     * <td align="center">AF_TRIGGER</td>
+     * <td align="center">NOT_FOCUSED_LOCKED</td>
+     * <td align="center">AF state query, Lens now locked</td>
+     * </tr>
+     * <tr>
+     * <td align="center">PASSIVE_SCAN</td>
+     * <td align="center">Camera device completes current scan</td>
+     * <td align="center">PASSIVE_FOCUSED</td>
+     * <td align="center">End AF scan, Lens now locked</td>
+     * </tr>
+     * <tr>
+     * <td align="center">PASSIVE_SCAN</td>
+     * <td align="center">Camera device fails current scan</td>
+     * <td align="center">PASSIVE_UNFOCUSED</td>
+     * <td align="center">End AF scan, Lens now locked</td>
+     * </tr>
+     * <tr>
+     * <td align="center">PASSIVE_SCAN</td>
+     * <td align="center">AF_TRIGGER</td>
+     * <td align="center">FOCUSED_LOCKED</td>
+     * <td align="center">Eventual transition once the focus is good. Lens now locked</td>
+     * </tr>
+     * <tr>
+     * <td align="center">PASSIVE_SCAN</td>
+     * <td align="center">AF_TRIGGER</td>
+     * <td align="center">NOT_FOCUSED_LOCKED</td>
+     * <td align="center">Eventual transition if cannot find focus. Lens now locked</td>
+     * </tr>
+     * <tr>
+     * <td align="center">PASSIVE_SCAN</td>
+     * <td align="center">AF_CANCEL</td>
+     * <td align="center">INACTIVE</td>
+     * <td align="center">Reset lens position, Lens now locked</td>
+     * </tr>
+     * <tr>
+     * <td align="center">PASSIVE_FOCUSED</td>
+     * <td align="center">Camera device initiates new scan</td>
+     * <td align="center">PASSIVE_SCAN</td>
+     * <td align="center">Start AF scan, Lens now moving</td>
+     * </tr>
+     * <tr>
+     * <td align="center">PASSIVE_UNFOCUSED</td>
+     * <td align="center">Camera device initiates new scan</td>
+     * <td align="center">PASSIVE_SCAN</td>
+     * <td align="center">Start AF scan, Lens now moving</td>
+     * </tr>
+     * <tr>
+     * <td align="center">PASSIVE_FOCUSED</td>
+     * <td align="center">AF_TRIGGER</td>
+     * <td align="center">FOCUSED_LOCKED</td>
+     * <td align="center">Immediate trans. Lens now locked</td>
+     * </tr>
+     * <tr>
+     * <td align="center">PASSIVE_UNFOCUSED</td>
+     * <td align="center">AF_TRIGGER</td>
+     * <td align="center">NOT_FOCUSED_LOCKED</td>
+     * <td align="center">Immediate trans. Lens now locked</td>
+     * </tr>
+     * <tr>
+     * <td align="center">FOCUSED_LOCKED</td>
+     * <td align="center">AF_TRIGGER</td>
+     * <td align="center">FOCUSED_LOCKED</td>
+     * <td align="center">No effect</td>
+     * </tr>
+     * <tr>
+     * <td align="center">FOCUSED_LOCKED</td>
+     * <td align="center">AF_CANCEL</td>
+     * <td align="center">INACTIVE</td>
+     * <td align="center">Restart AF scan</td>
+     * </tr>
+     * <tr>
+     * <td align="center">NOT_FOCUSED_LOCKED</td>
+     * <td align="center">AF_TRIGGER</td>
+     * <td align="center">NOT_FOCUSED_LOCKED</td>
+     * <td align="center">No effect</td>
+     * </tr>
+     * <tr>
+     * <td align="center">NOT_FOCUSED_LOCKED</td>
+     * <td align="center">AF_CANCEL</td>
+     * <td align="center">INACTIVE</td>
+     * <td align="center">Restart AF scan</td>
+     * </tr>
+     * </tbody>
+     * </table>
+     * <p>When switch between AF_MODE_CONTINUOUS_* (CAF modes) and AF_MODE_AUTO/AF_MODE_MACRO
+     * (AUTO modes), the initial INACTIVE or PASSIVE_SCAN states may be skipped by the
+     * camera device. When a trigger is included in a mode switch request, the trigger
+     * will be evaluated in the context of the new mode in the request.
+     * See below table for examples:</p>
+     * <table>
+     * <thead>
+     * <tr>
+     * <th align="center">State</th>
+     * <th align="center">Transition Cause</th>
+     * <th align="center">New State</th>
+     * <th align="center">Notes</th>
+     * </tr>
+     * </thead>
+     * <tbody>
+     * <tr>
+     * <td align="center">any state</td>
+     * <td align="center">CAF--&gt;AUTO mode switch</td>
+     * <td align="center">INACTIVE</td>
+     * <td align="center">Mode switch without trigger, initial state must be INACTIVE</td>
+     * </tr>
+     * <tr>
+     * <td align="center">any state</td>
+     * <td align="center">CAF--&gt;AUTO mode switch with AF_TRIGGER</td>
+     * <td align="center">trigger-reachable states from INACTIVE</td>
+     * <td align="center">Mode switch with trigger, INACTIVE is skipped</td>
+     * </tr>
+     * <tr>
+     * <td align="center">any state</td>
+     * <td align="center">AUTO--&gt;CAF mode switch</td>
+     * <td align="center">passively reachable states from INACTIVE</td>
+     * <td align="center">Mode switch without trigger, passive transient state is skipped</td>
+     * </tr>
+     * </tbody>
+     * </table>
+     *
+     * @see ACAMERA_CONTROL_AF_MODE
+     * @see ACAMERA_CONTROL_MODE
+     * @see ACAMERA_CONTROL_SCENE_MODE
+     */
     ACAMERA_CONTROL_AF_STATE =                                  // byte (enum)
             ACAMERA_CONTROL_START + 32,
+    /**
+     * <p>Current state of auto-white balance (AWB) algorithm.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraCaptureSession_captureCallback_result callbacks</li>
+     * </ul>
+     *
+     * <p>Switching between or enabling AWB modes (ACAMERA_CONTROL_AWB_MODE) always
+     * resets the AWB state to INACTIVE. Similarly, switching between ACAMERA_CONTROL_MODE,
+     * or ACAMERA_CONTROL_SCENE_MODE if <code>ACAMERA_CONTROL_MODE == USE_SCENE_MODE</code> resets all
+     * the algorithm states to INACTIVE.</p>
+     * <p>The camera device can do several state transitions between two results, if it is
+     * allowed by the state transition table. So INACTIVE may never actually be seen in
+     * a result.</p>
+     * <p>The state in the result is the state for this image (in sync with this image): if
+     * AWB state becomes CONVERGED, then the image data associated with this result should
+     * be good to use.</p>
+     * <p>Below are state transition tables for different AWB modes.</p>
+     * <p>When <code>ACAMERA_CONTROL_AWB_MODE != AWB_MODE_AUTO</code>:</p>
+     * <table>
+     * <thead>
+     * <tr>
+     * <th align="center">State</th>
+     * <th align="center">Transition Cause</th>
+     * <th align="center">New State</th>
+     * <th align="center">Notes</th>
+     * </tr>
+     * </thead>
+     * <tbody>
+     * <tr>
+     * <td align="center">INACTIVE</td>
+     * <td align="center"></td>
+     * <td align="center">INACTIVE</td>
+     * <td align="center">Camera device auto white balance algorithm is disabled</td>
+     * </tr>
+     * </tbody>
+     * </table>
+     * <p>When ACAMERA_CONTROL_AWB_MODE is AWB_MODE_AUTO:</p>
+     * <table>
+     * <thead>
+     * <tr>
+     * <th align="center">State</th>
+     * <th align="center">Transition Cause</th>
+     * <th align="center">New State</th>
+     * <th align="center">Notes</th>
+     * </tr>
+     * </thead>
+     * <tbody>
+     * <tr>
+     * <td align="center">INACTIVE</td>
+     * <td align="center">Camera device initiates AWB scan</td>
+     * <td align="center">SEARCHING</td>
+     * <td align="center">Values changing</td>
+     * </tr>
+     * <tr>
+     * <td align="center">INACTIVE</td>
+     * <td align="center">ACAMERA_CONTROL_AWB_LOCK is ON</td>
+     * <td align="center">LOCKED</td>
+     * <td align="center">Values locked</td>
+     * </tr>
+     * <tr>
+     * <td align="center">SEARCHING</td>
+     * <td align="center">Camera device finishes AWB scan</td>
+     * <td align="center">CONVERGED</td>
+     * <td align="center">Good values, not changing</td>
+     * </tr>
+     * <tr>
+     * <td align="center">SEARCHING</td>
+     * <td align="center">ACAMERA_CONTROL_AWB_LOCK is ON</td>
+     * <td align="center">LOCKED</td>
+     * <td align="center">Values locked</td>
+     * </tr>
+     * <tr>
+     * <td align="center">CONVERGED</td>
+     * <td align="center">Camera device initiates AWB scan</td>
+     * <td align="center">SEARCHING</td>
+     * <td align="center">Values changing</td>
+     * </tr>
+     * <tr>
+     * <td align="center">CONVERGED</td>
+     * <td align="center">ACAMERA_CONTROL_AWB_LOCK is ON</td>
+     * <td align="center">LOCKED</td>
+     * <td align="center">Values locked</td>
+     * </tr>
+     * <tr>
+     * <td align="center">LOCKED</td>
+     * <td align="center">ACAMERA_CONTROL_AWB_LOCK is OFF</td>
+     * <td align="center">SEARCHING</td>
+     * <td align="center">Values not good after unlock</td>
+     * </tr>
+     * </tbody>
+     * </table>
+     * <p>For the above table, the camera device may skip reporting any state changes that happen
+     * without application intervention (i.e. mode switch, trigger, locking). Any state that
+     * can be skipped in that manner is called a transient state.</p>
+     * <p>For example, for this AWB mode (AWB_MODE_AUTO), in addition to the state transitions
+     * listed in above table, it is also legal for the camera device to skip one or more
+     * transient states between two results. See below table for examples:</p>
+     * <table>
+     * <thead>
+     * <tr>
+     * <th align="center">State</th>
+     * <th align="center">Transition Cause</th>
+     * <th align="center">New State</th>
+     * <th align="center">Notes</th>
+     * </tr>
+     * </thead>
+     * <tbody>
+     * <tr>
+     * <td align="center">INACTIVE</td>
+     * <td align="center">Camera device finished AWB scan</td>
+     * <td align="center">CONVERGED</td>
+     * <td align="center">Values are already good, transient states are skipped by camera device.</td>
+     * </tr>
+     * <tr>
+     * <td align="center">LOCKED</td>
+     * <td align="center">ACAMERA_CONTROL_AWB_LOCK is OFF</td>
+     * <td align="center">CONVERGED</td>
+     * <td align="center">Values good after unlock, transient states are skipped by camera device.</td>
+     * </tr>
+     * </tbody>
+     * </table>
+     *
+     * @see ACAMERA_CONTROL_AWB_LOCK
+     * @see ACAMERA_CONTROL_AWB_MODE
+     * @see ACAMERA_CONTROL_MODE
+     * @see ACAMERA_CONTROL_SCENE_MODE
+     */
     ACAMERA_CONTROL_AWB_STATE =                                 // byte (enum)
             ACAMERA_CONTROL_START + 34,
+    /**
+     * <p>Whether the camera device supports ACAMERA_CONTROL_AE_LOCK</p>
+     *
+     * @see ACAMERA_CONTROL_AE_LOCK
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraManager_getCameraCharacteristics</li>
+     * </ul>
+     *
+     * <p>Devices with MANUAL_SENSOR capability or BURST_CAPTURE capability will always
+     * list <code>true</code>. This includes FULL devices.</p>
+     */
     ACAMERA_CONTROL_AE_LOCK_AVAILABLE =                         // byte (enum)
             ACAMERA_CONTROL_START + 36,
+    /**
+     * <p>Whether the camera device supports ACAMERA_CONTROL_AWB_LOCK</p>
+     *
+     * @see ACAMERA_CONTROL_AWB_LOCK
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraManager_getCameraCharacteristics</li>
+     * </ul>
+     *
+     * <p>Devices with MANUAL_POST_PROCESSING capability or BURST_CAPTURE capability will
+     * always list <code>true</code>. This includes FULL devices.</p>
+     */
     ACAMERA_CONTROL_AWB_LOCK_AVAILABLE =                        // byte (enum)
             ACAMERA_CONTROL_START + 37,
+    /**
+     * <p>List of control modes for ACAMERA_CONTROL_MODE that are supported by this camera
+     * device.</p>
+     *
+     * @see ACAMERA_CONTROL_MODE
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraManager_getCameraCharacteristics</li>
+     * </ul>
+     *
+     * <p>This list contains control modes that can be set for the camera device.
+     * LEGACY mode devices will always support AUTO mode. LIMITED and FULL
+     * devices will always support OFF, AUTO modes.</p>
+     */
     ACAMERA_CONTROL_AVAILABLE_MODES =                           // byte[n]
             ACAMERA_CONTROL_START + 38,
+    /**
+     * <p>Range of boosts for ACAMERA_CONTROL_POST_RAW_SENSITIVITY_BOOST supported
+     * by this camera device.</p>
+     *
+     * @see ACAMERA_CONTROL_POST_RAW_SENSITIVITY_BOOST
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraManager_getCameraCharacteristics</li>
+     * </ul>
+     *
+     * <p>Devices support post RAW sensitivity boost  will advertise
+     * ACAMERA_CONTROL_POST_RAW_SENSITIVITY_BOOST key for controling
+     * post RAW sensitivity boost.</p>
+     * <p>This key will be <code>null</code> for devices that do not support any RAW format
+     * outputs. For devices that do support RAW format outputs, this key will always
+     * present, and if a device does not support post RAW sensitivity boost, it will
+     * list <code>(100, 100)</code> in this key.</p>
+     *
+     * @see ACAMERA_CONTROL_POST_RAW_SENSITIVITY_BOOST
+     */
     ACAMERA_CONTROL_POST_RAW_SENSITIVITY_BOOST_RANGE =          // int32[2]
             ACAMERA_CONTROL_START + 39,
+    /**
+     * <p>The amount of additional sensitivity boost applied to output images
+     * after RAW sensor data is captured.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraCaptureSession_captureCallback_result callbacks</li>
+     *   <li>ACaptureRequest</li>
+     * </ul>
+     *
+     * <p>Some camera devices support additional digital sensitivity boosting in the
+     * camera processing pipeline after sensor RAW image is captured.
+     * Such a boost will be applied to YUV/JPEG format output images but will not
+     * have effect on RAW output formats like RAW_SENSOR, RAW10, RAW12 or RAW_OPAQUE.</p>
+     * <p>This key will be <code>null</code> for devices that do not support any RAW format
+     * outputs. For devices that do support RAW format outputs, this key will always
+     * present, and if a device does not support post RAW sensitivity boost, it will
+     * list <code>100</code> in this key.</p>
+     * <p>If the camera device cannot apply the exact boost requested, it will reduce the
+     * boost to the nearest supported value.
+     * The final boost value used will be available in the output capture result.</p>
+     * <p>For devices that support post RAW sensitivity boost, the YUV/JPEG output images
+     * of such device will have the total sensitivity of
+     * <code>ACAMERA_SENSOR_SENSITIVITY * ACAMERA_CONTROL_POST_RAW_SENSITIVITY_BOOST / 100</code>
+     * The sensitivity of RAW format images will always be <code>ACAMERA_SENSOR_SENSITIVITY</code></p>
+     * <p>This control is only effective if ACAMERA_CONTROL_AE_MODE or ACAMERA_CONTROL_MODE is set to
+     * OFF; otherwise the auto-exposure algorithm will override this value.</p>
+     *
+     * @see ACAMERA_CONTROL_AE_MODE
+     * @see ACAMERA_CONTROL_MODE
+     * @see ACAMERA_CONTROL_POST_RAW_SENSITIVITY_BOOST
+     * @see ACAMERA_SENSOR_SENSITIVITY
+     */
     ACAMERA_CONTROL_POST_RAW_SENSITIVITY_BOOST =                // int32
             ACAMERA_CONTROL_START + 40,
     ACAMERA_CONTROL_END,
 
+    /**
+     * <p>Operation mode for edge
+     * enhancement.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraCaptureSession_captureCallback_result callbacks</li>
+     *   <li>ACaptureRequest</li>
+     * </ul>
+     *
+     * <p>Edge enhancement improves sharpness and details in the captured image. OFF means
+     * no enhancement will be applied by the camera device.</p>
+     * <p>FAST/HIGH_QUALITY both mean camera device determined enhancement
+     * will be applied. HIGH_QUALITY mode indicates that the
+     * camera device will use the highest-quality enhancement algorithms,
+     * even if it slows down capture rate. FAST means the camera device will
+     * not slow down capture rate when applying edge enhancement. FAST may be the same as OFF if
+     * edge enhancement will slow down capture rate. Every output stream will have a similar
+     * amount of enhancement applied.</p>
+     * <p>ZERO_SHUTTER_LAG is meant to be used by applications that maintain a continuous circular
+     * buffer of high-resolution images during preview and reprocess image(s) from that buffer
+     * into a final capture when triggered by the user. In this mode, the camera device applies
+     * edge enhancement to low-resolution streams (below maximum recording resolution) to
+     * maximize preview quality, but does not apply edge enhancement to high-resolution streams,
+     * since those will be reprocessed later if necessary.</p>
+     * <p>For YUV_REPROCESSING, these FAST/HIGH_QUALITY modes both mean that the camera
+     * device will apply FAST/HIGH_QUALITY YUV-domain edge enhancement, respectively.
+     * The camera device may adjust its internal edge enhancement parameters for best
+     * image quality based on the android.reprocess.effectiveExposureFactor, if it is set.</p>
+     */
     ACAMERA_EDGE_MODE =                                         // byte (enum)
             ACAMERA_EDGE_START,
+    /**
+     * <p>List of edge enhancement modes for ACAMERA_EDGE_MODE that are supported by this camera
+     * device.</p>
+     *
+     * @see ACAMERA_EDGE_MODE
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraManager_getCameraCharacteristics</li>
+     * </ul>
+     *
+     * <p>Full-capability camera devices must always support OFF; camera devices that support
+     * YUV_REPROCESSING or PRIVATE_REPROCESSING will list ZERO_SHUTTER_LAG; all devices will
+     * list FAST.</p>
+     */
     ACAMERA_EDGE_AVAILABLE_EDGE_MODES =                         // byte[n]
             ACAMERA_EDGE_START + 2,
     ACAMERA_EDGE_END,
 
+    /**
+     * <p>The desired mode for for the camera device's flash control.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraCaptureSession_captureCallback_result callbacks</li>
+     *   <li>ACaptureRequest</li>
+     * </ul>
+     *
+     * <p>This control is only effective when flash unit is available
+     * (<code>ACAMERA_FLASH_INFO_AVAILABLE == true</code>).</p>
+     * <p>When this control is used, the ACAMERA_CONTROL_AE_MODE must be set to ON or OFF.
+     * Otherwise, the camera device auto-exposure related flash control (ON_AUTO_FLASH,
+     * ON_ALWAYS_FLASH, or ON_AUTO_FLASH_REDEYE) will override this control.</p>
+     * <p>When set to OFF, the camera device will not fire flash for this capture.</p>
+     * <p>When set to SINGLE, the camera device will fire flash regardless of the camera
+     * device's auto-exposure routine's result. When used in still capture case, this
+     * control should be used along with auto-exposure (AE) precapture metering sequence
+     * (ACAMERA_CONTROL_AE_PRECAPTURE_TRIGGER), otherwise, the image may be incorrectly exposed.</p>
+     * <p>When set to TORCH, the flash will be on continuously. This mode can be used
+     * for use cases such as preview, auto-focus assist, still capture, or video recording.</p>
+     * <p>The flash status will be reported by ACAMERA_FLASH_STATE in the capture result metadata.</p>
+     *
+     * @see ACAMERA_CONTROL_AE_MODE
+     * @see ACAMERA_CONTROL_AE_PRECAPTURE_TRIGGER
+     * @see ACAMERA_FLASH_INFO_AVAILABLE
+     * @see ACAMERA_FLASH_STATE
+     */
     ACAMERA_FLASH_MODE =                                        // byte (enum)
             ACAMERA_FLASH_START + 2,
+    /**
+     * <p>Current state of the flash
+     * unit.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraCaptureSession_captureCallback_result callbacks</li>
+     * </ul>
+     *
+     * <p>When the camera device doesn't have flash unit
+     * (i.e. <code>ACAMERA_FLASH_INFO_AVAILABLE == false</code>), this state will always be UNAVAILABLE.
+     * Other states indicate the current flash status.</p>
+     * <p>In certain conditions, this will be available on LEGACY devices:</p>
+     * <ul>
+     * <li>Flash-less cameras always return UNAVAILABLE.</li>
+     * <li>Using ACAMERA_CONTROL_AE_MODE <code>==</code> ON_ALWAYS_FLASH
+     *    will always return FIRED.</li>
+     * <li>Using ACAMERA_FLASH_MODE <code>==</code> TORCH
+     *    will always return FIRED.</li>
+     * </ul>
+     * <p>In all other conditions the state will not be available on
+     * LEGACY devices (i.e. it will be <code>null</code>).</p>
+     *
+     * @see ACAMERA_CONTROL_AE_MODE
+     * @see ACAMERA_FLASH_INFO_AVAILABLE
+     * @see ACAMERA_FLASH_MODE
+     */
     ACAMERA_FLASH_STATE =                                       // byte (enum)
             ACAMERA_FLASH_START + 5,
     ACAMERA_FLASH_END,
 
+    /**
+     * <p>Whether this camera device has a
+     * flash unit.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraManager_getCameraCharacteristics</li>
+     * </ul>
+     *
+     * <p>Will be <code>false</code> if no flash is available.</p>
+     * <p>If there is no flash unit, none of the flash controls do
+     * anything.</p>
+     */
     ACAMERA_FLASH_INFO_AVAILABLE =                              // byte (enum)
             ACAMERA_FLASH_INFO_START,
     ACAMERA_FLASH_INFO_END,
 
+    /**
+     * <p>Operational mode for hot pixel correction.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraCaptureSession_captureCallback_result callbacks</li>
+     *   <li>ACaptureRequest</li>
+     * </ul>
+     *
+     * <p>Hotpixel correction interpolates out, or otherwise removes, pixels
+     * that do not accurately measure the incoming light (i.e. pixels that
+     * are stuck at an arbitrary value or are oversensitive).</p>
+     */
     ACAMERA_HOT_PIXEL_MODE =                                    // byte (enum)
             ACAMERA_HOT_PIXEL_START,
+    /**
+     * <p>List of hot pixel correction modes for ACAMERA_HOT_PIXEL_MODE that are supported by this
+     * camera device.</p>
+     *
+     * @see ACAMERA_HOT_PIXEL_MODE
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraManager_getCameraCharacteristics</li>
+     * </ul>
+     *
+     * <p>FULL mode camera devices will always support FAST.</p>
+     */
     ACAMERA_HOT_PIXEL_AVAILABLE_HOT_PIXEL_MODES =               // byte[n]
             ACAMERA_HOT_PIXEL_START + 1,
     ACAMERA_HOT_PIXEL_END,
 
+    /**
+     * <p>GPS coordinates to include in output JPEG
+     * EXIF.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraCaptureSession_captureCallback_result callbacks</li>
+     *   <li>ACaptureRequest</li>
+     * </ul>
+     *
+     * <p>None</p>
+     */
     ACAMERA_JPEG_GPS_COORDINATES =                              // double[3]
             ACAMERA_JPEG_START,
+    /**
+     * <p>32 characters describing GPS algorithm to
+     * include in EXIF.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraCaptureSession_captureCallback_result callbacks</li>
+     *   <li>ACaptureRequest</li>
+     * </ul>
+     *
+     * <p>None</p>
+     */
     ACAMERA_JPEG_GPS_PROCESSING_METHOD =                        // byte
             ACAMERA_JPEG_START + 1,
+    /**
+     * <p>Time GPS fix was made to include in
+     * EXIF.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraCaptureSession_captureCallback_result callbacks</li>
+     *   <li>ACaptureRequest</li>
+     * </ul>
+     *
+     * <p>None</p>
+     */
     ACAMERA_JPEG_GPS_TIMESTAMP =                                // int64
             ACAMERA_JPEG_START + 2,
+    /**
+     * <p>The orientation for a JPEG image.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraCaptureSession_captureCallback_result callbacks</li>
+     *   <li>ACaptureRequest</li>
+     * </ul>
+     *
+     * <p>The clockwise rotation angle in degrees, relative to the orientation
+     * to the camera, that the JPEG picture needs to be rotated by, to be viewed
+     * upright.</p>
+     * <p>Camera devices may either encode this value into the JPEG EXIF header, or
+     * rotate the image data to match this orientation. When the image data is rotated,
+     * the thumbnail data will also be rotated.</p>
+     * <p>Note that this orientation is relative to the orientation of the camera sensor, given
+     * by ACAMERA_SENSOR_ORIENTATION.</p>
+     * <p>To translate from the device orientation given by the Android sensor APIs, the following
+     * sample code may be used:</p>
+     * <pre><code>private int getJpegOrientation(CameraCharacteristics c, int deviceOrientation) {
+     *     if (deviceOrientation == android.view.OrientationEventListener.ORIENTATION_UNKNOWN) return 0;
+     *     int sensorOrientation = c.get(CameraCharacteristics.SENSOR_ORIENTATION);
+     *
+     *     // Round device orientation to a multiple of 90
+     *     deviceOrientation = (deviceOrientation + 45) / 90 * 90;
+     *
+     *     // Reverse device orientation for front-facing cameras
+     *     boolean facingFront = c.get(CameraCharacteristics.LENS_FACING) == CameraCharacteristics.LENS_FACING_FRONT;
+     *     if (facingFront) deviceOrientation = -deviceOrientation;
+     *
+     *     // Calculate desired JPEG orientation relative to camera orientation to make
+     *     // the image upright relative to the device orientation
+     *     int jpegOrientation = (sensorOrientation + deviceOrientation + 360) % 360;
+     *
+     *     return jpegOrientation;
+     * }
+     * </code></pre>
+     *
+     * @see ACAMERA_SENSOR_ORIENTATION
+     */
     ACAMERA_JPEG_ORIENTATION =                                  // int32
             ACAMERA_JPEG_START + 3,
+    /**
+     * <p>Compression quality of the final JPEG
+     * image.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraCaptureSession_captureCallback_result callbacks</li>
+     *   <li>ACaptureRequest</li>
+     * </ul>
+     *
+     * <p>85-95 is typical usage range.</p>
+     */
     ACAMERA_JPEG_QUALITY =                                      // byte
             ACAMERA_JPEG_START + 4,
+    /**
+     * <p>Compression quality of JPEG
+     * thumbnail.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraCaptureSession_captureCallback_result callbacks</li>
+     *   <li>ACaptureRequest</li>
+     * </ul>
+     *
+     * <p>None</p>
+     */
     ACAMERA_JPEG_THUMBNAIL_QUALITY =                            // byte
             ACAMERA_JPEG_START + 5,
+    /**
+     * <p>Resolution of embedded JPEG thumbnail.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraCaptureSession_captureCallback_result callbacks</li>
+     *   <li>ACaptureRequest</li>
+     * </ul>
+     *
+     * <p>When set to (0, 0) value, the JPEG EXIF will not contain thumbnail,
+     * but the captured JPEG will still be a valid image.</p>
+     * <p>For best results, when issuing a request for a JPEG image, the thumbnail size selected
+     * should have the same aspect ratio as the main JPEG output.</p>
+     * <p>If the thumbnail image aspect ratio differs from the JPEG primary image aspect
+     * ratio, the camera device creates the thumbnail by cropping it from the primary image.
+     * For example, if the primary image has 4:3 aspect ratio, the thumbnail image has
+     * 16:9 aspect ratio, the primary image will be cropped vertically (letterbox) to
+     * generate the thumbnail image. The thumbnail image will always have a smaller Field
+     * Of View (FOV) than the primary image when aspect ratios differ.</p>
+     * <p>When an ACAMERA_JPEG_ORIENTATION of non-zero degree is requested,
+     * the camera device will handle thumbnail rotation in one of the following ways:</p>
+     * <ul>
+     * <li>Set the {@link android.media.ExifInterface#TAG_ORIENTATION EXIF orientation flag}
+     *   and keep jpeg and thumbnail image data unrotated.</li>
+     * <li>Rotate the jpeg and thumbnail image data and not set
+     *   {@link android.media.ExifInterface#TAG_ORIENTATION EXIF orientation flag}. In this
+     *   case, LIMITED or FULL hardware level devices will report rotated thumnail size in
+     *   capture result, so the width and height will be interchanged if 90 or 270 degree
+     *   orientation is requested. LEGACY device will always report unrotated thumbnail
+     *   size.</li>
+     * </ul>
+     *
+     * @see ACAMERA_JPEG_ORIENTATION
+     */
     ACAMERA_JPEG_THUMBNAIL_SIZE =                               // int32[2]
             ACAMERA_JPEG_START + 6,
+    /**
+     * <p>List of JPEG thumbnail sizes for ACAMERA_JPEG_THUMBNAIL_SIZE supported by this
+     * camera device.</p>
+     *
+     * @see ACAMERA_JPEG_THUMBNAIL_SIZE
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraManager_getCameraCharacteristics</li>
+     * </ul>
+     *
+     * <p>This list will include at least one non-zero resolution, plus <code>(0,0)</code> for indicating no
+     * thumbnail should be generated.</p>
+     * <p>Below condiditions will be satisfied for this size list:</p>
+     * <ul>
+     * <li>The sizes will be sorted by increasing pixel area (width x height).
+     * If several resolutions have the same area, they will be sorted by increasing width.</li>
+     * <li>The aspect ratio of the largest thumbnail size will be same as the
+     * aspect ratio of largest JPEG output size in ACAMERA_SCALER_AVAILABLE_STREAM_CONFIGURATIONS.
+     * The largest size is defined as the size that has the largest pixel area
+     * in a given size list.</li>
+     * <li>Each output JPEG size in ACAMERA_SCALER_AVAILABLE_STREAM_CONFIGURATIONS will have at least
+     * one corresponding size that has the same aspect ratio in availableThumbnailSizes,
+     * and vice versa.</li>
+     * <li>All non-<code>(0, 0)</code> sizes will have non-zero widths and heights.</li>
+     * </ul>
+     *
+     * @see ACAMERA_SCALER_AVAILABLE_STREAM_CONFIGURATIONS
+     */
     ACAMERA_JPEG_AVAILABLE_THUMBNAIL_SIZES =                    // int32[2*n]
             ACAMERA_JPEG_START + 7,
     ACAMERA_JPEG_END,
 
+    /**
+     * <p>The desired lens aperture size, as a ratio of lens focal length to the
+     * effective aperture diameter.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraCaptureSession_captureCallback_result callbacks</li>
+     *   <li>ACaptureRequest</li>
+     * </ul>
+     *
+     * <p>Setting this value is only supported on the camera devices that have a variable
+     * aperture lens.</p>
+     * <p>When this is supported and ACAMERA_CONTROL_AE_MODE is OFF,
+     * this can be set along with ACAMERA_SENSOR_EXPOSURE_TIME,
+     * ACAMERA_SENSOR_SENSITIVITY, and ACAMERA_SENSOR_FRAME_DURATION
+     * to achieve manual exposure control.</p>
+     * <p>The requested aperture value may take several frames to reach the
+     * requested value; the camera device will report the current (intermediate)
+     * aperture size in capture result metadata while the aperture is changing.
+     * While the aperture is still changing, ACAMERA_LENS_STATE will be set to MOVING.</p>
+     * <p>When this is supported and ACAMERA_CONTROL_AE_MODE is one of
+     * the ON modes, this will be overridden by the camera device
+     * auto-exposure algorithm, the overridden values are then provided
+     * back to the user in the corresponding result.</p>
+     *
+     * @see ACAMERA_CONTROL_AE_MODE
+     * @see ACAMERA_LENS_STATE
+     * @see ACAMERA_SENSOR_EXPOSURE_TIME
+     * @see ACAMERA_SENSOR_FRAME_DURATION
+     * @see ACAMERA_SENSOR_SENSITIVITY
+     */
     ACAMERA_LENS_APERTURE =                                     // float
             ACAMERA_LENS_START,
+    /**
+     * <p>The desired setting for the lens neutral density filter(s).</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraCaptureSession_captureCallback_result callbacks</li>
+     *   <li>ACaptureRequest</li>
+     * </ul>
+     *
+     * <p>This control will not be supported on most camera devices.</p>
+     * <p>Lens filters are typically used to lower the amount of light the
+     * sensor is exposed to (measured in steps of EV). As used here, an EV
+     * step is the standard logarithmic representation, which are
+     * non-negative, and inversely proportional to the amount of light
+     * hitting the sensor.  For example, setting this to 0 would result
+     * in no reduction of the incoming light, and setting this to 2 would
+     * mean that the filter is set to reduce incoming light by two stops
+     * (allowing 1/4 of the prior amount of light to the sensor).</p>
+     * <p>It may take several frames before the lens filter density changes
+     * to the requested value. While the filter density is still changing,
+     * ACAMERA_LENS_STATE will be set to MOVING.</p>
+     *
+     * @see ACAMERA_LENS_STATE
+     */
     ACAMERA_LENS_FILTER_DENSITY =                               // float
             ACAMERA_LENS_START + 1,
+    /**
+     * <p>The desired lens focal length; used for optical zoom.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraCaptureSession_captureCallback_result callbacks</li>
+     *   <li>ACaptureRequest</li>
+     * </ul>
+     *
+     * <p>This setting controls the physical focal length of the camera
+     * device's lens. Changing the focal length changes the field of
+     * view of the camera device, and is usually used for optical zoom.</p>
+     * <p>Like ACAMERA_LENS_FOCUS_DISTANCE and ACAMERA_LENS_APERTURE, this
+     * setting won't be applied instantaneously, and it may take several
+     * frames before the lens can change to the requested focal length.
+     * While the focal length is still changing, ACAMERA_LENS_STATE will
+     * be set to MOVING.</p>
+     * <p>Optical zoom will not be supported on most devices.</p>
+     *
+     * @see ACAMERA_LENS_APERTURE
+     * @see ACAMERA_LENS_FOCUS_DISTANCE
+     * @see ACAMERA_LENS_STATE
+     */
     ACAMERA_LENS_FOCAL_LENGTH =                                 // float
             ACAMERA_LENS_START + 2,
+    /**
+     * <p>Desired distance to plane of sharpest focus,
+     * measured from frontmost surface of the lens.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraCaptureSession_captureCallback_result callbacks</li>
+     *   <li>ACaptureRequest</li>
+     * </ul>
+     *
+     * <p>Should be zero for fixed-focus cameras</p>
+     */
     ACAMERA_LENS_FOCUS_DISTANCE =                               // float
             ACAMERA_LENS_START + 3,
+    /**
+     * <p>Sets whether the camera device uses optical image stabilization (OIS)
+     * when capturing images.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraCaptureSession_captureCallback_result callbacks</li>
+     *   <li>ACaptureRequest</li>
+     * </ul>
+     *
+     * <p>OIS is used to compensate for motion blur due to small
+     * movements of the camera during capture. Unlike digital image
+     * stabilization (ACAMERA_CONTROL_VIDEO_STABILIZATION_MODE), OIS
+     * makes use of mechanical elements to stabilize the camera
+     * sensor, and thus allows for longer exposure times before
+     * camera shake becomes apparent.</p>
+     * <p>Switching between different optical stabilization modes may take several
+     * frames to initialize, the camera device will report the current mode in
+     * capture result metadata. For example, When "ON" mode is requested, the
+     * optical stabilization modes in the first several capture results may still
+     * be "OFF", and it will become "ON" when the initialization is done.</p>
+     * <p>If a camera device supports both OIS and digital image stabilization
+     * (ACAMERA_CONTROL_VIDEO_STABILIZATION_MODE), turning both modes on may produce undesirable
+     * interaction, so it is recommended not to enable both at the same time.</p>
+     * <p>Not all devices will support OIS; see
+     * ACAMERA_LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION for
+     * available controls.</p>
+     *
+     * @see ACAMERA_CONTROL_VIDEO_STABILIZATION_MODE
+     * @see ACAMERA_LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION
+     */
     ACAMERA_LENS_OPTICAL_STABILIZATION_MODE =                   // byte (enum)
             ACAMERA_LENS_START + 4,
+    /**
+     * <p>Direction the camera faces relative to
+     * device screen.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraManager_getCameraCharacteristics</li>
+     * </ul>
+     *
+     * <p>None</p>
+     */
     ACAMERA_LENS_FACING =                                       // byte (enum)
             ACAMERA_LENS_START + 5,
+    /**
+     * <p>The orientation of the camera relative to the sensor
+     * coordinate system.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraManager_getCameraCharacteristics</li>
+     *   <li>ACameraMetadata from ACameraCaptureSession_captureCallback_result callbacks</li>
+     * </ul>
+     *
+     * <p>The four coefficients that describe the quaternion
+     * rotation from the Android sensor coordinate system to a
+     * camera-aligned coordinate system where the X-axis is
+     * aligned with the long side of the image sensor, the Y-axis
+     * is aligned with the short side of the image sensor, and
+     * the Z-axis is aligned with the optical axis of the sensor.</p>
+     * <p>To convert from the quaternion coefficients <code>(x,y,z,w)</code>
+     * to the axis of rotation <code>(a_x, a_y, a_z)</code> and rotation
+     * amount <code>theta</code>, the following formulas can be used:</p>
+     * <pre><code> theta = 2 * acos(w)
+     * a_x = x / sin(theta/2)
+     * a_y = y / sin(theta/2)
+     * a_z = z / sin(theta/2)
+     * </code></pre>
+     * <p>To create a 3x3 rotation matrix that applies the rotation
+     * defined by this quaternion, the following matrix can be
+     * used:</p>
+     * <pre><code>R = [ 1 - 2y^2 - 2z^2,       2xy - 2zw,       2xz + 2yw,
+     *            2xy + 2zw, 1 - 2x^2 - 2z^2,       2yz - 2xw,
+     *            2xz - 2yw,       2yz + 2xw, 1 - 2x^2 - 2y^2 ]
+     * </code></pre>
+     * <p>This matrix can then be used to apply the rotation to a
+     *  column vector point with</p>
+     * <p><code>p' = Rp</code></p>
+     * <p>where <code>p</code> is in the device sensor coordinate system, and
+     *  <code>p'</code> is in the camera-oriented coordinate system.</p>
+     */
     ACAMERA_LENS_POSE_ROTATION =                                // float[4]
             ACAMERA_LENS_START + 6,
+    /**
+     * <p>Position of the camera optical center.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraManager_getCameraCharacteristics</li>
+     *   <li>ACameraMetadata from ACameraCaptureSession_captureCallback_result callbacks</li>
+     * </ul>
+     *
+     * <p>The position of the camera device's lens optical center,
+     * as a three-dimensional vector <code>(x,y,z)</code>, relative to the
+     * optical center of the largest camera device facing in the
+     * same direction as this camera, in the {@link
+     * android.hardware.SensorEvent Android sensor coordinate
+     * axes}. Note that only the axis definitions are shared with
+     * the sensor coordinate system, but not the origin.</p>
+     * <p>If this device is the largest or only camera device with a
+     * given facing, then this position will be <code>(0, 0, 0)</code>; a
+     * camera device with a lens optical center located 3 cm from
+     * the main sensor along the +X axis (to the right from the
+     * user's perspective) will report <code>(0.03, 0, 0)</code>.</p>
+     * <p>To transform a pixel coordinates between two cameras
+     * facing the same direction, first the source camera
+     * ACAMERA_LENS_RADIAL_DISTORTION must be corrected for.  Then
+     * the source camera ACAMERA_LENS_INTRINSIC_CALIBRATION needs
+     * to be applied, followed by the ACAMERA_LENS_POSE_ROTATION
+     * of the source camera, the translation of the source camera
+     * relative to the destination camera, the
+     * ACAMERA_LENS_POSE_ROTATION of the destination camera, and
+     * finally the inverse of ACAMERA_LENS_INTRINSIC_CALIBRATION
+     * of the destination camera. This obtains a
+     * radial-distortion-free coordinate in the destination
+     * camera pixel coordinates.</p>
+     * <p>To compare this against a real image from the destination
+     * camera, the destination camera image then needs to be
+     * corrected for radial distortion before comparison or
+     * sampling.</p>
+     *
+     * @see ACAMERA_LENS_INTRINSIC_CALIBRATION
+     * @see ACAMERA_LENS_POSE_ROTATION
+     * @see ACAMERA_LENS_RADIAL_DISTORTION
+     */
     ACAMERA_LENS_POSE_TRANSLATION =                             // float[3]
             ACAMERA_LENS_START + 7,
+    /**
+     * <p>The range of scene distances that are in
+     * sharp focus (depth of field).</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraCaptureSession_captureCallback_result callbacks</li>
+     * </ul>
+     *
+     * <p>If variable focus not supported, can still report
+     * fixed depth of field range</p>
+     */
     ACAMERA_LENS_FOCUS_RANGE =                                  // float[2]
             ACAMERA_LENS_START + 8,
+    /**
+     * <p>Current lens status.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraCaptureSession_captureCallback_result callbacks</li>
+     * </ul>
+     *
+     * <p>For lens parameters ACAMERA_LENS_FOCAL_LENGTH, ACAMERA_LENS_FOCUS_DISTANCE,
+     * ACAMERA_LENS_FILTER_DENSITY and ACAMERA_LENS_APERTURE, when changes are requested,
+     * they may take several frames to reach the requested values. This state indicates
+     * the current status of the lens parameters.</p>
+     * <p>When the state is STATIONARY, the lens parameters are not changing. This could be
+     * either because the parameters are all fixed, or because the lens has had enough
+     * time to reach the most recently-requested values.
+     * If all these lens parameters are not changable for a camera device, as listed below:</p>
+     * <ul>
+     * <li>Fixed focus (<code>ACAMERA_LENS_INFO_MINIMUM_FOCUS_DISTANCE == 0</code>), which means
+     * ACAMERA_LENS_FOCUS_DISTANCE parameter will always be 0.</li>
+     * <li>Fixed focal length (ACAMERA_LENS_INFO_AVAILABLE_FOCAL_LENGTHS contains single value),
+     * which means the optical zoom is not supported.</li>
+     * <li>No ND filter (ACAMERA_LENS_INFO_AVAILABLE_FILTER_DENSITIES contains only 0).</li>
+     * <li>Fixed aperture (ACAMERA_LENS_INFO_AVAILABLE_APERTURES contains single value).</li>
+     * </ul>
+     * <p>Then this state will always be STATIONARY.</p>
+     * <p>When the state is MOVING, it indicates that at least one of the lens parameters
+     * is changing.</p>
+     *
+     * @see ACAMERA_LENS_APERTURE
+     * @see ACAMERA_LENS_FILTER_DENSITY
+     * @see ACAMERA_LENS_FOCAL_LENGTH
+     * @see ACAMERA_LENS_FOCUS_DISTANCE
+     * @see ACAMERA_LENS_INFO_AVAILABLE_APERTURES
+     * @see ACAMERA_LENS_INFO_AVAILABLE_FILTER_DENSITIES
+     * @see ACAMERA_LENS_INFO_AVAILABLE_FOCAL_LENGTHS
+     * @see ACAMERA_LENS_INFO_MINIMUM_FOCUS_DISTANCE
+     */
     ACAMERA_LENS_STATE =                                        // byte (enum)
             ACAMERA_LENS_START + 9,
+    /**
+     * <p>The parameters for this camera device's intrinsic
+     * calibration.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraManager_getCameraCharacteristics</li>
+     *   <li>ACameraMetadata from ACameraCaptureSession_captureCallback_result callbacks</li>
+     * </ul>
+     *
+     * <p>The five calibration parameters that describe the
+     * transform from camera-centric 3D coordinates to sensor
+     * pixel coordinates:</p>
+     * <pre><code>[f_x, f_y, c_x, c_y, s]
+     * </code></pre>
+     * <p>Where <code>f_x</code> and <code>f_y</code> are the horizontal and vertical
+     * focal lengths, <code>[c_x, c_y]</code> is the position of the optical
+     * axis, and <code>s</code> is a skew parameter for the sensor plane not
+     * being aligned with the lens plane.</p>
+     * <p>These are typically used within a transformation matrix K:</p>
+     * <pre><code>K = [ f_x,   s, c_x,
+     *        0, f_y, c_y,
+     *        0    0,   1 ]
+     * </code></pre>
+     * <p>which can then be combined with the camera pose rotation
+     * <code>R</code> and translation <code>t</code> (ACAMERA_LENS_POSE_ROTATION and
+     * ACAMERA_LENS_POSE_TRANSLATION, respective) to calculate the
+     * complete transform from world coordinates to pixel
+     * coordinates:</p>
+     * <pre><code>P = [ K 0   * [ R t
+     *      0 1 ]     0 1 ]
+     * </code></pre>
+     * <p>and with <code>p_w</code> being a point in the world coordinate system
+     * and <code>p_s</code> being a point in the camera active pixel array
+     * coordinate system, and with the mapping including the
+     * homogeneous division by z:</p>
+     * <pre><code> p_h = (x_h, y_h, z_h) = P p_w
+     * p_s = p_h / z_h
+     * </code></pre>
+     * <p>so <code>[x_s, y_s]</code> is the pixel coordinates of the world
+     * point, <code>z_s = 1</code>, and <code>w_s</code> is a measurement of disparity
+     * (depth) in pixel coordinates.</p>
+     * <p>Note that the coordinate system for this transform is the
+     * ACAMERA_SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE system,
+     * where <code>(0,0)</code> is the top-left of the
+     * preCorrectionActiveArraySize rectangle. Once the pose and
+     * intrinsic calibration transforms have been applied to a
+     * world point, then the ACAMERA_LENS_RADIAL_DISTORTION
+     * transform needs to be applied, and the result adjusted to
+     * be in the ACAMERA_SENSOR_INFO_ACTIVE_ARRAY_SIZE coordinate
+     * system (where <code>(0, 0)</code> is the top-left of the
+     * activeArraySize rectangle), to determine the final pixel
+     * coordinate of the world point for processed (non-RAW)
+     * output buffers.</p>
+     *
+     * @see ACAMERA_LENS_POSE_ROTATION
+     * @see ACAMERA_LENS_POSE_TRANSLATION
+     * @see ACAMERA_LENS_RADIAL_DISTORTION
+     * @see ACAMERA_SENSOR_INFO_ACTIVE_ARRAY_SIZE
+     * @see ACAMERA_SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE
+     */
     ACAMERA_LENS_INTRINSIC_CALIBRATION =                        // float[5]
             ACAMERA_LENS_START + 10,
+    /**
+     * <p>The correction coefficients to correct for this camera device's
+     * radial and tangential lens distortion.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraManager_getCameraCharacteristics</li>
+     *   <li>ACameraMetadata from ACameraCaptureSession_captureCallback_result callbacks</li>
+     * </ul>
+     *
+     * <p>Four radial distortion coefficients <code>[kappa_0, kappa_1, kappa_2,
+     * kappa_3]</code> and two tangential distortion coefficients
+     * <code>[kappa_4, kappa_5]</code> that can be used to correct the
+     * lens's geometric distortion with the mapping equations:</p>
+     * <pre><code> x_c = x_i * ( kappa_0 + kappa_1 * r^2 + kappa_2 * r^4 + kappa_3 * r^6 ) +
+     *        kappa_4 * (2 * x_i * y_i) + kappa_5 * ( r^2 + 2 * x_i^2 )
+     *  y_c = y_i * ( kappa_0 + kappa_1 * r^2 + kappa_2 * r^4 + kappa_3 * r^6 ) +
+     *        kappa_5 * (2 * x_i * y_i) + kappa_4 * ( r^2 + 2 * y_i^2 )
+     * </code></pre>
+     * <p>Here, <code>[x_c, y_c]</code> are the coordinates to sample in the
+     * input image that correspond to the pixel values in the
+     * corrected image at the coordinate <code>[x_i, y_i]</code>:</p>
+     * <pre><code> correctedImage(x_i, y_i) = sample_at(x_c, y_c, inputImage)
+     * </code></pre>
+     * <p>The pixel coordinates are defined in a normalized
+     * coordinate system related to the
+     * ACAMERA_LENS_INTRINSIC_CALIBRATION calibration fields.
+     * Both <code>[x_i, y_i]</code> and <code>[x_c, y_c]</code> have <code>(0,0)</code> at the
+     * lens optical center <code>[c_x, c_y]</code>. The maximum magnitudes
+     * of both x and y coordinates are normalized to be 1 at the
+     * edge further from the optical center, so the range
+     * for both dimensions is <code>-1 &lt;= x &lt;= 1</code>.</p>
+     * <p>Finally, <code>r</code> represents the radial distance from the
+     * optical center, <code>r^2 = x_i^2 + y_i^2</code>, and its magnitude
+     * is therefore no larger than <code>|r| &lt;= sqrt(2)</code>.</p>
+     * <p>The distortion model used is the Brown-Conrady model.</p>
+     *
+     * @see ACAMERA_LENS_INTRINSIC_CALIBRATION
+     */
     ACAMERA_LENS_RADIAL_DISTORTION =                            // float[6]
             ACAMERA_LENS_START + 11,
     ACAMERA_LENS_END,
 
+    /**
+     * <p>List of aperture size values for ACAMERA_LENS_APERTURE that are
+     * supported by this camera device.</p>
+     *
+     * @see ACAMERA_LENS_APERTURE
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraManager_getCameraCharacteristics</li>
+     * </ul>
+     *
+     * <p>If the camera device doesn't support a variable lens aperture,
+     * this list will contain only one value, which is the fixed aperture size.</p>
+     * <p>If the camera device supports a variable aperture, the aperture values
+     * in this list will be sorted in ascending order.</p>
+     */
     ACAMERA_LENS_INFO_AVAILABLE_APERTURES =                     // float[n]
             ACAMERA_LENS_INFO_START,
+    /**
+     * <p>List of neutral density filter values for
+     * ACAMERA_LENS_FILTER_DENSITY that are supported by this camera device.</p>
+     *
+     * @see ACAMERA_LENS_FILTER_DENSITY
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraManager_getCameraCharacteristics</li>
+     * </ul>
+     *
+     * <p>If a neutral density filter is not supported by this camera device,
+     * this list will contain only 0. Otherwise, this list will include every
+     * filter density supported by the camera device, in ascending order.</p>
+     */
     ACAMERA_LENS_INFO_AVAILABLE_FILTER_DENSITIES =              // float[n]
             ACAMERA_LENS_INFO_START + 1,
+    /**
+     * <p>List of focal lengths for ACAMERA_LENS_FOCAL_LENGTH that are supported by this camera
+     * device.</p>
+     *
+     * @see ACAMERA_LENS_FOCAL_LENGTH
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraManager_getCameraCharacteristics</li>
+     * </ul>
+     *
+     * <p>If optical zoom is not supported, this list will only contain
+     * a single value corresponding to the fixed focal length of the
+     * device. Otherwise, this list will include every focal length supported
+     * by the camera device, in ascending order.</p>
+     */
     ACAMERA_LENS_INFO_AVAILABLE_FOCAL_LENGTHS =                 // float[n]
             ACAMERA_LENS_INFO_START + 2,
+    /**
+     * <p>List of optical image stabilization (OIS) modes for
+     * ACAMERA_LENS_OPTICAL_STABILIZATION_MODE that are supported by this camera device.</p>
+     *
+     * @see ACAMERA_LENS_OPTICAL_STABILIZATION_MODE
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraManager_getCameraCharacteristics</li>
+     * </ul>
+     *
+     * <p>If OIS is not supported by a given camera device, this list will
+     * contain only OFF.</p>
+     */
     ACAMERA_LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION =         // byte[n]
             ACAMERA_LENS_INFO_START + 3,
+    /**
+     * <p>Hyperfocal distance for this lens.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraManager_getCameraCharacteristics</li>
+     * </ul>
+     *
+     * <p>If the lens is not fixed focus, the camera device will report this
+     * field when ACAMERA_LENS_INFO_FOCUS_DISTANCE_CALIBRATION is APPROXIMATE or CALIBRATED.</p>
+     *
+     * @see ACAMERA_LENS_INFO_FOCUS_DISTANCE_CALIBRATION
+     */
     ACAMERA_LENS_INFO_HYPERFOCAL_DISTANCE =                     // float
             ACAMERA_LENS_INFO_START + 4,
+    /**
+     * <p>Shortest distance from frontmost surface
+     * of the lens that can be brought into sharp focus.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraManager_getCameraCharacteristics</li>
+     * </ul>
+     *
+     * <p>If the lens is fixed-focus, this will be
+     * 0.</p>
+     */
     ACAMERA_LENS_INFO_MINIMUM_FOCUS_DISTANCE =                  // float
             ACAMERA_LENS_INFO_START + 5,
+    /**
+     * <p>Dimensions of lens shading map.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraManager_getCameraCharacteristics</li>
+     * </ul>
+     *
+     * <p>The map should be on the order of 30-40 rows and columns, and
+     * must be smaller than 64x64.</p>
+     */
     ACAMERA_LENS_INFO_SHADING_MAP_SIZE =                        // int32[2]
             ACAMERA_LENS_INFO_START + 6,
+    /**
+     * <p>The lens focus distance calibration quality.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraManager_getCameraCharacteristics</li>
+     * </ul>
+     *
+     * <p>The lens focus distance calibration quality determines the reliability of
+     * focus related metadata entries, i.e. ACAMERA_LENS_FOCUS_DISTANCE,
+     * ACAMERA_LENS_FOCUS_RANGE, ACAMERA_LENS_INFO_HYPERFOCAL_DISTANCE, and
+     * ACAMERA_LENS_INFO_MINIMUM_FOCUS_DISTANCE.</p>
+     * <p>APPROXIMATE and CALIBRATED devices report the focus metadata in
+     * units of diopters (1/meter), so <code>0.0f</code> represents focusing at infinity,
+     * and increasing positive numbers represent focusing closer and closer
+     * to the camera device. The focus distance control also uses diopters
+     * on these devices.</p>
+     * <p>UNCALIBRATED devices do not use units that are directly comparable
+     * to any real physical measurement, but <code>0.0f</code> still represents farthest
+     * focus, and ACAMERA_LENS_INFO_MINIMUM_FOCUS_DISTANCE represents the
+     * nearest focus the device can achieve.</p>
+     *
+     * @see ACAMERA_LENS_FOCUS_DISTANCE
+     * @see ACAMERA_LENS_FOCUS_RANGE
+     * @see ACAMERA_LENS_INFO_HYPERFOCAL_DISTANCE
+     * @see ACAMERA_LENS_INFO_MINIMUM_FOCUS_DISTANCE
+     */
     ACAMERA_LENS_INFO_FOCUS_DISTANCE_CALIBRATION =              // byte (enum)
             ACAMERA_LENS_INFO_START + 7,
     ACAMERA_LENS_INFO_END,
 
+    /**
+     * <p>Mode of operation for the noise reduction algorithm.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraCaptureSession_captureCallback_result callbacks</li>
+     *   <li>ACaptureRequest</li>
+     * </ul>
+     *
+     * <p>The noise reduction algorithm attempts to improve image quality by removing
+     * excessive noise added by the capture process, especially in dark conditions.</p>
+     * <p>OFF means no noise reduction will be applied by the camera device, for both raw and
+     * YUV domain.</p>
+     * <p>MINIMAL means that only sensor raw domain basic noise reduction is enabled ,to remove
+     * demosaicing or other processing artifacts. For YUV_REPROCESSING, MINIMAL is same as OFF.
+     * This mode is optional, may not be support by all devices. The application should check
+     * ACAMERA_NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES before using it.</p>
+     * <p>FAST/HIGH_QUALITY both mean camera device determined noise filtering
+     * will be applied. HIGH_QUALITY mode indicates that the camera device
+     * will use the highest-quality noise filtering algorithms,
+     * even if it slows down capture rate. FAST means the camera device will not
+     * slow down capture rate when applying noise filtering. FAST may be the same as MINIMAL if
+     * MINIMAL is listed, or the same as OFF if any noise filtering will slow down capture rate.
+     * Every output stream will have a similar amount of enhancement applied.</p>
+     * <p>ZERO_SHUTTER_LAG is meant to be used by applications that maintain a continuous circular
+     * buffer of high-resolution images during preview and reprocess image(s) from that buffer
+     * into a final capture when triggered by the user. In this mode, the camera device applies
+     * noise reduction to low-resolution streams (below maximum recording resolution) to maximize
+     * preview quality, but does not apply noise reduction to high-resolution streams, since
+     * those will be reprocessed later if necessary.</p>
+     * <p>For YUV_REPROCESSING, these FAST/HIGH_QUALITY modes both mean that the camera device
+     * will apply FAST/HIGH_QUALITY YUV domain noise reduction, respectively. The camera device
+     * may adjust the noise reduction parameters for best image quality based on the
+     * android.reprocess.effectiveExposureFactor if it is set.</p>
+     *
+     * @see ACAMERA_NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES
+     */
     ACAMERA_NOISE_REDUCTION_MODE =                              // byte (enum)
             ACAMERA_NOISE_REDUCTION_START,
+    /**
+     * <p>List of noise reduction modes for ACAMERA_NOISE_REDUCTION_MODE that are supported
+     * by this camera device.</p>
+     *
+     * @see ACAMERA_NOISE_REDUCTION_MODE
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraManager_getCameraCharacteristics</li>
+     * </ul>
+     *
+     * <p>Full-capability camera devices will always support OFF and FAST.</p>
+     * <p>Camera devices that support YUV_REPROCESSING or PRIVATE_REPROCESSING will support
+     * ZERO_SHUTTER_LAG.</p>
+     * <p>Legacy-capability camera devices will only support FAST mode.</p>
+     */
     ACAMERA_NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES =   // byte[n]
             ACAMERA_NOISE_REDUCTION_START + 2,
     ACAMERA_NOISE_REDUCTION_END,
 
+    /**
+     * <p>The maximum numbers of different types of output streams
+     * that can be configured and used simultaneously by a camera device.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraManager_getCameraCharacteristics</li>
+     * </ul>
+     *
+     * <p>This is a 3 element tuple that contains the max number of output simultaneous
+     * streams for raw sensor, processed (but not stalling), and processed (and stalling)
+     * formats respectively. For example, assuming that JPEG is typically a processed and
+     * stalling stream, if max raw sensor format output stream number is 1, max YUV streams
+     * number is 3, and max JPEG stream number is 2, then this tuple should be <code>(1, 3, 2)</code>.</p>
+     * <p>This lists the upper bound of the number of output streams supported by
+     * the camera device. Using more streams simultaneously may require more hardware and
+     * CPU resources that will consume more power. The image format for an output stream can
+     * be any supported format provided by ACAMERA_SCALER_AVAILABLE_STREAM_CONFIGURATIONS.
+     * The formats defined in ACAMERA_SCALER_AVAILABLE_STREAM_CONFIGURATIONS can be catergorized
+     * into the 3 stream types as below:</p>
+     * <ul>
+     * <li>Processed (but stalling): any non-RAW format with a stallDurations &gt; 0.
+     *   Typically {@link android.graphics.ImageFormat#JPEG JPEG format}.</li>
+     * <li>Raw formats: {@link android.graphics.ImageFormat#RAW_SENSOR RAW_SENSOR}, {@link
+     *   android.graphics.ImageFormat#RAW10 RAW10}, or {@link android.graphics.ImageFormat#RAW12
+     *   RAW12}.</li>
+     * <li>Processed (but not-stalling): any non-RAW format without a stall duration.
+     *   Typically {@link android.graphics.ImageFormat#YUV_420_888 YUV_420_888},
+     *   {@link android.graphics.ImageFormat#NV21 NV21}, or
+     *   {@link android.graphics.ImageFormat#YV12 YV12}.</li>
+     * </ul>
+     *
+     * @see ACAMERA_SCALER_AVAILABLE_STREAM_CONFIGURATIONS
+     */
     ACAMERA_REQUEST_MAX_NUM_OUTPUT_STREAMS =                    // int32[3]
             ACAMERA_REQUEST_START + 6,
+    /**
+     * <p>The maximum numbers of any type of input streams
+     * that can be configured and used simultaneously by a camera device.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraManager_getCameraCharacteristics</li>
+     * </ul>
+     *
+     * <p>When set to 0, it means no input stream is supported.</p>
+     * <p>The image format for a input stream can be any supported format returned by {@link
+     * android.hardware.camera2.params.StreamConfigurationMap#getInputFormats}. When using an
+     * input stream, there must be at least one output stream configured to to receive the
+     * reprocessed images.</p>
+     * <p>When an input stream and some output streams are used in a reprocessing request,
+     * only the input buffer will be used to produce these output stream buffers, and a
+     * new sensor image will not be captured.</p>
+     * <p>For example, for Zero Shutter Lag (ZSL) still capture use case, the input
+     * stream image format will be PRIVATE, the associated output stream image format
+     * should be JPEG.</p>
+     */
     ACAMERA_REQUEST_MAX_NUM_INPUT_STREAMS =                     // int32
             ACAMERA_REQUEST_START + 8,
+    /**
+     * <p>Specifies the number of pipeline stages the frame went
+     * through from when it was exposed to when the final completed result
+     * was available to the framework.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraCaptureSession_captureCallback_result callbacks</li>
+     * </ul>
+     *
+     * <p>Depending on what settings are used in the request, and
+     * what streams are configured, the data may undergo less processing,
+     * and some pipeline stages skipped.</p>
+     * <p>See ACAMERA_REQUEST_PIPELINE_MAX_DEPTH for more details.</p>
+     *
+     * @see ACAMERA_REQUEST_PIPELINE_MAX_DEPTH
+     */
     ACAMERA_REQUEST_PIPELINE_DEPTH =                            // byte
             ACAMERA_REQUEST_START + 9,
+    /**
+     * <p>Specifies the number of maximum pipeline stages a frame
+     * has to go through from when it's exposed to when it's available
+     * to the framework.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraManager_getCameraCharacteristics</li>
+     * </ul>
+     *
+     * <p>A typical minimum value for this is 2 (one stage to expose,
+     * one stage to readout) from the sensor. The ISP then usually adds
+     * its own stages to do custom HW processing. Further stages may be
+     * added by SW processing.</p>
+     * <p>Depending on what settings are used (e.g. YUV, JPEG) and what
+     * processing is enabled (e.g. face detection), the actual pipeline
+     * depth (specified by ACAMERA_REQUEST_PIPELINE_DEPTH) may be less than
+     * the max pipeline depth.</p>
+     * <p>A pipeline depth of X stages is equivalent to a pipeline latency of
+     * X frame intervals.</p>
+     * <p>This value will normally be 8 or less, however, for high speed capture session,
+     * the max pipeline depth will be up to 8 x size of high speed capture request list.</p>
+     *
+     * @see ACAMERA_REQUEST_PIPELINE_DEPTH
+     */
     ACAMERA_REQUEST_PIPELINE_MAX_DEPTH =                        // byte
             ACAMERA_REQUEST_START + 10,
+    /**
+     * <p>Defines how many sub-components
+     * a result will be composed of.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraManager_getCameraCharacteristics</li>
+     * </ul>
+     *
+     * <p>In order to combat the pipeline latency, partial results
+     * may be delivered to the application layer from the camera device as
+     * soon as they are available.</p>
+     * <p>Optional; defaults to 1. A value of 1 means that partial
+     * results are not supported, and only the final TotalCaptureResult will
+     * be produced by the camera device.</p>
+     * <p>A typical use case for this might be: after requesting an
+     * auto-focus (AF) lock the new AF state might be available 50%
+     * of the way through the pipeline.  The camera device could
+     * then immediately dispatch this state via a partial result to
+     * the application, and the rest of the metadata via later
+     * partial results.</p>
+     */
     ACAMERA_REQUEST_PARTIAL_RESULT_COUNT =                      // int32
             ACAMERA_REQUEST_START + 11,
+    /**
+     * <p>List of capabilities that this camera device
+     * advertises as fully supporting.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraManager_getCameraCharacteristics</li>
+     * </ul>
+     *
+     * <p>A capability is a contract that the camera device makes in order
+     * to be able to satisfy one or more use cases.</p>
+     * <p>Listing a capability guarantees that the whole set of features
+     * required to support a common use will all be available.</p>
+     * <p>Using a subset of the functionality provided by an unsupported
+     * capability may be possible on a specific camera device implementation;
+     * to do this query each of ACAMERA_REQUEST_AVAILABLE_REQUEST_KEYS,
+     * ACAMERA_REQUEST_AVAILABLE_RESULT_KEYS,
+     * ACAMERA_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS.</p>
+     * <p>The following capabilities are guaranteed to be available on
+     * ACAMERA_INFO_SUPPORTED_HARDWARE_LEVEL <code>==</code> FULL devices:</p>
+     * <ul>
+     * <li>MANUAL_SENSOR</li>
+     * <li>MANUAL_POST_PROCESSING</li>
+     * </ul>
+     * <p>Other capabilities may be available on either FULL or LIMITED
+     * devices, but the application should query this key to be sure.</p>
+     *
+     * @see ACAMERA_INFO_SUPPORTED_HARDWARE_LEVEL
+     * @see ACAMERA_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS
+     * @see ACAMERA_REQUEST_AVAILABLE_REQUEST_KEYS
+     * @see ACAMERA_REQUEST_AVAILABLE_RESULT_KEYS
+     */
     ACAMERA_REQUEST_AVAILABLE_CAPABILITIES =                    // byte[n] (enum)
             ACAMERA_REQUEST_START + 12,
+    /**
+     * <p>A list of all keys that the camera device has available
+     * to use with {@link android.hardware.camera2.CaptureRequest}.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraManager_getCameraCharacteristics</li>
+     * </ul>
+     *
+     * <p>Attempting to set a key into a CaptureRequest that is not
+     * listed here will result in an invalid request and will be rejected
+     * by the camera device.</p>
+     * <p>This field can be used to query the feature set of a camera device
+     * at a more granular level than capabilities. This is especially
+     * important for optional keys that are not listed under any capability
+     * in ACAMERA_REQUEST_AVAILABLE_CAPABILITIES.</p>
+     *
+     * @see ACAMERA_REQUEST_AVAILABLE_CAPABILITIES
+     */
     ACAMERA_REQUEST_AVAILABLE_REQUEST_KEYS =                    // int32[n]
             ACAMERA_REQUEST_START + 13,
+    /**
+     * <p>A list of all keys that the camera device has available
+     * to use with {@link android.hardware.camera2.CaptureResult}.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraManager_getCameraCharacteristics</li>
+     * </ul>
+     *
+     * <p>Attempting to get a key from a CaptureResult that is not
+     * listed here will always return a <code>null</code> value. Getting a key from
+     * a CaptureResult that is listed here will generally never return a <code>null</code>
+     * value.</p>
+     * <p>The following keys may return <code>null</code> unless they are enabled:</p>
+     * <ul>
+     * <li>ACAMERA_STATISTICS_LENS_SHADING_MAP (non-null iff ACAMERA_STATISTICS_LENS_SHADING_MAP_MODE == ON)</li>
+     * </ul>
+     * <p>(Those sometimes-null keys will nevertheless be listed here
+     * if they are available.)</p>
+     * <p>This field can be used to query the feature set of a camera device
+     * at a more granular level than capabilities. This is especially
+     * important for optional keys that are not listed under any capability
+     * in ACAMERA_REQUEST_AVAILABLE_CAPABILITIES.</p>
+     *
+     * @see ACAMERA_REQUEST_AVAILABLE_CAPABILITIES
+     * @see ACAMERA_STATISTICS_LENS_SHADING_MAP
+     * @see ACAMERA_STATISTICS_LENS_SHADING_MAP_MODE
+     */
     ACAMERA_REQUEST_AVAILABLE_RESULT_KEYS =                     // int32[n]
             ACAMERA_REQUEST_START + 14,
+    /**
+     * <p>A list of all keys that the camera device has available
+     * to use with {@link android.hardware.camera2.CameraCharacteristics}.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraManager_getCameraCharacteristics</li>
+     * </ul>
+     *
+     * <p>This entry follows the same rules as
+     * ACAMERA_REQUEST_AVAILABLE_RESULT_KEYS (except that it applies for
+     * CameraCharacteristics instead of CaptureResult). See above for more
+     * details.</p>
+     *
+     * @see ACAMERA_REQUEST_AVAILABLE_RESULT_KEYS
+     */
     ACAMERA_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS =            // int32[n]
             ACAMERA_REQUEST_START + 15,
     ACAMERA_REQUEST_END,
 
+    /**
+     * <p>The desired region of the sensor to read out for this capture.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraCaptureSession_captureCallback_result callbacks</li>
+     *   <li>ACaptureRequest</li>
+     * </ul>
+     *
+     * <p>This control can be used to implement digital zoom.</p>
+     * <p>The crop region coordinate system is based off
+     * ACAMERA_SENSOR_INFO_ACTIVE_ARRAY_SIZE, with <code>(0, 0)</code> being the
+     * top-left corner of the sensor active array.</p>
+     * <p>Output streams use this rectangle to produce their output,
+     * cropping to a smaller region if necessary to maintain the
+     * stream's aspect ratio, then scaling the sensor input to
+     * match the output's configured resolution.</p>
+     * <p>The crop region is applied after the RAW to other color
+     * space (e.g. YUV) conversion. Since raw streams
+     * (e.g. RAW16) don't have the conversion stage, they are not
+     * croppable. The crop region will be ignored by raw streams.</p>
+     * <p>For non-raw streams, any additional per-stream cropping will
+     * be done to maximize the final pixel area of the stream.</p>
+     * <p>For example, if the crop region is set to a 4:3 aspect
+     * ratio, then 4:3 streams will use the exact crop
+     * region. 16:9 streams will further crop vertically
+     * (letterbox).</p>
+     * <p>Conversely, if the crop region is set to a 16:9, then 4:3
+     * outputs will crop horizontally (pillarbox), and 16:9
+     * streams will match exactly. These additional crops will
+     * be centered within the crop region.</p>
+     * <p>The width and height of the crop region cannot
+     * be set to be smaller than
+     * <code>floor( activeArraySize.width / ACAMERA_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM )</code> and
+     * <code>floor( activeArraySize.height / ACAMERA_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM )</code>, respectively.</p>
+     * <p>The camera device may adjust the crop region to account
+     * for rounding and other hardware requirements; the final
+     * crop region used will be included in the output capture
+     * result.</p>
+     *
+     * @see ACAMERA_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM
+     * @see ACAMERA_SENSOR_INFO_ACTIVE_ARRAY_SIZE
+     */
     ACAMERA_SCALER_CROP_REGION =                                // int32[4]
             ACAMERA_SCALER_START,
+    /**
+     * <p>The maximum ratio between both active area width
+     * and crop region width, and active area height and
+     * crop region height, for ACAMERA_SCALER_CROP_REGION.</p>
+     *
+     * @see ACAMERA_SCALER_CROP_REGION
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraManager_getCameraCharacteristics</li>
+     * </ul>
+     *
+     * <p>This represents the maximum amount of zooming possible by
+     * the camera device, or equivalently, the minimum cropping
+     * window size.</p>
+     * <p>Crop regions that have a width or height that is smaller
+     * than this ratio allows will be rounded up to the minimum
+     * allowed size by the camera device.</p>
+     */
     ACAMERA_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM =                 // float
             ACAMERA_SCALER_START + 4,
+    /**
+     * <p>The available stream configurations that this
+     * camera device supports
+     * (i.e. format, width, height, output/input stream).</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraManager_getCameraCharacteristics</li>
+     * </ul>
+     *
+     * <p>The configurations are listed as <code>(format, width, height, input?)</code>
+     * tuples.</p>
+     * <p>For a given use case, the actual maximum supported resolution
+     * may be lower than what is listed here, depending on the destination
+     * Surface for the image data. For example, for recording video,
+     * the video encoder chosen may have a maximum size limit (e.g. 1080p)
+     * smaller than what the camera (e.g. maximum resolution is 3264x2448)
+     * can provide.</p>
+     * <p>Please reference the documentation for the image data destination to
+     * check if it limits the maximum size for image data.</p>
+     * <p>Not all output formats may be supported in a configuration with
+     * an input stream of a particular format. For more details, see
+     * android.scaler.availableInputOutputFormatsMap.</p>
+     * <p>The following table describes the minimum required output stream
+     * configurations based on the hardware level
+     * (ACAMERA_INFO_SUPPORTED_HARDWARE_LEVEL):</p>
+     * <table>
+     * <thead>
+     * <tr>
+     * <th align="center">Format</th>
+     * <th align="center">Size</th>
+     * <th align="center">Hardware Level</th>
+     * <th align="center">Notes</th>
+     * </tr>
+     * </thead>
+     * <tbody>
+     * <tr>
+     * <td align="center">JPEG</td>
+     * <td align="center">ACAMERA_SENSOR_INFO_ACTIVE_ARRAY_SIZE</td>
+     * <td align="center">Any</td>
+     * <td align="center"></td>
+     * </tr>
+     * <tr>
+     * <td align="center">JPEG</td>
+     * <td align="center">1920x1080 (1080p)</td>
+     * <td align="center">Any</td>
+     * <td align="center">if 1080p &lt;= activeArraySize</td>
+     * </tr>
+     * <tr>
+     * <td align="center">JPEG</td>
+     * <td align="center">1280x720 (720)</td>
+     * <td align="center">Any</td>
+     * <td align="center">if 720p &lt;= activeArraySize</td>
+     * </tr>
+     * <tr>
+     * <td align="center">JPEG</td>
+     * <td align="center">640x480 (480p)</td>
+     * <td align="center">Any</td>
+     * <td align="center">if 480p &lt;= activeArraySize</td>
+     * </tr>
+     * <tr>
+     * <td align="center">JPEG</td>
+     * <td align="center">320x240 (240p)</td>
+     * <td align="center">Any</td>
+     * <td align="center">if 240p &lt;= activeArraySize</td>
+     * </tr>
+     * <tr>
+     * <td align="center">YUV_420_888</td>
+     * <td align="center">all output sizes available for JPEG</td>
+     * <td align="center">FULL</td>
+     * <td align="center"></td>
+     * </tr>
+     * <tr>
+     * <td align="center">YUV_420_888</td>
+     * <td align="center">all output sizes available for JPEG, up to the maximum video size</td>
+     * <td align="center">LIMITED</td>
+     * <td align="center"></td>
+     * </tr>
+     * <tr>
+     * <td align="center">IMPLEMENTATION_DEFINED</td>
+     * <td align="center">same as YUV_420_888</td>
+     * <td align="center">Any</td>
+     * <td align="center"></td>
+     * </tr>
+     * </tbody>
+     * </table>
+     * <p>Refer to ACAMERA_REQUEST_AVAILABLE_CAPABILITIES for additional
+     * mandatory stream configurations on a per-capability basis.</p>
+     *
+     * @see ACAMERA_INFO_SUPPORTED_HARDWARE_LEVEL
+     * @see ACAMERA_REQUEST_AVAILABLE_CAPABILITIES
+     * @see ACAMERA_SENSOR_INFO_ACTIVE_ARRAY_SIZE
+     */
     ACAMERA_SCALER_AVAILABLE_STREAM_CONFIGURATIONS =            // int32[n*4] (enum)
             ACAMERA_SCALER_START + 10,
+    /**
+     * <p>This lists the minimum frame duration for each
+     * format/size combination.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraManager_getCameraCharacteristics</li>
+     * </ul>
+     *
+     * <p>This should correspond to the frame duration when only that
+     * stream is active, with all processing (typically in android.*.mode)
+     * set to either OFF or FAST.</p>
+     * <p>When multiple streams are used in a request, the minimum frame
+     * duration will be max(individual stream min durations).</p>
+     * <p>The minimum frame duration of a stream (of a particular format, size)
+     * is the same regardless of whether the stream is input or output.</p>
+     * <p>See ACAMERA_SENSOR_FRAME_DURATION and
+     * ACAMERA_SCALER_AVAILABLE_STALL_DURATIONS for more details about
+     * calculating the max frame rate.</p>
+     * <p>(Keep in sync with
+     * {@link android.hardware.camera2.params.StreamConfigurationMap#getOutputMinFrameDuration})</p>
+     *
+     * @see ACAMERA_SCALER_AVAILABLE_STALL_DURATIONS
+     * @see ACAMERA_SENSOR_FRAME_DURATION
+     */
     ACAMERA_SCALER_AVAILABLE_MIN_FRAME_DURATIONS =              // int64[4*n]
             ACAMERA_SCALER_START + 11,
+    /**
+     * <p>This lists the maximum stall duration for each
+     * output format/size combination.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraManager_getCameraCharacteristics</li>
+     * </ul>
+     *
+     * <p>A stall duration is how much extra time would get added
+     * to the normal minimum frame duration for a repeating request
+     * that has streams with non-zero stall.</p>
+     * <p>For example, consider JPEG captures which have the following
+     * characteristics:</p>
+     * <ul>
+     * <li>JPEG streams act like processed YUV streams in requests for which
+     * they are not included; in requests in which they are directly
+     * referenced, they act as JPEG streams. This is because supporting a
+     * JPEG stream requires the underlying YUV data to always be ready for
+     * use by a JPEG encoder, but the encoder will only be used (and impact
+     * frame duration) on requests that actually reference a JPEG stream.</li>
+     * <li>The JPEG processor can run concurrently to the rest of the camera
+     * pipeline, but cannot process more than 1 capture at a time.</li>
+     * </ul>
+     * <p>In other words, using a repeating YUV request would result
+     * in a steady frame rate (let's say it's 30 FPS). If a single
+     * JPEG request is submitted periodically, the frame rate will stay
+     * at 30 FPS (as long as we wait for the previous JPEG to return each
+     * time). If we try to submit a repeating YUV + JPEG request, then
+     * the frame rate will drop from 30 FPS.</p>
+     * <p>In general, submitting a new request with a non-0 stall time
+     * stream will <em>not</em> cause a frame rate drop unless there are still
+     * outstanding buffers for that stream from previous requests.</p>
+     * <p>Submitting a repeating request with streams (call this <code>S</code>)
+     * is the same as setting the minimum frame duration from
+     * the normal minimum frame duration corresponding to <code>S</code>, added with
+     * the maximum stall duration for <code>S</code>.</p>
+     * <p>If interleaving requests with and without a stall duration,
+     * a request will stall by the maximum of the remaining times
+     * for each can-stall stream with outstanding buffers.</p>
+     * <p>This means that a stalling request will not have an exposure start
+     * until the stall has completed.</p>
+     * <p>This should correspond to the stall duration when only that stream is
+     * active, with all processing (typically in android.*.mode) set to FAST
+     * or OFF. Setting any of the processing modes to HIGH_QUALITY
+     * effectively results in an indeterminate stall duration for all
+     * streams in a request (the regular stall calculation rules are
+     * ignored).</p>
+     * <p>The following formats may always have a stall duration:</p>
+     * <ul>
+     * <li>{@link android.graphics.ImageFormat#JPEG}</li>
+     * <li>{@link android.graphics.ImageFormat#RAW_SENSOR}</li>
+     * </ul>
+     * <p>The following formats will never have a stall duration:</p>
+     * <ul>
+     * <li>{@link android.graphics.ImageFormat#YUV_420_888}</li>
+     * <li>{@link android.graphics.ImageFormat#RAW10}</li>
+     * </ul>
+     * <p>All other formats may or may not have an allowed stall duration on
+     * a per-capability basis; refer to ACAMERA_REQUEST_AVAILABLE_CAPABILITIES
+     * for more details.</p>
+     * <p>See ACAMERA_SENSOR_FRAME_DURATION for more information about
+     * calculating the max frame rate (absent stalls).</p>
+     * <p>(Keep up to date with
+     * {@link android.hardware.camera2.params.StreamConfigurationMap#getOutputStallDuration} )</p>
+     *
+     * @see ACAMERA_REQUEST_AVAILABLE_CAPABILITIES
+     * @see ACAMERA_SENSOR_FRAME_DURATION
+     */
     ACAMERA_SCALER_AVAILABLE_STALL_DURATIONS =                  // int64[4*n]
             ACAMERA_SCALER_START + 12,
+    /**
+     * <p>The crop type that this camera device supports.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraManager_getCameraCharacteristics</li>
+     * </ul>
+     *
+     * <p>When passing a non-centered crop region (ACAMERA_SCALER_CROP_REGION) to a camera
+     * device that only supports CENTER_ONLY cropping, the camera device will move the
+     * crop region to the center of the sensor active array (ACAMERA_SENSOR_INFO_ACTIVE_ARRAY_SIZE)
+     * and keep the crop region width and height unchanged. The camera device will return the
+     * final used crop region in metadata result ACAMERA_SCALER_CROP_REGION.</p>
+     * <p>Camera devices that support FREEFORM cropping will support any crop region that
+     * is inside of the active array. The camera device will apply the same crop region and
+     * return the final used crop region in capture result metadata ACAMERA_SCALER_CROP_REGION.</p>
+     * <p>LEGACY capability devices will only support CENTER_ONLY cropping.</p>
+     *
+     * @see ACAMERA_SCALER_CROP_REGION
+     * @see ACAMERA_SENSOR_INFO_ACTIVE_ARRAY_SIZE
+     */
     ACAMERA_SCALER_CROPPING_TYPE =                              // byte (enum)
             ACAMERA_SCALER_START + 13,
     ACAMERA_SCALER_END,
 
+    /**
+     * <p>Duration each pixel is exposed to
+     * light.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraCaptureSession_captureCallback_result callbacks</li>
+     *   <li>ACaptureRequest</li>
+     * </ul>
+     *
+     * <p>If the sensor can't expose this exact duration, it will shorten the
+     * duration exposed to the nearest possible value (rather than expose longer).
+     * The final exposure time used will be available in the output capture result.</p>
+     * <p>This control is only effective if ACAMERA_CONTROL_AE_MODE or ACAMERA_CONTROL_MODE is set to
+     * OFF; otherwise the auto-exposure algorithm will override this value.</p>
+     *
+     * @see ACAMERA_CONTROL_AE_MODE
+     * @see ACAMERA_CONTROL_MODE
+     */
     ACAMERA_SENSOR_EXPOSURE_TIME =                              // int64
             ACAMERA_SENSOR_START,
+    /**
+     * <p>Duration from start of frame exposure to
+     * start of next frame exposure.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraCaptureSession_captureCallback_result callbacks</li>
+     *   <li>ACaptureRequest</li>
+     * </ul>
+     *
+     * <p>The maximum frame rate that can be supported by a camera subsystem is
+     * a function of many factors:</p>
+     * <ul>
+     * <li>Requested resolutions of output image streams</li>
+     * <li>Availability of binning / skipping modes on the imager</li>
+     * <li>The bandwidth of the imager interface</li>
+     * <li>The bandwidth of the various ISP processing blocks</li>
+     * </ul>
+     * <p>Since these factors can vary greatly between different ISPs and
+     * sensors, the camera abstraction tries to represent the bandwidth
+     * restrictions with as simple a model as possible.</p>
+     * <p>The model presented has the following characteristics:</p>
+     * <ul>
+     * <li>The image sensor is always configured to output the smallest
+     * resolution possible given the application's requested output stream
+     * sizes.  The smallest resolution is defined as being at least as large
+     * as the largest requested output stream size; the camera pipeline must
+     * never digitally upsample sensor data when the crop region covers the
+     * whole sensor. In general, this means that if only small output stream
+     * resolutions are configured, the sensor can provide a higher frame
+     * rate.</li>
+     * <li>Since any request may use any or all the currently configured
+     * output streams, the sensor and ISP must be configured to support
+     * scaling a single capture to all the streams at the same time.  This
+     * means the camera pipeline must be ready to produce the largest
+     * requested output size without any delay.  Therefore, the overall
+     * frame rate of a given configured stream set is governed only by the
+     * largest requested stream resolution.</li>
+     * <li>Using more than one output stream in a request does not affect the
+     * frame duration.</li>
+     * <li>Certain format-streams may need to do additional background processing
+     * before data is consumed/produced by that stream. These processors
+     * can run concurrently to the rest of the camera pipeline, but
+     * cannot process more than 1 capture at a time.</li>
+     * </ul>
+     * <p>The necessary information for the application, given the model above,
+     * is provided via the android.scaler.streamConfigurationMap field using
+     * {@link android.hardware.camera2.params.StreamConfigurationMap#getOutputMinFrameDuration}.
+     * These are used to determine the maximum frame rate / minimum frame
+     * duration that is possible for a given stream configuration.</p>
+     * <p>Specifically, the application can use the following rules to
+     * determine the minimum frame duration it can request from the camera
+     * device:</p>
+     * <ol>
+     * <li>Let the set of currently configured input/output streams
+     * be called <code>S</code>.</li>
+     * <li>Find the minimum frame durations for each stream in <code>S</code>, by looking
+     * it up in android.scaler.streamConfigurationMap using {@link
+     * android.hardware.camera2.params.StreamConfigurationMap#getOutputMinFrameDuration}
+     * (with its respective size/format). Let this set of frame durations be
+     * called <code>F</code>.</li>
+     * <li>For any given request <code>R</code>, the minimum frame duration allowed
+     * for <code>R</code> is the maximum out of all values in <code>F</code>. Let the streams
+     * used in <code>R</code> be called <code>S_r</code>.</li>
+     * </ol>
+     * <p>If none of the streams in <code>S_r</code> have a stall time (listed in {@link
+     * android.hardware.camera2.params.StreamConfigurationMap#getOutputStallDuration}
+     * using its respective size/format), then the frame duration in <code>F</code>
+     * determines the steady state frame rate that the application will get
+     * if it uses <code>R</code> as a repeating request. Let this special kind of
+     * request be called <code>Rsimple</code>.</p>
+     * <p>A repeating request <code>Rsimple</code> can be <em>occasionally</em> interleaved
+     * by a single capture of a new request <code>Rstall</code> (which has at least
+     * one in-use stream with a non-0 stall time) and if <code>Rstall</code> has the
+     * same minimum frame duration this will not cause a frame rate loss
+     * if all buffers from the previous <code>Rstall</code> have already been
+     * delivered.</p>
+     * <p>For more details about stalling, see
+     * {@link android.hardware.camera2.params.StreamConfigurationMap#getOutputStallDuration}.</p>
+     * <p>This control is only effective if ACAMERA_CONTROL_AE_MODE or ACAMERA_CONTROL_MODE is set to
+     * OFF; otherwise the auto-exposure algorithm will override this value.</p>
+     *
+     * @see ACAMERA_CONTROL_AE_MODE
+     * @see ACAMERA_CONTROL_MODE
+     */
     ACAMERA_SENSOR_FRAME_DURATION =                             // int64
             ACAMERA_SENSOR_START + 1,
+    /**
+     * <p>The amount of gain applied to sensor data
+     * before processing.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraCaptureSession_captureCallback_result callbacks</li>
+     *   <li>ACaptureRequest</li>
+     * </ul>
+     *
+     * <p>The sensitivity is the standard ISO sensitivity value,
+     * as defined in ISO 12232:2006.</p>
+     * <p>The sensitivity must be within ACAMERA_SENSOR_INFO_SENSITIVITY_RANGE, and
+     * if if it less than ACAMERA_SENSOR_MAX_ANALOG_SENSITIVITY, the camera device
+     * is guaranteed to use only analog amplification for applying the gain.</p>
+     * <p>If the camera device cannot apply the exact sensitivity
+     * requested, it will reduce the gain to the nearest supported
+     * value. The final sensitivity used will be available in the
+     * output capture result.</p>
+     * <p>This control is only effective if ACAMERA_CONTROL_AE_MODE or ACAMERA_CONTROL_MODE is set to
+     * OFF; otherwise the auto-exposure algorithm will override this value.</p>
+     *
+     * @see ACAMERA_CONTROL_AE_MODE
+     * @see ACAMERA_CONTROL_MODE
+     * @see ACAMERA_SENSOR_INFO_SENSITIVITY_RANGE
+     * @see ACAMERA_SENSOR_MAX_ANALOG_SENSITIVITY
+     */
     ACAMERA_SENSOR_SENSITIVITY =                                // int32
             ACAMERA_SENSOR_START + 2,
+    /**
+     * <p>The standard reference illuminant used as the scene light source when
+     * calculating the ACAMERA_SENSOR_COLOR_TRANSFORM1,
+     * ACAMERA_SENSOR_CALIBRATION_TRANSFORM1, and
+     * ACAMERA_SENSOR_FORWARD_MATRIX1 matrices.</p>
+     *
+     * @see ACAMERA_SENSOR_CALIBRATION_TRANSFORM1
+     * @see ACAMERA_SENSOR_COLOR_TRANSFORM1
+     * @see ACAMERA_SENSOR_FORWARD_MATRIX1
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraManager_getCameraCharacteristics</li>
+     * </ul>
+     *
+     * <p>The values in this key correspond to the values defined for the
+     * EXIF LightSource tag. These illuminants are standard light sources
+     * that are often used calibrating camera devices.</p>
+     * <p>If this key is present, then ACAMERA_SENSOR_COLOR_TRANSFORM1,
+     * ACAMERA_SENSOR_CALIBRATION_TRANSFORM1, and
+     * ACAMERA_SENSOR_FORWARD_MATRIX1 will also be present.</p>
+     * <p>Some devices may choose to provide a second set of calibration
+     * information for improved quality, including
+     * ACAMERA_SENSOR_REFERENCE_ILLUMINANT2 and its corresponding matrices.</p>
+     *
+     * @see ACAMERA_SENSOR_CALIBRATION_TRANSFORM1
+     * @see ACAMERA_SENSOR_COLOR_TRANSFORM1
+     * @see ACAMERA_SENSOR_FORWARD_MATRIX1
+     * @see ACAMERA_SENSOR_REFERENCE_ILLUMINANT2
+     */
     ACAMERA_SENSOR_REFERENCE_ILLUMINANT1 =                      // byte (enum)
             ACAMERA_SENSOR_START + 3,
+    /**
+     * <p>The standard reference illuminant used as the scene light source when
+     * calculating the ACAMERA_SENSOR_COLOR_TRANSFORM2,
+     * ACAMERA_SENSOR_CALIBRATION_TRANSFORM2, and
+     * ACAMERA_SENSOR_FORWARD_MATRIX2 matrices.</p>
+     *
+     * @see ACAMERA_SENSOR_CALIBRATION_TRANSFORM2
+     * @see ACAMERA_SENSOR_COLOR_TRANSFORM2
+     * @see ACAMERA_SENSOR_FORWARD_MATRIX2
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraManager_getCameraCharacteristics</li>
+     * </ul>
+     *
+     * <p>See ACAMERA_SENSOR_REFERENCE_ILLUMINANT1 for more details.</p>
+     * <p>If this key is present, then ACAMERA_SENSOR_COLOR_TRANSFORM2,
+     * ACAMERA_SENSOR_CALIBRATION_TRANSFORM2, and
+     * ACAMERA_SENSOR_FORWARD_MATRIX2 will also be present.</p>
+     *
+     * @see ACAMERA_SENSOR_CALIBRATION_TRANSFORM2
+     * @see ACAMERA_SENSOR_COLOR_TRANSFORM2
+     * @see ACAMERA_SENSOR_FORWARD_MATRIX2
+     * @see ACAMERA_SENSOR_REFERENCE_ILLUMINANT1
+     */
     ACAMERA_SENSOR_REFERENCE_ILLUMINANT2 =                      // byte
             ACAMERA_SENSOR_START + 4,
+    /**
+     * <p>A per-device calibration transform matrix that maps from the
+     * reference sensor colorspace to the actual device sensor colorspace.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraManager_getCameraCharacteristics</li>
+     * </ul>
+     *
+     * <p>This matrix is used to correct for per-device variations in the
+     * sensor colorspace, and is used for processing raw buffer data.</p>
+     * <p>The matrix is expressed as a 3x3 matrix in row-major-order, and
+     * contains a per-device calibration transform that maps colors
+     * from reference sensor color space (i.e. the "golden module"
+     * colorspace) into this camera device's native sensor color
+     * space under the first reference illuminant
+     * (ACAMERA_SENSOR_REFERENCE_ILLUMINANT1).</p>
+     *
+     * @see ACAMERA_SENSOR_REFERENCE_ILLUMINANT1
+     */
     ACAMERA_SENSOR_CALIBRATION_TRANSFORM1 =                     // rational[3*3]
             ACAMERA_SENSOR_START + 5,
+    /**
+     * <p>A per-device calibration transform matrix that maps from the
+     * reference sensor colorspace to the actual device sensor colorspace
+     * (this is the colorspace of the raw buffer data).</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraManager_getCameraCharacteristics</li>
+     * </ul>
+     *
+     * <p>This matrix is used to correct for per-device variations in the
+     * sensor colorspace, and is used for processing raw buffer data.</p>
+     * <p>The matrix is expressed as a 3x3 matrix in row-major-order, and
+     * contains a per-device calibration transform that maps colors
+     * from reference sensor color space (i.e. the "golden module"
+     * colorspace) into this camera device's native sensor color
+     * space under the second reference illuminant
+     * (ACAMERA_SENSOR_REFERENCE_ILLUMINANT2).</p>
+     * <p>This matrix will only be present if the second reference
+     * illuminant is present.</p>
+     *
+     * @see ACAMERA_SENSOR_REFERENCE_ILLUMINANT2
+     */
     ACAMERA_SENSOR_CALIBRATION_TRANSFORM2 =                     // rational[3*3]
             ACAMERA_SENSOR_START + 6,
+    /**
+     * <p>A matrix that transforms color values from CIE XYZ color space to
+     * reference sensor color space.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraManager_getCameraCharacteristics</li>
+     * </ul>
+     *
+     * <p>This matrix is used to convert from the standard CIE XYZ color
+     * space to the reference sensor colorspace, and is used when processing
+     * raw buffer data.</p>
+     * <p>The matrix is expressed as a 3x3 matrix in row-major-order, and
+     * contains a color transform matrix that maps colors from the CIE
+     * XYZ color space to the reference sensor color space (i.e. the
+     * "golden module" colorspace) under the first reference illuminant
+     * (ACAMERA_SENSOR_REFERENCE_ILLUMINANT1).</p>
+     * <p>The white points chosen in both the reference sensor color space
+     * and the CIE XYZ colorspace when calculating this transform will
+     * match the standard white point for the first reference illuminant
+     * (i.e. no chromatic adaptation will be applied by this transform).</p>
+     *
+     * @see ACAMERA_SENSOR_REFERENCE_ILLUMINANT1
+     */
     ACAMERA_SENSOR_COLOR_TRANSFORM1 =                           // rational[3*3]
             ACAMERA_SENSOR_START + 7,
+    /**
+     * <p>A matrix that transforms color values from CIE XYZ color space to
+     * reference sensor color space.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraManager_getCameraCharacteristics</li>
+     * </ul>
+     *
+     * <p>This matrix is used to convert from the standard CIE XYZ color
+     * space to the reference sensor colorspace, and is used when processing
+     * raw buffer data.</p>
+     * <p>The matrix is expressed as a 3x3 matrix in row-major-order, and
+     * contains a color transform matrix that maps colors from the CIE
+     * XYZ color space to the reference sensor color space (i.e. the
+     * "golden module" colorspace) under the second reference illuminant
+     * (ACAMERA_SENSOR_REFERENCE_ILLUMINANT2).</p>
+     * <p>The white points chosen in both the reference sensor color space
+     * and the CIE XYZ colorspace when calculating this transform will
+     * match the standard white point for the second reference illuminant
+     * (i.e. no chromatic adaptation will be applied by this transform).</p>
+     * <p>This matrix will only be present if the second reference
+     * illuminant is present.</p>
+     *
+     * @see ACAMERA_SENSOR_REFERENCE_ILLUMINANT2
+     */
     ACAMERA_SENSOR_COLOR_TRANSFORM2 =                           // rational[3*3]
             ACAMERA_SENSOR_START + 8,
+    /**
+     * <p>A matrix that transforms white balanced camera colors from the reference
+     * sensor colorspace to the CIE XYZ colorspace with a D50 whitepoint.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraManager_getCameraCharacteristics</li>
+     * </ul>
+     *
+     * <p>This matrix is used to convert to the standard CIE XYZ colorspace, and
+     * is used when processing raw buffer data.</p>
+     * <p>This matrix is expressed as a 3x3 matrix in row-major-order, and contains
+     * a color transform matrix that maps white balanced colors from the
+     * reference sensor color space to the CIE XYZ color space with a D50 white
+     * point.</p>
+     * <p>Under the first reference illuminant (ACAMERA_SENSOR_REFERENCE_ILLUMINANT1)
+     * this matrix is chosen so that the standard white point for this reference
+     * illuminant in the reference sensor colorspace is mapped to D50 in the
+     * CIE XYZ colorspace.</p>
+     *
+     * @see ACAMERA_SENSOR_REFERENCE_ILLUMINANT1
+     */
     ACAMERA_SENSOR_FORWARD_MATRIX1 =                            // rational[3*3]
             ACAMERA_SENSOR_START + 9,
+    /**
+     * <p>A matrix that transforms white balanced camera colors from the reference
+     * sensor colorspace to the CIE XYZ colorspace with a D50 whitepoint.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraManager_getCameraCharacteristics</li>
+     * </ul>
+     *
+     * <p>This matrix is used to convert to the standard CIE XYZ colorspace, and
+     * is used when processing raw buffer data.</p>
+     * <p>This matrix is expressed as a 3x3 matrix in row-major-order, and contains
+     * a color transform matrix that maps white balanced colors from the
+     * reference sensor color space to the CIE XYZ color space with a D50 white
+     * point.</p>
+     * <p>Under the second reference illuminant (ACAMERA_SENSOR_REFERENCE_ILLUMINANT2)
+     * this matrix is chosen so that the standard white point for this reference
+     * illuminant in the reference sensor colorspace is mapped to D50 in the
+     * CIE XYZ colorspace.</p>
+     * <p>This matrix will only be present if the second reference
+     * illuminant is present.</p>
+     *
+     * @see ACAMERA_SENSOR_REFERENCE_ILLUMINANT2
+     */
     ACAMERA_SENSOR_FORWARD_MATRIX2 =                            // rational[3*3]
             ACAMERA_SENSOR_START + 10,
+    /**
+     * <p>A fixed black level offset for each of the color filter arrangement
+     * (CFA) mosaic channels.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraManager_getCameraCharacteristics</li>
+     * </ul>
+     *
+     * <p>This key specifies the zero light value for each of the CFA mosaic
+     * channels in the camera sensor.  The maximal value output by the
+     * sensor is represented by the value in ACAMERA_SENSOR_INFO_WHITE_LEVEL.</p>
+     * <p>The values are given in the same order as channels listed for the CFA
+     * layout key (see ACAMERA_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT), i.e. the
+     * nth value given corresponds to the black level offset for the nth
+     * color channel listed in the CFA.</p>
+     * <p>The black level values of captured images may vary for different
+     * capture settings (e.g., ACAMERA_SENSOR_SENSITIVITY). This key
+     * represents a coarse approximation for such case. It is recommended to
+     * use ACAMERA_SENSOR_DYNAMIC_BLACK_LEVEL or use pixels from
+     * ACAMERA_SENSOR_OPTICAL_BLACK_REGIONS directly for captures when
+     * supported by the camera device, which provides more accurate black
+     * level values. For raw capture in particular, it is recommended to use
+     * pixels from ACAMERA_SENSOR_OPTICAL_BLACK_REGIONS to calculate black
+     * level values for each frame.</p>
+     *
+     * @see ACAMERA_SENSOR_DYNAMIC_BLACK_LEVEL
+     * @see ACAMERA_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT
+     * @see ACAMERA_SENSOR_INFO_WHITE_LEVEL
+     * @see ACAMERA_SENSOR_OPTICAL_BLACK_REGIONS
+     * @see ACAMERA_SENSOR_SENSITIVITY
+     */
     ACAMERA_SENSOR_BLACK_LEVEL_PATTERN =                        // int32[4]
             ACAMERA_SENSOR_START + 12,
+    /**
+     * <p>Maximum sensitivity that is implemented
+     * purely through analog gain.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraManager_getCameraCharacteristics</li>
+     * </ul>
+     *
+     * <p>For ACAMERA_SENSOR_SENSITIVITY values less than or
+     * equal to this, all applied gain must be analog. For
+     * values above this, the gain applied can be a mix of analog and
+     * digital.</p>
+     *
+     * @see ACAMERA_SENSOR_SENSITIVITY
+     */
     ACAMERA_SENSOR_MAX_ANALOG_SENSITIVITY =                     // int32
             ACAMERA_SENSOR_START + 13,
+    /**
+     * <p>Clockwise angle through which the output image needs to be rotated to be
+     * upright on the device screen in its native orientation.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraManager_getCameraCharacteristics</li>
+     * </ul>
+     *
+     * <p>Also defines the direction of rolling shutter readout, which is from top to bottom in
+     * the sensor's coordinate system.</p>
+     */
     ACAMERA_SENSOR_ORIENTATION =                                // int32
             ACAMERA_SENSOR_START + 14,
+    /**
+     * <p>Time at start of exposure of first
+     * row of the image sensor active array, in nanoseconds.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraCaptureSession_captureCallback_result callbacks</li>
+     * </ul>
+     *
+     * <p>The timestamps are also included in all image
+     * buffers produced for the same capture, and will be identical
+     * on all the outputs.</p>
+     * <p>When ACAMERA_SENSOR_INFO_TIMESTAMP_SOURCE <code>==</code> UNKNOWN,
+     * the timestamps measure time since an unspecified starting point,
+     * and are monotonically increasing. They can be compared with the
+     * timestamps for other captures from the same camera device, but are
+     * not guaranteed to be comparable to any other time source.</p>
+     * <p>When ACAMERA_SENSOR_INFO_TIMESTAMP_SOURCE <code>==</code> REALTIME, the
+     * timestamps measure time in the same timebase as {@link
+     * android.os.SystemClock#elapsedRealtimeNanos}, and they can
+     * be compared to other timestamps from other subsystems that
+     * are using that base.</p>
+     * <p>For reprocessing, the timestamp will match the start of exposure of
+     * the input image, i.e. {@link CaptureResult#SENSOR_TIMESTAMP the
+     * timestamp} in the TotalCaptureResult that was used to create the
+     * reprocess capture request.</p>
+     *
+     * @see ACAMERA_SENSOR_INFO_TIMESTAMP_SOURCE
+     */
     ACAMERA_SENSOR_TIMESTAMP =                                  // int64
             ACAMERA_SENSOR_START + 16,
+    /**
+     * <p>The estimated camera neutral color in the native sensor colorspace at
+     * the time of capture.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraCaptureSession_captureCallback_result callbacks</li>
+     * </ul>
+     *
+     * <p>This value gives the neutral color point encoded as an RGB value in the
+     * native sensor color space.  The neutral color point indicates the
+     * currently estimated white point of the scene illumination.  It can be
+     * used to interpolate between the provided color transforms when
+     * processing raw sensor data.</p>
+     * <p>The order of the values is R, G, B; where R is in the lowest index.</p>
+     */
     ACAMERA_SENSOR_NEUTRAL_COLOR_POINT =                        // rational[3]
             ACAMERA_SENSOR_START + 18,
+    /**
+     * <p>Noise model coefficients for each CFA mosaic channel.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraCaptureSession_captureCallback_result callbacks</li>
+     * </ul>
+     *
+     * <p>This key contains two noise model coefficients for each CFA channel
+     * corresponding to the sensor amplification (S) and sensor readout
+     * noise (O).  These are given as pairs of coefficients for each channel
+     * in the same order as channels listed for the CFA layout key
+     * (see ACAMERA_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT).  This is
+     * represented as an array of Pair&lt;Double, Double&gt;, where
+     * the first member of the Pair at index n is the S coefficient and the
+     * second member is the O coefficient for the nth color channel in the CFA.</p>
+     * <p>These coefficients are used in a two parameter noise model to describe
+     * the amount of noise present in the image for each CFA channel.  The
+     * noise model used here is:</p>
+     * <p>N(x) = sqrt(Sx + O)</p>
+     * <p>Where x represents the recorded signal of a CFA channel normalized to
+     * the range [0, 1], and S and O are the noise model coeffiecients for
+     * that channel.</p>
+     * <p>A more detailed description of the noise model can be found in the
+     * Adobe DNG specification for the NoiseProfile tag.</p>
+     *
+     * @see ACAMERA_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT
+     */
     ACAMERA_SENSOR_NOISE_PROFILE =                              // double[2*CFA Channels]
             ACAMERA_SENSOR_START + 19,
+    /**
+     * <p>The worst-case divergence between Bayer green channels.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraCaptureSession_captureCallback_result callbacks</li>
+     * </ul>
+     *
+     * <p>This value is an estimate of the worst case split between the
+     * Bayer green channels in the red and blue rows in the sensor color
+     * filter array.</p>
+     * <p>The green split is calculated as follows:</p>
+     * <ol>
+     * <li>A 5x5 pixel (or larger) window W within the active sensor array is
+     * chosen. The term 'pixel' here is taken to mean a group of 4 Bayer
+     * mosaic channels (R, Gr, Gb, B).  The location and size of the window
+     * chosen is implementation defined, and should be chosen to provide a
+     * green split estimate that is both representative of the entire image
+     * for this camera sensor, and can be calculated quickly.</li>
+     * <li>The arithmetic mean of the green channels from the red
+     * rows (mean_Gr) within W is computed.</li>
+     * <li>The arithmetic mean of the green channels from the blue
+     * rows (mean_Gb) within W is computed.</li>
+     * <li>The maximum ratio R of the two means is computed as follows:
+     * <code>R = max((mean_Gr + 1)/(mean_Gb + 1), (mean_Gb + 1)/(mean_Gr + 1))</code></li>
+     * </ol>
+     * <p>The ratio R is the green split divergence reported for this property,
+     * which represents how much the green channels differ in the mosaic
+     * pattern.  This value is typically used to determine the treatment of
+     * the green mosaic channels when demosaicing.</p>
+     * <p>The green split value can be roughly interpreted as follows:</p>
+     * <ul>
+     * <li>R &lt; 1.03 is a negligible split (&lt;3% divergence).</li>
+     * <li>1.20 &lt;= R &gt;= 1.03 will require some software
+     * correction to avoid demosaic errors (3-20% divergence).</li>
+     * <li>R &gt; 1.20 will require strong software correction to produce
+     * a usuable image (&gt;20% divergence).</li>
+     * </ul>
+     */
     ACAMERA_SENSOR_GREEN_SPLIT =                                // float
             ACAMERA_SENSOR_START + 22,
+    /**
+     * <p>A pixel <code>[R, G_even, G_odd, B]</code> that supplies the test pattern
+     * when ACAMERA_SENSOR_TEST_PATTERN_MODE is SOLID_COLOR.</p>
+     *
+     * @see ACAMERA_SENSOR_TEST_PATTERN_MODE
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraCaptureSession_captureCallback_result callbacks</li>
+     *   <li>ACaptureRequest</li>
+     * </ul>
+     *
+     * <p>Each color channel is treated as an unsigned 32-bit integer.
+     * The camera device then uses the most significant X bits
+     * that correspond to how many bits are in its Bayer raw sensor
+     * output.</p>
+     * <p>For example, a sensor with RAW10 Bayer output would use the
+     * 10 most significant bits from each color channel.</p>
+     */
     ACAMERA_SENSOR_TEST_PATTERN_DATA =                          // int32[4]
             ACAMERA_SENSOR_START + 23,
+    /**
+     * <p>When enabled, the sensor sends a test pattern instead of
+     * doing a real exposure from the camera.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraCaptureSession_captureCallback_result callbacks</li>
+     *   <li>ACaptureRequest</li>
+     * </ul>
+     *
+     * <p>When a test pattern is enabled, all manual sensor controls specified
+     * by ACAMERA_SENSOR_* will be ignored. All other controls should
+     * work as normal.</p>
+     * <p>For example, if manual flash is enabled, flash firing should still
+     * occur (and that the test pattern remain unmodified, since the flash
+     * would not actually affect it).</p>
+     * <p>Defaults to OFF.</p>
+     */
     ACAMERA_SENSOR_TEST_PATTERN_MODE =                          // int32 (enum)
             ACAMERA_SENSOR_START + 24,
+    /**
+     * <p>List of sensor test pattern modes for ACAMERA_SENSOR_TEST_PATTERN_MODE
+     * supported by this camera device.</p>
+     *
+     * @see ACAMERA_SENSOR_TEST_PATTERN_MODE
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraManager_getCameraCharacteristics</li>
+     * </ul>
+     *
+     * <p>Defaults to OFF, and always includes OFF if defined.</p>
+     */
     ACAMERA_SENSOR_AVAILABLE_TEST_PATTERN_MODES =               // int32[n]
             ACAMERA_SENSOR_START + 25,
+    /**
+     * <p>Duration between the start of first row exposure
+     * and the start of last row exposure.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraCaptureSession_captureCallback_result callbacks</li>
+     * </ul>
+     *
+     * <p>This is the exposure time skew between the first and last
+     * row exposure start times. The first row and the last row are
+     * the first and last rows inside of the
+     * ACAMERA_SENSOR_INFO_ACTIVE_ARRAY_SIZE.</p>
+     * <p>For typical camera sensors that use rolling shutters, this is also equivalent
+     * to the frame readout time.</p>
+     *
+     * @see ACAMERA_SENSOR_INFO_ACTIVE_ARRAY_SIZE
+     */
     ACAMERA_SENSOR_ROLLING_SHUTTER_SKEW =                       // int64
             ACAMERA_SENSOR_START + 26,
+    /**
+     * <p>List of disjoint rectangles indicating the sensor
+     * optically shielded black pixel regions.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraManager_getCameraCharacteristics</li>
+     * </ul>
+     *
+     * <p>In most camera sensors, the active array is surrounded by some
+     * optically shielded pixel areas. By blocking light, these pixels
+     * provides a reliable black reference for black level compensation
+     * in active array region.</p>
+     * <p>This key provides a list of disjoint rectangles specifying the
+     * regions of optically shielded (with metal shield) black pixel
+     * regions if the camera device is capable of reading out these black
+     * pixels in the output raw images. In comparison to the fixed black
+     * level values reported by ACAMERA_SENSOR_BLACK_LEVEL_PATTERN, this key
+     * may provide a more accurate way for the application to calculate
+     * black level of each captured raw images.</p>
+     * <p>When this key is reported, the ACAMERA_SENSOR_DYNAMIC_BLACK_LEVEL and
+     * ACAMERA_SENSOR_DYNAMIC_WHITE_LEVEL will also be reported.</p>
+     *
+     * @see ACAMERA_SENSOR_BLACK_LEVEL_PATTERN
+     * @see ACAMERA_SENSOR_DYNAMIC_BLACK_LEVEL
+     * @see ACAMERA_SENSOR_DYNAMIC_WHITE_LEVEL
+     */
     ACAMERA_SENSOR_OPTICAL_BLACK_REGIONS =                      // int32[4*num_regions]
             ACAMERA_SENSOR_START + 27,
+    /**
+     * <p>A per-frame dynamic black level offset for each of the color filter
+     * arrangement (CFA) mosaic channels.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraCaptureSession_captureCallback_result callbacks</li>
+     * </ul>
+     *
+     * <p>Camera sensor black levels may vary dramatically for different
+     * capture settings (e.g. ACAMERA_SENSOR_SENSITIVITY). The fixed black
+     * level reported by ACAMERA_SENSOR_BLACK_LEVEL_PATTERN may be too
+     * inaccurate to represent the actual value on a per-frame basis. The
+     * camera device internal pipeline relies on reliable black level values
+     * to process the raw images appropriately. To get the best image
+     * quality, the camera device may choose to estimate the per frame black
+     * level values either based on optically shielded black regions
+     * (ACAMERA_SENSOR_OPTICAL_BLACK_REGIONS) or its internal model.</p>
+     * <p>This key reports the camera device estimated per-frame zero light
+     * value for each of the CFA mosaic channels in the camera sensor. The
+     * ACAMERA_SENSOR_BLACK_LEVEL_PATTERN may only represent a coarse
+     * approximation of the actual black level values. This value is the
+     * black level used in camera device internal image processing pipeline
+     * and generally more accurate than the fixed black level values.
+     * However, since they are estimated values by the camera device, they
+     * may not be as accurate as the black level values calculated from the
+     * optical black pixels reported by ACAMERA_SENSOR_OPTICAL_BLACK_REGIONS.</p>
+     * <p>The values are given in the same order as channels listed for the CFA
+     * layout key (see ACAMERA_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT), i.e. the
+     * nth value given corresponds to the black level offset for the nth
+     * color channel listed in the CFA.</p>
+     * <p>This key will be available if ACAMERA_SENSOR_OPTICAL_BLACK_REGIONS is
+     * available or the camera device advertises this key via
+     * {@link android.hardware.camera2.CameraCharacteristics#getAvailableCaptureRequestKeys}.</p>
+     *
+     * @see ACAMERA_SENSOR_BLACK_LEVEL_PATTERN
+     * @see ACAMERA_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT
+     * @see ACAMERA_SENSOR_OPTICAL_BLACK_REGIONS
+     * @see ACAMERA_SENSOR_SENSITIVITY
+     */
     ACAMERA_SENSOR_DYNAMIC_BLACK_LEVEL =                        // float[4]
             ACAMERA_SENSOR_START + 28,
+    /**
+     * <p>Maximum raw value output by sensor for this frame.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraCaptureSession_captureCallback_result callbacks</li>
+     * </ul>
+     *
+     * <p>Since the ACAMERA_SENSOR_BLACK_LEVEL_PATTERN may change for different
+     * capture settings (e.g., ACAMERA_SENSOR_SENSITIVITY), the white
+     * level will change accordingly. This key is similar to
+     * ACAMERA_SENSOR_INFO_WHITE_LEVEL, but specifies the camera device
+     * estimated white level for each frame.</p>
+     * <p>This key will be available if ACAMERA_SENSOR_OPTICAL_BLACK_REGIONS is
+     * available or the camera device advertises this key via
+     * {@link android.hardware.camera2.CameraCharacteristics#getAvailableCaptureRequestKeys}.</p>
+     *
+     * @see ACAMERA_SENSOR_BLACK_LEVEL_PATTERN
+     * @see ACAMERA_SENSOR_INFO_WHITE_LEVEL
+     * @see ACAMERA_SENSOR_OPTICAL_BLACK_REGIONS
+     * @see ACAMERA_SENSOR_SENSITIVITY
+     */
     ACAMERA_SENSOR_DYNAMIC_WHITE_LEVEL =                        // int32
             ACAMERA_SENSOR_START + 29,
     ACAMERA_SENSOR_END,
 
+    /**
+     * <p>The area of the image sensor which corresponds to active pixels after any geometric
+     * distortion correction has been applied.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraManager_getCameraCharacteristics</li>
+     * </ul>
+     *
+     * <p>This is the rectangle representing the size of the active region of the sensor (i.e.
+     * the region that actually receives light from the scene) after any geometric correction
+     * has been applied, and should be treated as the maximum size in pixels of any of the
+     * image output formats aside from the raw formats.</p>
+     * <p>This rectangle is defined relative to the full pixel array; (0,0) is the top-left of
+     * the full pixel array, and the size of the full pixel array is given by
+     * ACAMERA_SENSOR_INFO_PIXEL_ARRAY_SIZE.</p>
+     * <p>The coordinate system for most other keys that list pixel coordinates, including
+     * ACAMERA_SCALER_CROP_REGION, is defined relative to the active array rectangle given in
+     * this field, with <code>(0, 0)</code> being the top-left of this rectangle.</p>
+     * <p>The active array may be smaller than the full pixel array, since the full array may
+     * include black calibration pixels or other inactive regions, and geometric correction
+     * resulting in scaling or cropping may have been applied.</p>
+     *
+     * @see ACAMERA_SCALER_CROP_REGION
+     * @see ACAMERA_SENSOR_INFO_PIXEL_ARRAY_SIZE
+     */
     ACAMERA_SENSOR_INFO_ACTIVE_ARRAY_SIZE =                     // int32[4]
             ACAMERA_SENSOR_INFO_START,
+    /**
+     * <p>Range of sensitivities for ACAMERA_SENSOR_SENSITIVITY supported by this
+     * camera device.</p>
+     *
+     * @see ACAMERA_SENSOR_SENSITIVITY
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraManager_getCameraCharacteristics</li>
+     * </ul>
+     *
+     * <p>The values are the standard ISO sensitivity values,
+     * as defined in ISO 12232:2006.</p>
+     */
     ACAMERA_SENSOR_INFO_SENSITIVITY_RANGE =                     // int32[2]
             ACAMERA_SENSOR_INFO_START + 1,
+    /**
+     * <p>The arrangement of color filters on sensor;
+     * represents the colors in the top-left 2x2 section of
+     * the sensor, in reading order.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraManager_getCameraCharacteristics</li>
+     * </ul>
+     *
+     * <p>None</p>
+     */
     ACAMERA_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT =              // byte (enum)
             ACAMERA_SENSOR_INFO_START + 2,
+    /**
+     * <p>The range of image exposure times for ACAMERA_SENSOR_EXPOSURE_TIME supported
+     * by this camera device.</p>
+     *
+     * @see ACAMERA_SENSOR_EXPOSURE_TIME
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraManager_getCameraCharacteristics</li>
+     * </ul>
+     *
+     * <p>None</p>
+     */
     ACAMERA_SENSOR_INFO_EXPOSURE_TIME_RANGE =                   // int64[2]
             ACAMERA_SENSOR_INFO_START + 3,
+    /**
+     * <p>The maximum possible frame duration (minimum frame rate) for
+     * ACAMERA_SENSOR_FRAME_DURATION that is supported this camera device.</p>
+     *
+     * @see ACAMERA_SENSOR_FRAME_DURATION
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraManager_getCameraCharacteristics</li>
+     * </ul>
+     *
+     * <p>Attempting to use frame durations beyond the maximum will result in the frame
+     * duration being clipped to the maximum. See that control for a full definition of frame
+     * durations.</p>
+     * <p>Refer to {@link
+     * android.hardware.camera2.params.StreamConfigurationMap#getOutputMinFrameDuration}
+     * for the minimum frame duration values.</p>
+     */
     ACAMERA_SENSOR_INFO_MAX_FRAME_DURATION =                    // int64
             ACAMERA_SENSOR_INFO_START + 4,
+    /**
+     * <p>The physical dimensions of the full pixel
+     * array.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraManager_getCameraCharacteristics</li>
+     * </ul>
+     *
+     * <p>This is the physical size of the sensor pixel
+     * array defined by ACAMERA_SENSOR_INFO_PIXEL_ARRAY_SIZE.</p>
+     *
+     * @see ACAMERA_SENSOR_INFO_PIXEL_ARRAY_SIZE
+     */
     ACAMERA_SENSOR_INFO_PHYSICAL_SIZE =                         // float[2]
             ACAMERA_SENSOR_INFO_START + 5,
+    /**
+     * <p>Dimensions of the full pixel array, possibly
+     * including black calibration pixels.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraManager_getCameraCharacteristics</li>
+     * </ul>
+     *
+     * <p>The pixel count of the full pixel array of the image sensor, which covers
+     * ACAMERA_SENSOR_INFO_PHYSICAL_SIZE area.  This represents the full pixel dimensions of
+     * the raw buffers produced by this sensor.</p>
+     * <p>If a camera device supports raw sensor formats, either this or
+     * ACAMERA_SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE is the maximum dimensions for the raw
+     * output formats listed in android.scaler.streamConfigurationMap (this depends on
+     * whether or not the image sensor returns buffers containing pixels that are not
+     * part of the active array region for blacklevel calibration or other purposes).</p>
+     * <p>Some parts of the full pixel array may not receive light from the scene,
+     * or be otherwise inactive.  The ACAMERA_SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE key
+     * defines the rectangle of active pixels that will be included in processed image
+     * formats.</p>
+     *
+     * @see ACAMERA_SENSOR_INFO_PHYSICAL_SIZE
+     * @see ACAMERA_SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE
+     */
     ACAMERA_SENSOR_INFO_PIXEL_ARRAY_SIZE =                      // int32[2]
             ACAMERA_SENSOR_INFO_START + 6,
+    /**
+     * <p>Maximum raw value output by sensor.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraManager_getCameraCharacteristics</li>
+     * </ul>
+     *
+     * <p>This specifies the fully-saturated encoding level for the raw
+     * sample values from the sensor.  This is typically caused by the
+     * sensor becoming highly non-linear or clipping. The minimum for
+     * each channel is specified by the offset in the
+     * ACAMERA_SENSOR_BLACK_LEVEL_PATTERN key.</p>
+     * <p>The white level is typically determined either by sensor bit depth
+     * (8-14 bits is expected), or by the point where the sensor response
+     * becomes too non-linear to be useful.  The default value for this is
+     * maximum representable value for a 16-bit raw sample (2^16 - 1).</p>
+     * <p>The white level values of captured images may vary for different
+     * capture settings (e.g., ACAMERA_SENSOR_SENSITIVITY). This key
+     * represents a coarse approximation for such case. It is recommended
+     * to use ACAMERA_SENSOR_DYNAMIC_WHITE_LEVEL for captures when supported
+     * by the camera device, which provides more accurate white level values.</p>
+     *
+     * @see ACAMERA_SENSOR_BLACK_LEVEL_PATTERN
+     * @see ACAMERA_SENSOR_DYNAMIC_WHITE_LEVEL
+     * @see ACAMERA_SENSOR_SENSITIVITY
+     */
     ACAMERA_SENSOR_INFO_WHITE_LEVEL =                           // int32
             ACAMERA_SENSOR_INFO_START + 7,
+    /**
+     * <p>The time base source for sensor capture start timestamps.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraManager_getCameraCharacteristics</li>
+     * </ul>
+     *
+     * <p>The timestamps provided for captures are always in nanoseconds and monotonic, but
+     * may not based on a time source that can be compared to other system time sources.</p>
+     * <p>This characteristic defines the source for the timestamps, and therefore whether they
+     * can be compared against other system time sources/timestamps.</p>
+     */
     ACAMERA_SENSOR_INFO_TIMESTAMP_SOURCE =                      // byte (enum)
             ACAMERA_SENSOR_INFO_START + 8,
+    /**
+     * <p>Whether the RAW images output from this camera device are subject to
+     * lens shading correction.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraManager_getCameraCharacteristics</li>
+     * </ul>
+     *
+     * <p>If TRUE, all images produced by the camera device in the RAW image formats will
+     * have lens shading correction already applied to it. If FALSE, the images will
+     * not be adjusted for lens shading correction.
+     * See android.request.maxNumOutputRaw for a list of RAW image formats.</p>
+     * <p>This key will be <code>null</code> for all devices do not report this information.
+     * Devices with RAW capability will always report this information in this key.</p>
+     */
     ACAMERA_SENSOR_INFO_LENS_SHADING_APPLIED =                  // byte (enum)
             ACAMERA_SENSOR_INFO_START + 9,
+    /**
+     * <p>The area of the image sensor which corresponds to active pixels prior to the
+     * application of any geometric distortion correction.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraManager_getCameraCharacteristics</li>
+     * </ul>
+     *
+     * <p>This is the rectangle representing the size of the active region of the sensor (i.e.
+     * the region that actually receives light from the scene) before any geometric correction
+     * has been applied, and should be treated as the active region rectangle for any of the
+     * raw formats.  All metadata associated with raw processing (e.g. the lens shading
+     * correction map, and radial distortion fields) treats the top, left of this rectangle as
+     * the origin, (0,0).</p>
+     * <p>The size of this region determines the maximum field of view and the maximum number of
+     * pixels that an image from this sensor can contain, prior to the application of
+     * geometric distortion correction. The effective maximum pixel dimensions of a
+     * post-distortion-corrected image is given by the ACAMERA_SENSOR_INFO_ACTIVE_ARRAY_SIZE
+     * field, and the effective maximum field of view for a post-distortion-corrected image
+     * can be calculated by applying the geometric distortion correction fields to this
+     * rectangle, and cropping to the rectangle given in ACAMERA_SENSOR_INFO_ACTIVE_ARRAY_SIZE.</p>
+     * <p>E.g. to calculate position of a pixel, (x,y), in a processed YUV output image with the
+     * dimensions in ACAMERA_SENSOR_INFO_ACTIVE_ARRAY_SIZE given the position of a pixel,
+     * (x', y'), in the raw pixel array with dimensions give in
+     * ACAMERA_SENSOR_INFO_PIXEL_ARRAY_SIZE:</p>
+     * <ol>
+     * <li>Choose a pixel (x', y') within the active array region of the raw buffer given in
+     * ACAMERA_SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE, otherwise this pixel is considered
+     * to be outside of the FOV, and will not be shown in the processed output image.</li>
+     * <li>Apply geometric distortion correction to get the post-distortion pixel coordinate,
+     * (x_i, y_i). When applying geometric correction metadata, note that metadata for raw
+     * buffers is defined relative to the top, left of the
+     * ACAMERA_SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE rectangle.</li>
+     * <li>If the resulting corrected pixel coordinate is within the region given in
+     * ACAMERA_SENSOR_INFO_ACTIVE_ARRAY_SIZE, then the position of this pixel in the
+     * processed output image buffer is <code>(x_i - activeArray.left, y_i - activeArray.top)</code>,
+     * when the top, left coordinate of that buffer is treated as (0, 0).</li>
+     * </ol>
+     * <p>Thus, for pixel x',y' = (25, 25) on a sensor where ACAMERA_SENSOR_INFO_PIXEL_ARRAY_SIZE
+     * is (100,100), ACAMERA_SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE is (10, 10, 100, 100),
+     * ACAMERA_SENSOR_INFO_ACTIVE_ARRAY_SIZE is (20, 20, 80, 80), and the geometric distortion
+     * correction doesn't change the pixel coordinate, the resulting pixel selected in
+     * pixel coordinates would be x,y = (25, 25) relative to the top,left of the raw buffer
+     * with dimensions given in ACAMERA_SENSOR_INFO_PIXEL_ARRAY_SIZE, and would be (5, 5)
+     * relative to the top,left of post-processed YUV output buffer with dimensions given in
+     * ACAMERA_SENSOR_INFO_ACTIVE_ARRAY_SIZE.</p>
+     * <p>The currently supported fields that correct for geometric distortion are:</p>
+     * <ol>
+     * <li>ACAMERA_LENS_RADIAL_DISTORTION.</li>
+     * </ol>
+     * <p>If all of the geometric distortion fields are no-ops, this rectangle will be the same
+     * as the post-distortion-corrected rectangle given in
+     * ACAMERA_SENSOR_INFO_ACTIVE_ARRAY_SIZE.</p>
+     * <p>This rectangle is defined relative to the full pixel array; (0,0) is the top-left of
+     * the full pixel array, and the size of the full pixel array is given by
+     * ACAMERA_SENSOR_INFO_PIXEL_ARRAY_SIZE.</p>
+     * <p>The pre-correction active array may be smaller than the full pixel array, since the
+     * full array may include black calibration pixels or other inactive regions.</p>
+     *
+     * @see ACAMERA_LENS_RADIAL_DISTORTION
+     * @see ACAMERA_SENSOR_INFO_ACTIVE_ARRAY_SIZE
+     * @see ACAMERA_SENSOR_INFO_PIXEL_ARRAY_SIZE
+     * @see ACAMERA_SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE
+     */
     ACAMERA_SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE =      // int32[4]
             ACAMERA_SENSOR_INFO_START + 10,
     ACAMERA_SENSOR_INFO_END,
 
+    /**
+     * <p>Quality of lens shading correction applied
+     * to the image data.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraCaptureSession_captureCallback_result callbacks</li>
+     *   <li>ACaptureRequest</li>
+     * </ul>
+     *
+     * <p>When set to OFF mode, no lens shading correction will be applied by the
+     * camera device, and an identity lens shading map data will be provided
+     * if <code>ACAMERA_STATISTICS_LENS_SHADING_MAP_MODE == ON</code>. For example, for lens
+     * shading map with size of <code>[ 4, 3 ]</code>,
+     * the output ACAMERA_STATISTICS_LENS_SHADING_CORRECTION_MAP for this case will be an identity
+     * map shown below:</p>
+     * <pre><code>[ 1.0, 1.0, 1.0, 1.0,  1.0, 1.0, 1.0, 1.0,
+     *  1.0, 1.0, 1.0, 1.0,  1.0, 1.0, 1.0, 1.0,
+     *  1.0, 1.0, 1.0, 1.0,  1.0, 1.0, 1.0, 1.0,
+     *  1.0, 1.0, 1.0, 1.0,  1.0, 1.0, 1.0, 1.0,
+     *  1.0, 1.0, 1.0, 1.0,  1.0, 1.0, 1.0, 1.0,
+     *  1.0, 1.0, 1.0, 1.0,  1.0, 1.0, 1.0, 1.0 ]
+     * </code></pre>
+     * <p>When set to other modes, lens shading correction will be applied by the camera
+     * device. Applications can request lens shading map data by setting
+     * ACAMERA_STATISTICS_LENS_SHADING_MAP_MODE to ON, and then the camera device will provide lens
+     * shading map data in ACAMERA_STATISTICS_LENS_SHADING_CORRECTION_MAP; the returned shading map
+     * data will be the one applied by the camera device for this capture request.</p>
+     * <p>The shading map data may depend on the auto-exposure (AE) and AWB statistics, therefore
+     * the reliability of the map data may be affected by the AE and AWB algorithms. When AE and
+     * AWB are in AUTO modes(ACAMERA_CONTROL_AE_MODE <code>!=</code> OFF and ACAMERA_CONTROL_AWB_MODE <code>!=</code>
+     * OFF), to get best results, it is recommended that the applications wait for the AE and AWB
+     * to be converged before using the returned shading map data.</p>
+     *
+     * @see ACAMERA_CONTROL_AE_MODE
+     * @see ACAMERA_CONTROL_AWB_MODE
+     * @see ACAMERA_STATISTICS_LENS_SHADING_CORRECTION_MAP
+     * @see ACAMERA_STATISTICS_LENS_SHADING_MAP_MODE
+     */
     ACAMERA_SHADING_MODE =                                      // byte (enum)
             ACAMERA_SHADING_START,
+    /**
+     * <p>List of lens shading modes for ACAMERA_SHADING_MODE that are supported by this camera device.</p>
+     *
+     * @see ACAMERA_SHADING_MODE
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraManager_getCameraCharacteristics</li>
+     * </ul>
+     *
+     * <p>This list contains lens shading modes that can be set for the camera device.
+     * Camera devices that support the MANUAL_POST_PROCESSING capability will always
+     * list OFF and FAST mode. This includes all FULL level devices.
+     * LEGACY devices will always only support FAST mode.</p>
+     */
     ACAMERA_SHADING_AVAILABLE_MODES =                           // byte[n]
             ACAMERA_SHADING_START + 2,
     ACAMERA_SHADING_END,
 
+    /**
+     * <p>Operating mode for the face detector
+     * unit.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraCaptureSession_captureCallback_result callbacks</li>
+     *   <li>ACaptureRequest</li>
+     * </ul>
+     *
+     * <p>Whether face detection is enabled, and whether it
+     * should output just the basic fields or the full set of
+     * fields.</p>
+     */
     ACAMERA_STATISTICS_FACE_DETECT_MODE =                       // byte (enum)
             ACAMERA_STATISTICS_START,
+    /**
+     * <p>Operating mode for hot pixel map generation.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraCaptureSession_captureCallback_result callbacks</li>
+     *   <li>ACaptureRequest</li>
+     * </ul>
+     *
+     * <p>If set to <code>true</code>, a hot pixel map is returned in ACAMERA_STATISTICS_HOT_PIXEL_MAP.
+     * If set to <code>false</code>, no hot pixel map will be returned.</p>
+     *
+     * @see ACAMERA_STATISTICS_HOT_PIXEL_MAP
+     */
     ACAMERA_STATISTICS_HOT_PIXEL_MAP_MODE =                     // byte (enum)
             ACAMERA_STATISTICS_START + 3,
+    /**
+     * <p>List of unique IDs for detected faces.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraCaptureSession_captureCallback_result callbacks</li>
+     * </ul>
+     *
+     * <p>Each detected face is given a unique ID that is valid for as long as the face is visible
+     * to the camera device.  A face that leaves the field of view and later returns may be
+     * assigned a new ID.</p>
+     * <p>Only available if ACAMERA_STATISTICS_FACE_DETECT_MODE == FULL</p>
+     *
+     * @see ACAMERA_STATISTICS_FACE_DETECT_MODE
+     */
     ACAMERA_STATISTICS_FACE_IDS =                               // int32[n]
             ACAMERA_STATISTICS_START + 4,
+    /**
+     * <p>List of landmarks for detected
+     * faces.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraCaptureSession_captureCallback_result callbacks</li>
+     * </ul>
+     *
+     * <p>The coordinate system is that of ACAMERA_SENSOR_INFO_ACTIVE_ARRAY_SIZE, with
+     * <code>(0, 0)</code> being the top-left pixel of the active array.</p>
+     * <p>Only available if ACAMERA_STATISTICS_FACE_DETECT_MODE == FULL</p>
+     *
+     * @see ACAMERA_SENSOR_INFO_ACTIVE_ARRAY_SIZE
+     * @see ACAMERA_STATISTICS_FACE_DETECT_MODE
+     */
     ACAMERA_STATISTICS_FACE_LANDMARKS =                         // int32[n*6]
             ACAMERA_STATISTICS_START + 5,
+    /**
+     * <p>List of the bounding rectangles for detected
+     * faces.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraCaptureSession_captureCallback_result callbacks</li>
+     * </ul>
+     *
+     * <p>The coordinate system is that of ACAMERA_SENSOR_INFO_ACTIVE_ARRAY_SIZE, with
+     * <code>(0, 0)</code> being the top-left pixel of the active array.</p>
+     * <p>Only available if ACAMERA_STATISTICS_FACE_DETECT_MODE != OFF</p>
+     *
+     * @see ACAMERA_SENSOR_INFO_ACTIVE_ARRAY_SIZE
+     * @see ACAMERA_STATISTICS_FACE_DETECT_MODE
+     */
     ACAMERA_STATISTICS_FACE_RECTANGLES =                        // int32[n*4]
             ACAMERA_STATISTICS_START + 6,
+    /**
+     * <p>List of the face confidence scores for
+     * detected faces</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraCaptureSession_captureCallback_result callbacks</li>
+     * </ul>
+     *
+     * <p>Only available if ACAMERA_STATISTICS_FACE_DETECT_MODE != OFF.</p>
+     *
+     * @see ACAMERA_STATISTICS_FACE_DETECT_MODE
+     */
     ACAMERA_STATISTICS_FACE_SCORES =                            // byte[n]
             ACAMERA_STATISTICS_START + 7,
+    /**
+     * <p>The shading map is a low-resolution floating-point map
+     * that lists the coefficients used to correct for vignetting, for each
+     * Bayer color channel.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraCaptureSession_captureCallback_result callbacks</li>
+     * </ul>
+     *
+     * <p>The least shaded section of the image should have a gain factor
+     * of 1; all other sections should have gains above 1.</p>
+     * <p>When ACAMERA_COLOR_CORRECTION_MODE = TRANSFORM_MATRIX, the map
+     * must take into account the colorCorrection settings.</p>
+     * <p>The shading map is for the entire active pixel array, and is not
+     * affected by the crop region specified in the request. Each shading map
+     * entry is the value of the shading compensation map over a specific
+     * pixel on the sensor.  Specifically, with a (N x M) resolution shading
+     * map, and an active pixel array size (W x H), shading map entry
+     * (x,y) ϵ (0 ... N-1, 0 ... M-1) is the value of the shading map at
+     * pixel ( ((W-1)/(N-1)) * x, ((H-1)/(M-1)) * y) for the four color channels.
+     * The map is assumed to be bilinearly interpolated between the sample points.</p>
+     * <p>The channel order is [R, Geven, Godd, B], where Geven is the green
+     * channel for the even rows of a Bayer pattern, and Godd is the odd rows.
+     * The shading map is stored in a fully interleaved format.</p>
+     * <p>The shading map should have on the order of 30-40 rows and columns,
+     * and must be smaller than 64x64.</p>
+     * <p>As an example, given a very small map defined as:</p>
+     * <pre><code>width,height = [ 4, 3 ]
+     * values =
+     * [ 1.3, 1.2, 1.15, 1.2,  1.2, 1.2, 1.15, 1.2,
+     *     1.1, 1.2, 1.2, 1.2,  1.3, 1.2, 1.3, 1.3,
+     *   1.2, 1.2, 1.25, 1.1,  1.1, 1.1, 1.1, 1.0,
+     *     1.0, 1.0, 1.0, 1.0,  1.2, 1.3, 1.25, 1.2,
+     *   1.3, 1.2, 1.2, 1.3,   1.2, 1.15, 1.1, 1.2,
+     *     1.2, 1.1, 1.0, 1.2,  1.3, 1.15, 1.2, 1.3 ]
+     * </code></pre>
+     * <p>The low-resolution scaling map images for each channel are
+     * (displayed using nearest-neighbor interpolation):</p>
+     * <p><img alt="Red lens shading map" src="../../../../images/camera2/metadata/android.statistics.lensShadingMap/red_shading.png" />
+     * <img alt="Green (even rows) lens shading map" src="../../../../images/camera2/metadata/android.statistics.lensShadingMap/green_e_shading.png" />
+     * <img alt="Green (odd rows) lens shading map" src="../../../../images/camera2/metadata/android.statistics.lensShadingMap/green_o_shading.png" />
+     * <img alt="Blue lens shading map" src="../../../../images/camera2/metadata/android.statistics.lensShadingMap/blue_shading.png" /></p>
+     * <p>As a visualization only, inverting the full-color map to recover an
+     * image of a gray wall (using bicubic interpolation for visual quality) as captured by the sensor gives:</p>
+     * <p><img alt="Image of a uniform white wall (inverse shading map)" src="../../../../images/camera2/metadata/android.statistics.lensShadingMap/inv_shading.png" /></p>
+     *
+     * @see ACAMERA_COLOR_CORRECTION_MODE
+     */
     ACAMERA_STATISTICS_LENS_SHADING_CORRECTION_MAP =            // byte
             ACAMERA_STATISTICS_START + 10,
+    /**
+     * <p>The shading map is a low-resolution floating-point map
+     * that lists the coefficients used to correct for vignetting, for each
+     * Bayer color channel of RAW image data.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraCaptureSession_captureCallback_result callbacks</li>
+     * </ul>
+     *
+     * <p>The least shaded section of the image should have a gain factor
+     * of 1; all other sections should have gains above 1.</p>
+     * <p>When ACAMERA_COLOR_CORRECTION_MODE = TRANSFORM_MATRIX, the map
+     * must take into account the colorCorrection settings.</p>
+     * <p>The shading map is for the entire active pixel array, and is not
+     * affected by the crop region specified in the request. Each shading map
+     * entry is the value of the shading compensation map over a specific
+     * pixel on the sensor.  Specifically, with a (N x M) resolution shading
+     * map, and an active pixel array size (W x H), shading map entry
+     * (x,y) ϵ (0 ... N-1, 0 ... M-1) is the value of the shading map at
+     * pixel ( ((W-1)/(N-1)) * x, ((H-1)/(M-1)) * y) for the four color channels.
+     * The map is assumed to be bilinearly interpolated between the sample points.</p>
+     * <p>The channel order is [R, Geven, Godd, B], where Geven is the green
+     * channel for the even rows of a Bayer pattern, and Godd is the odd rows.
+     * The shading map is stored in a fully interleaved format, and its size
+     * is provided in the camera static metadata by ACAMERA_LENS_INFO_SHADING_MAP_SIZE.</p>
+     * <p>The shading map should have on the order of 30-40 rows and columns,
+     * and must be smaller than 64x64.</p>
+     * <p>As an example, given a very small map defined as:</p>
+     * <pre><code>ACAMERA_LENS_INFO_SHADING_MAP_SIZE = [ 4, 3 ]
+     * ACAMERA_STATISTICS_LENS_SHADING_MAP =
+     * [ 1.3, 1.2, 1.15, 1.2,  1.2, 1.2, 1.15, 1.2,
+     *     1.1, 1.2, 1.2, 1.2,  1.3, 1.2, 1.3, 1.3,
+     *   1.2, 1.2, 1.25, 1.1,  1.1, 1.1, 1.1, 1.0,
+     *     1.0, 1.0, 1.0, 1.0,  1.2, 1.3, 1.25, 1.2,
+     *   1.3, 1.2, 1.2, 1.3,   1.2, 1.15, 1.1, 1.2,
+     *     1.2, 1.1, 1.0, 1.2,  1.3, 1.15, 1.2, 1.3 ]
+     * </code></pre>
+     * <p>The low-resolution scaling map images for each channel are
+     * (displayed using nearest-neighbor interpolation):</p>
+     * <p><img alt="Red lens shading map" src="../../../../images/camera2/metadata/android.statistics.lensShadingMap/red_shading.png" />
+     * <img alt="Green (even rows) lens shading map" src="../../../../images/camera2/metadata/android.statistics.lensShadingMap/green_e_shading.png" />
+     * <img alt="Green (odd rows) lens shading map" src="../../../../images/camera2/metadata/android.statistics.lensShadingMap/green_o_shading.png" />
+     * <img alt="Blue lens shading map" src="../../../../images/camera2/metadata/android.statistics.lensShadingMap/blue_shading.png" /></p>
+     * <p>As a visualization only, inverting the full-color map to recover an
+     * image of a gray wall (using bicubic interpolation for visual quality)
+     * as captured by the sensor gives:</p>
+     * <p><img alt="Image of a uniform white wall (inverse shading map)" src="../../../../images/camera2/metadata/android.statistics.lensShadingMap/inv_shading.png" /></p>
+     * <p>Note that the RAW image data might be subject to lens shading
+     * correction not reported on this map. Query
+     * ACAMERA_SENSOR_INFO_LENS_SHADING_APPLIED to see if RAW image data has subject
+     * to lens shading correction. If ACAMERA_SENSOR_INFO_LENS_SHADING_APPLIED
+     * is TRUE, the RAW image data is subject to partial or full lens shading
+     * correction. In the case full lens shading correction is applied to RAW
+     * images, the gain factor map reported in this key will contain all 1.0 gains.
+     * In other words, the map reported in this key is the remaining lens shading
+     * that needs to be applied on the RAW image to get images without lens shading
+     * artifacts. See android.request.maxNumOutputRaw for a list of RAW image
+     * formats.</p>
+     *
+     * @see ACAMERA_COLOR_CORRECTION_MODE
+     * @see ACAMERA_LENS_INFO_SHADING_MAP_SIZE
+     * @see ACAMERA_SENSOR_INFO_LENS_SHADING_APPLIED
+     * @see ACAMERA_STATISTICS_LENS_SHADING_MAP
+     */
     ACAMERA_STATISTICS_LENS_SHADING_MAP =                       // float[4*n*m]
             ACAMERA_STATISTICS_START + 11,
+    /**
+     * <p>The camera device estimated scene illumination lighting
+     * frequency.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraCaptureSession_captureCallback_result callbacks</li>
+     * </ul>
+     *
+     * <p>Many light sources, such as most fluorescent lights, flicker at a rate
+     * that depends on the local utility power standards. This flicker must be
+     * accounted for by auto-exposure routines to avoid artifacts in captured images.
+     * The camera device uses this entry to tell the application what the scene
+     * illuminant frequency is.</p>
+     * <p>When manual exposure control is enabled
+     * (<code>ACAMERA_CONTROL_AE_MODE == OFF</code> or <code>ACAMERA_CONTROL_MODE ==
+     * OFF</code>), the ACAMERA_CONTROL_AE_ANTIBANDING_MODE doesn't perform
+     * antibanding, and the application can ensure it selects
+     * exposure times that do not cause banding issues by looking
+     * into this metadata field. See
+     * ACAMERA_CONTROL_AE_ANTIBANDING_MODE for more details.</p>
+     * <p>Reports NONE if there doesn't appear to be flickering illumination.</p>
+     *
+     * @see ACAMERA_CONTROL_AE_ANTIBANDING_MODE
+     * @see ACAMERA_CONTROL_AE_MODE
+     * @see ACAMERA_CONTROL_MODE
+     */
     ACAMERA_STATISTICS_SCENE_FLICKER =                          // byte (enum)
             ACAMERA_STATISTICS_START + 14,
+    /**
+     * <p>List of <code>(x, y)</code> coordinates of hot/defective pixels on the sensor.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraCaptureSession_captureCallback_result callbacks</li>
+     * </ul>
+     *
+     * <p>A coordinate <code>(x, y)</code> must lie between <code>(0, 0)</code>, and
+     * <code>(width - 1, height - 1)</code> (inclusive), which are the top-left and
+     * bottom-right of the pixel array, respectively. The width and
+     * height dimensions are given in ACAMERA_SENSOR_INFO_PIXEL_ARRAY_SIZE.
+     * This may include hot pixels that lie outside of the active array
+     * bounds given by ACAMERA_SENSOR_INFO_ACTIVE_ARRAY_SIZE.</p>
+     *
+     * @see ACAMERA_SENSOR_INFO_ACTIVE_ARRAY_SIZE
+     * @see ACAMERA_SENSOR_INFO_PIXEL_ARRAY_SIZE
+     */
     ACAMERA_STATISTICS_HOT_PIXEL_MAP =                          // int32[2*n]
             ACAMERA_STATISTICS_START + 15,
+    /**
+     * <p>Whether the camera device will output the lens
+     * shading map in output result metadata.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraCaptureSession_captureCallback_result callbacks</li>
+     *   <li>ACaptureRequest</li>
+     * </ul>
+     *
+     * <p>When set to ON,
+     * ACAMERA_STATISTICS_LENS_SHADING_MAP will be provided in
+     * the output result metadata.</p>
+     * <p>ON is always supported on devices with the RAW capability.</p>
+     *
+     * @see ACAMERA_STATISTICS_LENS_SHADING_MAP
+     */
     ACAMERA_STATISTICS_LENS_SHADING_MAP_MODE =                  // byte (enum)
             ACAMERA_STATISTICS_START + 16,
     ACAMERA_STATISTICS_END,
 
+    /**
+     * <p>List of face detection modes for ACAMERA_STATISTICS_FACE_DETECT_MODE that are
+     * supported by this camera device.</p>
+     *
+     * @see ACAMERA_STATISTICS_FACE_DETECT_MODE
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraManager_getCameraCharacteristics</li>
+     * </ul>
+     *
+     * <p>OFF is always supported.</p>
+     */
     ACAMERA_STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES =       // byte[n]
             ACAMERA_STATISTICS_INFO_START,
+    /**
+     * <p>The maximum number of simultaneously detectable
+     * faces.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraManager_getCameraCharacteristics</li>
+     * </ul>
+     *
+     * <p>None</p>
+     */
     ACAMERA_STATISTICS_INFO_MAX_FACE_COUNT =                    // int32
             ACAMERA_STATISTICS_INFO_START + 2,
+    /**
+     * <p>List of hot pixel map output modes for ACAMERA_STATISTICS_HOT_PIXEL_MAP_MODE that are
+     * supported by this camera device.</p>
+     *
+     * @see ACAMERA_STATISTICS_HOT_PIXEL_MAP_MODE
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraManager_getCameraCharacteristics</li>
+     * </ul>
+     *
+     * <p>If no hotpixel map output is available for this camera device, this will contain only
+     * <code>false</code>.</p>
+     * <p>ON is always supported on devices with the RAW capability.</p>
+     */
     ACAMERA_STATISTICS_INFO_AVAILABLE_HOT_PIXEL_MAP_MODES =     // byte[n]
             ACAMERA_STATISTICS_INFO_START + 6,
+    /**
+     * <p>List of lens shading map output modes for ACAMERA_STATISTICS_LENS_SHADING_MAP_MODE that
+     * are supported by this camera device.</p>
+     *
+     * @see ACAMERA_STATISTICS_LENS_SHADING_MAP_MODE
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraManager_getCameraCharacteristics</li>
+     * </ul>
+     *
+     * <p>If no lens shading map output is available for this camera device, this key will
+     * contain only OFF.</p>
+     * <p>ON is always supported on devices with the RAW capability.
+     * LEGACY mode devices will always only support OFF.</p>
+     */
     ACAMERA_STATISTICS_INFO_AVAILABLE_LENS_SHADING_MAP_MODES =  // byte[n]
             ACAMERA_STATISTICS_INFO_START + 7,
     ACAMERA_STATISTICS_INFO_END,
 
+    /**
+     * <p>Tonemapping / contrast / gamma curve for the blue
+     * channel, to use when ACAMERA_TONEMAP_MODE is
+     * CONTRAST_CURVE.</p>
+     *
+     * @see ACAMERA_TONEMAP_MODE
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraCaptureSession_captureCallback_result callbacks</li>
+     *   <li>ACaptureRequest</li>
+     * </ul>
+     *
+     * <p>See ACAMERA_TONEMAP_CURVE_RED for more details.</p>
+     *
+     * @see ACAMERA_TONEMAP_CURVE_RED
+     */
     ACAMERA_TONEMAP_CURVE_BLUE =                                // float[n*2]
             ACAMERA_TONEMAP_START,
+    /**
+     * <p>Tonemapping / contrast / gamma curve for the green
+     * channel, to use when ACAMERA_TONEMAP_MODE is
+     * CONTRAST_CURVE.</p>
+     *
+     * @see ACAMERA_TONEMAP_MODE
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraCaptureSession_captureCallback_result callbacks</li>
+     *   <li>ACaptureRequest</li>
+     * </ul>
+     *
+     * <p>See ACAMERA_TONEMAP_CURVE_RED for more details.</p>
+     *
+     * @see ACAMERA_TONEMAP_CURVE_RED
+     */
     ACAMERA_TONEMAP_CURVE_GREEN =                               // float[n*2]
             ACAMERA_TONEMAP_START + 1,
+    /**
+     * <p>Tonemapping / contrast / gamma curve for the red
+     * channel, to use when ACAMERA_TONEMAP_MODE is
+     * CONTRAST_CURVE.</p>
+     *
+     * @see ACAMERA_TONEMAP_MODE
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraCaptureSession_captureCallback_result callbacks</li>
+     *   <li>ACaptureRequest</li>
+     * </ul>
+     *
+     * <p>Each channel's curve is defined by an array of control points:</p>
+     * <pre><code>ACAMERA_TONEMAP_CURVE_RED =
+     *   [ P0in, P0out, P1in, P1out, P2in, P2out, P3in, P3out, ..., PNin, PNout ]
+     * 2 &lt;= N &lt;= ACAMERA_TONEMAP_MAX_CURVE_POINTS</code></pre>
+     * <p>These are sorted in order of increasing <code>Pin</code>; it is
+     * required that input values 0.0 and 1.0 are included in the list to
+     * define a complete mapping. For input values between control points,
+     * the camera device must linearly interpolate between the control
+     * points.</p>
+     * <p>Each curve can have an independent number of points, and the number
+     * of points can be less than max (that is, the request doesn't have to
+     * always provide a curve with number of points equivalent to
+     * ACAMERA_TONEMAP_MAX_CURVE_POINTS).</p>
+     * <p>A few examples, and their corresponding graphical mappings; these
+     * only specify the red channel and the precision is limited to 4
+     * digits, for conciseness.</p>
+     * <p>Linear mapping:</p>
+     * <pre><code>ACAMERA_TONEMAP_CURVE_RED = [ 0, 0, 1.0, 1.0 ]
+     * </code></pre>
+     * <p><img alt="Linear mapping curve" src="../../../../images/camera2/metadata/android.tonemap.curveRed/linear_tonemap.png" /></p>
+     * <p>Invert mapping:</p>
+     * <pre><code>ACAMERA_TONEMAP_CURVE_RED = [ 0, 1.0, 1.0, 0 ]
+     * </code></pre>
+     * <p><img alt="Inverting mapping curve" src="../../../../images/camera2/metadata/android.tonemap.curveRed/inverse_tonemap.png" /></p>
+     * <p>Gamma 1/2.2 mapping, with 16 control points:</p>
+     * <pre><code>ACAMERA_TONEMAP_CURVE_RED = [
+     *   0.0000, 0.0000, 0.0667, 0.2920, 0.1333, 0.4002, 0.2000, 0.4812,
+     *   0.2667, 0.5484, 0.3333, 0.6069, 0.4000, 0.6594, 0.4667, 0.7072,
+     *   0.5333, 0.7515, 0.6000, 0.7928, 0.6667, 0.8317, 0.7333, 0.8685,
+     *   0.8000, 0.9035, 0.8667, 0.9370, 0.9333, 0.9691, 1.0000, 1.0000 ]
+     * </code></pre>
+     * <p><img alt="Gamma = 1/2.2 tonemapping curve" src="../../../../images/camera2/metadata/android.tonemap.curveRed/gamma_tonemap.png" /></p>
+     * <p>Standard sRGB gamma mapping, per IEC 61966-2-1:1999, with 16 control points:</p>
+     * <pre><code>ACAMERA_TONEMAP_CURVE_RED = [
+     *   0.0000, 0.0000, 0.0667, 0.2864, 0.1333, 0.4007, 0.2000, 0.4845,
+     *   0.2667, 0.5532, 0.3333, 0.6125, 0.4000, 0.6652, 0.4667, 0.7130,
+     *   0.5333, 0.7569, 0.6000, 0.7977, 0.6667, 0.8360, 0.7333, 0.8721,
+     *   0.8000, 0.9063, 0.8667, 0.9389, 0.9333, 0.9701, 1.0000, 1.0000 ]
+     * </code></pre>
+     * <p><img alt="sRGB tonemapping curve" src="../../../../images/camera2/metadata/android.tonemap.curveRed/srgb_tonemap.png" /></p>
+     *
+     * @see ACAMERA_TONEMAP_CURVE_RED
+     * @see ACAMERA_TONEMAP_MAX_CURVE_POINTS
+     */
     ACAMERA_TONEMAP_CURVE_RED =                                 // float[n*2]
             ACAMERA_TONEMAP_START + 2,
+    /**
+     * <p>High-level global contrast/gamma/tonemapping control.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraCaptureSession_captureCallback_result callbacks</li>
+     *   <li>ACaptureRequest</li>
+     * </ul>
+     *
+     * <p>When switching to an application-defined contrast curve by setting
+     * ACAMERA_TONEMAP_MODE to CONTRAST_CURVE, the curve is defined
+     * per-channel with a set of <code>(in, out)</code> points that specify the
+     * mapping from input high-bit-depth pixel value to the output
+     * low-bit-depth value.  Since the actual pixel ranges of both input
+     * and output may change depending on the camera pipeline, the values
+     * are specified by normalized floating-point numbers.</p>
+     * <p>More-complex color mapping operations such as 3D color look-up
+     * tables, selective chroma enhancement, or other non-linear color
+     * transforms will be disabled when ACAMERA_TONEMAP_MODE is
+     * CONTRAST_CURVE.</p>
+     * <p>When using either FAST or HIGH_QUALITY, the camera device will
+     * emit its own tonemap curve in android.tonemap.curve.
+     * These values are always available, and as close as possible to the
+     * actually used nonlinear/nonglobal transforms.</p>
+     * <p>If a request is sent with CONTRAST_CURVE with the camera device's
+     * provided curve in FAST or HIGH_QUALITY, the image's tonemap will be
+     * roughly the same.</p>
+     *
+     * @see ACAMERA_TONEMAP_MODE
+     */
     ACAMERA_TONEMAP_MODE =                                      // byte (enum)
             ACAMERA_TONEMAP_START + 3,
+    /**
+     * <p>Maximum number of supported points in the
+     * tonemap curve that can be used for android.tonemap.curve.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraManager_getCameraCharacteristics</li>
+     * </ul>
+     *
+     * <p>If the actual number of points provided by the application (in ACAMERA_TONEMAPCURVE_*) is
+     * less than this maximum, the camera device will resample the curve to its internal
+     * representation, using linear interpolation.</p>
+     * <p>The output curves in the result metadata may have a different number
+     * of points than the input curves, and will represent the actual
+     * hardware curves used as closely as possible when linearly interpolated.</p>
+     */
     ACAMERA_TONEMAP_MAX_CURVE_POINTS =                          // int32
             ACAMERA_TONEMAP_START + 4,
+    /**
+     * <p>List of tonemapping modes for ACAMERA_TONEMAP_MODE that are supported by this camera
+     * device.</p>
+     *
+     * @see ACAMERA_TONEMAP_MODE
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraManager_getCameraCharacteristics</li>
+     * </ul>
+     *
+     * <p>Camera devices that support the MANUAL_POST_PROCESSING capability will always contain
+     * at least one of below mode combinations:</p>
+     * <ul>
+     * <li>CONTRAST_CURVE, FAST and HIGH_QUALITY</li>
+     * <li>GAMMA_VALUE, PRESET_CURVE, FAST and HIGH_QUALITY</li>
+     * </ul>
+     * <p>This includes all FULL level devices.</p>
+     */
     ACAMERA_TONEMAP_AVAILABLE_TONE_MAP_MODES =                  // byte[n]
             ACAMERA_TONEMAP_START + 5,
+    /**
+     * <p>Tonemapping curve to use when ACAMERA_TONEMAP_MODE is
+     * GAMMA_VALUE</p>
+     *
+     * @see ACAMERA_TONEMAP_MODE
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraCaptureSession_captureCallback_result callbacks</li>
+     *   <li>ACaptureRequest</li>
+     * </ul>
+     *
+     * <p>The tonemap curve will be defined the following formula:
+     * * OUT = pow(IN, 1.0 / gamma)
+     * where IN and OUT is the input pixel value scaled to range [0.0, 1.0],
+     * pow is the power function and gamma is the gamma value specified by this
+     * key.</p>
+     * <p>The same curve will be applied to all color channels. The camera device
+     * may clip the input gamma value to its supported range. The actual applied
+     * value will be returned in capture result.</p>
+     * <p>The valid range of gamma value varies on different devices, but values
+     * within [1.0, 5.0] are guaranteed not to be clipped.</p>
+     */
     ACAMERA_TONEMAP_GAMMA =                                     // float
             ACAMERA_TONEMAP_START + 6,
+    /**
+     * <p>Tonemapping curve to use when ACAMERA_TONEMAP_MODE is
+     * PRESET_CURVE</p>
+     *
+     * @see ACAMERA_TONEMAP_MODE
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraCaptureSession_captureCallback_result callbacks</li>
+     *   <li>ACaptureRequest</li>
+     * </ul>
+     *
+     * <p>The tonemap curve will be defined by specified standard.</p>
+     * <p>sRGB (approximated by 16 control points):</p>
+     * <p><img alt="sRGB tonemapping curve" src="../../../../images/camera2/metadata/android.tonemap.curveRed/srgb_tonemap.png" /></p>
+     * <p>Rec. 709 (approximated by 16 control points):</p>
+     * <p><img alt="Rec. 709 tonemapping curve" src="../../../../images/camera2/metadata/android.tonemap.curveRed/rec709_tonemap.png" /></p>
+     * <p>Note that above figures show a 16 control points approximation of preset
+     * curves. Camera devices may apply a different approximation to the curve.</p>
+     */
     ACAMERA_TONEMAP_PRESET_CURVE =                              // byte (enum)
             ACAMERA_TONEMAP_START + 7,
     ACAMERA_TONEMAP_END,
 
+    /**
+     * <p>Generally classifies the overall set of the camera device functionality.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraManager_getCameraCharacteristics</li>
+     * </ul>
+     *
+     * <p>The supported hardware level is a high-level description of the camera device's
+     * capabilities, summarizing several capabilities into one field.  Each level adds additional
+     * features to the previous one, and is always a strict superset of the previous level.
+     * The ordering is <code>LEGACY &lt; LIMITED &lt; FULL &lt; LEVEL_3</code>.</p>
+     * <p>Starting from <code>LEVEL_3</code>, the level enumerations are guaranteed to be in increasing
+     * numerical value as well. To check if a given device is at least at a given hardware level,
+     * the following code snippet can be used:</p>
+     * <pre><code>// Returns true if the device supports the required hardware level, or better.
+     * boolean isHardwareLevelSupported(CameraCharacteristics c, int requiredLevel) {
+     *     int deviceLevel = c.get(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL);
+     *     if (deviceLevel == CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY) {
+     *         return requiredLevel == deviceLevel;
+     *     }
+     *     // deviceLevel is not LEGACY, can use numerical sort
+     *     return requiredLevel &lt;= deviceLevel;
+     * }
+     * </code></pre>
+     * <p>At a high level, the levels are:</p>
+     * <ul>
+     * <li><code>LEGACY</code> devices operate in a backwards-compatibility mode for older
+     *   Android devices, and have very limited capabilities.</li>
+     * <li><code>LIMITED</code> devices represent the
+     *   baseline feature set, and may also include additional capabilities that are
+     *   subsets of <code>FULL</code>.</li>
+     * <li><code>FULL</code> devices additionally support per-frame manual control of sensor, flash, lens and
+     *   post-processing settings, and image capture at a high rate.</li>
+     * <li><code>LEVEL_3</code> devices additionally support YUV reprocessing and RAW image capture, along
+     *   with additional output stream configurations.</li>
+     * </ul>
+     * <p>See the individual level enums for full descriptions of the supported capabilities.  The
+     * ACAMERA_REQUEST_AVAILABLE_CAPABILITIES entry describes the device's capabilities at a
+     * finer-grain level, if needed. In addition, many controls have their available settings or
+     * ranges defined in individual {@link android.hardware.camera2.CameraCharacteristics} entries.</p>
+     * <p>Some features are not part of any particular hardware level or capability and must be
+     * queried separately. These include:</p>
+     * <ul>
+     * <li>Calibrated timestamps (ACAMERA_SENSOR_INFO_TIMESTAMP_SOURCE <code>==</code> REALTIME)</li>
+     * <li>Precision lens control (ACAMERA_LENS_INFO_FOCUS_DISTANCE_CALIBRATION <code>==</code> CALIBRATED)</li>
+     * <li>Face detection (ACAMERA_STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES)</li>
+     * <li>Optical or electrical image stabilization
+     *   (ACAMERA_LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION,
+     *    ACAMERA_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES)</li>
+     * </ul>
+     *
+     * @see ACAMERA_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES
+     * @see ACAMERA_LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION
+     * @see ACAMERA_LENS_INFO_FOCUS_DISTANCE_CALIBRATION
+     * @see ACAMERA_REQUEST_AVAILABLE_CAPABILITIES
+     * @see ACAMERA_SENSOR_INFO_TIMESTAMP_SOURCE
+     * @see ACAMERA_STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES
+     */
     ACAMERA_INFO_SUPPORTED_HARDWARE_LEVEL =                     // byte (enum)
             ACAMERA_INFO_START,
     ACAMERA_INFO_END,
 
+    /**
+     * <p>Whether black-level compensation is locked
+     * to its current values, or is free to vary.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraCaptureSession_captureCallback_result callbacks</li>
+     *   <li>ACaptureRequest</li>
+     * </ul>
+     *
+     * <p>Whether the black level offset was locked for this frame.  Should be
+     * ON if ACAMERA_BLACK_LEVEL_LOCK was ON in the capture request, unless
+     * a change in other capture settings forced the camera device to
+     * perform a black level reset.</p>
+     *
+     * @see ACAMERA_BLACK_LEVEL_LOCK
+     */
     ACAMERA_BLACK_LEVEL_LOCK =                                  // byte (enum)
             ACAMERA_BLACK_LEVEL_START,
     ACAMERA_BLACK_LEVEL_END,
 
+    /**
+     * <p>The frame number corresponding to the last request
+     * with which the output result (metadata + buffers) has been fully
+     * synchronized.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraCaptureSession_captureCallback_result callbacks</li>
+     * </ul>
+     *
+     * <p>When a request is submitted to the camera device, there is usually a
+     * delay of several frames before the controls get applied. A camera
+     * device may either choose to account for this delay by implementing a
+     * pipeline and carefully submit well-timed atomic control updates, or
+     * it may start streaming control changes that span over several frame
+     * boundaries.</p>
+     * <p>In the latter case, whenever a request's settings change relative to
+     * the previous submitted request, the full set of changes may take
+     * multiple frame durations to fully take effect. Some settings may
+     * take effect sooner (in less frame durations) than others.</p>
+     * <p>While a set of control changes are being propagated, this value
+     * will be CONVERGING.</p>
+     * <p>Once it is fully known that a set of control changes have been
+     * finished propagating, and the resulting updated control settings
+     * have been read back by the camera device, this value will be set
+     * to a non-negative frame number (corresponding to the request to
+     * which the results have synchronized to).</p>
+     * <p>Older camera device implementations may not have a way to detect
+     * when all camera controls have been applied, and will always set this
+     * value to UNKNOWN.</p>
+     * <p>FULL capability devices will always have this value set to the
+     * frame number of the request corresponding to this result.</p>
+     * <p><em>Further details</em>:</p>
+     * <ul>
+     * <li>Whenever a request differs from the last request, any future
+     * results not yet returned may have this value set to CONVERGING (this
+     * could include any in-progress captures not yet returned by the camera
+     * device, for more details see pipeline considerations below).</li>
+     * <li>Submitting a series of multiple requests that differ from the
+     * previous request (e.g. r1, r2, r3 s.t. r1 != r2 != r3)
+     * moves the new synchronization frame to the last non-repeating
+     * request (using the smallest frame number from the contiguous list of
+     * repeating requests).</li>
+     * <li>Submitting the same request repeatedly will not change this value
+     * to CONVERGING, if it was already a non-negative value.</li>
+     * <li>When this value changes to non-negative, that means that all of the
+     * metadata controls from the request have been applied, all of the
+     * metadata controls from the camera device have been read to the
+     * updated values (into the result), and all of the graphics buffers
+     * corresponding to this result are also synchronized to the request.</li>
+     * </ul>
+     * <p><em>Pipeline considerations</em>:</p>
+     * <p>Submitting a request with updated controls relative to the previously
+     * submitted requests may also invalidate the synchronization state
+     * of all the results corresponding to currently in-flight requests.</p>
+     * <p>In other words, results for this current request and up to
+     * ACAMERA_REQUEST_PIPELINE_MAX_DEPTH prior requests may have their
+     * ACAMERA_SYNC_FRAME_NUMBER change to CONVERGING.</p>
+     *
+     * @see ACAMERA_REQUEST_PIPELINE_MAX_DEPTH
+     * @see ACAMERA_SYNC_FRAME_NUMBER
+     */
     ACAMERA_SYNC_FRAME_NUMBER =                                 // int64 (enum)
             ACAMERA_SYNC_START,
+    /**
+     * <p>The maximum number of frames that can occur after a request
+     * (different than the previous) has been submitted, and before the
+     * result's state becomes synchronized.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraManager_getCameraCharacteristics</li>
+     * </ul>
+     *
+     * <p>This defines the maximum distance (in number of metadata results),
+     * between the frame number of the request that has new controls to apply
+     * and the frame number of the result that has all the controls applied.</p>
+     * <p>In other words this acts as an upper boundary for how many frames
+     * must occur before the camera device knows for a fact that the new
+     * submitted camera settings have been applied in outgoing frames.</p>
+     */
     ACAMERA_SYNC_MAX_LATENCY =                                  // int32 (enum)
             ACAMERA_SYNC_START + 1,
     ACAMERA_SYNC_END,
 
+    /**
+     * <p>The available depth dataspace stream
+     * configurations that this camera device supports
+     * (i.e. format, width, height, output/input stream).</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraManager_getCameraCharacteristics</li>
+     * </ul>
+     *
+     * <p>These are output stream configurations for use with
+     * dataSpace HAL_DATASPACE_DEPTH. The configurations are
+     * listed as <code>(format, width, height, input?)</code> tuples.</p>
+     * <p>Only devices that support depth output for at least
+     * the HAL_PIXEL_FORMAT_Y16 dense depth map may include
+     * this entry.</p>
+     * <p>A device that also supports the HAL_PIXEL_FORMAT_BLOB
+     * sparse depth point cloud must report a single entry for
+     * the format in this list as <code>(HAL_PIXEL_FORMAT_BLOB,
+     * android.depth.maxDepthSamples, 1, OUTPUT)</code> in addition to
+     * the entries for HAL_PIXEL_FORMAT_Y16.</p>
+     */
     ACAMERA_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS =       // int32[n*4] (enum)
             ACAMERA_DEPTH_START + 1,
+    /**
+     * <p>This lists the minimum frame duration for each
+     * format/size combination for depth output formats.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraManager_getCameraCharacteristics</li>
+     * </ul>
+     *
+     * <p>This should correspond to the frame duration when only that
+     * stream is active, with all processing (typically in android.*.mode)
+     * set to either OFF or FAST.</p>
+     * <p>When multiple streams are used in a request, the minimum frame
+     * duration will be max(individual stream min durations).</p>
+     * <p>The minimum frame duration of a stream (of a particular format, size)
+     * is the same regardless of whether the stream is input or output.</p>
+     * <p>See ACAMERA_SENSOR_FRAME_DURATION and
+     * ACAMERA_SCALER_AVAILABLE_STALL_DURATIONS for more details about
+     * calculating the max frame rate.</p>
+     * <p>(Keep in sync with {@link
+     * android.hardware.camera2.params.StreamConfigurationMap#getOutputMinFrameDuration})</p>
+     *
+     * @see ACAMERA_SCALER_AVAILABLE_STALL_DURATIONS
+     * @see ACAMERA_SENSOR_FRAME_DURATION
+     */
     ACAMERA_DEPTH_AVAILABLE_DEPTH_MIN_FRAME_DURATIONS =         // int64[4*n]
             ACAMERA_DEPTH_START + 2,
+    /**
+     * <p>This lists the maximum stall duration for each
+     * output format/size combination for depth streams.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraManager_getCameraCharacteristics</li>
+     * </ul>
+     *
+     * <p>A stall duration is how much extra time would get added
+     * to the normal minimum frame duration for a repeating request
+     * that has streams with non-zero stall.</p>
+     * <p>This functions similarly to
+     * ACAMERA_SCALER_AVAILABLE_STALL_DURATIONS for depth
+     * streams.</p>
+     * <p>All depth output stream formats may have a nonzero stall
+     * duration.</p>
+     *
+     * @see ACAMERA_SCALER_AVAILABLE_STALL_DURATIONS
+     */
     ACAMERA_DEPTH_AVAILABLE_DEPTH_STALL_DURATIONS =             // int64[4*n]
             ACAMERA_DEPTH_START + 3,
+    /**
+     * <p>Indicates whether a capture request may target both a
+     * DEPTH16 / DEPTH_POINT_CLOUD output, and normal color outputs (such as
+     * YUV_420_888, JPEG, or RAW) simultaneously.</p>
+     *
+     * <p>This tag may appear in:</p>
+     * <ul>
+     *   <li>ACameraMetadata from ACameraManager_getCameraCharacteristics</li>
+     * </ul>
+     *
+     * <p>If TRUE, including both depth and color outputs in a single
+     * capture request is not supported. An application must interleave color
+     * and depth requests.  If FALSE, a single request can target both types
+     * of output.</p>
+     * <p>Typically, this restriction exists on camera devices that
+     * need to emit a specific pattern or wavelength of light to
+     * measure depth values, which causes the color image to be
+     * corrupted during depth measurement.</p>
+     */
     ACAMERA_DEPTH_DEPTH_IS_EXCLUSIVE =                          // byte (enum)
             ACAMERA_DEPTH_START + 4,
     ACAMERA_DEPTH_END,
@@ -474,7 +5345,7 @@
 
 // ACAMERA_COLOR_CORRECTION_MODE
 typedef enum acamera_metadata_enum_acamera_color_correction_mode {
-    /*
+    /**
      * <p>Use the ACAMERA_COLOR_CORRECTION_TRANSFORM matrix
      * and ACAMERA_COLOR_CORRECTION_GAINS to do color conversion.</p>
      * <p>All advanced white balance adjustments (not specified
@@ -489,7 +5360,7 @@
      */
     ACAMERA_COLOR_CORRECTION_MODE_TRANSFORM_MATRIX                   = 0,
 
-    /*
+    /**
      * <p>Color correction processing must not slow down
      * capture rate relative to sensor raw output.</p>
      * <p>Advanced white balance adjustments above and beyond
@@ -502,7 +5373,7 @@
      */
     ACAMERA_COLOR_CORRECTION_MODE_FAST                               = 1,
 
-    /*
+    /**
      * <p>Color correction processing operates at improved
      * quality but the capture rate might be reduced (relative to sensor
      * raw output rate)</p>
@@ -520,18 +5391,18 @@
 
 // ACAMERA_COLOR_CORRECTION_ABERRATION_MODE
 typedef enum acamera_metadata_enum_acamera_color_correction_aberration_mode {
-    /*
+    /**
      * <p>No aberration correction is applied.</p>
      */
     ACAMERA_COLOR_CORRECTION_ABERRATION_MODE_OFF                     = 0,
 
-    /*
+    /**
      * <p>Aberration correction will not slow down capture rate
      * relative to sensor raw output.</p>
      */
     ACAMERA_COLOR_CORRECTION_ABERRATION_MODE_FAST                    = 1,
 
-    /*
+    /**
      * <p>Aberration correction operates at improved quality but the capture rate might be
      * reduced (relative to sensor raw output rate)</p>
      */
@@ -542,26 +5413,26 @@
 
 // ACAMERA_CONTROL_AE_ANTIBANDING_MODE
 typedef enum acamera_metadata_enum_acamera_control_ae_antibanding_mode {
-    /*
+    /**
      * <p>The camera device will not adjust exposure duration to
      * avoid banding problems.</p>
      */
     ACAMERA_CONTROL_AE_ANTIBANDING_MODE_OFF                          = 0,
 
-    /*
+    /**
      * <p>The camera device will adjust exposure duration to
      * avoid banding problems with 50Hz illumination sources.</p>
      */
     ACAMERA_CONTROL_AE_ANTIBANDING_MODE_50HZ                         = 1,
 
-    /*
+    /**
      * <p>The camera device will adjust exposure duration to
      * avoid banding problems with 60Hz illumination
      * sources.</p>
      */
     ACAMERA_CONTROL_AE_ANTIBANDING_MODE_60HZ                         = 2,
 
-    /*
+    /**
      * <p>The camera device will automatically adapt its
      * antibanding routine to the current illumination
      * condition. This is the default mode if AUTO is
@@ -573,13 +5444,13 @@
 
 // ACAMERA_CONTROL_AE_LOCK
 typedef enum acamera_metadata_enum_acamera_control_ae_lock {
-    /*
+    /**
      * <p>Auto-exposure lock is disabled; the AE algorithm
      * is free to update its parameters.</p>
      */
     ACAMERA_CONTROL_AE_LOCK_OFF                                      = 0,
 
-    /*
+    /**
      * <p>Auto-exposure lock is enabled; the AE algorithm
      * must not update the exposure and sensitivity parameters
      * while the lock is active.</p>
@@ -596,7 +5467,7 @@
 
 // ACAMERA_CONTROL_AE_MODE
 typedef enum acamera_metadata_enum_acamera_control_ae_mode {
-    /*
+    /**
      * <p>The camera device's autoexposure routine is disabled.</p>
      * <p>The application-selected ACAMERA_SENSOR_EXPOSURE_TIME,
      * ACAMERA_SENSOR_SENSITIVITY and
@@ -624,7 +5495,7 @@
      */
     ACAMERA_CONTROL_AE_MODE_OFF                                      = 0,
 
-    /*
+    /**
      * <p>The camera device's autoexposure routine is active,
      * with no flash control.</p>
      * <p>The application's values for
@@ -640,7 +5511,7 @@
      */
     ACAMERA_CONTROL_AE_MODE_ON                                       = 1,
 
-    /*
+    /**
      * <p>Like ON, except that the camera device also controls
      * the camera's flash unit, firing it in low-light
      * conditions.</p>
@@ -655,7 +5526,7 @@
      */
     ACAMERA_CONTROL_AE_MODE_ON_AUTO_FLASH                            = 2,
 
-    /*
+    /**
      * <p>Like ON, except that the camera device also controls
      * the camera's flash unit, always firing it for still
      * captures.</p>
@@ -670,7 +5541,7 @@
      */
     ACAMERA_CONTROL_AE_MODE_ON_ALWAYS_FLASH                          = 3,
 
-    /*
+    /**
      * <p>Like ON_AUTO_FLASH, but with automatic red eye
      * reduction.</p>
      * <p>If deemed necessary by the camera device, a red eye
@@ -683,12 +5554,12 @@
 
 // ACAMERA_CONTROL_AE_PRECAPTURE_TRIGGER
 typedef enum acamera_metadata_enum_acamera_control_ae_precapture_trigger {
-    /*
+    /**
      * <p>The trigger is idle.</p>
      */
     ACAMERA_CONTROL_AE_PRECAPTURE_TRIGGER_IDLE                       = 0,
 
-    /*
+    /**
      * <p>The precapture metering sequence will be started
      * by the camera device.</p>
      * <p>The exact effect of the precapture trigger depends on
@@ -696,7 +5567,7 @@
      */
     ACAMERA_CONTROL_AE_PRECAPTURE_TRIGGER_START                      = 1,
 
-    /*
+    /**
      * <p>The camera device will cancel any currently active or completed
      * precapture metering sequence, the auto-exposure routine will return to its
      * initial state.</p>
@@ -707,7 +5578,7 @@
 
 // ACAMERA_CONTROL_AF_MODE
 typedef enum acamera_metadata_enum_acamera_control_af_mode {
-    /*
+    /**
      * <p>The auto-focus routine does not control the lens;
      * ACAMERA_LENS_FOCUS_DISTANCE is controlled by the
      * application.</p>
@@ -716,7 +5587,7 @@
      */
     ACAMERA_CONTROL_AF_MODE_OFF                                      = 0,
 
-    /*
+    /**
      * <p>Basic automatic focus mode.</p>
      * <p>In this mode, the lens does not move unless
      * the autofocus trigger action is called. When that trigger
@@ -732,7 +5603,7 @@
      */
     ACAMERA_CONTROL_AF_MODE_AUTO                                     = 1,
 
-    /*
+    /**
      * <p>Close-up focusing mode.</p>
      * <p>In this mode, the lens does not move unless the
      * autofocus trigger action is called. When that trigger is
@@ -748,7 +5619,7 @@
      */
     ACAMERA_CONTROL_AF_MODE_MACRO                                    = 2,
 
-    /*
+    /**
      * <p>In this mode, the AF algorithm modifies the lens
      * position continually to attempt to provide a
      * constantly-in-focus image stream.</p>
@@ -769,7 +5640,7 @@
      */
     ACAMERA_CONTROL_AF_MODE_CONTINUOUS_VIDEO                         = 3,
 
-    /*
+    /**
      * <p>In this mode, the AF algorithm modifies the lens
      * position continually to attempt to provide a
      * constantly-in-focus image stream.</p>
@@ -789,7 +5660,7 @@
      */
     ACAMERA_CONTROL_AF_MODE_CONTINUOUS_PICTURE                       = 4,
 
-    /*
+    /**
      * <p>Extended depth of field (digital focus) mode.</p>
      * <p>The camera device will produce images with an extended
      * depth of field automatically; no special focusing
@@ -803,17 +5674,17 @@
 
 // ACAMERA_CONTROL_AF_TRIGGER
 typedef enum acamera_metadata_enum_acamera_control_af_trigger {
-    /*
+    /**
      * <p>The trigger is idle.</p>
      */
     ACAMERA_CONTROL_AF_TRIGGER_IDLE                                  = 0,
 
-    /*
+    /**
      * <p>Autofocus will trigger now.</p>
      */
     ACAMERA_CONTROL_AF_TRIGGER_START                                 = 1,
 
-    /*
+    /**
      * <p>Autofocus will return to its initial
      * state, and cancel any currently active trigger.</p>
      */
@@ -823,14 +5694,14 @@
 
 // ACAMERA_CONTROL_AWB_LOCK
 typedef enum acamera_metadata_enum_acamera_control_awb_lock {
-    /*
+    /**
      * <p>Auto-white balance lock is disabled; the AWB
      * algorithm is free to update its parameters if in AUTO
      * mode.</p>
      */
     ACAMERA_CONTROL_AWB_LOCK_OFF                                     = 0,
 
-    /*
+    /**
      * <p>Auto-white balance lock is enabled; the AWB
      * algorithm will not update its parameters while the lock
      * is active.</p>
@@ -841,7 +5712,7 @@
 
 // ACAMERA_CONTROL_AWB_MODE
 typedef enum acamera_metadata_enum_acamera_control_awb_mode {
-    /*
+    /**
      * <p>The camera device's auto-white balance routine is disabled.</p>
      * <p>The application-selected color transform matrix
      * (ACAMERA_COLOR_CORRECTION_TRANSFORM) and gains
@@ -853,7 +5724,7 @@
      */
     ACAMERA_CONTROL_AWB_MODE_OFF                                     = 0,
 
-    /*
+    /**
      * <p>The camera device's auto-white balance routine is active.</p>
      * <p>The application's values for ACAMERA_COLOR_CORRECTION_TRANSFORM
      * and ACAMERA_COLOR_CORRECTION_GAINS are ignored.
@@ -866,7 +5737,7 @@
      */
     ACAMERA_CONTROL_AWB_MODE_AUTO                                    = 1,
 
-    /*
+    /**
      * <p>The camera device's auto-white balance routine is disabled;
      * the camera device uses incandescent light as the assumed scene
      * illumination for white balance.</p>
@@ -884,7 +5755,7 @@
      */
     ACAMERA_CONTROL_AWB_MODE_INCANDESCENT                            = 2,
 
-    /*
+    /**
      * <p>The camera device's auto-white balance routine is disabled;
      * the camera device uses fluorescent light as the assumed scene
      * illumination for white balance.</p>
@@ -902,7 +5773,7 @@
      */
     ACAMERA_CONTROL_AWB_MODE_FLUORESCENT                             = 3,
 
-    /*
+    /**
      * <p>The camera device's auto-white balance routine is disabled;
      * the camera device uses warm fluorescent light as the assumed scene
      * illumination for white balance.</p>
@@ -920,7 +5791,7 @@
      */
     ACAMERA_CONTROL_AWB_MODE_WARM_FLUORESCENT                        = 4,
 
-    /*
+    /**
      * <p>The camera device's auto-white balance routine is disabled;
      * the camera device uses daylight light as the assumed scene
      * illumination for white balance.</p>
@@ -938,7 +5809,7 @@
      */
     ACAMERA_CONTROL_AWB_MODE_DAYLIGHT                                = 5,
 
-    /*
+    /**
      * <p>The camera device's auto-white balance routine is disabled;
      * the camera device uses cloudy daylight light as the assumed scene
      * illumination for white balance.</p>
@@ -953,7 +5824,7 @@
      */
     ACAMERA_CONTROL_AWB_MODE_CLOUDY_DAYLIGHT                         = 6,
 
-    /*
+    /**
      * <p>The camera device's auto-white balance routine is disabled;
      * the camera device uses twilight light as the assumed scene
      * illumination for white balance.</p>
@@ -968,7 +5839,7 @@
      */
     ACAMERA_CONTROL_AWB_MODE_TWILIGHT                                = 7,
 
-    /*
+    /**
      * <p>The camera device's auto-white balance routine is disabled;
      * the camera device uses shade light as the assumed scene
      * illumination for white balance.</p>
@@ -987,34 +5858,34 @@
 
 // ACAMERA_CONTROL_CAPTURE_INTENT
 typedef enum acamera_metadata_enum_acamera_control_capture_intent {
-    /*
+    /**
      * <p>The goal of this request doesn't fall into the other
      * categories. The camera device will default to preview-like
      * behavior.</p>
      */
     ACAMERA_CONTROL_CAPTURE_INTENT_CUSTOM                            = 0,
 
-    /*
+    /**
      * <p>This request is for a preview-like use case.</p>
      * <p>The precapture trigger may be used to start off a metering
      * w/flash sequence.</p>
      */
     ACAMERA_CONTROL_CAPTURE_INTENT_PREVIEW                           = 1,
 
-    /*
+    /**
      * <p>This request is for a still capture-type
      * use case.</p>
      * <p>If the flash unit is under automatic control, it may fire as needed.</p>
      */
     ACAMERA_CONTROL_CAPTURE_INTENT_STILL_CAPTURE                     = 2,
 
-    /*
+    /**
      * <p>This request is for a video recording
      * use case.</p>
      */
     ACAMERA_CONTROL_CAPTURE_INTENT_VIDEO_RECORD                      = 3,
 
-    /*
+    /**
      * <p>This request is for a video snapshot (still
      * image while recording video) use case.</p>
      * <p>The camera device should take the highest-quality image
@@ -1023,7 +5894,7 @@
      */
     ACAMERA_CONTROL_CAPTURE_INTENT_VIDEO_SNAPSHOT                    = 4,
 
-    /*
+    /**
      * <p>This request is for a ZSL usecase; the
      * application will stream full-resolution images and
      * reprocess one or several later for a final
@@ -1031,7 +5902,7 @@
      */
     ACAMERA_CONTROL_CAPTURE_INTENT_ZERO_SHUTTER_LAG                  = 5,
 
-    /*
+    /**
      * <p>This request is for manual capture use case where
      * the applications want to directly control the capture parameters.</p>
      * <p>For example, the application may wish to manually control
@@ -1046,57 +5917,57 @@
 
 // ACAMERA_CONTROL_EFFECT_MODE
 typedef enum acamera_metadata_enum_acamera_control_effect_mode {
-    /*
+    /**
      * <p>No color effect will be applied.</p>
      */
     ACAMERA_CONTROL_EFFECT_MODE_OFF                                  = 0,
 
-    /*
+    /**
      * <p>A "monocolor" effect where the image is mapped into
      * a single color.</p>
      * <p>This will typically be grayscale.</p>
      */
     ACAMERA_CONTROL_EFFECT_MODE_MONO                                 = 1,
 
-    /*
+    /**
      * <p>A "photo-negative" effect where the image's colors
      * are inverted.</p>
      */
     ACAMERA_CONTROL_EFFECT_MODE_NEGATIVE                             = 2,
 
-    /*
+    /**
      * <p>A "solarisation" effect (Sabattier effect) where the
      * image is wholly or partially reversed in
      * tone.</p>
      */
     ACAMERA_CONTROL_EFFECT_MODE_SOLARIZE                             = 3,
 
-    /*
+    /**
      * <p>A "sepia" effect where the image is mapped into warm
      * gray, red, and brown tones.</p>
      */
     ACAMERA_CONTROL_EFFECT_MODE_SEPIA                                = 4,
 
-    /*
+    /**
      * <p>A "posterization" effect where the image uses
      * discrete regions of tone rather than a continuous
      * gradient of tones.</p>
      */
     ACAMERA_CONTROL_EFFECT_MODE_POSTERIZE                            = 5,
 
-    /*
+    /**
      * <p>A "whiteboard" effect where the image is typically displayed
      * as regions of white, with black or grey details.</p>
      */
     ACAMERA_CONTROL_EFFECT_MODE_WHITEBOARD                           = 6,
 
-    /*
+    /**
      * <p>A "blackboard" effect where the image is typically displayed
      * as regions of black, with white or grey details.</p>
      */
     ACAMERA_CONTROL_EFFECT_MODE_BLACKBOARD                           = 7,
 
-    /*
+    /**
      * <p>An "aqua" effect where a blue hue is added to the image.</p>
      */
     ACAMERA_CONTROL_EFFECT_MODE_AQUA                                 = 8,
@@ -1105,7 +5976,7 @@
 
 // ACAMERA_CONTROL_MODE
 typedef enum acamera_metadata_enum_acamera_control_mode {
-    /*
+    /**
      * <p>Full application control of pipeline.</p>
      * <p>All control by the device's metering and focusing (3A)
      * routines is disabled, and no other settings in
@@ -1123,7 +5994,7 @@
      */
     ACAMERA_CONTROL_MODE_OFF                                         = 0,
 
-    /*
+    /**
      * <p>Use settings for each individual 3A routine.</p>
      * <p>Manual control of capture parameters is disabled. All
      * controls in ACAMERA_CONTROL_* besides sceneMode take
@@ -1131,7 +6002,7 @@
      */
     ACAMERA_CONTROL_MODE_AUTO                                        = 1,
 
-    /*
+    /**
      * <p>Use a specific scene mode.</p>
      * <p>Enabling this disables control.aeMode, control.awbMode and
      * control.afMode controls; the camera device will ignore
@@ -1145,7 +6016,7 @@
      */
     ACAMERA_CONTROL_MODE_USE_SCENE_MODE                              = 2,
 
-    /*
+    /**
      * <p>Same as OFF mode, except that this capture will not be
      * used by camera device background auto-exposure, auto-white balance and
      * auto-focus algorithms (3A) to update their statistics.</p>
@@ -1161,12 +6032,12 @@
 
 // ACAMERA_CONTROL_SCENE_MODE
 typedef enum acamera_metadata_enum_acamera_control_scene_mode {
-    /*
+    /**
      * <p>Indicates that no scene modes are set for a given capture request.</p>
      */
     ACAMERA_CONTROL_SCENE_MODE_DISABLED                              = 0,
 
-    /*
+    /**
      * <p>If face detection support exists, use face
      * detection data for auto-focus, auto-white balance, and
      * auto-exposure routines.</p>
@@ -1185,91 +6056,91 @@
      */
     ACAMERA_CONTROL_SCENE_MODE_FACE_PRIORITY                         = 1,
 
-    /*
+    /**
      * <p>Optimized for photos of quickly moving objects.</p>
      * <p>Similar to SPORTS.</p>
      */
     ACAMERA_CONTROL_SCENE_MODE_ACTION                                = 2,
 
-    /*
+    /**
      * <p>Optimized for still photos of people.</p>
      */
     ACAMERA_CONTROL_SCENE_MODE_PORTRAIT                              = 3,
 
-    /*
+    /**
      * <p>Optimized for photos of distant macroscopic objects.</p>
      */
     ACAMERA_CONTROL_SCENE_MODE_LANDSCAPE                             = 4,
 
-    /*
+    /**
      * <p>Optimized for low-light settings.</p>
      */
     ACAMERA_CONTROL_SCENE_MODE_NIGHT                                 = 5,
 
-    /*
+    /**
      * <p>Optimized for still photos of people in low-light
      * settings.</p>
      */
     ACAMERA_CONTROL_SCENE_MODE_NIGHT_PORTRAIT                        = 6,
 
-    /*
+    /**
      * <p>Optimized for dim, indoor settings where flash must
      * remain off.</p>
      */
     ACAMERA_CONTROL_SCENE_MODE_THEATRE                               = 7,
 
-    /*
+    /**
      * <p>Optimized for bright, outdoor beach settings.</p>
      */
     ACAMERA_CONTROL_SCENE_MODE_BEACH                                 = 8,
 
-    /*
+    /**
      * <p>Optimized for bright, outdoor settings containing snow.</p>
      */
     ACAMERA_CONTROL_SCENE_MODE_SNOW                                  = 9,
 
-    /*
+    /**
      * <p>Optimized for scenes of the setting sun.</p>
      */
     ACAMERA_CONTROL_SCENE_MODE_SUNSET                                = 10,
 
-    /*
+    /**
      * <p>Optimized to avoid blurry photos due to small amounts of
      * device motion (for example: due to hand shake).</p>
      */
     ACAMERA_CONTROL_SCENE_MODE_STEADYPHOTO                           = 11,
 
-    /*
+    /**
      * <p>Optimized for nighttime photos of fireworks.</p>
      */
     ACAMERA_CONTROL_SCENE_MODE_FIREWORKS                             = 12,
 
-    /*
+    /**
      * <p>Optimized for photos of quickly moving people.</p>
      * <p>Similar to ACTION.</p>
      */
     ACAMERA_CONTROL_SCENE_MODE_SPORTS                                = 13,
 
-    /*
+    /**
      * <p>Optimized for dim, indoor settings with multiple moving
      * people.</p>
      */
     ACAMERA_CONTROL_SCENE_MODE_PARTY                                 = 14,
 
-    /*
+    /**
      * <p>Optimized for dim settings where the main light source
      * is a flame.</p>
      */
     ACAMERA_CONTROL_SCENE_MODE_CANDLELIGHT                           = 15,
 
-    /*
+    /**
      * <p>Optimized for accurately capturing a photo of barcode
      * for use by camera applications that wish to read the
      * barcode value.</p>
      */
     ACAMERA_CONTROL_SCENE_MODE_BARCODE                               = 16,
 
-    /*
+    /**
      * <p>This is deprecated, please use {@link
      * android.hardware.camera2.CameraDevice#createConstrainedHighSpeedCaptureSession}
      * and {@link
@@ -1354,7 +6225,7 @@
      */
     ACAMERA_CONTROL_SCENE_MODE_HIGH_SPEED_VIDEO                      = 17,
 
-    /*
+    /**
      * <p>Turn on a device-specific high dynamic range (HDR) mode.</p>
      * <p>In this scene mode, the camera device captures images
      * that keep a larger range of scene illumination levels
@@ -1382,11 +6253,20 @@
      * produced in response to a capture request submitted
      * while in HDR mode.</p>
      * <p>Since substantial post-processing is generally needed to
-     * produce an HDR image, only YUV and JPEG outputs are
-     * supported for LIMITED/FULL device HDR captures, and only
-     * JPEG outputs are supported for LEGACY HDR
-     * captures. Using a RAW output for HDR capture is not
+     * produce an HDR image, only YUV, PRIVATE, and JPEG
+     * outputs are supported for LIMITED/FULL device HDR
+     * captures, and only JPEG outputs are supported for LEGACY
+     * HDR captures. Using a RAW output for HDR capture is not
      * supported.</p>
+     * <p>Some devices may also support always-on HDR, which
+     * applies HDR processing at full frame rate.  For these
+     * devices, intents other than STILL_CAPTURE will also
+     * produce an HDR output with no frame rate impact compared
+     * to normal operation, though the quality may be lower
+     * than for STILL_CAPTURE intents.</p>
+     * <p>If SCENE_MODE_HDR is used with unsupported output types
+     * or capture intents, the images captured will be as if
+     * the SCENE_MODE was not enabled at all.</p>
      *
      * @see ACAMERA_CONTROL_CAPTURE_INTENT
      */
@@ -1396,12 +6276,12 @@
 
 // ACAMERA_CONTROL_VIDEO_STABILIZATION_MODE
 typedef enum acamera_metadata_enum_acamera_control_video_stabilization_mode {
-    /*
+    /**
      * <p>Video stabilization is disabled.</p>
      */
     ACAMERA_CONTROL_VIDEO_STABILIZATION_MODE_OFF                     = 0,
 
-    /*
+    /**
      * <p>Video stabilization is enabled.</p>
      */
     ACAMERA_CONTROL_VIDEO_STABILIZATION_MODE_ON                      = 1,
@@ -1410,7 +6290,7 @@
 
 // ACAMERA_CONTROL_AE_STATE
 typedef enum acamera_metadata_enum_acamera_control_ae_state {
-    /*
+    /**
      * <p>AE is off or recently reset.</p>
      * <p>When a camera device is opened, it starts in
      * this state. This is a transient state, the camera device may skip reporting
@@ -1418,7 +6298,7 @@
      */
     ACAMERA_CONTROL_AE_STATE_INACTIVE                                = 0,
 
-    /*
+    /**
      * <p>AE doesn't yet have a good set of control values
      * for the current scene.</p>
      * <p>This is a transient state, the camera device may skip
@@ -1426,25 +6306,25 @@
      */
     ACAMERA_CONTROL_AE_STATE_SEARCHING                               = 1,
 
-    /*
+    /**
      * <p>AE has a good set of control values for the
      * current scene.</p>
      */
     ACAMERA_CONTROL_AE_STATE_CONVERGED                               = 2,
 
-    /*
+    /**
      * <p>AE has been locked.</p>
      */
     ACAMERA_CONTROL_AE_STATE_LOCKED                                  = 3,
 
-    /*
+    /**
      * <p>AE has a good set of control values, but flash
      * needs to be fired for good quality still
      * capture.</p>
      */
     ACAMERA_CONTROL_AE_STATE_FLASH_REQUIRED                          = 4,
 
-    /*
+    /**
      * <p>AE has been asked to do a precapture sequence
      * and is currently executing it.</p>
      * <p>Precapture can be triggered through setting
@@ -1465,7 +6345,7 @@
 
 // ACAMERA_CONTROL_AF_STATE
 typedef enum acamera_metadata_enum_acamera_control_af_state {
-    /*
+    /**
      * <p>AF is off or has not yet tried to scan/been asked
      * to scan.</p>
      * <p>When a camera device is opened, it starts in this
@@ -1475,7 +6355,7 @@
      */
     ACAMERA_CONTROL_AF_STATE_INACTIVE                                = 0,
 
-    /*
+    /**
      * <p>AF is currently performing an AF scan initiated the
      * camera device in a continuous autofocus mode.</p>
      * <p>Only used by CONTINUOUS_* AF modes. This is a transient
@@ -1484,7 +6364,7 @@
      */
     ACAMERA_CONTROL_AF_STATE_PASSIVE_SCAN                            = 1,
 
-    /*
+    /**
      * <p>AF currently believes it is in focus, but may
      * restart scanning at any time.</p>
      * <p>Only used by CONTINUOUS_* AF modes. This is a transient
@@ -1493,7 +6373,7 @@
      */
     ACAMERA_CONTROL_AF_STATE_PASSIVE_FOCUSED                         = 2,
 
-    /*
+    /**
      * <p>AF is performing an AF scan because it was
      * triggered by AF trigger.</p>
      * <p>Only used by AUTO or MACRO AF modes. This is a transient
@@ -1502,7 +6382,7 @@
      */
     ACAMERA_CONTROL_AF_STATE_ACTIVE_SCAN                             = 3,
 
-    /*
+    /**
      * <p>AF believes it is focused correctly and has locked
      * focus.</p>
      * <p>This state is reached only after an explicit START AF trigger has been
@@ -1515,7 +6395,7 @@
      */
     ACAMERA_CONTROL_AF_STATE_FOCUSED_LOCKED                          = 4,
 
-    /*
+    /**
      * <p>AF has failed to focus successfully and has locked
      * focus.</p>
      * <p>This state is reached only after an explicit START AF trigger has been
@@ -1528,7 +6408,7 @@
      */
     ACAMERA_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED                      = 5,
 
-    /*
+    /**
      * <p>AF finished a passive scan without finding focus,
      * and may restart scanning at any time.</p>
      * <p>Only used by CONTINUOUS_* AF modes. This is a transient state, the camera
@@ -1542,7 +6422,7 @@
 
 // ACAMERA_CONTROL_AWB_STATE
 typedef enum acamera_metadata_enum_acamera_control_awb_state {
-    /*
+    /**
      * <p>AWB is not in auto mode, or has not yet started metering.</p>
      * <p>When a camera device is opened, it starts in this
      * state. This is a transient state, the camera device may
@@ -1551,7 +6431,7 @@
      */
     ACAMERA_CONTROL_AWB_STATE_INACTIVE                               = 0,
 
-    /*
+    /**
      * <p>AWB doesn't yet have a good set of control
      * values for the current scene.</p>
      * <p>This is a transient state, the camera device
@@ -1559,13 +6439,13 @@
      */
     ACAMERA_CONTROL_AWB_STATE_SEARCHING                              = 1,
 
-    /*
+    /**
      * <p>AWB has a good set of control values for the
      * current scene.</p>
      */
     ACAMERA_CONTROL_AWB_STATE_CONVERGED                              = 2,
 
-    /*
+    /**
      * <p>AWB has been locked.</p>
      */
     ACAMERA_CONTROL_AWB_STATE_LOCKED                                 = 3,
@@ -1592,24 +6472,24 @@
 
 // ACAMERA_EDGE_MODE
 typedef enum acamera_metadata_enum_acamera_edge_mode {
-    /*
+    /**
      * <p>No edge enhancement is applied.</p>
      */
     ACAMERA_EDGE_MODE_OFF                                            = 0,
 
-    /*
+    /**
      * <p>Apply edge enhancement at a quality level that does not slow down frame rate
      * relative to sensor output. It may be the same as OFF if edge enhancement will
      * slow down frame rate relative to sensor.</p>
      */
     ACAMERA_EDGE_MODE_FAST                                           = 1,
 
-    /*
+    /**
      * <p>Apply high-quality edge enhancement, at a cost of possibly reduced output frame rate.</p>
      */
     ACAMERA_EDGE_MODE_HIGH_QUALITY                                   = 2,
 
-    /*
+    /**
      * <p>Edge enhancement is applied at different levels for different output streams,
      * based on resolution. Streams at maximum recording resolution (see {@link
      * android.hardware.camera2.CameraDevice#createCaptureSession}) or below have
@@ -1639,18 +6519,18 @@
 
 // ACAMERA_FLASH_MODE
 typedef enum acamera_metadata_enum_acamera_flash_mode {
-    /*
+    /**
      * <p>Do not fire the flash for this capture.</p>
      */
     ACAMERA_FLASH_MODE_OFF                                           = 0,
 
-    /*
+    /**
      * <p>If the flash is available and charged, fire flash
      * for this capture.</p>
      */
     ACAMERA_FLASH_MODE_SINGLE                                        = 1,
 
-    /*
+    /**
      * <p>Transition flash to continuously on.</p>
      */
     ACAMERA_FLASH_MODE_TORCH                                         = 2,
@@ -1659,27 +6539,27 @@
 
 // ACAMERA_FLASH_STATE
 typedef enum acamera_metadata_enum_acamera_flash_state {
-    /*
+    /**
      * <p>No flash on camera.</p>
      */
     ACAMERA_FLASH_STATE_UNAVAILABLE                                  = 0,
 
-    /*
+    /**
      * <p>Flash is charging and cannot be fired.</p>
      */
     ACAMERA_FLASH_STATE_CHARGING                                     = 1,
 
-    /*
+    /**
      * <p>Flash is ready to fire.</p>
      */
     ACAMERA_FLASH_STATE_READY                                        = 2,
 
-    /*
+    /**
      * <p>Flash fired for this capture.</p>
      */
     ACAMERA_FLASH_STATE_FIRED                                        = 3,
 
-    /*
+    /**
      * <p>Flash partially illuminated this frame.</p>
      * <p>This is usually due to the next or previous frame having
      * the flash fire, and the flash spilling into this capture
@@ -1701,7 +6581,7 @@
 
 // ACAMERA_HOT_PIXEL_MODE
 typedef enum acamera_metadata_enum_acamera_hot_pixel_mode {
-    /*
+    /**
      * <p>No hot pixel correction is applied.</p>
      * <p>The frame rate must not be reduced relative to sensor raw output
      * for this option.</p>
@@ -1711,7 +6591,7 @@
      */
     ACAMERA_HOT_PIXEL_MODE_OFF                                       = 0,
 
-    /*
+    /**
      * <p>Hot pixel correction is applied, without reducing frame
      * rate relative to sensor raw output.</p>
      * <p>The hotpixel map may be returned in ACAMERA_STATISTICS_HOT_PIXEL_MAP.</p>
@@ -1720,7 +6600,7 @@
      */
     ACAMERA_HOT_PIXEL_MODE_FAST                                      = 1,
 
-    /*
+    /**
      * <p>High-quality hot pixel correction is applied, at a cost
      * of possibly reduced frame rate relative to sensor raw output.</p>
      * <p>The hotpixel map may be returned in ACAMERA_STATISTICS_HOT_PIXEL_MAP.</p>
@@ -1735,12 +6615,12 @@
 
 // ACAMERA_LENS_OPTICAL_STABILIZATION_MODE
 typedef enum acamera_metadata_enum_acamera_lens_optical_stabilization_mode {
-    /*
+    /**
      * <p>Optical stabilization is unavailable.</p>
      */
     ACAMERA_LENS_OPTICAL_STABILIZATION_MODE_OFF                      = 0,
 
-    /*
+    /**
      * <p>Optical stabilization is enabled.</p>
      */
     ACAMERA_LENS_OPTICAL_STABILIZATION_MODE_ON                       = 1,
@@ -1749,17 +6629,17 @@
 
 // ACAMERA_LENS_FACING
 typedef enum acamera_metadata_enum_acamera_lens_facing {
-    /*
+    /**
      * <p>The camera device faces the same direction as the device's screen.</p>
      */
     ACAMERA_LENS_FACING_FRONT                                        = 0,
 
-    /*
+    /**
      * <p>The camera device faces the opposite direction as the device's screen.</p>
      */
     ACAMERA_LENS_FACING_BACK                                         = 1,
 
-    /*
+    /**
      * <p>The camera device is an external camera, and has no fixed facing relative to the
      * device's screen.</p>
      */
@@ -1769,7 +6649,7 @@
 
 // ACAMERA_LENS_STATE
 typedef enum acamera_metadata_enum_acamera_lens_state {
-    /*
+    /**
      * <p>The lens parameters (ACAMERA_LENS_FOCAL_LENGTH, ACAMERA_LENS_FOCUS_DISTANCE,
      * ACAMERA_LENS_FILTER_DENSITY and ACAMERA_LENS_APERTURE) are not changing.</p>
      *
@@ -1780,7 +6660,7 @@
      */
     ACAMERA_LENS_STATE_STATIONARY                                    = 0,
 
-    /*
+    /**
      * <p>One or several of the lens parameters
      * (ACAMERA_LENS_FOCAL_LENGTH, ACAMERA_LENS_FOCUS_DISTANCE,
      * ACAMERA_LENS_FILTER_DENSITY or ACAMERA_LENS_APERTURE) is
@@ -1798,7 +6678,7 @@
 
 // ACAMERA_LENS_INFO_FOCUS_DISTANCE_CALIBRATION
 typedef enum acamera_metadata_enum_acamera_lens_info_focus_distance_calibration {
-    /*
+    /**
      * <p>The lens focus distance is not accurate, and the units used for
      * ACAMERA_LENS_FOCUS_DISTANCE do not correspond to any physical units.</p>
      * <p>Setting the lens to the same focus distance on separate occasions may
@@ -1813,7 +6693,7 @@
      */
     ACAMERA_LENS_INFO_FOCUS_DISTANCE_CALIBRATION_UNCALIBRATED        = 0,
 
-    /*
+    /**
      * <p>The lens focus distance is measured in diopters.</p>
      * <p>However, setting the lens to the same focus distance
      * on separate occasions may result in a different real
@@ -1823,7 +6703,7 @@
      */
     ACAMERA_LENS_INFO_FOCUS_DISTANCE_CALIBRATION_APPROXIMATE         = 1,
 
-    /*
+    /**
      * <p>The lens focus distance is measured in diopters, and
      * is calibrated.</p>
      * <p>The lens mechanism is calibrated so that setting the
@@ -1839,31 +6719,31 @@
 
 // ACAMERA_NOISE_REDUCTION_MODE
 typedef enum acamera_metadata_enum_acamera_noise_reduction_mode {
-    /*
+    /**
      * <p>No noise reduction is applied.</p>
      */
     ACAMERA_NOISE_REDUCTION_MODE_OFF                                 = 0,
 
-    /*
+    /**
      * <p>Noise reduction is applied without reducing frame rate relative to sensor
      * output. It may be the same as OFF if noise reduction will reduce frame rate
      * relative to sensor.</p>
      */
     ACAMERA_NOISE_REDUCTION_MODE_FAST                                = 1,
 
-    /*
+    /**
      * <p>High-quality noise reduction is applied, at the cost of possibly reduced frame
      * rate relative to sensor output.</p>
      */
     ACAMERA_NOISE_REDUCTION_MODE_HIGH_QUALITY                        = 2,
 
-    /*
+    /**
      * <p>MINIMAL noise reduction is applied without reducing frame rate relative to
      * sensor output. </p>
      */
     ACAMERA_NOISE_REDUCTION_MODE_MINIMAL                             = 3,
 
-    /*
+    /**
      * <p>Noise reduction is applied at different levels for different output streams,
      * based on resolution. Streams at maximum recording resolution (see {@link
      * android.hardware.camera2.CameraDevice#createCaptureSession}) or below have noise
@@ -1895,7 +6775,7 @@
 
 // ACAMERA_REQUEST_AVAILABLE_CAPABILITIES
 typedef enum acamera_metadata_enum_acamera_request_available_capabilities {
-    /*
+    /**
      * <p>The minimal set of capabilities that every camera
      * device (regardless of ACAMERA_INFO_SUPPORTED_HARDWARE_LEVEL)
      * supports.</p>
@@ -1911,7 +6791,7 @@
      */
     ACAMERA_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE       = 0,
 
-    /*
+    /**
      * <p>The camera device can be manually controlled (3A algorithms such
      * as auto-exposure, and auto-focus can be bypassed).
      * The camera device supports basic manual control of the sensor image
@@ -1970,7 +6850,7 @@
      */
     ACAMERA_REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR             = 1,
 
-    /*
+    /**
      * <p>The camera device post-processing stages can be manually controlled.
      * The camera device supports basic manual control of the image post-processing
      * stages. This means the following controls are guaranteed to be supported:</p>
@@ -2030,7 +6910,7 @@
      */
     ACAMERA_REQUEST_AVAILABLE_CAPABILITIES_MANUAL_POST_PROCESSING    = 2,
 
-    /*
+    /**
      * <p>The camera device supports outputting RAW buffers and
      * metadata for interpreting them.</p>
      * <p>Devices supporting the RAW capability allow both for
@@ -2051,7 +6931,7 @@
      */
     ACAMERA_REQUEST_AVAILABLE_CAPABILITIES_RAW                       = 3,
 
-    /*
+    /**
      * <p>The camera device supports accurately reporting the sensor settings for many of
      * the sensor controls while the built-in 3A algorithm is running.  This allows
      * reporting of sensor settings even when these settings cannot be manually changed.</p>
@@ -2082,7 +6962,7 @@
      */
     ACAMERA_REQUEST_AVAILABLE_CAPABILITIES_READ_SENSOR_SETTINGS      = 5,
 
-    /*
+    /**
      * <p>The camera device supports capturing high-resolution images at &gt;= 20 frames per
      * second, in at least the uncompressed YUV format, when post-processing settings are set
      * to FAST. Additionally, maximum-resolution images can be captured at &gt;= 10 frames
@@ -2120,7 +7000,7 @@
      */
     ACAMERA_REQUEST_AVAILABLE_CAPABILITIES_BURST_CAPTURE             = 6,
 
-    /*
+    /**
      * <p>The camera device can produce depth measurements from its field of view.</p>
      * <p>This capability requires the camera device to support the following:</p>
      * <ul>
@@ -2173,12 +7053,12 @@
 
 // ACAMERA_SCALER_CROPPING_TYPE
 typedef enum acamera_metadata_enum_acamera_scaler_cropping_type {
-    /*
+    /**
      * <p>The camera device only supports centered crop regions.</p>
      */
     ACAMERA_SCALER_CROPPING_TYPE_CENTER_ONLY                         = 0,
 
-    /*
+    /**
      * <p>The camera device supports arbitrarily chosen crop regions.</p>
      */
     ACAMERA_SCALER_CROPPING_TYPE_FREEFORM                            = 1,
@@ -2192,7 +7072,7 @@
 
     ACAMERA_SENSOR_REFERENCE_ILLUMINANT1_FLUORESCENT                 = 2,
 
-    /*
+    /**
      * <p>Incandescent light</p>
      */
     ACAMERA_SENSOR_REFERENCE_ILLUMINANT1_TUNGSTEN                    = 3,
@@ -2205,22 +7085,22 @@
 
     ACAMERA_SENSOR_REFERENCE_ILLUMINANT1_SHADE                       = 11,
 
-    /*
+    /**
      * <p>D 5700 - 7100K</p>
      */
     ACAMERA_SENSOR_REFERENCE_ILLUMINANT1_DAYLIGHT_FLUORESCENT        = 12,
 
-    /*
+    /**
      * <p>N 4600 - 5400K</p>
      */
     ACAMERA_SENSOR_REFERENCE_ILLUMINANT1_DAY_WHITE_FLUORESCENT       = 13,
 
-    /*
+    /**
      * <p>W 3900 - 4500K</p>
      */
     ACAMERA_SENSOR_REFERENCE_ILLUMINANT1_COOL_WHITE_FLUORESCENT      = 14,
 
-    /*
+    /**
      * <p>WW 3200 - 3700K</p>
      */
     ACAMERA_SENSOR_REFERENCE_ILLUMINANT1_WHITE_FLUORESCENT           = 15,
@@ -2245,14 +7125,14 @@
 
 // ACAMERA_SENSOR_TEST_PATTERN_MODE
 typedef enum acamera_metadata_enum_acamera_sensor_test_pattern_mode {
-    /*
+    /**
      * <p>No test pattern mode is used, and the camera
      * device returns captures from the image sensor.</p>
      * <p>This is the default if the key is not set.</p>
      */
     ACAMERA_SENSOR_TEST_PATTERN_MODE_OFF                             = 0,
 
-    /*
+    /**
      * <p>Each pixel in <code>[R, G_even, G_odd, B]</code> is replaced by its
      * respective color channel provided in
      * ACAMERA_SENSOR_TEST_PATTERN_DATA.</p>
@@ -2269,7 +7149,7 @@
      */
     ACAMERA_SENSOR_TEST_PATTERN_MODE_SOLID_COLOR                     = 1,
 
-    /*
+    /**
      * <p>All pixel data is replaced with an 8-bar color pattern.</p>
      * <p>The vertical bars (left-to-right) are as follows:</p>
      * <ul>
@@ -2305,7 +7185,7 @@
      */
     ACAMERA_SENSOR_TEST_PATTERN_MODE_COLOR_BARS                      = 2,
 
-    /*
+    /**
      * <p>The test pattern is similar to COLOR_BARS, except that
      * each bar should start at its specified color at the top,
      * and fade to gray at the bottom.</p>
@@ -2322,7 +7202,7 @@
      */
     ACAMERA_SENSOR_TEST_PATTERN_MODE_COLOR_BARS_FADE_TO_GRAY         = 3,
 
-    /*
+    /**
      * <p>All pixel data is replaced by a pseudo-random sequence
      * generated from a PN9 512-bit sequence (typically implemented
      * in hardware with a linear feedback shift register).</p>
@@ -2332,7 +7212,7 @@
      */
     ACAMERA_SENSOR_TEST_PATTERN_MODE_PN9                             = 4,
 
-    /*
+    /**
      * <p>The first custom test pattern. All custom patterns that are
      * available only on this camera device are at least this numeric
      * value.</p>
@@ -2354,7 +7234,7 @@
 
     ACAMERA_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_BGGR                = 3,
 
-    /*
+    /**
      * <p>Sensor is not Bayer; output has 3 16-bit
      * values for each pixel, instead of just 1 16-bit value
      * per pixel.</p>
@@ -2365,7 +7245,7 @@
 
 // ACAMERA_SENSOR_INFO_TIMESTAMP_SOURCE
 typedef enum acamera_metadata_enum_acamera_sensor_info_timestamp_source {
-    /*
+    /**
      * <p>Timestamps from ACAMERA_SENSOR_TIMESTAMP are in nanoseconds and monotonic,
      * but can not be compared to timestamps from other subsystems
      * (e.g. accelerometer, gyro etc.), or other instances of the same or different
@@ -2377,7 +7257,7 @@
      */
     ACAMERA_SENSOR_INFO_TIMESTAMP_SOURCE_UNKNOWN                     = 0,
 
-    /*
+    /**
      * <p>Timestamps from ACAMERA_SENSOR_TIMESTAMP are in the same timebase as
      * {@link android.os.SystemClock#elapsedRealtimeNanos},
      * and they can be compared to other timestamps using that base.</p>
@@ -2399,18 +7279,18 @@
 
 // ACAMERA_SHADING_MODE
 typedef enum acamera_metadata_enum_acamera_shading_mode {
-    /*
+    /**
      * <p>No lens shading correction is applied.</p>
      */
     ACAMERA_SHADING_MODE_OFF                                         = 0,
 
-    /*
+    /**
      * <p>Apply lens shading corrections, without slowing
      * frame rate relative to sensor raw output</p>
      */
     ACAMERA_SHADING_MODE_FAST                                        = 1,
 
-    /*
+    /**
      * <p>Apply high-quality lens shading correction, at the
      * cost of possibly reduced frame rate.</p>
      */
@@ -2421,18 +7301,18 @@
 
 // ACAMERA_STATISTICS_FACE_DETECT_MODE
 typedef enum acamera_metadata_enum_acamera_statistics_face_detect_mode {
-    /*
+    /**
      * <p>Do not include face detection statistics in capture
      * results.</p>
      */
     ACAMERA_STATISTICS_FACE_DETECT_MODE_OFF                          = 0,
 
-    /*
+    /**
      * <p>Return face rectangle and confidence values only.</p>
      */
     ACAMERA_STATISTICS_FACE_DETECT_MODE_SIMPLE                       = 1,
 
-    /*
+    /**
      * <p>Return all face
      * metadata.</p>
      * <p>In this mode, face rectangles, scores, landmarks, and face IDs are all valid.</p>
@@ -2443,12 +7323,12 @@
 
 // ACAMERA_STATISTICS_HOT_PIXEL_MAP_MODE
 typedef enum acamera_metadata_enum_acamera_statistics_hot_pixel_map_mode {
-    /*
+    /**
      * <p>Hot pixel map production is disabled.</p>
      */
     ACAMERA_STATISTICS_HOT_PIXEL_MAP_MODE_OFF                        = 0,
 
-    /*
+    /**
      * <p>Hot pixel map production is enabled.</p>
      */
     ACAMERA_STATISTICS_HOT_PIXEL_MAP_MODE_ON                         = 1,
@@ -2457,19 +7337,19 @@
 
 // ACAMERA_STATISTICS_SCENE_FLICKER
 typedef enum acamera_metadata_enum_acamera_statistics_scene_flicker {
-    /*
+    /**
      * <p>The camera device does not detect any flickering illumination
      * in the current scene.</p>
      */
     ACAMERA_STATISTICS_SCENE_FLICKER_NONE                            = 0,
 
-    /*
+    /**
      * <p>The camera device detects illumination flickering at 50Hz
      * in the current scene.</p>
      */
     ACAMERA_STATISTICS_SCENE_FLICKER_50HZ                            = 1,
 
-    /*
+    /**
      * <p>The camera device detects illumination flickering at 60Hz
      * in the current scene.</p>
      */
@@ -2479,12 +7359,12 @@
 
 // ACAMERA_STATISTICS_LENS_SHADING_MAP_MODE
 typedef enum acamera_metadata_enum_acamera_statistics_lens_shading_map_mode {
-    /*
+    /**
      * <p>Do not include a lens shading map in the capture result.</p>
      */
     ACAMERA_STATISTICS_LENS_SHADING_MAP_MODE_OFF                     = 0,
 
-    /*
+    /**
      * <p>Include a lens shading map in the capture result.</p>
      */
     ACAMERA_STATISTICS_LENS_SHADING_MAP_MODE_ON                      = 1,
@@ -2495,7 +7375,7 @@
 
 // ACAMERA_TONEMAP_MODE
 typedef enum acamera_metadata_enum_acamera_tonemap_mode {
-    /*
+    /**
      * <p>Use the tone mapping curve specified in
      * the ACAMERA_TONEMAPCURVE_* entries.</p>
      * <p>All color enhancement and tonemapping must be disabled, except
@@ -2506,19 +7386,19 @@
      */
     ACAMERA_TONEMAP_MODE_CONTRAST_CURVE                              = 0,
 
-    /*
+    /**
      * <p>Advanced gamma mapping and color enhancement may be applied, without
      * reducing frame rate compared to raw sensor output.</p>
      */
     ACAMERA_TONEMAP_MODE_FAST                                        = 1,
 
-    /*
+    /**
      * <p>High-quality gamma mapping and color enhancement will be applied, at
      * the cost of possibly reduced frame rate compared to raw sensor output.</p>
      */
     ACAMERA_TONEMAP_MODE_HIGH_QUALITY                                = 2,
 
-    /*
+    /**
      * <p>Use the gamma value specified in ACAMERA_TONEMAP_GAMMA to peform
      * tonemapping.</p>
      * <p>All color enhancement and tonemapping must be disabled, except
@@ -2529,7 +7409,7 @@
      */
     ACAMERA_TONEMAP_MODE_GAMMA_VALUE                                 = 3,
 
-    /*
+    /**
      * <p>Use the preset tonemapping curve specified in
      * ACAMERA_TONEMAP_PRESET_CURVE to peform tonemapping.</p>
      * <p>All color enhancement and tonemapping must be disabled, except
@@ -2545,12 +7425,12 @@
 
 // ACAMERA_TONEMAP_PRESET_CURVE
 typedef enum acamera_metadata_enum_acamera_tonemap_preset_curve {
-    /*
+    /**
      * <p>Tonemapping curve is defined by sRGB</p>
      */
     ACAMERA_TONEMAP_PRESET_CURVE_SRGB                                = 0,
 
-    /*
+    /**
      * <p>Tonemapping curve is defined by ITU-R BT.709</p>
      */
     ACAMERA_TONEMAP_PRESET_CURVE_REC709                              = 1,
@@ -2561,7 +7441,7 @@
 
 // ACAMERA_INFO_SUPPORTED_HARDWARE_LEVEL
 typedef enum acamera_metadata_enum_acamera_info_supported_hardware_level {
-    /*
+    /**
      * <p>This camera device does not have enough capabilities to qualify as a <code>FULL</code> device or
      * better.</p>
      * <p>Only the stream configurations listed in the <code>LEGACY</code> and <code>LIMITED</code> tables in the
@@ -2589,7 +7469,7 @@
      */
     ACAMERA_INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED                    = 0,
 
-    /*
+    /**
      * <p>This camera device is capable of supporting advanced imaging applications.</p>
      * <p>The stream configurations listed in the <code>FULL</code>, <code>LEGACY</code> and <code>LIMITED</code> tables in the
      * {@link android.hardware.camera2.CameraDevice#createCaptureSession
@@ -2618,7 +7498,7 @@
      */
     ACAMERA_INFO_SUPPORTED_HARDWARE_LEVEL_FULL                       = 1,
 
-    /*
+    /**
      * <p>This camera device is running in backward compatibility mode.</p>
      * <p>Only the stream configurations listed in the <code>LEGACY</code> table in the {@link
      * android.hardware.camera2.CameraDevice#createCaptureSession createCaptureSession}
@@ -2639,7 +7519,7 @@
      */
     ACAMERA_INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY                     = 2,
 
-    /*
+    /**
      * <p>This camera device is capable of YUV reprocessing and RAW data capture, in addition to
      * FULL-level capabilities.</p>
      * <p>The stream configurations listed in the <code>LEVEL_3</code>, <code>RAW</code>, <code>FULL</code>, <code>LEGACY</code> and
@@ -2672,7 +7552,7 @@
 
 // ACAMERA_SYNC_FRAME_NUMBER
 typedef enum acamera_metadata_enum_acamera_sync_frame_number {
-    /*
+    /**
      * <p>The current result is not yet fully synchronized to any request.</p>
      * <p>Synchronization is in progress, and reading metadata from this
      * result may include a mix of data that have taken effect since the
@@ -2686,7 +7566,7 @@
      */
     ACAMERA_SYNC_FRAME_NUMBER_CONVERGING                             = -1,
 
-    /*
+    /**
      * <p>The current result's synchronization status is unknown.</p>
      * <p>The result may have already converged, or it may be in
      * progress.  Reading from this result may include some mix
@@ -2705,7 +7585,7 @@
 
 // ACAMERA_SYNC_MAX_LATENCY
 typedef enum acamera_metadata_enum_acamera_sync_max_latency {
-    /*
+    /**
      * <p>Every frame has the requests immediately applied.</p>
      * <p>Changing controls over multiple requests one after another will
      * produce results that have those controls applied atomically
@@ -2714,7 +7594,7 @@
      */
     ACAMERA_SYNC_MAX_LATENCY_PER_FRAME_CONTROL                       = 0,
 
-    /*
+    /**
      * <p>Each new frame has some subset (potentially the entire set)
      * of the past requests applied to the camera settings.</p>
      * <p>By submitting a series of identical requests, the camera device
diff --git a/include/media/AudioIoDescriptor.h b/include/media/AudioIoDescriptor.h
index a4907cc..fed86c9 100644
--- a/include/media/AudioIoDescriptor.h
+++ b/include/media/AudioIoDescriptor.h
@@ -35,7 +35,7 @@
     AudioIoDescriptor() :
         mIoHandle(AUDIO_IO_HANDLE_NONE),
         mSamplingRate(0), mFormat(AUDIO_FORMAT_DEFAULT), mChannelMask(AUDIO_CHANNEL_NONE),
-        mFrameCount(0), mLatency(0)
+        mFrameCount(0), mFrameCountHAL(0), mLatency(0)
     {
         memset(&mPatch, 0, sizeof(struct audio_patch));
     }
@@ -62,6 +62,7 @@
     audio_format_t          mFormat;
     audio_channel_mask_t    mChannelMask;
     size_t                  mFrameCount;
+    size_t                  mFrameCountHAL;
     uint32_t                mLatency;   // only valid for output
 };
 
diff --git a/include/media/AudioSystem.h b/include/media/AudioSystem.h
index c9eac2e..585ef59 100644
--- a/include/media/AudioSystem.h
+++ b/include/media/AudioSystem.h
@@ -43,6 +43,8 @@
 {
 public:
 
+    // FIXME Declare in binder opcode order, similarly to IAudioFlinger.h and IAudioFlinger.cpp
+
     /* These are static methods to control the system-wide AudioFlinger
      * only privileged processes can have access to them
      */
@@ -117,8 +119,8 @@
     // returns the audio HAL sample rate
     static status_t getSamplingRate(audio_io_handle_t ioHandle,
                                           uint32_t* samplingRate);
-    // returns the number of frames per audio HAL buffer. Corresponds to
-    // audio_stream->get_buffer_size()/audio_stream_out/in_frame_size()
+    // For output threads with a fast mixer, returns the number of frames per normal mixer buffer.
+    // For output threads without a fast mixer, or for input, this is same as getFrameCountHAL().
     static status_t getFrameCount(audio_io_handle_t ioHandle,
                                   size_t* frameCount);
     // returns the audio output latency in ms. Corresponds to
@@ -166,6 +168,12 @@
     // Indicate JAVA services are ready (scheduling, power management ...)
     static status_t systemReady();
 
+    // Returns the number of frames per audio HAL buffer.
+    // Corresponds to audio_stream->get_buffer_size()/audio_stream_in_frame_size() for input.
+    // See also getFrameCount().
+    static status_t getFrameCountHAL(audio_io_handle_t ioHandle,
+                                     size_t* frameCount);
+
     // Events used to synchronize actions between audio sessions.
     // For instance SYNC_EVENT_PRESENTATION_COMPLETE can be used to delay recording start until
     // playback is complete on another audio session.
diff --git a/include/media/AudioTrack.h b/include/media/AudioTrack.h
index eaaef4a..fc7217a 100644
--- a/include/media/AudioTrack.h
+++ b/include/media/AudioTrack.h
@@ -201,6 +201,10 @@
                            binder to AudioFlinger.
                            It will return an error instead.  The application will recreate
                            the track based on offloading or different channel configuration, etc.
+     * maxRequiredSpeed:   For PCM tracks, this creates an appropriate buffer size that will allow
+     *                     maxRequiredSpeed playback. Values less than 1.0f and greater than
+     *                     AUDIO_TIMESTRETCH_SPEED_MAX will be clamped.  For non-PCM tracks
+     *                     and direct or offloaded tracks, this parameter is ignored.
      * threadCanCallJava:  Not present in parameter list, and so is fixed at false.
      */
 
@@ -219,7 +223,8 @@
                                     int uid = -1,
                                     pid_t pid = -1,
                                     const audio_attributes_t* pAttributes = NULL,
-                                    bool doNotReconnect = false);
+                                    bool doNotReconnect = false,
+                                    float maxRequiredSpeed = 1.0f);
 
     /* Creates an audio track and registers it with AudioFlinger.
      * With this constructor, the track is configured for static buffer mode.
@@ -248,7 +253,8 @@
                                     int uid = -1,
                                     pid_t pid = -1,
                                     const audio_attributes_t* pAttributes = NULL,
-                                    bool doNotReconnect = false);
+                                    bool doNotReconnect = false,
+                                    float maxRequiredSpeed = 1.0f);
 
     /* Terminates the AudioTrack and unregisters it from AudioFlinger.
      * Also destroys all resources associated with the AudioTrack.
@@ -293,7 +299,8 @@
                             int uid = -1,
                             pid_t pid = -1,
                             const audio_attributes_t* pAttributes = NULL,
-                            bool doNotReconnect = false);
+                            bool doNotReconnect = false,
+                            float maxRequiredSpeed = 1.0f);
 
     /* Result of constructing the AudioTrack. This must be checked for successful initialization
      * before using any AudioTrack API (except for set()), because using
@@ -333,6 +340,10 @@
      */
             ssize_t     getBufferSizeInFrames();
 
+    /* Returns the buffer duration in microseconds at current playback rate.
+     */
+            status_t    getBufferDurationInUs(int64_t *duration);
+
     /* Set the effective size of audio buffer that an application writes to.
      * This is used to determine the amount of available room in the buffer,
      * which determines when a write will block.
@@ -916,6 +927,7 @@
     mutable uint32_t        mSampleRate;            // mutable because getSampleRate() can update it
     uint32_t                mOriginalSampleRate;
     AudioPlaybackRate       mPlaybackRate;
+    float                   mMaxRequiredSpeed;      // use PCM buffer size to allow this speed
 
     // Corresponds to current IAudioTrack, value is reported back by AudioFlinger to the client.
     // This allocated buffer size is maintained by the proxy.
diff --git a/include/media/IAudioFlinger.h b/include/media/IAudioFlinger.h
index e48aa1c..1ade4ba 100644
--- a/include/media/IAudioFlinger.h
+++ b/include/media/IAudioFlinger.h
@@ -103,6 +103,9 @@
      * and therefore can be cached.
      */
     virtual     uint32_t    sampleRate(audio_io_handle_t ioHandle) const = 0;
+
+    // reserved; formerly channelCount()
+
     virtual     audio_format_t format(audio_io_handle_t output) const = 0;
     virtual     size_t      frameCount(audio_io_handle_t ioHandle) const = 0;
 
@@ -247,6 +250,9 @@
 
     /* Indicate JAVA services are ready (scheduling, power management ...) */
     virtual status_t systemReady() = 0;
+
+    // Returns the number of frames per audio HAL buffer.
+    virtual size_t frameCountHAL(audio_io_handle_t ioHandle) const = 0;
 };
 
 
diff --git a/include/media/MediaPlayerInterface.h b/include/media/MediaPlayerInterface.h
index 54862d1..4977efd 100644
--- a/include/media/MediaPlayerInterface.h
+++ b/include/media/MediaPlayerInterface.h
@@ -104,6 +104,7 @@
         virtual audio_session_t getSessionId() const = 0;
         virtual audio_stream_type_t getAudioStreamType() const = 0;
         virtual uint32_t    getSampleRate() const = 0;
+        virtual int64_t     getBufferDurationInUs() const = 0;
 
         // If no callback is specified, use the "write" API below to submit
         // audio data.
diff --git a/include/media/ToneGenerator.h b/include/media/ToneGenerator.h
index 8406ed6..c41c686 100644
--- a/include/media/ToneGenerator.h
+++ b/include/media/ToneGenerator.h
@@ -193,12 +193,15 @@
         TONE_JAPAN_DIAL,            // Dial tone: 400Hz, continuous
         TONE_JAPAN_BUSY,            // Busy tone: 400Hz, 500ms ON, 500ms OFF...
         TONE_JAPAN_RADIO_ACK,       // Radio path acknowlegment: 400Hz, 1s ON, 2s OFF...
+        // UK Supervisory tones
+        TONE_UK_RINGTONE,           // Ring Tone: A 400Hz + 450Hz tone repeated in a 0.4s on, 0.2s off, 0.4s on, 2.0s off pattern.
         NUM_ALTERNATE_TONES
     };
 
     enum region {
         ANSI,
         JAPAN,
+        UK,
         CEPT,
         NUM_REGIONS
     };
diff --git a/include/media/stagefright/DataSource.h b/include/media/stagefright/DataSource.h
index c5df1f6..0254545 100644
--- a/include/media/stagefright/DataSource.h
+++ b/include/media/stagefright/DataSource.h
@@ -19,7 +19,7 @@
 #define DATA_SOURCE_H_
 
 #include <sys/types.h>
-
+#include <media/stagefright/foundation/ADebug.h>
 #include <media/stagefright/MediaErrors.h>
 #include <utils/Errors.h>
 #include <utils/KeyedVector.h>
@@ -71,6 +71,20 @@
     bool getUInt32(off64_t offset, uint32_t *x);
     bool getUInt64(off64_t offset, uint64_t *x);
 
+    // Reads in "count" entries of type T into vector *x.
+    // Returns true if "count" entries can be read.
+    // If fewer than "count" entries can be read, return false. In this case,
+    // the output vector *x will still have those entries that were read. Call
+    // x->size() to obtain the number of entries read.
+    // The optional parameter chunkSize specifies how many entries should be
+    // read from the data source at one time into a temporary buffer. Increasing
+    // chunkSize can improve the performance at the cost of extra memory usage.
+    // The default value for chunkSize is set to read at least 4k bytes at a
+    // time, depending on sizeof(T).
+    template <typename T>
+    bool getVector(off64_t offset, Vector<T>* x, size_t count,
+                   size_t chunkSize = (4095 / sizeof(T)) + 1);
+
     // May return ERROR_UNSUPPORTED.
     virtual status_t getSize(off64_t *size);
 
@@ -127,6 +141,51 @@
     DataSource &operator=(const DataSource &);
 };
 
+template <typename T>
+bool DataSource::getVector(off64_t offset, Vector<T>* x, size_t count,
+                           size_t chunkSize)
+{
+    x->clear();
+    if (chunkSize == 0) {
+        return false;
+    }
+    if (count == 0) {
+        return true;
+    }
+
+    T tmp[chunkSize];
+    ssize_t numBytesRead;
+    size_t numBytesPerChunk = chunkSize * sizeof(T);
+    size_t i;
+
+    for (i = 0; i + chunkSize < count; i += chunkSize) {
+        // This loops is executed when more than chunkSize records need to be
+        // read.
+        numBytesRead = this->readAt(offset, (void*)&tmp, numBytesPerChunk);
+        if (numBytesRead == -1) { // If readAt() returns -1, there is an error.
+            return false;
+        }
+        if (numBytesRead < numBytesPerChunk) {
+            // This case is triggered when the stream ends before the whole
+            // chunk is read.
+            x->appendArray(tmp, (size_t)numBytesRead / sizeof(T));
+            return false;
+        }
+        x->appendArray(tmp, chunkSize);
+        offset += numBytesPerChunk;
+    }
+
+    // There are (count - i) more records to read.
+    // Right now, (count - i) <= chunkSize.
+    // We do the same thing as above, but with chunkSize replaced by count - i.
+    numBytesRead = this->readAt(offset, (void*)&tmp, (count - i) * sizeof(T));
+    if (numBytesRead == -1) {
+        return false;
+    }
+    x->appendArray(tmp, (size_t)numBytesRead / sizeof(T));
+    return x->size() == count;
+}
+
 }  // namespace android
 
 #endif  // DATA_SOURCE_H_
diff --git a/media/libmedia/AudioSystem.cpp b/media/libmedia/AudioSystem.cpp
index 3a5dee6..bbdf65e 100644
--- a/media/libmedia/AudioSystem.cpp
+++ b/media/libmedia/AudioSystem.cpp
@@ -104,6 +104,8 @@
     return DEAD_OBJECT;
 }
 
+// FIXME Declare in binder opcode order, similarly to IAudioFlinger.h and IAudioFlinger.cpp
+
 status_t AudioSystem::muteMicrophone(bool state)
 {
     const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
@@ -429,6 +431,27 @@
     return af->systemReady();
 }
 
+status_t AudioSystem::getFrameCountHAL(audio_io_handle_t ioHandle,
+                                       size_t* frameCount)
+{
+    const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
+    if (af == 0) return PERMISSION_DENIED;
+    sp<AudioIoDescriptor> desc = getIoDescriptor(ioHandle);
+    if (desc == 0) {
+        *frameCount = af->frameCountHAL(ioHandle);
+    } else {
+        *frameCount = desc->mFrameCountHAL;
+    }
+    if (*frameCount == 0) {
+        ALOGE("AudioSystem::getFrameCountHAL failed for ioHandle %d", ioHandle);
+        return BAD_VALUE;
+    }
+
+    ALOGV("getFrameCountHAL() ioHandle %d, frameCount %zu", ioHandle, *frameCount);
+
+    return NO_ERROR;
+}
+
 // ---------------------------------------------------------------------------
 
 
@@ -528,10 +551,10 @@
                 }
             }
             ALOGV("ioConfigChanged() new config for %s %d samplingRate %u, format %#x "
-                    "channel mask %#x frameCount %zu deviceId %d",
+                    "channel mask %#x frameCount %zu frameCountHAL %zu deviceId %d",
                     event == AUDIO_OUTPUT_CONFIG_CHANGED ? "output" : "input",
                     ioDesc->mIoHandle, ioDesc->mSamplingRate, ioDesc->mFormat,
-                    ioDesc->mChannelMask, ioDesc->mFrameCount, ioDesc->getDeviceId());
+                    ioDesc->mChannelMask, ioDesc->mFrameCount, ioDesc->mFrameCountHAL, ioDesc->getDeviceId());
 
         } break;
         }
diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp
index e757c7c..b9138f2 100644
--- a/media/libmedia/AudioTrack.cpp
+++ b/media/libmedia/AudioTrack.cpp
@@ -191,7 +191,8 @@
         int uid,
         pid_t pid,
         const audio_attributes_t* pAttributes,
-        bool doNotReconnect)
+        bool doNotReconnect,
+        float maxRequiredSpeed)
     : mStatus(NO_INIT),
       mState(STATE_STOPPED),
       mPreviousPriority(ANDROID_PRIORITY_NORMAL),
@@ -202,7 +203,7 @@
     mStatus = set(streamType, sampleRate, format, channelMask,
             frameCount, flags, cbf, user, notificationFrames,
             0 /*sharedBuffer*/, false /*threadCanCallJava*/, sessionId, transferType,
-            offloadInfo, uid, pid, pAttributes, doNotReconnect);
+            offloadInfo, uid, pid, pAttributes, doNotReconnect, maxRequiredSpeed);
 }
 
 AudioTrack::AudioTrack(
@@ -221,7 +222,8 @@
         int uid,
         pid_t pid,
         const audio_attributes_t* pAttributes,
-        bool doNotReconnect)
+        bool doNotReconnect,
+        float maxRequiredSpeed)
     : mStatus(NO_INIT),
       mState(STATE_STOPPED),
       mPreviousPriority(ANDROID_PRIORITY_NORMAL),
@@ -232,7 +234,7 @@
     mStatus = set(streamType, sampleRate, format, channelMask,
             0 /*frameCount*/, flags, cbf, user, notificationFrames,
             sharedBuffer, false /*threadCanCallJava*/, sessionId, transferType, offloadInfo,
-            uid, pid, pAttributes, doNotReconnect);
+            uid, pid, pAttributes, doNotReconnect, maxRequiredSpeed);
 }
 
 AudioTrack::~AudioTrack()
@@ -281,7 +283,8 @@
         int uid,
         pid_t pid,
         const audio_attributes_t* pAttributes,
-        bool doNotReconnect)
+        bool doNotReconnect,
+        float maxRequiredSpeed)
 {
     ALOGV("set(): streamType %d, sampleRate %u, format %#x, channelMask %#x, frameCount %zu, "
           "flags #%x, notificationFrames %u, sessionId %d, transferType %d, uid %d, pid %d",
@@ -422,6 +425,8 @@
     mSampleRate = sampleRate;
     mOriginalSampleRate = sampleRate;
     mPlaybackRate = AUDIO_PLAYBACK_RATE_DEFAULT;
+    // 1.0 <= mMaxRequiredSpeed <= AUDIO_TIMESTRETCH_SPEED_MAX
+    mMaxRequiredSpeed = min(max(maxRequiredSpeed, 1.0f), AUDIO_TIMESTRETCH_SPEED_MAX);
 
     // Make copy of input parameter offloadInfo so that in the future:
     //  (a) createTrack_l doesn't need it as an input parameter
@@ -532,24 +537,23 @@
         mTimestampStartupGlitchReported = false;
         mRetrogradeMotionReported = false;
 
-        // If previousState == STATE_STOPPED, we clear the timestamp so that it
-        // needs a new server push. We also reactivate markers (mMarkerPosition != 0)
-        // as the position is reset to 0. This is legacy behavior. This is not done
-        // in stop() to avoid a race condition where the last marker event is issued twice.
-        // Note: the if is technically unnecessary because previousState == STATE_FLUSHED
-        // is only for streaming tracks, and mMarkerReached is already set to false.
-        if (previousState == STATE_STOPPED) {
-            // read last server side position change via timestamp
-            ExtendedTimestamp ets;
-            if (mProxy->getTimestamp(&ets) == OK &&
-                    ets.mTimeNs[ExtendedTimestamp::LOCATION_SERVER] > 0) {
-                mFramesWrittenServerOffset = -(ets.mPosition[ExtendedTimestamp::LOCATION_SERVER]
-                                                             + ets.mFlushed);
-            }
-            mFramesWritten = 0;
-            mProxy->clearTimestamp(); // need new server push for valid timestamp
-            mMarkerReached = false;
+        // read last server side position change via timestamp.
+        ExtendedTimestamp ets;
+        if (mProxy->getTimestamp(&ets) == OK &&
+                ets.mTimeNs[ExtendedTimestamp::LOCATION_SERVER] > 0) {
+            // Server side has consumed something, but is it finished consuming?
+            // It is possible since flush and stop are asynchronous that the server
+            // is still active at this point.
+            ALOGV("start: server read:%lld  cumulative flushed:%lld  client written:%lld",
+                    (long long)(mFramesWrittenServerOffset
+                            + ets.mPosition[ExtendedTimestamp::LOCATION_SERVER]),
+                    (long long)ets.mFlushed,
+                    (long long)mFramesWritten);
+            mFramesWrittenServerOffset = -ets.mPosition[ExtendedTimestamp::LOCATION_SERVER];
         }
+        mFramesWritten = 0;
+        mProxy->clearTimestamp(); // need new server push for valid timestamp
+        mMarkerReached = false;
 
         // For offloaded tracks, we don't know if the hardware counters are really zero here,
         // since the flush is asynchronous and stop may not fully drain.
@@ -825,6 +829,9 @@
     if (mFlags & AUDIO_OUTPUT_FLAG_FAST) {
         return INVALID_OPERATION;
     }
+
+    ALOGV("setPlaybackRate (input): mSampleRate:%u  mSpeed:%f  mPitch:%f",
+            mSampleRate, playbackRate.mSpeed, playbackRate.mPitch);
     // pitch is emulated by adjusting speed and sampleRate
     const uint32_t effectiveRate = adjustSampleRate(mSampleRate, playbackRate.mPitch);
     const float effectiveSpeed = adjustSpeed(playbackRate.mSpeed, playbackRate.mPitch);
@@ -833,12 +840,18 @@
     playbackRateTemp.mSpeed = effectiveSpeed;
     playbackRateTemp.mPitch = effectivePitch;
 
+    ALOGV("setPlaybackRate (effective): mSampleRate:%u  mSpeed:%f  mPitch:%f",
+            effectiveRate, effectiveSpeed, effectivePitch);
+
     if (!isAudioPlaybackRateValid(playbackRateTemp)) {
+        ALOGV("setPlaybackRate(%f, %f) failed (effective rate out of bounds)",
+                playbackRate.mSpeed, playbackRate.mPitch);
         return BAD_VALUE;
     }
     // Check if the buffer size is compatible.
     if (!isSampleRateSpeedAllowed_l(effectiveRate, effectiveSpeed)) {
-        ALOGV("setPlaybackRate(%f, %f) failed", playbackRate.mSpeed, playbackRate.mPitch);
+        ALOGV("setPlaybackRate(%f, %f) failed (buffer size)",
+                playbackRate.mSpeed, playbackRate.mPitch);
         return BAD_VALUE;
     }
 
@@ -876,6 +889,24 @@
     return (ssize_t) mProxy->getBufferSizeInFrames();
 }
 
+status_t AudioTrack::getBufferDurationInUs(int64_t *duration)
+{
+    if (duration == nullptr) {
+        return BAD_VALUE;
+    }
+    AutoMutex lock(mLock);
+    if (mOutput == AUDIO_IO_HANDLE_NONE || mProxy.get() == 0) {
+        return NO_INIT;
+    }
+    ssize_t bufferSizeInFrames = (ssize_t) mProxy->getBufferSizeInFrames();
+    if (bufferSizeInFrames < 0) {
+        return (status_t)bufferSizeInFrames;
+    }
+    *duration = (int64_t)((double)bufferSizeInFrames * 1000000
+            / ((double)mSampleRate * mPlaybackRate.mSpeed));
+    return NO_ERROR;
+}
+
 ssize_t AudioTrack::setBufferSizeInFrames(size_t bufferSizeInFrames)
 {
     AutoMutex lock(mLock);
@@ -1276,9 +1307,11 @@
 
         if ((mFlags & AUDIO_OUTPUT_FLAG_FAST) == 0) {
             // for normal tracks precompute the frame count based on speed.
+            const float speed = !isPurePcmData_l() || isOffloadedOrDirect_l() ? 1.0f :
+                            max(mMaxRequiredSpeed, mPlaybackRate.mSpeed);
             const size_t minFrameCount = calculateMinFrameCount(
                     mAfLatency, mAfFrameCount, mAfSampleRate, mSampleRate,
-                    mPlaybackRate.mSpeed);
+                    speed);
             if (frameCount < minFrameCount) {
                 frameCount = minFrameCount;
             }
@@ -2206,18 +2239,18 @@
         return INVALID_OPERATION; // not supported
     }
     status_t status = mProxy->getTimestamp(timestamp);
+    LOG_ALWAYS_FATAL_IF(status != OK, "status %d not allowed from proxy getTimestamp", status);
     bool found = false;
-    if (status == OK) {
-        timestamp->mPosition[ExtendedTimestamp::LOCATION_CLIENT] = mFramesWritten;
-        timestamp->mTimeNs[ExtendedTimestamp::LOCATION_CLIENT] = 0;
-        // server side frame offset in case AudioTrack has been restored.
-        for (int i = ExtendedTimestamp::LOCATION_SERVER;
-                i < ExtendedTimestamp::LOCATION_MAX; ++i) {
-            if (timestamp->mTimeNs[i] >= 0) {
-                // apply server offset and the "flush frame correction here"
-                timestamp->mPosition[i] += mFramesWrittenServerOffset + timestamp->mFlushed;
-                found = true;
-            }
+    timestamp->mPosition[ExtendedTimestamp::LOCATION_CLIENT] = mFramesWritten;
+    timestamp->mTimeNs[ExtendedTimestamp::LOCATION_CLIENT] = 0;
+    // server side frame offset in case AudioTrack has been restored.
+    for (int i = ExtendedTimestamp::LOCATION_SERVER;
+            i < ExtendedTimestamp::LOCATION_MAX; ++i) {
+        if (timestamp->mTimeNs[i] >= 0) {
+            // apply server offset (frames flushed is ignored
+            // so we don't report the jump when the flush occurs).
+            timestamp->mPosition[i] += mFramesWrittenServerOffset;
+            found = true;
         }
     }
     return found ? OK : WOULD_BLOCK;
diff --git a/media/libmedia/IAudioFlinger.cpp b/media/libmedia/IAudioFlinger.cpp
index 7543b60..aa75188 100644
--- a/media/libmedia/IAudioFlinger.cpp
+++ b/media/libmedia/IAudioFlinger.cpp
@@ -81,7 +81,8 @@
     LIST_AUDIO_PATCHES,
     SET_AUDIO_PORT_CONFIG,
     GET_AUDIO_HW_SYNC,
-    SYSTEM_READY
+    SYSTEM_READY,
+    FRAME_COUNT_HAL,
 };
 
 #define MAX_ITEMS_PER_LIST 1024
@@ -274,6 +275,8 @@
         return reply.readInt32();
     }
 
+    // RESERVED for channelCount()
+
     virtual audio_format_t format(audio_io_handle_t output) const
     {
         Parcel data, reply;
@@ -911,6 +914,18 @@
         data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
         return remote()->transact(SYSTEM_READY, data, &reply, IBinder::FLAG_ONEWAY);
     }
+    virtual size_t frameCountHAL(audio_io_handle_t ioHandle) const
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
+        data.writeInt32((int32_t) ioHandle);
+        status_t status = remote()->transact(FRAME_COUNT_HAL, data, &reply);
+        if (status != NO_ERROR) {
+            return 0;
+        }
+        return reply.readInt64();
+    }
+
 };
 
 IMPLEMENT_META_INTERFACE(AudioFlinger, "android.media.IAudioFlinger");
@@ -993,6 +1008,9 @@
             reply->writeInt32( sampleRate((audio_io_handle_t) data.readInt32()) );
             return NO_ERROR;
         } break;
+
+        // RESERVED for channelCount()
+
         case FORMAT: {
             CHECK_INTERFACE(IAudioFlinger, data, reply);
             reply->writeInt32( format((audio_io_handle_t) data.readInt32()) );
@@ -1419,6 +1437,11 @@
             systemReady();
             return NO_ERROR;
         } break;
+        case FRAME_COUNT_HAL: {
+            CHECK_INTERFACE(IAudioFlinger, data, reply);
+            reply->writeInt64( frameCountHAL((audio_io_handle_t) data.readInt32()) );
+            return NO_ERROR;
+        } break;
         default:
             return BBinder::onTransact(code, data, reply, flags);
     }
diff --git a/media/libmedia/IAudioFlingerClient.cpp b/media/libmedia/IAudioFlingerClient.cpp
index 3429d36..8dca9e9 100644
--- a/media/libmedia/IAudioFlingerClient.cpp
+++ b/media/libmedia/IAudioFlingerClient.cpp
@@ -50,6 +50,7 @@
         data.writeInt32(ioDesc->mFormat);
         data.writeInt32(ioDesc->mChannelMask);
         data.writeInt64(ioDesc->mFrameCount);
+        data.writeInt64(ioDesc->mFrameCountHAL);
         data.writeInt32(ioDesc->mLatency);
         remote()->transact(IO_CONFIG_CHANGED, data, &reply, IBinder::FLAG_ONEWAY);
     }
@@ -73,6 +74,7 @@
             ioDesc->mFormat = (audio_format_t) data.readInt32();
             ioDesc->mChannelMask = (audio_channel_mask_t) data.readInt32();
             ioDesc->mFrameCount = data.readInt64();
+            ioDesc->mFrameCountHAL = data.readInt64();
             ioDesc->mLatency = data.readInt32();
             ioConfigChanged(event, ioDesc);
             return NO_ERROR;
diff --git a/media/libmedia/IMediaExtractor.cpp b/media/libmedia/IMediaExtractor.cpp
index b13b69f..f142ccc 100644
--- a/media/libmedia/IMediaExtractor.cpp
+++ b/media/libmedia/IMediaExtractor.cpp
@@ -216,13 +216,15 @@
     return str;
 }
 
-static Vector<ExtractorInstance> extractors;
+static Vector<ExtractorInstance> sExtractors;
+static Mutex sExtractorsLock;
 
 void registerMediaSource(
         const sp<IMediaExtractor> &ex,
         const sp<IMediaSource> &source) {
-    for (size_t i = 0; i < extractors.size(); i++) {
-        ExtractorInstance &instance = extractors.editItemAt(i);
+    Mutex::Autolock lock(sExtractorsLock);
+    for (size_t i = 0; i < sExtractors.size(); i++) {
+        ExtractorInstance &instance = sExtractors.editItemAt(i);
         sp<IMediaExtractor> extractor = instance.extractor.promote();
         if (extractor != NULL && extractor == ex) {
             if (instance.tracks.size() > 5) {
@@ -246,19 +248,25 @@
     ex.owner = IPCThreadState::self()->getCallingPid();
     ex.extractor = extractor;
 
-    if (extractors.size() > 10) {
-        extractors.resize(10);
+    {
+        Mutex::Autolock lock(sExtractorsLock);
+        if (sExtractors.size() > 10) {
+            sExtractors.resize(10);
+        }
+        sExtractors.push_front(ex);
     }
-    extractors.push_front(ex);
 }
 
 status_t dumpExtractors(int fd, const Vector<String16>&) {
     String8 out;
     out.append("Recent extractors, most recent first:\n");
-    for (size_t i = 0; i < extractors.size(); i++) {
-        const ExtractorInstance &instance = extractors.itemAt(i);
-        out.append("  ");
-        out.append(instance.toString());
+    {
+        Mutex::Autolock lock(sExtractorsLock);
+        for (size_t i = 0; i < sExtractors.size(); i++) {
+            const ExtractorInstance &instance = sExtractors.itemAt(i);
+            out.append("  ");
+            out.append(instance.toString());
+        }
     }
     write(fd, out.string(), out.size());
     return OK;
diff --git a/media/libmedia/ToneGenerator.cpp b/media/libmedia/ToneGenerator.cpp
index 9f4b4de..411519d 100644
--- a/media/libmedia/ToneGenerator.cpp
+++ b/media/libmedia/ToneGenerator.cpp
@@ -740,6 +740,13 @@
                         { .duration = 0 , .waveFreq = { 0 }, 0, 0}},
           .repeatCnt = ToneGenerator::TONEGEN_INF,
           .repeatSegment = 0 },                              // TONE_JAPAN_RADIO_ACK
+        { .segments = { { .duration = 400, .waveFreq = { 400, 450, 0 }, 0, 0 },
+                        { .duration = 200, .waveFreq = { 0 }, 0, 0 },
+                        { .duration = 400, .waveFreq = { 400, 450, 0 }, 0, 0 },
+                        { .duration = 2000, .waveFreq = { 0 }, 0, 0},
+                        { .duration = 0, .waveFreq = { 0 }, 0, 0}},
+          .repeatCnt = ToneGenerator::TONEGEN_INF,
+          .repeatSegment = 0 },                              // TONE_UK_RINGTONE
 
 
 
@@ -767,7 +774,18 @@
             TONE_SUP_ERROR,              // TONE_SUP_ERROR
             TONE_SUP_CALL_WAITING,       // TONE_SUP_CALL_WAITING
             TONE_SUP_RINGTONE            // TONE_SUP_RINGTONE
+        },
+        {   // UK
+            TONE_SUP_DIAL,               // TONE_SUP_DIAL
+            TONE_SUP_BUSY,               // TONE_SUP_BUSY
+            TONE_SUP_CONGESTION,         // TONE_SUP_CONGESTION
+            TONE_SUP_RADIO_ACK,          // TONE_SUP_RADIO_ACK
+            TONE_SUP_RADIO_NOTAVAIL,     // TONE_SUP_RADIO_NOTAVAIL
+            TONE_SUP_ERROR,              // TONE_SUP_ERROR
+            TONE_SUP_CALL_WAITING,       // TONE_SUP_CALL_WAITING
+            TONE_UK_RINGTONE             // TONE_SUP_RINGTONE
         }
+
 };
 
 
@@ -819,6 +837,9 @@
         mRegion = ANSI;
     } else if (strcmp(value,"jp") == 0) {
         mRegion = JAPAN;
+    } else if (strcmp(value,"uk") == 0 ||
+               strcmp(value,"uk,uk") == 0) {
+        mRegion = UK;
     } else {
         mRegion = CEPT;
     }
diff --git a/media/libmediaplayerservice/Android.mk b/media/libmediaplayerservice/Android.mk
index 7f41143..edad4be 100644
--- a/media/libmediaplayerservice/Android.mk
+++ b/media/libmediaplayerservice/Android.mk
@@ -32,6 +32,7 @@
     libgui                      \
     libmedia                    \
     libmediautils               \
+    libmemunreachable           \
     libsonivox                  \
     libstagefright              \
     libstagefright_foundation   \
@@ -54,6 +55,7 @@
     $(TOP)/frameworks/av/include/camera                             \
     $(TOP)/frameworks/native/include/media/openmax                  \
     $(TOP)/external/tremolo/Tremolo                                 \
+    libcore/include                                                 \
 
 LOCAL_CFLAGS += -Werror -Wno-error=deprecated-declarations -Wall
 LOCAL_CLANG := true
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index 251fc53..9b081e9 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -62,6 +62,7 @@
 #include <media/stagefright/foundation/ALooperRoster.h>
 #include <mediautils/BatteryNotifier.h>
 
+#include <memunreachable/memunreachable.h>
 #include <system/audio.h>
 
 #include <private/android_filesystem_config.h>
@@ -94,6 +95,8 @@
 // Max number of entries in the filter.
 const int kMaxFilterSize = 64;  // I pulled that out of thin air.
 
+const float kMaxRequiredSpeed = 8.0f; // for PCM tracks allow up to 8x speedup.
+
 // FIXME: Move all the metadata related function in the Metadata.cpp
 
 
@@ -147,7 +150,7 @@
 
     if (p.dataAvail() < size)
     {
-        ALOGE("Filter too short expected %d but got %d", size, p.dataAvail());
+        ALOGE("Filter too short expected %zu but got %zu", size, p.dataAvail());
         *status = NOT_ENOUGH_DATA;
         return false;
     }
@@ -534,14 +537,23 @@
         gLooperRoster.dump(fd, args);
 
         bool dumpMem = false;
+        bool unreachableMemory = false;
         for (size_t i = 0; i < args.size(); i++) {
             if (args[i] == String16("-m")) {
                 dumpMem = true;
+            } else if (args[i] == String16("--unreachable")) {
+                unreachableMemory = true;
             }
         }
         if (dumpMem) {
             dumpMemoryAddresses(fd);
         }
+        if (unreachableMemory) {
+            result.append("\nDumping unreachable memory:\n");
+            // TODO - should limit be an argument parameter?
+            std::string s = GetUnreachableMemoryString(true /* contents */, 10000 /* limit */);
+            result.append(s.c_str(), s.size());
+        }
     }
     write(fd, result.string(), result.size());
     return NO_ERROR;
@@ -737,11 +749,11 @@
         return UNKNOWN_ERROR;
     }
 
-    ALOGV("st_dev  = %llu", static_cast<uint64_t>(sb.st_dev));
+    ALOGV("st_dev  = %llu", static_cast<unsigned long long>(sb.st_dev));
     ALOGV("st_mode = %u", sb.st_mode);
     ALOGV("st_uid  = %lu", static_cast<unsigned long>(sb.st_uid));
     ALOGV("st_gid  = %lu", static_cast<unsigned long>(sb.st_gid));
-    ALOGV("st_size = %llu", sb.st_size);
+    ALOGV("st_size = %llu", static_cast<unsigned long long>(sb.st_size));
 
     if (offset >= sb.st_size) {
         ALOGE("offset error");
@@ -749,7 +761,7 @@
     }
     if (offset + length > sb.st_size) {
         length = sb.st_size - offset;
-        ALOGV("calculated length = %lld", length);
+        ALOGV("calculated length = %lld", (long long)length);
     }
 
     player_type playerType = MediaPlayerFactory::getPlayerType(this,
@@ -1337,7 +1349,6 @@
     : mCallback(NULL),
       mCallbackCookie(NULL),
       mCallbackData(NULL),
-      mBytesWritten(0),
       mStreamType(AUDIO_STREAM_MUSIC),
       mLeftVolume(1.0),
       mRightVolume(1.0),
@@ -1526,8 +1537,12 @@
 {
     Mutex::Autolock lock(mLock);
     if (mTrack == 0) return NO_INIT;
-    *frameswritten = mBytesWritten / mFrameSize;
-    return OK;
+    ExtendedTimestamp ets;
+    status_t status = mTrack->getTimestamp(&ets);
+    if (status == OK || status == WOULD_BLOCK) {
+        *frameswritten = (uint32_t)ets.mPosition[ExtendedTimestamp::LOCATION_CLIENT];
+    }
+    return status;
 }
 
 status_t MediaPlayerService::AudioOutput::setParameters(const String8& keyValuePairs)
@@ -1746,6 +1761,14 @@
                     mAttributes,
                     doNotReconnect);
         } else {
+            // TODO: Due to buffer memory concerns, we use a max target playback speed
+            // based on mPlaybackRate at the time of open (instead of kMaxRequiredSpeed),
+            // also clamping the target speed to 1.0 <= targetSpeed <= kMaxRequiredSpeed.
+            const float targetSpeed =
+                    std::min(std::max(mPlaybackRate.mSpeed, 1.0f), kMaxRequiredSpeed);
+            ALOGW_IF(targetSpeed != mPlaybackRate.mSpeed,
+                    "track target speed:%f clamped from playback speed:%f",
+                    targetSpeed, mPlaybackRate.mSpeed);
             t = new AudioTrack(
                     mStreamType,
                     sampleRate,
@@ -1762,7 +1785,8 @@
                     mUid,
                     mPid,
                     mAttributes,
-                    doNotReconnect);
+                    doNotReconnect,
+                    targetSpeed);
         }
 
         if ((t == 0) || (t->initCheck() != NO_ERROR)) {
@@ -1782,7 +1806,7 @@
 
         if (!bothOffloaded) {
             if (mRecycledTrack->frameCount() != t->frameCount()) {
-                ALOGV("framecount differs: %u/%u frames",
+                ALOGV("framecount differs: %zu/%zu frames",
                       mRecycledTrack->frameCount(), t->frameCount());
                 reuse = false;
             }
@@ -1817,10 +1841,6 @@
     mFlags = flags;
     mMsecsPerFrame = 1E3f / (mPlaybackRate.mSpeed * sampleRate);
     mFrameSize = t->frameSize();
-    uint32_t pos;
-    if (t->getPosition(&pos) == OK) {
-        mBytesWritten = uint64_t(pos) * mFrameSize;
-    }
     mTrack = t;
 
     status_t res = NO_ERROR;
@@ -1914,7 +1934,6 @@
                 mNextOutput->mRecycledTrack = mTrack;
                 mNextOutput->mSampleRateHz = mSampleRateHz;
                 mNextOutput->mMsecsPerFrame = mMsecsPerFrame;
-                mNextOutput->mBytesWritten = mBytesWritten;
                 mNextOutput->mFlags = mFlags;
                 mNextOutput->mFrameSize = mFrameSize;
                 close_l();
@@ -1939,11 +1958,7 @@
 
     //ALOGV("write(%p, %u)", buffer, size);
     if (mTrack != 0) {
-        ssize_t ret = mTrack->write(buffer, size, blocking);
-        if (ret >= 0) {
-            mBytesWritten += ret;
-        }
-        return ret;
+        return mTrack->write(buffer, size, blocking);
     }
     return NO_INIT;
 }
@@ -1952,7 +1967,6 @@
 {
     ALOGV("stop");
     Mutex::Autolock lock(mLock);
-    mBytesWritten = 0;
     if (mTrack != 0) mTrack->stop();
 }
 
@@ -1960,7 +1974,6 @@
 {
     ALOGV("flush");
     Mutex::Autolock lock(mLock);
-    mBytesWritten = 0;
     if (mTrack != 0) mTrack->flush();
 }
 
@@ -2086,7 +2099,6 @@
 
         ALOGV_IF(actualSize == 0 && buffer->size > 0, "callbackwrapper: empty buffer returned");
 
-        me->mBytesWritten += actualSize;  // benign race with reader.
         buffer->size = actualSize;
         } break;
 
@@ -2136,6 +2148,19 @@
     return mTrack->getSampleRate();
 }
 
+int64_t MediaPlayerService::AudioOutput::getBufferDurationInUs() const
+{
+    Mutex::Autolock lock(mLock);
+    if (mTrack == 0) {
+        return 0;
+    }
+    int64_t duration;
+    if (mTrack->getBufferDurationInUs(&duration) != OK) {
+        return 0;
+    }
+    return duration;
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 
 struct CallbackThread : public Thread {
diff --git a/media/libmediaplayerservice/MediaPlayerService.h b/media/libmediaplayerservice/MediaPlayerService.h
index 1dd2ddd..80593b2 100644
--- a/media/libmediaplayerservice/MediaPlayerService.h
+++ b/media/libmediaplayerservice/MediaPlayerService.h
@@ -92,6 +92,7 @@
         virtual status_t        getFramesWritten(uint32_t *frameswritten) const;
         virtual audio_session_t getSessionId() const;
         virtual uint32_t        getSampleRate() const;
+        virtual int64_t         getBufferDurationInUs() const;
 
         virtual status_t        open(
                 uint32_t sampleRate, int channelCount, audio_channel_mask_t channelMask,
@@ -141,7 +142,6 @@
         AudioCallback           mCallback;
         void *                  mCallbackCookie;
         CallbackData *          mCallbackData;
-        uint64_t                mBytesWritten;
         audio_stream_type_t     mStreamType;
         audio_attributes_t *    mAttributes;
         float                   mLeftVolume;
diff --git a/media/libmediaplayerservice/MediaRecorderClient.cpp b/media/libmediaplayerservice/MediaRecorderClient.cpp
index 73abe99..3152e04 100644
--- a/media/libmediaplayerservice/MediaRecorderClient.cpp
+++ b/media/libmediaplayerservice/MediaRecorderClient.cpp
@@ -163,7 +163,7 @@
 
 status_t MediaRecorderClient::setOutputFile(int fd, int64_t offset, int64_t length)
 {
-    ALOGV("setOutputFile(%d, %lld, %lld)", fd, offset, length);
+    ALOGV("setOutputFile(%d, %lld, %lld)", fd, (long long)offset, (long long)length);
     Mutex::Autolock lock(mLock);
     if (mRecorder == NULL) {
         ALOGE("recorder is not initialized");
diff --git a/media/libmediaplayerservice/MetadataRetrieverClient.cpp b/media/libmediaplayerservice/MetadataRetrieverClient.cpp
index b5e5225..bb808e1 100644
--- a/media/libmediaplayerservice/MetadataRetrieverClient.cpp
+++ b/media/libmediaplayerservice/MetadataRetrieverClient.cpp
@@ -143,19 +143,20 @@
         ALOGE("fstat(%d) failed: %d, %s", fd, ret, strerror(errno));
         return BAD_VALUE;
     }
-    ALOGV("st_dev  = %llu", static_cast<uint64_t>(sb.st_dev));
+    ALOGV("st_dev  = %llu", static_cast<unsigned long long>(sb.st_dev));
     ALOGV("st_mode = %u", sb.st_mode);
     ALOGV("st_uid  = %lu", static_cast<unsigned long>(sb.st_uid));
     ALOGV("st_gid  = %lu", static_cast<unsigned long>(sb.st_gid));
-    ALOGV("st_size = %llu", sb.st_size);
+    ALOGV("st_size = %llu", static_cast<unsigned long long>(sb.st_size));
 
     if (offset >= sb.st_size) {
-        ALOGE("offset (%lld) bigger than file size (%llu)", offset, sb.st_size);
+        ALOGE("offset (%lld) bigger than file size (%llu)",
+                (long long)offset, (unsigned long long)sb.st_size);
         return BAD_VALUE;
     }
     if (offset + length > sb.st_size) {
         length = sb.st_size - offset;
-        ALOGV("calculated length = %lld", length);
+        ALOGV("calculated length = %lld", (long long)length);
     }
 
     player_type playerType =
@@ -194,7 +195,7 @@
 
 sp<IMemory> MetadataRetrieverClient::getFrameAtTime(int64_t timeUs, int option)
 {
-    ALOGV("getFrameAtTime: time(%lld us) option(%d)", timeUs, option);
+    ALOGV("getFrameAtTime: time(%lld us) option(%d)", (long long)timeUs, option);
     Mutex::Autolock lock(mLock);
     Mutex::Autolock glock(sLock);
     mThumbnail.clear();
@@ -216,7 +217,7 @@
     }
     mThumbnail = new MemoryBase(heap, 0, size);
     if (mThumbnail == NULL) {
-        ALOGE("not enough memory for VideoFrame size=%u", size);
+        ALOGE("not enough memory for VideoFrame size=%zu", size);
         delete frame;
         return NULL;
     }
@@ -257,7 +258,7 @@
     }
     mAlbumArt = new MemoryBase(heap, 0, size);
     if (mAlbumArt == NULL) {
-        ALOGE("not enough memory for MediaAlbumArt size=%u", size);
+        ALOGE("not enough memory for MediaAlbumArt size=%zu", size);
         delete albumArt;
         return NULL;
     }
diff --git a/media/libmediaplayerservice/StagefrightRecorder.cpp b/media/libmediaplayerservice/StagefrightRecorder.cpp
index 78eb3b0..3f7367f 100644
--- a/media/libmediaplayerservice/StagefrightRecorder.cpp
+++ b/media/libmediaplayerservice/StagefrightRecorder.cpp
@@ -248,7 +248,7 @@
 }
 
 status_t StagefrightRecorder::setOutputFile(int fd, int64_t offset, int64_t length) {
-    ALOGV("setOutputFile: %d, %lld, %lld", fd, offset, length);
+    ALOGV("setOutputFile: %d, %lld, %lld", fd, (long long)offset, (long long)length);
     // These don't make any sense, do they?
     CHECK_EQ(offset, 0ll);
     CHECK_EQ(length, 0ll);
@@ -415,39 +415,40 @@
 }
 
 status_t StagefrightRecorder::setParamMaxFileDurationUs(int64_t timeUs) {
-    ALOGV("setParamMaxFileDurationUs: %lld us", timeUs);
+    ALOGV("setParamMaxFileDurationUs: %lld us", (long long)timeUs);
 
     // This is meant for backward compatibility for MediaRecorder.java
     if (timeUs <= 0) {
-        ALOGW("Max file duration is not positive: %lld us. Disabling duration limit.", timeUs);
+        ALOGW("Max file duration is not positive: %lld us. Disabling duration limit.",
+                (long long)timeUs);
         timeUs = 0; // Disable the duration limit for zero or negative values.
     } else if (timeUs <= 100000LL) {  // XXX: 100 milli-seconds
-        ALOGE("Max file duration is too short: %lld us", timeUs);
+        ALOGE("Max file duration is too short: %lld us", (long long)timeUs);
         return BAD_VALUE;
     }
 
     if (timeUs <= 15 * 1000000LL) {
-        ALOGW("Target duration (%lld us) too short to be respected", timeUs);
+        ALOGW("Target duration (%lld us) too short to be respected", (long long)timeUs);
     }
     mMaxFileDurationUs = timeUs;
     return OK;
 }
 
 status_t StagefrightRecorder::setParamMaxFileSizeBytes(int64_t bytes) {
-    ALOGV("setParamMaxFileSizeBytes: %lld bytes", bytes);
+    ALOGV("setParamMaxFileSizeBytes: %lld bytes", (long long)bytes);
 
     // This is meant for backward compatibility for MediaRecorder.java
     if (bytes <= 0) {
         ALOGW("Max file size is not positive: %lld bytes. "
-             "Disabling file size limit.", bytes);
+             "Disabling file size limit.", (long long)bytes);
         bytes = 0; // Disable the file size limit for zero or negative values.
     } else if (bytes <= 1024) {  // XXX: 1 kB
-        ALOGE("Max file size is too small: %lld bytes", bytes);
+        ALOGE("Max file size is too small: %lld bytes", (long long)bytes);
         return BAD_VALUE;
     }
 
     if (bytes <= 100 * 1024) {
-        ALOGW("Target file size (%lld bytes) is too small to be respected", bytes);
+        ALOGW("Target file size (%lld bytes) is too small to be respected", (long long)bytes);
     }
 
     mMaxFileSizeBytes = bytes;
@@ -499,9 +500,9 @@
 }
 
 status_t StagefrightRecorder::setParamTrackTimeStatus(int64_t timeDurationUs) {
-    ALOGV("setParamTrackTimeStatus: %lld", timeDurationUs);
+    ALOGV("setParamTrackTimeStatus: %lld", (long long)timeDurationUs);
     if (timeDurationUs < 20000) {  // Infeasible if shorter than 20 ms?
-        ALOGE("Tracking time duration too short: %lld us", timeDurationUs);
+        ALOGE("Tracking time duration too short: %lld us", (long long)timeDurationUs);
         return BAD_VALUE;
     }
     mTrackEveryTimeDurationUs = timeDurationUs;
@@ -584,7 +585,7 @@
 
     // Not allowing time more than a day
     if (timeUs <= 0 || timeUs > 86400*1E6) {
-        ALOGE("Time between frame capture (%lld) is out of range [0, 1 Day]", timeUs);
+        ALOGE("Time between frame capture (%lld) is out of range [0, 1 Day]", (long long)timeUs);
         return BAD_VALUE;
     }
 
@@ -1433,7 +1434,7 @@
     if (mCaptureFpsEnable) {
         if (mTimeBetweenCaptureUs < 0) {
             ALOGE("Invalid mTimeBetweenTimeLapseFrameCaptureUs value: %lld",
-                mTimeBetweenCaptureUs);
+                    (long long)mTimeBetweenCaptureUs);
             return BAD_VALUE;
         }
 
@@ -1538,7 +1539,7 @@
         if (mCaptureFpsEnable) {
             if (mTimeBetweenCaptureUs <= 0) {
                 ALOGE("Invalid mTimeBetweenCaptureUs value: %lld",
-                        mTimeBetweenCaptureUs);
+                        (long long)mTimeBetweenCaptureUs);
                 return BAD_VALUE;
             }
             format->setInt64("time-lapse", mTimeBetweenCaptureUs);
@@ -1792,6 +1793,7 @@
         mWriter.clear();
     }
     mTotalPausedDurationUs = 0;
+    mPauseStartTimeUs = 0;
 
     mGraphicBufferProducer.clear();
     mPersistentSurface.clear();
@@ -1872,7 +1874,6 @@
     mTotalBitRate = 0;
 
     mOutputFd = -1;
-    mPauseStartTimeUs = 0;
 
     return OK;
 }
diff --git a/media/libmediaplayerservice/nuplayer/GenericSource.cpp b/media/libmediaplayerservice/nuplayer/GenericSource.cpp
index 08ac941..81aafbe 100644
--- a/media/libmediaplayerservice/nuplayer/GenericSource.cpp
+++ b/media/libmediaplayerservice/nuplayer/GenericSource.cpp
@@ -1428,7 +1428,11 @@
 
         if (err == OK) {
             int64_t timeUs;
-            CHECK(mbuf->meta_data()->findInt64(kKeyTime, &timeUs));
+            if (!mbuf->meta_data()->findInt64(kKeyTime, &timeUs)) {
+                mbuf->meta_data()->dumpToLog();
+                track->mPackets->signalEOS(ERROR_MALFORMED);
+                break;
+            }
             if (trackType == MEDIA_TRACK_TYPE_AUDIO) {
                 mAudioTimeUs = timeUs;
                 mBufferingMonitor->updateQueuedTime(true /* isAudio */, timeUs);
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
index 42a82ac..46a51ce 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
@@ -400,14 +400,20 @@
 }
 
 void NuPlayer::resetAsync() {
-    if (mSource != NULL) {
+    sp<Source> source;
+    {
+        Mutex::Autolock autoLock(mSourceLock);
+        source = mSource;
+    }
+
+    if (source != NULL) {
         // During a reset, the data source might be unresponsive already, we need to
         // disconnect explicitly so that reads exit promptly.
         // We can't queue the disconnect request to the looper, as it might be
         // queued behind a stuck read and never gets processed.
         // Doing a disconnect outside the looper to allows the pending reads to exit
         // (either successfully or with error).
-        mSource->disconnect();
+        source->disconnect();
     }
 
     (new AMessage(kWhatReset, this))->post();
@@ -484,6 +490,7 @@
             sp<RefBase> obj;
             CHECK(msg->findObject("source", &obj));
             if (obj != NULL) {
+                Mutex::Autolock autoLock(mSourceLock);
                 mSource = static_cast<Source *>(obj.get());
             } else {
                 err = UNKNOWN_ERROR;
@@ -1144,6 +1151,11 @@
                 int32_t reason;
                 CHECK(msg->findInt32("reason", &reason));
                 ALOGV("Tear down audio with reason %d.", reason);
+                if (reason == Renderer::kDueToTimeout && !(mPaused && mOffloadAudio)) {
+                    // TimeoutWhenPaused is only for offload mode.
+                    ALOGW("Receive a stale message for teardown.");
+                    break;
+                }
                 int64_t positionUs;
                 if (!msg->findInt64("positionUs", &positionUs)) {
                     positionUs = mPreviousSeekTimeUs;
@@ -1998,6 +2010,7 @@
     if (mSource != NULL) {
         mSource->stop();
 
+        Mutex::Autolock autoLock(mSourceLock);
         mSource.clear();
     }
 
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.h b/media/libmediaplayerservice/nuplayer/NuPlayer.h
index 369590b..f6eb49e 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.h
@@ -140,6 +140,7 @@
     bool mUIDValid;
     uid_t mUID;
     pid_t mPID;
+    Mutex mSourceLock;  // guard |mSource|.
     sp<Source> mSource;
     uint32_t mSourceFlags;
     sp<Surface> mSurface;
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
index cbb9d95..4ae8e82 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
@@ -19,6 +19,7 @@
 #include <utils/Log.h>
 
 #include "NuPlayerRenderer.h"
+#include <algorithm>
 #include <cutils/properties.h>
 #include <media/stagefright/foundation/ABuffer.h>
 #include <media/stagefright/foundation/ADebug.h>
@@ -487,8 +488,14 @@
 
                 // Let's give it more data after about half that time
                 // has elapsed.
+                delayUs /= 2;
+                // check the buffer size to estimate maximum delay permitted.
+                const int64_t maxDrainDelayUs = std::max(
+                        mAudioSink->getBufferDurationInUs(), (int64_t)500000 /* half second */);
+                ALOGD_IF(delayUs > maxDrainDelayUs, "postDrainAudioQueue long delay: %lld > %lld",
+                        (long long)delayUs, (long long)maxDrainDelayUs);
                 Mutex::Autolock autoLock(mLock);
-                postDrainAudioQueue_l(delayUs / 2);
+                postDrainAudioQueue_l(delayUs);
             }
             break;
         }
@@ -1715,10 +1722,16 @@
 }
 
 void NuPlayer::Renderer::cancelAudioOffloadPauseTimeout() {
-    if (offloadingAudio()) {
-        mWakeLock->release(true);
-        ++mAudioOffloadPauseTimeoutGeneration;
-    }
+    // We may have called startAudioOffloadPauseTimeout() without
+    // the AudioSink open and with offloadingAudio enabled.
+    //
+    // When we cancel, it may be that offloadingAudio is subsequently disabled, so regardless
+    // we always release the wakelock and increment the pause timeout generation.
+    //
+    // Note: The acquired wakelock prevents the device from suspending
+    // immediately after offload pause (in case a resume happens shortly thereafter).
+    mWakeLock->release(true);
+    ++mAudioOffloadPauseTimeoutGeneration;
 }
 
 status_t NuPlayer::Renderer::onOpenAudioSink(
@@ -1876,6 +1889,10 @@
         // NuPlayer a chance to switch from non-offload mode to offload mode.
         // So we only set doNotReconnect when there's no video.
         const bool doNotReconnect = !hasVideo;
+
+        // We should always be able to set our playback settings if the sink is closed.
+        LOG_ALWAYS_FATAL_IF(mAudioSink->setPlaybackRate(mPlaybackSettings) != OK,
+                "onOpenAudioSink: can't set playback rate on closed sink");
         status_t err = mAudioSink->open(
                     sampleRate,
                     numChannels,
@@ -1888,9 +1905,6 @@
                     NULL,
                     doNotReconnect,
                     frameCount);
-        if (err == OK) {
-            err = mAudioSink->setPlaybackRate(mPlaybackSettings);
-        }
         if (err != OK) {
             ALOGW("openAudioSink: non offloaded open failed status: %d", err);
             mAudioSink->close();
diff --git a/media/libstagefright/MPEG4Writer.cpp b/media/libstagefright/MPEG4Writer.cpp
index 7a8f4c0..db20590 100644
--- a/media/libstagefright/MPEG4Writer.cpp
+++ b/media/libstagefright/MPEG4Writer.cpp
@@ -2261,6 +2261,7 @@
 
     HevcParameterSets paramSets;
     if (parseHEVCCodecSpecificData(data, size, paramSets) != OK) {
+        ALOGE("failed parsing codec specific data");
         return ERROR_MALFORMED;
     }
 
@@ -2271,8 +2272,9 @@
         return NO_MEMORY;
     }
     status_t err = paramSets.makeHvcc((uint8_t *)mCodecSpecificData,
-            &mCodecSpecificDataSize, mOwner->useNalLengthFour() ? 5 : 2);
+            &mCodecSpecificDataSize, mOwner->useNalLengthFour() ? 4 : 2);
     if (err != OK) {
+        ALOGE("failed constructing HVCC atom");
         return err;
     }
 
diff --git a/media/libstagefright/OggExtractor.cpp b/media/libstagefright/OggExtractor.cpp
index 9162f80..37e8e9c 100644
--- a/media/libstagefright/OggExtractor.cpp
+++ b/media/libstagefright/OggExtractor.cpp
@@ -713,6 +713,7 @@
                     packetSize);
 
             if (n < (ssize_t)packetSize) {
+                buffer->release();
                 ALOGV("failed to read %zu bytes at %#016llx, got %zd bytes",
                         packetSize, (long long)dataOffset, n);
                 return ERROR_IO;
diff --git a/media/libstagefright/SampleTable.cpp b/media/libstagefright/SampleTable.cpp
index 1bdd812..542a06d 100644
--- a/media/libstagefright/SampleTable.cpp
+++ b/media/libstagefright/SampleTable.cpp
@@ -121,8 +121,9 @@
       mSampleSizeFieldSize(0),
       mDefaultSampleSize(0),
       mNumSampleSizes(0),
+      mHasTimeToSample(false),
       mTimeToSampleCount(0),
-      mTimeToSample(NULL),
+      mTimeToSample(),
       mSampleTimeEntries(NULL),
       mCompositionTimeDeltaEntries(NULL),
       mNumCompositionTimeDeltaEntries(0),
@@ -151,9 +152,6 @@
     delete[] mSampleTimeEntries;
     mSampleTimeEntries = NULL;
 
-    delete[] mTimeToSample;
-    mTimeToSample = NULL;
-
     delete mSampleIterator;
     mSampleIterator = NULL;
 }
@@ -162,7 +160,7 @@
     return mChunkOffsetOffset >= 0
         && mSampleToChunkOffset >= 0
         && mSampleSizeOffset >= 0
-        && mTimeToSample != NULL;
+        && mHasTimeToSample;
 }
 
 status_t SampleTable::setChunkOffsetParams(
@@ -336,7 +334,7 @@
 
 status_t SampleTable::setTimeToSampleParams(
         off64_t data_offset, size_t data_size) {
-    if (mTimeToSample != NULL || data_size < 8) {
+    if (mHasTimeToSample || data_size < 8) {
         return ERROR_MALFORMED;
     }
 
@@ -352,24 +350,31 @@
     }
 
     mTimeToSampleCount = U32_AT(&header[4]);
-    uint64_t allocSize = (uint64_t)mTimeToSampleCount * 2 * sizeof(uint32_t);
-    if (allocSize > UINT32_MAX) {
+    if ((uint64_t)mTimeToSampleCount >
+        (uint64_t)UINT32_MAX / (2 * sizeof(uint32_t))) {
+        // Choose this bound because
+        // 1) 2 * sizeof(uint32_t) is the amount of memory needed for one
+        //    time-to-sample entry in the time-to-sample table.
+        // 2) mTimeToSampleCount is the number of entries of the time-to-sample
+        //    table.
+        // 3) We hope that the table size does not exceed UINT32_MAX.
+        ALOGE("  Error: Time-to-sample table size too large.");
         return ERROR_OUT_OF_RANGE;
     }
-    mTimeToSample = new (std::nothrow) uint32_t[mTimeToSampleCount * 2];
-    if (!mTimeToSample)
-        return ERROR_OUT_OF_RANGE;
 
-    size_t size = sizeof(uint32_t) * mTimeToSampleCount * 2;
-    if (mDataSource->readAt(
-                data_offset + 8, mTimeToSample, size) < (ssize_t)size) {
+    // Note: At this point, we know that mTimeToSampleCount * 2 will not
+    // overflow because of the above condition.
+    if (!mDataSource->getVector(data_offset + 8, &mTimeToSample,
+                                mTimeToSampleCount * 2)) {
+        ALOGE("  Error: Incomplete data read for time-to-sample table.");
         return ERROR_IO;
     }
 
-    for (uint32_t i = 0; i < mTimeToSampleCount * 2; ++i) {
-        mTimeToSample[i] = ntohl(mTimeToSample[i]);
+    for (size_t i = 0; i < mTimeToSample.size(); ++i) {
+        mTimeToSample.editItemAt(i) = ntohl(mTimeToSample[i]);
     }
 
+    mHasTimeToSample = true;
     return OK;
 }
 
diff --git a/media/libstagefright/StagefrightMetadataRetriever.cpp b/media/libstagefright/StagefrightMetadataRetriever.cpp
index c6e3571..a62e1a2 100644
--- a/media/libstagefright/StagefrightMetadataRetriever.cpp
+++ b/media/libstagefright/StagefrightMetadataRetriever.cpp
@@ -61,7 +61,9 @@
 StagefrightMetadataRetriever::~StagefrightMetadataRetriever() {
     ALOGV("~StagefrightMetadataRetriever()");
     clearMetadata();
-    mSource->close();
+    if (mSource != NULL) {
+        mSource->close();
+    }
 }
 
 status_t StagefrightMetadataRetriever::setDataSource(
@@ -704,7 +706,7 @@
         mMetaData.add(METADATA_KEY_BITRATE, String8(tmp));
     } else {
         off64_t sourceSize;
-        if (mSource->getSize(&sourceSize) == OK) {
+        if (mSource != NULL && mSource->getSize(&sourceSize) == OK) {
             int64_t avgBitRate = (int64_t)(sourceSize * 8E6 / maxDurationUs);
 
             sprintf(tmp, "%" PRId64, avgBitRate);
diff --git a/media/libstagefright/Utils.cpp b/media/libstagefright/Utils.cpp
index 7daae20..448f8aa 100644
--- a/media/libstagefright/Utils.cpp
+++ b/media/libstagefright/Utils.cpp
@@ -828,8 +828,13 @@
     }
 
     int32_t fps;
+    float fpsFloat;
     if (msg->findInt32("frame-rate", &fps) && fps > 0) {
         meta->setInt32(kKeyFrameRate, fps);
+    } else if (msg->findFloat("frame-rate", &fpsFloat)
+            && fpsFloat >= 1 && fpsFloat <= INT32_MAX) {
+        // truncate values to distinguish between e.g. 24 vs 23.976 fps
+        meta->setInt32(kKeyFrameRate, (int32_t)fpsFloat);
     }
 
     // reassemble the csd data into its original form
diff --git a/media/libstagefright/codecs/g711/dec/SoftG711.cpp b/media/libstagefright/codecs/g711/dec/SoftG711.cpp
index 958e7c4..9f7b590 100644
--- a/media/libstagefright/codecs/g711/dec/SoftG711.cpp
+++ b/media/libstagefright/codecs/g711/dec/SoftG711.cpp
@@ -240,6 +240,15 @@
             mSignalledError = true;
         }
 
+        if (inHeader->nFilledLen * sizeof(int16_t) > outHeader->nAllocLen) {
+            ALOGE("output buffer too small (%d).", outHeader->nAllocLen);
+            android_errorWriteLog(0x534e4554, "27793163");
+
+            notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
+            mSignalledError = true;
+            return;
+        }
+
         const uint8_t *inputptr = inHeader->pBuffer + inHeader->nOffset;
 
         if (mIsMLaw) {
diff --git a/media/libstagefright/codecs/gsm/dec/SoftGSM.cpp b/media/libstagefright/codecs/gsm/dec/SoftGSM.cpp
index 7916c45..04d5a33 100644
--- a/media/libstagefright/codecs/gsm/dec/SoftGSM.cpp
+++ b/media/libstagefright/codecs/gsm/dec/SoftGSM.cpp
@@ -228,6 +228,14 @@
             mSignalledError = true;
         }
 
+        if (outHeader->nAllocLen < (inHeader->nFilledLen / kMSGSMFrameSize) * 320) {
+            ALOGE("output buffer is not large enough (%d).", outHeader->nAllocLen);
+            android_errorWriteLog(0x534e4554, "27793367");
+            notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
+            mSignalledError = true;
+            return;
+        }
+
         uint8_t *inputptr = inHeader->pBuffer + inHeader->nOffset;
 
         int n = mSignalledError ? 0 : DecodeGSM(mGsm,
diff --git a/media/libstagefright/codecs/hevcdec/SoftHEVC.cpp b/media/libstagefright/codecs/hevcdec/SoftHEVC.cpp
index 7df6156..54736f8 100644
--- a/media/libstagefright/codecs/hevcdec/SoftHEVC.cpp
+++ b/media/libstagefright/codecs/hevcdec/SoftHEVC.cpp
@@ -564,6 +564,8 @@
                 mChangingResolution = false;
                 resetDecoder();
                 resetPlugin();
+                mStride = outputBufferWidth();
+                setParams(mStride);
                 continue;
             }
 
diff --git a/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp b/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp
index 0c1a149..bb59ae4 100644
--- a/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp
+++ b/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp
@@ -229,6 +229,14 @@
         int32_t bufferSize = inHeader->nFilledLen;
         int32_t tmp = bufferSize;
 
+        OMX_U32 frameSize = (mWidth * mHeight * 3) / 2;
+        if (outHeader->nAllocLen < frameSize) {
+            android_errorWriteLog(0x534e4554, "27833616");
+            ALOGE("Insufficient output buffer size");
+            notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
+            mSignalledError = true;
+            return;
+        }
         // The PV decoder is lying to us, sometimes it'll claim to only have
         // consumed a subset of the buffer when it clearly consumed all of it.
         // ignore whatever it says...
@@ -272,7 +280,7 @@
         ++mInputBufferCount;
 
         outHeader->nOffset = 0;
-        outHeader->nFilledLen = (mWidth * mHeight * 3) / 2;
+        outHeader->nFilledLen = frameSize;
 
         List<BufferInfo *>::iterator it = outQueue.begin();
         while ((*it)->mHeader != outHeader) {
diff --git a/media/libstagefright/codecs/on2/h264dec/SoftAVC.cpp b/media/libstagefright/codecs/on2/h264dec/SoftAVC.cpp
index 6b8b395..2f61d12 100644
--- a/media/libstagefright/codecs/on2/h264dec/SoftAVC.cpp
+++ b/media/libstagefright/codecs/on2/h264dec/SoftAVC.cpp
@@ -202,7 +202,12 @@
         }
 
         if (mFirstPicture && !outQueue.empty()) {
-            drainOneOutputBuffer(mFirstPictureId, mFirstPicture);
+            if (!drainOneOutputBuffer(mFirstPictureId, mFirstPicture)) {
+                ALOGE("Drain failed");
+                notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
+                mSignalledError = true;
+                return;
+            }
             delete[] mFirstPicture;
             mFirstPicture = NULL;
             mFirstPictureId = -1;
@@ -242,15 +247,20 @@
     memcpy(mFirstPicture, data, pictureSize);
 }
 
-void SoftAVC::drainOneOutputBuffer(int32_t picId, uint8_t* data) {
+bool SoftAVC::drainOneOutputBuffer(int32_t picId, uint8_t* data) {
     List<BufferInfo *> &outQueue = getPortQueue(kOutputPortIndex);
     BufferInfo *outInfo = *outQueue.begin();
-    outQueue.erase(outQueue.begin());
     OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader;
+    OMX_U32 frameSize = mWidth * mHeight * 3 / 2;
+    if (outHeader->nAllocLen - outHeader->nOffset < frameSize) {
+        android_errorWriteLog(0x534e4554, "27833616");
+        return false;
+    }
+    outQueue.erase(outQueue.begin());
     OMX_BUFFERHEADERTYPE *header = mPicToHeaderMap.valueFor(picId);
     outHeader->nTimeStamp = header->nTimeStamp;
     outHeader->nFlags = header->nFlags;
-    outHeader->nFilledLen = mWidth * mHeight * 3 / 2;
+    outHeader->nFilledLen = frameSize;
 
     uint8_t *dst = outHeader->pBuffer + outHeader->nOffset;
     const uint8_t *srcY = data;
@@ -265,6 +275,7 @@
     delete header;
     outInfo->mOwnedByUs = false;
     notifyFillBufferDone(outHeader);
+    return true;
 }
 
 void SoftAVC::drainAllOutputBuffers(bool eos) {
@@ -277,7 +288,12 @@
                     mHandle, &decodedPicture, eos /* flush */)) {
             int32_t picId = decodedPicture.picId;
             uint8_t *data = (uint8_t *) decodedPicture.pOutputPicture;
-            drainOneOutputBuffer(picId, data);
+            if (!drainOneOutputBuffer(picId, data)) {
+                ALOGE("Drain failed");
+                notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
+                mSignalledError = true;
+                return;
+            }
         }
     }
 
diff --git a/media/libstagefright/codecs/on2/h264dec/SoftAVC.h b/media/libstagefright/codecs/on2/h264dec/SoftAVC.h
index 069107d..b8c1807 100644
--- a/media/libstagefright/codecs/on2/h264dec/SoftAVC.h
+++ b/media/libstagefright/codecs/on2/h264dec/SoftAVC.h
@@ -71,7 +71,7 @@
 
     status_t initDecoder();
     void drainAllOutputBuffers(bool eos);
-    void drainOneOutputBuffer(int32_t picId, uint8_t *data);
+    bool drainOneOutputBuffer(int32_t picId, uint8_t *data);
     void saveFirstOutputBuffer(int32_t pidId, uint8_t *data);
     CropSettingsMode handleCropParams(const H264SwDecInfo& decInfo);
 
diff --git a/media/libstagefright/codecs/on2/h264dec/inc/H264SwDecApi.h b/media/libstagefright/codecs/on2/h264dec/inc/H264SwDecApi.h
index fe112bc..9814e73 100644
--- a/media/libstagefright/codecs/on2/h264dec/inc/H264SwDecApi.h
+++ b/media/libstagefright/codecs/on2/h264dec/inc/H264SwDecApi.h
@@ -161,7 +161,7 @@
     void H264SwDecTrace(char *);
 
     /* function prototype for memory allocation */
-    void* H264SwDecMalloc(u32 size);
+    void* H264SwDecMalloc(u32 size, u32 num);
 
     /* function prototype for memory free */
     void H264SwDecFree(void *ptr);
diff --git a/media/libstagefright/codecs/on2/h264dec/source/DecTestBench.c b/media/libstagefright/codecs/on2/h264dec/source/DecTestBench.c
index dcf2ef6..55c0065 100644
--- a/media/libstagefright/codecs/on2/h264dec/source/DecTestBench.c
+++ b/media/libstagefright/codecs/on2/h264dec/source/DecTestBench.c
@@ -700,18 +700,21 @@
         library function malloc for allocation of memory.
 
 ------------------------------------------------------------------------------*/
-void* H264SwDecMalloc(u32 size)
+void* H264SwDecMalloc(u32 size, u32 num)
 {
+    if (size > UINT32_MAX / num) {
+        return NULL;
+    }
 
 #if defined(CHECK_MEMORY_USAGE)
     /* Note that if the decoder has to free and reallocate some of the buffers
      * the total value will be invalid */
     static u32 numBytes = 0;
-    numBytes += size;
+    numBytes += size * num;
     DEBUG(("Allocated %d bytes, total %d\n", size, numBytes));
 #endif
 
-    return malloc(size);
+    return malloc(size * num);
 }
 
 /*------------------------------------------------------------------------------
diff --git a/media/libstagefright/codecs/on2/h264dec/source/EvaluationTestBench.c b/media/libstagefright/codecs/on2/h264dec/source/EvaluationTestBench.c
index aadc75f..e756a1f 100644
--- a/media/libstagefright/codecs/on2/h264dec/source/EvaluationTestBench.c
+++ b/media/libstagefright/codecs/on2/h264dec/source/EvaluationTestBench.c
@@ -85,7 +85,7 @@
     rewind(finput);
 
     /* allocate memory for stream buffer, exit if unsuccessful */
-    byteStrm = byteStrmStart = (u8 *)H264SwDecMalloc(sizeof(u8)*strmLen);
+    byteStrm = byteStrmStart = (u8 *)H264SwDecMalloc(sizeof(u8), strmLen);
     if (byteStrm == NULL)
     {
         printf("UNABLE TO ALLOCATE MEMORY\n");
@@ -298,9 +298,12 @@
         library function malloc for allocation of memory.
 
 ------------------------------------------------------------------------------*/
-void* H264SwDecMalloc(u32 size)
+void* H264SwDecMalloc(u32 size, u32 num)
 {
-    return malloc(size);
+    if (size > UINT32_MAX / num) {
+        return NULL;
+    }
+    return malloc(size * num);
 }
 
 /*------------------------------------------------------------------------------
diff --git a/media/libstagefright/codecs/on2/h264dec/source/H264SwDecApi.c b/media/libstagefright/codecs/on2/h264dec/source/H264SwDecApi.c
index a073dcb..f820dfd 100644
--- a/media/libstagefright/codecs/on2/h264dec/source/H264SwDecApi.c
+++ b/media/libstagefright/codecs/on2/h264dec/source/H264SwDecApi.c
@@ -35,6 +35,8 @@
 /*------------------------------------------------------------------------------
     1. Include headers
 ------------------------------------------------------------------------------*/
+#include <log/log.h>
+
 #include <stdlib.h>
 #include <string.h>
 #include "basetype.h"
@@ -79,8 +81,13 @@
     UNUSED(string);
 }
 
-void* H264SwDecMalloc(u32 size) {
-    return malloc(size);
+void* H264SwDecMalloc(u32 size, u32 num) {
+    if (size > UINT32_MAX / num) {
+        ALOGE("can't allocate %u * %u bytes", size, num);
+        android_errorWriteLog(0x534e4554, "27855419");
+        return NULL;
+    }
+    return malloc(size * num);
 }
 
 void H264SwDecFree(void *ptr) {
@@ -144,7 +151,7 @@
         return(H264SWDEC_PARAM_ERR);
     }
 
-    pDecCont = (decContainer_t *)H264SwDecMalloc(sizeof(decContainer_t));
+    pDecCont = (decContainer_t *)H264SwDecMalloc(sizeof(decContainer_t), 1);
 
     if (pDecCont == NULL)
     {
diff --git a/media/libstagefright/codecs/on2/h264dec/source/TestBenchMultipleInstance.c b/media/libstagefright/codecs/on2/h264dec/source/TestBenchMultipleInstance.c
index 42170d3..9a386bb 100644
--- a/media/libstagefright/codecs/on2/h264dec/source/TestBenchMultipleInstance.c
+++ b/media/libstagefright/codecs/on2/h264dec/source/TestBenchMultipleInstance.c
@@ -413,9 +413,12 @@
     Function name:  H264SwDecmalloc
 
 ------------------------------------------------------------------------------*/
-void* H264SwDecMalloc(u32 size)
+void* H264SwDecMalloc(u32 size, u32 num)
 {
-    return malloc(size);
+    if (size > UINT32_MAX / num) {
+        return NULL;
+    }
+    return malloc(size * num);
 }
 
 /*------------------------------------------------------------------------------
diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_decoder.c b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_decoder.c
index a816871..0ac480f 100644
--- a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_decoder.c
+++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_decoder.c
@@ -101,7 +101,7 @@
      * specific NEON optimized "memset" for clearing the structure */
     size = (sizeof(macroblockLayer_t) + 63) & ~0x3F;
 
-    pStorage->mbLayer = (macroblockLayer_t*)H264SwDecMalloc(size);
+    pStorage->mbLayer = (macroblockLayer_t*)H264SwDecMalloc(size, 1);
     if (!pStorage->mbLayer)
         return HANTRO_NOK;
 
diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_util.h b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_util.h
index 216ad04..9f0eb7d 100644
--- a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_util.h
+++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_util.h
@@ -141,7 +141,7 @@
 /* macro to allocate memory */
 #define ALLOCATE(ptr, count, type) \
 { \
-    (ptr) = H264SwDecMalloc((count) * sizeof(type)); \
+    (ptr) = H264SwDecMalloc(sizeof(type), (count)); \
 }
 
 /* macro to free allocated memory */
diff --git a/media/libstagefright/codecs/vorbis/dec/SoftVorbis.cpp b/media/libstagefright/codecs/vorbis/dec/SoftVorbis.cpp
index f648bb3..be04e08 100644
--- a/media/libstagefright/codecs/vorbis/dec/SoftVorbis.cpp
+++ b/media/libstagefright/codecs/vorbis/dec/SoftVorbis.cpp
@@ -84,7 +84,7 @@
     def.eDir = OMX_DirInput;
     def.nBufferCountMin = kNumBuffers;
     def.nBufferCountActual = def.nBufferCountMin;
-    def.nBufferSize = 8192;
+    def.nBufferSize = kMaxNumSamplesPerBuffer * sizeof(int16_t);
     def.bEnabled = OMX_TRUE;
     def.bPopulated = OMX_FALSE;
     def.eDomain = OMX_PortDomainAudio;
diff --git a/media/libstagefright/httplive/M3UParser.cpp b/media/libstagefright/httplive/M3UParser.cpp
index ff2bb27..935f1dc 100644
--- a/media/libstagefright/httplive/M3UParser.cpp
+++ b/media/libstagefright/httplive/M3UParser.cpp
@@ -603,6 +603,18 @@
                     return ERROR_MALFORMED;
                 }
                 err = parseMetaDataDuration(line, &itemMeta, "durationUs");
+            } else if (line.startsWith("#EXT-X-DISCONTINUITY-SEQUENCE")) {
+                if (mIsVariantPlaylist) {
+                    return ERROR_MALFORMED;
+                }
+                size_t seq;
+                err = parseDiscontinuitySequence(line, &seq);
+                if (err == OK) {
+                    mDiscontinuitySeq = seq;
+                    ALOGI("mDiscontinuitySeq %zu", mDiscontinuitySeq);
+                } else {
+                    ALOGI("Failed to parseDiscontinuitySequence %d", err);
+                }
             } else if (line.startsWith("#EXT-X-DISCONTINUITY")) {
                 if (mIsVariantPlaylist) {
                     return ERROR_MALFORMED;
@@ -638,15 +650,6 @@
                 }
             } else if (line.startsWith("#EXT-X-MEDIA")) {
                 err = parseMedia(line);
-            } else if (line.startsWith("#EXT-X-DISCONTINUITY-SEQUENCE")) {
-                if (mIsVariantPlaylist) {
-                    return ERROR_MALFORMED;
-                }
-                size_t seq;
-                err = parseDiscontinuitySequence(line, &seq);
-                if (err == OK) {
-                    mDiscontinuitySeq = seq;
-                }
             }
 
             if (err != OK) {
diff --git a/media/libstagefright/httplive/PlaylistFetcher.cpp b/media/libstagefright/httplive/PlaylistFetcher.cpp
index 0a1ed94..20d124c 100644
--- a/media/libstagefright/httplive/PlaylistFetcher.cpp
+++ b/media/libstagefright/httplive/PlaylistFetcher.cpp
@@ -368,11 +368,15 @@
         AString iv;
         if (itemMeta->findString("cipher-iv", &iv)) {
             if ((!iv.startsWith("0x") && !iv.startsWith("0X"))
-                    || iv.size() != 16 * 2 + 2) {
+                    || iv.size() > 16 * 2 + 2) {
                 ALOGE("malformed cipher IV '%s'.", iv.c_str());
                 return ERROR_MALFORMED;
             }
 
+            while (iv.size() < 16 * 2 + 2) {
+                iv.insert("0", 1, 2);
+            }
+
             memset(mAESInitVec, 0, sizeof(mAESInitVec));
             for (size_t i = 0; i < 16; ++i) {
                 char c1 = tolower(iv.c_str()[2 + 2 * i]);
@@ -1180,8 +1184,7 @@
         // Signal a format discontinuity to ATSParser to clear partial data
         // from previous streams. Not doing this causes bitstream corruption.
         if (mTSParser != NULL) {
-            mTSParser->signalDiscontinuity(
-                    ATSParser::DISCONTINUITY_FORMATCHANGE, NULL /* extra */);
+            mTSParser.clear();
         }
 
         queueDiscontinuity(
diff --git a/media/libstagefright/include/SampleTable.h b/media/libstagefright/include/SampleTable.h
index 738f864..54da497 100644
--- a/media/libstagefright/include/SampleTable.h
+++ b/media/libstagefright/include/SampleTable.h
@@ -24,6 +24,7 @@
 #include <media/stagefright/MediaErrors.h>
 #include <utils/RefBase.h>
 #include <utils/threads.h>
+#include <utils/Vector.h>
 
 namespace android {
 
@@ -110,8 +111,9 @@
     uint32_t mDefaultSampleSize;
     uint32_t mNumSampleSizes;
 
+    bool mHasTimeToSample;
     uint32_t mTimeToSampleCount;
-    uint32_t *mTimeToSample;
+    Vector<uint32_t> mTimeToSample;
 
     struct SampleTimeEntry {
         uint32_t mSampleIndex;
diff --git a/media/libstagefright/matroska/MatroskaExtractor.h b/media/libstagefright/matroska/MatroskaExtractor.h
index 592e7cf..9406829 100644
--- a/media/libstagefright/matroska/MatroskaExtractor.h
+++ b/media/libstagefright/matroska/MatroskaExtractor.h
@@ -18,7 +18,7 @@
 
 #define MATROSKA_EXTRACTOR_H_
 
-#include "mkvparser.hpp"
+#include "mkvparser/mkvparser.h"
 
 #include <media/stagefright/MediaExtractor.h>
 #include <utils/Vector.h>
diff --git a/media/libstagefright/mpeg2ts/ATSParser.cpp b/media/libstagefright/mpeg2ts/ATSParser.cpp
index fb43a38..b8248c4 100644
--- a/media/libstagefright/mpeg2ts/ATSParser.cpp
+++ b/media/libstagefright/mpeg2ts/ATSParser.cpp
@@ -1438,8 +1438,8 @@
 
             // The number of bytes received by this parser up to and
             // including the final byte of this PCR_ext field.
-            size_t byteOffsetFromStart =
-                mNumTSPacketsParsed * 188 + byteOffsetFromStartOfTSPacket;
+            uint64_t byteOffsetFromStart =
+                uint64_t(mNumTSPacketsParsed) * 188 + byteOffsetFromStartOfTSPacket;
 
             for (size_t i = 0; i < mPrograms.size(); ++i) {
                 updatePCR(PID, PCR, byteOffsetFromStart);
@@ -1558,8 +1558,8 @@
 
 __attribute__((no_sanitize("integer")))
 void ATSParser::updatePCR(
-        unsigned /* PID */, uint64_t PCR, size_t byteOffsetFromStart) {
-    ALOGV("PCR 0x%016" PRIx64 " @ %zu", PCR, byteOffsetFromStart);
+        unsigned /* PID */, uint64_t PCR, uint64_t byteOffsetFromStart) {
+    ALOGV("PCR 0x%016" PRIx64 " @ %" PRIx64, PCR, byteOffsetFromStart);
 
     if (mNumPCRs == 2) {
         mPCR[0] = mPCR[1];
diff --git a/media/libstagefright/mpeg2ts/ATSParser.h b/media/libstagefright/mpeg2ts/ATSParser.h
index fb03cd6..9d9102d 100644
--- a/media/libstagefright/mpeg2ts/ATSParser.h
+++ b/media/libstagefright/mpeg2ts/ATSParser.h
@@ -182,10 +182,10 @@
     // see feedTSPacket().
     status_t parseTS(ABitReader *br, SyncEvent *event);
 
-    void updatePCR(unsigned PID, uint64_t PCR, size_t byteOffsetFromStart);
+    void updatePCR(unsigned PID, uint64_t PCR, uint64_t byteOffsetFromStart);
 
     uint64_t mPCR[2];
-    size_t mPCRBytes[2];
+    uint64_t mPCRBytes[2];
     int64_t mSystemTimeUs[2];
     size_t mNumPCRs;
 
diff --git a/media/libstagefright/omx/SoftVideoEncoderOMXComponent.cpp b/media/libstagefright/omx/SoftVideoEncoderOMXComponent.cpp
index 72823e2..c3a481a 100644
--- a/media/libstagefright/omx/SoftVideoEncoderOMXComponent.cpp
+++ b/media/libstagefright/omx/SoftVideoEncoderOMXComponent.cpp
@@ -170,6 +170,11 @@
 
 OMX_ERRORTYPE SoftVideoEncoderOMXComponent::internalSetPortParams(
         const OMX_PARAM_PORTDEFINITIONTYPE *port) {
+
+    if (!isValidOMXParam(port)) {
+        return OMX_ErrorBadParameter;
+    }
+
     if (port->nPortIndex == kInputPortIndex) {
         mWidth = port->format.video.nFrameWidth;
         mHeight = port->format.video.nFrameHeight;
@@ -216,6 +221,10 @@
             const OMX_PARAM_COMPONENTROLETYPE *roleParams =
                 (const OMX_PARAM_COMPONENTROLETYPE *)param;
 
+            if (!isValidOMXParam(roleParams)) {
+                return OMX_ErrorBadParameter;
+            }
+
             if (strncmp((const char *)roleParams->cRole,
                         mComponentRole,
                         OMX_MAX_STRINGNAME_SIZE - 1)) {
@@ -241,6 +250,10 @@
             const OMX_VIDEO_PARAM_PORTFORMATTYPE* format =
                 (const OMX_VIDEO_PARAM_PORTFORMATTYPE *)param;
 
+            if (!isValidOMXParam(format)) {
+                return OMX_ErrorBadParameter;
+            }
+
             if (format->nPortIndex == kInputPortIndex) {
                 if (format->eColorFormat == OMX_COLOR_FormatYUV420Planar ||
                     format->eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar ||
@@ -270,6 +283,10 @@
             const StoreMetaDataInBuffersParams *storeParam =
                 (const StoreMetaDataInBuffersParams *)param;
 
+            if (!isValidOMXParam(storeParam)) {
+                return OMX_ErrorBadParameter;
+            }
+
             if (storeParam->nPortIndex == kOutputPortIndex) {
                 return storeParam->bStoreMetaData ? OMX_ErrorUnsupportedSetting : OMX_ErrorNone;
             } else if (storeParam->nPortIndex != kInputPortIndex) {
@@ -304,6 +321,10 @@
             OMX_VIDEO_PARAM_PORTFORMATTYPE *formatParams =
                 (OMX_VIDEO_PARAM_PORTFORMATTYPE *)param;
 
+            if (!isValidOMXParam(formatParams)) {
+                return OMX_ErrorBadParameter;
+            }
+
             if (formatParams->nPortIndex == kInputPortIndex) {
                 if (formatParams->nIndex >= NELEM(kSupportedColorFormats)) {
                     return OMX_ErrorNoMore;
@@ -329,6 +350,10 @@
             OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevel =
                   (OMX_VIDEO_PARAM_PROFILELEVELTYPE *) param;
 
+            if (!isValidOMXParam(profileLevel)) {
+                return OMX_ErrorBadParameter;
+            }
+
             if (profileLevel->nPortIndex != kOutputPortIndex) {
                 ALOGE("Invalid port index: %u", profileLevel->nPortIndex);
                 return OMX_ErrorUnsupportedIndex;
diff --git a/services/audioflinger/Android.mk b/services/audioflinger/Android.mk
index 6700f6e..4f826e5 100644
--- a/services/audioflinger/Android.mk
+++ b/services/audioflinger/Android.mk
@@ -34,6 +34,7 @@
 LOCAL_C_INCLUDES := \
     $(TOPDIR)frameworks/av/services/audiopolicy \
     $(TOPDIR)external/sonic \
+    libcore/include \
     $(call include-path-for, audio-effects) \
     $(call include-path-for, audio-utils)
 
@@ -54,7 +55,8 @@
     libpowermanager \
     libserviceutility \
     libsonic \
-    libmediautils
+    libmediautils \
+    libmemunreachable
 
 LOCAL_STATIC_LIBRARIES := \
     libcpustats \
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 208dc8b..ca1a0b7 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -31,6 +31,7 @@
 #include <utils/Log.h>
 #include <utils/Trace.h>
 #include <binder/Parcel.h>
+#include <memunreachable/memunreachable.h>
 #include <utils/String16.h>
 #include <utils/threads.h>
 #include <utils/Atomic.h>
@@ -175,7 +176,7 @@
       mHardwareStatus(AUDIO_HW_IDLE),
       mMasterVolume(1.0f),
       mMasterMute(false),
-      mNextUniqueId(AUDIO_UNIQUE_ID_USE_MAX),   // zero has a special meaning, so unavailable
+      // mNextUniqueId(AUDIO_UNIQUE_ID_USE_MAX),
       mMode(AUDIO_MODE_INVALID),
       mBtNrecIsOff(false),
       mIsLowRamDevice(true),
@@ -183,6 +184,12 @@
       mGlobalEffectEnableTime(0),
       mSystemReady(false)
 {
+    // unsigned instead of audio_unique_id_use_t, because ++ operator is unavailable for enum
+    for (unsigned use = AUDIO_UNIQUE_ID_USE_UNSPECIFIED; use < AUDIO_UNIQUE_ID_USE_MAX; use++) {
+        // zero ID has a special meaning, so unavailable
+        mNextUniqueIds[use] = AUDIO_UNIQUE_ID_USE_MAX;
+    }
+
     getpid_cached = getpid();
     const bool doLog = property_get_bool("ro.test_harness", false);
     if (doLog) {
@@ -462,6 +469,21 @@
                 binder->dump(fd, args);
             }
         }
+
+        // check for optional arguments
+        bool unreachableMemory = false;
+        for (const auto &arg : args) {
+            if (arg == String16("--unreachable")) {
+                unreachableMemory = true;
+            }
+        }
+
+        if (unreachableMemory) {
+            dprintf(fd, "\nDumping unreachable memory:\n");
+            // TODO - should limit be an argument parameter?
+            std::string s = GetUnreachableMemoryString(true /* contents */, 10000 /* limit */);
+            write(fd, s.c_str(), s.size());
+        }
     }
     return NO_ERROR;
 }
@@ -724,6 +746,17 @@
     return thread->frameCount();
 }
 
+size_t AudioFlinger::frameCountHAL(audio_io_handle_t ioHandle) const
+{
+    Mutex::Autolock _l(mLock);
+    ThreadBase *thread = checkThread_l(ioHandle);
+    if (thread == NULL) {
+        ALOGW("frameCountHAL() unknown thread %d", ioHandle);
+        return 0;
+    }
+    return thread->frameCountHAL();
+}
+
 uint32_t AudioFlinger::latency(audio_io_handle_t output) const
 {
     Mutex::Autolock _l(mLock);
@@ -2424,13 +2457,23 @@
 
 audio_unique_id_t AudioFlinger::nextUniqueId(audio_unique_id_use_t use)
 {
-    int32_t base = android_atomic_add(AUDIO_UNIQUE_ID_USE_MAX, &mNextUniqueId);
-    // We have no way of recovering from wraparound
-    LOG_ALWAYS_FATAL_IF(base == 0, "unique ID overflow");
     // This is the internal API, so it is OK to assert on bad parameter.
     LOG_ALWAYS_FATAL_IF((unsigned) use >= (unsigned) AUDIO_UNIQUE_ID_USE_MAX);
-    ALOG_ASSERT(audio_unique_id_get_use(base) == AUDIO_UNIQUE_ID_USE_UNSPECIFIED);
-    return (audio_unique_id_t) (base | use);
+    const int maxRetries = use == AUDIO_UNIQUE_ID_USE_SESSION ? 3 : 1;
+    for (int retry = 0; retry < maxRetries; retry++) {
+        // The cast allows wraparound from max positive to min negative instead of abort
+        uint32_t base = (uint32_t) atomic_fetch_add_explicit(&mNextUniqueIds[use],
+                (uint_fast32_t) AUDIO_UNIQUE_ID_USE_MAX, memory_order_acq_rel);
+        ALOG_ASSERT(audio_unique_id_get_use(base) == AUDIO_UNIQUE_ID_USE_UNSPECIFIED);
+        // allow wrap by skipping 0 and -1 for session ids
+        if (!(base == 0 || base == (~0u & ~AUDIO_UNIQUE_ID_USE_MASK))) {
+            ALOGW_IF(retry != 0, "unique ID overflow for use %d", use);
+            return (audio_unique_id_t) (base | use);
+        }
+    }
+    // We have no way of recovering from wraparound
+    LOG_ALWAYS_FATAL("unique ID overflow for use %d", use);
+    // TODO Use a floor after wraparound.  This may need a mutex.
 }
 
 AudioFlinger::PlaybackThread *AudioFlinger::primaryPlaybackThread_l() const
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index 498c33e..96d38d0 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -131,6 +131,7 @@
     virtual     uint32_t    sampleRate(audio_io_handle_t ioHandle) const;
     virtual     audio_format_t format(audio_io_handle_t output) const;
     virtual     size_t      frameCount(audio_io_handle_t ioHandle) const;
+    virtual     size_t      frameCountHAL(audio_io_handle_t ioHandle) const;
     virtual     uint32_t    latency(audio_io_handle_t output) const;
 
     virtual     status_t    setMasterVolume(float value);
@@ -679,9 +680,8 @@
                 // protected by mClientLock
                 DefaultKeyedVector< pid_t, sp<NotificationClient> >    mNotificationClients;
 
-                volatile int32_t                    mNextUniqueId;  // updated by android_atomic_inc
-                // nextUniqueId() returns uint32_t, but this is declared int32_t
-                // because the atomic operations require an int32_t
+                // updated by atomic_fetch_add_explicit
+                volatile atomic_uint_fast32_t       mNextUniqueIds[AUDIO_UNIQUE_ID_USE_MAX];
 
                 audio_mode_t                        mMode;
                 bool                                mBtNrecIsOff;
diff --git a/services/audioflinger/PatchPanel.cpp b/services/audioflinger/PatchPanel.cpp
index d85ac87..89de68e 100644
--- a/services/audioflinger/PatchPanel.cpp
+++ b/services/audioflinger/PatchPanel.cpp
@@ -248,14 +248,27 @@
                         goto exit;
                     }
                 }
-                uint32_t channelCount = newPatch->mPlaybackThread->channelCount();
                 audio_devices_t device = patch->sources[0].ext.device.type;
                 String8 address = String8(patch->sources[0].ext.device.address);
                 audio_config_t config = AUDIO_CONFIG_INITIALIZER;
-                audio_channel_mask_t inChannelMask = audio_channel_in_mask_from_count(channelCount);
-                config.sample_rate = newPatch->mPlaybackThread->sampleRate();
-                config.channel_mask = inChannelMask;
-                config.format = newPatch->mPlaybackThread->format();
+                // open input stream with source device audio properties if provided or
+                // default to peer output stream properties otherwise.
+                if (patch->sources[0].config_mask & AUDIO_PORT_CONFIG_SAMPLE_RATE) {
+                    config.sample_rate = patch->sources[0].sample_rate;
+                } else {
+                    config.sample_rate = newPatch->mPlaybackThread->sampleRate();
+                }
+                if (patch->sources[0].config_mask & AUDIO_PORT_CONFIG_CHANNEL_MASK) {
+                    config.channel_mask = patch->sources[0].channel_mask;
+                } else {
+                    config.channel_mask =
+                        audio_channel_in_mask_from_count(newPatch->mPlaybackThread->channelCount());
+                }
+                if (patch->sources[0].config_mask & AUDIO_PORT_CONFIG_FORMAT) {
+                    config.format = patch->sources[0].format;
+                } else {
+                    config.format = newPatch->mPlaybackThread->format();
+                }
                 audio_io_handle_t input = AUDIO_IO_HANDLE_NONE;
                 newPatch->mRecordThread = audioflinger->openInput_l(srcModule,
                                                                     &input,
@@ -265,7 +278,7 @@
                                                                     AUDIO_SOURCE_MIC,
                                                                     AUDIO_INPUT_FLAG_NONE);
                 ALOGV("audioflinger->openInput_l() returned %p inChannelMask %08x",
-                      newPatch->mRecordThread.get(), inChannelMask);
+                      newPatch->mRecordThread.get(), config.channel_mask);
                 if (newPatch->mRecordThread == 0) {
                     status = NO_MEMORY;
                     goto exit;
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index 87374bc..ff67fb2 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -2153,6 +2153,7 @@
         desc->mFormat = mFormat;
         desc->mFrameCount = mNormalFrameCount; // FIXME see
                                              // AudioFlinger::frameCount(audio_io_handle_t)
+        desc->mFrameCountHAL = mFrameCount;
         desc->mLatency = latency_l();
         break;
 
@@ -3488,7 +3489,7 @@
         MonoPipe *monoPipe = new MonoPipe(mNormalFrameCount * 4, format, true /*writeCanBlock*/);
         const NBAIO_Format offers[1] = {format};
         size_t numCounterOffers = 0;
-#if !LOG_NDEBUG
+#if !LOG_NDEBUG || defined(TEE_SINK)
         ssize_t index =
 #else
         (void)
@@ -7117,6 +7118,7 @@
         desc->mSamplingRate = mSampleRate;
         desc->mFormat = mFormat;
         desc->mFrameCount = mFrameCount;
+        desc->mFrameCountHAL = mFrameCount;
         desc->mLatency = 0;
         break;
 
diff --git a/services/audioflinger/Threads.h b/services/audioflinger/Threads.h
index cf896e0..e71840d 100644
--- a/services/audioflinger/Threads.h
+++ b/services/audioflinger/Threads.h
@@ -247,6 +247,10 @@
                 // Called by AudioFlinger::frameCount(audio_io_handle_t output) and effects,
                 // and returns the [normal mix] buffer's frame count.
     virtual     size_t      frameCount() const = 0;
+
+                // Return's the HAL's frame count i.e. fast mixer buffer size.
+                size_t      frameCountHAL() const { return mFrameCount; }
+
                 size_t      frameSize() const { return mFrameSize; }
 
     // Should be "virtual status_t requestExitAndWait()" and override same
@@ -606,9 +610,6 @@
 
     virtual     size_t      frameCount() const { return mNormalFrameCount; }
 
-                // Return's the HAL's frame count i.e. fast mixer buffer size.
-                size_t      frameCountHAL() const { return mFrameCount; }
-
                 status_t    getTimestamp_l(AudioTimestamp& timestamp);
 
                 void        addPatchTrack(const sp<PatchTrack>& track);
diff --git a/services/audioflinger/Tracks.cpp b/services/audioflinger/Tracks.cpp
index 00de4f0..61b30c1 100644
--- a/services/audioflinger/Tracks.cpp
+++ b/services/audioflinger/Tracks.cpp
@@ -1114,7 +1114,6 @@
         mAudioTrackServerProxy->setDrained(true);
     }
     // Set correction for flushed frames that are not accounted for in released.
-    // This is important for the new 64 bit timestamps which do not reset to 0 on flush.
     local.mFlushed = mAudioTrackServerProxy->framesFlushed();
     mServerProxy->setTimestamp(local);
 }
diff --git a/services/audiopolicy/AudioPolicyInterface.h b/services/audiopolicy/AudioPolicyInterface.h
index b1347f4..a215b95 100644
--- a/services/audiopolicy/AudioPolicyInterface.h
+++ b/services/audiopolicy/AudioPolicyInterface.h
@@ -158,14 +158,14 @@
                                       int indexMax) = 0;
 
     // sets the new stream volume at a level corresponding to the supplied index for the
-    // supplied device. By convention, specifying AUDIO_DEVICE_OUT_DEFAULT means
+    // supplied device. By convention, specifying AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME means
     // setting volume for all devices
     virtual status_t setStreamVolumeIndex(audio_stream_type_t stream,
                                           int index,
                                           audio_devices_t device) = 0;
 
     // retrieve current volume index for the specified stream and the
-    // specified device. By convention, specifying AUDIO_DEVICE_OUT_DEFAULT means
+    // specified device. By convention, specifying AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME means
     // querying the volume of the active device.
     virtual status_t getStreamVolumeIndex(audio_stream_type_t stream,
                                           int *index,
diff --git a/services/audiopolicy/common/include/policy.h b/services/audiopolicy/common/include/policy.h
index f73548d..55ee91f 100755
--- a/services/audiopolicy/common/include/policy.h
+++ b/services/audiopolicy/common/include/policy.h
@@ -47,6 +47,23 @@
 #define APM_AUDIO_DEVICE_IN_MATCH_ADDRESS_ALL (AUDIO_DEVICE_IN_REMOTE_SUBMIX|AUDIO_DEVICE_IN_BUS)
 
 /**
+ * Stub audio output device. Used in policy configuration file on platforms without audio outputs.
+ * This alias value to AUDIO_DEVICE_OUT_DEFAULT is only used in the audio policy context.
+ */
+#define AUDIO_DEVICE_OUT_STUB AUDIO_DEVICE_OUT_DEFAULT
+/**
+ * Stub audio input device. Used in policy configuration file on platforms without audio inputs.
+ * This alias value to AUDIO_DEVICE_IN_DEFAULT is only used in the audio policy context.
+ */
+#define AUDIO_DEVICE_IN_STUB AUDIO_DEVICE_IN_DEFAULT
+/**
+ * Alias to AUDIO_DEVICE_OUT_DEFAULT defined for clarification when this value is used by volume
+ * control APIs (e.g setStreamVolumeIndex().
+ */
+#define AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME AUDIO_DEVICE_OUT_DEFAULT
+
+
+/**
  * Check if the state given correspond to an in call state.
  * @TODO find a better name for widely call state
  *
diff --git a/services/audiopolicy/common/managerdefinitions/include/DeviceDescriptor.h b/services/audiopolicy/common/managerdefinitions/include/DeviceDescriptor.h
index 54fcd0b..ed2450c 100644
--- a/services/audiopolicy/common/managerdefinitions/include/DeviceDescriptor.h
+++ b/services/audiopolicy/common/managerdefinitions/include/DeviceDescriptor.h
@@ -84,8 +84,6 @@
 
     audio_devices_t getDevicesFromHwModule(audio_module_handle_t moduleHandle) const;
 
-    audio_policy_dev_state_t getDeviceConnectionState(const sp<DeviceDescriptor> &devDesc) const;
-
     status_t dump(int fd, const String8 &tag, int spaces = 0, bool verbose = true) const;
 
 private:
diff --git a/services/audiopolicy/common/managerdefinitions/include/EffectDescriptor.h b/services/audiopolicy/common/managerdefinitions/include/EffectDescriptor.h
index c9783a1..ab650c0 100644
--- a/services/audiopolicy/common/managerdefinitions/include/EffectDescriptor.h
+++ b/services/audiopolicy/common/managerdefinitions/include/EffectDescriptor.h
@@ -55,8 +55,9 @@
 private:
     status_t setEffectEnabled(const sp<EffectDescriptor> &effectDesc, bool enabled);
 
-    uint32_t mTotalEffectsCpuLoad; // current CPU load used by effects
-    uint32_t mTotalEffectsMemory;  // current memory used by effects
+    uint32_t mTotalEffectsCpuLoad; // current CPU load used by effects (in MIPS)
+    uint32_t mTotalEffectsMemory;  // current memory used by effects (in KB)
+    uint32_t mTotalEffectsMemoryMaxUsed; // maximum memory used by effects (in KB)
 
     /**
      * Maximum CPU load allocated to audio effects in 0.1 MIPS (ARMv5TE, 0 WS memory) units
diff --git a/services/audiopolicy/common/managerdefinitions/include/HwModule.h b/services/audiopolicy/common/managerdefinitions/include/HwModule.h
index 93d03e6..dd2993d 100644
--- a/services/audiopolicy/common/managerdefinitions/include/HwModule.h
+++ b/services/audiopolicy/common/managerdefinitions/include/HwModule.h
@@ -106,7 +106,8 @@
 
     sp<DeviceDescriptor> getDeviceDescriptor(const audio_devices_t device,
                                              const char *device_address,
-                                             const char *device_name) const;
+                                             const char *device_name,
+                                             bool matchAdress = true) const;
 
     status_t dump(int fd) const;
 };
diff --git a/services/audiopolicy/common/managerdefinitions/include/IVolumeCurvesCollection.h b/services/audiopolicy/common/managerdefinitions/include/IVolumeCurvesCollection.h
index 8dc3eda..a3de686 100644
--- a/services/audiopolicy/common/managerdefinitions/include/IVolumeCurvesCollection.h
+++ b/services/audiopolicy/common/managerdefinitions/include/IVolumeCurvesCollection.h
@@ -42,6 +42,8 @@
     {
         switchVolumeCurve(stream, stream);
     }
+    virtual bool hasVolumeIndexForDevice(audio_stream_type_t stream,
+                                         audio_devices_t device) const = 0;
 
     virtual status_t dump(int fd) const = 0;
 
diff --git a/services/audiopolicy/common/managerdefinitions/include/StreamDescriptor.h b/services/audiopolicy/common/managerdefinitions/include/StreamDescriptor.h
index af178f9..424df84 100644
--- a/services/audiopolicy/common/managerdefinitions/include/StreamDescriptor.h
+++ b/services/audiopolicy/common/managerdefinitions/include/StreamDescriptor.h
@@ -38,6 +38,11 @@
     int getVolumeIndexMax() const { return mIndexMax; }
     void setVolumeIndexMin(int volIndexMin);
     void setVolumeIndexMax(int volIndexMax);
+    bool hasVolumeIndexForDevice(audio_devices_t device) const
+    {
+        device = Volume::getDeviceForVolume(device);
+        return mIndexCur.indexOfKey(device) >= 0;
+    }
 
     void dump(int fd) const;
 
@@ -85,6 +90,11 @@
     virtual status_t initStreamVolume(audio_stream_type_t stream, int indexMin, int indexMax);
     virtual void initializeVolumeCurves(bool isSpeakerDrcEnabled);
     virtual void switchVolumeCurve(audio_stream_type_t streamSrc, audio_stream_type_t streamDst);
+    virtual bool hasVolumeIndexForDevice(audio_stream_type_t stream,
+                                         audio_devices_t device) const
+    {
+        return valueFor(stream).hasVolumeIndexForDevice(device);
+    }
 
     virtual status_t dump(int fd) const;
 
diff --git a/services/audiopolicy/common/managerdefinitions/include/VolumeCurve.h b/services/audiopolicy/common/managerdefinitions/include/VolumeCurve.h
index 009a26f..10f0766 100644
--- a/services/audiopolicy/common/managerdefinitions/include/VolumeCurve.h
+++ b/services/audiopolicy/common/managerdefinitions/include/VolumeCurve.h
@@ -44,8 +44,8 @@
     return lhs.mIndex < rhs.mIndex;
 }
 
-// A volume curve for a given use case and device cateory
-// It contains of list of points of this cuive expressing the atteunation in Millibels for
+// A volume curve for a given use case and device category
+// It contains of list of points of this curve expressing the attenuation in Millibels for
 // a given volume index from 0 to 100
 class VolumeCurve : public RefBase
 {
@@ -74,7 +74,7 @@
 public:
     VolumeCurvesForStream() : mIndexMin(0), mIndexMax(1), mCanBeMuted(true)
     {
-        mIndexCur.add(AUDIO_DEVICE_OUT_DEFAULT, 0);
+        mIndexCur.add(AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME, 0);
     }
 
     sp<VolumeCurve> getCurvesFor(device_category device) const
@@ -88,9 +88,9 @@
     int getVolumeIndex(audio_devices_t device) const
     {
         device = Volume::getDeviceForVolume(device);
-        // there is always a valid entry for AUDIO_DEVICE_OUT_DEFAULT
+        // there is always a valid entry for AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME
         if (mIndexCur.indexOfKey(device) < 0) {
-            device = AUDIO_DEVICE_OUT_DEFAULT;
+            device = AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME;
         }
         return mIndexCur.valueFor(device);
     }
@@ -105,6 +105,12 @@
     void setVolumeIndexMax(int volIndexMax) { mIndexMax = volIndexMax; }
     int getVolumeIndexMax() const { return mIndexMax; }
 
+    bool hasVolumeIndexForDevice(audio_devices_t device) const
+    {
+        device = Volume::getDeviceForVolume(device);
+        return mIndexCur.indexOfKey(device) >= 0;
+    }
+
     const sp<VolumeCurve> getOriginVolumeCurve(device_category deviceCategory) const
     {
         ALOG_ASSERT(mOriginVolumeCurves.indexOfKey(deviceCategory) >= 0, "Invalid device category");
@@ -200,6 +206,11 @@
     {
         return getCurvesFor(stream).volIndexToDb(cat, indexInUi);
     }
+    virtual bool hasVolumeIndexForDevice(audio_stream_type_t stream,
+                                         audio_devices_t device) const
+    {
+        return getCurvesFor(stream).hasVolumeIndexForDevice(device);
+    }
 
     virtual status_t dump(int fd) const;
 
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioPatch.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioPatch.cpp
index b8c0550..f382dec 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioPatch.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioPatch.cpp
@@ -128,14 +128,35 @@
 
     size_t patchesWritten = 0;
     size_t patchesMax = *num_patches;
-    for (size_t i = 0; i  < size() && patchesWritten < patchesMax; i++) {
-        const sp<AudioPatch>  patch = valueAt(i);
-        patches[patchesWritten] = patch->mPatch;
-        patches[patchesWritten++].id = patch->mHandle;
+    *num_patches = 0;
+    for (size_t patchIndex = 0; patchIndex < size(); patchIndex++) {
+        // do not report patches with AUDIO_DEVICE_IN_STUB as source or
+        // AUDIO_DEVICE_OUT_STUB as sink as those devices are used by stub HALs by convention
+        const sp<AudioPatch> patch = valueAt(patchIndex);
+        bool skip = false;
+        for (size_t srcIndex = 0; srcIndex < patch->mPatch.num_sources && !skip; srcIndex++) {
+            if (patch->mPatch.sources[srcIndex].type == AUDIO_PORT_TYPE_DEVICE &&
+                    patch->mPatch.sources[srcIndex].ext.device.type == AUDIO_DEVICE_IN_STUB) {
+                skip = true;
+            }
+        }
+        for (size_t sinkIndex = 0; sinkIndex < patch->mPatch.num_sinks && !skip; sinkIndex++) {
+            if (patch->mPatch.sinks[sinkIndex].type == AUDIO_PORT_TYPE_DEVICE &&
+                    patch->mPatch.sinks[sinkIndex].ext.device.type == AUDIO_DEVICE_OUT_STUB) {
+                skip = true;
+            }
+        }
+        if (skip) {
+            continue; // to next audio patch
+        }
+        if (patchesWritten < patchesMax) {
+            patches[patchesWritten] = patch->mPatch;
+            patches[patchesWritten++].id = patch->mHandle;
+        }
+        (*num_patches)++;
         ALOGV("listAudioPatches() patch %zu num_sources %d num_sinks %d",
-              i, patch->mPatch.num_sources, patch->mPatch.num_sinks);
+              patchIndex, patch->mPatch.num_sources, patch->mPatch.num_sinks);
     }
-    *num_patches = size();
 
     ALOGV("listAudioPatches() got %zu patches needed %d", patchesWritten, *num_patches);
     return NO_ERROR;
diff --git a/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp
index fe03429..35f078e 100644
--- a/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp
@@ -219,16 +219,20 @@
     return NO_ERROR;
 }
 
-audio_policy_dev_state_t DeviceVector::getDeviceConnectionState(const sp<DeviceDescriptor> &devDesc) const
-{
-    ssize_t index = indexOf(devDesc);
-    return index >= 0 ? AUDIO_POLICY_DEVICE_STATE_AVAILABLE : AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE;
-}
-
 void DeviceDescriptor::toAudioPortConfig(struct audio_port_config *dstConfig,
                                          const struct audio_port_config *srcConfig) const
 {
-    dstConfig->config_mask = AUDIO_PORT_CONFIG_CHANNEL_MASK|AUDIO_PORT_CONFIG_GAIN;
+    dstConfig->config_mask = AUDIO_PORT_CONFIG_GAIN;
+    if (mSamplingRate != 0) {
+        dstConfig->config_mask |= AUDIO_PORT_CONFIG_SAMPLE_RATE;
+    }
+    if (mChannelMask != AUDIO_CHANNEL_NONE) {
+        dstConfig->config_mask |= AUDIO_PORT_CONFIG_CHANNEL_MASK;
+    }
+    if (mFormat != AUDIO_FORMAT_INVALID) {
+        dstConfig->config_mask |= AUDIO_PORT_CONFIG_FORMAT;
+    }
+
     if (srcConfig != NULL) {
         dstConfig->config_mask |= srcConfig->config_mask;
     }
diff --git a/services/audiopolicy/common/managerdefinitions/src/EffectDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/EffectDescriptor.cpp
index 33d838d..7b2341e 100644
--- a/services/audiopolicy/common/managerdefinitions/src/EffectDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/EffectDescriptor.cpp
@@ -45,7 +45,8 @@
 
 EffectDescriptorCollection::EffectDescriptorCollection() :
     mTotalEffectsCpuLoad(0),
-    mTotalEffectsMemory(0)
+    mTotalEffectsMemory(0),
+    mTotalEffectsMemoryMaxUsed(0)
 {
 
 }
@@ -62,6 +63,9 @@
         return INVALID_OPERATION;
     }
     mTotalEffectsMemory += desc->memoryUsage;
+    if (mTotalEffectsMemory > mTotalEffectsMemoryMaxUsed) {
+        mTotalEffectsMemoryMaxUsed = mTotalEffectsMemory;
+    }
     ALOGV("registerEffect() effect %s, io %d, strategy %d session %d id %d",
             desc->name, io, strategy, session, id);
     ALOGV("registerEffect() memory %d, total memory %d", desc->memoryUsage, mTotalEffectsMemory);
@@ -175,8 +179,9 @@
     const size_t SIZE = 256;
     char buffer[SIZE];
 
-    snprintf(buffer, SIZE, "\nTotal Effects CPU: %f MIPS, Total Effects memory: %d KB\n",
-             (float)mTotalEffectsCpuLoad/10, mTotalEffectsMemory);
+    snprintf(buffer, SIZE,
+            "\nTotal Effects CPU: %f MIPS, Total Effects memory: %d KB, Max memory used: %d KB\n",
+             (float)mTotalEffectsCpuLoad/10, mTotalEffectsMemory, mTotalEffectsMemoryMaxUsed);
     write(fd, buffer, strlen(buffer));
 
     snprintf(buffer, SIZE, "Registered effects:\n");
diff --git a/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp b/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp
index 2d67bd2..a85c07f 100644
--- a/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp
@@ -292,7 +292,8 @@
 
 sp<DeviceDescriptor>  HwModuleCollection::getDeviceDescriptor(const audio_devices_t device,
                                                               const char *device_address,
-                                                              const char *device_name) const
+                                                              const char *device_name,
+                                                              bool matchAdress) const
 {
     String8 address = (device_address == NULL) ? String8("") : String8(device_address);
     // handle legacy remote submix case where the address was not always specified
@@ -305,11 +306,17 @@
         if (hwModule->mHandle == 0) {
             continue;
         }
-        DeviceVector deviceList =
-                hwModule->getDeclaredDevices().getDevicesFromTypeAddr(device, address);
+        DeviceVector declaredDevices = hwModule->getDeclaredDevices();
+        DeviceVector deviceList = declaredDevices.getDevicesFromTypeAddr(device, address);
         if (!deviceList.isEmpty()) {
             return deviceList.itemAt(0);
         }
+        if (!matchAdress) {
+            deviceList = declaredDevices.getDevicesFromType(device);
+            if (!deviceList.isEmpty()) {
+                return deviceList.itemAt(0);
+            }
+        }
     }
 
     sp<DeviceDescriptor> devDesc = new DeviceDescriptor(device);
diff --git a/services/audiopolicy/common/managerdefinitions/src/StreamDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/StreamDescriptor.cpp
index 8388a50..b3019e1 100644
--- a/services/audiopolicy/common/managerdefinitions/src/StreamDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/StreamDescriptor.cpp
@@ -26,6 +26,7 @@
 
 #include "StreamDescriptor.h"
 #include "Gains.h"
+#include "policy.h"
 #include <utils/Log.h>
 #include <utils/String8.h>
 
@@ -39,15 +40,15 @@
     // Initialize the current stream's index to mIndexMax so volume isn't 0 in
     // cases where the Java layer doesn't call into the audio policy service to
     // set the default volume.
-    mIndexCur.add(AUDIO_DEVICE_OUT_DEFAULT, mIndexMax);
+    mIndexCur.add(AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME, mIndexMax);
 }
 
 int StreamDescriptor::getVolumeIndex(audio_devices_t device) const
 {
     device = Volume::getDeviceForVolume(device);
-    // there is always a valid entry for AUDIO_DEVICE_OUT_DEFAULT
+    // there is always a valid entry for AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME
     if (mIndexCur.indexOfKey(device) < 0) {
-        device = AUDIO_DEVICE_OUT_DEFAULT;
+        device = AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME;
     }
     return mIndexCur.valueFor(device);
 }
diff --git a/services/audiopolicy/common/managerdefinitions/src/TypeConverter.cpp b/services/audiopolicy/common/managerdefinitions/src/TypeConverter.cpp
index c6ed53e..f639551 100644
--- a/services/audiopolicy/common/managerdefinitions/src/TypeConverter.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/TypeConverter.cpp
@@ -51,6 +51,7 @@
         MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_OUT_AUX_LINE),
         MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_OUT_IP),
         MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_OUT_BUS),
+        MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_OUT_STUB),
         MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_AMBIENT),
         MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_BUILTIN_MIC),
         MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET),
@@ -74,6 +75,7 @@
         MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_LOOPBACK),
         MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_IP),
         MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_BUS),
+        MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_STUB),
 };
 
 template<>
diff --git a/services/audiopolicy/config/audio_policy_configuration_stub.xml b/services/audiopolicy/config/audio_policy_configuration_stub.xml
new file mode 100644
index 0000000..a7747f8
--- /dev/null
+++ b/services/audiopolicy/config/audio_policy_configuration_stub.xml
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<audioPolicyConfiguration version="1.0" xmlns:xi="http://www.w3.org/2001/XInclude">
+  <modules>
+        <module name="stub" halVersion="2.0">
+            <attachedDevices>
+                <item>Default Out</item>
+                <item>Default In</item>
+            </attachedDevices>
+            <defaultOutputDevice>Default Out</defaultOutputDevice>
+            <mixPorts>
+                <mixPort name="stub output" role="source" flags="AUDIO_OUTPUT_FLAG_PRIMARY">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+                </mixPort>
+
+                <mixPort name="stub input" role="sink">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="48000" channelMasks="AUDIO_CHANNEL_IN_STEREO"/>
+                </mixPort>
+            </mixPorts>
+            <devicePorts>
+                <devicePort tagName="Default Out" type="AUDIO_DEVICE_OUT_STUB" role="sink">
+                </devicePort>
+
+                <devicePort tagName="Default In" type="AUDIO_DEVICE_IN_STUB" role="source">
+                </devicePort>
+            </devicePorts>
+            <routes>
+                <route type="mix" sink="Default Out" sources="stub output"/>
+
+                <route type="mix" sink="stub input" sources="Default In"/>
+            </routes>
+
+        </module>
+
+        <!-- Remote Submix Audio HAL -->
+        <xi:include href="r_submix_audio_policy_configuration.xml"/>
+
+    </modules>
+
+    <xi:include href="audio_policy_volumes.xml"/>
+    <xi:include href="default_volume_tables.xml"/>
+
+</audioPolicyConfiguration>
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/example/Settings/PolicyConfigurableDomains.xml b/services/audiopolicy/engineconfigurable/parameter-framework/example/Settings/PolicyConfigurableDomains.xml
index be86b8d..bc7ad6b 100644
--- a/services/audiopolicy/engineconfigurable/parameter-framework/example/Settings/PolicyConfigurableDomains.xml
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/example/Settings/PolicyConfigurableDomains.xml
@@ -939,6 +939,12 @@
           <SelectionCriterionRule SelectionCriterion="ForceUseForCommunication" MatchesWhen="IsNot" Value="ForceSpeaker"/>
         </CompoundRule>
       </Configuration>
+      <Configuration Name="Line">
+        <CompoundRule Type="All">
+          <SelectionCriterionRule SelectionCriterion="AvailableOutputDevices" MatchesWhen="Includes" Value="Line"/>
+          <SelectionCriterionRule SelectionCriterion="ForceUseForCommunication" MatchesWhen="IsNot" Value="ForceSpeaker"/>
+        </CompoundRule>
+      </Configuration>
       <Configuration Name="UsbDevice">
         <CompoundRule Type="All">
           <SelectionCriterionRule SelectionCriterion="AvailableOutputDevices" MatchesWhen="Includes" Value="UsbDevice"/>
@@ -988,12 +994,6 @@
           <SelectionCriterionRule SelectionCriterion="ForceUseForCommunication" MatchesWhen="IsNot" Value="ForceSpeaker"/>
         </CompoundRule>
       </Configuration>
-      <Configuration Name="Line">
-        <CompoundRule Type="All">
-          <SelectionCriterionRule SelectionCriterion="AvailableOutputDevices" MatchesWhen="Includes" Value="Line"/>
-          <SelectionCriterionRule SelectionCriterion="ForceUseForCommunication" MatchesWhen="Is" Value="ForceSpeaker"/>
-        </CompoundRule>
-      </Configuration>
       <Configuration Name="Speaker">
         <CompoundRule Type="All">
           <SelectionCriterionRule SelectionCriterion="AvailableOutputDevices" MatchesWhen="Includes" Value="Speaker"/>
@@ -1448,6 +1448,59 @@
           <BitParameter Name="speaker">0</BitParameter>
         </ConfigurableElement>
       </Configuration>
+      <Configuration Name="Line">
+        <ConfigurableElement Path="/Policy/policy/strategies/phone/selected_output_devices/mask/earpiece">
+          <BitParameter Name="earpiece">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/phone/selected_output_devices/mask/wired_headset">
+          <BitParameter Name="wired_headset">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/phone/selected_output_devices/mask/wired_headphone">
+          <BitParameter Name="wired_headphone">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/phone/selected_output_devices/mask/bluetooth_sco">
+          <BitParameter Name="bluetooth_sco">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/phone/selected_output_devices/mask/bluetooth_sco_headset">
+          <BitParameter Name="bluetooth_sco_headset">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/phone/selected_output_devices/mask/bluetooth_sco_carkit">
+          <BitParameter Name="bluetooth_sco_carkit">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/phone/selected_output_devices/mask/bluetooth_a2dp">
+          <BitParameter Name="bluetooth_a2dp">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/phone/selected_output_devices/mask/bluetooth_a2dp_headphones">
+          <BitParameter Name="bluetooth_a2dp_headphones">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/phone/selected_output_devices/mask/bluetooth_a2dp_speaker">
+          <BitParameter Name="bluetooth_a2dp_speaker">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/phone/selected_output_devices/mask/hdmi">
+          <BitParameter Name="hdmi">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/phone/selected_output_devices/mask/angl_dock_headset">
+          <BitParameter Name="angl_dock_headset">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/phone/selected_output_devices/mask/dgtl_dock_headset">
+          <BitParameter Name="dgtl_dock_headset">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/phone/selected_output_devices/mask/usb_accessory">
+          <BitParameter Name="usb_accessory">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/phone/selected_output_devices/mask/usb_device">
+          <BitParameter Name="usb_device">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/phone/selected_output_devices/mask/telephony_tx">
+          <BitParameter Name="telephony_tx">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/phone/selected_output_devices/mask/line">
+          <BitParameter Name="line">1</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/phone/selected_output_devices/mask/speaker">
+          <BitParameter Name="speaker">0</BitParameter>
+        </ConfigurableElement>
+      </Configuration>
       <Configuration Name="UsbDevice">
         <ConfigurableElement Path="/Policy/policy/strategies/phone/selected_output_devices/mask/earpiece">
           <BitParameter Name="earpiece">0</BitParameter>
@@ -1766,59 +1819,6 @@
           <BitParameter Name="speaker">0</BitParameter>
         </ConfigurableElement>
       </Configuration>
-      <Configuration Name="Line">
-        <ConfigurableElement Path="/Policy/policy/strategies/phone/selected_output_devices/mask/earpiece">
-          <BitParameter Name="earpiece">0</BitParameter>
-        </ConfigurableElement>
-        <ConfigurableElement Path="/Policy/policy/strategies/phone/selected_output_devices/mask/wired_headset">
-          <BitParameter Name="wired_headset">0</BitParameter>
-        </ConfigurableElement>
-        <ConfigurableElement Path="/Policy/policy/strategies/phone/selected_output_devices/mask/wired_headphone">
-          <BitParameter Name="wired_headphone">0</BitParameter>
-        </ConfigurableElement>
-        <ConfigurableElement Path="/Policy/policy/strategies/phone/selected_output_devices/mask/bluetooth_sco">
-          <BitParameter Name="bluetooth_sco">0</BitParameter>
-        </ConfigurableElement>
-        <ConfigurableElement Path="/Policy/policy/strategies/phone/selected_output_devices/mask/bluetooth_sco_headset">
-          <BitParameter Name="bluetooth_sco_headset">0</BitParameter>
-        </ConfigurableElement>
-        <ConfigurableElement Path="/Policy/policy/strategies/phone/selected_output_devices/mask/bluetooth_sco_carkit">
-          <BitParameter Name="bluetooth_sco_carkit">0</BitParameter>
-        </ConfigurableElement>
-        <ConfigurableElement Path="/Policy/policy/strategies/phone/selected_output_devices/mask/bluetooth_a2dp">
-          <BitParameter Name="bluetooth_a2dp">0</BitParameter>
-        </ConfigurableElement>
-        <ConfigurableElement Path="/Policy/policy/strategies/phone/selected_output_devices/mask/bluetooth_a2dp_headphones">
-          <BitParameter Name="bluetooth_a2dp_headphones">0</BitParameter>
-        </ConfigurableElement>
-        <ConfigurableElement Path="/Policy/policy/strategies/phone/selected_output_devices/mask/bluetooth_a2dp_speaker">
-          <BitParameter Name="bluetooth_a2dp_speaker">0</BitParameter>
-        </ConfigurableElement>
-        <ConfigurableElement Path="/Policy/policy/strategies/phone/selected_output_devices/mask/hdmi">
-          <BitParameter Name="hdmi">0</BitParameter>
-        </ConfigurableElement>
-        <ConfigurableElement Path="/Policy/policy/strategies/phone/selected_output_devices/mask/angl_dock_headset">
-          <BitParameter Name="angl_dock_headset">0</BitParameter>
-        </ConfigurableElement>
-        <ConfigurableElement Path="/Policy/policy/strategies/phone/selected_output_devices/mask/dgtl_dock_headset">
-          <BitParameter Name="dgtl_dock_headset">0</BitParameter>
-        </ConfigurableElement>
-        <ConfigurableElement Path="/Policy/policy/strategies/phone/selected_output_devices/mask/usb_accessory">
-          <BitParameter Name="usb_accessory">0</BitParameter>
-        </ConfigurableElement>
-        <ConfigurableElement Path="/Policy/policy/strategies/phone/selected_output_devices/mask/usb_device">
-          <BitParameter Name="usb_device">0</BitParameter>
-        </ConfigurableElement>
-        <ConfigurableElement Path="/Policy/policy/strategies/phone/selected_output_devices/mask/telephony_tx">
-          <BitParameter Name="telephony_tx">0</BitParameter>
-        </ConfigurableElement>
-        <ConfigurableElement Path="/Policy/policy/strategies/phone/selected_output_devices/mask/line">
-          <BitParameter Name="line">1</BitParameter>
-        </ConfigurableElement>
-        <ConfigurableElement Path="/Policy/policy/strategies/phone/selected_output_devices/mask/speaker">
-          <BitParameter Name="speaker">0</BitParameter>
-        </ConfigurableElement>
-      </Configuration>
       <Configuration Name="Speaker">
         <ConfigurableElement Path="/Policy/policy/strategies/phone/selected_output_devices/mask/earpiece">
           <BitParameter Name="earpiece">0</BitParameter>
@@ -2093,7 +2093,8 @@
                 <SelectionCriterionRule SelectionCriterion="TelephonyMode" MatchesWhen="Is" Value="InCall"/>
                 <SelectionCriterionRule SelectionCriterion="TelephonyMode" MatchesWhen="Is" Value="InCommunication"/>
               </CompoundRule>
-              <SelectionCriterionRule SelectionCriterion="ForceUseForCommunication" MatchesWhen="Is" Value="ForceSpeaker"/>
+              <SelectionCriterionRule SelectionCriterion="ForceUseForCommunication" MatchesWhen="IsNot" Value="ForceSpeaker"/>
+              <SelectionCriterionRule SelectionCriterion="AvailableOutputDevices" MatchesWhen="Excludes" Value="WiredHeadset"/>
             </CompoundRule>
             <CompoundRule Type="All">
               <SelectionCriterionRule SelectionCriterion="TelephonyMode" MatchesWhen="IsNot" Value="InCall"/>
@@ -3082,12 +3083,25 @@
           <SelectionCriterionRule SelectionCriterion="AvailableOutputDevices" MatchesWhen="Includes" Value="WiredHeadphone"/>
         </CompoundRule>
       </Configuration>
-      <Configuration Name="LineWhenFollowMediaStrategy">
+      <Configuration Name="Line">
         <CompoundRule Type="All">
-          <SelectionCriterionRule SelectionCriterion="TelephonyMode" MatchesWhen="IsNot" Value="InCall"/>
-          <SelectionCriterionRule SelectionCriterion="TelephonyMode" MatchesWhen="IsNot" Value="InCommunication"/>
-          <SelectionCriterionRule SelectionCriterion="AvailableOutputDevices" MatchesWhen="Includes" Value="WiredHeadphone"/>
-          <SelectionCriterionRule SelectionCriterion="ForceUseForMedia" MatchesWhen="IsNot" Value="ForceSpeaker"/>
+          <CompoundRule Type="Any">
+            <CompoundRule Type="All">
+              <CompoundRule Type="Any">
+                <SelectionCriterionRule SelectionCriterion="TelephonyMode" MatchesWhen="Is" Value="InCall"/>
+                <SelectionCriterionRule SelectionCriterion="TelephonyMode" MatchesWhen="Is" Value="InCommunication"/>
+              </CompoundRule>
+              <SelectionCriterionRule SelectionCriterion="ForceUseForCommunication" MatchesWhen="IsNot" Value="ForceSpeaker"/>
+              <SelectionCriterionRule SelectionCriterion="AvailableOutputDevices" MatchesWhen="Excludes" Value="WiredHeadset"/>
+            </CompoundRule>
+            <CompoundRule Type="All">
+              <SelectionCriterionRule SelectionCriterion="TelephonyMode" MatchesWhen="IsNot" Value="InCall"/>
+              <SelectionCriterionRule SelectionCriterion="TelephonyMode" MatchesWhen="IsNot" Value="InCommunication"/>
+              <SelectionCriterionRule SelectionCriterion="AvailableOutputDevices" MatchesWhen="Includes" Value="WiredHeadphone"/>
+              <SelectionCriterionRule SelectionCriterion="ForceUseForMedia" MatchesWhen="IsNot" Value="ForceSpeaker"/>
+            </CompoundRule>
+          </CompoundRule>
+          <SelectionCriterionRule SelectionCriterion="AvailableOutputDevices" MatchesWhen="Includes" Value="Line"/>
         </CompoundRule>
       </Configuration>
       <Configuration Name="WiredHeadset">
@@ -3172,16 +3186,6 @@
           <SelectionCriterionRule SelectionCriterion="AvailableOutputDevices" MatchesWhen="Includes" Value="Earpiece"/>
         </CompoundRule>
       </Configuration>
-      <Configuration Name="Line">
-        <CompoundRule Type="All">
-          <CompoundRule Type="Any">
-            <SelectionCriterionRule SelectionCriterion="TelephonyMode" MatchesWhen="Is" Value="InCall"/>
-            <SelectionCriterionRule SelectionCriterion="TelephonyMode" MatchesWhen="Is" Value="InCommunication"/>
-          </CompoundRule>
-          <SelectionCriterionRule SelectionCriterion="ForceUseForCommunication" MatchesWhen="Is" Value="ForceSpeaker"/>
-          <SelectionCriterionRule SelectionCriterion="AvailableOutputDevices" MatchesWhen="Includes" Value="Line"/>
-        </CompoundRule>
-      </Configuration>
     </Configurations>
     <ConfigurableElements>
       <ConfigurableElement Path="/Policy/policy/strategies/sonification_respectful/selected_output_devices/mask/earpiece"/>
@@ -3530,7 +3534,7 @@
           <BitParameter Name="hdmi">0</BitParameter>
         </ConfigurableElement>
       </Configuration>
-      <Configuration Name="LineWhenFollowMediaStrategy">
+      <Configuration Name="Line">
         <ConfigurableElement Path="/Policy/policy/strategies/sonification_respectful/selected_output_devices/mask/earpiece">
           <BitParameter Name="earpiece">0</BitParameter>
         </ConfigurableElement>
@@ -3906,53 +3910,6 @@
           <BitParameter Name="hdmi">0</BitParameter>
         </ConfigurableElement>
       </Configuration>
-      <Configuration Name="Line">
-        <ConfigurableElement Path="/Policy/policy/strategies/sonification_respectful/selected_output_devices/mask/earpiece">
-          <BitParameter Name="earpiece">0</BitParameter>
-        </ConfigurableElement>
-        <ConfigurableElement Path="/Policy/policy/strategies/sonification_respectful/selected_output_devices/mask/bluetooth_sco">
-          <BitParameter Name="bluetooth_sco">0</BitParameter>
-        </ConfigurableElement>
-        <ConfigurableElement Path="/Policy/policy/strategies/sonification_respectful/selected_output_devices/mask/bluetooth_sco_headset">
-          <BitParameter Name="bluetooth_sco_headset">0</BitParameter>
-        </ConfigurableElement>
-        <ConfigurableElement Path="/Policy/policy/strategies/sonification_respectful/selected_output_devices/mask/bluetooth_sco_carkit">
-          <BitParameter Name="bluetooth_sco_carkit">0</BitParameter>
-        </ConfigurableElement>
-        <ConfigurableElement Path="/Policy/policy/strategies/sonification_respectful/selected_output_devices/mask/bluetooth_a2dp_headphones">
-          <BitParameter Name="bluetooth_a2dp_headphones">0</BitParameter>
-        </ConfigurableElement>
-        <ConfigurableElement Path="/Policy/policy/strategies/sonification_respectful/selected_output_devices/mask/bluetooth_a2dp_speaker">
-          <BitParameter Name="bluetooth_a2dp_speaker">0</BitParameter>
-        </ConfigurableElement>
-        <ConfigurableElement Path="/Policy/policy/strategies/sonification_respectful/selected_output_devices/mask/bluetooth_a2dp">
-          <BitParameter Name="bluetooth_a2dp">0</BitParameter>
-        </ConfigurableElement>
-        <ConfigurableElement Path="/Policy/policy/strategies/sonification_respectful/selected_output_devices/mask/wired_headset">
-          <BitParameter Name="wired_headset">0</BitParameter>
-        </ConfigurableElement>
-        <ConfigurableElement Path="/Policy/policy/strategies/sonification_respectful/selected_output_devices/mask/wired_headphone">
-          <BitParameter Name="wired_headphone">0</BitParameter>
-        </ConfigurableElement>
-        <ConfigurableElement Path="/Policy/policy/strategies/sonification_respectful/selected_output_devices/mask/line">
-          <BitParameter Name="line">1</BitParameter>
-        </ConfigurableElement>
-        <ConfigurableElement Path="/Policy/policy/strategies/sonification_respectful/selected_output_devices/mask/angl_dock_headset">
-          <BitParameter Name="angl_dock_headset">0</BitParameter>
-        </ConfigurableElement>
-        <ConfigurableElement Path="/Policy/policy/strategies/sonification_respectful/selected_output_devices/mask/dgtl_dock_headset">
-          <BitParameter Name="dgtl_dock_headset">0</BitParameter>
-        </ConfigurableElement>
-        <ConfigurableElement Path="/Policy/policy/strategies/sonification_respectful/selected_output_devices/mask/usb_accessory">
-          <BitParameter Name="usb_accessory">0</BitParameter>
-        </ConfigurableElement>
-        <ConfigurableElement Path="/Policy/policy/strategies/sonification_respectful/selected_output_devices/mask/usb_device">
-          <BitParameter Name="usb_device">0</BitParameter>
-        </ConfigurableElement>
-        <ConfigurableElement Path="/Policy/policy/strategies/sonification_respectful/selected_output_devices/mask/hdmi">
-          <BitParameter Name="hdmi">0</BitParameter>
-        </ConfigurableElement>
-      </Configuration>
     </Settings>
   </ConfigurableDomain>
   <ConfigurableDomain Name="DeviceForStrategy.Dtmf.UnreachableDevices" SequenceAware="false">
@@ -4060,10 +4017,22 @@
           <SelectionCriterionRule SelectionCriterion="AvailableOutputDevices" MatchesWhen="Includes" Value="WiredHeadphone"/>
         </CompoundRule>
       </Configuration>
-      <Configuration Name="LineWhenFollowingMedia">
+      <Configuration Name="Line">
         <CompoundRule Type="All">
-          <SelectionCriterionRule SelectionCriterion="TelephonyMode" MatchesWhen="IsNot" Value="InCall"/>
-          <SelectionCriterionRule SelectionCriterion="TelephonyMode" MatchesWhen="IsNot" Value="InCommunication"/>
+          <CompoundRule Type="Any">
+            <CompoundRule Type="All">
+              <CompoundRule Type="Any">
+                <SelectionCriterionRule SelectionCriterion="TelephonyMode" MatchesWhen="Is" Value="InCall"/>
+                <SelectionCriterionRule SelectionCriterion="TelephonyMode" MatchesWhen="Is" Value="InCommunication"/>
+              </CompoundRule>
+              <SelectionCriterionRule SelectionCriterion="ForceUseForCommunication" MatchesWhen="IsNot" Value="ForceSpeaker"/>
+              <SelectionCriterionRule SelectionCriterion="AvailableOutputDevices" MatchesWhen="Excludes" Value="WiredHeadset"/>
+            </CompoundRule>
+            <CompoundRule Type="All">
+              <SelectionCriterionRule SelectionCriterion="TelephonyMode" MatchesWhen="IsNot" Value="InCall"/>
+              <SelectionCriterionRule SelectionCriterion="TelephonyMode" MatchesWhen="IsNot" Value="InCommunication"/>
+            </CompoundRule>
+          </CompoundRule>
           <SelectionCriterionRule SelectionCriterion="AvailableOutputDevices" MatchesWhen="Includes" Value="Line"/>
         </CompoundRule>
       </Configuration>
@@ -4144,16 +4113,6 @@
           <SelectionCriterionRule SelectionCriterion="ForceUseForCommunication" MatchesWhen="IsNot" Value="ForceSpeaker"/>
         </CompoundRule>
       </Configuration>
-      <Configuration Name="LineWhenFallThroughPhone">
-        <CompoundRule Type="All">
-          <CompoundRule Type="Any">
-            <SelectionCriterionRule SelectionCriterion="TelephonyMode" MatchesWhen="Is" Value="InCall"/>
-            <SelectionCriterionRule SelectionCriterion="TelephonyMode" MatchesWhen="Is" Value="InCommunication"/>
-          </CompoundRule>
-          <SelectionCriterionRule SelectionCriterion="AvailableOutputDevices" MatchesWhen="Includes" Value="Line"/>
-          <SelectionCriterionRule SelectionCriterion="ForceUseForCommunication" MatchesWhen="Is" Value="ForceSpeaker"/>
-        </CompoundRule>
-      </Configuration>
       <Configuration Name="Speaker">
         <CompoundRule Type="All">
           <CompoundRule Type="Any">
@@ -4621,7 +4580,7 @@
           <BitParameter Name="speaker">0</BitParameter>
         </ConfigurableElement>
       </Configuration>
-      <Configuration Name="LineWhenFollowingMedia">
+      <Configuration Name="Line">
         <ConfigurableElement Path="/Policy/policy/strategies/dtmf/selected_output_devices/mask/remote_submix">
           <BitParameter Name="remote_submix">0</BitParameter>
         </ConfigurableElement>
@@ -5045,59 +5004,6 @@
           <BitParameter Name="speaker">0</BitParameter>
         </ConfigurableElement>
       </Configuration>
-      <Configuration Name="LineWhenFallThroughPhone">
-        <ConfigurableElement Path="/Policy/policy/strategies/dtmf/selected_output_devices/mask/remote_submix">
-          <BitParameter Name="remote_submix">0</BitParameter>
-        </ConfigurableElement>
-        <ConfigurableElement Path="/Policy/policy/strategies/dtmf/selected_output_devices/mask/earpiece">
-          <BitParameter Name="earpiece">0</BitParameter>
-        </ConfigurableElement>
-        <ConfigurableElement Path="/Policy/policy/strategies/dtmf/selected_output_devices/mask/wired_headset">
-          <BitParameter Name="wired_headset">0</BitParameter>
-        </ConfigurableElement>
-        <ConfigurableElement Path="/Policy/policy/strategies/dtmf/selected_output_devices/mask/wired_headphone">
-          <BitParameter Name="wired_headphone">0</BitParameter>
-        </ConfigurableElement>
-        <ConfigurableElement Path="/Policy/policy/strategies/dtmf/selected_output_devices/mask/bluetooth_sco">
-          <BitParameter Name="bluetooth_sco">0</BitParameter>
-        </ConfigurableElement>
-        <ConfigurableElement Path="/Policy/policy/strategies/dtmf/selected_output_devices/mask/bluetooth_sco_headset">
-          <BitParameter Name="bluetooth_sco_headset">0</BitParameter>
-        </ConfigurableElement>
-        <ConfigurableElement Path="/Policy/policy/strategies/dtmf/selected_output_devices/mask/bluetooth_a2dp">
-          <BitParameter Name="bluetooth_a2dp">0</BitParameter>
-        </ConfigurableElement>
-        <ConfigurableElement Path="/Policy/policy/strategies/dtmf/selected_output_devices/mask/bluetooth_a2dp_headphones">
-          <BitParameter Name="bluetooth_a2dp_headphones">0</BitParameter>
-        </ConfigurableElement>
-        <ConfigurableElement Path="/Policy/policy/strategies/dtmf/selected_output_devices/mask/bluetooth_a2dp_speaker">
-          <BitParameter Name="bluetooth_a2dp_speaker">0</BitParameter>
-        </ConfigurableElement>
-        <ConfigurableElement Path="/Policy/policy/strategies/dtmf/selected_output_devices/mask/hdmi">
-          <BitParameter Name="hdmi">0</BitParameter>
-        </ConfigurableElement>
-        <ConfigurableElement Path="/Policy/policy/strategies/dtmf/selected_output_devices/mask/angl_dock_headset">
-          <BitParameter Name="angl_dock_headset">0</BitParameter>
-        </ConfigurableElement>
-        <ConfigurableElement Path="/Policy/policy/strategies/dtmf/selected_output_devices/mask/dgtl_dock_headset">
-          <BitParameter Name="dgtl_dock_headset">0</BitParameter>
-        </ConfigurableElement>
-        <ConfigurableElement Path="/Policy/policy/strategies/dtmf/selected_output_devices/mask/usb_accessory">
-          <BitParameter Name="usb_accessory">0</BitParameter>
-        </ConfigurableElement>
-        <ConfigurableElement Path="/Policy/policy/strategies/dtmf/selected_output_devices/mask/usb_device">
-          <BitParameter Name="usb_device">0</BitParameter>
-        </ConfigurableElement>
-        <ConfigurableElement Path="/Policy/policy/strategies/dtmf/selected_output_devices/mask/telephony_tx">
-          <BitParameter Name="telephony_tx">0</BitParameter>
-        </ConfigurableElement>
-        <ConfigurableElement Path="/Policy/policy/strategies/dtmf/selected_output_devices/mask/line">
-          <BitParameter Name="line">1</BitParameter>
-        </ConfigurableElement>
-        <ConfigurableElement Path="/Policy/policy/strategies/dtmf/selected_output_devices/mask/speaker">
-          <BitParameter Name="speaker">0</BitParameter>
-        </ConfigurableElement>
-      </Configuration>
       <Configuration Name="Speaker">
         <ConfigurableElement Path="/Policy/policy/strategies/dtmf/selected_output_devices/mask/remote_submix">
           <BitParameter Name="remote_submix">0</BitParameter>
@@ -6286,10 +6192,6 @@
       <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/aux_line"/>
       <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/fm"/>
       <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/speaker_safe"/>
-      <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/earpiece"/>
-      <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_sco"/>
-      <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_sco_headset"/>
-      <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_sco_carkit"/>
       <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/telephony_tx"/>
     </ConfigurableElements>
     <Settings>
@@ -6309,39 +6211,33 @@
         <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/speaker_safe">
           <BitParameter Name="speaker_safe">0</BitParameter>
         </ConfigurableElement>
-        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/earpiece">
-          <BitParameter Name="earpiece">0</BitParameter>
-        </ConfigurableElement>
-        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_sco">
-          <BitParameter Name="bluetooth_sco">0</BitParameter>
-        </ConfigurableElement>
-        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_sco_headset">
-          <BitParameter Name="bluetooth_sco_headset">0</BitParameter>
-        </ConfigurableElement>
-        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_sco_carkit">
-          <BitParameter Name="bluetooth_sco_carkit">0</BitParameter>
-        </ConfigurableElement>
         <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/telephony_tx">
           <BitParameter Name="telephony_tx">0</BitParameter>
         </ConfigurableElement>
       </Configuration>
     </Settings>
   </ConfigurableDomain>
-  <ConfigurableDomain Name="DeviceForStrategy.Accessibility.Device2" SequenceAware="false">
+  <ConfigurableDomain Name="DeviceForStrategy.Accessibility.Device" SequenceAware="false">
     <Configurations>
       <Configuration Name="RemoteSubmix">
         <CompoundRule Type="All">
+          <SelectionCriterionRule SelectionCriterion="TelephonyMode" MatchesWhen="IsNot" Value="InCall"/>
+          <SelectionCriterionRule SelectionCriterion="TelephonyMode" MatchesWhen="IsNot" Value="InCommunication"/>
           <SelectionCriterionRule SelectionCriterion="AvailableOutputDevices" MatchesWhen="Includes" Value="RemoteSubmix"/>
         </CompoundRule>
       </Configuration>
       <Configuration Name="BluetoothA2dp">
         <CompoundRule Type="All">
+          <SelectionCriterionRule SelectionCriterion="TelephonyMode" MatchesWhen="IsNot" Value="InCall"/>
+          <SelectionCriterionRule SelectionCriterion="TelephonyMode" MatchesWhen="IsNot" Value="InCommunication"/>
           <SelectionCriterionRule SelectionCriterion="ForceUseForMedia" MatchesWhen="IsNot" Value="ForceNoBtA2dp"/>
           <SelectionCriterionRule SelectionCriterion="AvailableOutputDevices" MatchesWhen="Includes" Value="BluetoothA2dp"/>
         </CompoundRule>
       </Configuration>
       <Configuration Name="BluetoothA2dpHeadphone">
         <CompoundRule Type="All">
+          <SelectionCriterionRule SelectionCriterion="TelephonyMode" MatchesWhen="IsNot" Value="InCall"/>
+          <SelectionCriterionRule SelectionCriterion="TelephonyMode" MatchesWhen="IsNot" Value="InCommunication"/>
           <SelectionCriterionRule SelectionCriterion="ForceUseForMedia" MatchesWhen="IsNot" Value="ForceNoBtA2dp"/>
           <SelectionCriterionRule SelectionCriterion="AvailableOutputDevices" MatchesWhen="Includes" Value="BluetoothA2dpHeadphones"/>
         </CompoundRule>
@@ -6349,56 +6245,159 @@
       <Configuration Name="BluetoothA2dpSpeaker">
         <CompoundRule Type="All">
           <SelectionCriterionRule SelectionCriterion="ForceUseForMedia" MatchesWhen="IsNot" Value="ForceNoBtA2dp"/>
+          <SelectionCriterionRule SelectionCriterion="TelephonyMode" MatchesWhen="IsNot" Value="InCall"/>
+          <SelectionCriterionRule SelectionCriterion="TelephonyMode" MatchesWhen="IsNot" Value="InCommunication"/>
           <SelectionCriterionRule SelectionCriterion="AvailableOutputDevices" MatchesWhen="Includes" Value="BluetoothA2dpSpeaker"/>
         </CompoundRule>
       </Configuration>
-      <Configuration Name="ForceSpeaker">
+      <Configuration Name="ForceSpeakerWhenNotInCall">
         <CompoundRule Type="All">
+          <SelectionCriterionRule SelectionCriterion="TelephonyMode" MatchesWhen="IsNot" Value="InCall"/>
+          <SelectionCriterionRule SelectionCriterion="TelephonyMode" MatchesWhen="IsNot" Value="InCommunication"/>
           <SelectionCriterionRule SelectionCriterion="ForceUseForMedia" MatchesWhen="Is" Value="ForceSpeaker"/>
           <SelectionCriterionRule SelectionCriterion="AvailableOutputDevices" MatchesWhen="Includes" Value="Speaker"/>
         </CompoundRule>
       </Configuration>
+      <Configuration Name="BluetoothScoCarkit">
+        <CompoundRule Type="All">
+          <CompoundRule Type="Any">
+            <SelectionCriterionRule SelectionCriterion="TelephonyMode" MatchesWhen="Is" Value="InCall"/>
+            <SelectionCriterionRule SelectionCriterion="TelephonyMode" MatchesWhen="Is" Value="InCommunication"/>
+          </CompoundRule>
+          <SelectionCriterionRule SelectionCriterion="AvailableOutputDevices" MatchesWhen="Includes" Value="BluetoothScoCarkit"/>
+          <SelectionCriterionRule SelectionCriterion="ForceUseForCommunication" MatchesWhen="Is" Value="ForceBtSco"/>
+        </CompoundRule>
+      </Configuration>
+      <Configuration Name="BluetoothScoHeadset">
+        <CompoundRule Type="All">
+          <CompoundRule Type="Any">
+            <SelectionCriterionRule SelectionCriterion="TelephonyMode" MatchesWhen="Is" Value="InCall"/>
+            <SelectionCriterionRule SelectionCriterion="TelephonyMode" MatchesWhen="Is" Value="InCommunication"/>
+          </CompoundRule>
+          <SelectionCriterionRule SelectionCriterion="AvailableOutputDevices" MatchesWhen="Includes" Value="BluetoothScoHeadset"/>
+          <SelectionCriterionRule SelectionCriterion="ForceUseForCommunication" MatchesWhen="Is" Value="ForceBtSco"/>
+        </CompoundRule>
+      </Configuration>
+      <Configuration Name="BluetoothSco">
+        <CompoundRule Type="All">
+          <CompoundRule Type="Any">
+            <SelectionCriterionRule SelectionCriterion="TelephonyMode" MatchesWhen="Is" Value="InCall"/>
+            <SelectionCriterionRule SelectionCriterion="TelephonyMode" MatchesWhen="Is" Value="InCommunication"/>
+          </CompoundRule>
+          <SelectionCriterionRule SelectionCriterion="AvailableOutputDevices" MatchesWhen="Includes" Value="BluetoothSco"/>
+          <SelectionCriterionRule SelectionCriterion="ForceUseForCommunication" MatchesWhen="Is" Value="ForceBtSco"/>
+        </CompoundRule>
+      </Configuration>
       <Configuration Name="WiredHeadphone">
         <CompoundRule Type="All">
+          <CompoundRule Type="Any">
+            <CompoundRule Type="All">
+              <CompoundRule Type="Any">
+                <SelectionCriterionRule SelectionCriterion="TelephonyMode" MatchesWhen="Is" Value="InCall"/>
+                <SelectionCriterionRule SelectionCriterion="TelephonyMode" MatchesWhen="Is" Value="InCommunication"/>
+              </CompoundRule>
+              <SelectionCriterionRule SelectionCriterion="ForceUseForCommunication" MatchesWhen="IsNot" Value="ForceSpeaker"/>
+            </CompoundRule>
+            <CompoundRule Type="All">
+              <SelectionCriterionRule SelectionCriterion="TelephonyMode" MatchesWhen="IsNot" Value="InCall"/>
+              <SelectionCriterionRule SelectionCriterion="TelephonyMode" MatchesWhen="IsNot" Value="InCommunication"/>
+            </CompoundRule>
+          </CompoundRule>
           <SelectionCriterionRule SelectionCriterion="AvailableOutputDevices" MatchesWhen="Includes" Value="WiredHeadphone"/>
         </CompoundRule>
       </Configuration>
       <Configuration Name="Line">
         <CompoundRule Type="All">
+          <CompoundRule Type="Any">
+            <CompoundRule Type="All">
+              <CompoundRule Type="Any">
+                <SelectionCriterionRule SelectionCriterion="TelephonyMode" MatchesWhen="Is" Value="InCall"/>
+                <SelectionCriterionRule SelectionCriterion="TelephonyMode" MatchesWhen="Is" Value="InCommunication"/>
+              </CompoundRule>
+              <SelectionCriterionRule SelectionCriterion="ForceUseForCommunication" MatchesWhen="IsNot" Value="ForceSpeaker"/>
+              <SelectionCriterionRule SelectionCriterion="AvailableOutputDevices" MatchesWhen="Excludes" Value="WiredHeadset"/>
+            </CompoundRule>
+          </CompoundRule>
           <SelectionCriterionRule SelectionCriterion="AvailableOutputDevices" MatchesWhen="Includes" Value="Line"/>
         </CompoundRule>
       </Configuration>
       <Configuration Name="WiredHeadset">
         <CompoundRule Type="All">
+          <CompoundRule Type="Any">
+            <CompoundRule Type="All">
+              <CompoundRule Type="Any">
+                <SelectionCriterionRule SelectionCriterion="TelephonyMode" MatchesWhen="Is" Value="InCall"/>
+                <SelectionCriterionRule SelectionCriterion="TelephonyMode" MatchesWhen="Is" Value="InCommunication"/>
+              </CompoundRule>
+              <SelectionCriterionRule SelectionCriterion="ForceUseForCommunication" MatchesWhen="IsNot" Value="ForceSpeaker"/>
+            </CompoundRule>
+            <CompoundRule Type="All">
+              <SelectionCriterionRule SelectionCriterion="TelephonyMode" MatchesWhen="IsNot" Value="InCall"/>
+              <SelectionCriterionRule SelectionCriterion="TelephonyMode" MatchesWhen="IsNot" Value="InCommunication"/>
+            </CompoundRule>
+          </CompoundRule>
           <SelectionCriterionRule SelectionCriterion="AvailableOutputDevices" MatchesWhen="Includes" Value="WiredHeadset"/>
         </CompoundRule>
       </Configuration>
-      <Configuration Name="UsbAccessory">
-        <CompoundRule Type="All">
-          <SelectionCriterionRule SelectionCriterion="AvailableOutputDevices" MatchesWhen="Includes" Value="UsbAccessory"/>
-        </CompoundRule>
-      </Configuration>
       <Configuration Name="UsbDevice">
         <CompoundRule Type="All">
+          <CompoundRule Type="Any">
+            <CompoundRule Type="All">
+              <CompoundRule Type="Any">
+                <SelectionCriterionRule SelectionCriterion="TelephonyMode" MatchesWhen="Is" Value="InCall"/>
+                <SelectionCriterionRule SelectionCriterion="TelephonyMode" MatchesWhen="Is" Value="InCommunication"/>
+              </CompoundRule>
+              <SelectionCriterionRule SelectionCriterion="ForceUseForCommunication" MatchesWhen="IsNot" Value="ForceSpeaker"/>
+            </CompoundRule>
+            <CompoundRule Type="All">
+              <SelectionCriterionRule SelectionCriterion="TelephonyMode" MatchesWhen="IsNot" Value="InCall"/>
+              <SelectionCriterionRule SelectionCriterion="TelephonyMode" MatchesWhen="IsNot" Value="InCommunication"/>
+              <SelectionCriterionRule SelectionCriterion="AvailableOutputDevices" MatchesWhen="Excludes" Value="UsbAccessory"/>
+              <SelectionCriterionRule SelectionCriterion="ForceUseForCommunication" MatchesWhen="Is" Value="ForceSpeaker"/>
+            </CompoundRule>
+          </CompoundRule>
           <SelectionCriterionRule SelectionCriterion="AvailableOutputDevices" MatchesWhen="Includes" Value="UsbDevice"/>
         </CompoundRule>
       </Configuration>
+      <Configuration Name="UsbAccessory">
+        <CompoundRule Type="All">
+          <SelectionCriterionRule SelectionCriterion="TelephonyMode" MatchesWhen="IsNot" Value="InCall"/>
+          <SelectionCriterionRule SelectionCriterion="TelephonyMode" MatchesWhen="IsNot" Value="InCommunication"/>
+          <SelectionCriterionRule SelectionCriterion="AvailableOutputDevices" MatchesWhen="Includes" Value="UsbAccessory"/>
+        </CompoundRule>
+      </Configuration>
       <Configuration Name="DgtlDockHeadset">
         <CompoundRule Type="All">
+          <SelectionCriterionRule SelectionCriterion="TelephonyMode" MatchesWhen="IsNot" Value="InCall"/>
+          <SelectionCriterionRule SelectionCriterion="TelephonyMode" MatchesWhen="IsNot" Value="InCommunication"/>
           <SelectionCriterionRule SelectionCriterion="AvailableOutputDevices" MatchesWhen="Includes" Value="DgtlDockHeadset"/>
         </CompoundRule>
       </Configuration>
       <Configuration Name="AuxDigital">
         <CompoundRule Type="All">
+          <SelectionCriterionRule SelectionCriterion="TelephonyMode" MatchesWhen="IsNot" Value="InCall"/>
+          <SelectionCriterionRule SelectionCriterion="TelephonyMode" MatchesWhen="IsNot" Value="InCommunication"/>
           <SelectionCriterionRule SelectionCriterion="AvailableOutputDevices" MatchesWhen="Includes" Value="Hdmi"/>
         </CompoundRule>
       </Configuration>
       <Configuration Name="AnlgDockHeadset">
         <CompoundRule Type="All">
+          <SelectionCriterionRule SelectionCriterion="TelephonyMode" MatchesWhen="IsNot" Value="InCall"/>
+          <SelectionCriterionRule SelectionCriterion="TelephonyMode" MatchesWhen="IsNot" Value="InCommunication"/>
           <SelectionCriterionRule SelectionCriterion="AvailableOutputDevices" MatchesWhen="Includes" Value="AnlgDockHeadset"/>
           <SelectionCriterionRule SelectionCriterion="ForceUseForDock" MatchesWhen="Is" Value="ForceAnalogDock"/>
         </CompoundRule>
       </Configuration>
+      <Configuration Name="Earpiece">
+        <CompoundRule Type="All">
+          <CompoundRule Type="Any">
+            <SelectionCriterionRule SelectionCriterion="TelephonyMode" MatchesWhen="Is" Value="InCall"/>
+            <SelectionCriterionRule SelectionCriterion="TelephonyMode" MatchesWhen="Is" Value="InCommunication"/>
+          </CompoundRule>
+          <SelectionCriterionRule SelectionCriterion="AvailableOutputDevices" MatchesWhen="Includes" Value="Earpiece"/>
+          <SelectionCriterionRule SelectionCriterion="ForceUseForCommunication" MatchesWhen="IsNot" Value="ForceSpeaker"/>
+        </CompoundRule>
+      </Configuration>
       <Configuration Name="Speaker">
         <CompoundRule Type="All">
           <SelectionCriterionRule SelectionCriterion="AvailableOutputDevices" MatchesWhen="Includes" Value="Speaker"/>
@@ -6410,9 +6409,13 @@
     </Configurations>
     <ConfigurableElements>
       <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/remote_submix"/>
+      <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/earpiece"/>
       <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_a2dp"/>
       <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_a2dp_headphones"/>
       <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_a2dp_speaker"/>
+      <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_sco_headset"/>
+      <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_sco_carkit"/>
+      <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_sco"/>
       <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/speaker"/>
       <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/wired_headset"/>
       <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/wired_headphone"/>
@@ -6428,6 +6431,9 @@
         <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/remote_submix">
           <BitParameter Name="remote_submix">1</BitParameter>
         </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/earpiece">
+          <BitParameter Name="earpiece">0</BitParameter>
+        </ConfigurableElement>
         <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_a2dp">
           <BitParameter Name="bluetooth_a2dp">0</BitParameter>
         </ConfigurableElement>
@@ -6437,6 +6443,15 @@
         <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_a2dp_speaker">
           <BitParameter Name="bluetooth_a2dp_speaker">0</BitParameter>
         </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_sco_headset">
+          <BitParameter Name="bluetooth_sco_headset">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_sco_carkit">
+          <BitParameter Name="bluetooth_sco_carkit">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_sco">
+          <BitParameter Name="bluetooth_sco">0</BitParameter>
+        </ConfigurableElement>
         <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/speaker">
           <BitParameter Name="speaker">0</BitParameter>
         </ConfigurableElement>
@@ -6469,6 +6484,9 @@
         <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/remote_submix">
           <BitParameter Name="remote_submix">0</BitParameter>
         </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/earpiece">
+          <BitParameter Name="earpiece">0</BitParameter>
+        </ConfigurableElement>
         <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_a2dp">
           <BitParameter Name="bluetooth_a2dp">1</BitParameter>
         </ConfigurableElement>
@@ -6478,6 +6496,15 @@
         <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_a2dp_speaker">
           <BitParameter Name="bluetooth_a2dp_speaker">0</BitParameter>
         </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_sco_headset">
+          <BitParameter Name="bluetooth_sco_headset">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_sco_carkit">
+          <BitParameter Name="bluetooth_sco_carkit">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_sco">
+          <BitParameter Name="bluetooth_sco">0</BitParameter>
+        </ConfigurableElement>
         <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/speaker">
           <BitParameter Name="speaker">0</BitParameter>
         </ConfigurableElement>
@@ -6510,6 +6537,9 @@
         <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/remote_submix">
           <BitParameter Name="remote_submix">0</BitParameter>
         </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/earpiece">
+          <BitParameter Name="earpiece">0</BitParameter>
+        </ConfigurableElement>
         <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_a2dp">
           <BitParameter Name="bluetooth_a2dp">0</BitParameter>
         </ConfigurableElement>
@@ -6519,6 +6549,15 @@
         <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_a2dp_speaker">
           <BitParameter Name="bluetooth_a2dp_speaker">0</BitParameter>
         </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_sco_headset">
+          <BitParameter Name="bluetooth_sco_headset">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_sco_carkit">
+          <BitParameter Name="bluetooth_sco_carkit">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_sco">
+          <BitParameter Name="bluetooth_sco">0</BitParameter>
+        </ConfigurableElement>
         <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/speaker">
           <BitParameter Name="speaker">0</BitParameter>
         </ConfigurableElement>
@@ -6551,6 +6590,9 @@
         <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/remote_submix">
           <BitParameter Name="remote_submix">0</BitParameter>
         </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/earpiece">
+          <BitParameter Name="earpiece">0</BitParameter>
+        </ConfigurableElement>
         <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_a2dp">
           <BitParameter Name="bluetooth_a2dp">0</BitParameter>
         </ConfigurableElement>
@@ -6560,6 +6602,15 @@
         <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_a2dp_speaker">
           <BitParameter Name="bluetooth_a2dp_speaker">1</BitParameter>
         </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_sco_headset">
+          <BitParameter Name="bluetooth_sco_headset">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_sco_carkit">
+          <BitParameter Name="bluetooth_sco_carkit">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_sco">
+          <BitParameter Name="bluetooth_sco">0</BitParameter>
+        </ConfigurableElement>
         <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/speaker">
           <BitParameter Name="speaker">0</BitParameter>
         </ConfigurableElement>
@@ -6588,10 +6639,13 @@
           <BitParameter Name="hdmi">0</BitParameter>
         </ConfigurableElement>
       </Configuration>
-      <Configuration Name="ForceSpeaker">
+      <Configuration Name="ForceSpeakerWhenNotInCall">
         <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/remote_submix">
           <BitParameter Name="remote_submix">0</BitParameter>
         </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/earpiece">
+          <BitParameter Name="earpiece">0</BitParameter>
+        </ConfigurableElement>
         <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_a2dp">
           <BitParameter Name="bluetooth_a2dp">0</BitParameter>
         </ConfigurableElement>
@@ -6601,6 +6655,15 @@
         <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_a2dp_speaker">
           <BitParameter Name="bluetooth_a2dp_speaker">0</BitParameter>
         </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_sco_headset">
+          <BitParameter Name="bluetooth_sco_headset">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_sco_carkit">
+          <BitParameter Name="bluetooth_sco_carkit">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_sco">
+          <BitParameter Name="bluetooth_sco">0</BitParameter>
+        </ConfigurableElement>
         <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/speaker">
           <BitParameter Name="speaker">1</BitParameter>
         </ConfigurableElement>
@@ -6629,10 +6692,13 @@
           <BitParameter Name="hdmi">0</BitParameter>
         </ConfigurableElement>
       </Configuration>
-      <Configuration Name="WiredHeadphone">
+      <Configuration Name="BluetoothScoCarkit">
         <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/remote_submix">
           <BitParameter Name="remote_submix">0</BitParameter>
         </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/earpiece">
+          <BitParameter Name="earpiece">0</BitParameter>
+        </ConfigurableElement>
         <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_a2dp">
           <BitParameter Name="bluetooth_a2dp">0</BitParameter>
         </ConfigurableElement>
@@ -6642,6 +6708,174 @@
         <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_a2dp_speaker">
           <BitParameter Name="bluetooth_a2dp_speaker">0</BitParameter>
         </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_sco_headset">
+          <BitParameter Name="bluetooth_sco_headset">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_sco_carkit">
+          <BitParameter Name="bluetooth_sco_carkit">1</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_sco">
+          <BitParameter Name="bluetooth_sco">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/speaker">
+          <BitParameter Name="speaker">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/wired_headset">
+          <BitParameter Name="wired_headset">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/wired_headphone">
+          <BitParameter Name="wired_headphone">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/line">
+          <BitParameter Name="line">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/angl_dock_headset">
+          <BitParameter Name="angl_dock_headset">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/dgtl_dock_headset">
+          <BitParameter Name="dgtl_dock_headset">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/usb_accessory">
+          <BitParameter Name="usb_accessory">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/usb_device">
+          <BitParameter Name="usb_device">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/hdmi">
+          <BitParameter Name="hdmi">0</BitParameter>
+        </ConfigurableElement>
+      </Configuration>
+      <Configuration Name="BluetoothScoHeadset">
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/remote_submix">
+          <BitParameter Name="remote_submix">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/earpiece">
+          <BitParameter Name="earpiece">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_a2dp">
+          <BitParameter Name="bluetooth_a2dp">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_a2dp_headphones">
+          <BitParameter Name="bluetooth_a2dp_headphones">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_a2dp_speaker">
+          <BitParameter Name="bluetooth_a2dp_speaker">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_sco_headset">
+          <BitParameter Name="bluetooth_sco_headset">1</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_sco_carkit">
+          <BitParameter Name="bluetooth_sco_carkit">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_sco">
+          <BitParameter Name="bluetooth_sco">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/speaker">
+          <BitParameter Name="speaker">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/wired_headset">
+          <BitParameter Name="wired_headset">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/wired_headphone">
+          <BitParameter Name="wired_headphone">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/line">
+          <BitParameter Name="line">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/angl_dock_headset">
+          <BitParameter Name="angl_dock_headset">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/dgtl_dock_headset">
+          <BitParameter Name="dgtl_dock_headset">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/usb_accessory">
+          <BitParameter Name="usb_accessory">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/usb_device">
+          <BitParameter Name="usb_device">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/hdmi">
+          <BitParameter Name="hdmi">0</BitParameter>
+        </ConfigurableElement>
+      </Configuration>
+      <Configuration Name="BluetoothSco">
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/remote_submix">
+          <BitParameter Name="remote_submix">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/earpiece">
+          <BitParameter Name="earpiece">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_a2dp">
+          <BitParameter Name="bluetooth_a2dp">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_a2dp_headphones">
+          <BitParameter Name="bluetooth_a2dp_headphones">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_a2dp_speaker">
+          <BitParameter Name="bluetooth_a2dp_speaker">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_sco_headset">
+          <BitParameter Name="bluetooth_sco_headset">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_sco_carkit">
+          <BitParameter Name="bluetooth_sco_carkit">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_sco">
+          <BitParameter Name="bluetooth_sco">1</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/speaker">
+          <BitParameter Name="speaker">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/wired_headset">
+          <BitParameter Name="wired_headset">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/wired_headphone">
+          <BitParameter Name="wired_headphone">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/line">
+          <BitParameter Name="line">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/angl_dock_headset">
+          <BitParameter Name="angl_dock_headset">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/dgtl_dock_headset">
+          <BitParameter Name="dgtl_dock_headset">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/usb_accessory">
+          <BitParameter Name="usb_accessory">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/usb_device">
+          <BitParameter Name="usb_device">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/hdmi">
+          <BitParameter Name="hdmi">0</BitParameter>
+        </ConfigurableElement>
+      </Configuration>
+      <Configuration Name="WiredHeadphone">
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/remote_submix">
+          <BitParameter Name="remote_submix">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/earpiece">
+          <BitParameter Name="earpiece">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_a2dp">
+          <BitParameter Name="bluetooth_a2dp">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_a2dp_headphones">
+          <BitParameter Name="bluetooth_a2dp_headphones">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_a2dp_speaker">
+          <BitParameter Name="bluetooth_a2dp_speaker">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_sco_headset">
+          <BitParameter Name="bluetooth_sco_headset">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_sco_carkit">
+          <BitParameter Name="bluetooth_sco_carkit">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_sco">
+          <BitParameter Name="bluetooth_sco">0</BitParameter>
+        </ConfigurableElement>
         <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/speaker">
           <BitParameter Name="speaker">0</BitParameter>
         </ConfigurableElement>
@@ -6674,6 +6908,9 @@
         <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/remote_submix">
           <BitParameter Name="remote_submix">0</BitParameter>
         </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/earpiece">
+          <BitParameter Name="earpiece">0</BitParameter>
+        </ConfigurableElement>
         <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_a2dp">
           <BitParameter Name="bluetooth_a2dp">0</BitParameter>
         </ConfigurableElement>
@@ -6683,6 +6920,15 @@
         <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_a2dp_speaker">
           <BitParameter Name="bluetooth_a2dp_speaker">0</BitParameter>
         </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_sco_headset">
+          <BitParameter Name="bluetooth_sco_headset">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_sco_carkit">
+          <BitParameter Name="bluetooth_sco_carkit">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_sco">
+          <BitParameter Name="bluetooth_sco">0</BitParameter>
+        </ConfigurableElement>
         <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/speaker">
           <BitParameter Name="speaker">0</BitParameter>
         </ConfigurableElement>
@@ -6715,6 +6961,9 @@
         <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/remote_submix">
           <BitParameter Name="remote_submix">0</BitParameter>
         </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/earpiece">
+          <BitParameter Name="earpiece">0</BitParameter>
+        </ConfigurableElement>
         <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_a2dp">
           <BitParameter Name="bluetooth_a2dp">0</BitParameter>
         </ConfigurableElement>
@@ -6724,6 +6973,15 @@
         <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_a2dp_speaker">
           <BitParameter Name="bluetooth_a2dp_speaker">0</BitParameter>
         </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_sco_headset">
+          <BitParameter Name="bluetooth_sco_headset">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_sco_carkit">
+          <BitParameter Name="bluetooth_sco_carkit">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_sco">
+          <BitParameter Name="bluetooth_sco">0</BitParameter>
+        </ConfigurableElement>
         <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/speaker">
           <BitParameter Name="speaker">0</BitParameter>
         </ConfigurableElement>
@@ -6752,51 +7010,13 @@
           <BitParameter Name="hdmi">0</BitParameter>
         </ConfigurableElement>
       </Configuration>
-      <Configuration Name="UsbAccessory">
-        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/remote_submix">
-          <BitParameter Name="remote_submix">0</BitParameter>
-        </ConfigurableElement>
-        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_a2dp">
-          <BitParameter Name="bluetooth_a2dp">0</BitParameter>
-        </ConfigurableElement>
-        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_a2dp_headphones">
-          <BitParameter Name="bluetooth_a2dp_headphones">0</BitParameter>
-        </ConfigurableElement>
-        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_a2dp_speaker">
-          <BitParameter Name="bluetooth_a2dp_speaker">0</BitParameter>
-        </ConfigurableElement>
-        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/speaker">
-          <BitParameter Name="speaker">0</BitParameter>
-        </ConfigurableElement>
-        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/wired_headset">
-          <BitParameter Name="wired_headset">0</BitParameter>
-        </ConfigurableElement>
-        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/wired_headphone">
-          <BitParameter Name="wired_headphone">0</BitParameter>
-        </ConfigurableElement>
-        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/line">
-          <BitParameter Name="line">0</BitParameter>
-        </ConfigurableElement>
-        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/angl_dock_headset">
-          <BitParameter Name="angl_dock_headset">0</BitParameter>
-        </ConfigurableElement>
-        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/dgtl_dock_headset">
-          <BitParameter Name="dgtl_dock_headset">0</BitParameter>
-        </ConfigurableElement>
-        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/usb_accessory">
-          <BitParameter Name="usb_accessory">1</BitParameter>
-        </ConfigurableElement>
-        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/usb_device">
-          <BitParameter Name="usb_device">0</BitParameter>
-        </ConfigurableElement>
-        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/hdmi">
-          <BitParameter Name="hdmi">0</BitParameter>
-        </ConfigurableElement>
-      </Configuration>
       <Configuration Name="UsbDevice">
         <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/remote_submix">
           <BitParameter Name="remote_submix">0</BitParameter>
         </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/earpiece">
+          <BitParameter Name="earpiece">0</BitParameter>
+        </ConfigurableElement>
         <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_a2dp">
           <BitParameter Name="bluetooth_a2dp">0</BitParameter>
         </ConfigurableElement>
@@ -6806,6 +7026,15 @@
         <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_a2dp_speaker">
           <BitParameter Name="bluetooth_a2dp_speaker">0</BitParameter>
         </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_sco_headset">
+          <BitParameter Name="bluetooth_sco_headset">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_sco_carkit">
+          <BitParameter Name="bluetooth_sco_carkit">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_sco">
+          <BitParameter Name="bluetooth_sco">0</BitParameter>
+        </ConfigurableElement>
         <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/speaker">
           <BitParameter Name="speaker">0</BitParameter>
         </ConfigurableElement>
@@ -6834,10 +7063,13 @@
           <BitParameter Name="hdmi">0</BitParameter>
         </ConfigurableElement>
       </Configuration>
-      <Configuration Name="DgtlDockHeadset">
+      <Configuration Name="UsbAccessory">
         <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/remote_submix">
           <BitParameter Name="remote_submix">0</BitParameter>
         </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/earpiece">
+          <BitParameter Name="earpiece">0</BitParameter>
+        </ConfigurableElement>
         <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_a2dp">
           <BitParameter Name="bluetooth_a2dp">0</BitParameter>
         </ConfigurableElement>
@@ -6847,6 +7079,68 @@
         <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_a2dp_speaker">
           <BitParameter Name="bluetooth_a2dp_speaker">0</BitParameter>
         </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_sco_headset">
+          <BitParameter Name="bluetooth_sco_headset">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_sco_carkit">
+          <BitParameter Name="bluetooth_sco_carkit">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_sco">
+          <BitParameter Name="bluetooth_sco">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/speaker">
+          <BitParameter Name="speaker">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/wired_headset">
+          <BitParameter Name="wired_headset">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/wired_headphone">
+          <BitParameter Name="wired_headphone">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/line">
+          <BitParameter Name="line">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/angl_dock_headset">
+          <BitParameter Name="angl_dock_headset">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/dgtl_dock_headset">
+          <BitParameter Name="dgtl_dock_headset">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/usb_accessory">
+          <BitParameter Name="usb_accessory">1</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/usb_device">
+          <BitParameter Name="usb_device">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/hdmi">
+          <BitParameter Name="hdmi">0</BitParameter>
+        </ConfigurableElement>
+      </Configuration>
+      <Configuration Name="DgtlDockHeadset">
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/remote_submix">
+          <BitParameter Name="remote_submix">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/earpiece">
+          <BitParameter Name="earpiece">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_a2dp">
+          <BitParameter Name="bluetooth_a2dp">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_a2dp_headphones">
+          <BitParameter Name="bluetooth_a2dp_headphones">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_a2dp_speaker">
+          <BitParameter Name="bluetooth_a2dp_speaker">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_sco_headset">
+          <BitParameter Name="bluetooth_sco_headset">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_sco_carkit">
+          <BitParameter Name="bluetooth_sco_carkit">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_sco">
+          <BitParameter Name="bluetooth_sco">0</BitParameter>
+        </ConfigurableElement>
         <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/speaker">
           <BitParameter Name="speaker">0</BitParameter>
         </ConfigurableElement>
@@ -6879,6 +7173,9 @@
         <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/remote_submix">
           <BitParameter Name="remote_submix">0</BitParameter>
         </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/earpiece">
+          <BitParameter Name="earpiece">0</BitParameter>
+        </ConfigurableElement>
         <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_a2dp">
           <BitParameter Name="bluetooth_a2dp">0</BitParameter>
         </ConfigurableElement>
@@ -6888,6 +7185,15 @@
         <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_a2dp_speaker">
           <BitParameter Name="bluetooth_a2dp_speaker">0</BitParameter>
         </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_sco_headset">
+          <BitParameter Name="bluetooth_sco_headset">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_sco_carkit">
+          <BitParameter Name="bluetooth_sco_carkit">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_sco">
+          <BitParameter Name="bluetooth_sco">0</BitParameter>
+        </ConfigurableElement>
         <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/speaker">
           <BitParameter Name="speaker">0</BitParameter>
         </ConfigurableElement>
@@ -6920,6 +7226,9 @@
         <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/remote_submix">
           <BitParameter Name="remote_submix">0</BitParameter>
         </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/earpiece">
+          <BitParameter Name="earpiece">0</BitParameter>
+        </ConfigurableElement>
         <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_a2dp">
           <BitParameter Name="bluetooth_a2dp">0</BitParameter>
         </ConfigurableElement>
@@ -6929,6 +7238,15 @@
         <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_a2dp_speaker">
           <BitParameter Name="bluetooth_a2dp_speaker">0</BitParameter>
         </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_sco_headset">
+          <BitParameter Name="bluetooth_sco_headset">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_sco_carkit">
+          <BitParameter Name="bluetooth_sco_carkit">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_sco">
+          <BitParameter Name="bluetooth_sco">0</BitParameter>
+        </ConfigurableElement>
         <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/speaker">
           <BitParameter Name="speaker">0</BitParameter>
         </ConfigurableElement>
@@ -6957,10 +7275,13 @@
           <BitParameter Name="hdmi">0</BitParameter>
         </ConfigurableElement>
       </Configuration>
-      <Configuration Name="Speaker">
+      <Configuration Name="Earpiece">
         <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/remote_submix">
           <BitParameter Name="remote_submix">0</BitParameter>
         </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/earpiece">
+          <BitParameter Name="earpiece">1</BitParameter>
+        </ConfigurableElement>
         <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_a2dp">
           <BitParameter Name="bluetooth_a2dp">0</BitParameter>
         </ConfigurableElement>
@@ -6970,6 +7291,68 @@
         <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_a2dp_speaker">
           <BitParameter Name="bluetooth_a2dp_speaker">0</BitParameter>
         </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_sco_headset">
+          <BitParameter Name="bluetooth_sco_headset">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_sco_carkit">
+          <BitParameter Name="bluetooth_sco_carkit">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_sco">
+          <BitParameter Name="bluetooth_sco">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/speaker">
+          <BitParameter Name="speaker">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/wired_headset">
+          <BitParameter Name="wired_headset">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/wired_headphone">
+          <BitParameter Name="wired_headphone">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/line">
+          <BitParameter Name="line">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/angl_dock_headset">
+          <BitParameter Name="angl_dock_headset">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/dgtl_dock_headset">
+          <BitParameter Name="dgtl_dock_headset">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/usb_accessory">
+          <BitParameter Name="usb_accessory">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/usb_device">
+          <BitParameter Name="usb_device">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/hdmi">
+          <BitParameter Name="hdmi">0</BitParameter>
+        </ConfigurableElement>
+      </Configuration>
+      <Configuration Name="Speaker">
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/remote_submix">
+          <BitParameter Name="remote_submix">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/earpiece">
+          <BitParameter Name="earpiece">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_a2dp">
+          <BitParameter Name="bluetooth_a2dp">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_a2dp_headphones">
+          <BitParameter Name="bluetooth_a2dp_headphones">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_a2dp_speaker">
+          <BitParameter Name="bluetooth_a2dp_speaker">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_sco_headset">
+          <BitParameter Name="bluetooth_sco_headset">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_sco_carkit">
+          <BitParameter Name="bluetooth_sco_carkit">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_sco">
+          <BitParameter Name="bluetooth_sco">0</BitParameter>
+        </ConfigurableElement>
         <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/speaker">
           <BitParameter Name="speaker">1</BitParameter>
         </ConfigurableElement>
@@ -7002,6 +7385,9 @@
         <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/remote_submix">
           <BitParameter Name="remote_submix">0</BitParameter>
         </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/earpiece">
+          <BitParameter Name="earpiece">0</BitParameter>
+        </ConfigurableElement>
         <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_a2dp">
           <BitParameter Name="bluetooth_a2dp">0</BitParameter>
         </ConfigurableElement>
@@ -7011,6 +7397,15 @@
         <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_a2dp_speaker">
           <BitParameter Name="bluetooth_a2dp_speaker">0</BitParameter>
         </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_sco_headset">
+          <BitParameter Name="bluetooth_sco_headset">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_sco_carkit">
+          <BitParameter Name="bluetooth_sco_carkit">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bluetooth_sco">
+          <BitParameter Name="bluetooth_sco">0</BitParameter>
+        </ConfigurableElement>
         <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/speaker">
           <BitParameter Name="speaker">0</BitParameter>
         </ConfigurableElement>
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/example/Settings/device_for_strategy_accessibility.pfw b/services/audiopolicy/engineconfigurable/parameter-framework/example/Settings/device_for_strategy_accessibility.pfw
index e8ab33b..dacf5b2 100644
--- a/services/audiopolicy/engineconfigurable/parameter-framework/example/Settings/device_for_strategy_accessibility.pfw
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/example/Settings/device_for_strategy_accessibility.pfw
@@ -2,9 +2,10 @@
 
 	supDomain: Accessibility
 		#
-		# @FIXME: STRATEGY_ACCESSIBILITY follows STRATEGY_MEDIA for now
+		# STRATEGY_ACCESSIBILITY follows STRATEGY_PHONE if in call widely speaking
+		# STRATEGY_ACCESSIBILITY follows STRATEGY_MEDIA otherwise
 		#
-		# @FIXME: How to disable HDMI if !audio_is_linear_pcm other than programmatically???
+		# Other case are handled programmatically has involving activity of streams.
 		#
 		domain: UnreachableDevices
 			conf: Calibration
@@ -14,21 +15,26 @@
 					aux_line = 0
 					fm = 0
 					speaker_safe = 0
-					earpiece = 0
-					bluetooth_sco = 0
-					bluetooth_sco_headset = 0
-					bluetooth_sco_carkit = 0
 					telephony_tx = 0
 
-		domain: Device2
+		domain: Device
 			conf: RemoteSubmix
+				#
+				# Accessibility follows Media strategy if not in call
+				#
+				TelephonyMode IsNot InCall
+				TelephonyMode IsNot InCommunication
 				AvailableOutputDevices Includes RemoteSubmix
 
 				component: /Policy/policy/strategies/accessibility/selected_output_devices/mask
 					remote_submix = 1
+					earpiece = 0
 					bluetooth_a2dp = 0
 					bluetooth_a2dp_headphones = 0
 					bluetooth_a2dp_speaker = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_sco = 0
 					speaker = 0
 					wired_headset = 0
 					wired_headphone = 0
@@ -40,14 +46,23 @@
 					hdmi = 0
 
 			conf: BluetoothA2dp
+				#
+				# Accessibility falls through media strategy if not in call (widely speaking)
+				#
+				TelephonyMode IsNot InCall
+				TelephonyMode IsNot InCommunication
 				ForceUseForMedia IsNot ForceNoBtA2dp
 				AvailableOutputDevices Includes BluetoothA2dp
 
 				component: /Policy/policy/strategies/accessibility/selected_output_devices/mask
 					remote_submix = 0
+					earpiece = 0
 					bluetooth_a2dp = 1
 					bluetooth_a2dp_headphones = 0
 					bluetooth_a2dp_speaker = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_sco = 0
 					speaker = 0
 					wired_headset = 0
 					wired_headphone = 0
@@ -59,14 +74,23 @@
 					hdmi = 0
 
 			conf: BluetoothA2dpHeadphone
+				#
+				# Accessibility falls through media strategy if not in call (widely speaking)
+				#
+				TelephonyMode IsNot InCall
+				TelephonyMode IsNot InCommunication
 				ForceUseForMedia IsNot ForceNoBtA2dp
 				AvailableOutputDevices Includes BluetoothA2dpHeadphones
 
 				component: /Policy/policy/strategies/accessibility/selected_output_devices/mask
 					remote_submix = 0
+					earpiece = 0
 					bluetooth_a2dp = 0
 					bluetooth_a2dp_headphones = 1
 					bluetooth_a2dp_speaker = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_sco = 0
 					speaker = 0
 					wired_headset = 0
 					wired_headphone = 0
@@ -78,14 +102,23 @@
 					hdmi = 0
 
 			conf: BluetoothA2dpSpeaker
+				#
+				# Accessibility falls through media strategy if not in call (widely speaking)
+				#
 				ForceUseForMedia IsNot ForceNoBtA2dp
+				TelephonyMode IsNot InCall
+				TelephonyMode IsNot InCommunication
 				AvailableOutputDevices Includes BluetoothA2dpSpeaker
 
 				component: /Policy/policy/strategies/accessibility/selected_output_devices/mask
 					remote_submix = 0
+					earpiece = 0
 					bluetooth_a2dp = 0
 					bluetooth_a2dp_headphones = 0
 					bluetooth_a2dp_speaker = 1
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_sco = 0
 					speaker = 0
 					wired_headset = 0
 					wired_headphone = 0
@@ -96,15 +129,24 @@
 					usb_device = 0
 					hdmi = 0
 
-			conf: ForceSpeaker
+			conf: ForceSpeakerWhenNotInCall
+				#
+				# Accessibility follows Media strategy if not in call
+				#
+				TelephonyMode IsNot InCall
+				TelephonyMode IsNot InCommunication
 				ForceUseForMedia Is ForceSpeaker
 				AvailableOutputDevices Includes Speaker
 
 				component: /Policy/policy/strategies/accessibility/selected_output_devices/mask
 					remote_submix = 0
+					earpiece = 0
 					bluetooth_a2dp = 0
 					bluetooth_a2dp_headphones = 0
 					bluetooth_a2dp_speaker = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_sco = 0
 					speaker = 1
 					wired_headset = 0
 					wired_headphone = 0
@@ -115,14 +157,120 @@
 					usb_device = 0
 					hdmi = 0
 
+			conf: BluetoothScoCarkit
+				#
+				# accessibility falls through Phone strategy if in call
+				#
+				ANY
+					TelephonyMode Is InCall
+					TelephonyMode Is InCommunication
+				AvailableOutputDevices Includes BluetoothScoCarkit
+				ForceUseForCommunication Is ForceBtSco
+
+				component: /Policy/policy/strategies/accessibility/selected_output_devices/mask
+					remote_submix = 0
+					earpiece = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 1
+					bluetooth_sco = 0
+					speaker = 0
+					wired_headset = 0
+					wired_headphone = 0
+					line = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					hdmi = 0
+
+			conf: BluetoothScoHeadset
+				#
+				# accessibility falls through Phone strategy if in call
+				#
+				ANY
+					TelephonyMode Is InCall
+					TelephonyMode Is InCommunication
+				AvailableOutputDevices Includes BluetoothScoHeadset
+				ForceUseForCommunication Is ForceBtSco
+
+				component: /Policy/policy/strategies/accessibility/selected_output_devices/mask
+					remote_submix = 0
+					earpiece = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					bluetooth_sco_headset = 1
+					bluetooth_sco_carkit = 0
+					bluetooth_sco = 0
+					speaker = 0
+					wired_headset = 0
+					wired_headphone = 0
+					line = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					hdmi = 0
+
+			conf: BluetoothSco
+				#
+				# accessibility falls through Phone strategy if in call
+				#
+				ANY
+					TelephonyMode Is InCall
+					TelephonyMode Is InCommunication
+				AvailableOutputDevices Includes BluetoothSco
+				ForceUseForCommunication Is ForceBtSco
+
+				component: /Policy/policy/strategies/accessibility/selected_output_devices/mask
+					remote_submix = 0
+					earpiece = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_sco = 1
+					speaker = 0
+					wired_headset = 0
+					wired_headphone = 0
+					line = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					hdmi = 0
+
 			conf: WiredHeadphone
+				ANY
+					#
+					# accessibility falls through Phone strategy if in call
+					#
+					ALL
+						ANY
+							TelephonyMode Is InCall
+							TelephonyMode Is InCommunication
+						ForceUseForCommunication IsNot ForceSpeaker
+					#
+					# accessibility follows Media strategy if not in call
+					#
+					ALL
+						TelephonyMode IsNot InCall
+						TelephonyMode IsNot InCommunication
 				AvailableOutputDevices Includes WiredHeadphone
 
 				component: /Policy/policy/strategies/accessibility/selected_output_devices/mask
 					remote_submix = 0
+					earpiece = 0
 					bluetooth_a2dp = 0
 					bluetooth_a2dp_headphones = 0
 					bluetooth_a2dp_speaker = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_sco = 0
 					speaker = 0
 					wired_headset = 0
 					wired_headphone = 1
@@ -134,13 +282,31 @@
 					hdmi = 0
 
 			conf: Line
+				ANY
+					#
+					# accessibility falls through Phone strategy if in call
+					# but Line has a lower priority than WiredHeadset in this case.
+					#
+					ALL
+						ANY
+							TelephonyMode Is InCall
+							TelephonyMode Is InCommunication
+						ForceUseForCommunication IsNot ForceSpeaker
+						AvailableOutputDevices Excludes WiredHeadset
+					#
+					# accessibility follows Media strategy if not in call
+					#
 				AvailableOutputDevices Includes Line
 
 				component: /Policy/policy/strategies/accessibility/selected_output_devices/mask
 					remote_submix = 0
+					earpiece = 0
 					bluetooth_a2dp = 0
 					bluetooth_a2dp_headphones = 0
 					bluetooth_a2dp_speaker = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_sco = 0
 					speaker = 0
 					wired_headset = 0
 					wired_headphone = 0
@@ -152,13 +318,32 @@
 					hdmi = 0
 
 			conf: WiredHeadset
+				ANY
+					#
+					# accessibility falls through Phone strategy if in call
+					#
+					ALL
+						ANY
+							TelephonyMode Is InCall
+							TelephonyMode Is InCommunication
+						ForceUseForCommunication IsNot ForceSpeaker
+					#
+					# accessibility follows Media strategy if not in call
+					#
+					ALL
+						TelephonyMode IsNot InCall
+						TelephonyMode IsNot InCommunication
 				AvailableOutputDevices Includes WiredHeadset
 
 				component: /Policy/policy/strategies/accessibility/selected_output_devices/mask
 					remote_submix = 0
+					earpiece = 0
 					bluetooth_a2dp = 0
 					bluetooth_a2dp_headphones = 0
 					bluetooth_a2dp_speaker = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_sco = 0
 					speaker = 0
 					wired_headset = 1
 					wired_headphone = 0
@@ -169,32 +354,36 @@
 					usb_device = 0
 					hdmi = 0
 
-			conf: UsbAccessory
-				AvailableOutputDevices Includes UsbAccessory
-
-				component: /Policy/policy/strategies/accessibility/selected_output_devices/mask
-					remote_submix = 0
-					bluetooth_a2dp = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					speaker = 0
-					wired_headset = 0
-					wired_headphone = 0
-					line = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 1
-					usb_device = 0
-					hdmi = 0
-
 			conf: UsbDevice
+				ANY
+					#
+					# accessibility falls through Phone strategy if in call (widely speaking)
+					#
+					ALL
+						ANY
+							TelephonyMode Is InCall
+							TelephonyMode Is InCommunication
+						ForceUseForCommunication IsNot ForceSpeaker
+					#
+					# accessibility follows Media strategy if not in call
+					# Media strategy inverts the priority of USB device vs accessory
+					#
+					ALL
+						TelephonyMode IsNot InCall
+						TelephonyMode IsNot InCommunication
+						AvailableOutputDevices Excludes UsbAccessory
+						ForceUseForCommunication Is ForceSpeaker
 				AvailableOutputDevices Includes UsbDevice
 
 				component: /Policy/policy/strategies/accessibility/selected_output_devices/mask
 					remote_submix = 0
+					earpiece = 0
 					bluetooth_a2dp = 0
 					bluetooth_a2dp_headphones = 0
 					bluetooth_a2dp_speaker = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_sco = 0
 					speaker = 0
 					wired_headset = 0
 					wired_headphone = 0
@@ -205,14 +394,57 @@
 					usb_device = 1
 					hdmi = 0
 
+			conf: UsbAccessory
+				#
+				# accessibility falls through Phone strategy if in call (widely speaking)
+				# but USB accessory not reachable in call
+				#
+				# accessibility follows Media strategy if not in call
+				# Media strategy inverts the priority of USB device vs accessory
+				#
+				TelephonyMode IsNot InCall
+				TelephonyMode IsNot InCommunication
+				AvailableOutputDevices Includes UsbAccessory
+
+				component: /Policy/policy/strategies/accessibility/selected_output_devices/mask
+					remote_submix = 0
+					earpiece = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_sco = 0
+					speaker = 0
+					wired_headset = 0
+					wired_headphone = 0
+					line = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 1
+					usb_device = 0
+					hdmi = 0
+
 			conf: DgtlDockHeadset
+				#
+				# accessibility falls through Phone strategy if in call (widely speaking)
+				# but DgtlDockHeadset not reachable in call
+				#
+				# accessibility follows Media strategy if not in call
+				#
+				TelephonyMode IsNot InCall
+				TelephonyMode IsNot InCommunication
 				AvailableOutputDevices Includes DgtlDockHeadset
 
 				component: /Policy/policy/strategies/accessibility/selected_output_devices/mask
 					remote_submix = 0
+					earpiece = 0
 					bluetooth_a2dp = 0
 					bluetooth_a2dp_headphones = 0
 					bluetooth_a2dp_speaker = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_sco = 0
 					speaker = 0
 					wired_headset = 0
 					wired_headphone = 0
@@ -225,19 +457,24 @@
 
 			conf: AuxDigital
 				#
-				# Do not route accessibility prompts to a digital output currently configured with a
-				# compressed format as they would likely not be mixed and dropped.
+				# accessibility falls through Phone strategy if in call (widely speaking)
+				# but Hdmi not reachable in call
 				#
-				# @TODO How to translate the following condition(???)
-				# desc->isActive() && !audio_is_linear_pcm(desc->mFormat) && devices != AUDIO_DEVICE_NONE
+				# accessibility follows Media strategy if not in call
 				#
+				TelephonyMode IsNot InCall
+				TelephonyMode IsNot InCommunication
 				AvailableOutputDevices Includes Hdmi
 
 				component: /Policy/policy/strategies/accessibility/selected_output_devices/mask
 					remote_submix = 0
+					earpiece = 0
 					bluetooth_a2dp = 0
 					bluetooth_a2dp_headphones = 0
 					bluetooth_a2dp_speaker = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_sco = 0
 					speaker = 0
 					wired_headset = 0
 					wired_headphone = 0
@@ -249,14 +486,27 @@
 					hdmi = 1
 
 			conf: AnlgDockHeadset
+				#
+				# accessibility falls through Phone strategy if in call (widely speaking)
+				# but AnlgDockHeadset not reachable in call
+				#
+				# accessibility follows Media strategy if not in call
+				# Media strategy inverts the priority of USB device vs accessory
+				#
+				TelephonyMode IsNot InCall
+				TelephonyMode IsNot InCommunication
 				AvailableOutputDevices Includes AnlgDockHeadset
 				ForceUseForDock Is ForceAnalogDock
 
 				component: /Policy/policy/strategies/accessibility/selected_output_devices/mask
 					remote_submix = 0
+					earpiece = 0
 					bluetooth_a2dp = 0
 					bluetooth_a2dp_headphones = 0
 					bluetooth_a2dp_speaker = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_sco = 0
 					speaker = 0
 					wired_headset = 0
 					wired_headphone = 0
@@ -267,14 +517,47 @@
 					usb_device = 0
 					hdmi = 0
 
+			conf: Earpiece
+				#
+				# accessibility falls through Phone strategy if in call
+				#
+				ANY
+					TelephonyMode Is InCall
+					TelephonyMode Is InCommunication
+				AvailableOutputDevices Includes Earpiece
+				ForceUseForCommunication IsNot ForceSpeaker
+
+				component: /Policy/policy/strategies/accessibility/selected_output_devices/mask
+					remote_submix = 0
+					earpiece = 1
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_sco = 0
+					speaker = 0
+					wired_headset = 0
+					wired_headphone = 0
+					line = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					hdmi = 0
+
 			conf: Speaker
 				AvailableOutputDevices Includes Speaker
 
 				component: /Policy/policy/strategies/accessibility/selected_output_devices/mask
 					remote_submix = 0
+					earpiece = 0
 					bluetooth_a2dp = 0
 					bluetooth_a2dp_headphones = 0
 					bluetooth_a2dp_speaker = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_sco = 0
 					speaker = 1
 					wired_headset = 0
 					wired_headphone = 0
@@ -288,9 +571,13 @@
 			conf: Default
 				component: /Policy/policy/strategies/accessibility/selected_output_devices/mask
 					remote_submix = 0
+					earpiece = 0
 					bluetooth_a2dp = 0
 					bluetooth_a2dp_headphones = 0
 					bluetooth_a2dp_speaker = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_sco = 0
 					speaker = 0
 					wired_headset = 0
 					wired_headphone = 0
@@ -300,3 +587,4 @@
 					usb_accessory = 0
 					usb_device = 0
 					hdmi = 0
+
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/example/Settings/device_for_strategy_dtmf.pfw b/services/audiopolicy/engineconfigurable/parameter-framework/example/Settings/device_for_strategy_dtmf.pfw
index d8b5b9d..d9469c0 100644
--- a/services/audiopolicy/engineconfigurable/parameter-framework/example/Settings/device_for_strategy_dtmf.pfw
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/example/Settings/device_for_strategy_dtmf.pfw
@@ -245,12 +245,24 @@
 					line = 0
 					speaker = 0
 
-			conf: LineWhenFollowingMedia
-				#
-				# DTMF follows Media strategy if not in call
-				#
-				TelephonyMode IsNot InCall
-				TelephonyMode IsNot InCommunication
+			conf: Line
+				ANY
+					#
+					# DTMF falls through Phone strategy if in call
+					# but Line has a lower priority than WiredHeadset in this case.
+					#
+					ALL
+						ANY
+							TelephonyMode Is InCall
+							TelephonyMode Is InCommunication
+						ForceUseForCommunication IsNot ForceSpeaker
+						AvailableOutputDevices Excludes WiredHeadset
+					#
+					# DTMF follows Media strategy if not in call
+					#
+					ALL
+						TelephonyMode IsNot InCall
+						TelephonyMode IsNot InCommunication
 				AvailableOutputDevices Includes Line
 
 				component: /Policy/policy/strategies/dtmf/selected_output_devices/mask
@@ -501,35 +513,6 @@
 					line = 0
 					speaker = 0
 
-			conf: LineWhenFallThroughPhone
-				#
-				# DTMF falls through Phone strategy if in call
-				#
-				ANY
-					TelephonyMode Is InCall
-					TelephonyMode Is InCommunication
-				AvailableOutputDevices Includes Line
-				ForceUseForCommunication Is ForceSpeaker
-
-				component: /Policy/policy/strategies/dtmf/selected_output_devices/mask
-					remote_submix = 0
-					earpiece = 0
-					wired_headset = 0
-					wired_headphone = 0
-					bluetooth_sco = 0
-					bluetooth_sco_headset = 0
-					bluetooth_a2dp = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					hdmi = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 0
-					telephony_tx = 0
-					line = 1
-					speaker = 0
-
 			conf: Speaker
 				ANY
 					#
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/example/Settings/device_for_strategy_phone.pfw b/services/audiopolicy/engineconfigurable/parameter-framework/example/Settings/device_for_strategy_phone.pfw
index ae70914..0dad830 100644
--- a/services/audiopolicy/engineconfigurable/parameter-framework/example/Settings/device_for_strategy_phone.pfw
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/example/Settings/device_for_strategy_phone.pfw
@@ -227,6 +227,29 @@
 					line = 0
 					speaker = 0
 
+			conf: Line
+				AvailableOutputDevices Includes Line
+				ForceUseForCommunication IsNot ForceSpeaker
+
+				component: /Policy/policy/strategies/phone/selected_output_devices/mask
+					earpiece = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					hdmi = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					telephony_tx = 0
+					line = 1
+					speaker = 0
+
 			conf: UsbDevice
 				#
 				# Fallback BT Sco devices in case of FORCE_BT_SCO
@@ -404,33 +427,6 @@
 					line = 0
 					speaker = 0
 
-			conf: Line
-				#
-				# Fallback BT Sco devices in case of FORCE_BT_SCO
-				# or FORCE_NONE
-				#
-				AvailableOutputDevices Includes Line
-				ForceUseForCommunication Is ForceSpeaker
-
-				component: /Policy/policy/strategies/phone/selected_output_devices/mask
-					earpiece = 0
-					wired_headset = 0
-					wired_headphone = 0
-					bluetooth_sco = 0
-					bluetooth_sco_headset = 0
-					bluetooth_sco_carkit = 0
-					bluetooth_a2dp = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					hdmi = 0
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 0
-					telephony_tx = 0
-					line = 1
-					speaker = 0
-
 			conf: Speaker
 				#
 				# Fallback BT Sco devices in case of FORCE_BT_SCO
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/example/Settings/device_for_strategy_sonification.pfw b/services/audiopolicy/engineconfigurable/parameter-framework/example/Settings/device_for_strategy_sonification.pfw
index 71101f8..96723f6 100644
--- a/services/audiopolicy/engineconfigurable/parameter-framework/example/Settings/device_for_strategy_sonification.pfw
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/example/Settings/device_for_strategy_sonification.pfw
@@ -247,12 +247,14 @@
 				ANY
 					#
 					# Sonification follows Phone strategy if in call (widely speaking)
+					# but Line has a lower priority than WiredHeadset in this case.
 					#
 					ALL
 						ANY
 							TelephonyMode Is InCall
 							TelephonyMode Is InCommunication
-						ForceUseForCommunication Is ForceSpeaker
+						ForceUseForCommunication IsNot ForceSpeaker
+						AvailableOutputDevices Excludes WiredHeadset
 					#
 					# Sonification falls through media strategy if not in call (widely speaking)
 					#
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/example/Settings/device_for_strategy_sonification_respectful.pfw b/services/audiopolicy/engineconfigurable/parameter-framework/example/Settings/device_for_strategy_sonification_respectful.pfw
index f66674c..7626944 100644
--- a/services/audiopolicy/engineconfigurable/parameter-framework/example/Settings/device_for_strategy_sonification_respectful.pfw
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/example/Settings/device_for_strategy_sonification_respectful.pfw
@@ -267,15 +267,29 @@
 					usb_device = 0
 					hdmi = 0
 
-			conf: LineWhenFollowMediaStrategy
-				#
-				# SonificationRespectful Follows Sonification that falls through Media strategy if not in call
-				# SonificationRespectful follows media if music stream is active
-				#
-				TelephonyMode IsNot InCall
-				TelephonyMode IsNot InCommunication
-				AvailableOutputDevices Includes WiredHeadphone
-				ForceUseForMedia IsNot ForceSpeaker
+			conf: Line
+				ANY
+					#
+					# SonificationRespectful Follows Phone strategy if in call
+					# but Line has a lower priority than WiredHeadset in this case.
+					#
+					#
+					ALL
+						ANY
+							TelephonyMode Is InCall
+							TelephonyMode Is InCommunication
+						ForceUseForCommunication IsNot ForceSpeaker
+						AvailableOutputDevices Excludes WiredHeadset
+					#
+					# SonificationRespectful Follows Sonification that falls through Media strategy if not in call
+					# SonificationRespectful follows media if music stream is active
+					#
+					ALL
+						TelephonyMode IsNot InCall
+						TelephonyMode IsNot InCommunication
+						AvailableOutputDevices Includes WiredHeadphone
+						ForceUseForMedia IsNot ForceSpeaker
+				AvailableOutputDevices Includes Line
 
 				component: /Policy/policy/strategies/sonification_respectful/selected_output_devices/mask
 					earpiece = 0
@@ -517,29 +531,3 @@
 					usb_device = 0
 					hdmi = 0
 
-			conf: Line
-				#
-				# SonificationRespectful Follows Phone strategy if in call
-				#
-				ANY
-					TelephonyMode Is InCall
-					TelephonyMode Is InCommunication
-				ForceUseForCommunication Is ForceSpeaker
-				AvailableOutputDevices Includes Line
-
-				component: /Policy/policy/strategies/sonification_respectful/selected_output_devices/mask
-					earpiece = 0
-					bluetooth_sco = 0
-					bluetooth_sco_headset = 0
-					bluetooth_sco_carkit = 0
-					bluetooth_a2dp_headphones = 0
-					bluetooth_a2dp_speaker = 0
-					bluetooth_a2dp = 0
-					wired_headset = 0
-					wired_headphone = 0
-					line = 1
-					angl_dock_headset = 0
-					dgtl_dock_headset = 0
-					usb_accessory = 0
-					usb_device = 0
-					hdmi = 0
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/example/policy_criteria.txt b/services/audiopolicy/engineconfigurable/parameter-framework/example/policy_criteria.txt
index ef06498..28a7ef1 100755
--- a/services/audiopolicy/engineconfigurable/parameter-framework/example/policy_criteria.txt
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/example/policy_criteria.txt
@@ -7,3 +7,4 @@
 ExclusiveCriterion ForceUseForDock              :   ForceNone       ForceWiredAccessory     ForceBtCarDock      ForceBtDeskDock     ForceAnalogDock ForceDigitalDock
 ExclusiveCriterion ForceUseForSystem            :   ForceNone       ForceSystemEnforced
 ExclusiveCriterion ForceUseForHdmiSystemAudio   :   ForceNone       ForceHdmiSystemEnforced
+ExclusiveCriterion ForceUseForEncodedSurround   :   ForceNone       ForceEncodedSurroundNever   ForceEncodedSurroundAlways
diff --git a/services/audiopolicy/engineconfigurable/src/Engine.cpp b/services/audiopolicy/engineconfigurable/src/Engine.cpp
index 7f8ed1f..0d18ffa 100755
--- a/services/audiopolicy/engineconfigurable/src/Engine.cpp
+++ b/services/audiopolicy/engineconfigurable/src/Engine.cpp
@@ -140,15 +140,6 @@
 
 routing_strategy Engine::ManagerInterfaceImpl::getStrategyForUsage(audio_usage_t usage)
 {
-    const SwAudioOutputCollection &outputs = mPolicyEngine->mApmObserver->getOutputs();
-
-    //FIXME: getStrategyForUsage() should return STRATEGY_ACCESSIBILITY and getDeviceForStrategy()
-    // should be implemented accordingly for STRATEGY_ACCESSIBILITY
-    if (usage == AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY &&
-            (outputs.isStreamActive(AUDIO_STREAM_RING) ||
-             outputs.isStreamActive(AUDIO_STREAM_ALARM))) {
-        return STRATEGY_SONIFICATION;
-    }
     return mPolicyEngine->getPropertyForKey<routing_strategy, audio_usage_t>(usage);
 }
 
@@ -173,6 +164,14 @@
             outputs.isStreamActive(AUDIO_STREAM_MUSIC, SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY)) {
         return mPolicyEngine->getPropertyForKey<audio_devices_t, routing_strategy>(STRATEGY_MEDIA);
     }
+    if (strategy == STRATEGY_ACCESSIBILITY &&
+        (outputs.isStreamActive(AUDIO_STREAM_RING) || outputs.isStreamActive(AUDIO_STREAM_ALARM))) {
+            // do not route accessibility prompts to a digital output currently configured with a
+            // compressed format as they would likely not be mixed and dropped.
+            // Device For Sonification conf file has HDMI, SPDIF and HDMI ARC unreacheable.
+        return mPolicyEngine->getPropertyForKey<audio_devices_t, routing_strategy>(
+                    STRATEGY_SONIFICATION);
+    }
     return mPolicyEngine->getPropertyForKey<audio_devices_t, routing_strategy>(strategy);
 }
 
diff --git a/services/audiopolicy/engineconfigurable/wrapper/audio_policy_criteria_conf.h b/services/audiopolicy/engineconfigurable/wrapper/audio_policy_criteria_conf.h
index 58e7135..31b7e0f 100755
--- a/services/audiopolicy/engineconfigurable/wrapper/audio_policy_criteria_conf.h
+++ b/services/audiopolicy/engineconfigurable/wrapper/audio_policy_criteria_conf.h
@@ -61,7 +61,8 @@
     [AUDIO_POLICY_FORCE_FOR_RECORD] =               "ForceUseForRecord",
     [AUDIO_POLICY_FORCE_FOR_DOCK] =                 "ForceUseForDock",
     [AUDIO_POLICY_FORCE_FOR_SYSTEM] =               "ForceUseForSystem",
-    [AUDIO_POLICY_FORCE_FOR_HDMI_SYSTEM_AUDIO] =    "ForceUseForHdmiSystemAudio"
+    [AUDIO_POLICY_FORCE_FOR_HDMI_SYSTEM_AUDIO] =    "ForceUseForHdmiSystemAudio",
+    [AUDIO_POLICY_FORCE_FOR_ENCODED_SURROUND] =     "ForceUseForEncodedSurround"
 };
 
 
diff --git a/services/audiopolicy/engineconfigurable/wrapper/config/audio_policy_criteria.conf b/services/audiopolicy/engineconfigurable/wrapper/config/audio_policy_criteria.conf
index 5b046a8..043d5a6 100755
--- a/services/audiopolicy/engineconfigurable/wrapper/config/audio_policy_criteria.conf
+++ b/services/audiopolicy/engineconfigurable/wrapper/config/audio_policy_criteria.conf
@@ -93,6 +93,11 @@
         # audio_policy_forced_config_t from system/audio.h
         #
         ForceUseForHdmiSystemAudioType  0:ForceNone,12:ForceHdmiSystemEnforced
+        #
+        # The values of the mode MUST be aligned with the definition of the
+        # audio_policy_forced_config_t from system/audio_policy.h
+        #
+        ForceUseForEncodedSurroundType  0:ForceNone,13:ForceEncodedSurroundNever,14:ForceEncodedSurroundAlways
     }
 
     Criterion {
@@ -132,6 +137,10 @@
             Type            ForceUseForHdmiSystemAudioType
             Default         ForceNone
         }
+        ForceUseForEncodedSurround {
+            Type            ForceUseForEncodedSurroundType
+            Default         ForceNone
+        }
     }
 }
 
diff --git a/services/audiopolicy/enginedefault/src/Engine.cpp b/services/audiopolicy/enginedefault/src/Engine.cpp
index f2224fd..d31429c 100755
--- a/services/audiopolicy/enginedefault/src/Engine.cpp
+++ b/services/audiopolicy/enginedefault/src/Engine.cpp
@@ -254,10 +254,6 @@
 
     case STRATEGY_TRANSMITTED_THROUGH_SPEAKER:
         device = availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER;
-        if (!device) {
-            ALOGE("getDeviceForStrategy() no device found for "\
-                    "STRATEGY_TRANSMITTED_THROUGH_SPEAKER");
-        }
         break;
 
     case STRATEGY_SONIFICATION_RESPECTFUL:
@@ -373,11 +369,6 @@
                 if (device) break;
             }
             device = availableOutputDevicesType & AUDIO_DEVICE_OUT_EARPIECE;
-            if (device) break;
-            device = mApmObserver->getDefaultOutputDevice()->type();
-            if (device == AUDIO_DEVICE_NONE) {
-                ALOGE("getDeviceForStrategy() no device found for STRATEGY_PHONE");
-            }
             break;
 
         case AUDIO_POLICY_FORCE_SPEAKER:
@@ -402,11 +393,6 @@
                 if (device) break;
             }
             device = availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER;
-            if (device) break;
-            device = mApmObserver->getDefaultOutputDevice()->type();
-            if (device == AUDIO_DEVICE_NONE) {
-                ALOGE("getDeviceForStrategy() no device found for STRATEGY_PHONE, FORCE_SPEAKER");
-            }
             break;
         }
     break;
@@ -431,9 +417,6 @@
         if ((strategy == STRATEGY_SONIFICATION) ||
                 (mForceUse[AUDIO_POLICY_FORCE_FOR_SYSTEM] == AUDIO_POLICY_FORCE_SYSTEM_ENFORCED)) {
             device = availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER;
-            if (device == AUDIO_DEVICE_NONE) {
-                ALOGE("getDeviceForStrategy() speaker device not found for STRATEGY_SONIFICATION");
-            }
         }
         // The second device used for sonification is the same as the device used by media strategy
         // FALL THROUGH
@@ -545,12 +528,6 @@
                 AUDIO_POLICY_FORCE_HDMI_SYSTEM_AUDIO_ENFORCED)) {
             device &= ~AUDIO_DEVICE_OUT_SPEAKER;
         }
-
-        if (device) break;
-        device = mApmObserver->getDefaultOutputDevice()->type();
-        if (device == AUDIO_DEVICE_NONE) {
-            ALOGE("getDeviceForStrategy() no device found for STRATEGY_MEDIA");
-        }
         } break;
 
     default:
@@ -558,6 +535,12 @@
         break;
     }
 
+    if (device == AUDIO_DEVICE_NONE) {
+        ALOGV("getDeviceForStrategy() no device found for strategy %d", strategy);
+        device = mApmObserver->getDefaultOutputDevice()->type();
+        ALOGE_IF(device == AUDIO_DEVICE_NONE,
+                 "getDeviceForStrategy() no default device defined");
+    }
     ALOGVV("getDeviceForStrategy() strategy %d, device %x", strategy, device);
     return device;
 }
@@ -677,6 +660,14 @@
         ALOGW("getDeviceForInputSource() invalid input source %d", inputSource);
         break;
     }
+    if (device == AUDIO_DEVICE_NONE) {
+        ALOGV("getDeviceForInputSource() no device found for source %d", inputSource);
+        if (availableDeviceTypes & AUDIO_DEVICE_IN_STUB) {
+            device = AUDIO_DEVICE_IN_STUB;
+        }
+        ALOGE_IF(device == AUDIO_DEVICE_NONE,
+                 "getDeviceForInputSource() no default device defined");
+    }
     ALOGV("getDeviceForInputSource()input source %d, device %08x", inputSource, device);
     return device;
 }
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index 35c868e..21ce8c9 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -291,7 +291,15 @@
 audio_policy_dev_state_t AudioPolicyManager::getDeviceConnectionState(audio_devices_t device,
                                                                       const char *device_address)
 {
-    sp<DeviceDescriptor> devDesc = mHwModules.getDeviceDescriptor(device, device_address, "");
+    sp<DeviceDescriptor> devDesc =
+            mHwModules.getDeviceDescriptor(device, device_address, "",
+                                           (strlen(device_address) != 0)/*matchAddress*/);
+
+    if (devDesc == 0) {
+        ALOGW("getDeviceConnectionState() undeclared device, type %08x, address: %s",
+              device, device_address);
+        return AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE;
+    }
 
     DeviceVector *deviceVector;
 
@@ -303,15 +311,14 @@
         ALOGW("getDeviceConnectionState() invalid device type %08x", device);
         return AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE;
     }
-    return deviceVector->getDeviceConnectionState(devDesc);
+
+    return (deviceVector->getDevice(device, String8(device_address)) != 0) ?
+            AUDIO_POLICY_DEVICE_STATE_AVAILABLE : AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE;
 }
 
 void AudioPolicyManager::updateCallRouting(audio_devices_t rxDevice, int delayMs)
 {
     bool createTxPatch = false;
-    struct audio_patch patch;
-    patch.num_sources = 1;
-    patch.num_sinks = 1;
     status_t status;
     audio_patch_handle_t afPatchHandle;
     DeviceVector deviceList;
@@ -344,8 +351,11 @@
                 == AUDIO_DEVICE_NONE) {
             createTxPatch = true;
         }
-    } else {
-        // create RX path audio patch
+    } else { // create RX path audio patch
+        struct audio_patch patch;
+
+        patch.num_sources = 1;
+        patch.num_sinks = 1;
         deviceList = mAvailableOutputDevices.getDevicesFromType(rxDevice);
         ALOG_ASSERT(!deviceList.isEmpty(),
                     "updateCallRouting() selected device not in output device list");
@@ -384,9 +394,9 @@
         }
         createTxPatch = true;
     }
-    if (createTxPatch) {
-
+    if (createTxPatch) { // create TX path audio patch
         struct audio_patch patch;
+
         patch.num_sources = 1;
         patch.num_sinks = 1;
         deviceList = mAvailableInputDevices.getDevicesFromType(txDevice);
@@ -1080,8 +1090,16 @@
     mOutputRoutes.incRouteActivity(session);
 
     audio_devices_t newDevice;
+    AudioMix *policyMix = NULL;
+    const char *address = NULL;
     if (outputDesc->mPolicyMix != NULL) {
-        newDevice = AUDIO_DEVICE_OUT_REMOTE_SUBMIX;
+        policyMix = outputDesc->mPolicyMix;
+        address = policyMix->mDeviceAddress.string();
+        if ((policyMix->mRouteFlags & MIX_ROUTE_FLAG_RENDER) == MIX_ROUTE_FLAG_RENDER) {
+            newDevice = policyMix->mDeviceType;
+        } else {
+            newDevice = AUDIO_DEVICE_OUT_REMOTE_SUBMIX;
+        }
     } else if (mOutputRoutes.hasRouteChanged(session)) {
         newDevice = getNewOutputDevice(outputDesc, false /*fromCache*/);
         checkStrategyRoute(getStrategy(stream), output);
@@ -1091,7 +1109,7 @@
 
     uint32_t delayMs = 0;
 
-    status_t status = startSource(outputDesc, stream, newDevice, &delayMs);
+    status_t status = startSource(outputDesc, stream, newDevice, address, &delayMs);
 
     if (status != NO_ERROR) {
         mOutputRoutes.decRouteActivity(session);
@@ -1099,11 +1117,11 @@
     }
     // Automatically enable the remote submix input when output is started on a re routing mix
     // of type MIX_TYPE_RECORDERS
-    if (audio_is_remote_submix_device(newDevice) && outputDesc->mPolicyMix != NULL &&
-            outputDesc->mPolicyMix->mMixType == MIX_TYPE_RECORDERS) {
+    if (audio_is_remote_submix_device(newDevice) && policyMix != NULL &&
+            policyMix->mMixType == MIX_TYPE_RECORDERS) {
             setDeviceConnectionStateInt(AUDIO_DEVICE_IN_REMOTE_SUBMIX,
                     AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
-                    outputDesc->mPolicyMix->mDeviceAddress,
+                    address,
                     "remote-submix");
     }
 
@@ -1117,6 +1135,7 @@
 status_t AudioPolicyManager::startSource(sp<AudioOutputDescriptor> outputDesc,
                                              audio_stream_type_t stream,
                                              audio_devices_t device,
+                                             const char *address,
                                              uint32_t *delayMs)
 {
     // cannot start playback of STREAM_TTS if any other output is being used
@@ -1173,7 +1192,7 @@
                 }
             }
         }
-        uint32_t muteWaitMs = setOutputDevice(outputDesc, device, force);
+        uint32_t muteWaitMs = setOutputDevice(outputDesc, device, force, 0, NULL, address);
 
         // handle special case for sonification while in call
         if (isInCall()) {
@@ -1821,15 +1840,9 @@
     // Force max volume if stream cannot be muted
     if (!mVolumeCurves->canBeMuted(stream)) index = mVolumeCurves->getVolumeIndexMax(stream);
 
-    ALOGV("setStreamVolumeIndex() stream %d, device %04x, index %d",
+    ALOGV("setStreamVolumeIndex() stream %d, device %08x, index %d",
           stream, device, index);
 
-    // if device is AUDIO_DEVICE_OUT_DEFAULT set default value and
-    // clear all device specific values
-    if (device == AUDIO_DEVICE_OUT_DEFAULT) {
-        mVolumeCurves->clearCurrentVolumeIndex(stream);
-    }
-
     // update other private stream volumes which follow this one
     for (int curStream = 0; curStream < AUDIO_STREAM_FOR_POLICY_CNT; curStream++) {
         if (!streamsMatchForvolume(stream, (audio_stream_type_t)curStream)) {
@@ -1838,8 +1851,14 @@
         mVolumeCurves->addCurrentVolumeIndex((audio_stream_type_t)curStream, device, index);
     }
 
-    // update volume on all outputs whose current device is also selected by the same
-    // strategy as the device specified by the caller
+    // update volume on all outputs and streams matching the following:
+    // - The requested stream (or a stream matching for volume control) is active on the output
+    // - The device (or devices) selected by the strategy corresponding to this stream includes
+    // the requested device
+    // - For non default requested device, currently selected device on the output is either the
+    // requested device or one of the devices selected by the strategy
+    // - For default requested device (AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME), apply volume only if
+    // no specific device volume value exists for currently selected device.
     status_t status = NO_ERROR;
     for (size_t i = 0; i < mOutputs.size(); i++) {
         sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
@@ -1848,16 +1867,24 @@
             if (!streamsMatchForvolume(stream, (audio_stream_type_t)curStream)) {
                 continue;
             }
+            if (!(desc->isStreamActive((audio_stream_type_t)curStream) ||
+                    (isInCall() && (curStream == AUDIO_STREAM_VOICE_CALL)))) {
+                continue;
+            }
             routing_strategy curStrategy = getStrategy((audio_stream_type_t)curStream);
             audio_devices_t curStreamDevice = getDeviceForStrategy(curStrategy, true /*fromCache*/);
-            // it is possible that the requested device is not selected by the strategy
-            // (e.g an explicit audio patch is active causing getDevicesForStream()
-            // to return this device. We must make sure that the device passed is part of the
-            // devices considered when applying volume below.
-            curStreamDevice |= device;
+            if ((curStreamDevice & device) == 0) {
+                continue;
+            }
+            bool applyDefault = false;
+            if (device != AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME) {
+                curStreamDevice |= device;
+            } else if (!mVolumeCurves->hasVolumeIndexForDevice(
+                    stream, Volume::getDeviceForVolume(curStreamDevice))) {
+                applyDefault = true;
+            }
 
-            if (((device == AUDIO_DEVICE_OUT_DEFAULT) ||
-                    ((curDevice & curStreamDevice) != 0))) {
+            if (applyDefault || ((curDevice & curStreamDevice) != 0)) {
                 status_t volStatus =
                         checkAndSetVolume((audio_stream_type_t)curStream, index, desc, curDevice);
                 if (volStatus != NO_ERROR) {
@@ -1879,9 +1906,9 @@
     if (!audio_is_output_device(device)) {
         return BAD_VALUE;
     }
-    // if device is AUDIO_DEVICE_OUT_DEFAULT, return volume for device corresponding to
+    // if device is AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME, return volume for device corresponding to
     // the strategy the stream belongs to.
-    if (device == AUDIO_DEVICE_OUT_DEFAULT) {
+    if (device == AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME) {
         device = getDeviceForStrategy(getStrategy(stream), true /*fromCache*/);
     }
     device = Volume::getDeviceForVolume(device);
@@ -2090,7 +2117,6 @@
                         && (patch->mPatch.sinks[0].ext.device.type == device)
                         && (strncmp(patch->mPatch.sinks[0].ext.device.address, address.string(),
                                 AUDIO_DEVICE_MAX_ADDRESS_LEN) == 0)) {
-
                     if (mPolicyMixes.registerMix(address, mixes[i], desc) != NO_ERROR) {
                         res = INVALID_OPERATION;
                     } else {
@@ -2316,19 +2342,29 @@
     size_t portsMax = *num_ports;
     *num_ports = 0;
     if (type == AUDIO_PORT_TYPE_NONE || type == AUDIO_PORT_TYPE_DEVICE) {
+        // do not report devices with type AUDIO_DEVICE_IN_STUB or AUDIO_DEVICE_OUT_STUB
+        // as they are used by stub HALs by convention
         if (role == AUDIO_PORT_ROLE_SINK || role == AUDIO_PORT_ROLE_NONE) {
-            for (size_t i = 0;
-                    i  < mAvailableOutputDevices.size() && portsWritten < portsMax; i++) {
-                mAvailableOutputDevices[i]->toAudioPort(&ports[portsWritten++]);
+            for (size_t i = 0; i < mAvailableOutputDevices.size(); i++) {
+                if (mAvailableOutputDevices[i]->type() == AUDIO_DEVICE_OUT_STUB) {
+                    continue;
+                }
+                if (portsWritten < portsMax) {
+                    mAvailableOutputDevices[i]->toAudioPort(&ports[portsWritten++]);
+                }
+                (*num_ports)++;
             }
-            *num_ports += mAvailableOutputDevices.size();
         }
         if (role == AUDIO_PORT_ROLE_SOURCE || role == AUDIO_PORT_ROLE_NONE) {
-            for (size_t i = 0;
-                    i  < mAvailableInputDevices.size() && portsWritten < portsMax; i++) {
-                mAvailableInputDevices[i]->toAudioPort(&ports[portsWritten++]);
+            for (size_t i = 0; i < mAvailableInputDevices.size(); i++) {
+                if (mAvailableInputDevices[i]->type() == AUDIO_DEVICE_IN_STUB) {
+                    continue;
+                }
+                if (portsWritten < portsMax) {
+                    mAvailableInputDevices[i]->toAudioPort(&ports[portsWritten++]);
+                }
+                (*num_ports)++;
             }
-            *num_ports += mAvailableInputDevices.size();
         }
     }
     if (type == AUDIO_PORT_TYPE_NONE || type == AUDIO_PORT_TYPE_MIX) {
@@ -2969,7 +3005,7 @@
             return INVALID_OPERATION;
         }
         uint32_t delayMs = 0;
-        status = startSource(outputDesc, stream, sinkDevice, &delayMs);
+        status = startSource(outputDesc, stream, sinkDevice, NULL, &delayMs);
 
         if (status != NO_ERROR) {
             mpClientInterface->releaseAudioPatch(sourceDesc->mPatchDesc->mAfPatchHandle, 0);
@@ -3193,6 +3229,10 @@
             }
             sp<SwAudioOutputDescriptor> outputDesc = new SwAudioOutputDescriptor(outProfile,
                                                                                  mpClientInterface);
+            const DeviceVector &supportedDevices = outProfile->getSupportedDevices();
+            const DeviceVector &devicesForType = supportedDevices.getDevicesFromType(profileType);
+            String8 address = devicesForType.size() > 0 ? devicesForType.itemAt(0)->mAddress
+                    : String8("");
 
             outputDesc->mDevice = profileType;
             audio_config_t config = AUDIO_CONFIG_INITIALIZER;
@@ -3204,7 +3244,7 @@
                                                             &output,
                                                             &config,
                                                             &outputDesc->mDevice,
-                                                            String8(""),
+                                                            address,
                                                             &outputDesc->mLatency,
                                                             outputDesc->mFlags);
 
@@ -3217,7 +3257,6 @@
                 outputDesc->mChannelMask = config.channel_mask;
                 outputDesc->mFormat = config.format;
 
-                const DeviceVector &supportedDevices = outProfile->getSupportedDevices();
                 for (size_t k = 0; k  < supportedDevices.size(); k++) {
                     ssize_t index = mAvailableOutputDevices.indexOf(supportedDevices[k]);
                     // give a valid ID to an attached device once confirmed it is reachable
@@ -3232,7 +3271,10 @@
                 addOutput(output, outputDesc);
                 setOutputDevice(outputDesc,
                                 outputDesc->mDevice,
-                                true);
+                                true,
+                                0,
+                                NULL,
+                                address.string());
             }
         }
         // open input streams needed to access attached devices to validate
@@ -4607,9 +4649,13 @@
     if (device == AUDIO_DEVICE_NONE) {
         resetOutputDevice(outputDesc, delayMs, NULL);
     } else {
-        DeviceVector deviceList = (address == NULL) ?
-                mAvailableOutputDevices.getDevicesFromType(device)
-                : mAvailableOutputDevices.getDevicesFromTypeAddr(device, String8(address));
+        DeviceVector deviceList;
+        if ((address == NULL) || (strlen(address) == 0)) {
+            deviceList = mAvailableOutputDevices.getDevicesFromType(device);
+        } else {
+            deviceList = mAvailableOutputDevices.getDevicesFromTypeAddr(device, String8(address));
+        }
+
         if (!deviceList.isEmpty()) {
             struct audio_patch patch;
             outputDesc->toAudioPortConfig(&patch.sources[0]);
@@ -4855,7 +4901,9 @@
     float volumeDb = mVolumeCurves->volIndexToDb(stream, Volume::getDeviceCategory(device), index);
     // if a headset is connected, apply the following rules to ring tones and notifications
     // to avoid sound level bursts in user's ears:
-    // - always attenuate ring tones and notifications volume by 6dB
+    // - always attenuate notifications volume by 6dB
+    // - attenuate ring tones volume by 6dB unless music is not playing and
+    // speaker is part of the select devices
     // - if music is playing, always limit the volume to current music volume,
     // with a minimum threshold at -36dB so that notification is always perceived.
     const routing_strategy stream_strategy = getStrategy(stream);
@@ -4869,12 +4917,12 @@
                 || ((stream_strategy == STRATEGY_ENFORCED_AUDIBLE) &&
                     (mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM) == AUDIO_POLICY_FORCE_NONE))) &&
             mVolumeCurves->canBeMuted(stream)) {
-        volumeDb += SONIFICATION_HEADSET_VOLUME_FACTOR_DB;
         // when the phone is ringing we must consider that music could have been paused just before
         // by the music application and behave as if music was active if the last music track was
         // just stopped
         if (isStreamActive(AUDIO_STREAM_MUSIC, SONIFICATION_HEADSET_MUSIC_DELAY) ||
                 mLimitRingtoneVolume) {
+            volumeDb += SONIFICATION_HEADSET_VOLUME_FACTOR_DB;
             audio_devices_t musicDevice = getDeviceForStrategy(STRATEGY_MEDIA, true /*fromCache*/);
             float musicVolDB = computeVolume(AUDIO_STREAM_MUSIC,
                                              mVolumeCurves->getVolumeIndex(AUDIO_STREAM_MUSIC,
@@ -4886,6 +4934,9 @@
                 volumeDb = minVolDB;
                 ALOGV("computeVolume limiting volume to %f musicVol %f", minVolDB, musicVolDB);
             }
+        } else if ((Volume::getDeviceForVolume(device) != AUDIO_DEVICE_OUT_SPEAKER) ||
+                stream_strategy != STRATEGY_SONIFICATION) {
+            volumeDb += SONIFICATION_HEADSET_VOLUME_FACTOR_DB;
         }
     }
 
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.h b/services/audiopolicy/managerdefault/AudioPolicyManager.h
index 0420679..2d6a873 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.h
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.h
@@ -49,10 +49,8 @@
 // ----------------------------------------------------------------------------
 
 // Attenuation applied to STRATEGY_SONIFICATION streams when a headset is connected: 6dB
-#define SONIFICATION_HEADSET_VOLUME_FACTOR 0.5
 #define SONIFICATION_HEADSET_VOLUME_FACTOR_DB (-6)
 // Min volume for STRATEGY_SONIFICATION streams when limited by music volume: -36dB
-#define SONIFICATION_HEADSET_VOLUME_MIN  0.016
 #define SONIFICATION_HEADSET_VOLUME_MIN_DB  (-36)
 
 // Time in milliseconds during which we consider that music is still active after a music
@@ -484,6 +482,7 @@
         status_t startSource(sp<AudioOutputDescriptor> outputDesc,
                              audio_stream_type_t stream,
                              audio_devices_t device,
+                             const char *address,
                              uint32_t *delayMs);
         status_t stopSource(sp<AudioOutputDescriptor> outputDesc,
                             audio_stream_type_t stream,
diff --git a/services/camera/libcameraservice/Android.mk b/services/camera/libcameraservice/Android.mk
index c011613..ebe65e4 100644
--- a/services/camera/libcameraservice/Android.mk
+++ b/services/camera/libcameraservice/Android.mk
@@ -66,7 +66,8 @@
     libhardware \
     libsync \
     libcamera_metadata \
-    libjpeg
+    libjpeg \
+    libmemunreachable
 
 LOCAL_C_INCLUDES += \
     system/media/private/camera/include \
diff --git a/services/camera/libcameraservice/CameraFlashlight.cpp b/services/camera/libcameraservice/CameraFlashlight.cpp
index 0afd945..ad08a68 100644
--- a/services/camera/libcameraservice/CameraFlashlight.cpp
+++ b/services/camera/libcameraservice/CameraFlashlight.cpp
@@ -679,7 +679,8 @@
     status_t res;
     if (enabled) {
         bool hasFlash = false;
-        res = hasFlashUnitLocked(cameraId, &hasFlash);
+        // Check if it has a flash unit and leave camera device open.
+        res = hasFlashUnitLocked(cameraId, &hasFlash, /*keepDeviceOpen*/true);
         // invalid camera?
         if (res) {
             // hasFlashUnitLocked() returns BAD_INDEX if mDevice is connected to
@@ -688,6 +689,8 @@
         }
         // no flash unit?
         if (!hasFlash) {
+            // Disconnect camera device if it has no flash.
+            disconnectCameraDevice();
             return -ENOSYS;
         }
     } else if (mDevice == NULL || cameraId != mCameraId) {
@@ -716,21 +719,28 @@
 status_t CameraHardwareInterfaceFlashControl::hasFlashUnit(
         const String8& cameraId, bool *hasFlash) {
     Mutex::Autolock l(mLock);
-    return hasFlashUnitLocked(cameraId, hasFlash);
+    // Close device after checking if it has a flash unit.
+    return hasFlashUnitLocked(cameraId, hasFlash, /*keepDeviceOpen*/false);
 }
 
 status_t CameraHardwareInterfaceFlashControl::hasFlashUnitLocked(
-        const String8& cameraId, bool *hasFlash) {
+        const String8& cameraId, bool *hasFlash, bool keepDeviceOpen) {
+    bool closeCameraDevice = false;
+
     if (!hasFlash) {
         return BAD_VALUE;
     }
 
     status_t res;
     if (mDevice == NULL) {
+        // Connect to camera device to query if it has a flash unit.
         res = connectCameraDevice(cameraId);
         if (res) {
             return res;
         }
+        // Close camera device only when it is just opened and the caller doesn't want to keep
+        // the camera device open.
+        closeCameraDevice = !keepDeviceOpen;
     }
 
     if (cameraId != mCameraId) {
@@ -745,6 +755,15 @@
         *hasFlash = false;
     }
 
+    if (closeCameraDevice) {
+        res = disconnectCameraDevice();
+        if (res != OK) {
+            ALOGE("%s: Failed to disconnect camera device. %s (%d)", __FUNCTION__,
+                    strerror(-res), res);
+            return res;
+        }
+    }
+
     return OK;
 }
 
@@ -869,9 +888,13 @@
         return OK;
     }
 
-    mParameters.set(CameraParameters::KEY_FLASH_MODE,
-            CameraParameters::FLASH_MODE_OFF);
-    mDevice->setParameters(mParameters);
+    if (mParameters.get(CameraParameters::KEY_FLASH_MODE)) {
+        // There is a flash, turn if off.
+        // (If there isn't one, leave the parameter null)
+        mParameters.set(CameraParameters::KEY_FLASH_MODE,
+                CameraParameters::FLASH_MODE_OFF);
+        mDevice->setParameters(mParameters);
+    }
     mDevice->stopPreview();
     status_t res = native_window_api_disconnect(mSurface.get(),
             NATIVE_WINDOW_API_CAMERA);
diff --git a/services/camera/libcameraservice/CameraFlashlight.h b/services/camera/libcameraservice/CameraFlashlight.h
index 4d5fe8d..5cde372 100644
--- a/services/camera/libcameraservice/CameraFlashlight.h
+++ b/services/camera/libcameraservice/CameraFlashlight.h
@@ -203,7 +203,11 @@
         status_t getSmallestSurfaceSize(int32_t *width, int32_t *height);
 
         // protected by mLock
-        status_t hasFlashUnitLocked(const String8& cameraId, bool *hasFlash);
+        // If this function opens camera device in order to check if it has a flash unit, the
+        // camera device will remain open if keepDeviceOpen is true and the camera device will be
+        // closed if keepDeviceOpen is false. If camera device is already open when calling this
+        // function, keepDeviceOpen is ignored.
+        status_t hasFlashUnitLocked(const String8& cameraId, bool *hasFlash, bool keepDeviceOpen);
 
         CameraModule *mCameraModule;
         const camera_module_callbacks_t *mCallbacks;
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index 0c88dad..fcb72e8 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -41,6 +41,7 @@
 #include <cutils/properties.h>
 #include <gui/Surface.h>
 #include <hardware/hardware.h>
+#include <memunreachable/memunreachable.h>
 #include <media/AudioSystem.h>
 #include <media/IMediaHTTPService.h>
 #include <media/mediaplayer.h>
@@ -2595,16 +2596,32 @@
         write(fd, "\n", 1);
         camera3::CameraTraces::dump(fd, args);
 
-        // change logging level
+        // Process dump arguments, if any
         int n = args.size();
-        for (int i = 0; i + 1 < n; i++) {
-            String16 verboseOption("-v");
+        String16 verboseOption("-v");
+        String16 unreachableOption("--unreachable");
+        for (int i = 0; i < n; i++) {
             if (args[i] == verboseOption) {
+                // change logging level
+                if (i + 1 >= n) continue;
                 String8 levelStr(args[i+1]);
                 int level = atoi(levelStr.string());
                 result = String8::format("\nSetting log level to %d.\n", level);
                 setLogLevel(level);
                 write(fd, result.string(), result.size());
+            } else if (args[i] == unreachableOption) {
+                // Dump memory analysis
+                // TODO - should limit be an argument parameter?
+                UnreachableMemoryInfo info;
+                bool success = GetUnreachableMemory(info, /*limit*/ 10000);
+                if (!success) {
+                    dprintf(fd, "\nUnable to dump unreachable memory. "
+                            "Try disabling SELinux enforcement.\n");
+                } else {
+                    dprintf(fd, "\nDumping unreachable memory:\n");
+                    std::string s = info.ToString(/*log_contents*/ true);
+                    write(fd, s.c_str(), s.size());
+                }
             }
         }
     }
diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
index b6c9900..63e44fd 100644
--- a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
+++ b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
@@ -75,6 +75,7 @@
     Camera2ClientBase(cameraService, remoteCallback, clientPackageName,
                 cameraId, cameraFacing, clientPid, clientUid, servicePid),
     mInputStream(),
+    mStreamingRequestId(REQUEST_ID_NONE),
     mRequestIdCounter(0) {
 
     ATRACE_CALL();
@@ -233,7 +234,7 @@
             res = STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION,
                     msg.string());
         } else {
-            mStreamingRequestList.push_back(submitInfo->mRequestId);
+            mStreamingRequestId = submitInfo->mRequestId;
         }
     } else {
         err = mDevice->captureList(metadataRequestList, &(submitInfo->mLastFrameNumber));
@@ -270,17 +271,9 @@
         return STATUS_ERROR(CameraService::ERROR_DISCONNECTED, "Camera device no longer alive");
     }
 
-    Vector<int>::iterator it, end;
-    for (it = mStreamingRequestList.begin(), end = mStreamingRequestList.end();
-         it != end; ++it) {
-        if (*it == requestId) {
-            break;
-        }
-    }
-
-    if (it == end) {
-        String8 msg = String8::format("Camera %d: Did not find request ID %d in list of "
-                "streaming requests", mCameraId, requestId);
+    if (mStreamingRequestId != requestId) {
+        String8 msg = String8::format("Camera %d: Canceling request ID %d doesn't match "
+                "current request ID %d", mCameraId, requestId, mStreamingRequestId);
         ALOGE("%s: %s", __FUNCTION__, msg.string());
         return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
     }
@@ -290,7 +283,7 @@
     if (err == OK) {
         ALOGV("%s: Camera %d: Successfully cleared streaming request",
               __FUNCTION__, mCameraId);
-        mStreamingRequestList.erase(it);
+        mStreamingRequestId = REQUEST_ID_NONE;
     } else {
         res = STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION,
                 "Camera %d: Error clearing streaming request: %s (%d)",
@@ -767,7 +760,7 @@
     }
 
     // FIXME: Also need check repeating burst.
-    if (!mStreamingRequestList.isEmpty()) {
+    if (mStreamingRequestId != REQUEST_ID_NONE) {
         String8 msg = String8::format(
             "Camera %d: Try to waitUntilIdle when there are active streaming requests",
             mCameraId);
@@ -799,7 +792,7 @@
         return STATUS_ERROR(CameraService::ERROR_DISCONNECTED, "Camera device no longer alive");
     }
 
-    mStreamingRequestList.clear();
+    mStreamingRequestId = REQUEST_ID_NONE;
     status_t err = mDevice->flush(lastFrameNumber);
     if (err != OK) {
         res = STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION,
@@ -982,6 +975,17 @@
     }
 }
 
+void CameraDeviceClient::notifyRepeatingRequestError(long lastFrameNumber) {
+    sp<hardware::camera2::ICameraDeviceCallbacks> remoteCb = getRemoteCallback();
+
+    if (remoteCb != 0) {
+        remoteCb->onRepeatingRequestError(lastFrameNumber);
+    }
+
+    Mutex::Autolock icl(mBinderSerializationLock);
+    mStreamingRequestId = REQUEST_ID_NONE;
+}
+
 void CameraDeviceClient::notifyIdle() {
     // Thread safe. Don't bother locking.
     sp<hardware::camera2::ICameraDeviceCallbacks> remoteCb = getRemoteCallback();
diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.h b/services/camera/libcameraservice/api2/CameraDeviceClient.h
index 38137a2..3660a18 100644
--- a/services/camera/libcameraservice/api2/CameraDeviceClient.h
+++ b/services/camera/libcameraservice/api2/CameraDeviceClient.h
@@ -160,6 +160,7 @@
                              const CaptureResultExtras& resultExtras);
     virtual void notifyShutter(const CaptureResultExtras& resultExtras, nsecs_t timestamp);
     virtual void notifyPrepared(int streamId);
+    virtual void notifyRepeatingRequestError(long lastFrameNumber);
 
     /**
      * Interface used by independent components of CameraDeviceClient.
@@ -205,8 +206,9 @@
         int32_t id;
     } mInputStream;
 
-    // Request ID
-    Vector<int> mStreamingRequestList;
+    // Streaming request ID
+    int32_t mStreamingRequestId;
+    static const int32_t REQUEST_ID_NONE = -1;
 
     int32_t mRequestIdCounter;
 
diff --git a/services/camera/libcameraservice/common/Camera2ClientBase.cpp b/services/camera/libcameraservice/common/Camera2ClientBase.cpp
index 2cc150d..c0d6da6 100644
--- a/services/camera/libcameraservice/common/Camera2ClientBase.cpp
+++ b/services/camera/libcameraservice/common/Camera2ClientBase.cpp
@@ -306,6 +306,14 @@
 }
 
 template <typename TClientBase>
+void Camera2ClientBase<TClientBase>::notifyRepeatingRequestError(long lastFrameNumber) {
+    (void)lastFrameNumber;
+
+    ALOGV("%s: Repeating request was stopped. Last frame number is %ld",
+            __FUNCTION__, lastFrameNumber);
+}
+
+template <typename TClientBase>
 int Camera2ClientBase<TClientBase>::getCameraId() const {
     return TClientBase::mCameraId;
 }
diff --git a/services/camera/libcameraservice/common/Camera2ClientBase.h b/services/camera/libcameraservice/common/Camera2ClientBase.h
index 6eea2f4..4f60034 100644
--- a/services/camera/libcameraservice/common/Camera2ClientBase.h
+++ b/services/camera/libcameraservice/common/Camera2ClientBase.h
@@ -73,6 +73,7 @@
     virtual void          notifyAutoWhitebalance(uint8_t newState,
                                                  int triggerId);
     virtual void          notifyPrepared(int streamId);
+    virtual void          notifyRepeatingRequestError(long lastFrameNumber);
 
     int                   getCameraId() const;
     const sp<CameraDeviceBase>&
diff --git a/services/camera/libcameraservice/common/CameraDeviceBase.h b/services/camera/libcameraservice/common/CameraDeviceBase.h
index d570d4b..35ec531 100644
--- a/services/camera/libcameraservice/common/CameraDeviceBase.h
+++ b/services/camera/libcameraservice/common/CameraDeviceBase.h
@@ -209,6 +209,7 @@
         virtual void notifyAutoExposure(uint8_t newState, int triggerId) = 0;
         virtual void notifyAutoWhitebalance(uint8_t newState,
                 int triggerId) = 0;
+        virtual void notifyRepeatingRequestError(long lastFrameNumber) = 0;
       protected:
         virtual ~NotificationListener();
     };
diff --git a/services/camera/libcameraservice/common/CameraModule.cpp b/services/camera/libcameraservice/common/CameraModule.cpp
index f33d1ba..073144c 100644
--- a/services/camera/libcameraservice/common/CameraModule.cpp
+++ b/services/camera/libcameraservice/common/CameraModule.cpp
@@ -29,6 +29,8 @@
     ATRACE_CALL();
 
     Vector<int32_t> derivedCharKeys;
+    Vector<int32_t> derivedRequestKeys;
+    Vector<int32_t> derivedResultKeys;
     // Keys added in HAL3.3
     if (deviceVersion < CAMERA_DEVICE_API_VERSION_3_3) {
         Vector<uint8_t> controlModes;
@@ -180,6 +182,9 @@
                         ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST_RANGE,
                         defaultRange, 2);
                 derivedCharKeys.push(ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST_RANGE);
+                // Actual request/results will be derived by camera device.
+                derivedRequestKeys.push(ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST);
+                derivedResultKeys.push(ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST);
             }
         }
     }
@@ -196,19 +201,35 @@
 
     // Add those newly added keys to AVAILABLE_CHARACTERISTICS_KEYS
     // This has to be done at this end of this function.
-    entry = chars.find(ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS);
-    Vector<int32_t> availableCharsKeys;
-    availableCharsKeys.setCapacity(entry.count + derivedCharKeys.size());
-    for (size_t i = 0; i < entry.count; i++) {
-        availableCharsKeys.push(entry.data.i32[i]);
+    if (derivedCharKeys.size() > 0) {
+        appendAvailableKeys(
+                chars, ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS, derivedCharKeys);
     }
-    for (size_t i = 0; i < derivedCharKeys.size(); i++) {
-        availableCharsKeys.push(derivedCharKeys[i]);
+    if (derivedRequestKeys.size() > 0) {
+        appendAvailableKeys(
+                chars, ANDROID_REQUEST_AVAILABLE_REQUEST_KEYS, derivedRequestKeys);
     }
-    chars.update(ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS, availableCharsKeys);
+    if (derivedResultKeys.size() > 0) {
+        appendAvailableKeys(
+                chars, ANDROID_REQUEST_AVAILABLE_RESULT_KEYS, derivedResultKeys);
+    }
     return;
 }
 
+void CameraModule::appendAvailableKeys(CameraMetadata &chars,
+        int32_t keyTag, const Vector<int32_t>& appendKeys) {
+    camera_metadata_entry entry = chars.find(keyTag);
+    Vector<int32_t> availableKeys;
+    availableKeys.setCapacity(entry.count + appendKeys.size());
+    for (size_t i = 0; i < entry.count; i++) {
+        availableKeys.push(entry.data.i32[i]);
+    }
+    for (size_t i = 0; i < appendKeys.size(); i++) {
+        availableKeys.push(appendKeys[i]);
+    }
+    chars.update(keyTag, availableKeys);
+}
+
 CameraModule::CameraModule(camera_module_t *module) {
     if (module == NULL) {
         ALOGE("%s: camera hardware module must not be null", __FUNCTION__);
diff --git a/services/camera/libcameraservice/common/CameraModule.h b/services/camera/libcameraservice/common/CameraModule.h
index 36822c7..1a1c274 100644
--- a/services/camera/libcameraservice/common/CameraModule.h
+++ b/services/camera/libcameraservice/common/CameraModule.h
@@ -57,8 +57,10 @@
 private:
     // Derive camera characteristics keys defined after HAL device version
     static void deriveCameraCharacteristicsKeys(uint32_t deviceVersion, CameraMetadata &chars);
+    // Helper function to append available[request|result|chars]Keys
+    static void appendAvailableKeys(CameraMetadata &chars,
+            int32_t keyTag, const Vector<int32_t>& appendKeys);
     status_t filterOpenErrorCode(status_t err);
-
     camera_module_t *mModule;
     KeyedVector<int, camera_info> mCameraInfoMap;
     Mutex mCameraInfoLock;
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index 1caf157..0de80bd 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -200,6 +200,14 @@
     mDeviceInfo = info.static_camera_characteristics;
     mHal3Device = device;
 
+    // Determine whether we need to derive sensitivity boost values for older devices.
+    // If post-RAW sensitivity boost range is listed, so should post-raw sensitivity control
+    // be listed (as the default value 100)
+    if (mDeviceVersion < CAMERA_DEVICE_API_VERSION_3_4 &&
+            mDeviceInfo.exists(ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST_RANGE)) {
+        mDerivePostRawSensKey = true;
+    }
+
     internalUpdateStatusLocked(STATUS_UNCONFIGURED);
     mNextStreamId = 0;
     mDummyStreamId = NO_STREAM;
@@ -1310,9 +1318,19 @@
               __FUNCTION__, templateId);
         return BAD_VALUE;
     }
-    *request = rawRequest;
+
     mRequestTemplateCache[templateId] = rawRequest;
 
+    // Derive some new keys for backward compatibility
+    if (mDerivePostRawSensKey && !mRequestTemplateCache[templateId].exists(
+            ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST)) {
+        int32_t defaultBoost[1] = {100};
+        mRequestTemplateCache[templateId].update(
+                ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST,
+                defaultBoost, 1);
+    }
+
+    *request = mRequestTemplateCache[templateId];
     return OK;
 }
 
@@ -2256,6 +2274,15 @@
         captureResult.mMetadata.append(collectedPartialResult);
     }
 
+    // Derive some new keys for backward compaibility
+    if (mDerivePostRawSensKey && !captureResult.mMetadata.exists(
+            ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST)) {
+        int32_t defaultBoost[1] = {100};
+        captureResult.mMetadata.update(
+                ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST,
+                defaultBoost, 1);
+    }
+
     captureResult.mMetadata.sort();
 
     // Check that there's a timestamp in the result metadata
@@ -2780,6 +2807,11 @@
 
 status_t Camera3Device::RequestThread::clearRepeatingRequests(/*out*/int64_t *lastFrameNumber) {
     Mutex::Autolock l(mRequestLock);
+    return clearRepeatingRequestsLocked(lastFrameNumber);
+
+}
+
+status_t Camera3Device::RequestThread::clearRepeatingRequestsLocked(/*out*/int64_t *lastFrameNumber) {
     mRepeatingRequests.clear();
     if (lastFrameNumber != NULL) {
         *lastFrameNumber = mRepeatingLastFrameNumber;
@@ -2934,6 +2966,22 @@
     }
 }
 
+void Camera3Device::RequestThread::checkAndStopRepeatingRequest() {
+    Mutex::Autolock l(mRequestLock);
+    // Check all streams needed by repeating requests are still valid. Otherwise, stop
+    // repeating requests.
+    for (const auto& request : mRepeatingRequests) {
+        for (const auto& s : request->mOutputStreams) {
+            if (s->isAbandoned()) {
+                int64_t lastFrameNumber = 0;
+                clearRepeatingRequestsLocked(&lastFrameNumber);
+                mListener->notifyRepeatingRequestError(lastFrameNumber);
+                return;
+            }
+        }
+    }
+}
+
 bool Camera3Device::RequestThread::threadLoop() {
     ATRACE_CALL();
     status_t res;
@@ -2965,6 +3013,8 @@
     if (res == TIMED_OUT) {
         // Not a fatal error if getting output buffers time out.
         cleanUpFailedRequests(/*sendRequestError*/ true);
+        // Check if any stream is abandoned.
+        checkAndStopRepeatingRequest();
         return true;
     } else if (res != OK) {
         cleanUpFailedRequests(/*sendRequestError*/ false);
diff --git a/services/camera/libcameraservice/device3/Camera3Device.h b/services/camera/libcameraservice/device3/Camera3Device.h
index 96ca7b7..0366ef6 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.h
+++ b/services/camera/libcameraservice/device3/Camera3Device.h
@@ -203,6 +203,10 @@
 
     uint32_t                   mDeviceVersion;
 
+    // whether Camera3Device should derive ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST for
+    // backward compatibility. Should not be changed after initialization.
+    bool                       mDerivePostRawSensKey = false;
+
     struct Size {
         uint32_t width;
         uint32_t height;
@@ -561,6 +565,9 @@
         // ERROR state to mark them as not having valid data. mNextRequests will be cleared.
         void cleanUpFailedRequests(bool sendRequestError);
 
+        // Stop the repeating request if any of its output streams is abandoned.
+        void checkAndStopRepeatingRequest();
+
         // Pause handling
         bool               waitIfPaused();
         void               unpauseForNewRequests();
@@ -574,6 +581,9 @@
         // Handle AE precapture trigger cancel for devices <= CAMERA_DEVICE_API_VERSION_3_2.
         void handleAePrecaptureCancelRequest(sp<CaptureRequest> request);
 
+        // Clear repeating requests. Must be called with mRequestLock held.
+        status_t clearRepeatingRequestsLocked(/*out*/ int64_t *lastFrameNumber = NULL);
+
         wp<Camera3Device>  mParent;
         wp<camera3::StatusTracker>  mStatusTracker;
         camera3_device_t  *mHal3Device;
diff --git a/services/camera/libcameraservice/device3/Camera3OutputStream.cpp b/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
index 1e6452f..d2b98e6 100644
--- a/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
@@ -157,6 +157,13 @@
         if (res != OK) {
             ALOGE("%s: Stream %d: Can't dequeue next output buffer: %s (%d)",
                     __FUNCTION__, mId, strerror(-res), res);
+
+            // Only transition to STATE_ABANDONED from STATE_CONFIGURED. (If it is STATE_PREPARING,
+            // let prepareNextBuffer handle the error.)
+            if (res == NO_INIT && mState == STATE_CONFIGURED) {
+                mState = STATE_ABANDONED;
+            }
+
             return res;
         }
     }
diff --git a/services/camera/libcameraservice/device3/Camera3Stream.cpp b/services/camera/libcameraservice/device3/Camera3Stream.cpp
index a4714a7..96d62d4 100644
--- a/services/camera/libcameraservice/device3/Camera3Stream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Stream.cpp
@@ -323,6 +323,11 @@
     return mState == STATE_PREPARING;
 }
 
+bool Camera3Stream::isAbandoned() const {
+    Mutex::Autolock l(mLock);
+    return mState == STATE_ABANDONED;
+}
+
 status_t Camera3Stream::prepareNextBuffer() {
     ATRACE_CALL();
 
@@ -476,16 +481,51 @@
     res = getBufferLocked(buffer);
     if (res == OK) {
         fireBufferListenersLocked(*buffer, /*acquired*/true, /*output*/true);
+        if (buffer->buffer) {
+            mOutstandingBuffers.push_back(*buffer->buffer);
+        }
     }
 
     return res;
 }
 
+bool Camera3Stream::isOutstandingBuffer(const camera3_stream_buffer &buffer) {
+    if (buffer.buffer == nullptr) {
+        return false;
+    }
+
+    for (auto b : mOutstandingBuffers) {
+        if (b == *buffer.buffer) {
+            return true;
+        }
+    }
+    return false;
+}
+
+void Camera3Stream::removeOutstandingBuffer(const camera3_stream_buffer &buffer) {
+    if (buffer.buffer == nullptr) {
+        return;
+    }
+
+    for (auto b = mOutstandingBuffers.begin(); b != mOutstandingBuffers.end(); b++) {
+        if (*b == *buffer.buffer) {
+            mOutstandingBuffers.erase(b);
+            return;
+        }
+    }
+}
+
 status_t Camera3Stream::returnBuffer(const camera3_stream_buffer &buffer,
         nsecs_t timestamp) {
     ATRACE_CALL();
     Mutex::Autolock l(mLock);
 
+    // Check if this buffer is outstanding.
+    if (!isOutstandingBuffer(buffer)) {
+        ALOGE("%s: Stream %d: Returning an unknown buffer.", __FUNCTION__, mId);
+        return BAD_VALUE;
+    }
+
     /**
      * TODO: Check that the state is valid first.
      *
@@ -503,6 +543,7 @@
     // buffer to be returned.
     mOutputBufferReturnedSignal.signal();
 
+    removeOutstandingBuffer(buffer);
     return res;
 }
 
@@ -535,6 +576,9 @@
     res = getInputBufferLocked(buffer);
     if (res == OK) {
         fireBufferListenersLocked(*buffer, /*acquired*/true, /*output*/false);
+        if (buffer->buffer) {
+            mOutstandingBuffers.push_back(*buffer->buffer);
+        }
     }
 
     return res;
@@ -544,11 +588,19 @@
     ATRACE_CALL();
     Mutex::Autolock l(mLock);
 
+    // Check if this buffer is outstanding.
+    if (!isOutstandingBuffer(buffer)) {
+        ALOGE("%s: Stream %d: Returning an unknown buffer.", __FUNCTION__, mId);
+        return BAD_VALUE;
+    }
+
     status_t res = returnInputBufferLocked(buffer);
     if (res == OK) {
         fireBufferListenersLocked(buffer, /*acquired*/false, /*output*/false);
         mInputBufferReturnedSignal.signal();
     }
+
+    removeOutstandingBuffer(buffer);
     return res;
 }
 
diff --git a/services/camera/libcameraservice/device3/Camera3Stream.h b/services/camera/libcameraservice/device3/Camera3Stream.h
index c932e253..0755700 100644
--- a/services/camera/libcameraservice/device3/Camera3Stream.h
+++ b/services/camera/libcameraservice/device3/Camera3Stream.h
@@ -95,6 +95,8 @@
  *    STATE_PREPARING      => STATE_CONFIGURED:
  *        When sufficient prepareNextBuffer calls have been made to allocate
  *        all stream buffers, or cancelPrepare is called.
+ *    STATE_CONFIGURED     => STATE_ABANDONED:
+ *        When the buffer queue of the stream is abandoned.
  *
  * Status Tracking:
  *    Each stream is tracked by StatusTracker as a separate component,
@@ -353,6 +355,11 @@
     void             removeBufferListener(
             const sp<Camera3StreamBufferListener>& listener);
 
+    /**
+     * Return if the buffer queue of the stream is abandoned.
+     */
+    bool             isAbandoned() const;
+
   protected:
     const int mId;
     /**
@@ -380,7 +387,8 @@
         STATE_IN_CONFIG,
         STATE_IN_RECONFIG,
         STATE_CONFIGURED,
-        STATE_PREPARING
+        STATE_PREPARING,
+        STATE_ABANDONED
     } mState;
 
     mutable Mutex mLock;
@@ -457,6 +465,12 @@
 
     status_t        cancelPrepareLocked();
 
+    // Return whether the buffer is in the list of outstanding buffers.
+    bool isOutstandingBuffer(const camera3_stream_buffer& buffer);
+
+    // Remove the buffer from the list of outstanding buffers.
+    void removeOutstandingBuffer(const camera3_stream_buffer& buffer);
+
     // Tracking for PREPARING state
 
     // State of buffer preallocation. Only true if either prepareNextBuffer
@@ -470,6 +484,9 @@
     // Number of buffers allocated on last prepare call.
     size_t mLastMaxCount;
 
+    // Outstanding buffers dequeued from the stream's buffer queue.
+    List<buffer_handle_t> mOutstandingBuffers;
+
 }; // class Camera3Stream
 
 }; // namespace camera3
diff --git a/services/camera/libcameraservice/device3/Camera3StreamInterface.h b/services/camera/libcameraservice/device3/Camera3StreamInterface.h
index 3f7e7a7..6cb7a54 100644
--- a/services/camera/libcameraservice/device3/Camera3StreamInterface.h
+++ b/services/camera/libcameraservice/device3/Camera3StreamInterface.h
@@ -262,6 +262,11 @@
     virtual status_t disconnect() = 0;
 
     /**
+     * Return if the buffer queue of the stream is abandoned.
+     */
+    virtual bool isAbandoned() const = 0;
+
+    /**
      * Debug dump of the stream's state.
      */
     virtual void     dump(int fd, const Vector<String16> &args) const = 0;
diff --git a/services/soundtrigger/SoundTriggerHwService.cpp b/services/soundtrigger/SoundTriggerHwService.cpp
index 8f37bed..bb2416a 100644
--- a/services/soundtrigger/SoundTriggerHwService.cpp
+++ b/services/soundtrigger/SoundTriggerHwService.cpp
@@ -545,33 +545,9 @@
     AutoMutex lock(mLock);
 
     if (mModels.size() >= mDescriptor.properties.max_sound_models) {
-        /* Make space for a keyphrase sound model by first trying to swap out a previously loaded
-         * keyphrase sound model, or if needed, another sound model. This decision would optimally
-         * happen in SoundTriggerHelper, but is happening here because state tracking isn't good
-         * enough in SoundTriggerHelper to ensure that state is consistent between it and the HAL,
-         * nor does sufficient error handling exist to recover from inconsistencies.
-         * Once that exists:
-         * TODO: we should return an error instead of unloading a previous sound model here.
-         */
-        if (mModels.size() == 0) {
-            return INVALID_OPERATION;
-        }
-        if (sound_model->type == SOUND_MODEL_TYPE_KEYPHRASE) {
-            ALOGW("loadSoundModel() max number of models exceeded %d making room for a new one",
-                  mDescriptor.properties.max_sound_models);
-            sound_model_handle_t unload_handle = mModels.valueAt(0)->mHandle;
-            for (size_t i = 0; i < mModels.size(); i++) {
-                if (mModels.valueAt(i)->mType == SOUND_MODEL_TYPE_KEYPHRASE) {
-                    unload_handle = mModels.keyAt(i);
-                    break;
-                }
-            }
-            unloadSoundModel_l(unload_handle);
-        } else {
-            ALOGW("loadSoundModel(): Not loading, max number of models (%d) would be exceeded",
-                  mDescriptor.properties.max_sound_models);
-            return INVALID_OPERATION;
-        }
+        ALOGW("loadSoundModel(): Not loading, max number of models (%d) would be exceeded",
+              mDescriptor.properties.max_sound_models);
+        return INVALID_OPERATION;
     }
 
     status_t status = mHwDevice->load_sound_model(mHwDevice, sound_model,