Merge pie-platform-release to aosp-master - DO NOT MERGE

Change-Id: I1169742007fab68dbf94b6f81bf042bbca0d6a3f
diff --git a/audio/Android.bp b/audio/Android.bp
index 68043da..bda39b4 100644
--- a/audio/Android.bp
+++ b/audio/Android.bp
@@ -16,7 +16,7 @@
             enabled: true,
         },
         vendor: {
-            cflags: ["AUDIO_NO_SYSTEM_DECLARATIONS"],
+            cflags: ["-DAUDIO_NO_SYSTEM_DECLARATIONS"],
         },
     }
 }
diff --git a/audio/include/system/audio.h b/audio/include/system/audio.h
index 13e6f8f..550913b 100644
--- a/audio/include/system/audio.h
+++ b/audio/include/system/audio.h
@@ -29,6 +29,19 @@
 #include "audio-base.h"
 #include "audio-base-utils.h"
 
+/*
+ * Annotation to tell clang that we intend to fall through from one case to
+ * another in a switch (for c++ files). Sourced from android-base/macros.h.
+ * TODO: See also C++17 [[fallthough]].
+ */
+#ifndef FALLTHROUGH_INTENDED
+#if defined(__clang__) && defined(__cplusplus)
+#define FALLTHROUGH_INTENDED [[clang::fallthrough]]
+#else
+#define FALLTHROUGH_INTENDED
+#endif // __clang__ && __cplusplus
+#endif // FALLTHROUGH_INTENDED
+
 __BEGIN_DECLS
 
 /* The enums were moved here mostly from
@@ -511,6 +524,29 @@
 /* an invalid HW synchronization source indicating an error */
 #define AUDIO_HW_SYNC_INVALID 0
 
+/** @TODO export from .hal */
+typedef enum {
+    NONE    = 0x0,
+    /**
+     * Only set this flag if applications can access the audio buffer memory
+     * shared with the backend (usually DSP) _without_ security issue.
+     *
+     * Setting this flag also implies that Binder will allow passing the shared memory FD
+     * to applications.
+     *
+     * That usually implies that the kernel will prevent any access to the
+     * memory surrounding the audio buffer as it could lead to a security breach.
+     *
+     * For example, a "/dev/snd/" file descriptor generally is not shareable,
+     * but an "anon_inode:dmabuffer" file descriptor is shareable.
+     * See also Linux kernel's dma_buf.
+     *
+     * This flag is required to support AAudio exclusive mode:
+     * See: https://source.android.com/devices/audio/aaudio
+     */
+    AUDIO_MMAP_APPLICATION_SHAREABLE    = 0x1,
+} audio_mmap_buffer_flag;
+
 /**
  * Mmap buffer descriptor returned by audio_stream->create_mmap_buffer().
  * note\ Used by streams opened in mmap mode.
@@ -521,6 +557,7 @@
     int32_t shared_memory_fd;       /**< FD for mmap memory buffer */
     int32_t buffer_size_frames;     /**< total buffer size in frames */
     int32_t burst_size_frames;      /**< transfer size granularity in frames */
