Merge "AudioFlinger: Group common tidy check parameters together"
diff --git a/cmds/stagefright/stagefright.cpp b/cmds/stagefright/stagefright.cpp
index 9783855..2edc0fe 100644
--- a/cmds/stagefright/stagefright.cpp
+++ b/cmds/stagefright/stagefright.cpp
@@ -749,7 +749,8 @@
                         mediaType.equalsIgnoreCase(MIMETYPE_VIDEO_VP8)   ? asString_VP8Profile(pl.mProfile) :
                         mediaType.equalsIgnoreCase(MIMETYPE_VIDEO_HEVC)  ? asString_HEVCProfile(pl.mProfile) :
                         mediaType.equalsIgnoreCase(MIMETYPE_VIDEO_VP9)   ? asString_VP9Profile(pl.mProfile) :
-                        mediaType.equalsIgnoreCase(MIMETYPE_VIDEO_AV1)   ? asString_AV1Profile(pl.mProfile) :"??";
+                        mediaType.equalsIgnoreCase(MIMETYPE_VIDEO_AV1)   ? asString_AV1Profile(pl.mProfile) :
+                        mediaType.equalsIgnoreCase(MIMETYPE_VIDEO_DOLBY_VISION) ? asString_DolbyVisionProfile(pl.mProfile) :"??";
                     const char *niceLevel =
                         mediaType.equalsIgnoreCase(MIMETYPE_VIDEO_MPEG2) ? asString_MPEG2Level(pl.mLevel) :
                         mediaType.equalsIgnoreCase(MIMETYPE_VIDEO_H263)  ? asString_H263Level(pl.mLevel) :
@@ -759,6 +760,7 @@
                         mediaType.equalsIgnoreCase(MIMETYPE_VIDEO_HEVC)  ? asString_HEVCTierLevel(pl.mLevel) :
                         mediaType.equalsIgnoreCase(MIMETYPE_VIDEO_VP9)   ? asString_VP9Level(pl.mLevel) :
                         mediaType.equalsIgnoreCase(MIMETYPE_VIDEO_AV1)   ? asString_AV1Level(pl.mLevel) :
