Merge "Add ACameraMetadata_fromCameraMetadata."
diff --git a/camera/ndk/include/camera/NdkCameraMetadataTags.h b/camera/ndk/include/camera/NdkCameraMetadataTags.h
index 6fefa41..3ac3ded 100644
--- a/camera/ndk/include/camera/NdkCameraMetadataTags.h
+++ b/camera/ndk/include/camera/NdkCameraMetadataTags.h
@@ -2509,6 +2509,11 @@
      * <p><code>p' = Rp</code></p>
      * <p>where <code>p</code> is in the device sensor coordinate system, and
      *  <code>p'</code> is in the camera-oriented coordinate system.</p>
+     * <p>If ACAMERA_LENS_POSE_REFERENCE is UNDEFINED, the quaternion rotation cannot
+     *  be accurately represented by the camera device, and will be represented by
+     *  default values matching its default facing.</p>
+     *
+     * @see ACAMERA_LENS_POSE_REFERENCE
      */
     ACAMERA_LENS_POSE_ROTATION =                                // float[4]
             ACAMERA_LENS_START + 6,
@@ -2549,6 +2554,8 @@
      * <p>When ACAMERA_LENS_POSE_REFERENCE is GYROSCOPE, then this position is relative to
      * the center of the primary gyroscope on the device. The axis definitions are the same as
      * with PRIMARY_CAMERA.</p>
+     * <p>When ACAMERA_LENS_POSE_REFERENCE is UNDEFINED, this position cannot be accurately
+     * represented by the camera device, and will be represented as <code>(0, 0, 0)</code>.</p>
      *
      * @see ACAMERA_LENS_DISTORTION
      * @see ACAMERA_LENS_INTRINSIC_CALIBRATION
@@ -2691,8 +2698,10 @@
     ACAMERA_LENS_RADIAL_DISTORTION =                            // Deprecated! DO NOT USE
             ACAMERA_LENS_START + 11,
     /**
-     * <p>The origin for ACAMERA_LENS_POSE_TRANSLATION.</p>
+     * <p>The origin for ACAMERA_LENS_POSE_TRANSLATION, and the accuracy of
+     * ACAMERA_LENS_POSE_TRANSLATION and ACAMERA_LENS_POSE_ROTATION.</p>
      *
+     * @see ACAMERA_LENS_POSE_ROTATION
      * @see ACAMERA_LENS_POSE_TRANSLATION
      *
      * <p>Type: byte (acamera_metadata_enum_android_lens_pose_reference_t)</p>
@@ -7539,6 +7548,19 @@
      */
     ACAMERA_LENS_POSE_REFERENCE_GYROSCOPE                            = 1,
 
+    /**
+     * <p>The camera device cannot represent the values of ACAMERA_LENS_POSE_TRANSLATION
+     * and ACAMERA_LENS_POSE_ROTATION accurately enough. One such example is a camera device
+     * on the cover of a foldable phone: in order to measure the pose translation and rotation,
+     * some kind of hinge position sensor would be needed.</p>
+     * <p>The value of ACAMERA_LENS_POSE_TRANSLATION must be all zeros, and
+     * ACAMERA_LENS_POSE_ROTATION must be values matching its default facing.</p>
+     *
+     * @see ACAMERA_LENS_POSE_ROTATION
+     * @see ACAMERA_LENS_POSE_TRANSLATION
+     */
+    ACAMERA_LENS_POSE_REFERENCE_UNDEFINED                            = 2,
+
 } acamera_metadata_enum_android_lens_pose_reference_t;
 
 
diff --git a/media/extractors/Android.bp b/media/extractors/Android.bp
new file mode 100644
index 0000000..bb42580
--- /dev/null
+++ b/media/extractors/Android.bp
@@ -0,0 +1,46 @@
+// 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_defaults {
+    name: "extractor-defaults",
+
+    include_dirs: [
+        "frameworks/av/media/libstagefright/include",
+    ],
+
+    shared_libs: [
+        "liblog",
+        "libmediandk#29",
+    ],
+
+    relative_install_path: "extractors",
+
+    compile_multilib: "first",
+
+    cflags: [
+        "-Werror",
+        "-Wall",
+        "-fvisibility=hidden",
+    ],
+
+    version_script: "exports.lds",
+
+    sanitize: {
+        cfi: true,
+        misc_undefined: [
+            "unsigned-integer-overflow",
+            "signed-integer-overflow",
+        ],
+    },
+}
\ No newline at end of file
diff --git a/media/extractors/aac/Android.bp b/media/extractors/aac/Android.bp
index 53b394f..60d3ae1 100644
--- a/media/extractors/aac/Android.bp
+++ b/media/extractors/aac/Android.bp
@@ -1,40 +1,13 @@
 cc_library {
+    name: "libaacextractor",
+    defaults: ["extractor-defaults"],
 
     srcs: ["AACExtractor.cpp"],
 
-    include_dirs: [
-        "frameworks/av/media/libstagefright/",
-    ],
-
-    shared_libs: [
-        "liblog",
-        "libmediandk",
-    ],
-
     static_libs: [
         "libstagefright_foundation",
         "libstagefright_metadatautils",
         "libutils",
     ],
 
-    name: "libaacextractor",
-    relative_install_path: "extractors",
-
-    compile_multilib: "first",
-
-    cflags: [
-        "-Werror",
-        "-Wall",
-        "-fvisibility=hidden",
-    ],
-    version_script: "exports.lds",
-
-    sanitize: {
-        cfi: true,
-        misc_undefined: [
-            "unsigned-integer-overflow",
-            "signed-integer-overflow",
-        ],
-    },
-
 }
diff --git a/media/extractors/amr/Android.bp b/media/extractors/amr/Android.bp
index cd76062..49c9567 100644
--- a/media/extractors/amr/Android.bp
+++ b/media/extractors/amr/Android.bp
@@ -1,38 +1,11 @@
 cc_library {
+    name: "libamrextractor",
+    defaults: ["extractor-defaults"],
 
     srcs: ["AMRExtractor.cpp"],
 
-    include_dirs: [
-        "frameworks/av/media/libstagefright/include",
-    ],
-
-    shared_libs: [
-        "liblog",
-        "libmediandk",
-    ],
-
     static_libs: [
         "libstagefright_foundation",
     ],
 
-    name: "libamrextractor",
-    relative_install_path: "extractors",
-
-    compile_multilib: "first",
-
-    cflags: [
-        "-Werror",
-        "-Wall",
-        "-fvisibility=hidden",
-    ],
-    version_script: "exports.lds",
-
-    sanitize: {
-        cfi: true,
-        misc_undefined: [
-            "unsigned-integer-overflow",
-            "signed-integer-overflow",
-        ],
-    },
-
 }
diff --git a/media/extractors/flac/Android.bp b/media/extractors/flac/Android.bp
index c669b34..3675611 100644
--- a/media/extractors/flac/Android.bp
+++ b/media/extractors/flac/Android.bp
@@ -1,16 +1,15 @@
 cc_library {
+    name: "libflacextractor",
+    defaults: ["extractor-defaults"],
 
     srcs: ["FLACExtractor.cpp"],
 
     include_dirs: [
-        "frameworks/av/media/libstagefright/include",
         "external/flac/include",
     ],
 
     shared_libs: [
         "libbinder_ndk",
-        "liblog",
-        "libmediandk",
     ],
 
     static_libs: [
@@ -21,24 +20,4 @@
         "libutils",
     ],
 
-    name: "libflacextractor",
-    relative_install_path: "extractors",
-
-    compile_multilib: "first",
-
-    cflags: [
-        "-Werror",
-        "-Wall",
-        "-fvisibility=hidden",
-    ],
-    version_script: "exports.lds",
-
-    sanitize: {
-        cfi: true,
-        misc_undefined: [
-            "unsigned-integer-overflow",
-            "signed-integer-overflow",
-        ],
-    },
-
 }
diff --git a/media/extractors/midi/Android.bp b/media/extractors/midi/Android.bp
index 40c91e7..592ffa9 100644
--- a/media/extractors/midi/Android.bp
+++ b/media/extractors/midi/Android.bp
@@ -1,43 +1,18 @@
 cc_library {
+    name: "libmidiextractor",
+    defaults: ["extractor-defaults"],
 
     srcs: ["MidiExtractor.cpp"],
 
-    include_dirs: [
-        "frameworks/av/media/libstagefright/include",
-    ],
-
     header_libs: [
         "libmedia_headers",
     ],
 
-    shared_libs: [
-        "liblog",
-        "libmediandk",
-    ],
-
     static_libs: [
         "libmedia_midiiowrapper",
         "libsonivox",
         "libstagefright_foundation"
     ],
-    name: "libmidiextractor",
-    relative_install_path: "extractors",
 
-    compile_multilib: "first",
-
-    cflags: [
-        "-Werror",
-        "-Wall",
-        "-fvisibility=hidden",
-    ],
-    version_script: "exports.lds",
-
-    sanitize: {
-        cfi: true,
-        misc_undefined: [
-            "unsigned-integer-overflow",
-            "signed-integer-overflow",
-        ],
-    },
 
 }
diff --git a/media/extractors/mkv/Android.bp b/media/extractors/mkv/Android.bp
index 942c88a..7ad8cc1 100644
--- a/media/extractors/mkv/Android.bp
+++ b/media/extractors/mkv/Android.bp
@@ -1,4 +1,6 @@
 cc_library {
+    name: "libmkvextractor",
+    defaults: ["extractor-defaults"],
 
     srcs: ["MatroskaExtractor.cpp"],
 
@@ -6,12 +8,9 @@
         "external/flac/include",
         "external/libvpx/libwebm",
         "frameworks/av/media/libstagefright/flac/dec",
-        "frameworks/av/media/libstagefright/include",
     ],
 
     shared_libs: [
-        "liblog",
-        "libmediandk",
         "libstagefright_flacdec",
     ],
 
@@ -22,24 +21,4 @@
         "libutils",
     ],
 
-    name: "libmkvextractor",
-    relative_install_path: "extractors",
-
-    compile_multilib: "first",
-
-    cflags: [
-        "-Werror",
-        "-Wall",
-        "-fvisibility=hidden",
-    ],
-    version_script: "exports.lds",
-
-    sanitize: {
-        cfi: true,
-        misc_undefined: [
-            "unsigned-integer-overflow",
-            "signed-integer-overflow",
-        ],
-    },
-
 }
diff --git a/media/extractors/mp3/Android.bp b/media/extractors/mp3/Android.bp
index 6f02b0f..102ac81 100644
--- a/media/extractors/mp3/Android.bp
+++ b/media/extractors/mp3/Android.bp
@@ -1,44 +1,16 @@
 cc_library {
-
+    name: "libmp3extractor",
+    defaults: ["extractor-defaults"],
     srcs: [
             "MP3Extractor.cpp",
             "VBRISeeker.cpp",
             "XINGSeeker.cpp",
     ],
 
-    include_dirs: [
-        "frameworks/av/media/libstagefright/include",
-    ],
-
-    shared_libs: [
-        "liblog",
-        "libmediandk",
-    ],
-
     static_libs: [
         "libutils",
         "libstagefright_id3",
         "libstagefright_foundation",
     ],
 
-    name: "libmp3extractor",
-    relative_install_path: "extractors",
-
-    compile_multilib: "first",
-
-    cflags: [
-        "-Werror",
-        "-Wall",
-        "-fvisibility=hidden",
-    ],
-    version_script: "exports.lds",
-
-    sanitize: {
-        cfi: true,
-        misc_undefined: [
-            "unsigned-integer-overflow",
-            "signed-integer-overflow",
-        ],
-    },
-
 }
