Make change and version bump to r_aml_300802200 for mainline module file: apex/manifest_codec.json

Change-Id: I138b4182596cd8111f31fc7256cb835956f82e02
diff --git a/apex/manifest.json b/apex/manifest.json
index 760095e..f13cb4d 100644
--- a/apex/manifest.json
+++ b/apex/manifest.json
@@ -1,4 +1,4 @@
 {
   "name": "com.android.media",
-  "version": 300802100
+  "version": 300802200
 }
diff --git a/apex/manifest_codec.json b/apex/manifest_codec.json
index baf4077..8d7328b 100644
--- a/apex/manifest_codec.json
+++ b/apex/manifest_codec.json
@@ -1,4 +1,4 @@
 {
   "name": "com.android.media.swcodec",
-  "version": 300802100
+  "version": 300802200
 }
diff --git a/camera/ndk/include/camera/NdkCameraMetadataTags.h b/camera/ndk/include/camera/NdkCameraMetadataTags.h
index 8763c62..6d9f90a 100644
--- a/camera/ndk/include/camera/NdkCameraMetadataTags.h
+++ b/camera/ndk/include/camera/NdkCameraMetadataTags.h
@@ -8088,19 +8088,35 @@
      * <li>ACAMERA_LENS_POSE_REFERENCE</li>
      * <li>ACAMERA_LENS_DISTORTION</li>
      * </ul>
-     * <p>The field of view of all non-RAW physical streams must be the same or as close as
-     * possible to that of non-RAW logical streams. If the requested FOV is outside of the
-     * range supported by the physical camera, the physical stream for that physical camera
-     * will use either the maximum or minimum scaler crop region, depending on which one is
-     * closer to the requested FOV. For example, for a logical camera with wide-tele lens
-     * configuration where the wide lens is the default, if the logical camera's crop region
-     * is set to maximum, the physical stream for the tele lens will be configured to its
-     * maximum crop region. On the other hand, if the logical camera has a normal-wide lens
-     * configuration where the normal lens is the default, when the logical camera's crop
-     * region is set to maximum, the FOV of the logical streams will be that of the normal
-     * lens. The FOV of the physical streams for the wide lens will be the same as the
-     * logical stream, by making the crop region smaller than its active array size to
-     * compensate for the smaller focal length.</p>
+     * <p>The field of view of non-RAW physical streams must not be smaller than that of the
+     * non-RAW logical streams, or the maximum field-of-view of the physical camera,
+     * whichever is smaller. The application should check the physical capture result
+     * metadata for how the physical streams are cropped or zoomed. More specifically, given
+     * the physical camera result metadata, the effective horizontal field-of-view of the
+     * physical camera is:</p>
+     * <pre><code>fov = 2 * atan2(cropW * sensorW / (2 * zoomRatio * activeArrayW), focalLength)
+     * </code></pre>
+     * <p>where the equation parameters are the physical camera's crop region width, physical
+     * sensor width, zoom ratio, active array width, and focal length respectively. Typically
+     * the physical stream of active physical camera has the same field-of-view as the
+     * logical streams. However, the same may not be true for physical streams from
+     * non-active physical cameras. For example, if the logical camera has a wide-ultrawide
+     * configuration where the wide lens is the default, when the crop region is set to the
+     * logical camera's active array size, (and the zoom ratio set to 1.0 starting from
+     * Android 11), a physical stream for the ultrawide camera may prefer outputing images
+     * with larger field-of-view than that of the wide camera for better stereo matching
+     * margin or more robust motion tracking. At the same time, the physical non-RAW streams'
+     * field of view must not be smaller than the requested crop region and zoom ratio, as
+     * long as it's within the physical lens' capability. For example, for a logical camera
+     * with wide-tele lens configuration where the wide lens is the default, if the logical
+     * camera's crop region is set to maximum size, and zoom ratio set to 1.0, the physical
+     * stream for the tele lens will be configured to its maximum size crop region (no zoom).</p>
+     * <p><em>Deprecated:</em> Prior to Android 11, the field of view of all non-RAW physical streams
+     * cannot be larger than that of non-RAW logical streams. If the logical camera has a
+     * wide-ultrawide lens configuration where the wide lens is the default, when the logical
+     * camera's crop region is set to maximum size, the FOV of the physical streams for the
+     * ultrawide lens will be the same as the logical stream, by making the crop region
+     * smaller than its active array size to compensate for the smaller focal length.</p>
      * <p>Even if the underlying physical cameras have different RAW characteristics (such as
      * size or CFA pattern), a logical camera can still advertise RAW capability. In this
      * case, when the application configures a RAW stream, the camera device will make sure
