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;
+ }
}
};