Camera2: Fix metering/focusing region coordinates, minor bugs

- Use active pixel array-based coordinates instead of the normalized
  camera API coordinates for ae/awb/af regions
- Fix calculation of UV stride for YV12 format

Bug: 6243944
Change-Id: I80cbd989858b0a3cb75c6f536c145e16e44fdb25
diff --git a/services/camera/libcameraservice/Camera2Client.cpp b/services/camera/libcameraservice/Camera2Client.cpp
index 21a0547..3f12ed0 100644
--- a/services/camera/libcameraservice/Camera2Client.cpp
+++ b/services/camera/libcameraservice/Camera2Client.cpp
@@ -1561,7 +1561,7 @@
     Vector<Parameters::Area> meteringAreas;
     res = parseAreas(newParams.get(CameraParameters::KEY_METERING_AREAS),
             &meteringAreas);
-    if (res == OK) res = validateAreas(focusingAreas, max3aRegions);
+    if (res == OK) res = validateAreas(meteringAreas, max3aRegions);
     if (res != OK) {
         ALOGE("%s: Requested metering areas are malformed: %s",
                 __FUNCTION__,
@@ -3729,10 +3729,17 @@
     size_t focusingAreasSize = params.focusingAreas.size() * 5;
     int32_t *focusingAreas = new int32_t[focusingAreasSize];
     for (size_t i = 0; i < focusingAreasSize; i += 5) {
-        focusingAreas[i + 0] = params.focusingAreas[i].left;
-        focusingAreas[i + 1] = params.focusingAreas[i].top;
-        focusingAreas[i + 2] = params.focusingAreas[i].right;
-        focusingAreas[i + 3] = params.focusingAreas[i].bottom;
+        if (params.focusingAreas[i].weight != 0) {
+            focusingAreas[i + 0] = normalizedXToArray(params.focusingAreas[i].left);
+            focusingAreas[i + 1] = normalizedYToArray(params.focusingAreas[i].top);
+            focusingAreas[i + 2] = normalizedXToArray(params.focusingAreas[i].right);
+            focusingAreas[i + 3] = normalizedYToArray(params.focusingAreas[i].bottom);
+        } else {
+            focusingAreas[i + 0] = 0;
+            focusingAreas[i + 1] = 0;
+            focusingAreas[i + 2] = 0;
+            focusingAreas[i + 3] = 0;
+        }
         focusingAreas[i + 4] = params.focusingAreas[i].weight;
     }
     res = request->update(ANDROID_CONTROL_AF_REGIONS,
@@ -3747,10 +3754,21 @@
     size_t meteringAreasSize = params.meteringAreas.size() * 5;
     int32_t *meteringAreas = new int32_t[meteringAreasSize];
     for (size_t i = 0; i < meteringAreasSize; i += 5) {
-        meteringAreas[i + 0] = params.meteringAreas[i].left;
-        meteringAreas[i + 1] = params.meteringAreas[i].top;
-        meteringAreas[i + 2] = params.meteringAreas[i].right;
-        meteringAreas[i + 3] = params.meteringAreas[i].bottom;
+        if (params.meteringAreas[i].weight != 0) {
+            meteringAreas[i + 0] =
+                normalizedXToArray(params.meteringAreas[i].left);
+            meteringAreas[i + 1] =
+                normalizedYToArray(params.meteringAreas[i].top);
+            meteringAreas[i + 2] =
+                normalizedXToArray(params.meteringAreas[i].right);
+            meteringAreas[i + 3] =
+                normalizedYToArray(params.meteringAreas[i].bottom);
+        } else {
+            meteringAreas[i + 0] = 0;
+            meteringAreas[i + 1] = 0;
+            meteringAreas[i + 2] = 0;
+            meteringAreas[i + 3] = 0;
+        }
         meteringAreas[i + 4] = params.meteringAreas[i].weight;
     }
     res = request->update(ANDROID_CONTROL_AE_REGIONS,
@@ -3808,6 +3826,14 @@
     return OK;
 }
 
+int Camera2Client::normalizedXToArray(int x) const {
+    return (x + 1000) * (mDeviceInfo->arrayWidth - 1) / 2000;
+}
+
+int Camera2Client::normalizedYToArray(int y) const {
+    return (y + 1000) * (mDeviceInfo->arrayHeight - 1) / 2000;
+}
+
 int Camera2Client::arrayXToNormalized(int width) const {
     return width * 2000 / (mDeviceInfo->arrayWidth - 1) - 1000;
 }
@@ -4099,7 +4125,7 @@
             return width * height * 2;
         case HAL_PIXEL_FORMAT_YV12: {      // YV12
             size_t ySize = stride * height;
-            size_t uvStride = (stride / 2 + 0xF) & ~0x10;
+            size_t uvStride = (stride / 2 + 0xF) & ~0xF;
             size_t uvSize = uvStride * height / 2;
             return ySize + uvSize * 2;
         }
diff --git a/services/camera/libcameraservice/Camera2Client.h b/services/camera/libcameraservice/Camera2Client.h
index e2f5cc4..a3ab128 100644
--- a/services/camera/libcameraservice/Camera2Client.h
+++ b/services/camera/libcameraservice/Camera2Client.h
@@ -464,6 +464,8 @@
     // Map from sensor active array pixel coordinates to normalized camera
     // parameter coordinates. The former are (0,0)-(array width - 1, array height
     // - 1), the latter from (-1000,-1000)-(1000,1000)
+    int normalizedXToArray(int x) const;
+    int normalizedYToArray(int y) const;
     int arrayXToNormalized(int width) const;
     int arrayYToNormalized(int height) const;