Merge "IAudioPolicyService is now in libaudioclient instead of libmedia"
am: 76f97250ff

Change-Id: Ie85b93bdb1b0b004c4cfe9cd2f60cc8766781ced
diff --git a/alsa_utils/alsa_device_profile.c b/alsa_utils/alsa_device_profile.c
index 0d9bd88..79ffcfc 100644
--- a/alsa_utils/alsa_device_profile.c
+++ b/alsa_utils/alsa_device_profile.c
@@ -192,6 +192,21 @@
     return profile_is_valid(profile) ? profile->channel_counts[0] : DEFAULT_CHANNEL_COUNT;
 }
 
+unsigned profile_get_closest_channel_count(alsa_device_profile* profile, unsigned count)
+{
+    if (profile_is_valid(profile)) {
+        if (count < profile->min_channel_count) {
+            return profile->min_channel_count;
+        } else if (count > profile->max_channel_count) {
+            return profile->max_channel_count;
+        } else {
+            return count;
+        }
+    } else {
+        return 0;
+    }
+}
+
 bool profile_is_channel_count_valid(alsa_device_profile* profile, unsigned count)
 {
     if (profile_is_initialized(profile)) {
@@ -566,3 +581,59 @@
 
     return strdup(buffer);
 }
+
+void profile_dump(const alsa_device_profile* profile, int fd)
+{
+    if (profile == NULL) {
+        dprintf(fd, "  %s\n", "No USB Profile");
+        return; /* bail early */
+    }
+
+    if (!profile->is_valid) {
+        dprintf(fd, "  Profile is INVALID");
+    }
+
+    /* card/device/direction */
+    dprintf(fd, "  card:%d, device:%d - %s\n",
+                profile->card, profile->device, profile->direction == PCM_OUT ? "OUT" : "IN");
+
+    /* formats */
+    dprintf(fd, "  Formats: ");
+    for (int fmtIndex = 0;
+          profile->formats[fmtIndex] != PCM_FORMAT_INVALID && fmtIndex < MAX_PROFILE_FORMATS;
+          fmtIndex++) {
+        dprintf(fd, "%d ", profile->formats[fmtIndex]);
+    }
+    dprintf(fd, "\n");
+
+    /* sample rates */
+    dprintf(fd, "  Rates: ");
+    for (int rateIndex = 0;
+          profile->sample_rates[rateIndex] != 0 && rateIndex < MAX_PROFILE_SAMPLE_RATES;
+          rateIndex++) {
+        dprintf(fd, "%u ", profile->sample_rates[rateIndex]);
+    }
+    dprintf(fd, "\n");
+
+    // channel counts
+    dprintf(fd, "  Channel Counts: ");
+    for (int cntIndex = 0;
+          profile->channel_counts[cntIndex] != 0 && cntIndex < MAX_PROFILE_CHANNEL_COUNTS;
+          cntIndex++) {
+        dprintf(fd, "%u ", profile->channel_counts[cntIndex]);
+    }
+    dprintf(fd, "\n");
+
+    dprintf(fd, "  min/max period size [%u : %u]\n",
+            profile->min_period_size,profile-> max_period_size);
+    dprintf(fd, "  min/max channel count [%u : %u]\n",
+            profile->min_channel_count, profile->max_channel_count);
+
+    // struct pcm_config default_config;
+    dprintf(fd, "  Default Config:\n");
+    dprintf(fd, "    channels: %d\n", profile->default_config.channels);
+    dprintf(fd, "    rate: %d\n", profile->default_config.rate);
+    dprintf(fd, "    period_size: %d\n", profile->default_config.period_size);
+    dprintf(fd, "    period_count: %d\n", profile->default_config.period_count);
+    dprintf(fd, "    format: %d\n", profile->default_config.format);
+}
diff --git a/alsa_utils/alsa_device_proxy.c b/alsa_utils/alsa_device_proxy.c
index ee92ed0..73e4375 100644
--- a/alsa_utils/alsa_device_proxy.c
+++ b/alsa_utils/alsa_device_proxy.c
@@ -69,10 +69,9 @@
     if (config->channels != 0 && profile_is_channel_count_valid(profile, config->channels)) {
         proxy->alsa_config.channels = config->channels;
     } else {
-        ALOGW("Invalid channel count %u - using default %u.",
-              config->channels, profile->default_config.channels);
-        proxy->alsa_config.channels = profile->default_config.channels;
-
+        proxy->alsa_config.channels = profile_get_closest_channel_count(profile, config->channels);
+        ALOGW("Invalid channel count %u - using closest %u.",
+              config->channels, proxy->alsa_config.channels);
     }
 
     proxy->alsa_config.period_count = profile->default_config.period_count;
@@ -218,3 +217,17 @@
 {
     return pcm_read(proxy->pcm, data, count);
 }
+
+/*
+ * Debugging
+ */
+void proxy_dump(const alsa_device_proxy* proxy, int fd)
+{
+    if (proxy != NULL) {
+        dprintf(fd, "  channels: %d\n", proxy->alsa_config.channels);
+        dprintf(fd, "  rate: %d\n", proxy->alsa_config.rate);
+        dprintf(fd, "  period_size: %d\n", proxy->alsa_config.period_size);
+        dprintf(fd, "  period_count: %d\n", proxy->alsa_config.period_count);
+        dprintf(fd, "  format: %d\n", proxy->alsa_config.format);
+    }
+}
diff --git a/alsa_utils/include/alsa_device_profile.h b/alsa_utils/include/alsa_device_profile.h
index 5520b8a..e056d70 100644
--- a/alsa_utils/include/alsa_device_profile.h
+++ b/alsa_utils/include/alsa_device_profile.h
@@ -81,10 +81,14 @@
 
 /* Channel Methods */
 unsigned profile_get_default_channel_count(alsa_device_profile* profile);
+unsigned profile_get_closest_channel_count(alsa_device_profile* profile, unsigned count);
 bool profile_is_channel_count_valid(alsa_device_profile* profile, unsigned count);
 
 /* Utility */
 unsigned profile_calc_min_period_size(alsa_device_profile* profile, unsigned sample_rate);
 unsigned int profile_get_period_size(alsa_device_profile* profile, unsigned sample_rate);
 
+/* Debugging */
+void profile_dump(const alsa_device_profile* profile, int fd);
+
 #endif /* ANDROID_SYSTEM_MEDIA_ALSA_UTILS_ALSA_DEVICE_PROFILE_H */
diff --git a/alsa_utils/include/alsa_device_proxy.h b/alsa_utils/include/alsa_device_proxy.h
index e1ff8f5..0bc0731 100644
--- a/alsa_utils/include/alsa_device_proxy.h
+++ b/alsa_utils/include/alsa_device_proxy.h
@@ -32,24 +32,27 @@
     uint64_t transferred; /* the total frames transferred, not cleared on standby */
 } alsa_device_proxy;
 
