Merge "Fix passing of ExtraAudioDescriptors to audio HAL"
diff --git a/media/TEST_MAPPING b/media/TEST_MAPPING
index 9a2aa0d..a4c03ba 100644
--- a/media/TEST_MAPPING
+++ b/media/TEST_MAPPING
@@ -23,52 +23,8 @@
         {
             "path": "frameworks/av/drm/mediadrm/plugins"
         }
-    ],
-
-    "platinum-postsubmit": [
-        // runs regularly, independent of changes in this tree.
-        // signals if changes elsewhere break media functionality
-        // @FlakyTest: in staged-postsubmit, but not postsubmit
-        {
-            "name": "CtsMediaCodecTestCases",
-            "options": [
-                {
-                    "include-filter": "android.media.codec.cts.EncodeDecodeTest"
-                },
-                {
-                    "exclude-annotation": "androidx.test.filters.FlakyTest"
-                }
-            ]
-        },
-        {
-            "name": "CtsMediaCodecTestCases",
-            "options": [
-                {
-                    "include-filter": "android.media.codec.cts.DecodeEditEncodeTest"
-                },
-                {
-                    "exclude-annotation": "androidx.test.filters.FlakyTest"
-                }
-            ]
-        }
-    ],
-    "staged-platinum-postsubmit": [
-        // runs every four hours
-        {
-            "name": "CtsMediaCodecTestCases",
-            "options": [
-                {
-                    "include-filter": "android.media.codec.cts.EncodeDecodeTest"
-                }
-            ]
-        },
-        {
-            "name": "CtsMediaCodecTestCases",
-            "options": [
-                {
-                    "include-filter": "android.media.codec.cts.DecodeEditEncodeTest"
-                }
-            ]
-        }
     ]
+
+    // TODO (b/229286407) Add EncodeDecodeTest and DecodeEditEncodeTest to
+    // platinum-postsubmit once issues in cuttlefish are fixed
 }
diff --git a/media/codec2/components/avc/C2SoftAvcEnc.cpp b/media/codec2/components/avc/C2SoftAvcEnc.cpp
index 4ffcd59..8b46d3f 100644
--- a/media/codec2/components/avc/C2SoftAvcEnc.cpp
+++ b/media/codec2/components/avc/C2SoftAvcEnc.cpp
@@ -1514,7 +1514,8 @@
             vPlane = uPlane + yPlaneSize / 4;
             yStride = width;
             uStride = vStride = yStride / 2;
