Merge "Don't TEMP_FAILURE_RETRY on close." am: e1c003dc11 am: 7f4b73fb1a
am: 619653d7b1

Change-Id: I1f896a59da33be27a5d81362a6a1897f0ec277cf
diff --git a/include/hardware/camera3.h b/include/hardware/camera3.h
index cec2ab3..11e2491 100644
--- a/include/hardware/camera3.h
+++ b/include/hardware/camera3.h
@@ -21,7 +21,7 @@
 #include "camera_common.h"
 
 /**
- * Camera device HAL 3.4 [ CAMERA_DEVICE_API_VERSION_3_4 ]
+ * Camera device HAL 3.5[ CAMERA_DEVICE_API_VERSION_3_5 ]
  *
  * This is the current recommended version of the camera device HAL.
  *
@@ -29,7 +29,7 @@
  * android.hardware.camera2 API as LIMITED or above hardware level.
  *
  * Camera devices that support this version of the HAL must return
- * CAMERA_DEVICE_API_VERSION_3_4 in camera_device_t.common.version and in
+ * CAMERA_DEVICE_API_VERSION_3_5 in camera_device_t.common.version and in
  * camera_info_t.device_version (from camera_module_t.get_camera_info).
  *
  * CAMERA_DEVICE_API_VERSION_3_3 and above:
@@ -157,6 +157,18 @@
  *     - ANDROID_SENSOR_DYNAMIC_WHITE_LEVEL
  *     - ANDROID_SENSOR_OPAQUE_RAW_SIZE
  *     - ANDROID_SENSOR_OPTICAL_BLACK_REGIONS
+ *
+ * 3.5: Minor additions to supported metadata and changes to camera3_stream_configuration.
+ *
+ *   - Add ANDROID_REQUEST_AVAILABLE_SESSION_KEYS static metadata, which is
+ *     optional for implementations that want to support session parameters. If support is
+ *     needed, then Hal should populate the list with all available capture request keys
+ *     that can cause severe processing delays when modified by client. Typical examples
+ *     include parameters that require time-consuming HW re-configuration or internal camera
+ *     pipeline update.
+ *
+ *   - Add a session parameter field to camera3_stream_configuration which can be populated
+ *     by clients with initial values for the keys found in ANDROID_REQUEST_AVAILABLE_SESSION_KEYS.
  */
 
 /**
@@ -1734,6 +1746,18 @@
      *
      */
     uint32_t operation_mode;
