Snap for 10750748 from 41d5a03355a8d00064790ce83b793e69e8e0832d to mainline-cellbroadcast-release

Change-Id: Ia01ac7ac5914462d662e6f32ee9172f39189ae70
diff --git a/camera/ndk/include/camera/NdkCameraMetadataTags.h b/camera/ndk/include/camera/NdkCameraMetadataTags.h
index af00e55..4a589bc 100644
--- a/camera/ndk/include/camera/NdkCameraMetadataTags.h
+++ b/camera/ndk/include/camera/NdkCameraMetadataTags.h
@@ -584,6 +584,13 @@
      * <p>Only constrains auto-exposure (AE) algorithm, not
      * manual control of ACAMERA_SENSOR_EXPOSURE_TIME and
      * ACAMERA_SENSOR_FRAME_DURATION.</p>
+     * <p>To start a CaptureSession with a target FPS range different from the
+     * capture request template's default value, the application
+     * is strongly recommended to call
+     * {@link ACameraDevice_createCaptureSessionWithSessionParameters }
+     * with the target fps range before creating the capture session. The aeTargetFpsRange is
+     * typically a session parameter. Specifying it at session creation time helps avoid
+     * session reconfiguration delays in cases like 60fps or high speed recording.</p>
      *
      * @see ACAMERA_SENSOR_EXPOSURE_TIME
      * @see ACAMERA_SENSOR_FRAME_DURATION
@@ -1128,6 +1135,12 @@
      * ACAMERA_CONTROL_VIDEO_STABILIZATION_MODE field will return
      * OFF if the recording output is not stabilized, or if there are no output
      * Surface types that can be stabilized.</p>
+     * <p>The application is strongly recommended to call
+     * {@link ACameraDevice_createCaptureSessionWithSessionParameters }
+     * with the desired video stabilization mode before creating the capture session.
+     * Video stabilization mode is a session parameter on many devices. Specifying
+     * it at session creation time helps avoid reconfiguration delay caused by difference
+     * between the default value and the first CaptureRequest.</p>
      * <p>If a camera device supports both this mode and OIS
      * (ACAMERA_LENS_OPTICAL_STABILIZATION_MODE), turning both modes on may
      * produce undesirable interaction, so it is recommended not to enable
diff --git a/media/codec2/components/aac/C2SoftAacEnc.cpp b/media/codec2/components/aac/C2SoftAacEnc.cpp
index d865ab2..721a12a 100644
--- a/media/codec2/components/aac/C2SoftAacEnc.cpp
+++ b/media/codec2/components/aac/C2SoftAacEnc.cpp
@@ -69,7 +69,7 @@
         addParameter(
                 DefineParam(mChannelCount, C2_PARAMKEY_CHANNEL_COUNT)
                 .withDefault(new C2StreamChannelCountInfo::input(0u, 1))
-                .withFields({C2F(mChannelCount, value).inRange(1, 6)})
+                .withFields({C2F(mChannelCount, value).inRange(1, kMaxChannelCount)})
                 .withSetter(Setter<decltype(*mChannelCount)>::StrictValueWithNoDeps)
                 .build());
 
@@ -198,10 +198,17 @@
 }
 
 c2_status_t C2SoftAacEnc::onFlush_sm() {
+    if (mAACEncoder != nullptr) {
+        /* encoder's internal input buffer needs to be reset during flush */
+        if (AACENC_OK != aacEncoder_SetParam(mAACEncoder, AACENC_CONTROL_STATE, AACENC_INIT_ALL)) {
+            ALOGE("Failed to reset AAC encoder");
+        }
+    }
     mSentCodecSpecificData = false;
     mInputSize = 0u;
     mNextFrameTimestampUs.reset();
     mLastFrameEndTimestampUs.reset();
+    mRemainderLen = 0;
     return C2_OK;
 }
 
@@ -562,6 +569,11 @@
                 inBufferSize[0] -= outargs.numInSamples * sizeof(int16_t);
                 inargs.numInSamples -= outargs.numInSamples;
             }
+        } else {
+            // In case of error in encode call, discard remaining input bytes.
+            inBuffer[0] = nullptr;
+            inBufferSize[0] = 0;
+            inargs.numInSamples = 0;
         }
         ALOGV("encoderErr = %d mInputSize = %zu "
               "inargs.numInSamples = %d, mNextFrameTimestampUs = %lld",
@@ -597,10 +609,19 @@
                            &outBufDesc,
                            &inargs,
                            &outargs);
