Merge changes I558b2d71,I1afce18b

* changes:
  Set min_sdk_version to be part of mainline modules
  Remove extractor-defaults_no-sanitizer
diff --git a/media/extractors/fuzzers/Android.bp b/media/extractors/fuzzers/Android.bp
index 7097b48..818e466 100644
--- a/media/extractors/fuzzers/Android.bp
+++ b/media/extractors/fuzzers/Android.bp
@@ -36,13 +36,13 @@
     static_libs: [
         "liblog",
         "libstagefright_foundation",
-        "libmedia",
+        "libmediandk_format",
+        "libmedia_ndkformatpriv",
     ],
 
     shared_libs: [
         "libutils",
         "libbinder",
-        "libmediandk",
     ],
 
     /* GETEXTRACTORDEF is not defined as extractor library is not linked in the
@@ -50,6 +50,14 @@
      * generated.
      */
     allow_undefined_symbols: true,
+
+    host_supported: true,
+
+    target: {
+        darwin: {
+            enabled: false,
+        },
+    },
 }
 
 cc_fuzz {
diff --git a/media/extractors/fuzzers/ExtractorFuzzerBase.cpp b/media/extractors/fuzzers/ExtractorFuzzerBase.cpp
index 291e020..1be8466 100644
--- a/media/extractors/fuzzers/ExtractorFuzzerBase.cpp
+++ b/media/extractors/fuzzers/ExtractorFuzzerBase.cpp
@@ -187,3 +187,15 @@
   cTrack->stop(track);
   free(cTrack);
 }
+
+void ExtractorFuzzerBase::processData(const uint8_t* data, size_t size) {
+  if (setDataSource(data, size)) {
+    if (createExtractor()) {
+      getExtractorDef();
+      getMetadata();
+      extractTracks();
+      getTracksMetadata();
+      seekAndExtractTracks();
+    }
+  }
+}
diff --git a/media/extractors/fuzzers/aac_extractor_fuzzer.cpp b/media/extractors/fuzzers/aac_extractor_fuzzer.cpp
index 93665f0..98a6cc9 100644
--- a/media/extractors/fuzzers/aac_extractor_fuzzer.cpp
+++ b/media/extractors/fuzzers/aac_extractor_fuzzer.cpp
@@ -46,17 +46,9 @@
     return 0;
   }
   AacExtractor* extractor = new AacExtractor();
-  if (!extractor) {
-    return 0;
+  if (extractor) {
+    extractor->processData(data, size);
+    delete extractor;
   }
-  if (extractor->setDataSource(data, size)) {
-    if (extractor->createExtractor()) {
-      extractor->getExtractorDef();
-      extractor->getMetadata();
-      extractor->extractTracks();
-      extractor->getTracksMetadata();
-    }
-  }
-  delete extractor;
   return 0;
 }
diff --git a/media/extractors/fuzzers/amr_extractor_fuzzer.cpp b/media/extractors/fuzzers/amr_extractor_fuzzer.cpp
index b2f9261..6c9e1a5 100644
--- a/media/extractors/fuzzers/amr_extractor_fuzzer.cpp
+++ b/media/extractors/fuzzers/amr_extractor_fuzzer.cpp
@@ -46,17 +46,9 @@
     return 0;
   }
   AmrExtractor* extractor = new AmrExtractor();
-  if (!extractor) {
-    return 0;
+  if (extractor) {
+    extractor->processData(data, size);
+    delete extractor;
   }
-  if (extractor->setDataSource(data, size)) {
-    if (extractor->createExtractor()) {
-      extractor->getExtractorDef();
-      extractor->getMetadata();
-      extractor->extractTracks();
-      extractor->getTracksMetadata();
-    }
-  }
-  delete extractor;
   return 0;
 }
diff --git a/media/extractors/fuzzers/flac_extractor_fuzzer.cpp b/media/extractors/fuzzers/flac_extractor_fuzzer.cpp
index 61e41cf..8734d45 100644
--- a/media/extractors/fuzzers/flac_extractor_fuzzer.cpp
+++ b/media/extractors/fuzzers/flac_extractor_fuzzer.cpp
@@ -46,17 +46,9 @@
     return 0;
   }
   FlacExtractor* extractor = new FlacExtractor();
-  if (!extractor) {
-    return 0;
+  if (extractor) {
+    extractor->processData(data, size);
+    delete extractor;
   }
-  if (extractor->setDataSource(data, size)) {
-    if (extractor->createExtractor()) {
-      extractor->getExtractorDef();
-      extractor->getMetadata();
-      extractor->extractTracks();
-      extractor->getTracksMetadata();
-    }
-  }
-  delete extractor;
   return 0;
 }
