Modify ACodec to allow using Treble.

ACodec will connect to the Treble version of Omx if the property
"debug.treble_omx" is set to true ("1", "y", "yes", "true" or "on").

Also, fix some bugs found so far.

Test: Compiles
Bug: 31399200
Change-Id: I52b27b5f99bc1d6797d3b83b8be794ed2de9956a
diff --git a/media/libmedia/OMXBuffer.cpp b/media/libmedia/OMXBuffer.cpp
index c8995c9..71d2908 100644
--- a/media/libmedia/OMXBuffer.cpp
+++ b/media/libmedia/OMXBuffer.cpp
@@ -166,7 +166,7 @@
     mMem = std::move(source.mMem);
     mGraphicBuffer = std::move(source.mGraphicBuffer);
     mNativeHandle = std::move(source.mNativeHandle);
-    mHidlMemory = source.mHidlMemory; // TODO(b/34093434): Use move when available
+    mHidlMemory = std::move(source.mHidlMemory);
     return *this;
 }
 
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index c63ab47..3235e81 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -46,6 +46,8 @@
 #include <media/hardware/HardwareAPI.h>
 #include <media/OMXBuffer.h>
 
+#include <hidlmemory/mapping.h>
+
 #include <OMX_AudioExt.h>
 #include <OMX_VideoExt.h>
 #include <OMX_Component.h>
@@ -59,6 +61,10 @@
 #include "include/SharedMemoryBuffer.h"
 #include "omx/OMXUtils.h"
 