diff --git a/media/extractors/mp4/Android.bp b/media/extractors/mp4/Android.bp
index d9f11fc..e48e1b7 100644
--- a/media/extractors/mp4/Android.bp
+++ b/media/extractors/mp4/Android.bp
@@ -1,5 +1,6 @@
-cc_defaults {
-    name: "libmp4extractor_defaults",
+cc_library {
+    name: "libmp4extractor",
+    defaults: ["extractor-defaults"],
 
     srcs: [
         "AC4Parser.cpp",
@@ -9,50 +10,10 @@
         "SampleTable.cpp",
     ],
 
-    include_dirs: [
-        "frameworks/av/media/libstagefright/",
-    ],
-
-    shared_libs: [
-        "liblog",
-        "libmediandk"
-    ],
-
     static_libs: [
         "libstagefright_esds",
         "libstagefright_foundation",
         "libstagefright_id3",
         "libutils",
     ],
-
-    cflags: [
-        "-Werror",
-        "-Wall",
-        "-fvisibility=hidden",
-    ],
-    version_script: "exports.lds",
-    relative_install_path: "extractors",
-    compile_multilib: "first",
-}
-
-cc_library {
-
-
-    name: "libmp4extractor",
-    defaults: ["libmp4extractor_defaults"],
-
-    sanitize: {
-        cfi: true,
-        misc_undefined: [
-            "unsigned-integer-overflow",
-            "signed-integer-overflow",
-        ],
-    },
-
-}
-
-cc_library_static {
-    name: "libmp4extractor_fuzzing",
-
-    defaults: ["libmp4extractor_defaults"],
 }
diff --git a/media/extractors/mp4/MPEG4Extractor.cpp b/media/extractors/mp4/MPEG4Extractor.cpp
index 9e0bc96..c8079eb 100755
--- a/media/extractors/mp4/MPEG4Extractor.cpp
+++ b/media/extractors/mp4/MPEG4Extractor.cpp
@@ -31,8 +31,9 @@
 #include "MPEG4Extractor.h"
 #include "SampleTable.h"
 #include "ItemTable.h"
-#include "include/ESDS.h"
 
+#include <ESDS.h>
+#include <ID3.h>
 #include <media/stagefright/DataSourceBase.h>
 #include <media/ExtractorUtils.h>
 #include <media/stagefright/foundation/ABitReader.h>
@@ -52,7 +53,6 @@
 #include <utils/String8.h>
 
 #include <byteswap.h>
-#include "include/ID3.h"
 
 #ifndef UINT32_MAX
 #define UINT32_MAX       (4294967295U)
diff --git a/media/extractors/mpeg2/Android.bp b/media/extractors/mpeg2/Android.bp
index 8d9145d..ef8431e 100644
--- a/media/extractors/mpeg2/Android.bp
+++ b/media/extractors/mpeg2/Android.bp
@@ -1,4 +1,7 @@
 cc_library {
+    name: "libmpeg2extractor",
+
+    defaults: ["extractor-defaults"],
 
     srcs: [
         "ExtractorBundle.cpp",
@@ -6,15 +9,8 @@
         "MPEG2TSExtractor.cpp",
     ],
 
-    include_dirs: [
-        "frameworks/av/media/libstagefright",
-        "frameworks/av/media/libstagefright/include",
-    ],
-
     shared_libs: [
         "libcgrouprc#29",
-        "liblog#10000",
-        "libmediandk#29",
         "libvndksupport#29",
     ],
 
@@ -46,27 +42,6 @@
         "libutils",
     ],
 
-    name: "libmpeg2extractor",
-    relative_install_path: "extractors",
-
-    compile_multilib: "first",
-
-    cflags: [
-        "-Werror",
-        "-Wall",
-        "-fvisibility=hidden",
-    ],
-    version_script: "exports.lds",
-
-    sanitize: {
-        // STOPSHIP: turn on cfi once b/139945549 is resolved.
-        cfi: false,
-        misc_undefined: [
-            "unsigned-integer-overflow",
-            "signed-integer-overflow",
-        ],
-    },
-
     apex_available: [
         "com.android.media",
         "test_com.android.media",
diff --git a/media/extractors/mpeg2/MPEG2PSExtractor.cpp b/media/extractors/mpeg2/MPEG2PSExtractor.cpp
index 002a855..d431b05 100644
--- a/media/extractors/mpeg2/MPEG2PSExtractor.cpp
+++ b/media/extractors/mpeg2/MPEG2PSExtractor.cpp
@@ -20,8 +20,8 @@
 
 #include "MPEG2PSExtractor.h"
 
-#include "mpeg2ts/AnotherPacketSource.h"
-#include "mpeg2ts/ESQueue.h"
+#include <AnotherPacketSource.h>
+#include <ESQueue.h>
 
 #include <media/stagefright/foundation/ABitReader.h>
 #include <media/stagefright/foundation/ABuffer.h>
diff --git a/media/extractors/mpeg2/MPEG2TSExtractor.cpp b/media/extractors/mpeg2/MPEG2TSExtractor.cpp
index f4643c5..9e093eb 100644
--- a/media/extractors/mpeg2/MPEG2TSExtractor.cpp
+++ b/media/extractors/mpeg2/MPEG2TSExtractor.cpp
@@ -37,8 +37,7 @@
 #include <media/stagefright/Utils.h>
 #include <utils/String8.h>
 
-#include "mpeg2ts/AnotherPacketSource.h"
-#include "mpeg2ts/ATSParser.h"
+#include <AnotherPacketSource.h>
 
 #include <hidl/HybridInterface.h>
 #include <android/hardware/cas/1.0/ICas.h>
diff --git a/media/extractors/mpeg2/MPEG2TSExtractor.h b/media/extractors/mpeg2/MPEG2TSExtractor.h
index dcd1e7b..fd77b08 100644
--- a/media/extractors/mpeg2/MPEG2TSExtractor.h
+++ b/media/extractors/mpeg2/MPEG2TSExtractor.h
@@ -27,7 +27,7 @@
 #include <utils/KeyedVector.h>
 #include <utils/Vector.h>
 
-#include "mpeg2ts/ATSParser.h"
+#include <ATSParser.h>
 
 namespace android {
 
diff --git a/media/extractors/ogg/Android.bp b/media/extractors/ogg/Android.bp
index e661b5d..7aed683 100644
--- a/media/extractors/ogg/Android.bp
+++ b/media/extractors/ogg/Android.bp
@@ -1,9 +1,11 @@
 cc_library {
+    name: "liboggextractor",
+
+    defaults: ["extractor-defaults"],
 
     srcs: ["OggExtractor.cpp"],
 
     include_dirs: [
-        "frameworks/av/media/libstagefright/include",
         "external/tremolo",
     ],
 
@@ -11,11 +13,6 @@
         "libaudio_system_headers",
     ],
 
-    shared_libs: [
-        "liblog",
-        "libmediandk",
-    ],
-
     static_libs: [
         "libstagefright_foundation",
         "libstagefright_metadatautils",
@@ -23,24 +20,4 @@
         "libvorbisidec",
     ],
 
-    name: "liboggextractor",
-    relative_install_path: "extractors",
-
-    compile_multilib: "first",
-
-    cflags: [
-        "-Werror",
-        "-Wall",
-        "-fvisibility=hidden",
-    ],
-    version_script: "exports.lds",
-
-    sanitize: {
-        cfi: true,
-        misc_undefined: [
-            "unsigned-integer-overflow",
-            "signed-integer-overflow",
-        ],
-    },
-
 }
diff --git a/media/extractors/tests/Android.bp b/media/extractors/tests/Android.bp
new file mode 100644
index 0000000..059c308
--- /dev/null
+++ b/media/extractors/tests/Android.bp
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2019 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: "ExtractorUnitTest",
+    gtest: true,
+
+    srcs: ["ExtractorUnitTest.cpp"],
+
+    static_libs: [
+        "libaacextractor",
+        "libamrextractor",
+        "libmp3extractor",
+        "libwavextractor",
+        "liboggextractor",
+        "libflacextractor",
+        "libmidiextractor",
+        "libmkvextractor",
+        "libmpeg2extractor",
+        "libmp4extractor",
+        "libaudioutils",
+        "libdatasource",
+
+        "libstagefright",
+        "libstagefright_id3",
+        "libstagefright_flacdec",
+        "libstagefright_esds",
+        "libstagefright_mpeg2support",
+        "libstagefright_mpeg2extractor",
+        "libstagefright_foundation",
+        "libstagefright_metadatautils",
+
+        "libmedia_midiiowrapper",
+        "libsonivox",
+        "libvorbisidec",
+        "libwebm",
+        "libFLAC",
+    ],
+
+    shared_libs: [
+        "android.hardware.cas@1.0",
+        "android.hardware.cas.native@1.0",
+        "android.hidl.token@1.0-utils",
+        "android.hidl.allocator@1.0",
+        "libbinder",
+        "libbinder_ndk",
+        "libutils",
+        "liblog",
+        "libcutils",
+        "libmediandk",
+        "libmedia",
+        "libcrypto",
+        "libhidlmemory",
+        "libhidlbase",
+    ],
+
+    include_dirs: [
+        "frameworks/av/media/extractors/",
+        "frameworks/av/media/libstagefright/",
+    ],
+
+    compile_multilib: "first",
+
+    cflags: [
+        "-Werror",
+        "-Wall",
+    ],
+
+    ldflags: [
+        "-Wl",
+        "-Bsymbolic",
+        // to ignore duplicate symbol: GETEXTRACTORDEF
+        "-z muldefs",
+    ],
+
+    sanitize: {
+        cfi: true,
+        misc_undefined: [
+            "unsigned-integer-overflow",
+            "signed-integer-overflow",
+        ],
+    },
+}
diff --git a/media/extractors/tests/ExtractorUnitTest.cpp b/media/extractors/tests/ExtractorUnitTest.cpp
new file mode 100644
index 0000000..518166e
--- /dev/null
+++ b/media/extractors/tests/ExtractorUnitTest.cpp
@@ -0,0 +1,528 @@
+/*
+ * Copyright (C) 2019 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 "ExtractorUnitTest"
+#include <utils/Log.h>
+
+#include <datasource/FileSource.h>
+#include <media/stagefright/MediaBufferGroup.h>
+#include <media/stagefright/MediaDefs.h>
+#include <media/stagefright/MetaDataUtils.h>
+
+#include "aac/AACExtractor.h"
+#include "amr/AMRExtractor.h"
+#include "flac/FLACExtractor.h"
+#include "midi/MidiExtractor.h"
+#include "mkv/MatroskaExtractor.h"
+#include "mp3/MP3Extractor.h"
+#include "mp4/MPEG4Extractor.h"
+#include "mp4/SampleTable.h"
+#include "mpeg2/MPEG2PSExtractor.h"
+#include "mpeg2/MPEG2TSExtractor.h"
+#include "ogg/OggExtractor.h"
+#include "wav/WAVExtractor.h"
+
+#include "ExtractorUnitTestEnvironment.h"
+
+using namespace android;
+
+#define OUTPUT_DUMP_FILE "/data/local/tmp/extractorOutput"
+
+constexpr int32_t kMaxCount = 10;
+constexpr int32_t kOpusSeekPreRollUs = 80000;  // 80 ms;
+
+static ExtractorUnitTestEnvironment *gEnv = nullptr;
+
+class ExtractorUnitTest : public ::testing::TestWithParam<pair<string, string>> {
+  public:
+    ExtractorUnitTest() : mInputFp(nullptr), mDataSource(nullptr), mExtractor(nullptr) {}
+
+    ~ExtractorUnitTest() {
+        if (mInputFp) {
+            fclose(mInputFp);
+            mInputFp = nullptr;
+        }
+        if (mDataSource) {
+            mDataSource.clear();
+            mDataSource = nullptr;
+        }
+        if (mExtractor) {
+            delete mExtractor;
+            mExtractor = nullptr;
+        }
+    }
+
+    virtual void SetUp() override {
+        mExtractorName = unknown_comp;
+        mDisableTest = false;
+
+        static const std::map<std::string, standardExtractors> mapExtractor = {
+                {"aac", AAC},     {"amr", AMR},         {"mp3", MP3},        {"ogg", OGG},
+                {"wav", WAV},     {"mkv", MKV},         {"flac", FLAC},      {"midi", MIDI},
+                {"mpeg4", MPEG4}, {"mpeg2ts", MPEG2TS}, {"mpeg2ps", MPEG2PS}};
+        // Find the component type
+        string writerFormat = GetParam().first;
+        if (mapExtractor.find(writerFormat) != mapExtractor.end()) {
+            mExtractorName = mapExtractor.at(writerFormat);
+        }
+        if (mExtractorName == standardExtractors::unknown_comp) {
+            cout << "[   WARN   ] Test Skipped. Invalid extractor\n";
+            mDisableTest = true;
+        }
+    }
+
+    int32_t setDataSource(string inputFileName);
+
+    int32_t createExtractor();
+
+    enum standardExtractors {
+        AAC,
+        AMR,
+        FLAC,
+        MIDI,
+        MKV,
+        MP3,
+        MPEG4,
+        MPEG2PS,
+        MPEG2TS,
+        OGG,
+        WAV,
+        unknown_comp,
+    };
+
+    bool mDisableTest;
+    standardExtractors mExtractorName;
+
+    FILE *mInputFp;
+    sp<DataSource> mDataSource;
+    MediaExtractorPluginHelper *mExtractor;
+};
+
+int32_t ExtractorUnitTest::setDataSource(string inputFileName) {
+    mInputFp = fopen(inputFileName.c_str(), "rb");
+    if (!mInputFp) {
+        ALOGE("Unable to open input file for reading");
+        return -1;
+    }
+    struct stat buf;
+    stat(inputFileName.c_str(), &buf);
+    int32_t fd = fileno(mInputFp);
+    mDataSource = new FileSource(dup(fd), 0, buf.st_size);
+    if (!mDataSource) return -1;
+    return 0;
+}
+
+int32_t ExtractorUnitTest::createExtractor() {
+    switch (mExtractorName) {
+        case AAC:
+            mExtractor = new AACExtractor(new DataSourceHelper(mDataSource->wrap()), 0);
+            break;
+        case AMR:
+            mExtractor = new AMRExtractor(new DataSourceHelper(mDataSource->wrap()));
+            break;
+        case MP3:
+            mExtractor = new MP3Extractor(new DataSourceHelper(mDataSource->wrap()), nullptr);
+            break;
+        case OGG:
+            mExtractor = new OggExtractor(new DataSourceHelper(mDataSource->wrap()));
+            break;
+        case WAV:
+            mExtractor = new WAVExtractor(new DataSourceHelper(mDataSource->wrap()));
+            break;
+        case MKV:
+            mExtractor = new MatroskaExtractor(new DataSourceHelper(mDataSource->wrap()));
+            break;
+        case FLAC:
+            mExtractor = new FLACExtractor(new DataSourceHelper(mDataSource->wrap()));
+            break;
+        case MPEG4:
+            mExtractor = new MPEG4Extractor(new DataSourceHelper(mDataSource->wrap()));
+            break;
+        case MPEG2TS:
+            mExtractor = new MPEG2TSExtractor(new DataSourceHelper(mDataSource->wrap()));
+            break;
+        case MPEG2PS:
+            mExtractor = new MPEG2PSExtractor(new DataSourceHelper(mDataSource->wrap()));
+            break;
+        case MIDI:
+            mExtractor = new MidiExtractor(mDataSource->wrap());
+            break;
+        default:
+            return -1;
+    }
+    if (!mExtractor) return -1;
+    return 0;
+}
+
+void getSeekablePoints(vector<int64_t> &seekablePoints, MediaTrackHelper *track) {
+    int32_t status = 0;
+    if (!seekablePoints.empty()) {
+        seekablePoints.clear();
+    }
+    int64_t timeStamp;
+    while (status != AMEDIA_ERROR_END_OF_STREAM) {
+        MediaBufferHelper *buffer = nullptr;
+        status = track->read(&buffer);
+        if (buffer) {
+            AMediaFormat *metaData = buffer->meta_data();
+            int32_t isSync = 0;
+            AMediaFormat_getInt32(metaData, AMEDIAFORMAT_KEY_IS_SYNC_FRAME, &isSync);
+            if (isSync) {
+                AMediaFormat_getInt64(metaData, AMEDIAFORMAT_KEY_TIME_US, &timeStamp);
+                seekablePoints.push_back(timeStamp);
+            }
+            buffer->release();
+        }
+    }
+}
+
+TEST_P(ExtractorUnitTest, CreateExtractorTest) {
+    if (mDisableTest) return;
+
+    ALOGV("Checks if a valid extractor is created for a given input file");
+    string inputFileName = gEnv->getRes() + GetParam().second;
+
+    ASSERT_EQ(setDataSource(inputFileName), 0)
+            << "SetDataSource failed for" << GetParam().first << "extractor";
+
+    ASSERT_EQ(createExtractor(), 0)
+            << "Extractor creation failed for" << GetParam().first << "extractor";
+
+    // A valid extractor instace should return success for following calls
+    ASSERT_GT(mExtractor->countTracks(), 0);
+
+    AMediaFormat *format = AMediaFormat_new();
+    ASSERT_NE(format, nullptr) << "AMediaFormat_new returned null AMediaformat";
+
+    ASSERT_EQ(mExtractor->getMetaData(format), AMEDIA_OK);
+    AMediaFormat_delete(format);
+}
+
+TEST_P(ExtractorUnitTest, ExtractorTest) {
+    if (mDisableTest) return;
+
+    ALOGV("Validates %s Extractor for a given input file", GetParam().first.c_str());
+    string inputFileName = gEnv->getRes() + GetParam().second;
+
+    int32_t status = setDataSource(inputFileName);
+    ASSERT_EQ(status, 0) << "SetDataSource failed for" << GetParam().first << "extractor";
+
+    status = createExtractor();
+    ASSERT_EQ(status, 0) << "Extractor creation failed for" << GetParam().first << "extractor";
+
+    int32_t numTracks = mExtractor->countTracks();
+    ASSERT_GT(numTracks, 0) << "Extractor didn't find any track for the given clip";
+
+    for (int32_t idx = 0; idx < numTracks; idx++) {
+        MediaTrackHelper *track = mExtractor->getTrack(idx);
+        ASSERT_NE(track, nullptr) << "Failed to get track for index " << idx;
+
+        CMediaTrack *cTrack = wrap(track);
+        ASSERT_NE(cTrack, nullptr) << "Failed to get track wrapper for index " << idx;
+
+        MediaBufferGroup *bufferGroup = new MediaBufferGroup();
+        status = cTrack->start(track, bufferGroup->wrap());
+        ASSERT_EQ(OK, (media_status_t)status) << "Failed to start the track";
+
+        FILE *outFp = fopen((OUTPUT_DUMP_FILE + to_string(idx)).c_str(), "wb");
+        if (!outFp) {
+            ALOGW("Unable to open output file for dumping extracted stream");
+        }
+
+        while (status != AMEDIA_ERROR_END_OF_STREAM) {
+            MediaBufferHelper *buffer = nullptr;
+            status = track->read(&buffer);
+            ALOGV("track->read Status = %d buffer %p", status, buffer);
+            if (buffer) {
+                ALOGV("buffer->data %p buffer->size() %zu buffer->range_length() %zu",
+                      buffer->data(), buffer->size(), buffer->range_length());
+                if (outFp) fwrite(buffer->data(), 1, buffer->range_length(), outFp);
+                buffer->release();
+            }
+        }
+        if (outFp) fclose(outFp);
+        status = cTrack->stop(track);
+        ASSERT_EQ(OK, status) << "Failed to stop the track";
+        delete bufferGroup;
+        delete track;
+    }
+}
+
+TEST_P(ExtractorUnitTest, MetaDataComparisonTest) {
+    if (mDisableTest) return;
+
+    ALOGV("Validates Extractor's meta data for a given input file");
+    string inputFileName = gEnv->getRes() + GetParam().second;
+
+    int32_t status = setDataSource(inputFileName);
+    ASSERT_EQ(status, 0) << "SetDataSource failed for" << GetParam().first << "extractor";
+
+    status = createExtractor();
+    ASSERT_EQ(status, 0) << "Extractor creation failed for" << GetParam().first << "extractor";
+
+    int32_t numTracks = mExtractor->countTracks();
+    ASSERT_GT(numTracks, 0) << "Extractor didn't find any track for the given clip";
+
+    AMediaFormat *extractorFormat = AMediaFormat_new();
+    ASSERT_NE(extractorFormat, nullptr) << "AMediaFormat_new returned null AMediaformat";
+    AMediaFormat *trackFormat = AMediaFormat_new();
+    ASSERT_NE(trackFormat, nullptr) << "AMediaFormat_new returned null AMediaformat";
+
+    for (int32_t idx = 0; idx < numTracks; idx++) {
+        MediaTrackHelper *track = mExtractor->getTrack(idx);
+        ASSERT_NE(track, nullptr) << "Failed to get track for index " << idx;
+
+        CMediaTrack *cTrack = wrap(track);
+        ASSERT_NE(cTrack, nullptr) << "Failed to get track wrapper for index " << idx;
+
+        MediaBufferGroup *bufferGroup = new MediaBufferGroup();
+        status = cTrack->start(track, bufferGroup->wrap());
+        ASSERT_EQ(OK, (media_status_t)status) << "Failed to start the track";
+
+        status = mExtractor->getTrackMetaData(extractorFormat, idx, 1);
+        ASSERT_EQ(OK, (media_status_t)status) << "Failed to get trackMetaData";
+
+        status = track->getFormat(trackFormat);
+        ASSERT_EQ(OK, (media_status_t)status) << "Failed to get track meta data";
+
+        const char *extractorMime, *trackMime;
+        AMediaFormat_getString(extractorFormat, AMEDIAFORMAT_KEY_MIME, &extractorMime);
+        AMediaFormat_getString(trackFormat, AMEDIAFORMAT_KEY_MIME, &trackMime);
+        ASSERT_TRUE(!strcmp(extractorMime, trackMime))
+                << "Extractor's format doesn't match track format";
+
+        if (!strncmp(extractorMime, "audio/", 6)) {
+            int32_t exSampleRate, exChannelCount;
+            int32_t trackSampleRate, trackChannelCount;
+            ASSERT_TRUE(AMediaFormat_getInt32(extractorFormat, AMEDIAFORMAT_KEY_CHANNEL_COUNT,
+                                              &exChannelCount));
+            ASSERT_TRUE(AMediaFormat_getInt32(extractorFormat, AMEDIAFORMAT_KEY_SAMPLE_RATE,
+                                              &exSampleRate));
+            ASSERT_TRUE(AMediaFormat_getInt32(trackFormat, AMEDIAFORMAT_KEY_CHANNEL_COUNT,
+                                              &trackChannelCount));
+            ASSERT_TRUE(AMediaFormat_getInt32(trackFormat, AMEDIAFORMAT_KEY_SAMPLE_RATE,
+                                              &trackSampleRate));
+            ASSERT_EQ(exChannelCount, trackChannelCount) << "ChannelCount not as expected";
+            ASSERT_EQ(exSampleRate, trackSampleRate) << "SampleRate not as expected";
+        } else {
+            int32_t exWidth, exHeight;
+            int32_t trackWidth, trackHeight;
+            ASSERT_TRUE(AMediaFormat_getInt32(extractorFormat, AMEDIAFORMAT_KEY_WIDTH, &exWidth));
+            ASSERT_TRUE(AMediaFormat_getInt32(extractorFormat, AMEDIAFORMAT_KEY_HEIGHT, &exHeight));
+            ASSERT_TRUE(AMediaFormat_getInt32(trackFormat, AMEDIAFORMAT_KEY_WIDTH, &trackWidth));
+            ASSERT_TRUE(AMediaFormat_getInt32(trackFormat, AMEDIAFORMAT_KEY_HEIGHT, &trackHeight));
+            ASSERT_EQ(exWidth, trackWidth) << "Width not as expected";
+            ASSERT_EQ(exHeight, trackHeight) << "Height not as expected";
+        }
+        status = cTrack->stop(track);
+        ASSERT_EQ(OK, status) << "Failed to stop the track";
+        delete bufferGroup;
+        delete track;
+    }
+    AMediaFormat_delete(trackFormat);
+    AMediaFormat_delete(extractorFormat);
+}
+
+TEST_P(ExtractorUnitTest, MultipleStartStopTest) {
+    if (mDisableTest) return;
+
+    ALOGV("Test %s extractor for multiple start and stop calls", GetParam().first.c_str());
+    string inputFileName = gEnv->getRes() + GetParam().second;
+
+    int32_t status = setDataSource(inputFileName);
+    ASSERT_EQ(status, 0) << "SetDataSource failed for" << GetParam().first << "extractor";
+
+    status = createExtractor();
+    ASSERT_EQ(status, 0) << "Extractor creation failed for" << GetParam().first << "extractor";
+
+    int32_t numTracks = mExtractor->countTracks();
+    ASSERT_GT(numTracks, 0) << "Extractor didn't find any track for the given clip";
+
+    // start/stop the tracks multiple times
+    for (int32_t count = 0; count < kMaxCount; count++) {
+        for (int32_t idx = 0; idx < numTracks; idx++) {
+            MediaTrackHelper *track = mExtractor->getTrack(idx);
+            ASSERT_NE(track, nullptr) << "Failed to get track for index " << idx;
+
+            CMediaTrack *cTrack = wrap(track);
+            ASSERT_NE(cTrack, nullptr) << "Failed to get track wrapper for index " << idx;
+
+            MediaBufferGroup *bufferGroup = new MediaBufferGroup();
+            status = cTrack->start(track, bufferGroup->wrap());
+            ASSERT_EQ(OK, (media_status_t)status) << "Failed to start the track";
+            MediaBufferHelper *buffer = nullptr;
+            status = track->read(&buffer);
+            if (buffer) {
+                ALOGV("buffer->data %p buffer->size() %zu buffer->range_length() %zu",
+                      buffer->data(), buffer->size(), buffer->range_length());
+                buffer->release();
+            }
+            status = cTrack->stop(track);
+            ASSERT_EQ(OK, status) << "Failed to stop the track";
+            delete bufferGroup;
+            delete track;
+        }
+    }
+}
+
+TEST_P(ExtractorUnitTest, SeekTest) {
+    // Both Flac and Wav extractor can give samples from any pts and mark the given sample as
+    // sync frame. So, this seek test is not applicable to FLAC and WAV extractors
+    if (mDisableTest || mExtractorName == FLAC || mExtractorName == WAV) return;
+
+    ALOGV("Validates %s Extractor behaviour for different seek modes", GetParam().first.c_str());
+    string inputFileName = gEnv->getRes() + GetParam().second;
+
+    int32_t status = setDataSource(inputFileName);
+    ASSERT_EQ(status, 0) << "SetDataSource failed for" << GetParam().first << "extractor";
+
+    status = createExtractor();
+    ASSERT_EQ(status, 0) << "Extractor creation failed for" << GetParam().first << "extractor";
+
+    int32_t numTracks = mExtractor->countTracks();
+    ASSERT_GT(numTracks, 0) << "Extractor didn't find any track for the given clip";
+
+    uint32_t seekFlag = mExtractor->flags();
+    if (!(seekFlag & MediaExtractorPluginHelper::CAN_SEEK)) {
+        cout << "[   WARN   ] Test Skipped. " << GetParam().first
+             << " Extractor doesn't support seek\n";
+        return;
+    }
+
+    vector<int64_t> seekablePoints;
+    for (int32_t idx = 0; idx < numTracks; idx++) {
+        MediaTrackHelper *track = mExtractor->getTrack(idx);
+        ASSERT_NE(track, nullptr) << "Failed to get track for index " << idx;
+
+        CMediaTrack *cTrack = wrap(track);
+        ASSERT_NE(cTrack, nullptr) << "Failed to get track wrapper for index " << idx;
+
+        // Get all the seekable points of a given input
+        MediaBufferGroup *bufferGroup = new MediaBufferGroup();
+        status = cTrack->start(track, bufferGroup->wrap());
+        ASSERT_EQ(OK, (media_status_t)status) << "Failed to start the track";
+        getSeekablePoints(seekablePoints, track);
+        ASSERT_GT(seekablePoints.size(), 0)
+                << "Failed to get seekable points for " << GetParam().first << " extractor";
+
+        AMediaFormat *trackFormat = AMediaFormat_new();
+        ASSERT_NE(trackFormat, nullptr) << "AMediaFormat_new returned null format";
+        status = track->getFormat(trackFormat);
+        ASSERT_EQ(OK, (media_status_t)status) << "Failed to get track meta data";
+
+        bool isOpus = false;
+        const char *mime;
+        AMediaFormat_getString(trackFormat, AMEDIAFORMAT_KEY_MIME, &mime);
+        if (!strcmp(mime, "audio/opus")) isOpus = true;
+        AMediaFormat_delete(trackFormat);
+
+        int32_t seekIdx = 0;
+        size_t seekablePointsSize = seekablePoints.size();
+        for (int32_t mode = CMediaTrackReadOptions::SEEK_PREVIOUS_SYNC;
+             mode <= CMediaTrackReadOptions::SEEK_CLOSEST; mode++) {
+            for (int32_t seekCount = 0; seekCount < kMaxCount; seekCount++) {
+                seekIdx = rand() % seekablePointsSize + 1;
+                if (seekIdx >= seekablePointsSize) seekIdx = seekablePointsSize - 1;
+
+                int64_t seekToTimeStamp = seekablePoints[seekIdx];
+                if (seekablePointsSize > 1) {
+                    int64_t prevTimeStamp = seekablePoints[seekIdx - 1];
+                    seekToTimeStamp = seekToTimeStamp - ((seekToTimeStamp - prevTimeStamp) >> 3);
+                }
+
+                // Opus has a seekPreRollUs. TimeStamp returned by the
+                // extractor is calculated based on (seekPts - seekPreRollUs).
+                // So we add the preRoll value to the timeStamp we want to seek to.
+                if (isOpus) {
+                    seekToTimeStamp += kOpusSeekPreRollUs;
+                }
+
+                MediaTrackHelper::ReadOptions *options = new MediaTrackHelper::ReadOptions(
+                        mode | CMediaTrackReadOptions::SEEK, seekToTimeStamp);
+                ASSERT_NE(options, nullptr) << "Cannot create read option";
+
+                MediaBufferHelper *buffer = nullptr;
+                status = track->read(&buffer, options);
+                if (status == AMEDIA_ERROR_END_OF_STREAM) {
+                    delete options;
+                    continue;
+                }
+                if (buffer) {
+                    AMediaFormat *metaData = buffer->meta_data();
+                    int64_t timeStamp;
+                    AMediaFormat_getInt64(metaData, AMEDIAFORMAT_KEY_TIME_US, &timeStamp);
+                    buffer->release();
+
+                    // CMediaTrackReadOptions::SEEK is 8. Using mask 0111b to get true modes
+                    switch (mode & 0x7) {
+                        case CMediaTrackReadOptions::SEEK_PREVIOUS_SYNC:
+                            if (seekablePointsSize == 1) {
+                                EXPECT_EQ(timeStamp, seekablePoints[seekIdx]);
+                            } else {
+                                EXPECT_EQ(timeStamp, seekablePoints[seekIdx - 1]);
+                            }
+                            break;
+                        case CMediaTrackReadOptions::SEEK_NEXT_SYNC:
+                        case CMediaTrackReadOptions::SEEK_CLOSEST_SYNC:
+                        case CMediaTrackReadOptions::SEEK_CLOSEST:
+                            EXPECT_EQ(timeStamp, seekablePoints[seekIdx]);
+                            break;
+                        default:
+                            break;
+                    }
+                }
+                delete options;
+            }
+        }
+        status = cTrack->stop(track);
+        ASSERT_EQ(OK, status) << "Failed to stop the track";
+        delete bufferGroup;
+        delete track;
+    }
+    seekablePoints.clear();
+}
+
+// TODO: (b/145332185)
+// Add MIDI inputs
+INSTANTIATE_TEST_SUITE_P(ExtractorUnitTestAll, ExtractorUnitTest,
+                         ::testing::Values(make_pair("aac", "loudsoftaac.aac"),
+                                           make_pair("amr", "testamr.amr"),
+                                           make_pair("amr", "amrwb.wav"),
+                                           make_pair("ogg", "john_cage.ogg"),
+                                           make_pair("wav", "monotestgsm.wav"),
+                                           make_pair("mpeg2ts", "segment000001.ts"),
+                                           make_pair("flac", "sinesweepflac.flac"),
+                                           make_pair("ogg", "testopus.opus"),
+                                           make_pair("mkv", "sinesweepvorbis.mkv"),
+                                           make_pair("mpeg4", "sinesweepoggmp4.mp4"),
+                                           make_pair("mp3", "sinesweepmp3lame.mp3"),
+                                           make_pair("mkv", "swirl_144x136_vp9.webm"),
+                                           make_pair("mkv", "swirl_144x136_vp8.webm"),
+                                           make_pair("mpeg2ps", "swirl_144x136_mpeg2.mpg"),
+                                           make_pair("mpeg4", "swirl_132x130_mpeg4.mp4")));
+
+int main(int argc, char **argv) {
+    gEnv = new ExtractorUnitTestEnvironment();
+    ::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/extractors/tests/ExtractorUnitTestEnvironment.h b/media/extractors/tests/ExtractorUnitTestEnvironment.h
new file mode 100644
index 0000000..fce8fc2
--- /dev/null
+++ b/media/extractors/tests/ExtractorUnitTestEnvironment.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2019 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 __EXTRACTOR_UNIT_TEST_ENVIRONMENT_H__
+#define __EXTRACTOR_UNIT_TEST_ENVIRONMENT_H__
+
+#include <gtest/gtest.h>
+
+#include <getopt.h>
+
+using namespace std;
+
+class ExtractorUnitTestEnvironment : public ::testing::Environment {
+  public:
+    ExtractorUnitTestEnvironment() : 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 ExtractorUnitTestEnvironment::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  // __EXTRACTOR_UNIT_TEST_ENVIRONMENT_H__
diff --git a/media/extractors/tests/README.md b/media/extractors/tests/README.md
new file mode 100644
index 0000000..6e02d3e
--- /dev/null
+++ b/media/extractors/tests/README.md
@@ -0,0 +1,34 @@
+## Media Testing ##
+---
+#### Extractor :
+The Extractor Test Suite validates the extractors available in the device.
+
+Run the following steps to build the test suite:
+```
+m ExtractorUnitTest
+```
+
+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/ExtractorUnitTest/ExtractorUnitTest /data/local/tmp/
+```
+
+To test 32-bit binary push binaries from nativetest.
+```
+adb push ${OUT}/data/nativetest/ExtractorUnitTest/ExtractorUnitTest /data/local/tmp/
+```
+
+The resource file for the tests is taken from [here](https://drive.google.com/drive/folders/1Z9nCIRB6pGLvb5mPkF8BURa5Nc6cY9pY). Push these files into device for testing.
+Download extractor folder and push all the files in this folder to /data/local/tmp/ on the device.
+```
+adb push extractor /data/local/tmp/
+```
+
+usage: ExtractorUnitTest -P \<path_to_folder\>
+```
+adb shell /data/local/tmp/ExtractorUnitTest -P /data/local/tmp/extractor/
+```
diff --git a/media/extractors/wav/Android.bp b/media/extractors/wav/Android.bp
index 51e3c31..8ce5c3f 100644
--- a/media/extractors/wav/Android.bp
+++ b/media/extractors/wav/Android.bp
@@ -1,4 +1,7 @@
 cc_library {
+    name: "libwavextractor",
+
+    defaults: ["extractor-defaults"],
 
     srcs: ["WAVExtractor.cpp"],
 
@@ -8,8 +11,6 @@
 
     shared_libs: [
         "libbinder_ndk",
-        "liblog",
-        "libmediandk",
     ],
 
     static_libs: [
@@ -17,25 +18,4 @@
         "libfifo",
         "libstagefright_foundation",
     ],
-
-    name: "libwavextractor",
-    relative_install_path: "extractors",
-
-    compile_multilib: "first",
-
-    cflags: [
-        "-Werror",
-        "-Wall",
-        "-fvisibility=hidden",
-    ],
-    version_script: "exports.lds",
-
-    sanitize: {
-        cfi: true,
-        misc_undefined: [
-            "unsigned-integer-overflow",
-            "signed-integer-overflow",
-        ],
-    },
-
 }
diff --git a/media/libaaudio/src/Android.bp b/media/libaaudio/src/Android.bp
index baada22..8753aa9 100644
--- a/media/libaaudio/src/Android.bp
+++ b/media/libaaudio/src/Android.bp
@@ -44,14 +44,6 @@
     sanitize: {
         integer_overflow: true,
         misc_undefined: ["bounds"],
-        diag: {
-            integer_overflow: true,
-            misc_undefined: ["bounds"],
-            no_recover: [
-                "bounds",
-                "integer",
-            ],
-        },
     },
 
     stubs: {
@@ -137,14 +129,5 @@
     sanitize: {
         integer_overflow: true,
         misc_undefined: ["bounds"],
-        diag: {
-            integer_overflow: true,
-            misc_undefined: ["bounds"],
-            no_recover: [
-                "bounds",
-                "integer",
-            ],
-        },
     },
-
 }
diff --git a/media/libaudioclient/AudioEffect.cpp b/media/libaudioclient/AudioEffect.cpp
index 7d5b690..a1b141b 100644
--- a/media/libaudioclient/AudioEffect.cpp
+++ b/media/libaudioclient/AudioEffect.cpp
@@ -138,6 +138,7 @@
 
     mIEffectClient = new EffectClient(this);
     mClientPid = IPCThreadState::self()->getCallingPid();
+    mClientUid = IPCThreadState::self()->getCallingUid();
 
     iEffect = audioFlinger->createEffect((effect_descriptor_t *)&mDescriptor,
             mIEffectClient, priority, io, mSessionId, device, mOpPackageName, mClientPid,
@@ -179,7 +180,7 @@
             mStatus, mEnabled, mClientPid);
 
     if (!audio_is_global_session(mSessionId)) {
-        AudioSystem::acquireAudioSessionId(mSessionId, mClientPid);
+        AudioSystem::acquireAudioSessionId(mSessionId, mClientPid, mClientUid);
     }
 
     return mStatus;
diff --git a/media/libaudioclient/AudioRecord.cpp b/media/libaudioclient/AudioRecord.cpp
index a438c77..981cfee 100644
--- a/media/libaudioclient/AudioRecord.cpp
+++ b/media/libaudioclient/AudioRecord.cpp
@@ -186,7 +186,7 @@
         IPCThreadState::self()->flushCommands();
         ALOGV("%s(%d): releasing session id %d",
                 __func__, mPortId, mSessionId);
-        AudioSystem::releaseAudioSessionId(mSessionId, -1 /*pid*/);
+        AudioSystem::releaseAudioSessionId(mSessionId, mClientPid);
     }
 }
 