diff --git a/media/extractors/fuzzers/include/ExtractorFuzzerBase.h b/media/extractors/fuzzers/include/ExtractorFuzzerBase.h
index 86c70fc..6a2a1c1 100644
--- a/media/extractors/fuzzers/include/ExtractorFuzzerBase.h
+++ b/media/extractors/fuzzers/include/ExtractorFuzzerBase.h
@@ -70,6 +70,8 @@
 
   void seekAndExtractTracks();
 
+  void processData(const uint8_t* data, size_t size);
+
  protected:
   class BufferSource : public DataSource {
    public:
diff --git a/media/extractors/fuzzers/mkv_extractor_fuzzer.cpp b/media/extractors/fuzzers/mkv_extractor_fuzzer.cpp
index 14274b7..eceb93f 100644
--- a/media/extractors/fuzzers/mkv_extractor_fuzzer.cpp
+++ b/media/extractors/fuzzers/mkv_extractor_fuzzer.cpp
@@ -46,17 +46,9 @@
     return 0;
   }
   MKVExtractor* extractor = new MKVExtractor();
-  if (!extractor) {
-    return 0;
+  if (extractor) {
+    extractor->processData(data, size);
+    delete extractor;
   }
-  if (extractor->setDataSource(data, size)) {
-    if (extractor->createExtractor()) {
-      extractor->getExtractorDef();
-      extractor->getMetadata();
-      extractor->extractTracks();
-      extractor->getTracksMetadata();
-    }
-  }
-  delete extractor;
   return 0;
 }
diff --git a/media/extractors/fuzzers/mp3_extractor_fuzzer.cpp b/media/extractors/fuzzers/mp3_extractor_fuzzer.cpp
index 71c154b..9a47c18 100644
--- a/media/extractors/fuzzers/mp3_extractor_fuzzer.cpp
+++ b/media/extractors/fuzzers/mp3_extractor_fuzzer.cpp
@@ -46,17 +46,9 @@
     return 0;
   }
   Mp3Extractor* extractor = new Mp3Extractor();
-  if (!extractor) {
-    return 0;
+  if (extractor) {
+    extractor->processData(data, size);
+    delete extractor;
   }
-  if (extractor->setDataSource(data, size)) {
-    if (extractor->createExtractor()) {
-      extractor->getExtractorDef();
-      extractor->getMetadata();
-      extractor->extractTracks();
-      extractor->getTracksMetadata();
-    }
-  }
-  delete extractor;
   return 0;
 }
diff --git a/media/extractors/fuzzers/mp4_extractor_fuzzer.cpp b/media/extractors/fuzzers/mp4_extractor_fuzzer.cpp
index d2cc133..3903519 100644
--- a/media/extractors/fuzzers/mp4_extractor_fuzzer.cpp
+++ b/media/extractors/fuzzers/mp4_extractor_fuzzer.cpp
@@ -48,17 +48,9 @@
     return 0;
   }
   MP4Extractor* extractor = new MP4Extractor();
-  if (!extractor) {
-    return 0;
+  if (extractor) {
+    extractor->processData(data, size);
+    delete extractor;
   }
-  if (extractor->setDataSource(data, size)) {
-    if (extractor->createExtractor()) {
-      extractor->getExtractorDef();
-      extractor->getMetadata();
-      extractor->extractTracks();
-      extractor->getTracksMetadata();
-    }
-  }
-  delete extractor;
   return 0;
 }
diff --git a/media/extractors/fuzzers/mpeg2_extractor_fuzzer.cpp b/media/extractors/fuzzers/mpeg2_extractor_fuzzer.cpp
index c34ffa0..240ef66 100644
--- a/media/extractors/fuzzers/mpeg2_extractor_fuzzer.cpp
+++ b/media/extractors/fuzzers/mpeg2_extractor_fuzzer.cpp
@@ -54,17 +54,9 @@
     return 0;
   }
   MPEG2Extractor* extractor = new MPEG2Extractor();
-  if (!extractor) {
-    return 0;
+  if (extractor) {
+    extractor->processData(data, size);
+    delete extractor;
   }
-  if (extractor->setDataSource(data, size)) {
-    if (extractor->createExtractor()) {
-      extractor->getExtractorDef();
-      extractor->extractTracks();
-      extractor->extractTracks();
-      extractor->getTracksMetadata();
-    }
-  }
-  delete extractor;
   return 0;
 }
