Merge "avoid crash in emptyBuffer when input buffer handle is invalid" 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/camera/ndk/ndk_vendor/impl/ACameraDevice.cpp b/camera/ndk/ndk_vendor/impl/ACameraDevice.cpp
index 529c167..a43d707 100644
--- a/camera/ndk/ndk_vendor/impl/ACameraDevice.cpp
+++ b/camera/ndk/ndk_vendor/impl/ACameraDevice.cpp
@@ -31,6 +31,17 @@
 
 #include "ACameraCaptureSession.inc"
 
+#define CHECK_TRANSACTION_AND_RET(remoteRet, status, callName) \
+    if (!remoteRet.isOk()) { \
+        ALOGE("%s: Transaction error during %s call %s", __FUNCTION__, callName, \
+                  remoteRet.description().c_str()); \
+        return ACAMERA_ERROR_UNKNOWN; \
+    } \
+    if (status != Status::NO_ERROR) { \
+        ALOGE("%s: %s call failed", __FUNCTION__, callName); \
+        return utils::convertFromHidl(status); \
+    }
+
 using namespace android;
 
 namespace android {
@@ -151,7 +162,7 @@
         return ACAMERA_ERROR_CAMERA_DISCONNECTED;
     }
     CameraMetadata rawRequest;
-    Status status = Status::NO_ERROR;
+    Status status = Status::UNKNOWN_ERROR;
     auto remoteRet = mRemote->createDefaultRequest(
         utils::convertToHidl(templateId),
         [&status, &rawRequest](auto s, const hidl_vec<uint8_t> &metadata) {
@@ -161,14 +172,7 @@
                 ALOGE("%s: Couldn't create default request", __FUNCTION__);
             }
         });
-    if (!remoteRet.isOk()) {
-        ALOGE("%s: Transaction error while trying to create default request %s", __FUNCTION__,
-              remoteRet.description().c_str());
-        return ACAMERA_ERROR_UNKNOWN;
-    }
-    if (status != Status::NO_ERROR) {
-        return utils::convertFromHidl(status);
-    }
+    CHECK_TRANSACTION_AND_RET(remoteRet, status, "createDefaultRequest()")
     ACaptureRequest* outReq = new ACaptureRequest();
     outReq->settings = new ACameraMetadata(rawRequest.release(), ACameraMetadata::ACM_REQUEST);
     if (physicalCameraIdList != nullptr) {
@@ -243,20 +247,15 @@
     }
 
     bool configSupported = false;
-    Status status = Status::NO_ERROR;
+    Status status = Status::UNKNOWN_ERROR;
     auto remoteRet = mRemote->isSessionConfigurationSupported(sessionConfig,
         [&status, &configSupported](auto s, auto supported) {
             status = s;
             configSupported = supported;
         });
 
-    if (status == Status::INVALID_OPERATION) {
-        return ACAMERA_ERROR_UNSUPPORTED_OPERATION;
-    } else if (!remoteRet.isOk()) {
-        return ACAMERA_ERROR_UNKNOWN;
-    } else {
-        return configSupported ? ACAMERA_OK : ACAMERA_ERROR_STREAM_CONFIGURE_FAIL;
-    }
+    CHECK_TRANSACTION_AND_RET(remoteRet, status, "isSessionConfigurationSupported()");
+    return configSupported ? ACAMERA_OK : ACAMERA_ERROR_STREAM_CONFIGURE_FAIL;
 }
 
 static void addMetadataToPhysicalCameraSettings(const CameraMetadata *metadata,
@@ -525,16 +524,13 @@
         mRepeatingSequenceId = REQUEST_ID_NONE;
 
         int64_t lastFrameNumber;
-        Status status = Status::NO_ERROR;
+        Status status = Status::UNKNOWN_ERROR;
         auto remoteRet = mRemote->cancelRepeatingRequest(
                 [&status, &lastFrameNumber](Status s, auto frameNumber) {
                     status = s;
                     lastFrameNumber = frameNumber;
                 });
-        if (!remoteRet.isOk() || status != Status::NO_ERROR) {
-            ALOGE("%s: Unable to cancel active repeating request", __FUNCTION__);
-            return utils::convertFromHidl(status);
-        }
+        CHECK_TRANSACTION_AND_RET(remoteRet, status, "cancelRepeatingRequest()");
         checkRepeatingSequenceCompleteLocked(repeatingSequenceId, lastFrameNumber);
     }
     return ACAMERA_OK;
@@ -582,15 +578,12 @@
     }
 
     int64_t lastFrameNumber;
-    Status status;
+    Status status = Status::UNKNOWN_ERROR;
     auto remoteRet = mRemote->flush([&status, &lastFrameNumber](auto s, auto frameNumber) {
                                         status = s;
                                         lastFrameNumber = frameNumber;
                                     });
