Merge "Remove use of PRODUCT_FULL_TREBLE from sensors." am: 49cf861945 am: 798c73b818
am: 69ecb1bd57

Change-Id: I23a86e0accda72ac5de6c5ba6032568e36179728
diff --git a/modules/camera/3_0/Metadata.cpp b/modules/camera/3_0/Metadata.cpp
index 440da5f..9b8eb1d 100644
--- a/modules/camera/3_0/Metadata.cpp
+++ b/modules/camera/3_0/Metadata.cpp
@@ -16,6 +16,8 @@
 //#define LOG_NDEBUG 0
 #define LOG_TAG "Metadata"
 
+#include <errno.h>
+
 #include <system/camera_metadata.h>
 
 #include <log/log.h>
diff --git a/modules/usbaudio/audio_hal.c b/modules/usbaudio/audio_hal.c
index e93396f..43d1daf 100644
--- a/modules/usbaudio/audio_hal.c
+++ b/modules/usbaudio/audio_hal.c
@@ -69,6 +69,8 @@
     bool mic_muted;
 
     bool standby;
+
+    int32_t inputs_open; /* number of input streams currently open. */
 };
 
 struct stream_lock {
@@ -85,7 +87,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 +123,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 +244,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("");
@@ -384,12 +396,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;
             }
         }
     }
@@ -572,9 +584,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;
 
@@ -787,18 +799,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;
             }
         }
     }
@@ -868,7 +880,7 @@
         in->standby = false;
     }
 
-    alsa_device_profile * profile = in->profile;
+    const alsa_device_profile *profile = in->profile;
 
     /*
      * OK, we need to figure out how much data to read to be able to output the requested
@@ -940,10 +952,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;
     }
 
@@ -975,10 +994,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) {
@@ -1083,6 +1121,10 @@
         free(in);
     }
 
+    device_lock(in->adev);
+    ++in->adev->inputs_open;
+    device_unlock(in->adev);
+
     return ret;
 }
 
@@ -1094,6 +1136,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);
 
diff --git a/modules/usbcamera/Metadata.cpp b/modules/usbcamera/Metadata.cpp
index 78318f3..b0d2f93 100644
--- a/modules/usbcamera/Metadata.cpp
+++ b/modules/usbcamera/Metadata.cpp
@@ -17,6 +17,8 @@
 //#define LOG_NDEBUG 0
 #define LOG_TAG "Metadata"
 
+#include <errno.h>
+
 #include <log/log.h>
 
 #define ATRACE_TAG (ATRACE_TAG_CAMERA | ATRACE_TAG_HAL)