+#include <android/hidl/memory/1.0/IAllocator.h>
+#include <android/hidl/memory/1.0/IMemory.h>
+#include "omx/hal/1.0/utils/WOmxNode.h"
+
 namespace android {
 
 using binder::Status;
@@ -282,7 +288,9 @@
 
 ////////////////////////////////////////////////////////////////////////////////
 
-struct ACodec::DeathNotifier : public IBinder::DeathRecipient {
+struct ACodec::DeathNotifier :
+        public IBinder::DeathRecipient,
+        public ::android::hardware::hidl_death_recipient {
     explicit DeathNotifier(const sp<AMessage> &notify)
         : mNotify(notify) {
     }
@@ -291,6 +299,12 @@
         mNotify->post();
     }
 
+    virtual void serviceDied(
+            uint64_t /* cookie */,
+            const wp<::android::hidl::base::V1_0::IBase>& /* who */) {
+        mNotify->post();
+    }
+
 protected:
     virtual ~DeathNotifier() {}
 
@@ -560,6 +574,8 @@
     memset(&mLastNativeWindowCrop, 0, sizeof(mLastNativeWindowCrop));
 
     changeState(mUninitializedState);
+
+    updateTrebleFlag();
 }
 
 ACodec::~ACodec() {
@@ -811,7 +827,11 @@
 status_t ACodec::allocateBuffersOnPort(OMX_U32 portIndex) {
     CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
 
-    CHECK(mDealer[portIndex] == NULL);
+    if (getTrebleFlag()) {
+        CHECK(mAllocator[portIndex] == NULL);
+    } else {
+        CHECK(mDealer[portIndex] == NULL);
+    }
     CHECK(mBuffers[portIndex].isEmpty());
 
     status_t err;
@@ -874,14 +894,26 @@
                 return NO_MEMORY;
             }
 
-            size_t totalSize = def.nBufferCountActual * (alignedSize + alignedConvSize);
             if (mode != IOMX::kPortModePresetSecureBuffer) {
-                mDealer[portIndex] = new MemoryDealer(totalSize, "ACodec");
+                if (getTrebleFlag()) {
+                    mAllocator[portIndex] = TAllocator::getService("ashmem");
+                    if (mAllocator[portIndex] == nullptr) {
+                        ALOGE("hidl allocator on port %d is null",
+                                (int)portIndex);
+                        return NO_MEMORY;
+                    }
+                } else {
+                    size_t totalSize = def.nBufferCountActual *
+                            (alignedSize + alignedConvSize);
+                    mDealer[portIndex] = new MemoryDealer(totalSize, "ACodec");
+                }
             }
 
             const sp<AMessage> &format =
                     portIndex == kPortIndexInput ? mInputFormat : mOutputFormat;
             for (OMX_U32 i = 0; i < def.nBufferCountActual && err == OK; ++i) {
+                hidl_memory hidlMemToken;
+                sp<TMemory> hidlMem;
                 sp<IMemory> mem;
 
                 BufferInfo info;
@@ -903,30 +935,86 @@
                             : new SecureBuffer(format, native_handle, bufSize);
                     info.mCodecData = info.mData;
                 } else {
-                    mem = mDealer[portIndex]->allocate(bufSize);
-                    if (mem == NULL || mem->pointer() == NULL) {
-                        return NO_MEMORY;
-                    }
+                    if (getTrebleFlag()) {
+                        bool success;
+                        auto transStatus = mAllocator[portIndex]->allocate(
+                                bufSize,
+                                [&success, &hidlMemToken](
+                                        bool s,
+                                        hidl_memory const& m) {
+                                    success = s;
+                                    hidlMemToken = m;
+                                });
 
-                    err = mOMXNode->useBuffer(portIndex, mem, &info.mBufferID);
+                        if (!transStatus.isOk()) {
+                            ALOGE("hidl's AshmemAllocator failed at the "
+                                    "transport: %s",
+                                    transStatus.description().c_str());
+                            return NO_MEMORY;
+                        }
+                        if (!success) {
+                            return NO_MEMORY;
+                        }
+                        hidlMem = mapMemory(hidlMemToken);
+
+                        err = mOMXNode->useBuffer(
+                                portIndex, hidlMemToken, &info.mBufferID);
+                    } else {
+                        mem = mDealer[portIndex]->allocate(bufSize);
+                        if (mem == NULL || mem->pointer() == NULL) {
+                            return NO_MEMORY;
+                        }
+
+                        err = mOMXNode->useBuffer(
+                                portIndex, mem, &info.mBufferID);
+                    }
 
                     if (mode == IOMX::kPortModeDynamicANWBuffer) {
-                        ((VideoNativeMetadata *)mem->pointer())->nFenceFd = -1;
+                        VideoNativeMetadata* metaData = (VideoNativeMetadata*)(
+                                getTrebleFlag() ?
+                                (void*)hidlMem->getPointer() : mem->pointer());
+                        metaData->nFenceFd = -1;
                     }
 
-                    info.mCodecData = new SharedMemoryBuffer(format, mem);
-                    info.mCodecRef = mem;
+                    if (getTrebleFlag()) {
+                        info.mCodecData = new SharedMemoryBuffer(
+                                format, hidlMem);
+                        info.mCodecRef = hidlMem;
+                    } else {
+                        info.mCodecData = new SharedMemoryBuffer(
+                                format, mem);
+                        info.mCodecRef = mem;
+                    }
 
                     // if we require conversion, allocate conversion buffer for client use;
                     // otherwise, reuse codec buffer
                     if (mConverter[portIndex] != NULL) {
                         CHECK_GT(conversionBufferSize, (size_t)0);
-                        mem = mDealer[portIndex]->allocate(conversionBufferSize);
-                        if (mem == NULL|| mem->pointer() == NULL) {
-                            return NO_MEMORY;
+                        if (getTrebleFlag()) {
+                            bool success;
+                            mAllocator[portIndex]->allocate(
+                                    conversionBufferSize,
+                                    [&success, &hidlMemToken](
+                                            bool s,
+                                            hidl_memory const& m) {
+                                        success = s;
+                                        hidlMemToken = m;
+                                    });
+                            if (!success) {
+                                return NO_MEMORY;
+                            }
+                            hidlMem = mapMemory(hidlMemToken);
+                            info.mData = new SharedMemoryBuffer(format, hidlMem);
+                            info.mMemRef = hidlMem;
+                        } else {
+                            mem = mDealer[portIndex]->allocate(
+                                    conversionBufferSize);
+                            if (mem == NULL|| mem->pointer() == NULL) {
+                                return NO_MEMORY;
+                            }
+                            info.mData = new SharedMemoryBuffer(format, mem);
+                            info.mMemRef = mem;
                         }
-                        info.mData = new SharedMemoryBuffer(format, mem);
-                        info.mMemRef = mem;
                     } else {
                         info.mData = info.mCodecData;
                         info.mMemRef = info.mCodecRef;
@@ -1458,8 +1546,11 @@
         }
     }
 
-    // clear mDealer even on an error
-    mDealer[portIndex].clear();
+    if (getTrebleFlag()) {
+        mAllocator[portIndex].clear();
+    } else {
+        mDealer[portIndex].clear();
+    }
     return err;
 }
 
@@ -6041,8 +6132,16 @@
 
     if (mDeathNotifier != NULL) {
         if (mCodec->mOMXNode != NULL) {
-            sp<IBinder> binder = IInterface::asBinder(mCodec->mOMXNode);
-            binder->unlinkToDeath(mDeathNotifier);
+            if (mCodec->getTrebleFlag()) {
+                auto tOmxNode =
+                        (static_cast<
+                        ::android::hardware::media::omx::V1_0::utils::
+                        LWOmxNode*>(mCodec->mOMXNode.get()))->mBase;
+                tOmxNode->unlinkToDeath(mDeathNotifier);
+            } else {
+                sp<IBinder> binder = IInterface::asBinder(mCodec->mOMXNode);
+                binder->unlinkToDeath(mDeathNotifier);
+            }
         }
         mDeathNotifier.clear();
     }
@@ -6130,7 +6229,8 @@
     CHECK(mCodec->mOMXNode == NULL);
 
     OMXClient client;
-    if (client.connect() != OK) {
+    if ((mCodec->updateTrebleFlag() ?
+            client.connectTreble() : client.connect()) != OK) {
         mCodec->signalError(OMX_ErrorUndefined, NO_INIT);
         return false;
     }
@@ -6202,10 +6302,18 @@
     }
 
     mDeathNotifier = new DeathNotifier(notify);
-    if (IInterface::asBinder(omxNode)->linkToDeath(mDeathNotifier) != OK) {
-        // This was a local binder, if it dies so do we, we won't care
-        // about any notifications in the afterlife.
-        mDeathNotifier.clear();
+    if (mCodec->getTrebleFlag()) {
+        auto tOmxNode = (static_cast<::android::hardware::media::omx::V1_0::
+                utils::LWOmxNode*>(omxNode.get()))->mBase;
+        if (!tOmxNode->linkToDeath(mDeathNotifier, 0)) {
+            mDeathNotifier.clear();
+        }
+    } else {
+        if (IInterface::asBinder(omxNode)->linkToDeath(mDeathNotifier) != OK) {
+            // This was a local binder, if it dies so do we, we won't care
+            // about any notifications in the afterlife.
+            mDeathNotifier.clear();
+        }
     }
 
     notify = new AMessage(kWhatOMXMessageList, mCodec);
@@ -7181,7 +7289,11 @@
                             mCodec->mBuffers[kPortIndexOutput].size());
                     err = FAILED_TRANSACTION;
                 } else {
-                    mCodec->mDealer[kPortIndexOutput].clear();
+                    if (mCodec->getTrebleFlag()) {
+                        mCodec->mAllocator[kPortIndexOutput].clear();
+                    } else {
+                        mCodec->mDealer[kPortIndexOutput].clear();
+                    }
                 }
 
                 if (err == OK) {
@@ -7564,7 +7676,8 @@
     }
 
     OMXClient client;
-    status_t err = client.connect();
+    status_t err = getTrebleFlag() ?
+            client.connectTreble() : client.connect();
     if (err != OK) {
         return err;
     }
@@ -7780,4 +7893,15 @@
     return OK;
 }
 