@@ -361,7 +361,7 @@
     mMarkerReached = false;
     mNewPosition = 0;
     mUpdatePeriod = 0;
-    AudioSystem::acquireAudioSessionId(mSessionId, -1);
+    AudioSystem::acquireAudioSessionId(mSessionId, mClientPid, mClientUid);
     mSequence = 1;
     mObservedSequence = mSequence;
     mInOverrun = false;
diff --git a/media/libaudioclient/AudioSystem.cpp b/media/libaudioclient/AudioSystem.cpp
index 0742091..342fbcb 100644
--- a/media/libaudioclient/AudioSystem.cpp
+++ b/media/libaudioclient/AudioSystem.cpp
@@ -36,10 +36,11 @@
 
 // client singleton for AudioFlinger binder interface
 Mutex AudioSystem::gLock;
+Mutex AudioSystem::gLockErrorCallbacks;
 Mutex AudioSystem::gLockAPS;
 sp<IAudioFlinger> AudioSystem::gAudioFlinger;
 sp<AudioSystem::AudioFlingerClient> AudioSystem::gAudioFlingerClient;
-audio_error_callback AudioSystem::gAudioErrorCallback = NULL;
+std::set<audio_error_callback> AudioSystem::gAudioErrorCallbacks;
 dynamic_policy_callback AudioSystem::gDynPolicyCallback = NULL;
 record_config_callback AudioSystem::gRecordConfigCallback = NULL;
 