diff --git a/media/codec2/hidl/1.0/vts/functional/common/media_c2_hidl_test_common.cpp b/media/codec2/hidl/1.0/vts/functional/common/media_c2_hidl_test_common.cpp
index a41c2dc..0251ec2 100644
--- a/media/codec2/hidl/1.0/vts/functional/common/media_c2_hidl_test_common.cpp
+++ b/media/codec2/hidl/1.0/vts/functional/common/media_c2_hidl_test_common.cpp
@@ -92,7 +92,10 @@
         for (size_t i = 0; i < updates.size(); ++i) {
             C2Param* param = updates[i].get();
             if (param->index() == C2StreamInitDataInfo::output::PARAM_TYPE) {
-                csd = true;
+                C2StreamInitDataInfo::output* csdBuffer =
+                        (C2StreamInitDataInfo::output*)(param);
+                size_t csdSize = csdBuffer->flexCount();
+                if (csdSize > 0) csd = true;
             } else if ((param->index() == C2StreamSampleRateInfo::output::PARAM_TYPE) ||
                        (param->index() == C2StreamChannelCountInfo::output::PARAM_TYPE) ||
                        (param->index() == C2StreamPictureSizeInfo::output::PARAM_TYPE)) {
diff --git a/media/codec2/hidl/1.0/vts/functional/video/VtsHalMediaC2V1_0TargetVideoDecTest.cpp b/media/codec2/hidl/1.0/vts/functional/video/VtsHalMediaC2V1_0TargetVideoDecTest.cpp
index 74088dd..12ed725 100644
--- a/media/codec2/hidl/1.0/vts/functional/video/VtsHalMediaC2V1_0TargetVideoDecTest.cpp
+++ b/media/codec2/hidl/1.0/vts/functional/video/VtsHalMediaC2V1_0TargetVideoDecTest.cpp
@@ -109,6 +109,7 @@
         mFramesReceived = 0;
         mTimestampUs = 0u;
         mWorkResult = C2_OK;
+        mReorderDepth = -1;
         mTimestampDevTest = false;
         mMd5Offset = 0;
         mMd5Enable = false;
@@ -211,34 +212,46 @@
         for (std::unique_ptr<C2Work>& work : workItems) {
             if (!work->worklets.empty()) {
                 // For decoder components current timestamp always exceeds
-                // previous timestamp
+                // previous timestamp if output is in display order
                 typedef std::unique_lock<std::mutex> ULock;
                 mWorkResult |= work->result;
                 bool codecConfig = ((work->worklets.front()->output.flags &
                                      C2FrameData::FLAG_CODEC_CONFIG) != 0);
                 if (!codecConfig && !work->worklets.front()->output.buffers.empty()) {
-                    EXPECT_GE((work->worklets.front()->output.ordinal.timestamp.peeku()),
-                              mTimestampUs);
-                    mTimestampUs = work->worklets.front()->output.ordinal.timestamp.peeku();
-
-                    ULock l(mQueueLock);
-                    if (mTimestampDevTest) {
-                        bool tsHit = false;
-                        std::list<uint64_t>::iterator it = mTimestampUslist.begin();
-                        while (it != mTimestampUslist.end()) {
-                            if (*it == mTimestampUs) {
-                                mTimestampUslist.erase(it);
-                                tsHit = true;
-                                break;
-                            }
-                            it++;
+                    if (mReorderDepth < 0) {
+                        C2PortReorderBufferDepthTuning::output reorderBufferDepth;
+                        mComponent->query({&reorderBufferDepth}, {}, C2_MAY_BLOCK,
+                                          nullptr);
+                        mReorderDepth = reorderBufferDepth.value;
+                        if (mReorderDepth > 0) {
+                            // TODO: Add validation for reordered output
+                            mTimestampDevTest = false;
                         }
-                        if (tsHit == false) {
-                            if (mTimestampUslist.empty() == false) {
-                                EXPECT_EQ(tsHit, true) << "TimeStamp not recognized";
-                            } else {
-                                std::cout << "[   INFO   ] Received non-zero "
-                                             "output / TimeStamp not recognized \n";
+                    }
+                    if (mTimestampDevTest) {
+                        EXPECT_GE((work->worklets.front()->output.ordinal.timestamp.peeku()),
+                                  mTimestampUs);
+                        mTimestampUs = work->worklets.front()->output.ordinal.timestamp.peeku();
+
+                        ULock l(mQueueLock);
+                        {
+                            bool tsHit = false;
+                            std::list<uint64_t>::iterator it = mTimestampUslist.begin();
+                            while (it != mTimestampUslist.end()) {
+                                if (*it == mTimestampUs) {
+                                    mTimestampUslist.erase(it);
+                                    tsHit = true;
+                                    break;
+                                }
+                                it++;
+                            }
+                            if (tsHit == false) {
+                                if (mTimestampUslist.empty() == false) {
+                                    EXPECT_EQ(tsHit, true) << "TimeStamp not recognized";
+                                } else {
+                                    std::cout << "[   INFO   ] Received non-zero "
+                                                 "output / TimeStamp not recognized \n";
+                                }
                             }
                         }
                     }
@@ -281,6 +294,7 @@
     standardComp mCompName;
 
     int32_t mWorkResult;
+    int32_t mReorderDepth;
     uint32_t mFramesReceived;
     C2BlockPool::local_id_t mBlockPoolId;
     std::shared_ptr<C2BlockPool> mLinearPool;
diff --git a/media/codec2/hidl/1.0/vts/functional/video/VtsHalMediaC2V1_0TargetVideoEncTest.cpp b/media/codec2/hidl/1.0/vts/functional/video/VtsHalMediaC2V1_0TargetVideoEncTest.cpp
index 9e425d2..ecaf3a8 100644
--- a/media/codec2/hidl/1.0/vts/functional/video/VtsHalMediaC2V1_0TargetVideoEncTest.cpp
+++ b/media/codec2/hidl/1.0/vts/functional/video/VtsHalMediaC2V1_0TargetVideoEncTest.cpp
@@ -510,12 +510,10 @@
         ASSERT_TRUE(false);
     }
 
-    if (!mCsd && (mCompName != vp8 && mCompName != vp9)) {
-        ASSERT_TRUE(false) << "CSD Buffer not received";
-    }
-
-    if (mCsd && (mCompName == vp8 || mCompName == vp9)) {
-        ASSERT_TRUE(false) << "CSD Buffer not expected";
+    if (mCompName == vp8 || mCompName == h263) {
+        ASSERT_FALSE(mCsd) << "CSD Buffer not expected";
+    } else if (mCompName != vp9) {
+        ASSERT_TRUE(mCsd) << "CSD Buffer not received";
     }
 
     if (mTimestampDevTest) EXPECT_EQ(mTimestampUslist.empty(), true);
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index 2dbe2e5..b36acb4 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -496,9 +496,6 @@
         clientToDisconnect->notifyError(
                 hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_DISCONNECTED,
                 CaptureResultExtras{});
-        // Ensure not in binder RPC so client disconnect PID checks work correctly
-        LOG_ALWAYS_FATAL_IF(CameraThreadState::getCallingPid() != getpid(),
-                "onDeviceStatusChanged must be called from the camera service process!");
         clientToDisconnect->disconnect();
     }
 }
diff --git a/services/mediametrics/AnalyticsState.h b/services/mediametrics/AnalyticsState.h
index b648947..09c0b4c 100644
--- a/services/mediametrics/AnalyticsState.h
+++ b/services/mediametrics/AnalyticsState.h
@@ -93,7 +93,7 @@
         int32_t ll = lines;
 
         if (ll > 0) {
-            ss << "TransactionLog:\n";
+            ss << "TransactionLog: gc(" << mTransactionLog.getGarbageCollectionCount() << ")\n";
             --ll;
         }
         if (ll > 0) {
@@ -102,7 +102,7 @@
             ll -= l;
         }
         if (ll > 0) {
-            ss << "TimeMachine:\n";
+            ss << "TimeMachine: gc(" << mTimeMachine.getGarbageCollectionCount() << ")\n";
             --ll;
         }
         if (ll > 0) {
diff --git a/services/mediametrics/AudioAnalytics.cpp b/services/mediametrics/AudioAnalytics.cpp
index 78e2c89..29801a4 100644
--- a/services/mediametrics/AudioAnalytics.cpp
+++ b/services/mediametrics/AudioAnalytics.cpp
@@ -64,6 +64,8 @@
 
 static constexpr const auto LOG_LEVEL = android::base::VERBOSE;
 
+static constexpr int PREVIOUS_STATE_EXPIRE_SEC = 60 * 60; // 1 hour.
+
 /*
  * For logging purposes, we list all of the MediaMetrics atom fields,
  * which can then be associated with consecutive arguments to the statsd write.
@@ -173,6 +175,19 @@
                 // to end of full expression.
                 mAnalyticsState->clear();  // TODO: filter the analytics state.
                 // Perhaps report this.
+
+                // Set up a timer to expire the previous audio state to save space.
+                // Use the transaction log size as a cookie to see if it is the
+                // same as before.  A benign race is possible where a state is cleared early.
+                const size_t size = mPreviousAnalyticsState->transactionLog().size();
+                mTimedAction.postIn(
+                        std::chrono::seconds(PREVIOUS_STATE_EXPIRE_SEC), [this, size](){
+                    if (mPreviousAnalyticsState->transactionLog().size() == size) {
+                        ALOGD("expiring previous audio state after %d seconds.",
+                                PREVIOUS_STATE_EXPIRE_SEC);
+                        mPreviousAnalyticsState->clear();  // removes data from the state.
+                    }
+                });
             }));
 
     // Handle device use record statistics
diff --git a/services/mediametrics/AudioAnalytics.h b/services/mediametrics/AudioAnalytics.h
index 809de19..df097b1 100644
--- a/services/mediametrics/AudioAnalytics.h
+++ b/services/mediametrics/AudioAnalytics.h
@@ -117,7 +117,7 @@
 
     // AnalyticsState is individually locked, and we use SharedPtrWrap
     // to allow safe access even if the shared pointer changes underneath.
-
+    // These wrap pointers always point to a valid state object.
     SharedPtrWrap<AnalyticsState> mAnalyticsState;
     SharedPtrWrap<AnalyticsState> mPreviousAnalyticsState;
 
diff --git a/services/mediametrics/TimeMachine.h b/services/mediametrics/TimeMachine.h
index 00a44a4..ce579b3 100644
--- a/services/mediametrics/TimeMachine.h
+++ b/services/mediametrics/TimeMachine.h
@@ -220,10 +220,10 @@
 
     using History = std::map<std::string /* key */, std::shared_ptr<KeyHistory>>;
 
-    static inline constexpr size_t kTimeSequenceMaxElements = 100;
-    static inline constexpr size_t kKeyMaxProperties = 100;
-    static inline constexpr size_t kKeyLowWaterMark = 500;
-    static inline constexpr size_t kKeyHighWaterMark = 1000;
+    static inline constexpr size_t kTimeSequenceMaxElements = 50;
+    static inline constexpr size_t kKeyMaxProperties = 50;
+    static inline constexpr size_t kKeyLowWaterMark = 400;
+    static inline constexpr size_t kKeyHighWaterMark = 500;
 
     // Estimated max data space usage is 3KB * kKeyHighWaterMark.
 
@@ -255,6 +255,7 @@
         {
             std::lock_guard lock2(other.mLock);
             mHistory = other.mHistory;
+            mGarbageCollectionCount = other.mGarbageCollectionCount.load();
         }
 
         // Now that we safely have our own shared pointers, let's dup them
@@ -420,6 +421,7 @@
     void clear() {
         std::lock_guard lock(mLock);
         mHistory.clear();
+        mGarbageCollectionCount = 0;
     }
 
     /**
@@ -453,6 +455,10 @@
         return { ss.str(), lines - ll };
     }
 
+    size_t getGarbageCollectionCount() const {
+        return mGarbageCollectionCount;
+    }
+
 private:
 
     // Obtains the lock for a KeyHistory.
@@ -496,8 +502,6 @@
         // TODO: something better than this for garbage collection.
         if (mHistory.size() < mKeyHighWaterMark) return false;
 
-        ALOGD("%s: garbage collection", __func__);
-
         // erase everything explicitly expired.
         std::multimap<int64_t, std::string> accessList;
         // use a stale vector with precise type to avoid type erasure overhead in garbage
@@ -534,12 +538,16 @@
         ALOGD("%s(%zu, %zu): key size:%zu",
                 __func__, mKeyLowWaterMark, mKeyHighWaterMark,
                 mHistory.size());
+
+        ++mGarbageCollectionCount;
         return true;
     }
 
     const size_t mKeyLowWaterMark = kKeyLowWaterMark;
     const size_t mKeyHighWaterMark = kKeyHighWaterMark;
 
+    std::atomic<size_t> mGarbageCollectionCount{};
+
     /**
      * Locking Strategy
      *
diff --git a/services/mediametrics/TransactionLog.h b/services/mediametrics/TransactionLog.h
index 8a22826..0ca4639 100644
--- a/services/mediametrics/TransactionLog.h
+++ b/services/mediametrics/TransactionLog.h
@@ -43,9 +43,9 @@
     // Transaction Log between the Low Water Mark and the High Water Mark.
 
     // low water mark
-    static inline constexpr size_t kLogItemsLowWater = 5000;
+    static inline constexpr size_t kLogItemsLowWater = 1700;
     // high water mark
-    static inline constexpr size_t kLogItemsHighWater = 10000;
+    static inline constexpr size_t kLogItemsHighWater = 2000;
 
     // Estimated max data usage is 1KB * kLogItemsHighWater.
 
@@ -79,6 +79,7 @@
         std::lock_guard lock2(other.mLock);
         mLog = other.mLog;
         mItemMap = other.mItemMap;
+        mGarbageCollectionCount = other.mGarbageCollectionCount.load();
 
         return *this;
     }
@@ -181,6 +182,11 @@
         std::lock_guard lock(mLock);
         mLog.clear();
         mItemMap.clear();
+        mGarbageCollectionCount = 0;
+    }
+
+    size_t getGarbageCollectionCount() const {
+        return mGarbageCollectionCount;
     }
 
 private:
@@ -216,8 +222,6 @@
     bool gc(std::vector<std::any>& garbage) REQUIRES(mLock) {
         if (mLog.size() < mHighWaterMark) return false;
 
-        ALOGD("%s: garbage collection", __func__);
-
         auto eraseEnd = mLog.begin();
         size_t toRemove = mLog.size() - mLowWaterMark;
         // remove at least those elements.
@@ -265,6 +269,7 @@
         ALOGD("%s(%zu, %zu): log size:%zu item map size:%zu, item map items:%zu",
                 __func__, mLowWaterMark, mHighWaterMark,
                 mLog.size(), mItemMap.size(), itemMapCount);
+        ++mGarbageCollectionCount;
         return true;
     }
 
@@ -287,6 +292,8 @@
     const size_t mLowWaterMark = kLogItemsLowWater;
     const size_t mHighWaterMark = kLogItemsHighWater;
 
+    std::atomic<size_t> mGarbageCollectionCount{};
+
     mutable std::mutex mLock;
 
     MapTimeItem mLog GUARDED_BY(mLock);