+                        mediaType.equalsIgnoreCase(MIMETYPE_VIDEO_DOLBY_VISION) ? asString_DolbyVisionLevel(pl.mLevel) :
                         "??";
 
                     list.add(AStringPrintf("% 5u/% 5u (%s/%s)",
diff --git a/media/codec2/core/include/C2Buffer.h b/media/codec2/core/include/C2Buffer.h
index abe343b..7e1df91 100644
--- a/media/codec2/core/include/C2Buffer.h
+++ b/media/codec2/core/include/C2Buffer.h
@@ -101,6 +101,8 @@
 
     /**
      * Returns a file descriptor that can be used to wait for this fence in a select system call.
+     * \note If there are multiple file descriptors in fence then a file descriptor for merged fence
+     *  would be returned
      * \note The returned file descriptor, if valid, must be closed by the caller.
      *
      * This can be used in e.g. poll() system calls. This file becomes readable (POLLIN) when the
@@ -129,6 +131,7 @@
     std::shared_ptr<Impl> mImpl;
     C2Fence(std::shared_ptr<Impl> impl);
     friend struct _C2FenceFactory;
+    friend std::vector<int> ExtractFdsFromCodec2SyncFence(const C2Fence& fence);
 };
 
 /**
diff --git a/media/codec2/vndk/C2Fence.cpp b/media/codec2/vndk/C2Fence.cpp
index aa908a8..0344fd3 100644
--- a/media/codec2/vndk/C2Fence.cpp
+++ b/media/codec2/vndk/C2Fence.cpp
@@ -190,7 +190,6 @@
         if (timeoutMs > INT_MAX) {
             timeoutMs = INT_MAX;
         }
-
         switch (mFence->wait((int)timeoutMs)) {
             case NO_ERROR:
                 return C2_OK;
@@ -202,7 +201,7 @@
     }
 
     virtual bool valid() const {
-        return mFence->getStatus() != Fence::Status::Invalid;
+        return (mFence && (mFence->getStatus() != Fence::Status::Invalid));
     }
 
     virtual bool ready() const {
@@ -213,6 +212,14 @@
         return mFence->dup();
     }
 
+    std::vector<int> fds() const {
+        std::vector<int> retFds;
+        for (int index = 0; index < mListFences.size(); index++) {
+            retFds.push_back(mListFences[index]->dup());
+        }
+        return retFds;
+    }
+
     virtual bool isHW() const {
         return true;
     }
@@ -222,39 +229,95 @@
     }
 
     virtual native_handle_t *createNativeHandle() const {
-        native_handle_t* nh = native_handle_create(1, 1);
+        std::vector<int> nativeFds = fds();
+        nativeFds.push_back(fd());
+        native_handle_t* nh = native_handle_create(nativeFds.size(), 1);
         if (!nh) {
             ALOGE("Failed to allocate native handle for sync fence");
+            for (int fd : nativeFds) {
+                close(fd);
+            }
             return nullptr;
         }
-        nh->data[0] = fd();
-        nh->data[1] = type();
+
+        for (int i = 0; i < nativeFds.size(); i++) {
+            nh->data[i] = nativeFds[i];
+        }
+        nh->data[nativeFds.size()] = type();
         return nh;
     }
 
     virtual ~SyncFenceImpl() {};
 
     SyncFenceImpl(int fenceFd) :
-            mFence(sp<Fence>::make(fenceFd)) {}
+        mFence(sp<Fence>::make(fenceFd)) {
+        mListFences.clear();
+        if (mFence) {
+            mListFences.push_back(mFence);
+        }
+    }
+
+    SyncFenceImpl(const std::vector<int>& fenceFds, int mergedFd) {
+        mListFences.clear();
+
+        for (int fenceFd : fenceFds) {
+            if (fenceFd < 0) {
+                continue;
+            } else {
+                mListFences.push_back(sp<Fence>::make(fenceFd));
+                if (!mListFences.back()) {
+                    mFence.clear();
+                    break;
+                }
+                if (mergedFd == -1) {
+                    mFence = (mFence == nullptr) ? (mListFences.back()) :
+                        (Fence::merge("syncFence", mFence, mListFences.back()));
+                }
+            }
+        }
+        if (mergedFd != -1)
+        {
+            mFence = sp<Fence>::make(mergedFd);
+        }
+        if (!mFence) {
+            mListFences.clear();
+        }
+    }
 
     static std::shared_ptr<SyncFenceImpl> CreateFromNativeHandle(const native_handle_t* nh) {
-        if (!nh || nh->numFds != 1 || nh->numInts != 1) {
+        if (!nh || nh->numFds < 1 || nh->numInts < 1) {
             ALOGE("Invalid handle for sync fence");
             return nullptr;
         }
-        int fd = dup(nh->data[0]);
-        std::shared_ptr<SyncFenceImpl> p = std::make_shared<SyncFenceImpl>(fd);
+        std::vector<int> fds;
+        for (int i = 0; i < nh->numFds-1; i++) {
+            fds.push_back(dup(nh->data[i]));
+        }
+        std::shared_ptr<SyncFenceImpl> p = (nh->numFds == 1)?
+                (std::make_shared<SyncFenceImpl>(fds.back())):
+                (std::make_shared<SyncFenceImpl>(fds, (dup(nh->data[nh->numFds-1]))));
         if (!p) {
             ALOGE("Failed to allocate sync fence impl");
-            close(fd);
+            for (int fd : fds) {
+                close(fd);
+            }
         }
         return p;
     }
 
 private:
-    const sp<Fence> mFence;
+    std::vector<sp<Fence>> mListFences;
+    sp<Fence> mFence;  //merged fence in case mListFences size > 0
 };
 
+std::vector<int> ExtractFdsFromCodec2SyncFence(const C2Fence& fence) {
+    std::vector<int> retFds;
+    if ((fence.mImpl) && (fence.mImpl->type() == C2Fence::Impl::SYNC_FENCE)) {
+        retFds = static_cast<_C2FenceFactory::SyncFenceImpl *>(fence.mImpl.get())->fds();
+    }
+    return retFds;
+}
+
 C2Fence _C2FenceFactory::CreateSyncFence(int fenceFd) {
     std::shared_ptr<C2Fence::Impl> p;
     if (fenceFd >= 0) {
@@ -262,8 +325,7 @@
         if (!p) {
             ALOGE("Failed to allocate sync fence impl");
             close(fenceFd);
-        }
-        if (!p->valid()) {
+        } else if (!p->valid()) {
             p.reset();
         }
     } else {
@@ -272,6 +334,25 @@
     return C2Fence(p);
 }
 
+C2Fence _C2FenceFactory::CreateMultipleFdSyncFence(const std::vector<int>& fenceFds) {
+    std::shared_ptr<C2Fence::Impl> p;
+    if (fenceFds.size() > 0) {
+        p = std::make_shared<_C2FenceFactory::SyncFenceImpl>(fenceFds, -1);
+        if (!p) {
+            ALOGE("Failed to allocate sync fence impl closing FDs");
+            for (int fenceFd : fenceFds) {
+                close(fenceFd);
+            }
+        } else if (!p->valid()) {
+            ALOGE("Invalid sync fence created");
+            p.reset();
+        }
+    } else {
+        ALOGE("Create sync fence from invalid fd list of size 0");
+    }
+    return C2Fence(p);
+}
+
 native_handle_t* _C2FenceFactory::CreateNativeHandle(const C2Fence& fence) {
     return fence.mImpl? fence.mImpl->createNativeHandle() : nullptr;
 }
diff --git a/media/codec2/vndk/include/C2FenceFactory.h b/media/codec2/vndk/include/C2FenceFactory.h
index 4944115..ef25c47 100644
--- a/media/codec2/vndk/include/C2FenceFactory.h
+++ b/media/codec2/vndk/include/C2FenceFactory.h
@@ -20,6 +20,16 @@
 
 #include <C2Buffer.h>
 
+/*
+ * Create a list of fds from fence
+ *
+ * \param fence   C2Fence object from which associated
+ *                file descriptors need to be extracted
+ * \return a vector of fds otherwise return vector of size 0
+ */
+
+std::vector<int> ExtractFdsFromCodec2SyncFence(const C2Fence& fence);
+
 class C2SurfaceSyncMemory;
 
 /**
@@ -48,6 +58,14 @@
      */
     static C2Fence CreateSyncFence(int fenceFd);
 
+    /*
+     * Create C2Fence from list of fence file fds.
+     *
+     * \param fenceFds          Vector of file descriptor for fence.
+     *                          It will be owned and closed by the returned fence object.
+     */
+    static C2Fence CreateMultipleFdSyncFence(const std::vector<int>& fenceFds);
+
     /**
      * Create a native handle from fence for marshalling
      *
diff --git a/media/libaudiohal/impl/StreamHalHidl.cpp b/media/libaudiohal/impl/StreamHalHidl.cpp
index 2b0af49..82062cc 100644
--- a/media/libaudiohal/impl/StreamHalHidl.cpp
+++ b/media/libaudiohal/impl/StreamHalHidl.cpp
@@ -979,9 +979,10 @@
 }
 
 status_t StreamOutHalHidl::exit() {
-    // Signal exiting to remote_submix HAL.
+    // Signal exiting to HALs that use intermediate pipes to close them.
     AudioParameter param;
     param.addInt(String8(AudioParameter::keyExiting), 1);
+    param.add(String8(AudioParameter::keyClosing), String8(AudioParameter::valueTrue));
     return setParameters(param.toString());
 }
 
diff --git a/media/libeffects/lvm/lib/Bundle/src/LVM_Process.cpp b/media/libeffects/lvm/lib/Bundle/src/LVM_Process.cpp
index 4eea04f..bfc5059 100644
--- a/media/libeffects/lvm/lib/Bundle/src/LVM_Process.cpp
+++ b/media/libeffects/lvm/lib/Bundle/src/LVM_Process.cpp
@@ -166,9 +166,9 @@
              * Bypass mode or everything off, so copy the input to the output
              */
             if (pToProcess != pProcessed) {
-                Copy_Float(pToProcess,                          /* Source */
-                           pProcessed,                          /* Destination */
-                           (LVM_INT16)(NrChannels * NrFrames)); /* Copy all samples */
+                Copy_Float(pToProcess,   /* Source */
+                           pProcessed,   /* Destination */
+                           SampleCount); /* Copy all samples */
             }
 
             /*
diff --git a/media/libmediahelper/include/media/AudioParameter.h b/media/libmediahelper/include/media/AudioParameter.h
index 8568b8f..3eee854 100644
--- a/media/libmediahelper/include/media/AudioParameter.h
+++ b/media/libmediahelper/include/media/AudioParameter.h
@@ -51,8 +51,7 @@
     static const char * const keyScreenState;
     static const char * const keyScreenRotation;
 
-    // TODO(b/73175392) consider improvement to AIDL StreamOut interface.
-    // keyClosing: "true" when AudioOutputDescriptor is closing.  Used by A2DP HAL.
+    // keyClosing: "true" on AudioFlinger Thread preExit.  Used by A2DP HAL.
     // keyExiting: "1" on AudioFlinger Thread preExit.  Used by remote_submix and A2DP HAL.
     static const char * const keyClosing;
     static const char * const keyExiting;
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index fdcf246..e5f9789 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -388,7 +388,9 @@
                         mediaType.equalsIgnoreCase(MIMETYPE_VIDEO_VP9)
                             ? asString_VP9Profile(pl.mProfile) :
                         mediaType.equalsIgnoreCase(MIMETYPE_VIDEO_AV1)
-                            ? asString_AV1Profile(pl.mProfile) : "??";
+                            ? asString_AV1Profile(pl.mProfile) :
+                        mediaType.equalsIgnoreCase(MIMETYPE_VIDEO_DOLBY_VISION)
+                            ? asString_DolbyVisionProfile(pl.mProfile) : "??";
                     const char *niceLevel =
                         mediaType.equalsIgnoreCase(MIMETYPE_VIDEO_MPEG2)
                             ? asString_MPEG2Level(pl.mLevel) :
@@ -405,7 +407,9 @@
                         mediaType.equalsIgnoreCase(MIMETYPE_VIDEO_VP9)
                             ? asString_VP9Level(pl.mLevel) :
                         mediaType.equalsIgnoreCase(MIMETYPE_VIDEO_AV1)
-                            ? asString_AV1Level(pl.mLevel) : "??";
+                            ? asString_AV1Level(pl.mLevel) :
+                        mediaType.equalsIgnoreCase(MIMETYPE_VIDEO_DOLBY_VISION)
+                            ? asString_DolbyVisionLevel(pl.mLevel) : "??";
 
                     list.add(AStringPrintf("% 5u/% 5u (%s/%s)",
                             pl.mProfile, pl.mLevel, niceProfile, niceLevel));
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
index be13340..329e0ca 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
@@ -674,12 +674,6 @@
             }
         }
 
-        // TODO(b/73175392) consider improving the AIDL interface.
-        // Signal closing to A2DP HAL.
-        AudioParameter param;
-        param.add(String8(AudioParameter::keyClosing), String8("true"));
-        mClientInterface->setParameters(mIoHandle, param.toString());
-
         mClientInterface->closeOutput(mIoHandle);
 
         LOG_ALWAYS_FATAL_IF(mProfile->curOpenCount < 1, "%s profile open count %u",
diff --git a/services/audiopolicy/engine/common/src/ProductStrategy.cpp b/services/audiopolicy/engine/common/src/ProductStrategy.cpp
index 1d3ad1c..0d25955 100644
--- a/services/audiopolicy/engine/common/src/ProductStrategy.cpp
+++ b/services/audiopolicy/engine/common/src/ProductStrategy.cpp
@@ -155,7 +155,7 @@
             return iter.second->getId();
         }
         if (score > matchScore) {
-            bestStrategyOrdefault = iter.second->getId();;
+            bestStrategyOrdefault = iter.second->getId();
             matchScore = score;
         }
     }