-    if (!remoteRet.isOk() || status != Status::NO_ERROR) {
-        ALOGE("%s: Abort captures failed", __FUNCTION__);
-        return utils::convertFromHidl(status);
-    }
+    CHECK_TRANSACTION_AND_RET(remoteRet, status, "flush()")
     if (mRepeatingSequenceId != REQUEST_ID_NONE) {
         checkRepeatingSequenceCompleteLocked(mRepeatingSequenceId, lastFrameNumber);
     }
@@ -611,10 +604,7 @@
     }
 
     auto remoteRet = mRemote->waitUntilIdle();
-    if (!remoteRet.isOk()) {
-        ALOGE("%s: Transaction waitUntilIdle failed", __FUNCTION__);
-        return utils::convertFromHidl(remoteRet);
-    }
+    CHECK_TRANSACTION_AND_RET(remoteRet, remoteRet, "waitUntilIdle()")
     return ACAMERA_OK;
 }
 
@@ -689,34 +679,25 @@
     mIdle = true;
 
     auto remoteRet = mRemote->beginConfigure();
-    if (!remoteRet.isOk()|| remoteRet != Status::NO_ERROR) {
-        ALOGE("Camera device %s begin configure failed", getId());
-        return utils::convertFromHidl(remoteRet);
-    }
+    CHECK_TRANSACTION_AND_RET(remoteRet, remoteRet, "beginConfigure()")
 
     // delete to-be-deleted streams
     for (auto streamId : deleteList) {
         remoteRet = mRemote->deleteStream(streamId);
-        if (!remoteRet.isOk() || remoteRet != Status::NO_ERROR) {
-            ALOGE("Camera device %s failed to remove stream %d", getId(), streamId);
-            return utils::convertFromHidl(remoteRet);
-        }
+        CHECK_TRANSACTION_AND_RET(remoteRet, remoteRet, "deleteStream()")
         mConfiguredOutputs.erase(streamId);
     }
 
     // add new streams
     for (auto outputPair : addSet) {
         int streamId;
-        Status status;
+        Status status = Status::UNKNOWN_ERROR;
         auto ret = mRemote->createStream(outputPair.second,
                                          [&status, &streamId](Status s, auto stream_id) {
                                              status = s;
                                              streamId = stream_id;
                                          });
-        if (!remoteRet.isOk() || status != Status::NO_ERROR) {
-            ALOGE("Camera device %s failed to create stream", getId());
-            return utils::convertFromHidl(status);
-        }
+        CHECK_TRANSACTION_AND_RET(ret, status, "createStream()")
         mConfiguredOutputs.insert(std::make_pair(streamId, outputPair));
     }
 
@@ -729,11 +710,8 @@
         params.unlock(params_metadata);
     }
     remoteRet = mRemote->endConfigure(StreamConfigurationMode::NORMAL_MODE, hidlParams);
-    if (!remoteRet.isOk()) {
-        ALOGE("Transaction error: endConfigure failed %s", remoteRet.description().c_str());
-    }
-
-    return utils::convertFromHidl(remoteRet);
+    CHECK_TRANSACTION_AND_RET(remoteRet, remoteRet, "endConfigure()")
+    return ACAMERA_OK;
 }
 
 void
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/libaudioclient/AudioSystem.cpp b/media/libaudioclient/AudioSystem.cpp
index 1e7f9fa..02dc516 100644
--- a/media/libaudioclient/AudioSystem.cpp
+++ b/media/libaudioclient/AudioSystem.cpp
@@ -1512,6 +1512,13 @@
     return aps->getVolumeGroupFromAudioAttributes(aa, volumeGroup);
 }
 
+status_t AudioSystem::setRttEnabled(bool enabled)
+{
+    const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+    if (aps == 0) return PERMISSION_DENIED;
+    return aps->setRttEnabled(enabled);
+}
+
 // ---------------------------------------------------------------------------
 
 int AudioSystem::AudioPolicyServiceClient::addAudioPortCallback(
diff --git a/media/libaudioclient/IAudioPolicyService.cpp b/media/libaudioclient/IAudioPolicyService.cpp
index c548457..64f0aca 100644
--- a/media/libaudioclient/IAudioPolicyService.cpp
+++ b/media/libaudioclient/IAudioPolicyService.cpp
@@ -104,6 +104,7 @@
     GET_VOLUME_GROUP_FOR_ATTRIBUTES,
     SET_ALLOWED_CAPTURE_POLICY,
     MOVE_EFFECTS_TO_IO,
+    SET_RTT_ENABLED
 };
 
 #define MAX_ITEMS_PER_LIST 1024
@@ -1271,6 +1272,18 @@
         volumeGroup = static_cast<volume_group_t>(reply.readInt32());
         return NO_ERROR;
     }