+bool ACodec::updateTrebleFlag() {
+    mTrebleFlag = bool(property_get_bool("debug.treble_omx", 0));
+    ALOGV("updateTrebleFlag() returns %s",
+            mTrebleFlag ? "true" : "false");
+    return mTrebleFlag;
+}
+
+bool ACodec::getTrebleFlag() const {
+    return mTrebleFlag;
+}
+
 }  // namespace android
diff --git a/media/libstagefright/Android.mk b/media/libstagefright/Android.mk
index d8f5106..410dbc9 100644
--- a/media/libstagefright/Android.mk
+++ b/media/libstagefright/Android.mk
@@ -114,6 +114,8 @@
         libdl \
         libRScpp \
         libhidlbase \
+        libhidlmemory \
+        android.hidl.memory@1.0 \
         android.hardware.media.omx@1.0 \
         android.hardware.media.omx@1.0-utils \
 
diff --git a/media/libstagefright/BufferImpl.cpp b/media/libstagefright/BufferImpl.cpp
index 40eb942..fee3739 100644
--- a/media/libstagefright/BufferImpl.cpp
+++ b/media/libstagefright/BufferImpl.cpp
@@ -34,6 +34,11 @@
       mMemory(mem) {
 }
 
+SharedMemoryBuffer::SharedMemoryBuffer(const sp<AMessage> &format, const sp<TMemory> &mem)
+    : MediaCodecBuffer(format, new ABuffer(mem->getPointer(), mem->getSize())),
+      mTMemory(mem) {
+}
+
 SecureBuffer::SecureBuffer(const sp<AMessage> &format, const void *ptr, size_t size)
     : MediaCodecBuffer(format, new ABuffer(nullptr, size)),
       mPointer(ptr) {
diff --git a/media/libstagefright/filters/Android.mk b/media/libstagefright/filters/Android.mk
index f8e8352..830d2aa 100644
--- a/media/libstagefright/filters/Android.mk
+++ b/media/libstagefright/filters/Android.mk
@@ -22,7 +22,9 @@
 
 LOCAL_CFLAGS += -Wno-multichar -Werror -Wall
 
-LOCAL_SHARED_LIBRARIES := libmedia
+LOCAL_SHARED_LIBRARIES := \
+        libmedia \
+        libhidlmemory \
 
 LOCAL_MODULE:= libstagefright_mediafilter
 
diff --git a/media/libstagefright/include/SharedMemoryBuffer.h b/media/libstagefright/include/SharedMemoryBuffer.h
index 1d7f7a6..92df68a 100644
--- a/media/libstagefright/include/SharedMemoryBuffer.h
+++ b/media/libstagefright/include/SharedMemoryBuffer.h
@@ -19,6 +19,7 @@
 #define SHARED_MEMORY_BUFFER_H_
 
 #include <media/MediaCodecBuffer.h>
+#include <android/hidl/memory/1.0/IMemory.h>
 
 namespace android {
 
@@ -30,7 +31,9 @@
  */
 class SharedMemoryBuffer : public MediaCodecBuffer {
 public:
+    typedef ::android::hidl::memory::V1_0::IMemory TMemory;
     SharedMemoryBuffer(const sp<AMessage> &format, const sp<IMemory> &mem);
+    SharedMemoryBuffer(const sp<AMessage> &format, const sp<TMemory> &mem);
 
     virtual ~SharedMemoryBuffer() = default;
 
@@ -38,6 +41,7 @@
     SharedMemoryBuffer() = delete;
 
     const sp<IMemory> mMemory;
+    const sp<TMemory> mTMemory;
 };
 
 }  // namespace android
diff --git a/media/libstagefright/omx/OMXNodeInstance.cpp b/media/libstagefright/omx/OMXNodeInstance.cpp
index 03aaa71..39ed759 100644
--- a/media/libstagefright/omx/OMXNodeInstance.cpp
+++ b/media/libstagefright/omx/OMXNodeInstance.cpp
@@ -1133,7 +1133,7 @@
             buffer_meta = new BufferMeta(
                     params, hParams, portIndex, false /* copy */, data);
         } else {
-            data = static_cast<OMX_U8 *>(params->pointer());
+            data = static_cast<OMX_U8 *>(paramsPointer);
 
             buffer_meta = new BufferMeta(
                     params, hParams, portIndex, false /* copy */, NULL);
diff --git a/media/libstagefright/omx/hal/1.0/impl/Conversion.h b/media/libstagefright/omx/hal/1.0/impl/Conversion.h
index 9cfb4f2..d27a496 100644
--- a/media/libstagefright/omx/hal/1.0/impl/Conversion.h
+++ b/media/libstagefright/omx/hal/1.0/impl/Conversion.h
@@ -298,6 +298,7 @@
     switch (l.type) {
         case omx_message::EVENT:
             t->type = Message::Type::EVENT;
+            t->data.eventData.event = uint32_t(l.u.event_data.event);
             t->data.eventData.data1 = l.u.event_data.data1;
             t->data.eventData.data2 = l.u.event_data.data2;
             t->data.eventData.data3 = l.u.event_data.data3;
@@ -343,6 +344,7 @@
     switch (t.type) {
         case Message::Type::EVENT:
             l->type = omx_message::EVENT;
+            l->u.event_data.event = OMX_EVENTTYPE(t.data.eventData.event);
             l->u.event_data.data1 = t.data.eventData.data1;
             l->u.event_data.data2 = t.data.eventData.data2;
             l->u.event_data.data3 = t.data.eventData.data3;
diff --git a/media/libstagefright/omx/hal/1.0/impl/WOmxNode.cpp b/media/libstagefright/omx/hal/1.0/impl/WOmxNode.cpp
index df3ef78..6b21138 100644
--- a/media/libstagefright/omx/hal/1.0/impl/WOmxNode.cpp
+++ b/media/libstagefright/omx/hal/1.0/impl/WOmxNode.cpp
@@ -196,6 +196,7 @@
     }
     status_t status = toStatusT(mBase->fillBuffer(
             buffer, codecBuffer, fenceNh));
+    native_handle_close(fenceNh);
     native_handle_delete(fenceNh);
     return status;
 }
@@ -217,6 +218,7 @@
             flags,
             toRawTicks(timestamp),
             fenceNh));