+    audio_mmap_buffer_flag flags;   /**< Attributes describing the buffer. */
 };
 
 /**
@@ -664,7 +701,7 @@
         if (bits & ~AUDIO_CHANNEL_IN_ALL) {
             bits = 0;
         }
-        // fall through
+        FALLTHROUGH_INTENDED;
     case AUDIO_CHANNEL_REPRESENTATION_INDEX:
         return bits != 0;
     default:
@@ -686,7 +723,7 @@
         if (bits & ~AUDIO_CHANNEL_OUT_ALL) {
             bits = 0;
         }
-        // fall through
+        FALLTHROUGH_INTENDED;
     case AUDIO_CHANNEL_REPRESENTATION_INDEX:
         return bits != 0;
     default:
@@ -707,7 +744,7 @@
     case AUDIO_CHANNEL_REPRESENTATION_POSITION:
         // TODO: We can now merge with from_out_mask and remove anding
         bits &= AUDIO_CHANNEL_IN_ALL;
-        // fall through
+        FALLTHROUGH_INTENDED;
     case AUDIO_CHANNEL_REPRESENTATION_INDEX:
         return popcount(bits);
     default:
@@ -728,7 +765,7 @@
     case AUDIO_CHANNEL_REPRESENTATION_POSITION:
         // TODO: We can now merge with from_in_mask and remove anding
         bits &= AUDIO_CHANNEL_OUT_ALL;
-        // fall through
+        FALLTHROUGH_INTENDED;
     case AUDIO_CHANNEL_REPRESENTATION_INDEX:
         return popcount(bits);
     default:
diff --git a/audio_utils/fifo.cpp b/audio_utils/fifo.cpp
index 883a9c0..a6dd545 100644
--- a/audio_utils/fifo.cpp
+++ b/audio_utils/fifo.cpp
@@ -26,7 +26,8 @@
 #include <audio_utils/fifo.h>
 #include <audio_utils/futex.h>
 #include <audio_utils/roundup.h>
-#include <cutils/log.h>
+#include <log/log.h>
+#include <system/audio.h> // FALLTHROUGH_INTENDED
 #include <utils/Errors.h>
 
 audio_utils_fifo_base::audio_utils_fifo_base(uint32_t frameCount,
@@ -238,7 +239,7 @@
                 break;
             case AUDIO_UTILS_FIFO_SYNC_PRIVATE:
                 op = FUTEX_WAIT_PRIVATE;
-                // fall through
+                FALLTHROUGH_INTENDED;
             case AUDIO_UTILS_FIFO_SYNC_SHARED:
                 if (timeout->tv_sec == LONG_MAX) {
                     timeout = NULL;
@@ -254,7 +255,7 @@
                             // bypass the "timeout = NULL;" below
                             continue;
                         }
-                        // fall through
+                        FALLTHROUGH_INTENDED;
                     case EINTR:
                     case ETIMEDOUT:
                         err = -errno;
@@ -322,7 +323,7 @@
                 break;
             case AUDIO_UTILS_FIFO_SYNC_PRIVATE:
                 op = FUTEX_WAKE_PRIVATE;
-                // fall through
+                FALLTHROUGH_INTENDED;
             case AUDIO_UTILS_FIFO_SYNC_SHARED:
                 if (filled >= 0) {
                     if ((uint32_t) filled < mArmLevel) {
@@ -480,7 +481,7 @@
                 break;
             case AUDIO_UTILS_FIFO_SYNC_PRIVATE:
                 op = FUTEX_WAKE_PRIVATE;
-                // fall through
+                FALLTHROUGH_INTENDED;
             case AUDIO_UTILS_FIFO_SYNC_SHARED:
                 if (filled >= 0) {
                     if (filled > mArmLevel) {
@@ -539,7 +540,7 @@
             break;
         case AUDIO_UTILS_FIFO_SYNC_PRIVATE:
             op = FUTEX_WAIT_PRIVATE;
-            // fall through
+            FALLTHROUGH_INTENDED;
         case AUDIO_UTILS_FIFO_SYNC_SHARED:
             if (timeout->tv_sec == LONG_MAX) {
                 timeout = NULL;
@@ -555,7 +556,7 @@
                         // bypass the "timeout = NULL;" below
                         continue;
                     }
-                    // fall through
+                    FALLTHROUGH_INTENDED;
                 case EINTR:
                 case ETIMEDOUT:
                     err = -errno;
diff --git a/audio_utils/spdif/AC3FrameScanner.cpp b/audio_utils/spdif/AC3FrameScanner.cpp
index 4055bb0..6ebe9e3 100644
--- a/audio_utils/spdif/AC3FrameScanner.cpp
+++ b/audio_utils/spdif/AC3FrameScanner.cpp
@@ -18,7 +18,7 @@
 
 #include <string.h>
 
-#include <utils/Log.h>
+#include <log/log.h>
 #include <audio_utils/spdif/FrameScanner.h>
 
 #include "AC3FrameScanner.h"
diff --git a/audio_utils/spdif/BitFieldParser.cpp b/audio_utils/spdif/BitFieldParser.cpp
index 8f1c11e..3d3642b 100644
--- a/audio_utils/spdif/BitFieldParser.cpp
+++ b/audio_utils/spdif/BitFieldParser.cpp
@@ -20,7 +20,7 @@
 #include <string.h>
 #include <assert.h>
 
-#include <utils/Log.h>
+#include <log/log.h>
 #include "BitFieldParser.h"
 
 namespace android {
diff --git a/audio_utils/spdif/DTSFrameScanner.cpp b/audio_utils/spdif/DTSFrameScanner.cpp
index 944f4a7..408f1b4 100644
--- a/audio_utils/spdif/DTSFrameScanner.cpp
+++ b/audio_utils/spdif/DTSFrameScanner.cpp
@@ -20,7 +20,7 @@
 #include <assert.h>
 #include <string.h>
 
-#include <utils/Log.h>
+#include <log/log.h>
 #include <audio_utils/spdif/FrameScanner.h>
 
 #include "BitFieldParser.h"
diff --git a/audio_utils/spdif/FrameScanner.cpp b/audio_utils/spdif/FrameScanner.cpp
index 2b591e3..81de943 100644
--- a/audio_utils/spdif/FrameScanner.cpp
+++ b/audio_utils/spdif/FrameScanner.cpp
@@ -19,7 +19,7 @@
 #include <string.h>
 #include <assert.h>
 
-#include <utils/Log.h>
+#include <log/log.h>
 #include <audio_utils/spdif/FrameScanner.h>
 
 namespace android {
diff --git a/audio_utils/spdif/SPDIFEncoder.cpp b/audio_utils/spdif/SPDIFEncoder.cpp
index 5c62299..250f961 100644
--- a/audio_utils/spdif/SPDIFEncoder.cpp
+++ b/audio_utils/spdif/SPDIFEncoder.cpp
@@ -18,7 +18,7 @@
 #include <string.h>
 
 #define LOG_TAG "AudioSPDIF"
-#include <utils/Log.h>
+#include <log/log.h>
 #include <audio_utils/spdif/SPDIFEncoder.h>
 
 #include "AC3FrameScanner.h"
diff --git a/camera/docs/docs.html b/camera/docs/docs.html
index 36a6967..4a8a9c7 100644
--- a/camera/docs/docs.html
+++ b/camera/docs/docs.html
@@ -2606,12 +2606,15 @@
             </td>
 
             <td class="entry_units">
-              Pixel coordinates within android.<wbr/>sensor.<wbr/>info.<wbr/>active<wbr/>Array<wbr/>Size
+              Pixel coordinates within android.<wbr/>sensor.<wbr/>info.<wbr/>active<wbr/>Array<wbr/>Size or
+            android.<wbr/>sensor.<wbr/>info.<wbr/>pre<wbr/>Correction<wbr/>Active<wbr/>Array<wbr/>Size depending on
+            distortion correction capability and mode
             </td>
 
             <td class="entry_range">
               <p>Coordinates must be between <code>[(0,<wbr/>0),<wbr/> (width,<wbr/> height))</code> of
-<a href="#static_android.sensor.info.activeArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>active<wbr/>Array<wbr/>Size</a></p>
+<a href="#static_android.sensor.info.activeArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>active<wbr/>Array<wbr/>Size</a> or <a href="#static_android.sensor.info.preCorrectionActiveArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>pre<wbr/>Correction<wbr/>Active<wbr/>Array<wbr/>Size</a>
+depending on distortion correction capability and mode</p>
             </td>
 
             <td class="entry_hal_version">
@@ -2634,11 +2637,26 @@
 Otherwise will always be present.<wbr/></p>
 <p>The maximum number of regions supported by the device is determined by the value
 of <a href="#static_android.control.maxRegionsAe">android.<wbr/>control.<wbr/>max<wbr/>Regions<wbr/>Ae</a>.<wbr/></p>
-<p>The coordinate system is based on the active pixel array,<wbr/>
-with (0,<wbr/>0) being the top-left pixel in the active pixel array,<wbr/> and
+<p>For devices not supporting <a href="#controls_android.distortionCorrection.mode">android.<wbr/>distortion<wbr/>Correction.<wbr/>mode</a> control,<wbr/> the coordinate
+system always follows that of <a href="#static_android.sensor.info.activeArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>active<wbr/>Array<wbr/>Size</a>,<wbr/> with (0,<wbr/>0) being
+the top-left pixel in the active pixel array,<wbr/> and
 (<a href="#static_android.sensor.info.activeArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>active<wbr/>Array<wbr/>Size</a>.<wbr/>width - 1,<wbr/>
-<a href="#static_android.sensor.info.activeArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>active<wbr/>Array<wbr/>Size</a>.<wbr/>height - 1) being the
-bottom-right pixel in the active pixel array.<wbr/></p>
+<a href="#static_android.sensor.info.activeArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>active<wbr/>Array<wbr/>Size</a>.<wbr/>height - 1) being the bottom-right pixel in the
+active pixel array.<wbr/></p>
+<p>For devices supporting <a href="#controls_android.distortionCorrection.mode">android.<wbr/>distortion<wbr/>Correction.<wbr/>mode</a> control,<wbr/> the coordinate
+system depends on the mode being set.<wbr/>
+When the distortion correction mode is OFF,<wbr/> the coordinate system follows
+<a href="#static_android.sensor.info.preCorrectionActiveArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>pre<wbr/>Correction<wbr/>Active<wbr/>Array<wbr/>Size</a>,<wbr/> with
+<code>(0,<wbr/> 0)</code> being the top-left pixel of the pre-correction active array,<wbr/> and
+(<a href="#static_android.sensor.info.preCorrectionActiveArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>pre<wbr/>Correction<wbr/>Active<wbr/>Array<wbr/>Size</a>.<wbr/>width - 1,<wbr/>
+<a href="#static_android.sensor.info.preCorrectionActiveArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>pre<wbr/>Correction<wbr/>Active<wbr/>Array<wbr/>Size</a>.<wbr/>height - 1) being the bottom-right
+pixel in the pre-correction active pixel array.<wbr/>
+When the distortion correction mode is not OFF,<wbr/> the coordinate system follows
+<a href="#static_android.sensor.info.activeArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>active<wbr/>Array<wbr/>Size</a>,<wbr/> with
+<code>(0,<wbr/> 0)</code> being the top-left pixel of the active array,<wbr/> and
+(<a href="#static_android.sensor.info.activeArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>active<wbr/>Array<wbr/>Size</a>.<wbr/>width - 1,<wbr/>
+<a href="#static_android.sensor.info.activeArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>active<wbr/>Array<wbr/>Size</a>.<wbr/>height - 1) being the bottom-right pixel in the
+active pixel array.<wbr/></p>
 <p>The weight must be within <code>[0,<wbr/> 1000]</code>,<wbr/> and represents a weight
 for every pixel in the area.<wbr/> This means that a large metering area
 with the same weight as a smaller area will have more effect in
@@ -2667,7 +2685,9 @@
 Every five elements represent a metering region of
 (xmin,<wbr/> ymin,<wbr/> xmax,<wbr/> ymax,<wbr/> weight).<wbr/>
 The rectangle is defined to be inclusive on xmin and ymin,<wbr/> but
-exclusive on xmax and ymax.<wbr/></p>
+exclusive on xmax and ymax.<wbr/>
+HAL must always report metering regions in the coordinate system of pre-correction
+active array.<wbr/></p>
             </td>
           </tr>
 
@@ -3067,12 +3087,15 @@
             </td>
 
             <td class="entry_units">
-              Pixel coordinates within android.<wbr/>sensor.<wbr/>info.<wbr/>active<wbr/>Array<wbr/>Size
+              Pixel coordinates within android.<wbr/>sensor.<wbr/>info.<wbr/>active<wbr/>Array<wbr/>Size or
+            android.<wbr/>sensor.<wbr/>info.<wbr/>pre<wbr/>Correction<wbr/>Active<wbr/>Array<wbr/>Size depending on
+            distortion correction capability and mode
             </td>
 
             <td class="entry_range">
               <p>Coordinates must be between <code>[(0,<wbr/>0),<wbr/> (width,<wbr/> height))</code> of
-<a href="#static_android.sensor.info.activeArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>active<wbr/>Array<wbr/>Size</a></p>
+<a href="#static_android.sensor.info.activeArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>active<wbr/>Array<wbr/>Size</a> or <a href="#static_android.sensor.info.preCorrectionActiveArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>pre<wbr/>Correction<wbr/>Active<wbr/>Array<wbr/>Size</a>
+depending on distortion correction capability and mode</p>
             </td>
 
             <td class="entry_hal_version">
@@ -3095,11 +3118,26 @@
 Otherwise will always be present.<wbr/></p>
 <p>The maximum number of focus areas supported by the device is determined by the value
 of <a href="#static_android.control.maxRegionsAf">android.<wbr/>control.<wbr/>max<wbr/>Regions<wbr/>Af</a>.<wbr/></p>
-<p>The coordinate system is based on the active pixel array,<wbr/>
-with (0,<wbr/>0) being the top-left pixel in the active pixel array,<wbr/> and
+<p>For devices not supporting <a href="#controls_android.distortionCorrection.mode">android.<wbr/>distortion<wbr/>Correction.<wbr/>mode</a> control,<wbr/> the coordinate
+system always follows that of <a href="#static_android.sensor.info.activeArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>active<wbr/>Array<wbr/>Size</a>,<wbr/> with (0,<wbr/>0) being
+the top-left pixel in the active pixel array,<wbr/> and
 (<a href="#static_android.sensor.info.activeArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>active<wbr/>Array<wbr/>Size</a>.<wbr/>width - 1,<wbr/>
-<a href="#static_android.sensor.info.activeArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>active<wbr/>Array<wbr/>Size</a>.<wbr/>height - 1) being the
-bottom-right pixel in the active pixel array.<wbr/></p>
+<a href="#static_android.sensor.info.activeArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>active<wbr/>Array<wbr/>Size</a>.<wbr/>height - 1) being the bottom-right pixel in the
+active pixel array.<wbr/></p>
+<p>For devices supporting <a href="#controls_android.distortionCorrection.mode">android.<wbr/>distortion<wbr/>Correction.<wbr/>mode</a> control,<wbr/> the coordinate
+system depends on the mode being set.<wbr/>
+When the distortion correction mode is OFF,<wbr/> the coordinate system follows
+<a href="#static_android.sensor.info.preCorrectionActiveArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>pre<wbr/>Correction<wbr/>Active<wbr/>Array<wbr/>Size</a>,<wbr/> with
+<code>(0,<wbr/> 0)</code> being the top-left pixel of the pre-correction active array,<wbr/> and
+(<a href="#static_android.sensor.info.preCorrectionActiveArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>pre<wbr/>Correction<wbr/>Active<wbr/>Array<wbr/>Size</a>.<wbr/>width - 1,<wbr/>
+<a href="#static_android.sensor.info.preCorrectionActiveArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>pre<wbr/>Correction<wbr/>Active<wbr/>Array<wbr/>Size</a>.<wbr/>height - 1) being the bottom-right
+pixel in the pre-correction active pixel array.<wbr/>
+When the distortion correction mode is not OFF,<wbr/> the coordinate system follows
+<a href="#static_android.sensor.info.activeArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>active<wbr/>Array<wbr/>Size</a>,<wbr/> with
+<code>(0,<wbr/> 0)</code> being the top-left pixel of the active array,<wbr/> and
+(<a href="#static_android.sensor.info.activeArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>active<wbr/>Array<wbr/>Size</a>.<wbr/>width - 1,<wbr/>
+<a href="#static_android.sensor.info.activeArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>active<wbr/>Array<wbr/>Size</a>.<wbr/>height - 1) being the bottom-right pixel in the
+active pixel array.<wbr/></p>
 <p>The weight must be within <code>[0,<wbr/> 1000]</code>,<wbr/> and represents a weight
 for every pixel in the area.<wbr/> This means that a large metering area
 with the same weight as a smaller area will have more effect in
@@ -3129,7 +3167,9 @@
 Every five elements represent a metering region of
 (xmin,<wbr/> ymin,<wbr/> xmax,<wbr/> ymax,<wbr/> weight).<wbr/>
 The rectangle is defined to be inclusive on xmin and ymin,<wbr/> but
-exclusive on xmax and ymax.<wbr/></p>
+exclusive on xmax and ymax.<wbr/>
+HAL must always report metering regions in the coordinate system of pre-correction
+active array.<wbr/></p>
             </td>
           </tr>
 
@@ -3528,12 +3568,15 @@
             </td>
 
             <td class="entry_units">
-              Pixel coordinates within android.<wbr/>sensor.<wbr/>info.<wbr/>active<wbr/>Array<wbr/>Size
+              Pixel coordinates within android.<wbr/>sensor.<wbr/>info.<wbr/>active<wbr/>Array<wbr/>Size or
+            android.<wbr/>sensor.<wbr/>info.<wbr/>pre<wbr/>Correction<wbr/>Active<wbr/>Array<wbr/>Size depending on
+            distortion correction capability and mode
             </td>
 
             <td class="entry_range">
               <p>Coordinates must be between <code>[(0,<wbr/>0),<wbr/> (width,<wbr/> height))</code> of
-<a href="#static_android.sensor.info.activeArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>active<wbr/>Array<wbr/>Size</a></p>
+<a href="#static_android.sensor.info.activeArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>active<wbr/>Array<wbr/>Size</a> or <a href="#static_android.sensor.info.preCorrectionActiveArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>pre<wbr/>Correction<wbr/>Active<wbr/>Array<wbr/>Size</a>
+depending on distortion correction capability and mode</p>
             </td>
 
             <td class="entry_hal_version">
@@ -3556,11 +3599,26 @@
 Otherwise will always be present.<wbr/></p>
 <p>The maximum number of regions supported by the device is determined by the value
 of <a href="#static_android.control.maxRegionsAwb">android.<wbr/>control.<wbr/>max<wbr/>Regions<wbr/>Awb</a>.<wbr/></p>
-<p>The coordinate system is based on the active pixel array,<wbr/>
-with (0,<wbr/>0) being the top-left pixel in the active pixel array,<wbr/> and
+<p>For devices not supporting <a href="#controls_android.distortionCorrection.mode">android.<wbr/>distortion<wbr/>Correction.<wbr/>mode</a> control,<wbr/> the coordinate
+system always follows that of <a href="#static_android.sensor.info.activeArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>active<wbr/>Array<wbr/>Size</a>,<wbr/> with (0,<wbr/>0) being
+the top-left pixel in the active pixel array,<wbr/> and
 (<a href="#static_android.sensor.info.activeArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>active<wbr/>Array<wbr/>Size</a>.<wbr/>width - 1,<wbr/>
-<a href="#static_android.sensor.info.activeArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>active<wbr/>Array<wbr/>Size</a>.<wbr/>height - 1) being the
-bottom-right pixel in the active pixel array.<wbr/></p>
+<a href="#static_android.sensor.info.activeArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>active<wbr/>Array<wbr/>Size</a>.<wbr/>height - 1) being the bottom-right pixel in the
+active pixel array.<wbr/></p>
+<p>For devices supporting <a href="#controls_android.distortionCorrection.mode">android.<wbr/>distortion<wbr/>Correction.<wbr/>mode</a> control,<wbr/> the coordinate
+system depends on the mode being set.<wbr/>
+When the distortion correction mode is OFF,<wbr/> the coordinate system follows
+<a href="#static_android.sensor.info.preCorrectionActiveArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>pre<wbr/>Correction<wbr/>Active<wbr/>Array<wbr/>Size</a>,<wbr/> with
+<code>(0,<wbr/> 0)</code> being the top-left pixel of the pre-correction active array,<wbr/> and
+(<a href="#static_android.sensor.info.preCorrectionActiveArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>pre<wbr/>Correction<wbr/>Active<wbr/>Array<wbr/>Size</a>.<wbr/>width - 1,<wbr/>
+<a href="#static_android.sensor.info.preCorrectionActiveArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>pre<wbr/>Correction<wbr/>Active<wbr/>Array<wbr/>Size</a>.<wbr/>height - 1) being the bottom-right
+pixel in the pre-correction active pixel array.<wbr/>
+When the distortion correction mode is not OFF,<wbr/> the coordinate system follows
+<a href="#static_android.sensor.info.activeArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>active<wbr/>Array<wbr/>Size</a>,<wbr/> with
+<code>(0,<wbr/> 0)</code> being the top-left pixel of the active array,<wbr/> and
+(<a href="#static_android.sensor.info.activeArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>active<wbr/>Array<wbr/>Size</a>.<wbr/>width - 1,<wbr/>
+<a href="#static_android.sensor.info.activeArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>active<wbr/>Array<wbr/>Size</a>.<wbr/>height - 1) being the bottom-right pixel in the
+active pixel array.<wbr/></p>
 <p>The weight must range from 0 to 1000,<wbr/> and represents a weight
 for every pixel in the area.<wbr/> This means that a large metering area
 with the same weight as a smaller area will have more effect in
@@ -3589,7 +3647,9 @@
 Every five elements represent a metering region of
 (xmin,<wbr/> ymin,<wbr/> xmax,<wbr/> ymax,<wbr/> weight).<wbr/>
 The rectangle is defined to be inclusive on xmin and ymin,<wbr/> but
-exclusive on xmax and ymax.<wbr/></p>
+exclusive on xmax and ymax.<wbr/>
+HAL must always report metering regions in the coordinate system of pre-correction
+active array.<wbr/></p>
             </td>
           </tr>
 
@@ -4057,7 +4117,7 @@
                     <span class="entry_type_enum_name">CANDLELIGHT (v3.2)</span>
                     <span class="entry_type_enum_optional">[optional]</span>
                     <span class="entry_type_enum_notes"><p>Optimized for dim settings where the main light source
-is a flame.<wbr/></p></span>
+is a candle.<wbr/></p></span>
                   </li>
                   <li>
                     <span class="entry_type_enum_name">BARCODE (v3.2)</span>
@@ -6505,12 +6565,15 @@
             </td>
 
             <td class="entry_units">
-              Pixel coordinates within android.<wbr/>sensor.<wbr/>info.<wbr/>active<wbr/>Array<wbr/>Size
+              Pixel coordinates within android.<wbr/>sensor.<wbr/>info.<wbr/>active<wbr/>Array<wbr/>Size or
+            android.<wbr/>sensor.<wbr/>info.<wbr/>pre<wbr/>Correction<wbr/>Active<wbr/>Array<wbr/>Size depending on
+            distortion correction capability and mode
             </td>
 
             <td class="entry_range">
               <p>Coordinates must be between <code>[(0,<wbr/>0),<wbr/> (width,<wbr/> height))</code> of
-<a href="#static_android.sensor.info.activeArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>active<wbr/>Array<wbr/>Size</a></p>
+<a href="#static_android.sensor.info.activeArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>active<wbr/>Array<wbr/>Size</a> or <a href="#static_android.sensor.info.preCorrectionActiveArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>pre<wbr/>Correction<wbr/>Active<wbr/>Array<wbr/>Size</a>
+depending on distortion correction capability and mode</p>
             </td>
 
             <td class="entry_hal_version">
@@ -6533,11 +6596,26 @@
 Otherwise will always be present.<wbr/></p>
 <p>The maximum number of regions supported by the device is determined by the value
 of <a href="#static_android.control.maxRegionsAe">android.<wbr/>control.<wbr/>max<wbr/>Regions<wbr/>Ae</a>.<wbr/></p>
-<p>The coordinate system is based on the active pixel array,<wbr/>
-with (0,<wbr/>0) being the top-left pixel in the active pixel array,<wbr/> and
+<p>For devices not supporting <a href="#controls_android.distortionCorrection.mode">android.<wbr/>distortion<wbr/>Correction.<wbr/>mode</a> control,<wbr/> the coordinate
+system always follows that of <a href="#static_android.sensor.info.activeArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>active<wbr/>Array<wbr/>Size</a>,<wbr/> with (0,<wbr/>0) being
+the top-left pixel in the active pixel array,<wbr/> and
 (<a href="#static_android.sensor.info.activeArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>active<wbr/>Array<wbr/>Size</a>.<wbr/>width - 1,<wbr/>
-<a href="#static_android.sensor.info.activeArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>active<wbr/>Array<wbr/>Size</a>.<wbr/>height - 1) being the
-bottom-right pixel in the active pixel array.<wbr/></p>
+<a href="#static_android.sensor.info.activeArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>active<wbr/>Array<wbr/>Size</a>.<wbr/>height - 1) being the bottom-right pixel in the
+active pixel array.<wbr/></p>
+<p>For devices supporting <a href="#controls_android.distortionCorrection.mode">android.<wbr/>distortion<wbr/>Correction.<wbr/>mode</a> control,<wbr/> the coordinate
+system depends on the mode being set.<wbr/>
+When the distortion correction mode is OFF,<wbr/> the coordinate system follows
+<a href="#static_android.sensor.info.preCorrectionActiveArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>pre<wbr/>Correction<wbr/>Active<wbr/>Array<wbr/>Size</a>,<wbr/> with
+<code>(0,<wbr/> 0)</code> being the top-left pixel of the pre-correction active array,<wbr/> and
+(<a href="#static_android.sensor.info.preCorrectionActiveArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>pre<wbr/>Correction<wbr/>Active<wbr/>Array<wbr/>Size</a>.<wbr/>width - 1,<wbr/>
+<a href="#static_android.sensor.info.preCorrectionActiveArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>pre<wbr/>Correction<wbr/>Active<wbr/>Array<wbr/>Size</a>.<wbr/>height - 1) being the bottom-right
+pixel in the pre-correction active pixel array.<wbr/>
+When the distortion correction mode is not OFF,<wbr/> the coordinate system follows
+<a href="#static_android.sensor.info.activeArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>active<wbr/>Array<wbr/>Size</a>,<wbr/> with
+<code>(0,<wbr/> 0)</code> being the top-left pixel of the active array,<wbr/> and
+(<a href="#static_android.sensor.info.activeArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>active<wbr/>Array<wbr/>Size</a>.<wbr/>width - 1,<wbr/>
+<a href="#static_android.sensor.info.activeArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>active<wbr/>Array<wbr/>Size</a>.<wbr/>height - 1) being the bottom-right pixel in the
+active pixel array.<wbr/></p>
 <p>The weight must be within <code>[0,<wbr/> 1000]</code>,<wbr/> and represents a weight
 for every pixel in the area.<wbr/> This means that a large metering area
 with the same weight as a smaller area will have more effect in
@@ -6566,7 +6644,9 @@
 Every five elements represent a metering region of
 (xmin,<wbr/> ymin,<wbr/> xmax,<wbr/> ymax,<wbr/> weight).<wbr/>
 The rectangle is defined to be inclusive on xmin and ymin,<wbr/> but
-exclusive on xmax and ymax.<wbr/></p>
+exclusive on xmax and ymax.<wbr/>
+HAL must always report metering regions in the coordinate system of pre-correction
+active array.<wbr/></p>
             </td>
           </tr>
 
@@ -7273,12 +7353,15 @@
             </td>
 
             <td class="entry_units">
-              Pixel coordinates within android.<wbr/>sensor.<wbr/>info.<wbr/>active<wbr/>Array<wbr/>Size
+              Pixel coordinates within android.<wbr/>sensor.<wbr/>info.<wbr/>active<wbr/>Array<wbr/>Size or
+            android.<wbr/>sensor.<wbr/>info.<wbr/>pre<wbr/>Correction<wbr/>Active<wbr/>Array<wbr/>Size depending on
+            distortion correction capability and mode
             </td>
 
             <td class="entry_range">
               <p>Coordinates must be between <code>[(0,<wbr/>0),<wbr/> (width,<wbr/> height))</code> of
-<a href="#static_android.sensor.info.activeArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>active<wbr/>Array<wbr/>Size</a></p>
+<a href="#static_android.sensor.info.activeArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>active<wbr/>Array<wbr/>Size</a> or <a href="#static_android.sensor.info.preCorrectionActiveArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>pre<wbr/>Correction<wbr/>Active<wbr/>Array<wbr/>Size</a>
+depending on distortion correction capability and mode</p>
             </td>
 
             <td class="entry_hal_version">
@@ -7301,11 +7384,26 @@
 Otherwise will always be present.<wbr/></p>
 <p>The maximum number of focus areas supported by the device is determined by the value
 of <a href="#static_android.control.maxRegionsAf">android.<wbr/>control.<wbr/>max<wbr/>Regions<wbr/>Af</a>.<wbr/></p>
-<p>The coordinate system is based on the active pixel array,<wbr/>
-with (0,<wbr/>0) being the top-left pixel in the active pixel array,<wbr/> and
+<p>For devices not supporting <a href="#controls_android.distortionCorrection.mode">android.<wbr/>distortion<wbr/>Correction.<wbr/>mode</a> control,<wbr/> the coordinate
+system always follows that of <a href="#static_android.sensor.info.activeArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>active<wbr/>Array<wbr/>Size</a>,<wbr/> with (0,<wbr/>0) being
+the top-left pixel in the active pixel array,<wbr/> and
 (<a href="#static_android.sensor.info.activeArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>active<wbr/>Array<wbr/>Size</a>.<wbr/>width - 1,<wbr/>
-<a href="#static_android.sensor.info.activeArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>active<wbr/>Array<wbr/>Size</a>.<wbr/>height - 1) being the
-bottom-right pixel in the active pixel array.<wbr/></p>
+<a href="#static_android.sensor.info.activeArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>active<wbr/>Array<wbr/>Size</a>.<wbr/>height - 1) being the bottom-right pixel in the
+active pixel array.<wbr/></p>
+<p>For devices supporting <a href="#controls_android.distortionCorrection.mode">android.<wbr/>distortion<wbr/>Correction.<wbr/>mode</a> control,<wbr/> the coordinate
+system depends on the mode being set.<wbr/>
+When the distortion correction mode is OFF,<wbr/> the coordinate system follows
+<a href="#static_android.sensor.info.preCorrectionActiveArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>pre<wbr/>Correction<wbr/>Active<wbr/>Array<wbr/>Size</a>,<wbr/> with
+<code>(0,<wbr/> 0)</code> being the top-left pixel of the pre-correction active array,<wbr/> and
+(<a href="#static_android.sensor.info.preCorrectionActiveArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>pre<wbr/>Correction<wbr/>Active<wbr/>Array<wbr/>Size</a>.<wbr/>width - 1,<wbr/>
+<a href="#static_android.sensor.info.preCorrectionActiveArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>pre<wbr/>Correction<wbr/>Active<wbr/>Array<wbr/>Size</a>.<wbr/>height - 1) being the bottom-right
+pixel in the pre-correction active pixel array.<wbr/>
+When the distortion correction mode is not OFF,<wbr/> the coordinate system follows
+<a href="#static_android.sensor.info.activeArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>active<wbr/>Array<wbr/>Size</a>,<wbr/> with
+<code>(0,<wbr/> 0)</code> being the top-left pixel of the active array,<wbr/> and
+(<a href="#static_android.sensor.info.activeArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>active<wbr/>Array<wbr/>Size</a>.<wbr/>width - 1,<wbr/>
+<a href="#static_android.sensor.info.activeArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>active<wbr/>Array<wbr/>Size</a>.<wbr/>height - 1) being the bottom-right pixel in the
+active pixel array.<wbr/></p>
 <p>The weight must be within <code>[0,<wbr/> 1000]</code>,<wbr/> and represents a weight
 for every pixel in the area.<wbr/> This means that a large metering area
 with the same weight as a smaller area will have more effect in
@@ -7335,7 +7433,9 @@
 Every five elements represent a metering region of
 (xmin,<wbr/> ymin,<wbr/> xmax,<wbr/> ymax,<wbr/> weight).<wbr/>
 The rectangle is defined to be inclusive on xmin and ymin,<wbr/> but
-exclusive on xmax and ymax.<wbr/></p>
+exclusive on xmax and ymax.<wbr/>
+HAL must always report metering regions in the coordinate system of pre-correction
+active array.<wbr/></p>
             </td>
           </tr>
 
@@ -8280,12 +8380,15 @@
             </td>
 
             <td class="entry_units">
-              Pixel coordinates within android.<wbr/>sensor.<wbr/>info.<wbr/>active<wbr/>Array<wbr/>Size
+              Pixel coordinates within android.<wbr/>sensor.<wbr/>info.<wbr/>active<wbr/>Array<wbr/>Size or
+            android.<wbr/>sensor.<wbr/>info.<wbr/>pre<wbr/>Correction<wbr/>Active<wbr/>Array<wbr/>Size depending on
+            distortion correction capability and mode
             </td>
 
             <td class="entry_range">
               <p>Coordinates must be between <code>[(0,<wbr/>0),<wbr/> (width,<wbr/> height))</code> of
-<a href="#static_android.sensor.info.activeArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>active<wbr/>Array<wbr/>Size</a></p>
+<a href="#static_android.sensor.info.activeArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>active<wbr/>Array<wbr/>Size</a> or <a href="#static_android.sensor.info.preCorrectionActiveArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>pre<wbr/>Correction<wbr/>Active<wbr/>Array<wbr/>Size</a>
+depending on distortion correction capability and mode</p>
             </td>
 
             <td class="entry_hal_version">
@@ -8308,11 +8411,26 @@
 Otherwise will always be present.<wbr/></p>
 <p>The maximum number of regions supported by the device is determined by the value
 of <a href="#static_android.control.maxRegionsAwb">android.<wbr/>control.<wbr/>max<wbr/>Regions<wbr/>Awb</a>.<wbr/></p>
-<p>The coordinate system is based on the active pixel array,<wbr/>
-with (0,<wbr/>0) being the top-left pixel in the active pixel array,<wbr/> and
+<p>For devices not supporting <a href="#controls_android.distortionCorrection.mode">android.<wbr/>distortion<wbr/>Correction.<wbr/>mode</a> control,<wbr/> the coordinate
+system always follows that of <a href="#static_android.sensor.info.activeArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>active<wbr/>Array<wbr/>Size</a>,<wbr/> with (0,<wbr/>0) being
+the top-left pixel in the active pixel array,<wbr/> and
 (<a href="#static_android.sensor.info.activeArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>active<wbr/>Array<wbr/>Size</a>.<wbr/>width - 1,<wbr/>
-<a href="#static_android.sensor.info.activeArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>active<wbr/>Array<wbr/>Size</a>.<wbr/>height - 1) being the
-bottom-right pixel in the active pixel array.<wbr/></p>
+<a href="#static_android.sensor.info.activeArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>active<wbr/>Array<wbr/>Size</a>.<wbr/>height - 1) being the bottom-right pixel in the
+active pixel array.<wbr/></p>
+<p>For devices supporting <a href="#controls_android.distortionCorrection.mode">android.<wbr/>distortion<wbr/>Correction.<wbr/>mode</a> control,<wbr/> the coordinate
+system depends on the mode being set.<wbr/>
+When the distortion correction mode is OFF,<wbr/> the coordinate system follows
+<a href="#static_android.sensor.info.preCorrectionActiveArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>pre<wbr/>Correction<wbr/>Active<wbr/>Array<wbr/>Size</a>,<wbr/> with
+<code>(0,<wbr/> 0)</code> being the top-left pixel of the pre-correction active array,<wbr/> and
+(<a href="#static_android.sensor.info.preCorrectionActiveArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>pre<wbr/>Correction<wbr/>Active<wbr/>Array<wbr/>Size</a>.<wbr/>width - 1,<wbr/>
+<a href="#static_android.sensor.info.preCorrectionActiveArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>pre<wbr/>Correction<wbr/>Active<wbr/>Array<wbr/>Size</a>.<wbr/>height - 1) being the bottom-right
+pixel in the pre-correction active pixel array.<wbr/>
+When the distortion correction mode is not OFF,<wbr/> the coordinate system follows
+<a href="#static_android.sensor.info.activeArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>active<wbr/>Array<wbr/>Size</a>,<wbr/> with
+<code>(0,<wbr/> 0)</code> being the top-left pixel of the active array,<wbr/> and
+(<a href="#static_android.sensor.info.activeArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>active<wbr/>Array<wbr/>Size</a>.<wbr/>width - 1,<wbr/>
+<a href="#static_android.sensor.info.activeArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>active<wbr/>Array<wbr/>Size</a>.<wbr/>height - 1) being the bottom-right pixel in the
+active pixel array.<wbr/></p>
 <p>The weight must range from 0 to 1000,<wbr/> and represents a weight
 for every pixel in the area.<wbr/> This means that a large metering area
 with the same weight as a smaller area will have more effect in
@@ -8341,7 +8459,9 @@
 Every five elements represent a metering region of
 (xmin,<wbr/> ymin,<wbr/> xmax,<wbr/> ymax,<wbr/> weight).<wbr/>
 The rectangle is defined to be inclusive on xmin and ymin,<wbr/> but
-exclusive on xmax and ymax.<wbr/></p>
+exclusive on xmax and ymax.<wbr/>
+HAL must always report metering regions in the coordinate system of pre-correction
+active array.<wbr/></p>
             </td>
           </tr>
 
@@ -8999,7 +9119,7 @@
                     <span class="entry_type_enum_name">CANDLELIGHT (v3.2)</span>
                     <span class="entry_type_enum_optional">[optional]</span>
                     <span class="entry_type_enum_notes"><p>Optimized for dim settings where the main light source
-is a flame.<wbr/></p></span>
+is a candle.<wbr/></p></span>
                   </li>
                   <li>
                     <span class="entry_type_enum_name">BARCODE (v3.2)</span>
@@ -11680,9 +11800,9 @@
           <tr class="entry_cont">
             <td class="entry_details" colspan="6">
               <p>The HAL must not squeeze or stretch the downscaled primary image to generate thumbnail.<wbr/>
-The cropping must be done on the primary jpeg image rather than the sensor active array.<wbr/>
-The stream cropping rule specified by "S5.<wbr/> Cropping" in camera3.<wbr/>h doesn't apply to the
-thumbnail image cropping.<wbr/></p>
+The cropping must be done on the primary jpeg image rather than the sensor pre-correction
+active array.<wbr/> The stream cropping rule specified by "S5.<wbr/> Cropping" in camera3.<wbr/>h doesn't
+apply to the thumbnail image cropping.<wbr/></p>
             </td>
           </tr>
 
@@ -12397,9 +12517,9 @@
           <tr class="entry_cont">
             <td class="entry_details" colspan="6">
               <p>The HAL must not squeeze or stretch the downscaled primary image to generate thumbnail.<wbr/>
-The cropping must be done on the primary jpeg image rather than the sensor active array.<wbr/>
-The stream cropping rule specified by "S5.<wbr/> Cropping" in camera3.<wbr/>h doesn't apply to the
-thumbnail image cropping.<wbr/></p>
+The cropping must be done on the primary jpeg image rather than the sensor pre-correction
+active array.<wbr/> The stream cropping rule specified by "S5.<wbr/> Cropping" in camera3.<wbr/>h doesn't
+apply to the thumbnail image cropping.<wbr/></p>
             </td>
           </tr>
 
@@ -13565,7 +13685,9 @@
 <p>If this device is the largest or only camera device with a given facing,<wbr/> then this
 position will be <code>(0,<wbr/> 0,<wbr/> 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.<wbr/>03,<wbr/> 0,<wbr/> 0)</code>.<wbr/></p>
+report <code>(0.<wbr/>03,<wbr/> 0,<wbr/> 0)</code>.<wbr/>  Note that this means that,<wbr/> for many computer vision
+applications,<wbr/> the position needs to be negated to convert it to a translation from the
+camera to the origin.<wbr/></p>
 <p>To transform a pixel coordinates between two cameras facing the same direction,<wbr/> first
 the source camera <a href="#static_android.lens.distortion">android.<wbr/>lens.<wbr/>distortion</a> must be corrected for.<wbr/>  Then the source
 camera <a href="#static_android.lens.intrinsicCalibration">android.<wbr/>lens.<wbr/>intrinsic<wbr/>Calibration</a> needs to be applied,<wbr/> followed by the
@@ -13577,7 +13699,8 @@
 <p>To compare this against a real image from the destination camera,<wbr/> the destination camera
 image then needs to be corrected for radial distortion before comparison or sampling.<wbr/></p>
 <p>When <a href="#static_android.lens.poseReference">android.<wbr/>lens.<wbr/>pose<wbr/>Reference</a> is GYROSCOPE,<wbr/> then this position is relative to
-the center of the primary gyroscope on the device.<wbr/></p>
+the center of the primary gyroscope on the device.<wbr/> The axis definitions are the same as
+with PRIMARY_<wbr/>CAMERA.<wbr/></p>
             </td>
           </tr>
 
@@ -13655,13 +13778,15 @@
 </code></pre>
 <p>which can then be combined with the camera pose rotation
 <code>R</code> and translation <code>t</code> (<a href="#static_android.lens.poseRotation">android.<wbr/>lens.<wbr/>pose<wbr/>Rotation</a> and
-<a href="#static_android.lens.poseTranslation">android.<wbr/>lens.<wbr/>pose<wbr/>Translation</a>,<wbr/> respective) to calculate the
+<a href="#static_android.lens.poseTranslation">android.<wbr/>lens.<wbr/>pose<wbr/>Translation</a>,<wbr/> respectively) to calculate the
 complete transform from world coordinates to pixel
 coordinates:</p>
-<pre><code>P = [ K 0   * [ R t
-     0 1 ]     0 1 ]
+<pre><code>P = [ K 0   * [ R -Rt
+     0 1 ]      0 1 ]
 </code></pre>
-<p>and with <code>p_<wbr/>w</code> being a point in the world coordinate system
+<p>(Note the negation of poseTranslation when mapping from camera
+to world coordinates,<wbr/> and multiplication by the rotation).<wbr/></p>
+<p>With <code>p_<wbr/>w</code> being a point in the world coordinate system
 and <code>p_<wbr/>s</code> being a point in the camera active pixel array
 coordinate system,<wbr/> and with the mapping including the
 homogeneous division by z:</p>
@@ -13683,6 +13808,13 @@
 activeArraySize rectangle),<wbr/> to determine the final pixel
 coordinate of the world point for processed (non-RAW)
 output buffers.<wbr/></p>
+<p>For camera devices,<wbr/> the center of pixel <code>(x,<wbr/>y)</code> is located at
+coordinate <code>(x + 0.<wbr/>5,<wbr/> y + 0.<wbr/>5)</code>.<wbr/>  So on a device with a
+precorrection active array of size <code>(10,<wbr/>10)</code>,<wbr/> the valid pixel
+indices go from <code>(0,<wbr/>0)-(9,<wbr/>9)</code>,<wbr/> and an perfectly-built camera would
+have an optical center at the exact center of the pixel grid,<wbr/> at
+coordinates <code>(5.<wbr/>0,<wbr/> 5.<wbr/>0)</code>,<wbr/> which is the top-left corner of pixel
+<code>(5,<wbr/>5)</code>.<wbr/></p>
             </td>
           </tr>
 
@@ -14582,7 +14714,9 @@
 <p>If this device is the largest or only camera device with a given facing,<wbr/> then this
 position will be <code>(0,<wbr/> 0,<wbr/> 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.<wbr/>03,<wbr/> 0,<wbr/> 0)</code>.<wbr/></p>
+report <code>(0.<wbr/>03,<wbr/> 0,<wbr/> 0)</code>.<wbr/>  Note that this means that,<wbr/> for many computer vision
+applications,<wbr/> the position needs to be negated to convert it to a translation from the
+camera to the origin.<wbr/></p>
 <p>To transform a pixel coordinates between two cameras facing the same direction,<wbr/> first
 the source camera <a href="#static_android.lens.distortion">android.<wbr/>lens.<wbr/>distortion</a> must be corrected for.<wbr/>  Then the source
 camera <a href="#static_android.lens.intrinsicCalibration">android.<wbr/>lens.<wbr/>intrinsic<wbr/>Calibration</a> needs to be applied,<wbr/> followed by the
@@ -14594,7 +14728,8 @@
 <p>To compare this against a real image from the destination camera,<wbr/> the destination camera
 image then needs to be corrected for radial distortion before comparison or sampling.<wbr/></p>
 <p>When <a href="#static_android.lens.poseReference">android.<wbr/>lens.<wbr/>pose<wbr/>Reference</a> is GYROSCOPE,<wbr/> then this position is relative to
-the center of the primary gyroscope on the device.<wbr/></p>
+the center of the primary gyroscope on the device.<wbr/> The axis definitions are the same as
+with PRIMARY_<wbr/>CAMERA.<wbr/></p>
             </td>
           </tr>
 
@@ -14672,13 +14807,15 @@
 </code></pre>
 <p>which can then be combined with the camera pose rotation
 <code>R</code> and translation <code>t</code> (<a href="#static_android.lens.poseRotation">android.<wbr/>lens.<wbr/>pose<wbr/>Rotation</a> and
-<a href="#static_android.lens.poseTranslation">android.<wbr/>lens.<wbr/>pose<wbr/>Translation</a>,<wbr/> respective) to calculate the
+<a href="#static_android.lens.poseTranslation">android.<wbr/>lens.<wbr/>pose<wbr/>Translation</a>,<wbr/> respectively) to calculate the
 complete transform from world coordinates to pixel
 coordinates:</p>
-<pre><code>P = [ K 0   * [ R t
-     0 1 ]     0 1 ]
+<pre><code>P = [ K 0   * [ R -Rt
+     0 1 ]      0 1 ]
 </code></pre>
-<p>and with <code>p_<wbr/>w</code> being a point in the world coordinate system
+<p>(Note the negation of poseTranslation when mapping from camera
+to world coordinates,<wbr/> and multiplication by the rotation).<wbr/></p>
+<p>With <code>p_<wbr/>w</code> being a point in the world coordinate system
 and <code>p_<wbr/>s</code> being a point in the camera active pixel array
 coordinate system,<wbr/> and with the mapping including the
 homogeneous division by z:</p>
@@ -14700,6 +14837,13 @@
 activeArraySize rectangle),<wbr/> to determine the final pixel
 coordinate of the world point for processed (non-RAW)
 output buffers.<wbr/></p>
+<p>For camera devices,<wbr/> the center of pixel <code>(x,<wbr/>y)</code> is located at
+coordinate <code>(x + 0.<wbr/>5,<wbr/> y + 0.<wbr/>5)</code>.<wbr/>  So on a device with a
+precorrection active array of size <code>(10,<wbr/>10)</code>,<wbr/> the valid pixel
+indices go from <code>(0,<wbr/>0)-(9,<wbr/>9)</code>,<wbr/> and an perfectly-built camera would
+have an optical center at the exact center of the pixel grid,<wbr/> at
+coordinates <code>(5.<wbr/>0,<wbr/> 5.<wbr/>0)</code>,<wbr/> which is the top-left corner of pixel
+<code>(5,<wbr/>5)</code>.<wbr/></p>
             </td>
           </tr>
 
@@ -17094,11 +17238,11 @@
 camera in the list of supported camera devices.<wbr/></p>
 <p>This capability requires the camera device to support the following:</p>
 <ul>
-<li>This camera device must list the following static metadata entries in <a href="https://developer.android.com/reference/android/hardware/camera2/CameraCharacteristics.html">CameraCharacteristics</a>:<ul>
-<li><a href="#static_android.logicalMultiCamera.physicalIds">android.<wbr/>logical<wbr/>Multi<wbr/>Camera.<wbr/>physical<wbr/>Ids</a></li>
-<li><a href="#static_android.logicalMultiCamera.sensorSyncType">android.<wbr/>logical<wbr/>Multi<wbr/>Camera.<wbr/>sensor<wbr/>Sync<wbr/>Type</a></li>
-</ul>
-</li>
+<li>The IDs of underlying physical cameras are returned via
+  <a href="https://developer.android.com/reference/android/hardware/camera2/CameraCharacteristics.html#getPhysicalCameraIds">CameraCharacteristics#getPhysicalCameraIds</a>.<wbr/></li>
+<li>This camera device must list static metadata
+  <a href="#static_android.logicalMultiCamera.sensorSyncType">android.<wbr/>logical<wbr/>Multi<wbr/>Camera.<wbr/>sensor<wbr/>Sync<wbr/>Type</a> in
+  <a href="https://developer.android.com/reference/android/hardware/camera2/CameraCharacteristics.html">CameraCharacteristics</a>.<wbr/></li>
 <li>The underlying physical cameras' static metadata must list the following entries,<wbr/>
   so that the application can correlate pixels from the physical streams:<ul>
 <li><a href="#static_android.lens.poseReference">android.<wbr/>lens.<wbr/>pose<wbr/>Reference</a></li>
@@ -18083,7 +18227,9 @@
 
             <td class="entry_units">
               Pixel coordinates relative to
-          android.<wbr/>sensor.<wbr/>info.<wbr/>active<wbr/>Array<wbr/>Size
+          android.<wbr/>sensor.<wbr/>info.<wbr/>active<wbr/>Array<wbr/>Size or
+          android.<wbr/>sensor.<wbr/>info.<wbr/>pre<wbr/>Correction<wbr/>Active<wbr/>Array<wbr/>Size depending on distortion correction
+          capability and mode
             </td>
 
             <td class="entry_range">
@@ -18106,9 +18252,17 @@
           <tr class="entry_cont">
             <td class="entry_details" colspan="6">
               <p>This control can be used to implement digital zoom.<wbr/></p>
-<p>The crop region coordinate system is based off
-<a href="#static_android.sensor.info.activeArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>active<wbr/>Array<wbr/>Size</a>,<wbr/> with <code>(0,<wbr/> 0)</code> being the
-top-left corner of the sensor active array.<wbr/></p>
+<p>For devices not supporting <a href="#controls_android.distortionCorrection.mode">android.<wbr/>distortion<wbr/>Correction.<wbr/>mode</a> control,<wbr/> the coordinate
+system always follows that of <a href="#static_android.sensor.info.activeArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>active<wbr/>Array<wbr/>Size</a>,<wbr/> with <code>(0,<wbr/> 0)</code> being
+the top-left pixel of the active array.<wbr/></p>
+<p>For devices supporting <a href="#controls_android.distortionCorrection.mode">android.<wbr/>distortion<wbr/>Correction.<wbr/>mode</a> control,<wbr/> the coordinate
+system depends on the mode being set.<wbr/>
+When the distortion correction mode is OFF,<wbr/> the coordinate system follows
+<a href="#static_android.sensor.info.preCorrectionActiveArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>pre<wbr/>Correction<wbr/>Active<wbr/>Array<wbr/>Size</a>,<wbr/> with
+<code>(0,<wbr/> 0)</code> being the top-left pixel of the pre-correction active array.<wbr/>
+When the distortion correction mode is not OFF,<wbr/> the coordinate system follows
+<a href="#static_android.sensor.info.activeArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>active<wbr/>Array<wbr/>Size</a>,<wbr/> with
+<code>(0,<wbr/> 0)</code> being the top-left pixel of the active array.<wbr/></p>
 <p>Output streams use this rectangle to produce their output,<wbr/>
 cropping to a smaller region if necessary to maintain the
 stream's aspect ratio,<wbr/> then scaling the sensor input to
@@ -18127,10 +18281,16 @@
 outputs will crop horizontally (pillarbox),<wbr/> and 16:9
 streams will match exactly.<wbr/> These additional crops will
 be centered within the crop region.<wbr/></p>
-<p>The width and height of the crop region cannot
-be set to be smaller than
+<p>If the coordinate system is <a href="#static_android.sensor.info.activeArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>active<wbr/>Array<wbr/>Size</a>,<wbr/> the width and height
+of the crop region cannot be set to be smaller than
 <code>floor( activeArraySize.<wbr/>width /<wbr/> <a href="#static_android.scaler.availableMaxDigitalZoom">android.<wbr/>scaler.<wbr/>available<wbr/>Max<wbr/>Digital<wbr/>Zoom</a> )</code> and
 <code>floor( activeArraySize.<wbr/>height /<wbr/> <a href="#static_android.scaler.availableMaxDigitalZoom">android.<wbr/>scaler.<wbr/>available<wbr/>Max<wbr/>Digital<wbr/>Zoom</a> )</code>,<wbr/> respectively.<wbr/></p>
+<p>If the coordinate system is <a href="#static_android.sensor.info.preCorrectionActiveArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>pre<wbr/>Correction<wbr/>Active<wbr/>Array<wbr/>Size</a>,<wbr/> the width
+and height of the crop region cannot be set to be smaller than
+<code>floor( preCorrectionActiveArraySize.<wbr/>width /<wbr/> <a href="#static_android.scaler.availableMaxDigitalZoom">android.<wbr/>scaler.<wbr/>available<wbr/>Max<wbr/>Digital<wbr/>Zoom</a> )</code>
+and
+<code>floor( preCorrectionActiveArraySize.<wbr/>height /<wbr/> <a href="#static_android.scaler.availableMaxDigitalZoom">android.<wbr/>scaler.<wbr/>available<wbr/>Max<wbr/>Digital<wbr/>Zoom</a> )</code>,<wbr/>
+respectively.<wbr/></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
@@ -18152,34 +18312,35 @@
 for raw output,<wbr/> where only a few fixed scales may be
 possible.<wbr/></p>
 <p>For a set of output streams configured,<wbr/> if the sensor output is cropped to a smaller
-size than active array size,<wbr/> the HAL need follow below cropping rules:</p>
+size than pre-correction active array size,<wbr/> the HAL need follow below cropping rules:</p>
 <ul>
 <li>
-<p>The HAL need handle the cropRegion as if the sensor crop size is the effective active
-array size.<wbr/>More specifically,<wbr/> the HAL must transform the request cropRegion from
-<a href="#static_android.sensor.info.activeArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>active<wbr/>Array<wbr/>Size</a> to the sensor cropped pixel area size in this way:</p>
+<p>The HAL need handle the cropRegion as if the sensor crop size is the effective
+pre-correction active array size.<wbr/> More specifically,<wbr/> the HAL must transform the request
+cropRegion from <a href="#static_android.sensor.info.preCorrectionActiveArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>pre<wbr/>Correction<wbr/>Active<wbr/>Array<wbr/>Size</a> to the sensor cropped
+pixel area size in this way:</p>
 <ol>
 <li>Translate the requested cropRegion w.<wbr/>r.<wbr/>t.,<wbr/> the left top corner of the sensor
 cropped pixel area by (tx,<wbr/> ty),<wbr/>
-where <code>ty = sensorCrop.<wbr/>top * (sensorCrop.<wbr/>height /<wbr/> activeArraySize.<wbr/>height)</code>
-and <code>tx = sensorCrop.<wbr/>left * (sensorCrop.<wbr/>width /<wbr/> activeArraySize.<wbr/>width)</code>.<wbr/> The
-(sensorCrop.<wbr/>top,<wbr/> sensorCrop.<wbr/>left) is the coordinate based off the
+where <code>ty = sensorCrop.<wbr/>top * (sensorCrop.<wbr/>height /<wbr/> preCorrectionActiveArraySize.<wbr/>height)</code>
+and <code>tx = sensorCrop.<wbr/>left * (sensorCrop.<wbr/>width /<wbr/> preCorrectionActiveArraySize.<wbr/>width)</code>.<wbr/>
+The (sensorCrop.<wbr/>top,<wbr/> sensorCrop.<wbr/>left) is the coordinate based off the
 <a href="#static_android.sensor.info.activeArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>active<wbr/>Array<wbr/>Size</a>.<wbr/></li>
 <li>Scale the width and height of requested cropRegion with scaling factor of
-sensor<wbr/>Crop.<wbr/>width/<wbr/>active<wbr/>Array<wbr/>Size.<wbr/>width and sensor<wbr/>Crop.<wbr/>height/<wbr/>active<wbr/>Array<wbr/>Size.<wbr/>height
+sensor<wbr/>Crop.<wbr/>width/<wbr/>pre<wbr/>Correction<wbr/>Active<wbr/>Array<wbr/>Size.<wbr/>width and sensor<wbr/>Crop.<wbr/>height/<wbr/>pre<wbr/>Correction<wbr/>Active<wbr/>Array<wbr/>Size.<wbr/>height
 respectively.<wbr/>
 Once this new cropRegion is calculated,<wbr/> the HAL must use this region to crop the image
-with regard to the sensor crop size (effective active array size).<wbr/> The HAL still need
-follow the general cropping rule for this new cropRegion and effective active
-array size.<wbr/></li>
+with regard to the sensor crop size (effective pre-correction active array size).<wbr/> The
+HAL still need follow the general cropping rule for this new cropRegion and effective
+pre-correction active array size.<wbr/></li>
 </ol>
 </li>
 <li>
-<p>The HAL must report the cropRegion with regard to <a href="#static_android.sensor.info.activeArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>active<wbr/>Array<wbr/>Size</a>.<wbr/>
-The HAL need convert the new cropRegion generated above w.<wbr/>r.<wbr/>t.,<wbr/> full active array size.<wbr/>
-The reported cropRegion may be slightly different with the requested cropRegion since
-the HAL may adjust the crop region to account for rounding,<wbr/> conversion error,<wbr/> or other
-hardware limitations.<wbr/></p>
+<p>The HAL must report the cropRegion with regard to <a href="#static_android.sensor.info.preCorrectionActiveArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>pre<wbr/>Correction<wbr/>Active<wbr/>Array<wbr/>Size</a>.<wbr/>
+The HAL need convert the new cropRegion generated above w.<wbr/>r.<wbr/>t.,<wbr/> full pre-correction
+active array size.<wbr/> The reported cropRegion may be slightly different with the requested
+cropRegion since the HAL may adjust the crop region to account for rounding,<wbr/> conversion
+error,<wbr/> or other hardware limitations.<wbr/></p>
 </li>
 </ul>
 <p>HAL2.<wbr/>x uses only (x,<wbr/> y,<wbr/> width)</p>
@@ -19683,7 +19844,9 @@
 
             <td class="entry_units">
               Pixel coordinates relative to
-          android.<wbr/>sensor.<wbr/>info.<wbr/>active<wbr/>Array<wbr/>Size
+          android.<wbr/>sensor.<wbr/>info.<wbr/>active<wbr/>Array<wbr/>Size or
+          android.<wbr/>sensor.<wbr/>info.<wbr/>pre<wbr/>Correction<wbr/>Active<wbr/>Array<wbr/>Size depending on distortion correction
+          capability and mode
             </td>
 
             <td class="entry_range">
@@ -19706,9 +19869,17 @@
           <tr class="entry_cont">
             <td class="entry_details" colspan="6">
               <p>This control can be used to implement digital zoom.<wbr/></p>
-<p>The crop region coordinate system is based off
-<a href="#static_android.sensor.info.activeArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>active<wbr/>Array<wbr/>Size</a>,<wbr/> with <code>(0,<wbr/> 0)</code> being the
-top-left corner of the sensor active array.<wbr/></p>
+<p>For devices not supporting <a href="#controls_android.distortionCorrection.mode">android.<wbr/>distortion<wbr/>Correction.<wbr/>mode</a> control,<wbr/> the coordinate
+system always follows that of <a href="#static_android.sensor.info.activeArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>active<wbr/>Array<wbr/>Size</a>,<wbr/> with <code>(0,<wbr/> 0)</code> being
+the top-left pixel of the active array.<wbr/></p>
+<p>For devices supporting <a href="#controls_android.distortionCorrection.mode">android.<wbr/>distortion<wbr/>Correction.<wbr/>mode</a> control,<wbr/> the coordinate
+system depends on the mode being set.<wbr/>
+When the distortion correction mode is OFF,<wbr/> the coordinate system follows
+<a href="#static_android.sensor.info.preCorrectionActiveArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>pre<wbr/>Correction<wbr/>Active<wbr/>Array<wbr/>Size</a>,<wbr/> with
+<code>(0,<wbr/> 0)</code> being the top-left pixel of the pre-correction active array.<wbr/>
+When the distortion correction mode is not OFF,<wbr/> the coordinate system follows
+<a href="#static_android.sensor.info.activeArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>active<wbr/>Array<wbr/>Size</a>,<wbr/> with
+<code>(0,<wbr/> 0)</code> being the top-left pixel of the active array.<wbr/></p>
 <p>Output streams use this rectangle to produce their output,<wbr/>
 cropping to a smaller region if necessary to maintain the
 stream's aspect ratio,<wbr/> then scaling the sensor input to
@@ -19727,10 +19898,16 @@
 outputs will crop horizontally (pillarbox),<wbr/> and 16:9
 streams will match exactly.<wbr/> These additional crops will
 be centered within the crop region.<wbr/></p>
-<p>The width and height of the crop region cannot
-be set to be smaller than
+<p>If the coordinate system is <a href="#static_android.sensor.info.activeArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>active<wbr/>Array<wbr/>Size</a>,<wbr/> the width and height
+of the crop region cannot be set to be smaller than
 <code>floor( activeArraySize.<wbr/>width /<wbr/> <a href="#static_android.scaler.availableMaxDigitalZoom">android.<wbr/>scaler.<wbr/>available<wbr/>Max<wbr/>Digital<wbr/>Zoom</a> )</code> and
 <code>floor( activeArraySize.<wbr/>height /<wbr/> <a href="#static_android.scaler.availableMaxDigitalZoom">android.<wbr/>scaler.<wbr/>available<wbr/>Max<wbr/>Digital<wbr/>Zoom</a> )</code>,<wbr/> respectively.<wbr/></p>
+<p>If the coordinate system is <a href="#static_android.sensor.info.preCorrectionActiveArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>pre<wbr/>Correction<wbr/>Active<wbr/>Array<wbr/>Size</a>,<wbr/> the width
+and height of the crop region cannot be set to be smaller than
+<code>floor( preCorrectionActiveArraySize.<wbr/>width /<wbr/> <a href="#static_android.scaler.availableMaxDigitalZoom">android.<wbr/>scaler.<wbr/>available<wbr/>Max<wbr/>Digital<wbr/>Zoom</a> )</code>
+and
+<code>floor( preCorrectionActiveArraySize.<wbr/>height /<wbr/> <a href="#static_android.scaler.availableMaxDigitalZoom">android.<wbr/>scaler.<wbr/>available<wbr/>Max<wbr/>Digital<wbr/>Zoom</a> )</code>,<wbr/>
+respectively.<wbr/></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
@@ -19752,34 +19929,35 @@
 for raw output,<wbr/> where only a few fixed scales may be
 possible.<wbr/></p>
 <p>For a set of output streams configured,<wbr/> if the sensor output is cropped to a smaller
-size than active array size,<wbr/> the HAL need follow below cropping rules:</p>
+size than pre-correction active array size,<wbr/> the HAL need follow below cropping rules:</p>
 <ul>
 <li>
-<p>The HAL need handle the cropRegion as if the sensor crop size is the effective active
-array size.<wbr/>More specifically,<wbr/> the HAL must transform the request cropRegion from
-<a href="#static_android.sensor.info.activeArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>active<wbr/>Array<wbr/>Size</a> to the sensor cropped pixel area size in this way:</p>
+<p>The HAL need handle the cropRegion as if the sensor crop size is the effective
+pre-correction active array size.<wbr/> More specifically,<wbr/> the HAL must transform the request
+cropRegion from <a href="#static_android.sensor.info.preCorrectionActiveArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>pre<wbr/>Correction<wbr/>Active<wbr/>Array<wbr/>Size</a> to the sensor cropped
+pixel area size in this way:</p>
 <ol>
 <li>Translate the requested cropRegion w.<wbr/>r.<wbr/>t.,<wbr/> the left top corner of the sensor
 cropped pixel area by (tx,<wbr/> ty),<wbr/>
-where <code>ty = sensorCrop.<wbr/>top * (sensorCrop.<wbr/>height /<wbr/> activeArraySize.<wbr/>height)</code>
-and <code>tx = sensorCrop.<wbr/>left * (sensorCrop.<wbr/>width /<wbr/> activeArraySize.<wbr/>width)</code>.<wbr/> The
-(sensorCrop.<wbr/>top,<wbr/> sensorCrop.<wbr/>left) is the coordinate based off the
+where <code>ty = sensorCrop.<wbr/>top * (sensorCrop.<wbr/>height /<wbr/> preCorrectionActiveArraySize.<wbr/>height)</code>
+and <code>tx = sensorCrop.<wbr/>left * (sensorCrop.<wbr/>width /<wbr/> preCorrectionActiveArraySize.<wbr/>width)</code>.<wbr/>
+The (sensorCrop.<wbr/>top,<wbr/> sensorCrop.<wbr/>left) is the coordinate based off the
 <a href="#static_android.sensor.info.activeArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>active<wbr/>Array<wbr/>Size</a>.<wbr/></li>
 <li>Scale the width and height of requested cropRegion with scaling factor of
-sensor<wbr/>Crop.<wbr/>width/<wbr/>active<wbr/>Array<wbr/>Size.<wbr/>width and sensor<wbr/>Crop.<wbr/>height/<wbr/>active<wbr/>Array<wbr/>Size.<wbr/>height
+sensor<wbr/>Crop.<wbr/>width/<wbr/>pre<wbr/>Correction<wbr/>Active<wbr/>Array<wbr/>Size.<wbr/>width and sensor<wbr/>Crop.<wbr/>height/<wbr/>pre<wbr/>Correction<wbr/>Active<wbr/>Array<wbr/>Size.<wbr/>height
 respectively.<wbr/>
 Once this new cropRegion is calculated,<wbr/> the HAL must use this region to crop the image
-with regard to the sensor crop size (effective active array size).<wbr/> The HAL still need
-follow the general cropping rule for this new cropRegion and effective active
-array size.<wbr/></li>
+with regard to the sensor crop size (effective pre-correction active array size).<wbr/> The
+HAL still need follow the general cropping rule for this new cropRegion and effective
+pre-correction active array size.<wbr/></li>
 </ol>
 </li>
 <li>
-<p>The HAL must report the cropRegion with regard to <a href="#static_android.sensor.info.activeArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>active<wbr/>Array<wbr/>Size</a>.<wbr/>
-The HAL need convert the new cropRegion generated above w.<wbr/>r.<wbr/>t.,<wbr/> full active array size.<wbr/>
-The reported cropRegion may be slightly different with the requested cropRegion since
-the HAL may adjust the crop region to account for rounding,<wbr/> conversion error,<wbr/> or other
-hardware limitations.<wbr/></p>
+<p>The HAL must report the cropRegion with regard to <a href="#static_android.sensor.info.preCorrectionActiveArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>pre<wbr/>Correction<wbr/>Active<wbr/>Array<wbr/>Size</a>.<wbr/>
+The HAL need convert the new cropRegion generated above w.<wbr/>r.<wbr/>t.,<wbr/> full pre-correction
+active array size.<wbr/> The reported cropRegion may be slightly different with the requested
+cropRegion since the HAL may adjust the crop region to account for rounding,<wbr/> conversion
+error,<wbr/> or other hardware limitations.<wbr/></p>
 </li>
 </ul>
 <p>HAL2.<wbr/>x uses only (x,<wbr/> y,<wbr/> width)</p>
@@ -20401,8 +20579,18 @@
 <a href="#controls_android.scaler.cropRegion">android.<wbr/>scaler.<wbr/>crop<wbr/>Region</a>,<wbr/> is defined relative to the active array rectangle given in
 this field,<wbr/> with <code>(0,<wbr/> 0)</code> being the top-left of this rectangle.<wbr/></p>
 <p>The active array may be smaller than the full pixel array,<wbr/> since the full array may
-include black calibration pixels or other inactive regions,<wbr/> and geometric correction
-resulting in scaling or cropping may have been applied.<wbr/></p>
+include black calibration pixels or other inactive regions.<wbr/></p>
+<p>For devices that do not support <a href="#controls_android.distortionCorrection.mode">android.<wbr/>distortion<wbr/>Correction.<wbr/>mode</a> control,<wbr/> the active
+array must be the same as <a href="#static_android.sensor.info.preCorrectionActiveArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>pre<wbr/>Correction<wbr/>Active<wbr/>Array<wbr/>Size</a>.<wbr/></p>
+<p>For devices that support <a href="#controls_android.distortionCorrection.mode">android.<wbr/>distortion<wbr/>Correction.<wbr/>mode</a> control,<wbr/> the active array must
+be enclosed by <a href="#static_android.sensor.info.preCorrectionActiveArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>pre<wbr/>Correction<wbr/>Active<wbr/>Array<wbr/>Size</a>.<wbr/> The difference between
+pre-correction active array and active array accounts for scaling or cropping caused
+by lens geometric distortion correction.<wbr/></p>
+<p>In general,<wbr/> application should always refer to active array size for controls like
+metering regions or crop region.<wbr/> Two exceptions are when the application is dealing with
+RAW image buffers (RAW_<wbr/>SENSOR,<wbr/> RAW10,<wbr/> RAW12 etc),<wbr/> or when application explicitly set
+<a href="#controls_android.distortionCorrection.mode">android.<wbr/>distortion<wbr/>Correction.<wbr/>mode</a> to OFF.<wbr/> In these cases,<wbr/> application should refer
+to <a href="#static_android.sensor.info.preCorrectionActiveArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>pre<wbr/>Correction<wbr/>Active<wbr/>Array<wbr/>Size</a>.<wbr/></p>
             </td>
           </tr>
 
@@ -21157,9 +21345,9 @@
 <ol>
 <li><a href="#static_android.lens.distortion">android.<wbr/>lens.<wbr/>distortion</a>.<wbr/></li>
 </ol>
-<p>If all of the geometric distortion fields are no-ops,<wbr/> this rectangle will be the same
-as the post-distortion-corrected rectangle given in
-<a href="#static_android.sensor.info.activeArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>active<wbr/>Array<wbr/>Size</a>.<wbr/></p>
+<p>If the camera device doesn't support geometric distortion correction,<wbr/> or all of the
+geometric distortion fields are no-ops,<wbr/> this rectangle will be the same as the
+post-distortion-corrected rectangle given in <a href="#static_android.sensor.info.activeArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>active<wbr/>Array<wbr/>Size</a>.<wbr/></p>
 <p>This rectangle is defined relative to the full pixel array; (0,<wbr/>0) is the top-left of
 the full pixel array,<wbr/> and the size of the full pixel array is given by
 <a href="#static_android.sensor.info.pixelArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>pixel<wbr/>Array<wbr/>Size</a>.<wbr/></p>
@@ -24358,7 +24546,7 @@
                 
           <tr class="entry" id="controls_android.statistics.oisDataMode">
             <td class="entry_name
-             " rowspan="1">
+             " rowspan="3">
               android.<wbr/>statistics.<wbr/>ois<wbr/>Data<wbr/>Mode
             </td>
             <td class="entry_type">
@@ -24384,8 +24572,8 @@
             </td> <!-- entry_type -->
 
             <td class="entry_description">
-              <p>A control for selecting whether OIS position information is included in output
-result metadata.<wbr/></p>
+              <p>A control for selecting whether optical stabilization (OIS) position
+information is included in output result metadata.<wbr/></p>
             </td>
 
             <td class="entry_units">
@@ -24403,6 +24591,19 @@
             </td>
 
           </tr>
+          <tr class="entries_header">
+            <th class="th_details" colspan="6">Details</th>
+          </tr>
+          <tr class="entry_cont">
+            <td class="entry_details" colspan="6">
+              <p>Since optical image stabilization generally involves motion much faster than the duration
+of individualq image exposure,<wbr/> multiple OIS samples can be included for a single capture
+result.<wbr/> For example,<wbr/> if the OIS reporting operates at 200 Hz,<wbr/> a typical camera operating
+at 30fps may have 6-7 OIS samples per capture result.<wbr/> This information can be combined
+with the rolling shutter skew to account for lens motion during image exposure in
+post-processing algorithms.<wbr/></p>
+            </td>
+          </tr>
 
 
           <tr class="entry_spacer"><td class="entry_spacer" colspan="7"></td></tr>
@@ -25090,7 +25291,7 @@
                 
           <tr class="entry" id="dynamic_android.statistics.faceLandmarks">
             <td class="entry_name
-             " rowspan="3">
+             " rowspan="5">
               android.<wbr/>statistics.<wbr/>face<wbr/>Landmarks
             </td>
             <td class="entry_type">
@@ -25138,12 +25339,30 @@
           </tr>
           <tr class="entry_cont">
             <td class="entry_details" colspan="6">
-              <p>The coordinate system is that of <a href="#static_android.sensor.info.activeArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>active<wbr/>Array<wbr/>Size</a>,<wbr/> with
+              <p>For devices not supporting <a href="#controls_android.distortionCorrection.mode">android.<wbr/>distortion<wbr/>Correction.<wbr/>mode</a> control,<wbr/> the coordinate
+system always follows that of <a href="#static_android.sensor.info.activeArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>active<wbr/>Array<wbr/>Size</a>,<wbr/> with <code>(0,<wbr/> 0)</code> being
+the top-left pixel of the active array.<wbr/></p>
+<p>For devices supporting <a href="#controls_android.distortionCorrection.mode">android.<wbr/>distortion<wbr/>Correction.<wbr/>mode</a> control,<wbr/> the coordinate
+system depends on the mode being set.<wbr/>
+When the distortion correction mode is OFF,<wbr/> the coordinate system follows
+<a href="#static_android.sensor.info.preCorrectionActiveArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>pre<wbr/>Correction<wbr/>Active<wbr/>Array<wbr/>Size</a>,<wbr/> with
+<code>(0,<wbr/> 0)</code> being the top-left pixel of the pre-correction active array.<wbr/>
+When the distortion correction mode is not OFF,<wbr/> the coordinate system follows
+<a href="#static_android.sensor.info.activeArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>active<wbr/>Array<wbr/>Size</a>,<wbr/> with
 <code>(0,<wbr/> 0)</code> being the top-left pixel of the active array.<wbr/></p>
 <p>Only available if <a href="#controls_android.statistics.faceDetectMode">android.<wbr/>statistics.<wbr/>face<wbr/>Detect<wbr/>Mode</a> == FULL</p>
             </td>
           </tr>
 
+          <tr class="entries_header">
+            <th class="th_details" colspan="6">HAL Implementation Details</th>
+          </tr>
+          <tr class="entry_cont">
+            <td class="entry_details" colspan="6">
+              <p>HAL must always report face landmarks in the coordinate system of pre-correction
+active array.<wbr/></p>
+            </td>
+          </tr>
 
           <tr class="entry_spacer"><td class="entry_spacer" colspan="7"></td></tr>
            <!-- end of entry -->
@@ -25151,7 +25370,7 @@
                 
           <tr class="entry" id="dynamic_android.statistics.faceRectangles">
             <td class="entry_name
-             " rowspan="3">
+             " rowspan="5">
               android.<wbr/>statistics.<wbr/>face<wbr/>Rectangles
             </td>
             <td class="entry_type">
@@ -25199,12 +25418,30 @@
           </tr>
           <tr class="entry_cont">
             <td class="entry_details" colspan="6">
-              <p>The coordinate system is that of <a href="#static_android.sensor.info.activeArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>active<wbr/>Array<wbr/>Size</a>,<wbr/> with
+              <p>For devices not supporting <a href="#controls_android.distortionCorrection.mode">android.<wbr/>distortion<wbr/>Correction.<wbr/>mode</a> control,<wbr/> the coordinate
+system always follows that of <a href="#static_android.sensor.info.activeArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>active<wbr/>Array<wbr/>Size</a>,<wbr/> with <code>(0,<wbr/> 0)</code> being
+the top-left pixel of the active array.<wbr/></p>
+<p>For devices supporting <a href="#controls_android.distortionCorrection.mode">android.<wbr/>distortion<wbr/>Correction.<wbr/>mode</a> control,<wbr/> the coordinate
+system depends on the mode being set.<wbr/>
+When the distortion correction mode is OFF,<wbr/> the coordinate system follows
+<a href="#static_android.sensor.info.preCorrectionActiveArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>pre<wbr/>Correction<wbr/>Active<wbr/>Array<wbr/>Size</a>,<wbr/> with
+<code>(0,<wbr/> 0)</code> being the top-left pixel of the pre-correction active array.<wbr/>
+When the distortion correction mode is not OFF,<wbr/> the coordinate system follows
+<a href="#static_android.sensor.info.activeArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>active<wbr/>Array<wbr/>Size</a>,<wbr/> with
 <code>(0,<wbr/> 0)</code> being the top-left pixel of the active array.<wbr/></p>
 <p>Only available if <a href="#controls_android.statistics.faceDetectMode">android.<wbr/>statistics.<wbr/>face<wbr/>Detect<wbr/>Mode</a> != OFF</p>
             </td>
           </tr>
 
+          <tr class="entries_header">
+            <th class="th_details" colspan="6">HAL Implementation Details</th>
+          </tr>
+          <tr class="entry_cont">
+            <td class="entry_details" colspan="6">
+              <p>HAL must always report face rectangles in the coordinate system of pre-correction
+active array.<wbr/></p>
+            </td>
+          </tr>
 
           <tr class="entry_spacer"><td class="entry_spacer" colspan="7"></td></tr>
            <!-- end of entry -->
@@ -26222,7 +26459,7 @@
                 
           <tr class="entry" id="dynamic_android.statistics.oisDataMode">
             <td class="entry_name
-             " rowspan="1">
+             " rowspan="3">
               android.<wbr/>statistics.<wbr/>ois<wbr/>Data<wbr/>Mode
             </td>
             <td class="entry_type">
@@ -26248,8 +26485,8 @@
             </td> <!-- entry_type -->
 
             <td class="entry_description">
-              <p>A control for selecting whether OIS position information is included in output
-result metadata.<wbr/></p>
+              <p>A control for selecting whether optical stabilization (OIS) position
+information is included in output result metadata.<wbr/></p>
             </td>
 
             <td class="entry_units">
@@ -26267,6 +26504,19 @@
             </td>
 
           </tr>
+          <tr class="entries_header">
+            <th class="th_details" colspan="6">Details</th>
+          </tr>
+          <tr class="entry_cont">
+            <td class="entry_details" colspan="6">
+              <p>Since optical image stabilization generally involves motion much faster than the duration
+of individualq image exposure,<wbr/> multiple OIS samples can be included for a single capture
+result.<wbr/> For example,<wbr/> if the OIS reporting operates at 200 Hz,<wbr/> a typical camera operating
+at 30fps may have 6-7 OIS samples per capture result.<wbr/> This information can be combined
+with the rolling shutter skew to account for lens motion during image exposure in
+post-processing algorithms.<wbr/></p>
+            </td>
+          </tr>
 
 
           <tr class="entry_spacer"><td class="entry_spacer" colspan="7"></td></tr>
@@ -26374,11 +26624,15 @@
           <tr class="entry_cont">
             <td class="entry_details" colspan="6">
               <p>The array contains the amount of shifts in x direction,<wbr/> in pixels,<wbr/> based on OIS samples.<wbr/>
-A positive value is a shift from left to right in active array coordinate system.<wbr/> For
-example,<wbr/> if the optical center is (1000,<wbr/> 500) in active array coordinates,<wbr/> a shift of
-(3,<wbr/> 0) puts the new optical center at (1003,<wbr/> 500).<wbr/></p>
+A positive value is a shift from left to right in the pre-correction active array
+coordinate system.<wbr/> For example,<wbr/> if the optical center is (1000,<wbr/> 500) in pre-correction
+active array coordinates,<wbr/> a shift of (3,<wbr/> 0) puts the new optical center at (1003,<wbr/> 500).<wbr/></p>
 <p>The number of shifts must match the number of timestamps in
 <a href="#dynamic_android.statistics.oisTimestamps">android.<wbr/>statistics.<wbr/>ois<wbr/>Timestamps</a>.<wbr/></p>
+<p>The OIS samples are not affected by whether lens distortion correction is enabled (on
+supporting devices).<wbr/> They are always reported in pre-correction active array coordinates,<wbr/>
+since the scaling of OIS shifts would depend on the specific spot on the sensor the shift
+is needed.<wbr/></p>
             </td>
           </tr>
 
@@ -26433,11 +26687,15 @@
           <tr class="entry_cont">
             <td class="entry_details" colspan="6">
               <p>The array contains the amount of shifts in y direction,<wbr/> in pixels,<wbr/> based on OIS samples.<wbr/>
-A positive value is a shift from top to bottom in active array coordinate system.<wbr/> For
-example,<wbr/> if the optical center is (1000,<wbr/> 500) in active array coordinates,<wbr/> a shift of
-(0,<wbr/> 5) puts the new optical center at (1000,<wbr/> 505).<wbr/></p>
+A positive value is a shift from top to bottom in pre-correction active array coordinate
+system.<wbr/> For example,<wbr/> if the optical center is (1000,<wbr/> 500) in active array coordinates,<wbr/> a
+shift of (0,<wbr/> 5) puts the new optical center at (1000,<wbr/> 505).<wbr/></p>
 <p>The number of shifts must match the number of timestamps in
 <a href="#dynamic_android.statistics.oisTimestamps">android.<wbr/>statistics.<wbr/>ois<wbr/>Timestamps</a>.<wbr/></p>
+<p>The OIS samples are not affected by whether lens distortion correction is enabled (on
+supporting devices).<wbr/> They are always reported in pre-correction active array coordinates,<wbr/>
+since the scaling of OIS shifts would depend on the specific spot on the sensor the shift
+is needed.<wbr/></p>
             </td>
           </tr>
 
@@ -26469,7 +26727,7 @@
             </td> <!-- entry_type -->
 
             <td class="entry_description">
-              <p>An array of OIS samples.<wbr/></p>
+              <p>An array of optical stabilization (OIS) position samples.<wbr/></p>
             </td>
 
             <td class="entry_units">
@@ -26493,12 +26751,18 @@
             <td class="entry_details" colspan="6">
               <p>Each OIS sample contains the timestamp and the amount of shifts in x and y direction,<wbr/>
 in pixels,<wbr/> of the OIS sample.<wbr/></p>
-<p>A positive value for a shift in x direction is a shift from left to right in active array
-coordinate system.<wbr/> For example,<wbr/> if the optical center is (1000,<wbr/> 500) in active array
-coordinates,<wbr/> a shift of (3,<wbr/> 0) puts the new optical center at (1003,<wbr/> 500).<wbr/></p>
-<p>A positive value for a shift in y direction is a shift from top to bottom in active array
-coordinate system.<wbr/> For example,<wbr/> if the optical center is (1000,<wbr/> 500) in active array
-coordinates,<wbr/> a shift of (0,<wbr/> 5) puts the new optical center at (1000,<wbr/> 505).<wbr/></p>
+<p>A positive value for a shift in x direction is a shift from left to right in the
+pre-correction active array coordinate system.<wbr/> For example,<wbr/> if the optical center is
+(1000,<wbr/> 500) in pre-correction active array coordinates,<wbr/> a shift of (3,<wbr/> 0) puts the new
+optical center at (1003,<wbr/> 500).<wbr/></p>
+<p>A positive value for a shift in y direction is a shift from top to bottom in
+pre-correction active array coordinate system.<wbr/> For example,<wbr/> if the optical center is
+(1000,<wbr/> 500) in active array coordinates,<wbr/> a shift of (0,<wbr/> 5) puts the new optical center at
+(1000,<wbr/> 505).<wbr/></p>
+<p>The OIS samples are not affected by whether lens distortion correction is enabled (on
+supporting devices).<wbr/> They are always reported in pre-correction active array coordinates,<wbr/>
+since the scaling of OIS shifts would depend on the specific spot on the sensor the shift
+is needed.<wbr/></p>
             </td>
           </tr>
 
@@ -28290,12 +28554,26 @@
 the following code snippet can be used:</p>
 <pre><code>//<wbr/> Returns true if the device supports the required hardware level,<wbr/> or better.<wbr/>
 boolean isHardwareLevelSupported(CameraCharacteristics c,<wbr/> int requiredLevel) {
+    final int[] sortedHwLevels = {
+        Camera<wbr/>Characteristics.<wbr/>INFO_<wbr/>SUPPORTED_<wbr/>HARDWARE_<wbr/>LEVEL_<wbr/>LEGACY,<wbr/>
+        Camera<wbr/>Characteristics.<wbr/>INFO_<wbr/>SUPPORTED_<wbr/>HARDWARE_<wbr/>LEVEL_<wbr/>EXTERNAL,<wbr/>
+        Camera<wbr/>Characteristics.<wbr/>INFO_<wbr/>SUPPORTED_<wbr/>HARDWARE_<wbr/>LEVEL_<wbr/>LIMITED,<wbr/>
+        Camera<wbr/>Characteristics.<wbr/>INFO_<wbr/>SUPPORTED_<wbr/>HARDWARE_<wbr/>LEVEL_<wbr/>FULL,<wbr/>
+        Camera<wbr/>Characteristics.<wbr/>INFO_<wbr/>SUPPORTED_<wbr/>HARDWARE_<wbr/>LEVEL_<wbr/>3
+    };
     int deviceLevel = c.<wbr/>get(Camera<wbr/>Characteristics.<wbr/>INFO_<wbr/>SUPPORTED_<wbr/>HARDWARE_<wbr/>LEVEL);
-    if (deviceLevel == Camera<wbr/>Characteristics.<wbr/>INFO_<wbr/>SUPPORTED_<wbr/>HARDWARE_<wbr/>LEVEL_<wbr/>LEGACY) {
-        return requiredLevel == deviceLevel;
+    if (requiredLevel == deviceLevel) {
+        return true;
     }
-    //<wbr/> deviceLevel is not LEGACY,<wbr/> can use numerical sort
-    return requiredLevel &lt;= deviceLevel;
+
+    for (int sortedlevel : sortedHwLevels) {
+        if (sortedlevel == requiredLevel) {
+            return true;
+        } else if (sortedlevel == deviceLevel) {
+            return false;
+        }
+    }
+    return false; //<wbr/> Should never reach here
 }
 </code></pre>
 <p>At a high level,<wbr/> the levels are:</p>
@@ -28309,6 +28587,8 @@
   post-processing settings,<wbr/> and image capture at a high rate.<wbr/></li>
 <li><code>LEVEL_<wbr/>3</code> devices additionally support YUV reprocessing and RAW image capture,<wbr/> along
   with additional output stream configurations.<wbr/></li>
+<li><code>EXTERNAL</code> devices are similar to <code>LIMITED</code> devices with exceptions like some sensor or
+  lens information not reorted or less stable framerates.<wbr/></li>
 </ul>
 <p>See the individual level enums for full descriptions of the supported capabilities.<wbr/>  The
 <a href="#static_android.request.availableCapabilities">android.<wbr/>request.<wbr/>available<wbr/>Capabilities</a> entry describes the device's capabilities at a
@@ -29956,15 +30236,28 @@
 any correction at all would slow down capture rate.<wbr/>  Every output stream will have a
 similar amount of enhancement applied.<wbr/></p>
 <p>The correction only applies to processed outputs such as YUV,<wbr/> JPEG,<wbr/> or DEPTH16; it is not
-applied to any RAW output.<wbr/>  Metadata coordinates such as face rectangles or metering
-regions are also not affected by correction.<wbr/></p>
-<p>Applications enabling distortion correction need to pay extra attention when converting
-image coordinates between corrected output buffers and the sensor array.<wbr/> For example,<wbr/> if
-the app supports tap-to-focus and enables correction,<wbr/> it then has to apply the distortion
-model described in <a href="#static_android.lens.distortion">android.<wbr/>lens.<wbr/>distortion</a> to the image buffer tap coordinates to properly
-calculate the tap position on the sensor active array to be used with
-<a href="#controls_android.control.afRegions">android.<wbr/>control.<wbr/>af<wbr/>Regions</a>.<wbr/> The same applies in reverse to detected face rectangles if
-they need to be drawn on top of the corrected output buffers.<wbr/></p>
+applied to any RAW output.<wbr/></p>
+<p>This control will be on by default on devices that support this control.<wbr/> Applications
+disabling distortion correction need to pay extra attention with the coordinate system of
+metering regions,<wbr/> crop region,<wbr/> and face rectangles.<wbr/> When distortion correction is OFF,<wbr/>
+metadata coordinates follow the coordinate system of
+<a href="#static_android.sensor.info.preCorrectionActiveArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>pre<wbr/>Correction<wbr/>Active<wbr/>Array<wbr/>Size</a>.<wbr/> When distortion is not OFF,<wbr/> metadata
+coordinates follow the coordinate system of <a href="#static_android.sensor.info.activeArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>active<wbr/>Array<wbr/>Size</a>.<wbr/>  The
+camera device will map these metadata fields to match the corrected image produced by the
+camera device,<wbr/> for both capture requests and results.<wbr/>  However,<wbr/> this mapping is not very
+precise,<wbr/> since rectangles do not generally map to rectangles when corrected.<wbr/>  Only linear
+scaling between the active array and precorrection active array coordinates is
+performed.<wbr/> Applications that require precise correction of metadata need to undo that
+linear scaling,<wbr/> and apply a more complete correction that takes into the account the app's
+own requirements.<wbr/></p>
+<p>The full list of metadata that is affected in this way by distortion correction is:</p>
+<ul>
+<li><a href="#controls_android.control.afRegions">android.<wbr/>control.<wbr/>af<wbr/>Regions</a></li>
+<li><a href="#controls_android.control.aeRegions">android.<wbr/>control.<wbr/>ae<wbr/>Regions</a></li>
+<li><a href="#controls_android.control.awbRegions">android.<wbr/>control.<wbr/>awb<wbr/>Regions</a></li>
+<li><a href="#controls_android.scaler.cropRegion">android.<wbr/>scaler.<wbr/>crop<wbr/>Region</a></li>
+<li><a href="#dynamic_android.statistics.faces">android.<wbr/>statistics.<wbr/>faces</a></li>
+</ul>
             </td>
           </tr>
 
@@ -30170,15 +30463,28 @@
 any correction at all would slow down capture rate.<wbr/>  Every output stream will have a
 similar amount of enhancement applied.<wbr/></p>
 <p>The correction only applies to processed outputs such as YUV,<wbr/> JPEG,<wbr/> or DEPTH16; it is not
-applied to any RAW output.<wbr/>  Metadata coordinates such as face rectangles or metering
-regions are also not affected by correction.<wbr/></p>
-<p>Applications enabling distortion correction need to pay extra attention when converting
-image coordinates between corrected output buffers and the sensor array.<wbr/> For example,<wbr/> if
-the app supports tap-to-focus and enables correction,<wbr/> it then has to apply the distortion
-model described in <a href="#static_android.lens.distortion">android.<wbr/>lens.<wbr/>distortion</a> to the image buffer tap coordinates to properly
-calculate the tap position on the sensor active array to be used with
-<a href="#controls_android.control.afRegions">android.<wbr/>control.<wbr/>af<wbr/>Regions</a>.<wbr/> The same applies in reverse to detected face rectangles if
-they need to be drawn on top of the corrected output buffers.<wbr/></p>
+applied to any RAW output.<wbr/></p>
+<p>This control will be on by default on devices that support this control.<wbr/> Applications
+disabling distortion correction need to pay extra attention with the coordinate system of
+metering regions,<wbr/> crop region,<wbr/> and face rectangles.<wbr/> When distortion correction is OFF,<wbr/>
+metadata coordinates follow the coordinate system of
+<a href="#static_android.sensor.info.preCorrectionActiveArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>pre<wbr/>Correction<wbr/>Active<wbr/>Array<wbr/>Size</a>.<wbr/> When distortion is not OFF,<wbr/> metadata
+coordinates follow the coordinate system of <a href="#static_android.sensor.info.activeArraySize">android.<wbr/>sensor.<wbr/>info.<wbr/>active<wbr/>Array<wbr/>Size</a>.<wbr/>  The
+camera device will map these metadata fields to match the corrected image produced by the
+camera device,<wbr/> for both capture requests and results.<wbr/>  However,<wbr/> this mapping is not very
+precise,<wbr/> since rectangles do not generally map to rectangles when corrected.<wbr/>  Only linear
+scaling between the active array and precorrection active array coordinates is
+performed.<wbr/> Applications that require precise correction of metadata need to undo that
+linear scaling,<wbr/> and apply a more complete correction that takes into the account the app's
+own requirements.<wbr/></p>
+<p>The full list of metadata that is affected in this way by distortion correction is:</p>
+<ul>
+<li><a href="#controls_android.control.afRegions">android.<wbr/>control.<wbr/>af<wbr/>Regions</a></li>
+<li><a href="#controls_android.control.aeRegions">android.<wbr/>control.<wbr/>ae<wbr/>Regions</a></li>
+<li><a href="#controls_android.control.awbRegions">android.<wbr/>control.<wbr/>awb<wbr/>Regions</a></li>
+<li><a href="#controls_android.scaler.cropRegion">android.<wbr/>scaler.<wbr/>crop<wbr/>Region</a></li>
+<li><a href="#dynamic_android.statistics.faces">android.<wbr/>statistics.<wbr/>faces</a></li>
+</ul>
             </td>
           </tr>
 
diff --git a/camera/docs/metadata_definitions.xml b/camera/docs/metadata_definitions.xml
index 6059fa0..c5a7456 100644
--- a/camera/docs/metadata_definitions.xml
+++ b/camera/docs/metadata_definitions.xml
@@ -686,9 +686,12 @@
             <size>area_count</size>
           </array>
           <description>List of metering areas to use for auto-exposure adjustment.</description>
-          <units>Pixel coordinates within android.sensor.info.activeArraySize</units>
+          <units>Pixel coordinates within android.sensor.info.activeArraySize or
+            android.sensor.info.preCorrectionActiveArraySize depending on
+            distortion correction capability and mode</units>
           <range>Coordinates must be between `[(0,0), (width, height))` of
-          android.sensor.info.activeArraySize</range>
+            android.sensor.info.activeArraySize or android.sensor.info.preCorrectionActiveArraySize
+            depending on distortion correction capability and mode</range>
           <details>
               Not available if android.control.maxRegionsAe is 0.
               Otherwise will always be present.
@@ -696,11 +699,27 @@
               The maximum number of regions supported by the device is determined by the value
               of android.control.maxRegionsAe.
 
-              The coordinate system is based on the active pixel array,
-              with (0,0) being the top-left pixel in the active pixel array, and
+              For devices not supporting android.distortionCorrection.mode control, the coordinate
+              system always follows that of android.sensor.info.activeArraySize, with (0,0) being
+              the top-left pixel in the active pixel array, and
               (android.sensor.info.activeArraySize.width - 1,
-              android.sensor.info.activeArraySize.height - 1) being the
-              bottom-right pixel in the active pixel array.
+              android.sensor.info.activeArraySize.height - 1) being the bottom-right pixel in the
+              active pixel array.
+
+              For devices supporting android.distortionCorrection.mode control, the coordinate
+              system depends on the mode being set.
+              When the distortion correction mode is OFF, the coordinate system follows
+              android.sensor.info.preCorrectionActiveArraySize, with
+              `(0, 0)` being the top-left pixel of the pre-correction active array, and
+              (android.sensor.info.preCorrectionActiveArraySize.width - 1,
+              android.sensor.info.preCorrectionActiveArraySize.height - 1) being the bottom-right
+              pixel in the pre-correction active pixel array.
+              When the distortion correction mode is not OFF, the coordinate system follows
+              android.sensor.info.activeArraySize, with
+              `(0, 0)` being the top-left pixel of the active array, and
+              (android.sensor.info.activeArraySize.width - 1,
+              android.sensor.info.activeArraySize.height - 1) being the bottom-right pixel in the
+              active pixel array.
 
               The weight must be within `[0, 1000]`, and represents a weight
               for every pixel in the area. This means that a large metering area
@@ -734,6 +753,8 @@
               (xmin, ymin, xmax, ymax, weight).
               The rectangle is defined to be inclusive on xmin and ymin, but
               exclusive on xmax and ymax.
+              HAL must always report metering regions in the coordinate system of pre-correction
+              active array.
           </hal_details>
           <tag id="BC" />
         </entry>
@@ -969,9 +990,12 @@
             <size>area_count</size>
           </array>
           <description>List of metering areas to use for auto-focus.</description>
-          <units>Pixel coordinates within android.sensor.info.activeArraySize</units>
+          <units>Pixel coordinates within android.sensor.info.activeArraySize or
+            android.sensor.info.preCorrectionActiveArraySize depending on
+            distortion correction capability and mode</units>
           <range>Coordinates must be between `[(0,0), (width, height))` of
-          android.sensor.info.activeArraySize</range>
+            android.sensor.info.activeArraySize or android.sensor.info.preCorrectionActiveArraySize
+            depending on distortion correction capability and mode</range>
           <details>
               Not available if android.control.maxRegionsAf is 0.
               Otherwise will always be present.
@@ -979,11 +1003,28 @@
               The maximum number of focus areas supported by the device is determined by the value
               of android.control.maxRegionsAf.
 
-              The coordinate system is based on the active pixel array,
-              with (0,0) being the top-left pixel in the active pixel array, and
+
+              For devices not supporting android.distortionCorrection.mode control, the coordinate
+              system always follows that of android.sensor.info.activeArraySize, with (0,0) being
+              the top-left pixel in the active pixel array, and
               (android.sensor.info.activeArraySize.width - 1,
-              android.sensor.info.activeArraySize.height - 1) being the
-              bottom-right pixel in the active pixel array.
+              android.sensor.info.activeArraySize.height - 1) being the bottom-right pixel in the
+              active pixel array.
+
+              For devices supporting android.distortionCorrection.mode control, the coordinate
+              system depends on the mode being set.
+              When the distortion correction mode is OFF, the coordinate system follows
+              android.sensor.info.preCorrectionActiveArraySize, with
+              `(0, 0)` being the top-left pixel of the pre-correction active array, and
+              (android.sensor.info.preCorrectionActiveArraySize.width - 1,
+              android.sensor.info.preCorrectionActiveArraySize.height - 1) being the bottom-right
+              pixel in the pre-correction active pixel array.
+              When the distortion correction mode is not OFF, the coordinate system follows
+              android.sensor.info.activeArraySize, with
+              `(0, 0)` being the top-left pixel of the active array, and
+              (android.sensor.info.activeArraySize.width - 1,
+              android.sensor.info.activeArraySize.height - 1) being the bottom-right pixel in the
+              active pixel array.
 
               The weight must be within `[0, 1000]`, and represents a weight
               for every pixel in the area. This means that a large metering area
@@ -1018,6 +1059,8 @@
               (xmin, ymin, xmax, ymax, weight).
               The rectangle is defined to be inclusive on xmin and ymin, but
               exclusive on xmax and ymax.
+              HAL must always report metering regions in the coordinate system of pre-correction
+              active array.
           </hal_details>
           <tag id="BC" />
         </entry>
@@ -1279,9 +1322,12 @@
           </array>
           <description>List of metering areas to use for auto-white-balance illuminant
           estimation.</description>
-          <units>Pixel coordinates within android.sensor.info.activeArraySize</units>
+          <units>Pixel coordinates within android.sensor.info.activeArraySize or
+            android.sensor.info.preCorrectionActiveArraySize depending on
+            distortion correction capability and mode</units>
           <range>Coordinates must be between `[(0,0), (width, height))` of
-          android.sensor.info.activeArraySize</range>
+            android.sensor.info.activeArraySize or android.sensor.info.preCorrectionActiveArraySize
+            depending on distortion correction capability and mode</range>
           <details>
               Not available if android.control.maxRegionsAwb is 0.
               Otherwise will always be present.
@@ -1289,11 +1335,27 @@
               The maximum number of regions supported by the device is determined by the value
               of android.control.maxRegionsAwb.
 
-              The coordinate system is based on the active pixel array,
-              with (0,0) being the top-left pixel in the active pixel array, and
+              For devices not supporting android.distortionCorrection.mode control, the coordinate
+              system always follows that of android.sensor.info.activeArraySize, with (0,0) being
+              the top-left pixel in the active pixel array, and
               (android.sensor.info.activeArraySize.width - 1,
-              android.sensor.info.activeArraySize.height - 1) being the
-              bottom-right pixel in the active pixel array.
+              android.sensor.info.activeArraySize.height - 1) being the bottom-right pixel in the
+              active pixel array.
+
+              For devices supporting android.distortionCorrection.mode control, the coordinate
+              system depends on the mode being set.
+              When the distortion correction mode is OFF, the coordinate system follows
+              android.sensor.info.preCorrectionActiveArraySize, with
+              `(0, 0)` being the top-left pixel of the pre-correction active array, and
+              (android.sensor.info.preCorrectionActiveArraySize.width - 1,
+              android.sensor.info.preCorrectionActiveArraySize.height - 1) being the bottom-right
+              pixel in the pre-correction active pixel array.
+              When the distortion correction mode is not OFF, the coordinate system follows
+              android.sensor.info.activeArraySize, with
+              `(0, 0)` being the top-left pixel of the active array, and
+              (android.sensor.info.activeArraySize.width - 1,
+              android.sensor.info.activeArraySize.height - 1) being the bottom-right pixel in the
+              active pixel array.
 
               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
@@ -1327,6 +1389,8 @@
               (xmin, ymin, xmax, ymax, weight).
               The rectangle is defined to be inclusive on xmin and ymin, but
               exclusive on xmax and ymax.
+              HAL must always report metering regions in the coordinate system of pre-correction
+              active array.
           </hal_details>
           <tag id="BC" />
         </entry>
@@ -1643,7 +1707,7 @@
             <value optional="true">CANDLELIGHT
               <notes>
               Optimized for dim settings where the main light source
-              is a flame.
+              is a candle.
               </notes>
             </value>
             <value optional="true">BARCODE
@@ -3410,9 +3474,9 @@
           </details>
           <hal_details>
           The HAL must not squeeze or stretch the downscaled primary image to generate thumbnail.
-          The cropping must be done on the primary jpeg image rather than the sensor active array.
-          The stream cropping rule specified by "S5. Cropping" in camera3.h doesn't apply to the
-          thumbnail image cropping.
+          The cropping must be done on the primary jpeg image rather than the sensor pre-correction
+          active array. The stream cropping rule specified by "S5. Cropping" in camera3.h doesn't
+          apply to the thumbnail image cropping.
           </hal_details>
           <tag id="BC" />
         </entry>
@@ -3896,7 +3960,9 @@
             If this device is the largest or only camera device with a given facing, then this
             position will be `(0, 0, 0)`; 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 `(0.03, 0, 0)`.
+            report `(0.03, 0, 0)`.  Note that this means that, for many computer vision
+            applications, the position needs to be negated to convert it to a translation from the
+            camera to the origin.
 
             To transform a pixel coordinates between two cameras facing the same direction, first
             the source camera android.lens.distortion must be corrected for.  Then the source
@@ -3911,7 +3977,8 @@
             image then needs to be corrected for radial distortion before comparison or sampling.
 
             When android.lens.poseReference is GYROSCOPE, then this position is relative to
-            the center of the primary gyroscope on the device.
+            the center of the primary gyroscope on the device. The axis definitions are the same as
+            with PRIMARY_CAMERA.
           </details>
           <tag id="DEPTH" />
         </entry>
@@ -4032,14 +4099,17 @@
 
             which can then be combined with the camera pose rotation
             `R` and translation `t` (android.lens.poseRotation and
-            android.lens.poseTranslation, respective) to calculate the
+            android.lens.poseTranslation, respectively) to calculate the
             complete transform from world coordinates to pixel
             coordinates:
 
-                P = [ K 0   * [ R t
-                     0 1 ]     0 1 ]
+                P = [ K 0   * [ R -Rt
+                     0 1 ]      0 1 ]
 
-            and with `p_w` being a point in the world coordinate system
+            (Note the negation of poseTranslation when mapping from camera
+            to world coordinates, and multiplication by the rotation).
+
+            With `p_w` being a point in the world coordinate system
             and `p_s` being a point in the camera active pixel array
             coordinate system, and with the mapping including the
             homogeneous division by z:
@@ -4063,6 +4133,14 @@
             activeArraySize rectangle), to determine the final pixel
             coordinate of the world point for processed (non-RAW)
             output buffers.
+
+            For camera devices, the center of pixel `(x,y)` is located at
+            coordinate `(x + 0.5, y + 0.5)`.  So on a device with a
+            precorrection active array of size `(10,10)`, the valid pixel
+            indices go from `(0,0)-(9,9)`, and an perfectly-built camera would
+            have an optical center at the exact center of the pixel grid, at
+            coordinates `(5.0, 5.0)`, which is the top-left corner of pixel
+            `(5,5)`.
           </details>
           <tag id="DEPTH" />
         </entry>
@@ -5217,10 +5295,11 @@
 
               This capability requires the camera device to support the following:
 
-              * This camera device must list the following static metadata entries in {@link
-                android.hardware.camera2.CameraCharacteristics}:
-                  - android.logicalMultiCamera.physicalIds
-                  - android.logicalMultiCamera.sensorSyncType
+              * The IDs of underlying physical cameras are returned via
+                {@link android.hardware.camera2.CameraCharacteristics#getPhysicalCameraIds}.
+              * This camera device must list static metadata
+                android.logicalMultiCamera.sensorSyncType in
+                {@link android.hardware.camera2.CameraCharacteristics}.
               * The underlying physical cameras' static metadata must list the following entries,
                 so that the application can correlate pixels from the physical streams:
                   - android.lens.poseReference
@@ -5577,13 +5656,24 @@
           </array>
           <description>The desired region of the sensor to read out for this capture.</description>
           <units>Pixel coordinates relative to
-          android.sensor.info.activeArraySize</units>
+          android.sensor.info.activeArraySize or
+          android.sensor.info.preCorrectionActiveArraySize depending on distortion correction
+          capability and mode</units>
           <details>
             This control can be used to implement digital zoom.
 
-            The crop region coordinate system is based off
-            android.sensor.info.activeArraySize, with `(0, 0)` being the
-            top-left corner of the sensor active array.
+            For devices not supporting android.distortionCorrection.mode control, the coordinate
+            system always follows that of android.sensor.info.activeArraySize, with `(0, 0)` being
+            the top-left pixel of the active array.
+
+            For devices supporting android.distortionCorrection.mode control, the coordinate
+            system depends on the mode being set.
+            When the distortion correction mode is OFF, the coordinate system follows
+            android.sensor.info.preCorrectionActiveArraySize, with
+            `(0, 0)` being the top-left pixel of the pre-correction active array.
+            When the distortion correction mode is not OFF, the coordinate system follows
+            android.sensor.info.activeArraySize, with
+            `(0, 0)` being the top-left pixel of the active array.
 
             Output streams use this rectangle to produce their output,
             cropping to a smaller region if necessary to maintain the
@@ -5608,11 +5698,18 @@
             streams will match exactly. These additional crops will
             be centered within the crop region.
 
-            The width and height of the crop region cannot
-            be set to be smaller than
+            If the coordinate system is android.sensor.info.activeArraySize, the width and height
+            of the crop region cannot be set to be smaller than
             `floor( activeArraySize.width / android.scaler.availableMaxDigitalZoom )` and
             `floor( activeArraySize.height / android.scaler.availableMaxDigitalZoom )`, respectively.
 
+            If the coordinate system is android.sensor.info.preCorrectionActiveArraySize, the width
+            and height of the crop region cannot be set to be smaller than
+            `floor( preCorrectionActiveArraySize.width / android.scaler.availableMaxDigitalZoom )`
+            and
+            `floor( preCorrectionActiveArraySize.height / android.scaler.availableMaxDigitalZoom )`,
+            respectively.
+
             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
@@ -5632,30 +5729,31 @@
             possible.
 
             For a set of output streams configured, if the sensor output is cropped to a smaller
-            size than active array size, the HAL need follow below cropping rules:
+            size than pre-correction active array size, the HAL need follow below cropping rules:
 
-            * The HAL need handle the cropRegion as if the sensor crop size is the effective active
-            array size.More specifically, the HAL must transform the request cropRegion from
-            android.sensor.info.activeArraySize to the sensor cropped pixel area size in this way:
+            * The HAL need handle the cropRegion as if the sensor crop size is the effective
+            pre-correction active array size. More specifically, the HAL must transform the request
+            cropRegion from android.sensor.info.preCorrectionActiveArraySize to the sensor cropped
+            pixel area size in this way:
                 1. Translate the requested cropRegion w.r.t., the left top corner of the sensor
                 cropped pixel area by (tx, ty),
-                where `ty = sensorCrop.top * (sensorCrop.height / activeArraySize.height)`
-                and `tx = sensorCrop.left * (sensorCrop.width / activeArraySize.width)`. The
-                (sensorCrop.top, sensorCrop.left) is the coordinate based off the
+                where `ty = sensorCrop.top * (sensorCrop.height / preCorrectionActiveArraySize.height)`
+                and `tx = sensorCrop.left * (sensorCrop.width / preCorrectionActiveArraySize.width)`.
+                The (sensorCrop.top, sensorCrop.left) is the coordinate based off the
                 android.sensor.info.activeArraySize.
                 2. Scale the width and height of requested cropRegion with scaling factor of
-                sensorCrop.width/activeArraySize.width and sensorCrop.height/activeArraySize.height
+                sensorCrop.width/preCorrectionActiveArraySize.width and sensorCrop.height/preCorrectionActiveArraySize.height
                 respectively.
             Once this new cropRegion is calculated, the HAL must use this region to crop the image
-            with regard to the sensor crop size (effective active array size). The HAL still need
-            follow the general cropping rule for this new cropRegion and effective active
-            array size.
+            with regard to the sensor crop size (effective pre-correction active array size). The
+            HAL still need follow the general cropping rule for this new cropRegion and effective
+            pre-correction active array size.
 
-            * The HAL must report the cropRegion with regard to android.sensor.info.activeArraySize.
-            The HAL need convert the new cropRegion generated above w.r.t., full active array size.
-            The reported cropRegion may be slightly different with the requested cropRegion since
-            the HAL may adjust the crop region to account for rounding, conversion error, or other
-            hardware limitations.
+            * The HAL must report the cropRegion with regard to android.sensor.info.preCorrectionActiveArraySize.
+            The HAL need convert the new cropRegion generated above w.r.t., full pre-correction
+            active array size. The reported cropRegion may be slightly different with the requested
+            cropRegion since the HAL may adjust the crop region to account for rounding, conversion
+            error, or other hardware limitations.
 
             HAL2.x uses only (x, y, width)
           </hal_details>
@@ -6517,8 +6615,21 @@
             this field, with `(0, 0)` being the top-left of this rectangle.
 
             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.
+            include black calibration pixels or other inactive regions.
+
+            For devices that do not support android.distortionCorrection.mode control, the active
+            array must be the same as android.sensor.info.preCorrectionActiveArraySize.
+
+            For devices that support android.distortionCorrection.mode control, the active array must
+            be enclosed by android.sensor.info.preCorrectionActiveArraySize. The difference between
+            pre-correction active array and active array accounts for scaling or cropping caused
+            by lens geometric distortion correction.
+
+            In general, application should always refer to active array size for controls like
+            metering regions or crop region. Two exceptions are when the application is dealing with
+            RAW image buffers (RAW_SENSOR, RAW10, RAW12 etc), or when application explicitly set
+            android.distortionCorrection.mode to OFF. In these cases, application should refer
+            to android.sensor.info.preCorrectionActiveArraySize.
             </details>
             <ndk_details>
             The data representation is `int[4]`, which maps to `(left, top, width, height)`.
@@ -6810,9 +6921,9 @@
 
             1. android.lens.distortion.
 
-            If all of the geometric distortion fields are no-ops, this rectangle will be the same
-            as the post-distortion-corrected rectangle given in
-            android.sensor.info.activeArraySize.
+            If the camera device doesn't support geometric distortion correction, or all of the
+            geometric distortion fields are no-ops, this rectangle will be the same as the
+            post-distortion-corrected rectangle given in android.sensor.info.activeArraySize.
 
             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
@@ -8063,10 +8174,24 @@
           <description>List of landmarks for detected
           faces.</description>
           <details>
-            The coordinate system is that of android.sensor.info.activeArraySize, with
+            For devices not supporting android.distortionCorrection.mode control, the coordinate
+            system always follows that of android.sensor.info.activeArraySize, with `(0, 0)` being
+            the top-left pixel of the active array.
+
+            For devices supporting android.distortionCorrection.mode control, the coordinate
+            system depends on the mode being set.
+            When the distortion correction mode is OFF, the coordinate system follows
+            android.sensor.info.preCorrectionActiveArraySize, with
+            `(0, 0)` being the top-left pixel of the pre-correction active array.
+            When the distortion correction mode is not OFF, the coordinate system follows
+            android.sensor.info.activeArraySize, with
             `(0, 0)` being the top-left pixel of the active array.
 
             Only available if android.statistics.faceDetectMode == FULL</details>
+          <hal_details>
+            HAL must always report face landmarks in the coordinate system of pre-correction
+            active array.
+          </hal_details>
           <tag id="BC" />
         </entry>
         <entry name="faceRectangles" type="int32" visibility="ndk_public"
@@ -8079,13 +8204,27 @@
           <description>List of the bounding rectangles for detected
           faces.</description>
           <details>
-            The coordinate system is that of android.sensor.info.activeArraySize, with
+            For devices not supporting android.distortionCorrection.mode control, the coordinate
+            system always follows that of android.sensor.info.activeArraySize, with `(0, 0)` being
+            the top-left pixel of the active array.
+
+            For devices supporting android.distortionCorrection.mode control, the coordinate
+            system depends on the mode being set.
+            When the distortion correction mode is OFF, the coordinate system follows
+            android.sensor.info.preCorrectionActiveArraySize, with
+            `(0, 0)` being the top-left pixel of the pre-correction active array.
+            When the distortion correction mode is not OFF, the coordinate system follows
+            android.sensor.info.activeArraySize, with
             `(0, 0)` being the top-left pixel of the active array.
 
             Only available if android.statistics.faceDetectMode != OFF</details>
           <ndk_details>
-            The data representation is `int[4]`, which maps to `(left, top, width, height)`.
+            The data representation is `int[4]`, which maps to `(left, top, right, bottom)`.
           </ndk_details>
+          <hal_details>
+            HAL must always report face rectangles in the coordinate system of pre-correction
+            active array.
+          </hal_details>
           <tag id="BC" />
         </entry>
         <entry name="faceScores" type="byte" visibility="ndk_public"
@@ -8485,9 +8624,17 @@
             </ndk_notes>
             </value>
           </enum>
-          <description>A control for selecting whether OIS position information is included in output
-          result metadata.</description>
+          <description>A control for selecting whether optical stabilization (OIS) position
+          information is included in output result metadata.</description>
           <range>android.statistics.info.availableOisDataModes</range>
+          <details>
+          Since optical image stabilization generally involves motion much faster than the duration
+          of individualq image exposure, multiple OIS samples can be included for a single capture
+          result. For example, if the OIS reporting operates at 200 Hz, a typical camera operating
+          at 30fps may have 6-7 OIS samples per capture result. This information can be combined
+          with the rolling shutter skew to account for lens motion during image exposure in
+          post-processing algorithms.
+          </details>
         </entry>
       </controls>
       <dynamic>
@@ -8516,12 +8663,17 @@
           <units>Pixels in active array.</units>
           <details>
           The array contains the amount of shifts in x direction, in pixels, based on OIS samples.
-          A positive value is a shift from left to right in active array coordinate system. For
-          example, if the optical center is (1000, 500) in active array coordinates, a shift of
-          (3, 0) puts the new optical center at (1003, 500).
+          A positive value is a shift from left to right in the pre-correction active array
+          coordinate system. For example, if the optical center is (1000, 500) in pre-correction
+          active array coordinates, a shift of (3, 0) puts the new optical center at (1003, 500).
 
           The number of shifts must match the number of timestamps in
           android.statistics.oisTimestamps.
+
+          The OIS samples are not affected by whether lens distortion correction is enabled (on
+          supporting devices). They are always reported in pre-correction active array coordinates,
+          since the scaling of OIS shifts would depend on the specific spot on the sensor the shift
+          is needed.
           </details>
         </entry>
         <entry name="oisYShifts" type="float" visibility="ndk_public" container="array" hal_version="3.3">
@@ -8534,12 +8686,17 @@
           <units>Pixels in active array.</units>
           <details>
           The array contains the amount of shifts in y direction, in pixels, based on OIS samples.
-          A positive value is a shift from top to bottom in active array coordinate system. For
-          example, if the optical center is (1000, 500) in active array coordinates, a shift of
-          (0, 5) puts the new optical center at (1000, 505).
+          A positive value is a shift from top to bottom in pre-correction active array coordinate
+          system. For example, if the optical center is (1000, 500) in active array coordinates, a
+          shift of (0, 5) puts the new optical center at (1000, 505).
 
           The number of shifts must match the number of timestamps in
           android.statistics.oisTimestamps.
+
+          The OIS samples are not affected by whether lens distortion correction is enabled (on
+          supporting devices). They are always reported in pre-correction active array coordinates,
+          since the scaling of OIS shifts would depend on the specific spot on the sensor the shift
+          is needed.
           </details>
         </entry>
         <entry name="oisSamples" type="float" visibility="java_public" synthetic="true"
@@ -8548,19 +8705,26 @@
             <size>n</size>
           </array>
           <description>
-          An array of OIS samples.
+          An array of optical stabilization (OIS) position samples.
           </description>
           <details>
           Each OIS sample contains the timestamp and the amount of shifts in x and y direction,
           in pixels, of the OIS sample.
 
-          A positive value for a shift in x direction is a shift from left to right in active array
-          coordinate system. For example, if the optical center is (1000, 500) in active array
-          coordinates, a shift of (3, 0) puts the new optical center at (1003, 500).
+          A positive value for a shift in x direction is a shift from left to right in the
+          pre-correction active array coordinate system. For example, if the optical center is
+          (1000, 500) in pre-correction active array coordinates, a shift of (3, 0) puts the new
+          optical center at (1003, 500).
 
-          A positive value for a shift in y direction is a shift from top to bottom in active array
-          coordinate system. For example, if the optical center is (1000, 500) in active array
-          coordinates, a shift of (0, 5) puts the new optical center at (1000, 505).
+          A positive value for a shift in y direction is a shift from top to bottom in
+          pre-correction active array coordinate system. For example, if the optical center is
+          (1000, 500) in active array coordinates, a shift of (0, 5) puts the new optical center at
+          (1000, 505).
+
+          The OIS samples are not affected by whether lens distortion correction is enabled (on
+          supporting devices). They are always reported in pre-correction active array coordinates,
+          since the scaling of OIS shifts would depend on the specific spot on the sensor the shift
+          is needed.
           </details>
         </entry>
       </dynamic>
@@ -9110,12 +9274,26 @@
 
               // Returns true if the device supports the required hardware level, or better.
               boolean isHardwareLevelSupported(CameraCharacteristics c, int requiredLevel) {
+                  final int[] sortedHwLevels = {
+                      CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY,
+                      CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_EXTERNAL,
+                      CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED,
+                      CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_FULL,
+                      CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_3
+                  };
                   int deviceLevel = c.get(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL);
-                  if (deviceLevel == CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY) {
-                      return requiredLevel == deviceLevel;
+                  if (requiredLevel == deviceLevel) {
+                      return true;
                   }
-                  // deviceLevel is not LEGACY, can use numerical sort
-                  return requiredLevel &lt;= deviceLevel;
+
+                  for (int sortedlevel : sortedHwLevels) {
+                      if (sortedlevel == requiredLevel) {
+                          return true;
+                      } else if (sortedlevel == deviceLevel) {
+                          return false;
+                      }
+                  }
+                  return false; // Should never reach here
               }
 
           At a high level, the levels are:
@@ -9129,6 +9307,8 @@
             post-processing settings, and image capture at a high rate.
           * `LEVEL_3` devices additionally support YUV reprocessing and RAW image capture, along
             with additional output stream configurations.
+          * `EXTERNAL` devices are similar to `LIMITED` devices with exceptions like some sensor or
+            lens information not reorted or less stable framerates.
 
           See the individual level enums for full descriptions of the supported capabilities.  The
           android.request.availableCapabilities entry describes the device's capabilities at a
@@ -9740,16 +9920,29 @@
           similar amount of enhancement applied.
 
           The correction only applies to processed outputs such as YUV, JPEG, or DEPTH16; it is not
-          applied to any RAW output.  Metadata coordinates such as face rectangles or metering
-          regions are also not affected by correction.
+          applied to any RAW output.
 
-          Applications enabling distortion correction need to pay extra attention when converting
-          image coordinates between corrected output buffers and the sensor array. For example, if
-          the app supports tap-to-focus and enables correction, it then has to apply the distortion
-          model described in android.lens.distortion to the image buffer tap coordinates to properly
-          calculate the tap position on the sensor active array to be used with
-          android.control.afRegions. The same applies in reverse to detected face rectangles if
-          they need to be drawn on top of the corrected output buffers.
+          This control will be on by default on devices that support this control. Applications
+          disabling distortion correction need to pay extra attention with the coordinate system of
+          metering regions, crop region, and face rectangles. When distortion correction is OFF,
+          metadata coordinates follow the coordinate system of
+          android.sensor.info.preCorrectionActiveArraySize. When distortion is not OFF, metadata
+          coordinates follow the coordinate system of android.sensor.info.activeArraySize.  The
+          camera device will map these metadata fields to match the corrected image produced by the
+          camera device, for both capture requests and results.  However, this mapping is not very
+          precise, since rectangles do not generally map to rectangles when corrected.  Only linear
+          scaling between the active array and precorrection active array coordinates is
+          performed. Applications that require precise correction of metadata need to undo that
+          linear scaling, and apply a more complete correction that takes into the account the app's
+          own requirements.
+
+          The full list of metadata that is affected in this way by distortion correction is:
+
+          * android.control.afRegions
+          * android.control.aeRegions
+          * android.control.awbRegions
+          * android.scaler.cropRegion
+          * android.statistics.faces
           </details>
         </entry>
       </controls>
diff --git a/radio/src/radio_metadata.c b/radio/src/radio_metadata.c
index 482dd87..70ff604 100644
--- a/radio/src/radio_metadata.c
+++ b/radio/src/radio_metadata.c
@@ -87,6 +87,9 @@
 
     ALOGV("%s growing from %u to %u", __func__, metadata->size_int, new_size_int);
     metadata = realloc(metadata, new_size_int * sizeof(uint32_t));
+    if (metadata == NULL) {
+        return -ENOMEM;
+    }
     /* move index table */
     memmove((uint32_t *)metadata + new_size_int - (metadata->count + 1),
             (uint32_t *)metadata + metadata->size_int - (metadata->count + 1),