Transcoder: Pass transcoding request parcel by value.

Fixes a HWASAN crash in CtsMediaTranscodingTestCases where
TranscoderWrapper reads the incoming request parcel asynchronously
without taking ownership of the memory.

Fixes: 183222648
Test: atest CtsMediaTranscodingTestCases:MediaTranscodeManagerTest
Change-Id: I27a667c1dfa46572f35a13af08fa9722eafaedbb
diff --git a/media/libmediatranscoding/TranscoderWrapper.cpp b/media/libmediatranscoding/TranscoderWrapper.cpp
index d9c98c6..a063565 100644
--- a/media/libmediatranscoding/TranscoderWrapper.cpp
+++ b/media/libmediatranscoding/TranscoderWrapper.cpp
@@ -22,6 +22,7 @@
 #include <media/MediaTranscoder.h>
 #include <media/NdkCommon.h>
 #include <media/TranscoderWrapper.h>
+#include <media/TranscodingRequest.h>
 #include <utils/Log.h>
 
 #include <thread>
@@ -221,9 +222,10 @@
 }
 
 void TranscoderWrapper::start(ClientIdType clientId, SessionIdType sessionId,
-                              const TranscodingRequestParcel& request, uid_t callingUid,
+                              const TranscodingRequestParcel& requestParcel, uid_t callingUid,
                               const std::shared_ptr<ITranscodingClientCallback>& clientCb) {
-    queueEvent(Event::Start, clientId, sessionId, [=, &request] {
+    TranscodingRequest request{requestParcel};
+    queueEvent(Event::Start, clientId, sessionId, [=] {
         media_status_t err = handleStart(clientId, sessionId, request, callingUid, clientCb);
         if (err != AMEDIA_OK) {
             cleanup();
@@ -255,9 +257,10 @@
 }
 
 void TranscoderWrapper::resume(ClientIdType clientId, SessionIdType sessionId,
-                               const TranscodingRequestParcel& request, uid_t callingUid,
+                               const TranscodingRequestParcel& requestParcel, uid_t callingUid,
                                const std::shared_ptr<ITranscodingClientCallback>& clientCb) {
-    queueEvent(Event::Resume, clientId, sessionId, [=, &request] {
+    TranscodingRequest request{requestParcel};
+    queueEvent(Event::Resume, clientId, sessionId, [=] {
         media_status_t err = handleResume(clientId, sessionId, request, callingUid, clientCb);
         if (err != AMEDIA_OK) {
             cleanup();
diff --git a/media/libmediatranscoding/include/media/TranscodingRequest.h b/media/libmediatranscoding/include/media/TranscodingRequest.h
index 16f4cc0..d38fc59 100644
--- a/media/libmediatranscoding/include/media/TranscodingRequest.h
+++ b/media/libmediatranscoding/include/media/TranscodingRequest.h
@@ -18,11 +18,15 @@
 #define ANDROID_MEDIA_TRANSCODING_REQUEST_H
 
 #include <aidl/android/media/TranscodingRequestParcel.h>
+#include <android/binder_parcel.h>
 
 namespace android {
 
 using ::aidl::android::media::TranscodingRequestParcel;
 
+// TODO: replace __ANDROID_API_FUTURE__with 31 when it's official (b/178144708)
+#define __TRANSCODING_MIN_API__ __ANDROID_API_FUTURE__
+
 // Helper class for duplicating a TranscodingRequestParcel
 class TranscodingRequest : public TranscodingRequestParcel {
 public:
@@ -36,20 +40,28 @@
 
 private:
     void setTo(const TranscodingRequestParcel& parcel) {
-        sourceFilePath = parcel.sourceFilePath;
-        sourceFd = ndk::ScopedFileDescriptor(dup(parcel.sourceFd.get()));
-        destinationFilePath = parcel.destinationFilePath;
-        destinationFd = ndk::ScopedFileDescriptor(dup(parcel.destinationFd.get()));
-        clientUid = parcel.clientUid;
-        clientPid = parcel.clientPid;
-        clientPackageName = parcel.clientPackageName;
-        transcodingType = parcel.transcodingType;
-        requestedVideoTrackFormat = parcel.requestedVideoTrackFormat;
-        priority = parcel.priority;
-        requestProgressUpdate = parcel.requestProgressUpdate;
-        requestSessionEventUpdate = parcel.requestSessionEventUpdate;
-        isForTesting = parcel.isForTesting;
-        testConfig = parcel.testConfig;
+        if (__builtin_available(android __TRANSCODING_MIN_API__, *)) {
+            AParcel* p = AParcel_create();
+            parcel.writeToParcel(p);
+            AParcel_setDataPosition(p, 0);
+            readFromParcel(p);
+            AParcel_delete(p);
+        } else {
+            sourceFilePath = parcel.sourceFilePath;
+            sourceFd = ndk::ScopedFileDescriptor(dup(parcel.sourceFd.get()));
+            destinationFilePath = parcel.destinationFilePath;
+            destinationFd = ndk::ScopedFileDescriptor(dup(parcel.destinationFd.get()));
+            clientUid = parcel.clientUid;
+            clientPid = parcel.clientPid;
+            clientPackageName = parcel.clientPackageName;
+            transcodingType = parcel.transcodingType;
+            requestedVideoTrackFormat = parcel.requestedVideoTrackFormat;
+            priority = parcel.priority;
+            requestProgressUpdate = parcel.requestProgressUpdate;
+            requestSessionEventUpdate = parcel.requestSessionEventUpdate;
+            isForTesting = parcel.isForTesting;
+            testConfig = parcel.testConfig;
+        }
     }
 };