+
+    /**
+     * >= CAMERA_DEVICE_API_VERSION_3_5:
+     *
+     * The session metadata buffer contains the initial values of
+     * ANDROID_REQUEST_AVAILABLE_SESSION_KEYS. This field is optional
+     * and camera clients can choose to ignore it, in which case it will
+     * be set to NULL. If parameters are present, then Hal should examine
+     * the parameter values and configure its internal camera pipeline
+     * accordingly.
+     */
+    const camera_metadata_t *session_parameters;
 } camera3_stream_configuration_t;
 
 /**
diff --git a/include/hardware/camera_common.h b/include/hardware/camera_common.h
index 7bafa88..edd1ada 100644
--- a/include/hardware/camera_common.h
+++ b/include/hardware/camera_common.h
@@ -148,10 +148,11 @@
 #define CAMERA_DEVICE_API_VERSION_3_2 HARDWARE_DEVICE_API_VERSION(3, 2)
 #define CAMERA_DEVICE_API_VERSION_3_3 HARDWARE_DEVICE_API_VERSION(3, 3)
 #define CAMERA_DEVICE_API_VERSION_3_4 HARDWARE_DEVICE_API_VERSION(3, 4)
+#define CAMERA_DEVICE_API_VERSION_3_5 HARDWARE_DEVICE_API_VERSION(3, 5)
 
-// Device version 3.4 is current, older HAL camera device versions are not
+// Device version 3.5 is current, older HAL camera device versions are not
 // recommended for new devices.
-#define CAMERA_DEVICE_API_VERSION_CURRENT CAMERA_DEVICE_API_VERSION_3_4
+#define CAMERA_DEVICE_API_VERSION_CURRENT CAMERA_DEVICE_API_VERSION_3_5
 
 /**
  * Defined in /system/media/camera/include/system/camera_metadata.h
diff --git a/modules/camera/3_4/README.md b/modules/camera/3_4/README.md
index 73d0c13..30f36d7 100644
--- a/modules/camera/3_4/README.md
+++ b/modules/camera/3_4/README.md
@@ -28,7 +28,7 @@
 Devices and cameras wishing to use this HAL must meet
 the following requirements:
 
-* The camera must support BGR32, YUV420, and JPEG formats.
+* The camera must support RGB24, YUV420, and JPEG formats.
 * The gralloc and other graphics modules used by the device must use
 `HAL_PIXEL_FORMAT_RGBA_8888` as the `HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED`
 
@@ -146,6 +146,3 @@
 
 * A variety of features are unimplemented: High speed capture,
 flash torch mode, hotplugging/unplugging.
-* The HAL uses BGR for RGBA. Again, the HAL was designed for the Raspberry Pi
-camera, which doesn't support RGB, but RGB is a common default format for
-graphics stacks.
diff --git a/modules/camera/3_4/camera.cpp b/modules/camera/3_4/camera.cpp
index 7f42eef..0f9e378 100644
--- a/modules/camera/3_4/camera.cpp
+++ b/modules/camera/3_4/camera.cpp
@@ -455,6 +455,7 @@
                     __func__, mId, strerror(-res), res);
             return res;
         }
+        ::close(buffer->acquire_fence);
     }
 
     // Acquire fence has been waited upon.
diff --git a/modules/camera/3_4/stream_format.cpp b/modules/camera/3_4/stream_format.cpp
index c85c26b..70900ab 100644
--- a/modules/camera/3_4/stream_format.cpp
+++ b/modules/camera/3_4/stream_format.cpp
@@ -57,7 +57,7 @@
     case V4L2_PIX_FMT_JPEG:
       return kFormatCategoryStalling;
     case V4L2_PIX_FMT_YUV420:  // Fall through.
-    case V4L2_PIX_FMT_BGR32:
+    case V4L2_PIX_FMT_RGB24:
       return kFormatCategoryNonStalling;
     default:
       // Note: currently no supported RAW formats.
@@ -87,7 +87,7 @@
     case V4L2_PIX_FMT_YUV420:
       hal_pixel_format = HAL_PIXEL_FORMAT_YCbCr_420_888;
       break;
-    case V4L2_PIX_FMT_BGR32:
+    case V4L2_PIX_FMT_RGB24:
       hal_pixel_format = HAL_PIXEL_FORMAT_RGBA_8888;
       break;
     default:
@@ -106,7 +106,7 @@
     case HAL_PIXEL_FORMAT_RGBA_8888:
       // Should be RGB32, but RPi doesn't support that.
       // For now we accept that the colors will be off.
-      v4l2_pixel_format = V4L2_PIX_FMT_BGR32;
+      v4l2_pixel_format = V4L2_PIX_FMT_RGB24;
       break;
     case HAL_PIXEL_FORMAT_YCbCr_420_888:
       v4l2_pixel_format = V4L2_PIX_FMT_YUV420;
diff --git a/modules/camera/3_4/v4l2_camera.cpp b/modules/camera/3_4/v4l2_camera.cpp
index 3e5b859..22406c9 100644
--- a/modules/camera/3_4/v4l2_camera.cpp
+++ b/modules/camera/3_4/v4l2_camera.cpp
@@ -295,32 +295,36 @@
 bool V4L2Camera::dequeueRequestBuffers() {
   // Dequeue a buffer.
   uint32_t result_index;
-  int res = device_->DequeueBuffer(&result_index);
-  if (res) {
-    if (res == -EAGAIN) {
-      // EAGAIN just means nothing to dequeue right now.
-      // Wait until something is available before looping again.
-      std::unique_lock<std::mutex> lock(in_flight_lock_);
-      while (in_flight_.empty()) {
-        buffers_in_flight_.wait(lock);
+  int res;
+
+  {
+    std::lock_guard<std::mutex> guard(in_flight_lock_);
+    res = device_->DequeueBuffer(&result_index);
+    if (!res) {
+      // Find the associated request and complete it.
+      auto index_request = in_flight_.find(result_index);
+      if (index_request != in_flight_.end()) {
+        completeRequest(index_request->second, 0);
+        in_flight_.erase(index_request);
+      } else {
+        HAL_LOGW(
+            "Dequeued non in-flight buffer index %d. "
+            "This buffer may have been flushed from the HAL but not the device.",
+            index_request->first);
       }
-    } else {
-      HAL_LOGW("Device failed to dequeue buffer: %d", res);
+      return true;
     }
-    return true;
   }
 
-  // Find the associated request and complete it.
-  std::lock_guard<std::mutex> guard(in_flight_lock_);
-  auto index_request = in_flight_.find(result_index);
-  if (index_request != in_flight_.end()) {
-    completeRequest(index_request->second, 0);
-    in_flight_.erase(index_request);
+  if (res == -EAGAIN) {
+    // EAGAIN just means nothing to dequeue right now.
+    // Wait until something is available before looping again.
+    std::unique_lock<std::mutex> lock(in_flight_lock_);
+    while (in_flight_.empty()) {
+      buffers_in_flight_.wait(lock);
+    }
   } else {
-    HAL_LOGW(
-        "Dequeued non in-flight buffer index %d. "
-        "This buffer may have been flushed from the HAL but not the device.",
-        index_request->first);
+    HAL_LOGW("Device failed to dequeue buffer: %d", res);
   }
   return true;
 }
@@ -409,6 +413,11 @@
   for (uint32_t i = 0; i < stream_config->num_streams; ++i) {
     stream = stream_config->streams[i];
 
+    // Override HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED format.
+    if (stream->format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) {
+      stream->format = HAL_PIXEL_FORMAT_RGBA_8888;
+    }
+
     // Max buffers as reported by the device.
     stream->max_buffers = max_buffers;
 
diff --git a/modules/camera/3_4/v4l2_gralloc.cpp b/modules/camera/3_4/v4l2_gralloc.cpp
index 7da3c4e..2fcef35 100644
--- a/modules/camera/3_4/v4l2_gralloc.cpp
+++ b/modules/camera/3_4/v4l2_gralloc.cpp
@@ -146,6 +146,7 @@
         return ret;
       }
       break;
+    case V4L2_PIX_FMT_RGB24:  // Fall-through.
     case V4L2_PIX_FMT_BGR32:  // Fall-through.
     case V4L2_PIX_FMT_RGB32:
       // RGB formats have nice agreed upon representation. Unless using android
@@ -204,6 +205,19 @@
   const camera3_stream_buffer_t* camera_buffer = buffer_data->camera_buffer;
   const buffer_handle_t buffer = *camera_buffer->buffer;
 
+  if (StreamFormat::HalToV4L2PixelFormat(camera_buffer->stream->format) == V4L2_PIX_FMT_RGB24) {
+    // Convert RGB24 to RGB32.
+    size_t rgb_size = camera_buffer->stream->width * camera_buffer->stream->height;
+    uint8_t* tail_rgb24 = (uint8_t*)data + 3 * rgb_size - 1;
+    uint8_t* tail_rgb32 = (uint8_t*)data + 4 * rgb_size - 1;
+    for (int i = 0; i < rgb_size; i++) {
+      *(tail_rgb32--) = 0xff;
+      *(tail_rgb32--) = *(tail_rgb24--);
+      *(tail_rgb32--) = *(tail_rgb24--);
+      *(tail_rgb32--) = *(tail_rgb24--);
+    }
+  }
+
   // Check for transform.
   if (buffer_data->transform_dest) {
     HAL_LOGV("Transforming V4L2 YUV to gralloc YUV.");
diff --git a/modules/camera/3_4/v4l2_wrapper.cpp b/modules/camera/3_4/v4l2_wrapper.cpp
index 3fafffd..b5a1c71 100644
--- a/modules/camera/3_4/v4l2_wrapper.cpp
+++ b/modules/camera/3_4/v4l2_wrapper.cpp
@@ -535,6 +535,7 @@
     std::lock_guard<std::mutex> guard(buffer_queue_lock_);
     for (int i = 0; i < buffers_.size(); ++i) {
       if (!buffers_[i]) {
+        buffers_[i] = true;
         index = i;
         break;
       }
@@ -557,6 +558,9 @@
   // and fill out remaining fields.
   if (IoctlLocked(VIDIOC_QUERYBUF, &device_buffer) < 0) {
     HAL_LOGE("QUERYBUF fails: %s", strerror(errno));
+    // Return buffer index.
+    std::lock_guard<std::mutex> guard(buffer_queue_lock_);
+    buffers_[index] = false;
     return -ENODEV;
   }
 
@@ -565,18 +569,20 @@
       gralloc_->lock(camera_buffer, format_->bytes_per_line(), &device_buffer);
   if (res) {
     HAL_LOGE("Gralloc failed to lock buffer.");
+    // Return buffer index.
+    std::lock_guard<std::mutex> guard(buffer_queue_lock_);
+    buffers_[index] = false;
     return res;
   }
   if (IoctlLocked(VIDIOC_QBUF, &device_buffer) < 0) {
     HAL_LOGE("QBUF fails: %s", strerror(errno));
     gralloc_->unlock(&device_buffer);
+    // Return buffer index.
+    std::lock_guard<std::mutex> guard(buffer_queue_lock_);
+    buffers_[index] = false;
     return -ENODEV;
   }
 
-  // Mark the buffer as in flight.
-  std::lock_guard<std::mutex> guard(buffer_queue_lock_);
-  buffers_[index] = true;
-
   if (enqueued_index) {
     *enqueued_index = index;
   }
diff --git a/modules/usbaudio/audio_hal.c b/modules/usbaudio/audio_hal.c
index 9b606b7..81c9fd6 100644
--- a/modules/usbaudio/audio_hal.c
+++ b/modules/usbaudio/audio_hal.c
@@ -44,8 +44,6 @@
 #include "alsa_device_proxy.h"
 #include "alsa_logging.h"
 
-#define DEFAULT_INPUT_BUFFER_SIZE_MS 20
-
 /* Lock play & record samples rates at or above this threshold */
 #define RATELOCK_THRESHOLD 96000
 
