Merge "CCodec: request initial input buffers after start complete callback" into tm-dev
diff --git a/camera/ndk/ndk_vendor/impl/ACameraDevice.cpp b/camera/ndk/ndk_vendor/impl/ACameraDevice.cpp
index 85ab0c2..0a57590 100644
--- a/camera/ndk/ndk_vendor/impl/ACameraDevice.cpp
+++ b/camera/ndk/ndk_vendor/impl/ACameraDevice.cpp
@@ -491,6 +491,7 @@
     }
 
     if (mRemote != nullptr) {
+        ALOGD("%s: binder disconnect reached", __FUNCTION__);
         auto ret = mRemote->disconnect();
         if (!ret.isOk()) {
             ALOGE("%s: Transaction error while disconnecting device %s", __FUNCTION__,
diff --git a/media/codec2/sfplugin/CCodecConfig.cpp b/media/codec2/sfplugin/CCodecConfig.cpp
index 836d2a7..f3fb5ff 100644
--- a/media/codec2/sfplugin/CCodecConfig.cpp
+++ b/media/codec2/sfplugin/CCodecConfig.cpp
@@ -1072,6 +1072,13 @@
                     C2_PARAMKEY_SURFACE_SCALING_MODE);
         } else {
             addLocalParam(new C2StreamColorAspectsInfo::input(0u), C2_PARAMKEY_COLOR_ASPECTS);
+
+            if (domain.value == C2Component::DOMAIN_VIDEO) {
+                addLocalParam(new C2AndroidStreamAverageBlockQuantizationInfo::output(0u, 0),
+                              C2_PARAMKEY_AVERAGE_QP);
+                addLocalParam(new C2StreamPictureTypeMaskInfo::output(0u, 0),
+                              C2_PARAMKEY_PICTURE_TYPE);
+            }
         }
     }
 
diff --git a/media/libaudioclient/ToneGenerator.cpp b/media/libaudioclient/ToneGenerator.cpp
index 9b43f3c..dd3f86e 100644
--- a/media/libaudioclient/ToneGenerator.cpp
+++ b/media/libaudioclient/ToneGenerator.cpp
@@ -17,6 +17,7 @@
 //#define LOG_NDEBUG 0
 #define LOG_TAG "ToneGenerator"
 
+#include <inttypes.h>
 #include <utility>
 
 #include <math.h>
@@ -1229,7 +1230,8 @@
                     sec = sec * 1000 + nsec / 1000000; // duration in milliseconds
                     mMaxSmp = (unsigned int)(((int64_t)sec * mSamplingRate) / 1000);
                 }
-                ALOGV("stopTone() forcing mMaxSmp to %d, total for far %d", mMaxSmp,  mTotalSmp);
+                ALOGV("stopTone() forcing mMaxSmp to %d, total for far %" PRIu64, mMaxSmp,
+                      mTotalSmp);
             } else {
                 mState = TONE_STOPPING;
             }
@@ -1399,7 +1401,7 @@
             mNextSegSmp = TONEGEN_INF; // forced to skip state machine management below
         }
 
