Merge "APM: Check dedicated VOIP downlink profile"
diff --git a/media/libaaudio/include/aaudio/AAudio.h b/media/libaaudio/include/aaudio/AAudio.h
index c21caa4..4e36e84 100644
--- a/media/libaaudio/include/aaudio/AAudio.h
+++ b/media/libaaudio/include/aaudio/AAudio.h
@@ -209,14 +209,13 @@
 /**
  * Request a sample rate in Hertz.
  *
- * The stream may be opened with a different sample rate.
- * So the application should query for the actual rate after the stream is opened.
- *
- * Technically, this should be called the "frame rate" or "frames per second",
- * because it refers to the number of complete frames transferred per second.
- * But it is traditionally called "sample rate". So we use that term.
- *
  * The default, if you do not call this function, is AAUDIO_UNSPECIFIED.
+ * An optimal value will then be chosen when the stream is opened.
+ * After opening a stream with an unspecified value, the application must
+ * query for the actual value, which may vary by device.
+ *
+ * If an exact value is specified then an opened stream will use that value.
+ * If a stream cannot be opened with the specified value then the open will fail.
  *
  * @param builder reference provided by AAudio_createStreamBuilder()
  * @param sampleRate frames per second. Common rates include 44100 and 48000 Hz.
@@ -227,12 +226,13 @@
 /**
  * Request a number of channels for the stream.
  *
- * The stream may be opened with a different value.
- * So the application should query for the actual value after the stream is opened.
- *
  * The default, if you do not call this function, is AAUDIO_UNSPECIFIED.
+ * An optimal value will then be chosen when the stream is opened.
+ * After opening a stream with an unspecified value, the application must
+ * query for the actual value, which may vary by device.
  *
- * Note, this quantity is sometimes referred to as "samples per frame".
+ * If an exact value is specified then an opened stream will use that value.
+ * If a stream cannot be opened with the specified value then the open will fail.
  *
  * @param builder reference provided by AAudio_createStreamBuilder()
  * @param channelCount Number of channels desired.
@@ -252,12 +252,15 @@
  * Request a sample data format, for example AAUDIO_FORMAT_PCM_I16.
  *
  * The default, if you do not call this function, is AAUDIO_UNSPECIFIED.
+ * An optimal value will then be chosen when the stream is opened.
+ * After opening a stream with an unspecified value, the application must
+ * query for the actual value, which may vary by device.
  *
- * The stream may be opened with a different value.
- * So the application should query for the actual value after the stream is opened.
+ * If an exact value is specified then an opened stream will use that value.
+ * If a stream cannot be opened with the specified value then the open will fail.
  *
  * @param builder reference provided by AAudio_createStreamBuilder()
- * @param format Most common formats are AAUDIO_FORMAT_PCM_FLOAT and AAUDIO_FORMAT_PCM_I16.
+ * @param format common formats are AAUDIO_FORMAT_PCM_FLOAT and AAUDIO_FORMAT_PCM_I16.
  */
 AAUDIO_API void AAudioStreamBuilder_setFormat(AAudioStreamBuilder* builder,
                                                    aaudio_audio_format_t format);
diff --git a/media/libaaudio/src/core/AudioStreamBuilder.cpp b/media/libaaudio/src/core/AudioStreamBuilder.cpp
index 9bc2ef2..f313b58 100644
--- a/media/libaaudio/src/core/AudioStreamBuilder.cpp
+++ b/media/libaaudio/src/core/AudioStreamBuilder.cpp
@@ -91,7 +91,8 @@
     AudioStream *audioStream = nullptr;
     *streamPtr = nullptr;
 