+
+        // after flush, discard remaining input bytes.
+        inBuffer[0] = nullptr;
         inBufferSize[0] = 0;
     }
 
     if (inBufferSize[0] > 0) {
+        if (inBufferSize[0] > kRemainderBufSize) {
+            ALOGE("Remaining bytes %d greater than remainder buffer size %zu", inBufferSize[0],
+                    kRemainderBufSize);
+            work->result = C2_CORRUPTED;
+            return;
+        }
         for (size_t i = 0; i < inBufferSize[0]; ++i) {
             mRemainder[i] = static_cast<uint8_t *>(inBuffer[0])[i];
         }
diff --git a/media/codec2/components/aac/C2SoftAacEnc.h b/media/codec2/components/aac/C2SoftAacEnc.h
index 9a28280..c79526c 100644
--- a/media/codec2/components/aac/C2SoftAacEnc.h
+++ b/media/codec2/components/aac/C2SoftAacEnc.h
@@ -47,6 +47,9 @@
             const std::shared_ptr<C2BlockPool> &pool) override;
 
 private:
+    static constexpr size_t kMaxChannelCount = 6;
+    static constexpr size_t kRemainderBufSize = kMaxChannelCount * sizeof(int16_t);
+
     std::shared_ptr<IntfImpl> mIntf;
 
     HANDLE_AACENCODER mAACEncoder;
@@ -63,7 +66,7 @@
     std::atomic_uint64_t mOutIndex;
 
     // We support max 6 channels
-    uint8_t mRemainder[6 * sizeof(int16_t)];
+    uint8_t mRemainder[kRemainderBufSize];
     size_t mRemainderLen;
 
     status_t initEncoder();
diff --git a/media/codec2/components/gav1/C2SoftGav1Dec.cpp b/media/codec2/components/gav1/C2SoftGav1Dec.cpp
index 3e4247b..d9c5d29 100644
--- a/media/codec2/components/gav1/C2SoftGav1Dec.cpp
+++ b/media/codec2/components/gav1/C2SoftGav1Dec.cpp
@@ -773,6 +773,14 @@
     return false;
   }
 
+  if (buffer->bitdepth > 10) {
+    ALOGE("bitdepth %d is not supported", buffer->bitdepth);
+    mSignalledError = true;
+    work->workletsProcessed = 1u;
+    work->result = C2_CORRUPTED;
+    return false;
+  }
+
   const int width = buffer->displayed_width[0];
   const int height = buffer->displayed_height[0];
   if (width != mWidth || height != mHeight) {
diff --git a/media/codec2/sfplugin/CCodecBufferChannel.cpp b/media/codec2/sfplugin/CCodecBufferChannel.cpp
index d72d228..feca03d 100644
--- a/media/codec2/sfplugin/CCodecBufferChannel.cpp
+++ b/media/codec2/sfplugin/CCodecBufferChannel.cpp
@@ -67,6 +67,7 @@
 using hardware::hidl_vec;
 using hardware::fromHeap;
 using hardware::HidlMemory;
+using server_configurable_flags::GetServerConfigurableFlag;
 
 using namespace hardware::cas::V1_0;
 using namespace hardware::cas::native::V1_0;
@@ -82,6 +83,11 @@
 // than making it non-blocking. Do not change this value.
 const static size_t kDequeueTimeoutNs = 0;
 
+static bool areRenderMetricsEnabled() {
+    std::string v = GetServerConfigurableFlag("media_native", "render_metrics_enabled", "false");
+    return v == "true";
+}
+
 }  // namespace
 
 CCodecBufferChannel::QueueGuard::QueueGuard(
@@ -148,6 +154,7 @@
       mCCodecCallback(callback),
       mFrameIndex(0u),
       mFirstValidFrameIndex(0u),
+      mAreRenderMetricsEnabled(areRenderMetricsEnabled()),
       mIsSurfaceToDisplay(false),
       mHasPresentFenceTimes(false),
       mRenderingDepth(3u),
@@ -174,8 +181,7 @@
         Mutexed<BlockPools>::Locked pools(mBlockPools);
         pools->outputPoolId = C2BlockPool::BASIC_LINEAR;
     }
