Merge "Add VTS tests for wps related APIs in ISupplicantIface" into oc-dev
diff --git a/media/Android.bp b/media/Android.bp
old mode 100644
new mode 100755
index f2abc67..34ecf17
--- a/media/Android.bp
+++ b/media/Android.bp
@@ -2,4 +2,7 @@
 subdirs = [
     "1.0",
     "omx/1.0",
+	"omx/1.0/vts/functional/master",
+	"omx/1.0/vts/functional/component",
+	"omx/1.0/vts/functional/audio",
 ]
diff --git a/media/omx/1.0/vts/functional/audio/Android.bp b/media/omx/1.0/vts/functional/audio/Android.bp
new file mode 100644
index 0000000..d6c73ce
--- /dev/null
+++ b/media/omx/1.0/vts/functional/audio/Android.bp
@@ -0,0 +1,79 @@
+//
+// Copyright (C) 2017 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+cc_test {
+    name: "VtsHalMediaOmxV1_0TargetAudioEncTest",
+    defaults: ["hidl_defaults"],
+    srcs: ["VtsHalMediaOmxV1_0TargetAudioEncTest.cpp",
+           "media_audio_hidl_test_common.cpp"],
+    shared_libs: [
+        "libbase",
+        "liblog",
+        "libcutils",
+        "libhidlbase",
+        "libhidlmemory",
+        "libhidltransport",
+        "libhwbinder",
+        "libnativehelper",
+        "libutils",
+        "libstagefright_foundation",
+        "android.hidl.allocator@1.0",
+        "android.hidl.memory@1.0",
+        "android.hardware.media.omx@1.0",
+    ],
+    static_libs: ["VtsHalHidlTargetTestBase"],
+    cflags: [
+        "-O0",
+        "-g",
+    ],
+    include_dirs: [
+        "frameworks/native/include/media/openmax/",
+        "hardware/interfaces/media/omx/1.0/vts/functional/common",
+    ],
+}
+
+cc_test {
+    name: "VtsHalMediaOmxV1_0TargetAudioDecTest",
+    defaults: ["hidl_defaults"],
+    srcs: ["VtsHalMediaOmxV1_0TargetAudioDecTest.cpp",
+           "media_audio_hidl_test_common.cpp"],
+    shared_libs: [
+        "libbase",
+        "liblog",
+        "libcutils",
+        "libhidlbase",
+        "libhidlmemory",
+        "libhidltransport",
+        "libhwbinder",
+        "libnativehelper",
+        "libutils",
+        "libstagefright_foundation",
+        "android.hidl.allocator@1.0",
+        "android.hidl.memory@1.0",
+        "android.hardware.media.omx@1.0",
+    ],
+    static_libs: ["VtsHalHidlTargetTestBase"],
+    cflags: [
+        "-O0",
+        "-g",
+    ],
+    include_dirs: [
+        "frameworks/native/include/media/openmax/",
+        "hardware/interfaces/media/omx/1.0/vts/functional/common",
+    ],
+}
+
+
diff --git a/media/omx/1.0/vts/functional/audio/VtsHalMediaOmxV1_0TargetAudioDecTest.cpp b/media/omx/1.0/vts/functional/audio/VtsHalMediaOmxV1_0TargetAudioDecTest.cpp
new file mode 100644
index 0000000..7c21753
--- /dev/null
+++ b/media/omx/1.0/vts/functional/audio/VtsHalMediaOmxV1_0TargetAudioDecTest.cpp
@@ -0,0 +1,687 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "media_omx_hidl_audio_dec_test"
+#include <android-base/logging.h>
+
+#include <android/hardware/media/omx/1.0/IOmx.h>
+#include <android/hardware/media/omx/1.0/IOmxNode.h>
+#include <android/hardware/media/omx/1.0/IOmxObserver.h>
+#include <android/hardware/media/omx/1.0/types.h>
+#include <android/hidl/allocator/1.0/IAllocator.h>
+#include <android/hidl/memory/1.0/IMapper.h>
+#include <android/hidl/memory/1.0/IMemory.h>
+
+using ::android::hardware::media::omx::V1_0::IOmx;
+using ::android::hardware::media::omx::V1_0::IOmxObserver;
+using ::android::hardware::media::omx::V1_0::IOmxNode;
+using ::android::hardware::media::omx::V1_0::Message;
+using ::android::hardware::media::omx::V1_0::CodecBuffer;
+using ::android::hidl::allocator::V1_0::IAllocator;
+using ::android::hidl::memory::V1_0::IMemory;
+using ::android::hidl::memory::V1_0::IMapper;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::hidl_string;
+using ::android::sp;
+
+#include <VtsHalHidlTargetTestBase.h>
+#include <getopt.h>
+#include <media_audio_hidl_test_common.h>
+#include <media_hidl_test_common.h>
+#include <fstream>
+
+// A class for test environment setup
+class ComponentTestEnvironment : public ::testing::Environment {
+   public:
+    virtual void SetUp() {}
+    virtual void TearDown() {}
+
+    ComponentTestEnvironment() : instance("default") {}
+
+    void setInstance(const char* _instance) { instance = _instance; }
+
+    void setComponent(const char* _component) { component = _component; }
+
+    void setRole(const char* _role) { role = _role; }
+
+    void setQuirks(int _quirks) { quirks = _quirks; }
+
+    const hidl_string getInstance() const { return instance; }
+
+    const hidl_string getComponent() const { return component; }
+
+    const hidl_string getRole() const { return role; }
+
+    int getQuirks() const { return quirks; }
+
+    int initFromOptions(int argc, char** argv) {
+        static struct option options[] = {
+            {"instance", required_argument, 0, 'I'},
+            {"component", required_argument, 0, 'C'},
+            {"role", required_argument, 0, 'R'},
+            {"quirks", required_argument, 0, 'Q'},
+            {0, 0, 0, 0}};
+
+        while (true) {
+            int index = 0;
+            int c = getopt_long(argc, argv, "I:C:Q:R:", options, &index);
+            if (c == -1) {
+                break;
+            }
+
+            switch (c) {
+                case 'I':
+                    setInstance(optarg);
+                    break;
+                case 'C':
+                    setComponent(optarg);
+                    break;
+                case 'Q':
+                    setQuirks(atoi(optarg));
+                    break;
+                case 'R':
+                    setRole(optarg);
+                    break;
+                case '?':
+                    break;
+            }
+        }
+
+        if (optind < argc) {
+            fprintf(stderr,
+                    "unrecognized option: %s\n\n"
+                    "usage: %s <gtest options> <test options>\n\n"
+                    "test options are:\n\n"
+                    "-I, --instance: HAL instance to test\n"
+                    "-C, --component: OMX component to test\n"
+                    "-R, --Role: OMX component Role\n"
+                    "-Q, --quirks: Component quirks\n",
+                    argv[optind ?: 1], argv[0]);
+            return 2;
+        }
+        return 0;
+    }
+
+   private:
+    hidl_string instance;
+    hidl_string component;
+    hidl_string role;
+    // to be removed when IOmxNode::setQuirks is removed
+    int quirks;
+};
+
+static ComponentTestEnvironment* gEnv = nullptr;
+
+class AudioDecHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+   public:
+    virtual void SetUp() override {
+        android::hardware::media::omx::V1_0::Status status;
+        omx = ::testing::VtsHalHidlTargetTestBase::getService<IOmx>(
+            gEnv->getInstance());
+        ASSERT_NE(omx, nullptr);
+        observer = new CodecObserver();
+        ASSERT_NE(observer, nullptr);
+        ASSERT_EQ(strncmp(gEnv->getComponent().c_str(), "OMX.", 4), 0)
+            << "Invalid Component Name";
+        EXPECT_TRUE(omx->allocateNode(
+                           gEnv->getComponent(), observer,
+                           [&](android::hardware::media::omx::V1_0::Status _s,
+                               sp<IOmxNode> const& _nl) {
+                               status = _s;
+                               this->omxNode = _nl;
+                           })
+                        .isOk());
+        ASSERT_NE(omxNode, nullptr);
+        ASSERT_NE(gEnv->getRole().empty(), true) << "Invalid Component Role";
+        struct StringToName {
+            const char* Name;
+            standardComp CompName;
+        };
+        const StringToName kStringToName[] = {
+            {"mp3", mp3}, {"amrnb", amrnb},   {"amrwb", amrwb},
+            {"aac", aac}, {"vorbis", vorbis}, {"opus", opus},
+            {"pcm", pcm}, {"flac", flac},
+        };
+        const size_t kNumStringToName =
+            sizeof(kStringToName) / sizeof(kStringToName[0]);
+        const char* pch;
+        char substring[OMX_MAX_STRINGNAME_SIZE];
+        strcpy(substring, gEnv->getRole().c_str());
+        pch = strchr(substring, '.');
+        ASSERT_NE(pch, nullptr);
+        compName = unknown_comp;
+        for (size_t i = 0; i < kNumStringToName; ++i) {
+            if (!strcasecmp(pch + 1, kStringToName[i].Name)) {
+                compName = kStringToName[i].CompName;
+                break;
+            }
+        }
+        ASSERT_NE(compName, unknown_comp);
+        struct CompToCoding {
+            standardComp CompName;
+            OMX_AUDIO_CODINGTYPE eEncoding;
+        };
+        static const CompToCoding kCompToCoding[] = {
+            {mp3, OMX_AUDIO_CodingMP3},
+            {amrnb, OMX_AUDIO_CodingAMR},
+            {amrwb, OMX_AUDIO_CodingAMR},
+            {aac, OMX_AUDIO_CodingAAC},
+            {vorbis, OMX_AUDIO_CodingVORBIS},
+            {pcm, OMX_AUDIO_CodingPCM},
+            {opus, (OMX_AUDIO_CODINGTYPE)OMX_AUDIO_CodingAndroidOPUS},
+            {flac, OMX_AUDIO_CodingFLAC},
+        };
+        static const size_t kNumCompToCoding =
+            sizeof(kCompToCoding) / sizeof(kCompToCoding[0]);
+        size_t i;
+        for (i = 0; i < kNumCompToCoding; ++i) {
+            if (kCompToCoding[i].CompName == compName) {
+                eEncoding = kCompToCoding[i].eEncoding;
+                break;
+            }
+        }
+        ASSERT_NE(i, kNumCompToCoding);
+    }
+
+    virtual void TearDown() override {
+        if (omxNode != nullptr) {
+            EXPECT_TRUE((omxNode->freeNode()).isOk());
+            omxNode = nullptr;
+        }
+    }
+
+    enum standardComp {
+        mp3,
+        amrnb,
+        amrwb,
+        aac,
+        vorbis,
+        opus,
+        pcm,
+        flac,
+        unknown_comp,
+    };
+
+    sp<IOmx> omx;
+    sp<CodecObserver> observer;
+    sp<IOmxNode> omxNode;
+    standardComp compName;
+    OMX_AUDIO_CODINGTYPE eEncoding;
+};
+
+void setDefaultPortParam(
+    sp<IOmxNode> omxNode, OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE eEncoding,
+    int32_t nChannels = 2, int32_t nSampleRate = 44100,
+    OMX_NUMERICALDATATYPE eNumData = OMX_NumericalDataSigned,
+    int32_t nBitPerSample = 16) {
+    android::hardware::media::omx::V1_0::Status status;
+    OMX_PARAM_PORTDEFINITIONTYPE portDef;
+    status = getPortParam(omxNode, OMX_IndexParamPortDefinition, portIndex,
+                          &portDef);
+    EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+
+    portDef.format.audio.bFlagErrorConcealment = OMX_TRUE;
+    portDef.format.audio.eEncoding = eEncoding;
+    status = setPortParam(omxNode, OMX_IndexParamPortDefinition, portIndex,
+                          &portDef);
+    EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+
+    switch ((int)eEncoding) {
+        case OMX_AUDIO_CodingPCM:
+            setupPCMPort(omxNode, portIndex, nChannels, eNumData, nBitPerSample,
+                         nSampleRate);
+            break;
+        default:
+            ASSERT_TRUE(false);
+            break;
+    }
+}
+
+void getInputChannelInfo(sp<IOmxNode> omxNode, OMX_U32 kPortIndexInput,
+                         OMX_AUDIO_CODINGTYPE eEncoding, int32_t* nChannels,
+                         int32_t* nSampleRate) {
+    *nChannels = 0;
+    *nSampleRate = 0;
+    android::hardware::media::omx::V1_0::Status status;
+
+    switch ((int)eEncoding) {
+        case OMX_AUDIO_CodingPCM: {
+            OMX_AUDIO_PARAM_PCMMODETYPE param;
+            status = getPortParam(omxNode, OMX_IndexParamAudioPcm,
+                                  kPortIndexInput, &param);
+            ASSERT_EQ(status,
+                      ::android::hardware::media::omx::V1_0::Status::OK);
+            *nChannels = param.nChannels;
+            *nSampleRate = param.nSamplingRate;
+            break;
+        }
+        case OMX_AUDIO_CodingMP3: {
+            OMX_AUDIO_PARAM_MP3TYPE param;
+            status = getPortParam(omxNode, OMX_IndexParamAudioMp3,
+                                  kPortIndexInput, &param);
+            ASSERT_EQ(status,
+                      ::android::hardware::media::omx::V1_0::Status::OK);
+            *nChannels = param.nChannels;
+            *nSampleRate = param.nSampleRate;
+            break;
+        }
+        case OMX_AUDIO_CodingFLAC: {
+            OMX_AUDIO_PARAM_FLACTYPE param;
+            status = getPortParam(omxNode, OMX_IndexParamAudioFlac,
+                                  kPortIndexInput, &param);
+            ASSERT_EQ(status,
+                      ::android::hardware::media::omx::V1_0::Status::OK);
+            *nChannels = param.nChannels;
+            *nSampleRate = param.nSampleRate;
+            break;
+        }
+        case OMX_AUDIO_CodingAndroidOPUS: {
+            OMX_AUDIO_PARAM_ANDROID_OPUSTYPE param;
+            status = getPortParam(omxNode,
+                                  (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidOpus,
+                                  kPortIndexInput, &param);
+            ASSERT_EQ(status,
+                      ::android::hardware::media::omx::V1_0::Status::OK);
+            *nChannels = param.nChannels;
+            *nSampleRate = param.nSampleRate;
+            break;
+        }
+        case OMX_AUDIO_CodingVORBIS: {
+            OMX_AUDIO_PARAM_VORBISTYPE param;
+            status = getPortParam(omxNode, OMX_IndexParamAudioVorbis,
+                                  kPortIndexInput, &param);
+            ASSERT_EQ(status,
+                      ::android::hardware::media::omx::V1_0::Status::OK);
+            *nChannels = param.nChannels;
+            *nSampleRate = param.nSampleRate;
+            break;
+        }
+        case OMX_AUDIO_CodingAMR: {
+            OMX_AUDIO_PARAM_AMRTYPE param;
+            status = getPortParam(omxNode, OMX_IndexParamAudioAmr,
+                                  kPortIndexInput, &param);
+            ASSERT_EQ(status,
+                      ::android::hardware::media::omx::V1_0::Status::OK);
+            *nChannels = param.nChannels;
+            *nSampleRate = 8000;
+            break;
+        }
+        case OMX_AUDIO_CodingAAC: {
+            OMX_AUDIO_PARAM_AACPROFILETYPE param;
+            status = getPortParam(omxNode, OMX_IndexParamAudioAac,
+                                  kPortIndexInput, &param);
+            ASSERT_EQ(status,
+                      ::android::hardware::media::omx::V1_0::Status::OK);
+            *nChannels = param.nChannels;
+            *nSampleRate = param.nSampleRate;
+            break;
+        }
+        default:
+            ASSERT_TRUE(false);
+            break;
+    }
+}
+
+void GetURLForComponent(AudioDecHidlTest::standardComp comp, const char** mURL,
+                        const char** info) {
+    struct CompToURL {
+        AudioDecHidlTest::standardComp comp;
+        const char* mURL;
+        const char* info;
+    };
+    static const CompToURL kCompToURL[] = {
+        {AudioDecHidlTest::standardComp::mp3,
+         "/sdcard/raw/MP3_48KHz_128kbps_s_1_17_CBR.audio.mp3",
+         "/sdcard/raw/MP3_48KHz_128kbps_s_1_17_CBR.audio.info"},
+        {AudioDecHidlTest::standardComp::aac,
+         "/sdcard/raw/H264_500_AAC_128.audio.aac",
+         "/sdcard/raw/H264_500_AAC_128.audio.info"},
+        {AudioDecHidlTest::standardComp::amrnb,
+         "/sdcard/raw/H264_320_AMRNB_6.audio.amr",
+         "/sdcard/raw/H264_320_AMRNB_6.audio.info"},
+        {AudioDecHidlTest::standardComp::amrwb, "", ""},
+        {AudioDecHidlTest::standardComp::vorbis, "", ""},
+        {AudioDecHidlTest::standardComp::opus, "", ""},
+        {AudioDecHidlTest::standardComp::flac, "", ""},
+    };
+
+    for (size_t i = 0; i < sizeof(kCompToURL) / sizeof(kCompToURL[0]); ++i) {
+        if (kCompToURL[i].comp == comp) {
+            *mURL = kCompToURL[i].mURL;
+            *info = kCompToURL[i].info;
+            return;
+        }
+    }
+}
+
+void flushAllPorts(sp<IOmxNode> omxNode, sp<CodecObserver> observer,
+                   android::Vector<BufferInfo>* iBuffer,
+                   android::Vector<BufferInfo>* oBuffer,
+                   OMX_U32 kPortIndexInput, OMX_U32 kPortIndexOutput) {
+    android::hardware::media::omx::V1_0::Status status;
+    Message msg;
+    // Flush
+    status = omxNode->sendCommand(toRawCommandType(OMX_CommandFlush),
+                                  kPortIndexInput);
+    ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+    status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, iBuffer, oBuffer);
+    ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+    ASSERT_EQ(msg.type, Message::Type::EVENT);
+    ASSERT_EQ(msg.data.eventData.event, OMX_EventCmdComplete);
+    ASSERT_EQ(msg.data.eventData.data1, OMX_CommandFlush);
+    ASSERT_EQ(msg.data.eventData.data2, kPortIndexInput);
+    // test if client got all its buffers back
+    for (size_t i = 0; i < iBuffer->size(); ++i) {
+        EXPECT_EQ((*iBuffer)[i].owner, client);
+    }
+
+    status = omxNode->sendCommand(toRawCommandType(OMX_CommandFlush),
+                                  kPortIndexOutput);
+    ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+    status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, iBuffer, oBuffer);
+    ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+    ASSERT_EQ(msg.type, Message::Type::EVENT);
+    ASSERT_EQ(msg.data.eventData.event, OMX_EventCmdComplete);
+    ASSERT_EQ(msg.data.eventData.data1, OMX_CommandFlush);
+    ASSERT_EQ(msg.data.eventData.data2, kPortIndexOutput);
+    // test if client got all its buffers back
+    for (size_t i = 0; i < oBuffer->size(); ++i) {
+        EXPECT_EQ((*oBuffer)[i].owner, client);
+    }
+}
+
+void decodeNFrames(sp<IOmxNode> omxNode, sp<CodecObserver> observer,
+                   android::Vector<BufferInfo>* iBuffer,
+                   android::Vector<BufferInfo>* oBuffer,
+                   OMX_AUDIO_CODINGTYPE eEncoding, OMX_U32 kPortIndexInput,
+                   OMX_U32 kPortIndexOutput, uint32_t nFrames,
+                   std::ifstream& eleStream, std::ifstream& eleInfo) {
+    android::hardware::media::omx::V1_0::Status status;
+    Message msg;
+
+    // dispatch output buffers
+    for (size_t i = 0; i < oBuffer->size(); i++) {
+        dispatchOutputBuffer(omxNode, oBuffer, i);
+    }
+    // dispatch input buffers
+    int bytesCount = 0;
+    for (size_t i = 0; i < iBuffer->size(); i++) {
+        char* ipBuffer = static_cast<char*>(
+            static_cast<void*>((*iBuffer)[i].mMemory->getPointer()));
+        if (!(eleInfo >> bytesCount)) break;
+        eleStream.read(ipBuffer, bytesCount);
+        ASSERT_EQ(eleStream.gcount(), bytesCount);
+        dispatchInputBuffer(omxNode, iBuffer, i, bytesCount, 0, 0);
+    }
+
+    while (nFrames != 0) {
+        status =
+            observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, iBuffer, oBuffer);
+        if (status == android::hardware::media::omx::V1_0::Status::OK &&
+            msg.type == Message::Type::EVENT &&
+            msg.data.eventData.event == OMX_EventPortSettingsChanged) {
+            ASSERT_EQ(msg.data.eventData.data1, kPortIndexOutput);
+
+            status = omxNode->sendCommand(
+                toRawCommandType(OMX_CommandPortDisable), kPortIndexOutput);
+            ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+
+            status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, iBuffer,
+                                              oBuffer);
+            if (status ==
+                android::hardware::media::omx::V1_0::Status::TIMED_OUT) {
+                for (size_t i = 0; i < oBuffer->size(); ++i) {
+                    // test if client got all its buffers back
+                    EXPECT_EQ((*oBuffer)[i].owner, client);
+                    // free the buffers
+                    status =
+                        omxNode->freeBuffer(kPortIndexOutput, (*oBuffer)[i].id);
+                    ASSERT_EQ(status,
+                              android::hardware::media::omx::V1_0::Status::OK);
+                }
+                status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT,
+                                                  iBuffer, oBuffer);
+                ASSERT_EQ(status,
+                          android::hardware::media::omx::V1_0::Status::OK);
+                ASSERT_EQ(msg.type, Message::Type::EVENT);
+                ASSERT_EQ(msg.data.eventData.event, OMX_EventCmdComplete);
+                ASSERT_EQ(msg.data.eventData.data1, OMX_CommandPortDisable);
+                ASSERT_EQ(msg.data.eventData.data2, kPortIndexOutput);
+
+                // Port Reconfigurations
+                int32_t nChannels;
+                int32_t nSampleRate;
+                getInputChannelInfo(omxNode, kPortIndexInput, eEncoding,
+                                    &nChannels, &nSampleRate);
+                setDefaultPortParam(omxNode, kPortIndexOutput,
+                                    OMX_AUDIO_CodingPCM, nChannels,
+                                    nSampleRate);
+
+                // If you can disable a port, then you should be able to enable
+                // it as well
+                status = omxNode->sendCommand(
+                    toRawCommandType(OMX_CommandPortEnable), kPortIndexOutput);
+                ASSERT_EQ(status,
+                          android::hardware::media::omx::V1_0::Status::OK);
+
+                // do not enable the port until all the buffers are supplied
+                status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT,
+                                                  iBuffer, oBuffer);
+                ASSERT_EQ(
+                    status,
+                    android::hardware::media::omx::V1_0::Status::TIMED_OUT);
+
+                allocatePortBuffers(omxNode, oBuffer, kPortIndexOutput);
+                status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT,
+                                                  iBuffer, oBuffer);
+                ASSERT_EQ(status,
+                          android::hardware::media::omx::V1_0::Status::OK);
+                ASSERT_EQ(msg.type, Message::Type::EVENT);
+                ASSERT_EQ(msg.data.eventData.data1, OMX_CommandPortEnable);
+                ASSERT_EQ(msg.data.eventData.data2, kPortIndexOutput);
+
+                // dispatch output buffers
+                for (size_t i = 0; i < oBuffer->size(); i++) {
+                    dispatchOutputBuffer(omxNode, oBuffer, i);
+                }
+            } else {
+                ASSERT_TRUE(false);
+            }
+            continue;
+        }
+        size_t index = 0;
+        if ((index = getEmptyBufferID(iBuffer)) < iBuffer->size()) {
+            char* ipBuffer = static_cast<char*>(
+                static_cast<void*>((*iBuffer)[index].mMemory->getPointer()));
+            if (!(eleInfo >> bytesCount)) break;
+            eleStream.read(ipBuffer, bytesCount);
+            ASSERT_EQ(eleStream.gcount(), bytesCount);
+            dispatchInputBuffer(omxNode, iBuffer, index, bytesCount, 0, 0);
+        }
+        if ((index = getEmptyBufferID(oBuffer)) < oBuffer->size()) {
+            dispatchOutputBuffer(omxNode, oBuffer, index);
+        }
+        nFrames--;
+    }
+}
+
+// Set Component Role
+TEST_F(AudioDecHidlTest, SetRole) {
+    android::hardware::media::omx::V1_0::Status status;
+    status = setRole(omxNode, gEnv->getRole().c_str());
+    ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+}
+
+// Enumerate Port Format
+TEST_F(AudioDecHidlTest, EnumeratePortFormat) {
+    android::hardware::media::omx::V1_0::Status status;
+    uint32_t kPortIndexInput = 0, kPortIndexOutput = 1;
+    status = setRole(omxNode, gEnv->getRole().c_str());
+    ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+    OMX_PORT_PARAM_TYPE params;
+    status = getParam(omxNode, OMX_IndexParamAudioInit, &params);
+    if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
+        ASSERT_EQ(params.nPorts, 2U);
+        kPortIndexInput = params.nStartPortNumber;
+        kPortIndexOutput = kPortIndexInput + 1;
+    }
+    status = setAudioPortFormat(omxNode, kPortIndexInput, eEncoding);
+    EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+    status = setAudioPortFormat(omxNode, kPortIndexOutput, OMX_AUDIO_CodingPCM);
+    EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+}
+
+// Decode Test
+TEST_F(AudioDecHidlTest, DecodeTest) {
+    android::hardware::media::omx::V1_0::Status status;
+    uint32_t kPortIndexInput = 0, kPortIndexOutput = 1;
+    status = setRole(omxNode, gEnv->getRole().c_str());
+    ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+    OMX_PORT_PARAM_TYPE params;
+    status = getParam(omxNode, OMX_IndexParamAudioInit, &params);
+    if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
+        ASSERT_EQ(params.nPorts, 2U);
+        kPortIndexInput = params.nStartPortNumber;
+        kPortIndexOutput = kPortIndexInput + 1;
+    }
+    const char *mURL = nullptr, *info = nullptr;
+    GetURLForComponent(compName, &mURL, &info);
+    EXPECT_NE(mURL, nullptr);
+    EXPECT_NE(info, nullptr);
+
+    std::ifstream eleStream, eleInfo;
+    eleStream.open(mURL, std::ifstream::binary);
+    ASSERT_EQ(eleStream.is_open(), true);
+    eleInfo.open(info);
+    ASSERT_EQ(eleInfo.is_open(), true);
+
+    if (eEncoding == OMX_AUDIO_CodingPCM)
+        setDefaultPortParam(omxNode, kPortIndexInput, eEncoding);
+    int32_t nChannels;
+    int32_t nSampleRate;
+    getInputChannelInfo(omxNode, kPortIndexInput, eEncoding, &nChannels,
+                        &nSampleRate);
+    setDefaultPortParam(omxNode, kPortIndexOutput, OMX_AUDIO_CodingPCM,
+                        nChannels, nSampleRate);
+
+    Message msg;
+    android::Vector<BufferInfo> iBuffer, oBuffer;
+
+    status = omxNode->sendCommand(toRawCommandType(OMX_CommandStateSet),
+                                  OMX_StateIdle);
+    ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+
+    status =
+        observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, &iBuffer, &oBuffer);
+    ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::TIMED_OUT);
+
+    allocatePortBuffers(omxNode, &iBuffer, kPortIndexInput);
+    status =
+        observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, &iBuffer, &oBuffer);
+
+    ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::TIMED_OUT);
+    allocatePortBuffers(omxNode, &oBuffer, kPortIndexOutput);
+
+    status =
+        observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, &iBuffer, &oBuffer);
+    ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+    ASSERT_EQ(msg.type, Message::Type::EVENT);
+    ASSERT_EQ(msg.data.eventData.event, OMX_EventCmdComplete);
+    ASSERT_EQ(msg.data.eventData.data1, OMX_CommandStateSet);
+    ASSERT_EQ(msg.data.eventData.data2, OMX_StateIdle);
+
+    status = omxNode->sendCommand(toRawCommandType(OMX_CommandStateSet),
+                                  OMX_StateExecuting);
+    ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+    status =
+        observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, &iBuffer, &oBuffer);
+    ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+    ASSERT_EQ(msg.type, Message::Type::EVENT);
+    ASSERT_EQ(msg.data.eventData.event, OMX_EventCmdComplete);
+    ASSERT_EQ(msg.data.eventData.data1, OMX_CommandStateSet);
+    ASSERT_EQ(msg.data.eventData.data2, OMX_StateExecuting);
+
+    // Port Reconfiguration
+    decodeNFrames(omxNode, observer, &iBuffer, &oBuffer, eEncoding,
+                  kPortIndexInput, kPortIndexOutput, (1 << 12), eleStream,
+                  eleInfo);
+
+    // flush
+    flushAllPorts(omxNode, observer, &iBuffer, &oBuffer, kPortIndexInput,
+                  kPortIndexOutput);
+
+    // set state to Idle
+    status = omxNode->sendCommand(toRawCommandType(OMX_CommandStateSet),
+                                  OMX_StateIdle);
+    ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+    status =
+        observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, &iBuffer, &oBuffer);
+    ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+    ASSERT_EQ(msg.type, Message::Type::EVENT);
+    ASSERT_EQ(msg.data.eventData.event, OMX_EventCmdComplete);
+    ASSERT_EQ(msg.data.eventData.data1, OMX_CommandStateSet);
+    ASSERT_EQ(msg.data.eventData.data2, OMX_StateIdle);
+
+    // set state to Loaded
+    status = omxNode->sendCommand(toRawCommandType(OMX_CommandStateSet),
+                                  OMX_StateLoaded);
+    ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+
+    // dont change state until all buffers are freed
+    status =
+        observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, &iBuffer, &oBuffer);
+    ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::TIMED_OUT);
+
+    for (size_t i = 0; i < iBuffer.size(); ++i) {
+        status = omxNode->freeBuffer(kPortIndexInput, iBuffer[i].id);
+        ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+    }
+
+    // dont change state until all buffers are freed
+    status =
+        observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, &iBuffer, &oBuffer);
+    ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::TIMED_OUT);
+
+    for (size_t i = 0; i < oBuffer.size(); ++i) {
+        status = omxNode->freeBuffer(kPortIndexOutput, oBuffer[i].id);
+        ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+    }
+
+    status =
+        observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, &iBuffer, &oBuffer);
+    ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+    ASSERT_EQ(msg.type, Message::Type::EVENT);
+    ASSERT_EQ(msg.data.eventData.event, OMX_EventCmdComplete);
+    ASSERT_EQ(msg.data.eventData.data1, OMX_CommandStateSet);
+    ASSERT_EQ(msg.data.eventData.data2, OMX_StateLoaded);
+
+    eleInfo.close();
+    eleStream.close();
+}
+
+int main(int argc, char** argv) {
+    gEnv = new ComponentTestEnvironment();
+    ::testing::AddGlobalTestEnvironment(gEnv);
+    ::testing::InitGoogleTest(&argc, argv);
+    int status = gEnv->initFromOptions(argc, argv);
+    if (status == 0) {
+        status = RUN_ALL_TESTS();
+        ALOGI("Test result = %d", status);
+    }
+    return status;
+}
diff --git a/media/omx/1.0/vts/functional/audio/VtsHalMediaOmxV1_0TargetAudioEncTest.cpp b/media/omx/1.0/vts/functional/audio/VtsHalMediaOmxV1_0TargetAudioEncTest.cpp
new file mode 100644
index 0000000..6a88b1a
--- /dev/null
+++ b/media/omx/1.0/vts/functional/audio/VtsHalMediaOmxV1_0TargetAudioEncTest.cpp
@@ -0,0 +1,263 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "media_omx_hidl_audio_enc_test"
+#include <android-base/logging.h>
+
+#include <android/hardware/media/omx/1.0/IOmx.h>
+#include <android/hardware/media/omx/1.0/IOmxNode.h>
+#include <android/hardware/media/omx/1.0/IOmxObserver.h>
+#include <android/hardware/media/omx/1.0/types.h>
+#include <android/hidl/allocator/1.0/IAllocator.h>
+#include <android/hidl/memory/1.0/IMapper.h>
+#include <android/hidl/memory/1.0/IMemory.h>
+
+using ::android::hardware::media::omx::V1_0::IOmx;
+using ::android::hardware::media::omx::V1_0::IOmxObserver;
+using ::android::hardware::media::omx::V1_0::IOmxNode;
+using ::android::hardware::media::omx::V1_0::Message;
+using ::android::hardware::media::omx::V1_0::CodecBuffer;
+using ::android::hidl::allocator::V1_0::IAllocator;
+using ::android::hidl::memory::V1_0::IMemory;
+using ::android::hidl::memory::V1_0::IMapper;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::hidl_string;
+using ::android::sp;
+
+#include <VtsHalHidlTargetTestBase.h>
+#include <getopt.h>
+#include <media_audio_hidl_test_common.h>
+#include <media_hidl_test_common.h>
+#include <fstream>
+
+// A class for test environment setup
+class ComponentTestEnvironment : public ::testing::Environment {
+   public:
+    virtual void SetUp() {}
+    virtual void TearDown() {}
+
+    ComponentTestEnvironment() : instance("default") {}
+
+    void setInstance(const char* _instance) { instance = _instance; }
+
+    void setComponent(const char* _component) { component = _component; }
+
+    void setRole(const char* _role) { role = _role; }
+
+    void setQuirks(int _quirks) { quirks = _quirks; }
+
+    const hidl_string getInstance() const { return instance; }
+
+    const hidl_string getComponent() const { return component; }
+
+    const hidl_string getRole() const { return role; }
+
+    int getQuirks() const { return quirks; }
+
+    int initFromOptions(int argc, char** argv) {
+        static struct option options[] = {
+            {"instance", required_argument, 0, 'I'},
+            {"component", required_argument, 0, 'C'},
+            {"role", required_argument, 0, 'R'},
+            {"quirks", required_argument, 0, 'Q'},
+            {0, 0, 0, 0}};
+
+        while (true) {
+            int index = 0;
+            int c = getopt_long(argc, argv, "I:C:Q:R:", options, &index);
+            if (c == -1) {
+                break;
+            }
+
+            switch (c) {
+                case 'I':
+                    setInstance(optarg);
+                    break;
+                case 'C':
+                    setComponent(optarg);
+                    break;
+                case 'Q':
+                    setQuirks(atoi(optarg));
+                    break;
+                case 'R':
+                    setRole(optarg);
+                    break;
+                case '?':
+                    break;
+            }
+        }
+
+        if (optind < argc) {
+            fprintf(stderr,
+                    "unrecognized option: %s\n\n"
+                    "usage: %s <gtest options> <test options>\n\n"
+                    "test options are:\n\n"
+                    "-I, --instance: HAL instance to test\n"
+                    "-C, --component: OMX component to test\n"
+                    "-R, --Role: OMX component Role\n"
+                    "-Q, --quirks: Component quirks\n",
+                    argv[optind ?: 1], argv[0]);
+            return 2;
+        }
+        return 0;
+    }
+
+   private:
+    hidl_string instance;
+    hidl_string component;
+    hidl_string role;
+    // to be removed when IOmxNode::setQuirks is removed
+    int quirks;
+};
+
+static ComponentTestEnvironment* gEnv = nullptr;
+
+class AudioEncHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+   public:
+    virtual void SetUp() override {
+        android::hardware::media::omx::V1_0::Status status;
+        omx = ::testing::VtsHalHidlTargetTestBase::getService<IOmx>(
+            gEnv->getInstance());
+        ASSERT_NE(omx, nullptr);
+        observer = new CodecObserver();
+        ASSERT_NE(observer, nullptr);
+        ASSERT_EQ(strncmp(gEnv->getComponent().c_str(), "OMX.", 4), 0)
+            << "Invalid Component Name";
+        EXPECT_TRUE(omx->allocateNode(
+                           gEnv->getComponent(), observer,
+                           [&](android::hardware::media::omx::V1_0::Status _s,
+                               sp<IOmxNode> const& _nl) {
+                               status = _s;
+                               this->omxNode = _nl;
+                           })
+                        .isOk());
+        ASSERT_NE(omxNode, nullptr);
+        ASSERT_NE(gEnv->getRole().empty(), true) << "Invalid Component Role";
+        struct StringToName {
+            const char* Name;
+            standardComp CompName;
+        };
+        const StringToName kStringToName[] = {
+            {"mp3", mp3}, {"amrnb", amrnb},   {"amrwb", amrwb},
+            {"aac", aac}, {"vorbis", vorbis}, {"opus", opus},
+            {"pcm", pcm}, {"flac", flac},
+        };
+        const size_t kNumStringToName =
+            sizeof(kStringToName) / sizeof(kStringToName[0]);
+        const char* pch;
+        char substring[OMX_MAX_STRINGNAME_SIZE];
+        strcpy(substring, gEnv->getRole().c_str());
+        pch = strchr(substring, '.');
+        ASSERT_NE(pch, nullptr);
+        compName = unknown_comp;
+        for (size_t i = 0; i < kNumStringToName; ++i) {
+            if (!strcasecmp(pch + 1, kStringToName[i].Name)) {
+                compName = kStringToName[i].CompName;
+                break;
+            }
+        }
+        ASSERT_NE(compName, unknown_comp);
+        struct CompToCoding {
+            standardComp CompName;
+            OMX_AUDIO_CODINGTYPE eEncoding;
+        };
+        static const CompToCoding kCompToCoding[] = {
+            {mp3, OMX_AUDIO_CodingMP3},
+            {amrnb, OMX_AUDIO_CodingAMR},
+            {amrwb, OMX_AUDIO_CodingAMR},
+            {aac, OMX_AUDIO_CodingAAC},
+            {vorbis, OMX_AUDIO_CodingVORBIS},
+            {pcm, OMX_AUDIO_CodingPCM},
+            {opus, (OMX_AUDIO_CODINGTYPE)OMX_AUDIO_CodingAndroidOPUS},
+            {flac, OMX_AUDIO_CodingFLAC},
+        };
+        static const size_t kNumCompToCoding =
+            sizeof(kCompToCoding) / sizeof(kCompToCoding[0]);
+        size_t i;
+        for (i = 0; i < kNumCompToCoding; ++i) {
+            if (kCompToCoding[i].CompName == compName) {
+                eEncoding = kCompToCoding[i].eEncoding;
+                break;
+            }
+        }
+        ASSERT_NE(i, kNumCompToCoding);
+    }
+
+    virtual void TearDown() override {
+        if (omxNode != nullptr) {
+            EXPECT_TRUE((omxNode->freeNode()).isOk());
+            omxNode = nullptr;
+        }
+    }
+
+    enum standardComp {
+        mp3,
+        amrnb,
+        amrwb,
+        aac,
+        vorbis,
+        opus,
+        pcm,
+        flac,
+        unknown_comp,
+    };
+
+    sp<IOmx> omx;
+    sp<CodecObserver> observer;
+    sp<IOmxNode> omxNode;
+    standardComp compName;
+    OMX_AUDIO_CODINGTYPE eEncoding;
+};
+
+// Set Component Role
+TEST_F(AudioEncHidlTest, SetRole) {
+    android::hardware::media::omx::V1_0::Status status;
+    status = setRole(omxNode, gEnv->getRole().c_str());
+    ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+}
+
+// Enumerate Port Format
+TEST_F(AudioEncHidlTest, EnumeratePortFormat) {
+    android::hardware::media::omx::V1_0::Status status;
+    uint32_t kPortIndexInput = 0, kPortIndexOutput = 1;
+    status = setRole(omxNode, gEnv->getRole().c_str());
+    ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+    OMX_PORT_PARAM_TYPE params;
+    status = getParam(omxNode, OMX_IndexParamAudioInit, &params);
+    if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
+        ASSERT_EQ(params.nPorts, 2U);
+        kPortIndexInput = params.nStartPortNumber;
+        kPortIndexOutput = kPortIndexInput + 1;
+    }
+    status = setAudioPortFormat(omxNode, kPortIndexInput, OMX_AUDIO_CodingPCM);
+    EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+    status = setAudioPortFormat(omxNode, kPortIndexOutput, eEncoding);
+    EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+}
+
+int main(int argc, char** argv) {
+    gEnv = new ComponentTestEnvironment();
+    ::testing::AddGlobalTestEnvironment(gEnv);
+    ::testing::InitGoogleTest(&argc, argv);
+    int status = gEnv->initFromOptions(argc, argv);
+    if (status == 0) {
+        status = RUN_ALL_TESTS();
+        ALOGI("Test result = %d", status);
+    }
+    return status;
+}
diff --git a/media/omx/1.0/vts/functional/audio/media_audio_hidl_test_common.cpp b/media/omx/1.0/vts/functional/audio/media_audio_hidl_test_common.cpp
new file mode 100644
index 0000000..e01e9aa
--- /dev/null
+++ b/media/omx/1.0/vts/functional/audio/media_audio_hidl_test_common.cpp
@@ -0,0 +1,316 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "media_omx_hidl_audio_test_common"
+#include <android-base/logging.h>
+
+#include <android/hardware/media/omx/1.0/IOmx.h>
+#include <android/hardware/media/omx/1.0/IOmxNode.h>
+#include <android/hardware/media/omx/1.0/IOmxObserver.h>
+#include <android/hardware/media/omx/1.0/types.h>
+#include <android/hidl/allocator/1.0/IAllocator.h>
+#include <android/hidl/memory/1.0/IMapper.h>
+#include <android/hidl/memory/1.0/IMemory.h>
+
+using ::android::hardware::media::omx::V1_0::IOmx;
+using ::android::hardware::media::omx::V1_0::IOmxObserver;
+using ::android::hardware::media::omx::V1_0::IOmxNode;
+using ::android::hardware::media::omx::V1_0::Message;
+using ::android::hardware::media::omx::V1_0::CodecBuffer;
+using ::android::hidl::allocator::V1_0::IAllocator;
+using ::android::hidl::memory::V1_0::IMemory;
+using ::android::hidl::memory::V1_0::IMapper;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::hidl_string;
+using ::android::sp;
+
+#include <VtsHalHidlTargetTestBase.h>
+#include <hidlmemory/mapping.h>
+#include <media_audio_hidl_test_common.h>
+#include <media_hidl_test_common.h>
+#include <memory>
+
+void allocatePortBuffers(sp<IOmxNode> omxNode,
+                         android::Vector<BufferInfo>* buffArray,
+                         OMX_U32 portIndex) {
+    android::hardware::media::omx::V1_0::Status status;
+    OMX_PARAM_PORTDEFINITIONTYPE portDef;
+
+    buffArray->clear();
+
+    sp<IAllocator> allocator = IAllocator::getService("ashmem");
+    EXPECT_NE(allocator, nullptr);
+
+    status = getPortParam(omxNode, OMX_IndexParamPortDefinition, portIndex,
+                          &portDef);
+    ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+    for (size_t i = 0; i < portDef.nBufferCountActual; i++) {
+        BufferInfo buffer;
+        buffer.owner = client;
+        buffer.omxBuffer.type = CodecBuffer::Type::SHARED_MEM;
+        buffer.omxBuffer.attr.preset.rangeOffset = 0;
+        buffer.omxBuffer.attr.preset.rangeLength = 0;
+        bool success;
+        allocator->allocate(
+            portDef.nBufferSize,
+            [&success, &buffer](bool _s,
+                                ::android::hardware::hidl_memory const& mem) {
+                success = _s;
+                buffer.omxBuffer.sharedMemory = mem;
+            });
+        ASSERT_EQ(success, true);
+        buffer.mMemory = mapMemory(buffer.omxBuffer.sharedMemory);
+        ASSERT_NE(buffer.mMemory, nullptr);
+        omxNode->useBuffer(
+            portIndex, buffer.omxBuffer,
+            [&status, &buffer](android::hardware::media::omx::V1_0::Status _s,
+                               uint32_t id) {
+                status = _s;
+                buffer.id = id;
+            });
+        buffArray->push(buffer);
+        ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+    }
+}
+
+size_t getEmptyBufferID(android::Vector<BufferInfo>* buffArray) {
+    for (size_t i = 0; i < buffArray->size(); i++) {
+        if ((*buffArray)[i].owner == client) return i;
+    }
+    return buffArray->size();
+}
+
+void dispatchInputBuffer(sp<IOmxNode> omxNode,
+                         android::Vector<BufferInfo>* buffArray,
+                         size_t bufferIndex, int bytesCount, uint32_t flags,
+                         uint64_t timestamp) {
+    android::hardware::media::omx::V1_0::Status status;
+    CodecBuffer t;
+    t.sharedMemory = android::hardware::hidl_memory();
+    t.nativeHandle = android::hardware::hidl_handle();
+    t.type = CodecBuffer::Type::PRESET;
+    t.attr.preset.rangeOffset = 0;
+    t.attr.preset.rangeLength = bytesCount;
+    native_handle_t* fenceNh = native_handle_create(0, 0);
+    ASSERT_NE(fenceNh, nullptr);
+    status = omxNode->emptyBuffer((*buffArray)[bufferIndex].id, t, flags,
+                                  timestamp, fenceNh);
+    native_handle_close(fenceNh);
+    native_handle_delete(fenceNh);
+    ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+    buffArray->editItemAt(bufferIndex).owner = component;
+}
+
+void dispatchOutputBuffer(sp<IOmxNode> omxNode,
+                          android::Vector<BufferInfo>* buffArray,
+                          size_t bufferIndex) {
+    android::hardware::media::omx::V1_0::Status status;
+    CodecBuffer t;
+    t.sharedMemory = android::hardware::hidl_memory();
+    t.nativeHandle = android::hardware::hidl_handle();
+    t.type = CodecBuffer::Type::PRESET;
+    t.attr.preset.rangeOffset = 0;
+    t.attr.preset.rangeLength = 0;
+    native_handle_t* fenceNh = native_handle_create(0, 0);
+    ASSERT_NE(fenceNh, nullptr);
+    status = omxNode->fillBuffer((*buffArray)[bufferIndex].id, t, fenceNh);
+    native_handle_close(fenceNh);
+    native_handle_delete(fenceNh);
+    ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+    buffArray->editItemAt(bufferIndex).owner = component;
+}
+
+Return<android::hardware::media::omx::V1_0::Status> setAudioPortFormat(
+    sp<IOmxNode> omxNode, OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE encoding) {
+    OMX_U32 index = 0;
+    OMX_AUDIO_PARAM_PORTFORMATTYPE portFormat;
+    std::vector<OMX_AUDIO_CODINGTYPE> eEncoding;
+    android::hardware::media::omx::V1_0::Status status;
+
+    while (1) {
+        portFormat.nIndex = index;
+        status = getPortParam(omxNode, OMX_IndexParamAudioPortFormat, portIndex,
+                              &portFormat);
+        if (status != ::android::hardware::media::omx::V1_0::Status::OK) break;
+        eEncoding.push_back(portFormat.eEncoding);
+        index++;
+        if (index == 512) {
+            EXPECT_LE(index, 512U)
+                << "Expecting OMX_ErrorNoMore but not received";
+            break;
+        }
+    }
+    if (!index) return status;
+    for (index = 0; index < eEncoding.size(); index++) {
+        if (eEncoding[index] == encoding) {
+            portFormat.eEncoding = eEncoding[index];
+            break;
+        }
+    }
+    if (index == eEncoding.size()) {
+        ALOGI("setting default Port format");
+        portFormat.eEncoding = eEncoding[0];
+    }
+    // In setParam call nIndex shall be ignored as per omx-il specification.
+    // see how this holds up by corrupting nIndex
+    portFormat.nIndex = RANDOM_INDEX;
+    status = setPortParam(omxNode, OMX_IndexParamAudioPortFormat, portIndex,
+                          &portFormat);
+    return status;
+}
+
+Return<android::hardware::media::omx::V1_0::Status> setRole(
+    sp<IOmxNode> omxNode, const char* role) {
+    OMX_PARAM_COMPONENTROLETYPE params;
+    strcpy((char*)params.cRole, role);
+    return setParam(omxNode, OMX_IndexParamStandardComponentRole, &params);
+}
+
+void setupPCMPort(sp<IOmxNode> omxNode, OMX_U32 portIndex, int32_t nChannels,
+                  OMX_NUMERICALDATATYPE eNumData, int32_t nBitPerSample,
+                  int32_t nSamplingRate) {
+    OMX_AUDIO_PARAM_PCMMODETYPE param;
+    android::hardware::media::omx::V1_0::Status status;
+    status = getPortParam(omxNode, OMX_IndexParamAudioPcm, portIndex, &param);
+    EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+    param.nChannels = nChannels;
+    param.eNumData = eNumData;
+    param.eEndian = OMX_EndianBig;
+    param.bInterleaved = OMX_TRUE;
+    param.nBitPerSample = nBitPerSample;
+    param.nSamplingRate = nSamplingRate;
+    param.ePCMMode = OMX_AUDIO_PCMModeLinear;
+    switch (nChannels) {
+        case 1:
+            param.eChannelMapping[0] = OMX_AUDIO_ChannelCF;
+            break;
+        case 2:
+            param.eChannelMapping[0] = OMX_AUDIO_ChannelLF;
+            param.eChannelMapping[1] = OMX_AUDIO_ChannelRF;
+            break;
+        default:
+            EXPECT_TRUE(false);
+    }
+    status = setPortParam(omxNode, OMX_IndexParamAudioPcm, portIndex, &param);
+    ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+}
+
+void setupMP3Port(sp<IOmxNode> omxNode, OMX_U32 portIndex,
+                  OMX_AUDIO_MP3STREAMFORMATTYPE eFormat, int32_t nChannels,
+                  int32_t nBitRate, int32_t nSampleRate, bool isEncoder) {
+    if (isEncoder == false) return;
+    OMX_AUDIO_PARAM_MP3TYPE param;
+    android::hardware::media::omx::V1_0::Status status;
+    status = getPortParam(omxNode, OMX_IndexParamAudioMp3, portIndex, &param);
+    EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+    param.nChannels = nChannels;
+    param.nBitRate = nBitRate;
+    param.nSampleRate = nSampleRate;
+    param.nAudioBandWidth = 0;
+    param.eChannelMode = (nChannels == 1) ? OMX_AUDIO_ChannelModeMono
+                                          : OMX_AUDIO_ChannelModeStereo;
+    param.eFormat = eFormat;
+    status = setPortParam(omxNode, OMX_IndexParamAudioMp3, portIndex, &param);
+    ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+}
+
+void setupFLACPort(sp<IOmxNode> omxNode, OMX_U32 portIndex, int32_t nChannels,
+                   int32_t nSampleRate, int32_t nCompressionLevel,
+                   bool isEncoder) {
+    if (isEncoder == false) return;
+    android::hardware::media::omx::V1_0::Status status;
+    OMX_AUDIO_PARAM_FLACTYPE param;
+    status = getPortParam(omxNode, OMX_IndexParamAudioFlac, portIndex, &param);
+    EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+    param.nChannels = nChannels;
+    param.nSampleRate = nSampleRate;
+    param.nCompressionLevel = nCompressionLevel;
+    status = setPortParam(omxNode, OMX_IndexParamAudioFlac, portIndex, &param);
+    ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+}
+
+void setupOPUSPort(sp<IOmxNode> omxNode, OMX_U32 portIndex, int32_t nChannels,
+                   int32_t nBitRate, int32_t nSampleRate, bool isEncoder) {
+    if (isEncoder == false) return;
+    android::hardware::media::omx::V1_0::Status status;
+    OMX_AUDIO_PARAM_ANDROID_OPUSTYPE param;
+    status =
+        getPortParam(omxNode, (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidOpus,
+                     portIndex, &param);
+    EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+    param.nChannels = nChannels;
+    param.nBitRate = nBitRate;
+    param.nSampleRate = nSampleRate;
+    status =
+        setPortParam(omxNode, (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidOpus,
+                     portIndex, &param);
+    ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+}
+
+void setupAMRPort(sp<IOmxNode> omxNode, OMX_U32 portIndex, int32_t nBitRate,
+                  OMX_AUDIO_AMRBANDMODETYPE eAMRBandMode, bool isEncoder) {
+    if (isEncoder == false) return;
+    android::hardware::media::omx::V1_0::Status status;
+    OMX_AUDIO_PARAM_AMRTYPE param;
+    status = getPortParam(omxNode, OMX_IndexParamAudioAmr, portIndex, &param);
+    EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+    param.nChannels = 1;
+    param.nBitRate = nBitRate;
+    param.eAMRBandMode = eAMRBandMode;
+    status = setPortParam(omxNode, OMX_IndexParamAudioAmr, portIndex, &param);
+    ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+}
+
+void setupVORBISPort(sp<IOmxNode> omxNode, OMX_U32 portIndex, int32_t nChannels,
+                     int32_t nBitRate, int32_t nSampleRate, int32_t nQuality,
+                     bool isEncoder) {
+    if (isEncoder == false) return;
+    android::hardware::media::omx::V1_0::Status status;
+    OMX_AUDIO_PARAM_VORBISTYPE param;
+    status =
+        getPortParam(omxNode, OMX_IndexParamAudioVorbis, portIndex, &param);
+    EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+    param.nChannels = nChannels;
+    param.nBitRate = nBitRate;
+    param.nSampleRate = nSampleRate;
+    param.nQuality = nQuality;
+    status =
+        setPortParam(omxNode, OMX_IndexParamAudioVorbis, portIndex, &param);
+    ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+}
+
+void setupAACPort(sp<IOmxNode> omxNode, OMX_U32 portIndex,
+                  OMX_AUDIO_AACPROFILETYPE eAACProfile,
+                  OMX_AUDIO_AACSTREAMFORMATTYPE eAACStreamFormat,
+                  int32_t nChannels, int32_t nBitRate, int32_t nSampleRate,
+                  bool isEncoder) {
+    if (isEncoder == false) return;
+    android::hardware::media::omx::V1_0::Status status;
+    OMX_AUDIO_PARAM_AACPROFILETYPE param;
+    status = getPortParam(omxNode, OMX_IndexParamAudioAac, portIndex, &param);
+    EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+    param.nChannels = nChannels;
+    param.nSampleRate = nSampleRate;
+    param.nBitRate = nBitRate;
+    param.eAACProfile = eAACProfile;
+    param.eAACStreamFormat = eAACStreamFormat;
+    param.eChannelMode = (nChannels == 1) ? OMX_AUDIO_ChannelModeMono
+                                          : OMX_AUDIO_ChannelModeStereo;
+    status = setPortParam(omxNode, OMX_IndexParamAudioAac, portIndex, &param);
+    ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+}
diff --git a/media/omx/1.0/vts/functional/audio/media_audio_hidl_test_common.h b/media/omx/1.0/vts/functional/audio/media_audio_hidl_test_common.h
new file mode 100644
index 0000000..bdf5d52
--- /dev/null
+++ b/media/omx/1.0/vts/functional/audio/media_audio_hidl_test_common.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MEDIA_AUDIO_HIDL_TEST_COMMON_H
+#define MEDIA_AUDIO_HIDL_TEST_COMMON_H
+
+#include <media_hidl_test_common.h>
+/*
+ * Random Index used for monkey testing while get/set parameters
+ */
+#define RANDOM_INDEX 1729
+
+/*
+ * Common audio utils
+ */
+void allocatePortBuffers(sp<IOmxNode> omxNode,
+                         android::Vector<BufferInfo>* buffArray,
+                         OMX_U32 portIndex);
+
+size_t getEmptyBufferID(android::Vector<BufferInfo>* buffArray);
+
+void dispatchInputBuffer(sp<IOmxNode> omxNode,
+                         android::Vector<BufferInfo>* buffArray,
+                         size_t bufferIndex, int bytesCount, uint32_t flags,
+                         uint64_t timestamp);
+
+void dispatchOutputBuffer(sp<IOmxNode> omxNode,
+                          android::Vector<BufferInfo>* buffArray,
+                          size_t bufferIndex);
+
+Return<android::hardware::media::omx::V1_0::Status> setAudioPortFormat(
+    sp<IOmxNode> omxNode, OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE encoding);
+
+Return<android::hardware::media::omx::V1_0::Status> setRole(
+    sp<IOmxNode> omxNode, const char* role);
+
+void setupPCMPort(sp<IOmxNode> omxNode, OMX_U32 portIndex, int32_t nChannels,
+                  OMX_NUMERICALDATATYPE eNumData, int32_t nBitPerSample,
+                  int32_t nSamplingRate);
+
+void setupMP3Port(sp<IOmxNode> omxNode, OMX_U32 portIndex,
+                  OMX_AUDIO_MP3STREAMFORMATTYPE eFormat, int32_t nChannels,
+                  int32_t nBitRate, int32_t nSampleRate, bool isEncoder);
+
+void setupFLACPort(sp<IOmxNode> omxNode, OMX_U32 portIndex, int32_t nChannels,
+                   int32_t nSampleRate, int32_t nCompressionLevel,
+                   bool isEncoder);
+
+void setupOPUSPort(sp<IOmxNode> omxNode, OMX_U32 portIndex, int32_t nChannels,
+                   int32_t nBitRate, int32_t nSampleRate, bool isEncoder);
+
+void setupAMRPort(sp<IOmxNode> omxNode, OMX_U32 portIndex, int32_t nBitRate,
+                  OMX_AUDIO_AMRBANDMODETYPE eAMRBandMode, bool isEncoder);
+
+void setupVORBISPort(sp<IOmxNode> omxNode, OMX_U32 portIndex, int32_t nChannels,
+                     int32_t nBitRate, int32_t nSampleRate, int32_t nQuality,
+                     bool isEncoder);
+
+void setupAACPort(sp<IOmxNode> omxNode, OMX_U32 portIndex,
+                  OMX_AUDIO_AACPROFILETYPE eAACProfile,
+                  OMX_AUDIO_AACSTREAMFORMATTYPE eAACStreamFormat,
+                  int32_t nChannels, int32_t nBitRate, int32_t nSampleRate,
+                  bool isEncoder);
+
+#endif  // MEDIA_AUDIO_HIDL_TEST_COMMON_H
diff --git a/media/omx/1.0/vts/functional/common/media_hidl_test_common.h b/media/omx/1.0/vts/functional/common/media_hidl_test_common.h
new file mode 100644
index 0000000..9421463
--- /dev/null
+++ b/media/omx/1.0/vts/functional/common/media_hidl_test_common.h
@@ -0,0 +1,206 @@
+/*
+ * Copyright 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MEDIA_HIDL_TEST_COMMON_H
+#define MEDIA_HIDL_TEST_COMMON_H
+
+#include <media/stagefright/foundation/ALooper.h>
+#include <utils/Condition.h>
+#include <utils/List.h>
+#include <utils/Mutex.h>
+
+#include <media/openmax/OMX_Index.h>
+#include <media/openmax/OMX_Core.h>
+#include <media/openmax/OMX_Component.h>
+#include <media/openmax/OMX_IndexExt.h>
+#include <media/openmax/OMX_AudioExt.h>
+
+/*
+ * TODO: Borrowed from Conversion.h. This is not the ideal way to do it.
+ * Loose these definitions once you include Conversion.h
+ */
+inline uint32_t toRawIndexType(OMX_INDEXTYPE l) {
+    return static_cast<uint32_t>(l);
+}
+
+inline android::hardware::media::omx::V1_0::Status toStatus(
+    android::status_t l) {
+    return static_cast<android::hardware::media::omx::V1_0::Status>(l);
+}
+
+inline hidl_vec<uint8_t> inHidlBytes(void const* l, size_t size) {
+    hidl_vec<uint8_t> t;
+    t.setToExternal(static_cast<uint8_t*>(const_cast<void*>(l)), size, false);
+    return t;
+}
+
+inline uint32_t toRawCommandType(OMX_COMMANDTYPE l) {
+    return static_cast<uint32_t>(l);
+}
+
+/*
+ * Handle Callback functions EmptythisBuffer(), FillthisBuffer(),
+ * EventHandler()
+ */
+#define DEFAULT_TIMEOUT 40000
+
+enum bufferOwner {
+    client,
+    component,
+    unknown,
+};
+
+struct BufferInfo {
+    uint32_t id;
+    bufferOwner owner;
+    android::hardware::media::omx::V1_0::CodecBuffer omxBuffer;
+    ::android::sp<IMemory> mMemory;
+};
+
+struct CodecObserver : public IOmxObserver {
+   public:
+    Return<void> onMessages(const hidl_vec<Message>& messages) override {
+        android::Mutex::Autolock autoLock(msgLock);
+        for (hidl_vec<Message>::const_iterator it = messages.begin();
+             it != messages.end(); ++it) {
+            msgQueue.push_back(*it);
+        }
+        msgCondition.signal();
+        return Void();
+    }
+    android::hardware::media::omx::V1_0::Status dequeueMessage(
+        Message* msg, int64_t timeoutUs,
+        android::Vector<BufferInfo>* iBuffers = nullptr,
+        android::Vector<BufferInfo>* oBuffers = nullptr) {
+        int64_t finishBy = android::ALooper::GetNowUs() + timeoutUs;
+        for (;;) {
+            android::Mutex::Autolock autoLock(msgLock);
+            android::List<Message>::iterator it = msgQueue.begin();
+            while (it != msgQueue.end()) {
+                if (it->type ==
+                    android::hardware::media::omx::V1_0::Message::Type::EVENT) {
+                    *msg = *it;
+                    msgQueue.erase(it);
+                    return ::android::hardware::media::omx::V1_0::Status::OK;
+                } else if (it->type == android::hardware::media::omx::V1_0::
+                                           Message::Type::FILL_BUFFER_DONE) {
+                    if (oBuffers) {
+                        size_t i;
+                        for (i = 0; i < oBuffers->size(); ++i) {
+                            if ((*oBuffers)[i].id ==
+                                it->data.bufferData.buffer) {
+                                oBuffers->editItemAt(i).owner = client;
+                                msgQueue.erase(it);
+                                break;
+                            }
+                        }
+                        EXPECT_LE(i, oBuffers->size());
+                    }
+                } else if (it->type == android::hardware::media::omx::V1_0::
+                                           Message::Type::EMPTY_BUFFER_DONE) {
+                    if (iBuffers) {
+                        size_t i;
+                        for (i = 0; i < iBuffers->size(); ++i) {
+                            if ((*iBuffers)[i].id ==
+                                it->data.bufferData.buffer) {
+                                iBuffers->editItemAt(i).owner = client;
+                                msgQueue.erase(it);
+                                break;
+                            }
+                        }
+                        EXPECT_LE(i, iBuffers->size());
+                    }
+                }
+                ++it;
+            }
+            android::status_t err =
+                (timeoutUs < 0)
+                    ? msgCondition.wait(msgLock)
+                    : msgCondition.waitRelative(
+                          msgLock,
+                          (finishBy - android::ALooper::GetNowUs()) * 1000);
+            if (err == android::TIMED_OUT) return toStatus(err);
+        }
+    }
+
+    android::List<Message> msgQueue;
+    android::Mutex msgLock;
+    android::Condition msgCondition;
+};
+
+/*
+ * Useful Wrapper utilities
+ */
+template <class T>
+void InitOMXParams(T* params) {
+    params->nSize = sizeof(T);
+    params->nVersion.s.nVersionMajor = 1;
+    params->nVersion.s.nVersionMinor = 0;
+    params->nVersion.s.nRevision = 0;
+    params->nVersion.s.nStep = 0;
+}
+
+template <class T>
+Return<android::hardware::media::omx::V1_0::Status> getParam(
+    sp<IOmxNode> omxNode, OMX_INDEXTYPE omxIdx, T* params) {
+    android::hardware::media::omx::V1_0::Status status;
+    InitOMXParams(params);
+    omxNode->getParameter(
+        toRawIndexType(omxIdx), inHidlBytes(params, sizeof(*params)),
+        [&status, &params](android::hardware::media::omx::V1_0::Status _s,
+                           hidl_vec<uint8_t> const& outParams) {
+            status = _s;
+            std::copy(outParams.data(), outParams.data() + outParams.size(),
+                      static_cast<uint8_t*>(static_cast<void*>(params)));
+        });
+    return status;
+}
+
+template <class T>
+Return<android::hardware::media::omx::V1_0::Status> setParam(
+    sp<IOmxNode> omxNode, OMX_INDEXTYPE omxIdx, T* params) {
+    InitOMXParams(params);
+    return omxNode->setParameter(toRawIndexType(omxIdx),
+                                 inHidlBytes(params, sizeof(*params)));
+}
+
+template <class T>
+Return<android::hardware::media::omx::V1_0::Status> getPortParam(
+    sp<IOmxNode> omxNode, OMX_INDEXTYPE omxIdx, OMX_U32 nPortIndex, T* params) {
+    android::hardware::media::omx::V1_0::Status status;
+    InitOMXParams(params);
+    params->nPortIndex = nPortIndex;
+    omxNode->getParameter(
+        toRawIndexType(omxIdx), inHidlBytes(params, sizeof(*params)),
+        [&status, &params](android::hardware::media::omx::V1_0::Status _s,
+                           hidl_vec<uint8_t> const& outParams) {
+            status = _s;
+            std::copy(outParams.data(), outParams.data() + outParams.size(),
+                      static_cast<uint8_t*>(static_cast<void*>(params)));
+        });
+    return status;
+}
+
+template <class T>
+Return<android::hardware::media::omx::V1_0::Status> setPortParam(
+    sp<IOmxNode> omxNode, OMX_INDEXTYPE omxIdx, OMX_U32 nPortIndex, T* params) {
+    InitOMXParams(params);
+    params->nPortIndex = nPortIndex;
+    return omxNode->setParameter(toRawIndexType(omxIdx),
+                                 inHidlBytes(params, sizeof(*params)));
+}
+
+#endif  // MEDIA_HIDL_TEST_COMMON_H
diff --git a/media/omx/1.0/vts/functional/component/Android.bp b/media/omx/1.0/vts/functional/component/Android.bp
new file mode 100644
index 0000000..02fe182
--- /dev/null
+++ b/media/omx/1.0/vts/functional/component/Android.bp
@@ -0,0 +1,45 @@
+//
+// Copyright (C) 2017 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+cc_test {
+    name: "VtsHalMediaOmxV1_0TargetComponentTest",
+    defaults: ["hidl_defaults"],
+    srcs: ["VtsHalMediaOmxV1_0TargetComponentTest.cpp"],
+    shared_libs: [
+        "libbase",
+        "liblog",
+        "libcutils",
+        "libhidlbase",
+        "libhidltransport",
+        "libhwbinder",
+        "libnativehelper",
+        "libutils",
+        "libstagefright_foundation",
+        "android.hidl.allocator@1.0",
+        "android.hidl.memory@1.0",
+        "android.hardware.media.omx@1.0",
+    ],
+    static_libs: ["VtsHalHidlTargetTestBase"],
+    cflags: [
+        "-O0",
+        "-g",
+    ],
+    include_dirs: [
+        "frameworks/native/include/media/openmax/",
+        "hardware/interfaces/media/omx/1.0/vts/functional/common",
+    ],
+}
+
diff --git a/media/omx/1.0/vts/functional/component/VtsHalMediaOmxV1_0TargetComponentTest.cpp b/media/omx/1.0/vts/functional/component/VtsHalMediaOmxV1_0TargetComponentTest.cpp
new file mode 100644
index 0000000..fdffd66
--- /dev/null
+++ b/media/omx/1.0/vts/functional/component/VtsHalMediaOmxV1_0TargetComponentTest.cpp
@@ -0,0 +1,1213 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "media_omx_hidl_component_test"
+#include <android-base/logging.h>
+
+#include <android/hardware/media/omx/1.0/IOmx.h>
+#include <android/hardware/media/omx/1.0/IOmxNode.h>
+#include <android/hardware/media/omx/1.0/IOmxObserver.h>
+#include <android/hardware/media/omx/1.0/types.h>
+#include <android/hidl/allocator/1.0/IAllocator.h>
+#include <android/hidl/memory/1.0/IMapper.h>
+#include <android/hidl/memory/1.0/IMemory.h>
+
+using ::android::hardware::media::omx::V1_0::IOmx;
+using ::android::hardware::media::omx::V1_0::IOmxObserver;
+using ::android::hardware::media::omx::V1_0::IOmxNode;
+using ::android::hardware::media::omx::V1_0::Message;
+using ::android::hardware::media::omx::V1_0::CodecBuffer;
+using ::android::hidl::allocator::V1_0::IAllocator;
+using ::android::hidl::memory::V1_0::IMemory;
+using ::android::hidl::memory::V1_0::IMapper;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::hidl_string;
+using ::android::sp;
+
+#include <VtsHalHidlTargetTestBase.h>
+#include <getopt.h>
+#include <media_hidl_test_common.h>
+
+// A class for test environment setup
+class ComponentTestEnvironment : public ::testing::Environment {
+   public:
+    virtual void SetUp() {}
+    virtual void TearDown() {}
+
+    ComponentTestEnvironment() : instance("default") {}
+
+    void setInstance(const char* _instance) { instance = _instance; }
+
+    void setComponent(const char* _component) { component = _component; }
+
+    void setRole(const char* _role) { role = _role; }
+
+    void setQuirks(int _quirks) { quirks = _quirks; }
+
+    const hidl_string getInstance() const { return instance; }
+
+    const hidl_string getComponent() const { return component; }
+
+    const hidl_string getRole() const { return role; }
+
+    int getQuirks() const { return quirks; }
+
+    int initFromOptions(int argc, char** argv) {
+        static struct option options[] = {
+            {"instance", required_argument, 0, 'I'},
+            {"component", required_argument, 0, 'C'},
+            {"role", required_argument, 0, 'R'},
+            {"quirks", required_argument, 0, 'Q'},
+            {0, 0, 0, 0}};
+
+        while (true) {
+            int index = 0;
+            int c = getopt_long(argc, argv, "I:C:Q:R:", options, &index);
+            if (c == -1) {
+                break;
+            }
+
+            switch (c) {
+                case 'I':
+                    setInstance(optarg);
+                    break;
+                case 'C':
+                    setComponent(optarg);
+                    break;
+                case 'Q':
+                    setQuirks(atoi(optarg));
+                    break;
+                case 'R':
+                    setRole(optarg);
+                    break;
+                case '?':
+                    break;
+            }
+        }
+
+        if (optind < argc) {
+            fprintf(stderr,
+                    "unrecognized option: %s\n\n"
+                    "usage: %s <gtest options> <test options>\n\n"
+                    "test options are:\n\n"
+                    "-I, --instance: HAL instance to test\n"
+                    "-C, --component: OMX component to test\n"
+                    "-R, --Role: OMX component Role\n"
+                    "-Q, --quirks: Component quirks\n",
+                    argv[optind ?: 1], argv[0]);
+            return 2;
+        }
+        return 0;
+    }
+
+   private:
+    hidl_string instance;
+    hidl_string component;
+    hidl_string role;
+    // to be removed when IOmxNode::setQuirks is removed
+    int quirks;
+};
+
+static ComponentTestEnvironment* gEnv = nullptr;
+
+class ComponentHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+   public:
+    virtual void SetUp() override {
+        android::hardware::media::omx::V1_0::Status status;
+        omx = ::testing::VtsHalHidlTargetTestBase::getService<IOmx>(
+            gEnv->getInstance());
+        ASSERT_NE(omx, nullptr);
+        observer = new CodecObserver();
+        ASSERT_NE(observer, nullptr);
+        ASSERT_EQ(strncmp(gEnv->getComponent().c_str(), "OMX.", 4), 0)
+            << "Invalid Component Name";
+        EXPECT_TRUE(omx->allocateNode(
+                           gEnv->getComponent(), observer,
+                           [&](android::hardware::media::omx::V1_0::Status _s,
+                               sp<IOmxNode> const& _nl) {
+                               status = _s;
+                               this->omxNode = _nl;
+                           })
+                        .isOk());
+        ASSERT_NE(omxNode, nullptr);
+        ASSERT_NE(gEnv->getRole().empty(), true) << "Invalid Component Role";
+        struct StringToClass {
+            const char* Class;
+            standardCompClass CompClass;
+        };
+        const StringToClass kStringToClass[] = {
+            {"audio_decoder", audio_decoder},
+            {"audio_encoder", audio_encoder},
+            {"video_decoder", video_decoder},
+            {"video_encoder", video_encoder},
+        };
+        const size_t kNumStringToClass =
+            sizeof(kStringToClass) / sizeof(kStringToClass[0]);
+        const char* pch;
+        char substring[OMX_MAX_STRINGNAME_SIZE];
+        strcpy(substring, gEnv->getRole().c_str());
+        pch = strchr(substring, '.');
+        ASSERT_NE(pch, nullptr) << "Invalid Component Role";
+        substring[pch - substring] = '\0';
+        compClass = unknown_class;
+        for (size_t i = 0; i < kNumStringToClass; ++i) {
+            if (!strcasecmp(substring, kStringToClass[i].Class)) {
+                compClass = kStringToClass[i].CompClass;
+                break;
+            }
+        }
+        ASSERT_NE(compClass, unknown_class) << "Invalid Component Class";
+
+        allocator = ::testing::VtsHalHidlTargetTestBase::getService<IAllocator>(
+            "ashmem");
+        ASSERT_NE(allocator, nullptr);
+    }
+
+    virtual void TearDown() override {
+        if (omxNode != nullptr) {
+            EXPECT_TRUE((omxNode->freeNode()).isOk());
+            omxNode = nullptr;
+        }
+    }
+
+    enum standardCompClass {
+        audio_decoder,
+        audio_encoder,
+        video_decoder,
+        video_encoder,
+        unknown_class,
+    };
+
+    sp<IOmx> omx;
+    sp<CodecObserver> observer;
+    sp<IOmxNode> omxNode;
+    sp<IAllocator> allocator;
+    standardCompClass compClass;
+};
+
+#define RANDOM_INDEX 1729
+
+void allocatePortBuffers(sp<IOmxNode> omxNode, sp<IAllocator> allocator,
+                         android::Vector<BufferInfo>* buffArray,
+                         OMX_U32 portIndex) {
+    android::hardware::media::omx::V1_0::Status status;
+    OMX_PARAM_PORTDEFINITIONTYPE portDef;
+
+    buffArray->clear();
+
+    status = getPortParam(omxNode, OMX_IndexParamPortDefinition, portIndex,
+                          &portDef);
+    ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+    for (size_t i = 0; i < portDef.nBufferCountActual; i++) {
+        BufferInfo buffer;
+        buffer.owner = client;
+        buffer.omxBuffer.type = CodecBuffer::Type::SHARED_MEM;
+        buffer.omxBuffer.attr.preset.rangeOffset = 0;
+        buffer.omxBuffer.attr.preset.rangeLength = 0;
+        bool success;
+        allocator->allocate(
+            portDef.nBufferSize,
+            [&success, &buffer](bool _s,
+                                ::android::hardware::hidl_memory const& mem) {
+                success = _s;
+                buffer.omxBuffer.sharedMemory = mem;
+            });
+        ASSERT_EQ(success, true);
+
+        omxNode->useBuffer(
+            portIndex, buffer.omxBuffer,
+            [&status, &buffer](android::hardware::media::omx::V1_0::Status _s,
+                               uint32_t id) {
+                status = _s;
+                buffer.id = id;
+            });
+        buffArray->push(buffer);
+        ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+    }
+}
+
+Return<android::hardware::media::omx::V1_0::Status> setVideoPortFormat(
+    sp<IOmxNode> omxNode, OMX_U32 portIndex,
+    OMX_VIDEO_CODINGTYPE compressionFormat, OMX_COLOR_FORMATTYPE colorFormat,
+    OMX_U32 frameRate) {
+    OMX_U32 index = 0;
+    OMX_VIDEO_PARAM_PORTFORMATTYPE portFormat;
+    std::vector<OMX_COLOR_FORMATTYPE> eColorFormat;
+    std::vector<OMX_VIDEO_CODINGTYPE> eCompressionFormat;
+    android::hardware::media::omx::V1_0::Status status;
+
+    while (1) {
+        portFormat.nIndex = index;
+        status = getPortParam(omxNode, OMX_IndexParamVideoPortFormat, portIndex,
+                              &portFormat);
+        if (status != ::android::hardware::media::omx::V1_0::Status::OK) break;
+        if (compressionFormat == OMX_VIDEO_CodingUnused)
+            eColorFormat.push_back(portFormat.eColorFormat);
+        else
+            eCompressionFormat.push_back(portFormat.eCompressionFormat);
+        index++;
+        if (index == 512) {
+            EXPECT_LE(index, 512U)
+                << "Expecting OMX_ErrorNoMore but not received";
+            break;
+        }
+    }
+    if (!index) return status;
+    if (compressionFormat == OMX_VIDEO_CodingUnused) {
+        for (index = 0; index < eColorFormat.size(); index++) {
+            if (eColorFormat[index] == colorFormat) {
+                portFormat.eColorFormat = eColorFormat[index];
+                break;
+            }
+        }
+        if (index == eColorFormat.size()) {
+            ALOGI("setting default color format");
+            portFormat.eColorFormat = eColorFormat[0];
+        }
+        portFormat.eCompressionFormat = OMX_VIDEO_CodingUnused;
+    } else {
+        for (index = 0; index < eCompressionFormat.size(); index++) {
+            if (eCompressionFormat[index] == compressionFormat) {
+                portFormat.eCompressionFormat = eCompressionFormat[index];
+                break;
+            }
+        }
+        if (index == eCompressionFormat.size()) {
+            ALOGI("setting default compression format");
+            portFormat.eCompressionFormat = eCompressionFormat[0];
+        }
+        portFormat.eColorFormat = OMX_COLOR_FormatUnused;
+    }
+    // In setParam call nIndex shall be ignored as per omx-il specification.
+    // see how this holds up by corrupting nIndex
+    portFormat.nIndex = RANDOM_INDEX;
+    portFormat.xFramerate = frameRate;
+    status = setPortParam(omxNode, OMX_IndexParamVideoPortFormat, portIndex,
+                          &portFormat);
+    return status;
+}
+
+Return<android::hardware::media::omx::V1_0::Status> setAudioPortFormat(
+    sp<IOmxNode> omxNode, OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE encoding) {
+    OMX_U32 index = 0;
+    OMX_AUDIO_PARAM_PORTFORMATTYPE portFormat;
+    std::vector<OMX_AUDIO_CODINGTYPE> eEncoding;
+    android::hardware::media::omx::V1_0::Status status;
+
+    while (1) {
+        portFormat.nIndex = index;
+        status = getPortParam(omxNode, OMX_IndexParamAudioPortFormat, portIndex,
+                              &portFormat);
+        if (status != ::android::hardware::media::omx::V1_0::Status::OK) break;
+        eEncoding.push_back(portFormat.eEncoding);
+        index++;
+        if (index == 512) {
+            EXPECT_LE(index, 512U)
+                << "Expecting OMX_ErrorNoMore but not received";
+            break;
+        }
+    }
+    if (!index) return status;
+    for (index = 0; index < eEncoding.size(); index++) {
+        if (eEncoding[index] == encoding) {
+            portFormat.eEncoding = eEncoding[index];
+            break;
+        }
+    }
+    if (index == eEncoding.size()) {
+        ALOGI("setting default Port format");
+        portFormat.eEncoding = eEncoding[0];
+    }
+    // In setParam call nIndex shall be ignored as per omx-il specification.
+    // see how this holds up by corrupting nIndex
+    portFormat.nIndex = RANDOM_INDEX;
+    status = setPortParam(omxNode, OMX_IndexParamAudioPortFormat, portIndex,
+                          &portFormat);
+    return status;
+}
+
+Return<android::hardware::media::omx::V1_0::Status> setRole(
+    sp<IOmxNode> omxNode, const char* role) {
+    OMX_PARAM_COMPONENTROLETYPE params;
+    strcpy((char*)params.cRole, role);
+    return setParam(omxNode, OMX_IndexParamStandardComponentRole, &params);
+}
+
+// Set Component Role
+TEST_F(ComponentHidlTest, SetRole) {
+    android::hardware::media::omx::V1_0::Status status;
+    status = setRole(omxNode, gEnv->getRole().c_str());
+    EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+}
+
+// Get Number of Ports and their Indices for all Domains
+// (Audio/Video/Image/Other)
+TEST_F(ComponentHidlTest, GetPortIndices) {
+    android::hardware::media::omx::V1_0::Status status;
+    OMX_PORT_PARAM_TYPE params;
+
+    status = setRole(omxNode, gEnv->getRole().c_str());
+    ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+
+    // All standard OMX components shall support following OMX Index types
+    status = getParam(omxNode, OMX_IndexParamAudioInit, &params);
+    EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+    status = getParam(omxNode, OMX_IndexParamVideoInit, &params);
+    EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+    status = getParam(omxNode, OMX_IndexParamImageInit, &params);
+    EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+    status = getParam(omxNode, OMX_IndexParamOtherInit, &params);
+    EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+}
+
+// Enumerate Port Format
+TEST_F(ComponentHidlTest, EnumeratePortFormat) {
+    android::hardware::media::omx::V1_0::Status status;
+    uint32_t kPortIndexInput = 0, kPortIndexOutput = 1;
+
+    status = setRole(omxNode, gEnv->getRole().c_str());
+    ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+    OMX_PORT_PARAM_TYPE params;
+    if (compClass == audio_decoder || compClass == audio_encoder) {
+        status = getParam(omxNode, OMX_IndexParamAudioInit, &params);
+    } else {
+        status = getParam(omxNode, OMX_IndexParamVideoInit, &params);
+    }
+    if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
+        ASSERT_EQ(params.nPorts, 2U);
+        kPortIndexInput = params.nStartPortNumber;
+        kPortIndexOutput = kPortIndexInput + 1;
+    }
+
+    OMX_COLOR_FORMATTYPE colorFormat = OMX_COLOR_FormatYUV420Planar;
+    OMX_U32 frameRate = 24 << 16;
+
+    if (compClass == audio_encoder) {
+        status =
+            setAudioPortFormat(omxNode, kPortIndexInput, OMX_AUDIO_CodingPCM);
+        EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+        status = setAudioPortFormat(omxNode, kPortIndexOutput,
+                                    OMX_AUDIO_CodingAutoDetect);
+        EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+    } else if (compClass == audio_decoder) {
+        status = setAudioPortFormat(omxNode, kPortIndexInput,
+                                    OMX_AUDIO_CodingAutoDetect);
+        EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+        status =
+            setAudioPortFormat(omxNode, kPortIndexOutput, OMX_AUDIO_CodingPCM);
+        EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+    } else if (compClass == video_encoder) {
+        status =
+            setVideoPortFormat(omxNode, kPortIndexInput, OMX_VIDEO_CodingUnused,
+                               colorFormat, frameRate);
+        EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+        status = setVideoPortFormat(omxNode, kPortIndexOutput,
+                                    OMX_VIDEO_CodingAutoDetect,
+                                    OMX_COLOR_FormatUnused, 0U);
+        EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+    } else {
+        status = setVideoPortFormat(omxNode, kPortIndexInput,
+                                    OMX_VIDEO_CodingAutoDetect,
+                                    OMX_COLOR_FormatUnused, 0U);
+        EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+        status =
+            setVideoPortFormat(omxNode, kPortIndexOutput,
+                               OMX_VIDEO_CodingUnused, colorFormat, frameRate);
+        EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+    }
+}
+
+// r/w default i/o port parameters
+TEST_F(ComponentHidlTest, SetDefaultPortParams) {
+    android::hardware::media::omx::V1_0::Status status;
+    uint32_t kPortIndexInput = 0, kPortIndexOutput = 1;
+
+    status = setRole(omxNode, gEnv->getRole().c_str());
+    ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+    OMX_PORT_PARAM_TYPE params;
+    if (compClass == audio_decoder || compClass == audio_encoder) {
+        status = getParam(omxNode, OMX_IndexParamAudioInit, &params);
+    } else {
+        status = getParam(omxNode, OMX_IndexParamVideoInit, &params);
+    }
+    if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
+        ASSERT_EQ(params.nPorts, 2U);
+        kPortIndexInput = params.nStartPortNumber;
+        kPortIndexOutput = kPortIndexInput + 1;
+    }
+
+    OMX_PARAM_PORTDEFINITIONTYPE iPortDef;
+    status = getPortParam(omxNode, OMX_IndexParamPortDefinition,
+                          kPortIndexInput, &iPortDef);
+    EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+
+    if (status == android::hardware::media::omx::V1_0::Status::OK) {
+        EXPECT_EQ(iPortDef.eDir, OMX_DirInput);
+        EXPECT_EQ(iPortDef.bEnabled, OMX_TRUE);
+        EXPECT_EQ(iPortDef.bPopulated, 0);
+        EXPECT_GE(iPortDef.nBufferCountMin, 1U);
+        EXPECT_GE(iPortDef.nBufferCountActual, iPortDef.nBufferCountMin);
+        if (compClass == audio_encoder || compClass == audio_decoder) {
+            EXPECT_EQ(iPortDef.eDomain, OMX_PortDomainAudio);
+            if (compClass == audio_decoder) {
+                iPortDef.format.audio.bFlagErrorConcealment = OMX_TRUE;
+                status = setPortParam(omxNode, OMX_IndexParamPortDefinition,
+                                      kPortIndexInput, &iPortDef);
+            }
+            EXPECT_EQ(status,
+                      ::android::hardware::media::omx::V1_0::Status::OK);
+        } else if (compClass == video_encoder || compClass == video_decoder) {
+            EXPECT_EQ(iPortDef.eDomain, OMX_PortDomainVideo);
+        }
+        OMX_PARAM_PORTDEFINITIONTYPE dummy = iPortDef;
+        iPortDef.nBufferCountActual = iPortDef.nBufferCountMin - 1;
+        status = setPortParam(omxNode, OMX_IndexParamPortDefinition,
+                              kPortIndexInput, &iPortDef);
+        EXPECT_NE(status, ::android::hardware::media::omx::V1_0::Status::OK);
+        // Edit Read-Only fields.
+        iPortDef.eDir = OMX_DirOutput;  // Read Only field
+        iPortDef.nBufferCountActual = dummy.nBufferCountActual << 1;
+        iPortDef.nBufferCountMin = dummy.nBufferCountMin
+                                   << 1;                // Read Only field
+        iPortDef.nBufferSize = dummy.nBufferSize << 1;  // Read Only field
+        status = setPortParam(omxNode, OMX_IndexParamPortDefinition,
+                              kPortIndexInput, &iPortDef);
+        EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+        status = getPortParam(omxNode, OMX_IndexParamPortDefinition,
+                              kPortIndexInput, &iPortDef);
+        EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+        EXPECT_EQ(iPortDef.nBufferCountActual, dummy.nBufferCountActual << 1);
+        if ((iPortDef.eDir != OMX_DirInput) ||
+            (iPortDef.nBufferCountMin != dummy.nBufferCountMin) ||
+            (iPortDef.nBufferSize != dummy.nBufferSize)) {
+            ALOGI(
+                "Warning, Component does not seem to preserve Read-Only "
+                "fields");
+            printf(
+                "Warning, Component does not seem to preserve Read-Only fields "
+                "\n");
+        }
+    }
+
+    OMX_PARAM_PORTDEFINITIONTYPE oPortDef;
+    status = getPortParam(omxNode, OMX_IndexParamPortDefinition,
+                          kPortIndexOutput, &oPortDef);
+    EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+    if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
+        EXPECT_EQ(oPortDef.eDir, OMX_DirOutput);
+        EXPECT_EQ(oPortDef.bEnabled, OMX_TRUE);
+        EXPECT_EQ(oPortDef.bPopulated, 0);
+        EXPECT_GE(oPortDef.nBufferCountMin, 1U);
+        EXPECT_GE(oPortDef.nBufferCountActual, oPortDef.nBufferCountMin);
+        if (compClass == audio_encoder || compClass == audio_decoder) {
+            EXPECT_EQ(oPortDef.eDomain, OMX_PortDomainAudio);
+            if (compClass == audio_encoder) {
+                oPortDef.format.audio.bFlagErrorConcealment = OMX_TRUE;
+                status = setPortParam(omxNode, OMX_IndexParamPortDefinition,
+                                      kPortIndexOutput, &oPortDef);
+            }
+            EXPECT_EQ(status,
+                      ::android::hardware::media::omx::V1_0::Status::OK);
+        } else if (compClass == video_encoder || compClass == video_decoder) {
+            EXPECT_EQ(oPortDef.eDomain, OMX_PortDomainVideo);
+        }
+        OMX_PARAM_PORTDEFINITIONTYPE dummy = oPortDef;
+        oPortDef.nBufferCountActual = oPortDef.nBufferCountMin - 1;
+        status = setPortParam(omxNode, OMX_IndexParamPortDefinition,
+                              kPortIndexOutput, &oPortDef);
+        EXPECT_NE(status, ::android::hardware::media::omx::V1_0::Status::OK);
+        // Edit Read-Only fields.
+        oPortDef.eDir = OMX_DirInput;  // Read Only field
+        oPortDef.nBufferCountActual = dummy.nBufferCountActual << 1;
+        oPortDef.nBufferCountMin = dummy.nBufferCountMin
+                                   << 1;                // Read Only field
+        oPortDef.nBufferSize = dummy.nBufferSize << 1;  // Read Only field
+        status = setPortParam(omxNode, OMX_IndexParamPortDefinition,
+                              kPortIndexOutput, &oPortDef);
+        EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+        status = getPortParam(omxNode, OMX_IndexParamPortDefinition,
+                              kPortIndexOutput, &oPortDef);
+        EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+        EXPECT_EQ(oPortDef.nBufferCountActual, dummy.nBufferCountActual << 1);
+        if ((oPortDef.eDir != OMX_DirOutput) ||
+            (oPortDef.nBufferCountMin != dummy.nBufferCountMin) ||
+            (oPortDef.nBufferSize != dummy.nBufferSize)) {
+            ALOGI(
+                "Warning, Component does not seem to preserve Read-Only "
+                "fields");
+            printf(
+                "Warning, Component does not seem to preserve Read-Only fields "
+                "\n");
+        }
+    }
+}
+
+// Test State Transitions & Flush
+TEST_F(ComponentHidlTest, StateTransitions_Flush) {
+    android::hardware::media::omx::V1_0::Status status;
+    uint32_t kPortIndexInput = 0, kPortIndexOutput = 1;
+    Message msg;
+
+    status = setRole(omxNode, gEnv->getRole().c_str());
+    ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+    OMX_PORT_PARAM_TYPE params;
+    if (compClass == audio_decoder || compClass == audio_encoder) {
+        status = getParam(omxNode, OMX_IndexParamAudioInit, &params);
+    } else {
+        status = getParam(omxNode, OMX_IndexParamVideoInit, &params);
+    }
+    if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
+        ASSERT_EQ(params.nPorts, 2U);
+        kPortIndexInput = params.nStartPortNumber;
+        kPortIndexOutput = kPortIndexInput + 1;
+    }
+
+    android::Vector<BufferInfo> iBuffer, oBuffer;
+
+    // set state to idle
+    status = omxNode->sendCommand(toRawCommandType(OMX_CommandStateSet),
+                                  OMX_StateIdle);
+    ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+
+    // Dont switch states until the ports got their buffers
+    status =
+        observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, &iBuffer, &oBuffer);
+    ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::TIMED_OUT);
+
+    // allocate buffers on input port
+    allocatePortBuffers(omxNode, allocator, &iBuffer, kPortIndexInput);
+
+    // Dont switch states until the ports got their buffers
+    status =
+        observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, &iBuffer, &oBuffer);
+    ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::TIMED_OUT);
+
+    // allocate buffers on output port
+    allocatePortBuffers(omxNode, allocator, &oBuffer, kPortIndexOutput);
+
+    status =
+        observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, &iBuffer, &oBuffer);
+    ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+    ASSERT_EQ(msg.type, Message::Type::EVENT);
+    ASSERT_EQ(msg.data.eventData.event, OMX_EventCmdComplete);
+    ASSERT_EQ(msg.data.eventData.data1, OMX_CommandStateSet);
+    ASSERT_EQ(msg.data.eventData.data2, OMX_StateIdle);
+
+    // set state to executing
+    status = omxNode->sendCommand(toRawCommandType(OMX_CommandStateSet),
+                                  OMX_StateExecuting);
+    ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+    status =
+        observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, &iBuffer, &oBuffer);
+    ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+    ASSERT_EQ(msg.type, Message::Type::EVENT);
+    ASSERT_EQ(msg.data.eventData.event, OMX_EventCmdComplete);
+    ASSERT_EQ(msg.data.eventData.data1, OMX_CommandStateSet);
+    ASSERT_EQ(msg.data.eventData.data2, OMX_StateExecuting);
+
+    CodecBuffer t;
+    t.sharedMemory = android::hardware::hidl_memory();
+    t.nativeHandle = android::hardware::hidl_handle();
+    t.type = CodecBuffer::Type::PRESET;
+    t.attr.preset.rangeOffset = 0;
+    t.attr.preset.rangeLength = 0;
+    for (size_t i = 0; i < oBuffer.size(); ++i) {
+        native_handle_t* fenceNh = native_handle_create(0, 0);
+        status = omxNode->fillBuffer(oBuffer[i].id, t, fenceNh);
+        native_handle_close(fenceNh);
+        native_handle_delete(fenceNh);
+        ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+        oBuffer.editItemAt(i).owner = component;
+    }
+
+    // set state to Idle
+    status = omxNode->sendCommand(toRawCommandType(OMX_CommandStateSet),
+                                  OMX_StateIdle);
+    ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+    status =
+        observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, &iBuffer, &oBuffer);
+    ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+    ASSERT_EQ(msg.type, Message::Type::EVENT);
+    ASSERT_EQ(msg.data.eventData.event, OMX_EventCmdComplete);
+    ASSERT_EQ(msg.data.eventData.data1, OMX_CommandStateSet);
+    ASSERT_EQ(msg.data.eventData.data2, OMX_StateIdle);
+
+    // test if client got all its buffers back
+    for (size_t i = 0; i < oBuffer.size(); ++i) {
+        EXPECT_EQ(oBuffer[i].owner, client);
+    }
+
+    // set state to executing
+    status = omxNode->sendCommand(toRawCommandType(OMX_CommandStateSet),
+                                  OMX_StateExecuting);
+    ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+    status =
+        observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, &iBuffer, &oBuffer);
+    ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+    ASSERT_EQ(msg.type, Message::Type::EVENT);
+    ASSERT_EQ(msg.data.eventData.event, OMX_EventCmdComplete);
+    ASSERT_EQ(msg.data.eventData.data1, OMX_CommandStateSet);
+    ASSERT_EQ(msg.data.eventData.data2, OMX_StateExecuting);
+
+    for (size_t i = 0; i < oBuffer.size(); i += 2) {
+        native_handle_t* fenceNh = native_handle_create(0, 0);
+        status = omxNode->fillBuffer(oBuffer[i].id, t, fenceNh);
+        native_handle_close(fenceNh);
+        native_handle_delete(fenceNh);
+        ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+        oBuffer.editItemAt(i).owner = component;
+    }
+
+    status = omxNode->sendCommand(toRawCommandType(OMX_CommandFlush),
+                                  kPortIndexOutput);
+    ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+    status =
+        observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, &iBuffer, &oBuffer);
+    ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+    ASSERT_EQ(msg.type, Message::Type::EVENT);
+    ASSERT_EQ(msg.data.eventData.event, OMX_EventCmdComplete);
+    ASSERT_EQ(msg.data.eventData.data1, OMX_CommandFlush);
+    ASSERT_EQ(msg.data.eventData.data2, kPortIndexOutput);
+
+    // test if client got all its buffers back
+    for (size_t i = 0; i < oBuffer.size(); ++i) {
+        EXPECT_EQ(oBuffer[i].owner, client);
+    }
+
+    // set state to Idle
+    status = omxNode->sendCommand(toRawCommandType(OMX_CommandStateSet),
+                                  OMX_StateIdle);
+    ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+    status =
+        observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, &iBuffer, &oBuffer);
+    ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+    ASSERT_EQ(msg.type, Message::Type::EVENT);
+    ASSERT_EQ(msg.data.eventData.event, OMX_EventCmdComplete);
+    ASSERT_EQ(msg.data.eventData.data1, OMX_CommandStateSet);
+    ASSERT_EQ(msg.data.eventData.data2, OMX_StateIdle);
+
+    // set state to Loaded
+    status = omxNode->sendCommand(toRawCommandType(OMX_CommandStateSet),
+                                  OMX_StateLoaded);
+    ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+
+    // dont change state until all buffers are freed
+    status =
+        observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, &iBuffer, &oBuffer);
+    ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::TIMED_OUT);
+
+    for (size_t i = 0; i < iBuffer.size(); ++i) {
+        status = omxNode->freeBuffer(kPortIndexInput, iBuffer[i].id);
+        ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+    }
+
+    // dont change state until all buffers are freed
+    status =
+        observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, &iBuffer, &oBuffer);
+    ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::TIMED_OUT);
+
+    for (size_t i = 0; i < oBuffer.size(); ++i) {
+        status = omxNode->freeBuffer(kPortIndexOutput, oBuffer[i].id);
+        ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+    }
+
+    status =
+        observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, &iBuffer, &oBuffer);
+    ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+    ASSERT_EQ(msg.type, Message::Type::EVENT);
+    ASSERT_EQ(msg.data.eventData.event, OMX_EventCmdComplete);
+    ASSERT_EQ(msg.data.eventData.data1, OMX_CommandStateSet);
+    ASSERT_EQ(msg.data.eventData.data2, OMX_StateLoaded);
+}
+
+// Test State Transitions
+TEST_F(ComponentHidlTest, StateTransitions_M) {
+    android::hardware::media::omx::V1_0::Status status;
+    uint32_t kPortIndexInput = 0, kPortIndexOutput = 1;
+    Message msg;
+
+    status = setRole(omxNode, gEnv->getRole().c_str());
+    ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+    OMX_PORT_PARAM_TYPE params;
+    if (compClass == audio_decoder || compClass == audio_encoder) {
+        status = getParam(omxNode, OMX_IndexParamAudioInit, &params);
+    } else {
+        status = getParam(omxNode, OMX_IndexParamVideoInit, &params);
+    }
+    if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
+        ASSERT_EQ(params.nPorts, 2U);
+        kPortIndexInput = params.nStartPortNumber;
+        kPortIndexOutput = kPortIndexInput + 1;
+    }
+
+    android::Vector<BufferInfo> iBuffer, oBuffer;
+
+    // set state to loaded ; receive error OMX_ErrorSameState
+    status = omxNode->sendCommand(toRawCommandType(OMX_CommandStateSet),
+                                  OMX_StateLoaded);
+    EXPECT_NE(status, android::hardware::media::omx::V1_0::Status::OK);
+
+    // set state to executing ; receive error OMX_ErrorIncorrectStateTransition
+    status = omxNode->sendCommand(toRawCommandType(OMX_CommandStateSet),
+                                  OMX_StateExecuting);
+    EXPECT_NE(status, android::hardware::media::omx::V1_0::Status::OK);
+
+    // set state to idle
+    status = omxNode->sendCommand(toRawCommandType(OMX_CommandStateSet),
+                                  OMX_StateIdle);
+    ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+
+    // allocate buffers on i/o port
+    allocatePortBuffers(omxNode, allocator, &iBuffer, kPortIndexInput);
+    allocatePortBuffers(omxNode, allocator, &oBuffer, kPortIndexOutput);
+
+    status =
+        observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, &iBuffer, &oBuffer);
+    ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+    ASSERT_EQ(msg.type, Message::Type::EVENT);
+    ASSERT_EQ(msg.data.eventData.event, OMX_EventCmdComplete);
+    ASSERT_EQ(msg.data.eventData.data1, OMX_CommandStateSet);
+    ASSERT_EQ(msg.data.eventData.data2, OMX_StateIdle);
+
+    // set state to idle ; receive error OMX_ErrorSameState
+    status = omxNode->sendCommand(toRawCommandType(OMX_CommandStateSet),
+                                  OMX_StateIdle);
+    EXPECT_NE(status, android::hardware::media::omx::V1_0::Status::OK);
+
+    // set state to executing
+    status = omxNode->sendCommand(toRawCommandType(OMX_CommandStateSet),
+                                  OMX_StateExecuting);
+    ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+    status =
+        observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, &iBuffer, &oBuffer);
+    ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+    ASSERT_EQ(msg.type, Message::Type::EVENT);
+    ASSERT_EQ(msg.data.eventData.event, OMX_EventCmdComplete);
+    ASSERT_EQ(msg.data.eventData.data1, OMX_CommandStateSet);
+    ASSERT_EQ(msg.data.eventData.data2, OMX_StateExecuting);
+
+    // set state to executing ; receive error OMX_ErrorSameState
+    status = omxNode->sendCommand(toRawCommandType(OMX_CommandStateSet),
+                                  OMX_StateExecuting);
+    EXPECT_NE(status, android::hardware::media::omx::V1_0::Status::OK);
+
+    // set state to Loaded ; receive error OMX_ErrorIncorrectStateTransition
+    status = omxNode->sendCommand(toRawCommandType(OMX_CommandStateSet),
+                                  OMX_StateLoaded);
+    EXPECT_NE(status, android::hardware::media::omx::V1_0::Status::OK);
+
+    // set state to Idle
+    status = omxNode->sendCommand(toRawCommandType(OMX_CommandStateSet),
+                                  OMX_StateIdle);
+    ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+    status =
+        observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, &iBuffer, &oBuffer);
+    ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+    ASSERT_EQ(msg.type, Message::Type::EVENT);
+    ASSERT_EQ(msg.data.eventData.event, OMX_EventCmdComplete);
+    ASSERT_EQ(msg.data.eventData.data1, OMX_CommandStateSet);
+    ASSERT_EQ(msg.data.eventData.data2, OMX_StateIdle);
+
+    // set state to Loaded
+    status = omxNode->sendCommand(toRawCommandType(OMX_CommandStateSet),
+                                  OMX_StateLoaded);
+    ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+
+    for (size_t i = 0; i < iBuffer.size(); ++i) {
+        status = omxNode->freeBuffer(kPortIndexInput, iBuffer[i].id);
+        ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+    }
+    for (size_t i = 0; i < oBuffer.size(); ++i) {
+        status = omxNode->freeBuffer(kPortIndexOutput, oBuffer[i].id);
+        ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+    }
+
+    status =
+        observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, &iBuffer, &oBuffer);
+    ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+    ASSERT_EQ(msg.type, Message::Type::EVENT);
+    ASSERT_EQ(msg.data.eventData.event, OMX_EventCmdComplete);
+    ASSERT_EQ(msg.data.eventData.data1, OMX_CommandStateSet);
+    ASSERT_EQ(msg.data.eventData.data2, OMX_StateLoaded);
+}
+
+// Enable and Disable Input and Output ports when the component is in Loaded
+// State
+TEST_F(ComponentHidlTest, PortEnableDisable_Loaded) {
+    android::hardware::media::omx::V1_0::Status status;
+    OMX_U32 portBase = 0;
+    Message msg;
+    status = setRole(omxNode, gEnv->getRole().c_str());
+    ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+    OMX_PORT_PARAM_TYPE params;
+    if (compClass == audio_decoder || compClass == audio_encoder) {
+        status = getParam(omxNode, OMX_IndexParamAudioInit, &params);
+    } else {
+        status = getParam(omxNode, OMX_IndexParamVideoInit, &params);
+    }
+    if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
+        ASSERT_EQ(params.nPorts, 2U);
+        portBase = params.nStartPortNumber;
+    }
+
+    for (size_t i = portBase; i < portBase + 2; i++) {
+        status =
+            omxNode->sendCommand(toRawCommandType(OMX_CommandPortDisable), i);
+        ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+        status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT);
+        ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+        ASSERT_EQ(msg.type, Message::Type::EVENT);
+        if (msg.data.eventData.event == OMX_EventCmdComplete) {
+            ASSERT_EQ(msg.data.eventData.data1, OMX_CommandPortDisable);
+            ASSERT_EQ(msg.data.eventData.data2, i);
+            // If you can disable a port, then you should be able to enable it
+            // as well
+            status = omxNode->sendCommand(
+                toRawCommandType(OMX_CommandPortEnable), i);
+            ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+            status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT);
+            ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+            ASSERT_EQ(msg.type, Message::Type::EVENT);
+            ASSERT_EQ(msg.data.eventData.data1, OMX_CommandPortEnable);
+            ASSERT_EQ(msg.data.eventData.data2, i);
+        } else if (msg.data.eventData.event == OMX_EventError) {
+            ALOGI("Port %d Disabling failed with error %d", (int)i,
+                  (int)msg.data.eventData.event);
+        } else {
+            // something unexpected happened
+            ASSERT_TRUE(false);
+        }
+    }
+}
+
+// Enable and Disable Input and Output ports when the component is in Idle State
+TEST_F(ComponentHidlTest, PortEnableDisable_Idle) {
+    android::hardware::media::omx::V1_0::Status status;
+    uint32_t kPortIndexInput = 0, kPortIndexOutput = 1;
+    OMX_U32 portBase = 0;
+    Message msg;
+    status = setRole(omxNode, gEnv->getRole().c_str());
+    ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+    OMX_PORT_PARAM_TYPE params;
+    if (compClass == audio_decoder || compClass == audio_encoder) {
+        status = getParam(omxNode, OMX_IndexParamAudioInit, &params);
+    } else {
+        status = getParam(omxNode, OMX_IndexParamVideoInit, &params);
+    }
+    if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
+        ASSERT_EQ(params.nPorts, 2U);
+        portBase = params.nStartPortNumber;
+    }
+    kPortIndexInput = portBase;
+    kPortIndexOutput = portBase + 1;
+
+    // Component State :: Idle
+    android::Vector<BufferInfo> pBuffer[2];
+    // set state to idle
+    status = omxNode->sendCommand(toRawCommandType(OMX_CommandStateSet),
+                                  OMX_StateIdle);
+    ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+
+    // allocate buffers on input port
+    allocatePortBuffers(omxNode, allocator, &pBuffer[0], kPortIndexInput);
+    allocatePortBuffers(omxNode, allocator, &pBuffer[1], kPortIndexOutput);
+
+    status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, &pBuffer[0],
+                                      &pBuffer[1]);
+    ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+    ASSERT_EQ(msg.type, Message::Type::EVENT);
+    ASSERT_EQ(msg.data.eventData.event, OMX_EventCmdComplete);
+    ASSERT_EQ(msg.data.eventData.data1, OMX_CommandStateSet);
+    ASSERT_EQ(msg.data.eventData.data2, OMX_StateIdle);
+
+    for (size_t i = portBase; i < portBase + 2; i++) {
+        status =
+            omxNode->sendCommand(toRawCommandType(OMX_CommandPortDisable), i);
+        ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+
+        status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, &pBuffer[0],
+                                          &pBuffer[1]);
+        if (status == android::hardware::media::omx::V1_0::Status::OK) {
+            ASSERT_EQ(msg.type, Message::Type::EVENT);
+            if (msg.data.eventData.event == OMX_EventCmdComplete) {
+                // do not disable the port until all the buffers are freed
+                ASSERT_TRUE(false);
+            } else if (msg.data.eventData.event == OMX_EventError) {
+                ALOGI("Port %d Disabling failed with error %d", (int)i,
+                      (int)msg.data.eventData.event);
+            } else {
+                // something unexpected happened
+                ASSERT_TRUE(false);
+            }
+        } else if (status ==
+                   android::hardware::media::omx::V1_0::Status::TIMED_OUT) {
+            for (size_t j = 0; j < pBuffer[i - portBase].size(); ++j) {
+                status = omxNode->freeBuffer(i, pBuffer[i - portBase][j].id);
+                ASSERT_EQ(status,
+                          android::hardware::media::omx::V1_0::Status::OK);
+            }
+
+            status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT,
+                                              &pBuffer[0], &pBuffer[1]);
+            ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+            ASSERT_EQ(msg.type, Message::Type::EVENT);
+            ASSERT_EQ(msg.data.eventData.event, OMX_EventCmdComplete);
+            ASSERT_EQ(msg.data.eventData.data1, OMX_CommandPortDisable);
+            ASSERT_EQ(msg.data.eventData.data2, i);
+
+            // If you can disable a port, then you should be able to enable it
+            // as well
+            status = omxNode->sendCommand(
+                toRawCommandType(OMX_CommandPortEnable), i);
+            ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+
+            // do not enable the port until all the buffers are supplied
+            status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT,
+                                              &pBuffer[0], &pBuffer[1]);
+            ASSERT_EQ(status,
+                      android::hardware::media::omx::V1_0::Status::TIMED_OUT);
+
+            allocatePortBuffers(omxNode, allocator, &pBuffer[i - portBase], i);
+            status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT,
+                                              &pBuffer[0], &pBuffer[1]);
+            ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+            ASSERT_EQ(msg.type, Message::Type::EVENT);
+            ASSERT_EQ(msg.data.eventData.data1, OMX_CommandPortEnable);
+            ASSERT_EQ(msg.data.eventData.data2, i);
+        } else {
+            // something unexpected happened
+            ASSERT_TRUE(false);
+        }
+    }
+}
+
+// Enable and Disable Input and Output ports when the component is in execute
+TEST_F(ComponentHidlTest, PortEnableDisable_Execute) {
+    android::hardware::media::omx::V1_0::Status status;
+    uint32_t kPortIndexInput = 0, kPortIndexOutput = 1;
+    OMX_U32 portBase = 0;
+    Message msg;
+    status = setRole(omxNode, gEnv->getRole().c_str());
+    ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+    OMX_PORT_PARAM_TYPE params;
+    if (compClass == audio_decoder || compClass == audio_encoder) {
+        status = getParam(omxNode, OMX_IndexParamAudioInit, &params);
+    } else {
+        status = getParam(omxNode, OMX_IndexParamVideoInit, &params);
+    }
+    if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
+        ASSERT_EQ(params.nPorts, 2U);
+        portBase = params.nStartPortNumber;
+    }
+    kPortIndexInput = portBase;
+    kPortIndexOutput = portBase + 1;
+
+    // Component State :: Idle
+    android::Vector<BufferInfo> pBuffer[2];
+    // set state to idle
+    status = omxNode->sendCommand(toRawCommandType(OMX_CommandStateSet),
+                                  OMX_StateIdle);
+    ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+
+    // allocate buffers on input port
+    allocatePortBuffers(omxNode, allocator, &pBuffer[0], kPortIndexInput);
+    allocatePortBuffers(omxNode, allocator, &pBuffer[1], kPortIndexOutput);
+
+    status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, &pBuffer[0],
+                                      &pBuffer[1]);
+    ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+    ASSERT_EQ(msg.type, Message::Type::EVENT);
+    ASSERT_EQ(msg.data.eventData.event, OMX_EventCmdComplete);
+    ASSERT_EQ(msg.data.eventData.data1, OMX_CommandStateSet);
+    ASSERT_EQ(msg.data.eventData.data2, OMX_StateIdle);
+
+    // Component State :: Execute
+    status = omxNode->sendCommand(toRawCommandType(OMX_CommandStateSet),
+                                  OMX_StateExecuting);
+    ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+    status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, &pBuffer[0],
+                                      &pBuffer[1]);
+    ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+    ASSERT_EQ(msg.type, Message::Type::EVENT);
+    ASSERT_EQ(msg.data.eventData.event, OMX_EventCmdComplete);
+    ASSERT_EQ(msg.data.eventData.data1, OMX_CommandStateSet);
+    ASSERT_EQ(msg.data.eventData.data2, OMX_StateExecuting);
+
+    CodecBuffer t;
+    t.sharedMemory = android::hardware::hidl_memory();
+    t.nativeHandle = android::hardware::hidl_handle();
+    t.type = CodecBuffer::Type::PRESET;
+    t.attr.preset.rangeOffset = 0;
+    t.attr.preset.rangeLength = 0;
+    for (size_t i = 0; i < pBuffer[1].size(); ++i) {
+        native_handle_t* fenceNh = native_handle_create(0, 0);
+        status = omxNode->fillBuffer(pBuffer[1][i].id, t, fenceNh);
+        native_handle_close(fenceNh);
+        native_handle_delete(fenceNh);
+        ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+        pBuffer[1].editItemAt(i).owner = component;
+    }
+
+    for (size_t i = portBase; i < portBase + 2; i++) {
+        status =
+            omxNode->sendCommand(toRawCommandType(OMX_CommandPortDisable), i);
+        ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+
+        status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, &pBuffer[0],
+                                          &pBuffer[1]);
+        if (status == android::hardware::media::omx::V1_0::Status::OK) {
+            ASSERT_EQ(msg.type, Message::Type::EVENT);
+            if (msg.data.eventData.event == OMX_EventCmdComplete) {
+                // do not disable the port until all the buffers are freed
+                ASSERT_TRUE(false);
+            } else if (msg.data.eventData.event == OMX_EventError) {
+                ALOGI("Port %d Disabling failed with error %d", (int)i,
+                      (int)msg.data.eventData.event);
+            } else {
+                // something unexpected happened
+                ASSERT_TRUE(false);
+            }
+        } else if (status ==
+                   android::hardware::media::omx::V1_0::Status::TIMED_OUT) {
+            for (size_t j = 0; j < pBuffer[i - portBase].size(); ++j) {
+                // test if client got all its buffers back
+                EXPECT_EQ(pBuffer[i - portBase][j].owner, client);
+                // free the buffers
+                status = omxNode->freeBuffer(i, pBuffer[i - portBase][j].id);
+                ASSERT_EQ(status,
+                          android::hardware::media::omx::V1_0::Status::OK);
+            }
+
+            status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT,
+                                              &pBuffer[0], &pBuffer[1]);
+            ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+            ASSERT_EQ(msg.type, Message::Type::EVENT);
+            ASSERT_EQ(msg.data.eventData.event, OMX_EventCmdComplete);
+            ASSERT_EQ(msg.data.eventData.data1, OMX_CommandPortDisable);
+            ASSERT_EQ(msg.data.eventData.data2, i);
+
+            // If you can disable a port, then you should be able to enable it
+            // as well
+            status = omxNode->sendCommand(
+                toRawCommandType(OMX_CommandPortEnable), i);
+            ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+
+            // do not enable the port until all the buffers are supplied
+            status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT,
+                                              &pBuffer[0], &pBuffer[1]);
+            ASSERT_EQ(status,
+                      android::hardware::media::omx::V1_0::Status::TIMED_OUT);
+
+            allocatePortBuffers(omxNode, allocator, &pBuffer[i - portBase], i);
+            status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT,
+                                              &pBuffer[0], &pBuffer[1]);
+            ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+            ASSERT_EQ(msg.type, Message::Type::EVENT);
+            ASSERT_EQ(msg.data.eventData.data1, OMX_CommandPortEnable);
+            ASSERT_EQ(msg.data.eventData.data2, i);
+        } else {
+            // something unexpected happened
+            ASSERT_TRUE(false);
+        }
+    }
+}
+
+// Enable and Disable Input and Output ports, (in loaded state)
+TEST_F(ComponentHidlTest, PortEnableDisable_M) {
+    android::hardware::media::omx::V1_0::Status status;
+    OMX_U32 portBase = 0;
+    Message msg;
+    status = setRole(omxNode, gEnv->getRole().c_str());
+    ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+    OMX_PORT_PARAM_TYPE params;
+    if (compClass == audio_decoder || compClass == audio_encoder) {
+        status = getParam(omxNode, OMX_IndexParamAudioInit, &params);
+    } else {
+        status = getParam(omxNode, OMX_IndexParamVideoInit, &params);
+    }
+    if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
+        ASSERT_EQ(params.nPorts, 2U);
+        portBase = params.nStartPortNumber;
+    }
+
+    // disable invalid port, expecting OMX_ErrorBadPortIndex
+    status = omxNode->sendCommand(toRawCommandType(OMX_CommandPortDisable),
+                                  RANDOM_INDEX);
+    ASSERT_NE(status, android::hardware::media::omx::V1_0::Status::OK);
+
+    // enable invalid port, expecting OMX_ErrorBadPortIndex
+    status = omxNode->sendCommand(toRawCommandType(OMX_CommandPortEnable),
+                                  RANDOM_INDEX);
+    ASSERT_NE(status, android::hardware::media::omx::V1_0::Status::OK);
+
+    // disable all ports
+    status =
+        omxNode->sendCommand(toRawCommandType(OMX_CommandPortDisable), OMX_ALL);
+    ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+    for (size_t i = 0; i < 2; i++) {
+        status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT);
+        ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+        ASSERT_EQ(msg.type, Message::Type::EVENT);
+        if (msg.data.eventData.event == OMX_EventCmdComplete) {
+            ASSERT_EQ(msg.data.eventData.data1, OMX_CommandPortDisable);
+            if (msg.data.eventData.data2 != portBase ||
+                msg.data.eventData.data2 != portBase + 1)
+                EXPECT_TRUE(false);
+        } else if (msg.data.eventData.event == OMX_EventError) {
+            ALOGI("Port %d Disabling failed with error %d", (int)i,
+                  (int)msg.data.eventData.event);
+        } else {
+            // something unexpected happened
+            ASSERT_TRUE(false);
+        }
+    }
+
+    // enable all ports
+    status =
+        omxNode->sendCommand(toRawCommandType(OMX_CommandPortEnable), OMX_ALL);
+    ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+    for (size_t i = 0; i < 2; i++) {
+        status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT);
+        ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+        ASSERT_EQ(msg.type, Message::Type::EVENT);
+        if (msg.data.eventData.event == OMX_EventCmdComplete) {
+            ASSERT_EQ(msg.data.eventData.data1, OMX_CommandPortEnable);
+            if (msg.data.eventData.data2 != portBase ||
+                msg.data.eventData.data2 != portBase + 1)
+                EXPECT_TRUE(false);
+        } else if (msg.data.eventData.event == OMX_EventError) {
+            ALOGI("Port %d Enabling failed with error %d", (int)i,
+                  (int)msg.data.eventData.event);
+        } else {
+            // something unexpected happened
+            ASSERT_TRUE(false);
+        }
+    }
+}
+
+int main(int argc, char** argv) {
+    gEnv = new ComponentTestEnvironment();
+    ::testing::AddGlobalTestEnvironment(gEnv);
+    ::testing::InitGoogleTest(&argc, argv);
+    int status = gEnv->initFromOptions(argc, argv);
+    if (status == 0) {
+        status = RUN_ALL_TESTS();
+        ALOGI("Test result = %d", status);
+    }
+    return status;
+}
diff --git a/media/omx/1.0/vts/functional/master/Android.bp b/media/omx/1.0/vts/functional/master/Android.bp
new file mode 100644
index 0000000..6edbf4a
--- /dev/null
+++ b/media/omx/1.0/vts/functional/master/Android.bp
@@ -0,0 +1,38 @@
+//
+// Copyright (C) 2017 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+cc_test {
+    name: "VtsHalMediaOmxV1_0TargetMasterTest",
+    defaults: ["hidl_defaults"],
+    srcs: ["VtsHalMediaOmxV1_0TargetMasterTest.cpp"],
+    shared_libs: [
+        "libbase",
+        "liblog",
+        "libcutils",
+        "libhidlbase",
+        "libhidltransport",
+        "libhwbinder",
+        "libnativehelper",
+        "libutils",
+        "android.hardware.media.omx@1.0",
+    ],
+    static_libs: ["VtsHalHidlTargetTestBase"],
+    cflags: [
+        "-O0",
+        "-g",
+    ],
+}
+
diff --git a/media/omx/1.0/vts/functional/master/VtsHalMediaOmxV1_0TargetMasterTest.cpp b/media/omx/1.0/vts/functional/master/VtsHalMediaOmxV1_0TargetMasterTest.cpp
new file mode 100644
index 0000000..65b999e
--- /dev/null
+++ b/media/omx/1.0/vts/functional/master/VtsHalMediaOmxV1_0TargetMasterTest.cpp
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "media_omx_hidl_master_test"
+#include <android-base/logging.h>
+
+#include <android/hardware/media/omx/1.0/IOmx.h>
+#include <android/hardware/media/omx/1.0/types.h>
+#include <getopt.h>
+#include <log/log.h>
+#include <VtsHalHidlTargetTestBase.h>
+
+using ::android::hardware::media::omx::V1_0::IOmx;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::hidl_string;
+using ::android::sp;
+
+// A class for test environment setup
+class ComponentTestEnvironment : public ::testing::Environment {
+   public:
+    virtual void SetUp() {}
+    virtual void TearDown() {}
+
+    ComponentTestEnvironment() : instance("default") {}
+
+    void setInstance(const char* _instance) { instance = _instance; }
+
+    const hidl_string getInstance() const { return instance; }
+
+    int initFromOptions(int argc, char** argv) {
+        static struct option options[] = {
+            {"instance", required_argument, 0, 'I'}, {0, 0, 0, 0}};
+
+        while (true) {
+            int index = 0;
+            int c = getopt_long(argc, argv, "I:", options, &index);
+            if (c == -1) {
+                break;
+            }
+
+            switch (c) {
+                case 'I':
+                    setInstance(optarg);
+                    break;
+                case '?':
+                    break;
+            }
+        }
+
+        if (optind < argc) {
+            fprintf(stderr,
+                    "unrecognized option: %s\n\n"
+                    "usage: %s <gtest options> <test options>\n\n"
+                    "test options are:\n\n"
+                    "-I, --instance: HAL instance to test\n",
+                    argv[optind ?: 1], argv[0]);
+            return 2;
+        }
+        return 0;
+    }
+
+   private:
+    hidl_string instance;
+};
+
+static ComponentTestEnvironment* gEnv = nullptr;
+
+class MasterHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+   public:
+    virtual void SetUp() override {
+        omx = ::testing::VtsHalHidlTargetTestBase::getService<IOmx>(
+            gEnv->getInstance());
+        ASSERT_NE(omx, nullptr);
+    }
+
+    virtual void TearDown() override {}
+
+    sp<IOmx> omx;
+};
+
+// enumerate list of components and roles
+TEST_F(MasterHidlTest, ListNodes) {
+    android::hardware::media::omx::V1_0::Status status;
+    hidl_vec<IOmx::ComponentInfo> nodeList;
+    EXPECT_TRUE(
+        omx->listNodes([&status, &nodeList](
+                           android::hardware::media::omx::V1_0::Status _s,
+                           hidl_vec<IOmx::ComponentInfo> const& _nl) {
+               status = _s;
+               nodeList = _nl;
+           })
+            .isOk());
+}
+
+int main(int argc, char** argv) {
+    gEnv = new ComponentTestEnvironment();
+    ::testing::AddGlobalTestEnvironment(gEnv);
+    ::testing::InitGoogleTest(&argc, argv);
+    int status = gEnv->initFromOptions(argc, argv);
+    if (status == 0) {
+        status = RUN_ALL_TESTS();
+        ALOGI("Test result = %d", status);
+    }
+    return status;
+}