Merge "Add APV Support flag" into main
diff --git a/drm/drmserver/Android.bp b/drm/drmserver/Android.bp
index 81c2003..cee44b9 100644
--- a/drm/drmserver/Android.bp
+++ b/drm/drmserver/Android.bp
@@ -78,9 +78,6 @@
         "libselinux",
         "libstagefright_foundation",
     ],
-    whole_static_libs: [
-        "libc++fs",
-    ],
 
     cflags: [
         "-Wall",
@@ -127,7 +124,6 @@
     ],
 
     static_libs: [
-        "libc++fs",
         "libmediautils",
         "liblog",
         "libdrmframeworkcommon",
diff --git a/drm/libdrmframework/plugins/passthru/Android.bp b/drm/libdrmframework/plugins/passthru/Android.bp
index 0a6cd47..6ac7188 100644
--- a/drm/libdrmframework/plugins/passthru/Android.bp
+++ b/drm/libdrmframework/plugins/passthru/Android.bp
@@ -45,9 +45,6 @@
         "libdl",
         "libdrmframeworkcommon",
     ],
-    whole_static_libs: [
-        "libc++fs",
-    ],
 
     local_include_dirs: ["include"],
 
diff --git a/media/codec2/sfplugin/CCodecBufferChannel.cpp b/media/codec2/sfplugin/CCodecBufferChannel.cpp
index 5c46d99..4353521 100644
--- a/media/codec2/sfplugin/CCodecBufferChannel.cpp
+++ b/media/codec2/sfplugin/CCodecBufferChannel.cpp
@@ -41,6 +41,7 @@
 #include <android/sysprop/MediaProperties.sysprop.h>
 #include <android-base/parseint.h>
 #include <android-base/properties.h>
+#include <android-base/no_destructor.h>
 #include <android-base/stringprintf.h>
 #include <binder/MemoryBase.h>
 #include <binder/MemoryDealer.h>
@@ -115,6 +116,109 @@
             });
 }
 
+class SurfaceCallbackHandler {
+public:
+    enum callback_type_t {
+        ON_BUFFER_RELEASED = 0,
+        ON_BUFFER_ATTACHED
+    };
+
+    void post(callback_type_t callback,
+            std::shared_ptr<Codec2Client::Component> component,
+            uint32_t generation) {
+        if (!component) {
+            ALOGW("surface callback psoted for invalid component");
+        }
+        std::shared_ptr<SurfaceCallbackItem> item =
+                std::make_shared<SurfaceCallbackItem>(callback, component, generation);
+        std::unique_lock<std::mutex> lock(mMutex);
+        mItems.emplace_back(std::move(item));
+        mCv.notify_one();
+    }
+
+    ~SurfaceCallbackHandler() {
+        {
+            std::unique_lock<std::mutex> lock(mMutex);
+            mDone = true;
+            mCv.notify_all();
+        }
+        if (mThread.joinable()) {
+            mThread.join();
+        }
+    }
+
+    static SurfaceCallbackHandler& GetInstance() {
+        static base::NoDestructor<SurfaceCallbackHandler> sSurfaceCallbackHandler{};
+        return *sSurfaceCallbackHandler;
+    }
+
+private:
+    struct SurfaceCallbackItem {
+        callback_type_t mCallback;
+        std::weak_ptr<Codec2Client::Component> mComp;
+        uint32_t mGeneration;
+
+        SurfaceCallbackItem(
+                callback_type_t callback,
+                std::shared_ptr<Codec2Client::Component> comp,
+                uint32_t generation)
+                : mCallback(callback), mComp(comp), mGeneration(generation) {}
+    };
+
+    SurfaceCallbackHandler() { mThread = std::thread(&SurfaceCallbackHandler::run, this); }
+
+    void run() {
+        std::unique_lock<std::mutex> lock(mMutex);
+        while (!mDone) {
+            while (!mItems.empty()) {
+                std::deque<std::shared_ptr<SurfaceCallbackItem>> items = std::move(mItems);
+                mItems.clear();
+                lock.unlock();
+                handle(items);
+                lock.lock();
+            }
+            mCv.wait(lock);
+        }
+    }
+
+    void handle(std::deque<std::shared_ptr<SurfaceCallbackItem>> &items) {
+        while (!items.empty()) {
+            std::shared_ptr<SurfaceCallbackItem> item = items.front();
+            items.pop_front();
+            switch (item->mCallback) {
+                case ON_BUFFER_RELEASED: {
+                    std::shared_ptr<Codec2Client::Component> comp = item->mComp.lock();;
+                    if (comp) {
+                        comp->onBufferReleasedFromOutputSurface(item->mGeneration);
+                    }
+                    break;
+                }
+                case ON_BUFFER_ATTACHED: {
+                    std::shared_ptr<Codec2Client::Component> comp = item->mComp.lock();
+                    if (comp) {
+                        comp->onBufferAttachedToOutputSurface(item->mGeneration);
+                    }
+                    break;
+                }
+                default:
+                    ALOGE("Non defined surface callback message");
+                    break;
+            }
+        }
+    }
+
+    std::thread mThread;
+    bool mDone = false;
+    std::deque<std::shared_ptr<SurfaceCallbackItem>> mItems;
+    std::mutex mMutex;
+    std::condition_variable mCv;
+
+
+    friend class base::NoDestructor<SurfaceCallbackHandler>;
+
+    DISALLOW_EVIL_CONSTRUCTORS(SurfaceCallbackHandler);
+};
+
 }  // namespace
 
 CCodecBufferChannel::QueueGuard::QueueGuard(
@@ -1503,7 +1607,8 @@
     // during this interface being executed.
     std::shared_ptr<Codec2Client::Component> comp = mComponent;
     if (comp) {
-        comp->onBufferReleasedFromOutputSurface(generation);
+      SurfaceCallbackHandler::GetInstance().post(
+                SurfaceCallbackHandler::ON_BUFFER_RELEASED, comp, generation);
     }
 }
 