+
+/* State */
 void proxy_prepare(alsa_device_proxy * proxy, alsa_device_profile * profile,
                    struct pcm_config * config);
-
-unsigned proxy_get_sample_rate(const alsa_device_proxy * proxy);
-enum pcm_format proxy_get_format(const alsa_device_proxy * proxy);
-unsigned proxy_get_channel_count(const alsa_device_proxy * proxy);
-
-unsigned int proxy_get_period_size(const alsa_device_proxy * proxy);
-
-unsigned proxy_get_latency(const alsa_device_proxy * proxy);
-
+int proxy_open(alsa_device_proxy * proxy);
+void proxy_close(alsa_device_proxy * proxy);
 int proxy_get_presentation_position(const alsa_device_proxy * proxy,
         uint64_t *frames, struct timespec *timestamp);
 
-int proxy_open(alsa_device_proxy * proxy);
-void proxy_close(alsa_device_proxy * proxy);
+/* Attributes */
+unsigned proxy_get_sample_rate(const alsa_device_proxy * proxy);
+enum pcm_format proxy_get_format(const alsa_device_proxy * proxy);
+unsigned proxy_get_channel_count(const alsa_device_proxy * proxy);
+unsigned int proxy_get_period_size(const alsa_device_proxy * proxy);
+unsigned proxy_get_latency(const alsa_device_proxy * proxy);
 