+    native_handle_close(fenceNh);
     native_handle_delete(fenceNh);
     return status;
 }
@@ -240,6 +242,7 @@
         return NO_MEMORY;
     }
     status_t status = toStatusT(mBase->dispatchMessage(tMsg));
+    native_handle_close(nh);
     native_handle_delete(nh);
     return status;
 }
@@ -392,7 +395,7 @@
     return toStatus(mBase->fillBuffer(
             buffer,
             omxBuffer,
-            native_handle_read_fd(fence)));
+            dup(native_handle_read_fd(fence))));
 }
 
 Return<Status> TWOmxNode::emptyBuffer(
@@ -407,7 +410,7 @@
             omxBuffer,
             flags,
             toOMXTicks(timestampUs),
-            native_handle_read_fd(fence)));
+            dup(native_handle_read_fd(fence))));
 }
 
 Return<void> TWOmxNode::getExtensionIndex(
@@ -422,7 +425,7 @@
 
 Return<Status> TWOmxNode::dispatchMessage(const Message& tMsg) {
     omx_message lMsg;
-    if (!wrapAs(&lMsg, tMsg)) {
+    if (!convertTo(&lMsg, tMsg)) {
         return Status::BAD_VALUE;
     }
     return toStatus(mBase->dispatchMessage(lMsg));
diff --git a/media/libstagefright/omx/hal/1.0/impl/WOmxObserver.cpp b/media/libstagefright/omx/hal/1.0/impl/WOmxObserver.cpp
index 87e7961..d5549fb 100644
--- a/media/libstagefright/omx/hal/1.0/impl/WOmxObserver.cpp
+++ b/media/libstagefright/omx/hal/1.0/impl/WOmxObserver.cpp
@@ -45,6 +45,7 @@
     }
     mBase->onMessages(tMessages);
     for (auto& handle : handles) {
+        native_handle_close(handle);
         native_handle_delete(handle);
     }
 }
@@ -61,7 +62,7 @@
     std::list<omx_message> lMessages;
     for (size_t i = 0; i < tMessages.size(); ++i) {
         lMessages.push_back(omx_message{});
-        wrapAs(&lMessages.back(), tMessages[i]);
+        convertTo(&lMessages.back(), tMessages[i]);
     }
     mBase->onMessages(lMessages);
     return Return<void>();
diff --git a/media/libstagefright/omx/hal/1.0/utils/Conversion.h b/media/libstagefright/omx/hal/1.0/utils/Conversion.h
index 6a99d8c..6f4d864 100644
--- a/media/libstagefright/omx/hal/1.0/utils/Conversion.h
+++ b/media/libstagefright/omx/hal/1.0/utils/Conversion.h
@@ -298,6 +298,7 @@
     switch (l.type) {
         case omx_message::EVENT:
             t->type = Message::Type::EVENT;
+            t->data.eventData.event = uint32_t(l.u.event_data.event);
             t->data.eventData.data1 = l.u.event_data.data1;
             t->data.eventData.data2 = l.u.event_data.data2;
             t->data.eventData.data3 = l.u.event_data.data3;
@@ -343,6 +344,7 @@
     switch (t.type) {
         case Message::Type::EVENT:
             l->type = omx_message::EVENT;
+            l->u.event_data.event = OMX_EVENTTYPE(t.data.eventData.event);
             l->u.event_data.data1 = t.data.eventData.data1;
             l->u.event_data.data2 = t.data.eventData.data2;
             l->u.event_data.data3 = t.data.eventData.data3;
diff --git a/media/libstagefright/omx/hal/1.0/utils/WOmxNode.cpp b/media/libstagefright/omx/hal/1.0/utils/WOmxNode.cpp
index dc04b67..6764ba8 100644
--- a/media/libstagefright/omx/hal/1.0/utils/WOmxNode.cpp
+++ b/media/libstagefright/omx/hal/1.0/utils/WOmxNode.cpp
@@ -196,6 +196,7 @@
     }
     status_t status = toStatusT(mBase->fillBuffer(
             buffer, codecBuffer, fenceNh));
+    native_handle_close(fenceNh);
     native_handle_delete(fenceNh);
     return status;
 }
@@ -217,6 +218,7 @@
             flags,
             toRawTicks(timestamp),
             fenceNh));