-        if (mTotalSmp > mNextSegSmp) {
+        if (mTotalSmp > mNextSegSmp && mNextSegSmp != TONEGEN_INF) {
             // Time to go to next sequence segment
 
             ALOGV("End Segment, time: %d", (unsigned int)(systemTime()/1000000));
diff --git a/media/libaudioclient/aidl/android/media/ISpatializer.aidl b/media/libaudioclient/aidl/android/media/ISpatializer.aidl
index b871238..a61ad58 100644
--- a/media/libaudioclient/aidl/android/media/ISpatializer.aidl
+++ b/media/libaudioclient/aidl/android/media/ISpatializer.aidl
@@ -57,8 +57,10 @@
     boolean isHeadTrackingSupported();
 
     /** Reports the list of supported head tracking modes (see SpatializerHeadTrackingMode.aidl).
-     * The list can be empty if the spatializer implementation does not support head tracking or if
-     * no head tracking sensor is registered (see setHeadSensor() and setScreenSensor()).
+     * The list always contains SpatializerHeadTrackingMode.DISABLED and can include other modes
+     * if the spatializer effect implementation supports head tracking.
+     * The result does not depend on currently connected sensors but reflects the capabilities
+     * when sensors are available.
      */
     SpatializerHeadTrackingMode[] getSupportedHeadTrackingModes();
 
diff --git a/media/libaudioclient/include/media/ToneGenerator.h b/media/libaudioclient/include/media/ToneGenerator.h
index 43c0100..d00dfd2 100644
--- a/media/libaudioclient/include/media/ToneGenerator.h
+++ b/media/libaudioclient/include/media/ToneGenerator.h
@@ -287,11 +287,10 @@
     static const ToneDescriptor sToneDescriptors[];
 
     bool mThreadCanCallJava;
-    unsigned int mTotalSmp;  // Total number of audio samples played (gives current time)
+    uint64_t mTotalSmp;  // Total number of audio samples played (gives current time)
+    // Since these types are 32 bit, we may have issues with aborting on
+    // overflow now that we have integer overflow sanitization enabled globally.
     unsigned int mNextSegSmp;  // Position of next segment transition expressed in samples
-    // NOTE: because mTotalSmp, mNextSegSmp are stored on 32 bit, current design will operate properly
-    // only if tone duration is less than about 27 Hours(@44100Hz sampling rate). If this time is exceeded,
-    // no crash will occur but tone sequence will show a glitch.
     unsigned int mMaxSmp;  // Maximum number of audio samples played (maximun tone duration)
     int mDurationMs;  // Maximum tone duration in ms
 
diff --git a/media/libheadtracking/SensorPoseProvider.cpp b/media/libheadtracking/SensorPoseProvider.cpp
index f3f9b77..4884ae4 100644
--- a/media/libheadtracking/SensorPoseProvider.cpp
+++ b/media/libheadtracking/SensorPoseProvider.cpp
@@ -158,7 +158,6 @@
     enum DataFormat {
         kUnknown,
         kQuaternion,
-        kRotationVectorsAndFlags,
         kRotationVectorsAndDiscontinuityCount,
     };
 
@@ -283,10 +282,6 @@
             return DataFormat::kRotationVectorsAndDiscontinuityCount;
         }
 
-        if (sensor->getStringType() == "com.google.hardware.sensor.hid_dynamic.headtracker") {
-            return DataFormat::kRotationVectorsAndFlags;
-        }
-
         return DataFormat::kUnknown;
     }
 
@@ -332,21 +327,6 @@
                 return PoseEvent{Pose3f(quat), std::optional<Twist3f>(), false};
             }
 
-            case DataFormat::kRotationVectorsAndFlags: {
-                // Custom sensor, assumed to contain:
-                // 3 floats representing orientation as a rotation vector (in rad).
-                // 3 floats representing angular velocity as a rotation vector (in rad/s).
-                // 1 uint32_t of flags, where:
-                // - LSb is '1' iff the given sample is the first one in a new frame of reference.
-                // - The rest of the bits are reserved for future use.
-                Eigen::Vector3f rotation = {event.data[0], event.data[1], event.data[2]};
-                Eigen::Vector3f twist = {event.data[3], event.data[4], event.data[5]};
-                Eigen::Quaternionf quat = rotationVectorToQuaternion(rotation);
-                uint32_t flags = *reinterpret_cast<const uint32_t*>(&event.data[6]);
-                return PoseEvent{Pose3f(quat), Twist3f(Eigen::Vector3f::Zero(), twist),
-                                 (flags & (1 << 0)) != 0};
-            }
-
             case DataFormat::kRotationVectorsAndDiscontinuityCount: {
                 Eigen::Vector3f rotation = {event.head_tracker.rx, event.head_tracker.ry,
                                             event.head_tracker.rz};
diff --git a/media/libstagefright/foundation/MetaDataBase.cpp b/media/libstagefright/foundation/MetaDataBase.cpp
index 980eb22..3370748 100644
--- a/media/libstagefright/foundation/MetaDataBase.cpp
+++ b/media/libstagefright/foundation/MetaDataBase.cpp
@@ -521,9 +521,64 @@
                 }
                 setData(key, type, blob.data(), size);
                 blob.release();