diff --git a/media/extractors/fuzzers/ogg_extractor_fuzzer.cpp b/media/extractors/fuzzers/ogg_extractor_fuzzer.cpp
index 033c50b..bd2fcc5 100644
--- a/media/extractors/fuzzers/ogg_extractor_fuzzer.cpp
+++ b/media/extractors/fuzzers/ogg_extractor_fuzzer.cpp
@@ -46,17 +46,9 @@
     return 0;
   }
   OGGExtractor* extractor = new OGGExtractor();
-  if (!extractor) {
-    return 0;
+  if (extractor) {
+    extractor->processData(data, size);
+    delete extractor;
   }
-  if (extractor->setDataSource(data, size)) {
-    if (extractor->createExtractor()) {
-      extractor->getExtractorDef();
-      extractor->getMetadata();
-      extractor->extractTracks();
-      extractor->getTracksMetadata();
-    }
-  }
-  delete extractor;
   return 0;
 }
diff --git a/media/extractors/fuzzers/wav_extractor_fuzzer.cpp b/media/extractors/fuzzers/wav_extractor_fuzzer.cpp
index 1397122..cb11ebd 100644
--- a/media/extractors/fuzzers/wav_extractor_fuzzer.cpp
+++ b/media/extractors/fuzzers/wav_extractor_fuzzer.cpp
@@ -46,17 +46,9 @@
     return 0;
   }
   wavExtractor* extractor = new wavExtractor();
-  if (!extractor) {
-    return 0;
+  if (extractor) {
+    extractor->processData(data, size);
+    delete extractor;
   }
-  if (extractor->setDataSource(data, size)) {
-    if (extractor->createExtractor()) {
-      extractor->getExtractorDef();
-      extractor->getMetadata();
-      extractor->extractTracks();
-      extractor->getTracksMetadata();
-    }
-  }
-  delete extractor;
   return 0;
 }
diff --git a/media/libstagefright/Android.bp b/media/libstagefright/Android.bp
index e2795ac..92df3b7 100644
--- a/media/libstagefright/Android.bp
+++ b/media/libstagefright/Android.bp
@@ -40,6 +40,12 @@
         "libstagefright_foundation",
         "libutils"
     ],
