Add source and destination fd in TranscodingRequest.

Bug: 177463767
Test: Unite test
Change-Id: I38c134dc71287255bc19e68ff668c908309e8c80
diff --git a/media/libmediatranscoding/TranscoderWrapper.cpp b/media/libmediatranscoding/TranscoderWrapper.cpp
index da86187..8410850 100644
--- a/media/libmediatranscoding/TranscoderWrapper.cpp
+++ b/media/libmediatranscoding/TranscoderWrapper.cpp
@@ -202,9 +202,8 @@
 void TranscoderWrapper::start(ClientIdType clientId, SessionIdType sessionId,
                               const TranscodingRequestParcel& request,
                               const std::shared_ptr<ITranscodingClientCallback>& clientCb) {
-    queueEvent(Event::Start, clientId, sessionId, [=] {
+    queueEvent(Event::Start, clientId, sessionId, [=, &request] {
         media_status_t err = handleStart(clientId, sessionId, request, clientCb);
-
         if (err != AMEDIA_OK) {
             cleanup();
             reportError(clientId, sessionId, err);
@@ -237,9 +236,8 @@
 void TranscoderWrapper::resume(ClientIdType clientId, SessionIdType sessionId,
                                const TranscodingRequestParcel& request,
                                const std::shared_ptr<ITranscodingClientCallback>& clientCb) {
-    queueEvent(Event::Resume, clientId, sessionId, [=] {
+    queueEvent(Event::Resume, clientId, sessionId, [=, &request] {
         media_status_t err = handleResume(clientId, sessionId, request, clientCb);
-
         if (err != AMEDIA_OK) {
             cleanup();
             reportError(clientId, sessionId, err);
@@ -329,19 +327,27 @@
 
     Status status;
     ::ndk::ScopedFileDescriptor srcFd, dstFd;
-    status = clientCb->openFileDescriptor(request.sourceFilePath, "r", &srcFd);
-    if (!status.isOk() || srcFd.get() < 0) {
-        ALOGE("failed to open source");
-        return AMEDIA_ERROR_IO;
+    int srcFdInt = request.sourceFd.get();
+    if (srcFdInt < 0) {
+        status = clientCb->openFileDescriptor(request.sourceFilePath, "r", &srcFd);
+        if (!status.isOk() || srcFd.get() < 0) {
+            ALOGE("failed to open source");
+            return AMEDIA_ERROR_IO;
+        }
+        srcFdInt = srcFd.get();
     }
 
-    // Open dest file with "rw", as the transcoder could potentially reuse part of it
-    // for resume case. We might want the further differentiate and open with "w" only
-    // for start.
-    status = clientCb->openFileDescriptor(request.destinationFilePath, "rw", &dstFd);
-    if (!status.isOk() || dstFd.get() < 0) {
-        ALOGE("failed to open destination");
-        return AMEDIA_ERROR_IO;
+    int dstFdInt = request.destinationFd.get();
+    if (dstFdInt < 0) {
+        // Open dest file with "rw", as the transcoder could potentially reuse part of it
+        // for resume case. We might want the further differentiate and open with "w" only
+        // for start.
+        status = clientCb->openFileDescriptor(request.destinationFilePath, "rw", &dstFd);
+        if (!status.isOk() || dstFd.get() < 0) {
+            ALOGE("failed to open destination");
+            return AMEDIA_ERROR_IO;
+        }
+        dstFdInt = dstFd.get();
     }
 
     mCurrentClientId = clientId;
@@ -354,7 +360,7 @@
         return AMEDIA_ERROR_UNKNOWN;
     }
 
-    media_status_t err = mTranscoder->configureSource(srcFd.get());
+    media_status_t err = mTranscoder->configureSource(srcFdInt);
     if (err != AMEDIA_OK) {
         ALOGE("failed to configure source: %d", err);
         return err;
@@ -385,7 +391,7 @@
         }
     }
 
-    err = mTranscoder->configureDestination(dstFd.get());
+    err = mTranscoder->configureDestination(dstFdInt);
     if (err != AMEDIA_OK) {
         ALOGE("failed to configure dest: %d", err);
         return err;
diff --git a/media/libmediatranscoding/aidl/android/media/TranscodingRequestParcel.aidl b/media/libmediatranscoding/aidl/android/media/TranscodingRequestParcel.aidl
index 7047073..71f82b8 100644
--- a/media/libmediatranscoding/aidl/android/media/TranscodingRequestParcel.aidl
+++ b/media/libmediatranscoding/aidl/android/media/TranscodingRequestParcel.aidl
@@ -16,6 +16,7 @@
 
 package android.media;
 
+import android.os.ParcelFileDescriptor;
 import android.media.TranscodingSessionPriority;
 import android.media.TranscodingTestConfig;
 import android.media.TranscodingType;
@@ -35,10 +36,10 @@
 
     /*
      * The filedescrptor of the sourceFilePath. If the source Fd is provided, transcoding service
-     * will use this fd instead of calling back to client side to open the sourceFilePath.
-     * -1 means not available.
+     * will use this fd instead of calling back to client side to open the sourceFilePath. It is
+     * client's responsibility to make sure sourceFd is opened from sourceFilePath.
      */
-     int sourceFd = -1;
+    @nullable ParcelFileDescriptor sourceFd;
 
     /**
      * The absolute file path of the destination file.
@@ -47,10 +48,11 @@
 
     /*
      * The filedescrptor of the destinationFilePath. If the destination Fd is provided, transcoding
-     * service will use this fd instead of calling back to client side to open the sourceFilePath.
-     * -1 means not available.
+     * service will use this fd instead of calling back to client side to open the
+     * destinationFilePath. It is client's responsibility to make sure destinationFd is opened
+     * from destinationFilePath.
      */
-     int destinationFd = -1;
+    @nullable ParcelFileDescriptor destinationFd;
 
     /**
      * The UID of the client that this transcoding request is for. Only privileged caller could
diff --git a/media/libmediatranscoding/include/media/TranscodingRequest.h b/media/libmediatranscoding/include/media/TranscodingRequest.h
index e782386..16f4cc0 100644
--- a/media/libmediatranscoding/include/media/TranscodingRequest.h
+++ b/media/libmediatranscoding/include/media/TranscodingRequest.h
@@ -28,6 +28,7 @@
 public:
     TranscodingRequest() = default;
     TranscodingRequest(const TranscodingRequestParcel& parcel) { setTo(parcel); }
+    TranscodingRequest(const TranscodingRequest& request) { setTo(request); }
     TranscodingRequest& operator=(const TranscodingRequest& request) {
         setTo(request);
         return *this;
@@ -36,9 +37,9 @@
 private:
     void setTo(const TranscodingRequestParcel& parcel) {
         sourceFilePath = parcel.sourceFilePath;
-        sourceFd = parcel.sourceFd;
+        sourceFd = ndk::ScopedFileDescriptor(dup(parcel.sourceFd.get()));
         destinationFilePath = parcel.destinationFilePath;
-        destinationFd = parcel.destinationFd;
+        destinationFd = ndk::ScopedFileDescriptor(dup(parcel.destinationFd.get()));
         clientUid = parcel.clientUid;
         clientPid = parcel.clientPid;
         clientPackageName = parcel.clientPackageName;