+            } else if (type == TYPE_C_STRING) {
+                // copy data directly from Parcel storage, then advance position
+                // NB: readInplace() bumps position, it is NOT idempotent.
+                const void *src = parcel.readInplace(size);
+                char *str = (char *) src;
+                if (src == nullptr || size == 0 || str[size-1] != '\0') {
+                    char ccKey[5];
+                    MakeFourCCString(key, ccKey);
+                    if (src == nullptr) {
+                        ALOGW("ignoring key '%s' string with no data (expected %d)", ccKey, size);
+                    } else {
+                        ALOGW("ignoring key '%s': unterminated string of %d bytes", ccKey, size);
+                    }
+                } else {
+                    setData(key, type, src, size);
+                }
             } else {
                 // copy data directly from Parcel storage, then advance position
-                setData(key, type, parcel.readInplace(size), size);
+                // verify that the received size is enough
+                uint32_t needed = 0;
+                switch (type) {
+                    case TYPE_INT32:
+                        needed = sizeof(int32_t);
+                        break;
+                    case TYPE_INT64:
+                        needed = sizeof(int64_t);
+                        break;
+                    case TYPE_FLOAT:
+                        needed = sizeof(float);
+                        break;
+                    case TYPE_POINTER:
+                        // NB: this rejects passing between 32-bit and 64-bit space.
+                        needed = sizeof(void*);
+                        break;
+                    case TYPE_RECT:
+                        needed = sizeof(Rect);
+                        break;
+                    default:
+                        // non-standard entities can be any size >= 0
+                        needed = 0;
+                        break;
+                }
+                const void *src = parcel.readInplace(size);
+                if (src == nullptr || (needed != 0 && size != needed)) {
+                    char ccKey[5];
+                    MakeFourCCString(key, ccKey);
+                    char ccType[5];
+                    MakeFourCCString(type, ccType);
+                    if (src == nullptr) {
+                        ALOGW("ignoring key '%s' type '%s' missing data (expected %d)",
+                              ccKey, ccType, size);
+                    } else {
+                        ALOGW("ignoring key '%s': type '%s' bytes: expected %d != %d received",
+                               ccKey, ccType, needed, size);
+                    }
+                } else {
+                    setData(key, type, src, size);
+                }
             }
          }
 
diff --git a/services/audiopolicy/config/bluetooth_with_le_audio_policy_configuration.xml b/services/audiopolicy/config/bluetooth_with_le_audio_policy_configuration.xml
index 22ff954..d34cca0 100644
--- a/services/audiopolicy/config/bluetooth_with_le_audio_policy_configuration.xml
+++ b/services/audiopolicy/config/bluetooth_with_le_audio_policy_configuration.xml
@@ -11,17 +11,7 @@
                      channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
         </mixPort>
         <!-- Le Audio Audio Ports -->
-        <mixPort name="le audio output" role="source">
-            <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
-                     samplingRates="8000,16000,24000,32000,44100,48000"
-                     channelMasks="AUDIO_CHANNEL_OUT_MONO,AUDIO_CHANNEL_OUT_STEREO"/>
-            <profile name="" format="AUDIO_FORMAT_PCM_24_BIT_PACKED"
-                     samplingRates="8000,16000,24000,32000,44100,48000"
-                     channelMasks="AUDIO_CHANNEL_OUT_MONO,AUDIO_CHANNEL_OUT_STEREO"/>
-            <profile name="" format="AUDIO_FORMAT_PCM_32_BIT"
-                     samplingRates="8000,16000,24000,32000,44100,48000"
-                     channelMasks="AUDIO_CHANNEL_OUT_MONO,AUDIO_CHANNEL_OUT_STEREO"/>
-        </mixPort>
+        <mixPort name="le audio output" role="source"/>
         <mixPort name="le audio input" role="sink">
             <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
                      samplingRates="8000,16000,24000,32000,44100,48000"