+    native_handle_close(fenceNh);
     native_handle_delete(fenceNh);
     return status;
 }
@@ -240,6 +242,7 @@
         return NO_MEMORY;
     }
     status_t status = toStatusT(mBase->dispatchMessage(tMsg));
+    native_handle_close(nh);
     native_handle_delete(nh);
     return status;
 }
@@ -392,7 +395,7 @@
     return toStatus(mBase->fillBuffer(
             buffer,
             omxBuffer,
-            native_handle_read_fd(fence)));
+            dup(native_handle_read_fd(fence))));
 }
 
 Return<Status> TWOmxNode::emptyBuffer(
@@ -407,7 +410,7 @@
             omxBuffer,
             flags,
             toOMXTicks(timestampUs),
-            native_handle_read_fd(fence)));
+            dup(native_handle_read_fd(fence))));
 }
 
 Return<void> TWOmxNode::getExtensionIndex(
@@ -422,7 +425,7 @@
 
 Return<Status> TWOmxNode::dispatchMessage(const Message& tMsg) {
     omx_message lMsg;
-    if (!wrapAs(&lMsg, tMsg)) {
+    if (!convertTo(&lMsg, tMsg)) {
         return Status::BAD_VALUE;
     }
     return toStatus(mBase->dispatchMessage(lMsg));
diff --git a/media/libstagefright/omx/hal/1.0/utils/WOmxObserver.cpp b/media/libstagefright/omx/hal/1.0/utils/WOmxObserver.cpp
index 4773572..fea5a9a 100644
--- a/media/libstagefright/omx/hal/1.0/utils/WOmxObserver.cpp
+++ b/media/libstagefright/omx/hal/1.0/utils/WOmxObserver.cpp
@@ -45,6 +45,7 @@
     }
     mBase->onMessages(tMessages);
     for (auto& handle : handles) {
+        native_handle_close(handle);
         native_handle_delete(handle);
     }
 }
@@ -61,7 +62,7 @@
     std::list<omx_message> lMessages;
     for (size_t i = 0; i < tMessages.size(); ++i) {
         lMessages.push_back(omx_message{});
-        wrapAs(&lMessages.back(), tMessages[i]);
+        convertTo(&lMessages.back(), tMessages[i]);
     }
     mBase->onMessages(lMessages);
     return Return<void>();