-    bool tryMMap = (sharingMode == AAUDIO_SHARING_MODE_SHARED) && MMAP_SHARED_ENABLED;
+    bool tryMMap = ((sharingMode == AAUDIO_SHARING_MODE_SHARED) && MMAP_SHARED_ENABLED) ||
+            ((sharingMode == AAUDIO_SHARING_MODE_EXCLUSIVE) && MMAP_EXCLUSIVE_ENABLED);
     aaudio_result_t result = builder_createStream(getDirection(), sharingMode,
                                                   tryMMap, &audioStream);
     if (result == AAUDIO_OK) {
diff --git a/media/libaaudio/tests/Android.mk b/media/libaaudio/tests/Android.mk
index 01360b1..fba81f2 100644
--- a/media/libaaudio/tests/Android.mk
+++ b/media/libaaudio/tests/Android.mk
@@ -47,3 +47,15 @@
 LOCAL_STATIC_LIBRARIES := libaaudio
 LOCAL_MODULE := test_linear_ramp
 include $(BUILD_NATIVE_TEST)
+
+include $(CLEAR_VARS)
+LOCAL_C_INCLUDES := \
+    $(call include-path-for, audio-utils) \
+    frameworks/av/media/libaaudio/include \
+    frameworks/av/media/libaaudio/src
+LOCAL_SRC_FILES:= test_open_params.cpp
+LOCAL_SHARED_LIBRARIES := libaudioclient libaudioutils libbinder \
+                          libcutils liblog libmedia libutils
+LOCAL_STATIC_LIBRARIES := libaaudio
+LOCAL_MODULE := test_open_params
+include $(BUILD_NATIVE_TEST)
diff --git a/media/libaaudio/tests/test_open_params.cpp b/media/libaaudio/tests/test_open_params.cpp
new file mode 100644
index 0000000..5125653
--- /dev/null
+++ b/media/libaaudio/tests/test_open_params.cpp
@@ -0,0 +1,157 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// Play sine waves using AAudio.
+
+#include <stdio.h>
+//#include <stdlib.h>
+//#include <math.h>
+
+#include <android-base/macros.h>
+#include <aaudio/AAudio.h>
+
+#include <gtest/gtest.h>
+
+static const char *getSharingModeText(aaudio_sharing_mode_t mode) {
+    const char *modeText = "unknown";
+    switch (mode) {
+    case AAUDIO_SHARING_MODE_EXCLUSIVE:
+        modeText = "EXCLUSIVE";
+        break;
+    case AAUDIO_SHARING_MODE_SHARED:
+        modeText = "SHARED";
+        break;
+    default:
+        break;
+    }
+    return modeText;
+}
+
+// Callback function that fills the audio output buffer.
+aaudio_data_callback_result_t MyDataCallbackProc(
+        AAudioStream *stream,
+        void *userData,
+        void *audioData,
+        int32_t numFrames
+) {
+    (void) stream;
+    (void) userData;
+    (void) audioData;
+    (void) numFrames;
+    return AAUDIO_CALLBACK_RESULT_CONTINUE;
+}
+
+static void testOpenOptions(aaudio_direction_t direction,
+                            int32_t channelCount,
+                            int32_t sampleRate,
+                            aaudio_audio_format_t format) {
+
+    aaudio_result_t result = AAUDIO_OK;
+
+    int32_t bufferCapacity;
+    int32_t framesPerBurst = 0;
+
+    int32_t actualChannelCount = 0;
+    int32_t actualSampleRate = 0;
+    aaudio_audio_format_t actualDataFormat = AAUDIO_FORMAT_UNSPECIFIED;
+    aaudio_sharing_mode_t actualSharingMode = AAUDIO_SHARING_MODE_SHARED;
+    aaudio_direction_t actualDirection;
+
+    AAudioStreamBuilder *aaudioBuilder = nullptr;
+    AAudioStream *aaudioStream = nullptr;
+
+    printf("TestOpen: dir = %d, chans = %3d, rate = %6d format = %d\n",
+           direction, channelCount, sampleRate, format);
+
+    // Use an AAudioStreamBuilder to contain requested parameters.
+    ASSERT_EQ(AAUDIO_OK, AAudio_createStreamBuilder(&aaudioBuilder));
+
+    // Request stream properties.
+    AAudioStreamBuilder_setDirection(aaudioBuilder, direction);
+    AAudioStreamBuilder_setSampleRate(aaudioBuilder, sampleRate);
+    AAudioStreamBuilder_setChannelCount(aaudioBuilder, channelCount);
+    AAudioStreamBuilder_setFormat(aaudioBuilder, format);
+    AAudioStreamBuilder_setDataCallback(aaudioBuilder, MyDataCallbackProc, nullptr);
+
+    //AAudioStreamBuilder_setPerformanceMode(aaudioBuilder, AAUDIO_PERFORMANCE_MODE_NONE);
+    AAudioStreamBuilder_setPerformanceMode(aaudioBuilder, AAUDIO_PERFORMANCE_MODE_LOW_LATENCY);
+    //AAudioStreamBuilder_setPerformanceMode(aaudioBuilder, AAUDIO_PERFORMANCE_MODE_POWER_SAVING);
+
+    // Create an AAudioStream using the Builder.
+    result = AAudioStreamBuilder_openStream(aaudioBuilder, &aaudioStream);
+    if (result != AAUDIO_OK) {
+        printf("Stream not opened! That may be OK.\n");
+        goto finish;
+    }
+
+    // Check to see what kind of stream we actually got.
+    actualSampleRate = AAudioStream_getSampleRate(aaudioStream);
+    actualChannelCount = AAudioStream_getChannelCount(aaudioStream);
+    actualDataFormat = AAudioStream_getFormat(aaudioStream);
+    actualDirection = AAudioStream_getDirection(aaudioStream);
+
+    printf("          dir = %d, chans = %3d, rate = %6d format = %d\n",
+           direction, actualChannelCount, actualSampleRate, actualDataFormat);
+
+    // If we ask for something specific then we should get that.
+    if (channelCount != AAUDIO_UNSPECIFIED) {
+        EXPECT_EQ(channelCount, actualChannelCount);
+    }
+    if (sampleRate != AAUDIO_UNSPECIFIED) {
+        EXPECT_EQ(sampleRate, actualSampleRate);
+    }
+    if (format != AAUDIO_FORMAT_UNSPECIFIED) {
+        EXPECT_EQ(format, actualDataFormat);
+    }
+    EXPECT_EQ(direction, actualDirection);
+
+    // This is the number of frames that are read in one chunk by a DMA controller
+    // or a DSP or a mixer.
+    framesPerBurst = AAudioStream_getFramesPerBurst(aaudioStream);
+    bufferCapacity = AAudioStream_getBufferCapacityInFrames(aaudioStream);
+    printf("          bufferCapacity = %d, remainder = %d\n",
+           bufferCapacity, bufferCapacity % framesPerBurst);
+
+finish:
+    AAudioStream_close(aaudioStream);
+    AAudioStreamBuilder_delete(aaudioBuilder);
+    printf("          result = %d = %s\n", result, AAudio_convertResultToText(result));
+}
+
+//void foo() { // for tricking the Android Studio formatter
+TEST(test_open_params, aaudio_open_all) {
+    aaudio_direction_t directions[] = {AAUDIO_DIRECTION_OUTPUT, AAUDIO_DIRECTION_INPUT};
+    aaudio_audio_format_t formats[] = {AAUDIO_FORMAT_UNSPECIFIED, AAUDIO_FORMAT_PCM_I16, AAUDIO_FORMAT_PCM_FLOAT};
+    int32_t rates[] = {AAUDIO_UNSPECIFIED, 22050, 32000, 44100, 48000, 88200, 96000, 37913, 59132};
+
+    // Make printf print immediately so that debug info is not stuck
+    // in a buffer if we hang or crash.
+    setvbuf(stdout, nullptr, _IONBF, (size_t) 0);
+
+    for (uint dirIndex = 0;dirIndex < arraysize(directions); dirIndex++) {
+        aaudio_direction_t direction = directions[dirIndex];
+        for (int32_t channelCount = 0; channelCount <= 8; channelCount++) {
+            testOpenOptions(direction, channelCount,
+                            AAUDIO_UNSPECIFIED, AAUDIO_FORMAT_UNSPECIFIED);
+        }
+        for (uint i = 0; i < arraysize(rates); i++) {
+            testOpenOptions(direction, AAUDIO_UNSPECIFIED, rates[i], AAUDIO_FORMAT_UNSPECIFIED);
+        }
+        for (uint i = 0; i < arraysize(formats); i++) {
+            testOpenOptions(direction, AAUDIO_UNSPECIFIED, AAUDIO_UNSPECIFIED, formats[i]);
+        }
+    }
+}
diff --git a/media/libaudiohal/StreamHalHidl.cpp b/media/libaudiohal/StreamHalHidl.cpp
index 5b06b73..42785d5 100644
--- a/media/libaudiohal/StreamHalHidl.cpp
+++ b/media/libaudiohal/StreamHalHidl.cpp
@@ -158,7 +158,7 @@
                 if (retval == Result::OK) {
                     const native_handle *handle = hidlInfo.sharedMemory.handle();
                     if (handle->numFds > 0) {
-                        info->shared_memory_fd = dup(handle->data[0]);
+                        info->shared_memory_fd = handle->data[0];
                         info->buffer_size_frames = hidlInfo.bufferSizeFrames;
                         info->burst_size_frames = hidlInfo.burstSizeFrames;
                         // info->shared_memory_address is not needed in HIDL context
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
index 0c06976..ad788f7 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
@@ -588,10 +588,10 @@
 
     // log only non-empty records
     // we always updateMetrics() before we get here
-    // and that always injects 2 fields (duration and playing time) into
-    // the record.
-    // So the canonical "empty" record has 2 elements in it.
-    if (mAnalyticsItem->count() > 2) {
+    // and that always injects 3 fields (duration, playing time, and
+    // datasource) into the record.
+    // So the canonical "empty" record has 3 elements in it.
+    if (mAnalyticsItem->count() > 3) {
 
         mAnalyticsItem->setFinalized(true);
         mAnalyticsItem->selfrecord();
diff --git a/media/libstagefright/OggExtractor.cpp b/media/libstagefright/OggExtractor.cpp
index 0343786..e31c37c 100644
--- a/media/libstagefright/OggExtractor.cpp
+++ b/media/libstagefright/OggExtractor.cpp
@@ -697,7 +697,21 @@
             if (buffer != NULL) {
                 fullSize += buffer->range_length();
             }
-            MediaBuffer *tmp = new MediaBuffer(fullSize);
+            if (fullSize > 16 * 1024 * 1024) { // arbitrary limit of 16 MB packet size
+                if (buffer != NULL) {
+                    buffer->release();
+                }
+                ALOGE("b/36592202");
+                return ERROR_MALFORMED;
+            }
+            MediaBuffer *tmp = new (std::nothrow) MediaBuffer(fullSize);
+            if (tmp == NULL) {
+                if (buffer != NULL) {
+                    buffer->release();
+                }
+                ALOGE("b/36592202");
+                return ERROR_MALFORMED;
+            }
             if (buffer != NULL) {
                 memcpy(tmp->data(), buffer->data(), buffer->range_length());
                 tmp->set_range(0, buffer->range_length());
diff --git a/services/camera/libcameraservice/common/CameraProviderManager.cpp b/services/camera/libcameraservice/common/CameraProviderManager.cpp
index 65633db..b9d6843 100644
--- a/services/camera/libcameraservice/common/CameraProviderManager.cpp
+++ b/services/camera/libcameraservice/common/CameraProviderManager.cpp
@@ -87,11 +87,7 @@
     int count = 0;
     for (auto& provider : mProviders) {
         if (kStandardProviderTypes.find(provider->getType()) != std::string::npos) {
-            for (auto& device : provider->mDevices) {
-                if (device->isAPI1Compatible()) {
-                    count++;
-                }
-            }
+            count += provider->mUniqueAPI1CompatibleCameraIds.size();
         }
     }
     return count;
@@ -113,10 +109,8 @@
     std::vector<std::string> deviceIds;
     for (auto& provider : mProviders) {
         if (kStandardProviderTypes.find(provider->getType()) != std::string::npos) {
-            for (auto& device : provider->mDevices) {
-                if (device->isAPI1Compatible()) {
-                    deviceIds.push_back(device->mId);
-                }
+            for (auto& id : provider->mUniqueAPI1CompatibleCameraIds) {
+                deviceIds.push_back(id);
             }
         }
     }
@@ -466,6 +460,7 @@
         mProviderName(providerName),
         mInterface(interface),
         mProviderTagid(generateVendorTagId(providerName)),
+        mUniqueDeviceCount(0),
         mManager(manager) {
     (void) mManager;
 }
@@ -539,6 +534,9 @@
 
     for (auto& device : mDevices) {
         mUniqueCameraIds.insert(device->mId);
+        if (device->isAPI1Compatible()) {
+            mUniqueAPI1CompatibleCameraIds.insert(device->mId);
+        }
     }
     mUniqueDeviceCount = mUniqueCameraIds.size();
 
diff --git a/services/camera/libcameraservice/common/CameraProviderManager.h b/services/camera/libcameraservice/common/CameraProviderManager.h
index 9ba7f91..e82282f 100644
--- a/services/camera/libcameraservice/common/CameraProviderManager.h
+++ b/services/camera/libcameraservice/common/CameraProviderManager.h
@@ -315,6 +315,7 @@
         std::vector<std::unique_ptr<DeviceInfo>> mDevices;
         std::set<std::string> mUniqueCameraIds;
         int mUniqueDeviceCount;
+        std::set<std::string> mUniqueAPI1CompatibleCameraIds;
 
         // HALv1-specific camera fields, including the actual device interface
         struct DeviceInfo1 : public DeviceInfo {