@@ -1514,7 +1619,8 @@
     // during this interface being executed.
     std::shared_ptr<Codec2Client::Component> comp = mComponent;
     if (comp) {
-        comp->onBufferAttachedToOutputSurface(generation);
+      SurfaceCallbackHandler::GetInstance().post(
+                SurfaceCallbackHandler::ON_BUFFER_ATTACHED, comp, generation);
     }
 }
 
@@ -1801,6 +1907,7 @@
             outputSurface = output->surface ?
                     output->surface->getIGraphicBufferProducer() : nullptr;
             if (outputSurface) {
+                (void)SurfaceCallbackHandler::GetInstance();
                 output->surface->setMaxDequeuedBufferCount(output->maxDequeueBuffers);
             }
             outputGeneration = output->generation;
@@ -2727,6 +2834,7 @@
         oldSurface = outputSurface->surface;
     }
     if (newSurface) {
+        (void)SurfaceCallbackHandler::GetInstance();
         newSurface->setScalingMode(NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
         newSurface->setDequeueTimeout(kDequeueTimeoutNs);
         newSurface->setMaxDequeuedBufferCount(maxDequeueCount);
diff --git a/media/janitors/media_solutions_OWNERS b/media/janitors/media_solutions_OWNERS
index 17bc7dd..3243726 100644
--- a/media/janitors/media_solutions_OWNERS
+++ b/media/janitors/media_solutions_OWNERS
@@ -1,22 +1,18 @@
 # Bug component: 1344
 # go/android-fwk-media-solutions for info on areas of ownership.
 
-# MediaRouter and native mirroring only:
-adadukin@google.com
-aquilescanta@google.com
-bishoygendy@google.com
-ivanbuper@google.com
-
-# MediaMuxer, MediaRecorder, and seamless transcoding only:
 andrewlewis@google.com
-claincly@google.com
-
-# Everything in go/android-fwk-media-solutions not covered above:
 bachinger@google.com
-christosts@google.com
+claincly@google.com
 ibaker@google.com
+ivanbuper@google.com
 jbibik@google.com
 michaelkatz@google.com
 rohks@google.com
+sheenachhabra@google.com
+simakova@google.com
 tianyifeng@google.com
 tonihei@google.com
+
+# MediaRouter and native mirroring only:
+aquilescanta@google.com
diff --git a/media/libeffects/dynamicsproc/aidl/DynamicsProcessingContext.cpp b/media/libeffects/dynamicsproc/aidl/DynamicsProcessingContext.cpp
index fd4e615..dd14ac2 100644
--- a/media/libeffects/dynamicsproc/aidl/DynamicsProcessingContext.cpp
+++ b/media/libeffects/dynamicsproc/aidl/DynamicsProcessingContext.cpp
@@ -52,6 +52,7 @@
     if (mDpFreq != nullptr) {
         mDpFreq->reset();
     }
+    mEngineInited = false;
     return RetCode::SUCCESS;
 }
 
diff --git a/media/libmedia/AudioCapabilities.cpp b/media/libmedia/AudioCapabilities.cpp
index e8cf517..908989f 100644
--- a/media/libmedia/AudioCapabilities.cpp
+++ b/media/libmedia/AudioCapabilities.cpp
@@ -94,30 +94,31 @@
     mSampleRateRanges.push_back(Range<int>(minSampleRate, maxSampleRate));
 }
 