-            ConvertRGBToPlanarYUV(yPlane, yStride, height, conversionBuffer.size(), *input);
+            ConvertRGBToPlanarYUV(yPlane, yStride, height, conversionBuffer.size(), *input,
+                                  mColorAspects->matrix, mColorAspects->range);
             break;
         }
         case C2PlanarLayout::TYPE_YUV: {
diff --git a/media/codec2/components/hevc/C2SoftHevcEnc.cpp b/media/codec2/components/hevc/C2SoftHevcEnc.cpp
index 947e387..60d5875 100644
--- a/media/codec2/components/hevc/C2SoftHevcEnc.cpp
+++ b/media/codec2/components/hevc/C2SoftHevcEnc.cpp
@@ -901,7 +901,8 @@
             yStride = width;
             uStride = vStride = yStride / 2;
             ConvertRGBToPlanarYUV(yPlane, yStride, height,
-                                  conversionBuffer.size(), *input);
+                                  conversionBuffer.size(), *input,
+                                  mColorAspects->matrix, mColorAspects->range);
             break;
         }
         case C2PlanarLayout::TYPE_YUV: {
diff --git a/media/codec2/components/vpx/C2SoftVpxEnc.cpp b/media/codec2/components/vpx/C2SoftVpxEnc.cpp
index 617769b..f99ee24 100644
--- a/media/codec2/components/vpx/C2SoftVpxEnc.cpp
+++ b/media/codec2/components/vpx/C2SoftVpxEnc.cpp
@@ -733,8 +733,14 @@
     switch (layout.type) {
         case C2PlanarLayout::TYPE_RGB:
         case C2PlanarLayout::TYPE_RGBA: {
+            std::shared_ptr<C2StreamColorAspectsInfo::output> colorAspects;
+            {
+                IntfImpl::Lock lock = mIntf->lock();
+                colorAspects = mIntf->getCodedColorAspects_l();
+            }
             ConvertRGBToPlanarYUV(mConversionBuffer.data(), stride, vstride,
-                                  mConversionBuffer.size(), *rView.get());
+                                  mConversionBuffer.size(), *rView.get(),
+                                  colorAspects->matrix, colorAspects->range);
             vpx_img_wrap(&raw_frame, VPX_IMG_FMT_I420, width, height,
                          mStrideAlign, mConversionBuffer.data());
             break;
diff --git a/media/codec2/components/vpx/C2SoftVpxEnc.h b/media/codec2/components/vpx/C2SoftVpxEnc.h
index e296c8f..714fadb 100644
--- a/media/codec2/components/vpx/C2SoftVpxEnc.h
+++ b/media/codec2/components/vpx/C2SoftVpxEnc.h
@@ -265,6 +265,9 @@
     std::shared_ptr<C2StreamTemporalLayeringTuning::output> getTemporalLayers_l() const {
         return mLayering;
     }
+    std::shared_ptr<C2StreamColorAspectsInfo::output> getCodedColorAspects_l() const {
+        return mCodedColorAspects;
+    }
     uint32_t getSyncFramePeriod() const;
     static C2R ColorAspectsSetter(bool mayBlock, C2P<C2StreamColorAspectsInfo::input> &me);
     static C2R CodedColorAspectsSetter(bool mayBlock, C2P<C2StreamColorAspectsInfo::output> &me,
diff --git a/media/codec2/sfplugin/CCodec.cpp b/media/codec2/sfplugin/CCodec.cpp
index 529ee36..296d7ed 100644
--- a/media/codec2/sfplugin/CCodec.cpp
+++ b/media/codec2/sfplugin/CCodec.cpp
@@ -1492,8 +1492,12 @@
                                                            // with more enc stat kinds
                 // Future extended encoding statistics for the level 2 should be added here
                 case VIDEO_ENCODING_STATISTICS_LEVEL_1:
-                    config->subscribeToConfigUpdate(comp,
-                        {kParamIndexAverageBlockQuantization, kParamIndexPictureType});
+                    config->subscribeToConfigUpdate(
+                            comp,
+                            {
+                                C2AndroidStreamAverageBlockQuantizationInfo::output::PARAM_TYPE,
+                                C2StreamPictureTypeInfo::output::PARAM_TYPE,
+                            });
                     break;
                 case VIDEO_ENCODING_STATISTICS_LEVEL_NONE:
                     break;
diff --git a/media/codec2/sfplugin/CCodecConfig.cpp b/media/codec2/sfplugin/CCodecConfig.cpp
index b7ee2f0..cfadc95 100644
--- a/media/codec2/sfplugin/CCodecConfig.cpp
+++ b/media/codec2/sfplugin/CCodecConfig.cpp
@@ -16,6 +16,9 @@
 
 //#define LOG_NDEBUG 0
 #define LOG_TAG "CCodecConfig"
+
+#include <initializer_list>
+
 #include <cutils/properties.h>
 #include <log/log.h>
 #include <utils/NativeHandle.h>
@@ -1128,7 +1131,7 @@
             if (domain.value == C2Component::DOMAIN_VIDEO) {
                 addLocalParam(new C2AndroidStreamAverageBlockQuantizationInfo::output(0u, 0),
                               C2_PARAMKEY_AVERAGE_QP);
-                addLocalParam(new C2StreamPictureTypeMaskInfo::output(0u, 0),
+                addLocalParam(new C2StreamPictureTypeInfo::output(0u, 0),
                               C2_PARAMKEY_PICTURE_TYPE);
             }
         }
@@ -1165,6 +1168,17 @@
         }
     }
 
+    // Parameters that are not subscribed initially, but can be subscribed
+    // upon explicit request.
+    static const std::initializer_list<C2Param::Index> kOptionalParams = {
+        C2AndroidStreamAverageBlockQuantizationInfo::output::PARAM_TYPE,
+        C2StreamPictureTypeInfo::output::PARAM_TYPE,
+    };
+    for (const C2Param::Index &index : kOptionalParams) {
+        mSubscribedIndices.erase(index);
+    }
+    subscribeToConfigUpdate(configurable, {}, C2_MAY_BLOCK);
+
     return OK;
 }
 
@@ -1196,6 +1210,20 @@
         ALOGV("Subscribed to %zu params", mSubscribedIndices.size());
         mSubscribedIndicesSize = mSubscribedIndices.size();
     }
+#if defined(LOG_NDEBUG) && !LOG_NDEBUG
+    ALOGV("subscribed to %zu params:", mSubscribedIndices.size());
+    std::stringstream ss;
+    for (const C2Param::Index &index : mSubscribedIndices) {
+        ss << index << " ";
+        if (ss.str().length() > 70) {
+            ALOGV("%s", ss.str().c_str());
+            std::stringstream().swap(ss);
+        }
+    }
+    if (!ss.str().empty()) {
+        ALOGV("%s", ss.str().c_str());
+    }
+#endif
     return OK;
 }
 