@@ -63,9 +64,7 @@
             if (gAudioFlingerClient == NULL) {
                 gAudioFlingerClient = new AudioFlingerClient();
             } else {
-                if (gAudioErrorCallback) {
-                    gAudioErrorCallback(NO_ERROR);
-                }
+                reportError(NO_ERROR);
             }
             binder->linkToDeath(gAudioFlingerClient);
             gAudioFlinger = interface_cast<IAudioFlinger>(binder);
@@ -434,11 +433,11 @@
     return af->newAudioUniqueId(use);
 }
 
-void AudioSystem::acquireAudioSessionId(audio_session_t audioSession, pid_t pid)
+void AudioSystem::acquireAudioSessionId(audio_session_t audioSession, pid_t pid, uid_t uid)
 {
     const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
     if (af != 0) {
-        af->acquireAudioSessionId(audioSession, pid);
+        af->acquireAudioSessionId(audioSession, pid, uid);
     }
 }
 
@@ -500,19 +499,16 @@
 
 void AudioSystem::AudioFlingerClient::binderDied(const wp<IBinder>& who __unused)
 {
-    audio_error_callback cb = NULL;
     {
         Mutex::Autolock _l(AudioSystem::gLock);
         AudioSystem::gAudioFlinger.clear();
-        cb = gAudioErrorCallback;
     }
 
     // clear output handles and stream to output map caches
     clearIoCache();
 
-    if (cb) {
-        cb(DEAD_OBJECT);
-    }
+    reportError(DEAD_OBJECT);
+
     ALOGW("AudioFlinger server died!");
 }
 
@@ -717,10 +713,23 @@
     return NO_ERROR;
 }
 
-/* static */ void AudioSystem::setErrorCallback(audio_error_callback cb)
+/* static */ uintptr_t AudioSystem::addErrorCallback(audio_error_callback cb)
 {
-    Mutex::Autolock _l(gLock);
-    gAudioErrorCallback = cb;
+    Mutex::Autolock _l(gLockErrorCallbacks);
+    gAudioErrorCallbacks.insert(cb);
+    return reinterpret_cast<uintptr_t>(cb);
+}
+
+/* static */ void AudioSystem::removeErrorCallback(uintptr_t cb) {
+    Mutex::Autolock _l(gLockErrorCallbacks);
+    gAudioErrorCallbacks.erase(reinterpret_cast<audio_error_callback>(cb));
+}
+
+/* static */ void AudioSystem::reportError(status_t err) {
+    Mutex::Autolock _l(gLockErrorCallbacks);
+    for (auto callback : gAudioErrorCallbacks) {
+      callback(err);
+    }
 }
 
 /*static*/ void AudioSystem::setDynPolicyCallback(dynamic_policy_callback cb)
diff --git a/media/libaudioclient/AudioTrack.cpp b/media/libaudioclient/AudioTrack.cpp
index 3151feb..8cfee50 100644
--- a/media/libaudioclient/AudioTrack.cpp
+++ b/media/libaudioclient/AudioTrack.cpp
@@ -599,7 +599,7 @@
     mReleased = 0;
     mStartNs = 0;
     mStartFromZeroUs = 0;
-    AudioSystem::acquireAudioSessionId(mSessionId, mClientPid);
+    AudioSystem::acquireAudioSessionId(mSessionId, mClientPid, mClientUid);
     mSequence = 1;
     mObservedSequence = mSequence;
     mInUnderrun = false;
diff --git a/media/libaudioclient/IAudioFlinger.cpp b/media/libaudioclient/IAudioFlinger.cpp
index cbc98bd..513da2b 100644
--- a/media/libaudioclient/IAudioFlinger.cpp
+++ b/media/libaudioclient/IAudioFlinger.cpp
@@ -571,12 +571,13 @@
         return id;
     }
 
-    virtual void acquireAudioSessionId(audio_session_t audioSession, int pid)
+    void acquireAudioSessionId(audio_session_t audioSession, pid_t pid, uid_t uid) override
     {
         Parcel data, reply;
         data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
         data.writeInt32(audioSession);
-        data.writeInt32(pid);
+        data.writeInt32((int32_t)pid);
+        data.writeInt32((int32_t)uid);
         remote()->transact(ACQUIRE_AUDIO_SESSION_ID, data, &reply);
     }
 
@@ -1326,8 +1327,9 @@
         case ACQUIRE_AUDIO_SESSION_ID: {
             CHECK_INTERFACE(IAudioFlinger, data, reply);
             audio_session_t audioSession = (audio_session_t) data.readInt32();
-            int pid = data.readInt32();
-            acquireAudioSessionId(audioSession, pid);
+            const pid_t pid = (pid_t)data.readInt32();
+            const uid_t uid = (uid_t)data.readInt32();
+            acquireAudioSessionId(audioSession, pid, uid);
             return NO_ERROR;
         } break;
         case RELEASE_AUDIO_SESSION_ID: {
diff --git a/media/libaudioclient/include/media/AudioEffect.h b/media/libaudioclient/include/media/AudioEffect.h
index f17d737..eec9dfc 100644
--- a/media/libaudioclient/include/media/AudioEffect.h
+++ b/media/libaudioclient/include/media/AudioEffect.h
@@ -639,7 +639,8 @@
     sp<EffectClient>        mIEffectClient;     // IEffectClient implementation
     sp<IMemory>             mCblkMemory;        // shared memory for deferred parameter setting
     effect_param_cblk_t*    mCblk;              // control block for deferred parameter setting
-    pid_t                   mClientPid;
+    pid_t                   mClientPid = (pid_t)-1;
+    uid_t                   mClientUid = (uid_t)-1;
 };
 
 
diff --git a/media/libaudioclient/include/media/AudioSystem.h b/media/libaudioclient/include/media/AudioSystem.h
index ae8b59c..730efc5 100644
--- a/media/libaudioclient/include/media/AudioSystem.h
+++ b/media/libaudioclient/include/media/AudioSystem.h
@@ -27,6 +27,7 @@
 #include <media/IAudioFlingerClient.h>
 #include <media/IAudioPolicyServiceClient.h>
 #include <media/MicrophoneInfo.h>
+#include <set>
 #include <system/audio.h>
 #include <system/audio_effect.h>
 #include <system/audio_policy.h>
@@ -107,7 +108,16 @@
     static status_t setParameters(const String8& keyValuePairs);
     static String8  getParameters(const String8& keys);
 
-    static void setErrorCallback(audio_error_callback cb);
+    // Registers an error callback. When this callback is invoked, it means all
+    // state implied by this interface has been reset.
+    // Returns a token that can be used for un-registering.
+    // Might block while callbacks are being invoked.
+    static uintptr_t addErrorCallback(audio_error_callback cb);
+
+    // Un-registers a callback previously added with addErrorCallback.
+    // Might block while callbacks are being invoked.
+    static void removeErrorCallback(uintptr_t cb);
+
     static void setDynPolicyCallback(dynamic_policy_callback cb);
     static void setRecordConfigCallback(record_config_callback);
 
@@ -172,7 +182,7 @@
     //       or an unspecified existing unique ID.
     static audio_unique_id_t newAudioUniqueId(audio_unique_id_use_t use);
 
-    static void acquireAudioSessionId(audio_session_t audioSession, pid_t pid);
+    static void acquireAudioSessionId(audio_session_t audioSession, pid_t pid, uid_t uid);
     static void releaseAudioSessionId(audio_session_t audioSession, pid_t pid);
 
     // Get the HW synchronization source used for an audio session.
@@ -562,15 +572,19 @@
     static const sp<AudioFlingerClient> getAudioFlingerClient();
     static sp<AudioIoDescriptor> getIoDescriptor(audio_io_handle_t ioHandle);
 
+    // Invokes all registered error callbacks with the given error code.
+    static void reportError(status_t err);
+
     static sp<AudioFlingerClient> gAudioFlingerClient;
     static sp<AudioPolicyServiceClient> gAudioPolicyServiceClient;
     friend class AudioFlingerClient;
     friend class AudioPolicyServiceClient;
 
-    static Mutex gLock;      // protects gAudioFlinger and gAudioErrorCallback,
+    static Mutex gLock;      // protects gAudioFlinger
+    static Mutex gLockErrorCallbacks;      // protects gAudioErrorCallbacks
     static Mutex gLockAPS;   // protects gAudioPolicyService and gAudioPolicyServiceClient
     static sp<IAudioFlinger> gAudioFlinger;
-    static audio_error_callback gAudioErrorCallback;
+    static std::set<audio_error_callback> gAudioErrorCallbacks;
     static dynamic_policy_callback gDynPolicyCallback;
     static record_config_callback gRecordConfigCallback;
 
diff --git a/media/libaudioclient/include/media/IAudioFlinger.h b/media/libaudioclient/include/media/IAudioFlinger.h
index 8703f55..8bc1d83 100644
--- a/media/libaudioclient/include/media/IAudioFlinger.h
+++ b/media/libaudioclient/include/media/IAudioFlinger.h
@@ -446,7 +446,7 @@
 
     virtual audio_unique_id_t newAudioUniqueId(audio_unique_id_use_t use) = 0;
 
-    virtual void acquireAudioSessionId(audio_session_t audioSession, pid_t pid) = 0;
+    virtual void acquireAudioSessionId(audio_session_t audioSession, pid_t pid, uid_t uid) = 0;
     virtual void releaseAudioSessionId(audio_session_t audioSession, pid_t pid) = 0;
 
     virtual status_t queryNumberEffects(uint32_t *numEffects) const = 0;
diff --git a/media/libmedia/mediaplayer.cpp b/media/libmedia/mediaplayer.cpp
index 60d2f85..1fadc94 100644
--- a/media/libmedia/mediaplayer.cpp
+++ b/media/libmedia/mediaplayer.cpp
@@ -60,7 +60,7 @@
     mVideoWidth = mVideoHeight = 0;
     mLockThreadId = 0;
     mAudioSessionId = (audio_session_t) AudioSystem::newAudioUniqueId(AUDIO_UNIQUE_ID_USE_SESSION);
-    AudioSystem::acquireAudioSessionId(mAudioSessionId, -1);
+    AudioSystem::acquireAudioSessionId(mAudioSessionId, (pid_t)-1, (uid_t)-1); // always in client.
     mSendLevel = 0;
     mRetransmitEndpointValid = false;
 }
@@ -72,7 +72,7 @@
         delete mAudioAttributesParcel;
         mAudioAttributesParcel = NULL;
     }
-    AudioSystem::releaseAudioSessionId(mAudioSessionId, -1);
+    AudioSystem::releaseAudioSessionId(mAudioSessionId, (pid_t)-1);
     disconnect();
     IPCThreadState::self()->flushCommands();
 }