diff --git a/services/audiopolicy/config/bluetooth_with_le_audio_policy_configuration_7_0.xml b/services/audiopolicy/config/bluetooth_with_le_audio_policy_configuration_7_0.xml
index aad00d6..e7908eb 100644
--- a/services/audiopolicy/config/bluetooth_with_le_audio_policy_configuration_7_0.xml
+++ b/services/audiopolicy/config/bluetooth_with_le_audio_policy_configuration_7_0.xml
@@ -11,17 +11,7 @@
                      channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
         </mixPort>
         <!-- Le Audio Audio Ports -->
-        <mixPort name="le audio output" role="source">
-            <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
-                     samplingRates="8000 16000 24000 32000 44100 48000"
-                     channelMasks="AUDIO_CHANNEL_OUT_MONO AUDIO_CHANNEL_OUT_STEREO"/>
-            <profile name="" format="AUDIO_FORMAT_PCM_24_BIT_PACKED"
-                     samplingRates="8000 16000 24000 32000 44100 48000"
-                     channelMasks="AUDIO_CHANNEL_OUT_MONO AUDIO_CHANNEL_OUT_STEREO"/>
-            <profile name="" format="AUDIO_FORMAT_PCM_32_BIT"
-                     samplingRates="8000 16000 24000 32000 44100 48000"
-                     channelMasks="AUDIO_CHANNEL_OUT_MONO AUDIO_CHANNEL_OUT_STEREO"/>
-        </mixPort>
+        <mixPort name="le audio output" role="source" />
         <mixPort name="le audio input" role="sink">
             <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
                      samplingRates="8000 16000 24000 32000 44100 48000"
diff --git a/services/audiopolicy/service/Spatializer.cpp b/services/audiopolicy/service/Spatializer.cpp
index 389233e..ef11072 100644
--- a/services/audiopolicy/service/Spatializer.cpp
+++ b/services/audiopolicy/service/Spatializer.cpp
@@ -342,12 +342,7 @@
 
     modes->push_back(SpatializerHeadTrackingMode::DISABLED);
     if (mSupportsHeadTracking) {
-        if (mHeadSensor != SpatializerPoseController::INVALID_SENSOR) {
-            modes->push_back(SpatializerHeadTrackingMode::RELATIVE_WORLD);
-            if (mScreenSensor != SpatializerPoseController::INVALID_SENSOR) {
-                modes->push_back(SpatializerHeadTrackingMode::RELATIVE_SCREEN);
-            }
-        }
+        modes->push_back(SpatializerHeadTrackingMode::RELATIVE_WORLD);
     }
     return Status::ok();
 }
diff --git a/services/camera/libcameraservice/common/Camera2ClientBase.cpp b/services/camera/libcameraservice/common/Camera2ClientBase.cpp
index 0ac047a..a7097fb 100644
--- a/services/camera/libcameraservice/common/Camera2ClientBase.cpp
+++ b/services/camera/libcameraservice/common/Camera2ClientBase.cpp
@@ -243,20 +243,23 @@
 template <typename TClientBase>
 binder::Status Camera2ClientBase<TClientBase>::disconnect() {
     ATRACE_CALL();
+    ALOGD("Camera %s: start to disconnect", TClientBase::mCameraIdStr.string());
     Mutex::Autolock icl(mBinderSerializationLock);
 
+    ALOGD("Camera %s: serializationLock acquired", TClientBase::mCameraIdStr.string());
     binder::Status res = binder::Status::ok();
     // Allow both client and the media server to disconnect at all times
     int callingPid = CameraThreadState::getCallingPid();
     if (callingPid != TClientBase::mClientPid &&
         callingPid != TClientBase::mServicePid) return res;
 
-    ALOGV("Camera %s: Shutting down", TClientBase::mCameraIdStr.string());
+    ALOGD("Camera %s: Shutting down", TClientBase::mCameraIdStr.string());
 
     // Before detaching the device, cache the info from current open session.
     // The disconnected check avoids duplication of info and also prevents
     // deadlock while acquiring service lock in cacheDump.
     if (!TClientBase::mDisconnected) {
+        ALOGD("Camera %s: start to cacheDump", TClientBase::mCameraIdStr.string());
         Camera2ClientBase::getCameraService()->cacheDump();
     }