+/* I/O */
 int proxy_write(alsa_device_proxy * proxy, const void *data, unsigned int count);
 int proxy_read(const alsa_device_proxy * proxy, void *data, unsigned int count);
 
+/* Debugging */
+void proxy_dump(const alsa_device_proxy * proxy, int fd);
+
 #endif /* ANDROID_SYSTEM_MEDIA_ALSA_UTILS_ALSA_DEVICE_PROXY_H */
diff --git a/audio/include/system/audio.h b/audio/include/system/audio.h
index d4456a9..d7a90ea 100644
--- a/audio/include/system/audio.h
+++ b/audio/include/system/audio.h
@@ -316,6 +316,7 @@
     AUDIO_FORMAT_DTS_HD              = 0x0C000000UL,
     // IEC61937 is encoded audio wrapped in 16-bit PCM.
     AUDIO_FORMAT_IEC61937            = 0x0D000000UL,
+    AUDIO_FORMAT_DOLBY_TRUEHD        = 0x0E000000UL,
     AUDIO_FORMAT_MAIN_MASK           = 0xFF000000UL, /* Deprecated. Use audio_get_main_format() */
     AUDIO_FORMAT_SUB_MASK            = 0x00FFFFFFUL,
 
@@ -1442,6 +1443,7 @@
     case AUDIO_FORMAT_DTS:
     case AUDIO_FORMAT_DTS_HD:
     case AUDIO_FORMAT_IEC61937:
+    case AUDIO_FORMAT_DOLBY_TRUEHD:
         return true;
     default:
         return false;
diff --git a/audio_effects/include/audio_effects/effect_visualizer.h b/audio_effects/include/audio_effects/effect_visualizer.h
index cfd99f5..fe46d7f 100644
--- a/audio_effects/include/audio_effects/effect_visualizer.h
+++ b/audio_effects/include/audio_effects/effect_visualizer.h
@@ -41,6 +41,7 @@
 
 #define MEASUREMENT_IDX_PEAK 0
 #define MEASUREMENT_IDX_RMS  1
+#define MEASUREMENT_COUNT 2
 
 /* enumerated parameters for Visualizer effect */
 typedef enum
diff --git a/audio_route/audio_route.c b/audio_route/audio_route.c
index 90b114d..bd5c112 100644
--- a/audio_route/audio_route.c
+++ b/audio_route/audio_route.c
@@ -420,13 +420,24 @@
 static int mixer_enum_string_to_value(struct mixer_ctl *ctl, const char *string)
 {
     unsigned int i;
+    unsigned int num_values = mixer_ctl_get_num_enums(ctl);
+
+    if (string == NULL) {
+        ALOGE("NULL enum value string passed to mixer_enum_string_to_value() for ctl %s",
+              mixer_ctl_get_name(ctl));
+        return 0;
+    }
 
     /* Search the enum strings for a particular one */
-    for (i = 0; i < mixer_ctl_get_num_enums(ctl); i++) {
+    for (i = 0; i < num_values; i++) {
         if (strcmp(mixer_ctl_get_enum_string(ctl, i), string) == 0)
             break;
     }
-
+    if (i == num_values) {
+        ALOGE("unknown enum value string %s for ctl %s",
+              string, mixer_ctl_get_name(ctl));
+        return 0;
+    }
     return i;
 }
 
diff --git a/audio_utils/format.c b/audio_utils/format.c
index 66b0a6d..3eda484 100644
--- a/audio_utils/format.c
+++ b/audio_utils/format.c
@@ -102,6 +102,12 @@
         case AUDIO_FORMAT_PCM_FLOAT:
             memcpy_to_p24_from_float((uint8_t*)dst, (float*)src, count);
             return;
+        case AUDIO_FORMAT_PCM_32_BIT:
+            memcpy_to_p24_from_i32((uint8_t*)dst, (int32_t*)src, count);
+            return;
+        case AUDIO_FORMAT_PCM_8_24_BIT:
+            memcpy_to_p24_from_q8_23((uint8_t*)dst, (int32_t*)src, count);
+            return;
         default:
             break;
         }