@@ -69,6 +67,8 @@
     bool mic_muted;
 
     bool standby;
+
+    int32_t inputs_open; /* number of input streams currently open. */
 };
 
 struct stream_lock {
@@ -85,7 +85,12 @@
 
     struct audio_device *adev;           /* hardware information - only using this for the lock */
 
-    alsa_device_profile * profile;      /* Points to the alsa_device_profile in the audio_device */
+    const alsa_device_profile *profile; /* Points to the alsa_device_profile in the audio_device.
+                                         * Const, so modifications go through adev->out_profile
+                                         * and thus should have the hardware lock and ensure
+                                         * stream is not active and no other open output streams.
+                                         */
+
     alsa_device_proxy proxy;            /* state of the stream */
 
     unsigned hal_channel_count;         /* channel count exposed to AudioFlinger.
@@ -116,7 +121,12 @@
 
     struct audio_device *adev;           /* hardware information - only using this for the lock */
 
-    alsa_device_profile * profile;      /* Points to the alsa_device_profile in the audio_device */
+    const alsa_device_profile *profile; /* Points to the alsa_device_profile in the audio_device.
+                                         * Const, so modifications go through adev->out_profile
+                                         * and thus should have the hardware lock and ensure
+                                         * stream is not active and no other open input streams.
+                                         */
+
     alsa_device_proxy proxy;            /* state of the stream */
 
     unsigned hal_channel_count;         /* channel count exposed to AudioFlinger.
@@ -232,7 +242,7 @@
     return *card >= 0 && *device >= 0;
 }
 
-static char * device_get_parameters(alsa_device_profile * profile, const char * keys)
+static char *device_get_parameters(const alsa_device_profile *profile, const char * keys)
 {
     if (profile->card < 0 || profile->device < 0) {
         return strdup("");
@@ -383,12 +393,12 @@
         else {
             int saved_card = out->profile->card;
             int saved_device = out->profile->device;
-            out->profile->card = card;
-            out->profile->device = device;
-            ret_value = profile_read_device_info(out->profile) ? 0 : -EINVAL;
+            out->adev->out_profile.card = card;
+            out->adev->out_profile.device = device;
+            ret_value = profile_read_device_info(&out->adev->out_profile) ? 0 : -EINVAL;
             if (ret_value != 0) {
-                out->profile->card = saved_card;
-                out->profile->device = saved_device;
+                out->adev->out_profile.card = saved_card;
+                out->adev->out_profile.device = saved_device;
             }
         }
     }
@@ -571,9 +581,9 @@
     memset(&proxy_config, 0, sizeof(proxy_config));
 
     /* Pull out the card/device pair */
-    parse_card_device_params(address, &(out->profile->card), &(out->profile->device));
+    parse_card_device_params(address, &out->adev->out_profile.card, &out->adev->out_profile.device);
 
-    profile_read_device_info(out->profile);
+    profile_read_device_info(&out->adev->out_profile);
 
     int ret = 0;
 
@@ -780,18 +790,18 @@
     device_lock(in->adev);
 
     if (card >= 0 && device >= 0 && !profile_is_cached_for(in->profile, card, device)) {
-        /* cannot read pcm device info if playback is active */
-        if (!in->standby)
+        /* cannot read pcm device info if playback is active, or more than one open stream */
+        if (!in->standby || in->adev->inputs_open > 1)
             ret_value = -ENOSYS;
         else {
             int saved_card = in->profile->card;
             int saved_device = in->profile->device;
-            in->profile->card = card;
-            in->profile->device = device;
-            ret_value = profile_read_device_info(in->profile) ? 0 : -EINVAL;
+            in->adev->in_profile.card = card;
+            in->adev->in_profile.device = device;
+            ret_value = profile_read_device_info(&in->adev->in_profile) ? 0 : -EINVAL;
             if (ret_value != 0) {
-                in->profile->card = saved_card;
-                in->profile->device = saved_device;
+                in->adev->in_profile.card = saved_card;
+                in->adev->in_profile.device = saved_device;
             }
         }
     }
@@ -931,10 +941,17 @@
     ALOGV("adev_open_input_stream() rate:%" PRIu32 ", chanMask:0x%" PRIX32 ", fmt:%" PRIu8,
           config->sample_rate, config->channel_mask, config->format);
 
-    struct stream_in *in = (struct stream_in *)calloc(1, sizeof(struct stream_in));
-    int ret = 0;
+    /* Pull out the card/device pair */
+    int32_t card, device;
+    if (!parse_card_device_params(address, &card, &device)) {
+        ALOGW("%s fail - invalid address %s", __func__, address);
+        *stream_in = NULL;
+        return -EINVAL;
+    }
 
+    struct stream_in * const in = (struct stream_in *)calloc(1, sizeof(struct stream_in));
     if (in == NULL) {
+        *stream_in = NULL;
         return -ENOMEM;
     }
 
@@ -966,10 +983,29 @@
     struct pcm_config proxy_config;
     memset(&proxy_config, 0, sizeof(proxy_config));
 
-    /* Pull out the card/device pair */
-    parse_card_device_params(address, &(in->profile->card), &(in->profile->device));
-
-    profile_read_device_info(in->profile);
+    int ret = 0;
+    /* Check if an input stream is already open */
+    if (in->adev->inputs_open > 0) {
+        if (!profile_is_cached_for(in->profile, card, device)) {
+            ALOGW("%s fail - address card:%d device:%d doesn't match existing profile",
+                    __func__, card, device);
+            ret = -EINVAL;
+        }
+    } else {
+        /* Read input profile only if necessary */
+        in->adev->in_profile.card = card;
+        in->adev->in_profile.device = device;
+        if (!profile_read_device_info(&in->adev->in_profile)) {
+            ALOGW("%s fail - cannot read profile", __func__);
+            ret = -EINVAL;
+        }
+    }
+    if (ret != 0) {
+        device_unlock(in->adev);
+        free(in);
+        *stream_in = NULL;
+        return ret;
+    }
 
     /* Rate */
     if (config->sample_rate == 0) {
@@ -1074,6 +1110,10 @@
         free(in);
     }
 
+    device_lock(in->adev);
+    ++in->adev->inputs_open;
+    device_unlock(in->adev);
+
     return ret;
 }
 
@@ -1085,6 +1125,12 @@
 
     adev_remove_stream_from_list(in->adev, &in->list_node);
 
+    device_lock(in->adev);
+    --in->adev->inputs_open;
+    LOG_ALWAYS_FATAL_IF(in->adev->inputs_open < 0,
+            "invalid inputs_open: %d", in->adev->inputs_open);
+    device_unlock(in->adev);
+
     /* Close the pcm device */
     in_standby(&stream->common);