@@ -1220,6 +1248,12 @@
     bool changed = false;
     for (std::unique_ptr<C2Param> &p : configUpdate) {
         if (p && *p) {
+            // Allow unsubscribed vendor parameters to go through --- it may be
+            // later handled by the format shaper.
+            if (!p->isVendor() && mSubscribedIndices.count(p->index()) == 0) {
+                ALOGV("updateConfiguration: skipped unsubscribed param %08x", p->index());
+                continue;
+            }
             auto insertion = mCurrentConfig.emplace(p->index(), nullptr);
             if (insertion.second || *insertion.first->second != *p) {
                 if (mSupportedIndices.count(p->index()) || mLocalParams.count(p->index())) {
diff --git a/media/libstagefright/Utils.cpp b/media/libstagefright/Utils.cpp
index a443ed9..900ac32 100644
--- a/media/libstagefright/Utils.cpp
+++ b/media/libstagefright/Utils.cpp
@@ -1911,10 +1911,10 @@
         if (msg->findString("ts-schema", &tsSchema)) {
             unsigned int numLayers = 0;
             unsigned int numBLayers = 0;
-            char dummy;
+            char placeholder;
             int tags = sscanf(tsSchema.c_str(), "android.generic.%u%c%u%c",
-                    &numLayers, &dummy, &numBLayers, &dummy);
-            if ((tags == 1 || (tags == 3 && dummy == '+'))
+                    &numLayers, &placeholder, &numBLayers, &placeholder);
+            if ((tags == 1 || (tags == 3 && placeholder == '+'))
                     && numLayers > 0 && numLayers < UINT32_MAX - numBLayers
                     && numLayers + numBLayers <= INT32_MAX) {
                 meta->setInt32(kKeyTemporalLayerCount, numLayers + numBLayers);
diff --git a/media/ndk/fuzzer/Android.bp b/media/ndk/fuzzer/Android.bp
index 82d03e5..b2ae220 100644
--- a/media/ndk/fuzzer/Android.bp
+++ b/media/ndk/fuzzer/Android.bp
@@ -14,6 +14,15 @@
  * limitations under the License.
  */
 
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_av_media_ndk_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_av_media_ndk_license"],
+}
+
 cc_defaults {
      name: "libmediandk_fuzzer_defaults",
      shared_libs: [
diff --git a/media/utils/ServiceUtilities.cpp b/media/utils/ServiceUtilities.cpp
index 1ab5bc1..07f4529 100644
--- a/media/utils/ServiceUtilities.cpp
+++ b/media/utils/ServiceUtilities.cpp
@@ -181,10 +181,14 @@
 
 bool captureAudioOutputAllowed(const AttributionSourceState& attributionSource) {
     uid_t uid = VALUE_OR_FATAL(aidl2legacy_int32_t_uid_t(attributionSource.uid));
-    pid_t pid = VALUE_OR_FATAL(aidl2legacy_int32_t_pid_t(attributionSource.pid));
     if (isAudioServerOrRootUid(uid)) return true;
     static const String16 sCaptureAudioOutput("android.permission.CAPTURE_AUDIO_OUTPUT");
-    bool ok = PermissionCache::checkPermission(sCaptureAudioOutput, pid, uid);
+    // Use PermissionChecker, which includes some logic for allowing the isolated
+    // HotwordDetectionService to hold certain permissions.
+    permission::PermissionChecker permissionChecker;
+    bool ok = (permissionChecker.checkPermissionForPreflight(
+            sCaptureAudioOutput, attributionSource, String16(),
+            AppOpsManager::OP_NONE) != permission::PermissionChecker::PERMISSION_HARD_DENIED);
     if (!ok) ALOGV("Request requires android.permission.CAPTURE_AUDIO_OUTPUT");
     return ok;
 }
diff --git a/services/camera/libcameraservice/common/Camera2ClientBase.cpp b/services/camera/libcameraservice/common/Camera2ClientBase.cpp
index 53a9b7e..ae22717 100644
--- a/services/camera/libcameraservice/common/Camera2ClientBase.cpp
+++ b/services/camera/libcameraservice/common/Camera2ClientBase.cpp
@@ -163,6 +163,11 @@
 
     disconnect();
 
+    if (mCameraServiceWatchdog != NULL) {
+        mCameraServiceWatchdog->requestExit();
+        mCameraServiceWatchdog.clear();
+    }
+
     ALOGI("Closed Camera %s. Client was: %s (PID %d, UID %u)",
             TClientBase::mCameraIdStr.string(),
             String8(TClientBase::mClientPackageName).string(),
@@ -248,8 +253,12 @@
 
 template <typename TClientBase>
 binder::Status Camera2ClientBase<TClientBase>::disconnect() {
-    return mCameraServiceWatchdog->WATCH_CUSTOM_TIMER(disconnectImpl(),
-            kDisconnectTimeoutMs / kCycleLengthMs, kCycleLengthMs);
+    if (mCameraServiceWatchdog != nullptr) {
+        // Initialization from hal succeeded, time disconnect.
+        return mCameraServiceWatchdog->WATCH_CUSTOM_TIMER(disconnectImpl(),
+                kDisconnectTimeoutMs / kCycleLengthMs, kCycleLengthMs);
+    }
+    return disconnectImpl();
 }
 
 template <typename TClientBase>