-bool AudioCapabilities::supports(int sampleRate, int inputChannels) {
+bool AudioCapabilities::supports(std::optional<int> sampleRate,
+        std::optional<int> inputChannels) {
     // channels and sample rates are checked orthogonally
-    if (inputChannels != 0
+    if (inputChannels
             && !std::any_of(mInputChannelRanges.begin(), mInputChannelRanges.end(),
-            [inputChannels](const Range<int> &a) { return a.contains(inputChannels); })) {
+            [inputChannels](const Range<int> &a) { return a.contains(inputChannels.value()); })) {
         return false;
     }
-    if (sampleRate != 0
+    if (sampleRate
             && !std::any_of(mSampleRateRanges.begin(), mSampleRateRanges.end(),
-            [sampleRate](const Range<int> &a) { return a.contains(sampleRate); })) {
+            [sampleRate](const Range<int> &a) { return a.contains(sampleRate.value()); })) {
         return false;
     }
     return true;
 }
 
 bool AudioCapabilities::isSampleRateSupported(int sampleRate) {
-    return supports(sampleRate, 0);
+    return supports(std::make_optional<int>(sampleRate), std::nullopt);
 }
 
 void AudioCapabilities::limitSampleRates(std::vector<int> rates) {
     std::vector<Range<int>> sampleRateRanges;
     std::sort(rates.begin(), rates.end());
     for (int rate : rates) {
-        if (supports(rate, 0 /* channels */)) {
+        if (supports(std::make_optional<int>(rate), std::nullopt /* channels */)) {
             sampleRateRanges.push_back(Range<int>(rate, rate));
         }
     }
@@ -372,10 +373,12 @@
 }
 
 bool AudioCapabilities::supportsFormat(const sp<AMessage> &format) {
-    int32_t sampleRate;
-    format->findInt32(KEY_SAMPLE_RATE, &sampleRate);
-    int32_t channels;
-    format->findInt32(KEY_CHANNEL_COUNT, &channels);
+    int32_t sampleRateValue;
+    std::optional<int> sampleRate = format->findInt32(KEY_SAMPLE_RATE, &sampleRateValue)
+            ? std::make_optional<int>(sampleRateValue) : std::nullopt;
+    int32_t channelsValue;
+    std::optional<int> channels = format->findInt32(KEY_CHANNEL_COUNT, &channelsValue)
+            ? std::make_optional<int>(channelsValue) : std::nullopt;
 
     if (!supports(sampleRate, channels)) {
         return false;
diff --git a/media/libmedia/include/media/AudioCapabilities.h b/media/libmedia/include/media/AudioCapabilities.h
index 2bc3335..2cb957e 100644
--- a/media/libmedia/include/media/AudioCapabilities.h
+++ b/media/libmedia/include/media/AudioCapabilities.h
@@ -121,7 +121,7 @@
     void init(std::string mediaType, std::vector<ProfileLevel> profLevs,
             const sp<AMessage> &format);
     void initWithPlatformLimits();
-    bool supports(int sampleRate, int inputChannels);
+    bool supports(std::optional<int> sampleRate, std::optional<int> inputChannels);
     void limitSampleRates(std::vector<int> rates);
     void createDiscreteSampleRates();
     void limitSampleRates(std::vector<Range<int>> rateRanges);