+
+    virtual status_t setRttEnabled(bool enabled)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
+        data.writeInt32(static_cast<int32_t>(enabled));
+        status_t status = remote()->transact(SET_RTT_ENABLED, data, &reply);
+        if (status != NO_ERROR) {
+           return status;
+        }
+        return static_cast<status_t>(reply.readInt32());
+    }
 };
 
 IMPLEMENT_META_INTERFACE(AudioPolicyService, "android.media.IAudioPolicyService");
@@ -1332,7 +1345,8 @@
         case REMOVE_UID_DEVICE_AFFINITY:
         case GET_OFFLOAD_FORMATS_A2DP:
         case LIST_AUDIO_VOLUME_GROUPS:
-        case GET_VOLUME_GROUP_FOR_ATTRIBUTES: {
+        case GET_VOLUME_GROUP_FOR_ATTRIBUTES:
+        case SET_RTT_ENABLED: {
             if (!isServiceUid(IPCThreadState::self()->getCallingUid())) {
                 ALOGW("%s: transaction %d received from PID %d unauthorized UID %d",
                       __func__, code, IPCThreadState::self()->getCallingPid(),
@@ -2347,6 +2361,14 @@
             return NO_ERROR;
         }
 
+        case SET_RTT_ENABLED: {
+            CHECK_INTERFACE(IAudioPolicyService, data, reply);
+            bool enabled = static_cast<bool>(data.readInt32());
+            status_t status = setRttEnabled(enabled);
+            reply->writeInt32(status);
+            return NO_ERROR;
+        }
+
         default:
             return BBinder::onTransact(code, data, reply, flags);
     }
diff --git a/media/libaudioclient/include/media/AudioSystem.h b/media/libaudioclient/include/media/AudioSystem.h
index 56c69f6..09e80b2 100644
--- a/media/libaudioclient/include/media/AudioSystem.h
+++ b/media/libaudioclient/include/media/AudioSystem.h
@@ -394,6 +394,8 @@
     static status_t getVolumeGroupFromAudioAttributes(const AudioAttributes &aa,
                                                       volume_group_t &volumeGroup);
 
+    static status_t setRttEnabled(bool enabled);
+
     // ----------------------------------------------------------------------------
 
     class AudioVolumeGroupCallback : public RefBase
diff --git a/media/libaudioclient/include/media/IAudioPolicyService.h b/media/libaudioclient/include/media/IAudioPolicyService.h
index 33ab1f9..32275cf 100644
--- a/media/libaudioclient/include/media/IAudioPolicyService.h
+++ b/media/libaudioclient/include/media/IAudioPolicyService.h
@@ -220,6 +220,8 @@
     virtual status_t listAudioVolumeGroups(AudioVolumeGroupVector &groups) = 0;
     virtual status_t getVolumeGroupFromAudioAttributes(const AudioAttributes &aa,
                                                        volume_group_t &volumeGroup) = 0;
+
+    virtual status_t setRttEnabled(bool enabled) = 0;
 };
 
 
diff --git a/media/libmediaplayerservice/nuplayer/GenericSource.cpp b/media/libmediaplayerservice/nuplayer/GenericSource.cpp
index 5a58aa0..5c77e41 100644
--- a/media/libmediaplayerservice/nuplayer/GenericSource.cpp
+++ b/media/libmediaplayerservice/nuplayer/GenericSource.cpp
@@ -90,8 +90,11 @@
     ALOGV("resetDataSource");
 
     mHTTPService.clear();
-    mHttpSource.clear();
-    mDisconnected = false;
+    {
+        Mutex::Autolock _l_d(mDisconnectLock);
+        mHttpSource.clear();
+        mDisconnected = false;
+    }
     mUri.clear();
     mUriHeaders.clear();
     mSources.clear();
@@ -152,7 +155,10 @@
     ALOGV("setDataSource (source: %p)", source.get());
 
     resetDataSource();
-    mDataSource = source;
+    {
+        Mutex::Autolock _l_d(mDisconnectLock);
+        mDataSource = source;
+    }
     return OK;
 }
 