@@ -709,8 +709,8 @@
         return BAD_VALUE;
     }
     if (sessionId != mAudioSessionId) {
-        AudioSystem::acquireAudioSessionId(sessionId, -1);
-        AudioSystem::releaseAudioSessionId(mAudioSessionId, -1);
+        AudioSystem::acquireAudioSessionId(sessionId, (pid_t)-1, (uid_t)-1);
+        AudioSystem::releaseAudioSessionId(mAudioSessionId, (pid_t)-1);
         mAudioSessionId = sessionId;
     }
     return NO_ERROR;
diff --git a/media/libmediatranscoding/Android.bp b/media/libmediatranscoding/Android.bp
index 8f0e278..9d0c534 100644
--- a/media/libmediatranscoding/Android.bp
+++ b/media/libmediatranscoding/Android.bp
@@ -6,10 +6,11 @@
         "aidl/android/media/IMediaTranscodingService.aidl",
         "aidl/android/media/ITranscodingServiceClient.aidl",
         "aidl/android/media/TranscodingErrorCode.aidl",
+        "aidl/android/media/TranscodingJobPriority.aidl",
         "aidl/android/media/TranscodingType.aidl",
         "aidl/android/media/TranscodingVideoCodecType.aidl",
-        "aidl/android/media/TranscodingJob.aidl",
-        "aidl/android/media/TranscodingRequest.aidl",
-        "aidl/android/media/TranscodingResult.aidl",
+        "aidl/android/media/TranscodingJobParcel.aidl",
+        "aidl/android/media/TranscodingRequestParcel.aidl",
+        "aidl/android/media/TranscodingResultParcel.aidl",
     ],
 }
diff --git a/media/libmediatranscoding/aidl/android/media/IMediaTranscodingService.aidl b/media/libmediatranscoding/aidl/android/media/IMediaTranscodingService.aidl
index cae8ff0..798300a 100644
--- a/media/libmediatranscoding/aidl/android/media/IMediaTranscodingService.aidl
+++ b/media/libmediatranscoding/aidl/android/media/IMediaTranscodingService.aidl
@@ -16,8 +16,8 @@
 
 package android.media;
 
-import android.media.TranscodingJob;
-import android.media.TranscodingRequest;
+import android.media.TranscodingJobParcel;
+import android.media.TranscodingRequestParcel;
 import android.media.ITranscodingServiceClient;
 
 /**
@@ -27,6 +27,25 @@
  */
 interface IMediaTranscodingService {
     /**
+     * All MediaTranscoding service and device Binder calls may return a
+     * ServiceSpecificException with the following error codes
+     */
+    const int ERROR_PERMISSION_DENIED = 1;
+    const int ERROR_ALREADY_EXISTS = 2;
+    const int ERROR_ILLEGAL_ARGUMENT = 3;
+    const int ERROR_DISCONNECTED = 4;
+    const int ERROR_TIMED_OUT = 5;
+    const int ERROR_DISABLED = 6;
+    const int ERROR_INVALID_OPERATION = 7;
+
+    /**
+     * Default UID/PID values for non-privileged callers of
+     * registerClient().
+     */
+    const int USE_CALLING_UID = -1;
+    const int USE_CALLING_PID = -1;
+
+    /**
      * Register the client with the MediaTranscodingService.
      *
      * Client must call this function to register itself with the service in order to perform
@@ -34,10 +53,16 @@
      * Client should save this Id and use it for all the transaction with the service.
      *
      * @param client interface for the MediaTranscodingService to call the client.
+     * @param opPackageName op package name of the client.
+     * @param clientUid user id of the client.
+     * @param clientPid process id of the client.
      * @return a unique positive Id assigned to the client by the service, -1  means failed to
      * register.
      */
-    int registerClient(in ITranscodingServiceClient client);
+    int registerClient(in ITranscodingServiceClient client,
+                       in String opPackageName,
+                       in int clientUid,
+                       in int clientPid);
 
     /**
     * Unregister the client with the MediaTranscodingService.
@@ -58,8 +83,8 @@
      * @return a unique positive jobId generated by the MediaTranscodingService, -1 means failure.
      */
     int submitRequest(in int clientId,
-                      in TranscodingRequest request,
-                      out TranscodingJob job);
+                      in TranscodingRequestParcel request,
+                      out TranscodingJobParcel job);
 
     /**
      * Cancels a transcoding job.
@@ -77,5 +102,5 @@
      * @param job(output variable) the TranscodingJob associated with the jobId.
      * @return true if succeeds, false otherwise.
      */
-    boolean getJobWithId(in int jobId, out TranscodingJob job);
+    boolean getJobWithId(in int jobId, out TranscodingJobParcel job);
 }
diff --git a/media/libmediatranscoding/aidl/android/media/ITranscodingServiceClient.aidl b/media/libmediatranscoding/aidl/android/media/ITranscodingServiceClient.aidl
index 29b6f35..e23c833 100644
--- a/media/libmediatranscoding/aidl/android/media/ITranscodingServiceClient.aidl
+++ b/media/libmediatranscoding/aidl/android/media/ITranscodingServiceClient.aidl
@@ -17,8 +17,8 @@
 package android.media;
 
 import android.media.TranscodingErrorCode;
-import android.media.TranscodingJob;
-import android.media.TranscodingResult;
+import android.media.TranscodingJobParcel;
+import android.media.TranscodingResultParcel;
 
 /**
  * ITranscodingServiceClient interface for the MediaTranscodingervice to communicate with the
@@ -39,7 +39,7 @@
     * @param jobId jobId assigned by the MediaTranscodingService upon receiving request.
     * @param result contains the transcoded file stats and other transcoding metrics if requested.
     */
-    oneway void onTranscodingFinished(in int jobId, in TranscodingResult result);
+    oneway void onTranscodingFinished(in int jobId, in TranscodingResultParcel result);
 
     /**
     * Called when the transcoding associated with the jobId failed.
@@ -60,7 +60,9 @@
     * @param oldAwaitNumber previous number of jobs ahead of current job.
     * @param newAwaitNumber updated number of jobs ahead of current job.
     */
-    oneway void onAwaitNumberOfJobsChanged(in int jobId, in int oldAwaitNumber, in int newAwaitNumber);
+    oneway void onAwaitNumberOfJobsChanged(in int jobId,
+                                           in int oldAwaitNumber,
+                                           in int newAwaitNumber);
 
     /**
     * Called when there is an update on the progress of the TranscodingJob.
diff --git a/media/libmediatranscoding/aidl/android/media/TranscodingJob.aidl b/media/libmediatranscoding/aidl/android/media/TranscodingJobParcel.aidl
similarity index 91%
rename from media/libmediatranscoding/aidl/android/media/TranscodingJob.aidl
rename to media/libmediatranscoding/aidl/android/media/TranscodingJobParcel.aidl
index 42ad8ad..d912c38 100644
--- a/media/libmediatranscoding/aidl/android/media/TranscodingJob.aidl
+++ b/media/libmediatranscoding/aidl/android/media/TranscodingJobParcel.aidl
@@ -16,7 +16,7 @@
 
 package android.media;
 
-import android.media.TranscodingRequest;
+import android.media.TranscodingRequestParcel;
 
 /**
  * TranscodingJob is generated by the MediaTranscodingService upon receiving a TranscodingRequest.
@@ -26,7 +26,7 @@
  * {@hide}
  */
 //TODO(hkuang): Implement the parcelable.
