Merge "audioservice: add RTT mode observer" into qt-dev
diff --git a/apex/manifest.json b/apex/manifest.json
index 03b9dd0..3011ee8 100644
--- a/apex/manifest.json
+++ b/apex/manifest.json
@@ -1,4 +1,4 @@
 {
   "name": "com.android.media",
-  "version": 220000000
+  "version": 290000000
 }
diff --git a/apex/manifest_codec.json b/apex/manifest_codec.json
index 58ce868..83a5178 100644
--- a/apex/manifest_codec.json
+++ b/apex/manifest_codec.json
@@ -1,4 +1,4 @@
 {
   "name": "com.android.media.swcodec",
-  "version": 220000000
+  "version": 290000000
 }
diff --git a/media/codec2/sfplugin/CCodecConfig.cpp b/media/codec2/sfplugin/CCodecConfig.cpp
index 077a91f..1cfdc19 100644
--- a/media/codec2/sfplugin/CCodecConfig.cpp
+++ b/media/codec2/sfplugin/CCodecConfig.cpp
@@ -508,7 +508,7 @@
                .limitTo(D::ENCODER & D::VIDEO));
     // convert to timestamp base
     add(ConfigMapper(KEY_I_FRAME_INTERVAL, C2_PARAMKEY_SYNC_FRAME_INTERVAL, "value")
-        .withMapper([](C2Value v) -> C2Value {
+        .withMappers([](C2Value v) -> C2Value {
             // convert from i32 to float
             int32_t i32Value;
             float fpValue;
@@ -518,6 +518,12 @@
                 return int64_t(c2_min(1000000 * fpValue + 0.5, (double)INT64_MAX));
             }
             return C2Value();
+        }, [](C2Value v) -> C2Value {
+            int64_t i64;
+            if (v.get(&i64)) {
+                return float(i64) / 1000000;
+            }
+            return C2Value();
         }));
     // remove when codecs switch to proper coding.gop (add support for calculating gop)
     deprecated(ConfigMapper("i-frame-period", "coding.gop", "intra-period")
@@ -711,7 +717,7 @@
 
     // convert to dBFS and add default
     add(ConfigMapper(KEY_AAC_DRC_TARGET_REFERENCE_LEVEL, C2_PARAMKEY_DRC_TARGET_REFERENCE_LEVEL, "value")
-        .limitTo(D::AUDIO & D::DECODER)
+        .limitTo(D::AUDIO & D::DECODER & D::CONFIG)
         .withMapper([](C2Value v) -> C2Value {
             int32_t value;
             if (!v.get(&value) || value < 0) {
@@ -722,7 +728,7 @@
 
     // convert to 0-1 (%) and add default
     add(ConfigMapper(KEY_AAC_DRC_ATTENUATION_FACTOR, C2_PARAMKEY_DRC_ATTENUATION_FACTOR, "value")
-        .limitTo(D::AUDIO & D::DECODER)
+        .limitTo(D::AUDIO & D::DECODER & D::CONFIG)
         .withMapper([](C2Value v) -> C2Value {
             int32_t value;
             if (!v.get(&value) || value < 0) {
@@ -733,7 +739,7 @@
 
     // convert to 0-1 (%) and add default
     add(ConfigMapper(KEY_AAC_DRC_BOOST_FACTOR, C2_PARAMKEY_DRC_BOOST_FACTOR, "value")
-        .limitTo(D::AUDIO & D::DECODER)
+        .limitTo(D::AUDIO & D::DECODER & D::CONFIG)
         .withMapper([](C2Value v) -> C2Value {
             int32_t value;
             if (!v.get(&value) || value < 0) {
@@ -744,7 +750,7 @@
 
     // convert to compression type and add default
     add(ConfigMapper(KEY_AAC_DRC_HEAVY_COMPRESSION, C2_PARAMKEY_DRC_COMPRESSION_MODE, "value")
-        .limitTo(D::AUDIO & D::DECODER)
+        .limitTo(D::AUDIO & D::DECODER & D::CONFIG)
         .withMapper([](C2Value v) -> C2Value {
             int32_t value;
             if (!v.get(&value) || value < 0) {
@@ -755,7 +761,7 @@
 
     // convert to dBFS and add default
     add(ConfigMapper(KEY_AAC_ENCODED_TARGET_LEVEL, C2_PARAMKEY_DRC_ENCODED_TARGET_LEVEL, "value")
-        .limitTo(D::AUDIO & D::DECODER)
+        .limitTo(D::AUDIO & D::DECODER & D::CONFIG)
         .withMapper([](C2Value v) -> C2Value {
             int32_t value;
             if (!v.get(&value) || value < 0) {
@@ -766,7 +772,7 @@
 
     // convert to effect type (these map to SDK values) and add default
     add(ConfigMapper(KEY_AAC_DRC_EFFECT_TYPE, C2_PARAMKEY_DRC_EFFECT_TYPE, "value")
-        .limitTo(D::AUDIO & D::DECODER)
+        .limitTo(D::AUDIO & D::DECODER & D::CONFIG)
         .withMapper([](C2Value v) -> C2Value {
             int32_t value;
             if (!v.get(&value) || value < -1 || value > 8) {
diff --git a/media/libstagefright/OggWriter.cpp b/media/libstagefright/OggWriter.cpp
index cb87b55..b738fef 100644
--- a/media/libstagefright/OggWriter.cpp
+++ b/media/libstagefright/OggWriter.cpp
@@ -52,6 +52,7 @@
 
 OggWriter::OggWriter(int fd)
       : mFd(dup(fd)),
+        mHaveAllCodecSpecificData(false),
         mInitCheck(mFd < 0 ? NO_INIT : OK) {
     // empty
 }
@@ -115,17 +116,26 @@
 
     mSampleRate = sampleRate;
     uint32_t type;
-    const void *header_data;
-    size_t packet_size;
+    const void *header_data = NULL;
+    size_t packet_size = 0;
+
     if (!source->getFormat()->findData(kKeyOpusHeader, &type, &header_data, &packet_size)) {
-        ALOGE("opus header not found");
-        return UNKNOWN_ERROR;
+        ALOGV("opus header not found in format");
+    } else if (header_data && packet_size) {
+        writeOggHeaderPackets((unsigned char *)header_data, packet_size);
+    } else {
+        ALOGD("ignoring incomplete opus header data in format");
     }
 
+    mSource = source;
+    return OK;
+}
+
+status_t OggWriter::writeOggHeaderPackets(unsigned char *buf, size_t size) {
     ogg_packet op;
     ogg_page og;
-    op.packet = (unsigned char *)header_data;
-    op.bytes = packet_size;
+    op.packet = buf;
+    op.bytes = size;
     op.b_o_s = 1;
     op.e_o_s = 0;
     op.granulepos = 0;
@@ -169,8 +179,8 @@
         write(mFd, og.body, og.body_len);
     }
 
-    mSource = source;
     free(comments);
+    mHaveAllCodecSpecificData = true;
     return OK;
 }
 
@@ -301,12 +311,35 @@
              && isCodecSpecific)
             || IsOpusHeader((uint8_t*)buffer->data() + buffer->range_offset(),
                          buffer->range_length())) {
-            ALOGV("Drop codec specific info buffer");
+            if (mHaveAllCodecSpecificData == false) {
+                size_t opusHeadSize = 0;
+                size_t codecDelayBufSize = 0;
+                size_t seekPreRollBufSize = 0;
+                void *opusHeadBuf = NULL;
+                void *codecDelayBuf = NULL;
+                void *seekPreRollBuf = NULL;
+                GetOpusHeaderBuffers((uint8_t*)buffer->data() + buffer->range_offset(),
+                                    buffer->range_length(), &opusHeadBuf,
+                                    &opusHeadSize, &codecDelayBuf,
+                                    &codecDelayBufSize, &seekPreRollBuf,
+                                    &seekPreRollBufSize);
+                writeOggHeaderPackets((unsigned char *)opusHeadBuf, opusHeadSize);
+            } else {
+                ALOGV("ignoring later copy of CSD contained in info buffer");
+            }
             buffer->release();
             buffer = nullptr;
             continue;
         }
 
+        if (mHaveAllCodecSpecificData == false) {
+            ALOGE("Did not get valid opus header before first sample data");
+            buffer->release();
+            buffer = nullptr;
+            err = ERROR_MALFORMED;
+            break;
+        }
+
         int64_t timestampUs;
         CHECK(buffer->meta_data().findInt64(kKeyTime, &timestampUs));
         if (timestampUs > mEstimatedDurationUs) {
diff --git a/media/libstagefright/include/media/stagefright/OggWriter.h b/media/libstagefright/include/media/stagefright/OggWriter.h
index e3837cd..1a0a1d2 100644
--- a/media/libstagefright/include/media/stagefright/OggWriter.h
+++ b/media/libstagefright/include/media/stagefright/OggWriter.h
@@ -43,6 +43,7 @@
 
 private:
     int mFd;
+    bool mHaveAllCodecSpecificData;
     status_t mInitCheck;
     sp<MediaSource> mSource;
     bool mStarted = false;
@@ -66,6 +67,8 @@
 
     OggWriter(const OggWriter&);
     OggWriter& operator=(const OggWriter&);
+
+    status_t writeOggHeaderPackets(unsigned char *buf, size_t size);
 };
 
 }  // namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp
index dca84c0..c42923a 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp
@@ -120,8 +120,9 @@
 
     ALOGV("getAudioPolicyMix() for dev=0x%x addr=%s", deviceType, address.string());
     for (ssize_t i = 0; i < size(); i++) {
-        if (itemAt(i)->mDeviceType == deviceType
-                && itemAt(i)->mDeviceAddress.compare(address) == 0) {
+        // Workaround: when an in audio policy is registered, it opens an output
+        // that tries to find the audio policy, thus the device must be ignored.
+        if (itemAt(i)->mDeviceAddress.compare(address) == 0) {
             policyMix = itemAt(i);
             ALOGV("getAudioPolicyMix: found mix %zu match (devType=0x%x addr=%s)",
                     i, deviceType, address.string());
diff --git a/services/camera/libcameraservice/device3/Camera3Stream.cpp b/services/camera/libcameraservice/device3/Camera3Stream.cpp
index 6d76802..2df084b 100644
--- a/services/camera/libcameraservice/device3/Camera3Stream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Stream.cpp
@@ -60,6 +60,8 @@
     mUsage(0),
     mOldUsage(0),
     mOldMaxBuffers(0),
+    mOldFormat(-1),
+    mOldDataSpace(HAL_DATASPACE_UNKNOWN),
     mPrepared(false),
     mPrepareBlockRequest(true),
     mPreparedBufferIdx(0),
@@ -256,6 +258,8 @@
 
     mOldUsage = mUsage;
     mOldMaxBuffers = camera3_stream::max_buffers;
+    mOldFormat = camera3_stream::format;
+    mOldDataSpace = camera3_stream::data_space;
 
     res = getEndpointUsage(&mUsage);
     if (res != OK) {
@@ -330,7 +334,9 @@
     // so. As documented in hardware/camera3.h:configure_streams().
     if (mState == STATE_IN_RECONFIG &&
             mOldUsage == mUsage &&
-            mOldMaxBuffers == camera3_stream::max_buffers && !mDataSpaceOverridden) {
+            mOldMaxBuffers == camera3_stream::max_buffers &&
+            mOldDataSpace == camera3_stream::data_space &&
+            mOldFormat == camera3_stream::format) {
         mState = STATE_CONFIGURED;
         return OK;
     }
diff --git a/services/camera/libcameraservice/device3/Camera3Stream.h b/services/camera/libcameraservice/device3/Camera3Stream.h
index c916fe8..533318f 100644
--- a/services/camera/libcameraservice/device3/Camera3Stream.h
+++ b/services/camera/libcameraservice/device3/Camera3Stream.h
@@ -540,8 +540,12 @@
     uint64_t mUsage;
 
   private:
+    // Previously configured stream properties (post HAL override)
     uint64_t mOldUsage;
     uint32_t mOldMaxBuffers;
+    int mOldFormat;
+    android_dataspace mOldDataSpace;
+
     Condition mOutputBufferReturnedSignal;
     Condition mInputBufferReturnedSignal;
     static const nsecs_t kWaitForBufferDuration = 3000000000LL; // 3000 ms