@@ -114,6 +120,9 @@
         case AUDIO_FORMAT_PCM_FLOAT:
             memcpy_to_i32_from_float((int32_t*)dst, (float*)src, count);
             return;
+        case AUDIO_FORMAT_PCM_24_BIT_PACKED:
+            memcpy_to_i32_from_p24((int32_t*)dst, (uint8_t *)src, count);
+            return;
         default:
             break;
         }
diff --git a/audio_utils/tests/Android.bp b/audio_utils/tests/Android.bp
index 33214cf..2d5f1a4 100644
--- a/audio_utils/tests/Android.bp
+++ b/audio_utils/tests/Android.bp
@@ -2,17 +2,25 @@
 
 cc_test {
     name: "primitives_tests",
+    host_supported: true,
 
     shared_libs: [
         "liblog",
         "libcutils",
-        "libaudioutils",
     ],
     srcs: ["primitives_tests.cpp"],
     cflags: [
         "-Werror",
         "-Wall",
     ],
+    target: {
+        android: {
+            shared_libs: ["libaudioutils"],
+        },
+        host: {
+            static_libs: ["libaudioutils"],
+        },
+    }
 }
 
 cc_binary {
diff --git a/audio_utils/tests/primitives_tests.cpp b/audio_utils/tests/primitives_tests.cpp
index 5b3cd2d..178490b 100644
--- a/audio_utils/tests/primitives_tests.cpp
+++ b/audio_utils/tests/primitives_tests.cpp
@@ -103,6 +103,14 @@
     }
 }
 