-    std::string value = server_configurable_flags::GetServerConfigurableFlag(
-            "media_native", "ccodec_rendering_depth", "3");
+    std::string value = GetServerConfigurableFlag("media_native", "ccodec_rendering_depth", "3");
     android::base::ParseInt(value, &mRenderingDepth);
     mOutputSurface.lock()->maxDequeueBuffers = kSmoothnessFactor + mRenderingDepth;
 }
@@ -996,7 +1002,7 @@
 
     int64_t mediaTimeUs = 0;
     (void)buffer->meta()->findInt64("timeUs", &mediaTimeUs);
-    if (mIsSurfaceToDisplay) {
+    if (mAreRenderMetricsEnabled && mIsSurfaceToDisplay) {
         trackReleasedFrame(qbo, mediaTimeUs, timestampNs);
         processRenderedFrames(qbo.frameTimestamps);
     } else {
diff --git a/media/codec2/sfplugin/CCodecBufferChannel.h b/media/codec2/sfplugin/CCodecBufferChannel.h
index 2d87aa9..41f5ae2 100644
--- a/media/codec2/sfplugin/CCodecBufferChannel.h
+++ b/media/codec2/sfplugin/CCodecBufferChannel.h
@@ -334,6 +334,7 @@
     sp<MemoryDealer> makeMemoryDealer(size_t heapSize);
 
     std::deque<TrackedFrame> mTrackedFrames;
+    bool mAreRenderMetricsEnabled;
     bool mIsSurfaceToDisplay;
     bool mHasPresentFenceTimes;
 
diff --git a/media/codec2/sfplugin/utils/Codec2CommonUtils.cpp b/media/codec2/sfplugin/utils/Codec2CommonUtils.cpp
index f428fce..43533fd 100644
--- a/media/codec2/sfplugin/utils/Codec2CommonUtils.cpp
+++ b/media/codec2/sfplugin/utils/Codec2CommonUtils.cpp
@@ -31,11 +31,19 @@
 
 namespace android {
 
-bool isAtLeastT() {
+
+static bool isAtLeast(int version, const char *codeName) {
     char deviceCodeName[PROP_VALUE_MAX];
     __system_property_get("ro.build.version.codename", deviceCodeName);
-    return android_get_device_api_level() >= __ANDROID_API_T__ ||
-           !strcmp(deviceCodeName, "Tiramisu");
+    return android_get_device_api_level() >= version || !strcmp(deviceCodeName, codeName);
+}
+
+bool isAtLeastT() {
+    return isAtLeast(__ANDROID_API_T__, "Tiramisu");
+}
+
+bool isAtLeastU() {
+    return isAtLeast(__ANDROID_API_U__, "UpsideDownCake");
 }
 
 static bool isP010Allowed() {
@@ -127,10 +135,16 @@
             .rfu0 = 0,
             .rfu1 = 0,
     };
-
-    return AHardwareBuffer_isSupported(&consumableForDisplayOrGpu)
-            && AHardwareBuffer_isSupported(&consumableForHwEncoder)
-            && AHardwareBuffer_isSupported(&consumableForSwEncoder);
+    // Some devices running versions prior to Android U aren't guaranteed to advertise support
+    // for some color formats when the consumer is an encoder. Hence limit these checks to
+    // Android U and beyond.
+    if (isAtLeastU()) {
+        return AHardwareBuffer_isSupported(&consumableForDisplayOrGpu)
+                && AHardwareBuffer_isSupported(&consumableForHwEncoder)
+                && AHardwareBuffer_isSupported(&consumableForSwEncoder);
+    } else {
+        return AHardwareBuffer_isSupported(&consumableForDisplayOrGpu);
+    }
 }
 
 }  // namespace android
diff --git a/media/codec2/sfplugin/utils/Codec2CommonUtils.h b/media/codec2/sfplugin/utils/Codec2CommonUtils.h
index 98dd65b..9bb52bd 100644
--- a/media/codec2/sfplugin/utils/Codec2CommonUtils.h
+++ b/media/codec2/sfplugin/utils/Codec2CommonUtils.h
@@ -23,6 +23,8 @@
 
 bool isAtLeastT();
 
+bool isAtLeastU();
+
 bool isVendorApiOrFirstApiAtLeastT();
 
 /**
diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp
index e0ebc11..2970aab 100644
--- a/media/libstagefright/MediaCodec.cpp
+++ b/media/libstagefright/MediaCodec.cpp
@@ -92,6 +92,7 @@
 using aidl::android::media::IResourceManagerClient;
 using aidl::android::media::IResourceManagerService;
 using aidl::android::media::ClientInfoParcel;
+using server_configurable_flags::GetServerConfigurableFlag;
 using FreezeEvent = VideoRenderQualityTracker::FreezeEvent;
 using JudderEvent = VideoRenderQualityTracker::JudderEvent;
 
@@ -282,6 +283,11 @@
     return (err == NO_MEMORY);
 }
 
+static bool areRenderMetricsEnabled() {
+    std::string v = GetServerConfigurableFlag("media_native", "render_metrics_enabled", "false");
+    return v == "true";
+}
+
 static const int kMaxRetry = 2;
 static const int kMaxReclaimWaitTimeInUs = 500000;  // 0.5s
 static const int kNumBuffersAlign = 16;
@@ -1025,9 +1031,10 @@
       mHavePendingInputBuffers(false),
       mCpuBoostRequested(false),
       mIsSurfaceToDisplay(false),
+      mAreRenderMetricsEnabled(areRenderMetricsEnabled()),
       mVideoRenderQualityTracker(
               VideoRenderQualityTracker::Configuration::getFromServerConfigurableFlags(
-                      server_configurable_flags::GetServerConfigurableFlag)),
+                      GetServerConfigurableFlag)),
       mLatencyUnknown(0),
       mBytesEncoded(0),
       mEarliestEncodedPtsUs(INT64_MAX),
@@ -6044,7 +6051,7 @@
 
         // If rendering to the screen, then schedule a time in the future to poll to see if this
         // frame was ever rendered to seed onFrameRendered callbacks.
-        if (mIsSurfaceToDisplay) {
+        if (mAreRenderMetricsEnabled && mIsSurfaceToDisplay) {
             if (mediaTimeUs != INT64_MIN) {
                 noRenderTime ? mVideoRenderQualityTracker.onFrameReleased(mediaTimeUs)
                              : mVideoRenderQualityTracker.onFrameReleased(mediaTimeUs,
diff --git a/media/libstagefright/VideoRenderQualityTracker.cpp b/media/libstagefright/VideoRenderQualityTracker.cpp
index 4f12a37..fbd8577 100644
--- a/media/libstagefright/VideoRenderQualityTracker.cpp
+++ b/media/libstagefright/VideoRenderQualityTracker.cpp
@@ -154,7 +154,7 @@
 }
 
 VideoRenderQualityTracker::Configuration::Configuration() {
-    enabled = true;
+    enabled = false;
 
     // Assume that the app is skipping frames because it's detected that the frame couldn't be
     // rendered in time.
diff --git a/media/libstagefright/include/media/stagefright/MediaCodec.h b/media/libstagefright/include/media/stagefright/MediaCodec.h
index 52d7d3d..163408d 100644
--- a/media/libstagefright/include/media/stagefright/MediaCodec.h
+++ b/media/libstagefright/include/media/stagefright/MediaCodec.h
@@ -572,6 +572,7 @@
     sp<ALooper> mCryptoLooper;
 
     bool mIsSurfaceToDisplay;
+    bool mAreRenderMetricsEnabled;
     PlaybackDurationAccumulator mPlaybackDurationAccumulator;
     VideoRenderQualityTracker mVideoRenderQualityTracker;
 
diff --git a/media/mtp/MtpFfsHandle.cpp b/media/mtp/MtpFfsHandle.cpp
index 2ffd775..ef8c9aa 100644
--- a/media/mtp/MtpFfsHandle.cpp
+++ b/media/mtp/MtpFfsHandle.cpp
@@ -297,6 +297,10 @@
 }
 
 void MtpFfsHandle::close() {
+    auto timeout = std::chrono::seconds(2);
+    std::unique_lock lk(m);
+    cv.wait_for(lk, timeout ,[this]{return child_threads==0;});
+
     io_destroy(mCtx);
     closeEndpoints();
     closeConfig();
@@ -669,6 +673,11 @@
     char *temp = new char[me.length];
     memcpy(temp, me.data, me.length);
     me.data = temp;
+
+    std::unique_lock lk(m);
+    child_threads++;
+    lk.unlock();
+
     std::thread t([this, me]() { return this->doSendEvent(me); });
     t.detach();
     return 0;
@@ -680,6 +689,11 @@
     if (static_cast<unsigned>(ret) != length)
         PLOG(ERROR) << "Mtp error sending event thread!";
     delete[] reinterpret_cast<char*>(me.data);
+
+    std::unique_lock lk(m);
+    child_threads--;
+    lk.unlock();
+    cv.notify_one();
 }
 
 } // namespace android
diff --git a/media/mtp/MtpFfsHandle.h b/media/mtp/MtpFfsHandle.h
index e552e03..51cdef0 100644
--- a/media/mtp/MtpFfsHandle.h
+++ b/media/mtp/MtpFfsHandle.h
@@ -60,6 +60,10 @@
     bool mCanceled;
     bool mBatchCancel;
 
+    std::mutex m;
+    std::condition_variable cv;
+    std::atomic<int> child_threads{0};
+
     android::base::unique_fd mControl;
     // "in" from the host's perspective => sink for mtp server
     android::base::unique_fd mBulkIn;
diff --git a/media/mtp/MtpPacket.cpp b/media/mtp/MtpPacket.cpp
index f069a83..5faaac2 100644
--- a/media/mtp/MtpPacket.cpp
+++ b/media/mtp/MtpPacket.cpp
@@ -92,24 +92,46 @@
 }
 
 uint16_t MtpPacket::getUInt16(int offset) const {
-    return ((uint16_t)mBuffer[offset + 1] << 8) | (uint16_t)mBuffer[offset];
+    if ((unsigned long)(offset+2) <= mBufferSize) {
+        return ((uint16_t)mBuffer[offset + 1] << 8) | (uint16_t)mBuffer[offset];
+    }
+    else {
+        ALOGE("offset for buffer read is greater than buffer size!");
+        abort();
+    }
 }
 
 uint32_t MtpPacket::getUInt32(int offset) const {
-    return ((uint32_t)mBuffer[offset + 3] << 24) | ((uint32_t)mBuffer[offset + 2] << 16) |
-           ((uint32_t)mBuffer[offset + 1] << 8)  | (uint32_t)mBuffer[offset];
+    if ((unsigned long)(offset+4) <= mBufferSize) {
+        return ((uint32_t)mBuffer[offset + 3] << 24) | ((uint32_t)mBuffer[offset + 2] << 16) |
+               ((uint32_t)mBuffer[offset + 1] << 8)  | (uint32_t)mBuffer[offset];
+    }
+    else {
+        ALOGE("offset for buffer read is greater than buffer size!");
+        abort();
+    }
 }
 
 void MtpPacket::putUInt16(int offset, uint16_t value) {
-    mBuffer[offset++] = (uint8_t)(value & 0xFF);
-    mBuffer[offset++] = (uint8_t)((value >> 8) & 0xFF);
+    if ((unsigned long)(offset+2) <= mBufferSize) {
+        mBuffer[offset++] = (uint8_t)(value & 0xFF);
+        mBuffer[offset++] = (uint8_t)((value >> 8) & 0xFF);
+    }
+    else {
+        ALOGE("offset for buffer write is greater than buffer size!");
+    }
 }
 
 void MtpPacket::putUInt32(int offset, uint32_t value) {
-    mBuffer[offset++] = (uint8_t)(value & 0xFF);
-    mBuffer[offset++] = (uint8_t)((value >> 8) & 0xFF);
-    mBuffer[offset++] = (uint8_t)((value >> 16) & 0xFF);
-    mBuffer[offset++] = (uint8_t)((value >> 24) & 0xFF);
+    if ((unsigned long)(offset+4) <= mBufferSize) {
+        mBuffer[offset++] = (uint8_t)(value & 0xFF);
+        mBuffer[offset++] = (uint8_t)((value >> 8) & 0xFF);
+        mBuffer[offset++] = (uint8_t)((value >> 16) & 0xFF);
+        mBuffer[offset++] = (uint8_t)((value >> 24) & 0xFF);
+    }
+    else {
+        ALOGE("offset for buffer write is greater than buffer size!");
+    }
 }
 
 uint16_t MtpPacket::getContainerCode() const {