+    host_supported: true,
+    target: {
+        darwin: {
+            enabled: false,
+        },
+    },
 }
 
 cc_library_static {
diff --git a/media/libstagefright/tests/ESDS/Android.bp b/media/libstagefright/tests/ESDS/Android.bp
new file mode 100644
index 0000000..1ad1a64
--- /dev/null
+++ b/media/libstagefright/tests/ESDS/Android.bp
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2020 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: "ESDSTest",
+    gtest: true,
+
+    srcs: [
+        "ESDSTest.cpp",
+    ],
+
+    shared_libs: [
+        "libbinder",
+        "libdatasource",
+        "liblog",
+        "libmedia",
+        "libstagefright",
+        "libstagefright_foundation",
+        "libutils",
+    ],
+
+    static_libs: [
+        "libstagefright_esds",
+    ],
+
+    cflags: [
+        "-Werror",
+        "-Wall",
+    ],
+
+    sanitize: {
+        cfi: true,
+        misc_undefined: [
+            "unsigned-integer-overflow",
+            "signed-integer-overflow",
+        ],
+    },
+}
diff --git a/media/libstagefright/tests/ESDS/AndroidTest.xml b/media/libstagefright/tests/ESDS/AndroidTest.xml
new file mode 100644
index 0000000..a4fbc7f
--- /dev/null
+++ b/media/libstagefright/tests/ESDS/AndroidTest.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2020 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.
+-->
+<configuration description="Test module config for ESDS unit test">
+    <option name="test-suite-tag" value="ESDSTest" />
+    <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+        <option name="cleanup" value="true" />
+        <option name="push" value="ESDSTest->/data/local/tmp/ESDSTest" />
+        <option name="push-file"
+            key="https://storage.googleapis.com/android_media/frameworks/av/media/libstagefright/tests/ESDS/ESDSTestRes-1.0.zip?unzip=true"
+            value="/data/local/tmp/ESDSTestRes/" />
+    </target_preparer>
+
+    <test class="com.android.tradefed.testtype.GTest" >
+        <option name="native-test-device-path" value="/data/local/tmp" />
+        <option name="module-name" value="ESDSTest" />
+        <option name="native-test-flag" value="-P /data/local/tmp/ESDSTestRes/" />
+    </test>
+</configuration>
diff --git a/media/libstagefright/tests/ESDS/ESDSTest.cpp b/media/libstagefright/tests/ESDS/ESDSTest.cpp
new file mode 100644
index 0000000..101e00c
--- /dev/null
+++ b/media/libstagefright/tests/ESDS/ESDSTest.cpp
@@ -0,0 +1,210 @@
+/*
+ * Copyright (C) 2020 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_NDEBUG 0
+#define LOG_TAG "ESDSTest"
+#include <utils/Log.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <fstream>
+
+#include <ESDS.h>
+#include <binder/ProcessState.h>
+#include <datasource/FileSource.h>
+#include <media/stagefright/MediaExtractorFactory.h>
+#include <media/stagefright/MetaData.h>
+
+#include "ESDSTestEnvironment.h"
+
+using namespace android;
+
+static ESDSTestEnvironment *gEnv = nullptr;
+
+struct ESDSParams {
+    const char *inputFile;
+    int32_t objectTypeIndication;
+    const char *codecSpecificInfoData;
+    int32_t codecSpecificInfoDataSize;
+    int32_t bitrateMax;
+    int32_t bitrateAvg;
+};
+
+class ESDSUnitTest : public ::testing::TestWithParam<tuple<
+                             /* InputFile */ const char *,
+                             /* ObjectTypeIndication */ int32_t,
+                             /* CodecSpecificInfoData */ const char *,
+                             /* CodecSpecificInfoDataSize */ int32_t,
+                             /* BitrateMax */ int32_t,
+                             /* BitrateAvg */ int32_t>> {
+  public:
+    ESDSUnitTest() : mESDSData(nullptr) {
+        mESDSParams.inputFile = get<0>(GetParam());
+        mESDSParams.objectTypeIndication = get<1>(GetParam());
+        mESDSParams.codecSpecificInfoData = get<2>(GetParam());
+        mESDSParams.codecSpecificInfoDataSize = get<3>(GetParam());
+        mESDSParams.bitrateMax = get<4>(GetParam());
+        mESDSParams.bitrateAvg = get<5>(GetParam());
+    };
+
+    virtual void TearDown() override {
+        if (mDataSource) mDataSource.clear();
+        if (mInputFp) {
+            fclose(mInputFp);
+            mInputFp = nullptr;
+        }
+    }
+
+    virtual void SetUp() override { ASSERT_NO_FATAL_FAILURE(readESDSData()); }
+    const void *mESDSData;
+    size_t mESDSSize;
+    ESDSParams mESDSParams;
+
+  private:
+    void readESDSData() {
+        string inputFile = gEnv->getRes() + mESDSParams.inputFile;
+        mInputFp = fopen(inputFile.c_str(), "rb");
+        ASSERT_NE(mInputFp, nullptr) << "File open failed for file: " << inputFile;
+        int32_t fd = fileno(mInputFp);
+        ASSERT_GE(fd, 0) << "File descriptor invalid for file: " << inputFile;
+
+        struct stat buf;
+        status_t status = stat(inputFile.c_str(), &buf);
+        ASSERT_EQ(status, 0) << "Failed to get properties of input file: " << mESDSParams.inputFile;
+        size_t fileSize = buf.st_size;
+
+        mDataSource = new FileSource(dup(fd), 0, fileSize);
+        ASSERT_NE(mDataSource, nullptr) << "Unable to create data source for file: " << inputFile;
+
+        sp<IMediaExtractor> extractor = MediaExtractorFactory::Create(mDataSource);
+        if (extractor == nullptr) {
+            mDataSource.clear();
+            ASSERT_TRUE(false) << "Unable to create extractor for file: " << inputFile;
+        }
+
+        size_t numTracks = extractor->countTracks();
+        ASSERT_GT(numTracks, 0) << "No tracks in file: " << inputFile;
+        ASSERT_TRUE(esdsDataPresent(numTracks, extractor))
+                << "Unable to find esds in any track in file: " << inputFile;
+    }
+
+    bool esdsDataPresent(size_t numTracks, sp<IMediaExtractor> extractor) {
+        bool foundESDS = false;
+        uint32_t type;
+        for (size_t i = 0; i < numTracks; ++i) {
+            sp<MetaData> trackMeta = extractor->getTrackMetaData(i);
+            if (trackMeta != nullptr &&
+                trackMeta->findData(kKeyESDS, &type, &mESDSData, &mESDSSize)) {
+                trackMeta->clear();
+                foundESDS = true;
+                break;
+            }
+        }
+        return foundESDS;
+    }
+
+    FILE *mInputFp;
+    sp<DataSource> mDataSource;
+};
+
+TEST_P(ESDSUnitTest, InvalidDataTest) {
+    void *invalidData = calloc(mESDSSize, 1);
+    ASSERT_NE(invalidData, nullptr) << "Unable to allocate memory";
+    ESDS esds(invalidData, mESDSSize);
+    free(invalidData);
+    ASSERT_NE(esds.InitCheck(), OK) << "invalid ESDS data accepted";
+}
+
+TEST(ESDSSanityUnitTest, ConstructorSanityTest) {
+    void *invalidData = malloc(1);
+    ASSERT_NE(invalidData, nullptr) << "Unable to allocate memory";
+    ESDS esds_zero(invalidData, 0);
+    free(invalidData);
+    ASSERT_NE(esds_zero.InitCheck(), OK) << "invalid ESDS data accepted";
+
+    ESDS esds_null(NULL, 0);
+    ASSERT_NE(esds_null.InitCheck(), OK) << "invalid ESDS data accepted";
+}
+
+TEST_P(ESDSUnitTest, CreateAndDestroyTest) {
+    ESDS esds(mESDSData, mESDSSize);
+    ASSERT_EQ(esds.InitCheck(), OK) << "ESDS data invalid";
+}
+
+TEST_P(ESDSUnitTest, ObjectTypeIndicationTest) {
+    ESDS esds(mESDSData, mESDSSize);
+    ASSERT_EQ(esds.InitCheck(), OK) << "ESDS data invalid";
+    uint8_t objectTypeIndication;
+    status_t status = esds.getObjectTypeIndication(&objectTypeIndication);
+    ASSERT_EQ(status, OK) << "ESDS objectTypeIndication data invalid";
+    ASSERT_EQ(objectTypeIndication, mESDSParams.objectTypeIndication)
+            << "ESDS objectTypeIndication data doesn't match";
+}
+
+TEST_P(ESDSUnitTest, CodecSpecificInfoTest) {
+    ESDS esds(mESDSData, mESDSSize);
+    ASSERT_EQ(esds.InitCheck(), OK) << "ESDS data invalid";
+    status_t status;
+    const void *codecSpecificInfo;
+    size_t codecSpecificInfoSize;
+    status = esds.getCodecSpecificInfo(&codecSpecificInfo, &codecSpecificInfoSize);
+    ASSERT_EQ(status, OK) << "ESDS getCodecSpecificInfo data invalid";
+    ASSERT_EQ(mESDSParams.codecSpecificInfoDataSize, codecSpecificInfoSize)
+            << "CodecSpecificInfo data doesn't match";
+    status = memcmp(codecSpecificInfo, mESDSParams.codecSpecificInfoData, codecSpecificInfoSize);
+    ASSERT_EQ(status, 0) << "CodecSpecificInfo data doesn't match";
+}
+
+TEST_P(ESDSUnitTest, GetBitrateTest) {
+    ESDS esds(mESDSData, mESDSSize);
+    ASSERT_EQ(esds.InitCheck(), OK) << "ESDS data invalid";
+    uint32_t bitrateMax;
+    uint32_t bitrateAvg;
+    status_t status = esds.getBitRate(&bitrateMax, &bitrateAvg);
+    ASSERT_EQ(status, OK) << "ESDS bitRate data invalid";
+    ASSERT_EQ(bitrateMax, mESDSParams.bitrateMax) << "ESDS bitrateMax doesn't match";
+    ASSERT_EQ(bitrateAvg, mESDSParams.bitrateAvg) << "ESDS bitrateAvg doesn't match";
+    ASSERT_LE(bitrateAvg, bitrateMax) << "ESDS bitrateMax is less than bitrateAvg";
+}
+
+INSTANTIATE_TEST_SUITE_P(
+        ESDSUnitTestAll, ESDSUnitTest,
+        ::testing::Values(
+                // InputFile, ObjectTypeIndication, CodecSpecificInfoData,
+                // CodecSpecificInfoDataSize, BitrateMax, BitrateAvg
+                make_tuple("video_176x144_3gp_h263_56kbps_12fps_aac_stereo_128kbps_22050hz.3gp", 64,
+                           "\x13\x90", 2, 131072, 0),
+                make_tuple("video_1280x720_mp4_mpeg2_3000kbps_30fps_aac_stereo_128kbps_48000hz.mp4",
+                           97,
+                           "\x00\x00\x01\xB3\x50\x02\xD0\x35\xFF\xFF\xE1\xA0\x00\x00\x01\xB5\x15"
+                           "\x6A\x00\x01\x00\x00",
+                           22, 3415452, 3415452),
+                make_tuple("video_176x144_3gp_h263_56kbps_25fps_aac_mono_24kbps_11025hz.3gp", 64,
+                           "\x15\x08", 2, 24576, 0)));
+
+int main(int argc, char **argv) {
+    // MediaExtractor needs binder thread pool
+    ProcessState::self()->startThreadPool();
+    gEnv = new ESDSTestEnvironment();
+    ::testing::AddGlobalTestEnvironment(gEnv);
+    ::testing::InitGoogleTest(&argc, argv);
+    int status = gEnv->initFromOptions(argc, argv);
+    if (status == 0) {
+        status = RUN_ALL_TESTS();
+        ALOGV("Test result = %d\n", status);
+    }
+    return status;
+}
diff --git a/media/libstagefright/tests/ESDS/ESDSTestEnvironment.h b/media/libstagefright/tests/ESDS/ESDSTestEnvironment.h
new file mode 100644
index 0000000..4ca2303
--- /dev/null
+++ b/media/libstagefright/tests/ESDS/ESDSTestEnvironment.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2020 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 __ESDS_TEST_ENVIRONMENT_H__
+#define __ESDS_TEST_ENVIRONMENT_H__
+
+#include <gtest/gtest.h>
+
+#include <getopt.h>
+
+using namespace std;
+
+class ESDSTestEnvironment : public ::testing::Environment {
+  public:
+    ESDSTestEnvironment() : res("/data/local/tmp/") {}
+
+    // Parses the command line arguments
+    int initFromOptions(int argc, char **argv);
+
+    void setRes(const char *_res) { res = _res; }
+
+    const string getRes() const { return res; }
+
+  private:
+    string res;
+};
+
+int ESDSTestEnvironment::initFromOptions(int argc, char **argv) {
+    static struct option options[] = {{"res", required_argument, 0, 'P'}, {0, 0, 0, 0}};
+
+    while (true) {
+        int index = 0;
+        int c = getopt_long(argc, argv, "P:", options, &index);
+        if (c == -1) {
+            break;
+        }
+
+        switch (c) {
+            case 'P':
+                setRes(optarg);
+                break;
+            default:
+                break;
+        }
+    }
+
+    if (optind < argc) {
+        fprintf(stderr,
+                "unrecognized option: %s\n\n"
+                "usage: %s <gtest options> <test options>\n\n"
+                "test options are:\n\n"
+                "-P, --path: Resource files directory location\n",
+                argv[optind ?: 1], argv[0]);
+        return 2;
+    }
+    return 0;
+}
+
+#endif  // __ESDS_TEST_ENVIRONMENT_H__
diff --git a/media/libstagefright/tests/ESDS/README.md b/media/libstagefright/tests/ESDS/README.md
new file mode 100644
index 0000000..100fb86
--- /dev/null
+++ b/media/libstagefright/tests/ESDS/README.md
@@ -0,0 +1,40 @@
+## Media Testing ##
+---
+#### ESDS Unit Test :
+The ESDS Unit Test Suite validates the ESDS class available in libstagefright.
+
+Run the following steps to build the test suite:
+```
+m ESDSTest
+```
+
+The 32-bit binaries will be created in the following path : ${OUT}/data/nativetest/
+
+The 64-bit binaries will be created in the following path : ${OUT}/data/nativetest64/
+
+To test 64-bit binary push binaries from nativetest64.
+```
+adb push ${OUT}/data/nativetest64/ESDSTest/ESDSTest /data/local/tmp/
+```
+
+To test 32-bit binary push binaries from nativetest.
+```
+adb push ${OUT}/data/nativetest/ESDSTest/ESDSTest /data/local/tmp/
+```
+
+The resource file for the tests is taken from [here](https://storage.googleapis.com/android_media/frameworks/av/media/libstagefright/tests/ESDS/ESDSTestRes-1.0.zip)
+Download, unzip and push these files into device for testing.
+
+```
+adb push ESDSTestRes /data/local/tmp/
+```
+
+usage: ESDSTest -P \<path_to_folder\>
+```
+adb shell /data/local/tmp/ESDSTest -P /data/local/tmp/ESDSTestRes/
+```
+Alternatively, the test can also be run using atest command.
+
+```
+atest ESDSTest -- --enable-module-dynamic-download=true
+```