+void checkMonotonep24(uint8_t * pary, size_t size)
+{
+    size_t frames = size/3;
+    for (size_t i = 1; i < frames; ++i) {
+        EXPECT_LT(i32_from_p24(pary + 3*(i-1)), i32_from_p24(pary + 3*i));
+    }
+}
+
 TEST(audio_utils_primitives, clamp_to_int) {
     static const float testArray[] = {
             -NAN, -INFINITY,
@@ -256,6 +264,31 @@
     memset(i32ary, 0, 65536 * sizeof(i32ary[0]));
     checkMonotone(i16ary, 65536);
 
+    // do round-trip test i16 -> p24 -> i32 -> p24 -> q8_23 -> p24 -> i16
+    memcpy_to_p24_from_i16(pary, i16ary, 65536);
+    memset(i16ary, 0, 65536 * sizeof(i16ary[0]));
+    checkMonotonep24(pary, 65536 * 3);
+
+    memcpy_to_i32_from_p24(i32ary, pary, 65536);
+    memset(pary, 0, 65536 * 3 * sizeof(pary[0]));
+    checkMonotone(i32ary, 65536);
+
+    memcpy_to_p24_from_i32(pary, i32ary, 65536);
+    memset(i32ary, 0, 65536 * sizeof(i32ary[0]));
+    checkMonotonep24(pary, 65536 * 3);
+
+    memcpy_to_q8_23_from_p24(i32ary, pary, 65536);
+    memset(pary, 0, 65536 * 3 * sizeof(pary[0]));
+    checkMonotone(i32ary, 65536);
+
+    memcpy_to_p24_from_q8_23(pary, i32ary, 65536);
+    memset(i32ary, 0, 65536 * sizeof(i32ary[0]));
+    checkMonotonep24(pary, 65536 * 3);
+
+    memcpy_to_i16_from_p24(i16ary, pary, 65536);
+    memset(pary, 0, 65536 * 3 * sizeof(pary[0]));
+    checkMonotone(i16ary, 65536);
+
     // do partial round-trip testing q4_27 to i16 and float
     memcpy_to_float_from_i16(fary, i16ary, 65536);
     //memset(i16ary, 0, 65536 * sizeof(i16ary[0])); // not cleared: we don't do full roundtrip
diff --git a/camera/src/camera_metadata.c b/camera/src/camera_metadata.c
index 9491e8e..4b0ed4f 100644
--- a/camera/src/camera_metadata.c
+++ b/camera/src/camera_metadata.c
@@ -25,9 +25,10 @@
 #include <stdlib.h>
 #include <errno.h>
 
-#define OK         0
-#define ERROR      1
-#define NOT_FOUND (-ENOENT)
+#define OK              0
+#define ERROR           1
+#define NOT_FOUND       (-ENOENT)
+#define SN_EVENT_LOG_ID 0x534e4554
 
 #define ALIGN_TO(val, alignment) \
     (((uintptr_t)(val) + ((alignment) - 1)) & ~((alignment) - 1))
@@ -305,6 +306,38 @@
     return metadata;
 }
 
+// This method should be used when the camera metadata cannot be trusted. For example, when it's
+// read from Parcel.
+static int validate_and_calculate_camera_metadata_entry_data_size(size_t *data_size, uint8_t type,
+        size_t data_count) {
+    if (type >= NUM_TYPES) return ERROR;
+
+    // Check for overflow
+    if (data_count != 0 &&
+            camera_metadata_type_size[type] > (SIZE_MAX - DATA_ALIGNMENT + 1) / data_count) {
+        android_errorWriteLog(SN_EVENT_LOG_ID, "30741779");
+        return ERROR;
+    }
+
+    size_t data_bytes = data_count * camera_metadata_type_size[type];
+
+    if (data_size) {
+        *data_size = data_bytes <= 4 ? 0 : ALIGN_TO(data_bytes, DATA_ALIGNMENT);
+    }
+
+    return OK;
+}
+
+size_t calculate_camera_metadata_entry_data_size(uint8_t type,
+        size_t data_count) {
+    if (type >= NUM_TYPES) return 0;
+
+    size_t data_bytes = data_count *
+            camera_metadata_type_size[type];
+
+    return data_bytes <= 4 ? 0 : ALIGN_TO(data_bytes, DATA_ALIGNMENT);
+}
+
 int validate_camera_metadata_structure(const camera_metadata_t *metadata,
                                        const size_t *expected_size) {
 
@@ -363,6 +396,14 @@
         return ERROR;
     }
 
+    if (metadata->data_count > metadata->data_capacity) {
+        ALOGE("%s: Data count (%" PRIu32 ") should be <= data capacity "
+              "(%" PRIu32 ")",
+              __FUNCTION__, metadata->data_count, metadata->data_capacity);
+        android_errorWriteLog(SN_EVENT_LOG_ID, "30591838");
+        return ERROR;
+    }
+
     const metadata_uptrdiff_t entries_end =
         metadata->entries_start + metadata->entry_capacity;
     if (entries_end < metadata->entries_start || // overflow check
@@ -420,9 +461,13 @@
             return ERROR;
         }
 
-        size_t data_size =
-                calculate_camera_metadata_entry_data_size(entry.type,
-                                                          entry.count);
+        size_t data_size;
+        if (validate_and_calculate_camera_metadata_entry_data_size(&data_size, entry.type,
+                entry.count) != OK) {
+            ALOGE("%s: Entry data size is invalid. type: %u count: %u", __FUNCTION__, entry.type,
+                    entry.count);
+            return ERROR;
+        }
 
         if (data_size != 0) {
             camera_metadata_data_t *data =
@@ -465,6 +510,10 @@
         const camera_metadata_t *src) {
     if (dst == NULL || src == NULL ) return ERROR;
 
+    // Check for overflow
+    if (src->entry_count + dst->entry_count < src->entry_count) return ERROR;
+    if (src->data_count + dst->data_count < src->data_count) return ERROR;
+    // Check for space
     if (dst->entry_capacity < src->entry_count + dst->entry_count) return ERROR;
     if (dst->data_capacity < src->data_count + dst->data_count) return ERROR;
 
@@ -514,14 +563,6 @@
     return clone;
 }
 
-size_t calculate_camera_metadata_entry_data_size(uint8_t type,
-        size_t data_count) {
-    if (type >= NUM_TYPES) return 0;
-    size_t data_bytes = data_count *
-            camera_metadata_type_size[type];
-    return data_bytes <= 4 ? 0 : ALIGN_TO(data_bytes, DATA_ALIGNMENT);
-}
-
 static int add_camera_metadata_entry_raw(camera_metadata_t *dst,
         uint32_t tag,
         uint8_t  type,