@@ -163,8 +169,12 @@
 
 status_t NuPlayer::GenericSource::initFromDataSource() {
     sp<IMediaExtractor> extractor;
-    CHECK(mDataSource != NULL);
-    sp<DataSource> dataSource = mDataSource;
+    sp<DataSource> dataSource;
+    {
+        Mutex::Autolock _l_d(mDisconnectLock);
+        dataSource = mDataSource;
+    }
+    CHECK(dataSource != NULL);
 
     mLock.unlock();
     // This might take long time if data source is not reliable.
@@ -359,6 +369,7 @@
 }
 
 void NuPlayer::GenericSource::onPrepareAsync() {
+    mDisconnectLock.lock();
     ALOGV("onPrepareAsync: mDataSource: %d", (mDataSource != NULL));
 
     // delayed data source creation
@@ -372,20 +383,30 @@
             String8 contentType;
 
             if (!strncasecmp("http://", uri, 7) || !strncasecmp("https://", uri, 8)) {
-                mHttpSource = DataSourceFactory::CreateMediaHTTP(mHTTPService);
-                if (mHttpSource == NULL) {
+                sp<DataSource> httpSource;
+                mDisconnectLock.unlock();
+                httpSource = DataSourceFactory::CreateMediaHTTP(mHTTPService);
+                if (httpSource == NULL) {
                     ALOGE("Failed to create http source!");
                     notifyPreparedAndCleanup(UNKNOWN_ERROR);
+                    mDisconnectLock.lock();
                     return;
                 }
+                mDisconnectLock.lock();
+
+                if (!mDisconnected) {
+                    mHttpSource = httpSource;
+                }
             }
 
             mLock.unlock();
+            mDisconnectLock.unlock();
             // This might take long time if connection has some issue.
             sp<DataSource> dataSource = DataSourceFactory::CreateFromURI(
                    mHTTPService, uri, &mUriHeaders, &contentType,
                    static_cast<HTTPBase *>(mHttpSource.get()));
             mLock.lock();
+            mDisconnectLock.lock();
             if (!mDisconnected) {
                 mDataSource = dataSource;
             }
@@ -437,6 +458,8 @@
         mCachedSource = static_cast<NuCachedSource2 *>(mDataSource.get());
     }
 
+    mDisconnectLock.unlock();
+
     // For cached streaming cases, we need to wait for enough
     // buffering before reporting prepared.
     mIsStreaming = (mCachedSource != NULL);
@@ -503,9 +526,13 @@
 
 void NuPlayer::GenericSource::notifyPreparedAndCleanup(status_t err) {
     if (err != OK) {
-        mDataSource.clear();
+        {
+            Mutex::Autolock _l_d(mDisconnectLock);
+            mDataSource.clear();
+            mHttpSource.clear();
+        }
+
         mCachedSource.clear();
-        mHttpSource.clear();
 
         mBitrate = -1;
         mPrevBufferPercentage = -1;
@@ -547,7 +574,7 @@
 void NuPlayer::GenericSource::disconnect() {
     sp<DataSource> dataSource, httpSource;
     {
-        Mutex::Autolock _l(mLock);
+        Mutex::Autolock _l_d(mDisconnectLock);
         dataSource = mDataSource;
         httpSource = mHttpSource;
         mDisconnected = true;
diff --git a/media/libmediaplayerservice/nuplayer/GenericSource.h b/media/libmediaplayerservice/nuplayer/GenericSource.h
index 065cac1..4d1905d 100644
--- a/media/libmediaplayerservice/nuplayer/GenericSource.h
+++ b/media/libmediaplayerservice/nuplayer/GenericSource.h
@@ -170,6 +170,7 @@
     sp<ABuffer> mGlobalTimedText;
 
     mutable Mutex mLock;
+    mutable Mutex mDisconnectLock; // Protects mDataSource, mHttpSource and mDisconnected
 
     sp<ALooper> mLooper;
 
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/media/utils/ServiceUtilities.cpp b/media/utils/ServiceUtilities.cpp
index 16fdeaf..b824212 100644
--- a/media/utils/ServiceUtilities.cpp
+++ b/media/utils/ServiceUtilities.cpp
@@ -128,7 +128,7 @@
     if (isAudioServerOrRootUid(uid)) return true;
     static const String16 sCaptureAudioOutput("android.permission.CAPTURE_AUDIO_OUTPUT");
     bool ok = PermissionCache::checkPermission(sCaptureAudioOutput, pid, uid);
-    if (!ok) ALOGE("Request requires android.permission.CAPTURE_AUDIO_OUTPUT");
+    if (!ok) ALOGV("Request requires android.permission.CAPTURE_AUDIO_OUTPUT");
     return ok;
 }
 
@@ -149,7 +149,7 @@
         // IMPORTANT: Use PermissionCache - not a runtime permission and may not change.
         ok = PermissionCache::checkPermission(sCaptureHotwordAllowed, pid, uid);
     }
-    if (!ok) ALOGE("android.permission.CAPTURE_AUDIO_HOTWORD");
+    if (!ok) ALOGV("android.permission.CAPTURE_AUDIO_HOTWORD");
     return ok;
 }
 
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/audiopolicy/service/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
index b0a8541..fa8da89 100644
--- a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
@@ -193,7 +193,8 @@
     if (!mPackageManager.allowPlaybackCapture(uid)) {
         attr->flags |= AUDIO_FLAG_NO_MEDIA_PROJECTION;
     }
-    if (!bypassInterruptionPolicyAllowed(pid, uid)) {
+    if (((attr->flags & (AUDIO_FLAG_BYPASS_INTERRUPTION_POLICY|AUDIO_FLAG_BYPASS_MUTE)) != 0)
+            && !bypassInterruptionPolicyAllowed(pid, uid)) {
         attr->flags &= ~(AUDIO_FLAG_BYPASS_INTERRUPTION_POLICY|AUDIO_FLAG_BYPASS_MUTE);
     }
     audio_output_flags_t originalFlags = flags;
@@ -1316,4 +1317,12 @@
     Mutex::Autolock _l(mLock);
     return mAudioPolicyManager->getVolumeGroupFromAudioAttributes(aa, volumeGroup);
 }
+
+status_t AudioPolicyService::setRttEnabled(bool enabled)
+{
+    Mutex::Autolock _l(mLock);
+    mUidPolicy->setRttEnabled(enabled);
+    return NO_ERROR;
+}
+
 } // namespace android
diff --git a/services/audiopolicy/service/AudioPolicyService.cpp b/services/audiopolicy/service/AudioPolicyService.cpp
index e3c72ae..77f7997 100644
--- a/services/audiopolicy/service/AudioPolicyService.cpp
+++ b/services/audiopolicy/service/AudioPolicyService.cpp
@@ -409,7 +409,7 @@
 //    following cases:
 //    Another client in the same UID has already been allowed to capture
 //    OR The client is the assistant
-//        AND an accessibility service is on TOP
+//        AND an accessibility service is on TOP or a RTT call is active
 //               AND the source is VOICE_RECOGNITION or HOTWORD
 //        OR uses VOICE_RECOGNITION AND is on TOP
 //               OR uses HOTWORD
@@ -436,6 +436,9 @@
     bool isAssistantOnTop = false;
     bool isSensitiveActive = false;
     bool isInCall = mPhoneState == AUDIO_MODE_IN_CALL;
+    bool rttCallActive =
+            (mPhoneState == AUDIO_MODE_IN_CALL || mPhoneState == AUDIO_MODE_IN_COMMUNICATION)
+            && mUidPolicy->isRttEnabled();
 
     // if Sensor Privacy is enabled then all recordings should be silenced.
     if (mSensorPrivacyPolicy->isSensorPrivacyEnabled()) {
@@ -518,13 +521,13 @@
             allowCapture = true;
         } else if (mUidPolicy->isAssistantUid(current->uid)) {
             // For assistant allow capture if:
-            //     An accessibility service is on TOP
+            //     An accessibility service is on TOP or a RTT call is active
             //            AND the source is VOICE_RECOGNITION or HOTWORD
             //     OR is on TOP AND uses VOICE_RECOGNITION
             //            OR uses HOTWORD
             //         AND there is no active privacy sensitive capture or call
             //             OR client has CAPTURE_AUDIO_OUTPUT privileged permission
-            if (isA11yOnTop) {
+            if (isA11yOnTop || rttCallActive) {
                 if (source == AUDIO_SOURCE_HOTWORD || source == AUDIO_SOURCE_VOICE_RECOGNITION) {
                     allowCapture = true;
                 }
diff --git a/services/audiopolicy/service/AudioPolicyService.h b/services/audiopolicy/service/AudioPolicyService.h
index 8db63a5..e467f70 100644
--- a/services/audiopolicy/service/AudioPolicyService.h
+++ b/services/audiopolicy/service/AudioPolicyService.h
@@ -256,6 +256,8 @@
     virtual status_t getVolumeGroupFromAudioAttributes(const AudioAttributes &aa,
                                                        volume_group_t &volumeGroup);
 
+    virtual status_t setRttEnabled(bool enabled);
+
             status_t doStopOutput(audio_port_handle_t portId);
             void doReleaseOutput(audio_port_handle_t portId);
 
@@ -345,7 +347,8 @@
     class UidPolicy : public BnUidObserver, public virtual IBinder::DeathRecipient {
     public:
         explicit UidPolicy(wp<AudioPolicyService> service)
-                : mService(service), mObserverRegistered(false), mAssistantUid(0) {}
+                : mService(service), mObserverRegistered(false),
+                  mAssistantUid(0), mRttEnabled(false) {}
 
         void registerSelf();
         void unregisterSelf();
@@ -360,6 +363,8 @@
         void setA11yUids(const std::vector<uid_t>& uids) { mA11yUids.clear(); mA11yUids = uids; }
         bool isA11yUid(uid_t uid);
         bool isA11yOnTop();
+        void setRttEnabled(bool enabled) { mRttEnabled = enabled; }
+        bool isRttEnabled() { return mRttEnabled; }
 
         // BnUidObserver implementation
         void onUidActive(uid_t uid) override;
@@ -387,6 +392,7 @@
         std::unordered_map<uid_t, std::pair<bool, int>> mCachedUids;
         uid_t mAssistantUid;
         std::vector<uid_t> mA11yUids;
+        bool mRttEnabled;
     };
 
     // If sensor privacy is enabled then all apps, including those that are active, should be
diff --git a/services/camera/libcameraservice/Android.bp b/services/camera/libcameraservice/Android.bp
index 7ec0e4c..1c1f5e6 100644
--- a/services/camera/libcameraservice/Android.bp
+++ b/services/camera/libcameraservice/Android.bp
@@ -70,6 +70,7 @@
     ],
 
     shared_libs: [
+        "libbase",
         "libdl",
         "libexif",
         "libui",
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index a87ebdf..3e62102 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -33,6 +33,7 @@
 
 #include <android-base/macros.h>
 #include <android-base/parseint.h>
+#include <android-base/stringprintf.h>
 #include <binder/ActivityManager.h>
 #include <binder/AppOpsManager.h>
 #include <binder/IPCThreadState.h>
@@ -81,6 +82,7 @@
 
 namespace android {
 
+using base::StringPrintf;
 using binder::Status;
 using frameworks::cameraservice::service::V2_0::implementation::HidlCameraService;
 using hardware::ICamera;
@@ -2366,6 +2368,13 @@
         }
         mClientPackageName = packages[0];
     }
+    if (hardware::IPCThreadState::self()->isServingCall()) {
+        std::string vendorClient =
+                StringPrintf("vendor.client.pid<%d>", CameraThreadState::getCallingPid());
+        mClientPackageName = String16(vendorClient.c_str());
+    } else {
+        mAppOpsManager = std::make_unique<AppOpsManager>();
+    }
 }
 
 CameraService::BasicClient::~BasicClient() {
@@ -2381,8 +2390,7 @@
     mDisconnected = true;
 
     sCameraService->removeByClient(this);
-    sCameraService->logDisconnected(mCameraIdStr, mClientPid,
-            String8(mClientPackageName));
+    sCameraService->logDisconnected(mCameraIdStr, mClientPid, String8(mClientPackageName));
     sCameraService->mCameraProviderManager->removeRef(CameraProviderManager::DeviceMode::CAMERA,
             mCameraIdStr.c_str());
 
@@ -2432,31 +2440,31 @@
 status_t CameraService::BasicClient::startCameraOps() {
     ATRACE_CALL();
 
-    int32_t res;
-    // Notify app ops that the camera is not available
-    mOpsCallback = new OpsCallback(this);
-
     {
         ALOGV("%s: Start camera ops, package name = %s, client UID = %d",
               __FUNCTION__, String8(mClientPackageName).string(), mClientUid);
     }
+    if (mAppOpsManager != nullptr) {
+        // Notify app ops that the camera is not available
+        mOpsCallback = new OpsCallback(this);
+        int32_t res;
+        mAppOpsManager->startWatchingMode(AppOpsManager::OP_CAMERA,
+                mClientPackageName, mOpsCallback);
+        res = mAppOpsManager->startOpNoThrow(AppOpsManager::OP_CAMERA,
+                mClientUid, mClientPackageName, /*startIfModeDefault*/ false);
 
-    mAppOpsManager.startWatchingMode(AppOpsManager::OP_CAMERA,
-            mClientPackageName, mOpsCallback);
-    res = mAppOpsManager.startOpNoThrow(AppOpsManager::OP_CAMERA,
-            mClientUid, mClientPackageName, /*startIfModeDefault*/ false);
+        if (res == AppOpsManager::MODE_ERRORED) {
+            ALOGI("Camera %s: Access for \"%s\" has been revoked",
+                    mCameraIdStr.string(), String8(mClientPackageName).string());
+            return PERMISSION_DENIED;
+        }
 
-    if (res == AppOpsManager::MODE_ERRORED) {
-        ALOGI("Camera %s: Access for \"%s\" has been revoked",
-                mCameraIdStr.string(), String8(mClientPackageName).string());
-        return PERMISSION_DENIED;
-    }
-
-    if (res == AppOpsManager::MODE_IGNORED) {
-        ALOGI("Camera %s: Access for \"%s\" has been restricted",
-                mCameraIdStr.string(), String8(mClientPackageName).string());
-        // Return the same error as for device policy manager rejection
-        return -EACCES;
+        if (res == AppOpsManager::MODE_IGNORED) {
+            ALOGI("Camera %s: Access for \"%s\" has been restricted",
+                    mCameraIdStr.string(), String8(mClientPackageName).string());
+            // Return the same error as for device policy manager rejection
+            return -EACCES;
+        }
     }
 
     mOpsActive = true;
@@ -2483,10 +2491,11 @@
     // Check if startCameraOps succeeded, and if so, finish the camera op
     if (mOpsActive) {
         // Notify app ops that the camera is available again
-        mAppOpsManager.finishOp(AppOpsManager::OP_CAMERA, mClientUid,
-                mClientPackageName);
-        mOpsActive = false;
-
+        if (mAppOpsManager != nullptr) {
+            mAppOpsManager->finishOp(AppOpsManager::OP_CAMERA, mClientUid,
+                    mClientPackageName);
+            mOpsActive = false;
+        }
         // This function is called when a client disconnects. This should
         // release the camera, but actually only if it was in a proper
         // functional state, i.e. with status NOT_AVAILABLE
@@ -2506,8 +2515,8 @@
                 mCameraIdStr, mCameraFacing, mClientPackageName, apiLevel);
     }
     // Always stop watching, even if no camera op is active
-    if (mOpsCallback != NULL) {
-        mAppOpsManager.stopWatchingMode(mOpsCallback);
+    if (mOpsCallback != nullptr && mAppOpsManager != nullptr) {
+        mAppOpsManager->stopWatchingMode(mOpsCallback);
     }
     mOpsCallback.clear();
 
@@ -2516,19 +2525,18 @@
     return OK;
 }
 
-void CameraService::BasicClient::opChanged(int32_t op, const String16& packageName) {
+void CameraService::BasicClient::opChanged(int32_t op, const String16&) {
     ATRACE_CALL();
-
-    String8 name(packageName);
-    String8 myName(mClientPackageName);
-
+    if (mAppOpsManager == nullptr) {
+        return;
+    }
     if (op != AppOpsManager::OP_CAMERA) {
         ALOGW("Unexpected app ops notification received: %d", op);
         return;
     }
 
     int32_t res;
-    res = mAppOpsManager.checkOp(AppOpsManager::OP_CAMERA,
+    res = mAppOpsManager->checkOp(AppOpsManager::OP_CAMERA,
             mClientUid, mClientPackageName);
     ALOGV("checkOp returns: %d, %s ", res,
             res == AppOpsManager::MODE_ALLOWED ? "ALLOWED" :
@@ -2538,7 +2546,7 @@
 
     if (res != AppOpsManager::MODE_ALLOWED) {
         ALOGI("Camera %s: Access for \"%s\" revoked", mCameraIdStr.string(),
-                myName.string());
+              String8(mClientPackageName).string());
         block();
     }
 }
diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h
index b8cec2c..065157d 100644
--- a/services/camera/libcameraservice/CameraService.h
+++ b/services/camera/libcameraservice/CameraService.h
@@ -293,7 +293,7 @@
         status_t                        finishCameraOps();
 
     private:
-        AppOpsManager                   mAppOpsManager;
+        std::unique_ptr<AppOpsManager>  mAppOpsManager = nullptr;
 
         class OpsCallback : public BnAppOpsCallback {
         public:
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index 00f0d86..9771f9e 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -2876,7 +2876,8 @@
     config.streams = streams.editArray();
 
     // Do the HAL configuration; will potentially touch stream
-    // max_buffers, usage, priv fields.
+    // max_buffers, usage, and priv fields, as well as data_space and format
+    // fields for IMPLEMENTATION_DEFINED formats.
 
     const camera_metadata_t *sessionBuffer = sessionParams.getAndLock();
     res = mInterface->configureStreams(sessionBuffer, &config, bufferSizes);
@@ -4202,10 +4203,19 @@
         dst3_2.streamType = streamType;
         dst3_2.width = src->width;
         dst3_2.height = src->height;
-        dst3_2.format = mapToPixelFormat(src->format);
         dst3_2.usage = mapToConsumerUsage(cam3stream->getUsage());
-        dst3_2.dataSpace = mapToHidlDataspace(src->data_space);
         dst3_2.rotation = mapToStreamRotation((camera3_stream_rotation_t) src->rotation);
+        // For HidlSession version 3.5 or newer, the format and dataSpace sent
+        // to HAL are original, not the overriden ones.
+        if (mHidlSession_3_5 != nullptr) {
+            dst3_2.format = mapToPixelFormat(cam3stream->isFormatOverridden() ?
+                    cam3stream->getOriginalFormat() : src->format);
+            dst3_2.dataSpace = mapToHidlDataspace(cam3stream->isDataSpaceOverridden() ?
+                    cam3stream->getOriginalDataSpace() : src->data_space);
+        } else {
+            dst3_2.format = mapToPixelFormat(src->format);
+            dst3_2.dataSpace = mapToHidlDataspace(src->data_space);
+        }
         dst3_4.v3_2 = dst3_2;
         dst3_4.bufferSize = bufferSizes[i];
         if (src->physical_camera_id != nullptr) {
@@ -4266,7 +4276,7 @@
                 return OK;
             };
 
-    // See if we have v3.4 or v3.3 HAL
+    // See which version of HAL we have
     if (mHidlSession_3_5 != nullptr) {
         ALOGV("%s: v3.5 device found", __FUNCTION__);
         device::V3_5::StreamConfiguration requestedConfiguration3_5;
@@ -4281,7 +4291,6 @@
     } else if (mHidlSession_3_4 != nullptr) {
         // We do; use v3.4 for the call
         ALOGV("%s: v3.4 device found", __FUNCTION__);
-        device::V3_4::HalStreamConfiguration finalConfiguration3_4;
         auto err = mHidlSession_3_4->configureStreams_3_4(
                 requestedConfiguration3_4, configStream34Cb);
         res = postprocConfigStream34(err);
@@ -4352,12 +4361,12 @@
         device::V3_3::HalStream &src = finalConfiguration.streams[realIdx];
 
         Camera3Stream* dstStream = Camera3Stream::cast(dst);
-        dstStream->setFormatOverride(false);
-        dstStream->setDataSpaceOverride(false);
         int overrideFormat = mapToFrameworkFormat(src.v3_2.overrideFormat);
         android_dataspace overrideDataSpace = mapToFrameworkDataspace(src.overrideDataSpace);
 
         if (dst->format != HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) {
+            dstStream->setFormatOverride(false);
+            dstStream->setDataSpaceOverride(false);
             if (dst->format != overrideFormat) {
                 ALOGE("%s: Stream %d: Format override not allowed for format 0x%x", __FUNCTION__,
                         streamId, dst->format);
@@ -4367,10 +4376,13 @@
                         streamId, dst->format);
             }
         } else {
-            dstStream->setFormatOverride((dst->format != overrideFormat) ? true : false);
-            dstStream->setDataSpaceOverride((dst->data_space != overrideDataSpace) ? true : false);
-
+            bool needFormatOverride =
+                    requestedConfiguration3_2.streams[i].format != src.v3_2.overrideFormat;
+            bool needDataspaceOverride =
+                    requestedConfiguration3_2.streams[i].dataSpace != src.overrideDataSpace;
             // Override allowed with IMPLEMENTATION_DEFINED
+            dstStream->setFormatOverride(needFormatOverride);
+            dstStream->setDataSpaceOverride(needDataspaceOverride);
             dst->format = overrideFormat;
             dst->data_space = overrideDataSpace;
         }
diff --git a/services/camera/libcameraservice/device3/Camera3SharedOutputStream.cpp b/services/camera/libcameraservice/device3/Camera3SharedOutputStream.cpp
index e3b74d7..86b45cb 100644
--- a/services/camera/libcameraservice/device3/Camera3SharedOutputStream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3SharedOutputStream.cpp
@@ -55,7 +55,7 @@
 
     mStreamSplitter = new Camera3StreamSplitter(mUseHalBufManager);
 
-    uint64_t usage;
+    uint64_t usage = 0;
     getEndpointUsage(&usage);
 
     std::unordered_map<size_t, sp<Surface>> initialSurfaces;
diff --git a/services/camera/libcameraservice/device3/Camera3Stream.cpp b/services/camera/libcameraservice/device3/Camera3Stream.cpp
index d73a2f9..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),
@@ -67,6 +69,8 @@
     mBufferLimitLatency(kBufferLimitLatencyBinSize),
     mFormatOverridden(false),
     mOriginalFormat(-1),
+    mDataSpaceOverridden(false),
+    mOriginalDataSpace(HAL_DATASPACE_UNKNOWN),
     mPhysicalCameraId(physicalCameraId),
     mLastTimestamp(0) {
 
@@ -121,7 +125,9 @@
 
 void Camera3Stream::setFormatOverride(bool formatOverridden) {
     mFormatOverridden = formatOverridden;
-    if (formatOverridden) mOriginalFormat = camera3_stream::format;
+    if (formatOverridden && mOriginalFormat == -1) {
+        mOriginalFormat = camera3_stream::format;
+    }
 }
 
 bool Camera3Stream::isFormatOverridden() const {
@@ -134,7 +140,9 @@
 
 void Camera3Stream::setDataSpaceOverride(bool dataSpaceOverridden) {
     mDataSpaceOverridden = dataSpaceOverridden;
-    if (dataSpaceOverridden) mOriginalDataSpace = camera3_stream::data_space;
+    if (dataSpaceOverridden && mOriginalDataSpace == HAL_DATASPACE_UNKNOWN) {
+        mOriginalDataSpace = camera3_stream::data_space;
+    }
 }
 
 bool Camera3Stream::isDataSpaceOverridden() const {
@@ -250,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) {
@@ -324,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