-parcelable TranscodingJob {
+parcelable TranscodingJobParcel {
     /**
      * A unique positive Id generated by the MediaTranscodingService.
      */
@@ -35,7 +35,7 @@
     /**
      * The request associated with the TranscodingJob.
      */
-    TranscodingRequest request;
+    TranscodingRequestParcel request;
 
     /**
     * Current number of jobs ahead of this job. The service schedules the job based on the priority
diff --git a/media/libmediatranscoding/aidl/android/media/TranscodingJobPriority.aidl b/media/libmediatranscoding/aidl/android/media/TranscodingJobPriority.aidl
new file mode 100644
index 0000000..1a5d81a
--- /dev/null
+++ b/media/libmediatranscoding/aidl/android/media/TranscodingJobPriority.aidl
@@ -0,0 +1,37 @@
+/*
+ * 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.
+ */
+
+package android.media;
+
+/**
+ * Priority of a transcoding job.
+ *
+ * {@hide}
+ */
+@Backing(type="int")
+enum TranscodingJobPriority {
+    // TODO(hkuang): define what each priority level actually mean.
+    kUnspecified = 0,
+    kLow = 1,
+    /**
+     * 2 ~ 20 is reserved for future use.
+     */
+    kNormal = 21,
+    /**
+     * 22 ~ 30 is reserved for future use.
+     */
+    kHigh = 31,
+}
\ No newline at end of file
diff --git a/media/libmediatranscoding/aidl/android/media/TranscodingRequest.aidl b/media/libmediatranscoding/aidl/android/media/TranscodingRequestParcel.aidl
similarity index 91%
rename from media/libmediatranscoding/aidl/android/media/TranscodingRequest.aidl
rename to media/libmediatranscoding/aidl/android/media/TranscodingRequestParcel.aidl
index 6b51ee3..7b7986d 100644
--- a/media/libmediatranscoding/aidl/android/media/TranscodingRequest.aidl
+++ b/media/libmediatranscoding/aidl/android/media/TranscodingRequestParcel.aidl
@@ -16,6 +16,7 @@
 
 package android.media;
 
+import android.media.TranscodingJobPriority;
 import android.media.TranscodingType;
 
 /**
@@ -24,7 +25,7 @@
  * {@hide}
  */
 //TODO(hkuang): Implement the parcelable.
-parcelable TranscodingRequest {
+parcelable TranscodingRequestParcel {
     /**
      * Name of file to be transcoded.
      */
@@ -48,8 +49,7 @@
     /**
      * Priority of this transcoding. Service will schedule the transcoding based on the priority.
      */
-    // TODO(hkuang): Define the priority level.
-    int priority;
+    TranscodingJobPriority priority;
 
     /**
      * Whether to receive update on progress and change of awaitNumJobs.
diff --git a/media/libmediatranscoding/aidl/android/media/TranscodingResult.aidl b/media/libmediatranscoding/aidl/android/media/TranscodingResultParcel.aidl
similarity index 93%
rename from media/libmediatranscoding/aidl/android/media/TranscodingResult.aidl
rename to media/libmediatranscoding/aidl/android/media/TranscodingResultParcel.aidl
index a41e025..65c49e7 100644
--- a/media/libmediatranscoding/aidl/android/media/TranscodingResult.aidl
+++ b/media/libmediatranscoding/aidl/android/media/TranscodingResultParcel.aidl
@@ -16,15 +16,13 @@
 
 package android.media;
 
-import android.media.TranscodingJob;
-
 /**
  * Result of the transcoding.
  *
  * {@hide}
  */
 //TODO(hkuang): Implement the parcelable.
-parcelable TranscodingResult {
+parcelable TranscodingResultParcel {
     /**
      * The jobId associated with the TranscodingResult.
      */
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index ef9d253..960120f 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -1310,7 +1310,7 @@
     OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
     status_t err = configureOutputBuffersFromNativeWindow(
             &bufferCount, &bufferSize, &minUndequeuedBuffers,
-            false /* preregister */);
+            mFlags & kFlagPreregisterMetadataBuffers /* preregister */);
     if (err != OK)
         return err;
     mNumUndequeuedBuffers = minUndequeuedBuffers;
@@ -1896,6 +1896,19 @@
             setPortMode(kPortIndexInput, IOMX::kPortModePresetByteBuffer);
             err = OK; // ignore error for now
         }
+
+        OMX_INDEXTYPE index;
+        if (mOMXNode->getExtensionIndex(
+                "OMX.google.android.index.preregisterMetadataBuffers", &index) == OK) {
+            OMX_CONFIG_BOOLEANTYPE param;
+            InitOMXParams(&param);
+            param.bEnabled = OMX_FALSE;
+            if (mOMXNode->getParameter(index, &param, sizeof(param)) == OK) {
+                if (param.bEnabled == OMX_TRUE) {
+                    mFlags |= kFlagPreregisterMetadataBuffers;
+                }
+            }
+        }
     }
     if (haveNativeWindow) {
         sp<ANativeWindow> nativeWindow =
diff --git a/media/libstagefright/flac/dec/Android.bp b/media/libstagefright/flac/dec/Android.bp
index 7ebe71f..d65a663 100644
--- a/media/libstagefright/flac/dec/Android.bp
+++ b/media/libstagefright/flac/dec/Android.bp
@@ -1,4 +1,4 @@
-cc_library_shared {
+cc_library {
     name: "libstagefright_flacdec",
     vendor_available: true,
 
diff --git a/media/libstagefright/include/media/stagefright/ACodec.h b/media/libstagefright/include/media/stagefright/ACodec.h
index 7754de4..d56ec4f 100644
--- a/media/libstagefright/include/media/stagefright/ACodec.h
+++ b/media/libstagefright/include/media/stagefright/ACodec.h
@@ -158,6 +158,7 @@
         kFlagIsSecure                                 = 1,
         kFlagPushBlankBuffersToNativeWindowOnShutdown = 2,
         kFlagIsGrallocUsageProtected                  = 4,
+        kFlagPreregisterMetadataBuffers               = 8,
     };
 
     enum {
diff --git a/media/libstagefright/include/media/stagefright/MediaErrors.h b/media/libstagefright/include/media/stagefright/MediaErrors.h
index 6f48c5d..5418f10 100644
--- a/media/libstagefright/include/media/stagefright/MediaErrors.h
+++ b/media/libstagefright/include/media/stagefright/MediaErrors.h
@@ -105,7 +105,8 @@
     ERROR_CAS_CARD_MUTE                      = CAS_ERROR_BASE - 15,
     ERROR_CAS_CARD_INVALID                   = CAS_ERROR_BASE - 16,
     ERROR_CAS_BLACKOUT                       = CAS_ERROR_BASE - 17,
-    ERROR_CAS_LAST_USED_ERRORCODE            = CAS_ERROR_BASE - 17,
+    ERROR_CAS_REBOOTING                      = CAS_ERROR_BASE - 18,
+    ERROR_CAS_LAST_USED_ERRORCODE            = CAS_ERROR_BASE - 18,
 
     ERROR_CAS_VENDOR_MAX                     = CAS_ERROR_BASE - 500,
     ERROR_CAS_VENDOR_MIN                     = CAS_ERROR_BASE - 999,
diff --git a/media/libstagefright/mpeg2ts/Android.bp b/media/libstagefright/mpeg2ts/Android.bp
index a507b91..42afea3 100644
--- a/media/libstagefright/mpeg2ts/Android.bp
+++ b/media/libstagefright/mpeg2ts/Android.bp
@@ -29,7 +29,6 @@
 
     shared_libs: [
         "libcrypto",
-        "libmedia",
         "libhidlmemory",
         "android.hardware.cas.native@1.0",
         "android.hidl.memory@1.0",
@@ -37,9 +36,13 @@
     ],
 
     header_libs: [
+        "libmedia_headers",
+        "libaudioclient_headers",
         "media_ndk_headers",
     ],
 
+    export_include_dirs: ["."],
+
     whole_static_libs: [
         "libstagefright_metadatautils",
     ],
diff --git a/media/libstagefright/tests/writer/README.md b/media/libstagefright/tests/writer/README.md
index 52db6f0..ae07917 100644
--- a/media/libstagefright/tests/writer/README.md
+++ b/media/libstagefright/tests/writer/README.md
@@ -19,12 +19,13 @@
 
 adb push ${OUT}/data/nativetest/writerTest/writerTest /data/local/tmp/
 
-The resource file for the tests is taken from Codec2 VTS resource folder. Push these files into device for testing.
+The resource file for the tests is taken from [here](https://storage.googleapis.com/android_media/frameworks/av/media/libstagefright/tests/writer/writerTestRes.zip).
+Download and extract the folder. Push all the files in this folder to /data/local/tmp/ on the device.
 ```
-adb push  $ANDROID_BUILD_TOP/frameworks/av/media/codec2/hidl/1.0/vts/functional/res /sdcard/
+adb push writerTestRes /data/local/tmp/
 ```
 
 usage: writerTest -P \<path_to_res_folder\>
 ```
-adb shell /data/local/tmp/writerTest -P /sdcard/res/
+adb shell /data/local/tmp/writerTest -P /data/local/tmp/
 ```
diff --git a/media/libstagefright/tests/writer/WriterTest.cpp b/media/libstagefright/tests/writer/WriterTest.cpp
index d68438c..409f141 100644
--- a/media/libstagefright/tests/writer/WriterTest.cpp
+++ b/media/libstagefright/tests/writer/WriterTest.cpp
@@ -29,9 +29,9 @@
 
 #include <media/stagefright/AACWriter.h>
 #include <media/stagefright/AMRWriter.h>
-#include <media/stagefright/OggWriter.h>
-#include <media/stagefright/MPEG4Writer.h>
 #include <media/stagefright/MPEG2TSWriter.h>
+#include <media/stagefright/MPEG4Writer.h>
+#include <media/stagefright/OggWriter.h>
 #include <webm/WebmWriter.h>
 
 #include "WriterTestEnvironment.h"
@@ -89,19 +89,36 @@
 
 class WriterTest : public ::testing::TestWithParam<pair<string, int32_t>> {
   public:
+    WriterTest() : mWriter(nullptr), mFileMeta(nullptr), mCurrentTrack(nullptr) {}
+
+    ~WriterTest() {
+        if (mWriter) {
+            mWriter.clear();
+            mWriter = nullptr;
+        }
+        if (mFileMeta) {
+            mFileMeta.clear();
+            mFileMeta = nullptr;
+        }
+        if (mCurrentTrack) {
+            mCurrentTrack.clear();
+            mCurrentTrack = nullptr;
+        }
+    }
+
     virtual void SetUp() override {
         mNumCsds = 0;
         mInputFrameId = 0;
         mWriterName = unknown_comp;
         mDisableTest = false;
 
-        std::map<std::string, standardWriters> mapWriter = {
+        static const std::map<std::string, standardWriters> mapWriter = {
                 {"ogg", OGG},     {"aac", AAC},      {"aac_adts", AAC_ADTS}, {"webm", WEBM},
                 {"mpeg4", MPEG4}, {"amrnb", AMR_NB}, {"amrwb", AMR_WB},      {"mpeg2Ts", MPEG2TS}};
         // Find the component type
         string writerFormat = GetParam().first;
         if (mapWriter.find(writerFormat) != mapWriter.end()) {
-            mWriterName = mapWriter[writerFormat];
+            mWriterName = mapWriter.at(writerFormat);
         }
         if (mWriterName == standardWriters::unknown_comp) {
             cout << "[   WARN   ] Test Skipped. No specific writer mentioned\n";
@@ -110,10 +127,8 @@
     }
 
     virtual void TearDown() override {
-        mWriter.clear();
-        mFileMeta.clear();
         mBufferInfo.clear();
-        if (mInputStream) mInputStream.close();
+        if (mInputStream.is_open()) mInputStream.close();
     }
 
     void getInputBufferInfo(string inputFileName, string inputInfo);
@@ -149,7 +164,7 @@
 void WriterTest::getInputBufferInfo(string inputFileName, string inputInfo) {
     std::ifstream eleInfo;
     eleInfo.open(inputInfo.c_str());
-    CHECK_EQ(eleInfo.is_open(), true);
+    ASSERT_EQ(eleInfo.is_open(), true);
     int32_t bytesCount = 0;
     uint32_t flags = 0;
     int64_t timestamp = 0;
@@ -162,7 +177,7 @@
     }
     eleInfo.close();
     mInputStream.open(inputFileName.c_str(), std::ifstream::binary);
-    CHECK_EQ(mInputStream.is_open(), true);
+    ASSERT_EQ(mInputStream.is_open(), true);
 }
 
 int32_t WriterTest::createWriter(int32_t fd) {
@@ -258,14 +273,11 @@
     string outputFile = OUTPUT_FILE_NAME;
     int32_t fd =
             open(outputFile.c_str(), O_CREAT | O_LARGEFILE | O_TRUNC | O_RDWR, S_IRUSR | S_IWUSR);
-    if (fd < 0) return;
+    ASSERT_GE(fd, 0) << "Failed to open output file to dump writer's data";
 
     // Creating writer within a test scope. Destructor should be called when the test ends
-    int32_t status = createWriter(fd);
-    if (status) {
-        cout << "Failed to create writer for output format:" << GetParam().first << "\n";
-        ASSERT_TRUE(false);
-    }
+    ASSERT_EQ((status_t)OK, createWriter(fd))
+            << "Failed to create writer for output format:" << GetParam().first;
 }
 
 TEST_P(WriterTest, WriterTest) {
@@ -276,38 +288,32 @@
     string outputFile = OUTPUT_FILE_NAME;
     int32_t fd =
             open(outputFile.c_str(), O_CREAT | O_LARGEFILE | O_TRUNC | O_RDWR, S_IRUSR | S_IWUSR);
-    if (fd < 0) return;
+    ASSERT_GE(fd, 0) << "Failed to open output file to dump writer's data";
+
     int32_t status = createWriter(fd);
-    if (status) {
-        cout << "Failed to create writer for output format:" << writerFormat << "\n";
-        ASSERT_TRUE(false);
-    }
+    ASSERT_EQ((status_t)OK, status) << "Failed to create writer for output format:" << writerFormat;
+
     string inputFile = gEnv->getRes();
     string inputInfo = gEnv->getRes();
     configFormat param;
     bool isAudio;
     int32_t inputFileIdx = GetParam().second;
     getFileDetails(inputFile, inputInfo, param, isAudio, inputFileIdx);
-    if (!inputFile.compare(gEnv->getRes())) {
-        ALOGV("No input file specified");
-        return;
-    }
+    ASSERT_NE(inputFile.compare(gEnv->getRes()), 0) << "No input file specified";
+
     getInputBufferInfo(inputFile, inputInfo);
     status = addWriterSource(isAudio, param);
-    if (status) {
-        cout << "Failed to add source for " << writerFormat << "Writer \n";
-        ASSERT_TRUE(false);
-    }
-    CHECK_EQ((status_t)OK, mWriter->start(mFileMeta.get()));
+    ASSERT_EQ((status_t)OK, status) << "Failed to add source for " << writerFormat << "Writer";
+
+    status = mWriter->start(mFileMeta.get());
+    ASSERT_EQ((status_t)OK, status);
     status = sendBuffersToWriter(mInputStream, mBufferInfo, mInputFrameId, mCurrentTrack, 0,
                                  mBufferInfo.size());
+    ASSERT_EQ((status_t)OK, status) << writerFormat << " writer failed";
     mCurrentTrack->stop();
-    if (status) {
-        cout << writerFormat << " writer failed \n";
-        mWriter->stop();
-        ASSERT_TRUE(false);
-    }
-    CHECK_EQ((status_t)OK, mWriter->stop());
+
+    status = mWriter->stop();
+    ASSERT_EQ((status_t)OK, status) << "Failed to stop the writer";
     close(fd);
 }
 
@@ -319,59 +325,125 @@
     string outputFile = OUTPUT_FILE_NAME;
     int32_t fd =
             open(outputFile.c_str(), O_CREAT | O_LARGEFILE | O_TRUNC | O_RDWR, S_IRUSR | S_IWUSR);
-    if (fd < 0) return;
+    ASSERT_GE(fd, 0) << "Failed to open output file to dump writer's data";
+
     int32_t status = createWriter(fd);
-    if (status) {
-        cout << "Failed to create writer for output format:" << writerFormat << "\n";
-        ASSERT_TRUE(false);
-    }
+    ASSERT_EQ((status_t)OK, status) << "Failed to create writer for output format:" << writerFormat;
+
     string inputFile = gEnv->getRes();
     string inputInfo = gEnv->getRes();
     configFormat param;
     bool isAudio;
     int32_t inputFileIdx = GetParam().second;
     getFileDetails(inputFile, inputInfo, param, isAudio, inputFileIdx);
-    if (!inputFile.compare(gEnv->getRes())) {
-        ALOGV("No input file specified");
-        return;
-    }
+    ASSERT_NE(inputFile.compare(gEnv->getRes()), 0) << "No input file specified";
+
     getInputBufferInfo(inputFile, inputInfo);
     status = addWriterSource(isAudio, param);
-    if (status) {
-        cout << "Failed to add source for " << writerFormat << "Writer \n";
-        ASSERT_TRUE(false);
-    }
-    CHECK_EQ((status_t)OK, mWriter->start(mFileMeta.get()));
+    ASSERT_EQ((status_t)OK, status) << "Failed to add source for " << writerFormat << "Writer";
+
+    status = mWriter->start(mFileMeta.get());
+    ASSERT_EQ((status_t)OK, status);
     status = sendBuffersToWriter(mInputStream, mBufferInfo, mInputFrameId, mCurrentTrack, 0,
                                  mBufferInfo.size() / 4);
-    if (status) {
-        cout << writerFormat << " writer failed \n";
-        mCurrentTrack->stop();
-        mWriter->stop();
-        ASSERT_TRUE(false);
-    }
+    ASSERT_EQ((status_t)OK, status) << writerFormat << " writer failed";
 
     bool isPaused = false;
     if ((mWriterName != standardWriters::MPEG2TS) && (mWriterName != standardWriters::MPEG4)) {
-        CHECK_EQ((status_t)OK, mWriter->pause());
+        status = mWriter->pause();
+        ASSERT_EQ((status_t)OK, status);
         isPaused = true;
     }
     // In the pause state, writers shouldn't write anything. Testing the writers for the same
     int32_t numFramesPaused = mBufferInfo.size() / 4;
-    status |= sendBuffersToWriter(mInputStream, mBufferInfo, mInputFrameId, mCurrentTrack,
+    status = sendBuffersToWriter(mInputStream, mBufferInfo, mInputFrameId, mCurrentTrack,
                                   mInputFrameId, numFramesPaused, isPaused);
+    ASSERT_EQ((status_t)OK, status) << writerFormat << " writer failed";
+
     if (isPaused) {
-        CHECK_EQ((status_t)OK, mWriter->start(mFileMeta.get()));
+        status = mWriter->start(mFileMeta.get());
+        ASSERT_EQ((status_t)OK, status);
     }
-    status |= sendBuffersToWriter(mInputStream, mBufferInfo, mInputFrameId, mCurrentTrack,
+    status = sendBuffersToWriter(mInputStream, mBufferInfo, mInputFrameId, mCurrentTrack,
                                   mInputFrameId, mBufferInfo.size());
+    ASSERT_EQ((status_t)OK, status) << writerFormat << " writer failed";
     mCurrentTrack->stop();
-    if (status) {
-        cout << writerFormat << " writer failed \n";
-        mWriter->stop();
-        ASSERT_TRUE(false);
+
+    status = mWriter->stop();
+    ASSERT_EQ((status_t)OK, status) << "Failed to stop the writer";
+    close(fd);
+}
+
+TEST_P(WriterTest, MultiStartStopPauseTest) {
+    // TODO: (b/144821804)
+    // Enable the test for MPE2TS writer
+    if (mDisableTest || mWriterName == standardWriters::MPEG2TS) return;
+    ALOGV("Test writers for multiple start, stop and pause calls");
+
+    string outputFile = OUTPUT_FILE_NAME;
+    int32_t fd =
+            open(outputFile.c_str(), O_CREAT | O_LARGEFILE | O_TRUNC | O_RDWR, S_IRUSR | S_IWUSR);
+    ASSERT_GE(fd, 0) << "Failed to open output file to dump writer's data";
+
+    string writerFormat = GetParam().first;
+    int32_t status = createWriter(fd);
+    ASSERT_EQ(status, (status_t)OK) << "Failed to create writer for output format:" << writerFormat;
+
+    string inputFile = gEnv->getRes();
+    string inputInfo = gEnv->getRes();
+    configFormat param;
+    bool isAudio;
+    int32_t inputFileIdx = GetParam().second;
+    getFileDetails(inputFile, inputInfo, param, isAudio, inputFileIdx);
+    ASSERT_NE(inputFile.compare(gEnv->getRes()), 0) << "No input file specified";
+
+    getInputBufferInfo(inputFile, inputInfo);
+    status = addWriterSource(isAudio, param);
+    ASSERT_EQ((status_t)OK, status) << "Failed to add source for " << writerFormat << "Writer";
+
+    // first start should succeed.
+    status = mWriter->start(mFileMeta.get());
+    ASSERT_EQ((status_t)OK, status) << "Could not start the writer";
+
+    // Multiple start() may/may not succeed.
+    // Writers are expected to not crash on multiple start() calls.
+    for (int32_t count = 0; count < kMaxCount; count++) {
+        mWriter->start(mFileMeta.get());
     }
-    CHECK_EQ((status_t)OK, mWriter->stop());
+
+    status = sendBuffersToWriter(mInputStream, mBufferInfo, mInputFrameId, mCurrentTrack, 0,
+                              mBufferInfo.size() / 4);
+    ASSERT_EQ((status_t)OK, status) << writerFormat << " writer failed";
+
+    for (int32_t count = 0; count < kMaxCount; count++) {
+        mWriter->pause();
+        mWriter->start(mFileMeta.get());
+    }
+
+    mWriter->pause();
+    int32_t numFramesPaused = mBufferInfo.size() / 4;
+    status = sendBuffersToWriter(mInputStream, mBufferInfo, mInputFrameId, mCurrentTrack,
+                              mInputFrameId, numFramesPaused, true);
+    ASSERT_EQ((status_t)OK, status) << writerFormat << " writer failed";
+
+    for (int32_t count = 0; count < kMaxCount; count++) {
+        mWriter->start(mFileMeta.get());
+    }
+
+    status = sendBuffersToWriter(mInputStream, mBufferInfo, mInputFrameId, mCurrentTrack,
+                              mInputFrameId, mBufferInfo.size());
+    ASSERT_EQ((status_t)OK, status) << writerFormat << " writer failed";
+
+    mCurrentTrack->stop();
+
+    // first stop should succeed.
+    status = mWriter->stop();
+    ASSERT_EQ((status_t)OK, status) << "Failed to stop the writer";
+    // Multiple stop() may/may not succeed.
+    // Writers are expected to not crash on multiple stop() calls.
+    for (int32_t count = 0; count < kMaxCount; count++) {
+        mWriter->stop();
+    }
     close(fd);
 }
 
diff --git a/media/libstagefright/tests/writer/WriterTestEnvironment.h b/media/libstagefright/tests/writer/WriterTestEnvironment.h
index 34c2baa..99e686f 100644
--- a/media/libstagefright/tests/writer/WriterTestEnvironment.h
+++ b/media/libstagefright/tests/writer/WriterTestEnvironment.h
@@ -25,7 +25,7 @@
 
 class WriterTestEnvironment : public ::testing::Environment {
   public:
-    WriterTestEnvironment() : res("/sdcard/media/") {}
+    WriterTestEnvironment() : res("/data/local/tmp/") {}
 
     // Parses the command line arguments
     int initFromOptions(int argc, char **argv);
diff --git a/media/libstagefright/tests/writer/WriterUtility.cpp b/media/libstagefright/tests/writer/WriterUtility.cpp
index 2ba90a0..f24ccb6 100644
--- a/media/libstagefright/tests/writer/WriterUtility.cpp
+++ b/media/libstagefright/tests/writer/WriterUtility.cpp
@@ -26,7 +26,7 @@
                             int32_t &inputFrameId, sp<MediaAdapter> &currentTrack, int32_t offset,
                             int32_t range, bool isPaused) {
     while (1) {
-        if (inputFrameId == (int)bufferInfo.size() || inputFrameId >= (offset + range)) break;
+        if (inputFrameId >= (int)bufferInfo.size() || inputFrameId >= (offset + range)) break;
         int32_t size = bufferInfo[inputFrameId].size;
         char *data = (char *)malloc(size);
         if (!data) {
diff --git a/media/libstagefright/tests/writer/WriterUtility.h b/media/libstagefright/tests/writer/WriterUtility.h
index d402798..cdd6246 100644
--- a/media/libstagefright/tests/writer/WriterUtility.h
+++ b/media/libstagefright/tests/writer/WriterUtility.h
@@ -33,6 +33,7 @@
 #define CODEC_CONFIG_FLAG 32
 
 constexpr uint32_t kMaxCSDStrlen = 16;
+constexpr uint32_t kMaxCount = 20;
 
 struct BufferInfo {
     int32_t size;
diff --git a/media/tests/benchmark/src/native/decoder/Decoder.cpp b/media/tests/benchmark/src/native/decoder/Decoder.cpp
index b797cc9..2171589 100644
--- a/media/tests/benchmark/src/native/decoder/Decoder.cpp
+++ b/media/tests/benchmark/src/native/decoder/Decoder.cpp
@@ -225,12 +225,12 @@
 }
 
 void Decoder::deInitCodec() {
-    int64_t sTime = mStats->getCurTime();
     if (mFormat) {
         AMediaFormat_delete(mFormat);
         mFormat = nullptr;
     }
     if (!mCodec) return;
+    int64_t sTime = mStats->getCurTime();
     AMediaCodec_stop(mCodec);
     AMediaCodec_delete(mCodec);
     int64_t eTime = mStats->getCurTime();
diff --git a/media/tests/benchmark/src/native/encoder/Encoder.cpp b/media/tests/benchmark/src/native/encoder/Encoder.cpp
index f119cf3..2db612c 100644
--- a/media/tests/benchmark/src/native/encoder/Encoder.cpp
+++ b/media/tests/benchmark/src/native/encoder/Encoder.cpp
@@ -154,11 +154,12 @@
 }
 
 void Encoder::deInitCodec() {
-    int64_t sTime = mStats->getCurTime();
     if (mFormat) {
         AMediaFormat_delete(mFormat);
         mFormat = nullptr;
     }
+    if (!mCodec) return;
+    int64_t sTime = mStats->getCurTime();
     AMediaCodec_stop(mCodec);
     AMediaCodec_delete(mCodec);
     int64_t eTime = mStats->getCurTime();
diff --git a/media/tests/benchmark/src/native/muxer/Muxer.cpp b/media/tests/benchmark/src/native/muxer/Muxer.cpp
index f8627cb..3e150ca 100644
--- a/media/tests/benchmark/src/native/muxer/Muxer.cpp
+++ b/media/tests/benchmark/src/native/muxer/Muxer.cpp
@@ -49,12 +49,12 @@
 }
 
 void Muxer::deInitMuxer() {
-    int64_t sTime = mStats->getCurTime();
     if (mFormat) {
         AMediaFormat_delete(mFormat);
         mFormat = nullptr;
     }
     if (!mMuxer) return;
+    int64_t sTime = mStats->getCurTime();
     AMediaMuxer_stop(mMuxer);
     AMediaMuxer_delete(mMuxer);
     int64_t eTime = mStats->getCurTime();
diff --git a/services/audioflinger/Android.bp b/services/audioflinger/Android.bp
index 3873600..f06d026 100644
--- a/services/audioflinger/Android.bp
+++ b/services/audioflinger/Android.bp
@@ -3,6 +3,8 @@
 cc_library_shared {
     name: "libaudioflinger",
 
+    tidy: false, // b/146435095, segmentation fault with Effects.cpp
+
     srcs: [
         "AudioFlinger.cpp",
         "AudioHwDevice.cpp",
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index ee4c5ba..d6f0824 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -464,10 +464,12 @@
     }
 
     result.append("Global session refs:\n");
-    result.append("  session  cnt     pid\n");
+    result.append("  session  cnt     pid    uid  name\n");
     for (size_t i = 0; i < mAudioSessionRefs.size(); i++) {
         AudioSessionRef *r = mAudioSessionRefs[i];
-        result.appendFormat("  %7d %4d %7d\n", r->mSessionid, r->mCnt, r->mPid);
+        const mediautils::UidInfo::Info info = mUidInfo.getInfo(r->mUid);
+        result.appendFormat("  %7d %4d %7d %6u  %s\n", r->mSessionid, r->mCnt, r->mPid,
+                r->mUid, info.package.c_str());
     }
     write(fd, result.string(), result.size());
 }
@@ -2895,14 +2897,18 @@
     return nextUniqueId(use);
 }
 
-void AudioFlinger::acquireAudioSessionId(audio_session_t audioSession, pid_t pid)
+void AudioFlinger::acquireAudioSessionId(
+        audio_session_t audioSession, pid_t pid, uid_t uid)
 {
     Mutex::Autolock _l(mLock);
     pid_t caller = IPCThreadState::self()->getCallingPid();
     ALOGV("acquiring %d from %d, for %d", audioSession, caller, pid);
     const uid_t callerUid = IPCThreadState::self()->getCallingUid();
-    if (pid != -1 && isAudioServerUid(callerUid)) { // check must match releaseAudioSessionId()
-        caller = pid;
+    if (pid != (pid_t)-1 && isAudioServerOrMediaServerUid(callerUid)) {
+        caller = pid;  // check must match releaseAudioSessionId()
+    }
+    if (uid == (uid_t)-1 || !isAudioServerOrMediaServerUid(callerUid)) {
+        uid = callerUid;
     }
 
     {
@@ -2926,7 +2932,7 @@
             return;
         }
     }
-    mAudioSessionRefs.push(new AudioSessionRef(audioSession, caller));
+    mAudioSessionRefs.push(new AudioSessionRef(audioSession, caller, uid));
     ALOGV(" added new entry for %d", audioSession);
 }
 
@@ -2938,8 +2944,8 @@
         pid_t caller = IPCThreadState::self()->getCallingPid();
         ALOGV("releasing %d from %d for %d", audioSession, caller, pid);
         const uid_t callerUid = IPCThreadState::self()->getCallingUid();
-        if (pid != -1 && isAudioServerUid(callerUid)) { // check must match acquireAudioSessionId()
-            caller = pid;
+        if (pid != (pid_t)-1 && isAudioServerOrMediaServerUid(callerUid)) {
+            caller = pid;  // check must match acquireAudioSessionId()
         }
         size_t num = mAudioSessionRefs.size();
         for (size_t i = 0; i < num; i++) {
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index 5c975e1..0fac36d 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -214,7 +214,7 @@
     // This is the binder API.  For the internal API see nextUniqueId().
     virtual audio_unique_id_t newAudioUniqueId(audio_unique_id_use_t use);
 
-    virtual void acquireAudioSessionId(audio_session_t audioSession, pid_t pid);
+    void acquireAudioSessionId(audio_session_t audioSession, pid_t pid, uid_t uid) override;
 
     virtual void releaseAudioSessionId(audio_session_t audioSession, pid_t pid);
 
@@ -808,10 +808,11 @@
 
     // for mAudioSessionRefs only
     struct AudioSessionRef {
-        AudioSessionRef(audio_session_t sessionid, pid_t pid) :
-            mSessionid(sessionid), mPid(pid), mCnt(1) {}
+        AudioSessionRef(audio_session_t sessionid, pid_t pid, uid_t uid) :
+            mSessionid(sessionid), mPid(pid), mUid(uid), mCnt(1) {}
         const audio_session_t mSessionid;
         const pid_t mPid;
+        const uid_t mUid;
         int         mCnt;
     };
 
diff --git a/services/audioflinger/PatchPanel.cpp b/services/audioflinger/PatchPanel.cpp
index 5501856..b58fd8b 100644
--- a/services/audioflinger/PatchPanel.cpp
+++ b/services/audioflinger/PatchPanel.cpp
@@ -497,10 +497,12 @@
     }
 
     sp<RecordThread::PatchRecord> tempRecordTrack;
+    const bool usePassthruPatchRecord =
+            (inputFlags & AUDIO_INPUT_FLAG_DIRECT) && (outputFlags & AUDIO_OUTPUT_FLAG_DIRECT);
     const size_t playbackFrameCount = mPlayback.thread()->frameCount();
     const size_t recordFrameCount = mRecord.thread()->frameCount();
     size_t frameCount = 0;
-    if ((inputFlags & AUDIO_INPUT_FLAG_DIRECT) && (outputFlags & AUDIO_OUTPUT_FLAG_DIRECT)) {
+    if (usePassthruPatchRecord) {
         // PassthruPatchRecord producesBufferOnDemand, so use
         // maximum of playback and record thread framecounts
         frameCount = std::max(playbackFrameCount, recordFrameCount);
@@ -557,8 +559,14 @@
     }
 
     // tie playback and record tracks together
-    mRecord.setTrackAndPeer(tempRecordTrack, tempPatchTrack);
-    mPlayback.setTrackAndPeer(tempPatchTrack, tempRecordTrack);
+    // In the case of PassthruPatchRecord no I/O activity happens on RecordThread,
+    // everything is driven from PlaybackThread. Thus AudioBufferProvider methods
+    // of PassthruPatchRecord can only be called if the corresponding PatchTrack
+    // is alive. There is no need to hold a reference, and there is no need
+    // to clear it. In fact, since playback stopping is asynchronous, there is
+    // no proper time when clearing could be done.
+    mRecord.setTrackAndPeer(tempRecordTrack, tempPatchTrack, !usePassthruPatchRecord);
+    mPlayback.setTrackAndPeer(tempPatchTrack, tempRecordTrack, true /*holdReference*/);
 
     // start capture and playback
     mRecord.track()->start(AudioSystem::SYNC_EVENT_NONE, AUDIO_SESSION_NONE);
diff --git a/services/audioflinger/PatchPanel.h b/services/audioflinger/PatchPanel.h
index 4e0d243..89d4eb1 100644
--- a/services/audioflinger/PatchPanel.h
+++ b/services/audioflinger/PatchPanel.h
@@ -128,18 +128,20 @@
             mCloseThread = closeThread;
         }
         template <typename T>
-        void setTrackAndPeer(const sp<TrackType>& track, const sp<T> &peer) {
+        void setTrackAndPeer(const sp<TrackType>& track, const sp<T> &peer, bool holdReference) {
             mTrack = track;
             mThread->addPatchTrack(mTrack);
-            mTrack->setPeerProxy(peer, true /* holdReference */);
+            mTrack->setPeerProxy(peer, holdReference);
+            mClearPeerProxy = holdReference;
         }
-        void clearTrackPeer() { if (mTrack) mTrack->clearPeerProxy(); }
+        void clearTrackPeer() { if (mClearPeerProxy && mTrack) mTrack->clearPeerProxy(); }
         void stopTrack() { if (mTrack) mTrack->stop(); }
 
         void swap(Endpoint &other) noexcept {
             using std::swap;
             swap(mThread, other.mThread);
             swap(mCloseThread, other.mCloseThread);
+            swap(mClearPeerProxy, other.mClearPeerProxy);
             swap(mHandle, other.mHandle);
             swap(mTrack, other.mTrack);
         }
@@ -151,6 +153,7 @@
     private:
         sp<ThreadType> mThread;
         bool mCloseThread = true;
+        bool mClearPeerProxy = true;
         audio_patch_handle_t mHandle = AUDIO_PATCH_HANDLE_NONE;
         sp<TrackType> mTrack;
     };
diff --git a/services/audiopolicy/common/managerdefinitions/src/Serializer.cpp b/services/audiopolicy/common/managerdefinitions/src/Serializer.cpp
index 4376802..1b2f7c7 100644
--- a/services/audiopolicy/common/managerdefinitions/src/Serializer.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/Serializer.cpp
@@ -200,6 +200,7 @@
     {
         static constexpr const char *speakerDrcEnabled = "speaker_drc_enabled";
         static constexpr const char *callScreenModeSupported= "call_screen_mode_supported";
+        static constexpr const char *engineLibrarySuffix = "engine_library";
     };
 
     static status_t deserialize(const xmlNode *root, AudioPolicyConfig *config);
@@ -692,6 +693,11 @@
                     convertTo<std::string, bool>(attr, value)) {
                 config->setCallScreenModeSupported(value);
             }
+            std::string engineLibrarySuffix = getXmlAttribute(cur, Attributes::engineLibrarySuffix);
+            if (!engineLibrarySuffix.empty()) {
+                config->setEngineLibraryNameSuffix(engineLibrarySuffix);
+            }
+            return NO_ERROR;
         }
     }
     return NO_ERROR;
diff --git a/services/audiopolicy/config/Android.bp b/services/audiopolicy/config/Android.bp
index 4b5e788..f4610bb 100644
--- a/services/audiopolicy/config/Android.bp
+++ b/services/audiopolicy/config/Android.bp
@@ -92,6 +92,10 @@
     srcs: ["audio_policy_configuration_generic.xml"],
 }
 filegroup {
+    name: "audio_policy_configuration_generic_configurable",
+    srcs: ["audio_policy_configuration_generic_configurable.xml"],
+}
+filegroup {
     name: "usb_audio_policy_configuration",
     srcs: ["usb_audio_policy_configuration.xml"],
 }
diff --git a/services/audiopolicy/config/audio_policy_configuration_generic_configurable.xml b/services/audiopolicy/config/audio_policy_configuration_generic_configurable.xml
new file mode 100644
index 0000000..fbe4f7f
--- /dev/null
+++ b/services/audiopolicy/config/audio_policy_configuration_generic_configurable.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!-- 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.
+-->
+
+<audioPolicyConfiguration version="1.0" xmlns:xi="http://www.w3.org/2001/XInclude">
+    <!-- version section contains a “version” tag in the form “major.minor” e.g version=”1.0” -->
+
+    <!-- Global configuration Decalaration -->
+    <globalConfiguration speaker_drc_enabled="false" engine_library="configurable"/>
+
+    <modules>
+        <!-- Primary Audio HAL -->
+        <xi:include href="primary_audio_policy_configuration.xml"/>
+
+        <!-- Remote Submix Audio HAL -->
+        <xi:include href="r_submix_audio_policy_configuration.xml"/>
+
+    </modules>
+    <!-- End of Modules section -->
+
+    <!-- Volume section:
+        IMPORTANT NOTE: Volume tables have been moved to engine configuration.
+                        Keep it here for legacy.
+                        Engine will fallback on these files if none are provided by engine.
+     -->
+
+    <xi:include href="audio_policy_volumes.xml"/>
+    <xi:include href="default_volume_tables.xml"/>
+
+    <!-- End of Volume section -->
+
+    <!-- Surround Sound configuration -->
+
+    <xi:include href="surround_sound_configuration_5_0.xml"/>
+
+    <!-- End of Surround Sound configuration -->
+
+</audioPolicyConfiguration>
diff --git a/services/audiopolicy/engine/config/Android.bp b/services/audiopolicy/engine/config/Android.bp
index 885b5fa..ff840f9 100644
--- a/services/audiopolicy/engine/config/Android.bp
+++ b/services/audiopolicy/engine/config/Android.bp
@@ -1,4 +1,4 @@
-cc_library_static {
+cc_library {
     name: "libaudiopolicyengine_config",
     export_include_dirs: ["include"],
     include_dirs: [
@@ -14,17 +14,14 @@
     ],
     shared_libs: [
         "libmedia_helper",
-        "libandroidicu",
         "libxml2",
         "libutils",
         "liblog",
         "libcutils",
     ],
-    static_libs: [
-        "libaudiopolicycomponents",
-    ],
     header_libs: [
         "libaudio_system_headers",
-        "libaudiopolicycommon",
+        "libmedia_headers",
+        "libaudioclient_headers",
     ],
 }
diff --git a/services/audiopolicy/engine/config/src/EngineConfig.cpp b/services/audiopolicy/engine/config/src/EngineConfig.cpp
index d47fbd2..7f8cdd9 100644
--- a/services/audiopolicy/engine/config/src/EngineConfig.cpp
+++ b/services/audiopolicy/engine/config/src/EngineConfig.cpp
@@ -18,7 +18,6 @@
 //#define LOG_NDEBUG 0
 
 #include "EngineConfig.h"
-#include <policy.h>
 #include <cutils/properties.h>
 #include <media/TypeConverter.h>
 #include <media/convert.h>
diff --git a/services/audiopolicy/engineconfigurable/src/Engine.cpp b/services/audiopolicy/engineconfigurable/src/Engine.cpp
index 752ba92..7e5c5e3 100644
--- a/services/audiopolicy/engineconfigurable/src/Engine.cpp
+++ b/services/audiopolicy/engineconfigurable/src/Engine.cpp
@@ -80,8 +80,9 @@
 
 status_t Engine::initCheck()
 {
-    if (mPolicyParameterMgr == nullptr || mPolicyParameterMgr->start() != NO_ERROR) {
-        ALOGE("%s: could not start Policy PFW", __FUNCTION__);
+    std::string error;
+    if (mPolicyParameterMgr == nullptr || mPolicyParameterMgr->start(error) != NO_ERROR) {
+        ALOGE("%s: could not start Policy PFW: %s", __FUNCTION__, error.c_str());
         return NO_INIT;
     }
     return EngineBase::initCheck();
@@ -162,21 +163,21 @@
     return mPolicyParameterMgr->getForceUse(usage);
 }
 
-status_t Engine::setDeviceConnectionState(const sp<DeviceDescriptor> devDesc,
+status_t Engine::setDeviceConnectionState(const sp<DeviceDescriptor> device,
                                           audio_policy_dev_state_t state)
 {
-    mPolicyParameterMgr->setDeviceConnectionState(devDesc, state);
-
-    if (audio_is_output_device(devDesc->type())) {
+    mPolicyParameterMgr->setDeviceConnectionState(
+                device->type(), device->address().c_str(), state);
+    if (audio_is_output_device(device->type())) {
         // FIXME: Use DeviceTypeSet when the interface is ready
         return mPolicyParameterMgr->setAvailableOutputDevices(
                     deviceTypesToBitMask(getApmObserver()->getAvailableOutputDevices().types()));
-    } else if (audio_is_input_device(devDesc->type())) {
+    } else if (audio_is_input_device(device->type())) {
         // FIXME: Use DeviceTypeSet when the interface is ready
         return mPolicyParameterMgr->setAvailableInputDevices(
                     deviceTypesToBitMask(getApmObserver()->getAvailableInputDevices().types()));
     }
-    return EngineBase::setDeviceConnectionState(devDesc, state);
+    return EngineBase::setDeviceConnectionState(device, state);
 }
 
 status_t Engine::loadAudioPolicyEngineConfig()
diff --git a/services/audiopolicy/engineconfigurable/wrapper/Android.bp b/services/audiopolicy/engineconfigurable/wrapper/Android.bp
index 6f59487..301ecc0 100644
--- a/services/audiopolicy/engineconfigurable/wrapper/Android.bp
+++ b/services/audiopolicy/engineconfigurable/wrapper/Android.bp
@@ -11,7 +11,6 @@
         "libbase_headers",
         "libaudiopolicycommon",
     ],
-    static_libs: ["libaudiopolicycomponents"],
     shared_libs: [
         "liblog",
         "libutils",
diff --git a/services/audiopolicy/engineconfigurable/wrapper/ParameterManagerWrapper.cpp b/services/audiopolicy/engineconfigurable/wrapper/ParameterManagerWrapper.cpp
index 465a6f9..1b3b9a0 100644
--- a/services/audiopolicy/engineconfigurable/wrapper/ParameterManagerWrapper.cpp
+++ b/services/audiopolicy/engineconfigurable/wrapper/ParameterManagerWrapper.cpp
@@ -92,7 +92,8 @@
 template <>
 struct ParameterManagerWrapper::parameterManagerElementSupported<ISelectionCriterionTypeInterface> {};
 
-ParameterManagerWrapper::ParameterManagerWrapper()
+ParameterManagerWrapper::ParameterManagerWrapper(bool enableSchemaVerification,
+                                                 const std::string &schemaUri)
     : mPfwConnectorLogger(new ParameterMgrPlatformConnectorLogger)
 {
     // Connector
@@ -104,6 +105,15 @@
 
     // Logger
     mPfwConnector->setLogger(mPfwConnectorLogger);
+
+    // Schema validation
+    std::string error;
+    bool ret = mPfwConnector->setValidateSchemasOnStart(enableSchemaVerification, error);
+    ALOGE_IF(!ret, "Failed to activate schema validation: %s", error.c_str());
+    if (enableSchemaVerification && ret && !schemaUri.empty()) {
+        ALOGE("Schema verification activated with schema URI: %s", schemaUri.c_str());
+        mPfwConnector->setSchemaUri(schemaUri);
+    }
 }
 
 status_t ParameterManagerWrapper::addCriterion(const std::string &name, bool isInclusive,
@@ -145,11 +155,10 @@
     delete mPfwConnector;
 }
 
-status_t ParameterManagerWrapper::start()
+status_t ParameterManagerWrapper::start(std::string &error)
 {
     ALOGD("%s: in", __FUNCTION__);
     /// Start PFW
-    std::string error;
     if (!mPfwConnector->start(error)) {
         ALOGE("%s: Policy PFW start error: %s", __FUNCTION__, error.c_str());
         return NO_INIT;
@@ -253,13 +262,13 @@
     return interface->getLiteralValue(valueToCheck, literalValue);
 }
 
-status_t ParameterManagerWrapper::setDeviceConnectionState(const sp<DeviceDescriptor> devDesc,
-                                                           audio_policy_dev_state_t state)
+status_t ParameterManagerWrapper::setDeviceConnectionState(
+        audio_devices_t type, const std::string address, audio_policy_dev_state_t state)
 {
-    std::string criterionName = audio_is_output_device(devDesc->type()) ?
+    std::string criterionName = audio_is_output_device(type) ?
                 gOutputDeviceAddressCriterionName : gInputDeviceAddressCriterionName;
 
-    ALOGV("%s: device with address %s %s", __FUNCTION__, devDesc->address().c_str(),
+    ALOGV("%s: device with address %s %s", __FUNCTION__, address.c_str(),
           state != AUDIO_POLICY_DEVICE_STATE_AVAILABLE? "disconnected" : "connected");
     ISelectionCriterionInterface *criterion =
             getElement<ISelectionCriterionInterface>(criterionName, mPolicyCriteria);
@@ -271,8 +280,8 @@
 
     auto criterionType = criterion->getCriterionType();
     int deviceAddressId;
-    if (not criterionType->getNumericalValue(devDesc->address().c_str(), deviceAddressId)) {
-        ALOGW("%s: unknown device address reported (%s)", __FUNCTION__, devDesc->address().c_str());
+    if (not criterionType->getNumericalValue(address.c_str(), deviceAddressId)) {
+        ALOGW("%s: unknown device address reported (%s)", __FUNCTION__, address.c_str());
         return BAD_TYPE;
     }
     int currentValueMask = criterion->getCriterionState();
diff --git a/services/audiopolicy/engineconfigurable/wrapper/include/ParameterManagerWrapper.h b/services/audiopolicy/engineconfigurable/wrapper/include/ParameterManagerWrapper.h
index 8443008..62b129a 100644
--- a/services/audiopolicy/engineconfigurable/wrapper/include/ParameterManagerWrapper.h
+++ b/services/audiopolicy/engineconfigurable/wrapper/include/ParameterManagerWrapper.h
@@ -16,9 +16,6 @@
 
 #pragma once
 
-#include <PolicyAudioPort.h>
-#include <HwModule.h>
-#include <DeviceDescriptor.h>
 #include <system/audio.h>
 #include <system/audio_policy.h>
 #include <utils/Errors.h>
@@ -47,16 +44,18 @@
     using Criteria = std::map<std::string, ISelectionCriterionInterface *>;
 
 public:
-    ParameterManagerWrapper();
+    ParameterManagerWrapper(bool enableSchemaVerification = false,
+                            const std::string &schemaUri = {});
     ~ParameterManagerWrapper();
 
     /**
      * Starts the platform state service.
      * It starts the parameter framework policy instance.
+     * @param[out] contains human readable error if starts failed
      *
-     * @return NO_ERROR if success, error code otherwise.
+     * @return NO_ERROR if success, error code otherwise, and error is set to human readable string.
      */
-    status_t start();
+    status_t start(std::string &error);
 
     /**
      * The following API wrap policy action to criteria
@@ -117,7 +116,15 @@
      */
     status_t setAvailableOutputDevices(audio_devices_t outputDevices);
 
-    status_t setDeviceConnectionState(const sp<DeviceDescriptor> devDesc,
+    /**
+     * @brief setDeviceConnectionState propagates a state event on a given device(s)
+     * @param type bit mask of the device whose state has changed
+     * @param address of the device whose state has changed
+     * @param state new state of the given device
+     * @return NO_ERROR if new state corretly propagated to Engine Parameter-Framework, error
+     * code otherwise.
+     */
+    status_t setDeviceConnectionState(audio_devices_t type, const std::string address,
                                       audio_policy_dev_state_t state);
 
     /**
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index 18ed3a5..a110c33 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -761,6 +761,7 @@
           case CAMERA_DEVICE_API_VERSION_3_3:
           case CAMERA_DEVICE_API_VERSION_3_4:
           case CAMERA_DEVICE_API_VERSION_3_5:
+          case CAMERA_DEVICE_API_VERSION_3_6:
             if (effectiveApiLevel == API_1) { // Camera1 API route
                 sp<ICameraClient> tmp = static_cast<ICameraClient*>(cameraCb.get());
                 *client = new Camera2Client(cameraService, tmp, packageName, featureId,
@@ -2093,6 +2094,7 @@
         case CAMERA_DEVICE_API_VERSION_3_3:
         case CAMERA_DEVICE_API_VERSION_3_4:
         case CAMERA_DEVICE_API_VERSION_3_5:
+        case CAMERA_DEVICE_API_VERSION_3_6:
             ALOGV("%s: Camera id %s uses HAL3.2 or newer, supports api1/api2 directly",
                     __FUNCTION__, id.string());
             *isSupported = true;
diff --git a/services/mediatranscoding/MediaTranscodingService.cpp b/services/mediatranscoding/MediaTranscodingService.cpp
index 2680cee..0269896 100644
--- a/services/mediatranscoding/MediaTranscodingService.cpp
+++ b/services/mediatranscoding/MediaTranscodingService.cpp
@@ -25,10 +25,6 @@
 
 namespace android {
 
-namespace media {
-
-using android::media::MediaTranscodingService;
-
 MediaTranscodingService::MediaTranscodingService() {
     ALOGV("MediaTranscodingService is created");
 }
@@ -56,7 +52,8 @@
 
 Status MediaTranscodingService::registerClient(
         const std::shared_ptr<ITranscodingServiceClient>& /*in_client*/,
-        int32_t* /*_aidl_return*/) {
+        const std::string& /* in_opPackageName */, int32_t /* in_clientUid */,
+        int32_t /* in_clientPid */, int32_t* /*_aidl_return*/) {
     // TODO(hkuang): Add implementation.
     return Status::ok();
 }
@@ -67,8 +64,9 @@
 }
 
 Status MediaTranscodingService::submitRequest(int32_t /*clientId*/,
-                                              const TranscodingRequest& /*request*/,
-                                              TranscodingJob* /*job*/, int32_t* /*_aidl_return*/) {
+                                              const TranscodingRequestParcel& /*request*/,
+                                              TranscodingJobParcel* /*job*/,
+                                              int32_t* /*_aidl_return*/) {
     // TODO(hkuang): Add implementation.
     return Status::ok();
 }
@@ -79,11 +77,11 @@
     return Status::ok();
 }
 
-Status MediaTranscodingService::getJobWithId(int32_t /*in_jobId*/, TranscodingJob* /*out_job*/,
+Status MediaTranscodingService::getJobWithId(int32_t /*in_jobId*/,
+                                             TranscodingJobParcel* /*out_job*/,
                                              bool* /*_aidl_return*/) {
     // TODO(hkuang): Add implementation.
     return Status::ok();
 }
 
-}  // namespace media
 }  // namespace android
diff --git a/services/mediatranscoding/MediaTranscodingService.h b/services/mediatranscoding/MediaTranscodingService.h
index c2c30b9..d225f9a 100644
--- a/services/mediatranscoding/MediaTranscodingService.h
+++ b/services/mediatranscoding/MediaTranscodingService.h
@@ -22,13 +22,11 @@
 
 namespace android {
 
-namespace media {
-
 using Status = ::ndk::ScopedAStatus;
 using ::aidl::android::media::BnMediaTranscodingService;
 using ::aidl::android::media::ITranscodingServiceClient;
-using ::aidl::android::media::TranscodingJob;
-using ::aidl::android::media::TranscodingRequest;
+using ::aidl::android::media::TranscodingJobParcel;
+using ::aidl::android::media::TranscodingRequestParcel;
 
 class MediaTranscodingService : public BnMediaTranscodingService {
 public:
@@ -40,23 +38,24 @@
     static const char* getServiceName() { return "media.transcoding"; }
 
     Status registerClient(const std::shared_ptr<ITranscodingServiceClient>& in_client,
-                          int32_t* _aidl_return) override;
+                          const std::string& in_opPackageName, int32_t in_clientUid,
+                          int32_t in_clientPid, int32_t* _aidl_return) override;
 
     Status unregisterClient(int32_t clientId, bool* _aidl_return) override;
 
-    Status submitRequest(int32_t in_clientId, const TranscodingRequest& in_request,
-                         TranscodingJob* out_job, int32_t* _aidl_return) override;
+    Status submitRequest(int32_t in_clientId, const TranscodingRequestParcel& in_request,
+                         TranscodingJobParcel* out_job, int32_t* _aidl_return) override;
 
     Status cancelJob(int32_t in_clientId, int32_t in_jobId, bool* _aidl_return) override;
 
-    Status getJobWithId(int32_t in_jobId, TranscodingJob* out_job, bool* _aidl_return) override;
+    Status getJobWithId(int32_t in_jobId, TranscodingJobParcel* out_job,
+                        bool* _aidl_return) override;
 
     virtual inline binder_status_t dump(int /*fd*/, const char** /*args*/, uint32_t /*numArgs*/);
 
 private:
 };
 
-}  // namespace media
 }  // namespace android
 
 #endif  // ANDROID_MEDIA_TRANSCODING_SERVICE_H
diff --git a/services/mediatranscoding/main_mediatranscodingservice.cpp b/services/mediatranscoding/main_mediatranscodingservice.cpp
index 1978eb4..7d862e6 100644
--- a/services/mediatranscoding/main_mediatranscodingservice.cpp
+++ b/services/mediatranscoding/main_mediatranscodingservice.cpp
@@ -29,7 +29,7 @@
     strcpy(argv[0], "media.transcoding");
     sp<ProcessState> proc(ProcessState::self());
     sp<IServiceManager> sm = defaultServiceManager();
-    android::media::MediaTranscodingService::instantiate();
+    android::MediaTranscodingService::instantiate();
 
     ProcessState::self()->startThreadPool();
     IPCThreadState::self()->joinThreadPool();