Merge "vorbisdec: support 192Khz sample rate for vorbis" into qt-aml-media-dev
am: f54b3d7732

Change-Id: I67fc51548fac57586e9841678731516d79c4f69d
diff --git a/apex/ld.config.txt b/apex/ld.config.txt
index af8ec06..f56e1b5 100644
--- a/apex/ld.config.txt
+++ b/apex/ld.config.txt
@@ -44,7 +44,7 @@
 namespace.platform.asan.search.paths += /apex/com.android.runtime/${LIB}
 
 # /system/lib/libc.so, etc are symlinks to /apex/com.android.lib/lib/bionic/libc.so, etc.
-# Add /apex/... pat to the permitted paths because linker uses realpath(3)
+# Add /apex/... path to the permitted paths because linker uses realpath(3)
 # to check the accessibility of the lib. We could add this to search.paths
 # instead but that makes the resolution of bionic libs be dependent on
 # the order of /system/lib and /apex/... in search.paths. If /apex/...
@@ -131,3 +131,9 @@
 
 # Add a link for libz.so which is llndk on devices where VNDK is not enforced.
 namespace.sphal.link.platform.shared_libs += libz.so
+
+# With VNDK APEX, /system/${LIB}/vndk-sp${VNDK_VER} is a symlink to the following.
+# Add /apex/... path to the permitted paths because linker uses realpath(3)
+# to check the accessibility of the lib.
+namespace.sphal.permitted.paths += /apex/com.android.vndk.${VNDK_APEX_VER}/${LIB}
+namespace.sphal.asan.permitted.paths += /apex/com.android.vndk.${VNDK_APEX_VER}/${LIB}
diff --git a/apex/manifest.json b/apex/manifest.json
index b11187d..3011ee8 100644
--- a/apex/manifest.json
+++ b/apex/manifest.json
@@ -1,4 +1,4 @@
 {
   "name": "com.android.media",
-  "version": 299900000
+  "version": 290000000
 }
diff --git a/apex/manifest_codec.json b/apex/manifest_codec.json
index 09c436d..83a5178 100644
--- a/apex/manifest_codec.json
+++ b/apex/manifest_codec.json
@@ -1,4 +1,4 @@
 {
   "name": "com.android.media.swcodec",
-  "version": 299900000
+  "version": 290000000
 }
diff --git a/camera/Android.bp b/camera/Android.bp
index 2800595..b288bcf 100644
--- a/camera/Android.bp
+++ b/camera/Android.bp
@@ -86,6 +86,7 @@
         "aidl/android/hardware/camera2/ICameraDeviceCallbacks.aidl",
         "aidl/android/hardware/camera2/ICameraDeviceUser.aidl",
     ],
+    path: "aidl",
 }
 
 // Extra AIDL files that are used by framework.jar but not libcamera_client
@@ -96,4 +97,5 @@
         "aidl/android/hardware/ICamera.aidl",
         "aidl/android/hardware/ICameraClient.aidl",
     ],
+    path: "aidl",
 }
diff --git a/camera/cameraserver/Android.bp b/camera/cameraserver/Android.bp
index ecaba3a..320c499 100644
--- a/camera/cameraserver/Android.bp
+++ b/camera/cameraserver/Android.bp
@@ -17,6 +17,10 @@
 
     srcs: ["main_cameraserver.cpp"],
 
+    header_libs: [
+        "libmedia_headers",
+    ],
+
     shared_libs: [
         "libcameraservice",
         "liblog",
@@ -25,7 +29,6 @@
         "libgui",
         "libbinder",
         "libhidlbase",
-        "libhidltransport",
         "android.hardware.camera.common@1.0",
         "android.hardware.camera.provider@2.4",
         "android.hardware.camera.provider@2.5",
diff --git a/camera/ndk/Android.bp b/camera/ndk/Android.bp
index a2ee65d..d8220eb 100644
--- a/camera/ndk/Android.bp
+++ b/camera/ndk/Android.bp
@@ -107,7 +107,6 @@
     ],
 
     shared_libs: [
-        "libhwbinder",
         "libfmq",
         "libhidlbase",
         "libhardware",
@@ -143,7 +142,6 @@
     vendor: true,
     srcs: ["ndk_vendor/tests/AImageReaderVendorTest.cpp"],
     shared_libs: [
-        "libhwbinder",
         "libcamera2ndk_vendor",
         "libcamera_metadata",
         "libmediandk",
diff --git a/camera/ndk/impl/ACameraDevice.cpp b/camera/ndk/impl/ACameraDevice.cpp
index d24cb81..46a8dae 100644
--- a/camera/ndk/impl/ACameraDevice.cpp
+++ b/camera/ndk/impl/ACameraDevice.cpp
@@ -29,7 +29,7 @@
 #include "ACameraCaptureSession.inc"
 
 ACameraDevice::~ACameraDevice() {
-    mDevice->stopLooper();
+    mDevice->stopLooperAndDisconnect();
 }
 
 namespace android {
@@ -112,19 +112,7 @@
     }
 }
 
-// Device close implementaiton
-CameraDevice::~CameraDevice() {
-    sp<ACameraCaptureSession> session = mCurrentSession.promote();
-    {
-        Mutex::Autolock _l(mDeviceLock);
-        if (!isClosed()) {
-            disconnectLocked(session);
-        }
-        LOG_ALWAYS_FATAL_IF(mCbLooper != nullptr,
-                "CameraDevice looper should've been stopped before ~CameraDevice");
-        mCurrentSession = nullptr;
-    }
-}
+CameraDevice::~CameraDevice() { }
 
 void
 CameraDevice::postSessionMsgAndCleanup(sp<AMessage>& msg) {
@@ -892,8 +880,14 @@
     return;
 }
 
-void CameraDevice::stopLooper() {
+void CameraDevice::stopLooperAndDisconnect() {
     Mutex::Autolock _l(mDeviceLock);
+    sp<ACameraCaptureSession> session = mCurrentSession.promote();
+    if (!isClosed()) {
+        disconnectLocked(session);
+    }
+    mCurrentSession = nullptr;
+
     if (mCbLooper != nullptr) {
       mCbLooper->unregisterHandler(mHandler->id());
       mCbLooper->stop();
diff --git a/camera/ndk/impl/ACameraDevice.h b/camera/ndk/impl/ACameraDevice.h
index 7a35bf0..6c2ceb3 100644
--- a/camera/ndk/impl/ACameraDevice.h
+++ b/camera/ndk/impl/ACameraDevice.h
@@ -40,6 +40,7 @@
 
 #include <camera/NdkCameraManager.h>
 #include <camera/NdkCameraCaptureSession.h>
+
 #include "ACameraMetadata.h"
 
 namespace android {
@@ -110,7 +111,7 @@
     inline ACameraDevice* getWrapper() const { return mWrapper; };
 
     // Stop the looper thread and unregister the handler
-    void stopLooper();
+    void stopLooperAndDisconnect();
 
   private:
     friend ACameraCaptureSession;
diff --git a/camera/ndk/ndk_vendor/impl/ACameraDevice.cpp b/camera/ndk/ndk_vendor/impl/ACameraDevice.cpp
index 35c8355..e511a3f 100644
--- a/camera/ndk/ndk_vendor/impl/ACameraDevice.cpp
+++ b/camera/ndk/ndk_vendor/impl/ACameraDevice.cpp
@@ -45,7 +45,7 @@
 using namespace android;
 
 ACameraDevice::~ACameraDevice() {
-    mDevice->stopLooper();
+    mDevice->stopLooperAndDisconnect();
 }
 
 namespace android {
@@ -125,19 +125,7 @@
     }
 }
 
-// Device close implementaiton
-CameraDevice::~CameraDevice() {
-    sp<ACameraCaptureSession> session = mCurrentSession.promote();
-    {
-        Mutex::Autolock _l(mDeviceLock);
-        if (!isClosed()) {
-            disconnectLocked(session);
-        }
-        mCurrentSession = nullptr;
-        LOG_ALWAYS_FATAL_IF(mCbLooper != nullptr,
-            "CameraDevice looper should've been stopped before ~CameraDevice");
-    }
-}
+CameraDevice::~CameraDevice() { }
 
 void
 CameraDevice::postSessionMsgAndCleanup(sp<AMessage>& msg) {
@@ -1388,6 +1376,7 @@
             // before cbh goes out of scope and causing we call the session
             // destructor while holding device lock
             cbh.mSession.clear();
+
             postSessionMsgAndCleanup(msg);
         }
 
@@ -1400,8 +1389,13 @@
     }
 }
 
-void CameraDevice::stopLooper() {
+void CameraDevice::stopLooperAndDisconnect() {
     Mutex::Autolock _l(mDeviceLock);
+    sp<ACameraCaptureSession> session = mCurrentSession.promote();
+    if (!isClosed()) {
+        disconnectLocked(session);
+    }
+    mCurrentSession = nullptr;
     if (mCbLooper != nullptr) {
       mCbLooper->unregisterHandler(mHandler->id());
       mCbLooper->stop();
diff --git a/camera/ndk/ndk_vendor/impl/ACameraDevice.h b/camera/ndk/ndk_vendor/impl/ACameraDevice.h
index 9e034c4..7fc699e 100644
--- a/camera/ndk/ndk_vendor/impl/ACameraDevice.h
+++ b/camera/ndk/ndk_vendor/impl/ACameraDevice.h
@@ -36,6 +36,7 @@
 
 #include <camera/NdkCameraManager.h>
 #include <camera/NdkCameraCaptureSession.h>
+
 #include "ACameraMetadata.h"
 #include "utils.h"
 
@@ -134,7 +135,7 @@
     inline ACameraDevice* getWrapper() const { return mWrapper; };
 
     // Stop the looper thread and unregister the handler
-    void stopLooper();
+    void stopLooperAndDisconnect();
 
   private:
     friend ACameraCaptureSession;
diff --git a/cmds/screenrecord/Android.bp b/cmds/screenrecord/Android.bp
index 86476cd..6bdbab1 100644
--- a/cmds/screenrecord/Android.bp
+++ b/cmds/screenrecord/Android.bp
@@ -24,6 +24,10 @@
         "Program.cpp",
     ],
 
+    header_libs: [
+        "libmediadrm_headers",
+    ],
+
     shared_libs: [
         "libstagefright",
         "libmedia",
diff --git a/cmds/screenrecord/screenrecord.cpp b/cmds/screenrecord/screenrecord.cpp
index 7aa655f..f2a71b3 100644
--- a/cmds/screenrecord/screenrecord.cpp
+++ b/cmds/screenrecord/screenrecord.cpp
@@ -52,7 +52,7 @@
 #include <media/stagefright/MediaErrors.h>
 #include <media/stagefright/MediaMuxer.h>
 #include <media/stagefright/PersistentSurface.h>
-#include <media/ICrypto.h>
+#include <mediadrm/ICrypto.h>
 #include <media/MediaCodecBuffer.h>
 
 #include "screenrecord.h"
@@ -368,6 +368,7 @@
     int64_t startWhenNsec = systemTime(CLOCK_MONOTONIC);
     int64_t endWhenNsec = startWhenNsec + seconds_to_nanoseconds(gTimeLimitSec);
     DisplayInfo mainDpyInfo;
+    bool firstFrame = true;
 
     assert((rawFp == NULL && muxer != NULL) || (rawFp != NULL && muxer == NULL));
 
@@ -384,6 +385,11 @@
         int64_t ptsUsec;
         uint32_t flags;
 
+        if (firstFrame) {
+            ATRACE_NAME("first_frame");
+            firstFrame = false;
+        }
+
         if (systemTime(CLOCK_MONOTONIC) > endWhenNsec) {
             if (gVerbose) {
                 printf("Time limit reached\n");
diff --git a/cmds/stagefright/Android.mk b/cmds/stagefright/Android.mk
index 6eb2e9f..defc94f 100644
--- a/cmds/stagefright/Android.mk
+++ b/cmds/stagefright/Android.mk
@@ -3,21 +3,21 @@
 include $(CLEAR_VARS)
 
 LOCAL_SRC_FILES:=       \
+        AudioPlayer.cpp \
         stagefright.cpp \
         jpeg.cpp        \
         SineSource.cpp
 
 LOCAL_SHARED_LIBRARIES := \
-        libstagefright libmedia libmedia_omx libutils libbinder \
+        libstagefright libmedia libmedia_codeclist libutils libbinder \
         libstagefright_foundation libjpeg libui libgui libcutils liblog \
-        libhidlbase \
+        libhidlbase libdatasource libaudioclient \
         android.hardware.media.omx@1.0 \
 
 LOCAL_C_INCLUDES:= \
         frameworks/av/media/libstagefright \
         frameworks/av/media/libstagefright/include \
         frameworks/native/include/media/openmax \
-        external/jpeg \
 
 LOCAL_CFLAGS += -Wno-multichar -Werror -Wall
 
@@ -32,14 +32,16 @@
 include $(CLEAR_VARS)
 
 LOCAL_SRC_FILES:=         \
+        AudioPlayer.cpp \
         SineSource.cpp    \
         record.cpp
 
 LOCAL_SHARED_LIBRARIES := \
         libstagefright libmedia liblog libutils libbinder \
-        libstagefright_foundation
+        libstagefright_foundation libdatasource libaudioclient
 
 LOCAL_C_INCLUDES:= \
+        frameworks/av/camera/include \
         frameworks/av/media/libstagefright \
         frameworks/native/include/media/openmax \
         frameworks/native/include/media/hardware
@@ -57,12 +59,12 @@
 include $(CLEAR_VARS)
 
 LOCAL_SRC_FILES:=         \
-        SineSource.cpp    \
+        AudioPlayer.cpp \
         recordvideo.cpp
 
 LOCAL_SHARED_LIBRARIES := \
         libstagefright libmedia liblog libutils libbinder \
-        libstagefright_foundation
+        libstagefright_foundation libaudioclient
 
 LOCAL_C_INCLUDES:= \
         frameworks/av/media/libstagefright \
@@ -83,12 +85,13 @@
 include $(CLEAR_VARS)
 
 LOCAL_SRC_FILES:=         \
+        AudioPlayer.cpp \
         SineSource.cpp    \
         audioloop.cpp
 
 LOCAL_SHARED_LIBRARIES := \
         libstagefright libmedia liblog libutils libbinder \
-        libstagefright_foundation
+        libstagefright_foundation libaudioclient
 
 LOCAL_C_INCLUDES:= \
         frameworks/av/media/libstagefright \
@@ -111,7 +114,7 @@
 
 LOCAL_SHARED_LIBRARIES := \
         libstagefright liblog libutils libbinder libui libgui \
-        libstagefright_foundation libmedia libcutils
+        libstagefright_foundation libmedia libcutils libdatasource
 
 LOCAL_C_INCLUDES:= \
         frameworks/av/media/libstagefright \
@@ -133,6 +136,9 @@
         codec.cpp               \
         SimplePlayer.cpp        \
 
+LOCAL_HEADER_LIBRARIES := \
+        libmediadrm_headers \
+
 LOCAL_SHARED_LIBRARIES := \
         libstagefright liblog libutils libbinder libstagefright_foundation \
         libmedia libmedia_omx libaudioclient libui libgui libcutils
@@ -154,22 +160,23 @@
 include $(CLEAR_VARS)
 
 LOCAL_SRC_FILES:= \
-        filters/argbtorgba.rs \
-        filters/nightvision.rs \
-        filters/saturation.rs \
+        filters/argbtorgba.rscript \
+        filters/nightvision.rscript \
+        filters/saturation.rscript \
         mediafilter.cpp \
 
+LOCAL_HEADER_LIBRARIES := \
+        libmediadrm_headers \
+
 LOCAL_SHARED_LIBRARIES := \
         libstagefright \
         liblog \
         libutils \
         libbinder \
         libstagefright_foundation \
-        libmedia \
         libmedia_omx \
         libui \
         libgui \
-        libcutils \
         libRScpp \
 
 LOCAL_C_INCLUDES:= \
diff --git a/media/libstagefright/AudioPlayer.cpp b/cmds/stagefright/AudioPlayer.cpp
similarity index 99%
rename from media/libstagefright/AudioPlayer.cpp
rename to cmds/stagefright/AudioPlayer.cpp
index 199b57b..208713d 100644
--- a/media/libstagefright/AudioPlayer.cpp
+++ b/cmds/stagefright/AudioPlayer.cpp
@@ -28,12 +28,13 @@
 #include <media/stagefright/foundation/ADebug.h>
 #include <media/stagefright/foundation/ALookup.h>
 #include <media/stagefright/foundation/ALooper.h>
-#include <media/stagefright/AudioPlayer.h>
 #include <media/stagefright/MediaDefs.h>
 #include <media/stagefright/MediaErrors.h>
 #include <media/stagefright/MetaData.h>
 #include <media/stagefright/Utils.h>
 
+#include "AudioPlayer.h"
+
 namespace android {
 
 AudioPlayer::AudioPlayer(
diff --git a/media/libstagefright/include/media/stagefright/AudioPlayer.h b/cmds/stagefright/AudioPlayer.h
similarity index 100%
rename from media/libstagefright/include/media/stagefright/AudioPlayer.h
rename to cmds/stagefright/AudioPlayer.h
diff --git a/cmds/stagefright/SimplePlayer.cpp b/cmds/stagefright/SimplePlayer.cpp
index afb7db3..f4b8164 100644
--- a/cmds/stagefright/SimplePlayer.cpp
+++ b/cmds/stagefright/SimplePlayer.cpp
@@ -23,7 +23,7 @@
 #include <gui/Surface.h>
 
 #include <media/AudioTrack.h>
-#include <media/ICrypto.h>
+#include <mediadrm/ICrypto.h>
 #include <media/IMediaHTTPService.h>
 #include <media/MediaCodecBuffer.h>
 #include <media/stagefright/foundation/ABuffer.h>
diff --git a/cmds/stagefright/audioloop.cpp b/cmds/stagefright/audioloop.cpp
index d4f2e8d..bd274d8 100644
--- a/cmds/stagefright/audioloop.cpp
+++ b/cmds/stagefright/audioloop.cpp
@@ -29,11 +29,11 @@
 #include <media/stagefright/foundation/ADebug.h>
 #include <media/stagefright/foundation/AMessage.h>
 #include <media/stagefright/AMRWriter.h>
-#include <media/stagefright/AudioPlayer.h>
 #include <media/stagefright/AudioSource.h>
 #include <media/stagefright/MediaCodecSource.h>
 #include <media/stagefright/MediaDefs.h>
 #include <media/stagefright/SimpleDecodingSource.h>
+#include "AudioPlayer.h"
 #include "SineSource.h"
 
 using namespace android;
diff --git a/cmds/stagefright/codec.cpp b/cmds/stagefright/codec.cpp
index e5a4337..f2d1c29 100644
--- a/cmds/stagefright/codec.cpp
+++ b/cmds/stagefright/codec.cpp
@@ -23,7 +23,7 @@
 
 #include <binder/IServiceManager.h>
 #include <binder/ProcessState.h>
-#include <media/ICrypto.h>
+#include <mediadrm/ICrypto.h>
 #include <media/IMediaHTTPService.h>
 #include <media/IMediaPlayerService.h>
 #include <media/MediaCodecBuffer.h>
diff --git a/cmds/stagefright/filters/argbtorgba.rs b/cmds/stagefright/filters/argbtorgba.rscript
similarity index 100%
rename from cmds/stagefright/filters/argbtorgba.rs
rename to cmds/stagefright/filters/argbtorgba.rscript
diff --git a/cmds/stagefright/filters/nightvision.rs b/cmds/stagefright/filters/nightvision.rscript
similarity index 100%
rename from cmds/stagefright/filters/nightvision.rs
rename to cmds/stagefright/filters/nightvision.rscript
diff --git a/cmds/stagefright/filters/saturation.rs b/cmds/stagefright/filters/saturation.rscript
similarity index 100%
rename from cmds/stagefright/filters/saturation.rs
rename to cmds/stagefright/filters/saturation.rscript
diff --git a/cmds/stagefright/mediafilter.cpp b/cmds/stagefright/mediafilter.cpp
index 2cf6955..66302b0 100644
--- a/cmds/stagefright/mediafilter.cpp
+++ b/cmds/stagefright/mediafilter.cpp
@@ -24,9 +24,9 @@
 #include <gui/ISurfaceComposer.h>
 #include <gui/SurfaceComposerClient.h>
 #include <gui/Surface.h>
-#include <media/ICrypto.h>
 #include <media/IMediaHTTPService.h>
 #include <media/MediaCodecBuffer.h>
+#include <mediadrm/ICrypto.h>
 #include <media/stagefright/foundation/ABuffer.h>
 #include <media/stagefright/foundation/ADebug.h>
 #include <media/stagefright/foundation/AMessage.h>
diff --git a/cmds/stagefright/record.cpp b/cmds/stagefright/record.cpp
index 95a16f3..37091c4 100644
--- a/cmds/stagefright/record.cpp
+++ b/cmds/stagefright/record.cpp
@@ -17,12 +17,11 @@
 #include "SineSource.h"
 
 #include <binder/ProcessState.h>
+#include <datasource/FileSource.h>
 #include <media/stagefright/foundation/ADebug.h>
 #include <media/stagefright/foundation/ALooper.h>
 #include <media/stagefright/foundation/AMessage.h>
-#include <media/stagefright/AudioPlayer.h>
 #include <media/stagefright/CameraSource.h>
-#include <media/stagefright/FileSource.h>
 #include <media/stagefright/MediaBufferGroup.h>
 #include <media/stagefright/MediaDefs.h>
 #include <media/stagefright/MediaCodecSource.h>
@@ -33,6 +32,8 @@
 #include <media/stagefright/SimpleDecodingSource.h>
 #include <media/MediaPlayerInterface.h>
 
+#include "AudioPlayer.h"
+
 using namespace android;
 
 static const int32_t kAudioBitRate = 12200;
diff --git a/cmds/stagefright/recordvideo.cpp b/cmds/stagefright/recordvideo.cpp
index a63b9b9..01a178e 100644
--- a/cmds/stagefright/recordvideo.cpp
+++ b/cmds/stagefright/recordvideo.cpp
@@ -14,8 +14,6 @@
  * limitations under the License.
  */
 
-#include "SineSource.h"
-
 #include <inttypes.h>
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -25,8 +23,8 @@
 #include <media/stagefright/foundation/ADebug.h>
 #include <media/stagefright/foundation/ALooper.h>
 #include <media/stagefright/foundation/AMessage.h>
-#include <media/stagefright/AudioPlayer.h>
 #include <media/stagefright/MediaBufferGroup.h>
+#include <media/stagefright/MediaBuffer.h>
 #include <media/stagefright/MediaCodecSource.h>
 #include <media/stagefright/MediaDefs.h>
 #include <media/stagefright/MetaData.h>
diff --git a/cmds/stagefright/stagefright.cpp b/cmds/stagefright/stagefright.cpp
index bf36be0..02ade94 100644
--- a/cmds/stagefright/stagefright.cpp
+++ b/cmds/stagefright/stagefright.cpp
@@ -31,18 +31,15 @@
 
 #include <binder/IServiceManager.h>
 #include <binder/ProcessState.h>
+#include <datasource/DataSourceFactory.h>
 #include <media/DataSource.h>
 #include <media/MediaSource.h>
-#include <media/ICrypto.h>
 #include <media/IMediaHTTPService.h>
 #include <media/IMediaPlayerService.h>
 #include <media/stagefright/foundation/ABuffer.h>
 #include <media/stagefright/foundation/ALooper.h>
 #include <media/stagefright/foundation/AMessage.h>
 #include <media/stagefright/foundation/AUtils.h>
-#include "include/NuCachedSource2.h"
-#include <media/stagefright/AudioPlayer.h>
-#include <media/stagefright/DataSourceFactory.h>
 #include <media/stagefright/JPEGSource.h>
 #include <media/stagefright/InterfaceUtils.h>
 #include <media/stagefright/MediaCodec.h>
@@ -69,6 +66,8 @@
 
 #include <android/hardware/media/omx/1.0/IOmx.h>
 
+#include "AudioPlayer.h"
+
 using namespace android;
 
 static long gNumRepetitions;
@@ -305,7 +304,7 @@
             seekTimeUs = -1;
 
             if (shouldSeek) {
-                seekTimeUs = (rand() * (float)durationUs) / RAND_MAX;
+                seekTimeUs = (rand() * (float)durationUs) / (float)RAND_MAX;
                 options.setSeekTo(seekTimeUs);
 
                 printf("seeking to %" PRId64 " us (%.2f secs)\n",
@@ -1086,7 +1085,7 @@
         const char *filename = argv[k];
 
         sp<DataSource> dataSource =
-            DataSourceFactory::CreateFromURI(NULL /* httpService */, filename);
+            DataSourceFactory::getInstance()->CreateFromURI(NULL /* httpService */, filename);
 
         if (strncasecmp(filename, "sine:", 5) && dataSource == NULL) {
             fprintf(stderr, "Unable to create data source.\n");
diff --git a/cmds/stagefright/stream.cpp b/cmds/stagefright/stream.cpp
index 35bdbc0..22e2ef3 100644
--- a/cmds/stagefright/stream.cpp
+++ b/cmds/stagefright/stream.cpp
@@ -21,6 +21,7 @@
 #include <binder/ProcessState.h>
 #include <cutils/properties.h> // for property_get
 
+#include <datasource/DataSourceFactory.h>
 #include <media/DataSource.h>
 #include <media/IMediaHTTPService.h>
 #include <media/IStreamSource.h>
@@ -28,7 +29,6 @@
 #include <media/MediaSource.h>
 #include <media/stagefright/foundation/ADebug.h>
 #include <media/stagefright/foundation/AMessage.h>
-#include <media/stagefright/DataSourceFactory.h>
 #include <media/stagefright/InterfaceUtils.h>
 #include <media/stagefright/MPEG2TSWriter.h>
 #include <media/stagefright/MediaExtractor.h>
@@ -164,7 +164,7 @@
     : mCurrentBufferIndex(-1),
       mCurrentBufferOffset(0) {
     sp<DataSource> dataSource =
-        DataSourceFactory::CreateFromURI(NULL /* httpService */, filename);
+        DataSourceFactory::getInstance()->CreateFromURI(NULL /* httpService */, filename);
 
     CHECK(dataSource != NULL);
 
diff --git a/drm/libmediadrm/Android.bp b/drm/libmediadrm/Android.bp
index d6db1d4..84f2f6d 100644
--- a/drm/libmediadrm/Android.bp
+++ b/drm/libmediadrm/Android.bp
@@ -2,9 +2,16 @@
 // libmediadrm
 //
 
-// TODO: change it back to cc_library_shared when MediaPlayer2 switches to
-// using NdkMediaDrm, instead of MediaDrm.java.
-cc_library {
+cc_library_headers {
+    name: "libmediadrm_headers",
+
+    export_include_dirs: [
+        "interface"
+    ],
+
+}
+
+cc_library_shared {
     name: "libmediadrm",
 
     srcs: [
@@ -19,6 +26,19 @@
         "CryptoHal.cpp",
     ],
 
+    local_include_dirs: [
+        "include",
+        "interface"
+    ],
+
+    export_include_dirs: [
+        "include"
+    ],
+
+    header_libs: [
+        "libmedia_headers",
+    ],
+
     shared_libs: [
         "libbinder",
         "libcutils",
@@ -34,7 +54,6 @@
         "android.hardware.drm@1.2",
         "libhidlallocatorutils",
         "libhidlbase",
-        "libhidltransport",
     ],
 
     cflags: [
@@ -52,10 +71,17 @@
         "protos/metrics.proto",
     ],
 
+    local_include_dirs: [
+        "include"
+    ],
+
     proto: {
         export_proto_headers: true,
         type: "lite",
     },
+    header_libs: [
+        "libmedia_headers",
+    ],
     shared_libs: [
         "android.hardware.drm@1.0",
         "android.hardware.drm@1.1",
@@ -83,10 +109,17 @@
         "protos/metrics.proto",
     ],
 
+    local_include_dirs: [
+        "include"
+    ],
+
     proto: {
         export_proto_headers: true,
         type: "full",
     },
+    header_libs: [
+        "libmedia_headers",
+    ],
     shared_libs: [
         "android.hardware.drm@1.0",
         "android.hardware.drm@1.1",
diff --git a/drm/libmediadrm/DrmHal.cpp b/drm/libmediadrm/DrmHal.cpp
index 919f4ee..e79fd4b 100644
--- a/drm/libmediadrm/DrmHal.cpp
+++ b/drm/libmediadrm/DrmHal.cpp
@@ -895,9 +895,8 @@
 status_t DrmHal::provideKeyResponse(Vector<uint8_t> const &sessionId,
         Vector<uint8_t> const &response, Vector<uint8_t> &keySetId) {
     Mutex::Autolock autoLock(mLock);
-    EventTimer<status_t> keyResponseTimer(&mMetrics.mProvideKeyResponseTimeUs);
-
     INIT_CHECK();
+    EventTimer<status_t> keyResponseTimer(&mMetrics.mProvideKeyResponseTimeUs);
 
     DrmSessionManager::Instance()->useSession(sessionId);
 
diff --git a/media/libmedia/include/media/CryptoHal.h b/drm/libmediadrm/include/mediadrm/CryptoHal.h
similarity index 100%
rename from media/libmedia/include/media/CryptoHal.h
rename to drm/libmediadrm/include/mediadrm/CryptoHal.h
diff --git a/media/libmedia/include/media/DrmHal.h b/drm/libmediadrm/include/mediadrm/DrmHal.h
similarity index 100%
rename from media/libmedia/include/media/DrmHal.h
rename to drm/libmediadrm/include/mediadrm/DrmHal.h
diff --git a/media/libmedia/include/media/DrmMetrics.h b/drm/libmediadrm/include/mediadrm/DrmMetrics.h
similarity index 100%
rename from media/libmedia/include/media/DrmMetrics.h
rename to drm/libmediadrm/include/mediadrm/DrmMetrics.h
diff --git a/media/libmedia/include/media/DrmPluginPath.h b/drm/libmediadrm/include/mediadrm/DrmPluginPath.h
similarity index 100%
rename from media/libmedia/include/media/DrmPluginPath.h
rename to drm/libmediadrm/include/mediadrm/DrmPluginPath.h
diff --git a/media/libmedia/include/media/DrmSessionClientInterface.h b/drm/libmediadrm/include/mediadrm/DrmSessionClientInterface.h
similarity index 100%
rename from media/libmedia/include/media/DrmSessionClientInterface.h
rename to drm/libmediadrm/include/mediadrm/DrmSessionClientInterface.h
diff --git a/media/libmedia/include/media/DrmSessionManager.h b/drm/libmediadrm/include/mediadrm/DrmSessionManager.h
similarity index 100%
rename from media/libmedia/include/media/DrmSessionManager.h
rename to drm/libmediadrm/include/mediadrm/DrmSessionManager.h
diff --git a/media/libmedia/include/media/IDrm.h b/drm/libmediadrm/include/mediadrm/IDrm.h
similarity index 100%
rename from media/libmedia/include/media/IDrm.h
rename to drm/libmediadrm/include/mediadrm/IDrm.h
diff --git a/media/libmedia/include/media/IDrmClient.h b/drm/libmediadrm/include/mediadrm/IDrmClient.h
similarity index 100%
rename from media/libmedia/include/media/IDrmClient.h
rename to drm/libmediadrm/include/mediadrm/IDrmClient.h
diff --git a/media/libmedia/include/media/IMediaDrmService.h b/drm/libmediadrm/include/mediadrm/IMediaDrmService.h
similarity index 100%
rename from media/libmedia/include/media/IMediaDrmService.h
rename to drm/libmediadrm/include/mediadrm/IMediaDrmService.h
diff --git a/media/libmedia/include/media/SharedLibrary.h b/drm/libmediadrm/include/mediadrm/SharedLibrary.h
similarity index 100%
rename from media/libmedia/include/media/SharedLibrary.h
rename to drm/libmediadrm/include/mediadrm/SharedLibrary.h
diff --git a/media/libmedia/include/media/ICrypto.h b/drm/libmediadrm/interface/mediadrm/ICrypto.h
similarity index 100%
rename from media/libmedia/include/media/ICrypto.h
rename to drm/libmediadrm/interface/mediadrm/ICrypto.h
diff --git a/drm/libmediadrm/tests/Android.bp b/drm/libmediadrm/tests/Android.bp
index 9e0115e..2e39943 100644
--- a/drm/libmediadrm/tests/Android.bp
+++ b/drm/libmediadrm/tests/Android.bp
@@ -3,8 +3,8 @@
 cc_test {
     name: "CounterMetric_test",
     srcs: ["CounterMetric_test.cpp"],
+    header_libs: ["libmedia_headers"],
     shared_libs: ["libmediadrm"],
-    include_dirs: ["frameworks/av/include/media"],
     cflags: [
       "-Werror",
       "-Wall",
@@ -14,6 +14,9 @@
 cc_test {
     name: "DrmMetrics_test",
     srcs: ["DrmMetrics_test.cpp"],
+    header_libs: [
+        "libmedia_headers"
+    ],
     shared_libs: [
       "android.hardware.drm@1.0",
       "android.hardware.drm@1.1",
@@ -28,7 +31,7 @@
     ],
     static_libs: ["libgmock"],
     include_dirs: [
-      "frameworks/av/include/media",
+      "frameworks/av/drm/libmediadrm/include",
     ],
     cflags: [
         // Suppress unused parameter and no error options. These cause problems
@@ -40,12 +43,14 @@
 cc_test {
     name: "EventMetric_test",
     srcs: ["EventMetric_test.cpp"],
+    header_libs: [
+        "libmedia_headers"
+    ],
     shared_libs: [
       "liblog",
       "libmediadrm",
       "libutils",
     ],
-    include_dirs: ["frameworks/av/include/media"],
     cflags: [
       "-Werror",
       "-Wall",
diff --git a/drm/libmediadrm/tests/CounterMetric_test.cpp b/drm/libmediadrm/tests/CounterMetric_test.cpp
index 6bca0da..c2becb4 100644
--- a/drm/libmediadrm/tests/CounterMetric_test.cpp
+++ b/drm/libmediadrm/tests/CounterMetric_test.cpp
@@ -16,7 +16,7 @@
 
 #include <gtest/gtest.h>
 
-#include "CounterMetric.h"
+#include <media/CounterMetric.h>
 
 namespace android {
 
diff --git a/drm/libmediadrm/tests/EventMetric_test.cpp b/drm/libmediadrm/tests/EventMetric_test.cpp
index eb6c4f6..b3c3f62 100644
--- a/drm/libmediadrm/tests/EventMetric_test.cpp
+++ b/drm/libmediadrm/tests/EventMetric_test.cpp
@@ -16,7 +16,7 @@
 
 #include <gtest/gtest.h>
 
-#include "EventMetric.h"
+#include <media/EventMetric.h>
 
 namespace android {
 
diff --git a/drm/mediacas/plugins/clearkey/Android.bp b/drm/mediacas/plugins/clearkey/Android.bp
new file mode 100644
index 0000000..0113cb8
--- /dev/null
+++ b/drm/mediacas/plugins/clearkey/Android.bp
@@ -0,0 +1,55 @@
+//
+// Copyright (C) 2017 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+cc_library_shared {
+    name: "libclearkeycasplugin",
+
+    srcs: [
+        "ClearKeyCasPlugin.cpp",
+        "ClearKeyFetcher.cpp",
+        "ClearKeyLicenseFetcher.cpp",
+        "ClearKeySessionLibrary.cpp",
+        "ecm.cpp",
+        "ecm_generator.cpp",
+        "JsonAssetLoader.cpp",
+        "protos/license_protos.proto",
+    ],
+
+    proprietary: true,
+    relative_install_path: "mediacas",
+
+    shared_libs: [
+        "libutils",
+        "liblog",
+        "libcrypto",
+        "libstagefright_foundation",
+        "libprotobuf-cpp-lite",
+    ],
+
+    header_libs: ["media_plugin_headers"],
+
+    static_libs: ["libjsmn"],
+
+    proto: {
+        type: "full",
+        export_proto_headers: true,
+    },
+
+    include_dirs: [
+        "frameworks/av/include",
+        "frameworks/native/include/media",
+    ],
+}
diff --git a/drm/mediacas/plugins/clearkey/Android.mk b/drm/mediacas/plugins/clearkey/Android.mk
deleted file mode 100644
index 4b139a8..0000000
--- a/drm/mediacas/plugins/clearkey/Android.mk
+++ /dev/null
@@ -1,71 +0,0 @@
-#
-# Copyright (C) 2017 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:= \
-    ClearKeyCasPlugin.cpp \
-    ClearKeyFetcher.cpp \
-    ClearKeyLicenseFetcher.cpp \
-    ClearKeySessionLibrary.cpp \
-    ecm.cpp \
-    ecm_generator.cpp \
-    JsonAssetLoader.cpp \
-    protos/license_protos.proto \
-
-LOCAL_MODULE := libclearkeycasplugin
-
-LOCAL_PROPRIETARY_MODULE := true
-LOCAL_MODULE_RELATIVE_PATH := mediacas
-
-LOCAL_SHARED_LIBRARIES := \
-    libutils \
-    liblog \
-    libcrypto \
-    libstagefright_foundation \
-    libprotobuf-cpp-lite \
-
-LOCAL_HEADER_LIBRARIES := \
-    media_plugin_headers
-
-LOCAL_STATIC_LIBRARIES := \
-    libjsmn \
-
-LOCAL_MODULE_CLASS := SHARED_LIBRARIES
-
-LOCAL_PROTOC_OPTIMIZE_TYPE := full
-
-define proto_includes
-$(call local-generated-sources-dir)/proto/$(LOCAL_PATH)
-endef
-
-LOCAL_C_INCLUDES += \
-    external/jsmn \
-    frameworks/av/include \
-    frameworks/native/include/media \
-    $(call proto_includes)
-
-LOCAL_EXPORT_C_INCLUDE_DIRS := \
-    $(call proto_includes)
-
-LOCAL_MODULE_TAGS := optional
-
-include $(BUILD_SHARED_LIBRARY)
-
-#########################################################################
-# Build unit tests
-
-include $(LOCAL_PATH)/tests/Android.mk
diff --git a/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.cpp b/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.cpp
index bf35224..af7c367 100644
--- a/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.cpp
+++ b/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.cpp
@@ -97,7 +97,8 @@
 ///////////////////////////////////////////////////////////////////////////////
 ClearKeyCasPlugin::ClearKeyCasPlugin(
         void *appData, CasPluginCallback callback)
-    : mCallback(callback), mCallbackExt(NULL), mAppData(appData) {
+    : mCallback(callback), mCallbackExt(NULL), mStatusCallback(NULL),
+    mAppData(appData) {
     ALOGV("CTOR");
 }
 
@@ -112,6 +113,13 @@
     ClearKeySessionLibrary::get()->destroyPlugin(this);
 }
 
+status_t ClearKeyCasPlugin::setStatusCallback(
+    CasPluginStatusCallback callback) {
+    ALOGV("setStatusCallback");
+    mStatusCallback = callback;
+    return OK;
+}
+
 status_t ClearKeyCasPlugin::setPrivateData(const CasData &/*data*/) {
     ALOGV("setPrivateData");
 
@@ -135,6 +143,19 @@
     return ClearKeySessionLibrary::get()->addSession(this, sessionId);
 }
 
+status_t ClearKeyCasPlugin::openSession(uint32_t intent, uint32_t mode,
+    CasSessionId* sessionId) {
+    ALOGV("openSession with intent=%d, mode=%d", intent, mode);
+    // Echo the received information to the callback.
+    // Clear key plugin doesn't use any event, echo'ing for testing only.
+    if (mStatusCallback != NULL) {
+        mStatusCallback((void*)mAppData, intent, mode);
+    }
+
+    // Clear key plugin doesn't use intent and mode.
+    return ClearKeySessionLibrary::get()->addSession(this, sessionId);
+}
+
 status_t ClearKeyCasPlugin::closeSession(const CasSessionId &sessionId) {
     ALOGV("closeSession: sessionId=%s", sessionIdToString(sessionId).string());
     std::shared_ptr<ClearKeyCasSession> session =
diff --git a/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.h b/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.h
index f48d5b1..c6938e6 100644
--- a/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.h
+++ b/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.h
@@ -71,11 +71,17 @@
     ClearKeyCasPlugin(void *appData, CasPluginCallbackExt callback);
     virtual ~ClearKeyCasPlugin();
 
+    virtual status_t setStatusCallback(
+            CasPluginStatusCallback callback) override;
+
     virtual status_t setPrivateData(
             const CasData &data) override;
 
     virtual status_t openSession(CasSessionId *sessionId) override;
 
+    virtual status_t openSession(uint32_t intent, uint32_t mode,
+                                     CasSessionId *sessionId) override;
+
     virtual status_t closeSession(
             const CasSessionId &sessionId) override;
 
@@ -105,6 +111,7 @@
     std::unique_ptr<KeyFetcher> mKeyFetcher;
     CasPluginCallback mCallback;
     CasPluginCallbackExt mCallbackExt;
+    CasPluginStatusCallback mStatusCallback;
     void* mAppData;
 };
 
diff --git a/drm/mediacas/plugins/clearkey/ClearKeyFetcher.cpp b/drm/mediacas/plugins/clearkey/ClearKeyFetcher.cpp
index eaa3390..cb69f91 100644
--- a/drm/mediacas/plugins/clearkey/ClearKeyFetcher.cpp
+++ b/drm/mediacas/plugins/clearkey/ClearKeyFetcher.cpp
@@ -89,7 +89,7 @@
     // asset_id change. If it sends an EcmContainer with 2 Ecms with different
     // asset_ids (old and new) then it might be best to prefetch the Emm.
     if ((asset_.id() != 0) && (*asset_id != asset_.id())) {
-        ALOGW("Asset_id change from %llu to %" PRIu64, asset_.id(), *asset_id);
+        ALOGW("Asset_id change from %" PRIu64 " to %" PRIu64, asset_.id(), *asset_id);
         asset_.Clear();
     }
 
diff --git a/drm/mediacas/plugins/clearkey/ecm.cpp b/drm/mediacas/plugins/clearkey/ecm.cpp
index 9fde13a..b3b5218 100644
--- a/drm/mediacas/plugins/clearkey/ecm.cpp
+++ b/drm/mediacas/plugins/clearkey/ecm.cpp
@@ -17,6 +17,8 @@
 //#define LOG_NDEBUG 0
 #define LOG_TAG "ecm"
 
+#include <inttypes.h>
+
 #include "ecm.h"
 #include "ecm_generator.h"
 #include "protos/license_protos.pb.h"
@@ -76,7 +78,7 @@
         return status;
     }
     if (asset.id() != asset_from_emm.id()) {
-        ALOGE("Asset_id from Emm (%llu) does not match asset_id from Ecm (%llu).",
+        ALOGE("Asset_id from Emm (%" PRIu64 ") does not match asset_id from Ecm (%" PRIu64 ").",
                 asset_from_emm.id(), asset.id());
         return CLEARKEY_STATUS_INVALID_PARAMETER;
     }
diff --git a/drm/mediacas/plugins/clearkey/tests/Android.bp b/drm/mediacas/plugins/clearkey/tests/Android.bp
new file mode 100644
index 0000000..575863c
--- /dev/null
+++ b/drm/mediacas/plugins/clearkey/tests/Android.bp
@@ -0,0 +1,45 @@
+//
+// Copyright (C) 2017 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+cc_test {
+    name: "ClearKeyFetcherTest",
+
+    srcs: ["ClearKeyFetcherTest.cpp"],
+
+    vendor: true,
+
+    // LOCAL_LDFLAGS is needed here for the test to use the plugin, because
+    // the plugin is not in standard library search path. Without this .so
+    // loading fails at run-time (linking is okay).
+    ldflags: [
+        "-Wl,--rpath,${ORIGIN}/../../../system/vendor/lib/mediacas",
+        "-Wl,--enable-new-dtags",
+    ],
+
+    shared_libs: [
+        "libutils",
+        "libclearkeycasplugin",
+        "libstagefright_foundation",
+        "libprotobuf-cpp-lite",
+        "liblog",
+    ],
+
+    include_dirs: [
+        "frameworks/av/drm/mediacas/plugins/clearkey",
+        "frameworks/av/include",
+        "frameworks/native/include/media",
+    ],
+}
diff --git a/drm/mediacas/plugins/clearkey/tests/Android.mk b/drm/mediacas/plugins/clearkey/tests/Android.mk
deleted file mode 100644
index e1545af..0000000
--- a/drm/mediacas/plugins/clearkey/tests/Android.mk
+++ /dev/null
@@ -1,45 +0,0 @@
-#
-# Copyright (C) 2017 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := \
-    ClearKeyFetcherTest.cpp
-
-LOCAL_MODULE := ClearKeyFetcherTest
-LOCAL_VENDOR_MODULE := true
-
-# LOCAL_LDFLAGS is needed here for the test to use the plugin, because
-# the plugin is not in standard library search path. Without this .so
-# loading fails at run-time (linking is okay).
-LOCAL_LDFLAGS := \
-    -Wl,--rpath,\$${ORIGIN}/../../../system/vendor/lib/mediacas -Wl,--enable-new-dtags
-
-LOCAL_SHARED_LIBRARIES := \
-    libutils libclearkeycasplugin libstagefright_foundation libprotobuf-cpp-lite liblog
-
-LOCAL_C_INCLUDES += \
-    $(TOP)/frameworks/av/drm/mediacas/plugins/clearkey \
-    $(TOP)/frameworks/av/include \
-    $(TOP)/frameworks/native/include/media \
-
-LOCAL_MODULE_TAGS := tests
-
-include $(BUILD_NATIVE_TEST)
-
-
-
diff --git a/drm/mediacas/plugins/mock/Android.bp b/drm/mediacas/plugins/mock/Android.bp
new file mode 100644
index 0000000..e8a3c6f
--- /dev/null
+++ b/drm/mediacas/plugins/mock/Android.bp
@@ -0,0 +1,39 @@
+//
+// Copyright (C) 2017 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+cc_library_shared {
+    name: "libmockcasplugin",
+
+    srcs: [
+        "MockCasPlugin.cpp",
+        "MockSessionLibrary.cpp",
+    ],
+
+    proprietary: true,
+    relative_install_path: "mediacas",
+
+    shared_libs: [
+        "libutils",
+        "liblog",
+    ],
+
+    header_libs: ["media_plugin_headers"],
+
+    include_dirs: [
+        "frameworks/av/include",
+        "frameworks/native/include/media",
+    ],
+}
diff --git a/drm/mediacas/plugins/mock/Android.mk b/drm/mediacas/plugins/mock/Android.mk
deleted file mode 100644
index a1d61da..0000000
--- a/drm/mediacas/plugins/mock/Android.mk
+++ /dev/null
@@ -1,39 +0,0 @@
-#
-# Copyright (C) 2017 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:= \
-    MockCasPlugin.cpp \
-    MockSessionLibrary.cpp \
-
-LOCAL_MODULE := libmockcasplugin
-
-LOCAL_PROPRIETARY_MODULE := true
-LOCAL_MODULE_RELATIVE_PATH := mediacas
-
-LOCAL_SHARED_LIBRARIES := \
-    libutils liblog
-
-LOCAL_HEADER_LIBRARIES := media_plugin_headers
-
-LOCAL_C_INCLUDES += \
-    $(TOP)/frameworks/av/include \
-    $(TOP)/frameworks/native/include/media \
-
-LOCAL_MODULE_TAGS := optional
-
-include $(BUILD_SHARED_LIBRARY)
diff --git a/drm/mediacas/plugins/mock/MockCasPlugin.cpp b/drm/mediacas/plugins/mock/MockCasPlugin.cpp
index 2964791..f8bab0a 100644
--- a/drm/mediacas/plugins/mock/MockCasPlugin.cpp
+++ b/drm/mediacas/plugins/mock/MockCasPlugin.cpp
@@ -111,6 +111,12 @@
     MockSessionLibrary::get()->destroyPlugin(this);
 }
 
+status_t MockCasPlugin::setStatusCallback(
+    CasPluginStatusCallback /*callback*/) {
+    ALOGV("setStatusCallback");
+    return OK;
+}
+
 status_t MockCasPlugin::setPrivateData(const CasData& /*data*/) {
     ALOGV("setPrivateData");
     return OK;
@@ -121,6 +127,13 @@
     return MockSessionLibrary::get()->addSession(this, sessionId);
 }
 
+status_t MockCasPlugin::openSession(uint32_t intent, uint32_t mode,
+    CasSessionId* sessionId) {
+    ALOGV("openSession with intent=%d, mode=%d", intent, mode);
+    // Clear key plugin doesn't use intent and mode.
+    return MockSessionLibrary::get()->addSession(this, sessionId);
+}
+
 status_t MockCasPlugin::closeSession(const CasSessionId &sessionId) {
     ALOGV("closeSession: sessionId=%s", arrayToString(sessionId).string());
     Mutex::Autolock lock(mLock);
diff --git a/drm/mediacas/plugins/mock/MockCasPlugin.h b/drm/mediacas/plugins/mock/MockCasPlugin.h
index 74b540c..660fd44 100644
--- a/drm/mediacas/plugins/mock/MockCasPlugin.h
+++ b/drm/mediacas/plugins/mock/MockCasPlugin.h
@@ -65,11 +65,17 @@
     MockCasPlugin();
     virtual ~MockCasPlugin();
 
+    virtual status_t setStatusCallback(
+            CasPluginStatusCallback callback) override;
+
     virtual status_t setPrivateData(
             const CasData &data) override;
 
     virtual status_t openSession(CasSessionId *sessionId) override;
 
+    virtual status_t openSession(uint32_t intent, uint32_t mode,
+                                     CasSessionId *sessionId) override;
+
     virtual status_t closeSession(
             const CasSessionId &sessionId) override;
 
diff --git a/drm/mediadrm/plugins/clearkey/hidl/Android.bp b/drm/mediadrm/plugins/clearkey/hidl/Android.bp
index e91e918..a153ce2 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/Android.bp
+++ b/drm/mediadrm/plugins/clearkey/hidl/Android.bp
@@ -48,7 +48,6 @@
         "libcrypto",
         "libhidlbase",
         "libhidlmemory",
-        "libhidltransport",
         "liblog",
         "libprotobuf-cpp-lite",
         "libutils",
diff --git a/drm/mediadrm/plugins/clearkey/hidl/serviceLazy.cpp b/drm/mediadrm/plugins/clearkey/hidl/serviceLazy.cpp
index 99fd883..a510487 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/serviceLazy.cpp
+++ b/drm/mediadrm/plugins/clearkey/hidl/serviceLazy.cpp
@@ -38,7 +38,7 @@
     configureRpcThreadpool(8, true /* callerWillJoin */);
 
     // Setup hwbinder service
-    LazyServiceRegistrar serviceRegistrar;
+    auto serviceRegistrar = LazyServiceRegistrar::getInstance();
 
     // Setup hwbinder service
     CHECK_EQ(serviceRegistrar.registerService(drmFactory, "clearkey"), android::NO_ERROR)
diff --git a/include/camera b/include/camera
deleted file mode 120000
index 00848e3..0000000
--- a/include/camera
+++ /dev/null
@@ -1 +0,0 @@
-../camera/include/camera/
\ No newline at end of file
diff --git a/include/cpustats b/include/cpustats
deleted file mode 120000
index 4a02d41..0000000
--- a/include/cpustats
+++ /dev/null
@@ -1 +0,0 @@
-../media/libcpustats/include/cpustats/
\ No newline at end of file
diff --git a/include/media/AVSyncSettings.h b/include/media/AVSyncSettings.h
deleted file mode 120000
index bbe211f..0000000
--- a/include/media/AVSyncSettings.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libmedia/include/media/AVSyncSettings.h
\ No newline at end of file
diff --git a/include/media/AudioAttributes.h b/include/media/AudioAttributes.h
deleted file mode 120000
index 27ba471..0000000
--- a/include/media/AudioAttributes.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libaudioclient/include/media/AudioAttributes.h
\ No newline at end of file
diff --git a/include/media/AudioBufferProvider.h b/include/media/AudioBufferProvider.h
deleted file mode 120000
index c4d6e79..0000000
--- a/include/media/AudioBufferProvider.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libaudioclient/include/media/AudioBufferProvider.h
\ No newline at end of file
diff --git a/include/media/AudioClient.h b/include/media/AudioClient.h
deleted file mode 120000
index a0530e4..0000000
--- a/include/media/AudioClient.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libaudioclient/include/media/AudioClient.h
\ No newline at end of file
diff --git a/include/media/AudioCommonTypes.h b/include/media/AudioCommonTypes.h
deleted file mode 120000
index ae7c99a..0000000
--- a/include/media/AudioCommonTypes.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libaudioclient/include/media/AudioCommonTypes.h
\ No newline at end of file
diff --git a/include/media/AudioEffect.h b/include/media/AudioEffect.h
deleted file mode 120000
index bf52955..0000000
--- a/include/media/AudioEffect.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libaudioclient/include/media/AudioEffect.h
\ No newline at end of file
diff --git a/include/media/AudioIoDescriptor.h b/include/media/AudioIoDescriptor.h
deleted file mode 120000
index 68f54c9..0000000
--- a/include/media/AudioIoDescriptor.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libaudioclient/include/media/AudioIoDescriptor.h
\ No newline at end of file
diff --git a/include/media/AudioMixer.h b/include/media/AudioMixer.h
deleted file mode 120000
index de839c6..0000000
--- a/include/media/AudioMixer.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libaudioclient/include/media/AudioMixer.h
\ No newline at end of file
diff --git a/include/media/AudioParameter.h b/include/media/AudioParameter.h
deleted file mode 120000
index a5889e5..0000000
--- a/include/media/AudioParameter.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libaudioclient/include/media/AudioParameter.h
\ No newline at end of file
diff --git a/include/media/AudioPolicy.h b/include/media/AudioPolicy.h
deleted file mode 120000
index dd4cd53..0000000
--- a/include/media/AudioPolicy.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libaudioclient/include/media/AudioPolicy.h
\ No newline at end of file
diff --git a/include/media/AudioProductStrategy.h b/include/media/AudioProductStrategy.h
deleted file mode 120000
index 6bfaf11..0000000
--- a/include/media/AudioProductStrategy.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libaudioclient/include/media/AudioProductStrategy.h
\ No newline at end of file
diff --git a/include/media/AudioRecord.h b/include/media/AudioRecord.h
deleted file mode 120000
index 7939dd3..0000000
--- a/include/media/AudioRecord.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libaudioclient/include/media/AudioRecord.h
\ No newline at end of file
diff --git a/include/media/AudioSystem.h b/include/media/AudioSystem.h
deleted file mode 120000
index 9fad2b7..0000000
--- a/include/media/AudioSystem.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libaudioclient/include/media/AudioSystem.h
\ No newline at end of file
diff --git a/include/media/AudioTimestamp.h b/include/media/AudioTimestamp.h
deleted file mode 120000
index b6b9278..0000000
--- a/include/media/AudioTimestamp.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libaudioclient/include/media/AudioTimestamp.h
\ No newline at end of file
diff --git a/include/media/AudioTrack.h b/include/media/AudioTrack.h
deleted file mode 120000
index 303bfcd..0000000
--- a/include/media/AudioTrack.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libaudioclient/include/media/AudioTrack.h
\ No newline at end of file
diff --git a/include/media/AudioVolumeGroup.h b/include/media/AudioVolumeGroup.h
deleted file mode 120000
index d6f1c99..0000000
--- a/include/media/AudioVolumeGroup.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libaudioclient/include/media/AudioVolumeGroup.h
\ No newline at end of file
diff --git a/include/media/BufferProviders.h b/include/media/BufferProviders.h
deleted file mode 120000
index 779bb15..0000000
--- a/include/media/BufferProviders.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libmedia/include/media/BufferProviders.h
\ No newline at end of file
diff --git a/include/media/BufferingSettings.h b/include/media/BufferingSettings.h
deleted file mode 120000
index 409203f..0000000
--- a/include/media/BufferingSettings.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libmedia/include/media/BufferingSettings.h
\ No newline at end of file
diff --git a/include/media/CharacterEncodingDetector.h b/include/media/CharacterEncodingDetector.h
deleted file mode 120000
index 2b28387..0000000
--- a/include/media/CharacterEncodingDetector.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libmedia/include/media/CharacterEncodingDetector.h
\ No newline at end of file
diff --git a/include/media/CounterMetric.h b/include/media/CounterMetric.h
deleted file mode 120000
index baba043..0000000
--- a/include/media/CounterMetric.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libmedia/include/media/CounterMetric.h
\ No newline at end of file
diff --git a/include/media/EventLog.h b/include/media/EventLog.h
deleted file mode 120000
index 9b2c4bf..0000000
--- a/include/media/EventLog.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/utils/include/mediautils/EventLog.h
\ No newline at end of file
diff --git a/include/media/EventMetric.h b/include/media/EventMetric.h
deleted file mode 120000
index 5707d9a..0000000
--- a/include/media/EventMetric.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libmedia/include/media/EventMetric.h
\ No newline at end of file
diff --git a/include/media/ExtendedAudioBufferProvider.h b/include/media/ExtendedAudioBufferProvider.h
deleted file mode 120000
index d653cc3..0000000
--- a/include/media/ExtendedAudioBufferProvider.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libmedia/include/media/ExtendedAudioBufferProvider.h
\ No newline at end of file
diff --git a/include/media/IAudioFlinger.h b/include/media/IAudioFlinger.h
deleted file mode 120000
index ef6f5be..0000000
--- a/include/media/IAudioFlinger.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libaudioclient/include/media/IAudioFlinger.h
\ No newline at end of file
diff --git a/include/media/IAudioFlingerClient.h b/include/media/IAudioFlingerClient.h
deleted file mode 120000
index dc481e8..0000000
--- a/include/media/IAudioFlingerClient.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libaudioclient/include/media/IAudioFlingerClient.h
\ No newline at end of file
diff --git a/include/media/IAudioPolicyService.h b/include/media/IAudioPolicyService.h
deleted file mode 120000
index 08101fc..0000000
--- a/include/media/IAudioPolicyService.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libaudioclient/include/media/IAudioPolicyService.h
\ No newline at end of file
diff --git a/include/media/IAudioPolicyServiceClient.h b/include/media/IAudioPolicyServiceClient.h
deleted file mode 120000
index 0d4b3e7..0000000
--- a/include/media/IAudioPolicyServiceClient.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libaudioclient/include/media/IAudioPolicyServiceClient.h
\ No newline at end of file
diff --git a/include/media/IAudioTrack.h b/include/media/IAudioTrack.h
deleted file mode 120000
index 7bab1fd..0000000
--- a/include/media/IAudioTrack.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libaudioclient/include/media/IAudioTrack.h
\ No newline at end of file
diff --git a/include/media/IDataSource.h b/include/media/IDataSource.h
deleted file mode 120000
index 41cdd8b..0000000
--- a/include/media/IDataSource.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libmedia/include/media/IDataSource.h
\ No newline at end of file
diff --git a/include/media/IEffect.h b/include/media/IEffect.h
deleted file mode 120000
index 2fb8bfb..0000000
--- a/include/media/IEffect.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libaudioclient/include/media/IEffect.h
\ No newline at end of file
diff --git a/include/media/IEffectClient.h b/include/media/IEffectClient.h
deleted file mode 120000
index b4e39cf..0000000
--- a/include/media/IEffectClient.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libaudioclient/include/media/IEffectClient.h
\ No newline at end of file
diff --git a/include/media/IMediaCodecList.h b/include/media/IMediaCodecList.h
deleted file mode 120000
index 2186312..0000000
--- a/include/media/IMediaCodecList.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libmedia/include/media/IMediaCodecList.h
\ No newline at end of file
diff --git a/include/media/IMediaDeathNotifier.h b/include/media/IMediaDeathNotifier.h
deleted file mode 120000
index ce3b8f0..0000000
--- a/include/media/IMediaDeathNotifier.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libmedia/include/media/IMediaDeathNotifier.h
\ No newline at end of file
diff --git a/include/media/IMediaExtractor.h b/include/media/IMediaExtractor.h
deleted file mode 120000
index 8708c8c..0000000
--- a/include/media/IMediaExtractor.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libmedia/include/media/IMediaExtractor.h
\ No newline at end of file
diff --git a/include/media/IMediaExtractorService.h b/include/media/IMediaExtractorService.h
deleted file mode 120000
index 3ee9f1e..0000000
--- a/include/media/IMediaExtractorService.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libmedia/include/media/IMediaExtractorService.h
\ No newline at end of file
diff --git a/include/media/IMediaHTTPConnection.h b/include/media/IMediaHTTPConnection.h
deleted file mode 120000
index 0970c15..0000000
--- a/include/media/IMediaHTTPConnection.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libmedia/include/media/IMediaHTTPConnection.h
\ No newline at end of file
diff --git a/include/media/IMediaHTTPService.h b/include/media/IMediaHTTPService.h
deleted file mode 120000
index b90c34f..0000000
--- a/include/media/IMediaHTTPService.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libmedia/include/media/IMediaHTTPService.h
\ No newline at end of file
diff --git a/include/media/IMediaLogService.h b/include/media/IMediaLogService.h
deleted file mode 120000
index 245a29d..0000000
--- a/include/media/IMediaLogService.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libmedia/include/media/IMediaLogService.h
\ No newline at end of file
diff --git a/include/media/IMediaMetadataRetriever.h b/include/media/IMediaMetadataRetriever.h
deleted file mode 120000
index 959df1a..0000000
--- a/include/media/IMediaMetadataRetriever.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libmedia/include/media/IMediaMetadataRetriever.h
\ No newline at end of file
diff --git a/include/media/IMediaPlayer.h b/include/media/IMediaPlayer.h
deleted file mode 120000
index 9414d37..0000000
--- a/include/media/IMediaPlayer.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libmedia/include/media/IMediaPlayer.h
\ No newline at end of file
diff --git a/include/media/IMediaPlayerClient.h b/include/media/IMediaPlayerClient.h
deleted file mode 120000
index b6547ce..0000000
--- a/include/media/IMediaPlayerClient.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libmedia/include/media/IMediaPlayerClient.h
\ No newline at end of file
diff --git a/include/media/IMediaPlayerService.h b/include/media/IMediaPlayerService.h
deleted file mode 120000
index 89c96cd..0000000
--- a/include/media/IMediaPlayerService.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libmedia/include/media/IMediaPlayerService.h
\ No newline at end of file
diff --git a/include/media/IMediaRecorder.h b/include/media/IMediaRecorder.h
deleted file mode 120000
index 57d192c..0000000
--- a/include/media/IMediaRecorder.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libmedia/include/media/IMediaRecorder.h
\ No newline at end of file
diff --git a/include/media/IMediaRecorderClient.h b/include/media/IMediaRecorderClient.h
deleted file mode 120000
index 89f4359..0000000
--- a/include/media/IMediaRecorderClient.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libmedia/include/media/IMediaRecorderClient.h
\ No newline at end of file
diff --git a/include/media/IMediaSource.h b/include/media/IMediaSource.h
deleted file mode 120000
index 1330ad3..0000000
--- a/include/media/IMediaSource.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libmedia/include/media/IMediaSource.h
\ No newline at end of file
diff --git a/include/media/IOMX.h b/include/media/IOMX.h
deleted file mode 120000
index 6d5b375..0000000
--- a/include/media/IOMX.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libmedia/include/media/IOMX.h
\ No newline at end of file
diff --git a/include/media/IRemoteDisplay.h b/include/media/IRemoteDisplay.h
deleted file mode 120000
index 4b0cf10..0000000
--- a/include/media/IRemoteDisplay.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libmedia/include/media/IRemoteDisplay.h
\ No newline at end of file
diff --git a/include/media/IRemoteDisplayClient.h b/include/media/IRemoteDisplayClient.h
deleted file mode 120000
index f29a2ee..0000000
--- a/include/media/IRemoteDisplayClient.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libmedia/include/media/IRemoteDisplayClient.h
\ No newline at end of file
diff --git a/include/media/IResourceManagerClient.h b/include/media/IResourceManagerClient.h
deleted file mode 120000
index 100af9b..0000000
--- a/include/media/IResourceManagerClient.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libmedia/include/media/IResourceManagerClient.h
\ No newline at end of file
diff --git a/include/media/IResourceManagerService.h b/include/media/IResourceManagerService.h
deleted file mode 120000
index 9b389c6..0000000
--- a/include/media/IResourceManagerService.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libmedia/include/media/IResourceManagerService.h
\ No newline at end of file
diff --git a/include/media/IStreamSource.h b/include/media/IStreamSource.h
deleted file mode 120000
index 4943af9..0000000
--- a/include/media/IStreamSource.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libmedia/include/media/IStreamSource.h
\ No newline at end of file
diff --git a/include/media/JetPlayer.h b/include/media/JetPlayer.h
deleted file mode 120000
index 5483fda..0000000
--- a/include/media/JetPlayer.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libmedia/include/media/JetPlayer.h
\ No newline at end of file
diff --git a/include/media/LinearMap.h b/include/media/LinearMap.h
deleted file mode 120000
index 30d4ca8..0000000
--- a/include/media/LinearMap.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libmedia/include/media/LinearMap.h
\ No newline at end of file
diff --git a/include/media/MediaCodecBuffer.h b/include/media/MediaCodecBuffer.h
deleted file mode 120000
index 8c9aa76..0000000
--- a/include/media/MediaCodecBuffer.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libmedia/include/media/MediaCodecBuffer.h
\ No newline at end of file
diff --git a/include/media/MediaCodecInfo.h b/include/media/MediaCodecInfo.h
deleted file mode 120000
index ff44ce4..0000000
--- a/include/media/MediaCodecInfo.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libmedia/include/media/MediaCodecInfo.h
\ No newline at end of file
diff --git a/include/media/MediaMetadataRetrieverInterface.h b/include/media/MediaMetadataRetrieverInterface.h
deleted file mode 120000
index 1c53511..0000000
--- a/include/media/MediaMetadataRetrieverInterface.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libmedia/include/media/MediaMetadataRetrieverInterface.h
\ No newline at end of file
diff --git a/include/media/MediaProfiles.h b/include/media/MediaProfiles.h
deleted file mode 120000
index 651c6e6..0000000
--- a/include/media/MediaProfiles.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libmedia/include/media/MediaProfiles.h
\ No newline at end of file
diff --git a/include/media/MediaRecorderBase.h b/include/media/MediaRecorderBase.h
deleted file mode 120000
index e40f992..0000000
--- a/include/media/MediaRecorderBase.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libmedia/include/media/MediaRecorderBase.h
\ No newline at end of file
diff --git a/include/media/MediaResource.h b/include/media/MediaResource.h
deleted file mode 120000
index 91346aa..0000000
--- a/include/media/MediaResource.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libmedia/include/media/MediaResource.h
\ No newline at end of file
diff --git a/include/media/MediaResourcePolicy.h b/include/media/MediaResourcePolicy.h
deleted file mode 120000
index 5d165ee..0000000
--- a/include/media/MediaResourcePolicy.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libmedia/include/media/MediaResourcePolicy.h
\ No newline at end of file
diff --git a/include/media/MemoryLeakTrackUtil.h b/include/media/MemoryLeakTrackUtil.h
deleted file mode 120000
index 504173e..0000000
--- a/include/media/MemoryLeakTrackUtil.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libmedia/include/media/MemoryLeakTrackUtil.h
\ No newline at end of file
diff --git a/include/media/Metadata.h b/include/media/Metadata.h
deleted file mode 120000
index e421168..0000000
--- a/include/media/Metadata.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libmedia/include/media/Metadata.h
\ No newline at end of file
diff --git a/include/media/MidiDeviceInfo.h b/include/media/MidiDeviceInfo.h
deleted file mode 120000
index 95da7cf..0000000
--- a/include/media/MidiDeviceInfo.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libmedia/include/media/MidiDeviceInfo.h
\ No newline at end of file
diff --git a/include/media/MidiIoWrapper.h b/include/media/MidiIoWrapper.h
deleted file mode 120000
index 786ec3d..0000000
--- a/include/media/MidiIoWrapper.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libmedia/include/media/MidiIoWrapper.h
\ No newline at end of file
diff --git a/include/media/Modulo.h b/include/media/Modulo.h
deleted file mode 120000
index 989c4cb..0000000
--- a/include/media/Modulo.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libmedia/include/media/Modulo.h
\ No newline at end of file
diff --git a/include/media/OMXBuffer.h b/include/media/OMXBuffer.h
deleted file mode 120000
index 00db207..0000000
--- a/include/media/OMXBuffer.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libmedia/include/media/OMXBuffer.h
\ No newline at end of file
diff --git a/include/media/OMXFenceParcelable.h b/include/media/OMXFenceParcelable.h
deleted file mode 120000
index c4c1b0a..0000000
--- a/include/media/OMXFenceParcelable.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libmedia/include/media/OMXFenceParcelable.h
\ No newline at end of file
diff --git a/include/media/PluginLoader.h b/include/media/PluginLoader.h
deleted file mode 120000
index 9101735..0000000
--- a/include/media/PluginLoader.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libmedia/include/media/PluginLoader.h
\ No newline at end of file
diff --git a/include/media/PluginMetricsReporting.h b/include/media/PluginMetricsReporting.h
deleted file mode 120000
index 7d9a7a0..0000000
--- a/include/media/PluginMetricsReporting.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libmedia/include/media/PluginMetricsReporting.h
\ No newline at end of file
diff --git a/include/media/RecordBufferConverter.h b/include/media/RecordBufferConverter.h
deleted file mode 120000
index 2d7bc0c..0000000
--- a/include/media/RecordBufferConverter.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libmedia/include/media/RecordBufferConverter.h
\ No newline at end of file
diff --git a/include/media/RingBuffer.h b/include/media/RingBuffer.h
deleted file mode 120000
index 9af28d5..0000000
--- a/include/media/RingBuffer.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libmedia/include/media/RingBuffer.h
\ No newline at end of file
diff --git a/include/media/SingleStateQueue.h b/include/media/SingleStateQueue.h
deleted file mode 120000
index 619f6ee..0000000
--- a/include/media/SingleStateQueue.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libmedia/include/media/SingleStateQueue.h
\ No newline at end of file
diff --git a/include/media/StringArray.h b/include/media/StringArray.h
deleted file mode 120000
index 616ce6c..0000000
--- a/include/media/StringArray.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libmedia/include/media/StringArray.h
\ No newline at end of file
diff --git a/include/media/TimeCheck.h b/include/media/TimeCheck.h
deleted file mode 120000
index 85e17f9..0000000
--- a/include/media/TimeCheck.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/utils/include/mediautils/TimeCheck.h
\ No newline at end of file
diff --git a/include/media/ToneGenerator.h b/include/media/ToneGenerator.h
deleted file mode 120000
index 33df0e3..0000000
--- a/include/media/ToneGenerator.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libaudioclient/include/media/ToneGenerator.h
\ No newline at end of file
diff --git a/include/media/TypeConverter.h b/include/media/TypeConverter.h
deleted file mode 120000
index 837af44..0000000
--- a/include/media/TypeConverter.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libmedia/include/media/TypeConverter.h
\ No newline at end of file
diff --git a/include/media/Visualizer.h b/include/media/Visualizer.h
deleted file mode 120000
index ed2ec15..0000000
--- a/include/media/Visualizer.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libmedia/include/media/Visualizer.h
\ No newline at end of file
diff --git a/include/media/convert.h b/include/media/convert.h
deleted file mode 120000
index cb0d00d..0000000
--- a/include/media/convert.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libmedia/include/media/convert.h
\ No newline at end of file
diff --git a/include/media/mediametadataretriever.h b/include/media/mediametadataretriever.h
deleted file mode 120000
index b401bab..0000000
--- a/include/media/mediametadataretriever.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libmedia/include/media/mediametadataretriever.h
\ No newline at end of file
diff --git a/include/media/mediaplayer.h b/include/media/mediaplayer.h
deleted file mode 120000
index 06d537b..0000000
--- a/include/media/mediaplayer.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libmedia/include/media/mediaplayer.h
\ No newline at end of file
diff --git a/include/media/mediarecorder.h b/include/media/mediarecorder.h
deleted file mode 120000
index a24deb3..0000000
--- a/include/media/mediarecorder.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libmedia/include/media/mediarecorder.h
\ No newline at end of file
diff --git a/include/media/mediascanner.h b/include/media/mediascanner.h
deleted file mode 120000
index 91479e0..0000000
--- a/include/media/mediascanner.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libmedia/include/media/mediascanner.h
\ No newline at end of file
diff --git a/include/media/nbaio/AudioBufferProviderSource.h b/include/media/nbaio/AudioBufferProviderSource.h
deleted file mode 120000
index 55841e7..0000000
--- a/include/media/nbaio/AudioBufferProviderSource.h
+++ /dev/null
@@ -1 +0,0 @@
-../../../media/libnbaio/include/media/nbaio/AudioBufferProviderSource.h
\ No newline at end of file
diff --git a/include/media/nbaio/AudioStreamInSource.h b/include/media/nbaio/AudioStreamInSource.h
deleted file mode 120000
index f5bcc76..0000000
--- a/include/media/nbaio/AudioStreamInSource.h
+++ /dev/null
@@ -1 +0,0 @@
-../../../media/libnbaio/include/media/nbaio/AudioStreamInSource.h
\ No newline at end of file
diff --git a/include/media/nbaio/LibsndfileSink.h b/include/media/nbaio/LibsndfileSink.h
deleted file mode 120000
index 8a13b6c..0000000
--- a/include/media/nbaio/LibsndfileSink.h
+++ /dev/null
@@ -1 +0,0 @@
-../../../media/libnbaio/include/media/nbaio/LibsndfileSink.h
\ No newline at end of file
diff --git a/include/media/nbaio/LibsndfileSource.h b/include/media/nbaio/LibsndfileSource.h
deleted file mode 120000
index 2750fde..0000000
--- a/include/media/nbaio/LibsndfileSource.h
+++ /dev/null
@@ -1 +0,0 @@
-../../../media/libnbaio/include/media/nbaio/LibsndfileSource.h
\ No newline at end of file
diff --git a/include/media/nbaio/MonoPipe.h b/include/media/nbaio/MonoPipe.h
deleted file mode 120000
index 4ea43be..0000000
--- a/include/media/nbaio/MonoPipe.h
+++ /dev/null
@@ -1 +0,0 @@
-../../../media/libnbaio/include_mono/media/nbaio/MonoPipe.h
\ No newline at end of file
diff --git a/include/media/nbaio/MonoPipeReader.h b/include/media/nbaio/MonoPipeReader.h
deleted file mode 120000
index 30f426c..0000000
--- a/include/media/nbaio/MonoPipeReader.h
+++ /dev/null
@@ -1 +0,0 @@
-../../../media/libnbaio/include_mono/media/nbaio/MonoPipeReader.h
\ No newline at end of file
diff --git a/include/media/nbaio/Pipe.h b/include/media/nbaio/Pipe.h
deleted file mode 120000
index a4bbbc9..0000000
--- a/include/media/nbaio/Pipe.h
+++ /dev/null
@@ -1 +0,0 @@
-../../../media/libnbaio/include/media/nbaio/Pipe.h
\ No newline at end of file
diff --git a/include/media/nbaio/PipeReader.h b/include/media/nbaio/PipeReader.h
deleted file mode 120000
index 64b21cf..0000000
--- a/include/media/nbaio/PipeReader.h
+++ /dev/null
@@ -1 +0,0 @@
-../../../media/libnbaio/include/media/nbaio/PipeReader.h
\ No newline at end of file
diff --git a/include/media/nbaio/SingleStateQueue.h b/include/media/nbaio/SingleStateQueue.h
new file mode 120000
index 0000000..d3e0553
--- /dev/null
+++ b/include/media/nbaio/SingleStateQueue.h
@@ -0,0 +1 @@
+../../../media/libnbaio/include_mono/media/nbaio/SingleStateQueue.h
\ No newline at end of file
diff --git a/include/media/nbaio/SourceAudioBufferProvider.h b/include/media/nbaio/SourceAudioBufferProvider.h
deleted file mode 120000
index 74a3b06..0000000
--- a/include/media/nbaio/SourceAudioBufferProvider.h
+++ /dev/null
@@ -1 +0,0 @@
-../../../media/libnbaio/include/media/nbaio/SourceAudioBufferProvider.h
\ No newline at end of file
diff --git a/include/media/nblog/NBLog.h b/include/media/nblog/NBLog.h
deleted file mode 120000
index 3cc366c..0000000
--- a/include/media/nblog/NBLog.h
+++ /dev/null
@@ -1 +0,0 @@
-../../../media/libnblog/include/media/nblog/NBLog.h
\ No newline at end of file
diff --git a/include/media/nblog/PerformanceAnalysis.h b/include/media/nblog/PerformanceAnalysis.h
deleted file mode 120000
index 6ead3bc..0000000
--- a/include/media/nblog/PerformanceAnalysis.h
+++ /dev/null
@@ -1 +0,0 @@
-../../../media/libnblog/include/media/nblog/PerformanceAnalysis.h
\ No newline at end of file
diff --git a/include/media/nblog/ReportPerformance.h b/include/media/nblog/ReportPerformance.h
deleted file mode 120000
index e9b8e80..0000000
--- a/include/media/nblog/ReportPerformance.h
+++ /dev/null
@@ -1 +0,0 @@
-../../../media/libnblog/include/media/nblog/ReportPerformance.h
\ No newline at end of file
diff --git a/include/mediadrm/CryptoHal.h b/include/mediadrm/CryptoHal.h
deleted file mode 120000
index 92f3137..0000000
--- a/include/mediadrm/CryptoHal.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libmedia/include/media/CryptoHal.h
\ No newline at end of file
diff --git a/include/mediadrm/DrmHal.h b/include/mediadrm/DrmHal.h
deleted file mode 120000
index 17bb667..0000000
--- a/include/mediadrm/DrmHal.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libmedia/include/media/DrmHal.h
\ No newline at end of file
diff --git a/include/mediadrm/DrmMetrics.h b/include/mediadrm/DrmMetrics.h
deleted file mode 120000
index abc966b..0000000
--- a/include/mediadrm/DrmMetrics.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libmedia/include/media/DrmMetrics.h
\ No newline at end of file
diff --git a/include/mediadrm/DrmPluginPath.h b/include/mediadrm/DrmPluginPath.h
deleted file mode 120000
index 9e05194..0000000
--- a/include/mediadrm/DrmPluginPath.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libmedia/include/media/DrmPluginPath.h
\ No newline at end of file
diff --git a/include/mediadrm/DrmSessionClientInterface.h b/include/mediadrm/DrmSessionClientInterface.h
deleted file mode 120000
index f4e3211..0000000
--- a/include/mediadrm/DrmSessionClientInterface.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libmedia/include/media/DrmSessionClientInterface.h
\ No newline at end of file
diff --git a/include/mediadrm/DrmSessionManager.h b/include/mediadrm/DrmSessionManager.h
deleted file mode 120000
index f0a47bf..0000000
--- a/include/mediadrm/DrmSessionManager.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libmedia/include/media/DrmSessionManager.h
\ No newline at end of file
diff --git a/include/mediadrm/ICrypto.h b/include/mediadrm/ICrypto.h
deleted file mode 120000
index b250e07..0000000
--- a/include/mediadrm/ICrypto.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libmedia/include/media/ICrypto.h
\ No newline at end of file
diff --git a/include/mediadrm/IDrm.h b/include/mediadrm/IDrm.h
deleted file mode 120000
index 841bb1b..0000000
--- a/include/mediadrm/IDrm.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libmedia/include/media/IDrm.h
\ No newline at end of file
diff --git a/include/mediadrm/IDrmClient.h b/include/mediadrm/IDrmClient.h
deleted file mode 120000
index 10aa5c0..0000000
--- a/include/mediadrm/IDrmClient.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libmedia/include/media/IDrmClient.h
\ No newline at end of file
diff --git a/include/mediadrm/IMediaDrmService.h b/include/mediadrm/IMediaDrmService.h
deleted file mode 120000
index f3c260f..0000000
--- a/include/mediadrm/IMediaDrmService.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libmedia/include/media/IMediaDrmService.h
\ No newline at end of file
diff --git a/include/mediadrm/SharedLibrary.h b/include/mediadrm/SharedLibrary.h
deleted file mode 120000
index 9f8f5a4..0000000
--- a/include/mediadrm/SharedLibrary.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libmedia/include/media/SharedLibrary.h
\ No newline at end of file
diff --git a/include/private/media/AudioTrackShared.h b/include/private/media/AudioTrackShared.h
index 5f19f74..1b1f149 100644
--- a/include/private/media/AudioTrackShared.h
+++ b/include/private/media/AudioTrackShared.h
@@ -28,7 +28,7 @@
 #include <media/AudioResamplerPublic.h>
 #include <media/AudioTimestamp.h>
 #include <media/Modulo.h>
-#include <media/SingleStateQueue.h>
+#include <media/nbaio/SingleStateQueue.h>
 
 namespace android {
 
diff --git a/media/audioserver/Android.mk b/media/audioserver/Android.mk
index 33b36b8..6697cb5 100644
--- a/media/audioserver/Android.mk
+++ b/media/audioserver/Android.mk
@@ -9,12 +9,11 @@
 	libaaudioservice \
 	libaudioflinger \
 	libaudiopolicyservice \
+	libaudioprocessing \
 	libbinder \
 	libcutils \
 	liblog \
 	libhidlbase \
-	libhidltransport \
-	libhwbinder \
 	libmedia \
 	libmedialogservice \
 	libmediautils \
@@ -34,13 +33,11 @@
 	frameworks/av/services/audiopolicy/service \
 	frameworks/av/services/medialog \
 	frameworks/av/services/oboeservice \
-	frameworks/av/services/radio \
 	frameworks/av/services/soundtrigger \
 	frameworks/av/media/libaaudio/include \
 	frameworks/av/media/libaaudio/src \
 	frameworks/av/media/libaaudio/src/binding \
 	frameworks/av/media/libmedia \
-	$(call include-path-for, audio-utils) \
 	external/sonic \
 
 # If AUDIOSERVER_MULTILIB in device.mk is non-empty then it is used to control
diff --git a/media/audioserver/audioserver.rc b/media/audioserver/audioserver.rc
index dfb1a3f..5484613 100644
--- a/media/audioserver/audioserver.rc
+++ b/media/audioserver/audioserver.rc
@@ -2,14 +2,14 @@
     class core
     user audioserver
     # media gid needed for /dev/fm (radio) and for /data/misc/media (tee)
-    group audio camera drmrpc inet media mediadrm net_bt net_bt_admin net_bw_acct wakelock
+    group audio camera drmrpc media mediadrm net_bt net_bt_admin net_bw_acct wakelock
     capabilities BLOCK_SUSPEND
     ioprio rt 4
     writepid /dev/cpuset/foreground/tasks /dev/stune/foreground/tasks
-    onrestart restart vendor.audio-hal-2-0
+    onrestart restart vendor.audio-hal
     onrestart restart vendor.audio-hal-4-0-msd
-    # Keep the original service name for backward compatibility when upgrading
-    # O-MR1 devices with framework-only.
+    # Keep the original service names for backward compatibility
+    onrestart restart vendor.audio-hal-2-0
     onrestart restart audio-hal-2-0
 
 on property:vts.native_server.on=1
diff --git a/media/bufferpool/1.0/Android.bp b/media/bufferpool/1.0/Android.bp
index c7ea70f..f817c76 100644
--- a/media/bufferpool/1.0/Android.bp
+++ b/media/bufferpool/1.0/Android.bp
@@ -16,8 +16,6 @@
         "libcutils",
         "libfmq",
         "libhidlbase",
-        "libhwbinder",
-        "libhidltransport",
         "liblog",
         "libutils",
         "android.hardware.media.bufferpool@1.0",
diff --git a/media/bufferpool/2.0/Android.bp b/media/bufferpool/2.0/Android.bp
index e8a69c9..97f114a 100644
--- a/media/bufferpool/2.0/Android.bp
+++ b/media/bufferpool/2.0/Android.bp
@@ -16,8 +16,6 @@
         "libcutils",
         "libfmq",
         "libhidlbase",
-        "libhwbinder",
-        "libhidltransport",
         "liblog",
         "libutils",
         "android.hardware.media.bufferpool@2.0",
diff --git a/media/codec2/components/cmds/Android.bp b/media/codec2/components/cmds/Android.bp
index 35f689e..a081e28 100644
--- a/media/codec2/components/cmds/Android.bp
+++ b/media/codec2/components/cmds/Android.bp
@@ -9,10 +9,15 @@
     include_dirs: [
     ],
 
+    header_libs: [
+        "libmediadrm_headers",
+    ],
+
     shared_libs: [
         "libbase",
         "libbinder",
         "libcutils",
+        "libdatasource",
         "libgui",
         "liblog",
         "libstagefright",
diff --git a/media/codec2/components/cmds/codec2.cpp b/media/codec2/components/cmds/codec2.cpp
index f2cf545..38eaf88 100644
--- a/media/codec2/components/cmds/codec2.cpp
+++ b/media/codec2/components/cmds/codec2.cpp
@@ -30,15 +30,15 @@
 
 #include <binder/IServiceManager.h>
 #include <binder/ProcessState.h>
+#include <datasource/DataSourceFactory.h>
 #include <media/DataSource.h>
-#include <media/ICrypto.h>
+#include <mediadrm/ICrypto.h>
 #include <media/IMediaHTTPService.h>
 #include <media/MediaSource.h>
 #include <media/stagefright/foundation/ABuffer.h>
 #include <media/stagefright/foundation/ALooper.h>
 #include <media/stagefright/foundation/AMessage.h>
 #include <media/stagefright/foundation/AUtils.h>
-#include <media/stagefright/DataSourceFactory.h>
 #include <media/stagefright/MediaDefs.h>
 #include <media/stagefright/MediaErrors.h>
 #include <media/stagefright/MediaExtractorFactory.h>
@@ -418,7 +418,7 @@
         const char *filename = argv[k];
 
         sp<DataSource> dataSource =
-            DataSourceFactory::CreateFromURI(nullptr /* httpService */, filename);
+            DataSourceFactory::getInstance()->CreateFromURI(nullptr /* httpService */, filename);
 
         if (strncasecmp(filename, "sine:", 5) && dataSource == nullptr) {
             fprintf(stderr, "Unable to create data source.\n");
diff --git a/media/codec2/components/hevc/C2SoftHevcEnc.cpp b/media/codec2/components/hevc/C2SoftHevcEnc.cpp
index b129b1b..19ccbf9 100644
--- a/media/codec2/components/hevc/C2SoftHevcEnc.cpp
+++ b/media/codec2/components/hevc/C2SoftHevcEnc.cpp
@@ -42,6 +42,36 @@
 
 constexpr char COMPONENT_NAME[] = "c2.android.hevc.encoder";
 
+void ParseGop(
+        const C2StreamGopTuning::output &gop,
+        uint32_t *syncInterval, uint32_t *iInterval, uint32_t *maxBframes) {
+    uint32_t syncInt = 1;
+    uint32_t iInt = 1;
+    for (size_t i = 0; i < gop.flexCount(); ++i) {
+        const C2GopLayerStruct &layer = gop.m.values[i];
+        if (layer.count == UINT32_MAX) {
+            syncInt = 0;
+        } else if (syncInt <= UINT32_MAX / (layer.count + 1)) {
+            syncInt *= (layer.count + 1);
+        }
+        if ((layer.type_ & I_FRAME) == 0) {
+            if (layer.count == UINT32_MAX) {
+                iInt = 0;
+            } else if (iInt <= UINT32_MAX / (layer.count + 1)) {
+                iInt *= (layer.count + 1);
+            }
+        }
+        if (layer.type_ == C2Config::picture_type_t(P_FRAME | B_FRAME) && maxBframes) {
+            *maxBframes = layer.count;
+        }
+    }
+    if (syncInterval) {
+        *syncInterval = syncInt;
+    }
+    if (iInterval) {
+        *iInterval = iInt;
+    }
+}
 } // namepsace
 
 class C2SoftHevcEnc::IntfImpl : public SimpleInterface<void>::BaseParams {
@@ -60,13 +90,21 @@
         setDerivedInstance(this);
 
         addParameter(
+                DefineParam(mGop, C2_PARAMKEY_GOP)
+                .withDefault(C2StreamGopTuning::output::AllocShared(
+                        0 /* flexCount */, 0u /* stream */))
+                .withFields({C2F(mGop, m.values[0].type_).any(),
+                             C2F(mGop, m.values[0].count).any()})
+                .withSetter(GopSetter)
+                .build());
+
+        addParameter(
                 DefineParam(mActualInputDelay, C2_PARAMKEY_INPUT_DELAY)
                 .withDefault(new C2PortActualDelayTuning::input(
                     DEFAULT_B_FRAMES + DEFAULT_RC_LOOKAHEAD))
                 .withFields({C2F(mActualInputDelay, value).inRange(
                     0, MAX_B_FRAMES + MAX_RC_LOOKAHEAD)})
-                .withSetter(
-                    Setter<decltype(*mActualInputDelay)>::StrictValueWithNoDeps)
+                .calculatedAs(InputDelaySetter, mGop)
                 .build());
 
         addParameter(
@@ -172,6 +210,17 @@
                 .build());
     }
 
+    static C2R InputDelaySetter(
+            bool mayBlock,
+            C2P<C2PortActualDelayTuning::input> &me,
+            const C2P<C2StreamGopTuning::output> &gop) {
+        (void)mayBlock;
+        uint32_t maxBframes = 0;
+        ParseGop(gop.v, nullptr, nullptr, &maxBframes);
+        me.set().value = maxBframes + DEFAULT_RC_LOOKAHEAD;
+        return C2R::Ok();
+    }
+
     static C2R BitrateSetter(bool mayBlock,
                              C2P<C2StreamBitrateInfo::output>& me) {
         (void)mayBlock;
@@ -270,6 +319,18 @@
         return C2R::Ok();
     }
 
+    static C2R GopSetter(bool mayBlock, C2P<C2StreamGopTuning::output> &me) {
+        (void)mayBlock;
+        for (size_t i = 0; i < me.v.flexCount(); ++i) {
+            const C2GopLayerStruct &layer = me.v.m.values[0];
+            if (layer.type_ == C2Config::picture_type_t(P_FRAME | B_FRAME)
+                    && layer.count > MAX_B_FRAMES) {
+                me.set().m.values[i].count = MAX_B_FRAMES;
+            }
+        }
+        return C2R::Ok();
+    }
+
     UWORD32 getProfile_l() const {
         switch (mProfileLevel->profile) {
         case PROFILE_HEVC_MAIN:  [[fallthrough]];
@@ -338,6 +399,9 @@
     std::shared_ptr<C2StreamQualityTuning::output> getQuality_l() const {
         return mQuality;
     }
+    std::shared_ptr<C2StreamGopTuning::output> getGop_l() const {
+        return mGop;
+    }
 
    private:
     std::shared_ptr<C2StreamUsageTuning::input> mUsage;
@@ -350,6 +414,7 @@
     std::shared_ptr<C2StreamQualityTuning::output> mQuality;
     std::shared_ptr<C2StreamProfileLevelInfo::output> mProfileLevel;
     std::shared_ptr<C2StreamSyncFrameIntervalTuning::output> mSyncFramePeriod;
+    std::shared_ptr<C2StreamGopTuning::output> mGop;
 };
 
 static size_t GetCPUCoreCount() {
@@ -449,7 +514,25 @@
         ALOGE("HEVC default init failed : 0x%x", err);
         return C2_CORRUPTED;
     }
-
+    mBframes = 0;
+    if (mGop && mGop->flexCount() > 0) {
+        uint32_t syncInterval = 1;
+        uint32_t iInterval = 1;
+        uint32_t maxBframes = 0;
+        ParseGop(*mGop, &syncInterval, &iInterval, &maxBframes);
+        if (syncInterval > 0) {
+            ALOGD("Updating IDR interval from GOP: old %u new %u", mIDRInterval, syncInterval);
+            mIDRInterval = syncInterval;
+        }
+        if (iInterval > 0) {
+            ALOGD("Updating I interval from GOP: old %u new %u", mIInterval, iInterval);
+            mIInterval = iInterval;
+        }
+        if (mBframes != maxBframes) {
+            ALOGD("Updating max B frames from GOP: old %u new %u", mBframes, maxBframes);
+            mBframes = maxBframes;
+        }
+    }
     // update configuration
     mEncParams.s_src_prms.i4_width = mSize->width;
     mEncParams.s_src_prms.i4_height = mSize->height;
@@ -463,12 +546,20 @@
         mBitrate->value << 1;
     mEncParams.s_tgt_lyr_prms.as_tgt_params[0].i4_codec_level = mHevcEncLevel;
     mEncParams.s_coding_tools_prms.i4_max_i_open_gop_period = mIDRInterval;
-    mEncParams.s_coding_tools_prms.i4_max_cra_open_gop_period = mIDRInterval;
+    mEncParams.s_coding_tools_prms.i4_max_cra_open_gop_period = mIInterval;
     mIvVideoColorFormat = IV_YUV_420P;
     mEncParams.s_multi_thrd_prms.i4_max_num_cores = mNumCores;
     mEncParams.s_out_strm_prms.i4_codec_profile = mHevcEncProfile;
     mEncParams.s_lap_prms.i4_rc_look_ahead_pics = DEFAULT_RC_LOOKAHEAD;
-    mEncParams.s_coding_tools_prms.i4_max_temporal_layers = DEFAULT_B_FRAMES;
+    if (mBframes == 0) {
+        mEncParams.s_coding_tools_prms.i4_max_temporal_layers = 0;
+    } else if (mBframes <= 2) {
+        mEncParams.s_coding_tools_prms.i4_max_temporal_layers = 1;
+    } else if (mBframes <= 6) {
+        mEncParams.s_coding_tools_prms.i4_max_temporal_layers = 2;
+    } else {
+        mEncParams.s_coding_tools_prms.i4_max_temporal_layers = 3;
+    }
 
     switch (mBitrateMode->value) {
         case C2Config::BITRATE_IGNORE:
@@ -523,6 +614,7 @@
 
 c2_status_t C2SoftHevcEnc::initEncoder() {
     CHECK(!mCodecCtx);
+
     {
         IntfImpl::Lock lock = mIntf->lock();
         mSize = mIntf->getSize_l();
@@ -532,8 +624,10 @@
         mHevcEncProfile = mIntf->getProfile_l();
         mHevcEncLevel = mIntf->getLevel_l();
         mIDRInterval = mIntf->getSyncFramePeriod_l();
+        mIInterval = mIntf->getSyncFramePeriod_l();
         mComplexity = mIntf->getComplexity_l();
         mQuality = mIntf->getQuality_l();
+        mGop = mIntf->getGop_l();
     }
 
     c2_status_t status = initEncParams();
diff --git a/media/codec2/components/hevc/C2SoftHevcEnc.h b/media/codec2/components/hevc/C2SoftHevcEnc.h
index f2c7642..140b4a9 100644
--- a/media/codec2/components/hevc/C2SoftHevcEnc.h
+++ b/media/codec2/components/hevc/C2SoftHevcEnc.h
@@ -67,6 +67,8 @@
     ihevce_static_cfg_params_t mEncParams;
     size_t mNumCores;
     UWORD32 mIDRInterval;
+    UWORD32 mIInterval;
+    UWORD32 mBframes;
     IV_COLOR_FORMAT_T mIvVideoColorFormat;
     UWORD32 mHevcEncProfile;
     UWORD32 mHevcEncLevel;
@@ -85,7 +87,7 @@
     std::shared_ptr<C2StreamBitrateModeTuning::output> mBitrateMode;
     std::shared_ptr<C2StreamComplexityTuning::output> mComplexity;
     std::shared_ptr<C2StreamQualityTuning::output> mQuality;
-
+    std::shared_ptr<C2StreamGopTuning::output> mGop;
 #ifdef FILE_DUMP_ENABLE
     char mInFile[200];
     char mOutFile[200];
diff --git a/media/codec2/components/mpeg4_h263/C2SoftMpeg4Enc.cpp b/media/codec2/components/mpeg4_h263/C2SoftMpeg4Enc.cpp
index 36053f6..54c8c47 100644
--- a/media/codec2/components/mpeg4_h263/C2SoftMpeg4Enc.cpp
+++ b/media/codec2/components/mpeg4_h263/C2SoftMpeg4Enc.cpp
@@ -517,9 +517,11 @@
             if (layout.planes[layout.PLANE_Y].colInc == 1
                     && layout.planes[layout.PLANE_U].colInc == 1
                     && layout.planes[layout.PLANE_V].colInc == 1
+                    && yStride == align(width, 16)
                     && uStride == vStride
                     && yStride == 2 * vStride) {
-                // I420 compatible - planes are already set up above
+                // I420 compatible with yStride being equal to aligned width
+                // planes are already set up above
                 break;
             }
 
diff --git a/media/codec2/components/vpx/C2SoftVpxEnc.cpp b/media/codec2/components/vpx/C2SoftVpxEnc.cpp
index 6dab70b..ebc7a8f 100644
--- a/media/codec2/components/vpx/C2SoftVpxEnc.cpp
+++ b/media/codec2/components/vpx/C2SoftVpxEnc.cpp
@@ -514,7 +514,7 @@
                         return;
                     }
                     vpx_img_wrap(&raw_frame, VPX_IMG_FMT_I420, stride, vstride,
-                                 mStrideAlign, (uint8_t*)rView->data()[0]);
+                                 mStrideAlign, mConversionBuffer.data());
                     vpx_img_set_rect(&raw_frame, 0, 0, width, height);
                 } else {
                     ALOGE("Conversion buffer is too small: %u x %u for %zu",
diff --git a/media/codec2/hidl/1.0/utils/Android.bp b/media/codec2/hidl/1.0/utils/Android.bp
index f1f1536..bdff29a 100644
--- a/media/codec2/hidl/1.0/utils/Android.bp
+++ b/media/codec2/hidl/1.0/utils/Android.bp
@@ -80,8 +80,6 @@
         "libcodec2_vndk",
         "libcutils",
         "libhidlbase",
-        "libhidltransport",
-        "libhwbinder",
         "liblog",
         "libstagefright_bufferpool@2.0.1",
         "libstagefright_bufferqueue_helper",
diff --git a/media/codec2/hidl/client/Android.bp b/media/codec2/hidl/client/Android.bp
index e184223..89c1c4a 100644
--- a/media/codec2/hidl/client/Android.bp
+++ b/media/codec2/hidl/client/Android.bp
@@ -17,7 +17,6 @@
         "libcutils",
         "libgui",
         "libhidlbase",
-        "libhidltransport",
         "liblog",
         "libstagefright_bufferpool@2.0.1",
         "libui",
diff --git a/media/codec2/hidl/services/Android.bp b/media/codec2/hidl/services/Android.bp
index 216525e..0403a1f 100644
--- a/media/codec2/hidl/services/Android.bp
+++ b/media/codec2/hidl/services/Android.bp
@@ -17,8 +17,6 @@
         "libcodec2_hidl@1.0",
         "libcodec2_vndk",
         "libhidlbase",
-        "libhidltransport",
-        "libhwbinder",
         "liblog",
         "libstagefright_omx",
         "libstagefright_xmlparser",
diff --git a/media/codec2/sfplugin/Android.bp b/media/codec2/sfplugin/Android.bp
index 9c84c71..ec576c9 100644
--- a/media/codec2/sfplugin/Android.bp
+++ b/media/codec2/sfplugin/Android.bp
@@ -22,6 +22,8 @@
 
     header_libs: [
         "libcodec2_internal",
+        "libmediadrm_headers",
+        "media_ndk_headers",
     ],
 
     shared_libs: [
@@ -39,7 +41,7 @@
         "libhidlallocatorutils",
         "libhidlbase",
         "liblog",
-        "libmedia",
+        "libmedia_codeclist",
         "libmedia_omx",
         "libsfplugin_ccodec_utils",
         "libstagefright_bufferqueue_helper",
diff --git a/media/codec2/sfplugin/CCodecBufferChannel.h b/media/codec2/sfplugin/CCodecBufferChannel.h
index ee3455d..c0fa138 100644
--- a/media/codec2/sfplugin/CCodecBufferChannel.h
+++ b/media/codec2/sfplugin/CCodecBufferChannel.h
@@ -29,7 +29,6 @@
 #include <codec2/hidl/client.h>
 #include <media/stagefright/foundation/Mutexed.h>
 #include <media/stagefright/CodecBase.h>
-#include <media/ICrypto.h>
 
 #include "CCodecBuffers.h"
 #include "InputSurfaceWrapper.h"
diff --git a/media/codec2/sfplugin/CCodecBuffers.cpp b/media/codec2/sfplugin/CCodecBuffers.cpp
index 26c702d..ed8b832 100644
--- a/media/codec2/sfplugin/CCodecBuffers.cpp
+++ b/media/codec2/sfplugin/CCodecBuffers.cpp
@@ -878,9 +878,10 @@
     switch (c2buffer->data().type()) {
         case C2BufferData::LINEAR: {
             uint32_t size = kLinearBufferSize;
-            const C2ConstLinearBlock &block = c2buffer->data().linearBlocks().front();
-            if (block.size() < kMaxLinearBufferSize / 2) {
-                size = block.size() * 2;
+            const std::vector<C2ConstLinearBlock> &linear_blocks = c2buffer->data().linearBlocks();
+            const uint32_t block_size = linear_blocks.front().size();
+            if (block_size < kMaxLinearBufferSize / 2) {
+                size = block_size * 2;
             } else {
                 size = kMaxLinearBufferSize;
             }
diff --git a/media/codec2/sfplugin/Codec2Buffer.h b/media/codec2/sfplugin/Codec2Buffer.h
index 36dcab9..6f87101 100644
--- a/media/codec2/sfplugin/Codec2Buffer.h
+++ b/media/codec2/sfplugin/Codec2Buffer.h
@@ -25,7 +25,7 @@
 #include <media/hardware/VideoAPI.h>
 #include <media/stagefright/foundation/ABuffer.h>
 #include <media/MediaCodecBuffer.h>
-#include <media/ICrypto.h>
+#include <mediadrm/ICrypto.h>
 
 namespace android {
 
diff --git a/media/codec2/sfplugin/tests/Android.bp b/media/codec2/sfplugin/tests/Android.bp
index be7f55c..b6eb2b4 100644
--- a/media/codec2/sfplugin/tests/Android.bp
+++ b/media/codec2/sfplugin/tests/Android.bp
@@ -33,6 +33,10 @@
         "frameworks/av/media/codec2/sfplugin",
     ],
 
+    header_libs: [
+        "libmediadrm_headers",
+    ],
+
     shared_libs: [
         "libbinder",
         "libcodec2",
diff --git a/media/codec2/sfplugin/tests/MediaCodec_sanity_test.cpp b/media/codec2/sfplugin/tests/MediaCodec_sanity_test.cpp
index ba3687b..6deede0 100644
--- a/media/codec2/sfplugin/tests/MediaCodec_sanity_test.cpp
+++ b/media/codec2/sfplugin/tests/MediaCodec_sanity_test.cpp
@@ -21,7 +21,7 @@
 #include <binder/ProcessState.h>
 #include <gtest/gtest.h>
 #include <gui/Surface.h>
-#include <media/ICrypto.h>
+#include <mediadrm/ICrypto.h>
 #include <media/MediaCodecBuffer.h>
 #include <media/hardware/VideoAPI.h>
 #include <media/stagefright/MediaCodec.h>
diff --git a/media/extractors/flac/FLACExtractor.h b/media/extractors/flac/FLACExtractor.h
index 5a73d20..223d359 100644
--- a/media/extractors/flac/FLACExtractor.h
+++ b/media/extractors/flac/FLACExtractor.h
@@ -17,7 +17,6 @@
 #ifndef FLAC_EXTRACTOR_H_
 #define FLAC_EXTRACTOR_H_
 
-#include <media/DataSourceBase.h>
 #include <media/MediaExtractorPluginApi.h>
 #include <media/MediaExtractorPluginHelper.h>
 #include <media/NdkMediaFormat.h>
diff --git a/media/extractors/midi/Android.bp b/media/extractors/midi/Android.bp
index 7d42e70..d36cb49 100644
--- a/media/extractors/midi/Android.bp
+++ b/media/extractors/midi/Android.bp
@@ -6,6 +6,10 @@
         "frameworks/av/media/libstagefright/include",
     ],
 
+    header_libs: [
+        "libmedia_headers",
+    ],
+
     shared_libs: [
         "liblog",
         "libmediandk",
diff --git a/media/extractors/midi/MidiExtractor.h b/media/extractors/midi/MidiExtractor.h
index 2e78086..b486fc6 100644
--- a/media/extractors/midi/MidiExtractor.h
+++ b/media/extractors/midi/MidiExtractor.h
@@ -17,7 +17,6 @@
 #ifndef MIDI_EXTRACTOR_H_
 #define MIDI_EXTRACTOR_H_
 
-#include <media/DataSourceBase.h>
 #include <media/MediaExtractorPluginApi.h>
 #include <media/MediaExtractorPluginHelper.h>
 #include <media/stagefright/MediaBufferBase.h>
diff --git a/media/extractors/mp4/SampleIterator.cpp b/media/extractors/mp4/SampleIterator.cpp
index 2890b26..85fbf97 100644
--- a/media/extractors/mp4/SampleIterator.cpp
+++ b/media/extractors/mp4/SampleIterator.cpp
@@ -22,7 +22,6 @@
 
 #include <arpa/inet.h>
 
-#include <media/DataSourceBase.h>
 #include <media/stagefright/foundation/ADebug.h>
 #include <media/stagefright/foundation/ByteUtils.h>
 
@@ -355,7 +354,7 @@
     if (offset > 0) {
         *time += offset;
     } else {
-        *time -= (offset == INT64_MIN ? INT64_MAX : (-offset));
+        *time -= (offset == INT32_MIN ? INT64_MAX : (-offset));
     }
 
     *duration = mTTSDuration;
diff --git a/media/extractors/mpeg2/Android.bp b/media/extractors/mpeg2/Android.bp
index 0f0c72c..1d9e1e6 100644
--- a/media/extractors/mpeg2/Android.bp
+++ b/media/extractors/mpeg2/Android.bp
@@ -16,6 +16,7 @@
         "android.hardware.cas.native@1.0",
         "android.hidl.token@1.0-utils",
         "android.hidl.allocator@1.0",
+        "libcrypto",
         "libhidlmemory",
         "libhidlbase",
         "liblog",
@@ -23,13 +24,13 @@
     ],
 
     header_libs: [
+        "libaudioclient_headers",
         "libbase_headers",
         "libstagefright_headers",
         "libmedia_headers",
     ],
 
     static_libs: [
-        "libcrypto",
         "libstagefright_foundation_without_imemory",
         "libstagefright_mpeg2support",
         "libutils",
diff --git a/media/extractors/mpeg2/MPEG2PSExtractor.cpp b/media/extractors/mpeg2/MPEG2PSExtractor.cpp
index 92ba039..002a855 100644
--- a/media/extractors/mpeg2/MPEG2PSExtractor.cpp
+++ b/media/extractors/mpeg2/MPEG2PSExtractor.cpp
@@ -23,7 +23,6 @@
 #include "mpeg2ts/AnotherPacketSource.h"
 #include "mpeg2ts/ESQueue.h"
 
-#include <media/DataSourceBase.h>
 #include <media/stagefright/foundation/ABitReader.h>
 #include <media/stagefright/foundation/ABuffer.h>
 #include <media/stagefright/foundation/ADebug.h>
diff --git a/media/libaaudio/Android.bp b/media/libaaudio/Android.bp
index 16958f9..140052f 100644
--- a/media/libaaudio/Android.bp
+++ b/media/libaaudio/Android.bp
@@ -24,7 +24,7 @@
 ndk_library {
     name: "libaaudio",
     // deliberately includes symbols from AAudioTesting.h
-    symbol_file: "libaaudio.map.txt",
+    symbol_file: "src/libaaudio.map.txt",
     first_version: "26",
     unversioned_until: "current",
 }
@@ -32,6 +32,5 @@
 cc_library_headers {
     name: "libaaudio_headers",
     export_include_dirs: ["include"],
-    version_script: "libaaudio.map.txt",
 }
 
diff --git a/media/libaaudio/include/aaudio/AAudio.h b/media/libaaudio/include/aaudio/AAudio.h
index ee5d089..8173e3c 100644
--- a/media/libaaudio/include/aaudio/AAudio.h
+++ b/media/libaaudio/include/aaudio/AAudio.h
@@ -472,6 +472,8 @@
  * This is intended for developers to use when debugging.
  * It is not for display to users.
  *
+ * Available since API level 26.
+ *
  * @return pointer to a text representation of an AAudio result code.
  */
 AAUDIO_API const char * AAudio_convertResultToText(aaudio_result_t returnCode) __INTRODUCED_IN(26);
@@ -482,6 +484,8 @@
  * This is intended for developers to use when debugging.
  * It is not for display to users.
  *
+ * Available since API level 26.
+ *
  * @return pointer to a text representation of an AAudio state.
  */
 AAUDIO_API const char * AAudio_convertStreamStateToText(aaudio_stream_state_t state)
@@ -502,6 +506,8 @@
  * chosen by the device when it is opened.
  *
  * AAudioStreamBuilder_delete() must be called when you are done using the builder.
+ *
+ * Available since API level 26.
  */
 AAUDIO_API aaudio_result_t AAudio_createStreamBuilder(AAudioStreamBuilder** builder)
         __INTRODUCED_IN(26);
@@ -513,6 +519,8 @@
  * The default, if you do not call this function, is {@link #AAUDIO_UNSPECIFIED},
  * in which case the primary device will be used.
  *
+ * Available since API level 26.
+ *
  * @param builder reference provided by AAudio_createStreamBuilder()
  * @param deviceId device identifier or {@link #AAUDIO_UNSPECIFIED}
  */
@@ -530,6 +538,8 @@
  * If an exact value is specified then an opened stream will use that value.
  * If a stream cannot be opened with the specified value then the open will fail.
  *
+ * Available since API level 26.
+ *
  * @param builder reference provided by AAudio_createStreamBuilder()
  * @param sampleRate frames per second. Common rates include 44100 and 48000 Hz.
  */
@@ -547,6 +557,8 @@
  * If an exact value is specified then an opened stream will use that value.
  * If a stream cannot be opened with the specified value then the open will fail.
  *
+ * Available since API level 26.
+ *
  * @param builder reference provided by AAudio_createStreamBuilder()
  * @param channelCount Number of channels desired.
  */
@@ -556,6 +568,8 @@
 /**
  * Identical to AAudioStreamBuilder_setChannelCount().
  *
+ * Available since API level 26.
+ *
  * @param builder reference provided by AAudio_createStreamBuilder()
  * @param samplesPerFrame Number of samples in a frame.
  */
@@ -573,6 +587,8 @@
  * If an exact value is specified then an opened stream will use that value.
  * If a stream cannot be opened with the specified value then the open will fail.
  *
+ * Available since API level 26.
+ *
  * @param builder reference provided by AAudio_createStreamBuilder()
  * @param format common formats are {@link #AAUDIO_FORMAT_PCM_FLOAT} and
  *               {@link #AAUDIO_FORMAT_PCM_I16}.
@@ -588,6 +604,8 @@
  * The requested sharing mode may not be available.
  * The application can query for the actual mode after the stream is opened.
  *
+ * Available since API level 26.
+ *
  * @param builder reference provided by AAudio_createStreamBuilder()
  * @param sharingMode {@link #AAUDIO_SHARING_MODE_SHARED} or {@link #AAUDIO_SHARING_MODE_EXCLUSIVE}
  */
@@ -599,6 +617,8 @@
  *
  * The default, if you do not call this function, is {@link #AAUDIO_DIRECTION_OUTPUT}.
  *
+ * Available since API level 26.
+ *
  * @param builder reference provided by AAudio_createStreamBuilder()
  * @param direction {@link #AAUDIO_DIRECTION_OUTPUT} or {@link #AAUDIO_DIRECTION_INPUT}
  */
@@ -611,6 +631,8 @@
  *
  * The default, if you do not call this function, is {@link #AAUDIO_UNSPECIFIED}.
  *
+ * Available since API level 26.
+ *
  * @param builder reference provided by AAudio_createStreamBuilder()
  * @param numFrames the desired buffer capacity in frames or {@link #AAUDIO_UNSPECIFIED}
  */
@@ -629,6 +651,8 @@
  * You can call AAudioStream_getPerformanceMode()
  * to find out the final mode for the stream.
  *
+ * Available since API level 26.
+ *
  * @param builder reference provided by AAudio_createStreamBuilder()
  * @param mode the desired performance mode, eg. {@link #AAUDIO_PERFORMANCE_MODE_LOW_LATENCY}
  */
@@ -644,7 +668,7 @@
  *
  * The default, if you do not call this function, is {@link #AAUDIO_USAGE_MEDIA}.
  *
- * Added in API level 28.
+ * Available since API level 28.
  *
  * @param builder reference provided by AAudio_createStreamBuilder()
  * @param usage the desired usage, eg. {@link #AAUDIO_USAGE_GAME}
@@ -661,7 +685,7 @@
  *
  * The default, if you do not call this function, is {@link #AAUDIO_CONTENT_TYPE_MUSIC}.
  *
- * Added in API level 28.
+ * Available since API level 28.
  *
  * @param builder reference provided by AAudio_createStreamBuilder()
  * @param contentType the type of audio data, eg. {@link #AAUDIO_CONTENT_TYPE_SPEECH}
@@ -681,7 +705,7 @@
  * That is because VOICE_RECOGNITION is the preset with the lowest latency
  * on many platforms.
  *
- * Added in API level 28.
+ * Available since API level 28.
  *
  * @param builder reference provided by AAudio_createStreamBuilder()
  * @param inputPreset the desired configuration for recording
@@ -697,7 +721,7 @@
  * Note that an application can also set its global policy, in which case the most restrictive
  * policy is always applied. See {@link android.media.AudioAttributes#setAllowedCapturePolicy(int)}
  *
- * Added in API level 29.
+ * Available since API level 29.
  *
  * @param builder reference provided by AAudio_createStreamBuilder()
  * @param inputPreset the desired level of opt-out from being captured.
@@ -727,7 +751,7 @@
  *
  * Allocated session IDs will always be positive and nonzero.
  *
- * Added in API level 28.
+ * Available since API level 28.
  *
  * @param builder reference provided by AAudio_createStreamBuilder()
  * @param sessionId an allocated sessionID or {@link #AAUDIO_SESSION_ID_ALLOCATE}
@@ -826,6 +850,8 @@
  *
  * Note that the AAudio callbacks will never be called simultaneously from multiple threads.
  *
+ * Available since API level 26.
+ *
  * @param builder reference provided by AAudio_createStreamBuilder()
  * @param callback pointer to a function that will process audio data.
  * @param userData pointer to an application data structure that will be passed
@@ -854,6 +880,8 @@
  * If you do call this function then the requested size should be less than
  * half the buffer capacity, to allow double buffering.
  *
+ * Available since API level 26.
+ *
  * @param builder reference provided by AAudio_createStreamBuilder()
  * @param numFrames the desired buffer size in frames or {@link #AAUDIO_UNSPECIFIED}
  */
@@ -905,6 +933,8 @@
  *
  * Note that the AAudio callbacks will never be called simultaneously from multiple threads.
  *
+ * Available since API level 26.
+ *
  * @param builder reference provided by AAudio_createStreamBuilder()
  * @param callback pointer to a function that will be called if an error occurs.
  * @param userData pointer to an application data structure that will be passed
@@ -919,6 +949,8 @@
  * AAudioStream_close() must be called when finished with the stream to recover
  * the memory and to free the associated resources.
  *
+ * Available since API level 26.
+ *
  * @param builder reference provided by AAudio_createStreamBuilder()
  * @param stream pointer to a variable to receive the new stream reference
  * @return {@link #AAUDIO_OK} or a negative error.
@@ -929,6 +961,8 @@
 /**
  * Delete the resources associated with the StreamBuilder.
  *
+ * Available since API level 26.
+ *
  * @param builder reference provided by AAudio_createStreamBuilder()
  * @return {@link #AAUDIO_OK} or a negative error.
  */
@@ -942,6 +976,8 @@
 /**
  * Free the resources associated with a stream created by AAudioStreamBuilder_openStream()
  *
+ * Available since API level 26.
+ *
  * @param stream reference provided by AAudioStreamBuilder_openStream()
  * @return {@link #AAUDIO_OK} or a negative error.
  */
@@ -954,6 +990,8 @@
  * After this call the state will be in {@link #AAUDIO_STREAM_STATE_STARTING} or
  * {@link #AAUDIO_STREAM_STATE_STARTED}.
  *
+ * Available since API level 26.
+ *
  * @param stream reference provided by AAudioStreamBuilder_openStream()
  * @return {@link #AAUDIO_OK} or a negative error.
  */
@@ -969,6 +1007,8 @@
  * This will return {@link #AAUDIO_ERROR_UNIMPLEMENTED} for input streams.
  * For input streams use AAudioStream_requestStop().
  *
+ * Available since API level 26.
+ *
  * @param stream reference provided by AAudioStreamBuilder_openStream()
  * @return {@link #AAUDIO_OK} or a negative error.
  */
@@ -984,6 +1024,8 @@
  *
  * This will return {@link #AAUDIO_ERROR_UNIMPLEMENTED} for input streams.
  *
+ * Available since API level 26.
+ *
  * @param stream reference provided by AAudioStreamBuilder_openStream()
  * @return {@link #AAUDIO_OK} or a negative error.
  */
@@ -995,6 +1037,8 @@
  * After this call the state will be in {@link #AAUDIO_STREAM_STATE_STOPPING} or
  * {@link #AAUDIO_STREAM_STATE_STOPPED}.
  *
+ * Available since API level 26.
+ *
  * @param stream reference provided by AAudioStreamBuilder_openStream()
  * @return {@link #AAUDIO_OK} or a negative error.
  */
@@ -1008,6 +1052,8 @@
  * call AAudioStream_waitForStateChange() with currentState
  * set to {@link #AAUDIO_STREAM_STATE_UNKNOWN} and a zero timeout.
  *
+ * Available since API level 26.
+ *
  * @param stream reference provided by AAudioStreamBuilder_openStream()
  */
 AAUDIO_API aaudio_stream_state_t AAudioStream_getState(AAudioStream* stream) __INTRODUCED_IN(26);
@@ -1028,6 +1074,8 @@
  * }
  * </code></pre>
  *
+ * Available since API level 26.
+ *
  * @param stream A reference provided by AAudioStreamBuilder_openStream()
  * @param inputState The state we want to avoid.
  * @param nextState Pointer to a variable that will be set to the new state.
@@ -1056,6 +1104,8 @@
  *
  * If the call times out then zero or a partial frame count will be returned.
  *
+ * Available since API level 26.
+ *
  * @param stream A stream created using AAudioStreamBuilder_openStream().
  * @param buffer The address of the first sample.
  * @param numFrames Number of frames to read. Only complete frames will be written.
@@ -1079,6 +1129,8 @@
  *
  * If the call times out then zero or a partial frame count will be returned.
  *
+ * Available since API level 26.
+ *
  * @param stream A stream created using AAudioStreamBuilder_openStream().
  * @param buffer The address of the first sample.
  * @param numFrames Number of frames to write. Only complete frames will be written.
@@ -1104,6 +1156,8 @@
  * You can check the return value or call AAudioStream_getBufferSizeInFrames()
  * to see what the actual final size is.
  *
+ * Available since API level 26.
+ *
  * @param stream reference provided by AAudioStreamBuilder_openStream()
  * @param numFrames requested number of frames that can be filled without blocking
  * @return actual buffer size in frames or a negative error
@@ -1114,6 +1168,8 @@
 /**
  * Query the maximum number of frames that can be filled without blocking.
  *
+ * Available since API level 26.
+ *
  * @param stream reference provided by AAudioStreamBuilder_openStream()
  * @return buffer size in frames.
  */
@@ -1129,6 +1185,8 @@
  * For some endpoints, the burst size can vary dynamically.
  * But these tend to be devices with high latency.
  *
+ * Available since API level 26.
+ *
  * @param stream reference provided by AAudioStreamBuilder_openStream()
  * @return burst size
  */
@@ -1137,6 +1195,8 @@
 /**
  * Query maximum buffer capacity in frames.
  *
+ * Available since API level 26.
+ *
  * @param stream reference provided by AAudioStreamBuilder_openStream()
  * @return  buffer capacity in frames
  */
@@ -1158,6 +1218,8 @@
  * {@link #AAUDIO_UNSPECIFIED} indicates that the callback buffer size for this stream
  * may vary from one dataProc callback to the next.
  *
+ * Available since API level 26.
+ *
  * @param stream reference provided by AAudioStreamBuilder_openStream()
  * @return callback buffer size in frames or {@link #AAUDIO_UNSPECIFIED}
  */
@@ -1175,12 +1237,16 @@
  * Note that some INPUT devices may not support this function.
  * In that case a 0 will always be returned.
  *
+ * Available since API level 26.
+ *
  * @param stream reference provided by AAudioStreamBuilder_openStream()
  * @return the underrun or overrun count
  */
 AAUDIO_API int32_t AAudioStream_getXRunCount(AAudioStream* stream) __INTRODUCED_IN(26);
 
 /**
+ * Available since API level 26.
+ *
  * @param stream reference provided by AAudioStreamBuilder_openStream()
  * @return actual sample rate
  */
@@ -1190,6 +1256,8 @@
  * A stream has one or more channels of data.
  * A frame will contain one sample for each channel.
  *
+ * Available since API level 26.
+ *
  * @param stream reference provided by AAudioStreamBuilder_openStream()
  * @return actual number of channels
  */
@@ -1198,18 +1266,24 @@
 /**
  * Identical to AAudioStream_getChannelCount().
  *
+ * Available since API level 26.
+ *
  * @param stream reference provided by AAudioStreamBuilder_openStream()
  * @return actual number of samples frame
  */
 AAUDIO_API int32_t AAudioStream_getSamplesPerFrame(AAudioStream* stream) __INTRODUCED_IN(26);
 
 /**
+ * Available since API level 26.
+ *
  * @param stream reference provided by AAudioStreamBuilder_openStream()
  * @return actual device ID
  */
 AAUDIO_API int32_t AAudioStream_getDeviceId(AAudioStream* stream) __INTRODUCED_IN(26);
 
 /**
+ * Available since API level 26.
+ *
  * @param stream reference provided by AAudioStreamBuilder_openStream()
  * @return actual data format
  */
@@ -1217,6 +1291,9 @@
 
 /**
  * Provide actual sharing mode.
+ *
+ * Available since API level 26.
+ *
  * @param stream reference provided by AAudioStreamBuilder_openStream()
  * @return  actual sharing mode
  */
@@ -1226,12 +1303,16 @@
 /**
  * Get the performance mode used by the stream.
  *
+ * Available since API level 26.
+ *
  * @param stream reference provided by AAudioStreamBuilder_openStream()
  */
 AAUDIO_API aaudio_performance_mode_t AAudioStream_getPerformanceMode(AAudioStream* stream)
         __INTRODUCED_IN(26);
 
 /**
+ * Available since API level 26.
+ *
  * @param stream reference provided by AAudioStreamBuilder_openStream()
  * @return direction
  */
@@ -1245,6 +1326,8 @@
  *
  * The frame position is monotonically increasing.
  *
+ * Available since API level 26.
+ *
  * @param stream reference provided by AAudioStreamBuilder_openStream()
  * @return frames written
  */
@@ -1258,6 +1341,8 @@
  *
  * The frame position is monotonically increasing.
  *
+ * Available since API level 26.
+ *
  * @param stream reference provided by AAudioStreamBuilder_openStream()
  * @return frames read
  */
@@ -1281,7 +1366,7 @@
  *
  * The sessionID for a stream should not change once the stream has been opened.
  *
- * Added in API level 28.
+ * Available since API level 28.
  *
  * @param stream reference provided by AAudioStreamBuilder_openStream()
  * @return session ID or {@link #AAUDIO_SESSION_ID_NONE}
@@ -1304,6 +1389,8 @@
  *
  * The position and time passed back are monotonically increasing.
  *
+ * Available since API level 26.
+ *
  * @param stream reference provided by AAudioStreamBuilder_openStream()
  * @param clockid CLOCK_MONOTONIC or CLOCK_BOOTTIME
  * @param framePosition pointer to a variable to receive the position
@@ -1316,7 +1403,7 @@
 /**
  * Return the use case for the stream.
  *
- * Added in API level 28.
+ * Available since API level 28.
  *
  * @param stream reference provided by AAudioStreamBuilder_openStream()
  * @return frames read
@@ -1326,7 +1413,7 @@
 /**
  * Return the content type for the stream.
  *
- * Added in API level 28.
+ * Available since API level 28.
  *
  * @param stream reference provided by AAudioStreamBuilder_openStream()
  * @return content type, for example {@link #AAUDIO_CONTENT_TYPE_MUSIC}
@@ -1337,7 +1424,7 @@
 /**
  * Return the input preset for the stream.
  *
- * Added in API level 28.
+ * Available since API level 28.
  *
  * @param stream reference provided by AAudioStreamBuilder_openStream()
  * @return input preset, for example {@link #AAUDIO_INPUT_PRESET_CAMCORDER}
@@ -1349,7 +1436,7 @@
  * Return the policy that determines whether the audio may or may not be captured
  * by other apps or the system.
  *
- * Added in API level 29.
+ * Available since API level 29.
  *
  * @param stream reference provided by AAudioStreamBuilder_openStream()
  * @return the allowed capture policy, for example {@link #AAUDIO_ALLOW_CAPTURE_BY_ALL}
diff --git a/media/libaaudio/src/Android.bp b/media/libaaudio/src/Android.bp
index 4090286..850b1d0 100644
--- a/media/libaaudio/src/Android.bp
+++ b/media/libaaudio/src/Android.bp
@@ -10,14 +10,76 @@
         "legacy",
         "utility",
     ],
-    export_include_dirs: ["."],
-    header_libs: ["libaaudio_headers"],
+    header_libs: [
+        "libaaudio_headers",
+    ],
     export_header_lib_headers: ["libaaudio_headers"],
+    version_script: "libaaudio.map.txt",
 
     srcs: [
+        "core/AAudioAudio.cpp",
+    ],
+
+    cflags: [
+        "-Wno-unused-parameter",
+        "-Wall",
+        "-Werror",
+
+        // By default, all symbols are hidden.
+        // "-fvisibility=hidden",
+        // AAUDIO_API is used to explicitly export a function or a variable as a visible symbol.
+        "-DAAUDIO_API=__attribute__((visibility(\"default\")))",
+    ],
+
+    shared_libs: [
+        "libaaudio_internal",
+        "libaudioclient",
+        "libaudioutils",
+        "liblog",
+        "libcutils",
+        "libutils",
+        "libbinder",
+    ],
+}
+
+cc_library {
+    name: "libaaudio_internal",
+
+    local_include_dirs: [
+        "binding",
+        "client",
+        "core",
+        "fifo",
+        "legacy",
+        "utility",
+    ],
+
+    export_include_dirs: ["."],
+    header_libs: [
+        "libaaudio_headers",
+        "libmedia_headers"
+    ],
+    export_header_lib_headers: ["libaaudio_headers"],
+
+    shared_libs: [
+        "libaudioclient",
+        "libaudioutils",
+        "liblog",
+        "libcutils",
+        "libutils",
+        "libbinder",
+    ],
+
+    cflags: [
+        "-Wno-unused-parameter",
+        "-Wall",
+        "-Werror",
+    ],
+
+    srcs: [
+        "core/AudioGlobal.cpp",
         "core/AudioStream.cpp",
         "core/AudioStreamBuilder.cpp",
-        "core/AAudioAudio.cpp",
         "core/AAudioStreamParameters.cpp",
         "legacy/AudioStreamLegacy.cpp",
         "legacy/AudioStreamRecord.cpp",
@@ -54,25 +116,4 @@
         "flowgraph/SourceI16.cpp",
         "flowgraph/SourceI24.cpp",
     ],
-
-    cflags: [
-        "-Wno-unused-parameter",
-        "-Wall",
-        "-Werror",
-
-        // By default, all symbols are hidden.
-        // "-fvisibility=hidden",
-        // AAUDIO_API is used to explicitly export a function or a variable as a visible symbol.
-        "-DAAUDIO_API=__attribute__((visibility(\"default\")))",
-    ],
-
-    shared_libs: [
-        "libaudioclient",
-        "libaudioutils",
-        "liblog",
-        "libcutils",
-        "libutils",
-        "libbinder",
-        "libaudiomanager",
-    ],
 }
diff --git a/media/libaaudio/src/client/AudioStreamInternal.cpp b/media/libaaudio/src/client/AudioStreamInternal.cpp
index 52eadd4..fb276c2 100644
--- a/media/libaaudio/src/client/AudioStreamInternal.cpp
+++ b/media/libaaudio/src/client/AudioStreamInternal.cpp
@@ -36,6 +36,7 @@
 #include "binding/AAudioStreamConfiguration.h"
 #include "binding/IAAudioService.h"
 #include "binding/AAudioServiceMessage.h"
+#include "core/AudioGlobal.h"
 #include "core/AudioStreamBuilder.h"
 #include "fifo/FifoBuffer.h"
 #include "utility/AudioClock.h"
diff --git a/media/libaaudio/src/core/AAudioAudio.cpp b/media/libaaudio/src/core/AAudioAudio.cpp
index 44d5122..8040e6a 100644
--- a/media/libaaudio/src/core/AAudioAudio.cpp
+++ b/media/libaaudio/src/core/AAudioAudio.cpp
@@ -27,6 +27,7 @@
 #include <aaudio/AAudioTesting.h>
 
 #include "AudioClock.h"
+#include "AudioGlobal.h"
 #include "AudioStreamBuilder.h"
 #include "AudioStream.h"
 #include "binding/AAudioCommon.h"
@@ -45,63 +46,14 @@
         return AAUDIO_ERROR_NULL; \
     }
 
-#define AAUDIO_CASE_ENUM(name) case name: return #name
-
 AAUDIO_API const char * AAudio_convertResultToText(aaudio_result_t returnCode) {
-    switch (returnCode) {
-        AAUDIO_CASE_ENUM(AAUDIO_OK);
-        AAUDIO_CASE_ENUM(AAUDIO_ERROR_DISCONNECTED);
-        AAUDIO_CASE_ENUM(AAUDIO_ERROR_ILLEGAL_ARGUMENT);
-        // reserved
-        AAUDIO_CASE_ENUM(AAUDIO_ERROR_INTERNAL);
-        AAUDIO_CASE_ENUM(AAUDIO_ERROR_INVALID_STATE);
-        // reserved
-        // reserved
-        AAUDIO_CASE_ENUM(AAUDIO_ERROR_INVALID_HANDLE);
-         // reserved
-        AAUDIO_CASE_ENUM(AAUDIO_ERROR_UNIMPLEMENTED);
-        AAUDIO_CASE_ENUM(AAUDIO_ERROR_UNAVAILABLE);
-        AAUDIO_CASE_ENUM(AAUDIO_ERROR_NO_FREE_HANDLES);
-        AAUDIO_CASE_ENUM(AAUDIO_ERROR_NO_MEMORY);
-        AAUDIO_CASE_ENUM(AAUDIO_ERROR_NULL);
-        AAUDIO_CASE_ENUM(AAUDIO_ERROR_TIMEOUT);
-        AAUDIO_CASE_ENUM(AAUDIO_ERROR_WOULD_BLOCK);
-        AAUDIO_CASE_ENUM(AAUDIO_ERROR_INVALID_FORMAT);
-        AAUDIO_CASE_ENUM(AAUDIO_ERROR_OUT_OF_RANGE);
-        AAUDIO_CASE_ENUM(AAUDIO_ERROR_NO_SERVICE);
-        AAUDIO_CASE_ENUM(AAUDIO_ERROR_INVALID_RATE);
-    }
-    return "Unrecognized AAudio error.";
+    return AudioGlobal_convertResultToText(returnCode);
 }
 
 AAUDIO_API const char * AAudio_convertStreamStateToText(aaudio_stream_state_t state) {
-    switch (state) {
-        AAUDIO_CASE_ENUM(AAUDIO_STREAM_STATE_UNINITIALIZED);
-        AAUDIO_CASE_ENUM(AAUDIO_STREAM_STATE_UNKNOWN);
-        AAUDIO_CASE_ENUM(AAUDIO_STREAM_STATE_OPEN);
-        AAUDIO_CASE_ENUM(AAUDIO_STREAM_STATE_STARTING);
-        AAUDIO_CASE_ENUM(AAUDIO_STREAM_STATE_STARTED);
-        AAUDIO_CASE_ENUM(AAUDIO_STREAM_STATE_PAUSING);
-        AAUDIO_CASE_ENUM(AAUDIO_STREAM_STATE_PAUSED);
-        AAUDIO_CASE_ENUM(AAUDIO_STREAM_STATE_FLUSHING);
-        AAUDIO_CASE_ENUM(AAUDIO_STREAM_STATE_FLUSHED);
-        AAUDIO_CASE_ENUM(AAUDIO_STREAM_STATE_STOPPING);
-        AAUDIO_CASE_ENUM(AAUDIO_STREAM_STATE_STOPPED);
-        AAUDIO_CASE_ENUM(AAUDIO_STREAM_STATE_DISCONNECTED);
-        AAUDIO_CASE_ENUM(AAUDIO_STREAM_STATE_CLOSING);
-        AAUDIO_CASE_ENUM(AAUDIO_STREAM_STATE_CLOSED);
-    }
-    return "Unrecognized AAudio state.";
+    return AudioGlobal_convertStreamStateToText(state);
 }
 
-#undef AAUDIO_CASE_ENUM
-
-
-/******************************************
- * Static globals.
- */
-static aaudio_policy_t s_MMapPolicy = AAUDIO_UNSPECIFIED;
-
 static AudioStream *convertAAudioStreamToAudioStream(AAudioStream* stream)
 {
     return (AudioStream*) stream;
@@ -543,23 +495,11 @@
 }
 
 AAUDIO_API aaudio_policy_t AAudio_getMMapPolicy() {
-    return s_MMapPolicy;
+    return AudioGlobal_getMMapPolicy();
 }
 
 AAUDIO_API aaudio_result_t AAudio_setMMapPolicy(aaudio_policy_t policy) {
-    aaudio_result_t result = AAUDIO_OK;
-    switch(policy) {
-        case AAUDIO_UNSPECIFIED:
-        case AAUDIO_POLICY_NEVER:
-        case AAUDIO_POLICY_AUTO:
-        case AAUDIO_POLICY_ALWAYS:
-            s_MMapPolicy = policy;
-            break;
-        default:
-            result = AAUDIO_ERROR_ILLEGAL_ARGUMENT;
-            break;
-    }
-    return result;
+    return AudioGlobal_setMMapPolicy(policy);
 }
 
 AAUDIO_API bool AAudioStream_isMMapUsed(AAudioStream* stream)
diff --git a/media/libaaudio/src/core/AudioGlobal.cpp b/media/libaaudio/src/core/AudioGlobal.cpp
new file mode 100644
index 0000000..e6d9a0d
--- /dev/null
+++ b/media/libaaudio/src/core/AudioGlobal.cpp
@@ -0,0 +1,99 @@
+/*
+ * 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.
+ */
+#include <aaudio/AAudio.h>
+#include <aaudio/AAudioTesting.h>
+
+#include "AudioGlobal.h"
+
+/******************************************
+ * Static globals.
+ */
+namespace aaudio {
+
+static aaudio_policy_t g_MMapPolicy = AAUDIO_UNSPECIFIED;
+
+aaudio_policy_t AudioGlobal_getMMapPolicy() {
+  return g_MMapPolicy;
+}
+
+aaudio_result_t AudioGlobal_setMMapPolicy(aaudio_policy_t policy) {
+    aaudio_result_t result = AAUDIO_OK;
+    switch(policy) {
+        case AAUDIO_UNSPECIFIED:
+        case AAUDIO_POLICY_NEVER:
+        case AAUDIO_POLICY_AUTO:
+        case AAUDIO_POLICY_ALWAYS:
+            g_MMapPolicy = policy;
+            break;
+        default:
+            result = AAUDIO_ERROR_ILLEGAL_ARGUMENT;
+            break;
+    }
+    return result;
+}
+
+#define AAUDIO_CASE_ENUM(name) case name: return #name
+
+const char* AudioGlobal_convertResultToText(aaudio_result_t returnCode) {
+    switch (returnCode) {
+        AAUDIO_CASE_ENUM(AAUDIO_OK);
+        AAUDIO_CASE_ENUM(AAUDIO_ERROR_DISCONNECTED);
+        AAUDIO_CASE_ENUM(AAUDIO_ERROR_ILLEGAL_ARGUMENT);
+        // reserved
+        AAUDIO_CASE_ENUM(AAUDIO_ERROR_INTERNAL);
+        AAUDIO_CASE_ENUM(AAUDIO_ERROR_INVALID_STATE);
+        // reserved
+        // reserved
+        AAUDIO_CASE_ENUM(AAUDIO_ERROR_INVALID_HANDLE);
+         // reserved
+        AAUDIO_CASE_ENUM(AAUDIO_ERROR_UNIMPLEMENTED);
+        AAUDIO_CASE_ENUM(AAUDIO_ERROR_UNAVAILABLE);
+        AAUDIO_CASE_ENUM(AAUDIO_ERROR_NO_FREE_HANDLES);
+        AAUDIO_CASE_ENUM(AAUDIO_ERROR_NO_MEMORY);
+        AAUDIO_CASE_ENUM(AAUDIO_ERROR_NULL);
+        AAUDIO_CASE_ENUM(AAUDIO_ERROR_TIMEOUT);
+        AAUDIO_CASE_ENUM(AAUDIO_ERROR_WOULD_BLOCK);
+        AAUDIO_CASE_ENUM(AAUDIO_ERROR_INVALID_FORMAT);
+        AAUDIO_CASE_ENUM(AAUDIO_ERROR_OUT_OF_RANGE);
+        AAUDIO_CASE_ENUM(AAUDIO_ERROR_NO_SERVICE);
+        AAUDIO_CASE_ENUM(AAUDIO_ERROR_INVALID_RATE);
+    }
+    return "Unrecognized AAudio error.";
+}
+
+const char* AudioGlobal_convertStreamStateToText(aaudio_stream_state_t state) {
+      switch (state) {
+        AAUDIO_CASE_ENUM(AAUDIO_STREAM_STATE_UNINITIALIZED);
+        AAUDIO_CASE_ENUM(AAUDIO_STREAM_STATE_UNKNOWN);
+        AAUDIO_CASE_ENUM(AAUDIO_STREAM_STATE_OPEN);
+        AAUDIO_CASE_ENUM(AAUDIO_STREAM_STATE_STARTING);
+        AAUDIO_CASE_ENUM(AAUDIO_STREAM_STATE_STARTED);
+        AAUDIO_CASE_ENUM(AAUDIO_STREAM_STATE_PAUSING);
+        AAUDIO_CASE_ENUM(AAUDIO_STREAM_STATE_PAUSED);
+        AAUDIO_CASE_ENUM(AAUDIO_STREAM_STATE_FLUSHING);
+        AAUDIO_CASE_ENUM(AAUDIO_STREAM_STATE_FLUSHED);
+        AAUDIO_CASE_ENUM(AAUDIO_STREAM_STATE_STOPPING);
+        AAUDIO_CASE_ENUM(AAUDIO_STREAM_STATE_STOPPED);
+        AAUDIO_CASE_ENUM(AAUDIO_STREAM_STATE_DISCONNECTED);
+        AAUDIO_CASE_ENUM(AAUDIO_STREAM_STATE_CLOSING);
+        AAUDIO_CASE_ENUM(AAUDIO_STREAM_STATE_CLOSED);
+    }
+    return "Unrecognized AAudio state.";
+}
+
+#undef AAUDIO_CASE_ENUM
+
+}  // namespace aaudio
diff --git a/media/libaaudio/src/core/AudioGlobal.h b/media/libaaudio/src/core/AudioGlobal.h
new file mode 100644
index 0000000..312cef2
--- /dev/null
+++ b/media/libaaudio/src/core/AudioGlobal.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright 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 AAUDIO_AUDIOGLOBAL_H
+#define AAUDIO_AUDIOGLOBAL_H
+
+#include <aaudio/AAudio.h>
+#include <aaudio/AAudioTesting.h>
+
+
+namespace aaudio {
+
+aaudio_policy_t AudioGlobal_getMMapPolicy();
+aaudio_result_t AudioGlobal_setMMapPolicy(aaudio_policy_t policy);
+
+const char* AudioGlobal_convertResultToText(aaudio_result_t returnCode);
+const char* AudioGlobal_convertStreamStateToText(aaudio_stream_state_t state);
+
+}
+
+#endif  // AAUDIO_AUDIOGLOBAL_H
+
diff --git a/media/libaaudio/src/core/AudioStream.cpp b/media/libaaudio/src/core/AudioStream.cpp
index 9b77223..5303631 100644
--- a/media/libaaudio/src/core/AudioStream.cpp
+++ b/media/libaaudio/src/core/AudioStream.cpp
@@ -25,8 +25,9 @@
 #include "AudioStreamBuilder.h"
 #include "AudioStream.h"
 #include "AudioClock.h"
+#include "AudioGlobal.h"
 
-using namespace aaudio;
+namespace aaudio {
 
 
 // Sequential number assigned to streams solely for debugging purposes.
@@ -51,7 +52,7 @@
                           || getState() == AAUDIO_STREAM_STATE_UNINITIALIZED
                           || getState() == AAUDIO_STREAM_STATE_DISCONNECTED),
                         "~AudioStream() - still in use, state = %s",
-                        AAudio_convertStreamStateToText(getState()));
+                        AudioGlobal_convertStreamStateToText(getState()));
 
     mPlayerBase->clearParentReference(); // remove reference to this AudioStream
 }
@@ -155,7 +156,7 @@
         case AAUDIO_STREAM_STATE_CLOSED:
         default:
             ALOGW("safePause() stream not running, state = %s",
-                  AAudio_convertStreamStateToText(getState()));
+                  AudioGlobal_convertStreamStateToText(getState()));
             return AAUDIO_ERROR_INVALID_STATE;
     }
 
@@ -240,7 +241,7 @@
         case AAUDIO_STREAM_STATE_CLOSED:
         default:
             ALOGW("%s() stream not running, state = %s", __func__,
-                  AAudio_convertStreamStateToText(getState()));
+                  AudioGlobal_convertStreamStateToText(getState()));
             return AAUDIO_ERROR_INVALID_STATE;
     }
 
@@ -488,3 +489,5 @@
 void AudioStream::MyPlayerBase::destroy() {
     unregisterWithAudioManager();
 }
+
+}  // namespace aaudio
diff --git a/media/libaaudio/src/core/AudioStreamBuilder.cpp b/media/libaaudio/src/core/AudioStreamBuilder.cpp
index 08f4958..44f45b3 100644
--- a/media/libaaudio/src/core/AudioStreamBuilder.cpp
+++ b/media/libaaudio/src/core/AudioStreamBuilder.cpp
@@ -27,6 +27,7 @@
 #include "binding/AAudioBinderClient.h"
 #include "client/AudioStreamInternalCapture.h"
 #include "client/AudioStreamInternalPlay.h"
+#include "core/AudioGlobal.h"
 #include "core/AudioStream.h"
 #include "core/AudioStreamBuilder.h"
 #include "legacy/AudioStreamRecord.h"
@@ -112,7 +113,7 @@
     }
 
     // The API setting is the highest priority.
-    aaudio_policy_t mmapPolicy = AAudio_getMMapPolicy();
+    aaudio_policy_t mmapPolicy = AudioGlobal_getMMapPolicy();
     // If not specified then get from a system property.
     if (mmapPolicy == AAUDIO_UNSPECIFIED) {
         mmapPolicy = AAudioProperty_getMMapPolicy();
diff --git a/media/libaaudio/libaaudio.map.txt b/media/libaaudio/src/libaaudio.map.txt
similarity index 100%
rename from media/libaaudio/libaaudio.map.txt
rename to media/libaaudio/src/libaaudio.map.txt
diff --git a/media/libaaudio/src/utility/AAudioUtilities.cpp b/media/libaaudio/src/utility/AAudioUtilities.cpp
index 96ed56a..cdd02c0 100644
--- a/media/libaaudio/src/utility/AAudioUtilities.cpp
+++ b/media/libaaudio/src/utility/AAudioUtilities.cpp
@@ -24,6 +24,7 @@
 #include <utils/Errors.h>
 
 #include "aaudio/AAudio.h"
+#include "core/AudioGlobal.h"
 #include <aaudio/AAudioTesting.h>
 #include <math.h>
 #include <system/audio-base.h>
@@ -355,7 +356,7 @@
         case AAUDIO_STREAM_STATE_DISCONNECTED:
         default:
             ALOGE("can only flush stream when PAUSED, OPEN or STOPPED, state = %s",
-                  AAudio_convertStreamStateToText(state));
+                  aaudio::AudioGlobal_convertStreamStateToText(state));
             result =  AAUDIO_ERROR_INVALID_STATE;
             break;
     }
diff --git a/media/libaaudio/tests/Android.bp b/media/libaaudio/tests/Android.bp
index 6101e99..19cd0a0 100644
--- a/media/libaaudio/tests/Android.bp
+++ b/media/libaaudio/tests/Android.bp
@@ -11,7 +11,7 @@
     defaults: ["libaaudio_tests_defaults"],
     srcs: ["test_marshalling.cpp"],
     shared_libs: [
-        "libaaudio",
+        "libaaudio_internal",
         "libbinder",
         "libcutils",
         "libutils",
@@ -23,7 +23,7 @@
     defaults: ["libaaudio_tests_defaults"],
     srcs: ["test_clock_model.cpp"],
     shared_libs: [
-        "libaaudio",
+        "libaaudio_internal",
         "libaudioutils",
         "libcutils",
         "libutils",
@@ -34,7 +34,7 @@
     name: "test_block_adapter",
     defaults: ["libaaudio_tests_defaults"],
     srcs: ["test_block_adapter.cpp"],
-    shared_libs: ["libaaudio"],
+    shared_libs: ["libaaudio_internal"],
 }
 
 cc_test {
@@ -170,7 +170,7 @@
     name: "test_atomic_fifo",
     defaults: ["libaaudio_tests_defaults"],
     srcs: ["test_atomic_fifo.cpp"],
-    shared_libs: ["libaaudio"],
+    shared_libs: ["libaaudio_internal"],
 }
 
 cc_test {
@@ -178,7 +178,7 @@
     defaults: ["libaaudio_tests_defaults"],
     srcs: ["test_flowgraph.cpp"],
     shared_libs: [
-        "libaaudio",
+        "libaaudio_internal",
         "libbinder",
         "libcutils",
         "libutils",
diff --git a/media/libaudioclient/Android.bp b/media/libaudioclient/Android.bp
index 03bd6ce..32904bb 100644
--- a/media/libaudioclient/Android.bp
+++ b/media/libaudioclient/Android.bp
@@ -42,7 +42,7 @@
         // AIDL files for audioclient interfaces
         // The headers for these interfaces will be available to any modules that
         // include libaudioclient, at the path "aidl/package/path/BnFoo.h"
-        "aidl/android/media/IAudioRecord.aidl",
+        ":libaudioclient_aidl_private",
         ":libaudioclient_aidl",
 
         "AudioEffect.cpp",
@@ -84,6 +84,7 @@
     header_libs: [
         "libaudioclient_headers",
         "libbase_headers",
+        "libmedia_headers",
     ],
     export_header_lib_headers: ["libaudioclient_headers"],
 
@@ -110,4 +111,15 @@
     srcs: [
         "aidl/android/media/IPlayer.aidl",
     ],
+    path: "aidl",
+}
+
+// Used to strip the "aidl/" from the path, so the build system can predict the
+// output filename.
+filegroup {
+    name: "libaudioclient_aidl_private",
+    srcs: [
+        "aidl/android/media/IAudioRecord.aidl",
+    ],
+    path: "aidl",
 }
diff --git a/media/libaudioclient/IAudioFlinger.cpp b/media/libaudioclient/IAudioFlinger.cpp
index dd95e34..e3e64af 100644
--- a/media/libaudioclient/IAudioFlinger.cpp
+++ b/media/libaudioclient/IAudioFlinger.cpp
@@ -24,8 +24,8 @@
 
 #include <binder/IPCThreadState.h>
 #include <binder/Parcel.h>
-#include <media/TimeCheck.h>
 #include <mediautils/ServiceUtilities.h>
+#include <mediautils/TimeCheck.h>
 #include "IAudioFlinger.h"
 
 namespace android {
diff --git a/media/libaudioclient/IAudioPolicyService.cpp b/media/libaudioclient/IAudioPolicyService.cpp
index 64f0aca..7cc95e5 100644
--- a/media/libaudioclient/IAudioPolicyService.cpp
+++ b/media/libaudioclient/IAudioPolicyService.cpp
@@ -26,8 +26,8 @@
 #include <binder/Parcel.h>
 #include <media/AudioEffect.h>
 #include <media/IAudioPolicyService.h>
-#include <media/TimeCheck.h>
 #include <mediautils/ServiceUtilities.h>
+#include <mediautils/TimeCheck.h>
 #include <system/audio.h>
 
 namespace android {
diff --git a/media/libaudioclient/include/media/AudioMixer.h b/media/libaudioclient/include/media/AudioMixer.h
index 783eef3..3f7cd48 100644
--- a/media/libaudioclient/include/media/AudioMixer.h
+++ b/media/libaudioclient/include/media/AudioMixer.h
@@ -18,87 +18,38 @@
 #ifndef ANDROID_AUDIO_MIXER_H
 #define ANDROID_AUDIO_MIXER_H
 
-#include <map>
 #include <pthread.h>
-#include <sstream>
 #include <stdint.h>
 #include <sys/types.h>
-#include <unordered_map>
-#include <vector>
 
 #include <android/os/IExternalVibratorService.h>
-#include <media/AudioBufferProvider.h>
-#include <media/AudioResampler.h>
-#include <media/AudioResamplerPublic.h>
+#include <media/AudioMixerBase.h>
 #include <media/BufferProviders.h>
-#include <system/audio.h>
-#include <utils/Compat.h>
 #include <utils/threads.h>
 
 // FIXME This is actually unity gain, which might not be max in future, expressed in U.12
-#define MAX_GAIN_INT AudioMixer::UNITY_GAIN_INT
-
-// This must match frameworks/av/services/audioflinger/Configuration.h
-#define FLOAT_AUX
+#define MAX_GAIN_INT AudioMixerBase::UNITY_GAIN_INT
 
 namespace android {
 
-namespace NBLog {
-class Writer;
-}   // namespace NBLog
-
 // ----------------------------------------------------------------------------
 
-class AudioMixer
+// AudioMixer extends AudioMixerBase by adding support for down- and up-mixing
+// and time stretch that are implemented via Effects HAL, and adding support
+// for haptic channels which depends on Vibrator service. This is the version
+// that is used by Audioflinger.
+
+class AudioMixer : public AudioMixerBase
 {
 public:
-    // Do not change these unless underlying code changes.
-    // This mixer has a hard-coded upper limit of 8 channels for output.
-    static constexpr uint32_t MAX_NUM_CHANNELS = FCC_8;
-    static constexpr uint32_t MAX_NUM_VOLUMES = FCC_2; // stereo volume only
     // maximum number of channels supported for the content
     static const uint32_t MAX_NUM_CHANNELS_TO_DOWNMIX = AUDIO_CHANNEL_COUNT_MAX;
 
-    static const uint16_t UNITY_GAIN_INT = 0x1000;
-    static const CONSTEXPR float UNITY_GAIN_FLOAT = 1.0f;
-
-    enum { // names
-        // setParameter targets
-        TRACK           = 0x3000,
-        RESAMPLE        = 0x3001,
-        RAMP_VOLUME     = 0x3002, // ramp to new volume
-        VOLUME          = 0x3003, // don't ramp
-        TIMESTRETCH     = 0x3004,
-
-        // set Parameter names
-        // for target TRACK
-        CHANNEL_MASK    = 0x4000,
-        FORMAT          = 0x4001,
-        MAIN_BUFFER     = 0x4002,
-        AUX_BUFFER      = 0x4003,
-        DOWNMIX_TYPE    = 0X4004,
-        MIXER_FORMAT    = 0x4005, // AUDIO_FORMAT_PCM_(FLOAT|16_BIT)
-        MIXER_CHANNEL_MASK = 0x4006, // Channel mask for mixer output
+    enum { // extension of AudioMixerBase parameters
+        DOWNMIX_TYPE    = 0x4004,
         // for haptic
         HAPTIC_ENABLED  = 0x4007, // Set haptic data from this track should be played or not.
         HAPTIC_INTENSITY = 0x4008, // Set the intensity to play haptic data.
-        // for target RESAMPLE
-        SAMPLE_RATE     = 0x4100, // Configure sample rate conversion on this track name;
-                                  // parameter 'value' is the new sample rate in Hz.
-                                  // Only creates a sample rate converter the first time that
-                                  // the track sample rate is different from the mix sample rate.
-                                  // If the new sample rate is the same as the mix sample rate,
-                                  // and a sample rate converter already exists,
-                                  // then the sample rate converter remains present but is a no-op.
-        RESET           = 0x4101, // Reset sample rate converter without changing sample rate.
-                                  // This clears out the resampler's input buffer.
-        REMOVE          = 0x4102, // Remove the sample rate converter on this track name;
-                                  // the track is restored to the mix sample rate.
-        // for target RAMP_VOLUME and VOLUME (8 channels max)
-        // FIXME use float for these 3 to improve the dynamic range
-        VOLUME0         = 0x4200,
-        VOLUME1         = 0x4201,
-        AUXLEVEL        = 0x4210,
         // for target TIMESTRETCH
         PLAYBACK_RATE   = 0x4300, // Configure timestretch on this track name;
                                   // parameter 'value' is a pointer to the new playback rate.
@@ -131,142 +82,23 @@
     }
 
     AudioMixer(size_t frameCount, uint32_t sampleRate)
-        : mSampleRate(sampleRate)
-        , mFrameCount(frameCount) {
+            : AudioMixerBase(frameCount, sampleRate) {
         pthread_once(&sOnceControl, &sInitRoutine);
     }
 
-    // Create a new track in the mixer.
-    //
-    // \param name        a unique user-provided integer associated with the track.
-    //                    If name already exists, the function will abort.
-    // \param channelMask output channel mask.
-    // \param format      PCM format
-    // \param sessionId   Session id for the track. Tracks with the same
-    //                    session id will be submixed together.
-    //
-    // \return OK        on success.
-    //         BAD_VALUE if the format does not satisfy isValidFormat()
-    //                   or the channelMask does not satisfy isValidChannelMask().
-    status_t    create(
-            int name, audio_channel_mask_t channelMask, audio_format_t format, int sessionId);
+    bool isValidChannelMask(audio_channel_mask_t channelMask) const override;
 
-    bool        exists(int name) const {
-        return mTracks.count(name) > 0;
-    }
-
-    // Free an allocated track by name.
-    void        destroy(int name);
-
-    // Enable or disable an allocated track by name
-    void        enable(int name);
-    void        disable(int name);
-
-    void        setParameter(int name, int target, int param, void *value);
-
-    void        setBufferProvider(int name, AudioBufferProvider* bufferProvider);
-
-    void        process() {
-        for (const auto &pair : mTracks) {
-            // Clear contracted buffer before processing if contracted channels are saved
-            const std::shared_ptr<Track> &t = pair.second;
-            if (t->mKeepContractedChannels) {
-                t->clearContractedBuffer();
-            }
-        }
-        (this->*mHook)();
-        processHapticData();
-    }
-
-    size_t      getUnreleasedFrames(int name) const;
-
-    std::string trackNames() const {
-        std::stringstream ss;
-        for (const auto &pair : mTracks) {
-            ss << pair.first << " ";
-        }
-        return ss.str();
-    }
-
-    void        setNBLogWriter(NBLog::Writer *logWriter) {
-        mNBLogWriter = logWriter;
-    }
-
-    static inline bool isValidFormat(audio_format_t format) {
-        switch (format) {
-        case AUDIO_FORMAT_PCM_8_BIT:
-        case AUDIO_FORMAT_PCM_16_BIT:
-        case AUDIO_FORMAT_PCM_24_BIT_PACKED:
-        case AUDIO_FORMAT_PCM_32_BIT:
-        case AUDIO_FORMAT_PCM_FLOAT:
-            return true;
-        default:
-            return false;
-        }
-    }
-
-    static inline bool isValidChannelMask(audio_channel_mask_t channelMask) {
-        return audio_channel_mask_is_valid(channelMask); // the RemixBufferProvider is flexible.
-    }
+    void setParameter(int name, int target, int param, void *value) override;
+    void setBufferProvider(int name, AudioBufferProvider* bufferProvider);
 
 private:
 
-    /* For multi-format functions (calls template functions
-     * in AudioMixerOps.h).  The template parameters are as follows:
-     *
-     *   MIXTYPE     (see AudioMixerOps.h MIXTYPE_* enumeration)
-     *   USEFLOATVOL (set to true if float volume is used)
-     *   ADJUSTVOL   (set to true if volume ramp parameters needs adjustment afterwards)
-     *   TO: int32_t (Q4.27) or float
-     *   TI: int32_t (Q4.27) or int16_t (Q0.15) or float
-     *   TA: int32_t (Q4.27)
-     */
-
-    enum {
-        // FIXME this representation permits up to 8 channels
-        NEEDS_CHANNEL_COUNT__MASK   = 0x00000007,
-    };
-
-    enum {
-        NEEDS_CHANNEL_1             = 0x00000000,   // mono
-        NEEDS_CHANNEL_2             = 0x00000001,   // stereo
-
-        // sample format is not explicitly specified, and is assumed to be AUDIO_FORMAT_PCM_16_BIT
-
-        NEEDS_MUTE                  = 0x00000100,
-        NEEDS_RESAMPLE              = 0x00001000,
-        NEEDS_AUX                   = 0x00010000,
-    };
-
-    // hook types
-    enum {
-        PROCESSTYPE_NORESAMPLEONETRACK, // others set elsewhere
-    };
-
-    enum {
-        TRACKTYPE_NOP,
-        TRACKTYPE_RESAMPLE,
-        TRACKTYPE_NORESAMPLE,
-        TRACKTYPE_NORESAMPLEMONO,
-    };
-
-    // process hook functionality
-    using process_hook_t = void(AudioMixer::*)();
-
-    struct Track;
-    using hook_t = void(Track::*)(int32_t* output, size_t numOutFrames, int32_t* temp, int32_t* aux);
-
-    struct Track {
-        Track()
-            : bufferProvider(nullptr)
-        {
-            // TODO: move additional initialization here.
-        }
+    struct Track : public TrackBase {
+        Track() : TrackBase() {}
 
         ~Track()
         {
-            // bufferProvider, mInputBufferProvider need not be deleted.
-            mResampler.reset(nullptr);
+            // mInputBufferProvider need not be deleted.
             // Ensure the order of destruction of buffer providers as they
             // release the upstream provider in the destructor.
             mTimestretchBufferProvider.reset(nullptr);
@@ -277,13 +109,12 @@
             mAdjustChannelsBufferProvider.reset(nullptr);
         }
 
-        bool        needsRamp() { return (volumeInc[0] | volumeInc[1] | auxInc) != 0; }
-        bool        setResampler(uint32_t trackSampleRate, uint32_t devSampleRate);
-        bool        doesResample() const { return mResampler.get() != nullptr; }
-        void        resetResampler() { if (mResampler.get() != nullptr) mResampler->reset(); }
-        void        adjustVolumeRamp(bool aux, bool useFloat = false);
-        size_t      getUnreleasedFrames() const { return mResampler.get() != nullptr ?
-                                                    mResampler->getUnreleasedFrames() : 0; };
+        uint32_t getOutputChannelCount() override {
+            return mDownmixerBufferProvider.get() != nullptr ? mMixerChannelCount : channelCount;
+        }
+        uint32_t getMixerChannelCount() override {
+            return mMixerChannelCount + mMixerHapticChannelCount;
+        }
 
         status_t    prepareForDownmix();
         void        unprepareForDownmix();
@@ -297,51 +128,9 @@
         bool        setPlaybackRate(const AudioPlaybackRate &playbackRate);
         void        reconfigureBufferProviders();
 
-        static hook_t getTrackHook(int trackType, uint32_t channelCount,
-                audio_format_t mixerInFormat, audio_format_t mixerOutFormat);
-
-        void track__nop(int32_t* out, size_t numFrames, int32_t* temp, int32_t* aux);
-
-        template <int MIXTYPE, bool USEFLOATVOL, bool ADJUSTVOL,
-            typename TO, typename TI, typename TA>
-        void volumeMix(TO *out, size_t outFrames, const TI *in, TA *aux, bool ramp);
-
-        uint32_t    needs;
-
-        // TODO: Eventually remove legacy integer volume settings
-        union {
-        int16_t     volume[MAX_NUM_VOLUMES]; // U4.12 fixed point (top bit should be zero)
-        int32_t     volumeRL;
-        };
-
-        int32_t     prevVolume[MAX_NUM_VOLUMES];
-        int32_t     volumeInc[MAX_NUM_VOLUMES];
-        int32_t     auxInc;
-        int32_t     prevAuxLevel;
-        int16_t     auxLevel;       // 0 <= auxLevel <= MAX_GAIN_INT, but signed for mul performance
-
-        uint16_t    frameCount;
-
-        uint8_t     channelCount;   // 1 or 2, redundant with (needs & NEEDS_CHANNEL_COUNT__MASK)
-        uint8_t     unused_padding; // formerly format, was always 16
-        uint16_t    enabled;        // actually bool
-        audio_channel_mask_t channelMask;
-
-        // actual buffer provider used by the track hooks, see DownmixerBufferProvider below
-        //  for how the Track buffer provider is wrapped by another one when dowmixing is required
-        AudioBufferProvider*                bufferProvider;
-
-        mutable AudioBufferProvider::Buffer buffer; // 8 bytes
-
-        hook_t      hook;
-        const void  *mIn;             // current location in buffer
-
-        std::unique_ptr<AudioResampler> mResampler;
-        uint32_t            sampleRate;
-        int32_t*           mainBuffer;
-        int32_t*           auxBuffer;
-
         /* Buffer providers are constructed to translate the track input data as needed.
+         * See DownmixerBufferProvider below for how the Track buffer provider
+         * is wrapped by another one when dowmixing is required.
          *
          * TODO: perhaps make a single PlaybackConverterProvider class to move
          * all pre-mixer track buffer conversions outside the AudioMixer class.
@@ -363,7 +152,7 @@
          *    the downmixer requirements to the mixer engine input requirements.
          * 7) mTimestretchBufferProvider: Adds timestretching for playback rate
          */
-        AudioBufferProvider*     mInputBufferProvider;    // externally provided buffer provider.
+        AudioBufferProvider* mInputBufferProvider;    // externally provided buffer provider.
         // TODO: combine mAdjustChannelsBufferProvider and
         // mContractChannelsNonDestructiveBufferProvider
         std::unique_ptr<PassthruBufferProvider> mAdjustChannelsBufferProvider;
@@ -373,27 +162,10 @@
         std::unique_ptr<PassthruBufferProvider> mPostDownmixReformatBufferProvider;
         std::unique_ptr<PassthruBufferProvider> mTimestretchBufferProvider;
 
-        int32_t     sessionId;
-
-        audio_format_t mMixerFormat;     // output mix format: AUDIO_FORMAT_PCM_(FLOAT|16_BIT)
-        audio_format_t mFormat;          // input track format
-        audio_format_t mMixerInFormat;   // mix internal format AUDIO_FORMAT_PCM_(FLOAT|16_BIT)
-                                         // each track must be converted to this format.
         audio_format_t mDownmixRequiresFormat;  // required downmixer format
                                                 // AUDIO_FORMAT_PCM_16_BIT if 16 bit necessary
                                                 // AUDIO_FORMAT_INVALID if no required format
 
-        float          mVolume[MAX_NUM_VOLUMES];     // floating point set volume
-        float          mPrevVolume[MAX_NUM_VOLUMES]; // floating point previous volume
-        float          mVolumeInc[MAX_NUM_VOLUMES];  // floating point volume increment
-
-        float          mAuxLevel;                     // floating point set aux level
-        float          mPrevAuxLevel;                 // floating point prev aux level
-        float          mAuxInc;                       // floating point aux increment
-
-        audio_channel_mask_t mMixerChannelMask;
-        uint32_t             mMixerChannelCount;
-
         AudioPlaybackRate    mPlaybackRate;
 
         // Haptic
@@ -440,76 +212,23 @@
             return 0.0f;
         }
         }
-
-    private:
-        // hooks
-        void track__genericResample(int32_t* out, size_t numFrames, int32_t* temp, int32_t* aux);
-        void track__16BitsStereo(int32_t* out, size_t numFrames, int32_t* temp, int32_t* aux);
-        void track__16BitsMono(int32_t* out, size_t numFrames, int32_t* temp, int32_t* aux);
-
-        void volumeRampStereo(int32_t* out, size_t frameCount, int32_t* temp, int32_t* aux);
-        void volumeStereo(int32_t* out, size_t frameCount, int32_t* temp, int32_t* aux);
-
-        // multi-format track hooks
-        template <int MIXTYPE, typename TO, typename TI, typename TA>
-        void track__Resample(TO* out, size_t frameCount, TO* temp __unused, TA* aux);
-        template <int MIXTYPE, typename TO, typename TI, typename TA>
-        void track__NoResample(TO* out, size_t frameCount, TO* temp __unused, TA* aux);
     };
 
-    // TODO: remove BLOCKSIZE unit of processing - it isn't needed anymore.
-    static constexpr int BLOCKSIZE = 16;
-
-    bool setChannelMasks(int name,
-            audio_channel_mask_t trackChannelMask, audio_channel_mask_t mixerChannelMask);
-
-    // Called when track info changes and a new process hook should be determined.
-    void invalidate() {
-        mHook = &AudioMixer::process__validate;
+    inline std::shared_ptr<Track> getTrack(int name) {
+        return std::static_pointer_cast<Track>(mTracks[name]);
     }
 
-    void process__validate();
-    void process__nop();
-    void process__genericNoResampling();
-    void process__genericResampling();
-    void process__oneTrack16BitsStereoNoResampling();
+    std::shared_ptr<TrackBase> preCreateTrack() override;
+    status_t postCreateTrack(TrackBase *track) override;
 
-    template <int MIXTYPE, typename TO, typename TI, typename TA>
-    void process__noResampleOneTrack();
+    void preProcess() override;
+    void postProcess() override;
 
-    void processHapticData();
-
-    static process_hook_t getProcessHook(int processType, uint32_t channelCount,
-            audio_format_t mixerInFormat, audio_format_t mixerOutFormat);
-
-    static void convertMixerFormat(void *out, audio_format_t mixerOutFormat,
-            void *in, audio_format_t mixerInFormat, size_t sampleCount);
+    bool setChannelMasks(int name,
+            audio_channel_mask_t trackChannelMask, audio_channel_mask_t mixerChannelMask) override;
 
     static void sInitRoutine();
 
-    // initialization constants
-    const uint32_t mSampleRate;
-    const size_t mFrameCount;
-
-    NBLog::Writer *mNBLogWriter = nullptr;   // associated NBLog::Writer
-
-    process_hook_t mHook = &AudioMixer::process__nop;   // one of process__*, never nullptr
-
-    // the size of the type (int32_t) should be the largest of all types supported
-    // by the mixer.
-    std::unique_ptr<int32_t[]> mOutputTemp;
-    std::unique_ptr<int32_t[]> mResampleTemp;
-
-    // track names grouped by main buffer, in no particular order of main buffer.
-    // however names for a particular main buffer are in order (by construction).
-    std::unordered_map<void * /* mainBuffer */, std::vector<int /* name */>> mGroups;
-
-    // track names that are enabled, in increasing order (by construction).
-    std::vector<int /* name */> mEnabled;
-
-    // track smart pointers, by name, in increasing order of name.
-    std::map<int /* name */, std::shared_ptr<Track>> mTracks;
-
     static pthread_once_t sOnceControl; // initialized in constructor by first new
 };
 
diff --git a/media/libaudioclient/include/media/AudioParameter.h b/media/libaudioclient/include/media/AudioParameter.h
index 24837e3..3c190f2 100644
--- a/media/libaudioclient/include/media/AudioParameter.h
+++ b/media/libaudioclient/include/media/AudioParameter.h
@@ -67,9 +67,12 @@
     //  keyAudioLanguagePreferred: Preferred audio language
     static const char * const keyAudioLanguagePreferred;
 
-    //  keyStreamConnect / Disconnect: value is an int in audio_devices_t
-    static const char * const keyStreamConnect;
-    static const char * const keyStreamDisconnect;
+    //  keyDeviceConnect / Disconnect: value is an int in audio_devices_t
+    static const char * const keyDeviceConnect;
+    static const char * const keyDeviceDisconnect;
+    //  Need to be here because vendors still use them.
+    static const char * const keyStreamConnect;  // Deprecated: DO NOT USE.
+    static const char * const keyStreamDisconnect;  // Deprecated: DO NOT USE.
 
     // For querying stream capabilities. All the returned values are lists.
     //   keyStreamSupportedFormats: audio_format_t
diff --git a/media/libmedia/include/media/ExtendedAudioBufferProvider.h b/media/libaudioclient/include/media/ExtendedAudioBufferProvider.h
similarity index 100%
rename from media/libmedia/include/media/ExtendedAudioBufferProvider.h
rename to media/libaudioclient/include/media/ExtendedAudioBufferProvider.h
diff --git a/media/libaudioclient/tests/Android.bp b/media/libaudioclient/tests/Android.bp
index 52bb2fb..d509be6 100644
--- a/media/libaudioclient/tests/Android.bp
+++ b/media/libaudioclient/tests/Android.bp
@@ -11,6 +11,9 @@
     defaults: ["libaudioclient_tests_defaults"],
     srcs: ["test_create_audiotrack.cpp",
            "test_create_utils.cpp"],
+    header_libs: [
+        "libmedia_headers",
+    ],
     shared_libs: [
         "libaudioclient",
         "libbinder",
@@ -25,6 +28,9 @@
     defaults: ["libaudioclient_tests_defaults"],
     srcs: ["test_create_audiorecord.cpp",
            "test_create_utils.cpp"],
+    header_libs: [
+        "libmedia_headers",
+    ],
     shared_libs: [
         "libaudioclient",
         "libbinder",
diff --git a/media/libaudiohal/Android.bp b/media/libaudiohal/Android.bp
index 584c2c0..74b48f3 100644
--- a/media/libaudiohal/Android.bp
+++ b/media/libaudiohal/Android.bp
@@ -13,20 +13,16 @@
     ],
 
     shared_libs: [
-        "android.hardware.audio.effect@2.0",
-        "android.hardware.audio.effect@4.0",
-        "android.hardware.audio.effect@5.0",
-        "android.hardware.audio@2.0",
-        "android.hardware.audio@4.0",
-        "android.hardware.audio@5.0",
         "libaudiohal@2.0",
         "libaudiohal@4.0",
         "libaudiohal@5.0",
+        "libaudiohal@6.0",
         "libutils",
     ],
 
     header_libs: [
-        "libaudiohal_headers"
+        "libaudiohal_headers",
+        "libbase_headers",
     ]
 }
 
@@ -57,4 +53,10 @@
     name: "libaudiohal_headers",
 
     export_include_dirs: ["include"],
+
+    // This is needed because the stream interface includes media/MicrophoneInfo.h
+    // which is not in any library but has a dependency on headers from libbinder.
+    header_libs: ["libbinder_headers"],
+
+    export_header_lib_headers: ["libbinder_headers"],
 }
diff --git a/media/libaudiohal/DevicesFactoryHalInterface.cpp b/media/libaudiohal/DevicesFactoryHalInterface.cpp
index f86009c..d5336fa 100644
--- a/media/libaudiohal/DevicesFactoryHalInterface.cpp
+++ b/media/libaudiohal/DevicesFactoryHalInterface.cpp
@@ -14,26 +14,16 @@
  * limitations under the License.
  */
 
-#include <android/hardware/audio/2.0/IDevicesFactory.h>
-#include <android/hardware/audio/4.0/IDevicesFactory.h>
-#include <android/hardware/audio/5.0/IDevicesFactory.h>
-
 #include <libaudiohal/FactoryHalHidl.h>
 
+#include <media/audiohal/DevicesFactoryHalInterface.h>
+
 namespace android {
 
 // static
 sp<DevicesFactoryHalInterface> DevicesFactoryHalInterface::create() {
-    if (hardware::audio::V5_0::IDevicesFactory::getService() != nullptr) {
-        return V5_0::createDevicesFactoryHal();
-    }
-    if (hardware::audio::V4_0::IDevicesFactory::getService() != nullptr) {
-        return V4_0::createDevicesFactoryHal();
-    }
-    if (hardware::audio::V2_0::IDevicesFactory::getService() != nullptr) {
-        return V2_0::createDevicesFactoryHal();
-    }
-    return nullptr;
+    return createPreferedImpl<DevicesFactoryHalInterface>();
 }
 
 } // namespace android
+
diff --git a/media/libaudiohal/EffectsFactoryHalInterface.cpp b/media/libaudiohal/EffectsFactoryHalInterface.cpp
index bd3ef61..d15b14e 100644
--- a/media/libaudiohal/EffectsFactoryHalInterface.cpp
+++ b/media/libaudiohal/EffectsFactoryHalInterface.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2016 The Android Open Source Project
+ * Copyright (C) 2017 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,26 +14,15 @@
  * limitations under the License.
  */
 
-#include <android/hardware/audio/effect/2.0/IEffectsFactory.h>
-#include <android/hardware/audio/effect/4.0/IEffectsFactory.h>
-#include <android/hardware/audio/effect/5.0/IEffectsFactory.h>
-
 #include <libaudiohal/FactoryHalHidl.h>
 
+#include <media/audiohal/EffectsFactoryHalInterface.h>
+
 namespace android {
 
 // static
 sp<EffectsFactoryHalInterface> EffectsFactoryHalInterface::create() {
-    if (hardware::audio::effect::V5_0::IEffectsFactory::getService() != nullptr) {
-        return effect::V5_0::createEffectsFactoryHal();
-    }
-    if (hardware::audio::effect::V4_0::IEffectsFactory::getService() != nullptr) {
-        return effect::V4_0::createEffectsFactoryHal();
-    }
-    if (hardware::audio::effect::V2_0::IEffectsFactory::getService() != nullptr) {
-        return effect::V2_0::createEffectsFactoryHal();
-    }
-    return nullptr;
+    return createPreferedImpl<EffectsFactoryHalInterface>();
 }
 
 // static
diff --git a/media/libaudiohal/impl/Android.bp b/media/libaudiohal/impl/Android.bp
index 88533da..8669e2a 100644
--- a/media/libaudiohal/impl/Android.bp
+++ b/media/libaudiohal/impl/Android.bp
@@ -36,8 +36,6 @@
         "libhardware",
         "libhidlbase",
         "libhidlmemory",
-        "libhidltransport",
-        "libhwbinder",
         "liblog",
         "libmedia_helper",
         "libmediautils",
@@ -45,6 +43,7 @@
     ],
     header_libs: [
         "android.hardware.audio.common.util@all-versions",
+        "libaudioclient_headers",
         "libaudiohal_headers"
     ],
 
@@ -100,3 +99,20 @@
         "-include common/all-versions/VersionMacro.h",
     ]
 }
+
+cc_library_shared {
+    name: "libaudiohal@6.0",
+    defaults: ["libaudiohal_default"],
+    shared_libs: [
+        "android.hardware.audio.common@6.0",
+        "android.hardware.audio.common@6.0-util",
+        "android.hardware.audio.effect@6.0",
+        "android.hardware.audio@6.0",
+    ],
+    cflags: [
+        "-DMAJOR_VERSION=6",
+        "-DMINOR_VERSION=0",
+        "-include common/all-versions/VersionMacro.h",
+    ]
+}
+
diff --git a/media/libaudiohal/impl/DevicesFactoryHalHidl.cpp b/media/libaudiohal/impl/DevicesFactoryHalHidl.cpp
index 5e01e42..1335a0c 100644
--- a/media/libaudiohal/impl/DevicesFactoryHalHidl.cpp
+++ b/media/libaudiohal/impl/DevicesFactoryHalHidl.cpp
@@ -35,13 +35,10 @@
 namespace android {
 namespace CPP_VERSION {
 
-DevicesFactoryHalHidl::DevicesFactoryHalHidl() {
-    sp<IDevicesFactory> defaultFactory{IDevicesFactory::getService()};
-    if (!defaultFactory) {
-        ALOGE("Failed to obtain IDevicesFactory/default service, terminating process.");
-        exit(1);
-    }
-    mDeviceFactories.push_back(defaultFactory);
+DevicesFactoryHalHidl::DevicesFactoryHalHidl(sp<IDevicesFactory> devicesFactory) {
+    ALOG_ASSERT(devicesFactory != nullptr, "Provided IDevicesFactory service is NULL");
+
+    mDeviceFactories.push_back(devicesFactory);
     if (MAJOR_VERSION >= 4) {
         // The MSD factory is optional and only available starting at HAL 4.0
         sp<IDevicesFactory> msdFactory{IDevicesFactory::getService(AUDIO_HAL_SERVICE_NAME_MSD)};
diff --git a/media/libaudiohal/impl/DevicesFactoryHalHidl.h b/media/libaudiohal/impl/DevicesFactoryHalHidl.h
index 27e0649..8775e7b 100644
--- a/media/libaudiohal/impl/DevicesFactoryHalHidl.h
+++ b/media/libaudiohal/impl/DevicesFactoryHalHidl.h
@@ -32,18 +32,14 @@
 class DevicesFactoryHalHidl : public DevicesFactoryHalInterface
 {
   public:
+    DevicesFactoryHalHidl(sp<IDevicesFactory> devicesFactory);
+
     // Opens a device with the specified name. To close the device, it is
     // necessary to release references to the returned object.
     virtual status_t openDevice(const char *name, sp<DeviceHalInterface> *device);
-
   private:
-    friend class DevicesFactoryHalHybrid;
-
     std::vector<sp<IDevicesFactory>> mDeviceFactories;
 
-    // Can not be constructed directly by clients.
-    DevicesFactoryHalHidl();
-
     virtual ~DevicesFactoryHalHidl() = default;
 };
 
diff --git a/media/libaudiohal/impl/DevicesFactoryHalHybrid.cpp b/media/libaudiohal/impl/DevicesFactoryHalHybrid.cpp
index f337a8b..0e1f1bb 100644
--- a/media/libaudiohal/impl/DevicesFactoryHalHybrid.cpp
+++ b/media/libaudiohal/impl/DevicesFactoryHalHybrid.cpp
@@ -17,16 +17,17 @@
 #define LOG_TAG "DevicesFactoryHalHybrid"
 //#define LOG_NDEBUG 0
 
+#include "DevicesFactoryHalHidl.h"
 #include "DevicesFactoryHalHybrid.h"
 #include "DevicesFactoryHalLocal.h"
-#include "DevicesFactoryHalHidl.h"
+#include <libaudiohal/FactoryHalHidl.h>
 
 namespace android {
 namespace CPP_VERSION {
 
-DevicesFactoryHalHybrid::DevicesFactoryHalHybrid()
+DevicesFactoryHalHybrid::DevicesFactoryHalHybrid(sp<IDevicesFactory> hidlFactory)
         : mLocalFactory(new DevicesFactoryHalLocal()),
-          mHidlFactory(new DevicesFactoryHalHidl()) {
+          mHidlFactory(new DevicesFactoryHalHidl(hidlFactory)) {
 }
 
 status_t DevicesFactoryHalHybrid::openDevice(const char *name, sp<DeviceHalInterface> *device) {
@@ -36,6 +37,12 @@
     }
     return mLocalFactory->openDevice(name, device);
 }
-
 } // namespace CPP_VERSION
+
+template <>
+sp<DevicesFactoryHalInterface> createFactoryHal<AudioHALVersion::CPP_VERSION>() {
+    auto service = hardware::audio::CPP_VERSION::IDevicesFactory::getService();
+    return service ? new CPP_VERSION::DevicesFactoryHalHybrid(service) : nullptr;
+}
+
 } // namespace android
diff --git a/media/libaudiohal/impl/DevicesFactoryHalHybrid.h b/media/libaudiohal/impl/DevicesFactoryHalHybrid.h
index 5ac0d0d..545bb70 100644
--- a/media/libaudiohal/impl/DevicesFactoryHalHybrid.h
+++ b/media/libaudiohal/impl/DevicesFactoryHalHybrid.h
@@ -17,17 +17,20 @@
 #ifndef ANDROID_HARDWARE_DEVICES_FACTORY_HAL_HYBRID_H
 #define ANDROID_HARDWARE_DEVICES_FACTORY_HAL_HYBRID_H
 
+#include PATH(android/hardware/audio/FILE_VERSION/IDevicesFactory.h)
 #include <media/audiohal/DevicesFactoryHalInterface.h>
 #include <utils/Errors.h>
 #include <utils/RefBase.h>
 
+using ::android::hardware::audio::CPP_VERSION::IDevicesFactory;
+
 namespace android {
 namespace CPP_VERSION {
 
 class DevicesFactoryHalHybrid : public DevicesFactoryHalInterface
 {
   public:
-    DevicesFactoryHalHybrid();
+    DevicesFactoryHalHybrid(sp<IDevicesFactory> hidlFactory);
 
     // Opens a device with the specified name. To close the device, it is
     // necessary to release references to the returned object.
@@ -38,10 +41,6 @@
     sp<DevicesFactoryHalInterface> mHidlFactory;
 };
 
-sp<DevicesFactoryHalInterface> createDevicesFactoryHal() {
-    return new DevicesFactoryHalHybrid();
-}
-
 } // namespace CPP_VERSION
 } // namespace android
 
diff --git a/media/libaudiohal/impl/EffectsFactoryHalHidl.cpp b/media/libaudiohal/impl/EffectsFactoryHalHidl.cpp
index 7fd6bde..ba7b195 100644
--- a/media/libaudiohal/impl/EffectsFactoryHalHidl.cpp
+++ b/media/libaudiohal/impl/EffectsFactoryHalHidl.cpp
@@ -19,11 +19,12 @@
 
 #include <cutils/native_handle.h>
 
-#include "EffectsFactoryHalHidl.h"
 #include "ConversionHelperHidl.h"
 #include "EffectBufferHalHidl.h"
 #include "EffectHalHidl.h"
+#include "EffectsFactoryHalHidl.h"
 #include "HidlUtils.h"
+#include <libaudiohal/FactoryHalHidl.h>
 
 using ::android::hardware::audio::common::CPP_VERSION::implementation::HidlUtils;
 using ::android::hardware::Return;
@@ -35,12 +36,10 @@
 using namespace ::android::hardware::audio::common::CPP_VERSION;
 using namespace ::android::hardware::audio::effect::CPP_VERSION;
 
-EffectsFactoryHalHidl::EffectsFactoryHalHidl() : ConversionHelperHidl("EffectsFactory") {
-    mEffectsFactory = IEffectsFactory::getService();
-    if (mEffectsFactory == 0) {
-        ALOGE("Failed to obtain IEffectsFactory service, terminating process.");
-        exit(1);
-    }
+EffectsFactoryHalHidl::EffectsFactoryHalHidl(sp<IEffectsFactory> effectsFactory)
+        : ConversionHelperHidl("EffectsFactory") {
+    ALOG_ASSERT(effectsFactory != nullptr, "Provided IDevicesFactory service is NULL");
+    mEffectsFactory = effectsFactory;
 }
 
 status_t EffectsFactoryHalHidl::queryAllDescriptors() {
@@ -147,4 +146,11 @@
 
 } // namespace CPP_VERSION
 } // namespace effect
+
+template<>
+sp<EffectsFactoryHalInterface> createFactoryHal<AudioHALVersion::CPP_VERSION>() {
+    auto service = hardware::audio::effect::CPP_VERSION::IEffectsFactory::getService();
+    return service ? new effect::CPP_VERSION::EffectsFactoryHalHidl(service) : nullptr;
+}
+
 } // namespace android
diff --git a/media/libaudiohal/impl/EffectsFactoryHalHidl.h b/media/libaudiohal/impl/EffectsFactoryHalHidl.h
index 01178ff..2828513 100644
--- a/media/libaudiohal/impl/EffectsFactoryHalHidl.h
+++ b/media/libaudiohal/impl/EffectsFactoryHalHidl.h
@@ -18,7 +18,6 @@
 #define ANDROID_HARDWARE_EFFECTS_FACTORY_HAL_HIDL_H
 
 #include PATH(android/hardware/audio/effect/FILE_VERSION/IEffectsFactory.h)
-#include PATH(android/hardware/audio/effect/FILE_VERSION/types.h)
 #include <media/audiohal/EffectsFactoryHalInterface.h>
 
 #include "ConversionHelperHidl.h"
@@ -34,7 +33,7 @@
 class EffectsFactoryHalHidl : public EffectsFactoryHalInterface, public ConversionHelperHidl
 {
   public:
-    EffectsFactoryHalHidl();
+    EffectsFactoryHalHidl(sp<IEffectsFactory> effectsFactory);
 
     // Returns the number of different effects in all loaded libraries.
     virtual status_t queryNumberEffects(uint32_t *pNumEffects);
@@ -66,10 +65,6 @@
     status_t queryAllDescriptors();
 };
 
-sp<EffectsFactoryHalInterface> createEffectsFactoryHal() {
-    return new EffectsFactoryHalHidl();
-}
-
 } // namespace CPP_VERSION
 } // namespace effect
 } // namespace android
diff --git a/media/libaudiohal/impl/include/libaudiohal/FactoryHalHidl.h b/media/libaudiohal/impl/include/libaudiohal/FactoryHalHidl.h
index c7319d0..271bafc 100644
--- a/media/libaudiohal/impl/include/libaudiohal/FactoryHalHidl.h
+++ b/media/libaudiohal/impl/include/libaudiohal/FactoryHalHidl.h
@@ -23,33 +23,43 @@
 #include <media/audiohal/EffectsFactoryHalInterface.h>
 #include <utils/StrongPointer.h>
 
+#include <array>
+#include <utility>
+
 namespace android {
 
-namespace effect {
-namespace V2_0 {
-sp<EffectsFactoryHalInterface> createEffectsFactoryHal();
-} // namespace V2_0
+/** Supported HAL versions, in order of preference.
+ * Implementation should use specialize the `create*FactoryHal` for their version.
+ * Client should use `createPreferedImpl<*FactoryHal>()` to instantiate
+ * the preferred available impl.
+ */
+enum class AudioHALVersion {
+    V6_0,
+    V5_0,
+    V4_0,
+    V2_0,
+    end, // used for iterating over supported versions
+};
 
-namespace V4_0 {
-sp<EffectsFactoryHalInterface> createEffectsFactoryHal();
-} // namespace V4_0
+/** Template function to fully specialized for each version and each Interface. */
+template <AudioHALVersion, class Interface>
+sp<Interface> createFactoryHal();
 
-namespace V5_0 {
-sp<EffectsFactoryHalInterface> createEffectsFactoryHal();
-} // namespace V5_0
-} // namespace effect
+/** @Return the preferred available implementation or nullptr if none are available. */
+template <class Interface, AudioHALVersion version = AudioHALVersion{}>
+static sp<Interface> createPreferedImpl() {
+    if constexpr (version == AudioHALVersion::end) {
+        return nullptr; // tried all version, all returned nullptr
+    } else {
+        if (auto created = createFactoryHal<version, Interface>(); created != nullptr) {
+           return created;
+        }
 
-namespace V2_0 {
-sp<DevicesFactoryHalInterface> createDevicesFactoryHal();
-} // namespace V2_0
+        using Raw = std::underlying_type_t<AudioHALVersion>; // cast as enum class do not support ++
+        return createPreferedImpl<Interface, AudioHALVersion(Raw(version) + 1)>();
+    }
+}
 
-namespace V4_0 {
-sp<DevicesFactoryHalInterface> createDevicesFactoryHal();
-} // namespace V4_0
-
-namespace V5_0 {
-sp<DevicesFactoryHalInterface> createDevicesFactoryHal();
-} // namespace V5_0
 
 } // namespace android
 
diff --git a/media/libaudioprocessing/Android.bp b/media/libaudioprocessing/Android.bp
index cb78063..9b5d58c 100644
--- a/media/libaudioprocessing/Android.bp
+++ b/media/libaudioprocessing/Android.bp
@@ -3,20 +3,13 @@
 
     export_include_dirs: ["include"],
 
+    header_libs: ["libaudioclient_headers"],
+
     shared_libs: [
-        "libaudiohal",
         "libaudioutils",
         "libcutils",
         "liblog",
-        "libnbaio",
-        "libnblog",
-        "libsonic",
         "libutils",
-        "libvibrator",
-    ],
-
-    header_libs: [
-        "libbase_headers",
     ],
 
     cflags: [
@@ -33,18 +26,32 @@
     defaults: ["libaudioprocessing_defaults"],
 
     srcs: [
+        "AudioMixer.cpp",
         "BufferProviders.cpp",
         "RecordBufferConverter.cpp",
     ],
-    whole_static_libs: ["libaudioprocessing_arm"],
+
+    header_libs: [
+        "libbase_headers",
+        "libmedia_headers"
+    ],
+
+    shared_libs: [
+        "libaudiohal",
+        "libsonic",
+        "libvibrator",
+    ],
+
+    whole_static_libs: ["libaudioprocessing_base"],
 }
 
 cc_library_static {
-    name: "libaudioprocessing_arm",
+    name: "libaudioprocessing_base",
     defaults: ["libaudioprocessing_defaults"],
+    vendor_available: true,
 
     srcs: [
-        "AudioMixer.cpp",
+        "AudioMixerBase.cpp",
         "AudioResampler.cpp",
         "AudioResamplerCubic.cpp",
         "AudioResamplerSinc.cpp",
diff --git a/media/libaudioprocessing/AudioMixer.cpp b/media/libaudioprocessing/AudioMixer.cpp
index f7cc096..c0b11a4 100644
--- a/media/libaudioprocessing/AudioMixer.cpp
+++ b/media/libaudioprocessing/AudioMixer.cpp
@@ -18,6 +18,7 @@
 #define LOG_TAG "AudioMixer"
 //#define LOG_NDEBUG 0
 
+#include <sstream>
 #include <stdint.h>
 #include <string.h>
 #include <stdlib.h>
@@ -27,9 +28,6 @@
 #include <utils/Errors.h>
 #include <utils/Log.h>
 
-#include <cutils/compiler.h>
-#include <utils/Debug.h>
-
 #include <system/audio.h>
 
 #include <audio_utils/primitives.h>
@@ -58,138 +56,15 @@
 #define ALOGVV(a...) do { } while (0)
 #endif
 
-#ifndef ARRAY_SIZE
-#define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0]))
-#endif
-
-// Set kUseNewMixer to true to use the new mixer engine always. Otherwise the
-// original code will be used for stereo sinks, the new mixer for multichannel.
-static constexpr bool kUseNewMixer = true;
-
-// Set kUseFloat to true to allow floating input into the mixer engine.
-// If kUseNewMixer is false, this is ignored or may be overridden internally
-// because of downmix/upmix support.
-static constexpr bool kUseFloat = true;
-
-#ifdef FLOAT_AUX
-using TYPE_AUX = float;
-static_assert(kUseNewMixer && kUseFloat,
-        "kUseNewMixer and kUseFloat must be true for FLOAT_AUX option");
-#else
-using TYPE_AUX = int32_t; // q4.27
-#endif
-
 // Set to default copy buffer size in frames for input processing.
-static const size_t kCopyBufferFrameCount = 256;
+static constexpr size_t kCopyBufferFrameCount = 256;
 
 namespace android {
 
 // ----------------------------------------------------------------------------
 
-static inline audio_format_t selectMixerInFormat(audio_format_t inputFormat __unused) {
-    return kUseFloat && kUseNewMixer ? AUDIO_FORMAT_PCM_FLOAT : AUDIO_FORMAT_PCM_16_BIT;
-}
-
-status_t AudioMixer::create(
-        int name, audio_channel_mask_t channelMask, audio_format_t format, int sessionId)
-{
-    LOG_ALWAYS_FATAL_IF(exists(name), "name %d already exists", name);
-
-    if (!isValidChannelMask(channelMask)) {
-        ALOGE("%s invalid channelMask: %#x", __func__, channelMask);
-        return BAD_VALUE;
-    }
-    if (!isValidFormat(format)) {
-        ALOGE("%s invalid format: %#x", __func__, format);
-        return BAD_VALUE;
-    }
-
-    auto t = std::make_shared<Track>();
-    {
-        // TODO: move initialization to the Track constructor.
-        // assume default parameters for the track, except where noted below
-        t->needs = 0;
-
-        // Integer volume.
-        // Currently integer volume is kept for the legacy integer mixer.
-        // Will be removed when the legacy mixer path is removed.
-        t->volume[0] = 0;
-        t->volume[1] = 0;
-        t->prevVolume[0] = 0 << 16;
-        t->prevVolume[1] = 0 << 16;
-        t->volumeInc[0] = 0;
-        t->volumeInc[1] = 0;
-        t->auxLevel = 0;
-        t->auxInc = 0;
-        t->prevAuxLevel = 0;
-
-        // Floating point volume.
-        t->mVolume[0] = 0.f;
-        t->mVolume[1] = 0.f;
-        t->mPrevVolume[0] = 0.f;
-        t->mPrevVolume[1] = 0.f;
-        t->mVolumeInc[0] = 0.;
-        t->mVolumeInc[1] = 0.;
-        t->mAuxLevel = 0.;
-        t->mAuxInc = 0.;
-        t->mPrevAuxLevel = 0.;
-
-        // no initialization needed
-        // t->frameCount
-        t->mHapticChannelMask = channelMask & AUDIO_CHANNEL_HAPTIC_ALL;
-        t->mHapticChannelCount = audio_channel_count_from_out_mask(t->mHapticChannelMask);
-        channelMask &= ~AUDIO_CHANNEL_HAPTIC_ALL;
-        t->channelCount = audio_channel_count_from_out_mask(channelMask);
-        t->enabled = false;
-        ALOGV_IF(audio_channel_mask_get_bits(channelMask) != AUDIO_CHANNEL_OUT_STEREO,
-                "Non-stereo channel mask: %d\n", channelMask);
-        t->channelMask = channelMask;
-        t->sessionId = sessionId;
-        // setBufferProvider(name, AudioBufferProvider *) is required before enable(name)
-        t->bufferProvider = NULL;
-        t->buffer.raw = NULL;
-        // no initialization needed
-        // t->buffer.frameCount
-        t->hook = NULL;
-        t->mIn = NULL;
-        t->sampleRate = mSampleRate;
-        // setParameter(name, TRACK, MAIN_BUFFER, mixBuffer) is required before enable(name)
-        t->mainBuffer = NULL;
-        t->auxBuffer = NULL;
-        t->mInputBufferProvider = NULL;
-        t->mMixerFormat = AUDIO_FORMAT_PCM_16_BIT;
-        t->mFormat = format;
-        t->mMixerInFormat = selectMixerInFormat(format);
-        t->mDownmixRequiresFormat = AUDIO_FORMAT_INVALID; // no format required
-        t->mMixerChannelMask = audio_channel_mask_from_representation_and_bits(
-                AUDIO_CHANNEL_REPRESENTATION_POSITION, AUDIO_CHANNEL_OUT_STEREO);
-        t->mMixerChannelCount = audio_channel_count_from_out_mask(t->mMixerChannelMask);
-        t->mPlaybackRate = AUDIO_PLAYBACK_RATE_DEFAULT;
-        // haptic
-        t->mHapticPlaybackEnabled = false;
-        t->mHapticIntensity = HAPTIC_SCALE_NONE;
-        t->mMixerHapticChannelMask = AUDIO_CHANNEL_NONE;
-        t->mMixerHapticChannelCount = 0;
-        t->mAdjustInChannelCount = t->channelCount + t->mHapticChannelCount;
-        t->mAdjustOutChannelCount = t->channelCount + t->mMixerHapticChannelCount;
-        t->mAdjustNonDestructiveInChannelCount = t->mAdjustOutChannelCount;
-        t->mAdjustNonDestructiveOutChannelCount = t->channelCount;
-        t->mKeepContractedChannels = false;
-        // Check the downmixing (or upmixing) requirements.
-        status_t status = t->prepareForDownmix();
-        if (status != OK) {
-            ALOGE("AudioMixer::getTrackName invalid channelMask (%#x)", channelMask);
-            return BAD_VALUE;
-        }
-        // prepareForDownmix() may change mDownmixRequiresFormat
-        ALOGVV("mMixerFormat:%#x  mMixerInFormat:%#x\n", t->mMixerFormat, t->mMixerInFormat);
-        t->prepareForReformat();
-        t->prepareForAdjustChannelsNonDestructive(mFrameCount);
-        t->prepareForAdjustChannels();
-
-        mTracks[name] = t;
-        return OK;
-    }
+bool AudioMixer::isValidChannelMask(audio_channel_mask_t channelMask) const {
+    return audio_channel_mask_is_valid(channelMask); // the RemixBufferProvider is flexible.
 }
 
 // Called when channel masks have changed for a track name
@@ -198,7 +73,7 @@
 bool AudioMixer::setChannelMasks(int name,
         audio_channel_mask_t trackChannelMask, audio_channel_mask_t mixerChannelMask) {
     LOG_ALWAYS_FATAL_IF(!exists(name), "invalid name: %d", name);
-    const std::shared_ptr<Track> &track = mTracks[name];
+    const std::shared_ptr<Track> &track = getTrack(name);
 
     if (trackChannelMask == (track->channelMask | track->mHapticChannelMask)
             && mixerChannelMask == (track->mMixerChannelMask | track->mMixerHapticChannelMask)) {
@@ -255,14 +130,8 @@
     track->prepareForAdjustChannelsNonDestructive(mFrameCount);
     track->prepareForAdjustChannels();
 
-    if (track->mResampler.get() != nullptr) {
-        // resampler channels may have changed.
-        const uint32_t resetToSampleRate = track->sampleRate;
-        track->mResampler.reset(nullptr);
-        track->sampleRate = mSampleRate; // without resampler, track rate is device sample rate.
-        // recreate the resampler with updated format, channels, saved sampleRate.
-        track->setResampler(resetToSampleRate /*trackSampleRate*/, mSampleRate /*devSampleRate*/);
-    }
+    // Resampler channels may have changed.
+    track->recreateResampler(mSampleRate);
     return true;
 }
 
@@ -477,171 +346,10 @@
     }
 }
 
-void AudioMixer::destroy(int name)
-{
-    LOG_ALWAYS_FATAL_IF(!exists(name), "invalid name: %d", name);
-    ALOGV("deleteTrackName(%d)", name);
-
-    if (mTracks[name]->enabled) {
-        invalidate();
-    }
-    mTracks.erase(name); // deallocate track
-}
-
-void AudioMixer::enable(int name)
-{
-    LOG_ALWAYS_FATAL_IF(!exists(name), "invalid name: %d", name);
-    const std::shared_ptr<Track> &track = mTracks[name];
-
-    if (!track->enabled) {
-        track->enabled = true;
-        ALOGV("enable(%d)", name);
-        invalidate();
-    }
-}
-
-void AudioMixer::disable(int name)
-{
-    LOG_ALWAYS_FATAL_IF(!exists(name), "invalid name: %d", name);
-    const std::shared_ptr<Track> &track = mTracks[name];
-
-    if (track->enabled) {
-        track->enabled = false;
-        ALOGV("disable(%d)", name);
-        invalidate();
-    }
-}
-
-/* Sets the volume ramp variables for the AudioMixer.
- *
- * The volume ramp variables are used to transition from the previous
- * volume to the set volume.  ramp controls the duration of the transition.
- * Its value is typically one state framecount period, but may also be 0,
- * meaning "immediate."
- *
- * FIXME: 1) Volume ramp is enabled only if there is a nonzero integer increment
- * even if there is a nonzero floating point increment (in that case, the volume
- * change is immediate).  This restriction should be changed when the legacy mixer
- * is removed (see #2).
- * FIXME: 2) Integer volume variables are used for Legacy mixing and should be removed
- * when no longer needed.
- *
- * @param newVolume set volume target in floating point [0.0, 1.0].
- * @param ramp number of frames to increment over. if ramp is 0, the volume
- * should be set immediately.  Currently ramp should not exceed 65535 (frames).
- * @param pIntSetVolume pointer to the U4.12 integer target volume, set on return.
- * @param pIntPrevVolume pointer to the U4.28 integer previous volume, set on return.
- * @param pIntVolumeInc pointer to the U4.28 increment per output audio frame, set on return.
- * @param pSetVolume pointer to the float target volume, set on return.
- * @param pPrevVolume pointer to the float previous volume, set on return.
- * @param pVolumeInc pointer to the float increment per output audio frame, set on return.
- * @return true if the volume has changed, false if volume is same.
- */
-static inline bool setVolumeRampVariables(float newVolume, int32_t ramp,
-        int16_t *pIntSetVolume, int32_t *pIntPrevVolume, int32_t *pIntVolumeInc,
-        float *pSetVolume, float *pPrevVolume, float *pVolumeInc) {
-    // check floating point volume to see if it is identical to the previously
-    // set volume.
-    // We do not use a tolerance here (and reject changes too small)
-    // as it may be confusing to use a different value than the one set.
-    // If the resulting volume is too small to ramp, it is a direct set of the volume.
-    if (newVolume == *pSetVolume) {
-        return false;
-    }
-    if (newVolume < 0) {
-        newVolume = 0; // should not have negative volumes
-    } else {
-        switch (fpclassify(newVolume)) {
-        case FP_SUBNORMAL:
-        case FP_NAN:
-            newVolume = 0;
-            break;
-        case FP_ZERO:
-            break; // zero volume is fine
-        case FP_INFINITE:
-            // Infinite volume could be handled consistently since
-            // floating point math saturates at infinities,
-            // but we limit volume to unity gain float.
-            // ramp = 0; break;
-            //
-            newVolume = AudioMixer::UNITY_GAIN_FLOAT;
-            break;
-        case FP_NORMAL:
-        default:
-            // Floating point does not have problems with overflow wrap
-            // that integer has.  However, we limit the volume to
-            // unity gain here.
-            // TODO: Revisit the volume limitation and perhaps parameterize.
-            if (newVolume > AudioMixer::UNITY_GAIN_FLOAT) {
-                newVolume = AudioMixer::UNITY_GAIN_FLOAT;
-            }
-            break;
-        }
-    }
-
-    // set floating point volume ramp
-    if (ramp != 0) {
-        // when the ramp completes, *pPrevVolume is set to *pSetVolume, so there
-        // is no computational mismatch; hence equality is checked here.
-        ALOGD_IF(*pPrevVolume != *pSetVolume, "previous float ramp hasn't finished,"
-                " prev:%f  set_to:%f", *pPrevVolume, *pSetVolume);
-        const float inc = (newVolume - *pPrevVolume) / ramp; // could be inf, nan, subnormal
-        // could be inf, cannot be nan, subnormal
-        const float maxv = std::max(newVolume, *pPrevVolume);
-
-        if (isnormal(inc) // inc must be a normal number (no subnormals, infinite, nan)
-                && maxv + inc != maxv) { // inc must make forward progress
-            *pVolumeInc = inc;
-            // ramp is set now.
-            // Note: if newVolume is 0, then near the end of the ramp,
-            // it may be possible that the ramped volume may be subnormal or
-            // temporarily negative by a small amount or subnormal due to floating
-            // point inaccuracies.
-        } else {
-            ramp = 0; // ramp not allowed
-        }
-    }
-
-    // compute and check integer volume, no need to check negative values
-    // The integer volume is limited to "unity_gain" to avoid wrapping and other
-    // audio artifacts, so it never reaches the range limit of U4.28.
-    // We safely use signed 16 and 32 bit integers here.
-    const float scaledVolume = newVolume * AudioMixer::UNITY_GAIN_INT; // not neg, subnormal, nan
-    const int32_t intVolume = (scaledVolume >= (float)AudioMixer::UNITY_GAIN_INT) ?
-            AudioMixer::UNITY_GAIN_INT : (int32_t)scaledVolume;
-
-    // set integer volume ramp
-    if (ramp != 0) {
-        // integer volume is U4.12 (to use 16 bit multiplies), but ramping uses U4.28.
-        // when the ramp completes, *pIntPrevVolume is set to *pIntSetVolume << 16, so there
-        // is no computational mismatch; hence equality is checked here.
-        ALOGD_IF(*pIntPrevVolume != *pIntSetVolume << 16, "previous int ramp hasn't finished,"
-                " prev:%d  set_to:%d", *pIntPrevVolume, *pIntSetVolume << 16);
-        const int32_t inc = ((intVolume << 16) - *pIntPrevVolume) / ramp;
-
-        if (inc != 0) { // inc must make forward progress
-            *pIntVolumeInc = inc;
-        } else {
-            ramp = 0; // ramp not allowed
-        }
-    }
-
-    // if no ramp, or ramp not allowed, then clear float and integer increments
-    if (ramp == 0) {
-        *pVolumeInc = 0;
-        *pPrevVolume = newVolume;
-        *pIntVolumeInc = 0;
-        *pIntPrevVolume = intVolume << 16;
-    }
-    *pSetVolume = newVolume;
-    *pIntSetVolume = intVolume;
-    return true;
-}
-
 void AudioMixer::setParameter(int name, int target, int param, void *value)
 {
     LOG_ALWAYS_FATAL_IF(!exists(name), "invalid name: %d", name);
-    const std::shared_ptr<Track> &track = mTracks[name];
+    const std::shared_ptr<Track> &track = getTrack(name);
 
     int valueInt = static_cast<int>(reinterpret_cast<uintptr_t>(value));
     int32_t *valueBuf = reinterpret_cast<int32_t*>(value);
@@ -670,11 +378,7 @@
             }
             break;
         case AUX_BUFFER:
-            if (track->auxBuffer != valueBuf) {
-                track->auxBuffer = valueBuf;
-                ALOGV("setParameter(TRACK, AUX_BUFFER, %p)", valueBuf);
-                invalidate();
-            }
+            AudioMixerBase::setParameter(name, target, param, value);
             break;
         case FORMAT: {
             audio_format_t format = static_cast<audio_format_t>(valueInt);
@@ -730,127 +434,38 @@
         break;
 
     case RESAMPLE:
-        switch (param) {
-        case SAMPLE_RATE:
-            ALOG_ASSERT(valueInt > 0, "bad sample rate %d", valueInt);
-            if (track->setResampler(uint32_t(valueInt), mSampleRate)) {
-                ALOGV("setParameter(RESAMPLE, SAMPLE_RATE, %u)",
-                        uint32_t(valueInt));
-                invalidate();
-            }
-            break;
-        case RESET:
-            track->resetResampler();
-            invalidate();
-            break;
-        case REMOVE:
-            track->mResampler.reset(nullptr);
-            track->sampleRate = mSampleRate;
-            invalidate();
-            break;
-        default:
-            LOG_ALWAYS_FATAL("setParameter resample: bad param %d", param);
-        }
-        break;
-
     case RAMP_VOLUME:
     case VOLUME:
+        AudioMixerBase::setParameter(name, target, param, value);
+        break;
+    case TIMESTRETCH:
         switch (param) {
-        case AUXLEVEL:
-            if (setVolumeRampVariables(*reinterpret_cast<float*>(value),
-                    target == RAMP_VOLUME ? mFrameCount : 0,
-                    &track->auxLevel, &track->prevAuxLevel, &track->auxInc,
-                    &track->mAuxLevel, &track->mPrevAuxLevel, &track->mAuxInc)) {
-                ALOGV("setParameter(%s, AUXLEVEL: %04x)",
-                        target == VOLUME ? "VOLUME" : "RAMP_VOLUME", track->auxLevel);
-                invalidate();
+        case PLAYBACK_RATE: {
+            const AudioPlaybackRate *playbackRate =
+                    reinterpret_cast<AudioPlaybackRate*>(value);
+            ALOGW_IF(!isAudioPlaybackRateValid(*playbackRate),
+                    "bad parameters speed %f, pitch %f",
+                    playbackRate->mSpeed, playbackRate->mPitch);
+            if (track->setPlaybackRate(*playbackRate)) {
+                ALOGV("setParameter(TIMESTRETCH, PLAYBACK_RATE, STRETCH_MODE, FALLBACK_MODE "
+                        "%f %f %d %d",
+                        playbackRate->mSpeed,
+                        playbackRate->mPitch,
+                        playbackRate->mStretchMode,
+                        playbackRate->mFallbackMode);
+                // invalidate();  (should not require reconfigure)
             }
-            break;
+        } break;
         default:
-            if ((unsigned)param >= VOLUME0 && (unsigned)param < VOLUME0 + MAX_NUM_VOLUMES) {
-                if (setVolumeRampVariables(*reinterpret_cast<float*>(value),
-                        target == RAMP_VOLUME ? mFrameCount : 0,
-                        &track->volume[param - VOLUME0],
-                        &track->prevVolume[param - VOLUME0],
-                        &track->volumeInc[param - VOLUME0],
-                        &track->mVolume[param - VOLUME0],
-                        &track->mPrevVolume[param - VOLUME0],
-                        &track->mVolumeInc[param - VOLUME0])) {
-                    ALOGV("setParameter(%s, VOLUME%d: %04x)",
-                            target == VOLUME ? "VOLUME" : "RAMP_VOLUME", param - VOLUME0,
-                                    track->volume[param - VOLUME0]);
-                    invalidate();
-                }
-            } else {
-                LOG_ALWAYS_FATAL("setParameter volume: bad param %d", param);
-            }
+            LOG_ALWAYS_FATAL("setParameter timestretch: bad param %d", param);
         }
         break;
-        case TIMESTRETCH:
-            switch (param) {
-            case PLAYBACK_RATE: {
-                const AudioPlaybackRate *playbackRate =
-                        reinterpret_cast<AudioPlaybackRate*>(value);
-                ALOGW_IF(!isAudioPlaybackRateValid(*playbackRate),
-                        "bad parameters speed %f, pitch %f",
-                        playbackRate->mSpeed, playbackRate->mPitch);
-                if (track->setPlaybackRate(*playbackRate)) {
-                    ALOGV("setParameter(TIMESTRETCH, PLAYBACK_RATE, STRETCH_MODE, FALLBACK_MODE "
-                            "%f %f %d %d",
-                            playbackRate->mSpeed,
-                            playbackRate->mPitch,
-                            playbackRate->mStretchMode,
-                            playbackRate->mFallbackMode);
-                    // invalidate();  (should not require reconfigure)
-                }
-            } break;
-            default:
-                LOG_ALWAYS_FATAL("setParameter timestretch: bad param %d", param);
-            }
-            break;
 
     default:
         LOG_ALWAYS_FATAL("setParameter: bad target %d", target);
     }
 }
 
-bool AudioMixer::Track::setResampler(uint32_t trackSampleRate, uint32_t devSampleRate)
-{
-    if (trackSampleRate != devSampleRate || mResampler.get() != nullptr) {
-        if (sampleRate != trackSampleRate) {
-            sampleRate = trackSampleRate;
-            if (mResampler.get() == nullptr) {
-                ALOGV("Creating resampler from track %d Hz to device %d Hz",
-                        trackSampleRate, devSampleRate);
-                AudioResampler::src_quality quality;
-                // force lowest quality level resampler if use case isn't music or video
-                // FIXME this is flawed for dynamic sample rates, as we choose the resampler
-                // quality level based on the initial ratio, but that could change later.
-                // Should have a way to distinguish tracks with static ratios vs. dynamic ratios.
-                if (isMusicRate(trackSampleRate)) {
-                    quality = AudioResampler::DEFAULT_QUALITY;
-                } else {
-                    quality = AudioResampler::DYN_LOW_QUALITY;
-                }
-
-                // TODO: Remove MONO_HACK. Resampler sees #channels after the downmixer
-                // but if none exists, it is the channel count (1 for mono).
-                const int resamplerChannelCount = mDownmixerBufferProvider.get() != nullptr
-                        ? mMixerChannelCount : channelCount;
-                ALOGVV("Creating resampler:"
-                        " format(%#x) channels(%d) devSampleRate(%u) quality(%d)\n",
-                        mMixerInFormat, resamplerChannelCount, devSampleRate, quality);
-                mResampler.reset(AudioResampler::create(
-                        mMixerInFormat,
-                        resamplerChannelCount,
-                        devSampleRate, quality));
-            }
-            return true;
-        }
-    }
-    return false;
-}
-
 bool AudioMixer::Track::setPlaybackRate(const AudioPlaybackRate &playbackRate)
 {
     if ((mTimestretchBufferProvider.get() == nullptr &&
@@ -863,8 +478,7 @@
     if (mTimestretchBufferProvider.get() == nullptr) {
         // TODO: Remove MONO_HACK. Resampler sees #channels after the downmixer
         // but if none exists, it is the channel count (1 for mono).
-        const int timestretchChannelCount = mDownmixerBufferProvider.get() != nullptr
-                ? mMixerChannelCount : channelCount;
+        const int timestretchChannelCount = getOutputChannelCount();
         mTimestretchBufferProvider.reset(new TimestretchBufferProvider(timestretchChannelCount,
                 mMixerInFormat, sampleRate, playbackRate));
         reconfigureBufferProviders();
@@ -875,84 +489,10 @@
     return true;
 }
 
-/* Checks to see if the volume ramp has completed and clears the increment
- * variables appropriately.
- *
- * FIXME: There is code to handle int/float ramp variable switchover should it not
- * complete within a mixer buffer processing call, but it is preferred to avoid switchover
- * due to precision issues.  The switchover code is included for legacy code purposes
- * and can be removed once the integer volume is removed.
- *
- * It is not sufficient to clear only the volumeInc integer variable because
- * if one channel requires ramping, all channels are ramped.
- *
- * There is a bit of duplicated code here, but it keeps backward compatibility.
- */
-inline void AudioMixer::Track::adjustVolumeRamp(bool aux, bool useFloat)
-{
-    if (useFloat) {
-        for (uint32_t i = 0; i < MAX_NUM_VOLUMES; i++) {
-            if ((mVolumeInc[i] > 0 && mPrevVolume[i] + mVolumeInc[i] >= mVolume[i]) ||
-                     (mVolumeInc[i] < 0 && mPrevVolume[i] + mVolumeInc[i] <= mVolume[i])) {
-                volumeInc[i] = 0;
-                prevVolume[i] = volume[i] << 16;
-                mVolumeInc[i] = 0.;
-                mPrevVolume[i] = mVolume[i];
-            } else {
-                //ALOGV("ramp: %f %f %f", mVolume[i], mPrevVolume[i], mVolumeInc[i]);
-                prevVolume[i] = u4_28_from_float(mPrevVolume[i]);
-            }
-        }
-    } else {
-        for (uint32_t i = 0; i < MAX_NUM_VOLUMES; i++) {
-            if (((volumeInc[i]>0) && (((prevVolume[i]+volumeInc[i])>>16) >= volume[i])) ||
-                    ((volumeInc[i]<0) && (((prevVolume[i]+volumeInc[i])>>16) <= volume[i]))) {
-                volumeInc[i] = 0;
-                prevVolume[i] = volume[i] << 16;
-                mVolumeInc[i] = 0.;
-                mPrevVolume[i] = mVolume[i];
-            } else {
-                //ALOGV("ramp: %d %d %d", volume[i] << 16, prevVolume[i], volumeInc[i]);
-                mPrevVolume[i]  = float_from_u4_28(prevVolume[i]);
-            }
-        }
-    }
-
-    if (aux) {
-#ifdef FLOAT_AUX
-        if (useFloat) {
-            if ((mAuxInc > 0.f && mPrevAuxLevel + mAuxInc >= mAuxLevel) ||
-                    (mAuxInc < 0.f && mPrevAuxLevel + mAuxInc <= mAuxLevel)) {
-                auxInc = 0;
-                prevAuxLevel = auxLevel << 16;
-                mAuxInc = 0.f;
-                mPrevAuxLevel = mAuxLevel;
-            }
-        } else
-#endif
-        if ((auxInc > 0 && ((prevAuxLevel + auxInc) >> 16) >= auxLevel) ||
-                (auxInc < 0 && ((prevAuxLevel + auxInc) >> 16) <= auxLevel)) {
-            auxInc = 0;
-            prevAuxLevel = auxLevel << 16;
-            mAuxInc = 0.f;
-            mPrevAuxLevel = mAuxLevel;
-        }
-    }
-}
-
-size_t AudioMixer::getUnreleasedFrames(int name) const
-{
-    const auto it = mTracks.find(name);
-    if (it != mTracks.end()) {
-        return it->second->getUnreleasedFrames();
-    }
-    return 0;
-}
-
 void AudioMixer::setBufferProvider(int name, AudioBufferProvider* bufferProvider)
 {
     LOG_ALWAYS_FATAL_IF(!exists(name), "invalid name: %d", name);
-    const std::shared_ptr<Track> &track = mTracks[name];
+    const std::shared_ptr<Track> &track = getTrack(name);
 
     if (track->mInputBufferProvider == bufferProvider) {
         return; // don't reset any buffer providers if identical.
@@ -976,679 +516,6 @@
     track->reconfigureBufferProviders();
 }
 
-void AudioMixer::process__validate()
-{
-    // TODO: fix all16BitsStereNoResample logic to
-    // either properly handle muted tracks (it should ignore them)
-    // or remove altogether as an obsolete optimization.
-    bool all16BitsStereoNoResample = true;
-    bool resampling = false;
-    bool volumeRamp = false;
-
-    mEnabled.clear();
-    mGroups.clear();
-    for (const auto &pair : mTracks) {
-        const int name = pair.first;
-        const std::shared_ptr<Track> &t = pair.second;
-        if (!t->enabled) continue;
-
-        mEnabled.emplace_back(name);  // we add to mEnabled in order of name.
-        mGroups[t->mainBuffer].emplace_back(name); // mGroups also in order of name.
-
-        uint32_t n = 0;
-        // FIXME can overflow (mask is only 3 bits)
-        n |= NEEDS_CHANNEL_1 + t->channelCount - 1;
-        if (t->doesResample()) {
-            n |= NEEDS_RESAMPLE;
-        }
-        if (t->auxLevel != 0 && t->auxBuffer != NULL) {
-            n |= NEEDS_AUX;
-        }
-
-        if (t->volumeInc[0]|t->volumeInc[1]) {
-            volumeRamp = true;
-        } else if (!t->doesResample() && t->volumeRL == 0) {
-            n |= NEEDS_MUTE;
-        }
-        t->needs = n;
-
-        if (n & NEEDS_MUTE) {
-            t->hook = &Track::track__nop;
-        } else {
-            if (n & NEEDS_AUX) {
-                all16BitsStereoNoResample = false;
-            }
-            if (n & NEEDS_RESAMPLE) {
-                all16BitsStereoNoResample = false;
-                resampling = true;
-                t->hook = Track::getTrackHook(TRACKTYPE_RESAMPLE, t->mMixerChannelCount,
-                        t->mMixerInFormat, t->mMixerFormat);
-                ALOGV_IF((n & NEEDS_CHANNEL_COUNT__MASK) > NEEDS_CHANNEL_2,
-                        "Track %d needs downmix + resample", name);
-            } else {
-                if ((n & NEEDS_CHANNEL_COUNT__MASK) == NEEDS_CHANNEL_1){
-                    t->hook = Track::getTrackHook(
-                            (t->mMixerChannelMask == AUDIO_CHANNEL_OUT_STEREO  // TODO: MONO_HACK
-                                    && t->channelMask == AUDIO_CHANNEL_OUT_MONO)
-                                ? TRACKTYPE_NORESAMPLEMONO : TRACKTYPE_NORESAMPLE,
-                            t->mMixerChannelCount,
-                            t->mMixerInFormat, t->mMixerFormat);
-                    all16BitsStereoNoResample = false;
-                }
-                if ((n & NEEDS_CHANNEL_COUNT__MASK) >= NEEDS_CHANNEL_2){
-                    t->hook = Track::getTrackHook(TRACKTYPE_NORESAMPLE, t->mMixerChannelCount,
-                            t->mMixerInFormat, t->mMixerFormat);
-                    ALOGV_IF((n & NEEDS_CHANNEL_COUNT__MASK) > NEEDS_CHANNEL_2,
-                            "Track %d needs downmix", name);
-                }
-            }
-        }
-    }
-
-    // select the processing hooks
-    mHook = &AudioMixer::process__nop;
-    if (mEnabled.size() > 0) {
-        if (resampling) {
-            if (mOutputTemp.get() == nullptr) {
-                mOutputTemp.reset(new int32_t[MAX_NUM_CHANNELS * mFrameCount]);
-            }
-            if (mResampleTemp.get() == nullptr) {
-                mResampleTemp.reset(new int32_t[MAX_NUM_CHANNELS * mFrameCount]);
-            }
-            mHook = &AudioMixer::process__genericResampling;
-        } else {
-            // we keep temp arrays around.
-            mHook = &AudioMixer::process__genericNoResampling;
-            if (all16BitsStereoNoResample && !volumeRamp) {
-                if (mEnabled.size() == 1) {
-                    const std::shared_ptr<Track> &t = mTracks[mEnabled[0]];
-                    if ((t->needs & NEEDS_MUTE) == 0) {
-                        // The check prevents a muted track from acquiring a process hook.
-                        //
-                        // This is dangerous if the track is MONO as that requires
-                        // special case handling due to implicit channel duplication.
-                        // Stereo or Multichannel should actually be fine here.
-                        mHook = getProcessHook(PROCESSTYPE_NORESAMPLEONETRACK,
-                                t->mMixerChannelCount, t->mMixerInFormat, t->mMixerFormat);
-                    }
-                }
-            }
-        }
-    }
-
-    ALOGV("mixer configuration change: %zu "
-        "all16BitsStereoNoResample=%d, resampling=%d, volumeRamp=%d",
-        mEnabled.size(), all16BitsStereoNoResample, resampling, volumeRamp);
-
-   process();
-
-    // Now that the volume ramp has been done, set optimal state and
-    // track hooks for subsequent mixer process
-    if (mEnabled.size() > 0) {
-        bool allMuted = true;
-
-        for (const int name : mEnabled) {
-            const std::shared_ptr<Track> &t = mTracks[name];
-            if (!t->doesResample() && t->volumeRL == 0) {
-                t->needs |= NEEDS_MUTE;
-                t->hook = &Track::track__nop;
-            } else {
-                allMuted = false;
-            }
-        }
-        if (allMuted) {
-            mHook = &AudioMixer::process__nop;
-        } else if (all16BitsStereoNoResample) {
-            if (mEnabled.size() == 1) {
-                //const int i = 31 - __builtin_clz(enabledTracks);
-                const std::shared_ptr<Track> &t = mTracks[mEnabled[0]];
-                // Muted single tracks handled by allMuted above.
-                mHook = getProcessHook(PROCESSTYPE_NORESAMPLEONETRACK,
-                        t->mMixerChannelCount, t->mMixerInFormat, t->mMixerFormat);
-            }
-        }
-    }
-}
-
-void AudioMixer::Track::track__genericResample(
-        int32_t* out, size_t outFrameCount, int32_t* temp, int32_t* aux)
-{
-    ALOGVV("track__genericResample\n");
-    mResampler->setSampleRate(sampleRate);
-
-    // ramp gain - resample to temp buffer and scale/mix in 2nd step
-    if (aux != NULL) {
-        // always resample with unity gain when sending to auxiliary buffer to be able
-        // to apply send level after resampling
-        mResampler->setVolume(UNITY_GAIN_FLOAT, UNITY_GAIN_FLOAT);
-        memset(temp, 0, outFrameCount * mMixerChannelCount * sizeof(int32_t));
-        mResampler->resample(temp, outFrameCount, bufferProvider);
-        if (CC_UNLIKELY(volumeInc[0]|volumeInc[1]|auxInc)) {
-            volumeRampStereo(out, outFrameCount, temp, aux);
-        } else {
-            volumeStereo(out, outFrameCount, temp, aux);
-        }
-    } else {
-        if (CC_UNLIKELY(volumeInc[0]|volumeInc[1])) {
-            mResampler->setVolume(UNITY_GAIN_FLOAT, UNITY_GAIN_FLOAT);
-            memset(temp, 0, outFrameCount * MAX_NUM_CHANNELS * sizeof(int32_t));
-            mResampler->resample(temp, outFrameCount, bufferProvider);
-            volumeRampStereo(out, outFrameCount, temp, aux);
-        }
-
-        // constant gain
-        else {
-            mResampler->setVolume(mVolume[0], mVolume[1]);
-            mResampler->resample(out, outFrameCount, bufferProvider);
-        }
-    }
-}
-
-void AudioMixer::Track::track__nop(int32_t* out __unused,
-        size_t outFrameCount __unused, int32_t* temp __unused, int32_t* aux __unused)
-{
-}
-
-void AudioMixer::Track::volumeRampStereo(
-        int32_t* out, size_t frameCount, int32_t* temp, int32_t* aux)
-{
-    int32_t vl = prevVolume[0];
-    int32_t vr = prevVolume[1];
-    const int32_t vlInc = volumeInc[0];
-    const int32_t vrInc = volumeInc[1];
-
-    //ALOGD("[0] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
-    //        t, vlInc/65536.0f, vl/65536.0f, volume[0],
-    //       (vl + vlInc*frameCount)/65536.0f, frameCount);
-
-    // ramp volume
-    if (CC_UNLIKELY(aux != NULL)) {
-        int32_t va = prevAuxLevel;
-        const int32_t vaInc = auxInc;
-        int32_t l;
-        int32_t r;
-
-        do {
-            l = (*temp++ >> 12);
-            r = (*temp++ >> 12);
-            *out++ += (vl >> 16) * l;
-            *out++ += (vr >> 16) * r;
-            *aux++ += (va >> 17) * (l + r);
-            vl += vlInc;
-            vr += vrInc;
-            va += vaInc;
-        } while (--frameCount);
-        prevAuxLevel = va;
-    } else {
-        do {
-            *out++ += (vl >> 16) * (*temp++ >> 12);
-            *out++ += (vr >> 16) * (*temp++ >> 12);
-            vl += vlInc;
-            vr += vrInc;
-        } while (--frameCount);
-    }
-    prevVolume[0] = vl;
-    prevVolume[1] = vr;
-    adjustVolumeRamp(aux != NULL);
-}
-
-void AudioMixer::Track::volumeStereo(
-        int32_t* out, size_t frameCount, int32_t* temp, int32_t* aux)
-{
-    const int16_t vl = volume[0];
-    const int16_t vr = volume[1];
-
-    if (CC_UNLIKELY(aux != NULL)) {
-        const int16_t va = auxLevel;
-        do {
-            int16_t l = (int16_t)(*temp++ >> 12);
-            int16_t r = (int16_t)(*temp++ >> 12);
-            out[0] = mulAdd(l, vl, out[0]);
-            int16_t a = (int16_t)(((int32_t)l + r) >> 1);
-            out[1] = mulAdd(r, vr, out[1]);
-            out += 2;
-            aux[0] = mulAdd(a, va, aux[0]);
-            aux++;
-        } while (--frameCount);
-    } else {
-        do {
-            int16_t l = (int16_t)(*temp++ >> 12);
-            int16_t r = (int16_t)(*temp++ >> 12);
-            out[0] = mulAdd(l, vl, out[0]);
-            out[1] = mulAdd(r, vr, out[1]);
-            out += 2;
-        } while (--frameCount);
-    }
-}
-
-void AudioMixer::Track::track__16BitsStereo(
-        int32_t* out, size_t frameCount, int32_t* temp __unused, int32_t* aux)
-{
-    ALOGVV("track__16BitsStereo\n");
-    const int16_t *in = static_cast<const int16_t *>(mIn);
-
-    if (CC_UNLIKELY(aux != NULL)) {
-        int32_t l;
-        int32_t r;
-        // ramp gain
-        if (CC_UNLIKELY(volumeInc[0]|volumeInc[1]|auxInc)) {
-            int32_t vl = prevVolume[0];
-            int32_t vr = prevVolume[1];
-            int32_t va = prevAuxLevel;
-            const int32_t vlInc = volumeInc[0];
-            const int32_t vrInc = volumeInc[1];
-            const int32_t vaInc = auxInc;
-            // ALOGD("[1] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
-            //        t, vlInc/65536.0f, vl/65536.0f, volume[0],
-            //        (vl + vlInc*frameCount)/65536.0f, frameCount);
-
-            do {
-                l = (int32_t)*in++;
-                r = (int32_t)*in++;
-                *out++ += (vl >> 16) * l;
-                *out++ += (vr >> 16) * r;
-                *aux++ += (va >> 17) * (l + r);
-                vl += vlInc;
-                vr += vrInc;
-                va += vaInc;
-            } while (--frameCount);
-
-            prevVolume[0] = vl;
-            prevVolume[1] = vr;
-            prevAuxLevel = va;
-            adjustVolumeRamp(true);
-        }
-
-        // constant gain
-        else {
-            const uint32_t vrl = volumeRL;
-            const int16_t va = (int16_t)auxLevel;
-            do {
-                uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
-                int16_t a = (int16_t)(((int32_t)in[0] + in[1]) >> 1);
-                in += 2;
-                out[0] = mulAddRL(1, rl, vrl, out[0]);
-                out[1] = mulAddRL(0, rl, vrl, out[1]);
-                out += 2;
-                aux[0] = mulAdd(a, va, aux[0]);
-                aux++;
-            } while (--frameCount);
-        }
-    } else {
-        // ramp gain
-        if (CC_UNLIKELY(volumeInc[0]|volumeInc[1])) {
-            int32_t vl = prevVolume[0];
-            int32_t vr = prevVolume[1];
-            const int32_t vlInc = volumeInc[0];
-            const int32_t vrInc = volumeInc[1];
-
-            // ALOGD("[1] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
-            //        t, vlInc/65536.0f, vl/65536.0f, volume[0],
-            //        (vl + vlInc*frameCount)/65536.0f, frameCount);
-
-            do {
-                *out++ += (vl >> 16) * (int32_t) *in++;
-                *out++ += (vr >> 16) * (int32_t) *in++;
-                vl += vlInc;
-                vr += vrInc;
-            } while (--frameCount);
-
-            prevVolume[0] = vl;
-            prevVolume[1] = vr;
-            adjustVolumeRamp(false);
-        }
-
-        // constant gain
-        else {
-            const uint32_t vrl = volumeRL;
-            do {
-                uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
-                in += 2;
-                out[0] = mulAddRL(1, rl, vrl, out[0]);
-                out[1] = mulAddRL(0, rl, vrl, out[1]);
-                out += 2;
-            } while (--frameCount);
-        }
-    }
-    mIn = in;
-}
-
-void AudioMixer::Track::track__16BitsMono(
-        int32_t* out, size_t frameCount, int32_t* temp __unused, int32_t* aux)
-{
-    ALOGVV("track__16BitsMono\n");
-    const int16_t *in = static_cast<int16_t const *>(mIn);
-
-    if (CC_UNLIKELY(aux != NULL)) {
-        // ramp gain
-        if (CC_UNLIKELY(volumeInc[0]|volumeInc[1]|auxInc)) {
-            int32_t vl = prevVolume[0];
-            int32_t vr = prevVolume[1];
-            int32_t va = prevAuxLevel;
-            const int32_t vlInc = volumeInc[0];
-            const int32_t vrInc = volumeInc[1];
-            const int32_t vaInc = auxInc;
-
-            // ALOGD("[2] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
-            //         t, vlInc/65536.0f, vl/65536.0f, volume[0],
-            //         (vl + vlInc*frameCount)/65536.0f, frameCount);
-
-            do {
-                int32_t l = *in++;
-                *out++ += (vl >> 16) * l;
-                *out++ += (vr >> 16) * l;
-                *aux++ += (va >> 16) * l;
-                vl += vlInc;
-                vr += vrInc;
-                va += vaInc;
-            } while (--frameCount);
-
-            prevVolume[0] = vl;
-            prevVolume[1] = vr;
-            prevAuxLevel = va;
-            adjustVolumeRamp(true);
-        }
-        // constant gain
-        else {
-            const int16_t vl = volume[0];
-            const int16_t vr = volume[1];
-            const int16_t va = (int16_t)auxLevel;
-            do {
-                int16_t l = *in++;
-                out[0] = mulAdd(l, vl, out[0]);
-                out[1] = mulAdd(l, vr, out[1]);
-                out += 2;
-                aux[0] = mulAdd(l, va, aux[0]);
-                aux++;
-            } while (--frameCount);
-        }
-    } else {
-        // ramp gain
-        if (CC_UNLIKELY(volumeInc[0]|volumeInc[1])) {
-            int32_t vl = prevVolume[0];
-            int32_t vr = prevVolume[1];
-            const int32_t vlInc = volumeInc[0];
-            const int32_t vrInc = volumeInc[1];
-
-            // ALOGD("[2] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
-            //         t, vlInc/65536.0f, vl/65536.0f, volume[0],
-            //         (vl + vlInc*frameCount)/65536.0f, frameCount);
-
-            do {
-                int32_t l = *in++;
-                *out++ += (vl >> 16) * l;
-                *out++ += (vr >> 16) * l;
-                vl += vlInc;
-                vr += vrInc;
-            } while (--frameCount);
-
-            prevVolume[0] = vl;
-            prevVolume[1] = vr;
-            adjustVolumeRamp(false);
-        }
-        // constant gain
-        else {
-            const int16_t vl = volume[0];
-            const int16_t vr = volume[1];
-            do {
-                int16_t l = *in++;
-                out[0] = mulAdd(l, vl, out[0]);
-                out[1] = mulAdd(l, vr, out[1]);
-                out += 2;
-            } while (--frameCount);
-        }
-    }
-    mIn = in;
-}
-
-// no-op case
-void AudioMixer::process__nop()
-{
-    ALOGVV("process__nop\n");
-
-    for (const auto &pair : mGroups) {
-        // process by group of tracks with same output buffer to
-        // avoid multiple memset() on same buffer
-        const auto &group = pair.second;
-
-        const std::shared_ptr<Track> &t = mTracks[group[0]];
-        memset(t->mainBuffer, 0,
-                mFrameCount * audio_bytes_per_frame(
-                        t->mMixerChannelCount + t->mMixerHapticChannelCount, t->mMixerFormat));
-
-        // now consume data
-        for (const int name : group) {
-            const std::shared_ptr<Track> &t = mTracks[name];
-            size_t outFrames = mFrameCount;
-            while (outFrames) {
-                t->buffer.frameCount = outFrames;
-                t->bufferProvider->getNextBuffer(&t->buffer);
-                if (t->buffer.raw == NULL) break;
-                outFrames -= t->buffer.frameCount;
-                t->bufferProvider->releaseBuffer(&t->buffer);
-            }
-        }
-    }
-}
-
-// generic code without resampling
-void AudioMixer::process__genericNoResampling()
-{
-    ALOGVV("process__genericNoResampling\n");
-    int32_t outTemp[BLOCKSIZE * MAX_NUM_CHANNELS] __attribute__((aligned(32)));
-
-    for (const auto &pair : mGroups) {
-        // process by group of tracks with same output main buffer to
-        // avoid multiple memset() on same buffer
-        const auto &group = pair.second;
-
-        // acquire buffer
-        for (const int name : group) {
-            const std::shared_ptr<Track> &t = mTracks[name];
-            t->buffer.frameCount = mFrameCount;
-            t->bufferProvider->getNextBuffer(&t->buffer);
-            t->frameCount = t->buffer.frameCount;
-            t->mIn = t->buffer.raw;
-        }
-
-        int32_t *out = (int *)pair.first;
-        size_t numFrames = 0;
-        do {
-            const size_t frameCount = std::min((size_t)BLOCKSIZE, mFrameCount - numFrames);
-            memset(outTemp, 0, sizeof(outTemp));
-            for (const int name : group) {
-                const std::shared_ptr<Track> &t = mTracks[name];
-                int32_t *aux = NULL;
-                if (CC_UNLIKELY(t->needs & NEEDS_AUX)) {
-                    aux = t->auxBuffer + numFrames;
-                }
-                for (int outFrames = frameCount; outFrames > 0; ) {
-                    // t->in == nullptr can happen if the track was flushed just after having
-                    // been enabled for mixing.
-                    if (t->mIn == nullptr) {
-                        break;
-                    }
-                    size_t inFrames = (t->frameCount > outFrames)?outFrames:t->frameCount;
-                    if (inFrames > 0) {
-                        (t.get()->*t->hook)(
-                                outTemp + (frameCount - outFrames) * t->mMixerChannelCount,
-                                inFrames, mResampleTemp.get() /* naked ptr */, aux);
-                        t->frameCount -= inFrames;
-                        outFrames -= inFrames;
-                        if (CC_UNLIKELY(aux != NULL)) {
-                            aux += inFrames;
-                        }
-                    }
-                    if (t->frameCount == 0 && outFrames) {
-                        t->bufferProvider->releaseBuffer(&t->buffer);
-                        t->buffer.frameCount = (mFrameCount - numFrames) -
-                                (frameCount - outFrames);
-                        t->bufferProvider->getNextBuffer(&t->buffer);
-                        t->mIn = t->buffer.raw;
-                        if (t->mIn == nullptr) {
-                            break;
-                        }
-                        t->frameCount = t->buffer.frameCount;
-                    }
-                }
-            }
-
-            const std::shared_ptr<Track> &t1 = mTracks[group[0]];
-            convertMixerFormat(out, t1->mMixerFormat, outTemp, t1->mMixerInFormat,
-                    frameCount * t1->mMixerChannelCount);
-            // TODO: fix ugly casting due to choice of out pointer type
-            out = reinterpret_cast<int32_t*>((uint8_t*)out
-                    + frameCount * t1->mMixerChannelCount
-                    * audio_bytes_per_sample(t1->mMixerFormat));
-            numFrames += frameCount;
-        } while (numFrames < mFrameCount);
-
-        // release each track's buffer
-        for (const int name : group) {
-            const std::shared_ptr<Track> &t = mTracks[name];
-            t->bufferProvider->releaseBuffer(&t->buffer);
-        }
-    }
-}
-
-// generic code with resampling
-void AudioMixer::process__genericResampling()
-{
-    ALOGVV("process__genericResampling\n");
-    int32_t * const outTemp = mOutputTemp.get(); // naked ptr
-    size_t numFrames = mFrameCount;
-
-    for (const auto &pair : mGroups) {
-        const auto &group = pair.second;
-        const std::shared_ptr<Track> &t1 = mTracks[group[0]];
-
-        // clear temp buffer
-        memset(outTemp, 0, sizeof(*outTemp) * t1->mMixerChannelCount * mFrameCount);
-        for (const int name : group) {
-            const std::shared_ptr<Track> &t = mTracks[name];
-            int32_t *aux = NULL;
-            if (CC_UNLIKELY(t->needs & NEEDS_AUX)) {
-                aux = t->auxBuffer;
-            }
-
-            // this is a little goofy, on the resampling case we don't
-            // acquire/release the buffers because it's done by
-            // the resampler.
-            if (t->needs & NEEDS_RESAMPLE) {
-                (t.get()->*t->hook)(outTemp, numFrames, mResampleTemp.get() /* naked ptr */, aux);
-            } else {
-
-                size_t outFrames = 0;
-
-                while (outFrames < numFrames) {
-                    t->buffer.frameCount = numFrames - outFrames;
-                    t->bufferProvider->getNextBuffer(&t->buffer);
-                    t->mIn = t->buffer.raw;
-                    // t->mIn == nullptr can happen if the track was flushed just after having
-                    // been enabled for mixing.
-                    if (t->mIn == nullptr) break;
-
-                    (t.get()->*t->hook)(
-                            outTemp + outFrames * t->mMixerChannelCount, t->buffer.frameCount,
-                            mResampleTemp.get() /* naked ptr */,
-                            aux != nullptr ? aux + outFrames : nullptr);
-                    outFrames += t->buffer.frameCount;
-
-                    t->bufferProvider->releaseBuffer(&t->buffer);
-                }
-            }
-        }
-        convertMixerFormat(t1->mainBuffer, t1->mMixerFormat,
-                outTemp, t1->mMixerInFormat, numFrames * t1->mMixerChannelCount);
-    }
-}
-
-// one track, 16 bits stereo without resampling is the most common case
-void AudioMixer::process__oneTrack16BitsStereoNoResampling()
-{
-    ALOGVV("process__oneTrack16BitsStereoNoResampling\n");
-    LOG_ALWAYS_FATAL_IF(mEnabled.size() != 0,
-            "%zu != 1 tracks enabled", mEnabled.size());
-    const int name = mEnabled[0];
-    const std::shared_ptr<Track> &t = mTracks[name];
-
-    AudioBufferProvider::Buffer& b(t->buffer);
-
-    int32_t* out = t->mainBuffer;
-    float *fout = reinterpret_cast<float*>(out);
-    size_t numFrames = mFrameCount;
-
-    const int16_t vl = t->volume[0];
-    const int16_t vr = t->volume[1];
-    const uint32_t vrl = t->volumeRL;
-    while (numFrames) {
-        b.frameCount = numFrames;
-        t->bufferProvider->getNextBuffer(&b);
-        const int16_t *in = b.i16;
-
-        // in == NULL can happen if the track was flushed just after having
-        // been enabled for mixing.
-        if (in == NULL || (((uintptr_t)in) & 3)) {
-            if ( AUDIO_FORMAT_PCM_FLOAT == t->mMixerFormat ) {
-                 memset((char*)fout, 0, numFrames
-                         * t->mMixerChannelCount * audio_bytes_per_sample(t->mMixerFormat));
-            } else {
-                 memset((char*)out, 0, numFrames
-                         * t->mMixerChannelCount * audio_bytes_per_sample(t->mMixerFormat));
-            }
-            ALOGE_IF((((uintptr_t)in) & 3),
-                    "process__oneTrack16BitsStereoNoResampling: misaligned buffer"
-                    " %p track %d, channels %d, needs %08x, volume %08x vfl %f vfr %f",
-                    in, name, t->channelCount, t->needs, vrl, t->mVolume[0], t->mVolume[1]);
-            return;
-        }
-        size_t outFrames = b.frameCount;
-
-        switch (t->mMixerFormat) {
-        case AUDIO_FORMAT_PCM_FLOAT:
-            do {
-                uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
-                in += 2;
-                int32_t l = mulRL(1, rl, vrl);
-                int32_t r = mulRL(0, rl, vrl);
-                *fout++ = float_from_q4_27(l);
-                *fout++ = float_from_q4_27(r);
-                // Note: In case of later int16_t sink output,
-                // conversion and clamping is done by memcpy_to_i16_from_float().
-            } while (--outFrames);
-            break;
-        case AUDIO_FORMAT_PCM_16_BIT:
-            if (CC_UNLIKELY(uint32_t(vl) > UNITY_GAIN_INT || uint32_t(vr) > UNITY_GAIN_INT)) {
-                // volume is boosted, so we might need to clamp even though
-                // we process only one track.
-                do {
-                    uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
-                    in += 2;
-                    int32_t l = mulRL(1, rl, vrl) >> 12;
-                    int32_t r = mulRL(0, rl, vrl) >> 12;
-                    // clamping...
-                    l = clamp16(l);
-                    r = clamp16(r);
-                    *out++ = (r<<16) | (l & 0xFFFF);
-                } while (--outFrames);
-            } else {
-                do {
-                    uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
-                    in += 2;
-                    int32_t l = mulRL(1, rl, vrl) >> 12;
-                    int32_t r = mulRL(0, rl, vrl) >> 12;
-                    *out++ = (r<<16) | (l & 0xFFFF);
-                } while (--outFrames);
-            }
-            break;
-        default:
-            LOG_ALWAYS_FATAL("bad mixer format: %d", t->mMixerFormat);
-        }
-        numFrames -= b.frameCount;
-        t->bufferProvider->releaseBuffer(&b);
-    }
-}
-
 /*static*/ pthread_once_t AudioMixer::sOnceControl = PTHREAD_ONCE_INIT;
 
 /*static*/ void AudioMixer::sInitRoutine()
@@ -1656,211 +523,71 @@
     DownmixerBufferProvider::init(); // for the downmixer
 }
 
-/* TODO: consider whether this level of optimization is necessary.
- * Perhaps just stick with a single for loop.
- */
-
-// Needs to derive a compile time constant (constexpr).  Could be targeted to go
-// to a MONOVOL mixtype based on MAX_NUM_VOLUMES, but that's an unnecessary complication.
-#define MIXTYPE_MONOVOL(mixtype) ((mixtype) == MIXTYPE_MULTI ? MIXTYPE_MULTI_MONOVOL : \
-        (mixtype) == MIXTYPE_MULTI_SAVEONLY ? MIXTYPE_MULTI_SAVEONLY_MONOVOL : (mixtype))
-
-/* MIXTYPE     (see AudioMixerOps.h MIXTYPE_* enumeration)
- * TO: int32_t (Q4.27) or float
- * TI: int32_t (Q4.27) or int16_t (Q0.15) or float
- * TA: int32_t (Q4.27) or float
- */
-template <int MIXTYPE,
-        typename TO, typename TI, typename TV, typename TA, typename TAV>
-static void volumeRampMulti(uint32_t channels, TO* out, size_t frameCount,
-        const TI* in, TA* aux, TV *vol, const TV *volinc, TAV *vola, TAV volainc)
+std::shared_ptr<AudioMixerBase::TrackBase> AudioMixer::preCreateTrack()
 {
-    switch (channels) {
-    case 1:
-        volumeRampMulti<MIXTYPE, 1>(out, frameCount, in, aux, vol, volinc, vola, volainc);
-        break;
-    case 2:
-        volumeRampMulti<MIXTYPE, 2>(out, frameCount, in, aux, vol, volinc, vola, volainc);
-        break;
-    case 3:
-        volumeRampMulti<MIXTYPE_MONOVOL(MIXTYPE), 3>(out,
-                frameCount, in, aux, vol, volinc, vola, volainc);
-        break;
-    case 4:
-        volumeRampMulti<MIXTYPE_MONOVOL(MIXTYPE), 4>(out,
-                frameCount, in, aux, vol, volinc, vola, volainc);
-        break;
-    case 5:
-        volumeRampMulti<MIXTYPE_MONOVOL(MIXTYPE), 5>(out,
-                frameCount, in, aux, vol, volinc, vola, volainc);
-        break;
-    case 6:
-        volumeRampMulti<MIXTYPE_MONOVOL(MIXTYPE), 6>(out,
-                frameCount, in, aux, vol, volinc, vola, volainc);
-        break;
-    case 7:
-        volumeRampMulti<MIXTYPE_MONOVOL(MIXTYPE), 7>(out,
-                frameCount, in, aux, vol, volinc, vola, volainc);
-        break;
-    case 8:
-        volumeRampMulti<MIXTYPE_MONOVOL(MIXTYPE), 8>(out,
-                frameCount, in, aux, vol, volinc, vola, volainc);
-        break;
-    }
+    return std::make_shared<Track>();
 }
 
-/* MIXTYPE     (see AudioMixerOps.h MIXTYPE_* enumeration)
- * TO: int32_t (Q4.27) or float
- * TI: int32_t (Q4.27) or int16_t (Q0.15) or float
- * TA: int32_t (Q4.27) or float
- */
-template <int MIXTYPE,
-        typename TO, typename TI, typename TV, typename TA, typename TAV>
-static void volumeMulti(uint32_t channels, TO* out, size_t frameCount,
-        const TI* in, TA* aux, const TV *vol, TAV vola)
+status_t AudioMixer::postCreateTrack(TrackBase *track)
 {
-    switch (channels) {
-    case 1:
-        volumeMulti<MIXTYPE, 1>(out, frameCount, in, aux, vol, vola);
-        break;
-    case 2:
-        volumeMulti<MIXTYPE, 2>(out, frameCount, in, aux, vol, vola);
-        break;
-    case 3:
-        volumeMulti<MIXTYPE_MONOVOL(MIXTYPE), 3>(out, frameCount, in, aux, vol, vola);
-        break;
-    case 4:
-        volumeMulti<MIXTYPE_MONOVOL(MIXTYPE), 4>(out, frameCount, in, aux, vol, vola);
-        break;
-    case 5:
-        volumeMulti<MIXTYPE_MONOVOL(MIXTYPE), 5>(out, frameCount, in, aux, vol, vola);
-        break;
-    case 6:
-        volumeMulti<MIXTYPE_MONOVOL(MIXTYPE), 6>(out, frameCount, in, aux, vol, vola);
-        break;
-    case 7:
-        volumeMulti<MIXTYPE_MONOVOL(MIXTYPE), 7>(out, frameCount, in, aux, vol, vola);
-        break;
-    case 8:
-        volumeMulti<MIXTYPE_MONOVOL(MIXTYPE), 8>(out, frameCount, in, aux, vol, vola);
-        break;
+    Track* t = static_cast<Track*>(track);
+
+    audio_channel_mask_t channelMask = t->channelMask;
+    t->mHapticChannelMask = channelMask & AUDIO_CHANNEL_HAPTIC_ALL;
+    t->mHapticChannelCount = audio_channel_count_from_out_mask(t->mHapticChannelMask);
+    channelMask &= ~AUDIO_CHANNEL_HAPTIC_ALL;
+    t->channelCount = audio_channel_count_from_out_mask(channelMask);
+    ALOGV_IF(audio_channel_mask_get_bits(channelMask) != AUDIO_CHANNEL_OUT_STEREO,
+            "Non-stereo channel mask: %d\n", channelMask);
+    t->channelMask = channelMask;
+    t->mInputBufferProvider = NULL;
+    t->mDownmixRequiresFormat = AUDIO_FORMAT_INVALID; // no format required
+    t->mPlaybackRate = AUDIO_PLAYBACK_RATE_DEFAULT;
+    // haptic
+    t->mHapticPlaybackEnabled = false;
+    t->mHapticIntensity = HAPTIC_SCALE_NONE;
+    t->mMixerHapticChannelMask = AUDIO_CHANNEL_NONE;
+    t->mMixerHapticChannelCount = 0;
+    t->mAdjustInChannelCount = t->channelCount + t->mHapticChannelCount;
+    t->mAdjustOutChannelCount = t->channelCount + t->mMixerHapticChannelCount;
+    t->mAdjustNonDestructiveInChannelCount = t->mAdjustOutChannelCount;
+    t->mAdjustNonDestructiveOutChannelCount = t->channelCount;
+    t->mKeepContractedChannels = false;
+    // Check the downmixing (or upmixing) requirements.
+    status_t status = t->prepareForDownmix();
+    if (status != OK) {
+        ALOGE("AudioMixer::getTrackName invalid channelMask (%#x)", channelMask);
+        return BAD_VALUE;
     }
+    // prepareForDownmix() may change mDownmixRequiresFormat
+    ALOGVV("mMixerFormat:%#x  mMixerInFormat:%#x\n", t->mMixerFormat, t->mMixerInFormat);
+    t->prepareForReformat();
+    t->prepareForAdjustChannelsNonDestructive(mFrameCount);
+    t->prepareForAdjustChannels();
+    return OK;
 }
 
-/* MIXTYPE     (see AudioMixerOps.h MIXTYPE_* enumeration)
- * USEFLOATVOL (set to true if float volume is used)
- * ADJUSTVOL   (set to true if volume ramp parameters needs adjustment afterwards)
- * TO: int32_t (Q4.27) or float
- * TI: int32_t (Q4.27) or int16_t (Q0.15) or float
- * TA: int32_t (Q4.27) or float
- */
-template <int MIXTYPE, bool USEFLOATVOL, bool ADJUSTVOL,
-    typename TO, typename TI, typename TA>
-void AudioMixer::Track::volumeMix(TO *out, size_t outFrames,
-        const TI *in, TA *aux, bool ramp)
+void AudioMixer::preProcess()
 {
-    if (USEFLOATVOL) {
-        if (ramp) {
-            volumeRampMulti<MIXTYPE>(mMixerChannelCount, out, outFrames, in, aux,
-                    mPrevVolume, mVolumeInc,
-#ifdef FLOAT_AUX
-                    &mPrevAuxLevel, mAuxInc
-#else
-                    &prevAuxLevel, auxInc
-#endif
-                );
-            if (ADJUSTVOL) {
-                adjustVolumeRamp(aux != NULL, true);
-            }
-        } else {
-            volumeMulti<MIXTYPE>(mMixerChannelCount, out, outFrames, in, aux,
-                    mVolume,
-#ifdef FLOAT_AUX
-                    mAuxLevel
-#else
-                    auxLevel
-#endif
-            );
-        }
-    } else {
-        if (ramp) {
-            volumeRampMulti<MIXTYPE>(mMixerChannelCount, out, outFrames, in, aux,
-                    prevVolume, volumeInc, &prevAuxLevel, auxInc);
-            if (ADJUSTVOL) {
-                adjustVolumeRamp(aux != NULL);
-            }
-        } else {
-            volumeMulti<MIXTYPE>(mMixerChannelCount, out, outFrames, in, aux,
-                    volume, auxLevel);
+    for (const auto &pair : mTracks) {
+        // Clear contracted buffer before processing if contracted channels are saved
+        const std::shared_ptr<TrackBase> &tb = pair.second;
+        Track *t = static_cast<Track*>(tb.get());
+        if (t->mKeepContractedChannels) {
+            t->clearContractedBuffer();
         }
     }
 }
 
-/* This process hook is called when there is a single track without
- * aux buffer, volume ramp, or resampling.
- * TODO: Update the hook selection: this can properly handle aux and ramp.
- *
- * MIXTYPE     (see AudioMixerOps.h MIXTYPE_* enumeration)
- * TO: int32_t (Q4.27) or float
- * TI: int32_t (Q4.27) or int16_t (Q0.15) or float
- * TA: int32_t (Q4.27)
- */
-template <int MIXTYPE, typename TO, typename TI, typename TA>
-void AudioMixer::process__noResampleOneTrack()
+void AudioMixer::postProcess()
 {
-    ALOGVV("process__noResampleOneTrack\n");
-    LOG_ALWAYS_FATAL_IF(mEnabled.size() != 1,
-            "%zu != 1 tracks enabled", mEnabled.size());
-    const std::shared_ptr<Track> &t = mTracks[mEnabled[0]];
-    const uint32_t channels = t->mMixerChannelCount;
-    TO* out = reinterpret_cast<TO*>(t->mainBuffer);
-    TA* aux = reinterpret_cast<TA*>(t->auxBuffer);
-    const bool ramp = t->needsRamp();
-
-    for (size_t numFrames = mFrameCount; numFrames > 0; ) {
-        AudioBufferProvider::Buffer& b(t->buffer);
-        // get input buffer
-        b.frameCount = numFrames;
-        t->bufferProvider->getNextBuffer(&b);
-        const TI *in = reinterpret_cast<TI*>(b.raw);
-
-        // in == NULL can happen if the track was flushed just after having
-        // been enabled for mixing.
-        if (in == NULL || (((uintptr_t)in) & 3)) {
-            memset(out, 0, numFrames
-                    * channels * audio_bytes_per_sample(t->mMixerFormat));
-            ALOGE_IF((((uintptr_t)in) & 3), "process__noResampleOneTrack: bus error: "
-                    "buffer %p track %p, channels %d, needs %#x",
-                    in, &t, t->channelCount, t->needs);
-            return;
-        }
-
-        const size_t outFrames = b.frameCount;
-        t->volumeMix<MIXTYPE, is_same<TI, float>::value /* USEFLOATVOL */, false /* ADJUSTVOL */> (
-                out, outFrames, in, aux, ramp);
-
-        out += outFrames * channels;
-        if (aux != NULL) {
-            aux += outFrames;
-        }
-        numFrames -= b.frameCount;
-
-        // release buffer
-        t->bufferProvider->releaseBuffer(&b);
-    }
-    if (ramp) {
-        t->adjustVolumeRamp(aux != NULL, is_same<TI, float>::value);
-    }
-}
-
-void AudioMixer::processHapticData()
-{
+    // Process haptic data.
     // Need to keep consistent with VibrationEffect.scale(int, float, int)
     for (const auto &pair : mGroups) {
         // process by group of tracks with same output main buffer.
         const auto &group = pair.second;
         for (const int name : group) {
-            const std::shared_ptr<Track> &t = mTracks[name];
+            const std::shared_ptr<Track> &t = getTrack(name);
             if (t->mHapticPlaybackEnabled) {
                 size_t sampleCount = mFrameCount * t->mMixerHapticChannelCount;
                 float gamma = t->getHapticScaleGamma();
@@ -1887,225 +614,5 @@
     }
 }
 
-/* This track hook is called to do resampling then mixing,
- * pulling from the track's upstream AudioBufferProvider.
- *
- * MIXTYPE     (see AudioMixerOps.h MIXTYPE_* enumeration)
- * TO: int32_t (Q4.27) or float
- * TI: int32_t (Q4.27) or int16_t (Q0.15) or float
- * TA: int32_t (Q4.27) or float
- */
-template <int MIXTYPE, typename TO, typename TI, typename TA>
-void AudioMixer::Track::track__Resample(TO* out, size_t outFrameCount, TO* temp, TA* aux)
-{
-    ALOGVV("track__Resample\n");
-    mResampler->setSampleRate(sampleRate);
-    const bool ramp = needsRamp();
-    if (ramp || aux != NULL) {
-        // if ramp:        resample with unity gain to temp buffer and scale/mix in 2nd step.
-        // if aux != NULL: resample with unity gain to temp buffer then apply send level.
-
-        mResampler->setVolume(UNITY_GAIN_FLOAT, UNITY_GAIN_FLOAT);
-        memset(temp, 0, outFrameCount * mMixerChannelCount * sizeof(TO));
-        mResampler->resample((int32_t*)temp, outFrameCount, bufferProvider);
-
-        volumeMix<MIXTYPE, is_same<TI, float>::value /* USEFLOATVOL */, true /* ADJUSTVOL */>(
-                out, outFrameCount, temp, aux, ramp);
-
-    } else { // constant volume gain
-        mResampler->setVolume(mVolume[0], mVolume[1]);
-        mResampler->resample((int32_t*)out, outFrameCount, bufferProvider);
-    }
-}
-
-/* This track hook is called to mix a track, when no resampling is required.
- * The input buffer should be present in in.
- *
- * MIXTYPE     (see AudioMixerOps.h MIXTYPE_* enumeration)
- * TO: int32_t (Q4.27) or float
- * TI: int32_t (Q4.27) or int16_t (Q0.15) or float
- * TA: int32_t (Q4.27) or float
- */
-template <int MIXTYPE, typename TO, typename TI, typename TA>
-void AudioMixer::Track::track__NoResample(TO* out, size_t frameCount, TO* temp __unused, TA* aux)
-{
-    ALOGVV("track__NoResample\n");
-    const TI *in = static_cast<const TI *>(mIn);
-
-    volumeMix<MIXTYPE, is_same<TI, float>::value /* USEFLOATVOL */, true /* ADJUSTVOL */>(
-            out, frameCount, in, aux, needsRamp());
-
-    // MIXTYPE_MONOEXPAND reads a single input channel and expands to NCHAN output channels.
-    // MIXTYPE_MULTI reads NCHAN input channels and places to NCHAN output channels.
-    in += (MIXTYPE == MIXTYPE_MONOEXPAND) ? frameCount : frameCount * mMixerChannelCount;
-    mIn = in;
-}
-
-/* The Mixer engine generates either int32_t (Q4_27) or float data.
- * We use this function to convert the engine buffers
- * to the desired mixer output format, either int16_t (Q.15) or float.
- */
-/* static */
-void AudioMixer::convertMixerFormat(void *out, audio_format_t mixerOutFormat,
-        void *in, audio_format_t mixerInFormat, size_t sampleCount)
-{
-    switch (mixerInFormat) {
-    case AUDIO_FORMAT_PCM_FLOAT:
-        switch (mixerOutFormat) {
-        case AUDIO_FORMAT_PCM_FLOAT:
-            memcpy(out, in, sampleCount * sizeof(float)); // MEMCPY. TODO optimize out
-            break;
-        case AUDIO_FORMAT_PCM_16_BIT:
-            memcpy_to_i16_from_float((int16_t*)out, (float*)in, sampleCount);
-            break;
-        default:
-            LOG_ALWAYS_FATAL("bad mixerOutFormat: %#x", mixerOutFormat);
-            break;
-        }
-        break;
-    case AUDIO_FORMAT_PCM_16_BIT:
-        switch (mixerOutFormat) {
-        case AUDIO_FORMAT_PCM_FLOAT:
-            memcpy_to_float_from_q4_27((float*)out, (const int32_t*)in, sampleCount);
-            break;
-        case AUDIO_FORMAT_PCM_16_BIT:
-            memcpy_to_i16_from_q4_27((int16_t*)out, (const int32_t*)in, sampleCount);
-            break;
-        default:
-            LOG_ALWAYS_FATAL("bad mixerOutFormat: %#x", mixerOutFormat);
-            break;
-        }
-        break;
-    default:
-        LOG_ALWAYS_FATAL("bad mixerInFormat: %#x", mixerInFormat);
-        break;
-    }
-}
-
-/* Returns the proper track hook to use for mixing the track into the output buffer.
- */
-/* static */
-AudioMixer::hook_t AudioMixer::Track::getTrackHook(int trackType, uint32_t channelCount,
-        audio_format_t mixerInFormat, audio_format_t mixerOutFormat __unused)
-{
-    if (!kUseNewMixer && channelCount == FCC_2 && mixerInFormat == AUDIO_FORMAT_PCM_16_BIT) {
-        switch (trackType) {
-        case TRACKTYPE_NOP:
-            return &Track::track__nop;
-        case TRACKTYPE_RESAMPLE:
-            return &Track::track__genericResample;
-        case TRACKTYPE_NORESAMPLEMONO:
-            return &Track::track__16BitsMono;
-        case TRACKTYPE_NORESAMPLE:
-            return &Track::track__16BitsStereo;
-        default:
-            LOG_ALWAYS_FATAL("bad trackType: %d", trackType);
-            break;
-        }
-    }
-    LOG_ALWAYS_FATAL_IF(channelCount > MAX_NUM_CHANNELS);
-    switch (trackType) {
-    case TRACKTYPE_NOP:
-        return &Track::track__nop;
-    case TRACKTYPE_RESAMPLE:
-        switch (mixerInFormat) {
-        case AUDIO_FORMAT_PCM_FLOAT:
-            return (AudioMixer::hook_t) &Track::track__Resample<
-                    MIXTYPE_MULTI, float /*TO*/, float /*TI*/, TYPE_AUX>;
-        case AUDIO_FORMAT_PCM_16_BIT:
-            return (AudioMixer::hook_t) &Track::track__Resample<
-                    MIXTYPE_MULTI, int32_t /*TO*/, int16_t /*TI*/, TYPE_AUX>;
-        default:
-            LOG_ALWAYS_FATAL("bad mixerInFormat: %#x", mixerInFormat);
-            break;
-        }
-        break;
-    case TRACKTYPE_NORESAMPLEMONO:
-        switch (mixerInFormat) {
-        case AUDIO_FORMAT_PCM_FLOAT:
-            return (AudioMixer::hook_t) &Track::track__NoResample<
-                            MIXTYPE_MONOEXPAND, float /*TO*/, float /*TI*/, TYPE_AUX>;
-        case AUDIO_FORMAT_PCM_16_BIT:
-            return (AudioMixer::hook_t) &Track::track__NoResample<
-                            MIXTYPE_MONOEXPAND, int32_t /*TO*/, int16_t /*TI*/, TYPE_AUX>;
-        default:
-            LOG_ALWAYS_FATAL("bad mixerInFormat: %#x", mixerInFormat);
-            break;
-        }
-        break;
-    case TRACKTYPE_NORESAMPLE:
-        switch (mixerInFormat) {
-        case AUDIO_FORMAT_PCM_FLOAT:
-            return (AudioMixer::hook_t) &Track::track__NoResample<
-                    MIXTYPE_MULTI, float /*TO*/, float /*TI*/, TYPE_AUX>;
-        case AUDIO_FORMAT_PCM_16_BIT:
-            return (AudioMixer::hook_t) &Track::track__NoResample<
-                    MIXTYPE_MULTI, int32_t /*TO*/, int16_t /*TI*/, TYPE_AUX>;
-        default:
-            LOG_ALWAYS_FATAL("bad mixerInFormat: %#x", mixerInFormat);
-            break;
-        }
-        break;
-    default:
-        LOG_ALWAYS_FATAL("bad trackType: %d", trackType);
-        break;
-    }
-    return NULL;
-}
-
-/* Returns the proper process hook for mixing tracks. Currently works only for
- * PROCESSTYPE_NORESAMPLEONETRACK, a mix involving one track, no resampling.
- *
- * TODO: Due to the special mixing considerations of duplicating to
- * a stereo output track, the input track cannot be MONO.  This should be
- * prevented by the caller.
- */
-/* static */
-AudioMixer::process_hook_t AudioMixer::getProcessHook(
-        int processType, uint32_t channelCount,
-        audio_format_t mixerInFormat, audio_format_t mixerOutFormat)
-{
-    if (processType != PROCESSTYPE_NORESAMPLEONETRACK) { // Only NORESAMPLEONETRACK
-        LOG_ALWAYS_FATAL("bad processType: %d", processType);
-        return NULL;
-    }
-    if (!kUseNewMixer && channelCount == FCC_2 && mixerInFormat == AUDIO_FORMAT_PCM_16_BIT) {
-        return &AudioMixer::process__oneTrack16BitsStereoNoResampling;
-    }
-    LOG_ALWAYS_FATAL_IF(channelCount > MAX_NUM_CHANNELS);
-    switch (mixerInFormat) {
-    case AUDIO_FORMAT_PCM_FLOAT:
-        switch (mixerOutFormat) {
-        case AUDIO_FORMAT_PCM_FLOAT:
-            return &AudioMixer::process__noResampleOneTrack<
-                    MIXTYPE_MULTI_SAVEONLY, float /*TO*/, float /*TI*/, TYPE_AUX>;
-        case AUDIO_FORMAT_PCM_16_BIT:
-            return &AudioMixer::process__noResampleOneTrack<
-                    MIXTYPE_MULTI_SAVEONLY, int16_t /*TO*/, float /*TI*/, TYPE_AUX>;
-        default:
-            LOG_ALWAYS_FATAL("bad mixerOutFormat: %#x", mixerOutFormat);
-            break;
-        }
-        break;
-    case AUDIO_FORMAT_PCM_16_BIT:
-        switch (mixerOutFormat) {
-        case AUDIO_FORMAT_PCM_FLOAT:
-            return &AudioMixer::process__noResampleOneTrack<
-                    MIXTYPE_MULTI_SAVEONLY, float /*TO*/, int16_t /*TI*/, TYPE_AUX>;
-        case AUDIO_FORMAT_PCM_16_BIT:
-            return &AudioMixer::process__noResampleOneTrack<
-                    MIXTYPE_MULTI_SAVEONLY, int16_t /*TO*/, int16_t /*TI*/, TYPE_AUX>;
-        default:
-            LOG_ALWAYS_FATAL("bad mixerOutFormat: %#x", mixerOutFormat);
-            break;
-        }
-        break;
-    default:
-        LOG_ALWAYS_FATAL("bad mixerInFormat: %#x", mixerInFormat);
-        break;
-    }
-    return NULL;
-}
-
 // ----------------------------------------------------------------------------
 } // namespace android
diff --git a/media/libaudioprocessing/AudioMixerBase.cpp b/media/libaudioprocessing/AudioMixerBase.cpp
new file mode 100644
index 0000000..75c077d
--- /dev/null
+++ b/media/libaudioprocessing/AudioMixerBase.cpp
@@ -0,0 +1,1692 @@
+/*
+**
+** Copyright 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_TAG "AudioMixer"
+//#define LOG_NDEBUG 0
+
+#include <sstream>
+#include <string.h>
+
+#include <audio_utils/primitives.h>
+#include <cutils/compiler.h>
+#include <media/AudioMixerBase.h>
+#include <utils/Log.h>
+
+#include "AudioMixerOps.h"
+
+// The FCC_2 macro refers to the Fixed Channel Count of 2 for the legacy integer mixer.
+#ifndef FCC_2
+#define FCC_2 2
+#endif
+
+// Look for MONO_HACK for any Mono hack involving legacy mono channel to
+// stereo channel conversion.
+
+/* VERY_VERY_VERBOSE_LOGGING will show exactly which process hook and track hook is
+ * being used. This is a considerable amount of log spam, so don't enable unless you
+ * are verifying the hook based code.
+ */
+//#define VERY_VERY_VERBOSE_LOGGING
+#ifdef VERY_VERY_VERBOSE_LOGGING
+#define ALOGVV ALOGV
+//define ALOGVV printf  // for test-mixer.cpp
+#else
+#define ALOGVV(a...) do { } while (0)
+#endif
+
+// TODO: remove BLOCKSIZE unit of processing - it isn't needed anymore.
+static constexpr int BLOCKSIZE = 16;
+
+namespace android {
+
+// ----------------------------------------------------------------------------
+
+bool AudioMixerBase::isValidFormat(audio_format_t format) const
+{
+    switch (format) {
+    case AUDIO_FORMAT_PCM_8_BIT:
+    case AUDIO_FORMAT_PCM_16_BIT:
+    case AUDIO_FORMAT_PCM_24_BIT_PACKED:
+    case AUDIO_FORMAT_PCM_32_BIT:
+    case AUDIO_FORMAT_PCM_FLOAT:
+        return true;
+    default:
+        return false;
+    }
+}
+
+bool AudioMixerBase::isValidChannelMask(audio_channel_mask_t channelMask) const
+{
+    return audio_channel_count_from_out_mask(channelMask) <= MAX_NUM_CHANNELS;
+}
+
+std::shared_ptr<AudioMixerBase::TrackBase> AudioMixerBase::preCreateTrack()
+{
+    return std::make_shared<TrackBase>();
+}
+
+status_t AudioMixerBase::create(
+        int name, audio_channel_mask_t channelMask, audio_format_t format, int sessionId)
+{
+    LOG_ALWAYS_FATAL_IF(exists(name), "name %d already exists", name);
+
+    if (!isValidChannelMask(channelMask)) {
+        ALOGE("%s invalid channelMask: %#x", __func__, channelMask);
+        return BAD_VALUE;
+    }
+    if (!isValidFormat(format)) {
+        ALOGE("%s invalid format: %#x", __func__, format);
+        return BAD_VALUE;
+    }
+
+    auto t = preCreateTrack();
+    {
+        // TODO: move initialization to the Track constructor.
+        // assume default parameters for the track, except where noted below
+        t->needs = 0;
+
+        // Integer volume.
+        // Currently integer volume is kept for the legacy integer mixer.
+        // Will be removed when the legacy mixer path is removed.
+        t->volume[0] = 0;
+        t->volume[1] = 0;
+        t->prevVolume[0] = 0 << 16;
+        t->prevVolume[1] = 0 << 16;
+        t->volumeInc[0] = 0;
+        t->volumeInc[1] = 0;
+        t->auxLevel = 0;
+        t->auxInc = 0;
+        t->prevAuxLevel = 0;
+
+        // Floating point volume.
+        t->mVolume[0] = 0.f;
+        t->mVolume[1] = 0.f;
+        t->mPrevVolume[0] = 0.f;
+        t->mPrevVolume[1] = 0.f;
+        t->mVolumeInc[0] = 0.;
+        t->mVolumeInc[1] = 0.;
+        t->mAuxLevel = 0.;
+        t->mAuxInc = 0.;
+        t->mPrevAuxLevel = 0.;
+
+        // no initialization needed
+        // t->frameCount
+        t->channelCount = audio_channel_count_from_out_mask(channelMask);
+        t->enabled = false;
+        ALOGV_IF(audio_channel_mask_get_bits(channelMask) != AUDIO_CHANNEL_OUT_STEREO,
+                "Non-stereo channel mask: %d\n", channelMask);
+        t->channelMask = channelMask;
+        t->sessionId = sessionId;
+        // setBufferProvider(name, AudioBufferProvider *) is required before enable(name)
+        t->bufferProvider = NULL;
+        t->buffer.raw = NULL;
+        // no initialization needed
+        // t->buffer.frameCount
+        t->hook = NULL;
+        t->mIn = NULL;
+        t->sampleRate = mSampleRate;
+        // setParameter(name, TRACK, MAIN_BUFFER, mixBuffer) is required before enable(name)
+        t->mainBuffer = NULL;
+        t->auxBuffer = NULL;
+        t->mMixerFormat = AUDIO_FORMAT_PCM_16_BIT;
+        t->mFormat = format;
+        t->mMixerInFormat = kUseFloat && kUseNewMixer ?
+                AUDIO_FORMAT_PCM_FLOAT : AUDIO_FORMAT_PCM_16_BIT;
+        t->mMixerChannelMask = audio_channel_mask_from_representation_and_bits(
+                AUDIO_CHANNEL_REPRESENTATION_POSITION, AUDIO_CHANNEL_OUT_STEREO);
+        t->mMixerChannelCount = audio_channel_count_from_out_mask(t->mMixerChannelMask);
+        status_t status = postCreateTrack(t.get());
+        if (status != OK) return status;
+        mTracks[name] = t;
+        return OK;
+    }
+}
+
+// Called when channel masks have changed for a track name
+bool AudioMixerBase::setChannelMasks(int name,
+        audio_channel_mask_t trackChannelMask, audio_channel_mask_t mixerChannelMask)
+{
+    LOG_ALWAYS_FATAL_IF(!exists(name), "invalid name: %d", name);
+    const std::shared_ptr<TrackBase> &track = mTracks[name];
+
+    if (trackChannelMask == track->channelMask && mixerChannelMask == track->mMixerChannelMask) {
+        return false;  // no need to change
+    }
+    // always recompute for both channel masks even if only one has changed.
+    const uint32_t trackChannelCount = audio_channel_count_from_out_mask(trackChannelMask);
+    const uint32_t mixerChannelCount = audio_channel_count_from_out_mask(mixerChannelMask);
+
+    ALOG_ASSERT(trackChannelCount && mixerChannelCount);
+    track->channelMask = trackChannelMask;
+    track->channelCount = trackChannelCount;
+    track->mMixerChannelMask = mixerChannelMask;
+    track->mMixerChannelCount = mixerChannelCount;
+
+    // Resampler channels may have changed.
+    track->recreateResampler(mSampleRate);
+    return true;
+}
+
+void AudioMixerBase::destroy(int name)
+{
+    LOG_ALWAYS_FATAL_IF(!exists(name), "invalid name: %d", name);
+    ALOGV("deleteTrackName(%d)", name);
+
+    if (mTracks[name]->enabled) {
+        invalidate();
+    }
+    mTracks.erase(name); // deallocate track
+}
+
+void AudioMixerBase::enable(int name)
+{
+    LOG_ALWAYS_FATAL_IF(!exists(name), "invalid name: %d", name);
+    const std::shared_ptr<TrackBase> &track = mTracks[name];
+
+    if (!track->enabled) {
+        track->enabled = true;
+        ALOGV("enable(%d)", name);
+        invalidate();
+    }
+}
+
+void AudioMixerBase::disable(int name)
+{
+    LOG_ALWAYS_FATAL_IF(!exists(name), "invalid name: %d", name);
+    const std::shared_ptr<TrackBase> &track = mTracks[name];
+
+    if (track->enabled) {
+        track->enabled = false;
+        ALOGV("disable(%d)", name);
+        invalidate();
+    }
+}
+
+/* Sets the volume ramp variables for the AudioMixer.
+ *
+ * The volume ramp variables are used to transition from the previous
+ * volume to the set volume.  ramp controls the duration of the transition.
+ * Its value is typically one state framecount period, but may also be 0,
+ * meaning "immediate."
+ *
+ * FIXME: 1) Volume ramp is enabled only if there is a nonzero integer increment
+ * even if there is a nonzero floating point increment (in that case, the volume
+ * change is immediate).  This restriction should be changed when the legacy mixer
+ * is removed (see #2).
+ * FIXME: 2) Integer volume variables are used for Legacy mixing and should be removed
+ * when no longer needed.
+ *
+ * @param newVolume set volume target in floating point [0.0, 1.0].
+ * @param ramp number of frames to increment over. if ramp is 0, the volume
+ * should be set immediately.  Currently ramp should not exceed 65535 (frames).
+ * @param pIntSetVolume pointer to the U4.12 integer target volume, set on return.
+ * @param pIntPrevVolume pointer to the U4.28 integer previous volume, set on return.
+ * @param pIntVolumeInc pointer to the U4.28 increment per output audio frame, set on return.
+ * @param pSetVolume pointer to the float target volume, set on return.
+ * @param pPrevVolume pointer to the float previous volume, set on return.
+ * @param pVolumeInc pointer to the float increment per output audio frame, set on return.
+ * @return true if the volume has changed, false if volume is same.
+ */
+static inline bool setVolumeRampVariables(float newVolume, int32_t ramp,
+        int16_t *pIntSetVolume, int32_t *pIntPrevVolume, int32_t *pIntVolumeInc,
+        float *pSetVolume, float *pPrevVolume, float *pVolumeInc) {
+    // check floating point volume to see if it is identical to the previously
+    // set volume.
+    // We do not use a tolerance here (and reject changes too small)
+    // as it may be confusing to use a different value than the one set.
+    // If the resulting volume is too small to ramp, it is a direct set of the volume.
+    if (newVolume == *pSetVolume) {
+        return false;
+    }
+    if (newVolume < 0) {
+        newVolume = 0; // should not have negative volumes
+    } else {
+        switch (fpclassify(newVolume)) {
+        case FP_SUBNORMAL:
+        case FP_NAN:
+            newVolume = 0;
+            break;
+        case FP_ZERO:
+            break; // zero volume is fine
+        case FP_INFINITE:
+            // Infinite volume could be handled consistently since
+            // floating point math saturates at infinities,
+            // but we limit volume to unity gain float.
+            // ramp = 0; break;
+            //
+            newVolume = AudioMixerBase::UNITY_GAIN_FLOAT;
+            break;
+        case FP_NORMAL:
+        default:
+            // Floating point does not have problems with overflow wrap
+            // that integer has.  However, we limit the volume to
+            // unity gain here.
+            // TODO: Revisit the volume limitation and perhaps parameterize.
+            if (newVolume > AudioMixerBase::UNITY_GAIN_FLOAT) {
+                newVolume = AudioMixerBase::UNITY_GAIN_FLOAT;
+            }
+            break;
+        }
+    }
+
+    // set floating point volume ramp
+    if (ramp != 0) {
+        // when the ramp completes, *pPrevVolume is set to *pSetVolume, so there
+        // is no computational mismatch; hence equality is checked here.
+        ALOGD_IF(*pPrevVolume != *pSetVolume, "previous float ramp hasn't finished,"
+                " prev:%f  set_to:%f", *pPrevVolume, *pSetVolume);
+        const float inc = (newVolume - *pPrevVolume) / ramp; // could be inf, nan, subnormal
+        // could be inf, cannot be nan, subnormal
+        const float maxv = std::max(newVolume, *pPrevVolume);
+
+        if (isnormal(inc) // inc must be a normal number (no subnormals, infinite, nan)
+                && maxv + inc != maxv) { // inc must make forward progress
+            *pVolumeInc = inc;
+            // ramp is set now.
+            // Note: if newVolume is 0, then near the end of the ramp,
+            // it may be possible that the ramped volume may be subnormal or
+            // temporarily negative by a small amount or subnormal due to floating
+            // point inaccuracies.
+        } else {
+            ramp = 0; // ramp not allowed
+        }
+    }
+
+    // compute and check integer volume, no need to check negative values
+    // The integer volume is limited to "unity_gain" to avoid wrapping and other
+    // audio artifacts, so it never reaches the range limit of U4.28.
+    // We safely use signed 16 and 32 bit integers here.
+    const float scaledVolume = newVolume * AudioMixerBase::UNITY_GAIN_INT; // not neg, subnormal, nan
+    const int32_t intVolume = (scaledVolume >= (float)AudioMixerBase::UNITY_GAIN_INT) ?
+            AudioMixerBase::UNITY_GAIN_INT : (int32_t)scaledVolume;
+
+    // set integer volume ramp
+    if (ramp != 0) {
+        // integer volume is U4.12 (to use 16 bit multiplies), but ramping uses U4.28.
+        // when the ramp completes, *pIntPrevVolume is set to *pIntSetVolume << 16, so there
+        // is no computational mismatch; hence equality is checked here.
+        ALOGD_IF(*pIntPrevVolume != *pIntSetVolume << 16, "previous int ramp hasn't finished,"
+                " prev:%d  set_to:%d", *pIntPrevVolume, *pIntSetVolume << 16);
+        const int32_t inc = ((intVolume << 16) - *pIntPrevVolume) / ramp;
+
+        if (inc != 0) { // inc must make forward progress
+            *pIntVolumeInc = inc;
+        } else {
+            ramp = 0; // ramp not allowed
+        }
+    }
+
+    // if no ramp, or ramp not allowed, then clear float and integer increments
+    if (ramp == 0) {
+        *pVolumeInc = 0;
+        *pPrevVolume = newVolume;
+        *pIntVolumeInc = 0;
+        *pIntPrevVolume = intVolume << 16;
+    }
+    *pSetVolume = newVolume;
+    *pIntSetVolume = intVolume;
+    return true;
+}
+
+void AudioMixerBase::setParameter(int name, int target, int param, void *value)
+{
+    LOG_ALWAYS_FATAL_IF(!exists(name), "invalid name: %d", name);
+    const std::shared_ptr<TrackBase> &track = mTracks[name];
+
+    int valueInt = static_cast<int>(reinterpret_cast<uintptr_t>(value));
+    int32_t *valueBuf = reinterpret_cast<int32_t*>(value);
+
+    switch (target) {
+
+    case TRACK:
+        switch (param) {
+        case CHANNEL_MASK: {
+            const audio_channel_mask_t trackChannelMask =
+                static_cast<audio_channel_mask_t>(valueInt);
+            if (setChannelMasks(name, trackChannelMask, track->mMixerChannelMask)) {
+                ALOGV("setParameter(TRACK, CHANNEL_MASK, %x)", trackChannelMask);
+                invalidate();
+            }
+            } break;
+        case MAIN_BUFFER:
+            if (track->mainBuffer != valueBuf) {
+                track->mainBuffer = valueBuf;
+                ALOGV("setParameter(TRACK, MAIN_BUFFER, %p)", valueBuf);
+                invalidate();
+            }
+            break;
+        case AUX_BUFFER:
+            if (track->auxBuffer != valueBuf) {
+                track->auxBuffer = valueBuf;
+                ALOGV("setParameter(TRACK, AUX_BUFFER, %p)", valueBuf);
+                invalidate();
+            }
+            break;
+        case FORMAT: {
+            audio_format_t format = static_cast<audio_format_t>(valueInt);
+            if (track->mFormat != format) {
+                ALOG_ASSERT(audio_is_linear_pcm(format), "Invalid format %#x", format);
+                track->mFormat = format;
+                ALOGV("setParameter(TRACK, FORMAT, %#x)", format);
+                invalidate();
+            }
+            } break;
+        case MIXER_FORMAT: {
+            audio_format_t format = static_cast<audio_format_t>(valueInt);
+            if (track->mMixerFormat != format) {
+                track->mMixerFormat = format;
+                ALOGV("setParameter(TRACK, MIXER_FORMAT, %#x)", format);
+            }
+            } break;
+        case MIXER_CHANNEL_MASK: {
+            const audio_channel_mask_t mixerChannelMask =
+                    static_cast<audio_channel_mask_t>(valueInt);
+            if (setChannelMasks(name, track->channelMask, mixerChannelMask)) {
+                ALOGV("setParameter(TRACK, MIXER_CHANNEL_MASK, %#x)", mixerChannelMask);
+                invalidate();
+            }
+            } break;
+        default:
+            LOG_ALWAYS_FATAL("setParameter track: bad param %d", param);
+        }
+        break;
+
+    case RESAMPLE:
+        switch (param) {
+        case SAMPLE_RATE:
+            ALOG_ASSERT(valueInt > 0, "bad sample rate %d", valueInt);
+            if (track->setResampler(uint32_t(valueInt), mSampleRate)) {
+                ALOGV("setParameter(RESAMPLE, SAMPLE_RATE, %u)",
+                        uint32_t(valueInt));
+                invalidate();
+            }
+            break;
+        case RESET:
+            track->resetResampler();
+            invalidate();
+            break;
+        case REMOVE:
+            track->mResampler.reset(nullptr);
+            track->sampleRate = mSampleRate;
+            invalidate();
+            break;
+        default:
+            LOG_ALWAYS_FATAL("setParameter resample: bad param %d", param);
+        }
+        break;
+
+    case RAMP_VOLUME:
+    case VOLUME:
+        switch (param) {
+        case AUXLEVEL:
+            if (setVolumeRampVariables(*reinterpret_cast<float*>(value),
+                    target == RAMP_VOLUME ? mFrameCount : 0,
+                    &track->auxLevel, &track->prevAuxLevel, &track->auxInc,
+                    &track->mAuxLevel, &track->mPrevAuxLevel, &track->mAuxInc)) {
+                ALOGV("setParameter(%s, AUXLEVEL: %04x)",
+                        target == VOLUME ? "VOLUME" : "RAMP_VOLUME", track->auxLevel);
+                invalidate();
+            }
+            break;
+        default:
+            if ((unsigned)param >= VOLUME0 && (unsigned)param < VOLUME0 + MAX_NUM_VOLUMES) {
+                if (setVolumeRampVariables(*reinterpret_cast<float*>(value),
+                        target == RAMP_VOLUME ? mFrameCount : 0,
+                        &track->volume[param - VOLUME0],
+                        &track->prevVolume[param - VOLUME0],
+                        &track->volumeInc[param - VOLUME0],
+                        &track->mVolume[param - VOLUME0],
+                        &track->mPrevVolume[param - VOLUME0],
+                        &track->mVolumeInc[param - VOLUME0])) {
+                    ALOGV("setParameter(%s, VOLUME%d: %04x)",
+                            target == VOLUME ? "VOLUME" : "RAMP_VOLUME", param - VOLUME0,
+                                    track->volume[param - VOLUME0]);
+                    invalidate();
+                }
+            } else {
+                LOG_ALWAYS_FATAL("setParameter volume: bad param %d", param);
+            }
+        }
+        break;
+
+    default:
+        LOG_ALWAYS_FATAL("setParameter: bad target %d", target);
+    }
+}
+
+bool AudioMixerBase::TrackBase::setResampler(uint32_t trackSampleRate, uint32_t devSampleRate)
+{
+    if (trackSampleRate != devSampleRate || mResampler.get() != nullptr) {
+        if (sampleRate != trackSampleRate) {
+            sampleRate = trackSampleRate;
+            if (mResampler.get() == nullptr) {
+                ALOGV("Creating resampler from track %d Hz to device %d Hz",
+                        trackSampleRate, devSampleRate);
+                AudioResampler::src_quality quality;
+                // force lowest quality level resampler if use case isn't music or video
+                // FIXME this is flawed for dynamic sample rates, as we choose the resampler
+                // quality level based on the initial ratio, but that could change later.
+                // Should have a way to distinguish tracks with static ratios vs. dynamic ratios.
+                if (isMusicRate(trackSampleRate)) {
+                    quality = AudioResampler::DEFAULT_QUALITY;
+                } else {
+                    quality = AudioResampler::DYN_LOW_QUALITY;
+                }
+
+                // TODO: Remove MONO_HACK. Resampler sees #channels after the downmixer
+                // but if none exists, it is the channel count (1 for mono).
+                const int resamplerChannelCount = getOutputChannelCount();
+                ALOGVV("Creating resampler:"
+                        " format(%#x) channels(%d) devSampleRate(%u) quality(%d)\n",
+                        mMixerInFormat, resamplerChannelCount, devSampleRate, quality);
+                mResampler.reset(AudioResampler::create(
+                        mMixerInFormat,
+                        resamplerChannelCount,
+                        devSampleRate, quality));
+            }
+            return true;
+        }
+    }
+    return false;
+}
+
+/* Checks to see if the volume ramp has completed and clears the increment
+ * variables appropriately.
+ *
+ * FIXME: There is code to handle int/float ramp variable switchover should it not
+ * complete within a mixer buffer processing call, but it is preferred to avoid switchover
+ * due to precision issues.  The switchover code is included for legacy code purposes
+ * and can be removed once the integer volume is removed.
+ *
+ * It is not sufficient to clear only the volumeInc integer variable because
+ * if one channel requires ramping, all channels are ramped.
+ *
+ * There is a bit of duplicated code here, but it keeps backward compatibility.
+ */
+void AudioMixerBase::TrackBase::adjustVolumeRamp(bool aux, bool useFloat)
+{
+    if (useFloat) {
+        for (uint32_t i = 0; i < MAX_NUM_VOLUMES; i++) {
+            if ((mVolumeInc[i] > 0 && mPrevVolume[i] + mVolumeInc[i] >= mVolume[i]) ||
+                     (mVolumeInc[i] < 0 && mPrevVolume[i] + mVolumeInc[i] <= mVolume[i])) {
+                volumeInc[i] = 0;
+                prevVolume[i] = volume[i] << 16;
+                mVolumeInc[i] = 0.;
+                mPrevVolume[i] = mVolume[i];
+            } else {
+                //ALOGV("ramp: %f %f %f", mVolume[i], mPrevVolume[i], mVolumeInc[i]);
+                prevVolume[i] = u4_28_from_float(mPrevVolume[i]);
+            }
+        }
+    } else {
+        for (uint32_t i = 0; i < MAX_NUM_VOLUMES; i++) {
+            if (((volumeInc[i]>0) && (((prevVolume[i]+volumeInc[i])>>16) >= volume[i])) ||
+                    ((volumeInc[i]<0) && (((prevVolume[i]+volumeInc[i])>>16) <= volume[i]))) {
+                volumeInc[i] = 0;
+                prevVolume[i] = volume[i] << 16;
+                mVolumeInc[i] = 0.;
+                mPrevVolume[i] = mVolume[i];
+            } else {
+                //ALOGV("ramp: %d %d %d", volume[i] << 16, prevVolume[i], volumeInc[i]);
+                mPrevVolume[i]  = float_from_u4_28(prevVolume[i]);
+            }
+        }
+    }
+
+    if (aux) {
+#ifdef FLOAT_AUX
+        if (useFloat) {
+            if ((mAuxInc > 0.f && mPrevAuxLevel + mAuxInc >= mAuxLevel) ||
+                    (mAuxInc < 0.f && mPrevAuxLevel + mAuxInc <= mAuxLevel)) {
+                auxInc = 0;
+                prevAuxLevel = auxLevel << 16;
+                mAuxInc = 0.f;
+                mPrevAuxLevel = mAuxLevel;
+            }
+        } else
+#endif
+        if ((auxInc > 0 && ((prevAuxLevel + auxInc) >> 16) >= auxLevel) ||
+                (auxInc < 0 && ((prevAuxLevel + auxInc) >> 16) <= auxLevel)) {
+            auxInc = 0;
+            prevAuxLevel = auxLevel << 16;
+            mAuxInc = 0.f;
+            mPrevAuxLevel = mAuxLevel;
+        }
+    }
+}
+
+void AudioMixerBase::TrackBase::recreateResampler(uint32_t devSampleRate)
+{
+    if (mResampler.get() != nullptr) {
+        const uint32_t resetToSampleRate = sampleRate;
+        mResampler.reset(nullptr);
+        sampleRate = devSampleRate; // without resampler, track rate is device sample rate.
+        // recreate the resampler with updated format, channels, saved sampleRate.
+        setResampler(resetToSampleRate /*trackSampleRate*/, devSampleRate);
+    }
+}
+
+size_t AudioMixerBase::getUnreleasedFrames(int name) const
+{
+    const auto it = mTracks.find(name);
+    if (it != mTracks.end()) {
+        return it->second->getUnreleasedFrames();
+    }
+    return 0;
+}
+
+std::string AudioMixerBase::trackNames() const
+{
+    std::stringstream ss;
+    for (const auto &pair : mTracks) {
+        ss << pair.first << " ";
+    }
+    return ss.str();
+}
+
+void AudioMixerBase::process__validate()
+{
+    // TODO: fix all16BitsStereNoResample logic to
+    // either properly handle muted tracks (it should ignore them)
+    // or remove altogether as an obsolete optimization.
+    bool all16BitsStereoNoResample = true;
+    bool resampling = false;
+    bool volumeRamp = false;
+
+    mEnabled.clear();
+    mGroups.clear();
+    for (const auto &pair : mTracks) {
+        const int name = pair.first;
+        const std::shared_ptr<TrackBase> &t = pair.second;
+        if (!t->enabled) continue;
+
+        mEnabled.emplace_back(name);  // we add to mEnabled in order of name.
+        mGroups[t->mainBuffer].emplace_back(name); // mGroups also in order of name.
+
+        uint32_t n = 0;
+        // FIXME can overflow (mask is only 3 bits)
+        n |= NEEDS_CHANNEL_1 + t->channelCount - 1;
+        if (t->doesResample()) {
+            n |= NEEDS_RESAMPLE;
+        }
+        if (t->auxLevel != 0 && t->auxBuffer != NULL) {
+            n |= NEEDS_AUX;
+        }
+
+        if (t->volumeInc[0]|t->volumeInc[1]) {
+            volumeRamp = true;
+        } else if (!t->doesResample() && t->volumeRL == 0) {
+            n |= NEEDS_MUTE;
+        }
+        t->needs = n;
+
+        if (n & NEEDS_MUTE) {
+            t->hook = &TrackBase::track__nop;
+        } else {
+            if (n & NEEDS_AUX) {
+                all16BitsStereoNoResample = false;
+            }
+            if (n & NEEDS_RESAMPLE) {
+                all16BitsStereoNoResample = false;
+                resampling = true;
+                t->hook = TrackBase::getTrackHook(TRACKTYPE_RESAMPLE, t->mMixerChannelCount,
+                        t->mMixerInFormat, t->mMixerFormat);
+                ALOGV_IF((n & NEEDS_CHANNEL_COUNT__MASK) > NEEDS_CHANNEL_2,
+                        "Track %d needs downmix + resample", name);
+            } else {
+                if ((n & NEEDS_CHANNEL_COUNT__MASK) == NEEDS_CHANNEL_1){
+                    t->hook = TrackBase::getTrackHook(
+                            (t->mMixerChannelMask == AUDIO_CHANNEL_OUT_STEREO  // TODO: MONO_HACK
+                                    && t->channelMask == AUDIO_CHANNEL_OUT_MONO)
+                                ? TRACKTYPE_NORESAMPLEMONO : TRACKTYPE_NORESAMPLE,
+                            t->mMixerChannelCount,
+                            t->mMixerInFormat, t->mMixerFormat);
+                    all16BitsStereoNoResample = false;
+                }
+                if ((n & NEEDS_CHANNEL_COUNT__MASK) >= NEEDS_CHANNEL_2){
+                    t->hook = TrackBase::getTrackHook(TRACKTYPE_NORESAMPLE, t->mMixerChannelCount,
+                            t->mMixerInFormat, t->mMixerFormat);
+                    ALOGV_IF((n & NEEDS_CHANNEL_COUNT__MASK) > NEEDS_CHANNEL_2,
+                            "Track %d needs downmix", name);
+                }
+            }
+        }
+    }
+
+    // select the processing hooks
+    mHook = &AudioMixerBase::process__nop;
+    if (mEnabled.size() > 0) {
+        if (resampling) {
+            if (mOutputTemp.get() == nullptr) {
+                mOutputTemp.reset(new int32_t[MAX_NUM_CHANNELS * mFrameCount]);
+            }
+            if (mResampleTemp.get() == nullptr) {
+                mResampleTemp.reset(new int32_t[MAX_NUM_CHANNELS * mFrameCount]);
+            }
+            mHook = &AudioMixerBase::process__genericResampling;
+        } else {
+            // we keep temp arrays around.
+            mHook = &AudioMixerBase::process__genericNoResampling;
+            if (all16BitsStereoNoResample && !volumeRamp) {
+                if (mEnabled.size() == 1) {
+                    const std::shared_ptr<TrackBase> &t = mTracks[mEnabled[0]];
+                    if ((t->needs & NEEDS_MUTE) == 0) {
+                        // The check prevents a muted track from acquiring a process hook.
+                        //
+                        // This is dangerous if the track is MONO as that requires
+                        // special case handling due to implicit channel duplication.
+                        // Stereo or Multichannel should actually be fine here.
+                        mHook = getProcessHook(PROCESSTYPE_NORESAMPLEONETRACK,
+                                t->mMixerChannelCount, t->mMixerInFormat, t->mMixerFormat);
+                    }
+                }
+            }
+        }
+    }
+
+    ALOGV("mixer configuration change: %zu "
+        "all16BitsStereoNoResample=%d, resampling=%d, volumeRamp=%d",
+        mEnabled.size(), all16BitsStereoNoResample, resampling, volumeRamp);
+
+    process();
+
+    // Now that the volume ramp has been done, set optimal state and
+    // track hooks for subsequent mixer process
+    if (mEnabled.size() > 0) {
+        bool allMuted = true;
+
+        for (const int name : mEnabled) {
+            const std::shared_ptr<TrackBase> &t = mTracks[name];
+            if (!t->doesResample() && t->volumeRL == 0) {
+                t->needs |= NEEDS_MUTE;
+                t->hook = &TrackBase::track__nop;
+            } else {
+                allMuted = false;
+            }
+        }
+        if (allMuted) {
+            mHook = &AudioMixerBase::process__nop;
+        } else if (all16BitsStereoNoResample) {
+            if (mEnabled.size() == 1) {
+                //const int i = 31 - __builtin_clz(enabledTracks);
+                const std::shared_ptr<TrackBase> &t = mTracks[mEnabled[0]];
+                // Muted single tracks handled by allMuted above.
+                mHook = getProcessHook(PROCESSTYPE_NORESAMPLEONETRACK,
+                        t->mMixerChannelCount, t->mMixerInFormat, t->mMixerFormat);
+            }
+        }
+    }
+}
+
+void AudioMixerBase::TrackBase::track__genericResample(
+        int32_t* out, size_t outFrameCount, int32_t* temp, int32_t* aux)
+{
+    ALOGVV("track__genericResample\n");
+    mResampler->setSampleRate(sampleRate);
+
+    // ramp gain - resample to temp buffer and scale/mix in 2nd step
+    if (aux != NULL) {
+        // always resample with unity gain when sending to auxiliary buffer to be able
+        // to apply send level after resampling
+        mResampler->setVolume(UNITY_GAIN_FLOAT, UNITY_GAIN_FLOAT);
+        memset(temp, 0, outFrameCount * mMixerChannelCount * sizeof(int32_t));
+        mResampler->resample(temp, outFrameCount, bufferProvider);
+        if (CC_UNLIKELY(volumeInc[0]|volumeInc[1]|auxInc)) {
+            volumeRampStereo(out, outFrameCount, temp, aux);
+        } else {
+            volumeStereo(out, outFrameCount, temp, aux);
+        }
+    } else {
+        if (CC_UNLIKELY(volumeInc[0]|volumeInc[1])) {
+            mResampler->setVolume(UNITY_GAIN_FLOAT, UNITY_GAIN_FLOAT);
+            memset(temp, 0, outFrameCount * MAX_NUM_CHANNELS * sizeof(int32_t));
+            mResampler->resample(temp, outFrameCount, bufferProvider);
+            volumeRampStereo(out, outFrameCount, temp, aux);
+        }
+
+        // constant gain
+        else {
+            mResampler->setVolume(mVolume[0], mVolume[1]);
+            mResampler->resample(out, outFrameCount, bufferProvider);
+        }
+    }
+}
+
+void AudioMixerBase::TrackBase::track__nop(int32_t* out __unused,
+        size_t outFrameCount __unused, int32_t* temp __unused, int32_t* aux __unused)
+{
+}
+
+void AudioMixerBase::TrackBase::volumeRampStereo(
+        int32_t* out, size_t frameCount, int32_t* temp, int32_t* aux)
+{
+    int32_t vl = prevVolume[0];
+    int32_t vr = prevVolume[1];
+    const int32_t vlInc = volumeInc[0];
+    const int32_t vrInc = volumeInc[1];
+
+    //ALOGD("[0] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
+    //        t, vlInc/65536.0f, vl/65536.0f, volume[0],
+    //       (vl + vlInc*frameCount)/65536.0f, frameCount);
+
+    // ramp volume
+    if (CC_UNLIKELY(aux != NULL)) {
+        int32_t va = prevAuxLevel;
+        const int32_t vaInc = auxInc;
+        int32_t l;
+        int32_t r;
+
+        do {
+            l = (*temp++ >> 12);
+            r = (*temp++ >> 12);
+            *out++ += (vl >> 16) * l;
+            *out++ += (vr >> 16) * r;
+            *aux++ += (va >> 17) * (l + r);
+            vl += vlInc;
+            vr += vrInc;
+            va += vaInc;
+        } while (--frameCount);
+        prevAuxLevel = va;
+    } else {
+        do {
+            *out++ += (vl >> 16) * (*temp++ >> 12);
+            *out++ += (vr >> 16) * (*temp++ >> 12);
+            vl += vlInc;
+            vr += vrInc;
+        } while (--frameCount);
+    }
+    prevVolume[0] = vl;
+    prevVolume[1] = vr;
+    adjustVolumeRamp(aux != NULL);
+}
+
+void AudioMixerBase::TrackBase::volumeStereo(
+        int32_t* out, size_t frameCount, int32_t* temp, int32_t* aux)
+{
+    const int16_t vl = volume[0];
+    const int16_t vr = volume[1];
+
+    if (CC_UNLIKELY(aux != NULL)) {
+        const int16_t va = auxLevel;
+        do {
+            int16_t l = (int16_t)(*temp++ >> 12);
+            int16_t r = (int16_t)(*temp++ >> 12);
+            out[0] = mulAdd(l, vl, out[0]);
+            int16_t a = (int16_t)(((int32_t)l + r) >> 1);
+            out[1] = mulAdd(r, vr, out[1]);
+            out += 2;
+            aux[0] = mulAdd(a, va, aux[0]);
+            aux++;
+        } while (--frameCount);
+    } else {
+        do {
+            int16_t l = (int16_t)(*temp++ >> 12);
+            int16_t r = (int16_t)(*temp++ >> 12);
+            out[0] = mulAdd(l, vl, out[0]);
+            out[1] = mulAdd(r, vr, out[1]);
+            out += 2;
+        } while (--frameCount);
+    }
+}
+
+void AudioMixerBase::TrackBase::track__16BitsStereo(
+        int32_t* out, size_t frameCount, int32_t* temp __unused, int32_t* aux)
+{
+    ALOGVV("track__16BitsStereo\n");
+    const int16_t *in = static_cast<const int16_t *>(mIn);
+
+    if (CC_UNLIKELY(aux != NULL)) {
+        int32_t l;
+        int32_t r;
+        // ramp gain
+        if (CC_UNLIKELY(volumeInc[0]|volumeInc[1]|auxInc)) {
+            int32_t vl = prevVolume[0];
+            int32_t vr = prevVolume[1];
+            int32_t va = prevAuxLevel;
+            const int32_t vlInc = volumeInc[0];
+            const int32_t vrInc = volumeInc[1];
+            const int32_t vaInc = auxInc;
+            // ALOGD("[1] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
+            //        t, vlInc/65536.0f, vl/65536.0f, volume[0],
+            //        (vl + vlInc*frameCount)/65536.0f, frameCount);
+
+            do {
+                l = (int32_t)*in++;
+                r = (int32_t)*in++;
+                *out++ += (vl >> 16) * l;
+                *out++ += (vr >> 16) * r;
+                *aux++ += (va >> 17) * (l + r);
+                vl += vlInc;
+                vr += vrInc;
+                va += vaInc;
+            } while (--frameCount);
+
+            prevVolume[0] = vl;
+            prevVolume[1] = vr;
+            prevAuxLevel = va;
+            adjustVolumeRamp(true);
+        }
+
+        // constant gain
+        else {
+            const uint32_t vrl = volumeRL;
+            const int16_t va = (int16_t)auxLevel;
+            do {
+                uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
+                int16_t a = (int16_t)(((int32_t)in[0] + in[1]) >> 1);
+                in += 2;
+                out[0] = mulAddRL(1, rl, vrl, out[0]);
+                out[1] = mulAddRL(0, rl, vrl, out[1]);
+                out += 2;
+                aux[0] = mulAdd(a, va, aux[0]);
+                aux++;
+            } while (--frameCount);
+        }
+    } else {
+        // ramp gain
+        if (CC_UNLIKELY(volumeInc[0]|volumeInc[1])) {
+            int32_t vl = prevVolume[0];
+            int32_t vr = prevVolume[1];
+            const int32_t vlInc = volumeInc[0];
+            const int32_t vrInc = volumeInc[1];
+
+            // ALOGD("[1] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
+            //        t, vlInc/65536.0f, vl/65536.0f, volume[0],
+            //        (vl + vlInc*frameCount)/65536.0f, frameCount);
+
+            do {
+                *out++ += (vl >> 16) * (int32_t) *in++;
+                *out++ += (vr >> 16) * (int32_t) *in++;
+                vl += vlInc;
+                vr += vrInc;
+            } while (--frameCount);
+
+            prevVolume[0] = vl;
+            prevVolume[1] = vr;
+            adjustVolumeRamp(false);
+        }
+
+        // constant gain
+        else {
+            const uint32_t vrl = volumeRL;
+            do {
+                uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
+                in += 2;
+                out[0] = mulAddRL(1, rl, vrl, out[0]);
+                out[1] = mulAddRL(0, rl, vrl, out[1]);
+                out += 2;
+            } while (--frameCount);
+        }
+    }
+    mIn = in;
+}
+
+void AudioMixerBase::TrackBase::track__16BitsMono(
+        int32_t* out, size_t frameCount, int32_t* temp __unused, int32_t* aux)
+{
+    ALOGVV("track__16BitsMono\n");
+    const int16_t *in = static_cast<int16_t const *>(mIn);
+
+    if (CC_UNLIKELY(aux != NULL)) {
+        // ramp gain
+        if (CC_UNLIKELY(volumeInc[0]|volumeInc[1]|auxInc)) {
+            int32_t vl = prevVolume[0];
+            int32_t vr = prevVolume[1];
+            int32_t va = prevAuxLevel;
+            const int32_t vlInc = volumeInc[0];
+            const int32_t vrInc = volumeInc[1];
+            const int32_t vaInc = auxInc;
+
+            // ALOGD("[2] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
+            //         t, vlInc/65536.0f, vl/65536.0f, volume[0],
+            //         (vl + vlInc*frameCount)/65536.0f, frameCount);
+
+            do {
+                int32_t l = *in++;
+                *out++ += (vl >> 16) * l;
+                *out++ += (vr >> 16) * l;
+                *aux++ += (va >> 16) * l;
+                vl += vlInc;
+                vr += vrInc;
+                va += vaInc;
+            } while (--frameCount);
+
+            prevVolume[0] = vl;
+            prevVolume[1] = vr;
+            prevAuxLevel = va;
+            adjustVolumeRamp(true);
+        }
+        // constant gain
+        else {
+            const int16_t vl = volume[0];
+            const int16_t vr = volume[1];
+            const int16_t va = (int16_t)auxLevel;
+            do {
+                int16_t l = *in++;
+                out[0] = mulAdd(l, vl, out[0]);
+                out[1] = mulAdd(l, vr, out[1]);
+                out += 2;
+                aux[0] = mulAdd(l, va, aux[0]);
+                aux++;
+            } while (--frameCount);
+        }
+    } else {
+        // ramp gain
+        if (CC_UNLIKELY(volumeInc[0]|volumeInc[1])) {
+            int32_t vl = prevVolume[0];
+            int32_t vr = prevVolume[1];
+            const int32_t vlInc = volumeInc[0];
+            const int32_t vrInc = volumeInc[1];
+
+            // ALOGD("[2] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
+            //         t, vlInc/65536.0f, vl/65536.0f, volume[0],
+            //         (vl + vlInc*frameCount)/65536.0f, frameCount);
+
+            do {
+                int32_t l = *in++;
+                *out++ += (vl >> 16) * l;
+                *out++ += (vr >> 16) * l;
+                vl += vlInc;
+                vr += vrInc;
+            } while (--frameCount);
+
+            prevVolume[0] = vl;
+            prevVolume[1] = vr;
+            adjustVolumeRamp(false);
+        }
+        // constant gain
+        else {
+            const int16_t vl = volume[0];
+            const int16_t vr = volume[1];
+            do {
+                int16_t l = *in++;
+                out[0] = mulAdd(l, vl, out[0]);
+                out[1] = mulAdd(l, vr, out[1]);
+                out += 2;
+            } while (--frameCount);
+        }
+    }
+    mIn = in;
+}
+
+// no-op case
+void AudioMixerBase::process__nop()
+{
+    ALOGVV("process__nop\n");
+
+    for (const auto &pair : mGroups) {
+        // process by group of tracks with same output buffer to
+        // avoid multiple memset() on same buffer
+        const auto &group = pair.second;
+
+        const std::shared_ptr<TrackBase> &t = mTracks[group[0]];
+        memset(t->mainBuffer, 0,
+                mFrameCount * audio_bytes_per_frame(t->getMixerChannelCount(), t->mMixerFormat));
+
+        // now consume data
+        for (const int name : group) {
+            const std::shared_ptr<TrackBase> &t = mTracks[name];
+            size_t outFrames = mFrameCount;
+            while (outFrames) {
+                t->buffer.frameCount = outFrames;
+                t->bufferProvider->getNextBuffer(&t->buffer);
+                if (t->buffer.raw == NULL) break;
+                outFrames -= t->buffer.frameCount;
+                t->bufferProvider->releaseBuffer(&t->buffer);
+            }
+        }
+    }
+}
+
+// generic code without resampling
+void AudioMixerBase::process__genericNoResampling()
+{
+    ALOGVV("process__genericNoResampling\n");
+    int32_t outTemp[BLOCKSIZE * MAX_NUM_CHANNELS] __attribute__((aligned(32)));
+
+    for (const auto &pair : mGroups) {
+        // process by group of tracks with same output main buffer to
+        // avoid multiple memset() on same buffer
+        const auto &group = pair.second;
+
+        // acquire buffer
+        for (const int name : group) {
+            const std::shared_ptr<TrackBase> &t = mTracks[name];
+            t->buffer.frameCount = mFrameCount;
+            t->bufferProvider->getNextBuffer(&t->buffer);
+            t->frameCount = t->buffer.frameCount;
+            t->mIn = t->buffer.raw;
+        }
+
+        int32_t *out = (int *)pair.first;
+        size_t numFrames = 0;
+        do {
+            const size_t frameCount = std::min((size_t)BLOCKSIZE, mFrameCount - numFrames);
+            memset(outTemp, 0, sizeof(outTemp));
+            for (const int name : group) {
+                const std::shared_ptr<TrackBase> &t = mTracks[name];
+                int32_t *aux = NULL;
+                if (CC_UNLIKELY(t->needs & NEEDS_AUX)) {
+                    aux = t->auxBuffer + numFrames;
+                }
+                for (int outFrames = frameCount; outFrames > 0; ) {
+                    // t->in == nullptr can happen if the track was flushed just after having
+                    // been enabled for mixing.
+                    if (t->mIn == nullptr) {
+                        break;
+                    }
+                    size_t inFrames = (t->frameCount > outFrames)?outFrames:t->frameCount;
+                    if (inFrames > 0) {
+                        (t.get()->*t->hook)(
+                                outTemp + (frameCount - outFrames) * t->mMixerChannelCount,
+                                inFrames, mResampleTemp.get() /* naked ptr */, aux);
+                        t->frameCount -= inFrames;
+                        outFrames -= inFrames;
+                        if (CC_UNLIKELY(aux != NULL)) {
+                            aux += inFrames;
+                        }
+                    }
+                    if (t->frameCount == 0 && outFrames) {
+                        t->bufferProvider->releaseBuffer(&t->buffer);
+                        t->buffer.frameCount = (mFrameCount - numFrames) -
+                                (frameCount - outFrames);
+                        t->bufferProvider->getNextBuffer(&t->buffer);
+                        t->mIn = t->buffer.raw;
+                        if (t->mIn == nullptr) {
+                            break;
+                        }
+                        t->frameCount = t->buffer.frameCount;
+                    }
+                }
+            }
+
+            const std::shared_ptr<TrackBase> &t1 = mTracks[group[0]];
+            convertMixerFormat(out, t1->mMixerFormat, outTemp, t1->mMixerInFormat,
+                    frameCount * t1->mMixerChannelCount);
+            // TODO: fix ugly casting due to choice of out pointer type
+            out = reinterpret_cast<int32_t*>((uint8_t*)out
+                    + frameCount * t1->mMixerChannelCount
+                    * audio_bytes_per_sample(t1->mMixerFormat));
+            numFrames += frameCount;
+        } while (numFrames < mFrameCount);
+
+        // release each track's buffer
+        for (const int name : group) {
+            const std::shared_ptr<TrackBase> &t = mTracks[name];
+            t->bufferProvider->releaseBuffer(&t->buffer);
+        }
+    }
+}
+
+// generic code with resampling
+void AudioMixerBase::process__genericResampling()
+{
+    ALOGVV("process__genericResampling\n");
+    int32_t * const outTemp = mOutputTemp.get(); // naked ptr
+    size_t numFrames = mFrameCount;
+
+    for (const auto &pair : mGroups) {
+        const auto &group = pair.second;
+        const std::shared_ptr<TrackBase> &t1 = mTracks[group[0]];
+
+        // clear temp buffer
+        memset(outTemp, 0, sizeof(*outTemp) * t1->mMixerChannelCount * mFrameCount);
+        for (const int name : group) {
+            const std::shared_ptr<TrackBase> &t = mTracks[name];
+            int32_t *aux = NULL;
+            if (CC_UNLIKELY(t->needs & NEEDS_AUX)) {
+                aux = t->auxBuffer;
+            }
+
+            // this is a little goofy, on the resampling case we don't
+            // acquire/release the buffers because it's done by
+            // the resampler.
+            if (t->needs & NEEDS_RESAMPLE) {
+                (t.get()->*t->hook)(outTemp, numFrames, mResampleTemp.get() /* naked ptr */, aux);
+            } else {
+
+                size_t outFrames = 0;
+
+                while (outFrames < numFrames) {
+                    t->buffer.frameCount = numFrames - outFrames;
+                    t->bufferProvider->getNextBuffer(&t->buffer);
+                    t->mIn = t->buffer.raw;
+                    // t->mIn == nullptr can happen if the track was flushed just after having
+                    // been enabled for mixing.
+                    if (t->mIn == nullptr) break;
+
+                    (t.get()->*t->hook)(
+                            outTemp + outFrames * t->mMixerChannelCount, t->buffer.frameCount,
+                            mResampleTemp.get() /* naked ptr */,
+                            aux != nullptr ? aux + outFrames : nullptr);
+                    outFrames += t->buffer.frameCount;
+
+                    t->bufferProvider->releaseBuffer(&t->buffer);
+                }
+            }
+        }
+        convertMixerFormat(t1->mainBuffer, t1->mMixerFormat,
+                outTemp, t1->mMixerInFormat, numFrames * t1->mMixerChannelCount);
+    }
+}
+
+// one track, 16 bits stereo without resampling is the most common case
+void AudioMixerBase::process__oneTrack16BitsStereoNoResampling()
+{
+    ALOGVV("process__oneTrack16BitsStereoNoResampling\n");
+    LOG_ALWAYS_FATAL_IF(mEnabled.size() != 0,
+            "%zu != 1 tracks enabled", mEnabled.size());
+    const int name = mEnabled[0];
+    const std::shared_ptr<TrackBase> &t = mTracks[name];
+
+    AudioBufferProvider::Buffer& b(t->buffer);
+
+    int32_t* out = t->mainBuffer;
+    float *fout = reinterpret_cast<float*>(out);
+    size_t numFrames = mFrameCount;
+
+    const int16_t vl = t->volume[0];
+    const int16_t vr = t->volume[1];
+    const uint32_t vrl = t->volumeRL;
+    while (numFrames) {
+        b.frameCount = numFrames;
+        t->bufferProvider->getNextBuffer(&b);
+        const int16_t *in = b.i16;
+
+        // in == NULL can happen if the track was flushed just after having
+        // been enabled for mixing.
+        if (in == NULL || (((uintptr_t)in) & 3)) {
+            if ( AUDIO_FORMAT_PCM_FLOAT == t->mMixerFormat ) {
+                 memset((char*)fout, 0, numFrames
+                         * t->mMixerChannelCount * audio_bytes_per_sample(t->mMixerFormat));
+            } else {
+                 memset((char*)out, 0, numFrames
+                         * t->mMixerChannelCount * audio_bytes_per_sample(t->mMixerFormat));
+            }
+            ALOGE_IF((((uintptr_t)in) & 3),
+                    "process__oneTrack16BitsStereoNoResampling: misaligned buffer"
+                    " %p track %d, channels %d, needs %08x, volume %08x vfl %f vfr %f",
+                    in, name, t->channelCount, t->needs, vrl, t->mVolume[0], t->mVolume[1]);
+            return;
+        }
+        size_t outFrames = b.frameCount;
+
+        switch (t->mMixerFormat) {
+        case AUDIO_FORMAT_PCM_FLOAT:
+            do {
+                uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
+                in += 2;
+                int32_t l = mulRL(1, rl, vrl);
+                int32_t r = mulRL(0, rl, vrl);
+                *fout++ = float_from_q4_27(l);
+                *fout++ = float_from_q4_27(r);
+                // Note: In case of later int16_t sink output,
+                // conversion and clamping is done by memcpy_to_i16_from_float().
+            } while (--outFrames);
+            break;
+        case AUDIO_FORMAT_PCM_16_BIT:
+            if (CC_UNLIKELY(uint32_t(vl) > UNITY_GAIN_INT || uint32_t(vr) > UNITY_GAIN_INT)) {
+                // volume is boosted, so we might need to clamp even though
+                // we process only one track.
+                do {
+                    uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
+                    in += 2;
+                    int32_t l = mulRL(1, rl, vrl) >> 12;
+                    int32_t r = mulRL(0, rl, vrl) >> 12;
+                    // clamping...
+                    l = clamp16(l);
+                    r = clamp16(r);
+                    *out++ = (r<<16) | (l & 0xFFFF);
+                } while (--outFrames);
+            } else {
+                do {
+                    uint32_t rl = *reinterpret_cast<const uint32_t *>(in);
+                    in += 2;
+                    int32_t l = mulRL(1, rl, vrl) >> 12;
+                    int32_t r = mulRL(0, rl, vrl) >> 12;
+                    *out++ = (r<<16) | (l & 0xFFFF);
+                } while (--outFrames);
+            }
+            break;
+        default:
+            LOG_ALWAYS_FATAL("bad mixer format: %d", t->mMixerFormat);
+        }
+        numFrames -= b.frameCount;
+        t->bufferProvider->releaseBuffer(&b);
+    }
+}
+
+/* TODO: consider whether this level of optimization is necessary.
+ * Perhaps just stick with a single for loop.
+ */
+
+// Needs to derive a compile time constant (constexpr).  Could be targeted to go
+// to a MONOVOL mixtype based on MAX_NUM_VOLUMES, but that's an unnecessary complication.
+#define MIXTYPE_MONOVOL(mixtype) ((mixtype) == MIXTYPE_MULTI ? MIXTYPE_MULTI_MONOVOL : \
+        (mixtype) == MIXTYPE_MULTI_SAVEONLY ? MIXTYPE_MULTI_SAVEONLY_MONOVOL : (mixtype))
+
+/* MIXTYPE     (see AudioMixerOps.h MIXTYPE_* enumeration)
+ * TO: int32_t (Q4.27) or float
+ * TI: int32_t (Q4.27) or int16_t (Q0.15) or float
+ * TA: int32_t (Q4.27) or float
+ */
+template <int MIXTYPE,
+        typename TO, typename TI, typename TV, typename TA, typename TAV>
+static void volumeRampMulti(uint32_t channels, TO* out, size_t frameCount,
+        const TI* in, TA* aux, TV *vol, const TV *volinc, TAV *vola, TAV volainc)
+{
+    switch (channels) {
+    case 1:
+        volumeRampMulti<MIXTYPE, 1>(out, frameCount, in, aux, vol, volinc, vola, volainc);
+        break;
+    case 2:
+        volumeRampMulti<MIXTYPE, 2>(out, frameCount, in, aux, vol, volinc, vola, volainc);
+        break;
+    case 3:
+        volumeRampMulti<MIXTYPE_MONOVOL(MIXTYPE), 3>(out,
+                frameCount, in, aux, vol, volinc, vola, volainc);
+        break;
+    case 4:
+        volumeRampMulti<MIXTYPE_MONOVOL(MIXTYPE), 4>(out,
+                frameCount, in, aux, vol, volinc, vola, volainc);
+        break;
+    case 5:
+        volumeRampMulti<MIXTYPE_MONOVOL(MIXTYPE), 5>(out,
+                frameCount, in, aux, vol, volinc, vola, volainc);
+        break;
+    case 6:
+        volumeRampMulti<MIXTYPE_MONOVOL(MIXTYPE), 6>(out,
+                frameCount, in, aux, vol, volinc, vola, volainc);
+        break;
+    case 7:
+        volumeRampMulti<MIXTYPE_MONOVOL(MIXTYPE), 7>(out,
+                frameCount, in, aux, vol, volinc, vola, volainc);
+        break;
+    case 8:
+        volumeRampMulti<MIXTYPE_MONOVOL(MIXTYPE), 8>(out,
+                frameCount, in, aux, vol, volinc, vola, volainc);
+        break;
+    }
+}
+
+/* MIXTYPE     (see AudioMixerOps.h MIXTYPE_* enumeration)
+ * TO: int32_t (Q4.27) or float
+ * TI: int32_t (Q4.27) or int16_t (Q0.15) or float
+ * TA: int32_t (Q4.27) or float
+ */
+template <int MIXTYPE,
+        typename TO, typename TI, typename TV, typename TA, typename TAV>
+static void volumeMulti(uint32_t channels, TO* out, size_t frameCount,
+        const TI* in, TA* aux, const TV *vol, TAV vola)
+{
+    switch (channels) {
+    case 1:
+        volumeMulti<MIXTYPE, 1>(out, frameCount, in, aux, vol, vola);
+        break;
+    case 2:
+        volumeMulti<MIXTYPE, 2>(out, frameCount, in, aux, vol, vola);
+        break;
+    case 3:
+        volumeMulti<MIXTYPE_MONOVOL(MIXTYPE), 3>(out, frameCount, in, aux, vol, vola);
+        break;
+    case 4:
+        volumeMulti<MIXTYPE_MONOVOL(MIXTYPE), 4>(out, frameCount, in, aux, vol, vola);
+        break;
+    case 5:
+        volumeMulti<MIXTYPE_MONOVOL(MIXTYPE), 5>(out, frameCount, in, aux, vol, vola);
+        break;
+    case 6:
+        volumeMulti<MIXTYPE_MONOVOL(MIXTYPE), 6>(out, frameCount, in, aux, vol, vola);
+        break;
+    case 7:
+        volumeMulti<MIXTYPE_MONOVOL(MIXTYPE), 7>(out, frameCount, in, aux, vol, vola);
+        break;
+    case 8:
+        volumeMulti<MIXTYPE_MONOVOL(MIXTYPE), 8>(out, frameCount, in, aux, vol, vola);
+        break;
+    }
+}
+
+/* MIXTYPE     (see AudioMixerOps.h MIXTYPE_* enumeration)
+ * USEFLOATVOL (set to true if float volume is used)
+ * ADJUSTVOL   (set to true if volume ramp parameters needs adjustment afterwards)
+ * TO: int32_t (Q4.27) or float
+ * TI: int32_t (Q4.27) or int16_t (Q0.15) or float
+ * TA: int32_t (Q4.27) or float
+ */
+template <int MIXTYPE, bool USEFLOATVOL, bool ADJUSTVOL,
+    typename TO, typename TI, typename TA>
+void AudioMixerBase::TrackBase::volumeMix(TO *out, size_t outFrames,
+        const TI *in, TA *aux, bool ramp)
+{
+    if (USEFLOATVOL) {
+        if (ramp) {
+            volumeRampMulti<MIXTYPE>(mMixerChannelCount, out, outFrames, in, aux,
+                    mPrevVolume, mVolumeInc,
+#ifdef FLOAT_AUX
+                    &mPrevAuxLevel, mAuxInc
+#else
+                    &prevAuxLevel, auxInc
+#endif
+                );
+            if (ADJUSTVOL) {
+                adjustVolumeRamp(aux != NULL, true);
+            }
+        } else {
+            volumeMulti<MIXTYPE>(mMixerChannelCount, out, outFrames, in, aux,
+                    mVolume,
+#ifdef FLOAT_AUX
+                    mAuxLevel
+#else
+                    auxLevel
+#endif
+            );
+        }
+    } else {
+        if (ramp) {
+            volumeRampMulti<MIXTYPE>(mMixerChannelCount, out, outFrames, in, aux,
+                    prevVolume, volumeInc, &prevAuxLevel, auxInc);
+            if (ADJUSTVOL) {
+                adjustVolumeRamp(aux != NULL);
+            }
+        } else {
+            volumeMulti<MIXTYPE>(mMixerChannelCount, out, outFrames, in, aux,
+                    volume, auxLevel);
+        }
+    }
+}
+
+/* This process hook is called when there is a single track without
+ * aux buffer, volume ramp, or resampling.
+ * TODO: Update the hook selection: this can properly handle aux and ramp.
+ *
+ * MIXTYPE     (see AudioMixerOps.h MIXTYPE_* enumeration)
+ * TO: int32_t (Q4.27) or float
+ * TI: int32_t (Q4.27) or int16_t (Q0.15) or float
+ * TA: int32_t (Q4.27)
+ */
+template <int MIXTYPE, typename TO, typename TI, typename TA>
+void AudioMixerBase::process__noResampleOneTrack()
+{
+    ALOGVV("process__noResampleOneTrack\n");
+    LOG_ALWAYS_FATAL_IF(mEnabled.size() != 1,
+            "%zu != 1 tracks enabled", mEnabled.size());
+    const std::shared_ptr<TrackBase> &t = mTracks[mEnabled[0]];
+    const uint32_t channels = t->mMixerChannelCount;
+    TO* out = reinterpret_cast<TO*>(t->mainBuffer);
+    TA* aux = reinterpret_cast<TA*>(t->auxBuffer);
+    const bool ramp = t->needsRamp();
+
+    for (size_t numFrames = mFrameCount; numFrames > 0; ) {
+        AudioBufferProvider::Buffer& b(t->buffer);
+        // get input buffer
+        b.frameCount = numFrames;
+        t->bufferProvider->getNextBuffer(&b);
+        const TI *in = reinterpret_cast<TI*>(b.raw);
+
+        // in == NULL can happen if the track was flushed just after having
+        // been enabled for mixing.
+        if (in == NULL || (((uintptr_t)in) & 3)) {
+            memset(out, 0, numFrames
+                    * channels * audio_bytes_per_sample(t->mMixerFormat));
+            ALOGE_IF((((uintptr_t)in) & 3), "process__noResampleOneTrack: bus error: "
+                    "buffer %p track %p, channels %d, needs %#x",
+                    in, &t, t->channelCount, t->needs);
+            return;
+        }
+
+        const size_t outFrames = b.frameCount;
+        t->volumeMix<MIXTYPE, is_same<TI, float>::value /* USEFLOATVOL */, false /* ADJUSTVOL */> (
+                out, outFrames, in, aux, ramp);
+
+        out += outFrames * channels;
+        if (aux != NULL) {
+            aux += outFrames;
+        }
+        numFrames -= b.frameCount;
+
+        // release buffer
+        t->bufferProvider->releaseBuffer(&b);
+    }
+    if (ramp) {
+        t->adjustVolumeRamp(aux != NULL, is_same<TI, float>::value);
+    }
+}
+
+/* This track hook is called to do resampling then mixing,
+ * pulling from the track's upstream AudioBufferProvider.
+ *
+ * MIXTYPE     (see AudioMixerOps.h MIXTYPE_* enumeration)
+ * TO: int32_t (Q4.27) or float
+ * TI: int32_t (Q4.27) or int16_t (Q0.15) or float
+ * TA: int32_t (Q4.27) or float
+ */
+template <int MIXTYPE, typename TO, typename TI, typename TA>
+void AudioMixerBase::TrackBase::track__Resample(TO* out, size_t outFrameCount, TO* temp, TA* aux)
+{
+    ALOGVV("track__Resample\n");
+    mResampler->setSampleRate(sampleRate);
+    const bool ramp = needsRamp();
+    if (ramp || aux != NULL) {
+        // if ramp:        resample with unity gain to temp buffer and scale/mix in 2nd step.
+        // if aux != NULL: resample with unity gain to temp buffer then apply send level.
+
+        mResampler->setVolume(UNITY_GAIN_FLOAT, UNITY_GAIN_FLOAT);
+        memset(temp, 0, outFrameCount * mMixerChannelCount * sizeof(TO));
+        mResampler->resample((int32_t*)temp, outFrameCount, bufferProvider);
+
+        volumeMix<MIXTYPE, is_same<TI, float>::value /* USEFLOATVOL */, true /* ADJUSTVOL */>(
+                out, outFrameCount, temp, aux, ramp);
+
+    } else { // constant volume gain
+        mResampler->setVolume(mVolume[0], mVolume[1]);
+        mResampler->resample((int32_t*)out, outFrameCount, bufferProvider);
+    }
+}
+
+/* This track hook is called to mix a track, when no resampling is required.
+ * The input buffer should be present in in.
+ *
+ * MIXTYPE     (see AudioMixerOps.h MIXTYPE_* enumeration)
+ * TO: int32_t (Q4.27) or float
+ * TI: int32_t (Q4.27) or int16_t (Q0.15) or float
+ * TA: int32_t (Q4.27) or float
+ */
+template <int MIXTYPE, typename TO, typename TI, typename TA>
+void AudioMixerBase::TrackBase::track__NoResample(
+        TO* out, size_t frameCount, TO* temp __unused, TA* aux)
+{
+    ALOGVV("track__NoResample\n");
+    const TI *in = static_cast<const TI *>(mIn);
+
+    volumeMix<MIXTYPE, is_same<TI, float>::value /* USEFLOATVOL */, true /* ADJUSTVOL */>(
+            out, frameCount, in, aux, needsRamp());
+
+    // MIXTYPE_MONOEXPAND reads a single input channel and expands to NCHAN output channels.
+    // MIXTYPE_MULTI reads NCHAN input channels and places to NCHAN output channels.
+    in += (MIXTYPE == MIXTYPE_MONOEXPAND) ? frameCount : frameCount * mMixerChannelCount;
+    mIn = in;
+}
+
+/* The Mixer engine generates either int32_t (Q4_27) or float data.
+ * We use this function to convert the engine buffers
+ * to the desired mixer output format, either int16_t (Q.15) or float.
+ */
+/* static */
+void AudioMixerBase::convertMixerFormat(void *out, audio_format_t mixerOutFormat,
+        void *in, audio_format_t mixerInFormat, size_t sampleCount)
+{
+    switch (mixerInFormat) {
+    case AUDIO_FORMAT_PCM_FLOAT:
+        switch (mixerOutFormat) {
+        case AUDIO_FORMAT_PCM_FLOAT:
+            memcpy(out, in, sampleCount * sizeof(float)); // MEMCPY. TODO optimize out
+            break;
+        case AUDIO_FORMAT_PCM_16_BIT:
+            memcpy_to_i16_from_float((int16_t*)out, (float*)in, sampleCount);
+            break;
+        default:
+            LOG_ALWAYS_FATAL("bad mixerOutFormat: %#x", mixerOutFormat);
+            break;
+        }
+        break;
+    case AUDIO_FORMAT_PCM_16_BIT:
+        switch (mixerOutFormat) {
+        case AUDIO_FORMAT_PCM_FLOAT:
+            memcpy_to_float_from_q4_27((float*)out, (const int32_t*)in, sampleCount);
+            break;
+        case AUDIO_FORMAT_PCM_16_BIT:
+            memcpy_to_i16_from_q4_27((int16_t*)out, (const int32_t*)in, sampleCount);
+            break;
+        default:
+            LOG_ALWAYS_FATAL("bad mixerOutFormat: %#x", mixerOutFormat);
+            break;
+        }
+        break;
+    default:
+        LOG_ALWAYS_FATAL("bad mixerInFormat: %#x", mixerInFormat);
+        break;
+    }
+}
+
+/* Returns the proper track hook to use for mixing the track into the output buffer.
+ */
+/* static */
+AudioMixerBase::hook_t AudioMixerBase::TrackBase::getTrackHook(int trackType, uint32_t channelCount,
+        audio_format_t mixerInFormat, audio_format_t mixerOutFormat __unused)
+{
+    if (!kUseNewMixer && channelCount == FCC_2 && mixerInFormat == AUDIO_FORMAT_PCM_16_BIT) {
+        switch (trackType) {
+        case TRACKTYPE_NOP:
+            return &TrackBase::track__nop;
+        case TRACKTYPE_RESAMPLE:
+            return &TrackBase::track__genericResample;
+        case TRACKTYPE_NORESAMPLEMONO:
+            return &TrackBase::track__16BitsMono;
+        case TRACKTYPE_NORESAMPLE:
+            return &TrackBase::track__16BitsStereo;
+        default:
+            LOG_ALWAYS_FATAL("bad trackType: %d", trackType);
+            break;
+        }
+    }
+    LOG_ALWAYS_FATAL_IF(channelCount > MAX_NUM_CHANNELS);
+    switch (trackType) {
+    case TRACKTYPE_NOP:
+        return &TrackBase::track__nop;
+    case TRACKTYPE_RESAMPLE:
+        switch (mixerInFormat) {
+        case AUDIO_FORMAT_PCM_FLOAT:
+            return (AudioMixerBase::hook_t) &TrackBase::track__Resample<
+                    MIXTYPE_MULTI, float /*TO*/, float /*TI*/, TYPE_AUX>;
+        case AUDIO_FORMAT_PCM_16_BIT:
+            return (AudioMixerBase::hook_t) &TrackBase::track__Resample<
+                    MIXTYPE_MULTI, int32_t /*TO*/, int16_t /*TI*/, TYPE_AUX>;
+        default:
+            LOG_ALWAYS_FATAL("bad mixerInFormat: %#x", mixerInFormat);
+            break;
+        }
+        break;
+    case TRACKTYPE_NORESAMPLEMONO:
+        switch (mixerInFormat) {
+        case AUDIO_FORMAT_PCM_FLOAT:
+            return (AudioMixerBase::hook_t) &TrackBase::track__NoResample<
+                            MIXTYPE_MONOEXPAND, float /*TO*/, float /*TI*/, TYPE_AUX>;
+        case AUDIO_FORMAT_PCM_16_BIT:
+            return (AudioMixerBase::hook_t) &TrackBase::track__NoResample<
+                            MIXTYPE_MONOEXPAND, int32_t /*TO*/, int16_t /*TI*/, TYPE_AUX>;
+        default:
+            LOG_ALWAYS_FATAL("bad mixerInFormat: %#x", mixerInFormat);
+            break;
+        }
+        break;
+    case TRACKTYPE_NORESAMPLE:
+        switch (mixerInFormat) {
+        case AUDIO_FORMAT_PCM_FLOAT:
+            return (AudioMixerBase::hook_t) &TrackBase::track__NoResample<
+                    MIXTYPE_MULTI, float /*TO*/, float /*TI*/, TYPE_AUX>;
+        case AUDIO_FORMAT_PCM_16_BIT:
+            return (AudioMixerBase::hook_t) &TrackBase::track__NoResample<
+                    MIXTYPE_MULTI, int32_t /*TO*/, int16_t /*TI*/, TYPE_AUX>;
+        default:
+            LOG_ALWAYS_FATAL("bad mixerInFormat: %#x", mixerInFormat);
+            break;
+        }
+        break;
+    default:
+        LOG_ALWAYS_FATAL("bad trackType: %d", trackType);
+        break;
+    }
+    return NULL;
+}
+
+/* Returns the proper process hook for mixing tracks. Currently works only for
+ * PROCESSTYPE_NORESAMPLEONETRACK, a mix involving one track, no resampling.
+ *
+ * TODO: Due to the special mixing considerations of duplicating to
+ * a stereo output track, the input track cannot be MONO.  This should be
+ * prevented by the caller.
+ */
+/* static */
+AudioMixerBase::process_hook_t AudioMixerBase::getProcessHook(
+        int processType, uint32_t channelCount,
+        audio_format_t mixerInFormat, audio_format_t mixerOutFormat)
+{
+    if (processType != PROCESSTYPE_NORESAMPLEONETRACK) { // Only NORESAMPLEONETRACK
+        LOG_ALWAYS_FATAL("bad processType: %d", processType);
+        return NULL;
+    }
+    if (!kUseNewMixer && channelCount == FCC_2 && mixerInFormat == AUDIO_FORMAT_PCM_16_BIT) {
+        return &AudioMixerBase::process__oneTrack16BitsStereoNoResampling;
+    }
+    LOG_ALWAYS_FATAL_IF(channelCount > MAX_NUM_CHANNELS);
+    switch (mixerInFormat) {
+    case AUDIO_FORMAT_PCM_FLOAT:
+        switch (mixerOutFormat) {
+        case AUDIO_FORMAT_PCM_FLOAT:
+            return &AudioMixerBase::process__noResampleOneTrack<
+                    MIXTYPE_MULTI_SAVEONLY, float /*TO*/, float /*TI*/, TYPE_AUX>;
+        case AUDIO_FORMAT_PCM_16_BIT:
+            return &AudioMixerBase::process__noResampleOneTrack<
+                    MIXTYPE_MULTI_SAVEONLY, int16_t /*TO*/, float /*TI*/, TYPE_AUX>;
+        default:
+            LOG_ALWAYS_FATAL("bad mixerOutFormat: %#x", mixerOutFormat);
+            break;
+        }
+        break;
+    case AUDIO_FORMAT_PCM_16_BIT:
+        switch (mixerOutFormat) {
+        case AUDIO_FORMAT_PCM_FLOAT:
+            return &AudioMixerBase::process__noResampleOneTrack<
+                    MIXTYPE_MULTI_SAVEONLY, float /*TO*/, int16_t /*TI*/, TYPE_AUX>;
+        case AUDIO_FORMAT_PCM_16_BIT:
+            return &AudioMixerBase::process__noResampleOneTrack<
+                    MIXTYPE_MULTI_SAVEONLY, int16_t /*TO*/, int16_t /*TI*/, TYPE_AUX>;
+        default:
+            LOG_ALWAYS_FATAL("bad mixerOutFormat: %#x", mixerOutFormat);
+            break;
+        }
+        break;
+    default:
+        LOG_ALWAYS_FATAL("bad mixerInFormat: %#x", mixerInFormat);
+        break;
+    }
+    return NULL;
+}
+
+// ----------------------------------------------------------------------------
+} // namespace android
diff --git a/media/libaudioprocessing/include/media/AudioMixerBase.h b/media/libaudioprocessing/include/media/AudioMixerBase.h
new file mode 100644
index 0000000..805b6d0
--- /dev/null
+++ b/media/libaudioprocessing/include/media/AudioMixerBase.h
@@ -0,0 +1,359 @@
+/*
+**
+** Copyright 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 ANDROID_AUDIO_MIXER_BASE_H
+#define ANDROID_AUDIO_MIXER_BASE_H
+
+#include <map>
+#include <memory>
+#include <string>
+#include <unordered_map>
+#include <vector>
+
+#include <media/AudioBufferProvider.h>
+#include <media/AudioResampler.h>
+#include <media/AudioResamplerPublic.h>
+#include <system/audio.h>
+#include <utils/Compat.h>
+
+// This must match frameworks/av/services/audioflinger/Configuration.h
+// when used with the Audio Framework.
+#define FLOAT_AUX
+
+namespace android {
+
+// ----------------------------------------------------------------------------
+
+// AudioMixerBase is functional on its own if only mixing and resampling
+// is needed.
+
+class AudioMixerBase
+{
+public:
+    // Do not change these unless underlying code changes.
+    // This mixer has a hard-coded upper limit of 8 channels for output.
+    static constexpr uint32_t MAX_NUM_CHANNELS = FCC_8;
+    static constexpr uint32_t MAX_NUM_VOLUMES = FCC_2; // stereo volume only
+
+    static const uint16_t UNITY_GAIN_INT = 0x1000;
+    static const CONSTEXPR float UNITY_GAIN_FLOAT = 1.0f;
+
+    enum { // names
+        // setParameter targets
+        TRACK           = 0x3000,
+        RESAMPLE        = 0x3001,
+        RAMP_VOLUME     = 0x3002, // ramp to new volume
+        VOLUME          = 0x3003, // don't ramp
+        TIMESTRETCH     = 0x3004,
+
+        // set Parameter names
+        // for target TRACK
+        CHANNEL_MASK    = 0x4000,
+        FORMAT          = 0x4001,
+        MAIN_BUFFER     = 0x4002,
+        AUX_BUFFER      = 0x4003,
+        // 0x4004 reserved
+        MIXER_FORMAT    = 0x4005, // AUDIO_FORMAT_PCM_(FLOAT|16_BIT)
+        MIXER_CHANNEL_MASK = 0x4006, // Channel mask for mixer output
+        // for target RESAMPLE
+        SAMPLE_RATE     = 0x4100, // Configure sample rate conversion on this track name;
+                                  // parameter 'value' is the new sample rate in Hz.
+                                  // Only creates a sample rate converter the first time that
+                                  // the track sample rate is different from the mix sample rate.
+                                  // If the new sample rate is the same as the mix sample rate,
+                                  // and a sample rate converter already exists,
+                                  // then the sample rate converter remains present but is a no-op.
+        RESET           = 0x4101, // Reset sample rate converter without changing sample rate.
+                                  // This clears out the resampler's input buffer.
+        REMOVE          = 0x4102, // Remove the sample rate converter on this track name;
+                                  // the track is restored to the mix sample rate.
+        // for target RAMP_VOLUME and VOLUME (8 channels max)
+        // FIXME use float for these 3 to improve the dynamic range
+        VOLUME0         = 0x4200,
+        VOLUME1         = 0x4201,
+        AUXLEVEL        = 0x4210,
+    };
+
+    AudioMixerBase(size_t frameCount, uint32_t sampleRate)
+        : mSampleRate(sampleRate)
+        , mFrameCount(frameCount) {
+    }
+
+    virtual ~AudioMixerBase() {}
+
+    virtual bool isValidFormat(audio_format_t format) const;
+    virtual bool isValidChannelMask(audio_channel_mask_t channelMask) const;
+
+    // Create a new track in the mixer.
+    //
+    // \param name        a unique user-provided integer associated with the track.
+    //                    If name already exists, the function will abort.
+    // \param channelMask output channel mask.
+    // \param format      PCM format
+    // \param sessionId   Session id for the track. Tracks with the same
+    //                    session id will be submixed together.
+    //
+    // \return OK        on success.
+    //         BAD_VALUE if the format does not satisfy isValidFormat()
+    //                   or the channelMask does not satisfy isValidChannelMask().
+    status_t    create(
+            int name, audio_channel_mask_t channelMask, audio_format_t format, int sessionId);
+
+    bool        exists(int name) const {
+        return mTracks.count(name) > 0;
+    }
+
+    // Free an allocated track by name.
+    void        destroy(int name);
+
+    // Enable or disable an allocated track by name
+    void        enable(int name);
+    void        disable(int name);
+
+    virtual void setParameter(int name, int target, int param, void *value);
+
+    void        process() {
+        preProcess();
+        (this->*mHook)();
+        postProcess();
+    }
+
+    size_t      getUnreleasedFrames(int name) const;
+
+    std::string trackNames() const;
+
+  protected:
+    // Set kUseNewMixer to true to use the new mixer engine always. Otherwise the
+    // original code will be used for stereo sinks, the new mixer for everything else.
+    static constexpr bool kUseNewMixer = true;
+
+    // Set kUseFloat to true to allow floating input into the mixer engine.
+    // If kUseNewMixer is false, this is ignored or may be overridden internally
+    static constexpr bool kUseFloat = true;
+
+#ifdef FLOAT_AUX
+    using TYPE_AUX = float;
+    static_assert(kUseNewMixer && kUseFloat,
+            "kUseNewMixer and kUseFloat must be true for FLOAT_AUX option");
+#else
+    using TYPE_AUX = int32_t; // q4.27
+#endif
+
+    /* For multi-format functions (calls template functions
+     * in AudioMixerOps.h).  The template parameters are as follows:
+     *
+     *   MIXTYPE     (see AudioMixerOps.h MIXTYPE_* enumeration)
+     *   USEFLOATVOL (set to true if float volume is used)
+     *   ADJUSTVOL   (set to true if volume ramp parameters needs adjustment afterwards)
+     *   TO: int32_t (Q4.27) or float
+     *   TI: int32_t (Q4.27) or int16_t (Q0.15) or float
+     *   TA: int32_t (Q4.27)
+     */
+
+    enum {
+        // FIXME this representation permits up to 8 channels
+        NEEDS_CHANNEL_COUNT__MASK   = 0x00000007,
+    };
+
+    enum {
+        NEEDS_CHANNEL_1             = 0x00000000,   // mono
+        NEEDS_CHANNEL_2             = 0x00000001,   // stereo
+
+        // sample format is not explicitly specified, and is assumed to be AUDIO_FORMAT_PCM_16_BIT
+
+        NEEDS_MUTE                  = 0x00000100,
+        NEEDS_RESAMPLE              = 0x00001000,
+        NEEDS_AUX                   = 0x00010000,
+    };
+
+    // hook types
+    enum {
+        PROCESSTYPE_NORESAMPLEONETRACK, // others set elsewhere
+    };
+
+    enum {
+        TRACKTYPE_NOP,
+        TRACKTYPE_RESAMPLE,
+        TRACKTYPE_NORESAMPLE,
+        TRACKTYPE_NORESAMPLEMONO,
+    };
+
+    // process hook functionality
+    using process_hook_t = void(AudioMixerBase::*)();
+
+    struct TrackBase;
+    using hook_t = void(TrackBase::*)(
+            int32_t* output, size_t numOutFrames, int32_t* temp, int32_t* aux);
+
+    struct TrackBase {
+        TrackBase()
+            : bufferProvider(nullptr)
+        {
+            // TODO: move additional initialization here.
+        }
+        virtual ~TrackBase() {}
+
+        virtual uint32_t getOutputChannelCount() { return channelCount; }
+        virtual uint32_t getMixerChannelCount() { return mMixerChannelCount; }
+
+        bool        needsRamp() { return (volumeInc[0] | volumeInc[1] | auxInc) != 0; }
+        bool        setResampler(uint32_t trackSampleRate, uint32_t devSampleRate);
+        bool        doesResample() const { return mResampler.get() != nullptr; }
+        void        recreateResampler(uint32_t devSampleRate);
+        void        resetResampler() { if (mResampler.get() != nullptr) mResampler->reset(); }
+        void        adjustVolumeRamp(bool aux, bool useFloat = false);
+        size_t      getUnreleasedFrames() const { return mResampler.get() != nullptr ?
+                                                    mResampler->getUnreleasedFrames() : 0; };
+
+        static hook_t getTrackHook(int trackType, uint32_t channelCount,
+                audio_format_t mixerInFormat, audio_format_t mixerOutFormat);
+
+        void track__nop(int32_t* out, size_t numFrames, int32_t* temp, int32_t* aux);
+
+        template <int MIXTYPE, bool USEFLOATVOL, bool ADJUSTVOL,
+            typename TO, typename TI, typename TA>
+        void volumeMix(TO *out, size_t outFrames, const TI *in, TA *aux, bool ramp);
+
+        uint32_t    needs;
+
+        // TODO: Eventually remove legacy integer volume settings
+        union {
+        int16_t     volume[MAX_NUM_VOLUMES]; // U4.12 fixed point (top bit should be zero)
+        int32_t     volumeRL;
+        };
+
+        int32_t     prevVolume[MAX_NUM_VOLUMES];
+        int32_t     volumeInc[MAX_NUM_VOLUMES];
+        int32_t     auxInc;
+        int32_t     prevAuxLevel;
+        int16_t     auxLevel;       // 0 <= auxLevel <= MAX_GAIN_INT, but signed for mul performance
+
+        uint16_t    frameCount;
+
+        uint8_t     channelCount;   // 1 or 2, redundant with (needs & NEEDS_CHANNEL_COUNT__MASK)
+        uint8_t     unused_padding; // formerly format, was always 16
+        uint16_t    enabled;        // actually bool
+        audio_channel_mask_t channelMask;
+
+        // actual buffer provider used by the track hooks
+        AudioBufferProvider*                bufferProvider;
+
+        mutable AudioBufferProvider::Buffer buffer; // 8 bytes
+
+        hook_t      hook;
+        const void  *mIn;             // current location in buffer
+
+        std::unique_ptr<AudioResampler> mResampler;
+        uint32_t    sampleRate;
+        int32_t*    mainBuffer;
+        int32_t*    auxBuffer;
+
+        int32_t     sessionId;
+
+        audio_format_t mMixerFormat;     // output mix format: AUDIO_FORMAT_PCM_(FLOAT|16_BIT)
+        audio_format_t mFormat;          // input track format
+        audio_format_t mMixerInFormat;   // mix internal format AUDIO_FORMAT_PCM_(FLOAT|16_BIT)
+                                         // each track must be converted to this format.
+
+        float          mVolume[MAX_NUM_VOLUMES];     // floating point set volume
+        float          mPrevVolume[MAX_NUM_VOLUMES]; // floating point previous volume
+        float          mVolumeInc[MAX_NUM_VOLUMES];  // floating point volume increment
+
+        float          mAuxLevel;                     // floating point set aux level
+        float          mPrevAuxLevel;                 // floating point prev aux level
+        float          mAuxInc;                       // floating point aux increment
+
+        audio_channel_mask_t mMixerChannelMask;
+        uint32_t             mMixerChannelCount;
+
+      protected:
+
+        // hooks
+        void track__genericResample(int32_t* out, size_t numFrames, int32_t* temp, int32_t* aux);
+        void track__16BitsStereo(int32_t* out, size_t numFrames, int32_t* temp, int32_t* aux);
+        void track__16BitsMono(int32_t* out, size_t numFrames, int32_t* temp, int32_t* aux);
+
+        void volumeRampStereo(int32_t* out, size_t frameCount, int32_t* temp, int32_t* aux);
+        void volumeStereo(int32_t* out, size_t frameCount, int32_t* temp, int32_t* aux);
+
+        // multi-format track hooks
+        template <int MIXTYPE, typename TO, typename TI, typename TA>
+        void track__Resample(TO* out, size_t frameCount, TO* temp __unused, TA* aux);
+        template <int MIXTYPE, typename TO, typename TI, typename TA>
+        void track__NoResample(TO* out, size_t frameCount, TO* temp __unused, TA* aux);
+    };
+
+    // preCreateTrack must create an instance of a proper TrackBase descendant.
+    // postCreateTrack is called after filling out fields of TrackBase. It can
+    // abort track creation by returning non-OK status. See the implementation
+    // of create() for details.
+    virtual std::shared_ptr<TrackBase> preCreateTrack();
+    virtual status_t postCreateTrack(TrackBase *track __unused) { return OK; }
+
+    // preProcess is called before the process hook, postProcess after,
+    // see the implementation of process() method.
+    virtual void preProcess() {}
+    virtual void postProcess() {}
+
+    virtual bool setChannelMasks(int name,
+            audio_channel_mask_t trackChannelMask, audio_channel_mask_t mixerChannelMask);
+
+    // Called when track info changes and a new process hook should be determined.
+    void invalidate() {
+        mHook = &AudioMixerBase::process__validate;
+    }
+
+    void process__validate();
+    void process__nop();
+    void process__genericNoResampling();
+    void process__genericResampling();
+    void process__oneTrack16BitsStereoNoResampling();
+
+    template <int MIXTYPE, typename TO, typename TI, typename TA>
+    void process__noResampleOneTrack();
+
+    static process_hook_t getProcessHook(int processType, uint32_t channelCount,
+            audio_format_t mixerInFormat, audio_format_t mixerOutFormat);
+
+    static void convertMixerFormat(void *out, audio_format_t mixerOutFormat,
+            void *in, audio_format_t mixerInFormat, size_t sampleCount);
+
+    // initialization constants
+    const uint32_t mSampleRate;
+    const size_t mFrameCount;
+
+    process_hook_t mHook = &AudioMixerBase::process__nop;   // one of process__*, never nullptr
+
+    // the size of the type (int32_t) should be the largest of all types supported
+    // by the mixer.
+    std::unique_ptr<int32_t[]> mOutputTemp;
+    std::unique_ptr<int32_t[]> mResampleTemp;
+
+    // track names grouped by main buffer, in no particular order of main buffer.
+    // however names for a particular main buffer are in order (by construction).
+    std::unordered_map<void * /* mainBuffer */, std::vector<int /* name */>> mGroups;
+
+    // track names that are enabled, in increasing order (by construction).
+    std::vector<int /* name */> mEnabled;
+
+    // track smart pointers, by name, in increasing order of name.
+    std::map<int /* name */, std::shared_ptr<TrackBase>> mTracks;
+};
+
+}  // namespace android
+
+#endif  // ANDROID_AUDIO_MIXER_BASE_H
diff --git a/media/libmedia/include/media/RecordBufferConverter.h b/media/libaudioprocessing/include/media/RecordBufferConverter.h
similarity index 100%
rename from media/libmedia/include/media/RecordBufferConverter.h
rename to media/libaudioprocessing/include/media/RecordBufferConverter.h
diff --git a/media/libaudioprocessing/tests/Android.bp b/media/libaudioprocessing/tests/Android.bp
index d990111..20c2c2c 100644
--- a/media/libaudioprocessing/tests/Android.bp
+++ b/media/libaudioprocessing/tests/Android.bp
@@ -3,8 +3,13 @@
 cc_defaults {
     name: "libaudioprocessing_test_defaults",
 
-    header_libs: ["libbase_headers"],
+    header_libs: [
+        "libbase_headers",
+        "libmedia_headers",
+    ],
+
     shared_libs: [
+        "libaudioclient",
         "libaudioprocessing",
         "libaudioutils",
         "libcutils",
diff --git a/media/libaudioprocessing/tests/fuzzer/Android.bp b/media/libaudioprocessing/tests/fuzzer/Android.bp
new file mode 100644
index 0000000..1df47b7
--- /dev/null
+++ b/media/libaudioprocessing/tests/fuzzer/Android.bp
@@ -0,0 +1,10 @@
+cc_fuzz {
+  name: "libaudioprocessing_resampler_fuzzer",
+  srcs: [
+    "libaudioprocessing_resampler_fuzzer.cpp",
+  ],
+  defaults: ["libaudioprocessing_test_defaults"],
+  static_libs: [
+    "libsndfile",
+  ],
+}
diff --git a/media/libaudioprocessing/tests/fuzzer/libaudioprocessing_resampler_fuzzer.cpp b/media/libaudioprocessing/tests/fuzzer/libaudioprocessing_resampler_fuzzer.cpp
new file mode 100644
index 0000000..938c610
--- /dev/null
+++ b/media/libaudioprocessing/tests/fuzzer/libaudioprocessing_resampler_fuzzer.cpp
@@ -0,0 +1,188 @@
+/*
+ * 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.
+ */
+
+#include <android-base/macros.h>
+#include <audio_utils/primitives.h>
+#include <audio_utils/sndfile.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <inttypes.h>
+#include <math.h>
+#include <media/AudioBufferProvider.h>
+#include <media/AudioResampler.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <time.h>
+#include <unistd.h>
+#include <utils/Vector.h>
+
+#include <memory>
+
+using namespace android;
+
+const int MAX_FRAMES = 10;
+const int MIN_FREQ = 1e3;
+const int MAX_FREQ = 100e3;
+
+const AudioResampler::src_quality qualities[] = {
+    AudioResampler::DEFAULT_QUALITY,
+    AudioResampler::LOW_QUALITY,
+    AudioResampler::MED_QUALITY,
+    AudioResampler::HIGH_QUALITY,
+    AudioResampler::VERY_HIGH_QUALITY,
+    AudioResampler::DYN_LOW_QUALITY,
+    AudioResampler::DYN_MED_QUALITY,
+    AudioResampler::DYN_HIGH_QUALITY,
+};
+
+class Provider : public AudioBufferProvider {
+  const void* mAddr;        // base address
+  const size_t mNumFrames;  // total frames
+  const size_t mFrameSize;  // size of each frame in bytes
+  size_t mNextFrame;        // index of next frame to provide
+  size_t mUnrel;            // number of frames not yet released
+ public:
+  Provider(const void* addr, size_t frames, size_t frameSize)
+      : mAddr(addr),
+        mNumFrames(frames),
+        mFrameSize(frameSize),
+        mNextFrame(0),
+        mUnrel(0) {}
+  status_t getNextBuffer(Buffer* buffer) override {
+    if (buffer->frameCount > mNumFrames - mNextFrame) {
+      buffer->frameCount = mNumFrames - mNextFrame;
+    }
+    mUnrel = buffer->frameCount;
+    if (buffer->frameCount > 0) {
+      buffer->raw = (char*)mAddr + mFrameSize * mNextFrame;
+      return NO_ERROR;
+    } else {
+      buffer->raw = nullptr;
+      return NOT_ENOUGH_DATA;
+    }
+  }
+  virtual void releaseBuffer(Buffer* buffer) {
+    if (buffer->frameCount > mUnrel) {
+      mNextFrame += mUnrel;
+      mUnrel = 0;
+    } else {
+      mNextFrame += buffer->frameCount;
+      mUnrel -= buffer->frameCount;
+    }
+    buffer->frameCount = 0;
+    buffer->raw = nullptr;
+  }
+  void reset() { mNextFrame = 0; }
+};
+
+audio_format_t chooseFormat(AudioResampler::src_quality quality,
+                            uint8_t input_byte) {
+  switch (quality) {
+    case AudioResampler::DYN_LOW_QUALITY:
+    case AudioResampler::DYN_MED_QUALITY:
+    case AudioResampler::DYN_HIGH_QUALITY:
+      if (input_byte % 2) {
+        return AUDIO_FORMAT_PCM_FLOAT;
+      }
+      FALLTHROUGH_INTENDED;
+    default:
+      return AUDIO_FORMAT_PCM_16_BIT;
+  }
+}
+
+int parseValue(const uint8_t* src, int index, void* dst, size_t size) {
+  memcpy(dst, &src[index], size);
+  return size;
+}
+
+bool validFreq(int freq) { return freq > MIN_FREQ && freq < MAX_FREQ; }
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+  int input_freq = 0;
+  int output_freq = 0;
+  int input_channels = 0;
+
+  float left_volume = 0;
+  float right_volume = 0;
+
+  size_t metadata_size = 2 + 3 * sizeof(int) + 2 * sizeof(float);
+  if (size < metadata_size) {
+    // not enough data to set options
+    return 0;
+  }
+
+  AudioResampler::src_quality quality = qualities[data[0] % 8];
+  audio_format_t format = chooseFormat(quality, data[1]);
+
+  int index = 2;
+
+  index += parseValue(data, index, &input_freq, sizeof(int));
+  index += parseValue(data, index, &output_freq, sizeof(int));
+  index += parseValue(data, index, &input_channels, sizeof(int));
+
+  index += parseValue(data, index, &left_volume, sizeof(float));
+  index += parseValue(data, index, &right_volume, sizeof(float));
+
+  if (!validFreq(input_freq) || !validFreq(output_freq)) {
+    // sampling frequencies must be reasonable
+    return 0;
+  }
+
+  if (input_channels < 1 ||
+      input_channels > (quality < AudioResampler::DYN_LOW_QUALITY ? 2 : 8)) {
+    // invalid number of input channels
+    return 0;
+  }
+
+  size_t single_channel_size =
+      format == AUDIO_FORMAT_PCM_FLOAT ? sizeof(float) : sizeof(int16_t);
+  size_t input_frame_size = single_channel_size * input_channels;
+  size_t input_size = size - metadata_size;
+  uint8_t input_data[input_size];
+  memcpy(input_data, &data[metadata_size], input_size);
+
+  size_t input_frames = input_size / input_frame_size;
+  if (input_frames > MAX_FRAMES) {
+    return 0;
+  }
+
+  Provider provider(input_data, input_frames, input_frame_size);
+
+  std::unique_ptr<AudioResampler> resampler(
+      AudioResampler::create(format, input_channels, output_freq, quality));
+
+  resampler->setSampleRate(input_freq);
+  resampler->setVolume(left_volume, right_volume);
+
+  // output is at least stereo samples
+  int output_channels = input_channels > 2 ? input_channels : 2;
+  size_t output_frame_size = output_channels * sizeof(int32_t);
+  size_t output_frames = (input_frames * output_freq) / input_freq;
+  size_t output_size = output_frames * output_frame_size;
+
+  uint8_t output_data[output_size];
+  for (size_t i = 0; i < output_frames; i++) {
+    memset(output_data, 0, output_size);
+    resampler->resample((int*)output_data, i, &provider);
+  }
+
+  return 0;
+}
diff --git a/media/libcpustats/Android.bp b/media/libcpustats/Android.bp
index 8fcd8a4..6e8ca1d 100644
--- a/media/libcpustats/Android.bp
+++ b/media/libcpustats/Android.bp
@@ -6,6 +6,14 @@
         "ThreadCpuUsage.cpp",
     ],
 
+    local_include_dirs: [
+        "include",
+    ],
+
+    export_include_dirs: [
+        "include",
+    ],
+
     cflags: [
         "-Werror",
         "-Wall",
diff --git a/media/libdatasource/Android.bp b/media/libdatasource/Android.bp
new file mode 100644
index 0000000..f191c21
--- /dev/null
+++ b/media/libdatasource/Android.bp
@@ -0,0 +1,63 @@
+cc_library {
+    name: "libdatasource",
+
+    srcs: [
+        "DataSourceFactory.cpp",
+        "DataURISource.cpp",
+        "FileSource.cpp",
+        "HTTPBase.cpp",
+        "MediaHTTP.cpp",
+        "NuCachedSource2.cpp",
+    ],
+
+    aidl: {
+        local_include_dirs: ["aidl"],
+        export_aidl_headers: true,
+    },
+
+    header_libs: [
+        "libstagefright_headers",
+        "media_ndk_headers",
+        "libmedia_headers",
+    ],
+
+    export_header_lib_headers: [
+        "libstagefright_headers",
+        "media_ndk_headers",
+    ],
+
+    shared_libs: [
+        "liblog",
+        "libcutils",
+        "libutils",
+        "libstagefright_foundation",
+        "libdl",
+    ],
+
+    static_libs: [
+        "libc_malloc_debug_backtrace",  // for memory heap analysis
+        "libmedia_midiiowrapper",
+    ],
+
+    local_include_dirs: [
+        "include",
+    ],
+
+    export_include_dirs: [
+        "include",
+    ],
+
+    cflags: [
+        "-Werror",
+        "-Wno-error=deprecated-declarations",
+        "-Wall",
+    ],
+
+    sanitize: {
+        misc_undefined: [
+            "unsigned-integer-overflow",
+            "signed-integer-overflow",
+        ],
+        cfi: true,
+    },
+}
diff --git a/media/libstagefright/DataSourceFactory.cpp b/media/libdatasource/DataSourceFactory.cpp
similarity index 72%
rename from media/libstagefright/DataSourceFactory.cpp
rename to media/libdatasource/DataSourceFactory.cpp
index 54bf0cc..bb6a08c 100644
--- a/media/libstagefright/DataSourceFactory.cpp
+++ b/media/libdatasource/DataSourceFactory.cpp
@@ -16,20 +16,33 @@
 //#define LOG_NDEBUG 0
 #define LOG_TAG "DataSource"
 
-#include "include/HTTPBase.h"
-#include "include/NuCachedSource2.h"
 
+#include <datasource/DataSourceFactory.h>
+#include <datasource/DataURISource.h>
+#include <datasource/HTTPBase.h>
+#include <datasource/FileSource.h>
+#include <datasource/MediaHTTP.h>
+#include <datasource/NuCachedSource2.h>
 #include <media/MediaHTTPConnection.h>
 #include <media/MediaHTTPService.h>
-#include <media/stagefright/DataSourceFactory.h>
-#include <media/stagefright/DataURISource.h>
-#include <media/stagefright/FileSource.h>
-#include <media/stagefright/MediaHTTP.h>
 #include <utils/String8.h>
 
 namespace android {
 
 // static
+sp<DataSourceFactory> DataSourceFactory::sInstance;
+// static
+Mutex DataSourceFactory::sInstanceLock;
+
+// static
+sp<DataSourceFactory> DataSourceFactory::getInstance() {
+    Mutex::Autolock l(sInstanceLock);
+    if (!sInstance) {
+        sInstance = new DataSourceFactory();
+    }
+    return sInstance;
+}
+
 sp<DataSource> DataSourceFactory::CreateFromURI(
         const sp<MediaHTTPService> &httpService,
         const char *uri,
@@ -42,20 +55,16 @@
 
     sp<DataSource> source;
     if (!strncasecmp("file://", uri, 7)) {
-        source = new FileSource(uri + 7);
+        source = CreateFileSource(uri + 7);
     } else if (!strncasecmp("http://", uri, 7) || !strncasecmp("https://", uri, 8)) {
         if (httpService == NULL) {
             ALOGE("Invalid http service!");
             return NULL;
         }
 
-        if (httpSource == NULL) {
-            sp<MediaHTTPConnection> conn = httpService->makeHTTPConnection();
-            if (conn == NULL) {
-                ALOGE("Failed to make http connection from http service!");
-                return NULL;
-            }
-            httpSource = new MediaHTTP(conn);
+        sp<HTTPBase> mediaHTTP = httpSource;
+        if (mediaHTTP == NULL) {
+            mediaHTTP = static_cast<HTTPBase *>(CreateMediaHTTP(httpService).get());
         }
 
         String8 cacheConfig;
@@ -69,24 +78,24 @@
                     &disconnectAtHighwatermark);
         }
 
-        if (httpSource->connect(uri, &nonCacheSpecificHeaders) != OK) {
+        if (mediaHTTP->connect(uri, &nonCacheSpecificHeaders) != OK) {
             ALOGE("Failed to connect http source!");
             return NULL;
         }
 
         if (contentType != NULL) {
-            *contentType = httpSource->getMIMEType();
+            *contentType = mediaHTTP->getMIMEType();
         }
 
         source = NuCachedSource2::Create(
-                httpSource,
+                mediaHTTP,
                 cacheConfig.isEmpty() ? NULL : cacheConfig.string(),
                 disconnectAtHighwatermark);
     } else if (!strncasecmp("data:", uri, 5)) {
         source = DataURISource::Create(uri);
     } else {
         // Assume it's a filename.
-        source = new FileSource(uri);
+        source = CreateFileSource(uri);
     }
 
     if (source == NULL || source->initCheck() != OK) {
@@ -108,10 +117,15 @@
 
     sp<MediaHTTPConnection> conn = httpService->makeHTTPConnection();
     if (conn == NULL) {
+        ALOGE("Failed to make http connection from http service!");
         return NULL;
     } else {
         return new MediaHTTP(conn);
     }
 }
 
+sp<DataSource> DataSourceFactory::CreateFileSource(const char *uri) {
+    return new FileSource(uri);
+}
+
 }  // namespace android
diff --git a/media/libstagefright/DataURISource.cpp b/media/libdatasource/DataURISource.cpp
similarity index 98%
rename from media/libstagefright/DataURISource.cpp
rename to media/libdatasource/DataURISource.cpp
index b975b38..216f3d0 100644
--- a/media/libstagefright/DataURISource.cpp
+++ b/media/libdatasource/DataURISource.cpp
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-#include <media/stagefright/DataURISource.h>
+#include <datasource/DataURISource.h>
 
 #include <media/stagefright/foundation/ABuffer.h>
 #include <media/stagefright/foundation/AString.h>
diff --git a/media/libstagefright/ClearFileSource.cpp b/media/libdatasource/FileSource.cpp
similarity index 85%
rename from media/libstagefright/ClearFileSource.cpp
rename to media/libdatasource/FileSource.cpp
index e3a2cb7..bbf7dda 100644
--- a/media/libstagefright/ClearFileSource.cpp
+++ b/media/libdatasource/FileSource.cpp
@@ -15,12 +15,12 @@
  */
 
 //#define LOG_NDEBUG 0
-#define LOG_TAG "ClearFileSource"
+#define LOG_TAG "FileSource"
 #include <utils/Log.h>
 
+#include <datasource/FileSource.h>
 #include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/ClearFileSource.h>
-#include <media/stagefright/Utils.h>
+#include <media/stagefright/FoundationUtils.h>
 #include <sys/types.h>
 #include <unistd.h>
 #include <sys/types.h>
@@ -29,7 +29,7 @@
 
 namespace android {
 
-ClearFileSource::ClearFileSource(const char *filename)
+FileSource::FileSource(const char *filename)
     : mFd(-1),
       mOffset(0),
       mLength(-1),
@@ -48,7 +48,7 @@
     }
 }
 
-ClearFileSource::ClearFileSource(int fd, int64_t offset, int64_t length)
+FileSource::FileSource(int fd, int64_t offset, int64_t length)
     : mFd(fd),
       mOffset(offset),
       mLength(length),
@@ -89,18 +89,18 @@
 
 }
 
-ClearFileSource::~ClearFileSource() {
+FileSource::~FileSource() {
     if (mFd >= 0) {
         ::close(mFd);
         mFd = -1;
     }
 }
 
-status_t ClearFileSource::initCheck() const {
+status_t FileSource::initCheck() const {
     return mFd >= 0 ? OK : NO_INIT;
 }
 
-ssize_t ClearFileSource::readAt(off64_t offset, void *data, size_t size) {
+ssize_t FileSource::readAt(off64_t offset, void *data, size_t size) {
     if (mFd < 0) {
         return NO_INIT;
     }
@@ -118,7 +118,7 @@
     return readAt_l(offset, data, size);
 }
 
-ssize_t ClearFileSource::readAt_l(off64_t offset, void *data, size_t size) {
+ssize_t FileSource::readAt_l(off64_t offset, void *data, size_t size) {
     off64_t result = lseek64(mFd, offset + mOffset, SEEK_SET);
     if (result == -1) {
         ALOGE("seek to %lld failed", (long long)(offset + mOffset));
@@ -128,7 +128,7 @@
     return ::read(mFd, data, size);
 }
 
-status_t ClearFileSource::getSize(off64_t *size) {
+status_t FileSource::getSize(off64_t *size) {
     Mutex::Autolock autoLock(mLock);
 
     if (mFd < 0) {
diff --git a/media/libstagefright/HTTPBase.cpp b/media/libdatasource/HTTPBase.cpp
similarity index 98%
rename from media/libstagefright/HTTPBase.cpp
rename to media/libdatasource/HTTPBase.cpp
index d118e8c..ef29c48 100644
--- a/media/libstagefright/HTTPBase.cpp
+++ b/media/libdatasource/HTTPBase.cpp
@@ -18,7 +18,7 @@
 #define LOG_TAG "HTTPBase"
 #include <utils/Log.h>
 
-#include "include/HTTPBase.h"
+#include <datasource/HTTPBase.h>
 
 #include <media/stagefright/foundation/ADebug.h>
 #include <media/stagefright/foundation/ALooper.h>
diff --git a/media/libstagefright/http/ClearMediaHTTP.cpp b/media/libdatasource/MediaHTTP.cpp
similarity index 82%
rename from media/libstagefright/http/ClearMediaHTTP.cpp
rename to media/libdatasource/MediaHTTP.cpp
index 9557c8a..58c1ce8 100644
--- a/media/libstagefright/http/ClearMediaHTTP.cpp
+++ b/media/libdatasource/MediaHTTP.cpp
@@ -15,30 +15,30 @@
  */
 
 //#define LOG_NDEBUG 0
-#define LOG_TAG "ClearMediaHTTP"
+#define LOG_TAG "MediaHTTP"
 #include <utils/Log.h>
 
-#include <media/stagefright/ClearMediaHTTP.h>
+#include <datasource/MediaHTTP.h>
 
 #include <media/stagefright/foundation/ADebug.h>
 #include <media/stagefright/foundation/ALooper.h>
-#include <media/stagefright/Utils.h>
+#include <media/stagefright/FoundationUtils.h>
 
 #include <media/MediaHTTPConnection.h>
 
 namespace android {
 
-ClearMediaHTTP::ClearMediaHTTP(const sp<MediaHTTPConnection> &conn)
+MediaHTTP::MediaHTTP(const sp<MediaHTTPConnection> &conn)
     : mInitCheck((conn != NULL) ? OK : NO_INIT),
       mHTTPConnection(conn),
       mCachedSizeValid(false),
       mCachedSize(0ll) {
 }
 
-ClearMediaHTTP::~ClearMediaHTTP() {
+MediaHTTP::~MediaHTTP() {
 }
 
-status_t ClearMediaHTTP::connect(
+status_t MediaHTTP::connect(
         const char *uri,
         const KeyedVector<String8, String8> *headers,
         off64_t /* offset */) {
@@ -68,18 +68,18 @@
 
     if (success) {
         AString sanitized = uriDebugString(mLastURI);
-        mName = String8::format("ClearMediaHTTP(%s)", sanitized.c_str());
+        mName = String8::format("MediaHTTP(%s)", sanitized.c_str());
     }
 
     return success ? OK : UNKNOWN_ERROR;
 }
 
-void ClearMediaHTTP::close() {
+void MediaHTTP::close() {
     disconnect();
 }
 
-void ClearMediaHTTP::disconnect() {
-    mName = String8("ClearMediaHTTP(<disconnected>)");
+void MediaHTTP::disconnect() {
+    mName = String8("MediaHTTP(<disconnected>)");
     if (mInitCheck != OK) {
         return;
     }
@@ -87,11 +87,11 @@
     mHTTPConnection->disconnect();
 }
 
-status_t ClearMediaHTTP::initCheck() const {
+status_t MediaHTTP::initCheck() const {
     return mInitCheck;
 }
 
-ssize_t ClearMediaHTTP::readAt(off64_t offset, void *data, size_t size) {
+ssize_t MediaHTTP::readAt(off64_t offset, void *data, size_t size) {
     if (mInitCheck != OK) {
         return mInitCheck;
     }
@@ -127,7 +127,7 @@
     return numBytesRead;
 }
 
-status_t ClearMediaHTTP::getSize(off64_t *size) {
+status_t MediaHTTP::getSize(off64_t *size) {
     if (mInitCheck != OK) {
         return mInitCheck;
     }
@@ -145,16 +145,16 @@
     return *size < 0 ? *size : static_cast<status_t>(OK);
 }
 
-uint32_t ClearMediaHTTP::flags() {
+uint32_t MediaHTTP::flags() {
     return kWantsPrefetching | kIsHTTPBasedSource;
 }
 
-status_t ClearMediaHTTP::reconnectAtOffset(off64_t offset) {
+status_t MediaHTTP::reconnectAtOffset(off64_t offset) {
     return connect(mLastURI.c_str(), &mLastHeaders, offset);
 }
 
 
-String8 ClearMediaHTTP::getUri() {
+String8 MediaHTTP::getUri() {
     if (mInitCheck != OK) {
         return String8::empty();
     }
@@ -166,7 +166,7 @@
     return String8(mLastURI.c_str());
 }
 
-String8 ClearMediaHTTP::getMIMEType() const {
+String8 MediaHTTP::getMIMEType() const {
     if (mInitCheck != OK) {
         return String8("application/octet-stream");
     }
diff --git a/media/libstagefright/NuCachedSource2.cpp b/media/libdatasource/NuCachedSource2.cpp
similarity index 99%
rename from media/libstagefright/NuCachedSource2.cpp
rename to media/libdatasource/NuCachedSource2.cpp
index 522c81d..7f5ae61 100644
--- a/media/libstagefright/NuCachedSource2.cpp
+++ b/media/libdatasource/NuCachedSource2.cpp
@@ -20,8 +20,8 @@
 #define LOG_TAG "NuCachedSource2"
 #include <utils/Log.h>
 
-#include "include/NuCachedSource2.h"
-#include "include/HTTPBase.h"
+#include <datasource/NuCachedSource2.h>
+#include <datasource/HTTPBase.h>
 
 #include <cutils/properties.h>
 #include <media/stagefright/foundation/ADebug.h>
diff --git a/media/libstagefright/include/media/stagefright/DataSourceFactory.h b/media/libdatasource/include/datasource/DataSourceFactory.h
similarity index 66%
rename from media/libstagefright/include/media/stagefright/DataSourceFactory.h
rename to media/libdatasource/include/datasource/DataSourceFactory.h
index 2a1d491..194abe2 100644
--- a/media/libstagefright/include/media/stagefright/DataSourceFactory.h
+++ b/media/libdatasource/include/datasource/DataSourceFactory.h
@@ -18,7 +18,9 @@
 
 #define DATA_SOURCE_FACTORY_H_
 
+#include <media/DataSource.h>
 #include <sys/types.h>
+#include <utils/KeyedVector.h>
 #include <utils/RefBase.h>
 
 namespace android {
@@ -27,17 +29,27 @@
 class String8;
 struct HTTPBase;
 
-class DataSourceFactory {
+class DataSourceFactory : public RefBase {
 public:
-    static sp<DataSource> CreateFromURI(
+    static sp<DataSourceFactory> getInstance();
+    sp<DataSource> CreateFromURI(
             const sp<MediaHTTPService> &httpService,
             const char *uri,
             const KeyedVector<String8, String8> *headers = NULL,
             String8 *contentType = NULL,
             HTTPBase *httpSource = NULL);
 
-    static sp<DataSource> CreateMediaHTTP(const sp<MediaHTTPService> &httpService);
-    static sp<DataSource> CreateFromFd(int fd, int64_t offset, int64_t length);
+    virtual sp<DataSource> CreateMediaHTTP(const sp<MediaHTTPService> &httpService);
+    sp<DataSource> CreateFromFd(int fd, int64_t offset, int64_t length);
+
+protected:
+    virtual sp<DataSource> CreateFileSource(const char *uri);
+    DataSourceFactory() {};
+    virtual ~DataSourceFactory() {};
+
+private:
+    static sp<DataSourceFactory> sInstance;
+    static Mutex sInstanceLock;
 };
 
 }  // namespace android
diff --git a/media/libstagefright/include/media/stagefright/DataURISource.h b/media/libdatasource/include/datasource/DataURISource.h
similarity index 100%
rename from media/libstagefright/include/media/stagefright/DataURISource.h
rename to media/libdatasource/include/datasource/DataURISource.h
diff --git a/media/libstagefright/include/media/stagefright/ClearFileSource.h b/media/libdatasource/include/datasource/FileSource.h
similarity index 74%
rename from media/libstagefright/include/media/stagefright/ClearFileSource.h
rename to media/libdatasource/include/datasource/FileSource.h
index be83748..dee0c33 100644
--- a/media/libstagefright/include/media/stagefright/ClearFileSource.h
+++ b/media/libdatasource/include/datasource/FileSource.h
@@ -14,9 +14,9 @@
  * limitations under the License.
  */
 
-#ifndef CLEAR_FILE_SOURCE_H_
+#ifndef FILE_SOURCE_H_
 
-#define CLEAR_FILE_SOURCE_H_
+#define FILE_SOURCE_H_
 
 #include <stdio.h>
 
@@ -26,11 +26,11 @@
 
 namespace android {
 
-class ClearFileSource : public DataSource {
+class FileSource : public DataSource {
 public:
-    ClearFileSource(const char *filename);
-    // ClearFileSource takes ownership and will close the fd
-    ClearFileSource(int fd, int64_t offset, int64_t length);
+    FileSource(const char *filename);
+    // FileSource takes ownership and will close the fd
+    FileSource(int fd, int64_t offset, int64_t length);
 
     virtual status_t initCheck() const;
 
@@ -47,7 +47,7 @@
     }
 
 protected:
-    virtual ~ClearFileSource();
+    virtual ~FileSource();
     virtual ssize_t readAt_l(off64_t offset, void *data, size_t size);
 
     int mFd;
@@ -58,11 +58,11 @@
 private:
     String8 mName;
 
-    ClearFileSource(const ClearFileSource &);
-    ClearFileSource &operator=(const ClearFileSource &);
+    FileSource(const FileSource &);
+    FileSource &operator=(const FileSource &);
 };
 
 }  // namespace android
 
-#endif  // CLEAR_FILE_SOURCE_H_
+#endif  // FILE_SOURCE_H_
 
diff --git a/media/libstagefright/include/HTTPBase.h b/media/libdatasource/include/datasource/HTTPBase.h
similarity index 100%
rename from media/libstagefright/include/HTTPBase.h
rename to media/libdatasource/include/datasource/HTTPBase.h
diff --git a/media/libstagefright/include/media/stagefright/ClearMediaHTTP.h b/media/libdatasource/include/datasource/MediaHTTP.h
similarity index 83%
rename from media/libstagefright/include/media/stagefright/ClearMediaHTTP.h
rename to media/libdatasource/include/datasource/MediaHTTP.h
index 72907a9..a8d203b 100644
--- a/media/libstagefright/include/media/stagefright/ClearMediaHTTP.h
+++ b/media/libdatasource/include/datasource/MediaHTTP.h
@@ -14,20 +14,20 @@
  * limitations under the License.
  */
 
-#ifndef CLEAR_MEDIA_HTTP_H_
+#ifndef MEDIA_HTTP_H_
 
-#define CLEAR_MEDIA_HTTP_H_
+#define MEDIA_HTTP_H_
 
 #include <media/stagefright/foundation/AString.h>
 
-#include "include/HTTPBase.h"
+#include "HTTPBase.h"
 
 namespace android {
 
 struct MediaHTTPConnection;
 
-struct ClearMediaHTTP : public HTTPBase {
-    ClearMediaHTTP(const sp<MediaHTTPConnection> &conn);
+struct MediaHTTP : public HTTPBase {
+    MediaHTTP(const sp<MediaHTTPConnection> &conn);
 
     virtual status_t connect(
             const char *uri,
@@ -49,7 +49,7 @@
     virtual status_t reconnectAtOffset(off64_t offset);
 
 protected:
-    virtual ~ClearMediaHTTP();
+    virtual ~MediaHTTP();
 
     virtual String8 getUri();
     virtual String8 getMIMEType() const;
@@ -65,9 +65,9 @@
     bool mCachedSizeValid;
     off64_t mCachedSize;
 
-    DISALLOW_EVIL_CONSTRUCTORS(ClearMediaHTTP);
+    DISALLOW_EVIL_CONSTRUCTORS(MediaHTTP);
 };
 
 }  // namespace android
 
-#endif  // CLEAR_MEDIA_HTTP_H_
+#endif  // MEDIA_HTTP_H_
diff --git a/media/libstagefright/include/NuCachedSource2.h b/media/libdatasource/include/datasource/NuCachedSource2.h
similarity index 100%
rename from media/libstagefright/include/NuCachedSource2.h
rename to media/libdatasource/include/datasource/NuCachedSource2.h
diff --git a/media/libmedia/Android.bp b/media/libmedia/Android.bp
index 1d33590..b49df9e 100644
--- a/media/libmedia/Android.bp
+++ b/media/libmedia/Android.bp
@@ -1,10 +1,3 @@
-cc_defaults {
-    name: "libmedia_defaults",
-    include_dirs: [
-        "bionic/libc/private",
-    ],
-}
-
 cc_library_headers {
     name: "libmedia_headers",
     vendor_available: true,
@@ -47,6 +40,15 @@
     clang: true,
 }
 
+filegroup {
+    name: "libmedia_omx_aidl",
+    srcs: [
+        "aidl/android/IGraphicBufferSource.aidl",
+        "aidl/android/IOMXBufferSource.aidl",
+    ],
+    path: "aidl",
+}
+
 cc_library_shared {
     name: "libmedia_omx",
     vendor_available: true,
@@ -56,13 +58,10 @@
     double_loadable: true,
 
     srcs: [
-        "aidl/android/IGraphicBufferSource.aidl",
-        "aidl/android/IOMXBufferSource.aidl",
+        ":libmedia_omx_aidl",
 
-        "IMediaCodecList.cpp",
         "IOMX.cpp",
         "MediaCodecBuffer.cpp",
-        "MediaCodecInfo.cpp",
         "OMXBuffer.cpp",
         "omx/1.0/WGraphicBufferSource.cpp",
         "omx/1.0/WOmxBufferSource.cpp",
@@ -74,7 +73,7 @@
         local_include_dirs: ["aidl"],
         export_aidl_headers: true,
     },
-    
+
     local_include_dirs: [
         "include",
     ],
@@ -85,7 +84,6 @@
         "libbinder",
         "libcutils",
         "libhidlbase",
-        "libhidltransport",
         "liblog",
         "libstagefright_foundation",
         "libui",
@@ -146,7 +144,6 @@
         "libcutils",
         "libgui",
         "libhidlbase",
-        "libhidltransport",
         "liblog",
         "libmedia_omx",
         "libstagefright_foundation",
@@ -200,6 +197,7 @@
     ],
 
     header_libs: [
+        "libmedia_headers",
         "media_ndk_headers",
     ],
 
@@ -218,11 +216,52 @@
     },
 }
 
+cc_library_shared {
+    name: "libmedia_codeclist",
+
+    srcs: [
+        "IMediaCodecList.cpp",
+        "MediaCodecInfo.cpp",
+    ],
+
+    local_include_dirs: [
+        "include",
+    ],
+
+    shared_libs: [
+        "android.hardware.media.omx@1.0",
+        "libbinder",
+        "liblog",
+        "libstagefright_foundation",
+        "libutils",
+    ],
+
+    include_dirs: [
+        "system/libhidl/transport/token/1.0/utils/include",
+    ],
+
+    export_include_dirs: [
+        "include",
+    ],
+
+    cflags: [
+        "-Werror",
+        "-Wno-error=deprecated-declarations",
+        "-Wall",
+    ],
+
+    sanitize: {
+        misc_undefined: [
+            "unsigned-integer-overflow",
+            "signed-integer-overflow",
+        ],
+        cfi: true,
+    },
+}
+
 cc_library {
     name: "libmedia",
 
-    defaults: [ "libmedia_defaults" ],
-
     srcs: [
         "IDataSource.cpp",
         "BufferingSettings.cpp",
@@ -247,8 +286,6 @@
         "mediarecorder.cpp",
         "IMediaMetadataRetriever.cpp",
         "mediametadataretriever.cpp",
-        "MidiDeviceInfo.cpp",
-        "JetPlayer.cpp",
         "MediaScanner.cpp",
         "MediaScannerClient.cpp",
         "CharacterEncodingDetector.cpp",
@@ -256,7 +293,6 @@
         "MediaProfiles.cpp",
         "MediaResource.cpp",
         "MediaResourcePolicy.cpp",
-        "Visualizer.cpp",
         "StringArray.cpp",
         "NdkMediaFormatPriv.cpp",
         "NdkMediaErrorPriv.cpp",
@@ -268,6 +304,7 @@
     },
 
     header_libs: [
+        "bionic_libc_platform_headers",
         "libstagefright_headers",
         "media_ndk_headers",
     ],
@@ -291,8 +328,8 @@
         "libstagefright_foundation",
         "libgui",
         "libdl",
-        "libaudioutils",
         "libaudioclient",
+        "libmedia_codeclist",
         "libmedia_omx",
     ],
 
@@ -306,7 +343,6 @@
 
     static_libs: [
         "libc_malloc_debug_backtrace",  // for memory heap analysis
-        "libmedia_midiiowrapper",
     ],
 
     export_include_dirs: [
@@ -329,66 +365,3 @@
         cfi: true,
     },
 }
-
-cc_library_static {
-    name: "libmedia_player2_util",
-
-    defaults: [ "libmedia_defaults" ],
-
-    srcs: [
-        "AudioParameter.cpp",
-        "BufferingSettings.cpp",
-        "DataSourceDesc.cpp",
-        "MediaCodecBuffer.cpp",
-        "Metadata.cpp",
-        "NdkWrapper.cpp",
-    ],
-
-    shared_libs: [
-        "libbinder",
-        "libcutils",
-        "liblog",
-        "libmediandk",
-        "libnativewindow",
-        "libmediandk_utils",
-        "libstagefright_foundation",
-        "libui",
-        "libutils",
-    ],
-
-    export_shared_lib_headers: [
-        "libbinder",
-        "libmediandk",
-    ],
-
-    header_libs: [
-        "media_plugin_headers",
-    ],
-
-    include_dirs: [
-        "frameworks/av/media/ndk",
-    ],
-
-    static_libs: [
-        "libstagefright_rtsp",
-        "libstagefright_timedtext",
-    ],
-
-    export_include_dirs: [
-        "include",
-    ],
-
-    cflags: [
-        "-Werror",
-        "-Wno-error=deprecated-declarations",
-        "-Wall",
-    ],
-
-    sanitize: {
-        misc_undefined: [
-            "unsigned-integer-overflow",
-            "signed-integer-overflow",
-        ],
-        cfi: true,
-    },
-}
diff --git a/media/libmedia/AudioParameter.cpp b/media/libmedia/AudioParameter.cpp
index 1c95e27..9f34035 100644
--- a/media/libmedia/AudioParameter.cpp
+++ b/media/libmedia/AudioParameter.cpp
@@ -40,6 +40,8 @@
         AUDIO_PARAMETER_KEY_AUDIO_LANGUAGE_PREFERRED;
 const char * const AudioParameter::keyMonoOutput = AUDIO_PARAMETER_MONO_OUTPUT;
 const char * const AudioParameter::keyStreamHwAvSync = AUDIO_PARAMETER_STREAM_HW_AV_SYNC;
+const char * const AudioParameter::keyDeviceConnect = AUDIO_PARAMETER_DEVICE_CONNECT;
+const char * const AudioParameter::keyDeviceDisconnect = AUDIO_PARAMETER_DEVICE_DISCONNECT;
 const char * const AudioParameter::keyStreamConnect = AUDIO_PARAMETER_DEVICE_CONNECT;
 const char * const AudioParameter::keyStreamDisconnect = AUDIO_PARAMETER_DEVICE_DISCONNECT;
 const char * const AudioParameter::keyStreamSupportedFormats = AUDIO_PARAMETER_STREAM_SUP_FORMATS;
diff --git a/media/libmedia/DataSourceDesc.cpp b/media/libmedia/DataSourceDesc.cpp
deleted file mode 100644
index b7ccbce..0000000
--- a/media/libmedia/DataSourceDesc.cpp
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright 2018 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 "DataSourceDesc"
-
-#include <media/DataSource.h>
-#include <media/DataSourceDesc.h>
-#include <media/MediaHTTPService.h>
-
-namespace android {
-
-static const int64_t kLongMax = 0x7ffffffffffffffL;
-
-DataSourceDesc::DataSourceDesc()
-    : mType(TYPE_NONE),
-      mFDOffset(0),
-      mFDLength(kLongMax),
-      mId(0),
-      mStartPositionMs(0),
-      mEndPositionMs(0) {
-}
-
-}  // namespace android
diff --git a/media/libmedia/JetPlayer.cpp b/media/libmedia/JetPlayer.cpp
deleted file mode 100644
index 0d3c1ba..0000000
--- a/media/libmedia/JetPlayer.cpp
+++ /dev/null
@@ -1,471 +0,0 @@
-/*
- * Copyright (C) 2008 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 "JetPlayer-C"
-
-#include <utils/Log.h>
-#include <media/JetPlayer.h>
-
-
-namespace android
-{
-
-static const int MIX_NUM_BUFFERS = 4;
-static const S_EAS_LIB_CONFIG* pLibConfig = NULL;
-
-//-------------------------------------------------------------------------------------------------
-JetPlayer::JetPlayer(void *javaJetPlayer, int maxTracks, int trackBufferSize) :
-        mEventCallback(NULL),
-        mJavaJetPlayerRef(javaJetPlayer),
-        mTid(-1),
-        mRender(false),
-        mPaused(false),
-        mMaxTracks(maxTracks),
-        mEasData(NULL),
-        mIoWrapper(NULL),
-        mTrackBufferSize(trackBufferSize)
-{
-    ALOGV("JetPlayer constructor");
-    mPreviousJetStatus.currentUserID = -1;
-    mPreviousJetStatus.segmentRepeatCount = -1;
-    mPreviousJetStatus.numQueuedSegments = -1;
-    mPreviousJetStatus.paused = true;
-}
-
-//-------------------------------------------------------------------------------------------------
-JetPlayer::~JetPlayer()
-{
-    ALOGV("~JetPlayer");
-    release();
-}
-
-//-------------------------------------------------------------------------------------------------
-int JetPlayer::init()
-{
-    //Mutex::Autolock lock(&mMutex);
-
-    EAS_RESULT result;
-
-    // retrieve the EAS library settings
-    if (pLibConfig == NULL)
-        pLibConfig = EAS_Config();
-    if (pLibConfig == NULL) {
-        ALOGE("JetPlayer::init(): EAS library configuration could not be retrieved, aborting.");
-        return EAS_FAILURE;
-    }
-
-    // init the EAS library
-    result = EAS_Init(&mEasData);
-    if (result != EAS_SUCCESS) {
-        ALOGE("JetPlayer::init(): Error initializing Sonivox EAS library, aborting.");
-        mState = EAS_STATE_ERROR;
-        return result;
-    }
-    // init the JET library with the default app event controller range
-    result = JET_Init(mEasData, NULL, sizeof(S_JET_CONFIG));
-    if (result != EAS_SUCCESS) {
-        ALOGE("JetPlayer::init(): Error initializing JET library, aborting.");
-        mState = EAS_STATE_ERROR;
-        return result;
-    }
-
-    // create the output AudioTrack
-    mAudioTrack = new AudioTrack();
-    status_t status = mAudioTrack->set(AUDIO_STREAM_MUSIC,  //TODO parameterize this
-            pLibConfig->sampleRate,
-            AUDIO_FORMAT_PCM_16_BIT,
-            audio_channel_out_mask_from_count(pLibConfig->numChannels),
-            (size_t) mTrackBufferSize,
-            AUDIO_OUTPUT_FLAG_NONE);
-    if (status != OK) {
-        ALOGE("JetPlayer::init(): Error initializing JET library; AudioTrack error %d", status);
-        mAudioTrack.clear();
-        mState = EAS_STATE_ERROR;
-        return EAS_FAILURE;
-    }
-
-    // create render and playback thread
-    {
-        Mutex::Autolock l(mMutex);
-        ALOGV("JetPlayer::init(): trying to start render thread");
-        mThread = new JetPlayerThread(this);
-        mThread->run("jetRenderThread", ANDROID_PRIORITY_AUDIO);
-        mCondition.wait(mMutex);
-    }
-    if (mTid > 0) {
-        // render thread started, we're ready
-        ALOGV("JetPlayer::init(): render thread(%d) successfully started.", mTid);
-        mState = EAS_STATE_READY;
-    } else {
-        ALOGE("JetPlayer::init(): failed to start render thread.");
-        mState = EAS_STATE_ERROR;
-        return EAS_FAILURE;
-    }
-
-    return EAS_SUCCESS;
-}
-
-void JetPlayer::setEventCallback(jetevent_callback eventCallback)
-{
-    Mutex::Autolock l(mMutex);
-    mEventCallback = eventCallback;
-}
-
-//-------------------------------------------------------------------------------------------------
-int JetPlayer::release()
-{
-    ALOGV("JetPlayer::release()");
-    Mutex::Autolock lock(mMutex);
-    mPaused = true;
-    mRender = false;
-    if (mEasData) {
-        JET_Pause(mEasData);
-        JET_CloseFile(mEasData);
-        JET_Shutdown(mEasData);
-        EAS_Shutdown(mEasData);
-    }
-    delete mIoWrapper;
-    mIoWrapper = NULL;
-    if (mAudioTrack != 0) {
-        mAudioTrack->stop();
-        mAudioTrack->flush();
-        mAudioTrack.clear();
-    }
-    if (mAudioBuffer) {
-        delete mAudioBuffer;
-        mAudioBuffer = NULL;
-    }
-    mEasData = NULL;
-
-    return EAS_SUCCESS;
-}
-
-
-//-------------------------------------------------------------------------------------------------
-int JetPlayer::render() {
-    EAS_RESULT result = EAS_FAILURE;
-    EAS_I32 count;
-    int temp;
-    bool audioStarted = false;
-
-    ALOGV("JetPlayer::render(): entering");
-
-    // allocate render buffer
-    mAudioBuffer =
-        new EAS_PCM[pLibConfig->mixBufferSize * pLibConfig->numChannels * MIX_NUM_BUFFERS];
-
-    // signal main thread that we started
-    {
-        Mutex::Autolock l(mMutex);
-        mTid = gettid();
-        ALOGV("JetPlayer::render(): render thread(%d) signal", mTid);
-        mCondition.signal();
-    }
-
-    while (1) {
-
-        mMutex.lock(); // [[[[[[[[ LOCK ---------------------------------------
-
-        if (mEasData == NULL) {
-            mMutex.unlock();
-            ALOGV("JetPlayer::render(): NULL EAS data, exiting render.");
-            goto threadExit;
-        }
-
-        // nothing to render, wait for client thread to wake us up
-        while (!mRender)
-        {
-            ALOGV("JetPlayer::render(): signal wait");
-            if (audioStarted) {
-                mAudioTrack->pause();
-                // we have to restart the playback once we start rendering again
-                audioStarted = false;
-            }
-            mCondition.wait(mMutex);
-            ALOGV("JetPlayer::render(): signal rx'd");
-        }
-
-        // render midi data into the input buffer
-        int num_output = 0;
-        EAS_PCM* p = mAudioBuffer;
-        for (int i = 0; i < MIX_NUM_BUFFERS; i++) {
-            result = EAS_Render(mEasData, p, pLibConfig->mixBufferSize, &count);
-            if (result != EAS_SUCCESS) {
-                ALOGE("JetPlayer::render(): EAS_Render returned error %ld", result);
-            }
-            p += count * pLibConfig->numChannels;
-            num_output += count * pLibConfig->numChannels * sizeof(EAS_PCM);
-
-            // send events that were generated (if any) to the event callback
-            fireEventsFromJetQueue();
-        }
-
-        // update playback state
-        //ALOGV("JetPlayer::render(): updating state");
-        JET_Status(mEasData, &mJetStatus);
-        fireUpdateOnStatusChange();
-        mPaused = mJetStatus.paused;
-
-        mMutex.unlock(); // UNLOCK ]]]]]]]] -----------------------------------
-
-        // check audio output track
-        if (mAudioTrack == NULL) {
-            ALOGE("JetPlayer::render(): output AudioTrack was not created");
-            goto threadExit;
-        }
-
-        // Write data to the audio hardware
-        //ALOGV("JetPlayer::render(): writing to audio output");
-        if ((temp = mAudioTrack->write(mAudioBuffer, num_output)) < 0) {
-            ALOGE("JetPlayer::render(): Error in writing:%d",temp);
-            return temp;
-        }
-
-        // start audio output if necessary
-        if (!audioStarted) {
-            ALOGV("JetPlayer::render(): starting audio playback");
-            mAudioTrack->start();
-            audioStarted = true;
-        }
-
-    }//while (1)
-
-threadExit:
-    if (mAudioTrack != NULL) {
-        mAudioTrack->stop();
-        mAudioTrack->flush();
-    }
-    delete [] mAudioBuffer;
-    mAudioBuffer = NULL;
-    mMutex.lock();
-    mTid = -1;
-    mCondition.signal();
-    mMutex.unlock();
-    return result;
-}
-
-
-//-------------------------------------------------------------------------------------------------
-// fire up an update if any of the status fields has changed
-// precondition: mMutex locked
-void JetPlayer::fireUpdateOnStatusChange()
-{
-    if ( (mJetStatus.currentUserID      != mPreviousJetStatus.currentUserID)
-       ||(mJetStatus.segmentRepeatCount != mPreviousJetStatus.segmentRepeatCount) ) {
-        if (mEventCallback)  {
-            mEventCallback(
-                JetPlayer::JET_USERID_UPDATE,
-                mJetStatus.currentUserID,
-                mJetStatus.segmentRepeatCount,
-                mJavaJetPlayerRef);
-        }
-        mPreviousJetStatus.currentUserID      = mJetStatus.currentUserID;
-        mPreviousJetStatus.segmentRepeatCount = mJetStatus.segmentRepeatCount;
-    }
-
-    if (mJetStatus.numQueuedSegments != mPreviousJetStatus.numQueuedSegments) {
-        if (mEventCallback)  {
-            mEventCallback(
-                JetPlayer::JET_NUMQUEUEDSEGMENT_UPDATE,
-                mJetStatus.numQueuedSegments,
-                -1,
-                mJavaJetPlayerRef);
-        }
-        mPreviousJetStatus.numQueuedSegments  = mJetStatus.numQueuedSegments;
-    }
-
-    if (mJetStatus.paused != mPreviousJetStatus.paused) {
-        if (mEventCallback)  {
-            mEventCallback(JetPlayer::JET_PAUSE_UPDATE,
-                mJetStatus.paused,
-                -1,
-                mJavaJetPlayerRef);
-        }
-        mPreviousJetStatus.paused = mJetStatus.paused;
-    }
-
-}
-
-
-//-------------------------------------------------------------------------------------------------
-// fire up all the JET events in the JET engine queue (until the queue is empty)
-// precondition: mMutex locked
-void JetPlayer::fireEventsFromJetQueue()
-{
-    if (!mEventCallback) {
-        // no callback, just empty the event queue
-        while (JET_GetEvent(mEasData, NULL, NULL)) { }
-        return;
-    }
-
-    EAS_U32 rawEvent;
-    while (JET_GetEvent(mEasData, &rawEvent, NULL)) {
-        mEventCallback(
-            JetPlayer::JET_EVENT,
-            rawEvent,
-            -1,
-            mJavaJetPlayerRef);
-    }
-}
-
-
-//-------------------------------------------------------------------------------------------------
-int JetPlayer::loadFromFile(const char* path)
-{
-    ALOGV("JetPlayer::loadFromFile(): path=%s", path);
-
-    Mutex::Autolock lock(mMutex);
-
-    delete mIoWrapper;
-    mIoWrapper = new MidiIoWrapper(path);
-
-    EAS_RESULT result = JET_OpenFile(mEasData, mIoWrapper->getLocator());
-    if (result != EAS_SUCCESS)
-        mState = EAS_STATE_ERROR;
-    else
-        mState = EAS_STATE_OPEN;
-    return( result );
-}
-
-
-//-------------------------------------------------------------------------------------------------
-int JetPlayer::loadFromFD(const int fd, const long long offset, const long long length)
-{
-    ALOGV("JetPlayer::loadFromFD(): fd=%d offset=%lld length=%lld", fd, offset, length);
-
-    Mutex::Autolock lock(mMutex);
-
-    delete mIoWrapper;
-    mIoWrapper = new MidiIoWrapper(fd, offset, length);
-
-    EAS_RESULT result = JET_OpenFile(mEasData, mIoWrapper->getLocator());
-    if (result != EAS_SUCCESS)
-        mState = EAS_STATE_ERROR;
-    else
-        mState = EAS_STATE_OPEN;
-    return( result );
-}
-
-
-//-------------------------------------------------------------------------------------------------
-int JetPlayer::closeFile()
-{
-    Mutex::Autolock lock(mMutex);
-    return JET_CloseFile(mEasData);
-}
-
-
-//-------------------------------------------------------------------------------------------------
-int JetPlayer::play()
-{
-    ALOGV("JetPlayer::play(): entering");
-    Mutex::Autolock lock(mMutex);
-
-    EAS_RESULT result = JET_Play(mEasData);
-
-    mPaused = false;
-    mRender = true;
-
-    JET_Status(mEasData, &mJetStatus);
-    this->dumpJetStatus(&mJetStatus);
-
-    fireUpdateOnStatusChange();
-
-    // wake up render thread
-    ALOGV("JetPlayer::play(): wakeup render thread");
-    mCondition.signal();
-
-    return result;
-}
-
-//-------------------------------------------------------------------------------------------------
-int JetPlayer::pause()
-{
-    Mutex::Autolock lock(mMutex);
-    mPaused = true;
-    EAS_RESULT result = JET_Pause(mEasData);
-
-    mRender = false;
-
-    JET_Status(mEasData, &mJetStatus);
-    this->dumpJetStatus(&mJetStatus);
-    fireUpdateOnStatusChange();
-
-
-    return result;
-}
-
-
-//-------------------------------------------------------------------------------------------------
-int JetPlayer::queueSegment(int segmentNum, int libNum, int repeatCount, int transpose,
-        EAS_U32 muteFlags, EAS_U8 userID)
-{
-    ALOGV("JetPlayer::queueSegment segmentNum=%d, libNum=%d, repeatCount=%d, transpose=%d",
-        segmentNum, libNum, repeatCount, transpose);
-    Mutex::Autolock lock(mMutex);
-    return JET_QueueSegment(mEasData, segmentNum, libNum, repeatCount, transpose, muteFlags,
-            userID);
-}
-
-//-------------------------------------------------------------------------------------------------
-int JetPlayer::setMuteFlags(EAS_U32 muteFlags, bool sync)
-{
-    Mutex::Autolock lock(mMutex);
-    return JET_SetMuteFlags(mEasData, muteFlags, sync);
-}
-
-//-------------------------------------------------------------------------------------------------
-int JetPlayer::setMuteFlag(int trackNum, bool muteFlag, bool sync)
-{
-    Mutex::Autolock lock(mMutex);
-    return JET_SetMuteFlag(mEasData, trackNum, muteFlag, sync);
-}
-
-//-------------------------------------------------------------------------------------------------
-int JetPlayer::triggerClip(int clipId)
-{
-    ALOGV("JetPlayer::triggerClip clipId=%d", clipId);
-    Mutex::Autolock lock(mMutex);
-    return JET_TriggerClip(mEasData, clipId);
-}
-
-//-------------------------------------------------------------------------------------------------
-int JetPlayer::clearQueue()
-{
-    ALOGV("JetPlayer::clearQueue");
-    Mutex::Autolock lock(mMutex);
-    return JET_Clear_Queue(mEasData);
-}
-
-//-------------------------------------------------------------------------------------------------
-void JetPlayer::dump()
-{
-}
-
-void JetPlayer::dumpJetStatus(S_JET_STATUS* pJetStatus)
-{
-    if (pJetStatus!=NULL)
-        ALOGV(">> current JET player status: userID=%d segmentRepeatCount=%d numQueuedSegments=%d "
-                "paused=%d",
-                pJetStatus->currentUserID, pJetStatus->segmentRepeatCount,
-                pJetStatus->numQueuedSegments, pJetStatus->paused);
-    else
-        ALOGE(">> JET player status is NULL");
-}
-
-
-} // end namespace android
diff --git a/media/libmedia/MediaUtils.cpp b/media/libmedia/MediaUtils.cpp
index 31972fa..2efb30e 100644
--- a/media/libmedia/MediaUtils.cpp
+++ b/media/libmedia/MediaUtils.cpp
@@ -22,7 +22,7 @@
 #include <sys/resource.h>
 #include <unistd.h>
 
-#include <bionic_malloc.h>
+#include <bionic/malloc.h>
 
 #include "MediaUtils.h"
 
diff --git a/media/libmedia/MidiDeviceInfo.cpp b/media/libmedia/MidiDeviceInfo.cpp
deleted file mode 100644
index 7588e00..0000000
--- a/media/libmedia/MidiDeviceInfo.cpp
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "MidiDeviceInfo"
-
-#include <media/MidiDeviceInfo.h>
-
-#include <binder/Parcel.h>
-#include <log/log.h>
-#include <utils/Errors.h>
-#include <utils/String16.h>
-
-namespace android {
-namespace media {
-namespace midi {
-
-// The constant values need to be kept in sync with MidiDeviceInfo.java.
-// static
-const char* const MidiDeviceInfo::PROPERTY_NAME = "name";
-const char* const MidiDeviceInfo::PROPERTY_MANUFACTURER = "manufacturer";
-const char* const MidiDeviceInfo::PROPERTY_PRODUCT = "product";
-const char* const MidiDeviceInfo::PROPERTY_VERSION = "version";
-const char* const MidiDeviceInfo::PROPERTY_SERIAL_NUMBER = "serial_number";
-const char* const MidiDeviceInfo::PROPERTY_ALSA_CARD = "alsa_card";
-const char* const MidiDeviceInfo::PROPERTY_ALSA_DEVICE = "alsa_device";
-
-String16 MidiDeviceInfo::getProperty(const char* propertyName) {
-    String16 value;
-    if (mProperties.getString(String16(propertyName), &value)) {
-        return value;
-    } else {
-        return String16();
-    }
-}
-
-#define RETURN_IF_FAILED(calledOnce)                                     \
-    {                                                                    \
-        status_t returnStatus = calledOnce;                              \
-        if (returnStatus) {                                              \
-            ALOGE("Failed at %s:%d (%s)", __FILE__, __LINE__, __func__); \
-            return returnStatus;                                         \
-         }                                                               \
-    }
-
-status_t MidiDeviceInfo::writeToParcel(Parcel* parcel) const {
-    // Needs to be kept in sync with code in MidiDeviceInfo.java
-    RETURN_IF_FAILED(parcel->writeInt32(mType));
-    RETURN_IF_FAILED(parcel->writeInt32(mId));
-    RETURN_IF_FAILED(parcel->writeInt32((int32_t)mInputPortNames.size()));
-    RETURN_IF_FAILED(parcel->writeInt32((int32_t)mOutputPortNames.size()));
-    RETURN_IF_FAILED(writeStringVector(parcel, mInputPortNames));
-    RETURN_IF_FAILED(writeStringVector(parcel, mOutputPortNames));
-    RETURN_IF_FAILED(parcel->writeInt32(mIsPrivate ? 1 : 0));
-    RETURN_IF_FAILED(mProperties.writeToParcel(parcel));
-    // This corresponds to "extra" properties written by Java code
-    RETURN_IF_FAILED(mProperties.writeToParcel(parcel));
-    return OK;
-}
-
-status_t MidiDeviceInfo::readFromParcel(const Parcel* parcel) {
-    // Needs to be kept in sync with code in MidiDeviceInfo.java
-    RETURN_IF_FAILED(parcel->readInt32(&mType));
-    RETURN_IF_FAILED(parcel->readInt32(&mId));
-    int32_t inputPortCount;
-    RETURN_IF_FAILED(parcel->readInt32(&inputPortCount));
-    int32_t outputPortCount;
-    RETURN_IF_FAILED(parcel->readInt32(&outputPortCount));
-    RETURN_IF_FAILED(readStringVector(parcel, &mInputPortNames, inputPortCount));
-    RETURN_IF_FAILED(readStringVector(parcel, &mOutputPortNames, outputPortCount));
-    int32_t isPrivate;
-    RETURN_IF_FAILED(parcel->readInt32(&isPrivate));
-    mIsPrivate = isPrivate == 1;
-    RETURN_IF_FAILED(mProperties.readFromParcel(parcel));
-    // Ignore "extra" properties as they may contain Java Parcelables
-    return OK;
-}
-
-status_t MidiDeviceInfo::readStringVector(
-        const Parcel* parcel, Vector<String16> *vectorPtr, size_t defaultLength) {
-    std::unique_ptr<std::vector<std::unique_ptr<String16>>> v;
-    status_t result = parcel->readString16Vector(&v);
-    if (result != OK) return result;
-    vectorPtr->clear();
-    if (v.get() != nullptr) {
-        for (const auto& iter : *v) {
-            if (iter.get() != nullptr) {
-                vectorPtr->push_back(*iter);
-            } else {
-                vectorPtr->push_back(String16());
-            }
-        }
-    } else {
-        vectorPtr->resize(defaultLength);
-    }
-    return OK;
-}
-
-status_t MidiDeviceInfo::writeStringVector(Parcel* parcel, const Vector<String16>& vector) const {
-    std::vector<String16> v;
-    for (size_t i = 0; i < vector.size(); ++i) {
-        v.push_back(vector[i]);
-    }
-    return parcel->writeString16Vector(v);
-}
-
-// Vector does not define operator==
-static inline bool areVectorsEqual(const Vector<String16>& lhs, const Vector<String16>& rhs) {
-    if (lhs.size() != rhs.size()) return false;
-    for (size_t i = 0; i < lhs.size(); ++i) {
-        if (lhs[i] != rhs[i]) return false;
-    }
-    return true;
-}
-
-bool operator==(const MidiDeviceInfo& lhs, const MidiDeviceInfo& rhs) {
-    return (lhs.mType == rhs.mType && lhs.mId == rhs.mId &&
-            areVectorsEqual(lhs.mInputPortNames, rhs.mInputPortNames) &&
-            areVectorsEqual(lhs.mOutputPortNames, rhs.mOutputPortNames) &&
-            lhs.mProperties == rhs.mProperties &&
-            lhs.mIsPrivate == rhs.mIsPrivate);
-}
-
-}  // namespace midi
-}  // namespace media
-}  // namespace android
diff --git a/media/libmedia/MidiIoWrapper.cpp b/media/libmedia/MidiIoWrapper.cpp
index d8ef9cf..6d46363 100644
--- a/media/libmedia/MidiIoWrapper.cpp
+++ b/media/libmedia/MidiIoWrapper.cpp
@@ -17,7 +17,6 @@
 //#define LOG_NDEBUG 0
 #define LOG_TAG "MidiIoWrapper"
 #include <utils/Log.h>
-#include <utils/RefBase.h>
 
 #include <sys/stat.h>
 #include <fcntl.h>
@@ -50,7 +49,7 @@
     mDataSource = nullptr;
 }
 
-class DataSourceUnwrapper : public DataSourceBase {
+class DataSourceUnwrapper {
 
 public:
     explicit DataSourceUnwrapper(CDataSource *csource) {
diff --git a/media/libmedia/NdkWrapper.cpp b/media/libmedia/NdkWrapper.cpp
deleted file mode 100644
index c150407..0000000
--- a/media/libmedia/NdkWrapper.cpp
+++ /dev/null
@@ -1,1290 +0,0 @@
-/*
- * Copyright 2017, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-//#define LOG_NDEBUG 0
-#define LOG_TAG "NdkWrapper"
-
-#include <media/NdkWrapper.h>
-
-#include <android/native_window.h>
-#include <log/log.h>
-#include <media/NdkMediaCodec.h>
-#include <media/NdkMediaCrypto.h>
-#include <media/NdkMediaDrm.h>
-#include <media/NdkMediaFormat.h>
-#include <media/NdkMediaExtractor.h>
-#include <media/stagefright/MetaData.h>
-#include <media/stagefright/foundation/ABuffer.h>
-#include <media/stagefright/foundation/AMessage.h>
-#include <utils/Errors.h>
-
-#include "NdkMediaDataSourceCallbacksPriv.h"
-
-namespace android {
-
-static const size_t kAESBlockSize = 16;  // AES_BLOCK_SIZE
-
-static const char *AMediaFormatKeyGroupInt32[] = {
-    AMEDIAFORMAT_KEY_AAC_DRC_ATTENUATION_FACTOR,
-    AMEDIAFORMAT_KEY_AAC_DRC_BOOST_FACTOR,
-    AMEDIAFORMAT_KEY_AAC_DRC_HEAVY_COMPRESSION,
-    AMEDIAFORMAT_KEY_AAC_DRC_TARGET_REFERENCE_LEVEL,
-    AMEDIAFORMAT_KEY_AAC_ENCODED_TARGET_LEVEL,
-    AMEDIAFORMAT_KEY_AAC_MAX_OUTPUT_CHANNEL_COUNT,
-    AMEDIAFORMAT_KEY_AAC_PROFILE,
-    AMEDIAFORMAT_KEY_AAC_SBR_MODE,
-    AMEDIAFORMAT_KEY_AUDIO_SESSION_ID,
-    AMEDIAFORMAT_KEY_BITRATE_MODE,
-    AMEDIAFORMAT_KEY_BIT_RATE,
-    AMEDIAFORMAT_KEY_CAPTURE_RATE,
-    AMEDIAFORMAT_KEY_CHANNEL_COUNT,
-    AMEDIAFORMAT_KEY_CHANNEL_MASK,
-    AMEDIAFORMAT_KEY_COLOR_FORMAT,
-    AMEDIAFORMAT_KEY_COLOR_RANGE,
-    AMEDIAFORMAT_KEY_COLOR_STANDARD,
-    AMEDIAFORMAT_KEY_COLOR_TRANSFER,
-    AMEDIAFORMAT_KEY_COMPLEXITY,
-    AMEDIAFORMAT_KEY_CREATE_INPUT_SURFACE_SUSPENDED,
-    AMEDIAFORMAT_KEY_CRYPTO_DEFAULT_IV_SIZE,
-    AMEDIAFORMAT_KEY_CRYPTO_ENCRYPTED_BYTE_BLOCK,
-    AMEDIAFORMAT_KEY_CRYPTO_MODE,
-    AMEDIAFORMAT_KEY_CRYPTO_SKIP_BYTE_BLOCK,
-    AMEDIAFORMAT_KEY_FLAC_COMPRESSION_LEVEL,
-    AMEDIAFORMAT_KEY_GRID_COLUMNS,
-    AMEDIAFORMAT_KEY_GRID_ROWS,
-    AMEDIAFORMAT_KEY_HAPTIC_CHANNEL_COUNT,
-    AMEDIAFORMAT_KEY_HEIGHT,
-    AMEDIAFORMAT_KEY_INTRA_REFRESH_PERIOD,
-    AMEDIAFORMAT_KEY_IS_ADTS,
-    AMEDIAFORMAT_KEY_IS_AUTOSELECT,
-    AMEDIAFORMAT_KEY_IS_DEFAULT,
-    AMEDIAFORMAT_KEY_IS_FORCED_SUBTITLE,
-    AMEDIAFORMAT_KEY_LATENCY,
-    AMEDIAFORMAT_KEY_LEVEL,
-    AMEDIAFORMAT_KEY_MAX_HEIGHT,
-    AMEDIAFORMAT_KEY_MAX_INPUT_SIZE,
-    AMEDIAFORMAT_KEY_MAX_WIDTH,
-    AMEDIAFORMAT_KEY_PCM_ENCODING,
-    AMEDIAFORMAT_KEY_PRIORITY,
-    AMEDIAFORMAT_KEY_PROFILE,
-    AMEDIAFORMAT_KEY_PUSH_BLANK_BUFFERS_ON_STOP,
-    AMEDIAFORMAT_KEY_ROTATION,
-    AMEDIAFORMAT_KEY_SAMPLE_RATE,
-    AMEDIAFORMAT_KEY_SLICE_HEIGHT,
-    AMEDIAFORMAT_KEY_STRIDE,
-    AMEDIAFORMAT_KEY_TRACK_ID,
-    AMEDIAFORMAT_KEY_WIDTH,
-    AMEDIAFORMAT_KEY_DISPLAY_HEIGHT,
-    AMEDIAFORMAT_KEY_DISPLAY_WIDTH,
-    AMEDIAFORMAT_KEY_TEMPORAL_LAYER_ID,
-    AMEDIAFORMAT_KEY_TILE_HEIGHT,
-    AMEDIAFORMAT_KEY_TILE_WIDTH,
-    AMEDIAFORMAT_KEY_TRACK_INDEX,
-};
-
-static const char *AMediaFormatKeyGroupInt64[] = {
-    AMEDIAFORMAT_KEY_DURATION,
-    AMEDIAFORMAT_KEY_MAX_PTS_GAP_TO_ENCODER,
-    AMEDIAFORMAT_KEY_REPEAT_PREVIOUS_FRAME_AFTER,
-    AMEDIAFORMAT_KEY_TIME_US,
-};
-
-static const char *AMediaFormatKeyGroupString[] = {
-    AMEDIAFORMAT_KEY_LANGUAGE,
-    AMEDIAFORMAT_KEY_MIME,
-    AMEDIAFORMAT_KEY_TEMPORAL_LAYERING,
-};
-
-static const char *AMediaFormatKeyGroupBuffer[] = {
-    AMEDIAFORMAT_KEY_CRYPTO_IV,
-    AMEDIAFORMAT_KEY_CRYPTO_KEY,
-    AMEDIAFORMAT_KEY_HDR_STATIC_INFO,
-    AMEDIAFORMAT_KEY_SEI,
-    AMEDIAFORMAT_KEY_MPEG_USER_DATA,
-};
-
-static const char *AMediaFormatKeyGroupCsd[] = {
-    AMEDIAFORMAT_KEY_CSD_0,
-    AMEDIAFORMAT_KEY_CSD_1,
-    AMEDIAFORMAT_KEY_CSD_2,
-};
-
-static const char *AMediaFormatKeyGroupRect[] = {
-    AMEDIAFORMAT_KEY_DISPLAY_CROP,
-};
-
-static const char *AMediaFormatKeyGroupFloatInt32[] = {
-    AMEDIAFORMAT_KEY_FRAME_RATE,
-    AMEDIAFORMAT_KEY_I_FRAME_INTERVAL,
-    AMEDIAFORMAT_KEY_MAX_FPS_TO_ENCODER,
-    AMEDIAFORMAT_KEY_OPERATING_RATE,
-};
-
-static status_t translateErrorCode(media_status_t err) {
-    if (err == AMEDIA_OK) {
-        return OK;
-    } else if (err == AMEDIA_ERROR_END_OF_STREAM) {
-        return ERROR_END_OF_STREAM;
-    } else if (err == AMEDIA_ERROR_IO) {
-        return ERROR_IO;
-    } else if (err == AMEDIACODEC_INFO_TRY_AGAIN_LATER) {
-        return -EAGAIN;
-    }
-
-    ALOGE("ndk error code: %d", err);
-    return UNKNOWN_ERROR;
-}
-
-static int32_t translateActionCode(int32_t actionCode) {
-    if (AMediaCodecActionCode_isTransient(actionCode)) {
-        return ACTION_CODE_TRANSIENT;
-    } else if (AMediaCodecActionCode_isRecoverable(actionCode)) {
-        return ACTION_CODE_RECOVERABLE;
-    }
-    return ACTION_CODE_FATAL;
-}
-
-static CryptoPlugin::Mode translateToCryptoPluginMode(cryptoinfo_mode_t mode) {
-    CryptoPlugin::Mode ret = CryptoPlugin::kMode_Unencrypted;
-    switch (mode) {
-        case AMEDIACODECRYPTOINFO_MODE_AES_CTR: {
-            ret = CryptoPlugin::kMode_AES_CTR;
-            break;
-        }
-
-        case AMEDIACODECRYPTOINFO_MODE_AES_WV: {
-            ret = CryptoPlugin::kMode_AES_WV;
-            break;
-        }
-
-        case AMEDIACODECRYPTOINFO_MODE_AES_CBC: {
-            ret = CryptoPlugin::kMode_AES_CBC;
-            break;
-        }
-
-        default:
-            break;
-    }
-
-    return ret;
-}
-
-static cryptoinfo_mode_t translateToCryptoInfoMode(CryptoPlugin::Mode mode) {
-    cryptoinfo_mode_t ret = AMEDIACODECRYPTOINFO_MODE_CLEAR;
-    switch (mode) {
-        case CryptoPlugin::kMode_AES_CTR: {
-            ret = AMEDIACODECRYPTOINFO_MODE_AES_CTR;
-            break;
-        }
-
-        case CryptoPlugin::kMode_AES_WV: {
-            ret = AMEDIACODECRYPTOINFO_MODE_AES_WV;
-            break;
-        }
-
-        case CryptoPlugin::kMode_AES_CBC: {
-            ret = AMEDIACODECRYPTOINFO_MODE_AES_CBC;
-            break;
-        }
-
-        default:
-            break;
-    }
-
-    return ret;
-}
-
-//////////// AMediaFormatWrapper
-// static
-sp<AMediaFormatWrapper> AMediaFormatWrapper::Create(const sp<AMessage> &message) {
-    sp<AMediaFormatWrapper> aMediaFormat = new AMediaFormatWrapper();
-
-    for (size_t i = 0; i < message->countEntries(); ++i) {
-        AMessage::Type valueType;
-        const char *key = message->getEntryNameAt(i, &valueType);
-
-        switch (valueType) {
-            case AMessage::kTypeInt32: {
-                int32_t val;
-                if (!message->findInt32(key, &val)) {
-                    ALOGE("AMediaFormatWrapper::Create: error at item %zu", i);
-                    continue;
-                }
-                aMediaFormat->setInt32(key, val);
-                break;
-            }
-
-            case AMessage::kTypeInt64: {
-                int64_t val;
-                if (!message->findInt64(key, &val)) {
-                    ALOGE("AMediaFormatWrapper::Create: error at item %zu", i);
-                    continue;
-                }
-                aMediaFormat->setInt64(key, val);
-                break;
-            }
-
-            case AMessage::kTypeFloat: {
-                float val;
-                if (!message->findFloat(key, &val)) {
-                    ALOGE("AMediaFormatWrapper::Create: error at item %zu", i);
-                    continue;
-                }
-                aMediaFormat->setFloat(key, val);
-                break;
-            }
-
-            case AMessage::kTypeDouble: {
-                double val;
-                if (!message->findDouble(key, &val)) {
-                    ALOGE("AMediaFormatWrapper::Create: error at item %zu", i);
-                    continue;
-                }
-                aMediaFormat->setDouble(key, val);
-                break;
-            }
-
-            case AMessage::kTypeSize: {
-                size_t val;
-                if (!message->findSize(key, &val)) {
-                    ALOGE("AMediaFormatWrapper::Create: error at item %zu", i);
-                    continue;
-                }
-                aMediaFormat->setSize(key, val);
-                break;
-            }
-
-            case AMessage::kTypeRect: {
-                int32_t left, top, right, bottom;
-                if (!message->findRect(key, &left, &top, &right, &bottom)) {
-                    ALOGE("AMediaFormatWrapper::Create: error at item %zu", i);
-                    continue;
-                }
-                aMediaFormat->setRect(key, left, top, right, bottom);
-                break;
-            }
-
-            case AMessage::kTypeString: {
-                AString val;
-                if (!message->findString(key, &val)) {
-                    ALOGE("AMediaFormatWrapper::Create: error at item %zu", i);
-                    continue;
-                }
-                aMediaFormat->setString(key, val);
-                break;
-            }
-
-            case AMessage::kTypeBuffer: {
-                sp<ABuffer> val;
-                if (!message->findBuffer(key, &val)) {
-                    ALOGE("AMediaFormatWrapper::Create: error at item %zu", i);
-                    continue;
-                }
-                aMediaFormat->setBuffer(key, val->data(), val->size());
-                break;
-            }
-
-            default: {
-                break;
-            }
-        }
-    }
-
-    return aMediaFormat;
-}
-
-AMediaFormatWrapper::AMediaFormatWrapper() {
-    mAMediaFormat = AMediaFormat_new();
-}
-
-AMediaFormatWrapper::AMediaFormatWrapper(AMediaFormat *aMediaFormat)
-    : mAMediaFormat(aMediaFormat) {
-}
-
-AMediaFormatWrapper::~AMediaFormatWrapper() {
-    release();
-}
-
-status_t AMediaFormatWrapper::release() {
-    if (mAMediaFormat != NULL) {
-        media_status_t err = AMediaFormat_delete(mAMediaFormat);
-        mAMediaFormat = NULL;
-        return translateErrorCode(err);
-    }
-    return OK;
-}
-
-AMediaFormat *AMediaFormatWrapper::getAMediaFormat() const {
-    return mAMediaFormat;
-}
-
-sp<AMessage> AMediaFormatWrapper::toAMessage() const {
-  sp<AMessage> msg;
-  writeToAMessage(msg);
-  return msg;
-}
-
-void AMediaFormatWrapper::writeToAMessage(sp<AMessage> &msg) const {
-    if (mAMediaFormat == NULL) {
-        msg = NULL;
-    }
-
-    if (msg == NULL) {
-        msg = new AMessage;
-    }
-    for (auto& key : AMediaFormatKeyGroupInt32) {
-        int32_t val;
-        if (getInt32(key, &val)) {
-            msg->setInt32(key, val);
-        }
-    }
-    for (auto& key : AMediaFormatKeyGroupInt64) {
-        int64_t val;
-        if (getInt64(key, &val)) {
-            msg->setInt64(key, val);
-        }
-    }
-    for (auto& key : AMediaFormatKeyGroupString) {
-        AString val;
-        if (getString(key, &val)) {
-            msg->setString(key, val);
-        }
-    }
-    for (auto& key : AMediaFormatKeyGroupBuffer) {
-        void *data;
-        size_t size;
-        if (getBuffer(key, &data, &size)) {
-            sp<ABuffer> buffer = ABuffer::CreateAsCopy(data, size);
-            msg->setBuffer(key, buffer);
-        }
-    }
-    for (auto& key : AMediaFormatKeyGroupCsd) {
-        void *data;
-        size_t size;
-        if (getBuffer(key, &data, &size)) {
-            sp<ABuffer> buffer = ABuffer::CreateAsCopy(data, size);
-            buffer->meta()->setInt32(AMEDIAFORMAT_KEY_CSD, 1);
-            buffer->meta()->setInt64(AMEDIAFORMAT_KEY_TIME_US, 0);
-            msg->setBuffer(key, buffer);
-        }
-    }
-    for (auto& key : AMediaFormatKeyGroupRect) {
-        int32_t left, top, right, bottom;
-        if (getRect(key, &left, &top, &right, &bottom)) {
-            msg->setRect(key, left, top, right, bottom);
-        }
-    }
-    for (auto& key : AMediaFormatKeyGroupFloatInt32) {
-        float valFloat;
-        if (getFloat(key, &valFloat)) {
-            msg->setFloat(key, valFloat);
-        } else {
-            int32_t valInt32;
-            if (getInt32(key, &valInt32)) {
-                msg->setFloat(key, (float)valInt32);
-            }
-        }
-    }
-}
-
-const char* AMediaFormatWrapper::toString() const {
-    if (mAMediaFormat == NULL) {
-        return NULL;
-    }
-    return AMediaFormat_toString(mAMediaFormat);
-}
-
-bool AMediaFormatWrapper::getInt32(const char *name, int32_t *out) const {
-    if (mAMediaFormat == NULL) {
-        return false;
-    }
-    return AMediaFormat_getInt32(mAMediaFormat, name, out);
-}
-
-bool AMediaFormatWrapper::getInt64(const char *name, int64_t *out) const {
-    if (mAMediaFormat == NULL) {
-        return false;
-    }
-    return AMediaFormat_getInt64(mAMediaFormat, name, out);
-}
-
-bool AMediaFormatWrapper::getFloat(const char *name, float *out) const {
-    if (mAMediaFormat == NULL) {
-        return false;
-    }
-    return AMediaFormat_getFloat(mAMediaFormat, name, out);
-}
-
-bool AMediaFormatWrapper::getDouble(const char *name, double *out) const {
-    if (mAMediaFormat == NULL) {
-        return false;
-    }
-    return AMediaFormat_getDouble(mAMediaFormat, name, out);
-}
-
-bool AMediaFormatWrapper::getSize(const char *name, size_t *out) const {
-    if (mAMediaFormat == NULL) {
-        return false;
-    }
-    return AMediaFormat_getSize(mAMediaFormat, name, out);
-}
-
-bool AMediaFormatWrapper::getRect(
-        const char *name, int32_t *left, int32_t *top, int32_t *right, int32_t *bottom) const {
-    if (mAMediaFormat == NULL) {
-        return false;
-    }
-    return AMediaFormat_getRect(mAMediaFormat, name, left, top, right, bottom);
-}
-
-bool AMediaFormatWrapper::getBuffer(const char *name, void** data, size_t *outSize) const {
-    if (mAMediaFormat == NULL) {
-        return false;
-    }
-    return AMediaFormat_getBuffer(mAMediaFormat, name, data, outSize);
-}
-
-bool AMediaFormatWrapper::getString(const char *name, AString *out) const {
-    if (mAMediaFormat == NULL) {
-        return false;
-    }
-    const char *outChar = NULL;
-    bool ret = AMediaFormat_getString(mAMediaFormat, name, &outChar);
-    if (ret) {
-        *out = AString(outChar);
-    }
-    return ret;
-}
-
-void AMediaFormatWrapper::setInt32(const char* name, int32_t value) {
-    if (mAMediaFormat != NULL) {
-        AMediaFormat_setInt32(mAMediaFormat, name, value);
-    }
-}
-
-void AMediaFormatWrapper::setInt64(const char* name, int64_t value) {
-    if (mAMediaFormat != NULL) {
-        AMediaFormat_setInt64(mAMediaFormat, name, value);
-    }
-}
-
-void AMediaFormatWrapper::setFloat(const char* name, float value) {
-    if (mAMediaFormat != NULL) {
-        AMediaFormat_setFloat(mAMediaFormat, name, value);
-    }
-}
-
-void AMediaFormatWrapper::setDouble(const char* name, double value) {
-    if (mAMediaFormat != NULL) {
-        AMediaFormat_setDouble(mAMediaFormat, name, value);
-    }
-}
-
-void AMediaFormatWrapper::setSize(const char* name, size_t value) {
-    if (mAMediaFormat != NULL) {
-        AMediaFormat_setSize(mAMediaFormat, name, value);
-    }
-}
-
-void AMediaFormatWrapper::setRect(
-        const char* name, int32_t left, int32_t top, int32_t right, int32_t bottom) {
-    if (mAMediaFormat != NULL) {
-        AMediaFormat_setRect(mAMediaFormat, name, left, top, right, bottom);
-    }
-}
-
-void AMediaFormatWrapper::setString(const char* name, const AString &value) {
-    if (mAMediaFormat != NULL) {
-        AMediaFormat_setString(mAMediaFormat, name, value.c_str());
-    }
-}
-
-void AMediaFormatWrapper::setBuffer(const char* name, void* data, size_t size) {
-    if (mAMediaFormat != NULL) {
-        AMediaFormat_setBuffer(mAMediaFormat, name, data, size);
-    }
-}
-
-
-//////////// ANativeWindowWrapper
-ANativeWindowWrapper::ANativeWindowWrapper(ANativeWindow *aNativeWindow)
-    : mANativeWindow(aNativeWindow) {
-    if (aNativeWindow != NULL) {
-        ANativeWindow_acquire(aNativeWindow);
-    }
-}
-
-ANativeWindowWrapper::~ANativeWindowWrapper() {
-    release();
-}
-
-status_t ANativeWindowWrapper::release() {
-    if (mANativeWindow != NULL) {
-        ANativeWindow_release(mANativeWindow);
-        mANativeWindow = NULL;
-    }
-    return OK;
-}
-
-ANativeWindow *ANativeWindowWrapper::getANativeWindow() const {
-    return mANativeWindow;
-}
-
-
-//////////// AMediaDrmWrapper
-AMediaDrmWrapper::AMediaDrmWrapper(const uint8_t uuid[16]) {
-    mAMediaDrm = AMediaDrm_createByUUID(uuid);
-}
-
-AMediaDrmWrapper::AMediaDrmWrapper(AMediaDrm *aMediaDrm)
-    : mAMediaDrm(aMediaDrm) {
-}
-
-AMediaDrmWrapper::~AMediaDrmWrapper() {
-    release();
-}
-
-status_t AMediaDrmWrapper::release() {
-    if (mAMediaDrm != NULL) {
-        AMediaDrm_release(mAMediaDrm);
-        mAMediaDrm = NULL;
-    }
-    return OK;
-}
-
-AMediaDrm *AMediaDrmWrapper::getAMediaDrm() const {
-    return mAMediaDrm;
-}
-
-// static
-bool AMediaDrmWrapper::isCryptoSchemeSupported(
-        const uint8_t uuid[16],
-        const char *mimeType) {
-    return AMediaDrm_isCryptoSchemeSupported(uuid, mimeType);
-}
-
-
-//////////// AMediaCryptoWrapper
-AMediaCryptoWrapper::AMediaCryptoWrapper(
-        const uint8_t uuid[16], const void *initData, size_t initDataSize) {
-    mAMediaCrypto = AMediaCrypto_new(uuid, initData, initDataSize);
-}
-
-AMediaCryptoWrapper::AMediaCryptoWrapper(AMediaCrypto *aMediaCrypto)
-    : mAMediaCrypto(aMediaCrypto) {
-}
-
-AMediaCryptoWrapper::~AMediaCryptoWrapper() {
-    release();
-}
-
-status_t AMediaCryptoWrapper::release() {
-    if (mAMediaCrypto != NULL) {
-        AMediaCrypto_delete(mAMediaCrypto);
-        mAMediaCrypto = NULL;
-    }
-    return OK;
-}
-
-AMediaCrypto *AMediaCryptoWrapper::getAMediaCrypto() const {
-    return mAMediaCrypto;
-}
-
-bool AMediaCryptoWrapper::isCryptoSchemeSupported(const uint8_t uuid[16]) {
-    if (mAMediaCrypto == NULL) {
-        return false;
-    }
-    return AMediaCrypto_isCryptoSchemeSupported(uuid);
-}
-
-bool AMediaCryptoWrapper::requiresSecureDecoderComponent(const char *mime) {
-    if (mAMediaCrypto == NULL) {
-        return false;
-    }
-    return AMediaCrypto_requiresSecureDecoderComponent(mime);
-}
-
-
-//////////// AMediaCodecCryptoInfoWrapper
-// static
-sp<AMediaCodecCryptoInfoWrapper> AMediaCodecCryptoInfoWrapper::Create(MetaDataBase &meta) {
-
-    uint32_t type;
-    const void *crypteddata;
-    size_t cryptedsize;
-
-    if (!meta.findData(kKeyEncryptedSizes, &type, &crypteddata, &cryptedsize)) {
-        return NULL;
-    }
-
-    int numSubSamples = cryptedsize / sizeof(size_t);
-
-    if (numSubSamples <= 0) {
-        ALOGE("Create: INVALID numSubSamples: %d", numSubSamples);
-        return NULL;
-    }
-
-    const void *cleardata;
-    size_t clearsize;
-    if (meta.findData(kKeyPlainSizes, &type, &cleardata, &clearsize)) {
-        if (clearsize != cryptedsize) {
-            // The two must be of the same length.
-            ALOGE("Create: mismatch cryptedsize: %zu != clearsize: %zu", cryptedsize, clearsize);
-            return NULL;
-        }
-    }
-
-    const void *key;
-    size_t keysize;
-    if (meta.findData(kKeyCryptoKey, &type, &key, &keysize)) {
-        if (keysize != kAESBlockSize) {
-            // Keys must be 16 bytes in length.
-            ALOGE("Create: Keys must be %zu bytes in length: %zu", kAESBlockSize, keysize);
-            return NULL;
-        }
-    }
-
-    const void *iv;
-    size_t ivsize;
-    if (meta.findData(kKeyCryptoIV, &type, &iv, &ivsize)) {
-        if (ivsize != kAESBlockSize) {
-            // IVs must be 16 bytes in length.
-            ALOGE("Create: IV must be %zu bytes in length: %zu", kAESBlockSize, ivsize);
-            return NULL;
-        }
-    }
-
-    int32_t mode;
-    if (!meta.findInt32(kKeyCryptoMode, &mode)) {
-        mode = CryptoPlugin::kMode_AES_CTR;
-    }
-
-    return new AMediaCodecCryptoInfoWrapper(
-            numSubSamples,
-            (uint8_t*) key,
-            (uint8_t*) iv,
-            (CryptoPlugin::Mode)mode,
-            (size_t*) cleardata,
-            (size_t*) crypteddata);
-}
-
-AMediaCodecCryptoInfoWrapper::AMediaCodecCryptoInfoWrapper(
-        int numsubsamples,
-        uint8_t key[16],
-        uint8_t iv[16],
-        CryptoPlugin::Mode mode,
-        size_t *clearbytes,
-        size_t *encryptedbytes) {
-    mAMediaCodecCryptoInfo =
-        AMediaCodecCryptoInfo_new(numsubsamples,
-                                  key,
-                                  iv,
-                                  translateToCryptoInfoMode(mode),
-                                  clearbytes,
-                                  encryptedbytes);
-}
-
-AMediaCodecCryptoInfoWrapper::AMediaCodecCryptoInfoWrapper(
-        AMediaCodecCryptoInfo *aMediaCodecCryptoInfo)
-    : mAMediaCodecCryptoInfo(aMediaCodecCryptoInfo) {
-}
-
-AMediaCodecCryptoInfoWrapper::~AMediaCodecCryptoInfoWrapper() {
-    release();
-}
-
-status_t AMediaCodecCryptoInfoWrapper::release() {
-    if (mAMediaCodecCryptoInfo != NULL) {
-        media_status_t err = AMediaCodecCryptoInfo_delete(mAMediaCodecCryptoInfo);
-        mAMediaCodecCryptoInfo = NULL;
-        return translateErrorCode(err);
-    }
-    return OK;
-}
-
-AMediaCodecCryptoInfo *AMediaCodecCryptoInfoWrapper::getAMediaCodecCryptoInfo() const {
-    return mAMediaCodecCryptoInfo;
-}
-
-void AMediaCodecCryptoInfoWrapper::setPattern(CryptoPlugin::Pattern *pattern) {
-    if (mAMediaCodecCryptoInfo == NULL || pattern == NULL) {
-        return;
-    }
-    cryptoinfo_pattern_t ndkPattern = {(int32_t)pattern->mEncryptBlocks,
-                                       (int32_t)pattern->mSkipBlocks };
-    return AMediaCodecCryptoInfo_setPattern(mAMediaCodecCryptoInfo, &ndkPattern);
-}
-
-size_t AMediaCodecCryptoInfoWrapper::getNumSubSamples() {
-    if (mAMediaCodecCryptoInfo == NULL) {
-        return 0;
-    }
-    return AMediaCodecCryptoInfo_getNumSubSamples(mAMediaCodecCryptoInfo);
-}
-
-status_t AMediaCodecCryptoInfoWrapper::getKey(uint8_t *dst) {
-    if (mAMediaCodecCryptoInfo == NULL) {
-        return DEAD_OBJECT;
-    }
-    if (dst == NULL) {
-        return BAD_VALUE;
-    }
-    return translateErrorCode(
-        AMediaCodecCryptoInfo_getKey(mAMediaCodecCryptoInfo, dst));
-}
-
-status_t AMediaCodecCryptoInfoWrapper::getIV(uint8_t *dst) {
-    if (mAMediaCodecCryptoInfo == NULL) {
-        return DEAD_OBJECT;
-    }
-    if (dst == NULL) {
-        return BAD_VALUE;
-    }
-    return translateErrorCode(
-        AMediaCodecCryptoInfo_getIV(mAMediaCodecCryptoInfo, dst));
-}
-
-CryptoPlugin::Mode AMediaCodecCryptoInfoWrapper::getMode() {
-    if (mAMediaCodecCryptoInfo == NULL) {
-        return CryptoPlugin::kMode_Unencrypted;
-    }
-    return translateToCryptoPluginMode(
-        AMediaCodecCryptoInfo_getMode(mAMediaCodecCryptoInfo));
-}
-
-status_t AMediaCodecCryptoInfoWrapper::getClearBytes(size_t *dst) {
-    if (mAMediaCodecCryptoInfo == NULL) {
-        return DEAD_OBJECT;
-    }
-    if (dst == NULL) {
-        return BAD_VALUE;
-    }
-    return translateErrorCode(
-        AMediaCodecCryptoInfo_getClearBytes(mAMediaCodecCryptoInfo, dst));
-}
-
-status_t AMediaCodecCryptoInfoWrapper::getEncryptedBytes(size_t *dst) {
-    if (mAMediaCodecCryptoInfo == NULL) {
-        return DEAD_OBJECT;
-    }
-    if (dst == NULL) {
-        return BAD_VALUE;
-    }
-    return translateErrorCode(
-        AMediaCodecCryptoInfo_getEncryptedBytes(mAMediaCodecCryptoInfo, dst));
-}
-
-
-//////////// AMediaCodecWrapper
-// static
-sp<AMediaCodecWrapper> AMediaCodecWrapper::CreateCodecByName(const AString &name) {
-    AMediaCodec *aMediaCodec = AMediaCodec_createCodecByName(name.c_str());
-    return new AMediaCodecWrapper(aMediaCodec);
-}
-
-// static
-sp<AMediaCodecWrapper> AMediaCodecWrapper::CreateDecoderByType(const AString &mimeType) {
-    AMediaCodec *aMediaCodec = AMediaCodec_createDecoderByType(mimeType.c_str());
-    return new AMediaCodecWrapper(aMediaCodec);
-}
-
-// static
-void AMediaCodecWrapper::OnInputAvailableCB(
-        AMediaCodec * /* aMediaCodec */,
-        void *userdata,
-        int32_t index) {
-    ALOGV("OnInputAvailableCB: index(%d)", index);
-    sp<AMessage> msg = sp<AMessage>((AMessage *)userdata)->dup();
-    msg->setInt32("callbackID", CB_INPUT_AVAILABLE);
-    msg->setInt32("index", index);
-    msg->post();
-}
-
-// static
-void AMediaCodecWrapper::OnOutputAvailableCB(
-        AMediaCodec * /* aMediaCodec */,
-        void *userdata,
-        int32_t index,
-        AMediaCodecBufferInfo *bufferInfo) {
-    ALOGV("OnOutputAvailableCB: index(%d), (%d, %d, %lld, 0x%x)",
-          index, bufferInfo->offset, bufferInfo->size,
-          (long long)bufferInfo->presentationTimeUs, bufferInfo->flags);
-    sp<AMessage> msg = sp<AMessage>((AMessage *)userdata)->dup();
-    msg->setInt32("callbackID", CB_OUTPUT_AVAILABLE);
-    msg->setInt32("index", index);
-    msg->setSize("offset", (size_t)(bufferInfo->offset));
-    msg->setSize("size", (size_t)(bufferInfo->size));
-    msg->setInt64("timeUs", bufferInfo->presentationTimeUs);
-    msg->setInt32("flags", (int32_t)(bufferInfo->flags));
-    msg->post();
-}
-
-// static
-void AMediaCodecWrapper::OnFormatChangedCB(
-        AMediaCodec * /* aMediaCodec */,
-        void *userdata,
-        AMediaFormat *format) {
-    sp<AMediaFormatWrapper> formatWrapper = new AMediaFormatWrapper(format);
-    sp<AMessage> outputFormat = formatWrapper->toAMessage();
-    ALOGV("OnFormatChangedCB: format(%s)", outputFormat->debugString().c_str());
-
-    sp<AMessage> msg = sp<AMessage>((AMessage *)userdata)->dup();
-    msg->setInt32("callbackID", CB_OUTPUT_FORMAT_CHANGED);
-    msg->setMessage("format", outputFormat);
-    msg->post();
-}
-
-// static
-void AMediaCodecWrapper::OnErrorCB(
-        AMediaCodec * /* aMediaCodec */,
-        void *userdata,
-        media_status_t err,
-        int32_t actionCode,
-        const char *detail) {
-    ALOGV("OnErrorCB: err(%d), actionCode(%d), detail(%s)", err, actionCode, detail);
-    sp<AMessage> msg = sp<AMessage>((AMessage *)userdata)->dup();
-    msg->setInt32("callbackID", CB_ERROR);
-    msg->setInt32("err", translateErrorCode(err));
-    msg->setInt32("actionCode", translateActionCode(actionCode));
-    msg->setString("detail", detail);
-    msg->post();
-}
-
-AMediaCodecWrapper::AMediaCodecWrapper(AMediaCodec *aMediaCodec)
-    : mAMediaCodec(aMediaCodec) {
-}
-
-AMediaCodecWrapper::~AMediaCodecWrapper() {
-    release();
-}
-
-status_t AMediaCodecWrapper::release() {
-    if (mAMediaCodec != NULL) {
-        AMediaCodecOnAsyncNotifyCallback aCB = {};
-        AMediaCodec_setAsyncNotifyCallback(mAMediaCodec, aCB, NULL);
-        mCallback = NULL;
-
-        media_status_t err = AMediaCodec_delete(mAMediaCodec);
-        mAMediaCodec = NULL;
-        return translateErrorCode(err);
-    }
-    return OK;
-}
-
-AMediaCodec *AMediaCodecWrapper::getAMediaCodec() const {
-    return mAMediaCodec;
-}
-
-status_t AMediaCodecWrapper::getName(AString *outComponentName) const {
-    if (mAMediaCodec == NULL) {
-        return DEAD_OBJECT;
-    }
-    char *name = NULL;
-    media_status_t err = AMediaCodec_getName(mAMediaCodec, &name);
-    if (err != AMEDIA_OK) {
-        return translateErrorCode(err);
-    }
-
-    *outComponentName = AString(name);
-    AMediaCodec_releaseName(mAMediaCodec, name);
-    return OK;
-}
-
-status_t AMediaCodecWrapper::configure(
-    const sp<AMediaFormatWrapper> &format,
-    const sp<ANativeWindowWrapper> &nww,
-    const sp<AMediaCryptoWrapper> &crypto,
-    uint32_t flags) {
-    if (mAMediaCodec == NULL) {
-        return DEAD_OBJECT;
-    }
-
-    media_status_t err = AMediaCodec_configure(
-            mAMediaCodec,
-            format->getAMediaFormat(),
-            (nww == NULL ? NULL : nww->getANativeWindow()),
-            crypto == NULL ? NULL : crypto->getAMediaCrypto(),
-            flags);
-
-    return translateErrorCode(err);
-}
-
-status_t AMediaCodecWrapper::setCallback(const sp<AMessage> &callback) {
-    if (mAMediaCodec == NULL) {
-        return DEAD_OBJECT;
-    }
-
-    mCallback = callback;
-
-    AMediaCodecOnAsyncNotifyCallback aCB = {
-        OnInputAvailableCB,
-        OnOutputAvailableCB,
-        OnFormatChangedCB,
-        OnErrorCB
-    };
-
-    return translateErrorCode(
-            AMediaCodec_setAsyncNotifyCallback(mAMediaCodec, aCB, callback.get()));
-}
-
-status_t AMediaCodecWrapper::releaseCrypto() {
-    if (mAMediaCodec == NULL) {
-        return DEAD_OBJECT;
-    }
-    return translateErrorCode(AMediaCodec_releaseCrypto(mAMediaCodec));
-}
-
-status_t AMediaCodecWrapper::start() {
-    if (mAMediaCodec == NULL) {
-        return DEAD_OBJECT;
-    }
-    return translateErrorCode(AMediaCodec_start(mAMediaCodec));
-}
-
-status_t AMediaCodecWrapper::stop() {
-    if (mAMediaCodec == NULL) {
-        return DEAD_OBJECT;
-    }
-    return translateErrorCode(AMediaCodec_stop(mAMediaCodec));
-}
-
-status_t AMediaCodecWrapper::flush() {
-    if (mAMediaCodec == NULL) {
-        return DEAD_OBJECT;
-    }
-    return translateErrorCode(AMediaCodec_flush(mAMediaCodec));
-}
-
-uint8_t* AMediaCodecWrapper::getInputBuffer(size_t idx, size_t *out_size) {
-    if (mAMediaCodec == NULL) {
-        return NULL;
-    }
-    return AMediaCodec_getInputBuffer(mAMediaCodec, idx, out_size);
-}
-
-uint8_t* AMediaCodecWrapper::getOutputBuffer(size_t idx, size_t *out_size) {
-    if (mAMediaCodec == NULL) {
-        return NULL;
-    }
-    return AMediaCodec_getOutputBuffer(mAMediaCodec, idx, out_size);
-}
-
-status_t AMediaCodecWrapper::queueInputBuffer(
-        size_t idx,
-        size_t offset,
-        size_t size,
-        uint64_t time,
-        uint32_t flags) {
-    if (mAMediaCodec == NULL) {
-        return DEAD_OBJECT;
-    }
-    return translateErrorCode(
-        AMediaCodec_queueInputBuffer(mAMediaCodec, idx, offset, size, time, flags));
-}
-
-status_t AMediaCodecWrapper::queueSecureInputBuffer(
-        size_t idx,
-        size_t offset,
-        sp<AMediaCodecCryptoInfoWrapper> &codecCryptoInfo,
-        uint64_t time,
-        uint32_t flags) {
-    if (mAMediaCodec == NULL) {
-        return DEAD_OBJECT;
-    }
-    return translateErrorCode(
-        AMediaCodec_queueSecureInputBuffer(
-            mAMediaCodec,
-            idx,
-            offset,
-            codecCryptoInfo->getAMediaCodecCryptoInfo(),
-            time,
-            flags));
-}
-
-sp<AMediaFormatWrapper> AMediaCodecWrapper::getOutputFormat() {
-    if (mAMediaCodec == NULL) {
-        return NULL;
-    }
-    return new AMediaFormatWrapper(AMediaCodec_getOutputFormat(mAMediaCodec));
-}
-
-sp<AMediaFormatWrapper> AMediaCodecWrapper::getInputFormat() {
-    if (mAMediaCodec == NULL) {
-        return NULL;
-    }
-    return new AMediaFormatWrapper(AMediaCodec_getInputFormat(mAMediaCodec));
-}
-
-status_t AMediaCodecWrapper::releaseOutputBuffer(size_t idx, bool render) {
-    if (mAMediaCodec == NULL) {
-        return DEAD_OBJECT;
-    }
-    return translateErrorCode(
-        AMediaCodec_releaseOutputBuffer(mAMediaCodec, idx, render));
-}
-
-status_t AMediaCodecWrapper::setOutputSurface(const sp<ANativeWindowWrapper> &nww) {
-    if (mAMediaCodec == NULL) {
-        return DEAD_OBJECT;
-    }
-    return translateErrorCode(
-        AMediaCodec_setOutputSurface(mAMediaCodec,
-                                     (nww == NULL ? NULL : nww->getANativeWindow())));
-}
-
-status_t AMediaCodecWrapper::releaseOutputBufferAtTime(size_t idx, int64_t timestampNs) {
-    if (mAMediaCodec == NULL) {
-        return DEAD_OBJECT;
-    }
-    return translateErrorCode(
-        AMediaCodec_releaseOutputBufferAtTime(mAMediaCodec, idx, timestampNs));
-}
-
-status_t AMediaCodecWrapper::setParameters(const sp<AMediaFormatWrapper> &params) {
-    if (mAMediaCodec == NULL) {
-        return DEAD_OBJECT;
-    }
-    return translateErrorCode(
-        AMediaCodec_setParameters(mAMediaCodec, params->getAMediaFormat()));
-}
-
-//////////// AMediaExtractorWrapper
-
-AMediaExtractorWrapper::AMediaExtractorWrapper(AMediaExtractor *aMediaExtractor)
-    : mAMediaExtractor(aMediaExtractor) {
-}
-
-AMediaExtractorWrapper::~AMediaExtractorWrapper() {
-    release();
-}
-
-status_t AMediaExtractorWrapper::release() {
-    if (mAMediaExtractor != NULL) {
-        media_status_t err = AMediaExtractor_delete(mAMediaExtractor);
-        mAMediaExtractor = NULL;
-        return translateErrorCode(err);
-    }
-    return OK;
-}
-
-AMediaExtractor *AMediaExtractorWrapper::getAMediaExtractor() const {
-    return mAMediaExtractor;
-}
-
-status_t AMediaExtractorWrapper::setDataSource(int fd, off64_t offset, off64_t length) {
-    if (mAMediaExtractor == NULL) {
-        return DEAD_OBJECT;
-    }
-    return translateErrorCode(AMediaExtractor_setDataSourceFd(
-            mAMediaExtractor, fd, offset, length));
-}
-
-status_t AMediaExtractorWrapper::setDataSource(const char *location) {
-    if (mAMediaExtractor == NULL) {
-        return DEAD_OBJECT;
-    }
-    return translateErrorCode(AMediaExtractor_setDataSource(mAMediaExtractor, location));
-}
-
-status_t AMediaExtractorWrapper::setDataSource(AMediaDataSource *source) {
-    if (mAMediaExtractor == NULL) {
-        return DEAD_OBJECT;
-    }
-    return translateErrorCode(AMediaExtractor_setDataSourceCustom(mAMediaExtractor, source));
-}
-
-size_t AMediaExtractorWrapper::getTrackCount() {
-    if (mAMediaExtractor == NULL) {
-        return 0;
-    }
-    return AMediaExtractor_getTrackCount(mAMediaExtractor);
-}
-
-sp<AMediaFormatWrapper> AMediaExtractorWrapper::getFormat() {
-    if (mAMediaExtractor == NULL) {
-        return NULL;
-    }
-    return new AMediaFormatWrapper(AMediaExtractor_getFileFormat(mAMediaExtractor));
-}
-
-sp<AMediaFormatWrapper> AMediaExtractorWrapper::getTrackFormat(size_t idx) {
-    if (mAMediaExtractor == NULL) {
-        return NULL;
-    }
-    return new AMediaFormatWrapper(AMediaExtractor_getTrackFormat(mAMediaExtractor, idx));
-}
-
-status_t AMediaExtractorWrapper::selectTrack(size_t idx) {
-    if (mAMediaExtractor == NULL) {
-        return DEAD_OBJECT;
-    }
-    return translateErrorCode(AMediaExtractor_selectTrack(mAMediaExtractor, idx));
-}
-
-status_t AMediaExtractorWrapper::unselectTrack(size_t idx) {
-    if (mAMediaExtractor == NULL) {
-        return DEAD_OBJECT;
-    }
-    return translateErrorCode(AMediaExtractor_unselectTrack(mAMediaExtractor, idx));
-}
-
-status_t AMediaExtractorWrapper::selectSingleTrack(size_t idx) {
-    if (mAMediaExtractor == NULL) {
-        return DEAD_OBJECT;
-    }
-    for (size_t i = 0; i < AMediaExtractor_getTrackCount(mAMediaExtractor); ++i) {
-        if (i == idx) {
-            media_status_t err = AMediaExtractor_selectTrack(mAMediaExtractor, i);
-            if (err != AMEDIA_OK) {
-                return translateErrorCode(err);
-            }
-        } else {
-            media_status_t err = AMediaExtractor_unselectTrack(mAMediaExtractor, i);
-            if (err != AMEDIA_OK) {
-                return translateErrorCode(err);
-            }
-        }
-    }
-    return OK;
-}
-
-ssize_t AMediaExtractorWrapper::readSampleData(const sp<ABuffer> &buffer) {
-    if (mAMediaExtractor == NULL) {
-        return -1;
-    }
-    return AMediaExtractor_readSampleData(mAMediaExtractor, buffer->data(), buffer->capacity());
-}
-
-ssize_t AMediaExtractorWrapper::getSampleSize() {
-    if (mAMediaExtractor == NULL) {
-        return 0;
-    }
-    return AMediaExtractor_getSampleSize(mAMediaExtractor);
-}
-
-uint32_t AMediaExtractorWrapper::getSampleFlags() {
-    if (mAMediaExtractor == NULL) {
-        return 0;
-    }
-    return AMediaExtractor_getSampleFlags(mAMediaExtractor);
-}
-
-int AMediaExtractorWrapper::getSampleTrackIndex() {
-    if (mAMediaExtractor == NULL) {
-        return -1;
-    }
-    return AMediaExtractor_getSampleTrackIndex(mAMediaExtractor);
-}
-
-int64_t AMediaExtractorWrapper::getSampleTime() {
-    if (mAMediaExtractor == NULL) {
-        return -1;
-    }
-    return AMediaExtractor_getSampleTime(mAMediaExtractor);
-}
-
-status_t AMediaExtractorWrapper::getSampleFormat(sp<AMediaFormatWrapper> &formatWrapper) {
-    if (mAMediaExtractor == NULL) {
-        return DEAD_OBJECT;
-    }
-    AMediaFormat *format = AMediaFormat_new();
-    formatWrapper = new AMediaFormatWrapper(format);
-    return translateErrorCode(AMediaExtractor_getSampleFormat(mAMediaExtractor, format));
-}
-
-int64_t AMediaExtractorWrapper::getCachedDuration() {
-    if (mAMediaExtractor == NULL) {
-        return -1;
-    }
-    return AMediaExtractor_getCachedDuration(mAMediaExtractor);
-}
-
-bool AMediaExtractorWrapper::advance() {
-    if (mAMediaExtractor == NULL) {
-        return false;
-    }
-    return AMediaExtractor_advance(mAMediaExtractor);
-}
-
-status_t AMediaExtractorWrapper::seekTo(int64_t seekPosUs, MediaSource::ReadOptions::SeekMode mode) {
-    if (mAMediaExtractor == NULL) {
-        return DEAD_OBJECT;
-    }
-
-    SeekMode aMode;
-    switch (mode) {
-        case MediaSource::ReadOptions::SEEK_PREVIOUS_SYNC: {
-            aMode = AMEDIAEXTRACTOR_SEEK_PREVIOUS_SYNC;
-            break;
-        }
-        case MediaSource::ReadOptions::SEEK_NEXT_SYNC: {
-            aMode = AMEDIAEXTRACTOR_SEEK_NEXT_SYNC;
-            break;
-        }
-        default: {
-            aMode = AMEDIAEXTRACTOR_SEEK_CLOSEST_SYNC;
-            break;
-        }
-    }
-    return AMediaExtractor_seekTo(mAMediaExtractor, seekPosUs, aMode);
-}
-
-PsshInfo* AMediaExtractorWrapper::getPsshInfo() {
-    if (mAMediaExtractor == NULL) {
-        return NULL;
-    }
-    return AMediaExtractor_getPsshInfo(mAMediaExtractor);
-}
-
-sp<AMediaCodecCryptoInfoWrapper> AMediaExtractorWrapper::getSampleCryptoInfo() {
-    if (mAMediaExtractor == NULL) {
-        return NULL;
-    }
-    AMediaCodecCryptoInfo *cryptoInfo = AMediaExtractor_getSampleCryptoInfo(mAMediaExtractor);
-    if (cryptoInfo == NULL) {
-        return NULL;
-    }
-    return new AMediaCodecCryptoInfoWrapper(cryptoInfo);
-}
-
-AMediaDataSourceWrapper::AMediaDataSourceWrapper(const sp<DataSource> &dataSource)
-    : mDataSource(dataSource),
-      mAMediaDataSource(convertDataSourceToAMediaDataSource(dataSource)) {
-}
-
-AMediaDataSourceWrapper::AMediaDataSourceWrapper(AMediaDataSource *aDataSource)
-    : mDataSource(NULL),
-      mAMediaDataSource(aDataSource) {
-}
-
-AMediaDataSourceWrapper::~AMediaDataSourceWrapper() {
-    if (mAMediaDataSource == NULL) {
-        return;
-    }
-    AMediaDataSource_close(mAMediaDataSource);
-    AMediaDataSource_delete(mAMediaDataSource);
-    mAMediaDataSource = NULL;
-}
-
-AMediaDataSource* AMediaDataSourceWrapper::getAMediaDataSource() {
-    return mAMediaDataSource;
-}
-
-void AMediaDataSourceWrapper::close() {
-    AMediaDataSource_close(mAMediaDataSource);
-}
-
-}  // namespace android
diff --git a/media/libmedia/Visualizer.cpp b/media/libmedia/Visualizer.cpp
deleted file mode 100644
index 2bf0802..0000000
--- a/media/libmedia/Visualizer.cpp
+++ /dev/null
@@ -1,445 +0,0 @@
-/*
-**
-** Copyright 2010, 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 "Visualizer"
-#include <utils/Log.h>
-
-#include <stdint.h>
-#include <sys/types.h>
-#include <limits.h>
-
-#include <media/Visualizer.h>
-#include <audio_utils/fixedfft.h>
-#include <utils/Thread.h>
-
-namespace android {
-
-// ---------------------------------------------------------------------------
-
-Visualizer::Visualizer (const String16& opPackageName,
-         int32_t priority,
-         effect_callback_t cbf,
-         void* user,
-         audio_session_t sessionId)
-    :   AudioEffect(SL_IID_VISUALIZATION, opPackageName, NULL, priority, cbf, user, sessionId),
-        mCaptureRate(CAPTURE_RATE_DEF),
-        mCaptureSize(CAPTURE_SIZE_DEF),
-        mSampleRate(44100000),
-        mScalingMode(VISUALIZER_SCALING_MODE_NORMALIZED),
-        mMeasurementMode(MEASUREMENT_MODE_NONE),
-        mCaptureCallBack(NULL),
-        mCaptureCbkUser(NULL)
-{
-    initCaptureSize();
-}
-
-Visualizer::~Visualizer()
-{
-    ALOGV("Visualizer::~Visualizer()");
-    setEnabled(false);
-    setCaptureCallBack(NULL, NULL, 0, 0);
-}
-
-void Visualizer::release()
-{
-    ALOGV("Visualizer::release()");
-    setEnabled(false);
-    Mutex::Autolock _l(mCaptureLock);
-
-    mCaptureThread.clear();
-    mCaptureCallBack = NULL;
-    mCaptureCbkUser = NULL;
-    mCaptureFlags = 0;
-    mCaptureRate = 0;
-}
-
-status_t Visualizer::setEnabled(bool enabled)
-{
-    Mutex::Autolock _l(mCaptureLock);
-
-    sp<CaptureThread> t = mCaptureThread;
-    if (t != 0) {
-        if (enabled) {
-            if (t->exitPending()) {
-                mCaptureLock.unlock();
-                if (t->requestExitAndWait() == WOULD_BLOCK) {
-                    mCaptureLock.lock();
-                    ALOGE("Visualizer::enable() called from thread");
-                    return INVALID_OPERATION;
-                }
-                mCaptureLock.lock();
-            }
-        }
-        t->mLock.lock();
-    }
-
-    status_t status = AudioEffect::setEnabled(enabled);
-
-    if (t != 0) {
-        if (enabled && status == NO_ERROR) {
-            t->run("Visualizer");
-        } else {
-            t->requestExit();
-        }
-    }
-
-    if (t != 0) {
-        t->mLock.unlock();
-    }
-
-    return status;
-}
-
-status_t Visualizer::setCaptureCallBack(capture_cbk_t cbk, void* user, uint32_t flags,
-        uint32_t rate)
-{
-    if (rate > CAPTURE_RATE_MAX) {
-        return BAD_VALUE;
-    }
-    Mutex::Autolock _l(mCaptureLock);
-
-    if (mEnabled) {
-        return INVALID_OPERATION;
-    }
-
-    if (mCaptureThread != 0) {
-        mCaptureLock.unlock();
-        mCaptureThread->requestExitAndWait();
-        mCaptureLock.lock();
-    }
-
-    mCaptureThread.clear();
-    mCaptureCallBack = cbk;
-    mCaptureCbkUser = user;
-    mCaptureFlags = flags;
-    mCaptureRate = rate;
-
-    if (cbk != NULL) {
-        mCaptureThread = new CaptureThread(this, rate, ((flags & CAPTURE_CALL_JAVA) != 0));
-    }
-    ALOGV("setCaptureCallBack() rate: %d thread %p flags 0x%08x",
-            rate, mCaptureThread.get(), mCaptureFlags);
-    return NO_ERROR;
-}
-
-status_t Visualizer::setCaptureSize(uint32_t size)
-{
-    if (size > VISUALIZER_CAPTURE_SIZE_MAX ||
-        size < VISUALIZER_CAPTURE_SIZE_MIN ||
-        popcount(size) != 1) {
-        return BAD_VALUE;
-    }
-
-    Mutex::Autolock _l(mCaptureLock);
-    if (mEnabled) {
-        return INVALID_OPERATION;
-    }
-
-    uint32_t buf32[sizeof(effect_param_t) / sizeof(uint32_t) + 2];
-    effect_param_t *p = (effect_param_t *)buf32;
-
-    p->psize = sizeof(uint32_t);
-    p->vsize = sizeof(uint32_t);
-    *(int32_t *)p->data = VISUALIZER_PARAM_CAPTURE_SIZE;
-    *((int32_t *)p->data + 1)= size;
-    status_t status = setParameter(p);
-
-    ALOGV("setCaptureSize size %d  status %d p->status %d", size, status, p->status);
-
-    if (status == NO_ERROR) {
-        status = p->status;
-        if (status == NO_ERROR) {
-            mCaptureSize = size;
-        }
-    }
-
-    return status;
-}
-
-status_t Visualizer::setScalingMode(uint32_t mode) {
-    if ((mode != VISUALIZER_SCALING_MODE_NORMALIZED)
-            && (mode != VISUALIZER_SCALING_MODE_AS_PLAYED)) {
-        return BAD_VALUE;
-    }
-
-    Mutex::Autolock _l(mCaptureLock);
-
-    uint32_t buf32[sizeof(effect_param_t) / sizeof(uint32_t) + 2];
-    effect_param_t *p = (effect_param_t *)buf32;
-
-    p->psize = sizeof(uint32_t);
-    p->vsize = sizeof(uint32_t);
-    *(int32_t *)p->data = VISUALIZER_PARAM_SCALING_MODE;
-    *((int32_t *)p->data + 1)= mode;
-    status_t status = setParameter(p);
-
-    ALOGV("setScalingMode mode %d  status %d p->status %d", mode, status, p->status);
-
-    if (status == NO_ERROR) {
-        status = p->status;
-        if (status == NO_ERROR) {
-            mScalingMode = mode;
-        }
-    }
-
-    return status;
-}
-
-status_t Visualizer::setMeasurementMode(uint32_t mode) {
-    if ((mode != MEASUREMENT_MODE_NONE)
-            //Note: needs to be handled as a mask when more measurement modes are added
-            && ((mode & MEASUREMENT_MODE_PEAK_RMS) != mode)) {
-        return BAD_VALUE;
-    }
-
-    Mutex::Autolock _l(mCaptureLock);
-
-    uint32_t buf32[sizeof(effect_param_t) / sizeof(uint32_t) + 2];
-    effect_param_t *p = (effect_param_t *)buf32;
-
-    p->psize = sizeof(uint32_t);
-    p->vsize = sizeof(uint32_t);
-    *(int32_t *)p->data = VISUALIZER_PARAM_MEASUREMENT_MODE;
-    *((int32_t *)p->data + 1)= mode;
-    status_t status = setParameter(p);
-
-    ALOGV("setMeasurementMode mode %d  status %d p->status %d", mode, status, p->status);
-
-    if (status == NO_ERROR) {
-        status = p->status;
-        if (status == NO_ERROR) {
-            mMeasurementMode = mode;
-        }
-    }
-    return status;
-}
-
-status_t Visualizer::getIntMeasurements(uint32_t type, uint32_t number, int32_t *measurements) {
-    if (mMeasurementMode == MEASUREMENT_MODE_NONE) {
-        ALOGE("Cannot retrieve int measurements, no measurement mode set");
-        return INVALID_OPERATION;
-    }
-    if (!(mMeasurementMode & type)) {
-        // measurement type has not been set on this Visualizer
-        ALOGE("Cannot retrieve int measurements, requested measurement mode 0x%x not set(0x%x)",
-                type, mMeasurementMode);
-        return INVALID_OPERATION;
-    }
-    // only peak+RMS measurement supported
-    if ((type != MEASUREMENT_MODE_PEAK_RMS)
-            // for peak+RMS measurement, the results are 2 int32_t values
-            || (number != 2)) {
-        ALOGE("Cannot retrieve int measurements, MEASUREMENT_MODE_PEAK_RMS returns 2 ints, not %d",
-                        number);
-        return BAD_VALUE;
-    }
-
-    status_t status = NO_ERROR;
-    if (mEnabled) {
-        uint32_t replySize = number * sizeof(int32_t);
-        status = command(VISUALIZER_CMD_MEASURE,
-                sizeof(uint32_t)  /*cmdSize*/,
-                &type /*cmdData*/,
-                &replySize, measurements);
-        ALOGV("getMeasurements() command returned %d", status);
-        if ((status == NO_ERROR) && (replySize == 0)) {
-            status = NOT_ENOUGH_DATA;
-        }
-    } else {
-        ALOGV("getMeasurements() disabled");
-        return INVALID_OPERATION;
-    }
-    return status;
-}
-
-status_t Visualizer::getWaveForm(uint8_t *waveform)
-{
-    if (waveform == NULL) {
-        return BAD_VALUE;
-    }
-    if (mCaptureSize == 0) {
-        return NO_INIT;
-    }
-
-    status_t status = NO_ERROR;
-    if (mEnabled) {
-        uint32_t replySize = mCaptureSize;
-        status = command(VISUALIZER_CMD_CAPTURE, 0, NULL, &replySize, waveform);
-        ALOGV("getWaveForm() command returned %d", status);
-        if ((status == NO_ERROR) && (replySize == 0)) {
-            status = NOT_ENOUGH_DATA;
-        }
-    } else {
-        ALOGV("getWaveForm() disabled");
-        memset(waveform, 0x80, mCaptureSize);
-    }
-    return status;
-}
-
-status_t Visualizer::getFft(uint8_t *fft)
-{
-    if (fft == NULL) {
-        return BAD_VALUE;
-    }
-    if (mCaptureSize == 0) {
-        return NO_INIT;
-    }
-
-    status_t status = NO_ERROR;
-    if (mEnabled) {
-        uint8_t buf[mCaptureSize];
-        status = getWaveForm(buf);
-        if (status == NO_ERROR) {
-            status = doFft(fft, buf);
-        }
-    } else {
-        memset(fft, 0, mCaptureSize);
-    }
-    return status;
-}
-
-status_t Visualizer::doFft(uint8_t *fft, uint8_t *waveform)
-{
-    int32_t workspace[mCaptureSize >> 1];
-    int32_t nonzero = 0;
-
-    for (uint32_t i = 0; i < mCaptureSize; i += 2) {
-        workspace[i >> 1] =
-                ((waveform[i] ^ 0x80) << 24) | ((waveform[i + 1] ^ 0x80) << 8);
-        nonzero |= workspace[i >> 1];
-    }
-
-    if (nonzero) {
-        fixed_fft_real(mCaptureSize >> 1, workspace);
-    }
-
-    for (uint32_t i = 0; i < mCaptureSize; i += 2) {
-        short tmp = workspace[i >> 1] >> 21;
-        while (tmp > 127 || tmp < -128) tmp >>= 1;
-        fft[i] = tmp;
-        tmp = workspace[i >> 1];
-        tmp >>= 5;
-        while (tmp > 127 || tmp < -128) tmp >>= 1;
-        fft[i + 1] = tmp;
-    }
-
-    return NO_ERROR;
-}
-
-void Visualizer::periodicCapture()
-{
-    Mutex::Autolock _l(mCaptureLock);
-    ALOGV("periodicCapture() %p mCaptureCallBack %p mCaptureFlags 0x%08x",
-            this, mCaptureCallBack, mCaptureFlags);
-    if (mCaptureCallBack != NULL &&
-        (mCaptureFlags & (CAPTURE_WAVEFORM|CAPTURE_FFT)) &&
-        mCaptureSize != 0) {
-        uint8_t waveform[mCaptureSize];
-        status_t status = getWaveForm(waveform);
-        if (status != NO_ERROR) {
-            return;
-        }
-        uint8_t fft[mCaptureSize];
-        if (mCaptureFlags & CAPTURE_FFT) {
-            status = doFft(fft, waveform);
-        }
-        if (status != NO_ERROR) {
-            return;
-        }
-        uint8_t *wavePtr = NULL;
-        uint8_t *fftPtr = NULL;
-        uint32_t waveSize = 0;
-        uint32_t fftSize = 0;
-        if (mCaptureFlags & CAPTURE_WAVEFORM) {
-            wavePtr = waveform;
-            waveSize = mCaptureSize;
-        }
-        if (mCaptureFlags & CAPTURE_FFT) {
-            fftPtr = fft;
-            fftSize = mCaptureSize;
-        }
-        mCaptureCallBack(mCaptureCbkUser, waveSize, wavePtr, fftSize, fftPtr, mSampleRate);
-    }
-}
-
-uint32_t Visualizer::initCaptureSize()
-{
-    uint32_t buf32[sizeof(effect_param_t) / sizeof(uint32_t) + 2];
-    effect_param_t *p = (effect_param_t *)buf32;
-
-    p->psize = sizeof(uint32_t);
-    p->vsize = sizeof(uint32_t);
-    *(int32_t *)p->data = VISUALIZER_PARAM_CAPTURE_SIZE;
-    status_t status = getParameter(p);
-
-    if (status == NO_ERROR) {
-        status = p->status;
-    }
-
-    uint32_t size = 0;
-    if (status == NO_ERROR) {
-        size = *((int32_t *)p->data + 1);
-    }
-    mCaptureSize = size;
-
-    ALOGV("initCaptureSize size %d status %d", mCaptureSize, status);
-
-    return size;
-}
-
-void Visualizer::controlStatusChanged(bool controlGranted) {
-    if (controlGranted) {
-        // this Visualizer instance regained control of the effect, reset the scaling mode
-        //   and capture size as has been cached through it.
-        ALOGV("controlStatusChanged(true) causes effect parameter reset:");
-        ALOGV("    scaling mode reset to %d", mScalingMode);
-        setScalingMode(mScalingMode);
-        ALOGV("    capture size reset to %d", mCaptureSize);
-        setCaptureSize(mCaptureSize);
-    }
-    AudioEffect::controlStatusChanged(controlGranted);
-}
-
-//-------------------------------------------------------------------------
-
-Visualizer::CaptureThread::CaptureThread(Visualizer* receiver, uint32_t captureRate,
-        bool bCanCallJava)
-    : Thread(bCanCallJava), mReceiver(receiver)
-{
-    mSleepTimeUs = 1000000000 / captureRate;
-    ALOGV("CaptureThread cstor %p captureRate %d mSleepTimeUs %d", this, captureRate, mSleepTimeUs);
-}
-
-bool Visualizer::CaptureThread::threadLoop()
-{
-    ALOGV("CaptureThread %p enter", this);
-    sp<Visualizer> receiver = mReceiver.promote();
-    if (receiver == NULL) {
-        return false;
-    }
-    while (!exitPending())
-    {
-        usleep(mSleepTimeUs);
-        receiver->periodicCapture();
-    }
-    ALOGV("CaptureThread %p exiting", this);
-    return false;
-}
-
-} // namespace android
diff --git a/media/libmedia/include/media/DataSourceDesc.h b/media/libmedia/include/media/DataSourceDesc.h
deleted file mode 100644
index 4336767..0000000
--- a/media/libmedia/include/media/DataSourceDesc.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright 2018 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 ANDROID_DATASOURCEDESC_H
-#define ANDROID_DATASOURCEDESC_H
-
-#include <media/stagefright/foundation/ABase.h>
-#include <utils/RefBase.h>
-#include <utils/KeyedVector.h>
-#include <utils/String8.h>
-
-namespace android {
-
-class DataSource;
-struct MediaHTTPService;
-
-// A binder interface for implementing a stagefright DataSource remotely.
-struct DataSourceDesc : public RefBase {
-public:
-    // intentionally less than INT64_MAX
-    // keep consistent with JAVA code
-    static const int64_t kMaxTimeMs = 0x7ffffffffffffffll / 1000;
-    static const int64_t kMaxTimeUs = kMaxTimeMs * 1000;
-
-    enum {
-        /* No data source has been set yet */
-        TYPE_NONE     = 0,
-        /* data source is type of MediaDataSource */
-        TYPE_CALLBACK = 1,
-        /* data source is type of FileDescriptor */
-        TYPE_FD       = 2,
-        /* data source is type of Url */
-        TYPE_URL      = 3,
-    };
-
-    DataSourceDesc();
-
-    int mType;
-
-    sp<MediaHTTPService> mHttpService;
-    String8 mUrl;
-    KeyedVector<String8, String8> mHeaders;
-
-    int mFD;
-    int64_t mFDOffset;
-    int64_t mFDLength;
-
-    sp<DataSource> mCallbackSource;
-
-    int64_t mId;
-    int64_t mStartPositionMs;
-    int64_t mEndPositionMs;
-
-private:
-    DISALLOW_EVIL_CONSTRUCTORS(DataSourceDesc);
-};
-
-}; // namespace android
-
-#endif // ANDROID_DATASOURCEDESC_H
diff --git a/media/libmedia/include/media/JetPlayer.h b/media/libmedia/include/media/JetPlayer.h
deleted file mode 100644
index bb569bc..0000000
--- a/media/libmedia/include/media/JetPlayer.h
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Copyright (C) 2008 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 JETPLAYER_H_
-#define JETPLAYER_H_
-
-#include <utils/threads.h>
-
-#include <libsonivox/jet.h>
-#include <libsonivox/eas_types.h>
-#include <media/AudioTrack.h>
-#include <media/MidiIoWrapper.h>
-
-
-namespace android {
-
-typedef void (*jetevent_callback)(int eventType, int val1, int val2, void *cookie);
-
-class JetPlayer {
-
-public:
-
-    // to keep in sync with the JetPlayer class constants
-    // defined in frameworks/base/media/java/android/media/JetPlayer.java
-    static const int JET_EVENT                   = 1;
-    static const int JET_USERID_UPDATE           = 2;
-    static const int JET_NUMQUEUEDSEGMENT_UPDATE = 3;
-    static const int JET_PAUSE_UPDATE            = 4;
-
-    JetPlayer(void *javaJetPlayer,
-            int maxTracks = 32,
-            int trackBufferSize = 1200);
-    ~JetPlayer();
-    int init();
-    int release();
-
-    int loadFromFile(const char* url);
-    int loadFromFD(const int fd, const long long offset, const long long length);
-    int closeFile();
-    int play();
-    int pause();
-    int queueSegment(int segmentNum, int libNum, int repeatCount, int transpose,
-            EAS_U32 muteFlags, EAS_U8 userID);
-    int setMuteFlags(EAS_U32 muteFlags, bool sync);
-    int setMuteFlag(int trackNum, bool muteFlag, bool sync);
-    int triggerClip(int clipId);
-    int clearQueue();
-
-    void setEventCallback(jetevent_callback callback);
-
-    int getMaxTracks() { return mMaxTracks; };
-
-
-private:
-    int                 render();
-    void                fireUpdateOnStatusChange();
-    void                fireEventsFromJetQueue();
-
-    JetPlayer() {} // no default constructor
-    void dump();
-    void dumpJetStatus(S_JET_STATUS* pJetStatus);
-
-    jetevent_callback   mEventCallback;
-
-    void*               mJavaJetPlayerRef;
-    Mutex               mMutex; // mutex to sync the render and playback thread with the JET calls
-    pid_t               mTid;
-    Condition           mCondition;
-    volatile bool       mRender;
-    bool                mPaused;
-
-    EAS_STATE           mState;
-    int*                mMemFailedVar;
-
-    int                 mMaxTracks; // max number of MIDI tracks, usually 32
-    EAS_DATA_HANDLE     mEasData;
-    MidiIoWrapper*      mIoWrapper;
-    EAS_PCM*            mAudioBuffer;// EAS renders the MIDI data into this buffer,
-    sp<AudioTrack>      mAudioTrack; // and we play it in this audio track
-    int                 mTrackBufferSize;
-    S_JET_STATUS        mJetStatus;
-    S_JET_STATUS        mPreviousJetStatus;
-
-    class JetPlayerThread : public Thread {
-    public:
-        JetPlayerThread(JetPlayer *player) : mPlayer(player) {
-        }
-
-    protected:
-        virtual ~JetPlayerThread() {}
-
-    private:
-        JetPlayer *mPlayer;
-
-        bool threadLoop() {
-            int result;
-            result = mPlayer->render();
-            return false;
-        }
-
-        JetPlayerThread(const JetPlayerThread &);
-        JetPlayerThread &operator=(const JetPlayerThread &);
-    };
-
-    sp<JetPlayerThread> mThread;
-
-}; // end class JetPlayer
-
-} // end namespace android
-
-
-
-#endif /*JETPLAYER_H_*/
diff --git a/media/libmedia/include/media/MidiDeviceInfo.h b/media/libmedia/include/media/MidiDeviceInfo.h
deleted file mode 100644
index 5b4a241..0000000
--- a/media/libmedia/include/media/MidiDeviceInfo.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_MEDIA_MIDI_DEVICE_INFO_H
-#define ANDROID_MEDIA_MIDI_DEVICE_INFO_H
-
-#include <binder/Parcelable.h>
-#include <binder/PersistableBundle.h>
-#include <utils/String16.h>
-#include <utils/Vector.h>
-
-namespace android {
-namespace media {
-namespace midi {
-
-class MidiDeviceInfo : public Parcelable {
-public:
-    MidiDeviceInfo() = default;
-    virtual ~MidiDeviceInfo() = default;
-    MidiDeviceInfo(const MidiDeviceInfo& midiDeviceInfo) = default;
-
-    status_t writeToParcel(Parcel* parcel) const override;
-    status_t readFromParcel(const Parcel* parcel) override;
-
-    int getType() const { return mType; }
-    int getUid() const { return mId; }
-    bool isPrivate() const { return mIsPrivate; }
-    const Vector<String16>& getInputPortNames() const { return mInputPortNames; }
-    const Vector<String16>&  getOutputPortNames() const { return mOutputPortNames; }
-    String16 getProperty(const char* propertyName);
-
-    // The constants need to be kept in sync with MidiDeviceInfo.java
-    enum {
-        TYPE_USB = 1,
-        TYPE_VIRTUAL = 2,
-        TYPE_BLUETOOTH = 3,
-    };
-    static const char* const PROPERTY_NAME;
-    static const char* const PROPERTY_MANUFACTURER;
-    static const char* const PROPERTY_PRODUCT;
-    static const char* const PROPERTY_VERSION;
-    static const char* const PROPERTY_SERIAL_NUMBER;
-    static const char* const PROPERTY_ALSA_CARD;
-    static const char* const PROPERTY_ALSA_DEVICE;
-
-    friend bool operator==(const MidiDeviceInfo& lhs, const MidiDeviceInfo& rhs);
-    friend bool operator!=(const MidiDeviceInfo& lhs, const MidiDeviceInfo& rhs) {
-        return !(lhs == rhs);
-    }
-
-private:
-    status_t readStringVector(
-            const Parcel* parcel, Vector<String16> *vectorPtr, size_t defaultLength);
-    status_t writeStringVector(Parcel* parcel, const Vector<String16>& vector) const;
-
-    int32_t mType;
-    int32_t mId;
-    Vector<String16> mInputPortNames;
-    Vector<String16> mOutputPortNames;
-    os::PersistableBundle mProperties;
-    bool mIsPrivate;
-};
-
-}  // namespace midi
-}  // namespace media
-}  // namespace android
-
-#endif  // ANDROID_MEDIA_MIDI_DEVICE_INFO_H
diff --git a/media/libmedia/include/media/Visualizer.h b/media/libmedia/include/media/Visualizer.h
deleted file mode 100644
index 8078e36..0000000
--- a/media/libmedia/include/media/Visualizer.h
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * Copyright (C) 2010 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 ANDROID_MEDIA_VISUALIZER_H
-#define ANDROID_MEDIA_VISUALIZER_H
-
-#include <media/AudioEffect.h>
-#include <system/audio_effects/effect_visualizer.h>
-#include <utils/Thread.h>
-
-/**
- * The Visualizer class enables application to retrieve part of the currently playing audio for
- * visualization purpose. It is not an audio recording interface and only returns partial and low
- * quality audio content. However, to protect privacy of certain audio data (e.g voice mail) the use
- * of the visualizer requires the permission android.permission.RECORD_AUDIO.
- * The audio session ID passed to the constructor indicates which audio content should be
- * visualized:
- * - If the session is 0, the audio output mix is visualized
- * - If the session is not 0, the audio from a particular MediaPlayer or AudioTrack
- *   using this audio session is visualized
- * Two types of representation of audio content can be captured:
- * - Waveform data: consecutive 8-bit (unsigned) mono samples by using the getWaveForm() method
- * - Frequency data: 8-bit magnitude FFT by using the getFft() method
- *
- * The length of the capture can be retrieved or specified by calling respectively
- * getCaptureSize() and setCaptureSize() methods. Note that the size of the FFT
- * is half of the specified capture size but both sides of the spectrum are returned yielding in a
- * number of bytes equal to the capture size. The capture size must be a power of 2 in the range
- * returned by getMinCaptureSize() and getMaxCaptureSize().
- * In addition to the polling capture mode, a callback mode is also available by installing a
- * callback function by use of the setCaptureCallBack() method. The rate at which the callback
- * is called as well as the type of data returned is specified.
- * Before capturing data, the Visualizer must be enabled by calling the setEnabled() method.
- * When data capture is not needed any more, the Visualizer should be disabled.
- */
-
-
-namespace android {
-
-// ----------------------------------------------------------------------------
-
-class Visualizer: public AudioEffect {
-public:
-
-    enum callback_flags {
-        CAPTURE_WAVEFORM = 0x00000001,  // capture callback returns a PCM wave form
-        CAPTURE_FFT = 0x00000002,       // apture callback returns a frequency representation
-        CAPTURE_CALL_JAVA = 0x00000004  // the callback thread can call java
-    };
-
-
-    /* Constructor.
-     * See AudioEffect constructor for details on parameters.
-     */
-                        Visualizer(const String16& opPackageName,
-                                   int32_t priority = 0,
-                                   effect_callback_t cbf = NULL,
-                                   void* user = NULL,
-                                   audio_session_t sessionId = AUDIO_SESSION_OUTPUT_MIX);
-
-                        ~Visualizer();
-
-    virtual status_t    setEnabled(bool enabled);
-
-    // maximum capture size in samples
-    static uint32_t getMaxCaptureSize() { return VISUALIZER_CAPTURE_SIZE_MAX; }
-    // minimum capture size in samples
-    static uint32_t getMinCaptureSize() { return VISUALIZER_CAPTURE_SIZE_MIN; }
-    // maximum capture rate in millihertz
-    static uint32_t getMaxCaptureRate() { return CAPTURE_RATE_MAX; }
-
-    // callback used to return periodic PCM or FFT captures to the application. Either one or both
-    // types of data are returned (PCM and FFT) according to flags indicated when installing the
-    // callback. When a type of data is not present, the corresponding size (waveformSize or
-    // fftSize) is 0.
-    typedef void (*capture_cbk_t)(void* user,
-                                    uint32_t waveformSize,
-                                    uint8_t *waveform,
-                                    uint32_t fftSize,
-                                    uint8_t *fft,
-                                    uint32_t samplingrate);
-
-    // install a callback to receive periodic captures. The capture rate is specified in milliHertz
-    // and the capture format is according to flags  (see callback_flags).
-    status_t setCaptureCallBack(capture_cbk_t cbk, void* user, uint32_t flags, uint32_t rate);
-
-    // set the capture size capture size must be a power of two in the range
-    // [VISUALIZER_CAPTURE_SIZE_MAX. VISUALIZER_CAPTURE_SIZE_MIN]
-    // must be called when the visualizer is not enabled
-    status_t setCaptureSize(uint32_t size);
-    uint32_t getCaptureSize() { return mCaptureSize; }
-
-    // returns the capture rate indicated when installing the callback
-    uint32_t getCaptureRate() { return mCaptureRate; }
-
-    // returns the sampling rate of the audio being captured
-    uint32_t getSamplingRate() { return mSampleRate; }
-
-    // set the way volume affects the captured data
-    // mode must one of VISUALIZER_SCALING_MODE_NORMALIZED,
-    //  VISUALIZER_SCALING_MODE_AS_PLAYED
-    status_t setScalingMode(uint32_t mode);
-    uint32_t getScalingMode() { return mScalingMode; }
-
-    // set which measurements are done on the audio buffers processed by the effect.
-    // valid measurements (mask): MEASUREMENT_MODE_PEAK_RMS
-    status_t setMeasurementMode(uint32_t mode);
-    uint32_t getMeasurementMode() { return mMeasurementMode; }
-
-    // return a set of int32_t measurements
-    status_t getIntMeasurements(uint32_t type, uint32_t number, int32_t *measurements);
-
-    // return a capture in PCM 8 bit unsigned format. The size of the capture is equal to
-    // getCaptureSize()
-    status_t getWaveForm(uint8_t *waveform);
-
-    // return a capture in FFT 8 bit signed format. The size of the capture is equal to
-    // getCaptureSize() but the length of the FFT is half of the size (both parts of the spectrum
-    // are returned
-    status_t getFft(uint8_t *fft);
-    void release();
-
-protected:
-    // from IEffectClient
-    virtual void controlStatusChanged(bool controlGranted);
-
-private:
-
-    static const uint32_t CAPTURE_RATE_MAX = 20000;
-    static const uint32_t CAPTURE_RATE_DEF = 10000;
-    static const uint32_t CAPTURE_SIZE_DEF = VISUALIZER_CAPTURE_SIZE_MAX;
-
-    /* internal class to handle the callback */
-    class CaptureThread : public Thread
-    {
-    public:
-        CaptureThread(Visualizer* visualizer, uint32_t captureRate, bool bCanCallJava = false);
-
-    private:
-        friend class Visualizer;
-        virtual bool        threadLoop();
-        wp<Visualizer> mReceiver;
-        Mutex       mLock;
-        uint32_t mSleepTimeUs;
-    };
-
-    status_t doFft(uint8_t *fft, uint8_t *waveform);
-    void periodicCapture();
-    uint32_t initCaptureSize();
-
-    Mutex mCaptureLock;
-    uint32_t mCaptureRate;
-    uint32_t mCaptureSize;
-    uint32_t mSampleRate;
-    uint32_t mScalingMode;
-    uint32_t mMeasurementMode;
-    capture_cbk_t mCaptureCallBack;
-    void *mCaptureCbkUser;
-    sp<CaptureThread> mCaptureThread;
-    uint32_t mCaptureFlags;
-};
-
-
-}; // namespace android
-
-#endif // ANDROID_MEDIA_VISUALIZER_H
diff --git a/media/libmediaplayer2/Android.bp b/media/libmediaplayer2/Android.bp
deleted file mode 100644
index dca6bb6..0000000
--- a/media/libmediaplayer2/Android.bp
+++ /dev/null
@@ -1,129 +0,0 @@
-cc_library_headers {
-    name: "libmediaplayer2_headers",
-    vendor_available: true,
-    export_include_dirs: ["include"],
-}
-
-cc_library_static {
-    name: "libmediaplayer2",
-
-    srcs: [
-        "MediaPlayer2AudioOutput.cpp",
-        "mediaplayer2.cpp",
-    ],
-
-    shared_libs: [
-        "libandroid_runtime",
-        "libaudioclient",
-        "libbinder",
-        "libbinder_ndk",
-        "libcutils",
-        "libgui",
-        "liblog",
-        "libmedia_omx",
-        "libui",
-        "libutils",
-
-        "libcrypto",
-        "libmediametrics",
-        "libmediandk",
-        "libmediandk_utils",
-        "libmediautils",
-        "libmemunreachable",
-        "libnativewindow",
-        "libpowermanager",
-        "libstagefright_httplive",
-    ],
-
-    export_shared_lib_headers: [
-        "libaudioclient",
-        "libbinder",
-        "libgui",
-        "libmedia_omx",
-    ],
-
-    header_libs: [
-        "media_plugin_headers",
-    ],
-
-    include_dirs: [
-        "frameworks/base/core/jni",
-    ],
-
-    static_libs: [
-        "libmedia_helper",
-        "libmediaplayer2-protos",
-        "libmedia_player2_util",
-        "libprotobuf-cpp-lite",
-        "libstagefright_foundation_without_imemory",
-        "libstagefright_nuplayer2",
-        "libstagefright_player2",
-        "libstagefright_rtsp",
-        "libstagefright_timedtext2",
-        "libmedia2_jni_core",
-    ],
-
-    export_include_dirs: [
-        "include",
-    ],
-
-    cflags: [
-        "-Werror",
-        "-Wno-error=deprecated-declarations",
-        "-Wall",
-    ],
-
-    sanitize: {
-        misc_undefined: [
-            "unsigned-integer-overflow",
-            "signed-integer-overflow",
-        ],
-        cfi: true,
-    },
-}
-
-cc_library {
-    name: "libmedia2_jni_core",
-
-    srcs: [
-        "JavaVMHelper.cpp",
-        "JAudioTrack.cpp",
-        "JMedia2HTTPService.cpp",
-        "JMedia2HTTPConnection.cpp",
-    ],
-
-    header_libs: [
-        "libbinder_headers",
-        "libnativehelper_header_only",
-    ],
-
-    shared_libs: [
-        "liblog",
-        "libutils",
-        "libdl",
-    ],
-
-    include_dirs: [
-        "frameworks/av/media/libmedia/include",
-        "frameworks/base/core/jni",
-    ],
-
-    export_include_dirs: [
-        "include",
-    ],
-
-    cflags: [
-        "-Werror",
-        "-Wno-error=deprecated-declarations",
-        "-Wall",
-    ],
-
-    sanitize: {
-        misc_undefined: [
-            "unsigned-integer-overflow",
-            "signed-integer-overflow",
-        ],
-        cfi: true,
-    },
-
-}
diff --git a/media/libmediaplayer2/JAudioTrack.cpp b/media/libmediaplayer2/JAudioTrack.cpp
deleted file mode 100644
index fab6c64..0000000
--- a/media/libmediaplayer2/JAudioTrack.cpp
+++ /dev/null
@@ -1,768 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "JAudioTrack"
-
-#include "media/JAudioAttributes.h"
-#include "media/JAudioFormat.h"
-#include "mediaplayer2/JAudioTrack.h"
-
-#include <android_media_AudioErrors.h>
-#include <mediaplayer2/JavaVMHelper.h>
-
-namespace android {
-
-// TODO: Store Java class/methodID as a member variable in the class.
-// TODO: Add NULL && Exception checks after every JNI call.
-JAudioTrack::JAudioTrack(                             // < Usages of the arguments are below >
-        uint32_t sampleRate,                          // AudioFormat && bufferSizeInBytes
-        audio_format_t format,                        // AudioFormat && bufferSizeInBytes
-        audio_channel_mask_t channelMask,             // AudioFormat && bufferSizeInBytes
-        callback_t cbf,                               // Offload
-        void* user,                                   // Offload
-        size_t frameCount,                            // bufferSizeInBytes
-        int32_t sessionId,                            // AudioTrack
-        const jobject attributes,                     // AudioAttributes
-        float maxRequiredSpeed) {                     // bufferSizeInBytes
-
-    JNIEnv *env = JavaVMHelper::getJNIEnv();
-
-    jclass jAudioTrackCls = env->FindClass("android/media/AudioTrack");
-    mAudioTrackCls = reinterpret_cast<jclass>(env->NewGlobalRef(jAudioTrackCls));
-    env->DeleteLocalRef(jAudioTrackCls);
-
-    maxRequiredSpeed = std::min(std::max(maxRequiredSpeed, 1.0f), AUDIO_TIMESTRETCH_SPEED_MAX);
-
-    int bufferSizeInBytes = 0;
-    if (sampleRate == 0 || frameCount > 0) {
-        // Manually calculate buffer size.
-        bufferSizeInBytes = audio_channel_count_from_out_mask(channelMask)
-                * audio_bytes_per_sample(format) * (frameCount > 0 ? frameCount : 1);
-    } else if (sampleRate > 0) {
-        // Call Java AudioTrack::getMinBufferSize().
-        jmethodID jGetMinBufferSize =
-                env->GetStaticMethodID(mAudioTrackCls, "getMinBufferSize", "(III)I");
-        bufferSizeInBytes = env->CallStaticIntMethod(mAudioTrackCls, jGetMinBufferSize,
-                sampleRate, outChannelMaskFromNative(channelMask), audioFormatFromNative(format));
-    }
-    bufferSizeInBytes = (int) (bufferSizeInBytes * maxRequiredSpeed);
-
-    // Create a Java AudioTrack object through its Builder.
-    jclass jBuilderCls = env->FindClass("android/media/AudioTrack$Builder");
-    jmethodID jBuilderCtor = env->GetMethodID(jBuilderCls, "<init>", "()V");
-    jobject jBuilderObj = env->NewObject(jBuilderCls, jBuilderCtor);
-
-    {
-        sp<JObjectHolder> audioAttributesObj;
-        if (attributes != NULL) {
-            audioAttributesObj = new JObjectHolder(attributes);
-        } else {
-            audioAttributesObj = new JObjectHolder(
-                    JAudioAttributes::createAudioAttributesObj(env, NULL));
-        }
-        jmethodID jSetAudioAttributes = env->GetMethodID(jBuilderCls, "setAudioAttributes",
-                "(Landroid/media/AudioAttributes;)Landroid/media/AudioTrack$Builder;");
-        jBuilderObj = env->CallObjectMethod(jBuilderObj,
-                jSetAudioAttributes, audioAttributesObj->getJObject());
-    }
-
-    jmethodID jSetAudioFormat = env->GetMethodID(jBuilderCls, "setAudioFormat",
-            "(Landroid/media/AudioFormat;)Landroid/media/AudioTrack$Builder;");
-    jBuilderObj = env->CallObjectMethod(jBuilderObj, jSetAudioFormat,
-            JAudioFormat::createAudioFormatObj(env, sampleRate, format, channelMask));
-
-    jmethodID jSetBufferSizeInBytes = env->GetMethodID(jBuilderCls, "setBufferSizeInBytes",
-            "(I)Landroid/media/AudioTrack$Builder;");
-    jBuilderObj = env->CallObjectMethod(jBuilderObj, jSetBufferSizeInBytes, bufferSizeInBytes);
-
-    // We only use streaming mode of Java AudioTrack.
-    jfieldID jModeStream = env->GetStaticFieldID(mAudioTrackCls, "MODE_STREAM", "I");
-    jint transferMode = env->GetStaticIntField(mAudioTrackCls, jModeStream);
-    jmethodID jSetTransferMode = env->GetMethodID(jBuilderCls, "setTransferMode",
-            "(I)Landroid/media/AudioTrack$Builder;");
-    jBuilderObj = env->CallObjectMethod(jBuilderObj, jSetTransferMode,
-            transferMode /* Java AudioTrack::MODE_STREAM */);
-
-    if (sessionId != 0) {
-        jmethodID jSetSessionId = env->GetMethodID(jBuilderCls, "setSessionId",
-                "(I)Landroid/media/AudioTrack$Builder;");
-        jBuilderObj = env->CallObjectMethod(jBuilderObj, jSetSessionId, sessionId);
-    }
-
-    mFlags = AUDIO_OUTPUT_FLAG_NONE;
-    if (cbf != NULL) {
-        jmethodID jSetOffloadedPlayback = env->GetMethodID(jBuilderCls, "setOffloadedPlayback",
-                "(Z)Landroid/media/AudioTrack$Builder;");
-        jBuilderObj = env->CallObjectMethod(jBuilderObj, jSetOffloadedPlayback, true);
-        mFlags = AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD;
-    }
-
-    jmethodID jBuild = env->GetMethodID(jBuilderCls, "build", "()Landroid/media/AudioTrack;");
-    jobject jAudioTrackObj = env->CallObjectMethod(jBuilderObj, jBuild);
-    mAudioTrackObj = reinterpret_cast<jobject>(env->NewGlobalRef(jAudioTrackObj));
-    env->DeleteLocalRef(jBuilderObj);
-
-    if (cbf != NULL) {
-        // Set offload mode callback
-        jobject jStreamEventCallbackObj = createStreamEventCallback(cbf, user);
-        jobject jExecutorObj = createCallbackExecutor();
-        jmethodID jSetStreamEventCallback = env->GetMethodID(
-                jAudioTrackCls,
-                "setStreamEventCallback",
-                "(Ljava/util/concurrent/Executor;Landroid/media/AudioTrack$StreamEventCallback;)V");
-        env->CallVoidMethod(
-                mAudioTrackObj, jSetStreamEventCallback, jExecutorObj, jStreamEventCallbackObj);
-    }
-}
-
-JAudioTrack::~JAudioTrack() {
-    JNIEnv *env = JavaVMHelper::getJNIEnv();
-    env->DeleteGlobalRef(mAudioTrackCls);
-    env->DeleteGlobalRef(mAudioTrackObj);
-}
-
-size_t JAudioTrack::frameCount() {
-    JNIEnv *env = JavaVMHelper::getJNIEnv();
-    jmethodID jGetBufferSizeInFrames = env->GetMethodID(
-            mAudioTrackCls, "getBufferSizeInFrames", "()I");
-    return env->CallIntMethod(mAudioTrackObj, jGetBufferSizeInFrames);
-}
-
-size_t JAudioTrack::channelCount() {
-    JNIEnv *env = JavaVMHelper::getJNIEnv();
-    jmethodID jGetChannelCount = env->GetMethodID(mAudioTrackCls, "getChannelCount", "()I");
-    return env->CallIntMethod(mAudioTrackObj, jGetChannelCount);
-}
-
-uint32_t JAudioTrack::latency() {
-    // TODO: Currently hard-coded as returning zero.
-    return 0;
-}
-
-status_t JAudioTrack::getPosition(uint32_t *position) {
-    if (position == NULL) {
-        return BAD_VALUE;
-    }
-
-    JNIEnv *env = JavaVMHelper::getJNIEnv();
-    jmethodID jGetPlaybackHeadPosition = env->GetMethodID(
-            mAudioTrackCls, "getPlaybackHeadPosition", "()I");
-    *position = env->CallIntMethod(mAudioTrackObj, jGetPlaybackHeadPosition);
-
-    return NO_ERROR;
-}
-
-status_t JAudioTrack::getTimestamp(AudioTimestamp& timestamp) {
-    JNIEnv *env = JavaVMHelper::getJNIEnv();
-
-    jclass jAudioTimeStampCls = env->FindClass("android/media/AudioTimestamp");
-    jobject jAudioTimeStampObj = env->AllocObject(jAudioTimeStampCls);
-
-    jfieldID jFramePosition = env->GetFieldID(jAudioTimeStampCls, "framePosition", "J");
-    jfieldID jNanoTime = env->GetFieldID(jAudioTimeStampCls, "nanoTime", "J");
-
-    jmethodID jGetTimestamp = env->GetMethodID(mAudioTrackCls,
-            "getTimestamp", "(Landroid/media/AudioTimestamp;)Z");
-    bool success = env->CallBooleanMethod(mAudioTrackObj, jGetTimestamp, jAudioTimeStampObj);
-
-    if (!success) {
-        return NO_INIT;
-    }
-
-    long long framePosition = env->GetLongField(jAudioTimeStampObj, jFramePosition);
-    long long nanoTime = env->GetLongField(jAudioTimeStampObj, jNanoTime);
-
-    struct timespec ts;
-    const long long secondToNano = 1000000000LL; // 1E9
-    ts.tv_sec = nanoTime / secondToNano;
-    ts.tv_nsec = nanoTime % secondToNano;
-    timestamp.mTime = ts;
-    timestamp.mPosition = (uint32_t) framePosition;
-
-    return NO_ERROR;
-}
-
-status_t JAudioTrack::getTimestamp(ExtendedTimestamp *timestamp __unused) {
-    // TODO: Implement this after appropriate Java AudioTrack method is available.
-    return NO_ERROR;
-}
-
-status_t JAudioTrack::setPlaybackRate(const AudioPlaybackRate &playbackRate) {
-    // TODO: existing native AudioTrack returns INVALID_OPERATION on offload/direct/fast tracks.
-    // Should we do the same thing?
-    JNIEnv *env = JavaVMHelper::getJNIEnv();
-
-    jclass jPlaybackParamsCls = env->FindClass("android/media/PlaybackParams");
-    jmethodID jPlaybackParamsCtor = env->GetMethodID(jPlaybackParamsCls, "<init>", "()V");
-    jobject jPlaybackParamsObj = env->NewObject(jPlaybackParamsCls, jPlaybackParamsCtor);
-
-    jmethodID jSetAudioFallbackMode = env->GetMethodID(
-            jPlaybackParamsCls, "setAudioFallbackMode", "(I)Landroid/media/PlaybackParams;");
-    jPlaybackParamsObj = env->CallObjectMethod(
-            jPlaybackParamsObj, jSetAudioFallbackMode, playbackRate.mFallbackMode);
-
-    jmethodID jSetAudioStretchMode = env->GetMethodID(
-                jPlaybackParamsCls, "setAudioStretchMode", "(I)Landroid/media/PlaybackParams;");
-    jPlaybackParamsObj = env->CallObjectMethod(
-            jPlaybackParamsObj, jSetAudioStretchMode, playbackRate.mStretchMode);
-
-    jmethodID jSetPitch = env->GetMethodID(
-            jPlaybackParamsCls, "setPitch", "(F)Landroid/media/PlaybackParams;");
-    jPlaybackParamsObj = env->CallObjectMethod(jPlaybackParamsObj, jSetPitch, playbackRate.mPitch);
-
-    jmethodID jSetSpeed = env->GetMethodID(
-            jPlaybackParamsCls, "setSpeed", "(F)Landroid/media/PlaybackParams;");
-    jPlaybackParamsObj = env->CallObjectMethod(jPlaybackParamsObj, jSetSpeed, playbackRate.mSpeed);
-
-
-    // Set this Java PlaybackParams object into Java AudioTrack.
-    jmethodID jSetPlaybackParams = env->GetMethodID(
-            mAudioTrackCls, "setPlaybackParams", "(Landroid/media/PlaybackParams;)V");
-    env->CallVoidMethod(mAudioTrackObj, jSetPlaybackParams, jPlaybackParamsObj);
-    // TODO: Should we catch the Java IllegalArgumentException?
-
-    return NO_ERROR;
-}
-
-const AudioPlaybackRate JAudioTrack::getPlaybackRate() {
-    JNIEnv *env = JavaVMHelper::getJNIEnv();
-
-    jmethodID jGetPlaybackParams = env->GetMethodID(
-            mAudioTrackCls, "getPlaybackParams", "()Landroid/media/PlaybackParams;");
-    jobject jPlaybackParamsObj = env->CallObjectMethod(mAudioTrackObj, jGetPlaybackParams);
-
-    AudioPlaybackRate playbackRate;
-    jclass jPlaybackParamsCls = env->FindClass("android/media/PlaybackParams");
-
-    jmethodID jGetAudioFallbackMode = env->GetMethodID(
-            jPlaybackParamsCls, "getAudioFallbackMode", "()I");
-    // TODO: Should we enable passing AUDIO_TIMESTRETCH_FALLBACK_CUT_REPEAT?
-    //       The enum is internal only, so it is not defined in PlaybackParmas.java.
-    // TODO: Is this right way to convert an int to an enum?
-    playbackRate.mFallbackMode = static_cast<AudioTimestretchFallbackMode>(
-            env->CallIntMethod(jPlaybackParamsObj, jGetAudioFallbackMode));
-
-    jmethodID jGetAudioStretchMode = env->GetMethodID(
-            jPlaybackParamsCls, "getAudioStretchMode", "()I");
-    playbackRate.mStretchMode = static_cast<AudioTimestretchStretchMode>(
-            env->CallIntMethod(jPlaybackParamsObj, jGetAudioStretchMode));
-
-    jmethodID jGetPitch = env->GetMethodID(jPlaybackParamsCls, "getPitch", "()F");
-    playbackRate.mPitch = env->CallFloatMethod(jPlaybackParamsObj, jGetPitch);
-
-    jmethodID jGetSpeed = env->GetMethodID(jPlaybackParamsCls, "getSpeed", "()F");
-    playbackRate.mSpeed = env->CallFloatMethod(jPlaybackParamsObj, jGetSpeed);
-
-    return playbackRate;
-}
-
-media::VolumeShaper::Status JAudioTrack::applyVolumeShaper(
-        const sp<media::VolumeShaper::Configuration>& configuration,
-        const sp<media::VolumeShaper::Operation>& operation) {
-
-    jobject jConfigurationObj = createVolumeShaperConfigurationObj(configuration);
-    jobject jOperationObj = createVolumeShaperOperationObj(operation);
-
-    if (jConfigurationObj == NULL || jOperationObj == NULL) {
-        return media::VolumeShaper::Status(BAD_VALUE);
-    }
-
-    JNIEnv *env = JavaVMHelper::getJNIEnv();
-
-    jmethodID jCreateVolumeShaper = env->GetMethodID(mAudioTrackCls, "createVolumeShaper",
-            "(Landroid/media/VolumeShaper$Configuration;)Landroid/media/VolumeShaper;");
-    jobject jVolumeShaperObj = env->CallObjectMethod(
-            mAudioTrackObj, jCreateVolumeShaper, jConfigurationObj);
-
-    jclass jVolumeShaperCls = env->FindClass("android/media/VolumeShaper");
-    jmethodID jApply = env->GetMethodID(jVolumeShaperCls, "apply",
-            "(Landroid/media/VolumeShaper$Operation;)V");
-    env->CallVoidMethod(jVolumeShaperObj, jApply, jOperationObj);
-
-    return media::VolumeShaper::Status(NO_ERROR);
-}
-
-status_t JAudioTrack::setAuxEffectSendLevel(float level) {
-    JNIEnv *env = JavaVMHelper::getJNIEnv();
-    jmethodID jSetAuxEffectSendLevel = env->GetMethodID(
-            mAudioTrackCls, "setAuxEffectSendLevel", "(F)I");
-    int result = env->CallIntMethod(mAudioTrackObj, jSetAuxEffectSendLevel, level);
-    return javaToNativeStatus(result);
-}
-
-status_t JAudioTrack::attachAuxEffect(int effectId) {
-    JNIEnv *env = JavaVMHelper::getJNIEnv();
-    jmethodID jAttachAuxEffect = env->GetMethodID(mAudioTrackCls, "attachAuxEffect", "(I)I");
-    int result = env->CallIntMethod(mAudioTrackObj, jAttachAuxEffect, effectId);
-    return javaToNativeStatus(result);
-}
-
-status_t JAudioTrack::setVolume(float left, float right) {
-    JNIEnv *env = JavaVMHelper::getJNIEnv();
-    // TODO: Java setStereoVolume is deprecated. Do we really need this method?
-    jmethodID jSetStereoVolume = env->GetMethodID(mAudioTrackCls, "setStereoVolume", "(FF)I");
-    int result = env->CallIntMethod(mAudioTrackObj, jSetStereoVolume, left, right);
-    return javaToNativeStatus(result);
-}
-
-status_t JAudioTrack::setVolume(float volume) {
-    JNIEnv *env = JavaVMHelper::getJNIEnv();
-    jmethodID jSetVolume = env->GetMethodID(mAudioTrackCls, "setVolume", "(F)I");
-    int result = env->CallIntMethod(mAudioTrackObj, jSetVolume, volume);
-    return javaToNativeStatus(result);
-}
-
-status_t JAudioTrack::start() {
-    JNIEnv *env = JavaVMHelper::getJNIEnv();
-    jmethodID jPlay = env->GetMethodID(mAudioTrackCls, "play", "()V");
-    // TODO: Should we catch the Java IllegalStateException from play()?
-    env->CallVoidMethod(mAudioTrackObj, jPlay);
-    return NO_ERROR;
-}
-
-ssize_t JAudioTrack::write(const void* buffer, size_t size, bool blocking) {
-    if (buffer == NULL) {
-        return BAD_VALUE;
-    }
-
-    JNIEnv *env = JavaVMHelper::getJNIEnv();
-    jbyteArray jAudioData = env->NewByteArray(size);
-    env->SetByteArrayRegion(jAudioData, 0, size, (jbyte *) buffer);
-
-    jclass jByteBufferCls = env->FindClass("java/nio/ByteBuffer");
-    jmethodID jWrap = env->GetStaticMethodID(jByteBufferCls, "wrap", "([B)Ljava/nio/ByteBuffer;");
-    jobject jByteBufferObj = env->CallStaticObjectMethod(jByteBufferCls, jWrap, jAudioData);
-
-    int writeMode = 0;
-    if (blocking) {
-        jfieldID jWriteBlocking = env->GetStaticFieldID(mAudioTrackCls, "WRITE_BLOCKING", "I");
-        writeMode = env->GetStaticIntField(mAudioTrackCls, jWriteBlocking);
-    } else {
-        jfieldID jWriteNonBlocking = env->GetStaticFieldID(
-                mAudioTrackCls, "WRITE_NON_BLOCKING", "I");
-        writeMode = env->GetStaticIntField(mAudioTrackCls, jWriteNonBlocking);
-    }
-
-    jmethodID jWrite = env->GetMethodID(mAudioTrackCls, "write", "(Ljava/nio/ByteBuffer;II)I");
-    int result = env->CallIntMethod(mAudioTrackObj, jWrite, jByteBufferObj, size, writeMode);
-
-    if (result >= 0) {
-        return result;
-    } else {
-        return javaToNativeStatus(result);
-    }
-}
-
-void JAudioTrack::stop() {
-    JNIEnv *env = JavaVMHelper::getJNIEnv();
-    jmethodID jStop = env->GetMethodID(mAudioTrackCls, "stop", "()V");
-    env->CallVoidMethod(mAudioTrackObj, jStop);
-    // TODO: Should we catch IllegalStateException?
-}
-
-// TODO: Is the right implementation?
-bool JAudioTrack::stopped() const {
-    return !isPlaying();
-}
-
-void JAudioTrack::flush() {
-    JNIEnv *env = JavaVMHelper::getJNIEnv();
-    jmethodID jFlush = env->GetMethodID(mAudioTrackCls, "flush", "()V");
-    env->CallVoidMethod(mAudioTrackObj, jFlush);
-}
-
-void JAudioTrack::pause() {
-    JNIEnv *env = JavaVMHelper::getJNIEnv();
-    jmethodID jPause = env->GetMethodID(mAudioTrackCls, "pause", "()V");
-    env->CallVoidMethod(mAudioTrackObj, jPause);
-    // TODO: Should we catch IllegalStateException?
-}
-
-bool JAudioTrack::isPlaying() const {
-    JNIEnv *env = JavaVMHelper::getJNIEnv();
-    jmethodID jGetPlayState = env->GetMethodID(mAudioTrackCls, "getPlayState", "()I");
-    int currentPlayState = env->CallIntMethod(mAudioTrackObj, jGetPlayState);
-
-    // TODO: In Java AudioTrack, there is no STOPPING state.
-    // This means while stopping, isPlaying() will return different value in two class.
-    //  - in existing native AudioTrack: true
-    //  - in JAudioTrack: false
-    // If not okay, also modify the implementation of stopped().
-    jfieldID jPlayStatePlaying = env->GetStaticFieldID(mAudioTrackCls, "PLAYSTATE_PLAYING", "I");
-    int statePlaying = env->GetStaticIntField(mAudioTrackCls, jPlayStatePlaying);
-    return currentPlayState == statePlaying;
-}
-
-uint32_t JAudioTrack::getSampleRate() {
-    JNIEnv *env = JavaVMHelper::getJNIEnv();
-    jmethodID jGetSampleRate = env->GetMethodID(mAudioTrackCls, "getSampleRate", "()I");
-    return env->CallIntMethod(mAudioTrackObj, jGetSampleRate);
-}
-
-status_t JAudioTrack::getBufferDurationInUs(int64_t *duration) {
-    if (duration == nullptr) {
-        return BAD_VALUE;
-    }
-
-    JNIEnv *env = JavaVMHelper::getJNIEnv();
-    jmethodID jGetBufferSizeInFrames = env->GetMethodID(
-            mAudioTrackCls, "getBufferSizeInFrames", "()I");
-    int bufferSizeInFrames = env->CallIntMethod(mAudioTrackObj, jGetBufferSizeInFrames);
-
-    const double secondToMicro = 1000000LL; // 1E6
-    int sampleRate = JAudioTrack::getSampleRate();
-    float speed = JAudioTrack::getPlaybackRate().mSpeed;
-
-    *duration = (int64_t) (bufferSizeInFrames * secondToMicro / (sampleRate * speed));
-    return NO_ERROR;
-}
-
-audio_format_t JAudioTrack::format() {
-    JNIEnv *env = JavaVMHelper::getJNIEnv();
-    jmethodID jGetAudioFormat = env->GetMethodID(mAudioTrackCls, "getAudioFormat", "()I");
-    int javaFormat = env->CallIntMethod(mAudioTrackObj, jGetAudioFormat);
-    return audioFormatToNative(javaFormat);
-}
-
-size_t JAudioTrack::frameSize() {
-    JNIEnv *env = JavaVMHelper::getJNIEnv();
-    jmethodID jGetFormat = env->GetMethodID(mAudioTrackCls,
-            "getFormat", "()Landroid/media/AudioFormat;");
-    jobject jAudioFormatObj = env->CallObjectMethod(mAudioTrackObj, jGetFormat);
-
-    jclass jAudioFormatCls = env->FindClass("android/media/AudioFormat");
-    jmethodID jGetFrameSizeInBytes = env->GetMethodID(
-            jAudioFormatCls, "getFrameSizeInBytes", "()I");
-    jint javaFrameSizeInBytes = env->CallIntMethod(jAudioFormatObj, jGetFrameSizeInBytes);
-
-    return (size_t)javaFrameSizeInBytes;
-}
-
-status_t JAudioTrack::dump(int fd, const Vector<String16>& args __unused) const
-{
-    String8 result;
-
-    result.append(" JAudioTrack::dump\n");
-
-    // TODO: Remove logs that includes unavailable information from below.
-//    result.appendFormat("  status(%d), state(%d), session Id(%d), flags(%#x)\n",
-//                        mStatus, mState, mSessionId, mFlags);
-//    result.appendFormat("  format(%#x), channel mask(%#x), channel count(%u)\n",
-//                  format(), mChannelMask, channelCount());
-//    result.appendFormat("  sample rate(%u), original sample rate(%u), speed(%f)\n",
-//            getSampleRate(), mOriginalSampleRate, mPlaybackRate.mSpeed);
-//    result.appendFormat("  frame count(%zu), req. frame count(%zu)\n",
-//                  frameCount(), mReqFrameCount);
-//    result.appendFormat("  notif. frame count(%u), req. notif. frame count(%u),"
-//            " req. notif. per buff(%u)\n",
-//             mNotificationFramesAct, mNotificationFramesReq, mNotificationsPerBufferReq);
-//    result.appendFormat("  latency (%d), selected device Id(%d), routed device Id(%d)\n",
-//                        latency(), mSelectedDeviceId, getRoutedDeviceId());
-//    result.appendFormat("  output(%d) AF latency (%u) AF frame count(%zu) AF SampleRate(%u)\n",
-//                        mOutput, mAfLatency, mAfFrameCount, mAfSampleRate);
-    ::write(fd, result.string(), result.size());
-    return NO_ERROR;
-}
-
-jobject JAudioTrack::getRoutedDevice() {
-    JNIEnv *env = JavaVMHelper::getJNIEnv();
-    jmethodID jGetRoutedDevice = env->GetMethodID(mAudioTrackCls, "getRoutedDevice",
-            "()Landroid/media/AudioDeviceInfo;");
-    return env->CallObjectMethod(mAudioTrackObj, jGetRoutedDevice);
-}
-
-int32_t JAudioTrack::getAudioSessionId() {
-    JNIEnv *env = JavaVMHelper::getJNIEnv();
-    jmethodID jGetAudioSessionId = env->GetMethodID(mAudioTrackCls, "getAudioSessionId", "()I");
-    jint sessionId = env->CallIntMethod(mAudioTrackObj, jGetAudioSessionId);
-    return sessionId;
-}
-
-status_t JAudioTrack::setPreferredDevice(jobject device) {
-    JNIEnv *env = JavaVMHelper::getJNIEnv();
-    jmethodID jSetPreferredDeviceId = env->GetMethodID(mAudioTrackCls, "setPreferredDevice",
-            "(Landroid/media/AudioDeviceInfo;)Z");
-    jboolean result = env->CallBooleanMethod(mAudioTrackObj, jSetPreferredDeviceId, device);
-    return result == true ? NO_ERROR : BAD_VALUE;
-}
-
-audio_stream_type_t JAudioTrack::getAudioStreamType() {
-    JNIEnv *env = JavaVMHelper::getJNIEnv();
-    jmethodID jGetAudioAttributes = env->GetMethodID(mAudioTrackCls, "getAudioAttributes",
-            "()Landroid/media/AudioAttributes;");
-    jobject jAudioAttributes = env->CallObjectMethod(mAudioTrackObj, jGetAudioAttributes);
-    jclass jAudioAttributesCls = env->FindClass("android/media/AudioAttributes");
-    jmethodID jGetVolumeControlStream = env->GetMethodID(jAudioAttributesCls,
-            "getVolumeControlStream", "()I");
-    int javaAudioStreamType = env->CallIntMethod(jAudioAttributes, jGetVolumeControlStream);
-    return (audio_stream_type_t)javaAudioStreamType;
-}
-
-status_t JAudioTrack::pendingDuration(int32_t *msec) {
-    if (msec == nullptr) {
-        return BAD_VALUE;
-    }
-
-    bool isPurePcmData = audio_is_linear_pcm(format()) && (getFlags() & AUDIO_FLAG_HW_AV_SYNC) == 0;
-    if (!isPurePcmData) {
-        return INVALID_OPERATION;
-    }
-
-    // TODO: Need to know the difference btw. client and server time.
-    // If getTimestamp(ExtendedTimestamp) is ready, and un-comment below and modify appropriately.
-    // (copied from AudioTrack.cpp)
-
-//    ExtendedTimestamp ets;
-//    ExtendedTimestamp::LOCATION location = ExtendedTimestamp::LOCATION_SERVER;
-//    if (getTimestamp_l(&ets) == OK && ets.mTimeNs[location] > 0) {
-//        int64_t diff = ets.mPosition[ExtendedTimestamp::LOCATION_CLIENT]
-//                - ets.mPosition[location];
-//        if (diff < 0) {
-//            *msec = 0;
-//        } else {
-//            // ms is the playback time by frames
-//            int64_t ms = (int64_t)((double)diff * 1000 /
-//                    ((double)mSampleRate * mPlaybackRate.mSpeed));
-//            // clockdiff is the timestamp age (negative)
-//            int64_t clockdiff = (mState != STATE_ACTIVE) ? 0 :
-//                    ets.mTimeNs[location]
-//                    + ets.mTimebaseOffset[ExtendedTimestamp::TIMEBASE_MONOTONIC]
-//                    - systemTime(SYSTEM_TIME_MONOTONIC);
-//
-//            //ALOGV("ms: %lld  clockdiff: %lld", (long long)ms, (long long)clockdiff);
-//            static const int NANOS_PER_MILLIS = 1000000;
-//            *msec = (int32_t)(ms + clockdiff / NANOS_PER_MILLIS);
-//        }
-//        return NO_ERROR;
-//    }
-
-    return NO_ERROR;
-}
-
-status_t JAudioTrack::addAudioDeviceCallback(jobject listener, jobject handler) {
-    JNIEnv *env = JavaVMHelper::getJNIEnv();
-    jmethodID jAddOnRoutingChangedListener = env->GetMethodID(mAudioTrackCls,
-            "addOnRoutingChangedListener",
-            "(Landroid/media/AudioRouting$OnRoutingChangedListener;Landroid/os/Handler;)V");
-    env->CallVoidMethod(mAudioTrackObj, jAddOnRoutingChangedListener, listener, handler);
-    return NO_ERROR;
-}
-
-status_t JAudioTrack::removeAudioDeviceCallback(jobject listener) {
-    JNIEnv *env = JavaVMHelper::getJNIEnv();
-    jmethodID jRemoveOnRoutingChangedListener = env->GetMethodID(mAudioTrackCls,
-            "removeOnRoutingChangedListener",
-            "(Landroid/media/AudioRouting$OnRoutingChangedListener;)V");
-    env->CallVoidMethod(mAudioTrackObj, jRemoveOnRoutingChangedListener, listener);
-    return NO_ERROR;
-}
-
-void JAudioTrack::registerRoutingDelegates(
-        Vector<std::pair<sp<JObjectHolder>, sp<JObjectHolder>>>& routingDelegates) {
-    for (auto it = routingDelegates.begin(); it != routingDelegates.end(); it++) {
-        addAudioDeviceCallback(it->second->getJObject(), getHandler(it->second->getJObject()));
-    }
-}
-
-/////////////////////////////////////////////////////////////
-///                Static methods begin                   ///
-/////////////////////////////////////////////////////////////
-jobject JAudioTrack::getListener(const jobject routingDelegateObj) {
-    JNIEnv *env = JavaVMHelper::getJNIEnv();
-    jclass jRoutingDelegateCls = env->FindClass("android/media/RoutingDelegate");
-    jmethodID jGetListener = env->GetMethodID(jRoutingDelegateCls,
-            "getListener", "()Landroid/media/AudioRouting$OnRoutingChangedListener;");
-    return env->CallObjectMethod(routingDelegateObj, jGetListener);
-}
-
-jobject JAudioTrack::getHandler(const jobject routingDelegateObj) {
-    JNIEnv *env = JavaVMHelper::getJNIEnv();
-    jclass jRoutingDelegateCls = env->FindClass("android/media/RoutingDelegate");
-    jmethodID jGetHandler = env->GetMethodID(jRoutingDelegateCls,
-        "getHandler", "()Landroid/os/Handler;");
-    return env->CallObjectMethod(routingDelegateObj, jGetHandler);
-}
-
-jobject JAudioTrack::findByKey(
-        Vector<std::pair<sp<JObjectHolder>, sp<JObjectHolder>>>& mp, const jobject key) {
-    JNIEnv *env = JavaVMHelper::getJNIEnv();
-    for (auto it = mp.begin(); it != mp.end(); it++) {
-        if (env->IsSameObject(it->first->getJObject(), key)) {
-            return it->second->getJObject();
-        }
-    }
-    return nullptr;
-}
-
-void JAudioTrack::eraseByKey(
-        Vector<std::pair<sp<JObjectHolder>, sp<JObjectHolder>>>& mp, const jobject key) {
-    JNIEnv *env = JavaVMHelper::getJNIEnv();
-    for (auto it = mp.begin(); it != mp.end(); it++) {
-        if (env->IsSameObject(it->first->getJObject(), key)) {
-            mp.erase(it);
-            return;
-        }
-    }
-}
-
-/////////////////////////////////////////////////////////////
-///                Private method begins                  ///
-/////////////////////////////////////////////////////////////
-
-jobject JAudioTrack::createVolumeShaperConfigurationObj(
-        const sp<media::VolumeShaper::Configuration>& config) {
-
-    // TODO: Java VolumeShaper's setId() / setOptionFlags() are hidden.
-    if (config == NULL || config->getType() == media::VolumeShaper::Configuration::TYPE_ID) {
-        return NULL;
-    }
-
-    JNIEnv *env = JavaVMHelper::getJNIEnv();
-
-    // Referenced "android_media_VolumeShaper.h".
-    jfloatArray xarray = nullptr;
-    jfloatArray yarray = nullptr;
-    if (config->getType() == media::VolumeShaper::Configuration::TYPE_SCALE) {
-        // convert curve arrays
-        xarray = env->NewFloatArray(config->size());
-        yarray = env->NewFloatArray(config->size());
-        float * const x = env->GetFloatArrayElements(xarray, nullptr /* isCopy */);
-        float * const y = env->GetFloatArrayElements(yarray, nullptr /* isCopy */);
-        float *xptr = x, *yptr = y;
-        for (const auto &pt : *config.get()) {
-            *xptr++ = pt.first;
-            *yptr++ = pt.second;
-        }
-        env->ReleaseFloatArrayElements(xarray, x, 0 /* mode */);
-        env->ReleaseFloatArrayElements(yarray, y, 0 /* mode */);
-    }
-
-    jclass jBuilderCls = env->FindClass("android/media/VolumeShaper$Configuration$Builder");
-    jmethodID jBuilderCtor = env->GetMethodID(jBuilderCls, "<init>", "()V");
-    jobject jBuilderObj = env->NewObject(jBuilderCls, jBuilderCtor);
-
-    jmethodID jSetDuration = env->GetMethodID(jBuilderCls, "setDuration",
-            "(L)Landroid/media/VolumeShaper$Configuration$Builder;");
-    jBuilderObj = env->CallObjectMethod(jBuilderCls, jSetDuration, (jlong) config->getDurationMs());
-
-    jmethodID jSetInterpolatorType = env->GetMethodID(jBuilderCls, "setInterpolatorType",
-            "(I)Landroid/media/VolumeShaper$Configuration$Builder;");
-    jBuilderObj = env->CallObjectMethod(jBuilderCls, jSetInterpolatorType,
-            config->getInterpolatorType());
-
-    jmethodID jSetCurve = env->GetMethodID(jBuilderCls, "setCurve",
-            "([F[F)Landroid/media/VolumeShaper$Configuration$Builder;");
-    jBuilderObj = env->CallObjectMethod(jBuilderCls, jSetCurve, xarray, yarray);
-
-    jmethodID jBuild = env->GetMethodID(jBuilderCls, "build",
-            "()Landroid/media/VolumeShaper$Configuration;");
-    return env->CallObjectMethod(jBuilderObj, jBuild);
-}
-
-jobject JAudioTrack::createVolumeShaperOperationObj(
-        const sp<media::VolumeShaper::Operation>& operation) {
-
-    JNIEnv *env = JavaVMHelper::getJNIEnv();
-
-    jclass jBuilderCls = env->FindClass("android/media/VolumeShaper$Operation$Builder");
-    jmethodID jBuilderCtor = env->GetMethodID(jBuilderCls, "<init>", "()V");
-    jobject jBuilderObj = env->NewObject(jBuilderCls, jBuilderCtor);
-
-    // Set XOffset
-    jmethodID jSetXOffset = env->GetMethodID(jBuilderCls, "setXOffset",
-            "(F)Landroid/media/VolumeShaper$Operation$Builder;");
-    jBuilderObj = env->CallObjectMethod(jBuilderCls, jSetXOffset, operation->getXOffset());
-
-    int32_t flags = operation->getFlags();
-
-    if (operation->getReplaceId() >= 0) {
-        jmethodID jReplace = env->GetMethodID(jBuilderCls, "replace",
-                "(IB)Landroid/media/VolumeShaper$Operation$Builder;");
-        bool join = (flags | media::VolumeShaper::Operation::FLAG_JOIN) != 0;
-        jBuilderObj = env->CallObjectMethod(jBuilderCls, jReplace, operation->getReplaceId(), join);
-    }
-
-    if (flags | media::VolumeShaper::Operation::FLAG_REVERSE) {
-        jmethodID jReverse = env->GetMethodID(jBuilderCls, "reverse",
-                "()Landroid/media/VolumeShaper$Operation$Builder;");
-        jBuilderObj = env->CallObjectMethod(jBuilderCls, jReverse);
-    }
-
-    // TODO: VolumeShaper Javadoc says "Do not call terminate() directly". Can we call this?
-    if (flags | media::VolumeShaper::Operation::FLAG_TERMINATE) {
-        jmethodID jTerminate = env->GetMethodID(jBuilderCls, "terminate",
-                "()Landroid/media/VolumeShaper$Operation$Builder;");
-        jBuilderObj = env->CallObjectMethod(jBuilderCls, jTerminate);
-    }
-
-    if (flags | media::VolumeShaper::Operation::FLAG_DELAY) {
-        jmethodID jDefer = env->GetMethodID(jBuilderCls, "defer",
-                "()Landroid/media/VolumeShaper$Operation$Builder;");
-        jBuilderObj = env->CallObjectMethod(jBuilderCls, jDefer);
-    }
-
-    if (flags | media::VolumeShaper::Operation::FLAG_CREATE_IF_NECESSARY) {
-        jmethodID jCreateIfNeeded = env->GetMethodID(jBuilderCls, "createIfNeeded",
-                "()Landroid/media/VolumeShaper$Operation$Builder;");
-        jBuilderObj = env->CallObjectMethod(jBuilderCls, jCreateIfNeeded);
-    }
-
-    // TODO: Handle error case (can it be NULL?)
-    jmethodID jBuild = env->GetMethodID(jBuilderCls, "build",
-            "()Landroid/media/VolumeShaper$Operation;");
-    return env->CallObjectMethod(jBuilderObj, jBuild);
-}
-
-jobject JAudioTrack::createStreamEventCallback(callback_t cbf, void* user) {
-    JNIEnv *env = JavaVMHelper::getJNIEnv();
-    jclass jCallbackCls = env->FindClass("android/media/MediaPlayer2$StreamEventCallback");
-    jmethodID jCallbackCtor = env->GetMethodID(jCallbackCls, "<init>", "(JJJ)V");
-    jobject jCallbackObj = env->NewObject(jCallbackCls, jCallbackCtor, this, cbf, user);
-    return jCallbackObj;
-}
-
-jobject JAudioTrack::createCallbackExecutor() {
-    JNIEnv *env = JavaVMHelper::getJNIEnv();
-    jclass jExecutorsCls = env->FindClass("java/util/concurrent/Executors");
-    jmethodID jNewSingleThreadExecutor = env->GetStaticMethodID(jExecutorsCls,
-            "newSingleThreadExecutor", "()Ljava/util/concurrent/ExecutorService;");
-    jobject jSingleThreadExecutorObj =
-            env->CallStaticObjectMethod(jExecutorsCls, jNewSingleThreadExecutor);
-    return jSingleThreadExecutorObj;
-}
-
-status_t JAudioTrack::javaToNativeStatus(int javaStatus) {
-    switch (javaStatus) {
-    case AUDIO_JAVA_SUCCESS:
-        return NO_ERROR;
-    case AUDIO_JAVA_BAD_VALUE:
-        return BAD_VALUE;
-    case AUDIO_JAVA_INVALID_OPERATION:
-        return INVALID_OPERATION;
-    case AUDIO_JAVA_PERMISSION_DENIED:
-        return PERMISSION_DENIED;
-    case AUDIO_JAVA_NO_INIT:
-        return NO_INIT;
-    case AUDIO_JAVA_WOULD_BLOCK:
-        return WOULD_BLOCK;
-    case AUDIO_JAVA_DEAD_OBJECT:
-        return DEAD_OBJECT;
-    default:
-        return UNKNOWN_ERROR;
-    }
-}
-
-} // namespace android
diff --git a/media/libmediaplayer2/JMedia2HTTPConnection.cpp b/media/libmediaplayer2/JMedia2HTTPConnection.cpp
deleted file mode 100644
index e1baa10..0000000
--- a/media/libmediaplayer2/JMedia2HTTPConnection.cpp
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * Copyright 2017, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-//#define LOG_NDEBUG 0
-#define LOG_TAG "JMedia2HTTPConnection"
-#include <utils/Log.h>
-
-#include <mediaplayer2/JavaVMHelper.h>
-#include <mediaplayer2/JMedia2HTTPConnection.h>
-#include <media/stagefright/foundation/ADebug.h>
-#include <nativehelper/scoped_local_ref.h>
-
-#include "log/log.h"
-#include "jni.h"
-
-namespace android {
-
-static const size_t kBufferSize = 32768;
-
-JMedia2HTTPConnection::JMedia2HTTPConnection(JNIEnv *env, jobject thiz) {
-    mMedia2HTTPConnectionObj = env->NewGlobalRef(thiz);
-    CHECK(mMedia2HTTPConnectionObj != NULL);
-
-    ScopedLocalRef<jclass> media2HTTPConnectionClass(
-            env, env->GetObjectClass(mMedia2HTTPConnectionObj));
-    CHECK(media2HTTPConnectionClass.get() != NULL);
-
-    mConnectMethod = env->GetMethodID(
-            media2HTTPConnectionClass.get(),
-            "connect",
-            "(Ljava/lang/String;Ljava/lang/String;)Z");
-    CHECK(mConnectMethod != NULL);
-
-    mDisconnectMethod = env->GetMethodID(
-            media2HTTPConnectionClass.get(),
-            "disconnect",
-            "()V");
-    CHECK(mDisconnectMethod != NULL);
-
-    mReadAtMethod = env->GetMethodID(
-            media2HTTPConnectionClass.get(),
-            "readAt",
-            "(J[BI)I");
-    CHECK(mReadAtMethod != NULL);
-
-    mGetSizeMethod = env->GetMethodID(
-            media2HTTPConnectionClass.get(),
-            "getSize",
-            "()J");
-    CHECK(mGetSizeMethod != NULL);
-
-    mGetMIMETypeMethod = env->GetMethodID(
-            media2HTTPConnectionClass.get(),
-            "getMIMEType",
-            "()Ljava/lang/String;");
-    CHECK(mGetMIMETypeMethod != NULL);
-
-    mGetUriMethod = env->GetMethodID(
-            media2HTTPConnectionClass.get(),
-            "getUri",
-            "()Ljava/lang/String;");
-    CHECK(mGetUriMethod != NULL);
-
-    ScopedLocalRef<jbyteArray> tmp(
-        env, env->NewByteArray(kBufferSize));
-    mByteArrayObj = (jbyteArray)env->NewGlobalRef(tmp.get());
-    CHECK(mByteArrayObj != NULL);
-}
-
-JMedia2HTTPConnection::~JMedia2HTTPConnection() {
-    JNIEnv *env = JavaVMHelper::getJNIEnv();
-    env->DeleteGlobalRef(mMedia2HTTPConnectionObj);
-    env->DeleteGlobalRef(mByteArrayObj);
-}
-
-bool JMedia2HTTPConnection::connect(
-        const char *uri, const KeyedVector<String8, String8> *headers) {
-    String8 tmp("");
-    if (headers != NULL) {
-        for (size_t i = 0; i < headers->size(); ++i) {
-            tmp.append(headers->keyAt(i));
-            tmp.append(String8(": "));
-            tmp.append(headers->valueAt(i));
-            tmp.append(String8("\r\n"));
-        }
-    }
-
-    JNIEnv* env = JavaVMHelper::getJNIEnv();
-    jstring juri = env->NewStringUTF(uri);
-    jstring jheaders = env->NewStringUTF(tmp.string());
-
-    jboolean ret =
-        env->CallBooleanMethod(mMedia2HTTPConnectionObj, mConnectMethod, juri, jheaders);
-
-    env->DeleteLocalRef(juri);
-    env->DeleteLocalRef(jheaders);
-
-    return (bool)ret;
-}
-
-void JMedia2HTTPConnection::disconnect() {
-    JNIEnv* env = JavaVMHelper::getJNIEnv();
-    env->CallVoidMethod(mMedia2HTTPConnectionObj, mDisconnectMethod);
-}
-
-ssize_t JMedia2HTTPConnection::readAt(off64_t offset, void *data, size_t size) {
-    JNIEnv* env = JavaVMHelper::getJNIEnv();
-
-    if (size > kBufferSize) {
-        size = kBufferSize;
-    }
-
-    jint n = env->CallIntMethod(
-            mMedia2HTTPConnectionObj, mReadAtMethod, (jlong)offset, mByteArrayObj, (jint)size);
-
-    if (n > 0) {
-        env->GetByteArrayRegion(
-                mByteArrayObj,
-                0,
-                n,
-                (jbyte *)data);
-    }
-
-    return n;
-}
-
-off64_t JMedia2HTTPConnection::getSize() {
-    JNIEnv* env = JavaVMHelper::getJNIEnv();
-    return (off64_t)(env->CallLongMethod(mMedia2HTTPConnectionObj, mGetSizeMethod));
-}
-
-status_t JMedia2HTTPConnection::getMIMEType(String8 *mimeType) {
-    JNIEnv* env = JavaVMHelper::getJNIEnv();
-    jstring jmime = (jstring)env->CallObjectMethod(mMedia2HTTPConnectionObj, mGetMIMETypeMethod);
-    jboolean flag = env->ExceptionCheck();
-    if (flag) {
-        env->ExceptionClear();
-        return UNKNOWN_ERROR;
-    }
-
-    const char *str = env->GetStringUTFChars(jmime, 0);
-    if (str != NULL) {
-        *mimeType = String8(str);
-    } else {
-        *mimeType = "application/octet-stream";
-    }
-    env->ReleaseStringUTFChars(jmime, str);
-    return OK;
-}
-
-status_t JMedia2HTTPConnection::getUri(String8 *uri) {
-    JNIEnv* env = JavaVMHelper::getJNIEnv();
-    jstring juri = (jstring)env->CallObjectMethod(mMedia2HTTPConnectionObj, mGetUriMethod);
-    jboolean flag = env->ExceptionCheck();
-    if (flag) {
-        env->ExceptionClear();
-        return UNKNOWN_ERROR;
-    }
-
-    const char *str = env->GetStringUTFChars(juri, 0);
-    *uri = String8(str);
-    env->ReleaseStringUTFChars(juri, str);
-    return OK;
-}
-
-}  // namespace android
diff --git a/media/libmediaplayer2/JMedia2HTTPService.cpp b/media/libmediaplayer2/JMedia2HTTPService.cpp
deleted file mode 100644
index 20e3573..0000000
--- a/media/libmediaplayer2/JMedia2HTTPService.cpp
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright 2017, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-//#define LOG_NDEBUG 0
-#define LOG_TAG "JMedia2HTTPService"
-#include <utils/Log.h>
-
-#include <jni.h>
-
-#include <mediaplayer2/JavaVMHelper.h>
-#include <mediaplayer2/JMedia2HTTPService.h>
-#include <mediaplayer2/JMedia2HTTPConnection.h>
-#include <media/stagefright/foundation/ADebug.h>
-
-#include <nativehelper/scoped_local_ref.h>
-
-namespace android {
-
-JMedia2HTTPService::JMedia2HTTPService(JNIEnv *env, jobject thiz) {
-    mMedia2HTTPServiceObj = env->NewGlobalRef(thiz);
-    CHECK(mMedia2HTTPServiceObj != NULL);
-
-    ScopedLocalRef<jclass> media2HTTPServiceClass(env, env->GetObjectClass(mMedia2HTTPServiceObj));
-    CHECK(media2HTTPServiceClass.get() != NULL);
-
-    mMakeHTTPConnectionMethod = env->GetMethodID(
-            media2HTTPServiceClass.get(),
-            "makeHTTPConnection",
-            "()Landroid/media/Media2HTTPConnection;");
-    CHECK(mMakeHTTPConnectionMethod != NULL);
-}
-
-JMedia2HTTPService::~JMedia2HTTPService() {
-    JNIEnv *env = JavaVMHelper::getJNIEnv();
-    env->DeleteGlobalRef(mMedia2HTTPServiceObj);
-}
-
-sp<MediaHTTPConnection> JMedia2HTTPService::makeHTTPConnection() {
-    JNIEnv* env = JavaVMHelper::getJNIEnv();
-    jobject media2HTTPConnectionObj =
-        env->CallObjectMethod(mMedia2HTTPServiceObj, mMakeHTTPConnectionMethod);
-
-    return new JMedia2HTTPConnection(env, media2HTTPConnectionObj);
-}
-
-}  // namespace android
diff --git a/media/libmediaplayer2/JavaVMHelper.cpp b/media/libmediaplayer2/JavaVMHelper.cpp
deleted file mode 100644
index 8d03ed0..0000000
--- a/media/libmediaplayer2/JavaVMHelper.cpp
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "JavaVMHelper"
-
-#include "mediaplayer2/JavaVMHelper.h"
-
-#include <media/stagefright/foundation/ADebug.h>
-#include <utils/threads.h>
-
-#include <stdlib.h>
-
-namespace android {
-
-// static
-std::atomic<JavaVM *> JavaVMHelper::sJavaVM(NULL);
-
-/*
- * Makes the current thread visible to the VM.
- *
- * The JNIEnv pointer returned is only valid for the current thread, and
- * thus must be tucked into thread-local storage.
- */
-static int javaAttachThread(const char* threadName, JNIEnv** pEnv) {
-    JavaVMAttachArgs args;
-    JavaVM* vm;
-    jint result;
-
-    vm = JavaVMHelper::getJavaVM();
-    if (vm == NULL) {
-        return JNI_ERR;
-    }
-
-    args.version = JNI_VERSION_1_4;
-    args.name = (char*) threadName;
-    args.group = NULL;
-
-    result = vm->AttachCurrentThread(pEnv, (void*) &args);
-    if (result != JNI_OK) {
-        ALOGI("NOTE: attach of thread '%s' failed\n", threadName);
-    }
-
-    return result;
-}
-
-/*
- * Detach the current thread from the set visible to the VM.
- */
-static int javaDetachThread(void) {
-    JavaVM* vm;
-    jint result;
-
-    vm = JavaVMHelper::getJavaVM();
-    if (vm == NULL) {
-        return JNI_ERR;
-    }
-
-    result = vm->DetachCurrentThread();
-    if (result != JNI_OK) {
-        ALOGE("ERROR: thread detach failed\n");
-    }
-    return result;
-}
-
-/*
- * When starting a native thread that will be visible from the VM, we
- * bounce through this to get the right attach/detach action.
- * Note that this function calls free(args)
- */
-static int javaThreadShell(void* args) {
-    void* start = ((void**)args)[0];
-    void* userData = ((void **)args)[1];
-    char* name = (char*) ((void **)args)[2];        // we own this storage
-    free(args);
-    JNIEnv* env;
-    int result;
-
-    /* hook us into the VM */
-    if (javaAttachThread(name, &env) != JNI_OK) {
-        return -1;
-    }
-
-    /* start the thread running */
-    result = (*(android_thread_func_t)start)(userData);
-
-    /* unhook us */
-    javaDetachThread();
-    free(name);
-
-    return result;
-}
-
-/*
- * This is invoked from androidCreateThreadEtc() via the callback
- * set with androidSetCreateThreadFunc().
- *
- * We need to create the new thread in such a way that it gets hooked
- * into the VM before it really starts executing.
- */
-static int javaCreateThreadEtc(
-        android_thread_func_t entryFunction,
-        void* userData,
-        const char* threadName,
-        int32_t threadPriority,
-        size_t threadStackSize,
-        android_thread_id_t* threadId) {
-    void** args = (void**) malloc(3 * sizeof(void*));   // javaThreadShell must free
-    int result;
-
-    LOG_ALWAYS_FATAL_IF(threadName == nullptr, "threadName not provided to javaCreateThreadEtc");
-
-    args[0] = (void*) entryFunction;
-    args[1] = userData;
-    args[2] = (void*) strdup(threadName);   // javaThreadShell must free
-
-    result = androidCreateRawThreadEtc(javaThreadShell, args,
-        threadName, threadPriority, threadStackSize, threadId);
-    return result;
-}
-
-// static
-JNIEnv *JavaVMHelper::getJNIEnv() {
-    JNIEnv *env;
-    JavaVM *vm = sJavaVM.load();
-    CHECK(vm != NULL);
-
-    if (vm->GetEnv((void **)&env, JNI_VERSION_1_4) != JNI_OK) {
-        return NULL;
-    }
-
-    return env;
-}
-
-//static
-JavaVM *JavaVMHelper::getJavaVM() {
-    return sJavaVM.load();
-}
-
-// static
-void JavaVMHelper::setJavaVM(JavaVM *vm) {
-    sJavaVM.store(vm);
-
-    // Ensure that Thread(/*canCallJava*/ true) in libutils is attached to the VM.
-    // This is supposed to be done by runtime, but when libutils is used with linker
-    // namespace, CreateThreadFunc should be initialized separately within the namespace.
-    androidSetCreateThreadFunc((android_create_thread_fn) javaCreateThreadEtc);
-}
-
-}  // namespace android
diff --git a/media/libmediaplayer2/MediaPlayer2AudioOutput.cpp b/media/libmediaplayer2/MediaPlayer2AudioOutput.cpp
deleted file mode 100644
index b4fa0c1..0000000
--- a/media/libmediaplayer2/MediaPlayer2AudioOutput.cpp
+++ /dev/null
@@ -1,656 +0,0 @@
-/*
-**
-** Copyright 2018, 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 "MediaPlayer2AudioOutput"
-#include <mediaplayer2/MediaPlayer2AudioOutput.h>
-
-#include <cutils/properties.h> // for property_get
-#include <utils/Log.h>
-
-#include <media/stagefright/foundation/ADebug.h>
-
-namespace {
-
-const float kMaxRequiredSpeed = 8.0f; // for PCM tracks allow up to 8x speedup.
-
-} // anonymous namespace
-
-namespace android {
-
-// TODO: Find real cause of Audio/Video delay in PV framework and remove this workaround
-/* static */ int MediaPlayer2AudioOutput::mMinBufferCount = 4;
-/* static */ bool MediaPlayer2AudioOutput::mIsOnEmulator = false;
-
-status_t MediaPlayer2AudioOutput::dump(int fd, const Vector<String16>& args) const {
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-    String8 result;
-
-    result.append(" MediaPlayer2AudioOutput\n");
-    snprintf(buffer, 255, "  volume(%f)\n", mVolume);
-    result.append(buffer);
-    snprintf(buffer, 255, "  msec per frame(%f), latency (%d)\n",
-            mMsecsPerFrame, (mJAudioTrack != nullptr) ? mJAudioTrack->latency() : -1);
-    result.append(buffer);
-    snprintf(buffer, 255, "  aux effect id(%d), send level (%f)\n",
-            mAuxEffectId, mSendLevel);
-    result.append(buffer);
-
-    ::write(fd, result.string(), result.size());
-    if (mJAudioTrack != nullptr) {
-        mJAudioTrack->dump(fd, args);
-    }
-    return NO_ERROR;
-}
-
-MediaPlayer2AudioOutput::MediaPlayer2AudioOutput(int32_t sessionId, uid_t uid, int pid,
-        const jobject attributes)
-    : mCallback(nullptr),
-      mCallbackCookie(nullptr),
-      mCallbackData(nullptr),
-      mVolume(1.0),
-      mPlaybackRate(AUDIO_PLAYBACK_RATE_DEFAULT),
-      mSampleRateHz(0),
-      mMsecsPerFrame(0),
-      mFrameSize(0),
-      mSessionId(sessionId),
-      mUid(uid),
-      mPid(pid),
-      mSendLevel(0.0),
-      mAuxEffectId(0),
-      mFlags(AUDIO_OUTPUT_FLAG_NONE) {
-    ALOGV("MediaPlayer2AudioOutput(%d)", sessionId);
-
-    if (attributes != nullptr) {
-        mAttributes = new JObjectHolder(attributes);
-    }
-
-    setMinBufferCount();
-    mRoutingDelegates.clear();
-}
-
-MediaPlayer2AudioOutput::~MediaPlayer2AudioOutput() {
-    close();
-    delete mCallbackData;
-}
-
-//static
-void MediaPlayer2AudioOutput::setMinBufferCount() {
-    char value[PROPERTY_VALUE_MAX];
-    if (property_get("ro.kernel.qemu", value, 0)) {
-        mIsOnEmulator = true;
-        mMinBufferCount = 12;  // to prevent systematic buffer underrun for emulator
-    }
-}
-
-// static
-bool MediaPlayer2AudioOutput::isOnEmulator() {
-    setMinBufferCount();  // benign race wrt other threads
-    return mIsOnEmulator;
-}
-
-// static
-int MediaPlayer2AudioOutput::getMinBufferCount() {
-    setMinBufferCount();  // benign race wrt other threads
-    return mMinBufferCount;
-}
-
-ssize_t MediaPlayer2AudioOutput::bufferSize() const {
-    Mutex::Autolock lock(mLock);
-    if (mJAudioTrack == nullptr) {
-        return NO_INIT;
-    }
-    return mJAudioTrack->frameCount() * mFrameSize;
-}
-
-ssize_t MediaPlayer2AudioOutput::frameCount() const {
-    Mutex::Autolock lock(mLock);
-    if (mJAudioTrack == nullptr) {
-        return NO_INIT;
-    }
-    return mJAudioTrack->frameCount();
-}
-
-ssize_t MediaPlayer2AudioOutput::channelCount() const {
-    Mutex::Autolock lock(mLock);
-    if (mJAudioTrack == nullptr) {
-        return NO_INIT;
-    }
-    return mJAudioTrack->channelCount();
-}
-
-ssize_t MediaPlayer2AudioOutput::frameSize() const {
-    Mutex::Autolock lock(mLock);
-    if (mJAudioTrack == nullptr) {
-        return NO_INIT;
-    }
-    return mFrameSize;
-}
-
-uint32_t MediaPlayer2AudioOutput::latency () const {
-    Mutex::Autolock lock(mLock);
-    if (mJAudioTrack == nullptr) {
-        return 0;
-    }
-    return mJAudioTrack->latency();
-}
-
-float MediaPlayer2AudioOutput::msecsPerFrame() const {
-    Mutex::Autolock lock(mLock);
-    return mMsecsPerFrame;
-}
-
-status_t MediaPlayer2AudioOutput::getPosition(uint32_t *position) const {
-    Mutex::Autolock lock(mLock);
-    if (mJAudioTrack == nullptr) {
-        return NO_INIT;
-    }
-    return mJAudioTrack->getPosition(position);
-}
-
-status_t MediaPlayer2AudioOutput::getTimestamp(AudioTimestamp &ts) const {
-    Mutex::Autolock lock(mLock);
-    if (mJAudioTrack == nullptr) {
-        return NO_INIT;
-    }
-    return mJAudioTrack->getTimestamp(ts);
-}
-
-// TODO: Remove unnecessary calls to getPlayedOutDurationUs()
-// as it acquires locks and may query the audio driver.
-//
-// Some calls could conceivably retrieve extrapolated data instead of
-// accessing getTimestamp() or getPosition() every time a data buffer with
-// a media time is received.
-//
-// Calculate duration of played samples if played at normal rate (i.e., 1.0).
-int64_t MediaPlayer2AudioOutput::getPlayedOutDurationUs(int64_t nowUs) const {
-    Mutex::Autolock lock(mLock);
-    if (mJAudioTrack == nullptr || mSampleRateHz == 0) {
-        return 0;
-    }
-
-    uint32_t numFramesPlayed;
-    int64_t numFramesPlayedAtUs;
-    AudioTimestamp ts;
-
-    status_t res = mJAudioTrack->getTimestamp(ts);
-
-    if (res == OK) {                 // case 1: mixing audio tracks and offloaded tracks.
-        numFramesPlayed = ts.mPosition;
-        numFramesPlayedAtUs = ts.mTime.tv_sec * 1000000LL + ts.mTime.tv_nsec / 1000;
-        //ALOGD("getTimestamp: OK %d %lld", numFramesPlayed, (long long)numFramesPlayedAtUs);
-    } else {                         // case 2: transitory state on start of a new track
-                                     // case 3: transitory at new track or audio fast tracks.
-        numFramesPlayed = 0;
-        numFramesPlayedAtUs = nowUs;
-        //ALOGD("getTimestamp: WOULD_BLOCK %d %lld",
-        //        numFramesPlayed, (long long)numFramesPlayedAtUs);
-    }
-
-    // CHECK_EQ(numFramesPlayed & (1 << 31), 0);  // can't be negative until 12.4 hrs, test
-    // TODO: remove the (int32_t) casting below as it may overflow at 12.4 hours.
-    int64_t durationUs = (int64_t)((int32_t)numFramesPlayed * 1000000LL / mSampleRateHz)
-            + nowUs - numFramesPlayedAtUs;
-    if (durationUs < 0) {
-        // Occurs when numFramesPlayed position is very small and the following:
-        // (1) In case 1, the time nowUs is computed before getTimestamp() is called and
-        //     numFramesPlayedAtUs is greater than nowUs by time more than numFramesPlayed.
-        // (2) In case 3, using getPosition and adding mAudioSink->latency() to
-        //     numFramesPlayedAtUs, by a time amount greater than numFramesPlayed.
-        //
-        // Both of these are transitory conditions.
-        ALOGV("getPlayedOutDurationUs: negative duration %lld set to zero", (long long)durationUs);
-        durationUs = 0;
-    }
-    ALOGV("getPlayedOutDurationUs(%lld) nowUs(%lld) frames(%u) framesAt(%lld)",
-            (long long)durationUs, (long long)nowUs,
-            numFramesPlayed, (long long)numFramesPlayedAtUs);
-    return durationUs;
-}
-
-status_t MediaPlayer2AudioOutput::getFramesWritten(uint32_t *frameswritten) const {
-    Mutex::Autolock lock(mLock);
-    if (mJAudioTrack == nullptr) {
-        return NO_INIT;
-    }
-    ExtendedTimestamp ets;
-    status_t status = mJAudioTrack->getTimestamp(&ets);
-    if (status == OK || status == WOULD_BLOCK) {
-        *frameswritten = (uint32_t)ets.mPosition[ExtendedTimestamp::LOCATION_CLIENT];
-    }
-    return status;
-}
-
-void MediaPlayer2AudioOutput::setAudioAttributes(const jobject attributes) {
-    Mutex::Autolock lock(mLock);
-    mAttributes = (attributes == nullptr) ? nullptr : new JObjectHolder(attributes);
-}
-
-audio_stream_type_t MediaPlayer2AudioOutput::getAudioStreamType() const {
-    ALOGV("getAudioStreamType");
-    Mutex::Autolock lock(mLock);
-    if (mJAudioTrack == nullptr) {
-        return AUDIO_STREAM_DEFAULT;
-    }
-    return mJAudioTrack->getAudioStreamType();
-}
-
-void MediaPlayer2AudioOutput::close_l() {
-    mJAudioTrack.clear();
-}
-
-status_t MediaPlayer2AudioOutput::open(
-        uint32_t sampleRate, int channelCount, audio_channel_mask_t channelMask,
-        audio_format_t format,
-        AudioCallback cb, void *cookie,
-        audio_output_flags_t flags,
-        const audio_offload_info_t *offloadInfo,
-        uint32_t suggestedFrameCount) {
-    ALOGV("open(%u, %d, 0x%x, 0x%x, %d 0x%x)", sampleRate, channelCount, channelMask,
-                format, mSessionId, flags);
-
-    // offloading is only supported in callback mode for now.
-    // offloadInfo must be present if offload flag is set
-    if (((flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0) &&
-            ((cb == nullptr) || (offloadInfo == nullptr))) {
-        return BAD_VALUE;
-    }
-
-    // compute frame count for the AudioTrack internal buffer
-    const size_t frameCount =
-           ((flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0) ? 0 : suggestedFrameCount;
-
-    if (channelMask == CHANNEL_MASK_USE_CHANNEL_ORDER) {
-        channelMask = audio_channel_out_mask_from_count(channelCount);
-        if (0 == channelMask) {
-            ALOGE("open() error, can\'t derive mask for %d audio channels", channelCount);
-            return NO_INIT;
-        }
-    }
-
-    Mutex::Autolock lock(mLock);
-    mCallback = cb;
-    mCallbackCookie = cookie;
-
-    sp<JAudioTrack> jT;
-    CallbackData *newcbd = nullptr;
-
-    ALOGV("creating new JAudioTrack");
-
-    if (mCallback != nullptr) {
-        newcbd = new CallbackData(this);
-        jT = new JAudioTrack(
-                 sampleRate,
-                 format,
-                 channelMask,
-                 CallbackWrapper,
-                 newcbd,
-                 frameCount,
-                 mSessionId,
-                 mAttributes != nullptr ? mAttributes->getJObject() : nullptr,
-                 1.0f);  // default value for maxRequiredSpeed
-    } else {
-        // TODO: Due to buffer memory concerns, we use a max target playback speed
-        // based on mPlaybackRate at the time of open (instead of kMaxRequiredSpeed),
-        // also clamping the target speed to 1.0 <= targetSpeed <= kMaxRequiredSpeed.
-        const float targetSpeed =
-                std::min(std::max(mPlaybackRate.mSpeed, 1.0f), kMaxRequiredSpeed);
-        ALOGW_IF(targetSpeed != mPlaybackRate.mSpeed,
-                "track target speed:%f clamped from playback speed:%f",
-                targetSpeed, mPlaybackRate.mSpeed);
-        jT = new JAudioTrack(
-                 sampleRate,
-                 format,
-                 channelMask,
-                 nullptr,
-                 nullptr,
-                 frameCount,
-                 mSessionId,
-                 mAttributes != nullptr ? mAttributes->getJObject() : nullptr,
-                 targetSpeed);
-    }
-
-    if (jT == 0) {
-        ALOGE("Unable to create audio track");
-        delete newcbd;
-        // t goes out of scope, so reference count drops to zero
-        return NO_INIT;
-    }
-
-    CHECK((jT != nullptr) && ((mCallback == nullptr) || (newcbd != nullptr)));
-
-    mCallbackData = newcbd;
-    ALOGV("setVolume");
-    jT->setVolume(mVolume);
-
-    mSampleRateHz = sampleRate;
-    mFlags = flags;
-    mMsecsPerFrame = 1E3f / (mPlaybackRate.mSpeed * sampleRate);
-    mFrameSize = jT->frameSize();
-    mJAudioTrack = jT;
-
-    return updateTrack_l();
-}
-
-status_t MediaPlayer2AudioOutput::updateTrack_l() {
-    if (mJAudioTrack == nullptr) {
-        return NO_ERROR;
-    }
-
-    status_t res = NO_ERROR;
-    // Note some output devices may give us a direct track even though we don't specify it.
-    // Example: Line application b/17459982.
-    if ((mJAudioTrack->getFlags()
-            & (AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD | AUDIO_OUTPUT_FLAG_DIRECT)) == 0) {
-        res = mJAudioTrack->setPlaybackRate(mPlaybackRate);
-        if (res == NO_ERROR) {
-            mJAudioTrack->setAuxEffectSendLevel(mSendLevel);
-            res = mJAudioTrack->attachAuxEffect(mAuxEffectId);
-        }
-    }
-    if (mPreferredDevice != nullptr) {
-        mJAudioTrack->setPreferredDevice(mPreferredDevice->getJObject());
-    }
-
-    mJAudioTrack->registerRoutingDelegates(mRoutingDelegates);
-
-    ALOGV("updateTrack_l() DONE status %d", res);
-    return res;
-}
-
-status_t MediaPlayer2AudioOutput::start() {
-    ALOGV("start");
-    Mutex::Autolock lock(mLock);
-    if (mCallbackData != nullptr) {
-        mCallbackData->endTrackSwitch();
-    }
-    if (mJAudioTrack != nullptr) {
-        mJAudioTrack->setVolume(mVolume);
-        mJAudioTrack->setAuxEffectSendLevel(mSendLevel);
-        status_t status = mJAudioTrack->start();
-        return status;
-    }
-    return NO_INIT;
-}
-
-ssize_t MediaPlayer2AudioOutput::write(const void* buffer, size_t size, bool blocking) {
-    Mutex::Autolock lock(mLock);
-    LOG_ALWAYS_FATAL_IF(mCallback != nullptr, "Don't call write if supplying a callback.");
-
-    //ALOGV("write(%p, %u)", buffer, size);
-    if (mJAudioTrack != nullptr) {
-        return mJAudioTrack->write(buffer, size, blocking);
-    }
-    return NO_INIT;
-}
-
-void MediaPlayer2AudioOutput::stop() {
-    ALOGV("stop");
-    Mutex::Autolock lock(mLock);
-    if (mJAudioTrack != nullptr) {
-        mJAudioTrack->stop();
-    }
-}
-
-void MediaPlayer2AudioOutput::flush() {
-    ALOGV("flush");
-    Mutex::Autolock lock(mLock);
-    if (mJAudioTrack != nullptr) {
-        mJAudioTrack->flush();
-    }
-}
-
-void MediaPlayer2AudioOutput::pause() {
-    ALOGV("pause");
-    Mutex::Autolock lock(mLock);
-    if (mJAudioTrack != nullptr) {
-        mJAudioTrack->pause();
-    }
-}
-
-void MediaPlayer2AudioOutput::close() {
-    ALOGV("close");
-    sp<JAudioTrack> track;
-    {
-        Mutex::Autolock lock(mLock);
-        track = mJAudioTrack;
-        close_l(); // clears mJAudioTrack
-    }
-    // destruction of the track occurs outside of mutex.
-}
-
-void MediaPlayer2AudioOutput::setVolume(float volume) {
-    ALOGV("setVolume(%f)", volume);
-    Mutex::Autolock lock(mLock);
-    mVolume = volume;
-    if (mJAudioTrack != nullptr) {
-        mJAudioTrack->setVolume(volume);
-    }
-}
-
-status_t MediaPlayer2AudioOutput::setPlaybackRate(const AudioPlaybackRate &rate) {
-    ALOGV("setPlaybackRate(%f %f %d %d)",
-                rate.mSpeed, rate.mPitch, rate.mFallbackMode, rate.mStretchMode);
-    Mutex::Autolock lock(mLock);
-    if (mJAudioTrack == 0) {
-        // remember rate so that we can set it when the track is opened
-        mPlaybackRate = rate;
-        return OK;
-    }
-    status_t res = mJAudioTrack->setPlaybackRate(rate);
-    if (res != NO_ERROR) {
-        return res;
-    }
-    // rate.mSpeed is always greater than 0 if setPlaybackRate succeeded
-    CHECK_GT(rate.mSpeed, 0.f);
-    mPlaybackRate = rate;
-    if (mSampleRateHz != 0) {
-        mMsecsPerFrame = 1E3f / (rate.mSpeed * mSampleRateHz);
-    }
-    return res;
-}
-
-status_t MediaPlayer2AudioOutput::getPlaybackRate(AudioPlaybackRate *rate) {
-    ALOGV("getPlaybackRate");
-    Mutex::Autolock lock(mLock);
-    if (mJAudioTrack == 0) {
-        return NO_INIT;
-    }
-    *rate = mJAudioTrack->getPlaybackRate();
-    return NO_ERROR;
-}
-
-status_t MediaPlayer2AudioOutput::setAuxEffectSendLevel(float level) {
-    ALOGV("setAuxEffectSendLevel(%f)", level);
-    Mutex::Autolock lock(mLock);
-    mSendLevel = level;
-    if (mJAudioTrack != nullptr) {
-        return mJAudioTrack->setAuxEffectSendLevel(level);
-    }
-    return NO_ERROR;
-}
-
-status_t MediaPlayer2AudioOutput::attachAuxEffect(int effectId) {
-    ALOGV("attachAuxEffect(%d)", effectId);
-    Mutex::Autolock lock(mLock);
-    mAuxEffectId = effectId;
-    if (mJAudioTrack != nullptr) {
-        return mJAudioTrack->attachAuxEffect(effectId);
-    }
-    return NO_ERROR;
-}
-
-status_t MediaPlayer2AudioOutput::setPreferredDevice(jobject device) {
-    ALOGV("setPreferredDevice");
-    Mutex::Autolock lock(mLock);
-    status_t ret = NO_ERROR;
-    if (mJAudioTrack != nullptr) {
-        ret = mJAudioTrack->setPreferredDevice(device);
-    }
-    if (ret == NO_ERROR) {
-        mPreferredDevice = new JObjectHolder(device);
-    }
-    return ret;
-}
-
-jobject MediaPlayer2AudioOutput::getRoutedDevice() {
-    ALOGV("getRoutedDevice");
-    Mutex::Autolock lock(mLock);
-    if (mJAudioTrack != nullptr) {
-        return mJAudioTrack->getRoutedDevice();
-    }
-    return nullptr;
-}
-
-status_t MediaPlayer2AudioOutput::addAudioDeviceCallback(jobject jRoutingDelegate) {
-    ALOGV("addAudioDeviceCallback");
-    Mutex::Autolock lock(mLock);
-    jobject listener = JAudioTrack::getListener(jRoutingDelegate);
-    if (JAudioTrack::findByKey(mRoutingDelegates, listener) == nullptr) {
-        sp<JObjectHolder> listenerHolder = new JObjectHolder(listener);
-        jobject handler = JAudioTrack::getHandler(jRoutingDelegate);
-        sp<JObjectHolder> routingDelegateHolder = new JObjectHolder(jRoutingDelegate);
-
-        mRoutingDelegates.push_back(std::pair<sp<JObjectHolder>, sp<JObjectHolder>>(
-                listenerHolder, routingDelegateHolder));
-
-        if (mJAudioTrack != nullptr) {
-            return mJAudioTrack->addAudioDeviceCallback(
-                    routingDelegateHolder->getJObject(), handler);
-        }
-    }
-    return NO_ERROR;
-}
-
-status_t MediaPlayer2AudioOutput::removeAudioDeviceCallback(jobject listener) {
-    ALOGV("removeAudioDeviceCallback");
-    Mutex::Autolock lock(mLock);
-    jobject routingDelegate = nullptr;
-    if ((routingDelegate = JAudioTrack::findByKey(mRoutingDelegates, listener)) != nullptr) {
-        if (mJAudioTrack != nullptr) {
-            mJAudioTrack->removeAudioDeviceCallback(routingDelegate);
-        }
-        JAudioTrack::eraseByKey(mRoutingDelegates, listener);
-    }
-    return NO_ERROR;
-}
-
-// static
-void MediaPlayer2AudioOutput::CallbackWrapper(
-        int event, void *cookie, void *info) {
-    //ALOGV("callbackwrapper");
-    CallbackData *data = (CallbackData*)cookie;
-    // lock to ensure we aren't caught in the middle of a track switch.
-    data->lock();
-    MediaPlayer2AudioOutput *me = data->getOutput();
-    JAudioTrack::Buffer *buffer = (JAudioTrack::Buffer *)info;
-    if (me == nullptr) {
-        // no output set, likely because the track was scheduled to be reused
-        // by another player, but the format turned out to be incompatible.
-        data->unlock();
-        if (buffer != nullptr) {
-            buffer->mSize = 0;
-        }
-        return;
-    }
-
-    switch(event) {
-    case JAudioTrack::EVENT_MORE_DATA: {
-        size_t actualSize = (*me->mCallback)(
-                me, buffer->mData, buffer->mSize, me->mCallbackCookie,
-                CB_EVENT_FILL_BUFFER);
-
-        // Log when no data is returned from the callback.
-        // (1) We may have no data (especially with network streaming sources).
-        // (2) We may have reached the EOS and the audio track is not stopped yet.
-        // Note that AwesomePlayer/AudioPlayer will only return zero size when it reaches the EOS.
-        // NuPlayer2Renderer will return zero when it doesn't have data (it doesn't block to fill).
-        //
-        // This is a benign busy-wait, with the next data request generated 10 ms or more later;
-        // nevertheless for power reasons, we don't want to see too many of these.
-
-        ALOGV_IF(actualSize == 0 && buffer->mSize > 0, "callbackwrapper: empty buffer returned");
-
-        buffer->mSize = actualSize;
-        } break;
-
-    case JAudioTrack::EVENT_STREAM_END:
-        // currently only occurs for offloaded callbacks
-        ALOGV("callbackwrapper: deliver EVENT_STREAM_END");
-        (*me->mCallback)(me, nullptr /* buffer */, 0 /* size */,
-                me->mCallbackCookie, CB_EVENT_STREAM_END);
-        break;
-
-    case JAudioTrack::EVENT_NEW_IAUDIOTRACK :
-        ALOGV("callbackwrapper: deliver EVENT_TEAR_DOWN");
-        (*me->mCallback)(me,  nullptr /* buffer */, 0 /* size */,
-                me->mCallbackCookie, CB_EVENT_TEAR_DOWN);
-        break;
-
-    case JAudioTrack::EVENT_UNDERRUN:
-        // This occurs when there is no data available, typically
-        // when there is a failure to supply data to the AudioTrack.  It can also
-        // occur in non-offloaded mode when the audio device comes out of standby.
-        //
-        // If an AudioTrack underruns it outputs silence. Since this happens suddenly
-        // it may sound like an audible pop or glitch.
-        //
-        // The underrun event is sent once per track underrun; the condition is reset
-        // when more data is sent to the AudioTrack.
-        ALOGD("callbackwrapper: EVENT_UNDERRUN (discarded)");
-        break;
-
-    default:
-        ALOGE("received unknown event type: %d inside CallbackWrapper !", event);
-    }
-
-    data->unlock();
-}
-
-int32_t MediaPlayer2AudioOutput::getSessionId() const {
-    Mutex::Autolock lock(mLock);
-    return mSessionId;
-}
-
-void MediaPlayer2AudioOutput::setSessionId(const int32_t sessionId) {
-    Mutex::Autolock lock(mLock);
-    mSessionId = sessionId;
-}
-
-uint32_t MediaPlayer2AudioOutput::getSampleRate() const {
-    Mutex::Autolock lock(mLock);
-    if (mJAudioTrack == 0) {
-        return 0;
-    }
-    return mJAudioTrack->getSampleRate();
-}
-
-int64_t MediaPlayer2AudioOutput::getBufferDurationInUs() const {
-    Mutex::Autolock lock(mLock);
-    if (mJAudioTrack == 0) {
-        return 0;
-    }
-    int64_t duration;
-    if (mJAudioTrack->getBufferDurationInUs(&duration) != OK) {
-        return 0;
-    }
-    return duration;
-}
-
-} // namespace android
diff --git a/media/libmediaplayer2/include/mediaplayer2/JAudioTrack.h b/media/libmediaplayer2/include/mediaplayer2/JAudioTrack.h
deleted file mode 100644
index 2ed4632..0000000
--- a/media/libmediaplayer2/include/mediaplayer2/JAudioTrack.h
+++ /dev/null
@@ -1,461 +0,0 @@
-/*
- * Copyright 2018 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 ANDROID_JAUDIOTRACK_H
-#define ANDROID_JAUDIOTRACK_H
-
-#include <utility>
-#include <jni.h>
-#include <media/AudioResamplerPublic.h>
-#include <media/AudioSystem.h>
-#include <media/VolumeShaper.h>
-#include <system/audio.h>
-#include <utils/Errors.h>
-#include <utils/Vector.h>
-#include <mediaplayer2/JObjectHolder.h>
-#include <media/AudioTimestamp.h>   // It has dependency on audio.h/Errors.h, but doesn't
-                                    // include them in it. Therefore it is included here at last.
-
-namespace android {
-
-class JAudioTrack : public RefBase {
-public:
-
-    /* Events used by AudioTrack callback function (callback_t).
-     * Keep in sync with frameworks/base/media/java/android/media/AudioTrack.java NATIVE_EVENT_*.
-     */
-    enum event_type {
-        EVENT_MORE_DATA = 0,        // Request to write more data to buffer.
-        EVENT_UNDERRUN = 1,         // Buffer underrun occurred. This will not occur for
-                                    // static tracks.
-        EVENT_NEW_IAUDIOTRACK = 6,  // IAudioTrack was re-created, either due to re-routing and
-                                    // voluntary invalidation by mediaserver, or mediaserver crash.
-        EVENT_STREAM_END = 7,       // Sent after all the buffers queued in AF and HW are played
-                                    // back (after stop is called) for an offloaded track.
-    };
-
-    class Buffer
-    {
-    public:
-        size_t      mSize;        // input/output in bytes.
-        void*       mData;        // pointer to the audio data.
-    };
-
-    /* As a convenience, if a callback is supplied, a handler thread
-     * is automatically created with the appropriate priority. This thread
-     * invokes the callback when a new buffer becomes available or various conditions occur.
-     *
-     * Parameters:
-     *
-     * event:   type of event notified (see enum AudioTrack::event_type).
-     * user:    Pointer to context for use by the callback receiver.
-     * info:    Pointer to optional parameter according to event type:
-     *          - EVENT_MORE_DATA: pointer to JAudioTrack::Buffer struct. The callback must not
-     *            write more bytes than indicated by 'size' field and update 'size' if fewer bytes
-     *            are written.
-     *          - EVENT_NEW_IAUDIOTRACK: unused.
-     *          - EVENT_STREAM_END: unused.
-     */
-
-    typedef void (*callback_t)(int event, void* user, void *info);
-
-    /* Creates an JAudioTrack object for non-offload mode.
-     * Once created, the track needs to be started before it can be used.
-     * Unspecified values are set to appropriate default values.
-     *
-     * Parameters:
-     *
-     * streamType:         Select the type of audio stream this track is attached to
-     *                     (e.g. AUDIO_STREAM_MUSIC).
-     * sampleRate:         Data source sampling rate in Hz.  Zero means to use the sink sample rate.
-     *                     A non-zero value must be specified if AUDIO_OUTPUT_FLAG_DIRECT is set.
-     *                     0 will not work with current policy implementation for direct output
-     *                     selection where an exact match is needed for sampling rate.
-     *                     (TODO: Check direct output after flags can be used in Java AudioTrack.)
-     * format:             Audio format. For mixed tracks, any PCM format supported by server is OK.
-     *                     For direct and offloaded tracks, the possible format(s) depends on the
-     *                     output sink.
-     *                     (TODO: How can we check whether a format is supported?)
-     * channelMask:        Channel mask, such that audio_is_output_channel(channelMask) is true.
-     * cbf:                Callback function. If not null, this function is called periodically
-     *                     to provide new data and inform of marker, position updates, etc.
-     * user:               Context for use by the callback receiver.
-     * frameCount:         Minimum size of track PCM buffer in frames. This defines the
-     *                     application's contribution to the latency of the track.
-     *                     The actual size selected by the JAudioTrack could be larger if the
-     *                     requested size is not compatible with current audio HAL configuration.
-     *                     Zero means to use a default value.
-     * sessionId:          Specific session ID, or zero to use default.
-     * pAttributes:        If not NULL, supersedes streamType for use case selection.
-     * maxRequiredSpeed:   For PCM tracks, this creates an appropriate buffer size that will allow
-     *                     maxRequiredSpeed playback. Values less than 1.0f and greater than
-     *                     AUDIO_TIMESTRETCH_SPEED_MAX will be clamped.  For non-PCM tracks
-     *                     and direct or offloaded tracks, this parameter is ignored.
-     *                     (TODO: Handle this after offload / direct track is supported.)
-     *
-     * TODO: Revive removed arguments after offload mode is supported.
-     */
-    JAudioTrack(uint32_t sampleRate,
-                audio_format_t format,
-                audio_channel_mask_t channelMask,
-                callback_t cbf,
-                void* user,
-                size_t frameCount = 0,
-                int32_t sessionId  = AUDIO_SESSION_ALLOCATE,
-                const jobject pAttributes = NULL,
-                float maxRequiredSpeed = 1.0f);
-
-    /*
-       // Q. May be used in AudioTrack.setPreferredDevice(AudioDeviceInfo)?
-       audio_port_handle_t selectedDeviceId,
-
-       // TODO: No place to use these values.
-       int32_t notificationFrames,
-       const audio_offload_info_t *offloadInfo,
-    */
-
-    virtual ~JAudioTrack();
-
-    size_t frameCount();
-    size_t channelCount();
-
-    /* Returns this track's estimated latency in milliseconds.
-     * This includes the latency due to AudioTrack buffer size, AudioMixer (if any)
-     * and audio hardware driver.
-     */
-    uint32_t latency();
-
-    /* Return the total number of frames played since playback start.
-     * The counter will wrap (overflow) periodically, e.g. every ~27 hours at 44.1 kHz.
-     * It is reset to zero by flush(), reload(), and stop().
-     *
-     * Parameters:
-     *
-     * position: Address where to return play head position.
-     *
-     * Returned status (from utils/Errors.h) can be:
-     *  - NO_ERROR: successful operation
-     *  - BAD_VALUE: position is NULL
-     */
-    status_t getPosition(uint32_t *position);
-
-    // TODO: Does this comment apply same to Java AudioTrack::getTimestamp?
-    // Changed the return type from status_t to bool, since Java AudioTrack::getTimestamp returns
-    // boolean. Will Java getTimestampWithStatus() be public?
-    /* Poll for a timestamp on demand.
-     * Use if EVENT_NEW_TIMESTAMP is not delivered often enough for your needs,
-     * or if you need to get the most recent timestamp outside of the event callback handler.
-     * Caution: calling this method too often may be inefficient;
-     * if you need a high resolution mapping between frame position and presentation time,
-     * consider implementing that at application level, based on the low resolution timestamps.
-     * Returns NO_ERROR if timestamp is valid.
-     *         NO_INIT if finds error, and timestamp parameter will be undefined on return.
-     */
-    status_t getTimestamp(AudioTimestamp& timestamp);
-
-    // TODO: This doc is just copied from AudioTrack.h. Revise it after implemenation.
-    /* Return the extended timestamp, with additional timebase info and improved drain behavior.
-     *
-     * This is similar to the AudioTrack.java API:
-     * getTimestamp(@NonNull AudioTimestamp timestamp, @AudioTimestamp.Timebase int timebase)
-     *
-     * Some differences between this method and the getTimestamp(AudioTimestamp& timestamp) method
-     *
-     *   1. stop() by itself does not reset the frame position.
-     *      A following start() resets the frame position to 0.
-     *   2. flush() by itself does not reset the frame position.
-     *      The frame position advances by the number of frames flushed,
-     *      when the first frame after flush reaches the audio sink.
-     *   3. BOOTTIME clock offsets are provided to help synchronize with
-     *      non-audio streams, e.g. sensor data.
-     *   4. Position is returned with 64 bits of resolution.
-     *
-     * Parameters:
-     *  timestamp: A pointer to the caller allocated ExtendedTimestamp.
-     *
-     * Returns NO_ERROR    on success; timestamp is filled with valid data.
-     *         BAD_VALUE   if timestamp is NULL.
-     *         WOULD_BLOCK if called immediately after start() when the number
-     *                     of frames consumed is less than the
-     *                     overall hardware latency to physical output. In WOULD_BLOCK cases,
-     *                     one might poll again, or use getPosition(), or use 0 position and
-     *                     current time for the timestamp.
-     *                     If WOULD_BLOCK is returned, the timestamp is still
-     *                     modified with the LOCATION_CLIENT portion filled.
-     *         DEAD_OBJECT if AudioFlinger dies or the output device changes and
-     *                     the track cannot be automatically restored.
-     *                     The application needs to recreate the AudioTrack
-     *                     because the audio device changed or AudioFlinger died.
-     *                     This typically occurs for direct or offloaded tracks
-     *                     or if mDoNotReconnect is true.
-     *         INVALID_OPERATION  if called on a offloaded or direct track.
-     *                     Use getTimestamp(AudioTimestamp& timestamp) instead.
-     */
-    status_t getTimestamp(ExtendedTimestamp *timestamp);
-
-    /* Set source playback rate for timestretch
-     * 1.0 is normal speed: < 1.0 is slower, > 1.0 is faster
-     * 1.0 is normal pitch: < 1.0 is lower pitch, > 1.0 is higher pitch
-     *
-     * AUDIO_TIMESTRETCH_SPEED_MIN <= speed <= AUDIO_TIMESTRETCH_SPEED_MAX
-     * AUDIO_TIMESTRETCH_PITCH_MIN <= pitch <= AUDIO_TIMESTRETCH_PITCH_MAX
-     *
-     * Speed increases the playback rate of media, but does not alter pitch.
-     * Pitch increases the "tonal frequency" of media, but does not affect the playback rate.
-     */
-    status_t setPlaybackRate(const AudioPlaybackRate &playbackRate);
-
-    /* Return current playback rate */
-    const AudioPlaybackRate getPlaybackRate();
-
-    /* Sets the volume shaper object */
-    media::VolumeShaper::Status applyVolumeShaper(
-            const sp<media::VolumeShaper::Configuration>& configuration,
-            const sp<media::VolumeShaper::Operation>& operation);
-
-    /* Set the send level for this track. An auxiliary effect should be attached
-     * to the track with attachEffect(). Level must be >= 0.0 and <= 1.0.
-     */
-    status_t setAuxEffectSendLevel(float level);
-
-    /* Attach track auxiliary output to specified effect. Use effectId = 0
-     * to detach track from effect.
-     *
-     * Parameters:
-     *
-     * effectId: effectId obtained from AudioEffect::id().
-     *
-     * Returned status (from utils/Errors.h) can be:
-     *  - NO_ERROR: successful operation
-     *  - INVALID_OPERATION: The effect is not an auxiliary effect.
-     *  - BAD_VALUE: The specified effect ID is invalid.
-     */
-    status_t attachAuxEffect(int effectId);
-
-    /* Set volume for this track, mostly used for games' sound effects
-     * left and right volumes. Levels must be >= 0.0 and <= 1.0.
-     * This is the older API.  New applications should use setVolume(float) when possible.
-     */
-    status_t setVolume(float left, float right);
-
-    /* Set volume for all channels. This is the preferred API for new applications,
-     * especially for multi-channel content.
-     */
-    status_t setVolume(float volume);
-
-    // TODO: Does this comment equally apply to the Java AudioTrack::play()?
-    /* After it's created the track is not active. Call start() to
-     * make it active. If set, the callback will start being called.
-     * If the track was previously paused, volume is ramped up over the first mix buffer.
-     */
-    status_t start();
-
-    // TODO: Does this comment still applies? It seems not. (obtainBuffer, AudioFlinger, ...)
-    /* As a convenience we provide a write() interface to the audio buffer.
-     * Input parameter 'size' is in byte units.
-     * This is implemented on top of obtainBuffer/releaseBuffer. For best
-     * performance use callbacks. Returns actual number of bytes written >= 0,
-     * or one of the following negative status codes:
-     *      INVALID_OPERATION   AudioTrack is configured for static buffer or streaming mode
-     *      BAD_VALUE           size is invalid
-     *      WOULD_BLOCK         when obtainBuffer() returns same, or
-     *                          AudioTrack was stopped during the write
-     *      DEAD_OBJECT         when AudioFlinger dies or the output device changes and
-     *                          the track cannot be automatically restored.
-     *                          The application needs to recreate the AudioTrack
-     *                          because the audio device changed or AudioFlinger died.
-     *                          This typically occurs for direct or offload tracks
-     *                          or if mDoNotReconnect is true.
-     *      or any other error code returned by IAudioTrack::start() or restoreTrack_l().
-     * Default behavior is to only return when all data has been transferred. Set 'blocking' to
-     * false for the method to return immediately without waiting to try multiple times to write
-     * the full content of the buffer.
-     */
-    ssize_t write(const void* buffer, size_t size, bool blocking = true);
-
-    // TODO: Does this comment equally apply to the Java AudioTrack::stop()?
-    /* Stop a track.
-     * In static buffer mode, the track is stopped immediately.
-     * In streaming mode, the callback will cease being called.  Note that obtainBuffer() still
-     * works and will fill up buffers until the pool is exhausted, and then will return WOULD_BLOCK.
-     * In streaming mode the stop does not occur immediately: any data remaining in the buffer
-     * is first drained, mixed, and output, and only then is the track marked as stopped.
-     */
-    void stop();
-    bool stopped() const;
-
-    // TODO: Does this comment equally apply to the Java AudioTrack::flush()?
-    /* Flush a stopped or paused track. All previously buffered data is discarded immediately.
-     * This has the effect of draining the buffers without mixing or output.
-     * Flush is intended for streaming mode, for example before switching to non-contiguous content.
-     * This function is a no-op if the track is not stopped or paused, or uses a static buffer.
-     */
-    void flush();
-
-    // TODO: Does this comment equally apply to the Java AudioTrack::pause()?
-    // At least we are not using obtainBuffer.
-    /* Pause a track. After pause, the callback will cease being called and
-     * obtainBuffer returns WOULD_BLOCK. Note that obtainBuffer() still works
-     * and will fill up buffers until the pool is exhausted.
-     * Volume is ramped down over the next mix buffer following the pause request,
-     * and then the track is marked as paused. It can be resumed with ramp up by start().
-     */
-    void pause();
-
-    bool isPlaying() const;
-
-    /* Return current source sample rate in Hz.
-     * If specified as zero in constructor, this will be the sink sample rate.
-     */
-    uint32_t getSampleRate();
-
-    /* Returns the buffer duration in microseconds at current playback rate. */
-    status_t getBufferDurationInUs(int64_t *duration);
-
-    audio_format_t format();
-
-    size_t frameSize();
-
-    /*
-     * Dumps the state of an audio track.
-     * Not a general-purpose API; intended only for use by media player service to dump its tracks.
-     */
-    status_t dump(int fd, const Vector<String16>& args) const;
-
-    /* Returns the AudioDeviceInfo used by the output to which this AudioTrack is
-     * attached.
-     */
-    jobject getRoutedDevice();
-
-    /* Returns the ID of the audio session this AudioTrack belongs to. */
-    int32_t getAudioSessionId();
-
-    /* Sets the preferred audio device to use for output of this AudioTrack.
-     *
-     * Parameters:
-     * Device: an AudioDeviceInfo object.
-     *
-     * Returned value:
-     *  - NO_ERROR: successful operation
-     *  - BAD_VALUE: failed to set the device
-     */
-    status_t setPreferredDevice(jobject device);
-
-    // TODO: Add AUDIO_OUTPUT_FLAG_DIRECT when it is possible to check.
-    // TODO: Add AUDIO_FLAG_HW_AV_SYNC when it is possible to check.
-    /* Returns the flags */
-    audio_output_flags_t getFlags() const { return mFlags; }
-
-    /* We don't keep stream type here,
-     * instead, we keep attributes and call getVolumeControlStream() to get stream type
-     */
-    audio_stream_type_t getAudioStreamType();
-
-    /* Obtain the pending duration in milliseconds for playback of pure PCM data remaining in
-     * AudioTrack.
-     *
-     * Returns NO_ERROR if successful.
-     *         INVALID_OPERATION if the AudioTrack does not contain pure PCM data.
-     *         BAD_VALUE if msec is nullptr.
-     */
-    status_t pendingDuration(int32_t *msec);
-
-    /* Adds an AudioDeviceCallback. The caller will be notified when the audio device to which this
-     * AudioTrack is routed is updated.
-     * Replaces any previously installed callback.
-     *
-     * Parameters:
-     * Listener: the listener to receive notification of rerouting events.
-     * Handler: the handler to handler the rerouting events.
-     *
-     * Returns NO_ERROR if successful.
-     *         (TODO) INVALID_OPERATION if the same callback is already installed.
-     *         (TODO) NO_INIT or PREMISSION_DENIED if AudioFlinger service is not reachable
-     *         (TODO) BAD_VALUE if the callback is NULL
-     */
-    status_t addAudioDeviceCallback(jobject listener, jobject rd);
-
-    /* Removes an AudioDeviceCallback.
-     *
-     * Parameters:
-     * Listener: the listener to receive notification of rerouting events.
-     *
-     * Returns NO_ERROR if successful.
-     *         (TODO) INVALID_OPERATION if the callback is not installed
-     *         (TODO) BAD_VALUE if the callback is NULL
-     */
-    status_t removeAudioDeviceCallback(jobject listener);
-
-    /* Register all backed-up routing delegates.
-     *
-     * Parameters:
-     * routingDelegates: backed-up routing delegates
-     *
-     */
-    void registerRoutingDelegates(
-            Vector<std::pair<sp<JObjectHolder>, sp<JObjectHolder>>>& routingDelegates);
-
-    /* get listener from RoutingDelegate object
-     */
-    static jobject getListener(const jobject routingDelegateObj);
-
-    /* get handler from RoutingDelegate object
-     */
-    static jobject getHandler(const jobject routingDelegateObj);
-
-    /*
-     * Parameters:
-     * map and key
-     *
-     * Returns value if key is in the map
-     *         nullptr if key is not in the map
-     */
-    static jobject findByKey(
-            Vector<std::pair<sp<JObjectHolder>, sp<JObjectHolder>>>& mp, const jobject key);
-
-    /*
-     * Parameters:
-     * map and key
-     */
-    static void eraseByKey(
-            Vector<std::pair<sp<JObjectHolder>, sp<JObjectHolder>>>& mp, const jobject key);
-
-private:
-    audio_output_flags_t mFlags;
-
-    jclass mAudioTrackCls;
-    jobject mAudioTrackObj;
-
-    /* Creates a Java VolumeShaper.Configuration object from VolumeShaper::Configuration */
-    jobject createVolumeShaperConfigurationObj(
-            const sp<media::VolumeShaper::Configuration>& config);
-
-    /* Creates a Java VolumeShaper.Operation object from VolumeShaper::Operation */
-    jobject createVolumeShaperOperationObj(
-            const sp<media::VolumeShaper::Operation>& operation);
-
-    /* Creates a Java StreamEventCallback object */
-    jobject createStreamEventCallback(callback_t cbf, void* user);
-
-    /* Creates a Java Executor object for running a callback */
-    jobject createCallbackExecutor();
-
-    status_t javaToNativeStatus(int javaStatus);
-};
-
-}; // namespace android
-
-#endif // ANDROID_JAUDIOTRACK_H
diff --git a/media/libmediaplayer2/include/mediaplayer2/JMedia2HTTPConnection.h b/media/libmediaplayer2/include/mediaplayer2/JMedia2HTTPConnection.h
deleted file mode 100644
index 15f7f83..0000000
--- a/media/libmediaplayer2/include/mediaplayer2/JMedia2HTTPConnection.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright 2017, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef _J_MEDIA2_HTTP_CONNECTION_H_
-#define _J_MEDIA2_HTTP_CONNECTION_H_
-
-#include "jni.h"
-
-#include <media/MediaHTTPConnection.h>
-#include <media/stagefright/foundation/ABase.h>
-
-namespace android {
-
-struct JMedia2HTTPConnection : public MediaHTTPConnection {
-    JMedia2HTTPConnection(JNIEnv *env, jobject thiz);
-
-    virtual bool connect(
-            const char *uri, const KeyedVector<String8, String8> *headers) override;
-
-    virtual void disconnect() override;
-    virtual ssize_t readAt(off64_t offset, void *data, size_t size) override;
-    virtual off64_t getSize() override;
-    virtual status_t getMIMEType(String8 *mimeType) override;
-    virtual status_t getUri(String8 *uri) override;
-
-protected:
-    virtual ~JMedia2HTTPConnection();
-
-private:
-    jobject mMedia2HTTPConnectionObj;
-    jmethodID mConnectMethod;
-    jmethodID mDisconnectMethod;
-    jmethodID mReadAtMethod;
-    jmethodID mGetSizeMethod;
-    jmethodID mGetMIMETypeMethod;
-    jmethodID mGetUriMethod;
-
-    jbyteArray mByteArrayObj;
-
-    DISALLOW_EVIL_CONSTRUCTORS(JMedia2HTTPConnection);
-};
-
-}  // namespace android
-
-#endif  // _J_MEDIA2_HTTP_CONNECTION_H_
diff --git a/media/libmediaplayer2/include/mediaplayer2/JMedia2HTTPService.h b/media/libmediaplayer2/include/mediaplayer2/JMedia2HTTPService.h
deleted file mode 100644
index bf61a7f..0000000
--- a/media/libmediaplayer2/include/mediaplayer2/JMedia2HTTPService.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright 2017, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef _J_MEDIA2_HTTP_SERVICE_H_
-#define _J_MEDIA2_HTTP_SERVICE_H_
-
-#include <jni.h>
-#include <utils/RefBase.h>
-
-#include <media/MediaHTTPService.h>
-#include <media/MediaHTTPConnection.h>
-#include <media/stagefright/foundation/ABase.h>
-
-namespace android {
-
-struct JMedia2HTTPService : public MediaHTTPService {
-    JMedia2HTTPService(JNIEnv *env, jobject thiz);
-
-    virtual sp<MediaHTTPConnection> makeHTTPConnection() override;
-
-protected:
-    virtual ~JMedia2HTTPService();
-
-private:
-    jobject mMedia2HTTPServiceObj;
-
-    jmethodID mMakeHTTPConnectionMethod;
-
-    DISALLOW_EVIL_CONSTRUCTORS(JMedia2HTTPService);
-};
-
-}  // namespace android
-
-#endif  // _J_MEDIA2_HTTP_SERVICE_H_
diff --git a/media/libmediaplayer2/include/mediaplayer2/JObjectHolder.h b/media/libmediaplayer2/include/mediaplayer2/JObjectHolder.h
deleted file mode 100644
index 93d8b40..0000000
--- a/media/libmediaplayer2/include/mediaplayer2/JObjectHolder.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright 2018, 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 JOBJECT_HOLDER_H_
-
-#define JOBJECT_HOLDER_H_
-
-#include "jni.h"
-#include <mediaplayer2/JavaVMHelper.h>
-#include <utils/RefBase.h>
-
-namespace android {
-
-// Helper class for managing global reference of jobject.
-struct JObjectHolder : public RefBase {
-    JObjectHolder(jobject obj) {
-        JNIEnv *env = JavaVMHelper::getJNIEnv();
-        mJObject = reinterpret_cast<jobject>(env->NewGlobalRef(obj));
-    }
-
-    virtual ~JObjectHolder() {
-        JNIEnv *env = JavaVMHelper::getJNIEnv();
-        env->DeleteGlobalRef(mJObject);
-    }
-
-    jobject getJObject() { return mJObject; }
-
-private:
-    jobject mJObject;
-};
-
-}  //" android
-
-#endif  // JOBJECT_HOLDER_H_
diff --git a/media/libmediaplayer2/include/mediaplayer2/JavaVMHelper.h b/media/libmediaplayer2/include/mediaplayer2/JavaVMHelper.h
deleted file mode 100644
index 4b56aca..0000000
--- a/media/libmediaplayer2/include/mediaplayer2/JavaVMHelper.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright 2018 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 JAVA_VM_HELPER_H_
-
-#define JAVA_VM_HELPER_H_
-
-#include "jni.h"
-
-#include <atomic>
-
-namespace android {
-
-struct JavaVMHelper {
-    static JNIEnv *getJNIEnv();
-    static JavaVM *getJavaVM();
-    static void setJavaVM(JavaVM *vm);
-
-private:
-    // Once a valid JavaVM has been set, it should never be reset or changed.
-    // However, as it may be accessed from multiple threads, access needs to be
-    // synchronized.
-    static std::atomic<JavaVM *> sJavaVM;
-};
-
-}  // namespace android
-
-#endif  // JAVA_VM_HELPER_H_
diff --git a/media/libmediaplayer2/include/mediaplayer2/MediaPlayer2AudioOutput.h b/media/libmediaplayer2/include/mediaplayer2/MediaPlayer2AudioOutput.h
deleted file mode 100644
index f38b7cc..0000000
--- a/media/libmediaplayer2/include/mediaplayer2/MediaPlayer2AudioOutput.h
+++ /dev/null
@@ -1,188 +0,0 @@
-/*
-**
-** Copyright 2018, 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 ANDROID_MEDIAPLAYER2AUDIOOUTPUT_H
-#define ANDROID_MEDIAPLAYER2AUDIOOUTPUT_H
-
-#include <mediaplayer2/MediaPlayer2Interface.h>
-#include <mediaplayer2/JAudioTrack.h>
-#include <mediaplayer2/JObjectHolder.h>
-
-#include <utility>
-#include <utils/String16.h>
-#include <utils/Vector.h>
-
-#include "jni.h"
-
-namespace android {
-
-class AudioTrack;
-
-class MediaPlayer2AudioOutput : public MediaPlayer2Interface::AudioSink
-{
-    class CallbackData;
-
-public:
-    MediaPlayer2AudioOutput(int32_t sessionId,
-                            uid_t uid,
-                            int pid,
-                            const jobject attributes);
-    virtual ~MediaPlayer2AudioOutput();
-
-    virtual bool ready() const {
-        return mJAudioTrack != nullptr;
-    }
-    virtual ssize_t bufferSize() const;
-    virtual ssize_t frameCount() const;
-    virtual ssize_t channelCount() const;
-    virtual ssize_t frameSize() const;
-    virtual uint32_t latency() const;
-    virtual float msecsPerFrame() const;
-    virtual status_t getPosition(uint32_t *position) const;
-    virtual status_t getTimestamp(AudioTimestamp &ts) const;
-    virtual int64_t getPlayedOutDurationUs(int64_t nowUs) const;
-    virtual status_t getFramesWritten(uint32_t *frameswritten) const;
-    virtual int32_t getSessionId() const;
-    virtual void setSessionId(const int32_t id);
-    virtual uint32_t getSampleRate() const;
-    virtual int64_t getBufferDurationInUs() const;
-
-    virtual status_t open(
-            uint32_t sampleRate, int channelCount, audio_channel_mask_t channelMask,
-            audio_format_t format,
-            AudioCallback cb, void *cookie,
-            audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE,
-            const audio_offload_info_t *offloadInfo = NULL,
-            uint32_t suggestedFrameCount = 0);
-
-    virtual status_t start();
-    virtual ssize_t write(const void* buffer, size_t size, bool blocking = true);
-    virtual void stop();
-    virtual void flush();
-    virtual void pause();
-    virtual void close();
-    void setAudioAttributes(const jobject attributes);
-    virtual audio_stream_type_t getAudioStreamType() const;
-
-    void setVolume(float volume);
-    virtual status_t setPlaybackRate(const AudioPlaybackRate& rate);
-    virtual status_t getPlaybackRate(AudioPlaybackRate* rate /* nonnull */);
-
-    status_t setAuxEffectSendLevel(float level);
-    status_t attachAuxEffect(int effectId);
-    virtual status_t dump(int fd, const Vector<String16>& args) const;
-
-    static bool isOnEmulator();
-    static int getMinBufferCount();
-    virtual bool needsTrailingPadding() {
-        return true;
-        // TODO: return correct value.
-        //return mNextOutput == NULL;
-    }
-    // AudioRouting
-    virtual status_t setPreferredDevice(jobject device);
-    virtual jobject getRoutedDevice();
-    virtual status_t addAudioDeviceCallback(jobject routingDelegate);
-    virtual status_t removeAudioDeviceCallback(jobject listener);
-
-private:
-    static void setMinBufferCount();
-    static void CallbackWrapper(int event, void *me, void *info);
-    void deleteRecycledTrack_l();
-    void close_l();
-    status_t updateTrack_l();
-
-    sp<JAudioTrack>         mJAudioTrack;
-    AudioCallback           mCallback;
-    void *                  mCallbackCookie;
-    CallbackData *          mCallbackData;
-    sp<JObjectHolder>       mAttributes;
-    float                   mVolume;
-    AudioPlaybackRate       mPlaybackRate;
-    uint32_t                mSampleRateHz; // sample rate of the content, as set in open()
-    float                   mMsecsPerFrame;
-    size_t                  mFrameSize;
-    int32_t                 mSessionId;
-    uid_t                   mUid;
-    int                     mPid;
-    float                   mSendLevel;
-    int                     mAuxEffectId;
-    audio_output_flags_t    mFlags;
-    sp<JObjectHolder>       mPreferredDevice;
-    mutable Mutex           mLock;
-
-    // <listener, routingDelegate>
-    Vector<std::pair<sp<JObjectHolder>, sp<JObjectHolder>>> mRoutingDelegates;
-
-    // static variables below not protected by mutex
-    static bool             mIsOnEmulator;
-    static int              mMinBufferCount;  // 12 for emulator; otherwise 4
-
-    // CallbackData is what is passed to the AudioTrack as the "user" data.
-    // We need to be able to target this to a different Output on the fly,
-    // so we can't use the Output itself for this.
-    class CallbackData {
-        friend MediaPlayer2AudioOutput;
-    public:
-        explicit CallbackData(MediaPlayer2AudioOutput *cookie) {
-            mData = cookie;
-            mSwitching = false;
-        }
-        MediaPlayer2AudioOutput *getOutput() const {
-            return mData;
-        }
-        void setOutput(MediaPlayer2AudioOutput* newcookie) {
-            mData = newcookie;
-        }
-        // lock/unlock are used by the callback before accessing the payload of this object
-        void lock() const {
-            mLock.lock();
-        }
-        void unlock() const {
-            mLock.unlock();
-        }
-
-        // tryBeginTrackSwitch/endTrackSwitch are used when the CallbackData is handed over
-        // to the next sink.
-
-        // tryBeginTrackSwitch() returns true only if it obtains the lock.
-        bool tryBeginTrackSwitch() {
-            LOG_ALWAYS_FATAL_IF(mSwitching, "tryBeginTrackSwitch() already called");
-            if (mLock.tryLock() != OK) {
-                return false;
-            }
-            mSwitching = true;
-            return true;
-        }
-        void endTrackSwitch() {
-            if (mSwitching) {
-                mLock.unlock();
-            }
-            mSwitching = false;
-        }
-
-    private:
-        MediaPlayer2AudioOutput *mData;
-        mutable Mutex mLock; // a recursive mutex might make this unnecessary.
-        bool mSwitching;
-        DISALLOW_EVIL_CONSTRUCTORS(CallbackData);
-    };
-};
-
-}; // namespace android
-
-#endif // ANDROID_MEDIAPLAYER2AUDIOOUTPUT_H
diff --git a/media/libmediaplayer2/include/mediaplayer2/MediaPlayer2Interface.h b/media/libmediaplayer2/include/mediaplayer2/MediaPlayer2Interface.h
deleted file mode 100644
index 7804a62..0000000
--- a/media/libmediaplayer2/include/mediaplayer2/MediaPlayer2Interface.h
+++ /dev/null
@@ -1,273 +0,0 @@
-/*
- * Copyright 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_MEDIAPLAYER2INTERFACE_H
-#define ANDROID_MEDIAPLAYER2INTERFACE_H
-
-#ifdef __cplusplus
-
-#include <sys/types.h>
-#include <utils/Errors.h>
-#include <utils/String8.h>
-#include <utils/RefBase.h>
-#include <jni.h>
-
-#include <media/AVSyncSettings.h>
-#include <media/AudioResamplerPublic.h>
-#include <media/AudioSystem.h>
-#include <media/AudioTimestamp.h>
-#include <media/BufferingSettings.h>
-#include <media/stagefright/foundation/AHandler.h>
-#include <mediaplayer2/MediaPlayer2Types.h>
-
-#include "jni.h"
-#include "mediaplayer2.pb.h"
-
-using android::media::MediaPlayer2Proto::PlayerMessage;
-
-// Fwd decl to make sure everyone agrees that the scope of struct sockaddr_in is
-// global, and not in android::
-struct sockaddr_in;
-
-namespace android {
-
-struct DataSourceDesc;
-class Parcel;
-struct ANativeWindowWrapper;
-
-#define DEFAULT_AUDIOSINK_BUFFERSIZE 1200
-#define DEFAULT_AUDIOSINK_SAMPLERATE 44100
-
-// when the channel mask isn't known, use the channel count to derive a mask in AudioSink::open()
-#define CHANNEL_MASK_USE_CHANNEL_ORDER 0
-
-// duration below which we do not allow deep audio buffering
-#define AUDIO_SINK_MIN_DEEP_BUFFER_DURATION_US 5000000
-
-class MediaPlayer2InterfaceListener: public RefBase
-{
-public:
-    virtual void notify(int64_t srcId, int msg, int ext1, int ext2,
-           const PlayerMessage *obj) = 0;
-};
-
-class MediaPlayer2Interface : public AHandler {
-public:
-    // AudioSink: abstraction layer for audio output
-    class AudioSink : public RefBase {
-    public:
-        enum cb_event_t {
-            CB_EVENT_FILL_BUFFER,   // Request to write more data to buffer.
-            CB_EVENT_STREAM_END,    // Sent after all the buffers queued in AF and HW are played
-                                    // back (after stop is called)
-            CB_EVENT_TEAR_DOWN      // The AudioTrack was invalidated due to use case change:
-                                    // Need to re-evaluate offloading options
-        };
-
-        // Callback returns the number of bytes actually written to the buffer.
-        typedef size_t (*AudioCallback)(
-                AudioSink *audioSink, void *buffer, size_t size, void *cookie, cb_event_t event);
-
-        virtual ~AudioSink() {}
-        virtual bool ready() const = 0; // audio output is open and ready
-        virtual ssize_t bufferSize() const = 0;
-        virtual ssize_t frameCount() const = 0;
-        virtual ssize_t channelCount() const = 0;
-        virtual ssize_t frameSize() const = 0;
-        virtual uint32_t latency() const = 0;
-        virtual float msecsPerFrame() const = 0;
-        virtual status_t getPosition(uint32_t *position) const = 0;
-        virtual status_t getTimestamp(AudioTimestamp &ts) const = 0;
-        virtual int64_t getPlayedOutDurationUs(int64_t nowUs) const = 0;
-        virtual status_t getFramesWritten(uint32_t *frameswritten) const = 0;
-        virtual int32_t getSessionId() const = 0;
-        virtual audio_stream_type_t getAudioStreamType() const = 0;
-        virtual uint32_t getSampleRate() const = 0;
-        virtual int64_t getBufferDurationInUs() const = 0;
-
-        // If no callback is specified, use the "write" API below to submit
-        // audio data.
-        virtual status_t open(
-                uint32_t sampleRate, int channelCount, audio_channel_mask_t channelMask,
-                audio_format_t format=AUDIO_FORMAT_PCM_16_BIT,
-                AudioCallback cb = NULL,
-                void *cookie = NULL,
-                audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE,
-                const audio_offload_info_t *offloadInfo = NULL,
-                uint32_t suggestedFrameCount = 0) = 0;
-
-        virtual status_t start() = 0;
-
-        /* Input parameter |size| is in byte units stored in |buffer|.
-         * Data is copied over and actual number of bytes written (>= 0)
-         * is returned, or no data is copied and a negative status code
-         * is returned (even when |blocking| is true).
-         * When |blocking| is false, AudioSink will immediately return after
-         * part of or full |buffer| is copied over.
-         * When |blocking| is true, AudioSink will wait to copy the entire
-         * buffer, unless an error occurs or the copy operation is
-         * prematurely stopped.
-         */
-        virtual ssize_t write(const void* buffer, size_t size, bool blocking = true) = 0;
-
-        virtual void stop() = 0;
-        virtual void flush() = 0;
-        virtual void pause() = 0;
-        virtual void close() = 0;
-
-        virtual status_t setPlaybackRate(const AudioPlaybackRate& rate) = 0;
-        virtual status_t getPlaybackRate(AudioPlaybackRate* rate /* nonnull */) = 0;
-        virtual bool needsTrailingPadding() {
-            return true;
-        }
-
-        virtual status_t setParameters(const String8& /* keyValuePairs */) {
-            return NO_ERROR;
-        }
-        virtual String8 getParameters(const String8& /* keys */) {
-            return String8::empty();
-        }
-
-        // AudioRouting
-        virtual status_t    setPreferredDevice(jobject device);
-        virtual jobject     getRoutedDevice();
-        virtual status_t    addAudioDeviceCallback(jobject routingDelegate);
-        virtual status_t    removeAudioDeviceCallback(jobject listener);
-    };
-
-    MediaPlayer2Interface() : mListener(NULL) { }
-    virtual ~MediaPlayer2Interface() { }
-    virtual status_t initCheck() = 0;
-
-    virtual void setAudioSink(const sp<AudioSink>& audioSink) {
-        mAudioSink = audioSink;
-    }
-
-    virtual status_t setDataSource(const sp<DataSourceDesc> &dsd) = 0;
-
-    virtual status_t prepareNextDataSource(const sp<DataSourceDesc> &dsd) = 0;
-
-    virtual status_t playNextDataSource(int64_t srcId) = 0;
-
-    // pass the buffered native window to the media player service
-    virtual status_t setVideoSurfaceTexture(const sp<ANativeWindowWrapper>& nww) = 0;
-
-    virtual status_t getBufferingSettings(BufferingSettings* buffering /* nonnull */) {
-        *buffering = BufferingSettings();
-        return OK;
-    }
-    virtual status_t setBufferingSettings(const BufferingSettings& /* buffering */) {
-        return OK;
-    }
-
-    virtual status_t prepareAsync() = 0;
-    virtual status_t start() = 0;
-    virtual status_t pause() = 0;
-    virtual bool isPlaying() = 0;
-    virtual status_t setPlaybackSettings(const AudioPlaybackRate& rate) {
-        // by default, players only support setting rate to the default
-        if (!isAudioPlaybackRateEqual(rate, AUDIO_PLAYBACK_RATE_DEFAULT)) {
-            return BAD_VALUE;
-        }
-        return OK;
-    }
-    virtual status_t getPlaybackSettings(AudioPlaybackRate* rate /* nonnull */) {
-        *rate = AUDIO_PLAYBACK_RATE_DEFAULT;
-        return OK;
-    }
-    virtual status_t setSyncSettings(const AVSyncSettings& sync, float /* videoFps */) {
-        // By default, players only support setting sync source to default; all other sync
-        // settings are ignored. There is no requirement for getters to return set values.
-        if (sync.mSource != AVSYNC_SOURCE_DEFAULT) {
-            return BAD_VALUE;
-        }
-        return OK;
-    }
-    virtual status_t getSyncSettings(
-            AVSyncSettings* sync /* nonnull */, float* videoFps /* nonnull */) {
-        *sync = AVSyncSettings();
-        *videoFps = -1.f;
-        return OK;
-    }
-    virtual status_t seekTo(
-            int64_t msec, MediaPlayer2SeekMode mode = MediaPlayer2SeekMode::SEEK_PREVIOUS_SYNC) = 0;
-    virtual status_t getCurrentPosition(int64_t *msec) = 0;
-    virtual status_t getDuration(int64_t *msec) = 0;
-    virtual status_t reset() = 0;
-    virtual status_t notifyAt(int64_t /* mediaTimeUs */) {
-        return INVALID_OPERATION;
-    }
-    virtual status_t setLooping(int loop) = 0;
-    virtual status_t setParameter(int key, const Parcel &request) = 0;
-    virtual status_t getParameter(int key, Parcel *reply) = 0;
-
-    virtual status_t getMetrics(char **buffer, size_t *length) = 0;
-
-    // Invoke a generic method on the player by using opaque parcels
-    // for the request and reply.
-    //
-    // @param request Parcel that is positioned at the start of the
-    //                data sent by the java layer.
-    // @param[out] reply Parcel to hold the reply data. Cannot be null.
-    // @return OK if the call was successful.
-    virtual status_t invoke(const PlayerMessage &request, PlayerMessage *reply) = 0;
-
-    void setListener(const sp<MediaPlayer2InterfaceListener> &listener) {
-        Mutex::Autolock autoLock(mListenerLock);
-        mListener = listener;
-    }
-
-    void sendEvent(int64_t srcId, int msg, int ext1=0, int ext2=0, const PlayerMessage *obj=NULL) {
-        sp<MediaPlayer2InterfaceListener> listener;
-        {
-            Mutex::Autolock autoLock(mListenerLock);
-            listener = mListener;
-        }
-
-        if (listener) {
-            listener->notify(srcId, msg, ext1, ext2, obj);
-        }
-    }
-
-    virtual status_t dump(int /* fd */, const Vector<String16>& /* args */) const {
-        return INVALID_OPERATION;
-    }
-
-    virtual void onMessageReceived(const sp<AMessage> & /* msg */) override { }
-
-    // Modular DRM
-    virtual status_t prepareDrm(int64_t /*srcId*/, const uint8_t /* uuid */[16],
-                                const Vector<uint8_t>& /* drmSessionId */) {
-        return INVALID_OPERATION;
-    }
-    virtual status_t releaseDrm(int64_t /*srcId*/) {
-        return INVALID_OPERATION;
-    }
-
-protected:
-    sp<AudioSink> mAudioSink;
-
-private:
-    Mutex mListenerLock;
-    sp<MediaPlayer2InterfaceListener> mListener;
-};
-
-}; // namespace android
-
-#endif // __cplusplus
-
-
-#endif // ANDROID_MEDIAPLAYER2INTERFACE_H
diff --git a/media/libmediaplayer2/include/mediaplayer2/MediaPlayer2Types.h b/media/libmediaplayer2/include/mediaplayer2/MediaPlayer2Types.h
deleted file mode 100644
index 2430289..0000000
--- a/media/libmediaplayer2/include/mediaplayer2/MediaPlayer2Types.h
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- * Copyright 2018 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 ANDROID_MEDIAPLAYER2_TYPES_H
-#define ANDROID_MEDIAPLAYER2_TYPES_H
-
-#include <media/mediaplayer_common.h>
-
-#include <media/MediaSource.h>
-
-namespace android {
-
-typedef MediaSource::ReadOptions::SeekMode MediaPlayer2SeekMode;
-
-enum media2_event_type {
-    MEDIA2_NOP               = 0, // interface test message
-    MEDIA2_PREPARED          = 1,
-    MEDIA2_PLAYBACK_COMPLETE = 2,
-    MEDIA2_BUFFERING_UPDATE  = 3,
-    MEDIA2_SEEK_COMPLETE     = 4,
-    MEDIA2_SET_VIDEO_SIZE    = 5,
-    MEDIA2_STARTED           = 6,
-    MEDIA2_PAUSED            = 7,
-    MEDIA2_SKIPPED           = 8,
-    MEDIA2_NOTIFY_TIME       = 98,
-    MEDIA2_TIMED_TEXT        = 99,
-    MEDIA2_ERROR             = 100,
-    MEDIA2_INFO              = 200,
-    MEDIA2_SUBTITLE_DATA     = 201,
-    MEDIA2_META_DATA         = 202,
-    MEDIA2_DRM_INFO          = 210,
-};
-
-// Generic error codes for the media player framework.  Errors are fatal, the
-// playback must abort.
-//
-// Errors are communicated back to the client using the
-// MediaPlayer2Listener::notify method defined below.
-// In this situation, 'notify' is invoked with the following:
-//   'msg' is set to MEDIA_ERROR.
-//   'ext1' should be a value from the enum media2_error_type.
-//   'ext2' contains an implementation dependant error code to provide
-//          more details. Should default to 0 when not used.
-//
-// The codes are distributed as follow:
-//   0xx: Reserved
-//   1xx: Android Player errors. Something went wrong inside the MediaPlayer2.
-//   2xx: Media errors (e.g Codec not supported). There is a problem with the
-//        media itself.
-//   3xx: Runtime errors. Some extraordinary condition arose making the playback
-//        impossible.
-//
-enum media2_error_type {
-    // 0xx
-    MEDIA2_ERROR_UNKNOWN = 1,
-    // 1xx
-    // MEDIA2_ERROR_SERVER_DIED = 100,
-    // 2xx
-    MEDIA2_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK = 200,
-    // 3xx
-    MEDIA2_ERROR_FAILED_TO_SET_DATA_SOURCE = 300,
-};
-
-
-// Info and warning codes for the media player framework.  These are non fatal,
-// the playback is going on but there might be some user visible issues.
-//
-// Info and warning messages are communicated back to the client using the
-// MediaPlayer2Listener::notify method defined below.  In this situation,
-// 'notify' is invoked with the following:
-//   'msg' is set to MEDIA_INFO.
-//   'ext1' should be a value from the enum media2_info_type.
-//   'ext2' contains an implementation dependant info code to provide
-//          more details. Should default to 0 when not used.
-//
-// The codes are distributed as follow:
-//   0xx: Reserved
-//   7xx: Android Player info/warning (e.g player lagging behind.)
-//   8xx: Media info/warning (e.g media badly interleaved.)
-//
-enum media2_info_type {
-    // 0xx
-    MEDIA2_INFO_UNKNOWN = 1,
-    // The player just started the playback of this data source.
-    MEDIA2_INFO_DATA_SOURCE_START = 2,
-    // The player just pushed the very first video frame for rendering
-    MEDIA2_INFO_VIDEO_RENDERING_START = 3,
-    // The player just pushed the very first audio frame for rendering
-    MEDIA2_INFO_AUDIO_RENDERING_START = 4,
-    // The player just completed the playback of this data source
-    MEDIA2_INFO_DATA_SOURCE_END = 5,
-    // The player just completed the playback of all data sources.
-    // But this is not visible in native code. Just keep this entry for completeness.
-    MEDIA2_INFO_DATA_SOURCE_LIST_END = 6,
-    // The player just completed an iteration of playback loop. This event is sent only when
-    // looping is enabled.
-    MEDIA2_INFO_DATA_SOURCE_REPEAT = 7,
-
-    //1xx
-    // The player just prepared a data source.
-    MEDIA2_INFO_PREPARED = 100,
-    // The player just completed a call play().
-    MEDIA2_INFO_COMPLETE_CALL_PLAY = 101,
-    // The player just completed a call pause().
-    MEDIA2_INFO_COMPLETE_CALL_PAUSE = 102,
-    // The player just completed a call seekTo.
-    MEDIA2_INFO_COMPLETE_CALL_SEEK = 103,
-
-    // 7xx
-    // The video is too complex for the decoder: it can't decode frames fast
-    // enough. Possibly only the audio plays fine at this stage.
-    MEDIA2_INFO_VIDEO_TRACK_LAGGING = 700,
-    // MediaPlayer2 is temporarily pausing playback internally in order to
-    // buffer more data.
-    MEDIA2_INFO_BUFFERING_START = 701,
-    // MediaPlayer2 is resuming playback after filling buffers.
-    MEDIA2_INFO_BUFFERING_END = 702,
-    // Bandwidth in recent past
-    MEDIA2_INFO_NETWORK_BANDWIDTH = 703,
-
-    // 8xx
-    // Bad interleaving means that a media has been improperly interleaved or not
-    // interleaved at all, e.g has all the video samples first then all the audio
-    // ones. Video is playing but a lot of disk seek may be happening.
-    MEDIA2_INFO_BAD_INTERLEAVING = 800,
-    // The media is not seekable (e.g live stream).
-    MEDIA2_INFO_NOT_SEEKABLE = 801,
-    // New media metadata is available.
-    MEDIA2_INFO_METADATA_UPDATE = 802,
-    // Audio can not be played.
-    MEDIA2_INFO_PLAY_AUDIO_ERROR = 804,
-    // Video can not be played.
-    MEDIA2_INFO_PLAY_VIDEO_ERROR = 805,
-
-    //9xx
-    MEDIA2_INFO_TIMED_TEXT_ERROR = 900,
-};
-
-// Do not change these values without updating their counterparts in MediaPlayer2.java
-enum mediaplayer2_states {
-    MEDIAPLAYER2_STATE_IDLE         = 1001,
-    MEDIAPLAYER2_STATE_PREPARED     = 1002,
-    MEDIAPLAYER2_STATE_PAUSED       = 1003,
-    MEDIAPLAYER2_STATE_PLAYING      = 1004,
-    MEDIAPLAYER2_STATE_ERROR        = 1005,
-};
-
-enum media_player2_internal_states {
-    MEDIA_PLAYER2_STATE_ERROR        = 0,
-    MEDIA_PLAYER2_IDLE               = 1 << 0,
-    MEDIA_PLAYER2_INITIALIZED        = 1 << 1,
-    MEDIA_PLAYER2_PREPARING          = 1 << 2,
-    MEDIA_PLAYER2_PREPARED           = 1 << 3,
-    MEDIA_PLAYER2_STARTED            = 1 << 4,
-    MEDIA_PLAYER2_PAUSED             = 1 << 5,
-    MEDIA_PLAYER2_PLAYBACK_COMPLETE  = 1 << 6
-};
-
-// Keep KEY_PARAMETER_* in sync with MediaPlayer2.java.
-// The same enum space is used for both set and get, in case there are future keys that
-// can be both set and get.  But as of now, all parameters are either set only or get only.
-enum media2_parameter_keys {
-    // Streaming/buffering parameters
-    MEDIA2_KEY_PARAMETER_CACHE_STAT_COLLECT_FREQ_MS = 1100,            // set only
-
-    // Return a Parcel containing a single int, which is the channel count of the
-    // audio track, or zero for error (e.g. no audio track) or unknown.
-    MEDIA2_KEY_PARAMETER_AUDIO_CHANNEL_COUNT = 1200,                   // get only
-
-    // Playback rate expressed in permille (1000 is normal speed), saved as int32_t, with negative
-    // values used for rewinding or reverse playback.
-    MEDIA2_KEY_PARAMETER_PLAYBACK_RATE_PERMILLE = 1300,                // set only
-
-    // Set a Parcel containing the value of a parcelled Java AudioAttribute instance
-    MEDIA2_KEY_PARAMETER_AUDIO_ATTRIBUTES = 1400                       // set only
-};
-
-// Keep INVOKE_ID_* in sync with MediaPlayer2.java.
-enum media_player2_invoke_ids {
-    MEDIA_PLAYER2_INVOKE_ID_GET_TRACK_INFO = 1,
-    MEDIA_PLAYER2_INVOKE_ID_ADD_EXTERNAL_SOURCE = 2,
-    MEDIA_PLAYER2_INVOKE_ID_ADD_EXTERNAL_SOURCE_FD = 3,
-    MEDIA_PLAYER2_INVOKE_ID_SELECT_TRACK = 4,
-    MEDIA_PLAYER2_INVOKE_ID_UNSELECT_TRACK = 5,
-    MEDIA_PLAYER2_INVOKE_ID_SET_VIDEO_SCALING_MODE = 6,
-    MEDIA_PLAYER2_INVOKE_ID_GET_SELECTED_TRACK = 7
-};
-
-}; // namespace android
-
-#endif // ANDROID_MEDIAPLAYER2_TYPES_H
diff --git a/media/libmediaplayer2/include/mediaplayer2/mediaplayer2.h b/media/libmediaplayer2/include/mediaplayer2/mediaplayer2.h
deleted file mode 100644
index 1e8a1d5..0000000
--- a/media/libmediaplayer2/include/mediaplayer2/mediaplayer2.h
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * Copyright 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_MEDIAPLAYER2_H
-#define ANDROID_MEDIAPLAYER2_H
-
-#include <media/AVSyncSettings.h>
-#include <media/AudioResamplerPublic.h>
-#include <media/BufferingSettings.h>
-#include <media/mediaplayer_common.h>
-#include <mediaplayer2/MediaPlayer2Interface.h>
-#include <mediaplayer2/MediaPlayer2Types.h>
-#include <mediaplayer2/JObjectHolder.h>
-
-#include <jni.h>
-#include <utils/Errors.h>
-#include <utils/Mutex.h>
-#include <utils/RefBase.h>
-#include <utils/String16.h>
-#include <utils/Vector.h>
-#include <system/audio-base.h>
-
-#include "jni.h"
-
-namespace android {
-
-struct ANativeWindowWrapper;
-struct DataSourceDesc;
-class MediaPlayer2AudioOutput;
-
-// ref-counted object for callbacks
-class MediaPlayer2Listener: virtual public RefBase
-{
-public:
-    virtual void notify(int64_t srcId, int msg, int ext1, int ext2,
-            const PlayerMessage *obj = NULL) = 0;
-};
-
-class MediaPlayer2 : public MediaPlayer2InterfaceListener
-{
-public:
-    ~MediaPlayer2();
-
-    static sp<MediaPlayer2> Create(int32_t sessionId, jobject context);
-    static status_t DumpAll(int fd, const Vector<String16>& args);
-
-            void            disconnect();
-
-            status_t        getSrcId(int64_t *srcId);
-            status_t        setDataSource(const sp<DataSourceDesc> &dsd);
-            status_t        prepareNextDataSource(const sp<DataSourceDesc> &dsd);
-            status_t        playNextDataSource(int64_t srcId);
-            status_t        setVideoSurfaceTexture(const sp<ANativeWindowWrapper>& nww);
-            status_t        setListener(const sp<MediaPlayer2Listener>& listener);
-            status_t        getBufferingSettings(BufferingSettings* buffering /* nonnull */);
-            status_t        setBufferingSettings(const BufferingSettings& buffering);
-            status_t        prepareAsync();
-            status_t        start();
-            status_t        pause();
-            bool            isPlaying();
-            mediaplayer2_states getState();
-            status_t        setPlaybackSettings(const AudioPlaybackRate& rate);
-            status_t        getPlaybackSettings(AudioPlaybackRate* rate /* nonnull */);
-            status_t        setSyncSettings(const AVSyncSettings& sync, float videoFpsHint);
-            status_t        getSyncSettings(
-                                    AVSyncSettings* sync /* nonnull */,
-                                    float* videoFps /* nonnull */);
-            status_t        getVideoWidth(int *w);
-            status_t        getVideoHeight(int *h);
-            status_t        seekTo(
-                    int64_t msec,
-                    MediaPlayer2SeekMode mode = MediaPlayer2SeekMode::SEEK_PREVIOUS_SYNC);
-            status_t        notifyAt(int64_t mediaTimeUs);
-            status_t        getCurrentPosition(int64_t *msec);
-            status_t        getDuration(int64_t srcId, int64_t *msec);
-            status_t        reset();
-            status_t        setAudioStreamType(audio_stream_type_t type);
-            status_t        getAudioStreamType(audio_stream_type_t *type);
-            status_t        setLooping(int loop);
-            bool            isLooping();
-            status_t        setVolume(float volume);
-            void            notify(int64_t srcId, int msg, int ext1, int ext2,
-                                   const PlayerMessage *obj = NULL);
-            status_t        invoke(const PlayerMessage &request, PlayerMessage *reply);
-            status_t        setAudioSessionId(int32_t sessionId);
-            int32_t         getAudioSessionId();
-            status_t        setAuxEffectSendLevel(float level);
-            status_t        attachAuxEffect(int effectId);
-            status_t        setAudioAttributes(const jobject attributes);
-            jobject         getAudioAttributes();
-            status_t        getParameter(int key, Parcel* reply);
-            status_t        getMetrics(char **buffer, size_t *length);
-
-            // Modular DRM
-            status_t        prepareDrm(int64_t srcId,
-                                       const uint8_t uuid[16],
-                                       const Vector<uint8_t>& drmSessionId);
-            status_t        releaseDrm(int64_t srcId);
-            // AudioRouting
-            status_t        setPreferredDevice(jobject device);
-            jobject         getRoutedDevice();
-            status_t        addAudioDeviceCallback(jobject routingDelegate);
-            status_t        removeAudioDeviceCallback(jobject listener);
-
-            status_t        dump(int fd, const Vector<String16>& args);
-
-private:
-    MediaPlayer2(int32_t sessionId, jobject context);
-    bool init();
-
-    // Disconnect from the currently connected ANativeWindow.
-    void disconnectNativeWindow_l();
-
-    status_t setAudioAttributes_l(const jobject attributes);
-
-    void clear_l();
-    status_t seekTo_l(int64_t msec, MediaPlayer2SeekMode mode);
-    status_t prepareAsync_l();
-    status_t getDuration_l(int64_t *msec);
-    status_t reset_l();
-    status_t checkState_l();
-
-    pid_t                       mPid;
-    uid_t                       mUid;
-    sp<MediaPlayer2Interface>   mPlayer;
-    sp<MediaPlayer2AudioOutput> mAudioOutput;
-    int64_t                     mSrcId;
-    thread_id_t                 mLockThreadId;
-    mutable Mutex               mLock;
-    Mutex                       mNotifyLock;
-    sp<MediaPlayer2Listener>    mListener;
-    media_player2_internal_states mCurrentState;
-    bool                        mTransitionToNext;
-    int64_t                     mCurrentPosition;
-    MediaPlayer2SeekMode        mCurrentSeekMode;
-    int64_t                     mSeekPosition;
-    MediaPlayer2SeekMode        mSeekMode;
-    audio_stream_type_t         mStreamType;
-    bool                        mLoop;
-    float                       mVolume;
-    int                         mVideoWidth;
-    int                         mVideoHeight;
-    int32_t                     mAudioSessionId;
-    sp<JObjectHolder>           mAudioAttributes;
-    sp<JObjectHolder>           mContext;
-    float                       mSendLevel;
-    sp<ANativeWindowWrapper>    mConnectedWindow;
-};
-
-}; // namespace android
-
-#endif // ANDROID_MEDIAPLAYER2_H
diff --git a/media/libmediaplayer2/mediaplayer2.cpp b/media/libmediaplayer2/mediaplayer2.cpp
deleted file mode 100644
index de65f8d..0000000
--- a/media/libmediaplayer2/mediaplayer2.cpp
+++ /dev/null
@@ -1,1261 +0,0 @@
-/*
-**
-** Copyright 2017, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
-
-//#define LOG_NDEBUG 0
-#define LOG_TAG "MediaPlayer2Native"
-
-#include <android/binder_ibinder.h>
-#include <media/AudioSystem.h>
-#include <media/DataSourceDesc.h>
-#include <media/MemoryLeakTrackUtil.h>
-#include <media/NdkWrapper.h>
-#include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/foundation/ALooperRoster.h>
-#include <mediaplayer2/MediaPlayer2AudioOutput.h>
-#include <mediaplayer2/mediaplayer2.h>
-
-#include <utils/Log.h>
-#include <utils/SortedVector.h>
-#include <utils/String8.h>
-
-#include <system/audio.h>
-#include <system/window.h>
-
-#include <nuplayer2/NuPlayer2Driver.h>
-
-#include <dirent.h>
-#include <sys/stat.h>
-
-namespace android {
-
-extern ALooperRoster gLooperRoster;
-
-namespace {
-
-const int kDumpLockRetries = 50;
-const int kDumpLockSleepUs = 20000;
-
-class proxyListener : public MediaPlayer2InterfaceListener {
-public:
-    proxyListener(const wp<MediaPlayer2> &player)
-        : mPlayer(player) { }
-
-    ~proxyListener() { };
-
-    virtual void notify(int64_t srcId, int msg, int ext1, int ext2,
-            const PlayerMessage *obj) override {
-        sp<MediaPlayer2> player = mPlayer.promote();
-        if (player != NULL) {
-            player->notify(srcId, msg, ext1, ext2, obj);
-        }
-    }
-
-private:
-    wp<MediaPlayer2> mPlayer;
-};
-
-Mutex sRecordLock;
-SortedVector<wp<MediaPlayer2> > *sPlayers;
-
-void ensureInit_l() {
-    if (sPlayers == NULL) {
-        sPlayers = new SortedVector<wp<MediaPlayer2> >();
-    }
-}
-
-void addPlayer(const wp<MediaPlayer2>& player) {
-    Mutex::Autolock lock(sRecordLock);
-    ensureInit_l();
-    sPlayers->add(player);
-}
-
-void removePlayer(const wp<MediaPlayer2>& player) {
-    Mutex::Autolock lock(sRecordLock);
-    ensureInit_l();
-    sPlayers->remove(player);
-}
-
-/**
- * The only arguments this understands right now are -c, -von and -voff,
- * which are parsed by ALooperRoster::dump()
- */
-status_t dumpPlayers(int fd, const Vector<String16>& args) {
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-    String8 result;
-    SortedVector< sp<MediaPlayer2> > players; //to serialise the mutex unlock & client destruction.
-
-    {
-        Mutex::Autolock lock(sRecordLock);
-        ensureInit_l();
-        for (int i = 0, n = sPlayers->size(); i < n; ++i) {
-            sp<MediaPlayer2> p = (*sPlayers)[i].promote();
-            if (p != 0) {
-                p->dump(fd, args);
-            }
-            players.add(p);
-        }
-    }
-
-    result.append(" Files opened and/or mapped:\n");
-    snprintf(buffer, SIZE, "/proc/%d/maps", getpid());
-    FILE *f = fopen(buffer, "r");
-    if (f) {
-        while (!feof(f)) {
-            fgets(buffer, SIZE, f);
-            if (strstr(buffer, " /storage/") ||
-                strstr(buffer, " /system/sounds/") ||
-                strstr(buffer, " /data/") ||
-                strstr(buffer, " /system/media/")) {
-                result.append("  ");
-                result.append(buffer);
-            }
-        }
-        fclose(f);
-    } else {
-        result.append("couldn't open ");
-        result.append(buffer);
-        result.append("\n");
-    }
-
-    snprintf(buffer, SIZE, "/proc/%d/fd", getpid());
-    DIR *d = opendir(buffer);
-    if (d) {
-        struct dirent *ent;
-        while((ent = readdir(d)) != NULL) {
-            if (strcmp(ent->d_name,".") && strcmp(ent->d_name,"..")) {
-                snprintf(buffer, SIZE, "/proc/%d/fd/%s", getpid(), ent->d_name);
-                struct stat s;
-                if (lstat(buffer, &s) == 0) {
-                    if ((s.st_mode & S_IFMT) == S_IFLNK) {
-                        char linkto[256];
-                        int len = readlink(buffer, linkto, sizeof(linkto));
-                        if(len > 0) {
-                            if(len > 255) {
-                                linkto[252] = '.';
-                                linkto[253] = '.';
-                                linkto[254] = '.';
-                                linkto[255] = 0;
-                            } else {
-                                linkto[len] = 0;
-                            }
-                            if (strstr(linkto, "/storage/") == linkto ||
-                                strstr(linkto, "/system/sounds/") == linkto ||
-                                strstr(linkto, "/data/") == linkto ||
-                                strstr(linkto, "/system/media/") == linkto) {
-                                result.append("  ");
-                                result.append(buffer);
-                                result.append(" -> ");
-                                result.append(linkto);
-                                result.append("\n");
-                            }
-                        }
-                    } else {
-                        result.append("  unexpected type for ");
-                        result.append(buffer);
-                        result.append("\n");
-                    }
-                }
-            }
-        }
-        closedir(d);
-    } else {
-        result.append("couldn't open ");
-        result.append(buffer);
-        result.append("\n");
-    }
-
-    gLooperRoster.dump(fd, args);
-
-    bool dumpMem = false;
-    bool unreachableMemory = false;
-    for (size_t i = 0; i < args.size(); i++) {
-        if (args[i] == String16("-m")) {
-            dumpMem = true;
-        } else if (args[i] == String16("--unreachable")) {
-            unreachableMemory = true;
-        }
-    }
-    if (dumpMem) {
-        result.append("\nDumping memory:\n");
-        std::string s = dumpMemoryAddresses(100 /* limit */);
-        result.append(s.c_str(), s.size());
-    }
-    if (unreachableMemory) {
-        result.append("\nDumping unreachable memory:\n");
-        // TODO - should limit be an argument parameter?
-        // TODO: enable GetUnreachableMemoryString if it's part of stable API
-        //std::string s = GetUnreachableMemoryString(true /* contents */, 10000 /* limit */);
-        //result.append(s.c_str(), s.size());
-    }
-
-    write(fd, result.string(), result.size());
-    return NO_ERROR;
-}
-
-}  // anonymous namespace
-
-//static
-sp<MediaPlayer2> MediaPlayer2::Create(int32_t sessionId, jobject context) {
-    sp<MediaPlayer2> player = new MediaPlayer2(sessionId, context);
-
-    if (!player->init()) {
-        return NULL;
-    }
-
-    ALOGV("Create new player(%p)", player.get());
-
-    addPlayer(player);
-    return player;
-}
-
-// static
-status_t MediaPlayer2::DumpAll(int fd, const Vector<String16>& args) {
-    return dumpPlayers(fd, args);
-}
-
-MediaPlayer2::MediaPlayer2(int32_t sessionId, jobject context) {
-    ALOGV("constructor");
-    mSrcId = 0;
-    mLockThreadId = 0;
-    mListener = NULL;
-    mStreamType = AUDIO_STREAM_MUSIC;
-    mAudioAttributes = NULL;
-    mContext = new JObjectHolder(context);
-    mCurrentPosition = -1;
-    mCurrentSeekMode = MediaPlayer2SeekMode::SEEK_PREVIOUS_SYNC;
-    mSeekPosition = -1;
-    mSeekMode = MediaPlayer2SeekMode::SEEK_PREVIOUS_SYNC;
-    mCurrentState = MEDIA_PLAYER2_IDLE;
-    mTransitionToNext = false;
-    mLoop = false;
-    mVolume = 1.0;
-    mVideoWidth = mVideoHeight = 0;
-    mSendLevel = 0;
-
-    mPid = AIBinder_getCallingPid();
-    mUid = AIBinder_getCallingUid();
-
-    mAudioOutput = new MediaPlayer2AudioOutput(sessionId, mUid, mPid, NULL /*attributes*/);
-}
-
-MediaPlayer2::~MediaPlayer2() {
-    ALOGV("destructor");
-    disconnect();
-    removePlayer(this);
-}
-
-bool MediaPlayer2::init() {
-    // TODO: after merge with NuPlayer2Driver, MediaPlayer2 will have its own
-    // looper for notification.
-    return true;
-}
-
-void MediaPlayer2::disconnect() {
-    ALOGV("disconnect");
-    sp<MediaPlayer2Interface> p;
-    {
-        Mutex::Autolock _l(mLock);
-        p = mPlayer;
-        mPlayer.clear();
-    }
-
-    if (p != 0) {
-        p->setListener(NULL);
-        p->reset();
-    }
-
-    {
-        Mutex::Autolock _l(mLock);
-        disconnectNativeWindow_l();
-    }
-}
-
-void MediaPlayer2::clear_l() {
-    mCurrentPosition = -1;
-    mCurrentSeekMode = MediaPlayer2SeekMode::SEEK_PREVIOUS_SYNC;
-    mSeekPosition = -1;
-    mSeekMode = MediaPlayer2SeekMode::SEEK_PREVIOUS_SYNC;
-    mVideoWidth = mVideoHeight = 0;
-}
-
-status_t MediaPlayer2::setListener(const sp<MediaPlayer2Listener>& listener) {
-    ALOGV("setListener");
-    Mutex::Autolock _l(mLock);
-    mListener = listener;
-    return NO_ERROR;
-}
-
-status_t MediaPlayer2::getSrcId(int64_t *srcId) {
-    if (srcId == NULL) {
-        return BAD_VALUE;
-    }
-
-    Mutex::Autolock _l(mLock);
-    *srcId = mSrcId;
-    return OK;
-}
-
-status_t MediaPlayer2::setDataSource(const sp<DataSourceDesc> &dsd) {
-    if (dsd == NULL) {
-        return BAD_VALUE;
-    }
-    // Microsecond is used in NuPlayer2.
-    if (dsd->mStartPositionMs > DataSourceDesc::kMaxTimeMs) {
-        dsd->mStartPositionMs = DataSourceDesc::kMaxTimeMs;
-        ALOGW("setDataSource, start poistion clamped to %lld ms", (long long)dsd->mStartPositionMs);
-    }
-    if (dsd->mEndPositionMs > DataSourceDesc::kMaxTimeMs) {
-        dsd->mEndPositionMs = DataSourceDesc::kMaxTimeMs;
-        ALOGW("setDataSource, end poistion clamped to %lld ms", (long long)dsd->mStartPositionMs);
-    }
-    ALOGV("setDataSource type(%d), srcId(%lld)", dsd->mType, (long long)dsd->mId);
-
-    sp<MediaPlayer2Interface> oldPlayer;
-
-    {
-        Mutex::Autolock _l(mLock);
-        if (!((mCurrentState & MEDIA_PLAYER2_IDLE)
-              || mCurrentState == MEDIA_PLAYER2_STATE_ERROR)) {
-            ALOGE("setDataSource called in wrong state %d", mCurrentState);
-            return INVALID_OPERATION;
-        }
-
-        sp<MediaPlayer2Interface> player = new NuPlayer2Driver(mPid, mUid, mContext);
-        status_t err = player->initCheck();
-        if (err != NO_ERROR) {
-            ALOGE("Failed to create player object, initCheck failed(%d)", err);
-            return err;
-        }
-
-        clear_l();
-
-        player->setListener(new proxyListener(this));
-        player->setAudioSink(mAudioOutput);
-
-        err = player->setDataSource(dsd);
-        if (err != OK) {
-            ALOGE("setDataSource error: %d", err);
-            return err;
-        }
-
-        sp<MediaPlayer2Interface> oldPlayer = mPlayer;
-        mPlayer = player;
-        mSrcId = dsd->mId;
-        mCurrentState = MEDIA_PLAYER2_INITIALIZED;
-    }
-
-    if (oldPlayer != NULL) {
-        oldPlayer->setListener(NULL);
-        oldPlayer->reset();
-    }
-
-    return OK;
-}
-
-status_t MediaPlayer2::prepareNextDataSource(const sp<DataSourceDesc> &dsd) {
-    if (dsd == NULL) {
-        return BAD_VALUE;
-    }
-    ALOGV("prepareNextDataSource type(%d), srcId(%lld)", dsd->mType, (long long)dsd->mId);
-
-    Mutex::Autolock _l(mLock);
-    if (mPlayer == NULL) {
-        ALOGE("prepareNextDataSource failed: state %X, mPlayer(%p)", mCurrentState, mPlayer.get());
-        return INVALID_OPERATION;
-    }
-    return mPlayer->prepareNextDataSource(dsd);
-}
-
-status_t MediaPlayer2::playNextDataSource(int64_t srcId) {
-    ALOGV("playNextDataSource srcId(%lld)", (long long)srcId);
-
-    Mutex::Autolock _l(mLock);
-    if (mPlayer == NULL) {
-        ALOGE("playNextDataSource failed: state %X, mPlayer(%p)", mCurrentState, mPlayer.get());
-        return INVALID_OPERATION;
-    }
-    mSrcId = srcId;
-    mTransitionToNext = true;
-    return mPlayer->playNextDataSource(srcId);
-}
-
-status_t MediaPlayer2::invoke(const PlayerMessage &request, PlayerMessage *reply) {
-    Mutex::Autolock _l(mLock);
-    const bool hasBeenInitialized =
-            (mCurrentState != MEDIA_PLAYER2_STATE_ERROR) &&
-            ((mCurrentState & MEDIA_PLAYER2_IDLE) != MEDIA_PLAYER2_IDLE);
-    if ((mPlayer == NULL) || !hasBeenInitialized) {
-        ALOGE("invoke() failed: wrong state %X, mPlayer(%p)", mCurrentState, mPlayer.get());
-        return INVALID_OPERATION;
-    }
-    return mPlayer->invoke(request, reply);
-}
-
-void MediaPlayer2::disconnectNativeWindow_l() {
-    if (mConnectedWindow != NULL && mConnectedWindow->getANativeWindow() != NULL) {
-        status_t err = native_window_api_disconnect(
-                mConnectedWindow->getANativeWindow(), NATIVE_WINDOW_API_MEDIA);
-
-        if (err != OK) {
-            ALOGW("nativeWindowDisconnect returned an error: %s (%d)",
-                  strerror(-err), err);
-        }
-    }
-    mConnectedWindow.clear();
-}
-
-status_t MediaPlayer2::setVideoSurfaceTexture(const sp<ANativeWindowWrapper>& nww) {
-    ANativeWindow *anw = (nww == NULL ? NULL : nww->getANativeWindow());
-    ALOGV("setVideoSurfaceTexture(%p)", anw);
-    Mutex::Autolock _l(mLock);
-    if (mPlayer == 0) {
-        return NO_INIT;
-    }
-
-    if (anw != NULL) {
-        if (mConnectedWindow != NULL
-            && mConnectedWindow->getANativeWindow() == anw) {
-            return OK;
-        }
-        status_t err = native_window_api_connect(anw, NATIVE_WINDOW_API_MEDIA);
-
-        if (err != OK) {
-            ALOGE("setVideoSurfaceTexture failed: %d", err);
-            // Note that we must do the reset before disconnecting from the ANW.
-            // Otherwise queue/dequeue calls could be made on the disconnected
-            // ANW, which may result in errors.
-            mPlayer->reset();
-            disconnectNativeWindow_l();
-            return err;
-        }
-    }
-
-    // Note that we must set the player's new GraphicBufferProducer before
-    // disconnecting the old one.  Otherwise queue/dequeue calls could be made
-    // on the disconnected ANW, which may result in errors.
-    status_t err = mPlayer->setVideoSurfaceTexture(nww);
-
-    disconnectNativeWindow_l();
-
-    if (err == OK) {
-        mConnectedWindow = nww;
-        mLock.unlock();
-    } else if (anw != NULL) {
-        mLock.unlock();
-        status_t err = native_window_api_disconnect(anw, NATIVE_WINDOW_API_MEDIA);
-
-        if (err != OK) {
-            ALOGW("nativeWindowDisconnect returned an error: %s (%d)",
-                  strerror(-err), err);
-        }
-    }
-
-    return err;
-}
-
-status_t MediaPlayer2::getBufferingSettings(BufferingSettings* buffering /* nonnull */) {
-    ALOGV("getBufferingSettings");
-
-    Mutex::Autolock _l(mLock);
-    if (mPlayer == 0) {
-        return NO_INIT;
-    }
-
-    status_t ret = mPlayer->getBufferingSettings(buffering);
-    if (ret == NO_ERROR) {
-        ALOGV("getBufferingSettings{%s}", buffering->toString().string());
-    } else {
-        ALOGE("getBufferingSettings returned %d", ret);
-    }
-    return ret;
-}
-
-status_t MediaPlayer2::setBufferingSettings(const BufferingSettings& buffering) {
-    ALOGV("setBufferingSettings{%s}", buffering.toString().string());
-
-    Mutex::Autolock _l(mLock);
-    if (mPlayer == 0) {
-        return NO_INIT;
-    }
-    return mPlayer->setBufferingSettings(buffering);
-}
-
-status_t MediaPlayer2::setAudioAttributes_l(const jobject attributes) {
-    if (mAudioOutput != NULL) {
-        mAudioOutput->setAudioAttributes(attributes);
-    }
-    return NO_ERROR;
-}
-
-status_t MediaPlayer2::prepareAsync() {
-    ALOGV("prepareAsync");
-    Mutex::Autolock _l(mLock);
-    if ((mPlayer != 0) && (mCurrentState & MEDIA_PLAYER2_INITIALIZED)) {
-        if (mAudioAttributes != NULL) {
-            status_t err = setAudioAttributes_l(mAudioAttributes->getJObject());
-            if (err != OK) {
-                return err;
-            }
-        }
-        mCurrentState = MEDIA_PLAYER2_PREPARING;
-        return mPlayer->prepareAsync();
-    }
-    ALOGE("prepareAsync called in state %d, mPlayer(%p)", mCurrentState, mPlayer.get());
-    return INVALID_OPERATION;
-}
-
-status_t MediaPlayer2::start() {
-    ALOGV("start");
-
-    status_t ret = NO_ERROR;
-    Mutex::Autolock _l(mLock);
-
-    mLockThreadId = getThreadId();
-
-    if (mCurrentState & MEDIA_PLAYER2_STARTED) {
-        ret = NO_ERROR;
-    } else if ( (mPlayer != 0) && ( mCurrentState & ( MEDIA_PLAYER2_PREPARED |
-                    MEDIA_PLAYER2_PLAYBACK_COMPLETE | MEDIA_PLAYER2_PAUSED ) ) ) {
-        mPlayer->setLooping(mLoop);
-
-        if (mAudioOutput != 0) {
-            mAudioOutput->setVolume(mVolume);
-        }
-
-        if (mAudioOutput != 0) {
-            mAudioOutput->setAuxEffectSendLevel(mSendLevel);
-        }
-        mCurrentState = MEDIA_PLAYER2_STARTED;
-        ret = mPlayer->start();
-        if (ret != NO_ERROR) {
-            mCurrentState = MEDIA_PLAYER2_STATE_ERROR;
-        } else {
-            if (mCurrentState == MEDIA_PLAYER2_PLAYBACK_COMPLETE) {
-                ALOGV("playback completed immediately following start()");
-            }
-        }
-    } else {
-        ALOGE("start called in state %d, mPlayer(%p)", mCurrentState, mPlayer.get());
-        ret = INVALID_OPERATION;
-    }
-
-    mLockThreadId = 0;
-
-    return ret;
-}
-
-status_t MediaPlayer2::pause() {
-    ALOGV("pause");
-    Mutex::Autolock _l(mLock);
-    if (mCurrentState & (MEDIA_PLAYER2_PAUSED|MEDIA_PLAYER2_PLAYBACK_COMPLETE))
-        return NO_ERROR;
-    if ((mPlayer != 0) && (mCurrentState & (MEDIA_PLAYER2_STARTED | MEDIA_PLAYER2_PREPARED))) {
-        status_t ret = mPlayer->pause();
-        if (ret != NO_ERROR) {
-            mCurrentState = MEDIA_PLAYER2_STATE_ERROR;
-        } else {
-            mCurrentState = MEDIA_PLAYER2_PAUSED;
-            mTransitionToNext = false;
-        }
-        return ret;
-    }
-    ALOGE("pause called in state %d, mPlayer(%p)", mCurrentState, mPlayer.get());
-    return INVALID_OPERATION;
-}
-
-bool MediaPlayer2::isPlaying() {
-    Mutex::Autolock _l(mLock);
-    if (mPlayer != 0) {
-        bool temp = mPlayer->isPlaying();
-        ALOGV("isPlaying: %d", temp);
-        if ((mCurrentState & MEDIA_PLAYER2_STARTED) && ! temp) {
-            ALOGE("internal/external state mismatch corrected");
-            mCurrentState = MEDIA_PLAYER2_PAUSED;
-        } else if ((mCurrentState & MEDIA_PLAYER2_PAUSED) && temp) {
-            ALOGE("internal/external state mismatch corrected");
-            mCurrentState = MEDIA_PLAYER2_STARTED;
-        }
-        return temp;
-    }
-    ALOGV("isPlaying: no active player");
-    return false;
-}
-
-mediaplayer2_states MediaPlayer2::getState() {
-    Mutex::Autolock _l(mLock);
-    if (mCurrentState & MEDIA_PLAYER2_STATE_ERROR) {
-        return MEDIAPLAYER2_STATE_ERROR;
-    }
-    if (mPlayer == 0
-        || (mCurrentState &
-            (MEDIA_PLAYER2_IDLE | MEDIA_PLAYER2_INITIALIZED | MEDIA_PLAYER2_PREPARING))) {
-        return MEDIAPLAYER2_STATE_IDLE;
-    }
-    if (mCurrentState & MEDIA_PLAYER2_STARTED) {
-        return MEDIAPLAYER2_STATE_PLAYING;
-    }
-    if (mCurrentState & (MEDIA_PLAYER2_PAUSED | MEDIA_PLAYER2_PLAYBACK_COMPLETE)) {
-        return MEDIAPLAYER2_STATE_PAUSED;
-    }
-    // now only mCurrentState & MEDIA_PLAYER2_PREPARED is true
-    return MEDIAPLAYER2_STATE_PREPARED;
-}
-
-status_t MediaPlayer2::setPlaybackSettings(const AudioPlaybackRate& rate) {
-    ALOGV("setPlaybackSettings: %f %f %d %d",
-            rate.mSpeed, rate.mPitch, rate.mFallbackMode, rate.mStretchMode);
-    // Negative speed and pitch does not make sense. Further validation will
-    // be done by the respective mediaplayers.
-    if (rate.mSpeed <= 0.f || rate.mPitch < 0.f) {
-        return BAD_VALUE;
-    }
-    Mutex::Autolock _l(mLock);
-    if (mPlayer == 0) {
-        return INVALID_OPERATION;
-    }
-
-    status_t err = mPlayer->setPlaybackSettings(rate);
-    return err;
-}
-
-status_t MediaPlayer2::getPlaybackSettings(AudioPlaybackRate* rate /* nonnull */) {
-    Mutex::Autolock _l(mLock);
-    if (mPlayer == 0) {
-        return INVALID_OPERATION;
-    }
-    status_t ret = mPlayer->getPlaybackSettings(rate);
-    if (ret == NO_ERROR) {
-        ALOGV("getPlaybackSettings(%f, %f, %d, %d)",
-                rate->mSpeed, rate->mPitch, rate->mFallbackMode, rate->mStretchMode);
-    } else {
-        ALOGV("getPlaybackSettings returned %d", ret);
-    }
-    return ret;
-}
-
-status_t MediaPlayer2::setSyncSettings(const AVSyncSettings& sync, float videoFpsHint) {
-    ALOGV("setSyncSettings: %u %u %f %f",
-            sync.mSource, sync.mAudioAdjustMode, sync.mTolerance, videoFpsHint);
-    Mutex::Autolock _l(mLock);
-    if (mPlayer == 0) return INVALID_OPERATION;
-    return mPlayer->setSyncSettings(sync, videoFpsHint);
-}
-
-status_t MediaPlayer2::getSyncSettings(
-        AVSyncSettings* sync /* nonnull */, float* videoFps /* nonnull */) {
-    Mutex::Autolock _l(mLock);
-    if (mPlayer == 0) {
-        return INVALID_OPERATION;
-    }
-    status_t ret = mPlayer->getSyncSettings(sync, videoFps);
-    if (ret == NO_ERROR) {
-        ALOGV("getSyncSettings(%u, %u, %f, %f)",
-                sync->mSource, sync->mAudioAdjustMode, sync->mTolerance, *videoFps);
-    } else {
-        ALOGV("getSyncSettings returned %d", ret);
-    }
-    return ret;
-
-}
-
-status_t MediaPlayer2::getVideoWidth(int *w) {
-    ALOGV("getVideoWidth");
-    Mutex::Autolock _l(mLock);
-    if (mPlayer == 0) {
-        return INVALID_OPERATION;
-    }
-    *w = mVideoWidth;
-    return NO_ERROR;
-}
-
-status_t MediaPlayer2::getVideoHeight(int *h) {
-    ALOGV("getVideoHeight");
-    Mutex::Autolock _l(mLock);
-    if (mPlayer == 0) {
-        return INVALID_OPERATION;
-    }
-    *h = mVideoHeight;
-    return NO_ERROR;
-}
-
-status_t MediaPlayer2::getCurrentPosition(int64_t *msec) {
-    ALOGV("getCurrentPosition");
-    Mutex::Autolock _l(mLock);
-    if (mPlayer == 0) {
-        return INVALID_OPERATION;
-    }
-    if (mCurrentPosition >= 0) {
-        ALOGV("Using cached seek position: %lld", (long long)mCurrentPosition);
-        *msec = mCurrentPosition;
-        return NO_ERROR;
-    }
-    status_t ret = mPlayer->getCurrentPosition(msec);
-    if (ret == NO_ERROR) {
-        ALOGV("getCurrentPosition = %lld", (long long)*msec);
-    } else {
-        ALOGE("getCurrentPosition returned %d", ret);
-    }
-    return ret;
-}
-
-status_t MediaPlayer2::getDuration(int64_t srcId, int64_t *msec) {
-    Mutex::Autolock _l(mLock);
-    // TODO: cache duration for currentSrcId and nextSrcId, and return correct
-    // value for nextSrcId.
-    if (srcId != mSrcId) {
-        *msec = -1;
-        return OK;
-    }
-
-    ALOGV("getDuration_l");
-    bool isValidState = (mCurrentState & (MEDIA_PLAYER2_PREPARED | MEDIA_PLAYER2_STARTED |
-            MEDIA_PLAYER2_PAUSED | MEDIA_PLAYER2_PLAYBACK_COMPLETE));
-    if (mPlayer == 0 || !isValidState) {
-        ALOGE("Attempt to call getDuration in wrong state: mPlayer=%p, mCurrentState=%u",
-                mPlayer.get(), mCurrentState);
-        return INVALID_OPERATION;
-    }
-    int64_t durationMs;
-    status_t ret = mPlayer->getDuration(&durationMs);
-
-    if (ret == NO_ERROR) {
-        ALOGV("getDuration = %lld", (long long)durationMs);
-    } else {
-        ALOGE("getDuration returned %d", ret);
-        // Do not enter error state just because no duration was available.
-        durationMs = -1;
-    }
-
-    if (msec) {
-        *msec = durationMs;
-    }
-    return OK;
-}
-
-status_t MediaPlayer2::seekTo_l(int64_t msec, MediaPlayer2SeekMode mode) {
-    ALOGV("seekTo (%lld, %d)", (long long)msec, mode);
-    if ((mPlayer == 0) || !(mCurrentState & (MEDIA_PLAYER2_STARTED | MEDIA_PLAYER2_PREPARED |
-            MEDIA_PLAYER2_PAUSED | MEDIA_PLAYER2_PLAYBACK_COMPLETE))) {
-        ALOGE("Attempt to perform seekTo in wrong state: mPlayer=%p, mCurrentState=%u",
-              mPlayer.get(), mCurrentState);
-        return INVALID_OPERATION;
-    }
-    if (msec < 0) {
-        ALOGW("Attempt to seek to invalid position: %lld", (long long)msec);
-        msec = 0;
-    }
-
-    int64_t durationMs;
-    status_t err = mPlayer->getDuration(&durationMs);
-
-    if (err != OK) {
-        ALOGW("Stream has no duration and is therefore not seekable.");
-        return err;
-    }
-
-    if (msec > durationMs) {
-        ALOGW("Attempt to seek to past end of file: request = %lld, durationMs = %lld",
-              (long long)msec, (long long)durationMs);
-
-        msec = durationMs;
-    }
-
-    // cache duration
-    mCurrentPosition = msec;
-    mCurrentSeekMode = mode;
-    if (mSeekPosition < 0) {
-        mSeekPosition = msec;
-        mSeekMode = mode;
-        return mPlayer->seekTo(msec, mode);
-    }
-    ALOGV("Seek in progress - queue up seekTo[%lld, %d]", (long long)msec, mode);
-    return NO_ERROR;
-}
-
-status_t MediaPlayer2::seekTo(int64_t msec, MediaPlayer2SeekMode mode) {
-    mLockThreadId = getThreadId();
-    Mutex::Autolock _l(mLock);
-    status_t result = seekTo_l(msec, mode);
-    mLockThreadId = 0;
-
-    return result;
-}
-
-status_t MediaPlayer2::notifyAt(int64_t mediaTimeUs) {
-    Mutex::Autolock _l(mLock);
-    if (mPlayer != 0) {
-        return INVALID_OPERATION;
-    }
-
-    return mPlayer->notifyAt(mediaTimeUs);
-}
-
-status_t MediaPlayer2::reset_l() {
-    mLoop = false;
-    if (mCurrentState == MEDIA_PLAYER2_IDLE) {
-        return NO_ERROR;
-    }
-    if (mPlayer != 0) {
-        status_t ret = mPlayer->reset();
-        if (ret != NO_ERROR) {
-            ALOGE("reset() failed with return code (%d)", ret);
-            mCurrentState = MEDIA_PLAYER2_STATE_ERROR;
-        } else {
-            mPlayer->setListener(NULL);
-            mCurrentState = MEDIA_PLAYER2_IDLE;
-            mTransitionToNext = false;
-        }
-        // setDataSource has to be called again to create a
-        // new mediaplayer.
-        mPlayer = 0;
-        return ret;
-    }
-    clear_l();
-    return NO_ERROR;
-}
-
-status_t MediaPlayer2::reset() {
-    ALOGV("reset");
-    mLockThreadId = getThreadId();
-    Mutex::Autolock _l(mLock);
-    status_t result = reset_l();
-    mLockThreadId = 0;
-
-    return result;
-}
-
-status_t MediaPlayer2::setAudioStreamType(audio_stream_type_t type) {
-    ALOGV("MediaPlayer2::setAudioStreamType");
-    Mutex::Autolock _l(mLock);
-    if (mStreamType == type) return NO_ERROR;
-    if (mCurrentState & ( MEDIA_PLAYER2_PREPARED | MEDIA_PLAYER2_STARTED |
-                MEDIA_PLAYER2_PAUSED | MEDIA_PLAYER2_PLAYBACK_COMPLETE ) ) {
-        // Can't change the stream type after prepare
-        ALOGE("setAudioStream called in state %d", mCurrentState);
-        return INVALID_OPERATION;
-    }
-    // cache
-    mStreamType = type;
-    return OK;
-}
-
-status_t MediaPlayer2::getAudioStreamType(audio_stream_type_t *type) {
-    ALOGV("getAudioStreamType");
-    Mutex::Autolock _l(mLock);
-    *type = mStreamType;
-    return OK;
-}
-
-status_t MediaPlayer2::setLooping(int loop) {
-    ALOGV("MediaPlayer2::setLooping");
-    Mutex::Autolock _l(mLock);
-    mLoop = (loop != 0);
-    if (mPlayer != 0) {
-        return mPlayer->setLooping(loop);
-    }
-    return OK;
-}
-
-bool MediaPlayer2::isLooping() {
-    ALOGV("isLooping");
-    Mutex::Autolock _l(mLock);
-    if (mPlayer != 0) {
-        return mLoop;
-    }
-    ALOGV("isLooping: no active player");
-    return false;
-}
-
-status_t MediaPlayer2::setVolume(float volume) {
-    ALOGV("MediaPlayer2::setVolume(%f)", volume);
-    Mutex::Autolock _l(mLock);
-    mVolume = volume;
-    if (mAudioOutput != 0) {
-        mAudioOutput->setVolume(volume);
-    }
-    return OK;
-}
-
-status_t MediaPlayer2::setAudioSessionId(int32_t sessionId) {
-    ALOGV("MediaPlayer2::setAudioSessionId(%d)", sessionId);
-    Mutex::Autolock _l(mLock);
-    if (!(mCurrentState & MEDIA_PLAYER2_IDLE)) {
-        ALOGE("setAudioSessionId called in state %d", mCurrentState);
-        return INVALID_OPERATION;
-    }
-    if (sessionId < 0) {
-        return BAD_VALUE;
-    }
-    if (mAudioOutput != NULL && sessionId != mAudioOutput->getSessionId()) {
-        mAudioOutput->setSessionId(sessionId);
-    }
-    return NO_ERROR;
-}
-
-int32_t MediaPlayer2::getAudioSessionId() {
-    Mutex::Autolock _l(mLock);
-    if (mAudioOutput != NULL) {
-        return mAudioOutput->getSessionId();
-    }
-    return 0;
-}
-
-status_t MediaPlayer2::setAuxEffectSendLevel(float level) {
-    ALOGV("MediaPlayer2::setAuxEffectSendLevel(%f)", level);
-    Mutex::Autolock _l(mLock);
-    mSendLevel = level;
-    if (mAudioOutput != 0) {
-        return mAudioOutput->setAuxEffectSendLevel(level);
-    }
-    return OK;
-}
-
-status_t MediaPlayer2::attachAuxEffect(int effectId) {
-    ALOGV("MediaPlayer2::attachAuxEffect(%d)", effectId);
-    Mutex::Autolock _l(mLock);
-    if (mAudioOutput == 0 ||
-        (mCurrentState & MEDIA_PLAYER2_IDLE) ||
-        (mCurrentState == MEDIA_PLAYER2_STATE_ERROR )) {
-        ALOGE("attachAuxEffect called in state %d, mPlayer(%p)", mCurrentState, mPlayer.get());
-        return INVALID_OPERATION;
-    }
-
-    return mAudioOutput->attachAuxEffect(effectId);
-}
-
-// always call with lock held
-status_t MediaPlayer2::checkState_l() {
-    if (mCurrentState & ( MEDIA_PLAYER2_PREPARED | MEDIA_PLAYER2_STARTED |
-            MEDIA_PLAYER2_PAUSED | MEDIA_PLAYER2_PLAYBACK_COMPLETE) ) {
-        // Can't change the audio attributes after prepare
-        ALOGE("trying to set audio attributes called in state %d", mCurrentState);
-        return INVALID_OPERATION;
-    }
-    return OK;
-}
-
-status_t MediaPlayer2::setAudioAttributes(const jobject attributes) {
-    ALOGV("MediaPlayer2::setAudioAttributes");
-    status_t status = INVALID_OPERATION;
-    Mutex::Autolock _l(mLock);
-    if (checkState_l() != OK) {
-        return status;
-    }
-    mAudioAttributes = new JObjectHolder(attributes);
-    status = setAudioAttributes_l(attributes);
-    return status;
-}
-
-jobject MediaPlayer2::getAudioAttributes() {
-    ALOGV("MediaPlayer2::getAudioAttributes)");
-    Mutex::Autolock _l(mLock);
-    return mAudioAttributes != NULL ? mAudioAttributes->getJObject() : NULL;
-}
-
-status_t MediaPlayer2::getParameter(int key, Parcel *reply) {
-    ALOGV("MediaPlayer2::getParameter(%d)", key);
-    Mutex::Autolock _l(mLock);
-    if (mPlayer == NULL) {
-        ALOGV("getParameter: no active player");
-        return INVALID_OPERATION;
-    }
-
-    status_t status =  mPlayer->getParameter(key, reply);
-    if (status != OK) {
-        ALOGD("getParameter returns %d", status);
-    }
-    return status;
-}
-
-// for mediametrics
-status_t MediaPlayer2::getMetrics(char **buffer, size_t *length) {
-    ALOGD("MediaPlayer2::getMetrics()");
-    Mutex::Autolock _l(mLock);
-    if (mPlayer == NULL) {
-        ALOGV("getMetrics: no active player");
-        return INVALID_OPERATION;
-    }
-
-    status_t status =  mPlayer->getMetrics(buffer, length);
-    if (status != OK) {
-        ALOGD("getMetrics returns %d", status);
-    }
-    return status;
-}
-
-void MediaPlayer2::notify(int64_t srcId, int msg, int ext1, int ext2, const PlayerMessage *obj) {
-    ALOGV("message received srcId=%lld, msg=%d, ext1=%d, ext2=%d",
-          (long long)srcId, msg, ext1, ext2);
-
-    bool send = true;
-    bool locked = false;
-
-    // TODO: In the future, we might be on the same thread if the app is
-    // running in the same process as the media server. In that case,
-    // this will deadlock.
-    //
-    // The threadId hack below works around this for the care of prepare,
-    // seekTo, start, and reset within the same process.
-    // FIXME: Remember, this is a hack, it's not even a hack that is applied
-    // consistently for all use-cases, this needs to be revisited.
-    if (mLockThreadId != getThreadId()) {
-        mLock.lock();
-        locked = true;
-    }
-
-    // Allows calls from JNI in idle state to notify errors
-    if (!(msg == MEDIA2_ERROR && mCurrentState == MEDIA_PLAYER2_IDLE) && mPlayer == 0) {
-        ALOGV("notify(%lld, %d, %d, %d) callback on disconnected mediaplayer",
-              (long long)srcId, msg, ext1, ext2);
-        if (locked) mLock.unlock();   // release the lock when done.
-        return;
-    }
-
-    switch (msg) {
-    case MEDIA2_NOP: // interface test message
-        break;
-    case MEDIA2_PREPARED:
-        ALOGV("MediaPlayer2::notify() prepared, srcId=%lld", (long long)srcId);
-        if (srcId == mSrcId) {
-            mCurrentState = MEDIA_PLAYER2_PREPARED;
-        }
-        break;
-    case MEDIA2_DRM_INFO:
-        ALOGV("MediaPlayer2::notify() MEDIA2_DRM_INFO(%lld, %d, %d, %d, %p)",
-              (long long)srcId, msg, ext1, ext2, obj);
-        break;
-    case MEDIA2_PLAYBACK_COMPLETE:
-        ALOGV("playback complete");
-        if (mCurrentState == MEDIA_PLAYER2_IDLE) {
-            ALOGE("playback complete in idle state");
-        }
-        if (!mLoop && srcId == mSrcId) {
-            mCurrentState = MEDIA_PLAYER2_PLAYBACK_COMPLETE;
-        }
-        break;
-    case MEDIA2_ERROR:
-        // Always log errors.
-        // ext1: Media framework error code.
-        // ext2: Implementation dependant error code.
-        ALOGE("error (%d, %d)", ext1, ext2);
-        mCurrentState = MEDIA_PLAYER2_STATE_ERROR;
-        break;
-    case MEDIA2_INFO:
-        // ext1: Media framework error code.
-        // ext2: Implementation dependant error code.
-        if (ext1 != MEDIA2_INFO_VIDEO_TRACK_LAGGING) {
-            ALOGW("info/warning (%d, %d)", ext1, ext2);
-
-            if (ext1 == MEDIA2_INFO_DATA_SOURCE_START && srcId == mSrcId && mTransitionToNext) {
-                mCurrentState = MEDIA_PLAYER2_STARTED;
-                mTransitionToNext = false;
-            }
-        }
-        break;
-    case MEDIA2_SEEK_COMPLETE:
-        ALOGV("Received seek complete");
-        if (mSeekPosition != mCurrentPosition || (mSeekMode != mCurrentSeekMode)) {
-            ALOGV("Executing queued seekTo(%lld, %d)",
-                  (long long)mCurrentPosition, mCurrentSeekMode);
-            mSeekPosition = -1;
-            mSeekMode = MediaPlayer2SeekMode::SEEK_PREVIOUS_SYNC;
-            seekTo_l(mCurrentPosition, mCurrentSeekMode);
-        }
-        else {
-            ALOGV("All seeks complete - return to regularly scheduled program");
-            mCurrentPosition = mSeekPosition = -1;
-            mCurrentSeekMode = mSeekMode = MediaPlayer2SeekMode::SEEK_PREVIOUS_SYNC;
-        }
-        break;
-    case MEDIA2_BUFFERING_UPDATE:
-        ALOGV("buffering %d", ext1);
-        break;
-    case MEDIA2_SET_VIDEO_SIZE:
-        ALOGV("New video size %d x %d", ext1, ext2);
-        mVideoWidth = ext1;
-        mVideoHeight = ext2;
-        break;
-    case MEDIA2_NOTIFY_TIME:
-        ALOGV("Received notify time message");
-        break;
-    case MEDIA2_TIMED_TEXT:
-        ALOGV("Received timed text message");
-        break;
-    case MEDIA2_SUBTITLE_DATA:
-        ALOGV("Received subtitle data message");
-        break;
-    case MEDIA2_META_DATA:
-        ALOGV("Received timed metadata message");
-        break;
-    default:
-        ALOGV("unrecognized message: (%d, %d, %d)", msg, ext1, ext2);
-        break;
-    }
-
-    sp<MediaPlayer2Listener> listener = mListener;
-    if (locked) mLock.unlock();
-
-    // this prevents re-entrant calls into client code
-    if ((listener != 0) && send) {
-        Mutex::Autolock _l(mNotifyLock);
-        ALOGV("callback application");
-        listener->notify(srcId, msg, ext1, ext2, obj);
-        ALOGV("back from callback");
-    }
-}
-
-// Modular DRM
-status_t MediaPlayer2::prepareDrm(
-        int64_t srcId, const uint8_t uuid[16], const Vector<uint8_t>& drmSessionId) {
-    // TODO change to ALOGV
-    ALOGD("prepareDrm: uuid: %p  drmSessionId: %p(%zu)", uuid,
-            drmSessionId.array(), drmSessionId.size());
-    Mutex::Autolock _l(mLock);
-    if (mPlayer == NULL) {
-        return NO_INIT;
-    }
-
-    // Only allowed it in player's preparing/prepared state.
-    // We get here only if MEDIA_DRM_INFO has already arrived (e.g., prepare is half-way through or
-    // completed) so the state change to "prepared" might not have happened yet (e.g., buffering).
-    // Still, we can allow prepareDrm for the use case of being called in OnDrmInfoListener.
-    if (!(mCurrentState & (MEDIA_PLAYER2_PREPARING | MEDIA_PLAYER2_PREPARED))) {
-        ALOGW("prepareDrm(%lld) called in non-prepare state(%d)", (long long)srcId, mCurrentState);
-        if (srcId == mSrcId) {
-            return INVALID_OPERATION;
-        }
-    }
-
-    if (drmSessionId.isEmpty()) {
-        ALOGE("prepareDrm: Unexpected. Can't proceed with crypto. Empty drmSessionId.");
-        return INVALID_OPERATION;
-    }
-
-    // Passing down to mediaserver mainly for creating the crypto
-    status_t status = mPlayer->prepareDrm(srcId, uuid, drmSessionId);
-    ALOGE_IF(status != OK, "prepareDrm: Failed at mediaserver with ret: %d", status);
-
-    // TODO change to ALOGV
-    ALOGD("prepareDrm: mediaserver::prepareDrm ret=%d", status);
-
-    return status;
-}
-
-status_t MediaPlayer2::releaseDrm(int64_t srcId) {
-    Mutex::Autolock _l(mLock);
-    if (mPlayer == NULL) {
-        return NO_INIT;
-    }
-
-    // Not allowing releaseDrm in an active/resumable state
-    if (mCurrentState & (MEDIA_PLAYER2_STARTED |
-                         MEDIA_PLAYER2_PAUSED |
-                         MEDIA_PLAYER2_PLAYBACK_COMPLETE |
-                         MEDIA_PLAYER2_STATE_ERROR)) {
-        ALOGE("releaseDrm Unexpected state %d. Can only be called in stopped/idle.", mCurrentState);
-        return INVALID_OPERATION;
-    }
-
-    status_t status = mPlayer->releaseDrm(srcId);
-    // TODO change to ALOGV
-    ALOGD("releaseDrm: mediaserver::releaseDrm ret: %d", status);
-    if (status != OK) {
-        ALOGE("releaseDrm: Failed at mediaserver with ret: %d", status);
-        // Overriding to OK so the client proceed with its own cleanup
-        // Client can't do more cleanup. mediaserver release its crypto at end of session anyway.
-        status = OK;
-    }
-
-    return status;
-}
-
-status_t MediaPlayer2::setPreferredDevice(jobject device) {
-    Mutex::Autolock _l(mLock);
-    if (mAudioOutput == NULL) {
-        ALOGV("setPreferredDevice: audio sink not init");
-        return NO_INIT;
-    }
-    return mAudioOutput->setPreferredDevice(device);
-}
-
-jobject MediaPlayer2::getRoutedDevice() {
-    Mutex::Autolock _l(mLock);
-    if (mAudioOutput == NULL) {
-        ALOGV("getRoutedDevice: audio sink not init");
-        return nullptr;
-    }
-    return mAudioOutput->getRoutedDevice();
-}
-
-status_t MediaPlayer2::addAudioDeviceCallback(jobject routingDelegate) {
-    Mutex::Autolock _l(mLock);
-    if (mAudioOutput == NULL) {
-        ALOGV("addAudioDeviceCallback: player not init");
-        return NO_INIT;
-    }
-    return mAudioOutput->addAudioDeviceCallback(routingDelegate);
-}
-
-status_t MediaPlayer2::removeAudioDeviceCallback(jobject listener) {
-    Mutex::Autolock _l(mLock);
-    if (mAudioOutput == NULL) {
-        ALOGV("addAudioDeviceCallback: player not init");
-        return NO_INIT;
-    }
-    return mAudioOutput->removeAudioDeviceCallback(listener);
-}
-
-status_t MediaPlayer2::dump(int fd, const Vector<String16>& args) {
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-    String8 result;
-    result.append(" MediaPlayer2\n");
-    snprintf(buffer, 255, "  pid(%d), looping(%s)\n", mPid, mLoop?"true": "false");
-    result.append(buffer);
-
-    sp<MediaPlayer2Interface> player;
-    sp<MediaPlayer2AudioOutput> audioOutput;
-    bool locked = false;
-    for (int i = 0; i < kDumpLockRetries; ++i) {
-        if (mLock.tryLock() == NO_ERROR) {
-            locked = true;
-            break;
-        }
-        usleep(kDumpLockSleepUs);
-    }
-
-    if (locked) {
-        player = mPlayer;
-        audioOutput = mAudioOutput;
-        mLock.unlock();
-    } else {
-        result.append("  lock is taken, no dump from player and audio output\n");
-    }
-    write(fd, result.string(), result.size());
-
-    if (player != NULL) {
-        player->dump(fd, args);
-    }
-    if (audioOutput != 0) {
-        audioOutput->dump(fd, args);
-    }
-    write(fd, "\n", 1);
-    return NO_ERROR;
-}
-
-} // namespace android
diff --git a/media/libmediaplayer2/nuplayer2/Android.bp b/media/libmediaplayer2/nuplayer2/Android.bp
deleted file mode 100644
index 0f69b2e..0000000
--- a/media/libmediaplayer2/nuplayer2/Android.bp
+++ /dev/null
@@ -1,72 +0,0 @@
-cc_library_static {
-
-    srcs: [
-        "JMediaPlayer2Utils.cpp",
-        "JWakeLock.cpp",
-        "GenericSource2.cpp",
-        "HTTPLiveSource2.cpp",
-        "NuPlayer2.cpp",
-        "NuPlayer2CCDecoder.cpp",
-        "NuPlayer2Decoder.cpp",
-        "NuPlayer2DecoderBase.cpp",
-        "NuPlayer2DecoderPassThrough.cpp",
-        "NuPlayer2Driver.cpp",
-        "NuPlayer2Drm.cpp",
-        "NuPlayer2Renderer.cpp",
-        "RTSPSource2.cpp",
-    ],
-
-    header_libs: [
-        "libbase_headers",
-        "libmediaplayer2_headers",
-        "media_plugin_headers",
-    ],
-
-    include_dirs: [
-        "frameworks/av/media/libstagefright",
-        "frameworks/av/media/libstagefright/httplive",
-        "frameworks/av/media/libstagefright/include",
-        "frameworks/av/media/libstagefright/mpeg2ts",
-        "frameworks/av/media/libstagefright/rtsp",
-        "frameworks/av/media/libstagefright/timedtext",
-        "frameworks/av/media/ndk",
-        "frameworks/base/core/jni",
-    ],
-
-    cflags: [
-        "-Werror",
-        "-Wall",
-    ],
-
-    product_variables: {
-        debuggable: {
-            cflags: [
-                "-DENABLE_STAGEFRIGHT_EXPERIMENTS",
-            ],
-        }
-    },
-
-    shared_libs: [
-        "libbinder",
-        "libui",
-        "libgui",
-        "libmedia",
-        "libmediametrics",
-        "libmediandk",
-        "libmediandk_utils",
-        "libpowermanager",
-    ],
-
-    static_libs: [
-        "libmedia_helper",
-        "libmediaplayer2-protos",
-        "libmedia2_jni_core",
-    ],
-
-    name: "libstagefright_nuplayer2",
-
-    sanitize: {
-        cfi: true,
-    },
-
-}
diff --git a/media/libmediaplayer2/nuplayer2/GenericSource2.cpp b/media/libmediaplayer2/nuplayer2/GenericSource2.cpp
deleted file mode 100644
index 9552580..0000000
--- a/media/libmediaplayer2/nuplayer2/GenericSource2.cpp
+++ /dev/null
@@ -1,1547 +0,0 @@
-/*
- * Copyright 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-//#define LOG_NDEBUG 0
-#define LOG_TAG "GenericSource2"
-
-#include "GenericSource2.h"
-#include "NuPlayer2Drm.h"
-
-#include "AnotherPacketSource.h"
-#include <cutils/properties.h>
-#include <media/DataSource.h>
-#include <media/MediaBufferHolder.h>
-#include <media/NdkWrapper.h>
-#include <media/stagefright/foundation/ABuffer.h>
-#include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/foundation/AMessage.h>
-#include <media/stagefright/MediaBuffer.h>
-#include <media/stagefright/MediaClock.h>
-#include <media/stagefright/MediaDefs.h>
-#include <media/stagefright/MetaData.h>
-#include <media/stagefright/NdkUtils.h>
-#include <media/stagefright/Utils.h>
-
-namespace android {
-
-static const int kInitialMarkMs        = 5000;  // 5secs
-
-//static const int kPausePlaybackMarkMs  = 2000;  // 2secs
-static const int kResumePlaybackMarkMs = 15000;  // 15secs
-
-NuPlayer2::GenericSource2::GenericSource2(
-        const sp<AMessage> &notify,
-        uid_t uid,
-        const sp<MediaClock> &mediaClock)
-    : Source(notify),
-      mAudioTimeUs(0),
-      mAudioLastDequeueTimeUs(0),
-      mVideoTimeUs(0),
-      mVideoLastDequeueTimeUs(0),
-      mPrevBufferPercentage(-1),
-      mPollBufferingGeneration(0),
-      mSentPauseOnBuffering(false),
-      mAudioDataGeneration(0),
-      mVideoDataGeneration(0),
-      mFetchSubtitleDataGeneration(0),
-      mFetchTimedTextDataGeneration(0),
-      mDurationUs(-1ll),
-      mAudioIsVorbis(false),
-      mIsSecure(false),
-      mIsStreaming(false),
-      mUID(uid),
-      mMediaClock(mediaClock),
-      mFd(-1),
-      mBitrate(-1ll),
-      mPendingReadBufferTypes(0) {
-    ALOGV("GenericSource2");
-    CHECK(mediaClock != NULL);
-
-    mBufferingSettings.mInitialMarkMs = kInitialMarkMs;
-    mBufferingSettings.mResumePlaybackMarkMs = kResumePlaybackMarkMs;
-    resetDataSource();
-}
-
-void NuPlayer2::GenericSource2::resetDataSource() {
-    ALOGV("resetDataSource");
-
-    mDisconnected = false;
-    mUri.clear();
-    mUriHeaders.clear();
-    if (mFd >= 0) {
-        close(mFd);
-        mFd = -1;
-    }
-    mOffset = 0;
-    mLength = 0;
-    mStarted = false;
-    mPreparing = false;
-
-    mIsDrmProtected = false;
-    mIsDrmReleased = false;
-    mIsSecure = false;
-    mMimes.clear();
-}
-
-status_t NuPlayer2::GenericSource2::setDataSource(
-        const char *url,
-        const KeyedVector<String8, String8> *headers) {
-    Mutex::Autolock _l(mLock);
-    ALOGV("setDataSource url: %s", url);
-
-    resetDataSource();
-
-    mUri = url;
-
-    if (headers) {
-        mUriHeaders = *headers;
-    }
-
-    // delay data source creation to prepareAsync() to avoid blocking
-    // the calling thread in setDataSource for any significant time.
-    return OK;
-}
-
-status_t NuPlayer2::GenericSource2::setDataSource(
-        int fd, int64_t offset, int64_t length) {
-    Mutex::Autolock _l(mLock);
-    ALOGV("setDataSource %d/%lld/%lld", fd, (long long)offset, (long long)length);
-
-    resetDataSource();
-
-    mFd = dup(fd);
-    mOffset = offset;
-    mLength = length;
-
-    // delay data source creation to prepareAsync() to avoid blocking
-    // the calling thread in setDataSource for any significant time.
-    return OK;
-}
-
-status_t NuPlayer2::GenericSource2::setDataSource(const sp<DataSource>& source) {
-    Mutex::Autolock _l(mLock);
-    ALOGV("setDataSource (source: %p)", source.get());
-
-    resetDataSource();
-    mDataSourceWrapper = new AMediaDataSourceWrapper(source);
-    return OK;
-}
-
-sp<MetaData> NuPlayer2::GenericSource2::getFileFormatMeta() const {
-    Mutex::Autolock _l(mLock);
-    return mFileMeta;
-}
-
-status_t NuPlayer2::GenericSource2::initFromDataSource() {
-    mExtractor = new AMediaExtractorWrapper(AMediaExtractor_new());
-    CHECK(mFd >=0 || mDataSourceWrapper != NULL);
-    sp<AMediaDataSourceWrapper> aSourceWrapper = mDataSourceWrapper;
-    const int fd = mFd;
-
-    mLock.unlock();
-    // This might take long time if data source is not reliable.
-    status_t err;
-    if (aSourceWrapper != NULL) {
-        err = mExtractor->setDataSource(aSourceWrapper->getAMediaDataSource());
-    } else {
-        err = mExtractor->setDataSource(fd, mOffset, mLength);
-    }
-
-    if (err != OK) {
-        ALOGE("initFromDataSource, failed to set extractor data source!");
-        mLock.lock();
-        return UNKNOWN_ERROR;
-    }
-
-    size_t numtracks = mExtractor->getTrackCount();
-    if (numtracks == 0) {
-        ALOGE("initFromDataSource, source has no track!");
-        mLock.lock();
-        return UNKNOWN_ERROR;
-    }
-
-    mFileMeta = convertMediaFormatWrapperToMetaData(mExtractor->getFormat());
-    mLock.lock();
-    if (mFileMeta != NULL) {
-        int64_t duration;
-        if (mFileMeta->findInt64(kKeyDuration, &duration)) {
-            mDurationUs = duration;
-        }
-    }
-
-    int32_t totalBitrate = 0;
-
-    mMimes.clear();
-
-    for (size_t i = 0; i < numtracks; ++i) {
-
-        sp<AMediaFormatWrapper> trackFormat = mExtractor->getTrackFormat(i);
-        if (trackFormat == NULL) {
-            ALOGE("no metadata for track %zu", i);
-            return UNKNOWN_ERROR;
-        }
-
-        sp<AMediaExtractorWrapper> trackExtractor = new AMediaExtractorWrapper(AMediaExtractor_new());
-        if (aSourceWrapper != NULL) {
-            trackExtractor->setDataSource(aSourceWrapper->getAMediaDataSource());
-        } else {
-            trackExtractor->setDataSource(fd, mOffset, mLength);
-        }
-
-        const char *mime;
-        sp<MetaData> meta = convertMediaFormatWrapperToMetaData(trackFormat);
-        CHECK(meta->findCString(kKeyMIMEType, &mime));
-
-        ALOGV("initFromDataSource track[%zu]: %s", i, mime);
-
-        // Do the string compare immediately with "mime",
-        // we can't assume "mime" would stay valid after another
-        // extractor operation, some extractors might modify meta
-        // during getTrack() and make it invalid.
-        if (!strncasecmp(mime, "audio/", 6)) {
-            if (mAudioTrack.mExtractor == NULL) {
-                mAudioTrack.mIndex = i;
-                mAudioTrack.mExtractor = trackExtractor;
-                mAudioTrack.mExtractor->selectTrack(i);
-                mAudioTrack.mPackets = new AnotherPacketSource(meta);
-
-                if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_VORBIS)) {
-                    mAudioIsVorbis = true;
-                } else {
-                    mAudioIsVorbis = false;
-                }
-
-                mMimes.add(String8(mime));
-            }
-        } else if (!strncasecmp(mime, "video/", 6)) {
-            if (mVideoTrack.mExtractor == NULL) {
-                mVideoTrack.mIndex = i;
-                mVideoTrack.mExtractor = trackExtractor;
-                mVideoTrack.mExtractor->selectTrack(i);
-                mVideoTrack.mPackets = new AnotherPacketSource(meta);
-
-                // video always at the beginning
-                mMimes.insertAt(String8(mime), 0);
-            }
-        }
-
-        mExtractors.push(trackExtractor);
-        int64_t durationUs;
-        if (meta->findInt64(kKeyDuration, &durationUs)) {
-            if (durationUs > mDurationUs) {
-                mDurationUs = durationUs;
-            }
-        }
-
-        int32_t bitrate;
-        if (totalBitrate >= 0 && meta->findInt32(kKeyBitRate, &bitrate)) {
-            totalBitrate += bitrate;
-        } else {
-            totalBitrate = -1;
-        }
-    }
-
-    ALOGV("initFromDataSource mExtractors.size(): %zu  mIsSecure: %d  mime[0]: %s", mExtractors.size(),
-            mIsSecure, (mMimes.isEmpty() ? "NONE" : mMimes[0].string()));
-
-    if (mExtractors.size() == 0) {
-        ALOGE("b/23705695");
-        return UNKNOWN_ERROR;
-    }
-
-    // Modular DRM: The return value doesn't affect source initialization.
-    (void)checkDrmInfo();
-
-    mBitrate = totalBitrate;
-
-    return OK;
-}
-
-status_t NuPlayer2::GenericSource2::getBufferingSettings(
-        BufferingSettings* buffering /* nonnull */) {
-    {
-        Mutex::Autolock _l(mLock);
-        *buffering = mBufferingSettings;
-    }
-
-    ALOGV("getBufferingSettings{%s}", buffering->toString().string());
-    return OK;
-}
-
-status_t NuPlayer2::GenericSource2::setBufferingSettings(const BufferingSettings& buffering) {
-    ALOGV("setBufferingSettings{%s}", buffering.toString().string());
-
-    Mutex::Autolock _l(mLock);
-    mBufferingSettings = buffering;
-    return OK;
-}
-
-int64_t NuPlayer2::GenericSource2::getLastReadPosition() {
-    if (mAudioTrack.mExtractor != NULL) {
-        return mAudioTimeUs;
-    } else if (mVideoTrack.mExtractor != NULL) {
-        return mVideoTimeUs;
-    } else {
-        return 0;
-    }
-}
-
-bool NuPlayer2::GenericSource2::isStreaming() const {
-    Mutex::Autolock _l(mLock);
-    return mIsStreaming;
-}
-
-NuPlayer2::GenericSource2::~GenericSource2() {
-    ALOGV("~GenericSource2");
-    if (mLooper != NULL) {
-        mLooper->unregisterHandler(id());
-        mLooper->stop();
-    }
-    if (mDataSourceWrapper != NULL) {
-        mDataSourceWrapper->close();
-    }
-    resetDataSource();
-}
-
-void NuPlayer2::GenericSource2::prepareAsync(int64_t startTimeUs) {
-    Mutex::Autolock _l(mLock);
-    ALOGV("prepareAsync: (looper: %d)", (mLooper != NULL));
-
-    if (mLooper == NULL) {
-        mLooper = new ALooper;
-        mLooper->setName("generic2");
-        mLooper->start(false, /* runOnCallingThread */
-                       true,  /* canCallJava */
-                       PRIORITY_DEFAULT);
-
-        mLooper->registerHandler(this);
-    }
-
-    sp<AMessage> msg = new AMessage(kWhatPrepareAsync, this);
-    msg->setInt64("startTimeUs", startTimeUs);
-
-    msg->post();
-}
-
-void NuPlayer2::GenericSource2::onPrepareAsync(int64_t startTimeUs) {
-    ALOGV("onPrepareAsync: mFd %d mUri %s mDataSourceWrapper: %p",
-            mFd, mUri.c_str(), mDataSourceWrapper.get());
-
-    if (!mUri.empty()) {
-        const char* uri = mUri.c_str();
-        size_t numheaders = mUriHeaders.size();
-        const char **key_values = numheaders ? new const char *[numheaders * 2] : NULL;
-        for (size_t i = 0; i < numheaders; ++i) {
-            key_values[i * 2] = mUriHeaders.keyAt(i).c_str();
-            key_values[i * 2 + 1] =  mUriHeaders.valueAt(i).c_str();
-        }
-        mLock.unlock();
-        AMediaDataSource *aSource = AMediaDataSource_newUri(uri, numheaders, key_values);
-        mLock.lock();
-        mDataSourceWrapper = aSource ? new AMediaDataSourceWrapper(aSource) : NULL;
-        delete[] key_values;
-        // For cached streaming cases, we need to wait for enough
-        // buffering before reporting prepared.
-        mIsStreaming = !strncasecmp("http://", uri, 7) || !strncasecmp("https://", uri, 8);
-    }
-
-    if (mDisconnected || (mFd < 0 && mDataSourceWrapper == NULL)) {
-        ALOGE("mDisconnected(%d) or Failed to create data source!", mDisconnected);
-        notifyPreparedAndCleanup(UNKNOWN_ERROR);
-        return;
-    }
-
-    // init extractor from data source
-    status_t err = initFromDataSource();
-    if (mFd >= 0) {
-        close(mFd);
-        mFd = -1;
-    }
-
-    if (err != OK) {
-        ALOGE("Failed to init from data source!");
-        notifyPreparedAndCleanup(err);
-        return;
-    }
-
-    if (mVideoTrack.mExtractor != NULL) {
-        sp<MetaData> meta = getFormatMeta_l(false /* audio */);
-        sp<AMessage> msg = new AMessage;
-        err = convertMetaDataToMessage(meta, &msg);
-        if(err != OK) {
-            notifyPreparedAndCleanup(err);
-            return;
-        }
-        notifyVideoSizeChanged(msg);
-    }
-
-    notifyFlagsChanged(
-            // FLAG_SECURE will be known if/when prepareDrm is called by the app
-            // FLAG_PROTECTED will be known if/when prepareDrm is called by the app
-            FLAG_CAN_PAUSE |
-            FLAG_CAN_SEEK_BACKWARD |
-            FLAG_CAN_SEEK_FORWARD |
-            FLAG_CAN_SEEK);
-
-    doSeek(startTimeUs, MediaPlayer2SeekMode::SEEK_CLOSEST);
-    finishPrepareAsync();
-
-    ALOGV("onPrepareAsync: Done");
-}
-
-void NuPlayer2::GenericSource2::finishPrepareAsync() {
-    ALOGV("finishPrepareAsync");
-
-    if (mIsStreaming) {
-        mPreparing = true;
-        ++mPollBufferingGeneration;
-        schedulePollBuffering();
-    } else {
-        notifyPrepared();
-    }
-
-    if (mAudioTrack.mExtractor != NULL) {
-        postReadBuffer(MEDIA_TRACK_TYPE_AUDIO);
-    }
-
-    if (mVideoTrack.mExtractor != NULL) {
-        postReadBuffer(MEDIA_TRACK_TYPE_VIDEO);
-    }
-}
-
-void NuPlayer2::GenericSource2::notifyPreparedAndCleanup(status_t err) {
-    if (err != OK) {
-        mDataSourceWrapper.clear();
-
-        mBitrate = -1;
-        mPrevBufferPercentage = -1;
-        ++mPollBufferingGeneration;
-    }
-    notifyPrepared(err);
-}
-
-void NuPlayer2::GenericSource2::start() {
-    Mutex::Autolock _l(mLock);
-    ALOGI("start");
-
-    if (mAudioTrack.mExtractor != NULL) {
-        postReadBuffer(MEDIA_TRACK_TYPE_AUDIO);
-    }
-
-    if (mVideoTrack.mExtractor != NULL) {
-        postReadBuffer(MEDIA_TRACK_TYPE_VIDEO);
-    }
-
-    mStarted = true;
-}
-
-void NuPlayer2::GenericSource2::stop() {
-    Mutex::Autolock _l(mLock);
-    mStarted = false;
-}
-
-void NuPlayer2::GenericSource2::pause() {
-    Mutex::Autolock _l(mLock);
-    mStarted = false;
-}
-
-void NuPlayer2::GenericSource2::resume() {
-    Mutex::Autolock _l(mLock);
-    mStarted = true;
-}
-
-void NuPlayer2::GenericSource2::disconnect() {
-    {
-        Mutex::Autolock _l(mLock);
-        mDisconnected = true;
-    }
-    if (mDataSourceWrapper != NULL) {
-        mDataSourceWrapper->close();
-    }
-}
-
-status_t NuPlayer2::GenericSource2::feedMoreTSData() {
-    return OK;
-}
-
-void NuPlayer2::GenericSource2::onMessageReceived(const sp<AMessage> &msg) {
-    Mutex::Autolock _l(mLock);
-    switch (msg->what()) {
-      case kWhatPrepareAsync:
-      {
-          int64_t startTimeUs;
-          CHECK(msg->findInt64("startTimeUs", &startTimeUs));
-          onPrepareAsync(startTimeUs);
-          break;
-      }
-      case kWhatFetchSubtitleData:
-      {
-          fetchTextData(kWhatSendSubtitleData, MEDIA_TRACK_TYPE_SUBTITLE,
-                  mFetchSubtitleDataGeneration, mSubtitleTrack.mPackets, msg);
-          break;
-      }
-
-      case kWhatFetchTimedTextData:
-      {
-          fetchTextData(kWhatSendTimedTextData, MEDIA_TRACK_TYPE_TIMEDTEXT,
-                  mFetchTimedTextDataGeneration, mTimedTextTrack.mPackets, msg);
-          break;
-      }
-
-      case kWhatSendSubtitleData:
-      {
-          sendTextData(kWhatSubtitleData, MEDIA_TRACK_TYPE_SUBTITLE,
-                  mFetchSubtitleDataGeneration, mSubtitleTrack.mPackets, msg);
-          break;
-      }
-
-      case kWhatSendGlobalTimedTextData:
-      {
-          sendGlobalTextData(kWhatTimedTextData, mFetchTimedTextDataGeneration, msg);
-          break;
-      }
-      case kWhatSendTimedTextData:
-      {
-          sendTextData(kWhatTimedTextData, MEDIA_TRACK_TYPE_TIMEDTEXT,
-                  mFetchTimedTextDataGeneration, mTimedTextTrack.mPackets, msg);
-          break;
-      }
-
-      case kWhatChangeAVSource:
-      {
-          int32_t trackIndex;
-          CHECK(msg->findInt32("trackIndex", &trackIndex));
-          const sp<AMediaExtractorWrapper> extractor = mExtractors.itemAt(trackIndex);
-
-          Track* track;
-          AString mime;
-          media_track_type trackType, counterpartType;
-          sp<AMediaFormatWrapper> format = extractor->getTrackFormat(trackIndex);
-          format->getString(AMEDIAFORMAT_KEY_MIME, &mime);
-          if (!strncasecmp(mime.c_str(), "audio/", 6)) {
-              track = &mAudioTrack;
-              trackType = MEDIA_TRACK_TYPE_AUDIO;
-              counterpartType = MEDIA_TRACK_TYPE_VIDEO;;
-          } else {
-              CHECK(!strncasecmp(mime.c_str(), "video/", 6));
-              track = &mVideoTrack;
-              trackType = MEDIA_TRACK_TYPE_VIDEO;
-              counterpartType = MEDIA_TRACK_TYPE_AUDIO;;
-          }
-
-
-          track->mExtractor = extractor;
-          track->mExtractor->selectSingleTrack(trackIndex);
-          track->mIndex = trackIndex;
-          ++mAudioDataGeneration;
-          ++mVideoDataGeneration;
-
-          int64_t timeUs, actualTimeUs;
-          const bool formatChange = true;
-          if (trackType == MEDIA_TRACK_TYPE_AUDIO) {
-              timeUs = mAudioLastDequeueTimeUs;
-          } else {
-              timeUs = mVideoLastDequeueTimeUs;
-          }
-          readBuffer(trackType, timeUs, MediaPlayer2SeekMode::SEEK_PREVIOUS_SYNC /* mode */,
-                  &actualTimeUs, formatChange);
-          readBuffer(counterpartType, -1, MediaPlayer2SeekMode::SEEK_PREVIOUS_SYNC /* mode */,
-                  NULL, !formatChange);
-          ALOGV("timeUs %lld actualTimeUs %lld", (long long)timeUs, (long long)actualTimeUs);
-
-          break;
-      }
-
-      case kWhatSeek:
-      {
-          onSeek(msg);
-          break;
-      }
-
-      case kWhatReadBuffer:
-      {
-          onReadBuffer(msg);
-          break;
-      }
-
-      case kWhatPollBuffering:
-      {
-          int32_t generation;
-          CHECK(msg->findInt32("generation", &generation));
-          if (generation == mPollBufferingGeneration) {
-              onPollBuffering();
-          }
-          break;
-      }
-
-      default:
-          Source::onMessageReceived(msg);
-          break;
-    }
-}
-
-void NuPlayer2::GenericSource2::fetchTextData(
-        uint32_t sendWhat,
-        media_track_type type,
-        int32_t curGen,
-        const sp<AnotherPacketSource>& packets,
-        const sp<AMessage>& msg) {
-    int32_t msgGeneration;
-    CHECK(msg->findInt32("generation", &msgGeneration));
-    if (msgGeneration != curGen) {
-        // stale
-        return;
-    }
-
-    int32_t avail;
-    if (packets->hasBufferAvailable(&avail)) {
-        return;
-    }
-
-    int64_t timeUs;
-    CHECK(msg->findInt64("timeUs", &timeUs));
-
-    int64_t subTimeUs = 0;
-    readBuffer(type, timeUs, MediaPlayer2SeekMode::SEEK_PREVIOUS_SYNC /* mode */, &subTimeUs);
-
-    status_t eosResult;
-    if (!packets->hasBufferAvailable(&eosResult)) {
-        return;
-    }
-
-    if (msg->what() == kWhatFetchSubtitleData) {
-        subTimeUs -= 1000000ll;  // send subtile data one second earlier
-    }
-    sp<AMessage> msg2 = new AMessage(sendWhat, this);
-    msg2->setInt32("generation", msgGeneration);
-    mMediaClock->addTimer(msg2, subTimeUs);
-}
-
-void NuPlayer2::GenericSource2::sendTextData(
-        uint32_t what,
-        media_track_type type,
-        int32_t curGen,
-        const sp<AnotherPacketSource>& packets,
-        const sp<AMessage>& msg) {
-    int32_t msgGeneration;
-    CHECK(msg->findInt32("generation", &msgGeneration));
-    if (msgGeneration != curGen) {
-        // stale
-        return;
-    }
-
-    int64_t subTimeUs;
-    if (packets->nextBufferTime(&subTimeUs) != OK) {
-        return;
-    }
-
-    int64_t nextSubTimeUs;
-    readBuffer(type, -1, MediaPlayer2SeekMode::SEEK_PREVIOUS_SYNC /* mode */, &nextSubTimeUs);
-
-    sp<ABuffer> buffer;
-    status_t dequeueStatus = packets->dequeueAccessUnit(&buffer);
-    if (dequeueStatus == OK) {
-        sp<AMessage> notify = dupNotify();
-        notify->setInt32("what", what);
-        notify->setBuffer("buffer", buffer);
-        notify->post();
-
-        if (msg->what() == kWhatSendSubtitleData) {
-            nextSubTimeUs -= 1000000ll;  // send subtile data one second earlier
-        }
-        mMediaClock->addTimer(msg, nextSubTimeUs);
-    }
-}
-
-void NuPlayer2::GenericSource2::sendGlobalTextData(
-        uint32_t what,
-        int32_t curGen,
-        sp<AMessage> msg) {
-    int32_t msgGeneration;
-    CHECK(msg->findInt32("generation", &msgGeneration));
-    if (msgGeneration != curGen) {
-        // stale
-        return;
-    }
-
-    void *data = NULL;
-    size_t size = 0;
-    if (mTimedTextTrack.mExtractor->getTrackFormat(mTimedTextTrack.mIndex)->getBuffer(
-                    "text", &data, &size)) {
-        mGlobalTimedText = new ABuffer(size);
-        if (mGlobalTimedText->data()) {
-            memcpy(mGlobalTimedText->data(), data, size);
-            sp<AMessage> globalMeta = mGlobalTimedText->meta();
-            globalMeta->setInt64("timeUs", 0);
-            globalMeta->setString("mime", MEDIA_MIMETYPE_TEXT_3GPP);
-            globalMeta->setInt32("global", 1);
-            sp<AMessage> notify = dupNotify();
-            notify->setInt32("what", what);
-            notify->setBuffer("buffer", mGlobalTimedText);
-            notify->post();
-        }
-    }
-}
-
-sp<AMessage> NuPlayer2::GenericSource2::getFormat(bool audio) {
-    Mutex::Autolock _l(mLock);
-    return getFormat_l(audio);
-}
-
-sp<MetaData> NuPlayer2::GenericSource2::getFormatMeta(bool audio) {
-    Mutex::Autolock _l(mLock);
-    return getFormatMeta_l(audio);
-}
-
-sp<AMessage> NuPlayer2::GenericSource2::getFormat_l(bool audio) {
-    sp<AMediaExtractorWrapper> extractor = audio ? mAudioTrack.mExtractor : mVideoTrack.mExtractor;
-    size_t trackIndex = audio ? mAudioTrack.mIndex : mVideoTrack.mIndex;
-
-    if (extractor == NULL) {
-        return NULL;
-    }
-
-    return extractor->getTrackFormat(trackIndex)->toAMessage();
-}
-
-sp<MetaData> NuPlayer2::GenericSource2::getFormatMeta_l(bool audio) {
-    sp<AMediaExtractorWrapper> extractor = audio ? mAudioTrack.mExtractor : mVideoTrack.mExtractor;
-    size_t trackIndex = audio ? mAudioTrack.mIndex : mVideoTrack.mIndex;
-
-    if (extractor == NULL) {
-        return NULL;
-    }
-
-    return convertMediaFormatWrapperToMetaData(extractor->getTrackFormat(trackIndex));
-}
-
-status_t NuPlayer2::GenericSource2::dequeueAccessUnit(
-        bool audio, sp<ABuffer> *accessUnit) {
-    Mutex::Autolock _l(mLock);
-    // If has gone through stop/releaseDrm sequence, we no longer send down any buffer b/c
-    // the codec's crypto object has gone away (b/37960096).
-    // Note: This will be unnecessary when stop() changes behavior and releases codec (b/35248283).
-    if (!mStarted && mIsDrmReleased) {
-        return -EWOULDBLOCK;
-    }
-
-    Track *track = audio ? &mAudioTrack : &mVideoTrack;
-
-    if (track->mExtractor == NULL) {
-        return -EWOULDBLOCK;
-    }
-
-    status_t finalResult;
-    if (!track->mPackets->hasBufferAvailable(&finalResult)) {
-        if (finalResult == OK) {
-            postReadBuffer(
-                    audio ? MEDIA_TRACK_TYPE_AUDIO : MEDIA_TRACK_TYPE_VIDEO);
-            return -EWOULDBLOCK;
-        }
-        return finalResult;
-    }
-
-    status_t result = track->mPackets->dequeueAccessUnit(accessUnit);
-
-    // start pulling in more buffers if cache is running low
-    // so that decoder has less chance of being starved
-    if (!mIsStreaming) {
-        if (track->mPackets->getAvailableBufferCount(&finalResult) < 2) {
-            postReadBuffer(audio? MEDIA_TRACK_TYPE_AUDIO : MEDIA_TRACK_TYPE_VIDEO);
-        }
-    } else {
-        int64_t durationUs = track->mPackets->getBufferedDurationUs(&finalResult);
-        // TODO: maxRebufferingMarkMs could be larger than
-        // mBufferingSettings.mResumePlaybackMarkMs
-        int64_t restartBufferingMarkUs =
-             mBufferingSettings.mResumePlaybackMarkMs * 1000ll / 2;
-        if (finalResult == OK) {
-            if (durationUs < restartBufferingMarkUs) {
-                postReadBuffer(audio? MEDIA_TRACK_TYPE_AUDIO : MEDIA_TRACK_TYPE_VIDEO);
-            }
-            if (track->mPackets->getAvailableBufferCount(&finalResult) < 2
-                && !mSentPauseOnBuffering && !mPreparing) {
-                mSentPauseOnBuffering = true;
-                sp<AMessage> notify = dupNotify();
-                notify->setInt32("what", kWhatPauseOnBufferingStart);
-                notify->post();
-            }
-        }
-    }
-
-    if (result != OK) {
-        if (mSubtitleTrack.mExtractor != NULL) {
-            mSubtitleTrack.mPackets->clear();
-            mFetchSubtitleDataGeneration++;
-        }
-        if (mTimedTextTrack.mExtractor != NULL) {
-            mTimedTextTrack.mPackets->clear();
-            mFetchTimedTextDataGeneration++;
-        }
-        return result;
-    }
-
-    int64_t timeUs;
-    status_t eosResult; // ignored
-    CHECK((*accessUnit)->meta()->findInt64("timeUs", &timeUs));
-    if (audio) {
-        mAudioLastDequeueTimeUs = timeUs;
-    } else {
-        mVideoLastDequeueTimeUs = timeUs;
-    }
-
-    if (mSubtitleTrack.mExtractor != NULL
-            && !mSubtitleTrack.mPackets->hasBufferAvailable(&eosResult)) {
-        sp<AMessage> msg = new AMessage(kWhatFetchSubtitleData, this);
-        msg->setInt64("timeUs", timeUs);
-        msg->setInt32("generation", mFetchSubtitleDataGeneration);
-        msg->post();
-    }
-
-    if (mTimedTextTrack.mExtractor != NULL
-            && !mTimedTextTrack.mPackets->hasBufferAvailable(&eosResult)) {
-        sp<AMessage> msg = new AMessage(kWhatFetchTimedTextData, this);
-        msg->setInt64("timeUs", timeUs);
-        msg->setInt32("generation", mFetchTimedTextDataGeneration);
-        msg->post();
-    }
-
-    return result;
-}
-
-status_t NuPlayer2::GenericSource2::getDuration(int64_t *durationUs) {
-    Mutex::Autolock _l(mLock);
-    *durationUs = mDurationUs;
-    return OK;
-}
-
-size_t NuPlayer2::GenericSource2::getTrackCount() const {
-    Mutex::Autolock _l(mLock);
-    return mExtractors.size();
-}
-
-sp<AMessage> NuPlayer2::GenericSource2::getTrackInfo(size_t trackIndex) const {
-    Mutex::Autolock _l(mLock);
-    size_t trackCount = mExtractors.size();
-    if (trackIndex >= trackCount) {
-        return NULL;
-    }
-
-    sp<AMessage> format = mExtractors.itemAt(trackIndex)->getTrackFormat(trackIndex)->toAMessage();
-    if (format == NULL) {
-        ALOGE("no metadata for track %zu", trackIndex);
-        return NULL;
-    }
-
-    AString mime;
-    CHECK(format->findString(AMEDIAFORMAT_KEY_MIME, &mime));
-
-    int32_t trackType;
-    if (!strncasecmp(mime.c_str(), "video/", 6)) {
-        trackType = MEDIA_TRACK_TYPE_VIDEO;
-    } else if (!strncasecmp(mime.c_str(), "audio/", 6)) {
-        trackType = MEDIA_TRACK_TYPE_AUDIO;
-    } else if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_TEXT_3GPP)) {
-        trackType = MEDIA_TRACK_TYPE_TIMEDTEXT;
-    } else {
-        trackType = MEDIA_TRACK_TYPE_UNKNOWN;
-    }
-    format->setInt32("type", trackType);
-
-    AString lang;
-    if (!format->findString("language", &lang)) {
-        format->setString("language", "und");
-    }
-
-    if (trackType == MEDIA_TRACK_TYPE_SUBTITLE) {
-        int32_t isAutoselect = 1, isDefault = 0, isForced = 0;
-        format->findInt32(AMEDIAFORMAT_KEY_IS_AUTOSELECT, &isAutoselect);
-        format->findInt32(AMEDIAFORMAT_KEY_IS_DEFAULT, &isDefault);
-        format->findInt32(AMEDIAFORMAT_KEY_IS_FORCED_SUBTITLE, &isForced);
-
-        format->setInt32("auto", !!isAutoselect);
-        format->setInt32("default", !!isDefault);
-        format->setInt32("forced", !!isForced);
-    }
-
-    return format;
-}
-
-ssize_t NuPlayer2::GenericSource2::getSelectedTrack(media_track_type type) const {
-    Mutex::Autolock _l(mLock);
-    const Track *track = NULL;
-    switch (type) {
-    case MEDIA_TRACK_TYPE_VIDEO:
-        track = &mVideoTrack;
-        break;
-    case MEDIA_TRACK_TYPE_AUDIO:
-        track = &mAudioTrack;
-        break;
-    case MEDIA_TRACK_TYPE_TIMEDTEXT:
-        track = &mTimedTextTrack;
-        break;
-    case MEDIA_TRACK_TYPE_SUBTITLE:
-        track = &mSubtitleTrack;
-        break;
-    default:
-        break;
-    }
-
-    if (track != NULL && track->mExtractor != NULL) {
-        return track->mIndex;
-    }
-
-    return -1;
-}
-
-status_t NuPlayer2::GenericSource2::selectTrack(size_t trackIndex, bool select, int64_t timeUs) {
-    Mutex::Autolock _l(mLock);
-    ALOGV("%s track: %zu", select ? "select" : "deselect", trackIndex);
-
-    if (trackIndex >= mExtractors.size()) {
-        return BAD_INDEX;
-    }
-
-    if (!select) {
-        Track* track = NULL;
-        if (mSubtitleTrack.mExtractor != NULL && trackIndex == mSubtitleTrack.mIndex) {
-            track = &mSubtitleTrack;
-            mFetchSubtitleDataGeneration++;
-        } else if (mTimedTextTrack.mExtractor != NULL && trackIndex == mTimedTextTrack.mIndex) {
-            track = &mTimedTextTrack;
-            mFetchTimedTextDataGeneration++;
-        }
-        if (track == NULL) {
-            return INVALID_OPERATION;
-        }
-        track->mExtractor = NULL;
-        track->mPackets->clear();
-        return OK;
-    }
-
-    const sp<AMediaExtractorWrapper> extractor = mExtractors.itemAt(trackIndex);
-    sp<MetaData> meta = convertMediaFormatWrapperToMetaData(extractor->getTrackFormat(trackIndex));
-    const char *mime;
-    CHECK(meta->findCString(kKeyMIMEType, &mime));
-    if (!strncasecmp(mime, "text/", 5)) {
-        bool isSubtitle = strcasecmp(mime, MEDIA_MIMETYPE_TEXT_3GPP);
-        Track *track = isSubtitle ? &mSubtitleTrack : &mTimedTextTrack;
-        if (track->mExtractor != NULL && track->mIndex == trackIndex) {
-            return OK;
-        }
-        track->mIndex = trackIndex;
-        track->mExtractor = mExtractors.itemAt(trackIndex);
-        track->mExtractor->selectSingleTrack(trackIndex);
-        if (track->mPackets == NULL) {
-            track->mPackets = new AnotherPacketSource(meta);
-        } else {
-            track->mPackets->clear();
-            track->mPackets->setFormat(meta);
-
-        }
-
-        if (isSubtitle) {
-            mFetchSubtitleDataGeneration++;
-        } else {
-            mFetchTimedTextDataGeneration++;
-        }
-
-        status_t eosResult; // ignored
-        if (mSubtitleTrack.mExtractor != NULL
-                && !mSubtitleTrack.mPackets->hasBufferAvailable(&eosResult)) {
-            sp<AMessage> msg = new AMessage(kWhatFetchSubtitleData, this);
-            msg->setInt64("timeUs", timeUs);
-            msg->setInt32("generation", mFetchSubtitleDataGeneration);
-            msg->post();
-        }
-
-        sp<AMessage> msg2 = new AMessage(kWhatSendGlobalTimedTextData, this);
-        msg2->setInt32("generation", mFetchTimedTextDataGeneration);
-        msg2->post();
-
-        if (mTimedTextTrack.mExtractor != NULL
-                && !mTimedTextTrack.mPackets->hasBufferAvailable(&eosResult)) {
-            sp<AMessage> msg = new AMessage(kWhatFetchTimedTextData, this);
-            msg->setInt64("timeUs", timeUs);
-            msg->setInt32("generation", mFetchTimedTextDataGeneration);
-            msg->post();
-        }
-
-        return OK;
-    } else if (!strncasecmp(mime, "audio/", 6) || !strncasecmp(mime, "video/", 6)) {
-        bool audio = !strncasecmp(mime, "audio/", 6);
-        Track *track = audio ? &mAudioTrack : &mVideoTrack;
-        if (track->mExtractor != NULL && track->mIndex == trackIndex) {
-            return OK;
-        }
-
-        sp<AMessage> msg = new AMessage(kWhatChangeAVSource, this);
-        msg->setInt32("trackIndex", trackIndex);
-        msg->post();
-        return OK;
-    }
-
-    return INVALID_OPERATION;
-}
-
-status_t NuPlayer2::GenericSource2::seekTo(int64_t seekTimeUs, MediaPlayer2SeekMode mode) {
-    ALOGV("seekTo: %lld, %d", (long long)seekTimeUs, mode);
-    sp<AMessage> msg = new AMessage(kWhatSeek, this);
-    msg->setInt64("seekTimeUs", seekTimeUs);
-    msg->setInt32("mode", mode);
-
-    // Need to call readBuffer on |mLooper| to ensure the calls to
-    // IMediaSource::read* are serialized. Note that IMediaSource::read*
-    // is called without |mLock| acquired and MediaSource is not thread safe.
-    sp<AMessage> response;
-    status_t err = msg->postAndAwaitResponse(&response);
-    if (err == OK && response != NULL) {
-        CHECK(response->findInt32("err", &err));
-    }
-
-    return err;
-}
-
-void NuPlayer2::GenericSource2::onSeek(const sp<AMessage>& msg) {
-    int64_t seekTimeUs;
-    int32_t mode;
-    CHECK(msg->findInt64("seekTimeUs", &seekTimeUs));
-    CHECK(msg->findInt32("mode", &mode));
-
-    sp<AMessage> response = new AMessage;
-    status_t err = doSeek(seekTimeUs, (MediaPlayer2SeekMode)mode);
-    response->setInt32("err", err);
-
-    sp<AReplyToken> replyID;
-    CHECK(msg->senderAwaitsResponse(&replyID));
-    response->postReply(replyID);
-}
-
-status_t NuPlayer2::GenericSource2::doSeek(int64_t seekTimeUs, MediaPlayer2SeekMode mode) {
-    if (mVideoTrack.mExtractor != NULL) {
-        ++mVideoDataGeneration;
-
-        int64_t actualTimeUs;
-        readBuffer(MEDIA_TRACK_TYPE_VIDEO, seekTimeUs, mode, &actualTimeUs);
-
-        if (mode != MediaPlayer2SeekMode::SEEK_CLOSEST) {
-            seekTimeUs = actualTimeUs;
-        }
-        mVideoLastDequeueTimeUs = actualTimeUs;
-    }
-
-    if (mAudioTrack.mExtractor != NULL) {
-        ++mAudioDataGeneration;
-        readBuffer(MEDIA_TRACK_TYPE_AUDIO, seekTimeUs, MediaPlayer2SeekMode::SEEK_CLOSEST);
-        mAudioLastDequeueTimeUs = seekTimeUs;
-    }
-
-    if (mSubtitleTrack.mExtractor != NULL) {
-        mSubtitleTrack.mPackets->clear();
-        mFetchSubtitleDataGeneration++;
-    }
-
-    if (mTimedTextTrack.mExtractor != NULL) {
-        mTimedTextTrack.mPackets->clear();
-        mFetchTimedTextDataGeneration++;
-    }
-
-    ++mPollBufferingGeneration;
-    schedulePollBuffering();
-    return OK;
-}
-
-sp<ABuffer> NuPlayer2::GenericSource2::mediaBufferToABuffer(
-        MediaBufferBase* mb,
-        media_track_type trackType) {
-    bool audio = trackType == MEDIA_TRACK_TYPE_AUDIO;
-    size_t outLength = mb->range_length();
-
-    if (audio && mAudioIsVorbis) {
-        outLength += sizeof(int32_t);
-    }
-
-    sp<ABuffer> ab;
-
-    if (mIsDrmProtected)   {
-        // Modular DRM
-        // Enabled for both video/audio so 1) media buffer is reused without extra copying
-        // 2) meta data can be retrieved in onInputBufferFetched for calling queueSecureInputBuffer.
-
-        // data is already provided in the buffer
-        ab = new ABuffer(NULL, mb->range_length());
-        ab->meta()->setObject("mediaBufferHolder", new MediaBufferHolder(mb));
-
-        // Modular DRM: Required b/c of the above add_ref.
-        // If ref>0, there must be an observer, or it'll crash at release().
-        // TODO: MediaBuffer might need to be revised to ease such need.
-        mb->setObserver(this);
-        // setMediaBufferBase() interestingly doesn't increment the ref count on its own.
-        // Extra increment (since we want to keep mb alive and attached to ab beyond this function
-        // call. This is to counter the effect of mb->release() towards the end.
-        mb->add_ref();
-
-    } else {
-        ab = new ABuffer(outLength);
-        memcpy(ab->data(),
-               (const uint8_t *)mb->data() + mb->range_offset(),
-               mb->range_length());
-    }
-
-    if (audio && mAudioIsVorbis) {
-        int32_t numPageSamples;
-        if (!mb->meta_data().findInt32(kKeyValidSamples, &numPageSamples)) {
-            numPageSamples = -1;
-        }
-
-        uint8_t* abEnd = ab->data() + mb->range_length();
-        memcpy(abEnd, &numPageSamples, sizeof(numPageSamples));
-    }
-
-    sp<AMessage> meta = ab->meta();
-
-    int64_t timeUs;
-    CHECK(mb->meta_data().findInt64(kKeyTime, &timeUs));
-    meta->setInt64("timeUs", timeUs);
-
-    if (trackType == MEDIA_TRACK_TYPE_VIDEO) {
-        int32_t layerId;
-        if (mb->meta_data().findInt32(kKeyTemporalLayerId, &layerId)) {
-            meta->setInt32("temporal-layer-id", layerId);
-        }
-    }
-
-    if (trackType == MEDIA_TRACK_TYPE_TIMEDTEXT) {
-        AString mime;
-        sp<AMediaExtractorWrapper> extractor = mTimedTextTrack.mExtractor;
-        size_t trackIndex = mTimedTextTrack.mIndex;
-        CHECK(extractor != NULL
-                && extractor->getTrackFormat(trackIndex)->getString(AMEDIAFORMAT_KEY_MIME, &mime));
-        meta->setString("mime", mime.c_str());
-    }
-
-    int64_t durationUs;
-    if (mb->meta_data().findInt64(kKeyDuration, &durationUs)) {
-        meta->setInt64("durationUs", durationUs);
-    }
-
-    if (trackType == MEDIA_TRACK_TYPE_SUBTITLE) {
-        meta->setInt32(AMEDIAFORMAT_KEY_TRACK_INDEX, mSubtitleTrack.mIndex);
-    }
-
-    uint32_t dataType; // unused
-    const void *seiData;
-    size_t seiLength;
-    if (mb->meta_data().findData(kKeySEI, &dataType, &seiData, &seiLength)) {
-        sp<ABuffer> sei = ABuffer::CreateAsCopy(seiData, seiLength);;
-        meta->setBuffer("sei", sei);
-    }
-
-    const void *mpegUserDataPointer;
-    size_t mpegUserDataLength;
-    if (mb->meta_data().findData(
-            kKeyMpegUserData, &dataType, &mpegUserDataPointer, &mpegUserDataLength)) {
-        sp<ABuffer> mpegUserData = ABuffer::CreateAsCopy(mpegUserDataPointer, mpegUserDataLength);
-        meta->setBuffer(AMEDIAFORMAT_KEY_MPEG_USER_DATA, mpegUserData);
-    }
-
-    mb->release();
-    mb = NULL;
-
-    return ab;
-}
-
-int32_t NuPlayer2::GenericSource2::getDataGeneration(media_track_type type) const {
-    int32_t generation = -1;
-    switch (type) {
-    case MEDIA_TRACK_TYPE_VIDEO:
-        generation = mVideoDataGeneration;
-        break;
-    case MEDIA_TRACK_TYPE_AUDIO:
-        generation = mAudioDataGeneration;
-        break;
-    case MEDIA_TRACK_TYPE_TIMEDTEXT:
-        generation = mFetchTimedTextDataGeneration;
-        break;
-    case MEDIA_TRACK_TYPE_SUBTITLE:
-        generation = mFetchSubtitleDataGeneration;
-        break;
-    default:
-        break;
-    }
-
-    return generation;
-}
-
-void NuPlayer2::GenericSource2::postReadBuffer(media_track_type trackType) {
-    if ((mPendingReadBufferTypes & (1 << trackType)) == 0) {
-        mPendingReadBufferTypes |= (1 << trackType);
-        sp<AMessage> msg = new AMessage(kWhatReadBuffer, this);
-        msg->setInt32("trackType", trackType);
-        msg->post();
-    }
-}
-
-void NuPlayer2::GenericSource2::onReadBuffer(const sp<AMessage>& msg) {
-    int32_t tmpType;
-    CHECK(msg->findInt32("trackType", &tmpType));
-    media_track_type trackType = (media_track_type)tmpType;
-    mPendingReadBufferTypes &= ~(1 << trackType);
-    readBuffer(trackType);
-}
-
-void NuPlayer2::GenericSource2::readBuffer(
-        media_track_type trackType, int64_t seekTimeUs, MediaPlayer2SeekMode mode,
-        int64_t *actualTimeUs, bool formatChange) {
-    Track *track;
-    size_t maxBuffers = 1;
-    switch (trackType) {
-        case MEDIA_TRACK_TYPE_VIDEO:
-            track = &mVideoTrack;
-            maxBuffers = 8;  // too large of a number may influence seeks
-            break;
-        case MEDIA_TRACK_TYPE_AUDIO:
-            track = &mAudioTrack;
-            maxBuffers = 64;
-            break;
-        case MEDIA_TRACK_TYPE_SUBTITLE:
-            track = &mSubtitleTrack;
-            break;
-        case MEDIA_TRACK_TYPE_TIMEDTEXT:
-            track = &mTimedTextTrack;
-            break;
-        default:
-            TRESPASS();
-    }
-
-    if (track->mExtractor == NULL) {
-        return;
-    }
-
-    if (actualTimeUs) {
-        *actualTimeUs = seekTimeUs;
-    }
-
-
-    bool seeking = false;
-    sp<AMediaExtractorWrapper> extractor = track->mExtractor;
-    if (seekTimeUs >= 0) {
-        extractor->seekTo(seekTimeUs, mode);
-        seeking = true;
-    }
-
-    int32_t generation = getDataGeneration(trackType);
-    for (size_t numBuffers = 0; numBuffers < maxBuffers; ) {
-        Vector<sp<ABuffer> > aBuffers;
-
-        mLock.unlock();
-
-        sp<AMediaFormatWrapper> format;
-        ssize_t sampleSize = -1;
-        status_t err = extractor->getSampleFormat(format);
-        if (err == OK) {
-            sampleSize = extractor->getSampleSize();
-        }
-
-        if (err != OK || sampleSize < 0) {
-            mLock.lock();
-            track->mPackets->signalEOS(err != OK ? err : ERROR_END_OF_STREAM);
-            break;
-        }
-
-        sp<ABuffer> abuf = new ABuffer(sampleSize);
-        sampleSize = extractor->readSampleData(abuf);
-        mLock.lock();
-
-        // in case track has been changed since we don't have lock for some time.
-        if (generation != getDataGeneration(trackType)) {
-            break;
-        }
-
-        int64_t timeUs = extractor->getSampleTime();
-        if (timeUs < 0) {
-            track->mPackets->signalEOS(ERROR_MALFORMED);
-            break;
-        }
-
-        sp<AMessage> meta = abuf->meta();
-        format->writeToAMessage(meta);
-        meta->setInt64("timeUs", timeUs);
-        if (trackType == MEDIA_TRACK_TYPE_AUDIO) {
-            mAudioTimeUs = timeUs;
-        } else if (trackType == MEDIA_TRACK_TYPE_VIDEO) {
-            mVideoTimeUs = timeUs;
-        }
-
-        sp<AMediaCodecCryptoInfoWrapper> cryptInfo = extractor->getSampleCryptoInfo();
-        if (cryptInfo != NULL) {
-            meta->setObject("cryptInfo", cryptInfo);
-        }
-
-        queueDiscontinuityIfNeeded(seeking, formatChange, trackType, track);
-
-        if (numBuffers == 0 && actualTimeUs != nullptr) {
-            *actualTimeUs = timeUs;
-        }
-        if (seeking) {
-            if (meta != nullptr && mode == MediaPlayer2SeekMode::SEEK_CLOSEST
-                    && seekTimeUs > timeUs) {
-                sp<AMessage> extra = new AMessage;
-                extra->setInt64("resume-at-mediaTimeUs", seekTimeUs);
-                meta->setMessage("extra", extra);
-            }
-        }
-
-        track->mPackets->queueAccessUnit(abuf);
-        formatChange = false;
-        seeking = false;
-        ++numBuffers;
-        extractor->advance();
-
-    }
-
-    if (mIsStreaming
-        && (trackType == MEDIA_TRACK_TYPE_VIDEO || trackType == MEDIA_TRACK_TYPE_AUDIO)) {
-        status_t finalResult;
-        int64_t durationUs = track->mPackets->getBufferedDurationUs(&finalResult);
-
-        // TODO: maxRebufferingMarkMs could be larger than
-        // mBufferingSettings.mResumePlaybackMarkMs
-        int64_t markUs = (mPreparing ? mBufferingSettings.mInitialMarkMs
-            : mBufferingSettings.mResumePlaybackMarkMs) * 1000ll;
-        if (finalResult == ERROR_END_OF_STREAM || durationUs >= markUs) {
-            if (mPreparing || mSentPauseOnBuffering) {
-                Track *counterTrack =
-                    (trackType == MEDIA_TRACK_TYPE_VIDEO ? &mAudioTrack : &mVideoTrack);
-                if (counterTrack->mExtractor != NULL) {
-                    durationUs = counterTrack->mPackets->getBufferedDurationUs(&finalResult);
-                }
-                if (finalResult == ERROR_END_OF_STREAM || durationUs >= markUs) {
-                    if (mPreparing) {
-                        notifyPrepared();
-                        mPreparing = false;
-                    } else {
-                        mSentPauseOnBuffering = false;
-                        sp<AMessage> notify = dupNotify();
-                        notify->setInt32("what", kWhatResumeOnBufferingEnd);
-                        notify->post();
-                    }
-                }
-            }
-            return;
-        }
-
-        postReadBuffer(trackType);
-    }
-}
-
-void NuPlayer2::GenericSource2::queueDiscontinuityIfNeeded(
-        bool seeking, bool formatChange, media_track_type trackType, Track *track) {
-    // formatChange && seeking: track whose source is changed during selection
-    // formatChange && !seeking: track whose source is not changed during selection
-    // !formatChange: normal seek
-    if ((seeking || formatChange)
-            && (trackType == MEDIA_TRACK_TYPE_AUDIO
-            || trackType == MEDIA_TRACK_TYPE_VIDEO)) {
-        ATSParser::DiscontinuityType type = (formatChange && seeking)
-                ? ATSParser::DISCONTINUITY_FORMATCHANGE
-                : ATSParser::DISCONTINUITY_NONE;
-        track->mPackets->queueDiscontinuity(type, NULL /* extra */, true /* discard */);
-    }
-}
-
-void NuPlayer2::GenericSource2::notifyBufferingUpdate(int32_t percentage) {
-    // Buffering percent could go backward as it's estimated from remaining
-    // data and last access time. This could cause the buffering position
-    // drawn on media control to jitter slightly. Remember previously reported
-    // percentage and don't allow it to go backward.
-    if (percentage < mPrevBufferPercentage) {
-        percentage = mPrevBufferPercentage;
-    } else if (percentage > 100) {
-        percentage = 100;
-    }
-
-    mPrevBufferPercentage = percentage;
-
-    ALOGV("notifyBufferingUpdate: buffering %d%%", percentage);
-
-    sp<AMessage> notify = dupNotify();
-    notify->setInt32("what", kWhatBufferingUpdate);
-    notify->setInt32("percentage", percentage);
-    notify->post();
-}
-
-void NuPlayer2::GenericSource2::schedulePollBuffering() {
-    if (mIsStreaming) {
-        sp<AMessage> msg = new AMessage(kWhatPollBuffering, this);
-        msg->setInt32("generation", mPollBufferingGeneration);
-        // Enquires buffering status every second.
-        msg->post(1000000ll);
-    }
-}
-
-void NuPlayer2::GenericSource2::onPollBuffering() {
-    int64_t cachedDurationUs = -1ll;
-
-    sp<AMediaExtractorWrapper> extractor;
-    if (mVideoTrack.mExtractor != NULL) {
-        extractor = mVideoTrack.mExtractor;
-    } else if (mAudioTrack.mExtractor != NULL) {
-        extractor = mAudioTrack.mExtractor;
-    }
-
-    if (extractor != NULL) {
-        cachedDurationUs = extractor->getCachedDuration();
-    }
-
-    if (cachedDurationUs >= 0ll) {
-        ssize_t sampleSize = extractor->getSampleSize();
-        if (sampleSize >= 0ll) {
-            int64_t cachedPosUs = getLastReadPosition() + cachedDurationUs;
-            int percentage = 100.0 * cachedPosUs / mDurationUs;
-            if (percentage > 100) {
-                percentage = 100;
-            }
-
-            notifyBufferingUpdate(percentage);
-            ALOGV("onPollBuffering: cachedDurationUs %.1f sec", cachedDurationUs / 1000000.0f);
-        } else {
-            notifyBufferingUpdate(100);
-            ALOGV("onPollBuffering: EOS");
-        }
-    }
-
-    schedulePollBuffering();
-}
-
-// Modular DRM
-status_t NuPlayer2::GenericSource2::prepareDrm(
-        const uint8_t uuid[16],
-        const Vector<uint8_t> &drmSessionId,
-        sp<AMediaCryptoWrapper> *outCrypto) {
-    Mutex::Autolock _l(mLock);
-    ALOGV("prepareDrm");
-
-    mIsDrmProtected = false;
-    mIsDrmReleased = false;
-    mIsSecure = false;
-
-    status_t status = OK;
-    sp<AMediaCryptoWrapper> crypto =
-        new AMediaCryptoWrapper(uuid, drmSessionId.array(), drmSessionId.size());
-    if (crypto == NULL) {
-        ALOGE("prepareDrm: failed to create crypto.");
-        return UNKNOWN_ERROR;
-    }
-    ALOGV("prepareDrm: crypto created for uuid: %s",
-            DrmUUID::toHexString(uuid).string());
-
-    *outCrypto = crypto;
-    // as long a there is an active crypto
-    mIsDrmProtected = true;
-
-    if (mMimes.size() == 0) {
-        status = UNKNOWN_ERROR;
-        ALOGE("prepareDrm: Unexpected. Must have at least one track. status: %d", status);
-        return status;
-    }
-
-    // first mime in this list is either the video track, or the first audio track
-    const char *mime = mMimes[0].string();
-    mIsSecure = crypto->requiresSecureDecoderComponent(mime);
-    ALOGV("prepareDrm: requiresSecureDecoderComponent mime: %s  isSecure: %d",
-            mime, mIsSecure);
-
-    // Checking the member flags while in the looper to send out the notification.
-    // The legacy mDecryptHandle!=NULL check (for FLAG_PROTECTED) is equivalent to mIsDrmProtected.
-    notifyFlagsChanged(
-            (mIsSecure ? FLAG_SECURE : 0) |
-            // Setting "protected screen" only for L1: b/38390836
-            (mIsSecure ? FLAG_PROTECTED : 0) |
-            FLAG_CAN_PAUSE |
-            FLAG_CAN_SEEK_BACKWARD |
-            FLAG_CAN_SEEK_FORWARD |
-            FLAG_CAN_SEEK);
-
-    if (status == OK) {
-        ALOGV("prepareDrm: mCrypto: %p", outCrypto->get());
-        ALOGD("prepareDrm ret: %d ", status);
-    } else {
-        ALOGE("prepareDrm err: %d", status);
-    }
-    return status;
-}
-
-status_t NuPlayer2::GenericSource2::releaseDrm() {
-    Mutex::Autolock _l(mLock);
-    ALOGV("releaseDrm");
-
-    if (mIsDrmProtected) {
-        mIsDrmProtected = false;
-        // to prevent returning any more buffer after stop/releaseDrm (b/37960096)
-        mIsDrmReleased = true;
-        ALOGV("releaseDrm: mIsDrmProtected is reset.");
-    } else {
-        ALOGE("releaseDrm: mIsDrmProtected is already false.");
-    }
-
-    return OK;
-}
-
-status_t NuPlayer2::GenericSource2::checkDrmInfo()
-{
-    // clearing the flag at prepare in case the player is reused after stop/releaseDrm with the
-    // same source without being reset (called by prepareAsync/initFromDataSource)
-    mIsDrmReleased = false;
-
-    if (mExtractor == NULL) {
-        ALOGV("checkDrmInfo: No extractor");
-        return OK; // letting the caller responds accordingly
-    }
-
-    PsshInfo *psshInfo = mExtractor->getPsshInfo();
-    if (psshInfo == NULL) {
-        ALOGV("checkDrmInfo: No PSSH");
-        return OK; // source without DRM info
-    }
-
-    PlayerMessage playerMsg;
-    status_t ret = NuPlayer2Drm::retrieveDrmInfo(psshInfo, &playerMsg);
-    ALOGV("checkDrmInfo: MEDIA_DRM_INFO PSSH drm info size: %d", (int)playerMsg.ByteSize());
-
-    if (ret != OK) {
-        ALOGE("checkDrmInfo: failed to retrive DrmInfo %d", ret);
-        return UNKNOWN_ERROR;
-    }
-
-    int size = playerMsg.ByteSize();
-    sp<ABuffer> drmInfoBuf = new ABuffer(size);
-    playerMsg.SerializeToArray(drmInfoBuf->data(), size);
-    drmInfoBuf->setRange(0, size);
-    notifyDrmInfo(drmInfoBuf);
-
-    return OK;
-}
-
-void NuPlayer2::GenericSource2::signalBufferReturned(MediaBufferBase *buffer)
-{
-    //ALOGV("signalBufferReturned %p  refCount: %d", buffer, buffer->localRefcount());
-
-    buffer->setObserver(NULL);
-    buffer->release(); // this leads to delete since that there is no observor
-}
-
-}  // namespace android
diff --git a/media/libmediaplayer2/nuplayer2/GenericSource2.h b/media/libmediaplayer2/nuplayer2/GenericSource2.h
deleted file mode 100644
index ade1aa3..0000000
--- a/media/libmediaplayer2/nuplayer2/GenericSource2.h
+++ /dev/null
@@ -1,246 +0,0 @@
-/*
- * Copyright 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef GENERIC_SOURCE2_H_
-
-#define GENERIC_SOURCE2_H_
-
-#include "NuPlayer2.h"
-#include "NuPlayer2Source.h"
-
-#include "ATSParser.h"
-
-#include <media/stagefright/MediaBuffer.h>
-#include <mediaplayer2/mediaplayer2.h>
-#include <media/NdkMediaDataSource.h>
-#include <media/NdkMediaExtractor.h>
-#include <media/NdkWrapper.h>
-
-namespace android {
-
-class DecryptHandle;
-struct AnotherPacketSource;
-struct ARTSPController;
-class DataSource;
-class IDataSource;
-class IMediaSource;
-struct MediaSource;
-class MediaBuffer;
-struct MediaClock;
-
-struct NuPlayer2::GenericSource2 : public NuPlayer2::Source,
-                                   public MediaBufferObserver // Modular DRM
-{
-    GenericSource2(const sp<AMessage> &notify, uid_t uid,
-                   const sp<MediaClock> &mediaClock);
-
-    status_t setDataSource(
-            const char *url,
-            const KeyedVector<String8, String8> *headers);
-
-    status_t setDataSource(int fd, int64_t offset, int64_t length);
-
-    status_t setDataSource(const sp<DataSource>& dataSource);
-
-    virtual status_t getBufferingSettings(
-            BufferingSettings* buffering /* nonnull */) override;
-    virtual status_t setBufferingSettings(const BufferingSettings& buffering) override;
-
-    virtual void prepareAsync(int64_t startTimeUs);
-
-    virtual void start();
-    virtual void stop();
-    virtual void pause();
-    virtual void resume();
-
-    virtual void disconnect();
-
-    virtual status_t feedMoreTSData();
-
-    virtual sp<MetaData> getFileFormatMeta() const;
-
-    virtual status_t dequeueAccessUnit(bool audio, sp<ABuffer> *accessUnit);
-
-    virtual status_t getDuration(int64_t *durationUs);
-    virtual size_t getTrackCount() const;
-    virtual sp<AMessage> getTrackInfo(size_t trackIndex) const;
-    virtual ssize_t getSelectedTrack(media_track_type type) const;
-    virtual status_t selectTrack(size_t trackIndex, bool select, int64_t timeUs);
-    virtual status_t seekTo(
-        int64_t seekTimeUs,
-        MediaPlayer2SeekMode mode = MediaPlayer2SeekMode::SEEK_PREVIOUS_SYNC) override;
-
-    virtual bool isStreaming() const;
-
-    // Modular DRM
-    virtual void signalBufferReturned(MediaBufferBase *buffer);
-
-    virtual status_t prepareDrm(
-            const uint8_t uuid[16],
-            const Vector<uint8_t> &drmSessionId,
-            sp<AMediaCryptoWrapper> *outCrypto);
-
-    virtual status_t releaseDrm();
-
-
-protected:
-    virtual ~GenericSource2();
-
-    virtual void onMessageReceived(const sp<AMessage> &msg);
-
-    virtual sp<AMessage> getFormat(bool audio);
-    virtual sp<MetaData> getFormatMeta(bool audio);
-
-private:
-    enum {
-        kWhatPrepareAsync,
-        kWhatFetchSubtitleData,
-        kWhatFetchTimedTextData,
-        kWhatSendSubtitleData,
-        kWhatSendGlobalTimedTextData,
-        kWhatSendTimedTextData,
-        kWhatChangeAVSource,
-        kWhatPollBuffering,
-        kWhatSeek,
-        kWhatReadBuffer,
-        kWhatStart,
-        kWhatResume,
-        kWhatSecureDecodersInstantiated,
-    };
-
-    struct Track {
-        size_t mIndex;
-        sp<AMediaExtractorWrapper> mExtractor;
-        sp<AnotherPacketSource> mPackets;
-    };
-
-    int64_t mAudioTimeUs;
-    int64_t mAudioLastDequeueTimeUs;
-    int64_t mVideoTimeUs;
-    int64_t mVideoLastDequeueTimeUs;
-
-    BufferingSettings mBufferingSettings;
-    int32_t mPrevBufferPercentage;
-    int32_t mPollBufferingGeneration;
-    bool mSentPauseOnBuffering;
-
-    int32_t mAudioDataGeneration;
-    int32_t mVideoDataGeneration;
-    int32_t mFetchSubtitleDataGeneration;
-    int32_t mFetchTimedTextDataGeneration;
-    int64_t mDurationUs;
-    bool mAudioIsVorbis;
-    // Secure codec is required.
-    bool mIsSecure;
-    bool mIsStreaming;
-    uid_t mUID;
-    const sp<MediaClock> mMediaClock;
-    AString mUri;
-    KeyedVector<String8, String8> mUriHeaders;
-    int mFd;
-    int64_t mOffset;
-    int64_t mLength;
-
-    bool mDisconnected;
-    sp<MetaData> mFileMeta;
-    sp<AMediaDataSourceWrapper> mDataSourceWrapper;
-    sp<AMediaExtractorWrapper> mExtractor;
-    Vector<sp<AMediaExtractorWrapper> > mExtractors;
-    bool mStarted;
-    bool mPreparing;
-    int64_t mBitrate;
-    uint32_t mPendingReadBufferTypes;
-    sp<ABuffer> mGlobalTimedText;
-
-    Track mVideoTrack;
-    Track mAudioTrack;
-    Track mSubtitleTrack;
-    Track mTimedTextTrack;
-
-    mutable Mutex mLock;
-
-    sp<ALooper> mLooper;
-
-    void resetDataSource();
-
-    status_t initFromDataSource();
-    int64_t getLastReadPosition();
-
-    void notifyPreparedAndCleanup(status_t err);
-    void onSecureDecodersInstantiated(status_t err);
-    void finishPrepareAsync();
-    status_t startSources();
-
-    void onSeek(const sp<AMessage>& msg);
-    status_t doSeek(int64_t seekTimeUs, MediaPlayer2SeekMode mode);
-
-    void onPrepareAsync(int64_t startTimeUs);
-
-    void fetchTextData(
-            uint32_t what, media_track_type type,
-            int32_t curGen, const sp<AnotherPacketSource>& packets, const sp<AMessage>& msg);
-
-    void sendGlobalTextData(
-            uint32_t what,
-            int32_t curGen, sp<AMessage> msg);
-
-    void sendTextData(
-            uint32_t what, media_track_type type,
-            int32_t curGen, const sp<AnotherPacketSource>& packets, const sp<AMessage>& msg);
-
-    sp<ABuffer> mediaBufferToABuffer(
-            MediaBufferBase *mbuf,
-            media_track_type trackType);
-
-    void postReadBuffer(media_track_type trackType);
-    void onReadBuffer(const sp<AMessage>& msg);
-    // When |mode| is MediaPlayer2SeekMode::SEEK_CLOSEST, the buffer read shall
-    // include an item indicating skipping rendering all buffers with timestamp
-    // earlier than |seekTimeUs|.
-    // For other modes, the buffer read will not include the item as above in order
-    // to facilitate fast seek operation.
-    void readBuffer(
-            media_track_type trackType,
-            int64_t seekTimeUs = -1ll,
-            MediaPlayer2SeekMode mode = MediaPlayer2SeekMode::SEEK_PREVIOUS_SYNC,
-            int64_t *actualTimeUs = NULL, bool formatChange = false);
-
-    void queueDiscontinuityIfNeeded(
-            bool seeking, bool formatChange, media_track_type trackType, Track *track);
-
-    void schedulePollBuffering();
-    void onPollBuffering();
-    void notifyBufferingUpdate(int32_t percentage);
-
-    sp<AMessage> getFormat_l(bool audio);
-    sp<MetaData> getFormatMeta_l(bool audio);
-    int32_t getDataGeneration(media_track_type type) const;
-
-    // Modular DRM
-    // The source is DRM protected and is prepared for DRM.
-    bool mIsDrmProtected;
-    // releaseDrm has been processed.
-    bool mIsDrmReleased;
-    Vector<String8> mMimes;
-
-    status_t checkDrmInfo();
-
-    DISALLOW_EVIL_CONSTRUCTORS(GenericSource2);
-};
-
-}  // namespace android
-
-#endif  // GENERIC_SOURCE2_H_
diff --git a/media/libmediaplayer2/nuplayer2/HTTPLiveSource2.cpp b/media/libmediaplayer2/nuplayer2/HTTPLiveSource2.cpp
deleted file mode 100644
index e53900b..0000000
--- a/media/libmediaplayer2/nuplayer2/HTTPLiveSource2.cpp
+++ /dev/null
@@ -1,450 +0,0 @@
-/*
- * Copyright 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-//#define LOG_NDEBUG 0
-#define LOG_TAG "HTTPLiveSource2"
-#include <utils/Log.h>
-
-#include "HTTPLiveSource2.h"
-
-#include "AnotherPacketSource.h"
-#include "LiveDataSource.h"
-
-#include <media/MediaHTTPService.h>
-#include <media/stagefright/foundation/ABuffer.h>
-#include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/foundation/AMessage.h>
-#include <media/stagefright/MediaErrors.h>
-#include <media/stagefright/MetaData.h>
-#include <media/stagefright/MediaDefs.h>
-#include <media/stagefright/Utils.h>
-
-// default buffer prepare/ready/underflow marks
-static const int kReadyMarkMs     = 5000;  // 5 seconds
-static const int kPrepareMarkMs   = 1500;  // 1.5 seconds
-
-namespace android {
-
-NuPlayer2::HTTPLiveSource2::HTTPLiveSource2(
-        const sp<AMessage> &notify,
-        const sp<MediaHTTPService> &httpService,
-        const char *url,
-        const KeyedVector<String8, String8> *headers)
-    : Source(notify),
-      mHTTPService(httpService),
-      mURL(url),
-      mFlags(0),
-      mFinalResult(OK),
-      mOffset(0),
-      mFetchSubtitleDataGeneration(0),
-      mFetchMetaDataGeneration(0),
-      mHasMetadata(false),
-      mMetadataSelected(false) {
-    mBufferingSettings.mInitialMarkMs = kPrepareMarkMs;
-    mBufferingSettings.mResumePlaybackMarkMs = kReadyMarkMs;
-    if (headers) {
-        mExtraHeaders = *headers;
-
-        ssize_t index =
-            mExtraHeaders.indexOfKey(String8("x-hide-urls-from-log"));
-
-        if (index >= 0) {
-            mFlags |= kFlagIncognito;
-
-            mExtraHeaders.removeItemsAt(index);
-        }
-    }
-}
-
-NuPlayer2::HTTPLiveSource2::~HTTPLiveSource2() {
-    if (mLiveSession != NULL) {
-        mLiveSession->disconnect();
-
-        mLiveLooper->unregisterHandler(mLiveSession->id());
-        mLiveLooper->unregisterHandler(id());
-        mLiveLooper->stop();
-
-        mLiveSession.clear();
-        mLiveLooper.clear();
-    }
-}
-
-status_t NuPlayer2::HTTPLiveSource2::getBufferingSettings(
-            BufferingSettings* buffering /* nonnull */) {
-    *buffering = mBufferingSettings;
-
-    return OK;
-}
-
-status_t NuPlayer2::HTTPLiveSource2::setBufferingSettings(const BufferingSettings& buffering) {
-    mBufferingSettings = buffering;
-
-    if (mLiveSession != NULL) {
-        mLiveSession->setBufferingSettings(mBufferingSettings);
-    }
-
-    return OK;
-}
-
-// TODO: fetch data starting from |startTimeUs|
-void NuPlayer2::HTTPLiveSource2::prepareAsync(int64_t /* startTimeUs */) {
-    if (mLiveLooper == NULL) {
-        mLiveLooper = new ALooper;
-        mLiveLooper->setName("http live2");
-        mLiveLooper->start(false, /* runOnCallingThread */
-                           true /* canCallJava */);
-
-        mLiveLooper->registerHandler(this);
-    }
-
-    sp<AMessage> notify = new AMessage(kWhatSessionNotify, this);
-
-    mLiveSession = new LiveSession(
-            notify,
-            (mFlags & kFlagIncognito) ? LiveSession::kFlagIncognito : 0,
-            mHTTPService);
-
-    mLiveLooper->registerHandler(mLiveSession);
-
-    mLiveSession->setBufferingSettings(mBufferingSettings);
-    mLiveSession->connectAsync(
-            mURL.c_str(), mExtraHeaders.isEmpty() ? NULL : &mExtraHeaders);
-}
-
-void NuPlayer2::HTTPLiveSource2::start() {
-}
-
-sp<MetaData> NuPlayer2::HTTPLiveSource2::getFormatMeta(bool audio) {
-    sp<MetaData> meta;
-    if (mLiveSession != NULL) {
-        mLiveSession->getStreamFormatMeta(
-                audio ? LiveSession::STREAMTYPE_AUDIO
-                      : LiveSession::STREAMTYPE_VIDEO,
-                &meta);
-    }
-
-    return meta;
-}
-
-sp<AMessage> NuPlayer2::HTTPLiveSource2::getFormat(bool audio) {
-    sp<MetaData> meta;
-    status_t err = -EWOULDBLOCK;
-    if (mLiveSession != NULL) {
-        err = mLiveSession->getStreamFormatMeta(
-                audio ? LiveSession::STREAMTYPE_AUDIO
-                      : LiveSession::STREAMTYPE_VIDEO,
-                &meta);
-    }
-
-    sp<AMessage> format;
-    if (err == -EWOULDBLOCK) {
-        format = new AMessage();
-        format->setInt32("err", err);
-        return format;
-    }
-
-    if (err != OK || convertMetaDataToMessage(meta, &format) != OK) {
-        return NULL;
-    }
-    return format;
-}
-
-status_t NuPlayer2::HTTPLiveSource2::feedMoreTSData() {
-    return OK;
-}
-
-status_t NuPlayer2::HTTPLiveSource2::dequeueAccessUnit(
-        bool audio, sp<ABuffer> *accessUnit) {
-    return mLiveSession->dequeueAccessUnit(
-            audio ? LiveSession::STREAMTYPE_AUDIO
-                  : LiveSession::STREAMTYPE_VIDEO,
-            accessUnit);
-}
-
-status_t NuPlayer2::HTTPLiveSource2::getDuration(int64_t *durationUs) {
-    return mLiveSession->getDuration(durationUs);
-}
-
-size_t NuPlayer2::HTTPLiveSource2::getTrackCount() const {
-    return mLiveSession->getTrackCount();
-}
-
-sp<AMessage> NuPlayer2::HTTPLiveSource2::getTrackInfo(size_t trackIndex) const {
-    return mLiveSession->getTrackInfo(trackIndex);
-}
-
-ssize_t NuPlayer2::HTTPLiveSource2::getSelectedTrack(media_track_type type) const {
-    if (mLiveSession == NULL) {
-        return -1;
-    } else if (type == MEDIA_TRACK_TYPE_METADATA) {
-        // MEDIA_TRACK_TYPE_METADATA is always last track
-        // mMetadataSelected can only be true when mHasMetadata is true
-        return mMetadataSelected ? (mLiveSession->getTrackCount() - 1) : -1;
-    } else {
-        return mLiveSession->getSelectedTrack(type);
-    }
-}
-
-status_t NuPlayer2::HTTPLiveSource2::selectTrack(size_t trackIndex, bool select, int64_t /*timeUs*/) {
-    if (mLiveSession == NULL) {
-        return INVALID_OPERATION;
-    }
-
-    status_t err = INVALID_OPERATION;
-    bool postFetchMsg = false, isSub = false;
-    if (!mHasMetadata || trackIndex != mLiveSession->getTrackCount() - 1) {
-        err = mLiveSession->selectTrack(trackIndex, select);
-        postFetchMsg = select;
-        isSub = true;
-    } else {
-        // metadata track; i.e. (mHasMetadata && trackIndex == mLiveSession->getTrackCount() - 1)
-        if (mMetadataSelected && !select) {
-            err = OK;
-        } else if (!mMetadataSelected && select) {
-            postFetchMsg = true;
-            err = OK;
-        } else {
-            err = BAD_VALUE; // behave as LiveSession::selectTrack
-        }
-
-        mMetadataSelected = select;
-    }
-
-    if (err == OK) {
-        int32_t &generation = isSub ? mFetchSubtitleDataGeneration : mFetchMetaDataGeneration;
-        generation++;
-        if (postFetchMsg) {
-            int32_t what = isSub ? kWhatFetchSubtitleData : kWhatFetchMetaData;
-            sp<AMessage> msg = new AMessage(what, this);
-            msg->setInt32("generation", generation);
-            msg->post();
-        }
-    }
-
-    // LiveSession::selectTrack returns BAD_VALUE when selecting the currently
-    // selected track, or unselecting a non-selected track. In this case it's an
-    // no-op so we return OK.
-    return (err == OK || err == BAD_VALUE) ? (status_t)OK : err;
-}
-
-status_t NuPlayer2::HTTPLiveSource2::seekTo(int64_t seekTimeUs, MediaPlayer2SeekMode mode) {
-    if (mLiveSession->isSeekable()) {
-        return mLiveSession->seekTo(seekTimeUs, mode);
-    } else {
-        return INVALID_OPERATION;
-    }
-}
-
-void NuPlayer2::HTTPLiveSource2::pollForRawData(
-        const sp<AMessage> &msg, int32_t currentGeneration,
-        LiveSession::StreamType fetchType, int32_t pushWhat) {
-
-    int32_t generation;
-    CHECK(msg->findInt32("generation", &generation));
-
-    if (generation != currentGeneration) {
-        return;
-    }
-
-    sp<ABuffer> buffer;
-    while (mLiveSession->dequeueAccessUnit(fetchType, &buffer) == OK) {
-
-        sp<AMessage> notify = dupNotify();
-        notify->setInt32("what", pushWhat);
-        notify->setBuffer("buffer", buffer);
-
-        int64_t timeUs, baseUs, delayUs;
-        CHECK(buffer->meta()->findInt64("baseUs", &baseUs));
-        CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
-        delayUs = baseUs + timeUs - ALooper::GetNowUs();
-
-        if (fetchType == LiveSession::STREAMTYPE_SUBTITLES) {
-            notify->post();
-            msg->post(delayUs > 0LL ? delayUs : 0LL);
-            return;
-        } else if (fetchType == LiveSession::STREAMTYPE_METADATA) {
-            if (delayUs < -1000000LL) { // 1 second
-                continue;
-            }
-            notify->post();
-            // push all currently available metadata buffers in each invocation of pollForRawData
-            // continue;
-        } else {
-            TRESPASS();
-        }
-    }
-
-    // try again in 1 second
-    msg->post(1000000LL);
-}
-
-void NuPlayer2::HTTPLiveSource2::onMessageReceived(const sp<AMessage> &msg) {
-    switch (msg->what()) {
-        case kWhatSessionNotify:
-        {
-            onSessionNotify(msg);
-            break;
-        }
-
-        case kWhatFetchSubtitleData:
-        {
-            pollForRawData(
-                    msg, mFetchSubtitleDataGeneration,
-                    /* fetch */ LiveSession::STREAMTYPE_SUBTITLES,
-                    /* push */ kWhatSubtitleData);
-
-            break;
-        }
-
-        case kWhatFetchMetaData:
-        {
-            if (!mMetadataSelected) {
-                break;
-            }
-
-            pollForRawData(
-                    msg, mFetchMetaDataGeneration,
-                    /* fetch */ LiveSession::STREAMTYPE_METADATA,
-                    /* push */ kWhatTimedMetaData);
-
-            break;
-        }
-
-        default:
-            Source::onMessageReceived(msg);
-            break;
-    }
-}
-
-void NuPlayer2::HTTPLiveSource2::onSessionNotify(const sp<AMessage> &msg) {
-    int32_t what;
-    CHECK(msg->findInt32("what", &what));
-
-    switch (what) {
-        case LiveSession::kWhatPrepared:
-        {
-            // notify the current size here if we have it, otherwise report an initial size of (0,0)
-            sp<AMessage> format = getFormat(false /* audio */);
-            int32_t width;
-            int32_t height;
-            if (format != NULL &&
-                    format->findInt32("width", &width) && format->findInt32("height", &height)) {
-                notifyVideoSizeChanged(format);
-            } else {
-                notifyVideoSizeChanged();
-            }
-
-            uint32_t flags = 0;
-            if (mLiveSession->isSeekable()) {
-                flags |= FLAG_CAN_PAUSE;
-                flags |= FLAG_CAN_SEEK;
-                flags |= FLAG_CAN_SEEK_BACKWARD;
-                flags |= FLAG_CAN_SEEK_FORWARD;
-            }
-
-            if (mLiveSession->hasDynamicDuration()) {
-                flags |= FLAG_DYNAMIC_DURATION;
-            }
-
-            notifyFlagsChanged(flags);
-
-            notifyPrepared();
-            break;
-        }
-
-        case LiveSession::kWhatPreparationFailed:
-        {
-            status_t err;
-            CHECK(msg->findInt32("err", &err));
-
-            notifyPrepared(err);
-            break;
-        }
-
-        case LiveSession::kWhatStreamsChanged:
-        {
-            uint32_t changedMask;
-            CHECK(msg->findInt32(
-                        "changedMask", (int32_t *)&changedMask));
-
-            bool audio = changedMask & LiveSession::STREAMTYPE_AUDIO;
-            bool video = changedMask & LiveSession::STREAMTYPE_VIDEO;
-
-            sp<AMessage> reply;
-            CHECK(msg->findMessage("reply", &reply));
-
-            sp<AMessage> notify = dupNotify();
-            notify->setInt32("what", kWhatQueueDecoderShutdown);
-            notify->setInt32("audio", audio);
-            notify->setInt32("video", video);
-            notify->setMessage("reply", reply);
-            notify->post();
-            break;
-        }
-
-        case LiveSession::kWhatBufferingStart:
-        {
-            sp<AMessage> notify = dupNotify();
-            notify->setInt32("what", kWhatPauseOnBufferingStart);
-            notify->post();
-            break;
-        }
-
-        case LiveSession::kWhatBufferingEnd:
-        {
-            sp<AMessage> notify = dupNotify();
-            notify->setInt32("what", kWhatResumeOnBufferingEnd);
-            notify->post();
-            break;
-        }
-
-
-        case LiveSession::kWhatBufferingUpdate:
-        {
-            sp<AMessage> notify = dupNotify();
-            int32_t percentage;
-            CHECK(msg->findInt32("percentage", &percentage));
-            notify->setInt32("what", kWhatBufferingUpdate);
-            notify->setInt32("percentage", percentage);
-            notify->post();
-            break;
-        }
-
-        case LiveSession::kWhatMetadataDetected:
-        {
-            if (!mHasMetadata) {
-                mHasMetadata = true;
-
-                sp<AMessage> notify = dupNotify();
-                // notification without buffer triggers MEDIA2_INFO_METADATA_UPDATE
-                notify->setInt32("what", kWhatTimedMetaData);
-                notify->post();
-            }
-            break;
-        }
-
-        case LiveSession::kWhatError:
-        {
-            break;
-        }
-
-        default:
-            TRESPASS();
-    }
-}
-
-}  // namespace android
-
diff --git a/media/libmediaplayer2/nuplayer2/HTTPLiveSource2.h b/media/libmediaplayer2/nuplayer2/HTTPLiveSource2.h
deleted file mode 100644
index 8fc71e2..0000000
--- a/media/libmediaplayer2/nuplayer2/HTTPLiveSource2.h
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef HTTP_LIVE_SOURCE2_H_
-
-#define HTTP_LIVE_SOURCE2_H_
-
-#include "NuPlayer2.h"
-#include "NuPlayer2Source.h"
-
-#include "LiveSession.h"
-
-namespace android {
-
-struct LiveSession;
-
-struct NuPlayer2::HTTPLiveSource2 : public NuPlayer2::Source {
-    HTTPLiveSource2(
-            const sp<AMessage> &notify,
-            const sp<MediaHTTPService> &httpService,
-            const char *url,
-            const KeyedVector<String8, String8> *headers);
-
-    virtual status_t getBufferingSettings(
-            BufferingSettings* buffering /* nonnull */) override;
-    virtual status_t setBufferingSettings(const BufferingSettings& buffering) override;
-
-    virtual void prepareAsync(int64_t startTimeUs);
-    virtual void start();
-
-    virtual status_t dequeueAccessUnit(bool audio, sp<ABuffer> *accessUnit);
-    virtual sp<MetaData> getFormatMeta(bool audio);
-    virtual sp<AMessage> getFormat(bool audio);
-
-    virtual status_t feedMoreTSData();
-    virtual status_t getDuration(int64_t *durationUs);
-    virtual size_t getTrackCount() const;
-    virtual sp<AMessage> getTrackInfo(size_t trackIndex) const;
-    virtual ssize_t getSelectedTrack(media_track_type /* type */) const;
-    virtual status_t selectTrack(size_t trackIndex, bool select, int64_t timeUs);
-    virtual status_t seekTo(
-            int64_t seekTimeUs,
-            MediaPlayer2SeekMode mode = MediaPlayer2SeekMode::SEEK_PREVIOUS_SYNC) override;
-
-protected:
-    virtual ~HTTPLiveSource2();
-
-    virtual void onMessageReceived(const sp<AMessage> &msg);
-
-private:
-    enum Flags {
-        // Don't log any URLs.
-        kFlagIncognito = 1,
-    };
-
-    enum {
-        kWhatSessionNotify,
-        kWhatFetchSubtitleData,
-        kWhatFetchMetaData,
-    };
-
-    sp<MediaHTTPService> mHTTPService;
-    AString mURL;
-    KeyedVector<String8, String8> mExtraHeaders;
-    uint32_t mFlags;
-    status_t mFinalResult;
-    off64_t mOffset;
-    sp<ALooper> mLiveLooper;
-    sp<LiveSession> mLiveSession;
-    int32_t mFetchSubtitleDataGeneration;
-    int32_t mFetchMetaDataGeneration;
-    bool mHasMetadata;
-    bool mMetadataSelected;
-    BufferingSettings mBufferingSettings;
-
-    void onSessionNotify(const sp<AMessage> &msg);
-    void pollForRawData(
-            const sp<AMessage> &msg, int32_t currentGeneration,
-            LiveSession::StreamType fetchType, int32_t pushWhat);
-
-    DISALLOW_EVIL_CONSTRUCTORS(HTTPLiveSource2);
-};
-
-}  // namespace android
-
-#endif  // HTTP_LIVE_SOURCE2_H_
diff --git a/media/libmediaplayer2/nuplayer2/JMediaPlayer2Utils.cpp b/media/libmediaplayer2/nuplayer2/JMediaPlayer2Utils.cpp
deleted file mode 100644
index 89703de..0000000
--- a/media/libmediaplayer2/nuplayer2/JMediaPlayer2Utils.cpp
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright 2018, 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 "JMediaPlayer2Utils"
-
-#include "JMediaPlayer2Utils.h"
-#include <mediaplayer2/JavaVMHelper.h>
-
-#include <media/stagefright/MediaDefs.h>
-#include <media/stagefright/Utils.h>
-#include <utils/Log.h>
-
-#include "log/log.h"
-
-namespace android {
-
-static const int64_t kOffloadMinDurationSec = 60;
-
-// static
-bool JMediaPlayer2Utils::isOffloadedAudioPlaybackSupported(
-        const sp<MetaData>& meta, bool hasVideo, bool isStreaming, audio_stream_type_t streamType)
-{
-    if (hasVideo || streamType != AUDIO_STREAM_MUSIC) {
-        return false;
-    }
-
-    audio_offload_info_t info = AUDIO_INFO_INITIALIZER;
-    if (OK != getAudioOffloadInfo(meta, hasVideo, isStreaming, streamType, &info)) {
-        return false;
-    }
-
-    if (info.duration_us < kOffloadMinDurationSec * 1000000) {
-        return false;
-    }
-
-    int32_t audioFormat = audioFormatFromNative(info.format);
-    int32_t channelMask = outChannelMaskFromNative(info.channel_mask);
-    if (audioFormat == ENCODING_INVALID || channelMask == CHANNEL_INVALID) {
-        return false;
-    }
-
-    JNIEnv* env = JavaVMHelper::getJNIEnv();
-    jclass jMP2UtilsCls = env->FindClass("android/media/MediaPlayer2Utils");
-    jmethodID jSetAudioOutputDeviceById = env->GetStaticMethodID(
-            jMP2UtilsCls, "isOffloadedAudioPlaybackSupported", "(III)Z");
-    jboolean result = env->CallStaticBooleanMethod(
-            jMP2UtilsCls, jSetAudioOutputDeviceById, audioFormat, info.sample_rate, channelMask);
-    return result;
-}
-
-}  // namespace android
diff --git a/media/libmediaplayer2/nuplayer2/JMediaPlayer2Utils.h b/media/libmediaplayer2/nuplayer2/JMediaPlayer2Utils.h
deleted file mode 100644
index fcbd43c..0000000
--- a/media/libmediaplayer2/nuplayer2/JMediaPlayer2Utils.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright 2018, 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 _J_MEDIAPLAYER2_UTILS2_H_
-#define _J_MEDIAPLAYER2_UTILS2_H_
-
-#include <media/stagefright/MetaData.h>
-
-#include "jni.h"
-#include "android_media_AudioFormat.h"
-
-namespace android {
-
-struct JMediaPlayer2Utils {
-    static bool isOffloadedAudioPlaybackSupported(
-            const sp<MetaData>& meta, bool hasVideo, bool isStreaming,
-            audio_stream_type_t streamType);
-};
-
-}  // namespace android
-
-#endif  // _J_MEDIAPLAYER2_UTILS2_H_
diff --git a/media/libmediaplayer2/nuplayer2/JWakeLock.cpp b/media/libmediaplayer2/nuplayer2/JWakeLock.cpp
deleted file mode 100644
index 983d77e..0000000
--- a/media/libmediaplayer2/nuplayer2/JWakeLock.cpp
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-//#define LOG_NDEBUG 0
-#define LOG_TAG "JWakeLock"
-#include <utils/Log.h>
-
-#include "JWakeLock.h"
-
-#include <media/stagefright/foundation/ADebug.h>
-
-namespace android {
-
-JWakeLock::JWakeLock(const sp<JObjectHolder> &context) :
-    mWakeLockCount(0),
-    mWakeLock(NULL),
-    mContext(context) {}
-
-JWakeLock::~JWakeLock() {
-    clearJavaWakeLock();
-}
-
-bool JWakeLock::acquire() {
-    if (mWakeLockCount == 0) {
-        if (mWakeLock == NULL) {
-            JNIEnv *env = JavaVMHelper::getJNIEnv();
-            jclass jContextCls = env->FindClass("android/content/Context");
-            jclass jPowerManagerCls = env->FindClass("android/os/PowerManager");
-
-            jmethodID jGetSystemService = env->GetMethodID(jContextCls,
-                    "getSystemService", "(Ljava/lang/String;)Ljava/lang/Object;");
-            jobject javaPowerManagerObj = env->CallObjectMethod(mContext->getJObject(),
-                    jGetSystemService, env->NewStringUTF("power"));
-
-            jfieldID jPARTIAL_WAKE_LOCK = env->GetStaticFieldID(jPowerManagerCls,
-                    "PARTIAL_WAKE_LOCK", "I");
-            jint PARTIAL_WAKE_LOCK = env->GetStaticIntField(jPowerManagerCls, jPARTIAL_WAKE_LOCK);
-
-            jmethodID jNewWakeLock = env->GetMethodID(jPowerManagerCls,
-                    "newWakeLock", "(ILjava/lang/String;)Landroid/os/PowerManager$WakeLock;");
-            jobject javaWakeLock = env->CallObjectMethod(javaPowerManagerObj,
-                    jNewWakeLock, PARTIAL_WAKE_LOCK, env->NewStringUTF("JWakeLock"));
-            mWakeLock = new JObjectHolder(javaWakeLock);
-            env->DeleteLocalRef(javaPowerManagerObj);
-            env->DeleteLocalRef(javaWakeLock);
-        }
-        if (mWakeLock != NULL) {
-            JNIEnv *env = JavaVMHelper::getJNIEnv();
-            jclass wakeLockCls = env->FindClass("android/os/PowerManager$WakeLock");
-            jmethodID jAcquire = env->GetMethodID(wakeLockCls, "acquire", "()V");
-            env->CallVoidMethod(mWakeLock->getJObject(), jAcquire);
-            mWakeLockCount++;
-            return true;
-        }
-    } else {
-        mWakeLockCount++;
-        return true;
-    }
-    return false;
-}
-
-void JWakeLock::release(bool force) {
-    if (mWakeLockCount == 0) {
-        return;
-    }
-    if (force) {
-        // Force wakelock release below by setting reference count to 1.
-        mWakeLockCount = 1;
-    }
-    if (--mWakeLockCount == 0) {
-        if (mWakeLock != NULL) {
-            JNIEnv *env = JavaVMHelper::getJNIEnv();
-            jclass wakeLockCls = env->FindClass("android/os/PowerManager$WakeLock");
-            jmethodID jRelease = env->GetMethodID(wakeLockCls, "release", "()V");
-            env->CallVoidMethod(mWakeLock->getJObject(), jRelease);
-        }
-    }
-}
-
-void JWakeLock::clearJavaWakeLock() {
-    release(true);
-}
-
-}  // namespace android
diff --git a/media/libmediaplayer2/nuplayer2/JWakeLock.h b/media/libmediaplayer2/nuplayer2/JWakeLock.h
deleted file mode 100644
index 36c542e..0000000
--- a/media/libmediaplayer2/nuplayer2/JWakeLock.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef J_WAKELOCK_H_
-#define J_WAKELOCK_H_
-
-#include <media/stagefright/foundation/ABase.h>
-#include <mediaplayer2/JObjectHolder.h>
-#include <utils/RefBase.h>
-
-namespace android {
-
-class JWakeLock : public RefBase {
-
-public:
-    JWakeLock(const sp<JObjectHolder> &context);
-
-    // NOTE: acquire and release are not thread safe
-
-    // returns true if wakelock was acquired
-    bool acquire();
-    void release(bool force = false);
-
-    virtual ~JWakeLock();
-
-private:
-    uint32_t                mWakeLockCount;
-    sp<JObjectHolder>       mWakeLock;
-    const sp<JObjectHolder> mContext;
-
-    void clearJavaWakeLock();
-
-    DISALLOW_EVIL_CONSTRUCTORS(JWakeLock);
-};
-
-}  // namespace android
-
-#endif  // J_WAKELOCK_H_
diff --git a/media/libmediaplayer2/nuplayer2/MODULE_LICENSE_APACHE2 b/media/libmediaplayer2/nuplayer2/MODULE_LICENSE_APACHE2
deleted file mode 100644
index e69de29..0000000
--- a/media/libmediaplayer2/nuplayer2/MODULE_LICENSE_APACHE2
+++ /dev/null
diff --git a/media/libmediaplayer2/nuplayer2/NOTICE b/media/libmediaplayer2/nuplayer2/NOTICE
deleted file mode 100644
index c5b1efa..0000000
--- a/media/libmediaplayer2/nuplayer2/NOTICE
+++ /dev/null
@@ -1,190 +0,0 @@
-
-   Copyright (c) 2005-2008, 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.
-
-   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.
-
-
-                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
-
diff --git a/media/libmediaplayer2/nuplayer2/NuPlayer2.cpp b/media/libmediaplayer2/nuplayer2/NuPlayer2.cpp
deleted file mode 100644
index d608d4a..0000000
--- a/media/libmediaplayer2/nuplayer2/NuPlayer2.cpp
+++ /dev/null
@@ -1,3308 +0,0 @@
-/*
- * Copyright 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-//#define LOG_NDEBUG 0
-#define LOG_TAG "NuPlayer2"
-
-#include <inttypes.h>
-
-#include <utils/Log.h>
-
-#include "NuPlayer2.h"
-
-#include "HTTPLiveSource2.h"
-#include "JMediaPlayer2Utils.h"
-#include "NuPlayer2CCDecoder.h"
-#include "NuPlayer2Decoder.h"
-#include "NuPlayer2DecoderBase.h"
-#include "NuPlayer2DecoderPassThrough.h"
-#include "NuPlayer2Driver.h"
-#include "NuPlayer2Renderer.h"
-#include "NuPlayer2Source.h"
-#include "RTSPSource2.h"
-#include "GenericSource2.h"
-#include "TextDescriptions2.h"
-
-#include "ATSParser.h"
-
-#include <cutils/properties.h>
-
-#include <media/AudioParameter.h>
-#include <media/AudioResamplerPublic.h>
-#include <media/AVSyncSettings.h>
-#include <media/DataSourceDesc.h>
-#include <media/MediaCodecBuffer.h>
-#include <media/NdkWrapper.h>
-
-#include <media/stagefright/foundation/hexdump.h>
-#include <media/stagefright/foundation/ABuffer.h>
-#include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/foundation/AMessage.h>
-#include <media/stagefright/foundation/avc_utils.h>
-#include <media/stagefright/MediaBuffer.h>
-#include <media/stagefright/MediaClock.h>
-#include <media/stagefright/MediaDefs.h>
-#include <media/stagefright/MediaErrors.h>
-#include <media/stagefright/MetaData.h>
-
-#include "ESDS.h"
-#include <media/stagefright/Utils.h>
-
-#include <system/window.h>
-
-namespace android {
-
-static status_t sendMetaDataToHal(sp<MediaPlayer2Interface::AudioSink>& sink,
-                                  const sp<MetaData>& meta) {
-    int32_t sampleRate = 0;
-    int32_t bitRate = 0;
-    int32_t channelMask = 0;
-    int32_t delaySamples = 0;
-    int32_t paddingSamples = 0;
-
-    AudioParameter param = AudioParameter();
-
-    if (meta->findInt32(kKeySampleRate, &sampleRate)) {
-        param.addInt(String8(AUDIO_OFFLOAD_CODEC_SAMPLE_RATE), sampleRate);
-    }
-    if (meta->findInt32(kKeyChannelMask, &channelMask)) {
-        param.addInt(String8(AUDIO_OFFLOAD_CODEC_NUM_CHANNEL), channelMask);
-    }
-    if (meta->findInt32(kKeyBitRate, &bitRate)) {
-        param.addInt(String8(AUDIO_OFFLOAD_CODEC_AVG_BIT_RATE), bitRate);
-    }
-    if (meta->findInt32(kKeyEncoderDelay, &delaySamples)) {
-        param.addInt(String8(AUDIO_OFFLOAD_CODEC_DELAY_SAMPLES), delaySamples);
-    }
-    if (meta->findInt32(kKeyEncoderPadding, &paddingSamples)) {
-        param.addInt(String8(AUDIO_OFFLOAD_CODEC_PADDING_SAMPLES), paddingSamples);
-    }
-
-    ALOGV("sendMetaDataToHal: bitRate %d, sampleRate %d, chanMask %d,"
-          "delaySample %d, paddingSample %d", bitRate, sampleRate,
-          channelMask, delaySamples, paddingSamples);
-
-    sink->setParameters(param.toString());
-    return OK;
-}
-
-
-struct NuPlayer2::Action : public RefBase {
-    Action() {}
-
-    virtual void execute(NuPlayer2 *player) = 0;
-
-private:
-    DISALLOW_EVIL_CONSTRUCTORS(Action);
-};
-
-struct NuPlayer2::SeekAction : public Action {
-    explicit SeekAction(int64_t seekTimeUs, MediaPlayer2SeekMode mode)
-        : mSeekTimeUs(seekTimeUs),
-          mMode(mode) {
-    }
-
-    virtual void execute(NuPlayer2 *player) {
-        player->performSeek(mSeekTimeUs, mMode);
-    }
-
-private:
-    int64_t mSeekTimeUs;
-    MediaPlayer2SeekMode mMode;
-
-    DISALLOW_EVIL_CONSTRUCTORS(SeekAction);
-};
-
-struct NuPlayer2::ResumeDecoderAction : public Action {
-    explicit ResumeDecoderAction(bool needNotify)
-        : mNeedNotify(needNotify) {
-    }
-
-    virtual void execute(NuPlayer2 *player) {
-        player->performResumeDecoders(mNeedNotify);
-    }
-
-private:
-    bool mNeedNotify;
-
-    DISALLOW_EVIL_CONSTRUCTORS(ResumeDecoderAction);
-};
-
-struct NuPlayer2::SetSurfaceAction : public Action {
-    explicit SetSurfaceAction(const sp<ANativeWindowWrapper> &nww)
-        : mNativeWindow(nww) {
-    }
-
-    virtual void execute(NuPlayer2 *player) {
-        player->performSetSurface(mNativeWindow);
-    }
-
-private:
-    sp<ANativeWindowWrapper> mNativeWindow;
-
-    DISALLOW_EVIL_CONSTRUCTORS(SetSurfaceAction);
-};
-
-struct NuPlayer2::FlushDecoderAction : public Action {
-    FlushDecoderAction(FlushCommand audio, FlushCommand video)
-        : mAudio(audio),
-          mVideo(video) {
-    }
-
-    virtual void execute(NuPlayer2 *player) {
-        player->performDecoderFlush(mAudio, mVideo);
-    }
-
-private:
-    FlushCommand mAudio;
-    FlushCommand mVideo;
-
-    DISALLOW_EVIL_CONSTRUCTORS(FlushDecoderAction);
-};
-
-struct NuPlayer2::PostMessageAction : public Action {
-    explicit PostMessageAction(const sp<AMessage> &msg)
-        : mMessage(msg) {
-    }
-
-    virtual void execute(NuPlayer2 *) {
-        mMessage->post();
-    }
-
-private:
-    sp<AMessage> mMessage;
-
-    DISALLOW_EVIL_CONSTRUCTORS(PostMessageAction);
-};
-
-// Use this if there's no state necessary to save in order to execute
-// the action.
-struct NuPlayer2::SimpleAction : public Action {
-    typedef void (NuPlayer2::*ActionFunc)();
-
-    explicit SimpleAction(ActionFunc func)
-        : mFunc(func) {
-    }
-
-    virtual void execute(NuPlayer2 *player) {
-        (player->*mFunc)();
-    }
-
-private:
-    ActionFunc mFunc;
-
-    DISALLOW_EVIL_CONSTRUCTORS(SimpleAction);
-};
-
-////////////////////////////////////////////////////////////////////////////////
-
-NuPlayer2::NuPlayer2(
-        pid_t pid, uid_t uid, const sp<MediaClock> &mediaClock, const sp<JObjectHolder> &context)
-    : mPID(pid),
-      mUID(uid),
-      mMediaClock(mediaClock),
-      mOffloadAudio(false),
-      mAudioDecoderGeneration(0),
-      mVideoDecoderGeneration(0),
-      mRendererGeneration(0),
-      mEOSMonitorGeneration(0),
-      mLastStartedPlayingTimeNs(0),
-      mPreviousSeekTimeUs(0),
-      mAudioEOS(false),
-      mVideoEOS(false),
-      mScanSourcesPending(false),
-      mScanSourcesGeneration(0),
-      mPollDurationGeneration(0),
-      mTimedTextGeneration(0),
-      mFlushingAudio(NONE),
-      mFlushingVideo(NONE),
-      mResumePending(false),
-      mVideoScalingMode(NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW),
-      mPlaybackSettings(AUDIO_PLAYBACK_RATE_DEFAULT),
-      mVideoFpsHint(-1.f),
-      mStarted(false),
-      mPrepared(false),
-      mResetting(false),
-      mSourceStarted(false),
-      mAudioDecoderError(false),
-      mVideoDecoderError(false),
-      mPaused(false),
-      mPausedByClient(true),
-      mPausedForBuffering(false),
-      mContext(context) {
-    CHECK(mediaClock != NULL);
-    clearFlushComplete();
-}
-
-NuPlayer2::~NuPlayer2() {
-}
-
-void NuPlayer2::setDriver(const wp<NuPlayer2Driver> &driver) {
-    mDriver = driver;
-}
-
-static bool IsHTTPLiveURL(const char *url) {
-    if (!strncasecmp("http://", url, 7)
-            || !strncasecmp("https://", url, 8)
-            || !strncasecmp("file://", url, 7)) {
-        size_t len = strlen(url);
-        if (len >= 5 && !strcasecmp(".m3u8", &url[len - 5])) {
-            return true;
-        }
-
-        if (strstr(url,"m3u8")) {
-            return true;
-        }
-    }
-
-    return false;
-}
-
-status_t NuPlayer2::createNuPlayer2Source(const sp<DataSourceDesc> &dsd,
-                                          sp<Source> *source,
-                                          DATA_SOURCE_TYPE *dataSourceType) {
-    status_t err = NO_ERROR;
-    sp<AMessage> notify = new AMessage(kWhatSourceNotify, this);
-    notify->setInt64("srcId", dsd->mId);
-
-    switch (dsd->mType) {
-        case DataSourceDesc::TYPE_URL:
-        {
-            const char *url = dsd->mUrl.c_str();
-            size_t len = strlen(url);
-
-            const sp<MediaHTTPService> &httpService = dsd->mHttpService;
-            KeyedVector<String8, String8> *headers = &(dsd->mHeaders);
-
-            if (IsHTTPLiveURL(url)) {
-                *source = new HTTPLiveSource2(notify, httpService, url, headers);
-                ALOGV("createNuPlayer2Source HTTPLiveSource2 %s", url);
-                *dataSourceType = DATA_SOURCE_TYPE_HTTP_LIVE;
-            } else if (!strncasecmp(url, "rtsp://", 7)) {
-                *source = new RTSPSource2(
-                        notify, httpService, url, headers, mUID);
-                ALOGV("createNuPlayer2Source RTSPSource2 %s", url);
-                *dataSourceType = DATA_SOURCE_TYPE_RTSP;
-            } else if ((!strncasecmp(url, "http://", 7)
-                        || !strncasecmp(url, "https://", 8))
-                            && ((len >= 4 && !strcasecmp(".sdp", &url[len - 4]))
-                            || strstr(url, ".sdp?"))) {
-                *source = new RTSPSource2(
-                        notify, httpService, url, headers, mUID, true);
-                ALOGV("createNuPlayer2Source RTSPSource2 http/https/.sdp %s", url);
-                *dataSourceType = DATA_SOURCE_TYPE_RTSP;
-            } else {
-                ALOGV("createNuPlayer2Source GenericSource2 %s", url);
-
-                sp<GenericSource2> genericSource =
-                        new GenericSource2(notify, mUID, mMediaClock);
-
-                err = genericSource->setDataSource(url, headers);
-
-                if (err == OK) {
-                    *source = genericSource;
-                } else {
-                    *source = NULL;
-                    ALOGE("Failed to create NuPlayer2Source!");
-                }
-
-                // regardless of success/failure
-                *dataSourceType = DATA_SOURCE_TYPE_GENERIC_URL;
-            }
-            break;
-        }
-
-        case DataSourceDesc::TYPE_FD:
-        {
-            sp<GenericSource2> genericSource =
-                    new GenericSource2(notify, mUID, mMediaClock);
-
-            ALOGV("createNuPlayer2Source fd %d/%lld/%lld source: %p",
-                  dsd->mFD, (long long)dsd->mFDOffset, (long long)dsd->mFDLength,
-                  genericSource.get());
-
-            err = genericSource->setDataSource(dsd->mFD, dsd->mFDOffset, dsd->mFDLength);
-
-            if (err != OK) {
-                ALOGE("Failed to create NuPlayer2Source!");
-                *source = NULL;
-            } else {
-                *source = genericSource;
-            }
-
-            *dataSourceType = DATA_SOURCE_TYPE_GENERIC_FD;
-            break;
-        }
-
-        case DataSourceDesc::TYPE_CALLBACK:
-        {
-            sp<GenericSource2> genericSource =
-                    new GenericSource2(notify, mUID, mMediaClock);
-            err = genericSource->setDataSource(dsd->mCallbackSource);
-
-            if (err != OK) {
-                ALOGE("Failed to create NuPlayer2Source!");
-                *source = NULL;
-            } else {
-                *source = genericSource;
-            }
-
-            *dataSourceType = DATA_SOURCE_TYPE_MEDIA;
-            break;
-        }
-
-        default:
-            err = BAD_TYPE;
-            *source = NULL;
-            *dataSourceType = DATA_SOURCE_TYPE_NONE;
-            ALOGE("invalid data source type!");
-            break;
-    }
-
-    return err;
-}
-
-void NuPlayer2::setDataSourceAsync(const sp<DataSourceDesc> &dsd) {
-    DATA_SOURCE_TYPE dataSourceType;
-    sp<Source> source;
-    createNuPlayer2Source(dsd, &source, &dataSourceType);
-
-    // TODO: currently NuPlayer2Driver makes blocking call to setDataSourceAsync
-    // and expects notifySetDataSourceCompleted regardless of success or failure.
-    // This will be changed since setDataSource should be asynchronous at JAVA level.
-    // When it succeeds, app will get onInfo notification. Otherwise, onError
-    // will be called.
-    /*
-    if (err != OK) {
-        notifyListener(dsd->mId, MEDIA2_ERROR, MEDIA2_ERROR_FAILED_TO_SET_DATA_SOURCE, err);
-        return;
-    }
-
-    // Now, source != NULL.
-    */
-
-    mCurrentSourceInfo.mDataSourceType = dataSourceType;
-
-    sp<AMessage> msg = new AMessage(kWhatSetDataSource, this);
-    msg->setObject("source", source);
-    msg->setInt64("srcId", dsd->mId);
-    msg->setInt64("startTimeUs", dsd->mStartPositionMs * 1000);
-    msg->setInt64("endTimeUs", dsd->mEndPositionMs * 1000);
-    msg->post();
-}
-
-void NuPlayer2::prepareNextDataSourceAsync(const sp<DataSourceDesc> &dsd) {
-    DATA_SOURCE_TYPE dataSourceType;
-    sp<Source> source;
-    createNuPlayer2Source(dsd, &source, &dataSourceType);
-
-    /*
-    if (err != OK) {
-        notifyListener(dsd->mId, MEDIA2_ERROR, MEDIA2_ERROR_FAILED_TO_SET_DATA_SOURCE, err);
-        return;
-    }
-
-    // Now, source != NULL.
-    */
-
-    mNextSourceInfo.mDataSourceType = dataSourceType;
-
-    sp<AMessage> msg = new AMessage(kWhatPrepareNextDataSource, this);
-    msg->setObject("source", source);
-    msg->setInt64("srcId", dsd->mId);
-    msg->setInt64("startTimeUs", dsd->mStartPositionMs * 1000);
-    msg->setInt64("endTimeUs", dsd->mEndPositionMs * 1000);
-    msg->post();
-}
-
-void NuPlayer2::playNextDataSource(int64_t srcId) {
-    disconnectSource();
-
-    sp<AMessage> msg = new AMessage(kWhatPlayNextDataSource, this);
-    msg->setInt64("srcId", srcId);
-    msg->post();
-}
-
-status_t NuPlayer2::getBufferingSettings(
-        BufferingSettings *buffering /* nonnull */) {
-    sp<AMessage> msg = new AMessage(kWhatGetBufferingSettings, this);
-    sp<AMessage> response;
-    status_t err = msg->postAndAwaitResponse(&response);
-    if (err == OK && response != NULL) {
-        CHECK(response->findInt32("err", &err));
-        if (err == OK) {
-            readFromAMessage(response, buffering);
-        }
-    }
-    return err;
-}
-
-status_t NuPlayer2::setBufferingSettings(const BufferingSettings& buffering) {
-    sp<AMessage> msg = new AMessage(kWhatSetBufferingSettings, this);
-    writeToAMessage(msg, buffering);
-    sp<AMessage> response;
-    status_t err = msg->postAndAwaitResponse(&response);
-    if (err == OK && response != NULL) {
-        CHECK(response->findInt32("err", &err));
-    }
-    return err;
-}
-
-void NuPlayer2::prepareAsync() {
-    ALOGV("prepareAsync");
-
-    (new AMessage(kWhatPrepare, this))->post();
-}
-
-void NuPlayer2::setVideoSurfaceTextureAsync(const sp<ANativeWindowWrapper> &nww) {
-    sp<AMessage> msg = new AMessage(kWhatSetVideoSurface, this);
-
-    if (nww == NULL || nww->getANativeWindow() == NULL) {
-        msg->setObject("surface", NULL);
-    } else {
-        msg->setObject("surface", nww);
-    }
-
-    msg->post();
-}
-
-void NuPlayer2::setAudioSink(const sp<MediaPlayer2Interface::AudioSink> &sink) {
-    sp<AMessage> msg = new AMessage(kWhatSetAudioSink, this);
-    msg->setObject("sink", sink);
-    msg->post();
-}
-
-void NuPlayer2::start() {
-    (new AMessage(kWhatStart, this))->post();
-}
-
-status_t NuPlayer2::setPlaybackSettings(const AudioPlaybackRate &rate) {
-    // do some cursory validation of the settings here. audio modes are
-    // only validated when set on the audiosink.
-     if (rate.mSpeed < AUDIO_TIMESTRETCH_SPEED_MIN
-            || rate.mSpeed > AUDIO_TIMESTRETCH_SPEED_MAX
-            || rate.mPitch < AUDIO_TIMESTRETCH_SPEED_MIN
-            || rate.mPitch > AUDIO_TIMESTRETCH_SPEED_MAX) {
-        return BAD_VALUE;
-    }
-    sp<AMessage> msg = new AMessage(kWhatConfigPlayback, this);
-    writeToAMessage(msg, rate);
-    sp<AMessage> response;
-    status_t err = msg->postAndAwaitResponse(&response);
-    if (err == OK && response != NULL) {
-        CHECK(response->findInt32("err", &err));
-    }
-    return err;
-}
-
-status_t NuPlayer2::getPlaybackSettings(AudioPlaybackRate *rate /* nonnull */) {
-    sp<AMessage> msg = new AMessage(kWhatGetPlaybackSettings, this);
-    sp<AMessage> response;
-    status_t err = msg->postAndAwaitResponse(&response);
-    if (err == OK && response != NULL) {
-        CHECK(response->findInt32("err", &err));
-        if (err == OK) {
-            readFromAMessage(response, rate);
-        }
-    }
-    return err;
-}
-
-status_t NuPlayer2::setSyncSettings(const AVSyncSettings &sync, float videoFpsHint) {
-    sp<AMessage> msg = new AMessage(kWhatConfigSync, this);
-    writeToAMessage(msg, sync, videoFpsHint);
-    sp<AMessage> response;
-    status_t err = msg->postAndAwaitResponse(&response);
-    if (err == OK && response != NULL) {
-        CHECK(response->findInt32("err", &err));
-    }
-    return err;
-}
-
-status_t NuPlayer2::getSyncSettings(
-        AVSyncSettings *sync /* nonnull */, float *videoFps /* nonnull */) {
-    sp<AMessage> msg = new AMessage(kWhatGetSyncSettings, this);
-    sp<AMessage> response;
-    status_t err = msg->postAndAwaitResponse(&response);
-    if (err == OK && response != NULL) {
-        CHECK(response->findInt32("err", &err));
-        if (err == OK) {
-            readFromAMessage(response, sync, videoFps);
-        }
-    }
-    return err;
-}
-
-void NuPlayer2::pause() {
-    (new AMessage(kWhatPause, this))->post();
-}
-
-void NuPlayer2::resetAsync() {
-    disconnectSource();
-    (new AMessage(kWhatReset, this))->post();
-}
-
-void NuPlayer2::disconnectSource() {
-    sp<Source> source;
-    {
-        Mutex::Autolock autoLock(mSourceLock);
-        source = mCurrentSourceInfo.mSource;
-    }
-
-    if (source != NULL) {
-        // During a reset, the data source might be unresponsive already, we need to
-        // disconnect explicitly so that reads exit promptly.
-        // We can't queue the disconnect request to the looper, as it might be
-        // queued behind a stuck read and never gets processed.
-        // Doing a disconnect outside the looper to allows the pending reads to exit
-        // (either successfully or with error).
-        source->disconnect();
-    }
-
-}
-
-status_t NuPlayer2::notifyAt(int64_t mediaTimeUs) {
-    sp<AMessage> notify = new AMessage(kWhatNotifyTime, this);
-    notify->setInt64("timerUs", mediaTimeUs);
-    mMediaClock->addTimer(notify, mediaTimeUs);
-    return OK;
-}
-
-void NuPlayer2::seekToAsync(int64_t seekTimeUs, MediaPlayer2SeekMode mode, bool needNotify) {
-    sp<AMessage> msg = new AMessage(kWhatSeek, this);
-    msg->setInt64("seekTimeUs", seekTimeUs);
-    msg->setInt32("mode", mode);
-    msg->setInt32("needNotify", needNotify);
-    msg->post();
-}
-
-void NuPlayer2::rewind() {
-    sp<AMessage> msg = new AMessage(kWhatRewind, this);
-    msg->post();
-}
-
-void NuPlayer2::writeTrackInfo(
-        PlayerMessage* reply, const sp<AMessage>& format) const {
-    if (format == NULL) {
-        ALOGE("NULL format");
-        return;
-    }
-    int32_t trackType;
-    if (!format->findInt32("type", &trackType)) {
-        ALOGE("no track type");
-        return;
-    }
-
-    AString mime;
-    if (!format->findString("mime", &mime)) {
-        // Java MediaPlayer only uses mimetype for subtitle and timedtext tracks.
-        // If we can't find the mimetype here it means that we wouldn't be needing
-        // the mimetype on the Java end. We still write a placeholder mime to keep the
-        // (de)serialization logic simple.
-        if (trackType == MEDIA_TRACK_TYPE_AUDIO) {
-            mime = "audio/";
-        } else if (trackType == MEDIA_TRACK_TYPE_VIDEO) {
-            mime = "video/";
-        } else {
-            ALOGE("unknown track type: %d", trackType);
-            return;
-        }
-    }
-
-    AString lang;
-    if (!format->findString("language", &lang)) {
-        ALOGE("no language");
-        return;
-    }
-
-    reply->add_values()->set_int32_value(trackType);
-    reply->add_values()->set_string_value(mime.c_str());
-    reply->add_values()->set_string_value(lang.c_str());
-
-    if (trackType == MEDIA_TRACK_TYPE_SUBTITLE) {
-        int32_t isAuto, isDefault, isForced;
-        CHECK(format->findInt32("auto", &isAuto));
-        CHECK(format->findInt32("default", &isDefault));
-        CHECK(format->findInt32("forced", &isForced));
-
-        reply->add_values()->set_int32_value(isAuto);
-        reply->add_values()->set_int32_value(isDefault);
-        reply->add_values()->set_int32_value(isForced);
-    }
-}
-
-void NuPlayer2::onMessageReceived(const sp<AMessage> &msg) {
-
-    switch (msg->what()) {
-        case kWhatSetDataSource:
-        {
-            ALOGV("kWhatSetDataSource");
-
-            CHECK(mCurrentSourceInfo.mSource == NULL);
-
-            status_t err = OK;
-            sp<RefBase> obj;
-            CHECK(msg->findObject("source", &obj));
-            if (obj != NULL) {
-                Mutex::Autolock autoLock(mSourceLock);
-                CHECK(msg->findInt64("srcId", &mCurrentSourceInfo.mSrcId));
-                CHECK(msg->findInt64("startTimeUs", &mCurrentSourceInfo.mStartTimeUs));
-                CHECK(msg->findInt64("endTimeUs", &mCurrentSourceInfo.mEndTimeUs));
-                mCurrentSourceInfo.mSource = static_cast<Source *>(obj.get());
-            } else {
-                err = UNKNOWN_ERROR;
-                ALOGE("kWhatSetDataSource, source should not be NULL");
-            }
-
-            CHECK(mDriver != NULL);
-            sp<NuPlayer2Driver> driver = mDriver.promote();
-            if (driver != NULL) {
-                driver->notifySetDataSourceCompleted(mCurrentSourceInfo.mSrcId, err);
-            }
-            break;
-        }
-
-        case kWhatPrepareNextDataSource:
-        {
-            ALOGV("kWhatPrepareNextDataSource");
-
-            status_t err = OK;
-            sp<RefBase> obj;
-            CHECK(msg->findObject("source", &obj));
-            if (obj != NULL) {
-                Mutex::Autolock autoLock(mSourceLock);
-                CHECK(msg->findInt64("srcId", &mNextSourceInfo.mSrcId));
-                CHECK(msg->findInt64("startTimeUs", &mNextSourceInfo.mStartTimeUs));
-                CHECK(msg->findInt64("endTimeUs", &mNextSourceInfo.mEndTimeUs));
-                mNextSourceInfo.mSource = static_cast<Source *>(obj.get());
-                mNextSourceInfo.mSource->prepareAsync(mNextSourceInfo.mStartTimeUs);
-            } else {
-                err = UNKNOWN_ERROR;
-            }
-
-            break;
-        }
-
-        case kWhatPlayNextDataSource:
-        {
-            ALOGV("kWhatPlayNextDataSource");
-            int64_t srcId;
-            CHECK(msg->findInt64("srcId", &srcId));
-            if (srcId != mNextSourceInfo.mSrcId) {
-                notifyListener(srcId, MEDIA2_ERROR, MEDIA2_ERROR_UNKNOWN, 0);
-                return;
-            }
-
-            mResetting = true;
-            stopPlaybackTimer("kWhatPlayNextDataSource");
-            stopRebufferingTimer(true);
-
-            mDeferredActions.push_back(
-                    new FlushDecoderAction(
-                        FLUSH_CMD_SHUTDOWN /* audio */,
-                        FLUSH_CMD_SHUTDOWN /* video */));
-
-            mDeferredActions.push_back(
-                    new SimpleAction(&NuPlayer2::performPlayNextDataSource));
-
-            processDeferredActions();
-            break;
-        }
-
-        case kWhatEOSMonitor:
-        {
-            int32_t generation;
-            CHECK(msg->findInt32("generation", &generation));
-            int32_t reason;
-            CHECK(msg->findInt32("reason", &reason));
-
-            if (generation != mEOSMonitorGeneration || reason != MediaClock::TIMER_REASON_REACHED) {
-                break;  // stale or reset
-            }
-
-            ALOGV("kWhatEOSMonitor");
-            notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_PLAYBACK_COMPLETE, 0, 0);
-            break;
-        }
-
-        case kWhatGetBufferingSettings:
-        {
-            sp<AReplyToken> replyID;
-            CHECK(msg->senderAwaitsResponse(&replyID));
-
-            ALOGV("kWhatGetBufferingSettings");
-            BufferingSettings buffering;
-            status_t err = OK;
-            if (mCurrentSourceInfo.mSource != NULL) {
-                err = mCurrentSourceInfo.mSource->getBufferingSettings(&buffering);
-            } else {
-                err = INVALID_OPERATION;
-            }
-            sp<AMessage> response = new AMessage;
-            if (err == OK) {
-                writeToAMessage(response, buffering);
-            }
-            response->setInt32("err", err);
-            response->postReply(replyID);
-            break;
-        }
-
-        case kWhatSetBufferingSettings:
-        {
-            sp<AReplyToken> replyID;
-            CHECK(msg->senderAwaitsResponse(&replyID));
-
-            ALOGV("kWhatSetBufferingSettings");
-            BufferingSettings buffering;
-            readFromAMessage(msg, &buffering);
-            status_t err = OK;
-            if (mCurrentSourceInfo.mSource != NULL) {
-                err = mCurrentSourceInfo.mSource->setBufferingSettings(buffering);
-            } else {
-                err = INVALID_OPERATION;
-            }
-            sp<AMessage> response = new AMessage;
-            response->setInt32("err", err);
-            response->postReply(replyID);
-            break;
-        }
-
-        case kWhatPrepare:
-        {
-            ALOGV("onMessageReceived kWhatPrepare");
-
-            mCurrentSourceInfo.mSource->prepareAsync(mCurrentSourceInfo.mStartTimeUs);
-            break;
-        }
-
-        case kWhatGetTrackInfo:
-        {
-            sp<AReplyToken> replyID;
-            CHECK(msg->senderAwaitsResponse(&replyID));
-
-            int64_t srcId;
-            CHECK(msg->findInt64("srcId", (int64_t*)&srcId));
-
-            PlayerMessage* reply;
-            CHECK(msg->findPointer("reply", (void**)&reply));
-
-            // TODO: use correct source info based on srcId.
-            size_t inbandTracks = 0;
-            if (mCurrentSourceInfo.mSource != NULL) {
-                inbandTracks = mCurrentSourceInfo.mSource->getTrackCount();
-            }
-
-            size_t ccTracks = 0;
-            if (mCCDecoder != NULL) {
-                ccTracks = mCCDecoder->getTrackCount();
-            }
-
-            // total track count
-            reply->add_values()->set_int32_value(inbandTracks + ccTracks);
-
-            // write inband tracks
-            for (size_t i = 0; i < inbandTracks; ++i) {
-                writeTrackInfo(reply, mCurrentSourceInfo.mSource->getTrackInfo(i));
-            }
-
-            // write CC track
-            for (size_t i = 0; i < ccTracks; ++i) {
-                writeTrackInfo(reply, mCCDecoder->getTrackInfo(i));
-            }
-
-            sp<AMessage> response = new AMessage;
-            response->postReply(replyID);
-            break;
-        }
-
-        case kWhatGetSelectedTrack:
-        {
-            int64_t srcId;
-            CHECK(msg->findInt64("srcId", (int64_t*)&srcId));
-
-            int32_t type32;
-            CHECK(msg->findInt32("type", (int32_t*)&type32));
-            media_track_type type = (media_track_type)type32;
-
-            // TODO: use correct source info based on srcId.
-            size_t inbandTracks = 0;
-            status_t err = INVALID_OPERATION;
-            ssize_t selectedTrack = -1;
-            if (mCurrentSourceInfo.mSource != NULL) {
-                err = OK;
-                inbandTracks = mCurrentSourceInfo.mSource->getTrackCount();
-                selectedTrack = mCurrentSourceInfo.mSource->getSelectedTrack(type);
-            }
-
-            if (selectedTrack == -1 && mCCDecoder != NULL) {
-                err = OK;
-                selectedTrack = mCCDecoder->getSelectedTrack(type);
-                if (selectedTrack != -1) {
-                    selectedTrack += inbandTracks;
-                }
-            }
-
-            PlayerMessage* reply;
-            CHECK(msg->findPointer("reply", (void**)&reply));
-            reply->add_values()->set_int32_value(selectedTrack);
-
-            sp<AMessage> response = new AMessage;
-            response->setInt32("err", err);
-
-            sp<AReplyToken> replyID;
-            CHECK(msg->senderAwaitsResponse(&replyID));
-            response->postReply(replyID);
-            break;
-        }
-
-        case kWhatSelectTrack:
-        {
-            sp<AReplyToken> replyID;
-            CHECK(msg->senderAwaitsResponse(&replyID));
-
-            int64_t srcId;
-            size_t trackIndex;
-            int32_t select;
-            int64_t timeUs;
-            CHECK(msg->findInt64("srcId", (int64_t*)&srcId));
-            CHECK(msg->findSize("trackIndex", &trackIndex));
-            CHECK(msg->findInt32("select", &select));
-            CHECK(msg->findInt64("timeUs", &timeUs));
-
-            status_t err = INVALID_OPERATION;
-
-            // TODO: use correct source info based on srcId.
-            size_t inbandTracks = 0;
-            if (mCurrentSourceInfo.mSource != NULL) {
-                inbandTracks = mCurrentSourceInfo.mSource->getTrackCount();
-            }
-            size_t ccTracks = 0;
-            if (mCCDecoder != NULL) {
-                ccTracks = mCCDecoder->getTrackCount();
-            }
-
-            if (trackIndex < inbandTracks) {
-                err = mCurrentSourceInfo.mSource->selectTrack(trackIndex, select, timeUs);
-
-                if (!select && err == OK) {
-                    int32_t type;
-                    sp<AMessage> info = mCurrentSourceInfo.mSource->getTrackInfo(trackIndex);
-                    if (info != NULL
-                            && info->findInt32("type", &type)
-                            && type == MEDIA_TRACK_TYPE_TIMEDTEXT) {
-                        ++mTimedTextGeneration;
-                    }
-                }
-            } else {
-                trackIndex -= inbandTracks;
-
-                if (trackIndex < ccTracks) {
-                    err = mCCDecoder->selectTrack(trackIndex, select);
-                }
-            }
-
-            sp<AMessage> response = new AMessage;
-            response->setInt32("err", err);
-
-            response->postReply(replyID);
-            break;
-        }
-
-        case kWhatPollDuration:
-        {
-            int32_t generation;
-            CHECK(msg->findInt32("generation", &generation));
-
-            if (generation != mPollDurationGeneration) {
-                // stale
-                break;
-            }
-
-            int64_t durationUs;
-            if (mDriver != NULL && mCurrentSourceInfo.mSource->getDuration(&durationUs) == OK) {
-                sp<NuPlayer2Driver> driver = mDriver.promote();
-                if (driver != NULL) {
-                    driver->notifyDuration(mCurrentSourceInfo.mSrcId, durationUs);
-                }
-            }
-
-            msg->post(1000000LL);  // poll again in a second.
-            break;
-        }
-
-        case kWhatSetVideoSurface:
-        {
-
-            sp<RefBase> obj;
-            CHECK(msg->findObject("surface", &obj));
-            sp<ANativeWindowWrapper> nww = static_cast<ANativeWindowWrapper *>(obj.get());
-
-            ALOGD("onSetVideoSurface(%p, %s video decoder)",
-                    (nww == NULL ? NULL : nww->getANativeWindow()),
-                    (mCurrentSourceInfo.mSource != NULL && mStarted
-                            && mCurrentSourceInfo.mSource->getFormat(false /* audio */) != NULL
-                            && mVideoDecoder != NULL) ? "have" : "no");
-
-            // Need to check mStarted before calling mCurrentSourceInfo.mSource->getFormat
-            // because NuPlayer2 might be in preparing state and it could take long time.
-            // When mStarted is true, mCurrentSourceInfo.mSource must have been set.
-            if (mCurrentSourceInfo.mSource == NULL || !mStarted
-                    || mCurrentSourceInfo.mSource->getFormat(false /* audio */) == NULL
-                    // NOTE: mVideoDecoder's mNativeWindow is always non-null
-                    || (mVideoDecoder != NULL && mVideoDecoder->setVideoSurface(nww) == OK)) {
-                performSetSurface(nww);
-                break;
-            }
-
-            mDeferredActions.push_back(
-                    new FlushDecoderAction(
-                            (obj != NULL ? FLUSH_CMD_FLUSH : FLUSH_CMD_NONE) /* audio */,
-                                           FLUSH_CMD_SHUTDOWN /* video */));
-
-            mDeferredActions.push_back(new SetSurfaceAction(nww));
-
-            if (obj != NULL) {
-                if (mStarted) {
-                    // Issue a seek to refresh the video screen only if started otherwise
-                    // the extractor may not yet be started and will assert.
-                    // If the video decoder is not set (perhaps audio only in this case)
-                    // do not perform a seek as it is not needed.
-                    int64_t currentPositionUs = 0;
-                    if (getCurrentPosition(&currentPositionUs) == OK) {
-                        mDeferredActions.push_back(
-                                new SeekAction(currentPositionUs,
-                                        MediaPlayer2SeekMode::SEEK_PREVIOUS_SYNC /* mode */));
-                    }
-                }
-
-                // If there is a new surface texture, instantiate decoders
-                // again if possible.
-                mDeferredActions.push_back(
-                        new SimpleAction(&NuPlayer2::performScanSources));
-
-                // After a flush without shutdown, decoder is paused.
-                // Don't resume it until source seek is done, otherwise it could
-                // start pulling stale data too soon.
-                mDeferredActions.push_back(
-                        new ResumeDecoderAction(false /* needNotify */));
-            }
-
-            processDeferredActions();
-            break;
-        }
-
-        case kWhatSetAudioSink:
-        {
-            ALOGV("kWhatSetAudioSink");
-
-            sp<RefBase> obj;
-            CHECK(msg->findObject("sink", &obj));
-
-            mAudioSink = static_cast<MediaPlayer2Interface::AudioSink *>(obj.get());
-            break;
-        }
-
-        case kWhatStart:
-        {
-            ALOGV("kWhatStart");
-            if (mStarted) {
-                // do not resume yet if the source is still buffering
-                if (!mPausedForBuffering) {
-                    onResume();
-                }
-            } else {
-                onStart(true /* play */);
-            }
-            mPausedByClient = false;
-            notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_STARTED, 0, 0);
-            break;
-        }
-
-        case kWhatConfigPlayback:
-        {
-            sp<AReplyToken> replyID;
-            CHECK(msg->senderAwaitsResponse(&replyID));
-            AudioPlaybackRate rate /* sanitized */;
-            readFromAMessage(msg, &rate);
-            status_t err = OK;
-            if (mRenderer != NULL) {
-                // AudioSink allows only 1.f and 0.f for offload mode.
-                // For other speed, switch to non-offload mode.
-                if (mOffloadAudio && (rate.mSpeed != 1.f || rate.mPitch != 1.f)) {
-                    int64_t currentPositionUs;
-                    if (getCurrentPosition(&currentPositionUs) != OK) {
-                        currentPositionUs = mPreviousSeekTimeUs;
-                    }
-
-                    // Set mPlaybackSettings so that the new audio decoder can
-                    // be created correctly.
-                    mPlaybackSettings = rate;
-                    if (!mPaused) {
-                        mRenderer->pause();
-                    }
-                    restartAudio(
-                            currentPositionUs, true /* forceNonOffload */,
-                            true /* needsToCreateAudioDecoder */);
-                    if (!mPaused) {
-                        mRenderer->resume();
-                    }
-                }
-
-                err = mRenderer->setPlaybackSettings(rate);
-            }
-            if (err == OK) {
-                mPlaybackSettings = rate;
-
-                if (mVideoDecoder != NULL) {
-                    sp<AMessage> params = new AMessage();
-                    params->setFloat("playback-speed", mPlaybackSettings.mSpeed);
-                    mVideoDecoder->setParameters(params);
-                }
-            }
-
-            sp<AMessage> response = new AMessage;
-            response->setInt32("err", err);
-            response->postReply(replyID);
-            break;
-        }
-
-        case kWhatGetPlaybackSettings:
-        {
-            sp<AReplyToken> replyID;
-            CHECK(msg->senderAwaitsResponse(&replyID));
-            AudioPlaybackRate rate = mPlaybackSettings;
-            status_t err = OK;
-            if (mRenderer != NULL) {
-                err = mRenderer->getPlaybackSettings(&rate);
-            }
-            if (err == OK) {
-                // get playback settings used by renderer, as it may be
-                // slightly off due to audiosink not taking small changes.
-                mPlaybackSettings = rate;
-            }
-            sp<AMessage> response = new AMessage;
-            if (err == OK) {
-                writeToAMessage(response, rate);
-            }
-            response->setInt32("err", err);
-            response->postReply(replyID);
-            break;
-        }
-
-        case kWhatConfigSync:
-        {
-            sp<AReplyToken> replyID;
-            CHECK(msg->senderAwaitsResponse(&replyID));
-
-            ALOGV("kWhatConfigSync");
-            AVSyncSettings sync;
-            float videoFpsHint;
-            readFromAMessage(msg, &sync, &videoFpsHint);
-            status_t err = OK;
-            if (mRenderer != NULL) {
-                err = mRenderer->setSyncSettings(sync, videoFpsHint);
-            }
-            if (err == OK) {
-                mSyncSettings = sync;
-                mVideoFpsHint = videoFpsHint;
-            }
-            sp<AMessage> response = new AMessage;
-            response->setInt32("err", err);
-            response->postReply(replyID);
-            break;
-        }
-
-        case kWhatGetSyncSettings:
-        {
-            sp<AReplyToken> replyID;
-            CHECK(msg->senderAwaitsResponse(&replyID));
-            AVSyncSettings sync = mSyncSettings;
-            float videoFps = mVideoFpsHint;
-            status_t err = OK;
-            if (mRenderer != NULL) {
-                err = mRenderer->getSyncSettings(&sync, &videoFps);
-                if (err == OK) {
-                    mSyncSettings = sync;
-                    mVideoFpsHint = videoFps;
-                }
-            }
-            sp<AMessage> response = new AMessage;
-            if (err == OK) {
-                writeToAMessage(response, sync, videoFps);
-            }
-            response->setInt32("err", err);
-            response->postReply(replyID);
-            break;
-        }
-
-        case kWhatScanSources:
-        {
-            int32_t generation;
-            CHECK(msg->findInt32("generation", &generation));
-            if (generation != mScanSourcesGeneration) {
-                // Drop obsolete msg.
-                break;
-            }
-
-            mScanSourcesPending = false;
-
-            ALOGV("scanning sources haveAudio=%d, haveVideo=%d",
-                 mAudioDecoder != NULL, mVideoDecoder != NULL);
-
-            bool mHadAnySourcesBefore =
-                (mAudioDecoder != NULL) || (mVideoDecoder != NULL);
-            bool rescan = false;
-
-            // initialize video before audio because successful initialization of
-            // video may change deep buffer mode of audio.
-            if (mNativeWindow != NULL && mNativeWindow->getANativeWindow() != NULL) {
-                if (instantiateDecoder(false, &mVideoDecoder) == -EWOULDBLOCK) {
-                    rescan = true;
-                }
-            }
-
-            // Don't try to re-open audio sink if there's an existing decoder.
-            if (mAudioSink != NULL && mAudioDecoder == NULL) {
-                if (instantiateDecoder(true, &mAudioDecoder) == -EWOULDBLOCK) {
-                    rescan = true;
-                }
-            }
-
-            if (!mHadAnySourcesBefore
-                    && (mAudioDecoder != NULL || mVideoDecoder != NULL)) {
-                // This is the first time we've found anything playable.
-
-                if (mCurrentSourceInfo.mSourceFlags & Source::FLAG_DYNAMIC_DURATION) {
-                    schedulePollDuration();
-                }
-            }
-
-            status_t err;
-            if ((err = mCurrentSourceInfo.mSource->feedMoreTSData()) != OK) {
-                if (mAudioDecoder == NULL && mVideoDecoder == NULL) {
-                    // We're not currently decoding anything (no audio or
-                    // video tracks found) and we just ran out of input data.
-
-                    if (err == ERROR_END_OF_STREAM) {
-                        notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_PLAYBACK_COMPLETE, 0, 0);
-                    } else {
-                        notifyListener(
-                                mCurrentSourceInfo.mSrcId, MEDIA2_ERROR, MEDIA2_ERROR_UNKNOWN, err);
-                    }
-                }
-                break;
-            }
-
-            if (rescan) {
-                msg->post(100000LL);
-                mScanSourcesPending = true;
-            }
-            break;
-        }
-
-        case kWhatVideoNotify:
-        case kWhatAudioNotify:
-        {
-            bool audio = msg->what() == kWhatAudioNotify;
-
-            int32_t currentDecoderGeneration =
-                (audio? mAudioDecoderGeneration : mVideoDecoderGeneration);
-            int32_t requesterGeneration = currentDecoderGeneration - 1;
-            CHECK(msg->findInt32("generation", &requesterGeneration));
-
-            if (requesterGeneration != currentDecoderGeneration) {
-                ALOGV("got message from old %s decoder, generation(%d:%d)",
-                        audio ? "audio" : "video", requesterGeneration,
-                        currentDecoderGeneration);
-                sp<AMessage> reply;
-                if (!(msg->findMessage("reply", &reply))) {
-                    return;
-                }
-
-                reply->setInt32("err", INFO_DISCONTINUITY);
-                reply->post();
-                return;
-            }
-
-            int32_t what;
-            CHECK(msg->findInt32("what", &what));
-
-            if (what == DecoderBase::kWhatInputDiscontinuity) {
-                int32_t formatChange;
-                CHECK(msg->findInt32("formatChange", &formatChange));
-
-                ALOGV("%s discontinuity: formatChange %d",
-                        audio ? "audio" : "video", formatChange);
-
-                if (formatChange) {
-                    mDeferredActions.push_back(
-                            new FlushDecoderAction(
-                                audio ? FLUSH_CMD_SHUTDOWN : FLUSH_CMD_NONE,
-                                audio ? FLUSH_CMD_NONE : FLUSH_CMD_SHUTDOWN));
-                }
-
-                mDeferredActions.push_back(
-                        new SimpleAction(
-                                &NuPlayer2::performScanSources));
-
-                processDeferredActions();
-            } else if (what == DecoderBase::kWhatEOS) {
-                int32_t err;
-                CHECK(msg->findInt32("err", &err));
-
-                if (err == ERROR_END_OF_STREAM) {
-                    ALOGV("got %s decoder EOS", audio ? "audio" : "video");
-                } else {
-                    ALOGV("got %s decoder EOS w/ error %d",
-                         audio ? "audio" : "video",
-                         err);
-                }
-
-                mRenderer->queueEOS(audio, err);
-            } else if (what == DecoderBase::kWhatFlushCompleted) {
-                ALOGV("decoder %s flush completed", audio ? "audio" : "video");
-
-                handleFlushComplete(audio, true /* isDecoder */);
-                finishFlushIfPossible();
-            } else if (what == DecoderBase::kWhatVideoSizeChanged) {
-                sp<AMessage> format;
-                CHECK(msg->findMessage("format", &format));
-
-                sp<AMessage> inputFormat =
-                        mCurrentSourceInfo.mSource->getFormat(false /* audio */);
-
-                setVideoScalingMode(mVideoScalingMode);
-                updateVideoSize(mCurrentSourceInfo.mSrcId, inputFormat, format);
-            } else if (what == DecoderBase::kWhatShutdownCompleted) {
-                ALOGV("%s shutdown completed", audio ? "audio" : "video");
-                if (audio) {
-                    Mutex::Autolock autoLock(mDecoderLock);
-                    mAudioDecoder.clear();
-                    mAudioDecoderError = false;
-                    ++mAudioDecoderGeneration;
-
-                    CHECK_EQ((int)mFlushingAudio, (int)SHUTTING_DOWN_DECODER);
-                    mFlushingAudio = SHUT_DOWN;
-                } else {
-                    Mutex::Autolock autoLock(mDecoderLock);
-                    mVideoDecoder.clear();
-                    mVideoDecoderError = false;
-                    ++mVideoDecoderGeneration;
-
-                    CHECK_EQ((int)mFlushingVideo, (int)SHUTTING_DOWN_DECODER);
-                    mFlushingVideo = SHUT_DOWN;
-                }
-
-                finishFlushIfPossible();
-            } else if (what == DecoderBase::kWhatResumeCompleted) {
-                finishResume();
-            } else if (what == DecoderBase::kWhatError) {
-                status_t err;
-                if (!msg->findInt32("err", &err) || err == OK) {
-                    err = UNKNOWN_ERROR;
-                }
-
-                // Decoder errors can be due to Source (e.g. from streaming),
-                // or from decoding corrupted bitstreams, or from other decoder
-                // MediaCodec operations (e.g. from an ongoing reset or seek).
-                // They may also be due to openAudioSink failure at
-                // decoder start or after a format change.
-                //
-                // We try to gracefully shut down the affected decoder if possible,
-                // rather than trying to force the shutdown with something
-                // similar to performReset(). This method can lead to a hang
-                // if MediaCodec functions block after an error, but they should
-                // typically return INVALID_OPERATION instead of blocking.
-
-                FlushStatus *flushing = audio ? &mFlushingAudio : &mFlushingVideo;
-                ALOGE("received error(%#x) from %s decoder, flushing(%d), now shutting down",
-                        err, audio ? "audio" : "video", *flushing);
-
-                switch (*flushing) {
-                    case NONE:
-                        mDeferredActions.push_back(
-                                new FlushDecoderAction(
-                                    audio ? FLUSH_CMD_SHUTDOWN : FLUSH_CMD_NONE,
-                                    audio ? FLUSH_CMD_NONE : FLUSH_CMD_SHUTDOWN));
-                        processDeferredActions();
-                        break;
-                    case FLUSHING_DECODER:
-                        *flushing = FLUSHING_DECODER_SHUTDOWN; // initiate shutdown after flush.
-                        break; // Wait for flush to complete.
-                    case FLUSHING_DECODER_SHUTDOWN:
-                        break; // Wait for flush to complete.
-                    case SHUTTING_DOWN_DECODER:
-                        break; // Wait for shutdown to complete.
-                    case FLUSHED:
-                        getDecoder(audio)->initiateShutdown(); // In the middle of a seek.
-                        *flushing = SHUTTING_DOWN_DECODER;     // Shut down.
-                        break;
-                    case SHUT_DOWN:
-                        finishFlushIfPossible();  // Should not occur.
-                        break;                    // Finish anyways.
-                }
-                if (mCurrentSourceInfo.mSource != nullptr) {
-                    if (audio) {
-                        if (mVideoDecoderError
-                                || mCurrentSourceInfo.mSource->getFormat(false /* audio */) == NULL
-                                || mNativeWindow == NULL
-                                || mNativeWindow->getANativeWindow() == NULL
-                                || mVideoDecoder == NULL) {
-                            // When both audio and video have error, or this stream has only audio
-                            // which has error, notify client of error.
-                            notifyListener(
-                                    mCurrentSourceInfo.mSrcId, MEDIA2_ERROR,
-                                    MEDIA2_ERROR_UNKNOWN, err);
-                        } else {
-                            // Only audio track has error. Video track could be still good to play.
-                            notifyListener(
-                                    mCurrentSourceInfo.mSrcId, MEDIA2_INFO,
-                                    MEDIA2_INFO_PLAY_AUDIO_ERROR, err);
-                        }
-                        mAudioDecoderError = true;
-                    } else {
-                        if (mAudioDecoderError
-                                || mCurrentSourceInfo.mSource->getFormat(true /* audio */) == NULL
-                                || mAudioSink == NULL || mAudioDecoder == NULL) {
-                            // When both audio and video have error, or this stream has only video
-                            // which has error, notify client of error.
-                            notifyListener(
-                                    mCurrentSourceInfo.mSrcId, MEDIA2_ERROR,
-                                    MEDIA2_ERROR_UNKNOWN, err);
-                        } else {
-                            // Only video track has error. Audio track could be still good to play.
-                            notifyListener(
-                                    mCurrentSourceInfo.mSrcId, MEDIA2_INFO,
-                                    MEDIA2_INFO_PLAY_VIDEO_ERROR, err);
-                        }
-                        mVideoDecoderError = true;
-                    }
-                }
-            } else {
-                ALOGV("Unhandled decoder notification %d '%c%c%c%c'.",
-                      what,
-                      what >> 24,
-                      (what >> 16) & 0xff,
-                      (what >> 8) & 0xff,
-                      what & 0xff);
-            }
-
-            break;
-        }
-
-        case kWhatRendererNotify:
-        {
-            int32_t requesterGeneration = mRendererGeneration - 1;
-            CHECK(msg->findInt32("generation", &requesterGeneration));
-            if (requesterGeneration != mRendererGeneration) {
-                ALOGV("got message from old renderer, generation(%d:%d)",
-                        requesterGeneration, mRendererGeneration);
-                return;
-            }
-
-            int32_t what;
-            CHECK(msg->findInt32("what", &what));
-
-            if (what == Renderer::kWhatEOS) {
-                int32_t audio;
-                CHECK(msg->findInt32("audio", &audio));
-
-                int32_t finalResult;
-                CHECK(msg->findInt32("finalResult", &finalResult));
-
-                if (audio) {
-                    mAudioEOS = true;
-                } else {
-                    mVideoEOS = true;
-                }
-
-                if (finalResult == ERROR_END_OF_STREAM) {
-                    ALOGV("reached %s EOS", audio ? "audio" : "video");
-                } else {
-                    ALOGE("%s track encountered an error (%d)",
-                         audio ? "audio" : "video", finalResult);
-
-                    notifyListener(
-                            mCurrentSourceInfo.mSrcId, MEDIA2_ERROR,
-                            MEDIA2_ERROR_UNKNOWN, finalResult);
-                }
-
-                if ((mAudioEOS || mAudioDecoder == NULL)
-                        && (mVideoEOS || mVideoDecoder == NULL)) {
-                    notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_PLAYBACK_COMPLETE, 0, 0);
-                }
-            } else if (what == Renderer::kWhatFlushComplete) {
-                int32_t audio;
-                CHECK(msg->findInt32("audio", &audio));
-
-                if (audio) {
-                    mAudioEOS = false;
-                } else {
-                    mVideoEOS = false;
-                }
-
-                ALOGV("renderer %s flush completed.", audio ? "audio" : "video");
-                if (audio && (mFlushingAudio == NONE || mFlushingAudio == FLUSHED
-                        || mFlushingAudio == SHUT_DOWN)) {
-                    // Flush has been handled by tear down.
-                    break;
-                }
-                handleFlushComplete(audio, false /* isDecoder */);
-                finishFlushIfPossible();
-            } else if (what == Renderer::kWhatVideoRenderingStart) {
-                notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_INFO,
-                               MEDIA2_INFO_VIDEO_RENDERING_START, 0);
-            } else if (what == Renderer::kWhatMediaRenderingStart) {
-                ALOGV("media rendering started");
-                notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_STARTED, 0, 0);
-            } else if (what == Renderer::kWhatAudioTearDown) {
-                int32_t reason;
-                CHECK(msg->findInt32("reason", &reason));
-                ALOGV("Tear down audio with reason %d.", reason);
-                if (reason == Renderer::kDueToTimeout && !(mPaused && mOffloadAudio)) {
-                    // TimeoutWhenPaused is only for offload mode.
-                    ALOGW("Receive a stale message for teardown.");
-                    break;
-                }
-                int64_t positionUs;
-                if (!msg->findInt64("positionUs", &positionUs)) {
-                    positionUs = mPreviousSeekTimeUs;
-                }
-
-                restartAudio(
-                        positionUs, reason == Renderer::kForceNonOffload /* forceNonOffload */,
-                        reason != Renderer::kDueToTimeout /* needsToCreateAudioDecoder */);
-            }
-            break;
-        }
-
-        case kWhatMoreDataQueued:
-        {
-            break;
-        }
-
-        case kWhatReset:
-        {
-            ALOGV("kWhatReset");
-
-            mResetting = true;
-            stopPlaybackTimer("kWhatReset");
-            stopRebufferingTimer(true);
-
-            mDeferredActions.push_back(
-                    new FlushDecoderAction(
-                        FLUSH_CMD_SHUTDOWN /* audio */,
-                        FLUSH_CMD_SHUTDOWN /* video */));
-
-            mDeferredActions.push_back(
-                    new SimpleAction(&NuPlayer2::performReset));
-
-            processDeferredActions();
-            break;
-        }
-
-        case kWhatNotifyTime:
-        {
-            ALOGV("kWhatNotifyTime");
-            int64_t timerUs;
-            CHECK(msg->findInt64("timerUs", &timerUs));
-
-            notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_NOTIFY_TIME, timerUs, 0);
-            break;
-        }
-
-        case kWhatSeek:
-        {
-            int64_t seekTimeUs;
-            int32_t mode;
-            int32_t needNotify;
-            CHECK(msg->findInt64("seekTimeUs", &seekTimeUs));
-            CHECK(msg->findInt32("mode", &mode));
-            CHECK(msg->findInt32("needNotify", &needNotify));
-
-            ALOGV("kWhatSeek seekTimeUs=%lld us, mode=%d, needNotify=%d",
-                    (long long)seekTimeUs, mode, needNotify);
-
-            if (!mStarted) {
-                if (!mSourceStarted) {
-                    mSourceStarted = true;
-                    mCurrentSourceInfo.mSource->start();
-                }
-                if (seekTimeUs > 0) {
-                    performSeek(seekTimeUs, (MediaPlayer2SeekMode)mode);
-                }
-
-                if (needNotify) {
-                    notifyDriverSeekComplete(mCurrentSourceInfo.mSrcId);
-                }
-                break;
-            }
-
-            // seeks can take a while, so we essentially paused
-            notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_PAUSED, 0, 0);
-
-            mDeferredActions.push_back(
-                    new FlushDecoderAction(FLUSH_CMD_FLUSH /* audio */,
-                                           FLUSH_CMD_FLUSH /* video */));
-
-            mDeferredActions.push_back(
-                    new SeekAction(seekTimeUs, (MediaPlayer2SeekMode)mode));
-
-            // After a flush without shutdown, decoder is paused.
-            // Don't resume it until source seek is done, otherwise it could
-            // start pulling stale data too soon.
-            mDeferredActions.push_back(
-                    new ResumeDecoderAction(needNotify));
-
-            processDeferredActions();
-            break;
-        }
-
-        case kWhatRewind:
-        {
-            ALOGV("kWhatRewind");
-
-            int64_t seekTimeUs = mCurrentSourceInfo.mStartTimeUs;
-            int32_t mode = MediaPlayer2SeekMode::SEEK_CLOSEST;
-
-            if (!mStarted) {
-                if (!mSourceStarted) {
-                    mSourceStarted = true;
-                    mCurrentSourceInfo.mSource->start();
-                }
-                performSeek(seekTimeUs, (MediaPlayer2SeekMode)mode);
-                break;
-            }
-
-            // seeks can take a while, so we essentially paused
-            notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_PAUSED, 0, 0);
-
-            mDeferredActions.push_back(
-                    new FlushDecoderAction(FLUSH_CMD_FLUSH /* audio */,
-                                           FLUSH_CMD_FLUSH /* video */));
-
-            mDeferredActions.push_back(
-                    new SeekAction(seekTimeUs, (MediaPlayer2SeekMode)mode));
-
-            // After a flush without shutdown, decoder is paused.
-            // Don't resume it until source seek is done, otherwise it could
-            // start pulling stale data too soon.
-            mDeferredActions.push_back(
-                    new ResumeDecoderAction(false /* needNotify */));
-
-            processDeferredActions();
-            break;
-        }
-
-        case kWhatPause:
-        {
-            if (!mStarted) {
-                onStart(false /* play */);
-            }
-            onPause();
-            notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_PAUSED, 0, 0);
-            mPausedByClient = true;
-            break;
-        }
-
-        case kWhatSourceNotify:
-        {
-            onSourceNotify(msg);
-            break;
-        }
-
-        case kWhatClosedCaptionNotify:
-        {
-            onClosedCaptionNotify(msg);
-            break;
-        }
-
-        case kWhatPrepareDrm:
-        {
-            status_t status = onPrepareDrm(msg);
-
-            sp<AMessage> response = new AMessage;
-            response->setInt32("status", status);
-            sp<AReplyToken> replyID;
-            CHECK(msg->senderAwaitsResponse(&replyID));
-            response->postReply(replyID);
-            break;
-        }
-
-        case kWhatReleaseDrm:
-        {
-            status_t status = onReleaseDrm(msg);
-
-            sp<AMessage> response = new AMessage;
-            response->setInt32("status", status);
-            sp<AReplyToken> replyID;
-            CHECK(msg->senderAwaitsResponse(&replyID));
-            response->postReply(replyID);
-            break;
-        }
-
-        default:
-            TRESPASS();
-            break;
-    }
-}
-
-void NuPlayer2::onResume() {
-    if (!mPaused || mResetting) {
-        ALOGD_IF(mResetting, "resetting, onResume discarded");
-        return;
-    }
-    mPaused = false;
-    if (mCurrentSourceInfo.mSource != NULL) {
-        mCurrentSourceInfo.mSource->resume();
-    } else {
-        ALOGW("resume called when source is gone or not set");
-    }
-    // |mAudioDecoder| may have been released due to the pause timeout, so re-create it if
-    // needed.
-    if (audioDecoderStillNeeded() && mAudioDecoder == NULL) {
-        instantiateDecoder(true /* audio */, &mAudioDecoder);
-    }
-    if (mRenderer != NULL) {
-        mRenderer->resume();
-    } else {
-        ALOGW("resume called when renderer is gone or not set");
-    }
-
-    startPlaybackTimer("onresume");
-}
-
-void NuPlayer2::onStart(bool play) {
-    ALOGV("onStart: mCrypto: %p", mCurrentSourceInfo.mCrypto.get());
-
-    if (!mSourceStarted) {
-        mSourceStarted = true;
-        mCurrentSourceInfo.mSource->start();
-    }
-
-    mOffloadAudio = false;
-    mAudioEOS = false;
-    mVideoEOS = false;
-    mStarted = true;
-    mPaused = false;
-
-    uint32_t flags = 0;
-
-    if (mCurrentSourceInfo.mSource->isRealTime()) {
-        flags |= Renderer::FLAG_REAL_TIME;
-    }
-
-    bool hasAudio = (mCurrentSourceInfo.mSource->getFormat(true /* audio */) != NULL);
-    bool hasVideo = (mCurrentSourceInfo.mSource->getFormat(false /* audio */) != NULL);
-    if (!hasAudio && !hasVideo) {
-        ALOGE("no metadata for either audio or video source");
-        mCurrentSourceInfo.mSource->stop();
-        mSourceStarted = false;
-        notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_ERROR,
-                       MEDIA2_ERROR_UNKNOWN, ERROR_MALFORMED);
-        return;
-    }
-    ALOGV_IF(!hasAudio, "no metadata for audio source");  // video only stream
-
-    sp<MetaData> audioMeta = mCurrentSourceInfo.mSource->getFormatMeta(true /* audio */);
-
-    audio_stream_type_t streamType = AUDIO_STREAM_MUSIC;
-    if (mAudioSink != NULL) {
-        streamType = mAudioSink->getAudioStreamType();
-    }
-
-    mOffloadAudio =
-        JMediaPlayer2Utils::isOffloadedAudioPlaybackSupported(
-                audioMeta, hasVideo, mCurrentSourceInfo.mSource->isStreaming(), streamType)
-                && (mPlaybackSettings.mSpeed == 1.f && mPlaybackSettings.mPitch == 1.f);
-
-    // Modular DRM: Disabling audio offload if the source is protected
-    if (mOffloadAudio && mCurrentSourceInfo.mIsDrmProtected) {
-        mOffloadAudio = false;
-        ALOGV("onStart: Disabling mOffloadAudio now that the source is protected.");
-    }
-
-    if (mOffloadAudio) {
-        flags |= Renderer::FLAG_OFFLOAD_AUDIO;
-    }
-
-    sp<AMessage> notify = new AMessage(kWhatRendererNotify, this);
-    ++mRendererGeneration;
-    notify->setInt32("generation", mRendererGeneration);
-    mRenderer = new Renderer(mAudioSink, mMediaClock, notify, mContext, flags);
-    mRendererLooper = new ALooper;
-    mRendererLooper->setName("NuPlayer2Renderer");
-    mRendererLooper->start(false, true, ANDROID_PRIORITY_AUDIO);
-    mRendererLooper->registerHandler(mRenderer);
-
-    status_t err = mRenderer->setPlaybackSettings(mPlaybackSettings);
-    if (err != OK) {
-        mCurrentSourceInfo.mSource->stop();
-        mSourceStarted = false;
-        notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_ERROR, MEDIA2_ERROR_UNKNOWN, err);
-        return;
-    }
-
-    float rate = getFrameRate();
-    if (rate > 0) {
-        mRenderer->setVideoFrameRate(rate);
-    }
-
-    addEndTimeMonitor();
-    // Renderer is created in paused state.
-    if (play) {
-        mRenderer->resume();
-    }
-
-    if (mVideoDecoder != NULL) {
-        mVideoDecoder->setRenderer(mRenderer);
-    }
-    if (mAudioDecoder != NULL) {
-        mAudioDecoder->setRenderer(mRenderer);
-    }
-
-    startPlaybackTimer("onstart");
-    notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_INFO, MEDIA2_INFO_DATA_SOURCE_START, 0);
-
-    postScanSources();
-}
-
-void NuPlayer2::addEndTimeMonitor() {
-    ++mEOSMonitorGeneration;
-
-    if (mCurrentSourceInfo.mEndTimeUs == DataSourceDesc::kMaxTimeUs) {
-        return;
-    }
-
-    sp<AMessage> msg = new AMessage(kWhatEOSMonitor, this);
-    msg->setInt32("generation", mEOSMonitorGeneration);
-    mMediaClock->addTimer(msg, mCurrentSourceInfo.mEndTimeUs);
-}
-
-void NuPlayer2::startPlaybackTimer(const char *where) {
-    Mutex::Autolock autoLock(mPlayingTimeLock);
-    if (mLastStartedPlayingTimeNs == 0) {
-        mLastStartedPlayingTimeNs = systemTime();
-        ALOGV("startPlaybackTimer() time %20" PRId64 " (%s)",  mLastStartedPlayingTimeNs, where);
-    }
-}
-
-void NuPlayer2::stopPlaybackTimer(const char *where) {
-    Mutex::Autolock autoLock(mPlayingTimeLock);
-
-    ALOGV("stopPlaybackTimer()  time %20" PRId64 " (%s)", mLastStartedPlayingTimeNs, where);
-
-    if (mLastStartedPlayingTimeNs != 0) {
-        sp<NuPlayer2Driver> driver = mDriver.promote();
-        if (driver != NULL) {
-            int64_t now = systemTime();
-            int64_t played = now - mLastStartedPlayingTimeNs;
-            ALOGV("stopPlaybackTimer()  log  %20" PRId64 "", played);
-
-            if (played > 0) {
-                driver->notifyMorePlayingTimeUs(mCurrentSourceInfo.mSrcId, (played+500)/1000);
-            }
-        }
-        mLastStartedPlayingTimeNs = 0;
-    }
-}
-
-void NuPlayer2::startRebufferingTimer() {
-    Mutex::Autolock autoLock(mPlayingTimeLock);
-    if (mLastStartedRebufferingTimeNs == 0) {
-        mLastStartedRebufferingTimeNs = systemTime();
-        ALOGV("startRebufferingTimer() time %20" PRId64 "",  mLastStartedRebufferingTimeNs);
-    }
-}
-
-void NuPlayer2::stopRebufferingTimer(bool exitingPlayback) {
-    Mutex::Autolock autoLock(mPlayingTimeLock);
-
-    ALOGV("stopRebufferTimer()  time %20" PRId64 " (exiting %d)",
-          mLastStartedRebufferingTimeNs, exitingPlayback);
-
-    if (mLastStartedRebufferingTimeNs != 0) {
-        sp<NuPlayer2Driver> driver = mDriver.promote();
-        if (driver != NULL) {
-            int64_t now = systemTime();
-            int64_t rebuffered = now - mLastStartedRebufferingTimeNs;
-            ALOGV("stopRebufferingTimer()  log  %20" PRId64 "", rebuffered);
-
-            if (rebuffered > 0) {
-                driver->notifyMoreRebufferingTimeUs(
-                        mCurrentSourceInfo.mSrcId, (rebuffered+500)/1000);
-                if (exitingPlayback) {
-                    driver->notifyRebufferingWhenExit(mCurrentSourceInfo.mSrcId, true);
-                }
-            }
-        }
-        mLastStartedRebufferingTimeNs = 0;
-    }
-}
-
-void NuPlayer2::onPause() {
-
-    stopPlaybackTimer("onPause");
-
-    if (mPaused) {
-        return;
-    }
-    mPaused = true;
-    if (mCurrentSourceInfo.mSource != NULL) {
-        mCurrentSourceInfo.mSource->pause();
-    } else {
-        ALOGW("pause called when source is gone or not set");
-    }
-    if (mRenderer != NULL) {
-        mRenderer->pause();
-    } else {
-        ALOGW("pause called when renderer is gone or not set");
-    }
-
-}
-
-bool NuPlayer2::audioDecoderStillNeeded() {
-    // Audio decoder is no longer needed if it's in shut/shutting down status.
-    return ((mFlushingAudio != SHUT_DOWN) && (mFlushingAudio != SHUTTING_DOWN_DECODER));
-}
-
-void NuPlayer2::handleFlushComplete(bool audio, bool isDecoder) {
-    // We wait for both the decoder flush and the renderer flush to complete
-    // before entering either the FLUSHED or the SHUTTING_DOWN_DECODER state.
-
-    mFlushComplete[audio][isDecoder] = true;
-    if (!mFlushComplete[audio][!isDecoder]) {
-        return;
-    }
-
-    FlushStatus *state = audio ? &mFlushingAudio : &mFlushingVideo;
-    switch (*state) {
-        case FLUSHING_DECODER:
-        {
-            *state = FLUSHED;
-            break;
-        }
-
-        case FLUSHING_DECODER_SHUTDOWN:
-        {
-            *state = SHUTTING_DOWN_DECODER;
-
-            ALOGV("initiating %s decoder shutdown", audio ? "audio" : "video");
-            getDecoder(audio)->initiateShutdown();
-            break;
-        }
-
-        default:
-            // decoder flush completes only occur in a flushing state.
-            LOG_ALWAYS_FATAL_IF(isDecoder, "decoder flush in invalid state %d", *state);
-            break;
-    }
-}
-
-void NuPlayer2::finishFlushIfPossible() {
-    if (mFlushingAudio != NONE && mFlushingAudio != FLUSHED
-            && mFlushingAudio != SHUT_DOWN) {
-        return;
-    }
-
-    if (mFlushingVideo != NONE && mFlushingVideo != FLUSHED
-            && mFlushingVideo != SHUT_DOWN) {
-        return;
-    }
-
-    ALOGV("both audio and video are flushed now.");
-
-    mFlushingAudio = NONE;
-    mFlushingVideo = NONE;
-
-    clearFlushComplete();
-
-    processDeferredActions();
-}
-
-void NuPlayer2::postScanSources() {
-    if (mScanSourcesPending) {
-        return;
-    }
-
-    sp<AMessage> msg = new AMessage(kWhatScanSources, this);
-    msg->setInt32("generation", mScanSourcesGeneration);
-    msg->post();
-
-    mScanSourcesPending = true;
-}
-
-void NuPlayer2::tryOpenAudioSinkForOffload(
-        const sp<AMessage> &format, const sp<MetaData> &audioMeta, bool hasVideo) {
-    // Note: This is called early in NuPlayer2 to determine whether offloading
-    // is possible; otherwise the decoders call the renderer openAudioSink directly.
-
-    status_t err = mRenderer->openAudioSink(
-            format, true /* offloadOnly */, hasVideo,
-            AUDIO_OUTPUT_FLAG_NONE, &mOffloadAudio, mCurrentSourceInfo.mSource->isStreaming());
-    if (err != OK) {
-        // Any failure we turn off mOffloadAudio.
-        mOffloadAudio = false;
-    } else if (mOffloadAudio) {
-        sendMetaDataToHal(mAudioSink, audioMeta);
-    }
-}
-
-void NuPlayer2::closeAudioSink() {
-    mRenderer->closeAudioSink();
-}
-
-void NuPlayer2::restartAudio(
-        int64_t currentPositionUs, bool forceNonOffload, bool needsToCreateAudioDecoder) {
-    if (mAudioDecoder != NULL) {
-        mAudioDecoder->pause();
-        Mutex::Autolock autoLock(mDecoderLock);
-        mAudioDecoder.clear();
-        mAudioDecoderError = false;
-        ++mAudioDecoderGeneration;
-    }
-    if (mFlushingAudio == FLUSHING_DECODER) {
-        mFlushComplete[1 /* audio */][1 /* isDecoder */] = true;
-        mFlushingAudio = FLUSHED;
-        finishFlushIfPossible();
-    } else if (mFlushingAudio == FLUSHING_DECODER_SHUTDOWN
-            || mFlushingAudio == SHUTTING_DOWN_DECODER) {
-        mFlushComplete[1 /* audio */][1 /* isDecoder */] = true;
-        mFlushingAudio = SHUT_DOWN;
-        finishFlushIfPossible();
-        needsToCreateAudioDecoder = false;
-    }
-    if (mRenderer == NULL) {
-        return;
-    }
-    closeAudioSink();
-    mRenderer->flush(true /* audio */, false /* notifyComplete */);
-    if (mVideoDecoder != NULL) {
-        mDeferredActions.push_back(
-                new FlushDecoderAction(FLUSH_CMD_NONE /* audio */,
-                                       FLUSH_CMD_FLUSH /* video */));
-        mDeferredActions.push_back(
-                new SeekAction(currentPositionUs,
-                MediaPlayerSeekMode::SEEK_PREVIOUS_SYNC /* mode */));
-        // After a flush without shutdown, decoder is paused.
-        // Don't resume it until source seek is done, otherwise it could
-        // start pulling stale data too soon.
-        mDeferredActions.push_back(new ResumeDecoderAction(false));
-        processDeferredActions();
-    } else {
-        performSeek(currentPositionUs, MediaPlayerSeekMode::SEEK_PREVIOUS_SYNC /* mode */);
-    }
-
-    if (forceNonOffload) {
-        mRenderer->signalDisableOffloadAudio();
-        mOffloadAudio = false;
-    }
-    if (needsToCreateAudioDecoder) {
-        instantiateDecoder(true /* audio */, &mAudioDecoder, !forceNonOffload);
-    }
-}
-
-void NuPlayer2::determineAudioModeChange(const sp<AMessage> &audioFormat) {
-    if (mCurrentSourceInfo.mSource == NULL || mAudioSink == NULL) {
-        return;
-    }
-
-    if (mRenderer == NULL) {
-        ALOGW("No renderer can be used to determine audio mode. Use non-offload for safety.");
-        mOffloadAudio = false;
-        return;
-    }
-
-    sp<MetaData> audioMeta = mCurrentSourceInfo.mSource->getFormatMeta(true /* audio */);
-    sp<AMessage> videoFormat = mCurrentSourceInfo.mSource->getFormat(false /* audio */);
-    audio_stream_type_t streamType = mAudioSink->getAudioStreamType();
-    const bool hasVideo = (videoFormat != NULL);
-    bool canOffload = JMediaPlayer2Utils::isOffloadedAudioPlaybackSupported(
-            audioMeta, hasVideo, mCurrentSourceInfo.mSource->isStreaming(), streamType)
-                    && (mPlaybackSettings.mSpeed == 1.f && mPlaybackSettings.mPitch == 1.f);
-
-    // Modular DRM: Disabling audio offload if the source is protected
-    if (canOffload && mCurrentSourceInfo.mIsDrmProtected) {
-        canOffload = false;
-        ALOGV("determineAudioModeChange: Disabling mOffloadAudio b/c the source is protected.");
-    }
-
-    if (canOffload) {
-        if (!mOffloadAudio) {
-            mRenderer->signalEnableOffloadAudio();
-        }
-        // open audio sink early under offload mode.
-        tryOpenAudioSinkForOffload(audioFormat, audioMeta, hasVideo);
-    } else {
-        if (mOffloadAudio) {
-            mRenderer->signalDisableOffloadAudio();
-            mOffloadAudio = false;
-        }
-    }
-}
-
-status_t NuPlayer2::instantiateDecoder(
-        bool audio, sp<DecoderBase> *decoder, bool checkAudioModeChange) {
-    // The audio decoder could be cleared by tear down. If still in shut down
-    // process, no need to create a new audio decoder.
-    if (*decoder != NULL || (audio && mFlushingAudio == SHUT_DOWN)) {
-        return OK;
-    }
-
-    sp<AMessage> format = mCurrentSourceInfo.mSource->getFormat(audio);
-
-    if (format == NULL) {
-        return UNKNOWN_ERROR;
-    } else {
-        status_t err;
-        if (format->findInt32("err", &err) && err) {
-            return err;
-        }
-    }
-
-    format->setInt32("priority", 0 /* realtime */);
-
-    if (!audio) {
-        AString mime;
-        CHECK(format->findString("mime", &mime));
-
-        sp<AMessage> ccNotify = new AMessage(kWhatClosedCaptionNotify, this);
-        if (mCCDecoder == NULL) {
-            mCCDecoder = new CCDecoder(ccNotify);
-        }
-
-        if (mCurrentSourceInfo.mSourceFlags & Source::FLAG_SECURE) {
-            format->setInt32("secure", true);
-        }
-
-        if (mCurrentSourceInfo.mSourceFlags & Source::FLAG_PROTECTED) {
-            format->setInt32("protected", true);
-        }
-
-        float rate = getFrameRate();
-        if (rate > 0) {
-            format->setFloat("operating-rate", rate * mPlaybackSettings.mSpeed);
-        }
-    }
-
-    Mutex::Autolock autoLock(mDecoderLock);
-
-    if (audio) {
-        sp<AMessage> notify = new AMessage(kWhatAudioNotify, this);
-        ++mAudioDecoderGeneration;
-        notify->setInt32("generation", mAudioDecoderGeneration);
-
-        if (checkAudioModeChange) {
-            determineAudioModeChange(format);
-        }
-        if (mOffloadAudio) {
-            mCurrentSourceInfo.mSource->setOffloadAudio(true /* offload */);
-
-            const bool hasVideo = (mCurrentSourceInfo.mSource->getFormat(false /*audio */) != NULL);
-            format->setInt32("has-video", hasVideo);
-            *decoder = new DecoderPassThrough(notify, mCurrentSourceInfo.mSource, mRenderer);
-            ALOGV("instantiateDecoder audio DecoderPassThrough  hasVideo: %d", hasVideo);
-        } else {
-            mCurrentSourceInfo.mSource->setOffloadAudio(false /* offload */);
-
-            *decoder = new Decoder(notify, mCurrentSourceInfo.mSource, mPID, mUID, mRenderer);
-            ALOGV("instantiateDecoder audio Decoder");
-        }
-        mAudioDecoderError = false;
-    } else {
-        sp<AMessage> notify = new AMessage(kWhatVideoNotify, this);
-        ++mVideoDecoderGeneration;
-        notify->setInt32("generation", mVideoDecoderGeneration);
-
-        *decoder = new Decoder(
-                notify, mCurrentSourceInfo.mSource, mPID, mUID, mRenderer, mNativeWindow,
-                mCCDecoder);
-        mVideoDecoderError = false;
-
-        // enable FRC if high-quality AV sync is requested, even if not
-        // directly queuing to display, as this will even improve textureview
-        // playback.
-        {
-            if (property_get_bool("persist.sys.media.avsync", false)) {
-                format->setInt32("auto-frc", 1);
-            }
-        }
-    }
-    (*decoder)->init();
-
-    // Modular DRM
-    if (mCurrentSourceInfo.mIsDrmProtected) {
-        format->setObject("crypto", mCurrentSourceInfo.mCrypto);
-        ALOGV("instantiateDecoder: mCrypto: %p isSecure: %d",
-                mCurrentSourceInfo.mCrypto.get(),
-                (mCurrentSourceInfo.mSourceFlags & Source::FLAG_SECURE) != 0);
-    }
-
-    (*decoder)->configure(format);
-
-    if (!audio) {
-        sp<AMessage> params = new AMessage();
-        float rate = getFrameRate();
-        if (rate > 0) {
-            params->setFloat("frame-rate-total", rate);
-        }
-
-        sp<MetaData> fileMeta = getFileMeta();
-        if (fileMeta != NULL) {
-            int32_t videoTemporalLayerCount;
-            if (fileMeta->findInt32(kKeyTemporalLayerCount, &videoTemporalLayerCount)
-                    && videoTemporalLayerCount > 0) {
-                params->setInt32("temporal-layer-count", videoTemporalLayerCount);
-            }
-        }
-
-        if (params->countEntries() > 0) {
-            (*decoder)->setParameters(params);
-        }
-    }
-    return OK;
-}
-
-void NuPlayer2::updateVideoSize(
-        int64_t srcId,
-        const sp<AMessage> &inputFormat,
-        const sp<AMessage> &outputFormat) {
-    if (inputFormat == NULL) {
-        ALOGW("Unknown video size, reporting 0x0!");
-        notifyListener(srcId, MEDIA2_SET_VIDEO_SIZE, 0, 0);
-        return;
-    }
-    int32_t err = OK;
-    inputFormat->findInt32("err", &err);
-    if (err == -EWOULDBLOCK) {
-        ALOGW("Video meta is not available yet!");
-        return;
-    }
-    if (err != OK) {
-        ALOGW("Something is wrong with video meta!");
-        return;
-    }
-
-    int32_t displayWidth, displayHeight;
-    if (outputFormat != NULL) {
-        int32_t width, height;
-        CHECK(outputFormat->findInt32("width", &width));
-        CHECK(outputFormat->findInt32("height", &height));
-
-        int32_t cropLeft, cropTop, cropRight, cropBottom;
-        CHECK(outputFormat->findRect(
-                    "crop",
-                    &cropLeft, &cropTop, &cropRight, &cropBottom));
-
-        displayWidth = cropRight - cropLeft + 1;
-        displayHeight = cropBottom - cropTop + 1;
-
-        ALOGV("Video output format changed to %d x %d "
-             "(crop: %d x %d @ (%d, %d))",
-             width, height,
-             displayWidth,
-             displayHeight,
-             cropLeft, cropTop);
-    } else {
-        CHECK(inputFormat->findInt32("width", &displayWidth));
-        CHECK(inputFormat->findInt32("height", &displayHeight));
-
-        ALOGV("Video input format %d x %d", displayWidth, displayHeight);
-    }
-
-    // Take into account sample aspect ratio if necessary:
-    int32_t sarWidth, sarHeight;
-    if (inputFormat->findInt32("sar-width", &sarWidth)
-            && inputFormat->findInt32("sar-height", &sarHeight)
-            && sarWidth > 0 && sarHeight > 0) {
-        ALOGV("Sample aspect ratio %d : %d", sarWidth, sarHeight);
-
-        displayWidth = (displayWidth * sarWidth) / sarHeight;
-
-        ALOGV("display dimensions %d x %d", displayWidth, displayHeight);
-    } else {
-        int32_t width, height;
-        if (inputFormat->findInt32("display-width", &width)
-                && inputFormat->findInt32("display-height", &height)
-                && width > 0 && height > 0
-                && displayWidth > 0 && displayHeight > 0) {
-            if (displayHeight * (int64_t)width / height > (int64_t)displayWidth) {
-                displayHeight = (int32_t)(displayWidth * (int64_t)height / width);
-            } else {
-                displayWidth = (int32_t)(displayHeight * (int64_t)width / height);
-            }
-            ALOGV("Video display width and height are overridden to %d x %d",
-                 displayWidth, displayHeight);
-        }
-    }
-
-    int32_t rotationDegrees;
-    if (!inputFormat->findInt32("rotation-degrees", &rotationDegrees)) {
-        rotationDegrees = 0;
-    }
-
-    if (rotationDegrees == 90 || rotationDegrees == 270) {
-        int32_t tmp = displayWidth;
-        displayWidth = displayHeight;
-        displayHeight = tmp;
-    }
-
-    notifyListener(
-            srcId,
-            MEDIA2_SET_VIDEO_SIZE,
-            displayWidth,
-            displayHeight);
-}
-
-void NuPlayer2::notifyListener(
-        int64_t srcId, int msg, int ext1, int ext2, const PlayerMessage *in) {
-    if (mDriver == NULL) {
-        return;
-    }
-
-    sp<NuPlayer2Driver> driver = mDriver.promote();
-
-    if (driver == NULL) {
-        return;
-    }
-
-    driver->notifyListener(srcId, msg, ext1, ext2, in);
-}
-
-void NuPlayer2::flushDecoder(bool audio, bool needShutdown) {
-    ALOGV("[%s] flushDecoder needShutdown=%d",
-          audio ? "audio" : "video", needShutdown);
-
-    const sp<DecoderBase> &decoder = getDecoder(audio);
-    if (decoder == NULL) {
-        ALOGI("flushDecoder %s without decoder present",
-             audio ? "audio" : "video");
-        return;
-    }
-
-    // Make sure we don't continue to scan sources until we finish flushing.
-    ++mScanSourcesGeneration;
-    if (mScanSourcesPending) {
-        if (!needShutdown) {
-            mDeferredActions.push_back(
-                    new SimpleAction(&NuPlayer2::performScanSources));
-        }
-        mScanSourcesPending = false;
-    }
-
-    decoder->signalFlush();
-
-    FlushStatus newStatus =
-        needShutdown ? FLUSHING_DECODER_SHUTDOWN : FLUSHING_DECODER;
-
-    mFlushComplete[audio][false /* isDecoder */] = (mRenderer == NULL);
-    mFlushComplete[audio][true /* isDecoder */] = false;
-    if (audio) {
-        ALOGE_IF(mFlushingAudio != NONE,
-                "audio flushDecoder() is called in state %d", mFlushingAudio);
-        mFlushingAudio = newStatus;
-    } else {
-        ALOGE_IF(mFlushingVideo != NONE,
-                "video flushDecoder() is called in state %d", mFlushingVideo);
-        mFlushingVideo = newStatus;
-    }
-}
-
-void NuPlayer2::queueDecoderShutdown(
-        bool audio, bool video, const sp<AMessage> &reply) {
-    ALOGI("queueDecoderShutdown audio=%d, video=%d", audio, video);
-
-    mDeferredActions.push_back(
-            new FlushDecoderAction(
-                audio ? FLUSH_CMD_SHUTDOWN : FLUSH_CMD_NONE,
-                video ? FLUSH_CMD_SHUTDOWN : FLUSH_CMD_NONE));
-
-    mDeferredActions.push_back(
-            new SimpleAction(&NuPlayer2::performScanSources));
-
-    mDeferredActions.push_back(new PostMessageAction(reply));
-
-    processDeferredActions();
-}
-
-status_t NuPlayer2::setVideoScalingMode(int32_t mode) {
-    mVideoScalingMode = mode;
-    if (mNativeWindow != NULL && mNativeWindow->getANativeWindow() != NULL) {
-        status_t ret = native_window_set_scaling_mode(
-                mNativeWindow->getANativeWindow(), mVideoScalingMode);
-        if (ret != OK) {
-            ALOGE("Failed to set scaling mode (%d): %s",
-                -ret, strerror(-ret));
-            return ret;
-        }
-    }
-    return OK;
-}
-
-status_t NuPlayer2::getTrackInfo(int64_t srcId, PlayerMessage* reply) const {
-    sp<AMessage> msg = new AMessage(kWhatGetTrackInfo, this);
-    msg->setInt64("srcId", srcId);
-    msg->setPointer("reply", reply);
-
-    sp<AMessage> response;
-    status_t err = msg->postAndAwaitResponse(&response);
-    return err;
-}
-
-status_t NuPlayer2::getSelectedTrack(int64_t srcId, int32_t type, PlayerMessage* reply) const {
-    sp<AMessage> msg = new AMessage(kWhatGetSelectedTrack, this);
-    msg->setPointer("reply", reply);
-    msg->setInt64("srcId", srcId);
-    msg->setInt32("type", type);
-
-    sp<AMessage> response;
-    status_t err = msg->postAndAwaitResponse(&response);
-    if (err == OK && response != NULL) {
-        CHECK(response->findInt32("err", &err));
-    }
-    return err;
-}
-
-status_t NuPlayer2::selectTrack(int64_t srcId, size_t trackIndex, bool select, int64_t timeUs) {
-    sp<AMessage> msg = new AMessage(kWhatSelectTrack, this);
-    msg->setInt64("srcId", srcId);
-    msg->setSize("trackIndex", trackIndex);
-    msg->setInt32("select", select);
-    msg->setInt64("timeUs", timeUs);
-
-    sp<AMessage> response;
-    status_t err = msg->postAndAwaitResponse(&response);
-
-    if (err != OK) {
-        return err;
-    }
-
-    if (!response->findInt32("err", &err)) {
-        err = OK;
-    }
-
-    return err;
-}
-
-status_t NuPlayer2::getCurrentPosition(int64_t *mediaUs) {
-    sp<Renderer> renderer = mRenderer;
-    if (renderer == NULL) {
-        return NO_INIT;
-    }
-
-    return renderer->getCurrentPosition(mediaUs);
-}
-
-void NuPlayer2::getStats(Vector<sp<AMessage> > *mTrackStats) {
-    CHECK(mTrackStats != NULL);
-
-    mTrackStats->clear();
-
-    Mutex::Autolock autoLock(mDecoderLock);
-    if (mVideoDecoder != NULL) {
-        mTrackStats->push_back(mVideoDecoder->getStats());
-    }
-    if (mAudioDecoder != NULL) {
-        mTrackStats->push_back(mAudioDecoder->getStats());
-    }
-}
-
-sp<MetaData> NuPlayer2::getFileMeta() {
-    return mCurrentSourceInfo.mSource->getFileFormatMeta();
-}
-
-float NuPlayer2::getFrameRate() {
-    sp<MetaData> meta = mCurrentSourceInfo.mSource->getFormatMeta(false /* audio */);
-    if (meta == NULL) {
-        return 0;
-    }
-    int32_t rate;
-    if (!meta->findInt32(kKeyFrameRate, &rate)) {
-        // fall back to try file meta
-        sp<MetaData> fileMeta = getFileMeta();
-        if (fileMeta == NULL) {
-            ALOGW("source has video meta but not file meta");
-            return -1;
-        }
-        int32_t fileMetaRate;
-        if (!fileMeta->findInt32(kKeyFrameRate, &fileMetaRate)) {
-            return -1;
-        }
-        return fileMetaRate;
-    }
-    return rate;
-}
-
-void NuPlayer2::schedulePollDuration() {
-    sp<AMessage> msg = new AMessage(kWhatPollDuration, this);
-    msg->setInt32("generation", mPollDurationGeneration);
-    msg->post();
-}
-
-void NuPlayer2::cancelPollDuration() {
-    ++mPollDurationGeneration;
-}
-
-void NuPlayer2::processDeferredActions() {
-    while (!mDeferredActions.empty()) {
-        // We won't execute any deferred actions until we're no longer in
-        // an intermediate state, i.e. one more more decoders are currently
-        // flushing or shutting down.
-
-        if (mFlushingAudio != NONE || mFlushingVideo != NONE) {
-            // We're currently flushing, postpone the reset until that's
-            // completed.
-
-            ALOGV("postponing action mFlushingAudio=%d, mFlushingVideo=%d",
-                  mFlushingAudio, mFlushingVideo);
-
-            break;
-        }
-
-        sp<Action> action = *mDeferredActions.begin();
-        mDeferredActions.erase(mDeferredActions.begin());
-
-        action->execute(this);
-    }
-}
-
-void NuPlayer2::performSeek(int64_t seekTimeUs, MediaPlayer2SeekMode mode) {
-    ALOGV("performSeek seekTimeUs=%lld us (%.2f secs), mode=%d",
-          (long long)seekTimeUs, seekTimeUs / 1E6, mode);
-
-    if (mCurrentSourceInfo.mSource == NULL) {
-        // This happens when reset occurs right before the loop mode
-        // asynchronously seeks to the start of the stream.
-        LOG_ALWAYS_FATAL_IF(mAudioDecoder != NULL || mVideoDecoder != NULL,
-                "mCurrentSourceInfo.mSource is NULL and decoders not NULL audio(%p) video(%p)",
-                mAudioDecoder.get(), mVideoDecoder.get());
-        return;
-    }
-    mPreviousSeekTimeUs = seekTimeUs;
-    mCurrentSourceInfo.mSource->seekTo(seekTimeUs, mode);
-    ++mTimedTextGeneration;
-
-    // everything's flushed, continue playback.
-}
-
-void NuPlayer2::performDecoderFlush(FlushCommand audio, FlushCommand video) {
-    ALOGV("performDecoderFlush audio=%d, video=%d", audio, video);
-
-    if ((audio == FLUSH_CMD_NONE || mAudioDecoder == NULL)
-            && (video == FLUSH_CMD_NONE || mVideoDecoder == NULL)) {
-        return;
-    }
-
-    if (audio != FLUSH_CMD_NONE && mAudioDecoder != NULL) {
-        flushDecoder(true /* audio */, (audio == FLUSH_CMD_SHUTDOWN));
-    }
-
-    if (video != FLUSH_CMD_NONE && mVideoDecoder != NULL) {
-        flushDecoder(false /* audio */, (video == FLUSH_CMD_SHUTDOWN));
-    }
-}
-
-void NuPlayer2::performReset() {
-    ALOGV("performReset");
-
-    CHECK(mAudioDecoder == NULL);
-    CHECK(mVideoDecoder == NULL);
-
-    stopPlaybackTimer("performReset");
-    stopRebufferingTimer(true);
-
-    cancelPollDuration();
-
-    ++mScanSourcesGeneration;
-    mScanSourcesPending = false;
-
-    if (mRendererLooper != NULL) {
-        if (mRenderer != NULL) {
-            mRendererLooper->unregisterHandler(mRenderer->id());
-        }
-        mRendererLooper->stop();
-        mRendererLooper.clear();
-    }
-    mRenderer.clear();
-    ++mRendererGeneration;
-
-    resetSourceInfo(mCurrentSourceInfo);
-    resetSourceInfo(mNextSourceInfo);
-
-    if (mDriver != NULL) {
-        sp<NuPlayer2Driver> driver = mDriver.promote();
-        if (driver != NULL) {
-            driver->notifyResetComplete(mCurrentSourceInfo.mSrcId);
-        }
-    }
-
-    mStarted = false;
-    mPrepared = false;
-    mResetting = false;
-    mSourceStarted = false;
-
-}
-
-void NuPlayer2::performPlayNextDataSource() {
-    ALOGV("performPlayNextDataSource");
-
-    CHECK(mAudioDecoder == NULL);
-    CHECK(mVideoDecoder == NULL);
-
-    stopPlaybackTimer("performPlayNextDataSource");
-    stopRebufferingTimer(true);
-
-    cancelPollDuration();
-
-    ++mScanSourcesGeneration;
-    mScanSourcesPending = false;
-
-    ++mRendererGeneration;
-
-    if (mCurrentSourceInfo.mSource != NULL) {
-        mCurrentSourceInfo.mSource->stop();
-    }
-
-    long previousSrcId;
-    {
-        Mutex::Autolock autoLock(mSourceLock);
-        previousSrcId = mCurrentSourceInfo.mSrcId;
-
-        mCurrentSourceInfo = mNextSourceInfo;
-        mNextSourceInfo = SourceInfo();
-        mNextSourceInfo.mSrcId = ~mCurrentSourceInfo.mSrcId;  // to distinguish the two sources.
-    }
-
-    if (mDriver != NULL) {
-        sp<NuPlayer2Driver> driver = mDriver.promote();
-        if (driver != NULL) {
-            notifyListener(previousSrcId, MEDIA2_INFO, MEDIA2_INFO_DATA_SOURCE_END, 0);
-
-            int64_t durationUs;
-            if (mCurrentSourceInfo.mSource->getDuration(&durationUs) == OK) {
-                driver->notifyDuration(mCurrentSourceInfo.mSrcId, durationUs);
-            }
-            notifyListener(
-                    mCurrentSourceInfo.mSrcId, MEDIA2_INFO, MEDIA2_INFO_DATA_SOURCE_START, 0);
-        }
-    }
-
-    mStarted = false;
-    mPrepared = true;  // TODO: what if it's not prepared
-    mResetting = false;
-    mSourceStarted = false;
-
-    addEndTimeMonitor();
-
-    if (mRenderer != NULL) {
-        mRenderer->resume();
-    }
-
-    onStart(true /* play */);
-    mPausedByClient = false;
-    notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_STARTED, 0, 0);
-}
-
-void NuPlayer2::performScanSources() {
-    ALOGV("performScanSources");
-
-    if (!mStarted) {
-        return;
-    }
-
-    if (mAudioDecoder == NULL || mVideoDecoder == NULL) {
-        postScanSources();
-    }
-}
-
-void NuPlayer2::performSetSurface(const sp<ANativeWindowWrapper> &nww) {
-    ALOGV("performSetSurface");
-
-    mNativeWindow = nww;
-
-    // XXX - ignore error from setVideoScalingMode for now
-    setVideoScalingMode(mVideoScalingMode);
-
-    if (mDriver != NULL) {
-        sp<NuPlayer2Driver> driver = mDriver.promote();
-        if (driver != NULL) {
-            driver->notifySetSurfaceComplete(mCurrentSourceInfo.mSrcId);
-        }
-    }
-}
-
-void NuPlayer2::performResumeDecoders(bool needNotify) {
-    if (needNotify) {
-        mResumePending = true;
-        if (mVideoDecoder == NULL) {
-            // if audio-only, we can notify seek complete now,
-            // as the resume operation will be relatively fast.
-            finishResume();
-        }
-    }
-
-    if (mVideoDecoder != NULL) {
-        // When there is continuous seek, MediaPlayer will cache the seek
-        // position, and send down new seek request when previous seek is
-        // complete. Let's wait for at least one video output frame before
-        // notifying seek complete, so that the video thumbnail gets updated
-        // when seekbar is dragged.
-        mVideoDecoder->signalResume(needNotify);
-    }
-
-    if (mAudioDecoder != NULL) {
-        mAudioDecoder->signalResume(false /* needNotify */);
-    }
-}
-
-void NuPlayer2::finishResume() {
-    if (mResumePending) {
-        mResumePending = false;
-        notifyDriverSeekComplete(mCurrentSourceInfo.mSrcId);
-    }
-}
-
-void NuPlayer2::notifyDriverSeekComplete(int64_t srcId) {
-    if (mDriver != NULL) {
-        sp<NuPlayer2Driver> driver = mDriver.promote();
-        if (driver != NULL) {
-            driver->notifySeekComplete(srcId);
-        }
-    }
-}
-
-void NuPlayer2::onSourceNotify(const sp<AMessage> &msg) {
-    int32_t what;
-    CHECK(msg->findInt32("what", &what));
-
-    int64_t srcId;
-    CHECK(msg->findInt64("srcId", &srcId));
-    switch (what) {
-        case Source::kWhatPrepared:
-        {
-            ALOGV("NuPlayer2::onSourceNotify Source::kWhatPrepared source:%p, Id(%lld)",
-                  mCurrentSourceInfo.mSource.get(), (long long)srcId);
-            if (srcId == mCurrentSourceInfo.mSrcId) {
-                if (mCurrentSourceInfo.mSource == NULL) {
-                    // This is a stale notification from a source that was
-                    // asynchronously preparing when the client called reset().
-                    // We handled the reset, the source is gone.
-                    break;
-                }
-
-                int32_t err;
-                CHECK(msg->findInt32("err", &err));
-
-                if (err != OK) {
-                    // shut down potential secure codecs in case client never calls reset
-                    mDeferredActions.push_back(
-                            new FlushDecoderAction(FLUSH_CMD_SHUTDOWN /* audio */,
-                                                   FLUSH_CMD_SHUTDOWN /* video */));
-                    processDeferredActions();
-                } else {
-                    mPrepared = true;
-                }
-
-                sp<NuPlayer2Driver> driver = mDriver.promote();
-                if (driver != NULL) {
-                    // notify duration first, so that it's definitely set when
-                    // the app received the "prepare complete" callback.
-                    int64_t durationUs;
-                    if (mCurrentSourceInfo.mSource->getDuration(&durationUs) == OK) {
-                        driver->notifyDuration(srcId, durationUs);
-                    }
-                    driver->notifyPrepareCompleted(srcId, err);
-                }
-            } else if (srcId == mNextSourceInfo.mSrcId) {
-                if (mNextSourceInfo.mSource == NULL) {
-                    break;  // stale
-                }
-
-                sp<NuPlayer2Driver> driver = mDriver.promote();
-                if (driver != NULL) {
-                    int32_t err;
-                    CHECK(msg->findInt32("err", &err));
-                    driver->notifyPrepareCompleted(srcId, err);
-                }
-            }
-
-            break;
-        }
-
-        // Modular DRM
-        case Source::kWhatDrmInfo:
-        {
-            PlayerMessage playerMsg;
-            sp<ABuffer> drmInfo;
-            CHECK(msg->findBuffer("drmInfo", &drmInfo));
-            playerMsg.ParseFromArray(drmInfo->data(), drmInfo->size());
-
-            ALOGV("onSourceNotify() kWhatDrmInfo MEDIA2_DRM_INFO drmInfo: %p  playerMsg size: %d",
-                    drmInfo.get(), playerMsg.ByteSize());
-
-            notifyListener(srcId, MEDIA2_DRM_INFO, 0 /* ext1 */, 0 /* ext2 */, &playerMsg);
-
-            break;
-        }
-
-        case Source::kWhatFlagsChanged:
-        {
-            uint32_t flags;
-            CHECK(msg->findInt32("flags", (int32_t *)&flags));
-
-            sp<NuPlayer2Driver> driver = mDriver.promote();
-            if (driver != NULL) {
-
-                ALOGV("onSourceNotify() kWhatFlagsChanged  FLAG_CAN_PAUSE: %d  "
-                        "FLAG_CAN_SEEK_BACKWARD: %d \n\t\t\t\t FLAG_CAN_SEEK_FORWARD: %d  "
-                        "FLAG_CAN_SEEK: %d  FLAG_DYNAMIC_DURATION: %d \n"
-                        "\t\t\t\t FLAG_SECURE: %d  FLAG_PROTECTED: %d",
-                        (flags & Source::FLAG_CAN_PAUSE) != 0,
-                        (flags & Source::FLAG_CAN_SEEK_BACKWARD) != 0,
-                        (flags & Source::FLAG_CAN_SEEK_FORWARD) != 0,
-                        (flags & Source::FLAG_CAN_SEEK) != 0,
-                        (flags & Source::FLAG_DYNAMIC_DURATION) != 0,
-                        (flags & Source::FLAG_SECURE) != 0,
-                        (flags & Source::FLAG_PROTECTED) != 0);
-
-                if ((flags & NuPlayer2::Source::FLAG_CAN_SEEK) == 0) {
-                    driver->notifyListener(
-                            srcId, MEDIA2_INFO, MEDIA2_INFO_NOT_SEEKABLE, 0);
-                }
-                if (srcId == mCurrentSourceInfo.mSrcId) {
-                    driver->notifyFlagsChanged(srcId, flags);
-                }
-            }
-
-            if (srcId == mCurrentSourceInfo.mSrcId) {
-                if ((mCurrentSourceInfo.mSourceFlags & Source::FLAG_DYNAMIC_DURATION)
-                        && (!(flags & Source::FLAG_DYNAMIC_DURATION))) {
-                    cancelPollDuration();
-                } else if (!(mCurrentSourceInfo.mSourceFlags & Source::FLAG_DYNAMIC_DURATION)
-                        && (flags & Source::FLAG_DYNAMIC_DURATION)
-                        && (mAudioDecoder != NULL || mVideoDecoder != NULL)) {
-                    schedulePollDuration();
-                }
-
-                mCurrentSourceInfo.mSourceFlags = flags;
-            } else if (srcId == mNextSourceInfo.mSrcId) {
-                // TODO: handle duration polling for next source.
-                mNextSourceInfo.mSourceFlags = flags;
-            }
-            break;
-        }
-
-        case Source::kWhatVideoSizeChanged:
-        {
-            sp<AMessage> format;
-            CHECK(msg->findMessage("format", &format));
-
-            updateVideoSize(srcId, format);
-            break;
-        }
-
-        case Source::kWhatBufferingUpdate:
-        {
-            int32_t percentage;
-            CHECK(msg->findInt32("percentage", &percentage));
-
-            notifyListener(srcId, MEDIA2_BUFFERING_UPDATE, percentage, 0);
-            break;
-        }
-
-        case Source::kWhatPauseOnBufferingStart:
-        {
-            // ignore if not playing
-            if (mStarted) {
-                ALOGI("buffer low, pausing...");
-
-                startRebufferingTimer();
-                mPausedForBuffering = true;
-                onPause();
-            }
-            notifyListener(srcId, MEDIA2_INFO, MEDIA2_INFO_BUFFERING_START, 0);
-            break;
-        }
-
-        case Source::kWhatResumeOnBufferingEnd:
-        {
-            // ignore if not playing
-            if (mStarted) {
-                ALOGI("buffer ready, resuming...");
-
-                stopRebufferingTimer(false);
-                mPausedForBuffering = false;
-
-                // do not resume yet if client didn't unpause
-                if (!mPausedByClient) {
-                    onResume();
-                }
-            }
-            notifyListener(srcId, MEDIA2_INFO, MEDIA2_INFO_BUFFERING_END, 0);
-            break;
-        }
-
-        case Source::kWhatCacheStats:
-        {
-            int32_t kbps;
-            CHECK(msg->findInt32("bandwidth", &kbps));
-
-            notifyListener(srcId, MEDIA2_INFO, MEDIA2_INFO_NETWORK_BANDWIDTH, kbps);
-            break;
-        }
-
-        case Source::kWhatSubtitleData:
-        {
-            sp<ABuffer> buffer;
-            CHECK(msg->findBuffer("buffer", &buffer));
-
-            sendSubtitleData(buffer, 0 /* baseIndex */);
-            break;
-        }
-
-        case Source::kWhatTimedMetaData:
-        {
-            sp<ABuffer> buffer;
-            if (!msg->findBuffer("buffer", &buffer)) {
-                notifyListener(srcId, MEDIA2_INFO, MEDIA2_INFO_METADATA_UPDATE, 0);
-            } else {
-                sendTimedMetaData(buffer);
-            }
-            break;
-        }
-
-        case Source::kWhatTimedTextData:
-        {
-            int32_t generation;
-            if (msg->findInt32("generation", &generation)
-                    && generation != mTimedTextGeneration) {
-                break;
-            }
-
-            sp<ABuffer> buffer;
-            CHECK(msg->findBuffer("buffer", &buffer));
-
-            sp<NuPlayer2Driver> driver = mDriver.promote();
-            if (driver == NULL) {
-                break;
-            }
-
-            int64_t posMs;
-            int64_t timeUs, posUs;
-            driver->getCurrentPosition(&posMs);
-            posUs = posMs * 1000LL;
-            CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
-
-            if (posUs < timeUs) {
-                if (!msg->findInt32("generation", &generation)) {
-                    msg->setInt32("generation", mTimedTextGeneration);
-                }
-                msg->post(timeUs - posUs);
-            } else {
-                sendTimedTextData(buffer);
-            }
-            break;
-        }
-
-        case Source::kWhatQueueDecoderShutdown:
-        {
-            int32_t audio, video;
-            CHECK(msg->findInt32("audio", &audio));
-            CHECK(msg->findInt32("video", &video));
-
-            sp<AMessage> reply;
-            CHECK(msg->findMessage("reply", &reply));
-
-            queueDecoderShutdown(audio, video, reply);
-            break;
-        }
-
-        case Source::kWhatDrmNoLicense:
-        {
-            notifyListener(srcId, MEDIA2_ERROR, MEDIA2_ERROR_UNKNOWN, ERROR_DRM_NO_LICENSE);
-            break;
-        }
-
-        default:
-            TRESPASS();
-    }
-}
-
-void NuPlayer2::onClosedCaptionNotify(const sp<AMessage> &msg) {
-    int32_t what;
-    CHECK(msg->findInt32("what", &what));
-
-    switch (what) {
-        case NuPlayer2::CCDecoder::kWhatClosedCaptionData:
-        {
-            sp<ABuffer> buffer;
-            CHECK(msg->findBuffer("buffer", &buffer));
-
-            size_t inbandTracks = 0;
-            if (mCurrentSourceInfo.mSource != NULL) {
-                inbandTracks = mCurrentSourceInfo.mSource->getTrackCount();
-            }
-
-            sendSubtitleData(buffer, inbandTracks);
-            break;
-        }
-
-        case NuPlayer2::CCDecoder::kWhatTrackAdded:
-        {
-            notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_INFO, MEDIA2_INFO_METADATA_UPDATE, 0);
-
-            break;
-        }
-
-        default:
-            TRESPASS();
-    }
-
-
-}
-
-void NuPlayer2::sendSubtitleData(const sp<ABuffer> &buffer, int32_t baseIndex) {
-    int32_t trackIndex;
-    int64_t timeUs, durationUs;
-    CHECK(buffer->meta()->findInt32(AMEDIAFORMAT_KEY_TRACK_INDEX, &trackIndex));
-    CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
-    CHECK(buffer->meta()->findInt64("durationUs", &durationUs));
-
-    PlayerMessage playerMsg;
-    playerMsg.add_values()->set_int32_value(trackIndex + baseIndex);
-    playerMsg.add_values()->set_int64_value(timeUs);
-    playerMsg.add_values()->set_int64_value(durationUs);
-    playerMsg.add_values()->set_bytes_value(buffer->data(), buffer->size());
-
-    notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_SUBTITLE_DATA, 0, 0, &playerMsg);
-}
-
-void NuPlayer2::sendTimedMetaData(const sp<ABuffer> &buffer) {
-    int64_t timeUs;
-    CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
-
-    PlayerMessage playerMsg;
-    playerMsg.add_values()->set_int64_value(timeUs);
-    playerMsg.add_values()->set_bytes_value(buffer->data(), buffer->size());
-
-    notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_META_DATA, 0, 0, &playerMsg);
-}
-
-void NuPlayer2::sendTimedTextData(const sp<ABuffer> &buffer) {
-    const void *data;
-    size_t size = 0;
-    int64_t timeUs;
-    int32_t flag = TextDescriptions2::IN_BAND_TEXT_3GPP;
-
-    AString mime;
-    CHECK(buffer->meta()->findString("mime", &mime));
-    CHECK(strcasecmp(mime.c_str(), MEDIA_MIMETYPE_TEXT_3GPP) == 0);
-
-    data = buffer->data();
-    size = buffer->size();
-
-    PlayerMessage playerMsg;
-    if (size > 0) {
-        CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
-        int32_t global = 0;
-        if (buffer->meta()->findInt32("global", &global) && global) {
-            flag |= TextDescriptions2::GLOBAL_DESCRIPTIONS;
-        } else {
-            flag |= TextDescriptions2::LOCAL_DESCRIPTIONS;
-        }
-        TextDescriptions2::getPlayerMessageOfDescriptions(
-                (const uint8_t *)data, size, flag, timeUs / 1000, &playerMsg);
-    }
-
-    if (playerMsg.values_size() > 0) {
-        notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_TIMED_TEXT, 0, 0, &playerMsg);
-    } else {  // send an empty timed text
-        notifyListener(mCurrentSourceInfo.mSrcId, MEDIA2_TIMED_TEXT, 0, 0);
-    }
-}
-
-const char *NuPlayer2::getDataSourceType() {
-    switch (mCurrentSourceInfo.mDataSourceType) {
-        case DATA_SOURCE_TYPE_HTTP_LIVE:
-            return "HTTPLive";
-
-        case DATA_SOURCE_TYPE_RTSP:
-            return "RTSP";
-
-        case DATA_SOURCE_TYPE_GENERIC_URL:
-            return "GenURL";
-
-        case DATA_SOURCE_TYPE_GENERIC_FD:
-            return "GenFD";
-
-        case DATA_SOURCE_TYPE_MEDIA:
-            return "Media";
-
-        case DATA_SOURCE_TYPE_NONE:
-        default:
-            return "None";
-    }
- }
-
-NuPlayer2::SourceInfo* NuPlayer2::getSourceInfoByIdInMsg(const sp<AMessage> &msg) {
-    int64_t srcId;
-    CHECK(msg->findInt64("srcId", &srcId));
-    if (mCurrentSourceInfo.mSrcId == srcId) {
-        return &mCurrentSourceInfo;
-    } else if (mNextSourceInfo.mSrcId == srcId) {
-        return &mNextSourceInfo;
-    } else {
-        return NULL;
-    }
-}
-
-void NuPlayer2::resetSourceInfo(NuPlayer2::SourceInfo &srcInfo) {
-    if (srcInfo.mSource != NULL) {
-        srcInfo.mSource->stop();
-
-        Mutex::Autolock autoLock(mSourceLock);
-        srcInfo.mSource.clear();
-    }
-    // Modular DRM
-    ALOGD("performReset mCrypto: %p", srcInfo.mCrypto.get());
-    srcInfo.mCrypto.clear();
-    srcInfo.mIsDrmProtected = false;
-}
-
-// Modular DRM begin
-status_t NuPlayer2::prepareDrm(
-        int64_t srcId, const uint8_t uuid[16], const Vector<uint8_t> &drmSessionId)
-{
-    ALOGV("prepareDrm ");
-
-    // Passing to the looper anyway; called in a pre-config prepared state so no race on mCrypto
-    sp<AMessage> msg = new AMessage(kWhatPrepareDrm, this);
-    // synchronous call so just passing the address but with local copies of "const" args
-    uint8_t UUID[16];
-    memcpy(UUID, uuid, sizeof(UUID));
-    Vector<uint8_t> sessionId = drmSessionId;
-    msg->setInt64("srcId", srcId);
-    msg->setPointer("uuid", (void*)UUID);
-    msg->setPointer("drmSessionId", (void*)&sessionId);
-
-    sp<AMessage> response;
-    status_t status = msg->postAndAwaitResponse(&response);
-
-    if (status == OK && response != NULL) {
-        CHECK(response->findInt32("status", &status));
-        ALOGV("prepareDrm ret: %d ", status);
-    } else {
-        ALOGE("prepareDrm err: %d", status);
-    }
-
-    return status;
-}
-
-status_t NuPlayer2::releaseDrm(int64_t srcId)
-{
-    ALOGV("releaseDrm ");
-
-    sp<AMessage> msg = new AMessage(kWhatReleaseDrm, this);
-    msg->setInt64("srcId", srcId);
-
-    sp<AMessage> response;
-    status_t status = msg->postAndAwaitResponse(&response);
-
-    if (status == OK && response != NULL) {
-        CHECK(response->findInt32("status", &status));
-        ALOGV("releaseDrm ret: %d ", status);
-    } else {
-        ALOGE("releaseDrm err: %d", status);
-    }
-
-    return status;
-}
-
-status_t NuPlayer2::onPrepareDrm(const sp<AMessage> &msg)
-{
-    // TODO change to ALOGV
-    ALOGD("onPrepareDrm ");
-
-    status_t status = INVALID_OPERATION;
-    SourceInfo *srcInfo = getSourceInfoByIdInMsg(msg);
-    if (srcInfo == NULL) {
-        return status;
-    }
-
-    int64_t srcId = srcInfo->mSrcId;
-    if (srcInfo->mSource == NULL) {
-        ALOGE("onPrepareDrm: srcInfo(%lld) No source. onPrepareDrm failed with %d.",
-                (long long)srcId, status);
-        return status;
-    }
-
-    uint8_t *uuid;
-    Vector<uint8_t> *drmSessionId;
-    CHECK(msg->findPointer("uuid", (void**)&uuid));
-    CHECK(msg->findPointer("drmSessionId", (void**)&drmSessionId));
-
-    status = OK;
-    sp<AMediaCryptoWrapper> crypto = NULL;
-
-    status = srcInfo->mSource->prepareDrm(uuid, *drmSessionId, &crypto);
-    if (crypto == NULL) {
-        ALOGE("onPrepareDrm: srcInfo(%lld).mSource->prepareDrm failed. status: %d",
-                (long long)srcId, status);
-        return status;
-    }
-    ALOGV("onPrepareDrm: srcInfo(%lld).mSource->prepareDrm succeeded", (long long)srcId);
-
-    if (srcInfo->mCrypto != NULL) {
-        ALOGE("onPrepareDrm: srcInfo(%lld) Unexpected. Already having mCrypto: %p",
-                (long long)srcId, srcInfo->mCrypto.get());
-        srcInfo->mCrypto.clear();
-    }
-
-    srcInfo->mCrypto = crypto;
-    srcInfo->mIsDrmProtected = true;
-    // TODO change to ALOGV
-    ALOGD("onPrepareDrm: mCrypto: %p", srcInfo->mCrypto.get());
-
-    return status;
-}
-
-status_t NuPlayer2::onReleaseDrm(const sp<AMessage> &msg)
-{
-    // TODO change to ALOGV
-    ALOGD("onReleaseDrm ");
-    SourceInfo *srcInfo = getSourceInfoByIdInMsg(msg);;
-    if (srcInfo == NULL) {
-        return INVALID_OPERATION;
-    }
-
-    int64_t srcId = srcInfo->mSrcId;
-    if (!srcInfo->mIsDrmProtected) {
-        ALOGW("onReleaseDrm: srcInfo(%lld) Unexpected. mIsDrmProtected is already false.",
-                (long long)srcId);
-    }
-
-    srcInfo->mIsDrmProtected = false;
-
-    status_t status;
-    if (srcInfo->mCrypto != NULL) {
-        // notifying the source first before removing crypto from codec
-        if (srcInfo->mSource != NULL) {
-            srcInfo->mSource->releaseDrm();
-        }
-
-        status=OK;
-        // first making sure the codecs have released their crypto reference
-        const sp<DecoderBase> &videoDecoder = getDecoder(false/*audio*/);
-        if (videoDecoder != NULL) {
-            status = videoDecoder->releaseCrypto();
-            ALOGV("onReleaseDrm: video decoder ret: %d", status);
-        }
-
-        const sp<DecoderBase> &audioDecoder = getDecoder(true/*audio*/);
-        if (audioDecoder != NULL) {
-            status_t status_audio = audioDecoder->releaseCrypto();
-            if (status == OK) {   // otherwise, returning the first error
-                status = status_audio;
-            }
-            ALOGV("onReleaseDrm: audio decoder ret: %d", status_audio);
-        }
-
-        // TODO change to ALOGV
-        ALOGD("onReleaseDrm: mCrypto: %p", srcInfo->mCrypto.get());
-        srcInfo->mCrypto.clear();
-    } else {   // srcInfo->mCrypto == NULL
-        ALOGE("onReleaseDrm: Unexpected. There is no crypto.");
-        status = INVALID_OPERATION;
-    }
-
-    return status;
-}
-// Modular DRM end
-////////////////////////////////////////////////////////////////////////////////
-
-sp<AMessage> NuPlayer2::Source::getFormat(bool audio) {
-    sp<MetaData> meta = getFormatMeta(audio);
-
-    if (meta == NULL) {
-        return NULL;
-    }
-
-    sp<AMessage> msg = new AMessage;
-
-    if(convertMetaDataToMessage(meta, &msg) == OK) {
-        return msg;
-    }
-    return NULL;
-}
-
-void NuPlayer2::Source::notifyFlagsChanged(uint32_t flags) {
-    sp<AMessage> notify = dupNotify();
-    notify->setInt32("what", kWhatFlagsChanged);
-    notify->setInt32("flags", flags);
-    notify->post();
-}
-
-void NuPlayer2::Source::notifyVideoSizeChanged(const sp<AMessage> &format) {
-    sp<AMessage> notify = dupNotify();
-    notify->setInt32("what", kWhatVideoSizeChanged);
-    notify->setMessage("format", format);
-    notify->post();
-}
-
-void NuPlayer2::Source::notifyPrepared(status_t err) {
-    ALOGV("Source::notifyPrepared %d", err);
-    sp<AMessage> notify = dupNotify();
-    notify->setInt32("what", kWhatPrepared);
-    notify->setInt32("err", err);
-    notify->post();
-}
-
-void NuPlayer2::Source::notifyDrmInfo(const sp<ABuffer> &drmInfoBuffer)
-{
-    ALOGV("Source::notifyDrmInfo");
-
-    sp<AMessage> notify = dupNotify();
-    notify->setInt32("what", kWhatDrmInfo);
-    notify->setBuffer("drmInfo", drmInfoBuffer);
-
-    notify->post();
-}
-
-void NuPlayer2::Source::onMessageReceived(const sp<AMessage> & /* msg */) {
-    TRESPASS();
-}
-
-NuPlayer2::SourceInfo::SourceInfo()
-    : mDataSourceType(DATA_SOURCE_TYPE_NONE),
-      mSrcId(0),
-      mSourceFlags(0),
-      mStartTimeUs(0),
-      mEndTimeUs(DataSourceDesc::kMaxTimeUs) {
-}
-
-NuPlayer2::SourceInfo & NuPlayer2::SourceInfo::operator=(const NuPlayer2::SourceInfo &other) {
-    mSource = other.mSource;
-    mCrypto = other.mCrypto;
-    mDataSourceType = (DATA_SOURCE_TYPE)other.mDataSourceType;
-    mSrcId = other.mSrcId;
-    mSourceFlags = other.mSourceFlags;
-    mStartTimeUs = other.mStartTimeUs;
-    mEndTimeUs = other.mEndTimeUs;
-    mIsDrmProtected = other.mIsDrmProtected;
-    return *this;
-}
-
-}  // namespace android
diff --git a/media/libmediaplayer2/nuplayer2/NuPlayer2.h b/media/libmediaplayer2/nuplayer2/NuPlayer2.h
deleted file mode 100644
index b8fb988..0000000
--- a/media/libmediaplayer2/nuplayer2/NuPlayer2.h
+++ /dev/null
@@ -1,369 +0,0 @@
-/*
- * Copyright 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef NU_PLAYER2_H_
-
-#define NU_PLAYER2_H_
-
-#include <media/AudioResamplerPublic.h>
-#include <media/stagefright/foundation/AHandler.h>
-
-#include <mediaplayer2/MediaPlayer2Interface.h>
-#include <mediaplayer2/JObjectHolder.h>
-
-#include "mediaplayer2.pb.h"
-
-using android::media::MediaPlayer2Proto::PlayerMessage;
-
-namespace android {
-
-struct ABuffer;
-struct AMediaCryptoWrapper;
-struct AMessage;
-struct ANativeWindowWrapper;
-struct AudioPlaybackRate;
-struct AVSyncSettings;
-struct DataSourceDesc;
-struct MediaClock;
-struct MediaHTTPService;
-class MetaData;
-struct NuPlayer2Driver;
-
-struct NuPlayer2 : public AHandler {
-    explicit NuPlayer2(pid_t pid, uid_t uid,
-            const sp<MediaClock> &mediaClock, const sp<JObjectHolder> &context);
-
-    void setDriver(const wp<NuPlayer2Driver> &driver);
-
-    void setDataSourceAsync(const sp<DataSourceDesc> &dsd);
-    void prepareNextDataSourceAsync(const sp<DataSourceDesc> &dsd);
-    void playNextDataSource(int64_t srcId);
-
-    status_t getBufferingSettings(BufferingSettings* buffering /* nonnull */);
-    status_t setBufferingSettings(const BufferingSettings& buffering);
-
-    void prepareAsync();
-
-    void setVideoSurfaceTextureAsync(const sp<ANativeWindowWrapper> &nww);
-
-    void setAudioSink(const sp<MediaPlayer2Interface::AudioSink> &sink);
-    status_t setPlaybackSettings(const AudioPlaybackRate &rate);
-    status_t getPlaybackSettings(AudioPlaybackRate *rate /* nonnull */);
-    status_t setSyncSettings(const AVSyncSettings &sync, float videoFpsHint);
-    status_t getSyncSettings(AVSyncSettings *sync /* nonnull */, float *videoFps /* nonnull */);
-
-    void start();
-
-    void pause();
-
-    // Will notify the driver through "notifyResetComplete" once finished.
-    void resetAsync();
-
-    // Request a notification when specified media time is reached.
-    status_t notifyAt(int64_t mediaTimeUs);
-
-    // Will notify the driver through "notifySeekComplete" once finished
-    // and needNotify is true.
-    void seekToAsync(
-            int64_t seekTimeUs,
-            MediaPlayer2SeekMode mode = MediaPlayer2SeekMode::SEEK_PREVIOUS_SYNC,
-            bool needNotify = false);
-    void rewind();
-
-    status_t setVideoScalingMode(int32_t mode);
-    status_t getTrackInfo(int64_t srcId, PlayerMessage* reply) const;
-    status_t getSelectedTrack(int64_t srcId, int32_t type, PlayerMessage* reply) const;
-    status_t selectTrack(int64_t srcId, size_t trackIndex, bool select, int64_t timeUs);
-    status_t getCurrentPosition(int64_t *mediaUs);
-    void getStats(Vector<sp<AMessage> > *mTrackStats);
-
-    sp<MetaData> getFileMeta();
-    float getFrameRate();
-
-    // Modular DRM
-    status_t prepareDrm(int64_t srcId, const uint8_t uuid[16], const Vector<uint8_t> &drmSessionId);
-    status_t releaseDrm(int64_t srcId);
-
-    const char *getDataSourceType();
-
-protected:
-    virtual ~NuPlayer2();
-
-    virtual void onMessageReceived(const sp<AMessage> &msg);
-
-public:
-    struct StreamListener;
-    struct Source;
-
-private:
-    struct Decoder;
-    struct DecoderBase;
-    struct DecoderPassThrough;
-    struct CCDecoder;
-    struct GenericSource2;
-    struct HTTPLiveSource2;
-    struct Renderer;
-    struct RTSPSource2;
-    struct Action;
-    struct SeekAction;
-    struct SetSurfaceAction;
-    struct ResumeDecoderAction;
-    struct FlushDecoderAction;
-    struct PostMessageAction;
-    struct SimpleAction;
-
-    enum {
-        kWhatSetDataSource              = '=DaS',
-        kWhatPrepare                    = 'prep',
-        kWhatPrepareNextDataSource      = 'pNDS',
-        kWhatPlayNextDataSource         = 'plNS',
-        kWhatSetVideoSurface            = '=VSu',
-        kWhatSetAudioSink               = '=AuS',
-        kWhatMoreDataQueued             = 'more',
-        kWhatConfigPlayback             = 'cfPB',
-        kWhatConfigSync                 = 'cfSy',
-        kWhatGetPlaybackSettings        = 'gPbS',
-        kWhatGetSyncSettings            = 'gSyS',
-        kWhatStart                      = 'strt',
-        kWhatScanSources                = 'scan',
-        kWhatVideoNotify                = 'vidN',
-        kWhatAudioNotify                = 'audN',
-        kWhatClosedCaptionNotify        = 'capN',
-        kWhatRendererNotify             = 'renN',
-        kWhatReset                      = 'rset',
-        kWhatNotifyTime                 = 'nfyT',
-        kWhatSeek                       = 'seek',
-        kWhatPause                      = 'paus',
-        kWhatResume                     = 'rsme',
-        kWhatPollDuration               = 'polD',
-        kWhatSourceNotify               = 'srcN',
-        kWhatGetTrackInfo               = 'gTrI',
-        kWhatGetSelectedTrack           = 'gSel',
-        kWhatSelectTrack                = 'selT',
-        kWhatGetBufferingSettings       = 'gBus',
-        kWhatSetBufferingSettings       = 'sBuS',
-        kWhatPrepareDrm                 = 'pDrm',
-        kWhatReleaseDrm                 = 'rDrm',
-        kWhatRewind                     = 'reWd',
-        kWhatEOSMonitor                 = 'eosM',
-    };
-
-    typedef enum {
-        DATA_SOURCE_TYPE_NONE,
-        DATA_SOURCE_TYPE_HTTP_LIVE,
-        DATA_SOURCE_TYPE_RTSP,
-        DATA_SOURCE_TYPE_GENERIC_URL,
-        DATA_SOURCE_TYPE_GENERIC_FD,
-        DATA_SOURCE_TYPE_MEDIA,
-    } DATA_SOURCE_TYPE;
-
-    struct SourceInfo {
-        SourceInfo();
-        SourceInfo &operator=(const SourceInfo &);
-
-        sp<Source> mSource;
-        std::atomic<DATA_SOURCE_TYPE> mDataSourceType;
-        int64_t mSrcId;
-        uint32_t mSourceFlags;
-        int64_t mStartTimeUs;
-        int64_t mEndTimeUs;
-        // Modular DRM
-        sp<AMediaCryptoWrapper> mCrypto;
-        bool mIsDrmProtected = false;
-    };
-
-    wp<NuPlayer2Driver> mDriver;
-    pid_t mPID;
-    uid_t mUID;
-    const sp<MediaClock> mMediaClock;
-    Mutex mSourceLock;  // guard |mSource|.
-    SourceInfo mCurrentSourceInfo;
-    SourceInfo mNextSourceInfo;
-    sp<ANativeWindowWrapper> mNativeWindow;
-    sp<MediaPlayer2Interface::AudioSink> mAudioSink;
-    sp<DecoderBase> mVideoDecoder;
-    bool mOffloadAudio;
-    sp<DecoderBase> mAudioDecoder;
-    Mutex mDecoderLock;  // guard |mAudioDecoder| and |mVideoDecoder|.
-    sp<CCDecoder> mCCDecoder;
-    sp<Renderer> mRenderer;
-    sp<ALooper> mRendererLooper;
-    int32_t mAudioDecoderGeneration;
-    int32_t mVideoDecoderGeneration;
-    int32_t mRendererGeneration;
-    int32_t mEOSMonitorGeneration;
-
-    Mutex mPlayingTimeLock;
-    int64_t mLastStartedPlayingTimeNs;
-    void stopPlaybackTimer(const char *where);
-    void startPlaybackTimer(const char *where);
-
-    int64_t mLastStartedRebufferingTimeNs;
-    void startRebufferingTimer();
-    void stopRebufferingTimer(bool exitingPlayback);
-
-    int64_t mPreviousSeekTimeUs;
-
-    List<sp<Action> > mDeferredActions;
-
-    bool mAudioEOS;
-    bool mVideoEOS;
-
-    bool mScanSourcesPending;
-    int32_t mScanSourcesGeneration;
-
-    int32_t mPollDurationGeneration;
-    int32_t mTimedTextGeneration;
-
-    enum FlushStatus {
-        NONE,
-        FLUSHING_DECODER,
-        FLUSHING_DECODER_SHUTDOWN,
-        SHUTTING_DOWN_DECODER,
-        FLUSHED,
-        SHUT_DOWN,
-    };
-
-    enum FlushCommand {
-        FLUSH_CMD_NONE,
-        FLUSH_CMD_FLUSH,
-        FLUSH_CMD_SHUTDOWN,
-    };
-
-    // Status of flush responses from the decoder and renderer.
-    bool mFlushComplete[2][2];
-
-    FlushStatus mFlushingAudio;
-    FlushStatus mFlushingVideo;
-
-    // Status of flush responses from the decoder and renderer.
-    bool mResumePending;
-
-    int32_t mVideoScalingMode;
-
-    AudioPlaybackRate mPlaybackSettings;
-    AVSyncSettings mSyncSettings;
-    float mVideoFpsHint;
-    bool mStarted;
-    bool mPrepared;
-    bool mResetting;
-    bool mSourceStarted;
-    bool mAudioDecoderError;
-    bool mVideoDecoderError;
-
-    // Actual pause state, either as requested by client or due to buffering.
-    bool mPaused;
-
-    // Pause state as requested by client. Note that if mPausedByClient is
-    // true, mPaused is always true; if mPausedByClient is false, mPaused could
-    // still become true, when we pause internally due to buffering.
-    bool mPausedByClient;
-
-    // Pause state as requested by source (internally) due to buffering
-    bool mPausedForBuffering;
-
-    // Passed from JAVA
-    const sp<JObjectHolder> mContext;
-
-    inline const sp<DecoderBase> &getDecoder(bool audio) {
-        return audio ? mAudioDecoder : mVideoDecoder;
-    }
-
-    inline void clearFlushComplete() {
-        mFlushComplete[0][0] = false;
-        mFlushComplete[0][1] = false;
-        mFlushComplete[1][0] = false;
-        mFlushComplete[1][1] = false;
-    }
-
-    void disconnectSource();
-
-    status_t createNuPlayer2Source(const sp<DataSourceDesc> &dsd,
-                                   sp<Source> *source,
-                                   DATA_SOURCE_TYPE *dataSourceType);
-
-    void tryOpenAudioSinkForOffload(
-            const sp<AMessage> &format, const sp<MetaData> &audioMeta, bool hasVideo);
-    void closeAudioSink();
-    void restartAudio(
-            int64_t currentPositionUs, bool forceNonOffload, bool needsToCreateAudioDecoder);
-    void determineAudioModeChange(const sp<AMessage> &audioFormat);
-
-    status_t instantiateDecoder(
-            bool audio, sp<DecoderBase> *decoder, bool checkAudioModeChange = true);
-
-    void updateVideoSize(
-            int64_t srcId,
-            const sp<AMessage> &inputFormat,
-            const sp<AMessage> &outputFormat = NULL);
-
-    void notifyListener(int64_t srcId, int msg, int ext1, int ext2, const PlayerMessage *in = NULL);
-
-    void addEndTimeMonitor();
-
-    void handleFlushComplete(bool audio, bool isDecoder);
-    void finishFlushIfPossible();
-
-    void onStart(bool play);
-    void onResume();
-    void onPause();
-
-    bool audioDecoderStillNeeded();
-
-    void flushDecoder(bool audio, bool needShutdown);
-
-    void finishResume();
-    void notifyDriverSeekComplete(int64_t srcId);
-
-    void postScanSources();
-
-    void schedulePollDuration();
-    void cancelPollDuration();
-
-    void processDeferredActions();
-
-    void performSeek(int64_t seekTimeUs, MediaPlayer2SeekMode mode);
-    void performDecoderFlush(FlushCommand audio, FlushCommand video);
-    void performReset();
-    void performPlayNextDataSource();
-    void performScanSources();
-    void performSetSurface(const sp<ANativeWindowWrapper> &nw);
-    void performResumeDecoders(bool needNotify);
-
-    void onSourceNotify(const sp<AMessage> &msg);
-    void onClosedCaptionNotify(const sp<AMessage> &msg);
-
-    void queueDecoderShutdown(
-            bool audio, bool video, const sp<AMessage> &reply);
-
-    void sendSubtitleData(const sp<ABuffer> &buffer, int32_t baseIndex);
-    void sendTimedMetaData(const sp<ABuffer> &buffer);
-    void sendTimedTextData(const sp<ABuffer> &buffer);
-
-    void writeTrackInfo(PlayerMessage* reply, const sp<AMessage>& format) const;
-
-    status_t onPrepareDrm(const sp<AMessage> &msg);
-    status_t onReleaseDrm(const sp<AMessage> &msg);
-
-    SourceInfo* getSourceInfoByIdInMsg(const sp<AMessage> &msg);
-    void resetSourceInfo(SourceInfo &srcInfo);
-
-    DISALLOW_EVIL_CONSTRUCTORS(NuPlayer2);
-};
-
-}  // namespace android
-
-#endif  // NU_PLAYER2_H_
diff --git a/media/libmediaplayer2/nuplayer2/NuPlayer2CCDecoder.cpp b/media/libmediaplayer2/nuplayer2/NuPlayer2CCDecoder.cpp
deleted file mode 100644
index 98c3403..0000000
--- a/media/libmediaplayer2/nuplayer2/NuPlayer2CCDecoder.cpp
+++ /dev/null
@@ -1,606 +0,0 @@
-/*
- * Copyright 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-//#define LOG_NDEBUG 0
-#define LOG_TAG "NuPlayer2CCDecoder"
-#include <utils/Log.h>
-#include <inttypes.h>
-
-#include "NuPlayer2CCDecoder.h"
-
-#include <media/NdkMediaFormat.h>
-#include <media/stagefright/foundation/ABitReader.h>
-#include <media/stagefright/foundation/ABuffer.h>
-#include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/foundation/AMessage.h>
-#include <media/stagefright/foundation/avc_utils.h>
-#include <media/stagefright/MediaDefs.h>
-
-namespace android {
-
-// In CEA-708B, the maximum bandwidth of CC is set to 9600bps.
-static const size_t kMaxBandwithSizeBytes = 9600 / 8;
-
-struct CCData {
-    CCData(uint8_t type, uint8_t data1, uint8_t data2)
-        : mType(type), mData1(data1), mData2(data2) {
-    }
-    bool getChannel(size_t *channel) const {
-        if (mData1 >= 0x10 && mData1 <= 0x1f) {
-            *channel = (mData1 >= 0x18 ? 1 : 0) + (mType ? 2 : 0);
-            return true;
-        }
-        return false;
-    }
-
-    uint8_t mType;
-    uint8_t mData1;
-    uint8_t mData2;
-};
-
-static bool isNullPad(CCData *cc) {
-    return cc->mData1 < 0x10 && cc->mData2 < 0x10;
-}
-
-static void dumpBytePair(const sp<ABuffer> &ccBuf) __attribute__ ((unused));
-static void dumpBytePair(const sp<ABuffer> &ccBuf) {
-    size_t offset = 0;
-    AString out;
-
-    while (offset < ccBuf->size()) {
-        char tmp[128];
-
-        CCData *cc = (CCData *) (ccBuf->data() + offset);
-
-        if (isNullPad(cc)) {
-            // 1 null pad or XDS metadata, ignore
-            offset += sizeof(CCData);
-            continue;
-        }
-
-        if (cc->mData1 >= 0x20 && cc->mData1 <= 0x7f) {
-            // 2 basic chars
-            snprintf(tmp, sizeof(tmp), "[%d]Basic: %c %c", cc->mType, cc->mData1, cc->mData2);
-        } else if ((cc->mData1 == 0x11 || cc->mData1 == 0x19)
-                 && cc->mData2 >= 0x30 && cc->mData2 <= 0x3f) {
-            // 1 special char
-            snprintf(tmp, sizeof(tmp), "[%d]Special: %02x %02x", cc->mType, cc->mData1, cc->mData2);
-        } else if ((cc->mData1 == 0x12 || cc->mData1 == 0x1A)
-                 && cc->mData2 >= 0x20 && cc->mData2 <= 0x3f){
-            // 1 Spanish/French char
-            snprintf(tmp, sizeof(tmp), "[%d]Spanish: %02x %02x", cc->mType, cc->mData1, cc->mData2);
-        } else if ((cc->mData1 == 0x13 || cc->mData1 == 0x1B)
-                 && cc->mData2 >= 0x20 && cc->mData2 <= 0x3f){
-            // 1 Portuguese/German/Danish char
-            snprintf(tmp, sizeof(tmp), "[%d]German: %02x %02x", cc->mType, cc->mData1, cc->mData2);
-        } else if ((cc->mData1 == 0x11 || cc->mData1 == 0x19)
-                 && cc->mData2 >= 0x20 && cc->mData2 <= 0x2f){
-            // Mid-Row Codes (Table 69)
-            snprintf(tmp, sizeof(tmp), "[%d]Mid-row: %02x %02x", cc->mType, cc->mData1, cc->mData2);
-        } else if (((cc->mData1 == 0x14 || cc->mData1 == 0x1c)
-                  && cc->mData2 >= 0x20 && cc->mData2 <= 0x2f)
-                  ||
-                   ((cc->mData1 == 0x17 || cc->mData1 == 0x1f)
-                  && cc->mData2 >= 0x21 && cc->mData2 <= 0x23)){
-            // Misc Control Codes (Table 70)
-            snprintf(tmp, sizeof(tmp), "[%d]Ctrl: %02x %02x", cc->mType, cc->mData1, cc->mData2);
-        } else if ((cc->mData1 & 0x70) == 0x10
-                && (cc->mData2 & 0x40) == 0x40
-                && ((cc->mData1 & 0x07) || !(cc->mData2 & 0x20)) ) {
-            // Preamble Address Codes (Table 71)
-            snprintf(tmp, sizeof(tmp), "[%d]PAC: %02x %02x", cc->mType, cc->mData1, cc->mData2);
-        } else {
-            snprintf(tmp, sizeof(tmp), "[%d]Invalid: %02x %02x", cc->mType, cc->mData1, cc->mData2);
-        }
-
-        if (out.size() > 0) {
-            out.append(", ");
-        }
-
-        out.append(tmp);
-
-        offset += sizeof(CCData);
-    }
-
-    ALOGI("%s", out.c_str());
-}
-
-NuPlayer2::CCDecoder::CCDecoder(const sp<AMessage> &notify)
-    : mNotify(notify),
-      mSelectedTrack(-1),
-      mDTVCCPacket(new ABuffer(kMaxBandwithSizeBytes)) {
-    mDTVCCPacket->setRange(0, 0);
-
-    // In CEA-608, streams from packets which have the value 0 of cc_type contain CC1 and CC2, and
-    // streams from packets which have the value 1 of cc_type contain CC3 and CC4.
-    // The following array indicates the current transmitting channels for each value of cc_type.
-    mLine21Channels[0] = 0; // CC1
-    mLine21Channels[1] = 2; // CC3
-}
-
-size_t NuPlayer2::CCDecoder::getTrackCount() const {
-    return mTracks.size();
-}
-
-sp<AMessage> NuPlayer2::CCDecoder::getTrackInfo(size_t index) const {
-    if (!isTrackValid(index)) {
-        return NULL;
-    }
-
-    sp<AMessage> format = new AMessage();
-
-    CCTrack track = mTracks[index];
-
-    format->setInt32("type", MEDIA_TRACK_TYPE_SUBTITLE);
-    format->setString("language", "und");
-
-    switch (track.mTrackType) {
-        case kTrackTypeCEA608:
-            format->setString("mime", MEDIA_MIMETYPE_TEXT_CEA_608);
-            break;
-        case kTrackTypeCEA708:
-            format->setString("mime", MEDIA_MIMETYPE_TEXT_CEA_708);
-            break;
-        default:
-            ALOGE("Unknown track type: %d", track.mTrackType);
-            return NULL;
-    }
-
-    // For CEA-608 CC1, field 0 channel 0
-    bool isDefaultAuto = track.mTrackType == kTrackTypeCEA608
-            && track.mTrackChannel == 0;
-    // For CEA-708, Primary Caption Service.
-    bool isDefaultOnly = track.mTrackType == kTrackTypeCEA708
-            && track.mTrackChannel == 1;
-    format->setInt32("auto", isDefaultAuto);
-    format->setInt32("default", isDefaultAuto || isDefaultOnly);
-    format->setInt32("forced", 0);
-
-    return format;
-}
-
-status_t NuPlayer2::CCDecoder::selectTrack(size_t index, bool select) {
-    if (!isTrackValid(index)) {
-        return BAD_VALUE;
-    }
-
-    if (select) {
-        if (mSelectedTrack == (ssize_t)index) {
-            ALOGE("track %zu already selected", index);
-            return BAD_VALUE;
-        }
-        ALOGV("selected track %zu", index);
-        mSelectedTrack = index;
-    } else {
-        if (mSelectedTrack != (ssize_t)index) {
-            ALOGE("track %zu is not selected", index);
-            return BAD_VALUE;
-        }
-        ALOGV("unselected track %zu", index);
-        mSelectedTrack = -1;
-    }
-
-    // Clear the previous track payloads
-    mCCMap.clear();
-
-    return OK;
-}
-
-ssize_t NuPlayer2::CCDecoder::getSelectedTrack(media_track_type type) const {
-    if (mSelectedTrack != -1) {
-        CCTrack track = mTracks[mSelectedTrack];
-        if (track.mTrackType == kTrackTypeCEA608 || track.mTrackType == kTrackTypeCEA708) {
-            return (type == MEDIA_TRACK_TYPE_SUBTITLE ? mSelectedTrack : -1);
-        }
-        return (type == MEDIA_TRACK_TYPE_UNKNOWN ? mSelectedTrack : -1);
-    }
-
-    return -1;
-}
-
-bool NuPlayer2::CCDecoder::isSelected() const {
-    return mSelectedTrack >= 0 && mSelectedTrack < (int32_t)getTrackCount();
-}
-
-bool NuPlayer2::CCDecoder::isTrackValid(size_t index) const {
-    return index < getTrackCount();
-}
-
-// returns true if a new CC track is found
-bool NuPlayer2::CCDecoder::extractFromSEI(const sp<ABuffer> &accessUnit) {
-    sp<ABuffer> sei;
-    if (!accessUnit->meta()->findBuffer("sei", &sei) || sei == NULL) {
-        return false;
-    }
-
-    int64_t timeUs;
-    CHECK(accessUnit->meta()->findInt64("timeUs", &timeUs));
-
-    bool trackAdded = false;
-
-    const NALPosition *nal = (NALPosition *)sei->data();
-
-    for (size_t i = 0; i < sei->size() / sizeof(NALPosition); ++i, ++nal) {
-        trackAdded |= parseSEINalUnit(
-                timeUs, accessUnit->data() + nal->nalOffset, nal->nalSize);
-    }
-
-    return trackAdded;
-}
-
-// returns true if a new CC track is found
-bool NuPlayer2::CCDecoder::parseSEINalUnit(int64_t timeUs, const uint8_t *data, size_t size) {
-    unsigned nalType = data[0] & 0x1f;
-
-    // the buffer should only have SEI in it
-    if (nalType != 6) {
-        return false;
-    }
-
-    bool trackAdded = false;
-    NALBitReader br(data + 1, size - 1);
-
-    // sei_message()
-    while (br.atLeastNumBitsLeft(16)) { // at least 16-bit for sei_message()
-        uint32_t payload_type = 0;
-        size_t payload_size = 0;
-        uint8_t last_byte;
-
-        do {
-            last_byte = br.getBits(8);
-            payload_type += last_byte;
-        } while (last_byte == 0xFF);
-
-        do {
-            last_byte = br.getBits(8);
-            payload_size += last_byte;
-        } while (last_byte == 0xFF);
-
-        if (payload_size > SIZE_MAX / 8
-                || !br.atLeastNumBitsLeft(payload_size * 8)) {
-            ALOGV("Malformed SEI payload");
-            break;
-        }
-
-        // sei_payload()
-        if (payload_type == 4) {
-            bool isCC = false;
-            if (payload_size > 1 + 2 + 4 + 1) {
-                // user_data_registered_itu_t_t35()
-
-                // ATSC A/72: 6.4.2
-                uint8_t itu_t_t35_country_code = br.getBits(8);
-                uint16_t itu_t_t35_provider_code = br.getBits(16);
-                uint32_t user_identifier = br.getBits(32);
-                uint8_t user_data_type_code = br.getBits(8);
-
-                payload_size -= 1 + 2 + 4 + 1;
-
-                isCC = itu_t_t35_country_code == 0xB5
-                        && itu_t_t35_provider_code == 0x0031
-                        && user_identifier == 'GA94'
-                        && user_data_type_code == 0x3;
-            }
-
-            if (isCC && payload_size > 2) {
-                trackAdded |= parseMPEGCCData(timeUs, br.data(), br.numBitsLeft() / 8);
-            } else {
-                ALOGV("Malformed SEI payload type 4");
-            }
-        } else {
-            ALOGV("Unsupported SEI payload type %d", payload_type);
-        }
-
-        // skipping remaining bits of this payload
-        br.skipBits(payload_size * 8);
-    }
-
-    return trackAdded;
-}
-
-// returns true if a new CC track is found
-bool NuPlayer2::CCDecoder::extractFromMPEGUserData(const sp<ABuffer> &accessUnit) {
-    sp<ABuffer> mpegUserData;
-    if (!accessUnit->meta()->findBuffer(AMEDIAFORMAT_KEY_MPEG_USER_DATA, &mpegUserData)
-            || mpegUserData == NULL) {
-        return false;
-    }
-
-    int64_t timeUs;
-    CHECK(accessUnit->meta()->findInt64("timeUs", &timeUs));
-
-    bool trackAdded = false;
-
-    const size_t *userData = (size_t *)mpegUserData->data();
-
-    for (size_t i = 0; i < mpegUserData->size() / sizeof(size_t); ++i) {
-        trackAdded |= parseMPEGUserDataUnit(
-                timeUs, accessUnit->data() + userData[i], accessUnit->size() - userData[i]);
-    }
-
-    return trackAdded;
-}
-
-// returns true if a new CC track is found
-bool NuPlayer2::CCDecoder::parseMPEGUserDataUnit(int64_t timeUs, const uint8_t *data, size_t size) {
-    ABitReader br(data + 4, 5);
-
-    uint32_t user_identifier = br.getBits(32);
-    uint8_t user_data_type = br.getBits(8);
-
-    if (user_identifier == 'GA94' && user_data_type == 0x3) {
-        return parseMPEGCCData(timeUs, data + 9, size - 9);
-    }
-
-    return false;
-}
-
-// returns true if a new CC track is found
-bool NuPlayer2::CCDecoder::parseMPEGCCData(int64_t timeUs, const uint8_t *data, size_t size) {
-    bool trackAdded = false;
-
-    // MPEG_cc_data()
-    // ATSC A/53 Part 4: 6.2.3.1
-    ABitReader br(data, size);
-
-    if (br.numBitsLeft() <= 16) {
-        return false;
-    }
-
-    br.skipBits(1);
-    bool process_cc_data_flag = br.getBits(1);
-    br.skipBits(1);
-    size_t cc_count = br.getBits(5);
-    br.skipBits(8);
-
-    if (!process_cc_data_flag || 3 * 8 * cc_count >= br.numBitsLeft()) {
-        return false;
-    }
-
-    sp<ABuffer> line21CCBuf = NULL;
-
-    for (size_t i = 0; i < cc_count; ++i) {
-        br.skipBits(5);
-        bool cc_valid = br.getBits(1);
-        uint8_t cc_type = br.getBits(2);
-
-        if (cc_valid) {
-            if (cc_type == 3) {
-                if (mDTVCCPacket->size() > 0) {
-                    trackAdded |= parseDTVCCPacket(
-                            timeUs, mDTVCCPacket->data(), mDTVCCPacket->size());
-                    mDTVCCPacket->setRange(0, 0);
-                }
-                if (mDTVCCPacket->size() + 2 > mDTVCCPacket->capacity()) {
-                    return false;
-                }
-                memcpy(mDTVCCPacket->data() + mDTVCCPacket->size(), br.data(), 2);
-                mDTVCCPacket->setRange(0, mDTVCCPacket->size() + 2);
-                br.skipBits(16);
-            } else if (mDTVCCPacket->size() > 0 && cc_type == 2) {
-                if (mDTVCCPacket->size() + 2 > mDTVCCPacket->capacity()) {
-                    return false;
-                }
-                memcpy(mDTVCCPacket->data() + mDTVCCPacket->size(), br.data(), 2);
-                mDTVCCPacket->setRange(0, mDTVCCPacket->size() + 2);
-                br.skipBits(16);
-            } else if (cc_type == 0 || cc_type == 1) {
-                uint8_t cc_data_1 = br.getBits(8) & 0x7f;
-                uint8_t cc_data_2 = br.getBits(8) & 0x7f;
-
-                CCData cc(cc_type, cc_data_1, cc_data_2);
-
-                if (isNullPad(&cc)) {
-                    continue;
-                }
-
-                size_t channel;
-                if (cc.getChannel(&channel)) {
-                    mLine21Channels[cc_type] = channel;
-
-                    // create a new track if it does not exist.
-                    getTrackIndex(kTrackTypeCEA608, channel, &trackAdded);
-                }
-
-                if (isSelected() && mTracks[mSelectedTrack].mTrackType == kTrackTypeCEA608
-                        && mTracks[mSelectedTrack].mTrackChannel == mLine21Channels[cc_type]) {
-                    if (line21CCBuf == NULL) {
-                        line21CCBuf = new ABuffer((cc_count - i) * sizeof(CCData));
-                        line21CCBuf->setRange(0, 0);
-                    }
-                    if (line21CCBuf->size() + sizeof(cc) > line21CCBuf->capacity()) {
-                        return false;
-                    }
-                    memcpy(line21CCBuf->data() + line21CCBuf->size(), &cc, sizeof(cc));
-                    line21CCBuf->setRange(0, line21CCBuf->size() + sizeof(CCData));
-                }
-            } else {
-                br.skipBits(16);
-            }
-        } else {
-            if ((cc_type == 3 || cc_type == 2) && mDTVCCPacket->size() > 0) {
-                trackAdded |= parseDTVCCPacket(timeUs, mDTVCCPacket->data(), mDTVCCPacket->size());
-                mDTVCCPacket->setRange(0, 0);
-            }
-            br.skipBits(16);
-        }
-    }
-
-    if (isSelected() && mTracks[mSelectedTrack].mTrackType == kTrackTypeCEA608
-            && line21CCBuf != NULL && line21CCBuf->size() > 0) {
-        mCCMap.add(timeUs, line21CCBuf);
-    }
-
-    return trackAdded;
-}
-
-// returns true if a new CC track is found
-bool NuPlayer2::CCDecoder::parseDTVCCPacket(int64_t timeUs, const uint8_t *data, size_t size) {
-    // CEA-708B 5 DTVCC Packet Layer.
-    ABitReader br(data, size);
-    br.skipBits(2);
-
-    size_t packet_size = br.getBits(6);
-    if (packet_size == 0) packet_size = 64;
-    packet_size *= 2;
-
-    if (size != packet_size) {
-        return false;
-    }
-
-    bool trackAdded = false;
-
-    while (br.numBitsLeft() >= 16) {
-        // CEA-708B Figure 5 and 6.
-        uint8_t service_number = br.getBits(3);
-        size_t block_size = br.getBits(5);
-
-        if (service_number == 64) {
-            br.skipBits(2);
-            service_number = br.getBits(6);
-
-            if (service_number < 64) {
-                return trackAdded;
-            }
-        }
-
-        if (br.numBitsLeft() < block_size * 8) {
-            return trackAdded;
-        }
-
-        if (block_size > 0) {
-            size_t trackIndex = getTrackIndex(kTrackTypeCEA708, service_number, &trackAdded);
-            if (mSelectedTrack == (ssize_t)trackIndex) {
-                sp<ABuffer> ccPacket = new ABuffer(block_size);
-                if (ccPacket->capacity() == 0) {
-                    return false;
-                }
-                memcpy(ccPacket->data(), br.data(), block_size);
-                mCCMap.add(timeUs, ccPacket);
-            }
-        }
-        br.skipBits(block_size * 8);
-    }
-
-    return trackAdded;
-}
-
-// return the track index for a given type and channel.
-// if the track does not exist, creates a new one.
-size_t NuPlayer2::CCDecoder::getTrackIndex(
-        int32_t trackType, size_t channel, bool *trackAdded) {
-    CCTrack track(trackType, channel);
-    ssize_t index = mTrackIndices.indexOfKey(track);
-
-    if (index < 0) {
-        // A new track is added.
-        index = mTracks.size();
-        mTrackIndices.add(track, index);
-        mTracks.add(track);
-        *trackAdded = true;
-        return index;
-    }
-
-    return mTrackIndices.valueAt(index);
-}
-
-void NuPlayer2::CCDecoder::decode(const sp<ABuffer> &accessUnit) {
-    if (extractFromMPEGUserData(accessUnit) || extractFromSEI(accessUnit)) {
-        sp<AMessage> msg = mNotify->dup();
-        msg->setInt32("what", kWhatTrackAdded);
-        msg->post();
-    }
-    // TODO: extract CC from other sources
-}
-
-void NuPlayer2::CCDecoder::display(int64_t timeUs) {
-    if (!isSelected()) {
-        return;
-    }
-
-    ssize_t index = mCCMap.indexOfKey(timeUs);
-    if (index < 0) {
-        ALOGV("cc for timestamp %" PRId64 " not found", timeUs);
-        return;
-    }
-
-    sp<ABuffer> ccBuf;
-
-    if (index == 0) {
-        ccBuf = mCCMap.valueAt(index);
-    } else {
-        size_t size = 0;
-
-        for (ssize_t i = 0; i <= index; ++i) {
-            size += mCCMap.valueAt(i)->size();
-        }
-
-        ccBuf = new ABuffer(size);
-        ccBuf->setRange(0, 0);
-
-        if (ccBuf->capacity() > 0) {
-            for (ssize_t i = 0; i <= index; ++i) {
-                sp<ABuffer> buf = mCCMap.valueAt(i);
-                memcpy(ccBuf->data() + ccBuf->size(), buf->data(), buf->size());
-                ccBuf->setRange(0, ccBuf->size() + buf->size());
-            }
-        }
-    }
-
-    if (ccBuf->size() > 0) {
-#if 0
-        dumpBytePair(ccBuf);
-#endif
-
-        ccBuf->meta()->setInt32(AMEDIAFORMAT_KEY_TRACK_INDEX, mSelectedTrack);
-        ccBuf->meta()->setInt64("timeUs", timeUs);
-        ccBuf->meta()->setInt64("durationUs", 0LL);
-
-        sp<AMessage> msg = mNotify->dup();
-        msg->setInt32("what", kWhatClosedCaptionData);
-        msg->setBuffer("buffer", ccBuf);
-        msg->post();
-    }
-
-    // remove all entries before timeUs
-    mCCMap.removeItemsAt(0, index + 1);
-}
-
-void NuPlayer2::CCDecoder::flush() {
-    mCCMap.clear();
-    mDTVCCPacket->setRange(0, 0);
-}
-
-int32_t NuPlayer2::CCDecoder::CCTrack::compare(const NuPlayer2::CCDecoder::CCTrack& rhs) const {
-    int32_t cmp = mTrackType - rhs.mTrackType;
-    if (cmp != 0) return cmp;
-    return mTrackChannel - rhs.mTrackChannel;
-}
-
-bool NuPlayer2::CCDecoder::CCTrack::operator<(const NuPlayer2::CCDecoder::CCTrack& rhs) const {
-    return compare(rhs) < 0;
-}
-
-bool NuPlayer2::CCDecoder::CCTrack::operator==(const NuPlayer2::CCDecoder::CCTrack& rhs) const {
-    return compare(rhs) == 0;
-}
-
-bool NuPlayer2::CCDecoder::CCTrack::operator!=(const NuPlayer2::CCDecoder::CCTrack& rhs) const {
-    return compare(rhs) != 0;
-}
-
-}  // namespace android
-
diff --git a/media/libmediaplayer2/nuplayer2/NuPlayer2CCDecoder.h b/media/libmediaplayer2/nuplayer2/NuPlayer2CCDecoder.h
deleted file mode 100644
index 97834d1..0000000
--- a/media/libmediaplayer2/nuplayer2/NuPlayer2CCDecoder.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef NUPLAYER2_CCDECODER_H_
-
-#define NUPLAYER2_CCDECODER_H_
-
-#include "NuPlayer2.h"
-
-namespace android {
-
-struct NuPlayer2::CCDecoder : public RefBase {
-    enum {
-        kWhatClosedCaptionData,
-        kWhatTrackAdded,
-    };
-
-    enum {
-        kTrackTypeCEA608,
-        kTrackTypeCEA708,
-    };
-
-    explicit CCDecoder(const sp<AMessage> &notify);
-
-    size_t getTrackCount() const;
-    sp<AMessage> getTrackInfo(size_t index) const;
-    status_t selectTrack(size_t index, bool select);
-    ssize_t getSelectedTrack(media_track_type type) const;
-    bool isSelected() const;
-    void decode(const sp<ABuffer> &accessUnit);
-    void display(int64_t timeUs);
-    void flush();
-
-private:
-    // CC track identifier.
-    struct CCTrack {
-        CCTrack() : mTrackType(0), mTrackChannel(0) { }
-
-        CCTrack(const int32_t trackType, const size_t trackChannel)
-            : mTrackType(trackType), mTrackChannel(trackChannel) { }
-
-        int32_t mTrackType;
-        size_t mTrackChannel;
-
-        // The ordering of CCTracks is to build a map of track to index.
-        // It is necessary to find the index of the matched CCTrack when CC data comes.
-        int compare(const NuPlayer2::CCDecoder::CCTrack& rhs) const;
-        inline bool operator<(const NuPlayer2::CCDecoder::CCTrack& rhs) const;
-        inline bool operator==(const NuPlayer2::CCDecoder::CCTrack& rhs) const;
-        inline bool operator!=(const NuPlayer2::CCDecoder::CCTrack& rhs) const;
-    };
-
-    sp<AMessage> mNotify;
-    KeyedVector<int64_t, sp<ABuffer> > mCCMap;
-    ssize_t mSelectedTrack;
-    KeyedVector<CCTrack, size_t> mTrackIndices;
-    Vector<CCTrack> mTracks;
-
-    // CEA-608 closed caption
-    size_t mLine21Channels[2]; // The current channels of NTSC_CC_FIELD_{1, 2}
-
-    // CEA-708 closed caption
-    sp<ABuffer> mDTVCCPacket;
-
-    bool isTrackValid(size_t index) const;
-    size_t getTrackIndex(int32_t trackType, size_t channel, bool *trackAdded);
-
-    // Extract from H.264 SEIs
-    bool extractFromSEI(const sp<ABuffer> &accessUnit);
-    bool parseSEINalUnit(int64_t timeUs, const uint8_t *data, size_t size);
-
-    // Extract from MPEG user data
-    bool extractFromMPEGUserData(const sp<ABuffer> &accessUnit);
-    bool parseMPEGUserDataUnit(int64_t timeUs, const uint8_t *data, size_t size);
-
-    // Extract CC tracks from MPEG_cc_data
-    bool parseMPEGCCData(int64_t timeUs, const uint8_t *data, size_t size);
-    bool parseDTVCCPacket(int64_t timeUs, const uint8_t *data, size_t size);
-
-    DISALLOW_EVIL_CONSTRUCTORS(CCDecoder);
-};
-
-}  // namespace android
-
-#endif  // NUPLAYER2_CCDECODER_H_
diff --git a/media/libmediaplayer2/nuplayer2/NuPlayer2Decoder.cpp b/media/libmediaplayer2/nuplayer2/NuPlayer2Decoder.cpp
deleted file mode 100644
index 66bfae5..0000000
--- a/media/libmediaplayer2/nuplayer2/NuPlayer2Decoder.cpp
+++ /dev/null
@@ -1,1315 +0,0 @@
-/*
- * Copyright 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-//#define LOG_NDEBUG 0
-#define LOG_TAG "NuPlayer2Decoder"
-#include <utils/Log.h>
-#include <inttypes.h>
-
-#include <algorithm>
-
-#include "NuPlayer2CCDecoder.h"
-#include "NuPlayer2Decoder.h"
-#include "NuPlayer2Drm.h"
-#include "NuPlayer2Renderer.h"
-#include "NuPlayer2Source.h"
-
-#include <cutils/properties.h>
-#include <media/MediaBufferHolder.h>
-#include <media/MediaCodecBuffer.h>
-#include <media/NdkMediaCodec.h>
-#include <media/NdkWrapper.h>
-#include <media/stagefright/foundation/ABuffer.h>
-#include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/foundation/AMessage.h>
-#include <media/stagefright/foundation/avc_utils.h>
-#include <media/stagefright/MediaBuffer.h>
-#include <media/stagefright/MediaDefs.h>
-#include <media/stagefright/MediaErrors.h>
-#include <media/stagefright/SurfaceUtils.h>
-
-#include <system/window.h>
-#include "ATSParser.h"
-
-namespace android {
-
-static float kDisplayRefreshingRate = 60.f; // TODO: get this from the display
-
-// The default total video frame rate of a stream when that info is not available from
-// the source.
-static float kDefaultVideoFrameRateTotal = 30.f;
-
-static inline bool getAudioDeepBufferSetting() {
-    return property_get_bool("media.stagefright.audio.deep", false /* default_value */);
-}
-
-NuPlayer2::Decoder::Decoder(
-        const sp<AMessage> &notify,
-        const sp<Source> &source,
-        pid_t pid,
-        uid_t uid,
-        const sp<Renderer> &renderer,
-        const sp<ANativeWindowWrapper> &nww,
-        const sp<CCDecoder> &ccDecoder)
-    : DecoderBase(notify),
-      mNativeWindow(nww),
-      mSource(source),
-      mRenderer(renderer),
-      mCCDecoder(ccDecoder),
-      mPid(pid),
-      mUid(uid),
-      mSkipRenderingUntilMediaTimeUs(-1LL),
-      mNumFramesTotal(0LL),
-      mNumInputFramesDropped(0LL),
-      mNumOutputFramesDropped(0LL),
-      mVideoWidth(0),
-      mVideoHeight(0),
-      mIsAudio(true),
-      mIsVideoAVC(false),
-      mIsSecure(false),
-      mIsEncrypted(false),
-      mIsEncryptedObservedEarlier(false),
-      mFormatChangePending(false),
-      mTimeChangePending(false),
-      mFrameRateTotal(kDefaultVideoFrameRateTotal),
-      mPlaybackSpeed(1.0f),
-      mNumVideoTemporalLayerTotal(1), // decode all layers
-      mNumVideoTemporalLayerAllowed(1),
-      mCurrentMaxVideoTemporalLayerId(0),
-      mResumePending(false),
-      mComponentName("decoder") {
-    mVideoTemporalLayerAggregateFps[0] = mFrameRateTotal;
-}
-
-NuPlayer2::Decoder::~Decoder() {
-    // Need to stop looper first since mCodec could be accessed on the mDecoderLooper.
-    stopLooper();
-    if (mCodec != NULL) {
-        mCodec->release();
-    }
-    releaseAndResetMediaBuffers();
-}
-
-sp<AMessage> NuPlayer2::Decoder::getStats() const {
-    mStats->setInt64("frames-total", mNumFramesTotal);
-    mStats->setInt64("frames-dropped-input", mNumInputFramesDropped);
-    mStats->setInt64("frames-dropped-output", mNumOutputFramesDropped);
-    mStats->setFloat("frame-rate-total", mFrameRateTotal);
-
-    // i'm mutexed right now.
-    // make our own copy, so we aren't victim to any later changes.
-    sp<AMessage> copiedStats = mStats->dup();
-    return copiedStats;
-}
-
-status_t NuPlayer2::Decoder::setVideoSurface(const sp<ANativeWindowWrapper> &nww) {
-    if (nww == NULL || nww->getANativeWindow() == NULL
-        || ADebug::isExperimentEnabled("legacy-setsurface")) {
-        return BAD_VALUE;
-    }
-
-    sp<AMessage> msg = new AMessage(kWhatSetVideoSurface, this);
-
-    msg->setObject("surface", nww);
-    sp<AMessage> response;
-    status_t err = msg->postAndAwaitResponse(&response);
-    if (err == OK && response != NULL) {
-        CHECK(response->findInt32("err", &err));
-    }
-    return err;
-}
-
-void NuPlayer2::Decoder::onMessageReceived(const sp<AMessage> &msg) {
-    ALOGV("[%s] onMessage: %s", mComponentName.c_str(), msg->debugString().c_str());
-
-    switch (msg->what()) {
-        case kWhatCodecNotify:
-        {
-            int32_t cbID;
-            CHECK(msg->findInt32("callbackID", &cbID));
-
-            ALOGV("[%s] kWhatCodecNotify: cbID = %d, paused = %d",
-                    mIsAudio ? "audio" : "video", cbID, mPaused);
-
-            if (mPaused) {
-                break;
-            }
-
-            switch (cbID) {
-                case AMediaCodecWrapper::CB_INPUT_AVAILABLE:
-                {
-                    int32_t index;
-                    CHECK(msg->findInt32("index", &index));
-
-                    handleAnInputBuffer(index);
-                    break;
-                }
-
-                case AMediaCodecWrapper::CB_OUTPUT_AVAILABLE:
-                {
-                    int32_t index;
-                    size_t offset;
-                    size_t size;
-                    int64_t timeUs;
-                    int32_t flags;
-
-                    CHECK(msg->findInt32("index", &index));
-                    CHECK(msg->findSize("offset", &offset));
-                    CHECK(msg->findSize("size", &size));
-                    CHECK(msg->findInt64("timeUs", &timeUs));
-                    CHECK(msg->findInt32("flags", &flags));
-
-                    handleAnOutputBuffer(index, offset, size, timeUs, flags);
-                    break;
-                }
-
-                case AMediaCodecWrapper::CB_OUTPUT_FORMAT_CHANGED:
-                {
-                    sp<AMessage> format;
-                    CHECK(msg->findMessage("format", &format));
-
-                    handleOutputFormatChange(format);
-                    break;
-                }
-
-                case AMediaCodecWrapper::CB_ERROR:
-                {
-                    status_t err;
-                    CHECK(msg->findInt32("err", &err));
-                    ALOGE("Decoder (%s) reported error : 0x%x",
-                            mIsAudio ? "audio" : "video", err);
-
-                    handleError(err);
-                    break;
-                }
-
-                default:
-                {
-                    TRESPASS();
-                    break;
-                }
-            }
-
-            break;
-        }
-
-        case kWhatRenderBuffer:
-        {
-            if (!isStaleReply(msg)) {
-                onRenderBuffer(msg);
-            }
-            break;
-        }
-
-        case kWhatAudioOutputFormatChanged:
-        {
-            if (!isStaleReply(msg)) {
-                status_t err;
-                if (msg->findInt32("err", &err) && err != OK) {
-                    ALOGE("Renderer reported 0x%x when changing audio output format", err);
-                    handleError(err);
-                }
-            }
-            break;
-        }
-
-        case kWhatSetVideoSurface:
-        {
-            sp<AReplyToken> replyID;
-            CHECK(msg->senderAwaitsResponse(&replyID));
-
-            sp<RefBase> obj;
-            CHECK(msg->findObject("surface", &obj));
-            sp<ANativeWindowWrapper> nww =
-                static_cast<ANativeWindowWrapper *>(obj.get()); // non-null
-            if (nww == NULL || nww->getANativeWindow() == NULL) {
-                break;
-            }
-            int32_t err = INVALID_OPERATION;
-            // NOTE: in practice mNativeWindow is always non-null,
-            // but checking here for completeness
-            if (mCodec != NULL
-                && mNativeWindow != NULL && mNativeWindow->getANativeWindow() != NULL) {
-                // TODO: once AwesomePlayer is removed, remove this automatic connecting
-                // to the surface by MediaPlayerService.
-                //
-                // at this point MediaPlayer2Manager::client has already connected to the
-                // surface, which MediaCodec does not expect
-                err = native_window_api_disconnect(nww->getANativeWindow(),
-                                                   NATIVE_WINDOW_API_MEDIA);
-                if (err == OK) {
-                    err = mCodec->setOutputSurface(nww);
-                    ALOGI_IF(err, "codec setOutputSurface returned: %d", err);
-                    if (err == OK) {
-                        // reconnect to the old surface as MPS::Client will expect to
-                        // be able to disconnect from it.
-                        (void)native_window_api_connect(mNativeWindow->getANativeWindow(),
-                                                        NATIVE_WINDOW_API_MEDIA);
-
-                        mNativeWindow = nww;
-                    }
-                }
-                if (err != OK) {
-                    // reconnect to the new surface on error as MPS::Client will expect to
-                    // be able to disconnect from it.
-                    (void)native_window_api_connect(nww->getANativeWindow(),
-                                                    NATIVE_WINDOW_API_MEDIA);
-                }
-            }
-
-            sp<AMessage> response = new AMessage;
-            response->setInt32("err", err);
-            response->postReply(replyID);
-            break;
-        }
-
-        case kWhatDrmReleaseCrypto:
-        {
-            ALOGV("kWhatDrmReleaseCrypto");
-            onReleaseCrypto(msg);
-            break;
-        }
-
-        default:
-            DecoderBase::onMessageReceived(msg);
-            break;
-    }
-}
-
-void NuPlayer2::Decoder::onConfigure(const sp<AMessage> &format) {
-    ALOGV("[%s] onConfigure (format=%s)", mComponentName.c_str(), format->debugString().c_str());
-    CHECK(mCodec == NULL);
-
-    mFormatChangePending = false;
-    mTimeChangePending = false;
-
-    ++mBufferGeneration;
-
-    AString mime;
-    CHECK(format->findString("mime", &mime));
-
-    mIsAudio = !strncasecmp("audio/", mime.c_str(), 6);
-    mIsVideoAVC = !strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime.c_str());
-
-    mComponentName = mime;
-    mComponentName.append(" decoder");
-    ALOGV("[%s] onConfigure (nww=%p)", mComponentName.c_str(),
-          (mNativeWindow == NULL ? NULL : mNativeWindow->getANativeWindow()));
-
-    mCodec = AMediaCodecWrapper::CreateDecoderByType(mime);
-    int32_t secure = 0;
-    if (format->findInt32("secure", &secure) && secure != 0) {
-        if (mCodec != NULL) {
-            if (mCodec->getName(&mComponentName) == OK) {
-                mComponentName.append(".secure");
-                mCodec->release();
-                ALOGI("[%s] creating", mComponentName.c_str());
-                mCodec = AMediaCodecWrapper::CreateCodecByName(mComponentName);
-            } else {
-                mCodec = NULL;
-            }
-        }
-    }
-    if (mCodec == NULL) {
-        ALOGE("Failed to create %s%s decoder",
-                (secure ? "secure " : ""), mime.c_str());
-        handleError(NO_INIT);
-        return;
-    }
-    mIsSecure = secure;
-
-    mCodec->getName(&mComponentName);
-
-    status_t err;
-    if (mNativeWindow != NULL && mNativeWindow->getANativeWindow() != NULL) {
-        // disconnect from surface as MediaCodec will reconnect
-        err = native_window_api_disconnect(mNativeWindow->getANativeWindow(),
-                                           NATIVE_WINDOW_API_MEDIA);
-        // We treat this as a warning, as this is a preparatory step.
-        // Codec will try to connect to the surface, which is where
-        // any error signaling will occur.
-        ALOGW_IF(err != OK, "failed to disconnect from surface: %d", err);
-    }
-
-    // Modular DRM
-    sp<RefBase> objCrypto;
-    format->findObject("crypto", &objCrypto);
-    sp<AMediaCryptoWrapper> crypto = static_cast<AMediaCryptoWrapper *>(objCrypto.get());
-    // non-encrypted source won't have a crypto
-    mIsEncrypted = (crypto != NULL);
-    // configure is called once; still using OR in case the behavior changes.
-    mIsEncryptedObservedEarlier = mIsEncryptedObservedEarlier || mIsEncrypted;
-    ALOGV("onConfigure mCrypto: %p, mIsSecure: %d", crypto.get(), mIsSecure);
-
-    err = mCodec->configure(
-            AMediaFormatWrapper::Create(format),
-            mNativeWindow,
-            crypto,
-            0 /* flags */);
-
-    if (err != OK) {
-        ALOGE("Failed to configure [%s] decoder (err=%d)", mComponentName.c_str(), err);
-        mCodec->release();
-        mCodec.clear();
-        handleError(err);
-        return;
-    }
-    rememberCodecSpecificData(format);
-
-    // the following should work in configured state
-    sp<AMediaFormatWrapper> outputFormat = mCodec->getOutputFormat();
-    if (outputFormat == NULL) {
-        handleError(INVALID_OPERATION);
-        return;
-    }
-    mInputFormat = mCodec->getInputFormat();
-    if (mInputFormat == NULL) {
-        handleError(INVALID_OPERATION);
-        return;
-    }
-
-    mStats->setString("mime", mime.c_str());
-    mStats->setString("component-name", mComponentName.c_str());
-
-    if (!mIsAudio) {
-        int32_t width, height;
-        if (outputFormat->getInt32("width", &width)
-                && outputFormat->getInt32("height", &height)) {
-            mStats->setInt32("width", width);
-            mStats->setInt32("height", height);
-        }
-    }
-
-    sp<AMessage> reply = new AMessage(kWhatCodecNotify, this);
-    mCodec->setCallback(reply);
-
-    err = mCodec->start();
-    if (err != OK) {
-        ALOGE("Failed to start [%s] decoder (err=%d)", mComponentName.c_str(), err);
-        mCodec->release();
-        mCodec.clear();
-        handleError(err);
-        return;
-    }
-
-    releaseAndResetMediaBuffers();
-
-    mPaused = false;
-    mResumePending = false;
-}
-
-void NuPlayer2::Decoder::onSetParameters(const sp<AMessage> &params) {
-    bool needAdjustLayers = false;
-    float frameRateTotal;
-    if (params->findFloat("frame-rate-total", &frameRateTotal)
-            && mFrameRateTotal != frameRateTotal) {
-        needAdjustLayers = true;
-        mFrameRateTotal = frameRateTotal;
-    }
-
-    int32_t numVideoTemporalLayerTotal;
-    if (params->findInt32("temporal-layer-count", &numVideoTemporalLayerTotal)
-            && numVideoTemporalLayerTotal >= 0
-            && numVideoTemporalLayerTotal <= kMaxNumVideoTemporalLayers
-            && mNumVideoTemporalLayerTotal != numVideoTemporalLayerTotal) {
-        needAdjustLayers = true;
-        mNumVideoTemporalLayerTotal = std::max(numVideoTemporalLayerTotal, 1);
-    }
-
-    if (needAdjustLayers && mNumVideoTemporalLayerTotal > 1) {
-        // TODO: For now, layer fps is calculated for some specific architectures.
-        // But it really should be extracted from the stream.
-        mVideoTemporalLayerAggregateFps[0] =
-            mFrameRateTotal / (float)(1LL << (mNumVideoTemporalLayerTotal - 1));
-        for (int32_t i = 1; i < mNumVideoTemporalLayerTotal; ++i) {
-            mVideoTemporalLayerAggregateFps[i] =
-                mFrameRateTotal / (float)(1LL << (mNumVideoTemporalLayerTotal - i))
-                + mVideoTemporalLayerAggregateFps[i - 1];
-        }
-    }
-
-    float playbackSpeed;
-    if (params->findFloat("playback-speed", &playbackSpeed)
-            && mPlaybackSpeed != playbackSpeed) {
-        needAdjustLayers = true;
-        mPlaybackSpeed = playbackSpeed;
-    }
-
-    if (needAdjustLayers) {
-        float decodeFrameRate = mFrameRateTotal;
-        // enable temporal layering optimization only if we know the layering depth
-        if (mNumVideoTemporalLayerTotal > 1) {
-            int32_t layerId;
-            for (layerId = 0; layerId < mNumVideoTemporalLayerTotal - 1; ++layerId) {
-                if (mVideoTemporalLayerAggregateFps[layerId] * mPlaybackSpeed
-                        >= kDisplayRefreshingRate * 0.9) {
-                    break;
-                }
-            }
-            mNumVideoTemporalLayerAllowed = layerId + 1;
-            decodeFrameRate = mVideoTemporalLayerAggregateFps[layerId];
-        }
-        ALOGV("onSetParameters: allowed layers=%d, decodeFps=%g",
-                mNumVideoTemporalLayerAllowed, decodeFrameRate);
-
-        if (mCodec == NULL) {
-            ALOGW("onSetParameters called before codec is created.");
-            return;
-        }
-
-        sp<AMediaFormatWrapper> codecParams = new AMediaFormatWrapper();
-        codecParams->setFloat("operating-rate", decodeFrameRate * mPlaybackSpeed);
-        mCodec->setParameters(codecParams);
-    }
-}
-
-void NuPlayer2::Decoder::onSetRenderer(const sp<Renderer> &renderer) {
-    mRenderer = renderer;
-}
-
-void NuPlayer2::Decoder::onResume(bool notifyComplete) {
-    mPaused = false;
-
-    if (notifyComplete) {
-        mResumePending = true;
-    }
-
-    if (mCodec == NULL) {
-        ALOGE("[%s] onResume without a valid codec", mComponentName.c_str());
-        handleError(NO_INIT);
-        return;
-    }
-    mCodec->start();
-}
-
-void NuPlayer2::Decoder::doFlush(bool notifyComplete) {
-    if (mCCDecoder != NULL) {
-        mCCDecoder->flush();
-    }
-
-    if (mRenderer != NULL) {
-        mRenderer->flush(mIsAudio, notifyComplete);
-        mRenderer->signalTimeDiscontinuity();
-    }
-
-    status_t err = OK;
-    if (mCodec != NULL) {
-        err = mCodec->flush();
-        mCSDsToSubmit = mCSDsForCurrentFormat; // copy operator
-        ++mBufferGeneration;
-    }
-
-    if (err != OK) {
-        ALOGE("failed to flush [%s] (err=%d)", mComponentName.c_str(), err);
-        handleError(err);
-        // finish with posting kWhatFlushCompleted.
-        // we attempt to release the buffers even if flush fails.
-    }
-    releaseAndResetMediaBuffers();
-    mPaused = true;
-}
-
-
-void NuPlayer2::Decoder::onFlush() {
-    doFlush(true);
-
-    if (isDiscontinuityPending()) {
-        // This could happen if the client starts seeking/shutdown
-        // after we queued an EOS for discontinuities.
-        // We can consider discontinuity handled.
-        finishHandleDiscontinuity(false /* flushOnTimeChange */);
-    }
-
-    sp<AMessage> notify = mNotify->dup();
-    notify->setInt32("what", kWhatFlushCompleted);
-    notify->post();
-}
-
-void NuPlayer2::Decoder::onShutdown(bool notifyComplete) {
-    status_t err = OK;
-
-    // if there is a pending resume request, notify complete now
-    notifyResumeCompleteIfNecessary();
-
-    if (mCodec != NULL) {
-        err = mCodec->release();
-        mCodec = NULL;
-        ++mBufferGeneration;
-
-        if (mNativeWindow != NULL && mNativeWindow->getANativeWindow() != NULL) {
-            // reconnect to surface as MediaCodec disconnected from it
-            status_t error = native_window_api_connect(mNativeWindow->getANativeWindow(),
-                                                       NATIVE_WINDOW_API_MEDIA);
-            ALOGW_IF(error != NO_ERROR,
-                    "[%s] failed to connect to native window, error=%d",
-                    mComponentName.c_str(), error);
-        }
-        mComponentName = "decoder";
-    }
-
-    releaseAndResetMediaBuffers();
-
-    if (err != OK) {
-        ALOGE("failed to release [%s] (err=%d)", mComponentName.c_str(), err);
-        handleError(err);
-        // finish with posting kWhatShutdownCompleted.
-    }
-
-    if (notifyComplete) {
-        sp<AMessage> notify = mNotify->dup();
-        notify->setInt32("what", kWhatShutdownCompleted);
-        notify->post();
-        mPaused = true;
-    }
-}
-
-/*
- * returns true if we should request more data
- */
-bool NuPlayer2::Decoder::doRequestBuffers() {
-    if (isDiscontinuityPending()) {
-        return false;
-    }
-    status_t err = OK;
-    while (err == OK && !mDequeuedInputBuffers.empty()) {
-        size_t bufferIx = *mDequeuedInputBuffers.begin();
-        sp<AMessage> msg = new AMessage();
-        msg->setSize("buffer-ix", bufferIx);
-        err = fetchInputData(msg);
-        if (err != OK && err != ERROR_END_OF_STREAM) {
-            // if EOS, need to queue EOS buffer
-            break;
-        }
-        mDequeuedInputBuffers.erase(mDequeuedInputBuffers.begin());
-
-        if (!mPendingInputMessages.empty()
-                || !onInputBufferFetched(msg)) {
-            mPendingInputMessages.push_back(msg);
-        }
-    }
-
-    return err == -EWOULDBLOCK
-            && mSource->feedMoreTSData() == OK;
-}
-
-void NuPlayer2::Decoder::handleError(int32_t err)
-{
-    // We cannot immediately release the codec due to buffers still outstanding
-    // in the renderer.  We signal to the player the error so it can shutdown/release the
-    // decoder after flushing and increment the generation to discard unnecessary messages.
-
-    ++mBufferGeneration;
-
-    sp<AMessage> notify = mNotify->dup();
-    notify->setInt32("what", kWhatError);
-    notify->setInt32("err", err);
-    notify->post();
-}
-
-status_t NuPlayer2::Decoder::releaseCrypto()
-{
-    ALOGV("releaseCrypto");
-
-    sp<AMessage> msg = new AMessage(kWhatDrmReleaseCrypto, this);
-
-    sp<AMessage> response;
-    status_t status = msg->postAndAwaitResponse(&response);
-    if (status == OK && response != NULL) {
-        CHECK(response->findInt32("status", &status));
-        ALOGV("releaseCrypto ret: %d ", status);
-    } else {
-        ALOGE("releaseCrypto err: %d", status);
-    }
-
-    return status;
-}
-
-void NuPlayer2::Decoder::onReleaseCrypto(const sp<AMessage>& msg)
-{
-    status_t status = INVALID_OPERATION;
-    if (mCodec != NULL) {
-        status = mCodec->releaseCrypto();
-    } else {
-        // returning OK if the codec has been already released
-        status = OK;
-        ALOGE("onReleaseCrypto No mCodec. err: %d", status);
-    }
-
-    sp<AMessage> response = new AMessage;
-    response->setInt32("status", status);
-    // Clearing the state as it's tied to crypto. mIsEncryptedObservedEarlier is sticky though
-    // and lasts for the lifetime of this codec. See its use in fetchInputData.
-    mIsEncrypted = false;
-
-    sp<AReplyToken> replyID;
-    CHECK(msg->senderAwaitsResponse(&replyID));
-    response->postReply(replyID);
-}
-
-bool NuPlayer2::Decoder::handleAnInputBuffer(size_t index) {
-    if (isDiscontinuityPending()) {
-        return false;
-    }
-
-    if (mCodec == NULL) {
-        ALOGE("[%s] handleAnInputBuffer without a valid codec", mComponentName.c_str());
-        handleError(NO_INIT);
-        return false;
-    }
-
-    size_t bufferSize = 0;
-    uint8_t *bufferBase = mCodec->getInputBuffer(index, &bufferSize);
-
-    if (bufferBase == NULL) {
-        ALOGE("[%s] handleAnInputBuffer, failed to get input buffer", mComponentName.c_str());
-        handleError(UNKNOWN_ERROR);
-        return false;
-    }
-
-    sp<MediaCodecBuffer> buffer =
-        new MediaCodecBuffer(NULL /* format */, new ABuffer(bufferBase, bufferSize));
-
-    if (index >= mInputBuffers.size()) {
-        for (size_t i = mInputBuffers.size(); i <= index; ++i) {
-            mInputBuffers.add();
-            mMediaBuffers.add();
-            mInputBufferIsDequeued.add();
-            mMediaBuffers.editItemAt(i) = NULL;
-            mInputBufferIsDequeued.editItemAt(i) = false;
-        }
-    }
-    mInputBuffers.editItemAt(index) = buffer;
-
-    //CHECK_LT(bufferIx, mInputBuffers.size());
-
-    if (mMediaBuffers[index] != NULL) {
-        mMediaBuffers[index]->release();
-        mMediaBuffers.editItemAt(index) = NULL;
-    }
-    mInputBufferIsDequeued.editItemAt(index) = true;
-
-    if (!mCSDsToSubmit.isEmpty()) {
-        sp<AMessage> msg = new AMessage();
-        msg->setSize("buffer-ix", index);
-
-        sp<ABuffer> buffer = mCSDsToSubmit.itemAt(0);
-        ALOGI("[%s] resubmitting CSD", mComponentName.c_str());
-        msg->setBuffer("buffer", buffer);
-        mCSDsToSubmit.removeAt(0);
-        if (!onInputBufferFetched(msg)) {
-            handleError(UNKNOWN_ERROR);
-            return false;
-        }
-        return true;
-    }
-
-    while (!mPendingInputMessages.empty()) {
-        sp<AMessage> msg = *mPendingInputMessages.begin();
-        if (!onInputBufferFetched(msg)) {
-            break;
-        }
-        mPendingInputMessages.erase(mPendingInputMessages.begin());
-    }
-
-    if (!mInputBufferIsDequeued.editItemAt(index)) {
-        return true;
-    }
-
-    mDequeuedInputBuffers.push_back(index);
-
-    onRequestInputBuffers();
-    return true;
-}
-
-bool NuPlayer2::Decoder::handleAnOutputBuffer(
-        size_t index,
-        size_t offset,
-        size_t size,
-        int64_t timeUs,
-        int32_t flags) {
-    if (mCodec == NULL) {
-        ALOGE("[%s] handleAnOutputBuffer without a valid codec", mComponentName.c_str());
-        handleError(NO_INIT);
-        return false;
-    }
-
-//    CHECK_LT(bufferIx, mOutputBuffers.size());
-
-    size_t bufferSize = 0;
-    uint8_t *bufferBase = mCodec->getOutputBuffer(index, &bufferSize);
-
-    if (bufferBase == NULL) {
-        ALOGE("[%s] handleAnOutputBuffer, failed to get output buffer", mComponentName.c_str());
-        handleError(UNKNOWN_ERROR);
-        return false;
-    }
-
-    sp<MediaCodecBuffer> buffer =
-        new MediaCodecBuffer(NULL /* format */, new ABuffer(bufferBase, bufferSize));
-
-    if (index >= mOutputBuffers.size()) {
-        for (size_t i = mOutputBuffers.size(); i <= index; ++i) {
-            mOutputBuffers.add();
-        }
-    }
-
-    mOutputBuffers.editItemAt(index) = buffer;
-
-    buffer->setRange(offset, size);
-    buffer->meta()->clear();
-    buffer->meta()->setInt64("timeUs", timeUs);
-
-    bool eos = flags & AMEDIACODEC_BUFFER_FLAG_END_OF_STREAM;
-    // we do not expect CODECCONFIG or SYNCFRAME for decoder
-
-    sp<AMessage> reply = new AMessage(kWhatRenderBuffer, this);
-    reply->setSize("buffer-ix", index);
-    reply->setInt32("generation", mBufferGeneration);
-
-    if (eos) {
-        ALOGI("[%s] saw output EOS", mIsAudio ? "audio" : "video");
-
-        buffer->meta()->setInt32("eos", true);
-        reply->setInt32("eos", true);
-    }
-
-    mNumFramesTotal += !mIsAudio;
-
-    if (mSkipRenderingUntilMediaTimeUs >= 0) {
-        if (timeUs < mSkipRenderingUntilMediaTimeUs) {
-            ALOGV("[%s] dropping buffer at time %lld as requested.",
-                     mComponentName.c_str(), (long long)timeUs);
-
-            reply->post();
-            if (eos) {
-                notifyResumeCompleteIfNecessary();
-                if (mRenderer != NULL && !isDiscontinuityPending()) {
-                    mRenderer->queueEOS(mIsAudio, ERROR_END_OF_STREAM);
-                }
-            }
-            return true;
-        }
-
-        mSkipRenderingUntilMediaTimeUs = -1;
-    }
-
-    // wait until 1st frame comes out to signal resume complete
-    notifyResumeCompleteIfNecessary();
-
-    if (mRenderer != NULL) {
-        // send the buffer to renderer.
-        mRenderer->queueBuffer(mIsAudio, buffer, reply);
-        if (eos && !isDiscontinuityPending()) {
-            mRenderer->queueEOS(mIsAudio, ERROR_END_OF_STREAM);
-        }
-    }
-
-    return true;
-}
-
-void NuPlayer2::Decoder::handleOutputFormatChange(const sp<AMessage> &format) {
-    if (!mIsAudio) {
-        int32_t width, height;
-        if (format->findInt32("width", &width)
-                && format->findInt32("height", &height)) {
-            mStats->setInt32("width", width);
-            mStats->setInt32("height", height);
-        }
-        sp<AMessage> notify = mNotify->dup();
-        notify->setInt32("what", kWhatVideoSizeChanged);
-        notify->setMessage("format", format);
-        notify->post();
-    } else if (mRenderer != NULL) {
-        uint32_t flags;
-        int64_t durationUs;
-        bool hasVideo = (mSource->getFormat(false /* audio */) != NULL);
-        if (getAudioDeepBufferSetting() // override regardless of source duration
-                || (mSource->getDuration(&durationUs) == OK
-                        && durationUs > AUDIO_SINK_MIN_DEEP_BUFFER_DURATION_US)) {
-            flags = AUDIO_OUTPUT_FLAG_DEEP_BUFFER;
-        } else {
-            flags = AUDIO_OUTPUT_FLAG_NONE;
-        }
-
-        sp<AMessage> reply = new AMessage(kWhatAudioOutputFormatChanged, this);
-        reply->setInt32("generation", mBufferGeneration);
-        mRenderer->changeAudioFormat(
-                format, false /* offloadOnly */, hasVideo,
-                flags, mSource->isStreaming(), reply);
-    }
-}
-
-void NuPlayer2::Decoder::releaseAndResetMediaBuffers() {
-    for (size_t i = 0; i < mMediaBuffers.size(); i++) {
-        if (mMediaBuffers[i] != NULL) {
-            mMediaBuffers[i]->release();
-            mMediaBuffers.editItemAt(i) = NULL;
-        }
-    }
-    mMediaBuffers.resize(mInputBuffers.size());
-    for (size_t i = 0; i < mMediaBuffers.size(); i++) {
-        mMediaBuffers.editItemAt(i) = NULL;
-    }
-    mInputBufferIsDequeued.clear();
-    mInputBufferIsDequeued.resize(mInputBuffers.size());
-    for (size_t i = 0; i < mInputBufferIsDequeued.size(); i++) {
-        mInputBufferIsDequeued.editItemAt(i) = false;
-    }
-
-    mPendingInputMessages.clear();
-    mDequeuedInputBuffers.clear();
-    mSkipRenderingUntilMediaTimeUs = -1;
-}
-
-bool NuPlayer2::Decoder::isStaleReply(const sp<AMessage> &msg) {
-    int32_t generation;
-    CHECK(msg->findInt32("generation", &generation));
-    return generation != mBufferGeneration;
-}
-
-status_t NuPlayer2::Decoder::fetchInputData(sp<AMessage> &reply) {
-    sp<ABuffer> accessUnit;
-    bool dropAccessUnit = true;
-    do {
-        status_t err = mSource->dequeueAccessUnit(mIsAudio, &accessUnit);
-
-        if (err == -EWOULDBLOCK) {
-            return err;
-        } else if (err != OK) {
-            if (err == INFO_DISCONTINUITY) {
-                int32_t type;
-                CHECK(accessUnit->meta()->findInt32("discontinuity", &type));
-
-                bool formatChange =
-                    (mIsAudio &&
-                     (type & ATSParser::DISCONTINUITY_AUDIO_FORMAT))
-                    || (!mIsAudio &&
-                            (type & ATSParser::DISCONTINUITY_VIDEO_FORMAT));
-
-                bool timeChange = (type & ATSParser::DISCONTINUITY_TIME) != 0;
-
-                ALOGI("%s discontinuity (format=%d, time=%d)",
-                        mIsAudio ? "audio" : "video", formatChange, timeChange);
-
-                bool seamlessFormatChange = false;
-                sp<AMessage> newFormat = mSource->getFormat(mIsAudio);
-                if (formatChange) {
-                    seamlessFormatChange =
-                        supportsSeamlessFormatChange(newFormat);
-                    // treat seamless format change separately
-                    formatChange = !seamlessFormatChange;
-                }
-
-                // For format or time change, return EOS to queue EOS input,
-                // then wait for EOS on output.
-                if (formatChange /* not seamless */) {
-                    mFormatChangePending = true;
-                    err = ERROR_END_OF_STREAM;
-                } else if (timeChange) {
-                    rememberCodecSpecificData(newFormat);
-                    mTimeChangePending = true;
-                    err = ERROR_END_OF_STREAM;
-                } else if (seamlessFormatChange) {
-                    // reuse existing decoder and don't flush
-                    rememberCodecSpecificData(newFormat);
-                    continue;
-                } else {
-                    // This stream is unaffected by the discontinuity
-                    return -EWOULDBLOCK;
-                }
-            }
-
-            // reply should only be returned without a buffer set
-            // when there is an error (including EOS)
-            CHECK(err != OK);
-
-            reply->setInt32("err", err);
-            return ERROR_END_OF_STREAM;
-        }
-
-        dropAccessUnit = false;
-        if (!mIsAudio && !mIsEncrypted) {
-            // Extra safeguard if higher-level behavior changes. Otherwise, not required now.
-            // Preventing the buffer from being processed (and sent to codec) if this is a later
-            // round of playback but this time without prepareDrm. Or if there is a race between
-            // stop (which is not blocking) and releaseDrm allowing buffers being processed after
-            // Crypto has been released (GenericSource currently prevents this race though).
-            // Particularly doing this check before IsAVCReferenceFrame call to prevent parsing
-            // of encrypted data.
-            if (mIsEncryptedObservedEarlier) {
-                ALOGE("fetchInputData: mismatched mIsEncrypted/mIsEncryptedObservedEarlier (0/1)");
-
-                return INVALID_OPERATION;
-            }
-
-            int32_t layerId = 0;
-            bool haveLayerId = accessUnit->meta()->findInt32("temporal-layer-id", &layerId);
-            if (mRenderer->getVideoLateByUs() > 100000LL
-                    && mIsVideoAVC
-                    && !IsAVCReferenceFrame(accessUnit)) {
-                dropAccessUnit = true;
-            } else if (haveLayerId && mNumVideoTemporalLayerTotal > 1) {
-                // Add only one layer each time.
-                if (layerId > mCurrentMaxVideoTemporalLayerId + 1
-                        || layerId >= mNumVideoTemporalLayerAllowed) {
-                    dropAccessUnit = true;
-                    ALOGV("dropping layer(%d), speed=%g, allowed layer count=%d, max layerId=%d",
-                            layerId, mPlaybackSpeed, mNumVideoTemporalLayerAllowed,
-                            mCurrentMaxVideoTemporalLayerId);
-                } else if (layerId > mCurrentMaxVideoTemporalLayerId) {
-                    mCurrentMaxVideoTemporalLayerId = layerId;
-                } else if (layerId == 0 && mNumVideoTemporalLayerTotal > 1
-                        && IsIDR(accessUnit->data(), accessUnit->size())) {
-                    mCurrentMaxVideoTemporalLayerId = mNumVideoTemporalLayerTotal - 1;
-                }
-            }
-            if (dropAccessUnit) {
-                if (layerId <= mCurrentMaxVideoTemporalLayerId && layerId > 0) {
-                    mCurrentMaxVideoTemporalLayerId = layerId - 1;
-                }
-                ++mNumInputFramesDropped;
-            }
-        }
-    } while (dropAccessUnit);
-
-    // ALOGV("returned a valid buffer of %s data", mIsAudio ? "mIsAudio" : "video");
-#if 0
-    int64_t mediaTimeUs;
-    CHECK(accessUnit->meta()->findInt64("timeUs", &mediaTimeUs));
-    ALOGV("[%s] feeding input buffer at media time %.3f",
-         mIsAudio ? "audio" : "video",
-         mediaTimeUs / 1E6);
-#endif
-
-    if (mCCDecoder != NULL) {
-        mCCDecoder->decode(accessUnit);
-    }
-
-    reply->setBuffer("buffer", accessUnit);
-
-    return OK;
-}
-
-bool NuPlayer2::Decoder::onInputBufferFetched(const sp<AMessage> &msg) {
-    if (mCodec == NULL) {
-        ALOGE("[%s] onInputBufferFetched without a valid codec", mComponentName.c_str());
-        handleError(NO_INIT);
-        return false;
-    }
-
-    size_t bufferIx;
-    CHECK(msg->findSize("buffer-ix", &bufferIx));
-    CHECK_LT(bufferIx, mInputBuffers.size());
-    sp<MediaCodecBuffer> codecBuffer = mInputBuffers[bufferIx];
-
-    sp<ABuffer> buffer;
-    bool hasBuffer = msg->findBuffer("buffer", &buffer);
-    bool needsCopy = true;
-
-    if (buffer == NULL /* includes !hasBuffer */) {
-        int32_t streamErr = ERROR_END_OF_STREAM;
-        CHECK(msg->findInt32("err", &streamErr) || !hasBuffer);
-
-        CHECK(streamErr != OK);
-
-        // attempt to queue EOS
-        status_t err = mCodec->queueInputBuffer(
-                bufferIx,
-                0,
-                0,
-                0,
-                AMEDIACODEC_BUFFER_FLAG_END_OF_STREAM);
-        if (err == OK) {
-            mInputBufferIsDequeued.editItemAt(bufferIx) = false;
-        } else if (streamErr == ERROR_END_OF_STREAM) {
-            streamErr = err;
-            // err will not be ERROR_END_OF_STREAM
-        }
-
-        if (streamErr != ERROR_END_OF_STREAM) {
-            ALOGE("Stream error for [%s] (err=%d), EOS %s queued",
-                    mComponentName.c_str(),
-                    streamErr,
-                    err == OK ? "successfully" : "unsuccessfully");
-            handleError(streamErr);
-        }
-    } else {
-        sp<AMessage> extra;
-        if (buffer->meta()->findMessage("extra", &extra) && extra != NULL) {
-            int64_t resumeAtMediaTimeUs;
-            if (extra->findInt64(
-                        "resume-at-mediaTimeUs", &resumeAtMediaTimeUs)) {
-                ALOGI("[%s] suppressing rendering until %lld us",
-                        mComponentName.c_str(), (long long)resumeAtMediaTimeUs);
-                mSkipRenderingUntilMediaTimeUs = resumeAtMediaTimeUs;
-            }
-        }
-
-        int64_t timeUs = 0;
-        uint32_t flags = 0;
-        CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
-
-        int32_t eos, csd;
-        // we do not expect SYNCFRAME for decoder
-        if (buffer->meta()->findInt32("eos", &eos) && eos) {
-            flags |= AMEDIACODEC_BUFFER_FLAG_END_OF_STREAM;
-        } else if (buffer->meta()->findInt32("csd", &csd) && csd) {
-            flags |= AMEDIACODEC_BUFFER_FLAG_CODEC_CONFIG;
-        }
-
-        // Modular DRM
-        MediaBufferBase *mediaBuf = NULL;
-        sp<AMediaCodecCryptoInfoWrapper> cryptInfo;
-
-        // copy into codec buffer
-        if (needsCopy) {
-            if (buffer->size() > codecBuffer->capacity()) {
-                handleError(ERROR_BUFFER_TOO_SMALL);
-                mDequeuedInputBuffers.push_back(bufferIx);
-                return false;
-            }
-
-            if (buffer->data() != NULL) {
-                codecBuffer->setRange(0, buffer->size());
-                memcpy(codecBuffer->data(), buffer->data(), buffer->size());
-            } else { // No buffer->data()
-                //Modular DRM
-                sp<RefBase> holder;
-                if (buffer->meta()->findObject("mediaBufferHolder", &holder)) {
-                    mediaBuf = (holder != nullptr) ?
-                        static_cast<MediaBufferHolder*>(holder.get())->mediaBuffer() : nullptr;
-                }
-                if (mediaBuf != NULL) {
-                    if (mediaBuf->size() > codecBuffer->capacity()) {
-                        handleError(ERROR_BUFFER_TOO_SMALL);
-                        mDequeuedInputBuffers.push_back(bufferIx);
-                        return false;
-                    }
-
-                    codecBuffer->setRange(0, mediaBuf->size());
-                    memcpy(codecBuffer->data(), mediaBuf->data(), mediaBuf->size());
-
-                    MetaDataBase &meta_data = mediaBuf->meta_data();
-                    cryptInfo = AMediaCodecCryptoInfoWrapper::Create(meta_data);
-                } else { // No mediaBuf
-                    ALOGE("onInputBufferFetched: buffer->data()/mediaBuf are NULL for %p",
-                            buffer.get());
-                    handleError(UNKNOWN_ERROR);
-                    return false;
-                }
-            } // buffer->data()
-        } // needsCopy
-
-        sp<RefBase> cryptInfoObj;
-        if (buffer->meta()->findObject("cryptInfo", &cryptInfoObj)) {
-            cryptInfo = static_cast<AMediaCodecCryptoInfoWrapper *>(cryptInfoObj.get());
-        }
-
-        status_t err;
-        if (cryptInfo != NULL) {
-            err = mCodec->queueSecureInputBuffer(
-                    bufferIx,
-                    codecBuffer->offset(),
-                    cryptInfo,
-                    timeUs,
-                    flags);
-            // synchronous call so done with cryptInfo here
-        } else {
-            err = mCodec->queueInputBuffer(
-                    bufferIx,
-                    codecBuffer->offset(),
-                    codecBuffer->size(),
-                    timeUs,
-                    flags);
-        } // no cryptInfo
-
-        if (err != OK) {
-            ALOGE("onInputBufferFetched: queue%sInputBuffer failed for [%s] (err=%d)",
-                    (cryptInfo != NULL ? "Secure" : ""),
-                    mComponentName.c_str(), err);
-            handleError(err);
-        } else {
-            mInputBufferIsDequeued.editItemAt(bufferIx) = false;
-        }
-
-    }   // buffer != NULL
-    return true;
-}
-
-void NuPlayer2::Decoder::onRenderBuffer(const sp<AMessage> &msg) {
-    status_t err;
-    int32_t render;
-    size_t bufferIx;
-    int32_t eos;
-    CHECK(msg->findSize("buffer-ix", &bufferIx));
-
-    if (!mIsAudio) {
-        int64_t timeUs;
-        sp<MediaCodecBuffer> buffer = mOutputBuffers[bufferIx];
-        buffer->meta()->findInt64("timeUs", &timeUs);
-
-        if (mCCDecoder != NULL && mCCDecoder->isSelected()) {
-            mCCDecoder->display(timeUs);
-        }
-    }
-
-    if (mCodec == NULL) {
-        err = NO_INIT;
-    } else if (msg->findInt32("render", &render) && render) {
-        int64_t timestampNs;
-        CHECK(msg->findInt64("timestampNs", &timestampNs));
-        err = mCodec->releaseOutputBufferAtTime(bufferIx, timestampNs);
-    } else {
-        mNumOutputFramesDropped += !mIsAudio;
-        err = mCodec->releaseOutputBuffer(bufferIx, false /* render */);
-    }
-    if (err != OK) {
-        ALOGE("failed to release output buffer for [%s] (err=%d)",
-                mComponentName.c_str(), err);
-        handleError(err);
-    }
-    if (msg->findInt32("eos", &eos) && eos
-            && isDiscontinuityPending()) {
-        finishHandleDiscontinuity(true /* flushOnTimeChange */);
-    }
-}
-
-bool NuPlayer2::Decoder::isDiscontinuityPending() const {
-    return mFormatChangePending || mTimeChangePending;
-}
-
-void NuPlayer2::Decoder::finishHandleDiscontinuity(bool flushOnTimeChange) {
-    ALOGV("finishHandleDiscontinuity: format %d, time %d, flush %d",
-            mFormatChangePending, mTimeChangePending, flushOnTimeChange);
-
-    // If we have format change, pause and wait to be killed;
-    // If we have time change only, flush and restart fetching.
-
-    if (mFormatChangePending) {
-        mPaused = true;
-    } else if (mTimeChangePending) {
-        if (flushOnTimeChange) {
-            doFlush(false /* notifyComplete */);
-            signalResume(false /* notifyComplete */);
-        }
-    }
-
-    // Notify NuPlayer2 to either shutdown decoder, or rescan sources
-    sp<AMessage> msg = mNotify->dup();
-    msg->setInt32("what", kWhatInputDiscontinuity);
-    msg->setInt32("formatChange", mFormatChangePending);
-    msg->post();
-
-    mFormatChangePending = false;
-    mTimeChangePending = false;
-}
-
-bool NuPlayer2::Decoder::supportsSeamlessAudioFormatChange(
-        const sp<AMessage> &targetFormat) const {
-    if (targetFormat == NULL) {
-        return true;
-    }
-
-    AString mime;
-    if (!targetFormat->findString("mime", &mime)) {
-        return false;
-    }
-
-    if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_AUDIO_AAC)) {
-        // field-by-field comparison
-        const char * keys[] = { "channel-count", "sample-rate", "is-adts" };
-        for (unsigned int i = 0; i < sizeof(keys) / sizeof(keys[0]); i++) {
-            int32_t oldVal, newVal;
-            if (!mInputFormat->getInt32(keys[i], &oldVal) ||
-                    !targetFormat->findInt32(keys[i], &newVal) ||
-                    oldVal != newVal) {
-                return false;
-            }
-        }
-
-        sp<ABuffer> newBuf;
-        uint8_t *oldBufData = NULL;
-        size_t oldBufSize = 0;
-        if (mInputFormat->getBuffer("csd-0", (void**)&oldBufData, &oldBufSize) &&
-                targetFormat->findBuffer("csd-0", &newBuf)) {
-            if (oldBufSize != newBuf->size()) {
-                return false;
-            }
-            return !memcmp(oldBufData, newBuf->data(), oldBufSize);
-        }
-    }
-    return false;
-}
-
-bool NuPlayer2::Decoder::supportsSeamlessFormatChange(const sp<AMessage> &targetFormat) const {
-    if (mInputFormat == NULL) {
-        return false;
-    }
-
-    if (targetFormat == NULL) {
-        return true;
-    }
-
-    AString oldMime, newMime;
-    if (!mInputFormat->getString("mime", &oldMime)
-            || !targetFormat->findString("mime", &newMime)
-            || !(oldMime == newMime)) {
-        return false;
-    }
-
-    bool audio = !strncasecmp(oldMime.c_str(), "audio/", strlen("audio/"));
-    bool seamless;
-    if (audio) {
-        seamless = supportsSeamlessAudioFormatChange(targetFormat);
-    } else {
-        int32_t isAdaptive;
-        seamless = (mCodec != NULL &&
-                mInputFormat->getInt32("adaptive-playback", &isAdaptive) &&
-                isAdaptive);
-    }
-
-    ALOGV("%s seamless support for %s", seamless ? "yes" : "no", oldMime.c_str());
-    return seamless;
-}
-
-void NuPlayer2::Decoder::rememberCodecSpecificData(const sp<AMessage> &format) {
-    if (format == NULL) {
-        return;
-    }
-    mCSDsForCurrentFormat.clear();
-    for (int32_t i = 0; ; ++i) {
-        AString tag = "csd-";
-        tag.append(i);
-        sp<ABuffer> buffer;
-        if (!format->findBuffer(tag.c_str(), &buffer)) {
-            break;
-        }
-        mCSDsForCurrentFormat.push(buffer);
-    }
-}
-
-void NuPlayer2::Decoder::notifyResumeCompleteIfNecessary() {
-    if (mResumePending) {
-        mResumePending = false;
-
-        sp<AMessage> notify = mNotify->dup();
-        notify->setInt32("what", kWhatResumeCompleted);
-        notify->post();
-    }
-}
-
-}  // namespace android
-
diff --git a/media/libmediaplayer2/nuplayer2/NuPlayer2Decoder.h b/media/libmediaplayer2/nuplayer2/NuPlayer2Decoder.h
deleted file mode 100644
index fdfb10e..0000000
--- a/media/libmediaplayer2/nuplayer2/NuPlayer2Decoder.h
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- * Copyright 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef NUPLAYER2_DECODER_H_
-#define NUPLAYER2_DECODER_H_
-
-#include "NuPlayer2.h"
-
-#include "NuPlayer2DecoderBase.h"
-
-namespace android {
-
-class MediaCodecBuffer;
-
-struct AMediaCodecWrapper;
-struct AMediaFormatWrapper;
-
-struct NuPlayer2::Decoder : public DecoderBase {
-    Decoder(const sp<AMessage> &notify,
-            const sp<Source> &source,
-            pid_t pid,
-            uid_t uid,
-            const sp<Renderer> &renderer = NULL,
-            const sp<ANativeWindowWrapper> &nww = NULL,
-            const sp<CCDecoder> &ccDecoder = NULL);
-
-    virtual sp<AMessage> getStats() const;
-
-    // sets the output surface of video decoders.
-    virtual status_t setVideoSurface(const sp<ANativeWindowWrapper> &nww);
-
-    virtual status_t releaseCrypto();
-
-protected:
-    virtual ~Decoder();
-
-    virtual void onMessageReceived(const sp<AMessage> &msg);
-
-    virtual void onConfigure(const sp<AMessage> &format);
-    virtual void onSetParameters(const sp<AMessage> &params);
-    virtual void onSetRenderer(const sp<Renderer> &renderer);
-    virtual void onResume(bool notifyComplete);
-    virtual void onFlush();
-    virtual void onShutdown(bool notifyComplete);
-    virtual bool doRequestBuffers();
-
-private:
-    enum {
-        kWhatCodecNotify         = 'cdcN',
-        kWhatRenderBuffer        = 'rndr',
-        kWhatSetVideoSurface     = 'sSur',
-        kWhatAudioOutputFormatChanged = 'aofc',
-        kWhatDrmReleaseCrypto    = 'rDrm',
-    };
-
-    enum {
-        kMaxNumVideoTemporalLayers = 32,
-    };
-
-    sp<ANativeWindowWrapper> mNativeWindow;
-
-    sp<Source> mSource;
-    sp<Renderer> mRenderer;
-    sp<CCDecoder> mCCDecoder;
-
-    sp<AMediaFormatWrapper> mInputFormat;
-    sp<AMediaCodecWrapper> mCodec;
-
-    List<sp<AMessage> > mPendingInputMessages;
-
-    Vector<sp<MediaCodecBuffer> > mInputBuffers;
-    Vector<sp<MediaCodecBuffer> > mOutputBuffers;
-    Vector<sp<ABuffer> > mCSDsForCurrentFormat;
-    Vector<sp<ABuffer> > mCSDsToSubmit;
-    Vector<bool> mInputBufferIsDequeued;
-    Vector<MediaBuffer *> mMediaBuffers;
-    Vector<size_t> mDequeuedInputBuffers;
-
-    const pid_t mPid;
-    const uid_t mUid;
-    int64_t mSkipRenderingUntilMediaTimeUs;
-    int64_t mNumFramesTotal;
-    int64_t mNumInputFramesDropped;
-    int64_t mNumOutputFramesDropped;
-    int32_t mVideoWidth;
-    int32_t mVideoHeight;
-    bool mIsAudio;
-    bool mIsVideoAVC;
-    bool mIsSecure;
-    bool mIsEncrypted;
-    bool mIsEncryptedObservedEarlier;
-    bool mFormatChangePending;
-    bool mTimeChangePending;
-    float mFrameRateTotal;
-    float mPlaybackSpeed;
-    int32_t mNumVideoTemporalLayerTotal;
-    int32_t mNumVideoTemporalLayerAllowed;
-    int32_t mCurrentMaxVideoTemporalLayerId;
-    float mVideoTemporalLayerAggregateFps[kMaxNumVideoTemporalLayers];
-
-    bool mResumePending;
-    AString mComponentName;
-
-    void handleError(int32_t err);
-    bool handleAnInputBuffer(size_t index);
-    bool handleAnOutputBuffer(
-            size_t index,
-            size_t offset,
-            size_t size,
-            int64_t timeUs,
-            int32_t flags);
-    void handleOutputFormatChange(const sp<AMessage> &format);
-
-    void releaseAndResetMediaBuffers();
-    bool isStaleReply(const sp<AMessage> &msg);
-
-    void doFlush(bool notifyComplete);
-    status_t fetchInputData(sp<AMessage> &reply);
-    bool onInputBufferFetched(const sp<AMessage> &msg);
-    void onRenderBuffer(const sp<AMessage> &msg);
-
-    bool supportsSeamlessFormatChange(const sp<AMessage> &to) const;
-    bool supportsSeamlessAudioFormatChange(const sp<AMessage> &targetFormat) const;
-    void rememberCodecSpecificData(const sp<AMessage> &format);
-    bool isDiscontinuityPending() const;
-    void finishHandleDiscontinuity(bool flushOnTimeChange);
-
-    void notifyResumeCompleteIfNecessary();
-
-    void onReleaseCrypto(const sp<AMessage>& msg);
-
-    DISALLOW_EVIL_CONSTRUCTORS(Decoder);
-};
-
-}  // namespace android
-
-#endif  // NUPLAYER2_DECODER_H_
diff --git a/media/libmediaplayer2/nuplayer2/NuPlayer2DecoderBase.cpp b/media/libmediaplayer2/nuplayer2/NuPlayer2DecoderBase.cpp
deleted file mode 100644
index 914f29f..0000000
--- a/media/libmediaplayer2/nuplayer2/NuPlayer2DecoderBase.cpp
+++ /dev/null
@@ -1,216 +0,0 @@
-/*
- * Copyright 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-//#define LOG_NDEBUG 0
-#define LOG_TAG "NuPlayer2DecoderBase"
-#include <utils/Log.h>
-#include <inttypes.h>
-
-#include "NuPlayer2DecoderBase.h"
-
-#include "NuPlayer2Renderer.h"
-
-#include <media/MediaCodecBuffer.h>
-#include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/foundation/AMessage.h>
-
-namespace android {
-
-NuPlayer2::DecoderBase::DecoderBase(const sp<AMessage> &notify)
-    :  mNotify(notify),
-       mBufferGeneration(0),
-       mPaused(false),
-       mStats(new AMessage),
-       mRequestInputBuffersPending(false) {
-    // Every decoder has its own looper because MediaCodec operations
-    // are blocking, but NuPlayer2 needs asynchronous operations.
-    mDecoderLooper = new ALooper;
-    mDecoderLooper->setName("NP2Decoder");
-    mDecoderLooper->start(false, /* runOnCallingThread */
-                          true,  /* canCallJava */
-                          ANDROID_PRIORITY_AUDIO);
-}
-
-NuPlayer2::DecoderBase::~DecoderBase() {
-    stopLooper();
-}
-
-static
-status_t PostAndAwaitResponse(
-        const sp<AMessage> &msg, sp<AMessage> *response) {
-    status_t err = msg->postAndAwaitResponse(response);
-
-    if (err != OK) {
-        return err;
-    }
-
-    if (!(*response)->findInt32("err", &err)) {
-        err = OK;
-    }
-
-    return err;
-}
-
-void NuPlayer2::DecoderBase::configure(const sp<AMessage> &format) {
-    sp<AMessage> msg = new AMessage(kWhatConfigure, this);
-    msg->setMessage("format", format);
-    msg->post();
-}
-
-void NuPlayer2::DecoderBase::init() {
-    mDecoderLooper->registerHandler(this);
-}
-
-void NuPlayer2::DecoderBase::stopLooper() {
-    mDecoderLooper->unregisterHandler(id());
-    mDecoderLooper->stop();
-}
-
-void NuPlayer2::DecoderBase::setParameters(const sp<AMessage> &params) {
-    sp<AMessage> msg = new AMessage(kWhatSetParameters, this);
-    msg->setMessage("params", params);
-    msg->post();
-}
-
-void NuPlayer2::DecoderBase::setRenderer(const sp<Renderer> &renderer) {
-    sp<AMessage> msg = new AMessage(kWhatSetRenderer, this);
-    msg->setObject("renderer", renderer);
-    msg->post();
-}
-
-void NuPlayer2::DecoderBase::pause() {
-    sp<AMessage> msg = new AMessage(kWhatPause, this);
-
-    sp<AMessage> response;
-    PostAndAwaitResponse(msg, &response);
-}
-
-void NuPlayer2::DecoderBase::signalFlush() {
-    (new AMessage(kWhatFlush, this))->post();
-}
-
-void NuPlayer2::DecoderBase::signalResume(bool notifyComplete) {
-    sp<AMessage> msg = new AMessage(kWhatResume, this);
-    msg->setInt32("notifyComplete", notifyComplete);
-    msg->post();
-}
-
-void NuPlayer2::DecoderBase::initiateShutdown() {
-    (new AMessage(kWhatShutdown, this))->post();
-}
-
-void NuPlayer2::DecoderBase::onRequestInputBuffers() {
-    if (mRequestInputBuffersPending) {
-        return;
-    }
-
-    // doRequestBuffers() return true if we should request more data
-    if (doRequestBuffers()) {
-        mRequestInputBuffersPending = true;
-
-        sp<AMessage> msg = new AMessage(kWhatRequestInputBuffers, this);
-        msg->post(10 * 1000LL);
-    }
-}
-
-void NuPlayer2::DecoderBase::onMessageReceived(const sp<AMessage> &msg) {
-
-    switch (msg->what()) {
-        case kWhatConfigure:
-        {
-            sp<AMessage> format;
-            CHECK(msg->findMessage("format", &format));
-            onConfigure(format);
-            break;
-        }
-
-        case kWhatSetParameters:
-        {
-            sp<AMessage> params;
-            CHECK(msg->findMessage("params", &params));
-            onSetParameters(params);
-            break;
-        }
-
-        case kWhatSetRenderer:
-        {
-            sp<RefBase> obj;
-            CHECK(msg->findObject("renderer", &obj));
-            onSetRenderer(static_cast<Renderer *>(obj.get()));
-            break;
-        }
-
-        case kWhatPause:
-        {
-            sp<AReplyToken> replyID;
-            CHECK(msg->senderAwaitsResponse(&replyID));
-
-            mPaused = true;
-
-            (new AMessage)->postReply(replyID);
-            break;
-        }
-
-        case kWhatRequestInputBuffers:
-        {
-            mRequestInputBuffersPending = false;
-            onRequestInputBuffers();
-            break;
-        }
-
-        case kWhatFlush:
-        {
-            onFlush();
-            break;
-        }
-
-        case kWhatResume:
-        {
-            int32_t notifyComplete;
-            CHECK(msg->findInt32("notifyComplete", &notifyComplete));
-
-            onResume(notifyComplete);
-            break;
-        }
-
-        case kWhatShutdown:
-        {
-            onShutdown(true);
-            break;
-        }
-
-        default:
-            TRESPASS();
-            break;
-    }
-}
-
-void NuPlayer2::DecoderBase::handleError(int32_t err)
-{
-    // We cannot immediately release the codec due to buffers still outstanding
-    // in the renderer.  We signal to the player the error so it can shutdown/release the
-    // decoder after flushing and increment the generation to discard unnecessary messages.
-
-    ++mBufferGeneration;
-
-    sp<AMessage> notify = mNotify->dup();
-    notify->setInt32("what", kWhatError);
-    notify->setInt32("err", err);
-    notify->post();
-}
-
-}  // namespace android
-
diff --git a/media/libmediaplayer2/nuplayer2/NuPlayer2DecoderBase.h b/media/libmediaplayer2/nuplayer2/NuPlayer2DecoderBase.h
deleted file mode 100644
index 1e57f0d..0000000
--- a/media/libmediaplayer2/nuplayer2/NuPlayer2DecoderBase.h
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Copyright 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef NUPLAYER2_DECODER_BASE_H_
-
-#define NUPLAYER2_DECODER_BASE_H_
-
-#include "NuPlayer2.h"
-
-#include <media/stagefright/foundation/AHandler.h>
-
-namespace android {
-
-struct ABuffer;
-struct ANativeWindowWrapper;
-struct MediaCodec;
-class MediaBuffer;
-class MediaCodecBuffer;
-
-struct NuPlayer2::DecoderBase : public AHandler {
-    explicit DecoderBase(const sp<AMessage> &notify);
-
-    void configure(const sp<AMessage> &format);
-    void init();
-    void setParameters(const sp<AMessage> &params);
-
-    // Synchronous call to ensure decoder will not request or send out data.
-    void pause();
-
-    void setRenderer(const sp<Renderer> &renderer);
-    virtual status_t setVideoSurface(const sp<ANativeWindowWrapper> &) { return INVALID_OPERATION; }
-
-    void signalFlush();
-    void signalResume(bool notifyComplete);
-    void initiateShutdown();
-
-    virtual sp<AMessage> getStats() const {
-        return mStats;
-    }
-
-    virtual status_t releaseCrypto() {
-        return INVALID_OPERATION;
-    }
-
-    enum {
-        kWhatInputDiscontinuity  = 'inDi',
-        kWhatVideoSizeChanged    = 'viSC',
-        kWhatFlushCompleted      = 'flsC',
-        kWhatShutdownCompleted   = 'shDC',
-        kWhatResumeCompleted     = 'resC',
-        kWhatEOS                 = 'eos ',
-        kWhatError               = 'err ',
-    };
-
-protected:
-
-    virtual ~DecoderBase();
-
-    void stopLooper();
-
-    virtual void onMessageReceived(const sp<AMessage> &msg);
-
-    virtual void onConfigure(const sp<AMessage> &format) = 0;
-    virtual void onSetParameters(const sp<AMessage> &params) = 0;
-    virtual void onSetRenderer(const sp<Renderer> &renderer) = 0;
-    virtual void onResume(bool notifyComplete) = 0;
-    virtual void onFlush() = 0;
-    virtual void onShutdown(bool notifyComplete) = 0;
-
-    void onRequestInputBuffers();
-    virtual bool doRequestBuffers() = 0;
-    virtual void handleError(int32_t err);
-
-    sp<AMessage> mNotify;
-    int32_t mBufferGeneration;
-    bool mPaused;
-    sp<AMessage> mStats;
-
-private:
-    enum {
-        kWhatConfigure           = 'conf',
-        kWhatSetParameters       = 'setP',
-        kWhatSetRenderer         = 'setR',
-        kWhatPause               = 'paus',
-        kWhatRequestInputBuffers = 'reqB',
-        kWhatFlush               = 'flus',
-        kWhatShutdown            = 'shuD',
-    };
-
-    sp<ALooper> mDecoderLooper;
-    bool mRequestInputBuffersPending;
-
-    DISALLOW_EVIL_CONSTRUCTORS(DecoderBase);
-};
-
-}  // namespace android
-
-#endif  // NUPLAYER2_DECODER_BASE_H_
diff --git a/media/libmediaplayer2/nuplayer2/NuPlayer2DecoderPassThrough.cpp b/media/libmediaplayer2/nuplayer2/NuPlayer2DecoderPassThrough.cpp
deleted file mode 100644
index 0514e88..0000000
--- a/media/libmediaplayer2/nuplayer2/NuPlayer2DecoderPassThrough.cpp
+++ /dev/null
@@ -1,434 +0,0 @@
-/*
- * Copyright 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-//#define LOG_NDEBUG 0
-#define LOG_TAG "NuPlayer2DecoderPassThrough"
-#include <utils/Log.h>
-#include <inttypes.h>
-
-#include "NuPlayer2DecoderPassThrough.h"
-
-#include "NuPlayer2Renderer.h"
-#include "NuPlayer2Source.h"
-
-#include <media/MediaCodecBuffer.h>
-#include <media/stagefright/foundation/ABuffer.h>
-#include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/foundation/AMessage.h>
-#include <media/stagefright/MediaErrors.h>
-
-#include "ATSParser.h"
-
-namespace android {
-
-// TODO optimize buffer size for power consumption
-// The offload read buffer size is 32 KB but 24 KB uses less power.
-static const size_t kAggregateBufferSizeBytes = 24 * 1024;
-static const size_t kMaxCachedBytes = 200000;
-
-NuPlayer2::DecoderPassThrough::DecoderPassThrough(
-        const sp<AMessage> &notify,
-        const sp<Source> &source,
-        const sp<Renderer> &renderer)
-    : DecoderBase(notify),
-      mSource(source),
-      mRenderer(renderer),
-      mSkipRenderingUntilMediaTimeUs(-1LL),
-      mReachedEOS(true),
-      mPendingAudioErr(OK),
-      mPendingBuffersToDrain(0),
-      mCachedBytes(0),
-      mComponentName("pass through decoder") {
-    ALOGW_IF(renderer == NULL, "expect a non-NULL renderer");
-}
-
-NuPlayer2::DecoderPassThrough::~DecoderPassThrough() {
-}
-
-void NuPlayer2::DecoderPassThrough::onConfigure(const sp<AMessage> &format) {
-    ALOGV("[%s] onConfigure", mComponentName.c_str());
-    mCachedBytes = 0;
-    mPendingBuffersToDrain = 0;
-    mReachedEOS = false;
-    ++mBufferGeneration;
-
-    onRequestInputBuffers();
-
-    int32_t hasVideo = 0;
-    format->findInt32("has-video", &hasVideo);
-
-    // The audio sink is already opened before the PassThrough decoder is created.
-    // Opening again might be relevant if decoder is instantiated after shutdown and
-    // format is different.
-    status_t err = mRenderer->openAudioSink(
-            format, true /* offloadOnly */, hasVideo,
-            AUDIO_OUTPUT_FLAG_NONE /* flags */, NULL /* isOffloaded */, mSource->isStreaming());
-    if (err != OK) {
-        handleError(err);
-    }
-}
-
-void NuPlayer2::DecoderPassThrough::onSetParameters(const sp<AMessage> &/*params*/) {
-    ALOGW("onSetParameters() called unexpectedly");
-}
-
-void NuPlayer2::DecoderPassThrough::onSetRenderer(
-        const sp<Renderer> &renderer) {
-    // renderer can't be changed during offloading
-    ALOGW_IF(renderer != mRenderer,
-            "ignoring request to change renderer");
-}
-
-bool NuPlayer2::DecoderPassThrough::isStaleReply(const sp<AMessage> &msg) {
-    int32_t generation;
-    CHECK(msg->findInt32("generation", &generation));
-    return generation != mBufferGeneration;
-}
-
-bool NuPlayer2::DecoderPassThrough::isDoneFetching() const {
-    ALOGV("[%s] mCachedBytes = %zu, mReachedEOS = %d mPaused = %d",
-            mComponentName.c_str(), mCachedBytes, mReachedEOS, mPaused);
-
-    return mCachedBytes >= kMaxCachedBytes || mReachedEOS || mPaused;
-}
-
-/*
- * returns true if we should request more data
- */
-bool NuPlayer2::DecoderPassThrough::doRequestBuffers() {
-    status_t err = OK;
-    while (!isDoneFetching()) {
-        sp<AMessage> msg = new AMessage();
-
-        err = fetchInputData(msg);
-        if (err != OK) {
-            break;
-        }
-
-        onInputBufferFetched(msg);
-    }
-
-    return err == -EWOULDBLOCK
-            && mSource->feedMoreTSData() == OK;
-}
-
-status_t NuPlayer2::DecoderPassThrough::dequeueAccessUnit(sp<ABuffer> *accessUnit) {
-    status_t err;
-
-    // Did we save an accessUnit earlier because of a discontinuity?
-    if (mPendingAudioAccessUnit != NULL) {
-        *accessUnit = mPendingAudioAccessUnit;
-        mPendingAudioAccessUnit.clear();
-        err = mPendingAudioErr;
-        ALOGV("feedDecoderInputData() use mPendingAudioAccessUnit");
-    } else {
-        err = mSource->dequeueAccessUnit(true /* audio */, accessUnit);
-    }
-
-    if (err == INFO_DISCONTINUITY || err == ERROR_END_OF_STREAM) {
-        if (mAggregateBuffer != NULL) {
-            // We already have some data so save this for later.
-            mPendingAudioErr = err;
-            mPendingAudioAccessUnit = *accessUnit;
-            (*accessUnit).clear();
-            ALOGD("return aggregated buffer and save err(=%d) for later", err);
-            err = OK;
-        }
-    }
-
-    return err;
-}
-
-sp<ABuffer> NuPlayer2::DecoderPassThrough::aggregateBuffer(
-        const sp<ABuffer> &accessUnit) {
-    sp<ABuffer> aggregate;
-
-    if (accessUnit == NULL) {
-        // accessUnit is saved to mPendingAudioAccessUnit
-        // return current mAggregateBuffer
-        aggregate = mAggregateBuffer;
-        mAggregateBuffer.clear();
-        return aggregate;
-    }
-
-    size_t smallSize = accessUnit->size();
-    if ((mAggregateBuffer == NULL)
-            // Don't bother if only room for a few small buffers.
-            && (smallSize < (kAggregateBufferSizeBytes / 3))) {
-        // Create a larger buffer for combining smaller buffers from the extractor.
-        mAggregateBuffer = new ABuffer(kAggregateBufferSizeBytes);
-        mAggregateBuffer->setRange(0, 0); // start empty
-    }
-
-    if (mAggregateBuffer != NULL) {
-        int64_t timeUs;
-        int64_t dummy;
-        bool smallTimestampValid = accessUnit->meta()->findInt64("timeUs", &timeUs);
-        bool bigTimestampValid = mAggregateBuffer->meta()->findInt64("timeUs", &dummy);
-        // Will the smaller buffer fit?
-        size_t bigSize = mAggregateBuffer->size();
-        size_t roomLeft = mAggregateBuffer->capacity() - bigSize;
-        // Should we save this small buffer for the next big buffer?
-        // If the first small buffer did not have a timestamp then save
-        // any buffer that does have a timestamp until the next big buffer.
-        if ((smallSize > roomLeft)
-            || (!bigTimestampValid && (bigSize > 0) && smallTimestampValid)) {
-            mPendingAudioErr = OK;
-            mPendingAudioAccessUnit = accessUnit;
-            aggregate = mAggregateBuffer;
-            mAggregateBuffer.clear();
-        } else {
-            // Grab time from first small buffer if available.
-            if ((bigSize == 0) && smallTimestampValid) {
-                mAggregateBuffer->meta()->setInt64("timeUs", timeUs);
-            }
-            // Append small buffer to the bigger buffer.
-            memcpy(mAggregateBuffer->base() + bigSize, accessUnit->data(), smallSize);
-            bigSize += smallSize;
-            mAggregateBuffer->setRange(0, bigSize);
-
-            ALOGV("feedDecoderInputData() smallSize = %zu, bigSize = %zu, capacity = %zu",
-                    smallSize, bigSize, mAggregateBuffer->capacity());
-        }
-    } else {
-        // decided not to aggregate
-        aggregate = accessUnit;
-    }
-
-    return aggregate;
-}
-
-status_t NuPlayer2::DecoderPassThrough::fetchInputData(sp<AMessage> &reply) {
-    sp<ABuffer> accessUnit;
-
-    do {
-        status_t err = dequeueAccessUnit(&accessUnit);
-
-        if (err == -EWOULDBLOCK) {
-            // Flush out the aggregate buffer to try to avoid underrun.
-            accessUnit = aggregateBuffer(NULL /* accessUnit */);
-            if (accessUnit != NULL) {
-                break;
-            }
-            return err;
-        } else if (err != OK) {
-            if (err == INFO_DISCONTINUITY) {
-                int32_t type;
-                CHECK(accessUnit->meta()->findInt32("discontinuity", &type));
-
-                bool formatChange =
-                        (type & ATSParser::DISCONTINUITY_AUDIO_FORMAT) != 0;
-
-                bool timeChange =
-                        (type & ATSParser::DISCONTINUITY_TIME) != 0;
-
-                ALOGI("audio discontinuity (formatChange=%d, time=%d)",
-                        formatChange, timeChange);
-
-                if (formatChange || timeChange) {
-                    sp<AMessage> msg = mNotify->dup();
-                    msg->setInt32("what", kWhatInputDiscontinuity);
-                    // will perform seamless format change,
-                    // only notify NuPlayer2 to scan sources
-                    msg->setInt32("formatChange", false);
-                    msg->post();
-                }
-
-                if (timeChange) {
-                    doFlush(false /* notifyComplete */);
-                    err = OK;
-                } else if (formatChange) {
-                    // do seamless format change
-                    err = OK;
-                } else {
-                    // This stream is unaffected by the discontinuity
-                    return -EWOULDBLOCK;
-                }
-            }
-
-            reply->setInt32("err", err);
-            return OK;
-        }
-
-        accessUnit = aggregateBuffer(accessUnit);
-    } while (accessUnit == NULL);
-
-#if 0
-    int64_t mediaTimeUs;
-    CHECK(accessUnit->meta()->findInt64("timeUs", &mediaTimeUs));
-    ALOGV("feeding audio input buffer at media time %.2f secs",
-         mediaTimeUs / 1E6);
-#endif
-
-    reply->setBuffer("buffer", accessUnit);
-
-    return OK;
-}
-
-void NuPlayer2::DecoderPassThrough::onInputBufferFetched(
-        const sp<AMessage> &msg) {
-    if (mReachedEOS) {
-        return;
-    }
-
-    sp<ABuffer> buffer;
-    bool hasBuffer = msg->findBuffer("buffer", &buffer);
-    if (buffer == NULL) {
-        int32_t streamErr = ERROR_END_OF_STREAM;
-        CHECK(msg->findInt32("err", &streamErr) || !hasBuffer);
-        if (streamErr == OK) {
-            return;
-        }
-
-        if (streamErr != ERROR_END_OF_STREAM) {
-            handleError(streamErr);
-        }
-        mReachedEOS = true;
-        if (mRenderer != NULL) {
-            mRenderer->queueEOS(true /* audio */, ERROR_END_OF_STREAM);
-        }
-        return;
-    }
-
-    sp<AMessage> extra;
-    if (buffer->meta()->findMessage("extra", &extra) && extra != NULL) {
-        int64_t resumeAtMediaTimeUs;
-        if (extra->findInt64(
-                    "resume-at-mediatimeUs", &resumeAtMediaTimeUs)) {
-            ALOGI("[%s] suppressing rendering until %lld us",
-                    mComponentName.c_str(), (long long)resumeAtMediaTimeUs);
-            mSkipRenderingUntilMediaTimeUs = resumeAtMediaTimeUs;
-        }
-    }
-
-    int32_t bufferSize = buffer->size();
-    mCachedBytes += bufferSize;
-
-    int64_t timeUs = 0;
-    CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
-    if (mSkipRenderingUntilMediaTimeUs >= 0) {
-        if (timeUs < mSkipRenderingUntilMediaTimeUs) {
-            ALOGV("[%s] dropping buffer at time %lld as requested.",
-                     mComponentName.c_str(), (long long)timeUs);
-
-            onBufferConsumed(bufferSize);
-            return;
-        }
-
-        mSkipRenderingUntilMediaTimeUs = -1;
-    }
-
-    if (mRenderer == NULL) {
-        onBufferConsumed(bufferSize);
-        return;
-    }
-
-    sp<AMessage> reply = new AMessage(kWhatBufferConsumed, this);
-    reply->setInt32("generation", mBufferGeneration);
-    reply->setInt32("size", bufferSize);
-
-    sp<MediaCodecBuffer> mcBuffer = new MediaCodecBuffer(nullptr, buffer);
-    mcBuffer->meta()->setInt64("timeUs", timeUs);
-
-    mRenderer->queueBuffer(true /* audio */, mcBuffer, reply);
-
-    ++mPendingBuffersToDrain;
-    ALOGV("onInputBufferFilled: #ToDrain = %zu, cachedBytes = %zu",
-            mPendingBuffersToDrain, mCachedBytes);
-}
-
-void NuPlayer2::DecoderPassThrough::onBufferConsumed(int32_t size) {
-    --mPendingBuffersToDrain;
-    mCachedBytes -= size;
-    ALOGV("onBufferConsumed: #ToDrain = %zu, cachedBytes = %zu",
-            mPendingBuffersToDrain, mCachedBytes);
-    onRequestInputBuffers();
-}
-
-void NuPlayer2::DecoderPassThrough::onResume(bool notifyComplete) {
-    mPaused = false;
-
-    onRequestInputBuffers();
-
-    if (notifyComplete) {
-        sp<AMessage> notify = mNotify->dup();
-        notify->setInt32("what", kWhatResumeCompleted);
-        notify->post();
-    }
-}
-
-void NuPlayer2::DecoderPassThrough::doFlush(bool notifyComplete) {
-    ++mBufferGeneration;
-    mSkipRenderingUntilMediaTimeUs = -1;
-    mPendingAudioAccessUnit.clear();
-    mPendingAudioErr = OK;
-    mAggregateBuffer.clear();
-
-    if (mRenderer != NULL) {
-        mRenderer->flush(true /* audio */, notifyComplete);
-        mRenderer->signalTimeDiscontinuity();
-    }
-
-    mPendingBuffersToDrain = 0;
-    mCachedBytes = 0;
-    mReachedEOS = false;
-}
-
-void NuPlayer2::DecoderPassThrough::onFlush() {
-    doFlush(true /* notifyComplete */);
-
-    mPaused = true;
-    sp<AMessage> notify = mNotify->dup();
-    notify->setInt32("what", kWhatFlushCompleted);
-    notify->post();
-
-}
-
-void NuPlayer2::DecoderPassThrough::onShutdown(bool notifyComplete) {
-    ++mBufferGeneration;
-    mSkipRenderingUntilMediaTimeUs = -1;
-
-    if (notifyComplete) {
-        sp<AMessage> notify = mNotify->dup();
-        notify->setInt32("what", kWhatShutdownCompleted);
-        notify->post();
-    }
-
-    mReachedEOS = true;
-}
-
-void NuPlayer2::DecoderPassThrough::onMessageReceived(const sp<AMessage> &msg) {
-    ALOGV("[%s] onMessage: %s", mComponentName.c_str(),
-            msg->debugString().c_str());
-
-    switch (msg->what()) {
-        case kWhatBufferConsumed:
-        {
-            if (!isStaleReply(msg)) {
-                int32_t size;
-                CHECK(msg->findInt32("size", &size));
-                onBufferConsumed(size);
-            }
-            break;
-        }
-
-        default:
-            DecoderBase::onMessageReceived(msg);
-            break;
-    }
-}
-
-}  // namespace android
diff --git a/media/libmediaplayer2/nuplayer2/NuPlayer2DecoderPassThrough.h b/media/libmediaplayer2/nuplayer2/NuPlayer2DecoderPassThrough.h
deleted file mode 100644
index 838c60a..0000000
--- a/media/libmediaplayer2/nuplayer2/NuPlayer2DecoderPassThrough.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef NUPLAYER2_DECODER_PASS_THROUGH_H_
-
-#define NUPLAYER2_DECODER_PASS_THROUGH_H_
-
-#include "NuPlayer2.h"
-
-#include "NuPlayer2DecoderBase.h"
-
-namespace android {
-
-struct NuPlayer2::DecoderPassThrough : public DecoderBase {
-    DecoderPassThrough(const sp<AMessage> &notify,
-                       const sp<Source> &source,
-                       const sp<Renderer> &renderer);
-
-protected:
-
-    virtual ~DecoderPassThrough();
-
-    virtual void onMessageReceived(const sp<AMessage> &msg);
-
-    virtual void onConfigure(const sp<AMessage> &format);
-    virtual void onSetParameters(const sp<AMessage> &params);
-    virtual void onSetRenderer(const sp<Renderer> &renderer);
-    virtual void onResume(bool notifyComplete);
-    virtual void onFlush();
-    virtual void onShutdown(bool notifyComplete);
-    virtual bool doRequestBuffers();
-
-private:
-    enum {
-        kWhatBufferConsumed     = 'bufC',
-    };
-
-    sp<Source> mSource;
-    sp<Renderer> mRenderer;
-    int64_t mSkipRenderingUntilMediaTimeUs;
-
-    bool    mReachedEOS;
-
-    // Used by feedDecoderInputData to aggregate small buffers into
-    // one large buffer.
-    sp<ABuffer> mPendingAudioAccessUnit;
-    status_t    mPendingAudioErr;
-    sp<ABuffer> mAggregateBuffer;
-
-    // mPendingBuffersToDrain are only for debugging. It can be removed
-    // when the power investigation is done.
-    size_t  mPendingBuffersToDrain;
-    size_t  mCachedBytes;
-    AString mComponentName;
-
-    bool isStaleReply(const sp<AMessage> &msg);
-    bool isDoneFetching() const;
-
-    status_t dequeueAccessUnit(sp<ABuffer> *accessUnit);
-    sp<ABuffer> aggregateBuffer(const sp<ABuffer> &accessUnit);
-    status_t fetchInputData(sp<AMessage> &reply);
-    void doFlush(bool notifyComplete);
-
-    void onInputBufferFetched(const sp<AMessage> &msg);
-    void onBufferConsumed(int32_t size);
-
-    DISALLOW_EVIL_CONSTRUCTORS(DecoderPassThrough);
-};
-
-}  // namespace android
-
-#endif  // NUPLAYER2_DECODER_PASS_THROUGH_H_
diff --git a/media/libmediaplayer2/nuplayer2/NuPlayer2Driver.cpp b/media/libmediaplayer2/nuplayer2/NuPlayer2Driver.cpp
deleted file mode 100644
index 1876496..0000000
--- a/media/libmediaplayer2/nuplayer2/NuPlayer2Driver.cpp
+++ /dev/null
@@ -1,1010 +0,0 @@
-/*
- * Copyright 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-//#define LOG_NDEBUG 0
-#define LOG_TAG "NuPlayer2Driver"
-#include <inttypes.h>
-#include <android-base/macros.h>
-#include <utils/Log.h>
-#include <cutils/properties.h>
-
-#include "NuPlayer2Driver.h"
-
-#include "NuPlayer2.h"
-#include "NuPlayer2Source.h"
-
-#include <media/DataSourceDesc.h>
-#include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/foundation/ALooper.h>
-#include <media/stagefright/foundation/AUtils.h>
-#include <media/stagefright/foundation/ByteUtils.h>
-#include <media/stagefright/MediaClock.h>
-#include <media/stagefright/MetaData.h>
-#include <media/stagefright/Utils.h>
-
-#include <media/IMediaAnalyticsService.h>
-
-using google::protobuf::RepeatedPtrField;
-using android::media::MediaPlayer2Proto::Value;
-
-static const int kDumpLockRetries = 50;
-static const int kDumpLockSleepUs = 20000;
-
-namespace android {
-
-struct PlayerMessageWrapper : public RefBase {
-    static sp<PlayerMessageWrapper> Create(const PlayerMessage *p) {
-        if (p != NULL) {
-            sp<PlayerMessageWrapper> pw = new PlayerMessageWrapper();
-            pw->copyFrom(p);
-            return pw;
-        }
-        return NULL;
-    }
-
-    const PlayerMessage *getPlayerMessage() {
-        return mPlayerMessage;
-    }
-
-protected:
-    virtual ~PlayerMessageWrapper() {
-        if (mPlayerMessage != NULL) {
-            delete mPlayerMessage;
-        }
-    }
-
-private:
-    PlayerMessageWrapper()
-        : mPlayerMessage(NULL) { }
-
-    void copyFrom(const PlayerMessage *p) {
-        if (mPlayerMessage == NULL) {
-            mPlayerMessage = new PlayerMessage;
-        }
-        mPlayerMessage->CopyFrom(*p);
-    }
-
-    PlayerMessage *mPlayerMessage;
-};
-
-// key for media statistics
-static const char *kKeyPlayer = "nuplayer2";
-// attrs for media statistics
-    // NB: these are matched with public Java API constants defined
-    // in frameworks/base/media/java/android/media/MediaPlayer2.java
-    // These must be kept synchronized with the constants there.
-static const char *kPlayerVMime = "android.media.mediaplayer.video.mime";
-static const char *kPlayerVCodec = "android.media.mediaplayer.video.codec";
-static const char *kPlayerWidth = "android.media.mediaplayer.width";
-static const char *kPlayerHeight = "android.media.mediaplayer.height";
-static const char *kPlayerFrames = "android.media.mediaplayer.frames";
-static const char *kPlayerFramesDropped = "android.media.mediaplayer.dropped";
-static const char *kPlayerFrameRate = "android.media.mediaplayer.fps";
-static const char *kPlayerAMime = "android.media.mediaplayer.audio.mime";
-static const char *kPlayerACodec = "android.media.mediaplayer.audio.codec";
-static const char *kPlayerDuration = "android.media.mediaplayer.durationMs";
-static const char *kPlayerPlaying = "android.media.mediaplayer.playingMs";
-static const char *kPlayerError = "android.media.mediaplayer.err";
-static const char *kPlayerErrorCode = "android.media.mediaplayer.errcode";
-
-// NB: These are not yet exposed as public Java API constants.
-static const char *kPlayerErrorState = "android.media.mediaplayer.errstate";
-static const char *kPlayerDataSourceType = "android.media.mediaplayer.dataSource";
-//
-static const char *kPlayerRebuffering = "android.media.mediaplayer.rebufferingMs";
-static const char *kPlayerRebufferingCount = "android.media.mediaplayer.rebuffers";
-static const char *kPlayerRebufferingAtExit = "android.media.mediaplayer.rebufferExit";
-
-static const char *kPlayerVersion = "android.media.mediaplayer.version";
-
-
-NuPlayer2Driver::NuPlayer2Driver(pid_t pid, uid_t uid, const sp<JObjectHolder> &context)
-    : mState(STATE_IDLE),
-      mAsyncResult(UNKNOWN_ERROR),
-      mSrcId(0),
-      mSetSurfaceInProgress(false),
-      mDurationUs(-1),
-      mPositionUs(-1),
-      mSeekInProgress(false),
-      mPlayingTimeUs(0),
-      mRebufferingTimeUs(0),
-      mRebufferingEvents(0),
-      mRebufferingAtExit(false),
-      mLooper(new ALooper),
-      mNuPlayer2Looper(new ALooper),
-      mMediaClock(new MediaClock),
-      mPlayer(new NuPlayer2(pid, uid, mMediaClock, context)),
-      mPlayerFlags(0),
-      mMetricsHandle(0),
-      mPlayerVersion(0),
-      mClientUid(uid),
-      mAtEOS(false),
-      mLooping(false),
-      mAutoLoop(false) {
-    ALOGD("NuPlayer2Driver(%p) created, clientPid(%d)", this, pid);
-    mLooper->setName("NuPlayer2Driver Looper");
-    mNuPlayer2Looper->setName("NuPlayer2 Looper");
-
-    mMediaClock->init();
-
-    // XXX: what version are we?
-    // Ideally, this ticks with the apk version info for the APEX packaging
-
-    // set up media metrics record
-    mMetricsHandle = mediametrics_create(kKeyPlayer);
-    mediametrics_setUid(mMetricsHandle, mClientUid);
-    mediametrics_setInt64(mMetricsHandle, kPlayerVersion, mPlayerVersion);
-
-    mNuPlayer2Looper->start(
-            false, /* runOnCallingThread */
-            true,  /* canCallJava */
-            PRIORITY_AUDIO);
-
-    mNuPlayer2Looper->registerHandler(mPlayer);
-
-    mPlayer->setDriver(this);
-}
-
-NuPlayer2Driver::~NuPlayer2Driver() {
-    ALOGV("~NuPlayer2Driver(%p)", this);
-    mNuPlayer2Looper->stop();
-    mLooper->stop();
-
-    // finalize any pending metrics, usually a no-op.
-    updateMetrics("destructor");
-    logMetrics("destructor");
-
-    mediametrics_delete(mMetricsHandle);
-}
-
-status_t NuPlayer2Driver::initCheck() {
-    mLooper->start(
-            false, /* runOnCallingThread */
-            true,  /* canCallJava */
-            PRIORITY_AUDIO);
-
-    mLooper->registerHandler(this);
-    return OK;
-}
-
-status_t NuPlayer2Driver::setDataSource(const sp<DataSourceDesc> &dsd) {
-    ALOGV("setDataSource(%p)", this);
-    Mutex::Autolock autoLock(mLock);
-
-    if (mState != STATE_IDLE) {
-        return INVALID_OPERATION;
-    }
-
-    mSrcId = dsd->mId;
-    mState = STATE_SET_DATASOURCE_PENDING;
-
-    mPlayer->setDataSourceAsync(dsd);
-
-    while (mState == STATE_SET_DATASOURCE_PENDING) {
-        mCondition.wait(mLock);
-    }
-
-    return mAsyncResult;
-}
-
-status_t NuPlayer2Driver::prepareNextDataSource(const sp<DataSourceDesc> &dsd) {
-    ALOGV("prepareNextDataSource(%p)", this);
-    Mutex::Autolock autoLock(mLock);
-
-    mPlayer->prepareNextDataSourceAsync(dsd);
-
-    return OK;
-}
-
-status_t NuPlayer2Driver::playNextDataSource(int64_t srcId) {
-    ALOGV("playNextDataSource(%p)", this);
-    Mutex::Autolock autoLock(mLock);
-
-    mSrcId = srcId;
-    mPlayer->playNextDataSource(srcId);
-
-    return OK;
-}
-
-status_t NuPlayer2Driver::setVideoSurfaceTexture(const sp<ANativeWindowWrapper> &nww) {
-    ALOGV("setVideoSurfaceTexture(%p)", this);
-    Mutex::Autolock autoLock(mLock);
-
-    if (mSetSurfaceInProgress) {
-        return INVALID_OPERATION;
-    }
-
-    switch (mState) {
-        case STATE_SET_DATASOURCE_PENDING:
-        case STATE_RESET_IN_PROGRESS:
-            return INVALID_OPERATION;
-
-        default:
-            break;
-    }
-
-    mSetSurfaceInProgress = true;
-
-    mPlayer->setVideoSurfaceTextureAsync(nww);
-
-    while (mSetSurfaceInProgress) {
-        mCondition.wait(mLock);
-    }
-
-    return OK;
-}
-
-status_t NuPlayer2Driver::getBufferingSettings(BufferingSettings* buffering) {
-    ALOGV("getBufferingSettings(%p)", this);
-    {
-        Mutex::Autolock autoLock(mLock);
-        if (mState == STATE_IDLE) {
-            return INVALID_OPERATION;
-        }
-    }
-
-    return mPlayer->getBufferingSettings(buffering);
-}
-
-status_t NuPlayer2Driver::setBufferingSettings(const BufferingSettings& buffering) {
-    ALOGV("setBufferingSettings(%p)", this);
-    {
-        Mutex::Autolock autoLock(mLock);
-        if (mState == STATE_IDLE) {
-            return INVALID_OPERATION;
-        }
-    }
-
-    return mPlayer->setBufferingSettings(buffering);
-}
-
-status_t NuPlayer2Driver::prepareAsync() {
-    ALOGV("prepareAsync(%p)", this);
-    Mutex::Autolock autoLock(mLock);
-
-    switch (mState) {
-        case STATE_UNPREPARED:
-            mState = STATE_PREPARING;
-            mPlayer->prepareAsync();
-            return OK;
-        default:
-            return INVALID_OPERATION;
-    };
-}
-
-status_t NuPlayer2Driver::start() {
-    ALOGD("start(%p), state is %d, eos is %d", this, mState, mAtEOS);
-    Mutex::Autolock autoLock(mLock);
-    return start_l();
-}
-
-status_t NuPlayer2Driver::start_l() {
-    switch (mState) {
-        case STATE_PAUSED:
-        case STATE_PREPARED:
-        {
-            mPlayer->start();
-            FALLTHROUGH_INTENDED;
-        }
-
-        case STATE_RUNNING:
-        {
-            if (mAtEOS) {
-                mPlayer->rewind();
-                mAtEOS = false;
-                mPositionUs = -1;
-            }
-            break;
-        }
-
-        default:
-            return INVALID_OPERATION;
-    }
-
-    mState = STATE_RUNNING;
-
-    return OK;
-}
-
-status_t NuPlayer2Driver::pause() {
-    ALOGD("pause(%p)", this);
-    // The NuPlayerRenderer may get flushed if pause for long enough, e.g. the pause timeout tear
-    // down for audio offload mode. If that happens, the NuPlayerRenderer will no longer know the
-    // current position. So similar to seekTo, update |mPositionUs| to the pause position by calling
-    // getCurrentPosition here.
-    int64_t unused;
-    getCurrentPosition(&unused);
-
-    Mutex::Autolock autoLock(mLock);
-
-    switch (mState) {
-        case STATE_PAUSED:
-            return OK;
-
-        case STATE_PREPARED:
-        case STATE_RUNNING:
-            mState = STATE_PAUSED;
-            mPlayer->pause();
-            break;
-
-        default:
-            return INVALID_OPERATION;
-    }
-
-    return OK;
-}
-
-bool NuPlayer2Driver::isPlaying() {
-    return mState == STATE_RUNNING && !mAtEOS;
-}
-
-status_t NuPlayer2Driver::setPlaybackSettings(const AudioPlaybackRate &rate) {
-    status_t err = mPlayer->setPlaybackSettings(rate);
-    if (err == OK) {
-        // try to update position
-        int64_t unused;
-        getCurrentPosition(&unused);
-    }
-    return err;
-}
-
-status_t NuPlayer2Driver::getPlaybackSettings(AudioPlaybackRate *rate) {
-    return mPlayer->getPlaybackSettings(rate);
-}
-
-status_t NuPlayer2Driver::setSyncSettings(const AVSyncSettings &sync, float videoFpsHint) {
-    return mPlayer->setSyncSettings(sync, videoFpsHint);
-}
-
-status_t NuPlayer2Driver::getSyncSettings(AVSyncSettings *sync, float *videoFps) {
-    return mPlayer->getSyncSettings(sync, videoFps);
-}
-
-status_t NuPlayer2Driver::seekTo(int64_t msec, MediaPlayer2SeekMode mode) {
-    ALOGD("seekTo(%p) (%lld ms, %d) at state %d", this, (long long)msec, mode, mState);
-    Mutex::Autolock autoLock(mLock);
-
-    int64_t seekTimeUs = msec * 1000LL;
-
-    switch (mState) {
-        case STATE_PREPARED:
-        case STATE_PAUSED:
-        case STATE_RUNNING:
-        {
-            mAtEOS = false;
-            mSeekInProgress = true;
-            mPlayer->seekToAsync(seekTimeUs, mode, true /* needNotify */);
-            break;
-        }
-
-        default:
-            return INVALID_OPERATION;
-    }
-
-    mPositionUs = seekTimeUs;
-    return OK;
-}
-
-status_t NuPlayer2Driver::getCurrentPosition(int64_t *msec) {
-    int64_t tempUs = 0;
-    {
-        Mutex::Autolock autoLock(mLock);
-        if (mSeekInProgress || (mState == STATE_PAUSED && !mAtEOS)) {
-            tempUs = (mPositionUs <= 0) ? 0 : mPositionUs;
-            *msec = divRound(tempUs, (int64_t)(1000));
-            return OK;
-        }
-    }
-
-    status_t ret = mPlayer->getCurrentPosition(&tempUs);
-
-    Mutex::Autolock autoLock(mLock);
-    // We need to check mSeekInProgress here because mPlayer->seekToAsync is an async call, which
-    // means getCurrentPosition can be called before seek is completed. Iow, renderer may return a
-    // position value that's different the seek to position.
-    if (ret != OK) {
-        tempUs = (mPositionUs <= 0) ? 0 : mPositionUs;
-    } else {
-        mPositionUs = tempUs;
-    }
-    *msec = divRound(tempUs, (int64_t)(1000));
-    return OK;
-}
-
-status_t NuPlayer2Driver::getDuration(int64_t *msec) {
-    Mutex::Autolock autoLock(mLock);
-
-    if (mDurationUs < 0) {
-        return UNKNOWN_ERROR;
-    }
-
-    *msec = (mDurationUs + 500LL) / 1000;
-
-    return OK;
-}
-
-void NuPlayer2Driver::updateMetrics(const char *where) {
-    if (where == NULL) {
-        where = "unknown";
-    }
-    ALOGV("updateMetrics(%p) from %s at state %d", this, where, mState);
-
-    // gather the final stats for this record
-    Vector<sp<AMessage>> trackStats;
-    mPlayer->getStats(&trackStats);
-
-    if (trackStats.size() > 0) {
-        for (size_t i = 0; i < trackStats.size(); ++i) {
-            const sp<AMessage> &stats = trackStats.itemAt(i);
-
-            AString mime;
-            stats->findString("mime", &mime);
-
-            AString name;
-            stats->findString("component-name", &name);
-
-            if (mime.startsWith("video/")) {
-                int32_t width, height;
-                mediametrics_setCString(mMetricsHandle, kPlayerVMime, mime.c_str());
-                if (!name.empty()) {
-                    mediametrics_setCString(mMetricsHandle, kPlayerVCodec, name.c_str());
-                }
-
-                if (stats->findInt32("width", &width)
-                        && stats->findInt32("height", &height)) {
-                    mediametrics_setInt32(mMetricsHandle, kPlayerWidth, width);
-                    mediametrics_setInt32(mMetricsHandle, kPlayerHeight, height);
-                }
-
-                int64_t numFramesTotal = 0;
-                int64_t numFramesDropped = 0;
-                stats->findInt64("frames-total", &numFramesTotal);
-                stats->findInt64("frames-dropped-output", &numFramesDropped);
-
-                mediametrics_setInt64(mMetricsHandle, kPlayerFrames, numFramesTotal);
-                mediametrics_setInt64(mMetricsHandle, kPlayerFramesDropped, numFramesDropped);
-
-                float frameRate = 0;
-                if (stats->findFloat("frame-rate-output", &frameRate)) {
-                    mediametrics_setInt64(mMetricsHandle, kPlayerFrameRate, frameRate);
-                }
-
-            } else if (mime.startsWith("audio/")) {
-                mediametrics_setCString(mMetricsHandle, kPlayerAMime, mime.c_str());
-                if (!name.empty()) {
-                    mediametrics_setCString(mMetricsHandle, kPlayerACodec, name.c_str());
-                }
-            }
-        }
-    }
-
-    // always provide duration and playing time, even if they have 0/unknown values.
-
-    // getDuration() uses mLock for mutex -- careful where we use it.
-    int64_t duration_ms = -1;
-    getDuration(&duration_ms);
-    mediametrics_setInt64(mMetricsHandle, kPlayerDuration, duration_ms);
-
-    mediametrics_setInt64(mMetricsHandle, kPlayerPlaying, (mPlayingTimeUs+500)/1000 );
-
-    if (mRebufferingEvents != 0) {
-        mediametrics_setInt64(mMetricsHandle, kPlayerRebuffering, (mRebufferingTimeUs+500)/1000 );
-        mediametrics_setInt32(mMetricsHandle, kPlayerRebufferingCount, mRebufferingEvents);
-        mediametrics_setInt32(mMetricsHandle, kPlayerRebufferingAtExit, mRebufferingAtExit);
-    }
-
-    mediametrics_setCString(mMetricsHandle, kPlayerDataSourceType, mPlayer->getDataSourceType());
-}
-
-
-void NuPlayer2Driver::logMetrics(const char *where) {
-    if (where == NULL) {
-        where = "unknown";
-    }
-    ALOGV("logMetrics(%p) from %s at state %d", this, where, mState);
-
-    if (mMetricsHandle == 0 || mediametrics_isEnabled() == false) {
-        return;
-    }
-
-    // log only non-empty records
-    // we always updateMetrics() before we get here
-    // and that always injects 3 fields (duration, playing time, and
-    // datasource) into the record.
-    // So the canonical "empty" record has 3 elements in it.
-    if (mediametrics_count(mMetricsHandle) > 3) {
-        mediametrics_selfRecord(mMetricsHandle);
-        // re-init in case we prepare() and start() again.
-        mediametrics_delete(mMetricsHandle);
-        mMetricsHandle = mediametrics_create(kKeyPlayer);
-        mediametrics_setUid(mMetricsHandle, mClientUid);
-        mediametrics_setInt64(mMetricsHandle, kPlayerVersion, mPlayerVersion);
-    } else {
-        ALOGV("did not have anything to record");
-    }
-}
-
-status_t NuPlayer2Driver::reset() {
-    ALOGD("reset(%p) at state %d", this, mState);
-
-    updateMetrics("reset");
-    logMetrics("reset");
-
-    Mutex::Autolock autoLock(mLock);
-
-    switch (mState) {
-        case STATE_IDLE:
-            return OK;
-
-        case STATE_SET_DATASOURCE_PENDING:
-        case STATE_RESET_IN_PROGRESS:
-            return INVALID_OPERATION;
-
-        case STATE_PREPARING:
-        {
-            notifyListener_l(mSrcId, MEDIA2_PREPARED);
-            break;
-        }
-
-        default:
-            break;
-    }
-
-    mState = STATE_RESET_IN_PROGRESS;
-    mPlayer->resetAsync();
-
-    while (mState == STATE_RESET_IN_PROGRESS) {
-        mCondition.wait(mLock);
-    }
-
-    mDurationUs = -1;
-    mPositionUs = -1;
-    mLooping = false;
-    mPlayingTimeUs = 0;
-    mRebufferingTimeUs = 0;
-    mRebufferingEvents = 0;
-    mRebufferingAtExit = false;
-
-    return OK;
-}
-
-status_t NuPlayer2Driver::notifyAt(int64_t mediaTimeUs) {
-    ALOGV("notifyAt(%p), time:%lld", this, (long long)mediaTimeUs);
-    return mPlayer->notifyAt(mediaTimeUs);
-}
-
-status_t NuPlayer2Driver::setLooping(int loop) {
-    mLooping = loop != 0;
-    return OK;
-}
-
-status_t NuPlayer2Driver::invoke(const PlayerMessage &request, PlayerMessage *response) {
-    if (response == NULL) {
-        ALOGE("reply is a NULL pointer");
-        return BAD_VALUE;
-    }
-
-    RepeatedPtrField<const Value>::const_iterator it = request.values().cbegin();
-    int32_t methodId = (it++)->int32_value();
-
-    switch (methodId) {
-        case MEDIA_PLAYER2_INVOKE_ID_SET_VIDEO_SCALING_MODE:
-        {
-            int mode = (it++)->int32_value();
-            return mPlayer->setVideoScalingMode(mode);
-        }
-
-        case MEDIA_PLAYER2_INVOKE_ID_GET_TRACK_INFO:
-        {
-            int64_t srcId = (it++)->int64_value();
-            return mPlayer->getTrackInfo(srcId, response);
-        }
-
-        case MEDIA_PLAYER2_INVOKE_ID_SELECT_TRACK:
-        {
-            int64_t srcId = (it++)->int64_value();
-            int trackIndex = (it++)->int32_value();
-            int64_t msec = 0;
-            // getCurrentPosition should always return OK
-            getCurrentPosition(&msec);
-            return mPlayer->selectTrack(srcId, trackIndex, true /* select */, msec * 1000LL);
-        }
-
-        case MEDIA_PLAYER2_INVOKE_ID_UNSELECT_TRACK:
-        {
-            int64_t srcId = (it++)->int64_value();
-            int trackIndex = (it++)->int32_value();
-            return mPlayer->selectTrack(
-                    srcId, trackIndex, false /* select */, 0xdeadbeef /* not used */);
-        }
-
-        case MEDIA_PLAYER2_INVOKE_ID_GET_SELECTED_TRACK:
-        {
-            int64_t srcId = (it++)->int64_value();
-            int32_t type = (it++)->int32_value();
-            return mPlayer->getSelectedTrack(srcId, type, response);
-        }
-
-        default:
-        {
-            return INVALID_OPERATION;
-        }
-    }
-}
-
-void NuPlayer2Driver::setAudioSink(const sp<AudioSink> &audioSink) {
-    mPlayer->setAudioSink(audioSink);
-    mAudioSink = audioSink;
-}
-
-status_t NuPlayer2Driver::setParameter(
-        int /* key */, const Parcel & /* request */) {
-    return INVALID_OPERATION;
-}
-
-status_t NuPlayer2Driver::getParameter(int key __unused, Parcel *reply __unused) {
-    return INVALID_OPERATION;
-}
-
-status_t NuPlayer2Driver::getMetrics(char **buffer, size_t *length) {
-    updateMetrics("api");
-    if (mediametrics_getAttributes(mMetricsHandle, buffer, length))
-        return OK;
-    else
-        return FAILED_TRANSACTION;
-}
-
-void NuPlayer2Driver::notifyResetComplete(int64_t /* srcId */) {
-    ALOGD("notifyResetComplete(%p)", this);
-    Mutex::Autolock autoLock(mLock);
-
-    CHECK_EQ(mState, STATE_RESET_IN_PROGRESS);
-    mState = STATE_IDLE;
-    mCondition.broadcast();
-}
-
-void NuPlayer2Driver::notifySetSurfaceComplete(int64_t /* srcId */) {
-    ALOGV("notifySetSurfaceComplete(%p)", this);
-    Mutex::Autolock autoLock(mLock);
-
-    CHECK(mSetSurfaceInProgress);
-    mSetSurfaceInProgress = false;
-
-    mCondition.broadcast();
-}
-
-void NuPlayer2Driver::notifyDuration(int64_t /* srcId */, int64_t durationUs) {
-    Mutex::Autolock autoLock(mLock);
-    mDurationUs = durationUs;
-}
-
-void NuPlayer2Driver::notifyMorePlayingTimeUs(int64_t /* srcId */, int64_t playingUs) {
-    Mutex::Autolock autoLock(mLock);
-    mPlayingTimeUs += playingUs;
-}
-
-void NuPlayer2Driver::notifyMoreRebufferingTimeUs(int64_t /* srcId */, int64_t rebufferingUs) {
-    Mutex::Autolock autoLock(mLock);
-    mRebufferingTimeUs += rebufferingUs;
-    mRebufferingEvents++;
-}
-
-void NuPlayer2Driver::notifyRebufferingWhenExit(int64_t /* srcId */, bool status) {
-    Mutex::Autolock autoLock(mLock);
-    mRebufferingAtExit = status;
-}
-
-void NuPlayer2Driver::notifySeekComplete(int64_t srcId) {
-    ALOGV("notifySeekComplete(%p)", this);
-    Mutex::Autolock autoLock(mLock);
-    mSeekInProgress = false;
-    notifyListener_l(srcId, MEDIA2_SEEK_COMPLETE);
-}
-
-status_t NuPlayer2Driver::dump(
-        int fd, const Vector<String16> & /* args */) const {
-
-    Vector<sp<AMessage> > trackStats;
-    mPlayer->getStats(&trackStats);
-
-    AString logString(" NuPlayer2\n");
-    char buf[256] = {0};
-
-    bool locked = false;
-    for (int i = 0; i < kDumpLockRetries; ++i) {
-        if (mLock.tryLock() == NO_ERROR) {
-            locked = true;
-            break;
-        }
-        usleep(kDumpLockSleepUs);
-    }
-
-    if (locked) {
-        snprintf(buf, sizeof(buf), "  state(%d), atEOS(%d), looping(%d), autoLoop(%d)\n",
-                mState, mAtEOS, mLooping, mAutoLoop);
-        mLock.unlock();
-    } else {
-        snprintf(buf, sizeof(buf), "  NPD(%p) lock is taken\n", this);
-    }
-    logString.append(buf);
-
-    for (size_t i = 0; i < trackStats.size(); ++i) {
-        const sp<AMessage> &stats = trackStats.itemAt(i);
-
-        AString mime;
-        if (stats->findString("mime", &mime)) {
-            snprintf(buf, sizeof(buf), "  mime(%s)\n", mime.c_str());
-            logString.append(buf);
-        }
-
-        AString name;
-        if (stats->findString("component-name", &name)) {
-            snprintf(buf, sizeof(buf), "    decoder(%s)\n", name.c_str());
-            logString.append(buf);
-        }
-
-        if (mime.startsWith("video/")) {
-            int32_t width, height;
-            if (stats->findInt32("width", &width)
-                    && stats->findInt32("height", &height)) {
-                snprintf(buf, sizeof(buf), "    resolution(%d x %d)\n", width, height);
-                logString.append(buf);
-            }
-
-            int64_t numFramesTotal = 0;
-            int64_t numFramesDropped = 0;
-
-            stats->findInt64("frames-total", &numFramesTotal);
-            stats->findInt64("frames-dropped-output", &numFramesDropped);
-            snprintf(buf, sizeof(buf), "    numFramesTotal(%lld), numFramesDropped(%lld), "
-                     "percentageDropped(%.2f%%)\n",
-                     (long long)numFramesTotal,
-                     (long long)numFramesDropped,
-                     numFramesTotal == 0
-                            ? 0.0 : (double)(numFramesDropped * 100) / numFramesTotal);
-            logString.append(buf);
-        }
-    }
-
-    ALOGI("%s", logString.c_str());
-
-    if (fd >= 0) {
-        FILE *out = fdopen(dup(fd), "w");
-        fprintf(out, "%s", logString.c_str());
-        fclose(out);
-        out = NULL;
-    }
-
-    return OK;
-}
-
-void NuPlayer2Driver::onMessageReceived(const sp<AMessage> &msg) {
-    switch (msg->what()) {
-        case kWhatNotifyListener: {
-            int64_t srcId;
-            int32_t msgId;
-            int32_t ext1 = 0;
-            int32_t ext2 = 0;
-            CHECK(msg->findInt64("srcId", &srcId));
-            CHECK(msg->findInt32("messageId", &msgId));
-            msg->findInt32("ext1", &ext1);
-            msg->findInt32("ext2", &ext2);
-            sp<PlayerMessageWrapper> in;
-            sp<RefBase> obj;
-            if (msg->findObject("obj", &obj) && obj != NULL) {
-                in = static_cast<PlayerMessageWrapper *>(obj.get());
-            }
-            sendEvent(srcId, msgId, ext1, ext2, (in == NULL ? NULL : in->getPlayerMessage()));
-            break;
-        }
-        default:
-            break;
-    }
-}
-
-void NuPlayer2Driver::notifyListener(
-        int64_t srcId, int msg, int ext1, int ext2, const PlayerMessage *in) {
-    Mutex::Autolock autoLock(mLock);
-    notifyListener_l(srcId, msg, ext1, ext2, in);
-}
-
-void NuPlayer2Driver::notifyListener_l(
-        int64_t srcId, int msg, int ext1, int ext2, const PlayerMessage *in) {
-    ALOGD("notifyListener_l(%p), (%lld, %d, %d, %d, %d), loop setting(%d, %d)",
-            this, (long long)srcId, msg, ext1, ext2,
-            (in == NULL ? -1 : (int)in->ByteSize()), mAutoLoop, mLooping);
-    if (srcId == mSrcId) {
-        switch (msg) {
-            case MEDIA2_PLAYBACK_COMPLETE:
-            {
-                if (mState != STATE_RESET_IN_PROGRESS) {
-                    if (mAutoLoop) {
-                        audio_stream_type_t streamType = AUDIO_STREAM_MUSIC;
-                        if (mAudioSink != NULL) {
-                            streamType = mAudioSink->getAudioStreamType();
-                        }
-                        if (streamType == AUDIO_STREAM_NOTIFICATION) {
-                            ALOGW("disabling auto-loop for notification");
-                            mAutoLoop = false;
-                        }
-                    }
-                    if (mLooping || mAutoLoop) {
-                        mPlayer->rewind();
-                        if (mAudioSink != NULL) {
-                            // The renderer has stopped the sink at the end in order to play out
-                            // the last little bit of audio. In looping mode, we need to restart it.
-                            mAudioSink->start();
-                        }
-
-                        sp<AMessage> notify = new AMessage(kWhatNotifyListener, this);
-                        notify->setInt64("srcId", srcId);
-                        notify->setInt32("messageId", MEDIA2_INFO);
-                        notify->setInt32("ext1", MEDIA2_INFO_DATA_SOURCE_REPEAT);
-                        notify->post();
-                        return;
-                    }
-                    if (property_get_bool("persist.debug.sf.stats", false)) {
-                        Vector<String16> args;
-                        dump(-1, args);
-                    }
-                    mPlayer->pause();
-                    mState = STATE_PAUSED;
-                }
-                FALLTHROUGH_INTENDED;
-            }
-
-            case MEDIA2_ERROR:
-            {
-                // when we have an error, add it to the analytics for this playback.
-                // ext1 is our primary 'error type' value. Only add ext2 when non-zero.
-                // [test against msg is due to fall through from previous switch value]
-                if (msg == MEDIA2_ERROR) {
-                    mediametrics_setInt32(mMetricsHandle, kPlayerError, ext1);
-                    if (ext2 != 0) {
-                        mediametrics_setInt32(mMetricsHandle, kPlayerErrorCode, ext2);
-                    }
-                    mediametrics_setCString(mMetricsHandle, kPlayerErrorState, stateString(mState).c_str());
-                }
-                mAtEOS = true;
-                break;
-            }
-
-            default:
-                break;
-        }
-    }
-
-    sp<AMessage> notify = new AMessage(kWhatNotifyListener, this);
-    notify->setInt64("srcId", srcId);
-    notify->setInt32("messageId", msg);
-    notify->setInt32("ext1", ext1);
-    notify->setInt32("ext2", ext2);
-    notify->setObject("obj", PlayerMessageWrapper::Create((PlayerMessage*)in));
-    notify->post();
-}
-
-void NuPlayer2Driver::notifySetDataSourceCompleted(int64_t /* srcId */, status_t err) {
-    Mutex::Autolock autoLock(mLock);
-
-    CHECK_EQ(mState, STATE_SET_DATASOURCE_PENDING);
-
-    mAsyncResult = err;
-    mState = (err == OK) ? STATE_UNPREPARED : STATE_IDLE;
-    mCondition.broadcast();
-}
-
-void NuPlayer2Driver::notifyPrepareCompleted(int64_t srcId, status_t err) {
-    ALOGV("notifyPrepareCompleted %d", err);
-
-    Mutex::Autolock autoLock(mLock);
-
-    if (srcId != mSrcId) {
-        if (err == OK) {
-            notifyListener_l(srcId, MEDIA2_PREPARED);
-        } else {
-            notifyListener_l(srcId, MEDIA2_ERROR, MEDIA2_ERROR_UNKNOWN, err);
-        }
-        return;
-    }
-
-    if (mState != STATE_PREPARING) {
-        // We were preparing asynchronously when the client called
-        // reset(), we sent a premature "prepared" notification and
-        // then initiated the reset. This notification is stale.
-        CHECK(mState == STATE_RESET_IN_PROGRESS || mState == STATE_IDLE);
-        return;
-    }
-
-    CHECK_EQ(mState, STATE_PREPARING);
-
-    mAsyncResult = err;
-
-    if (err == OK) {
-        // update state before notifying client, so that if client calls back into NuPlayer2Driver
-        // in response, NuPlayer2Driver has the right state
-        mState = STATE_PREPARED;
-        notifyListener_l(srcId, MEDIA2_PREPARED);
-    } else {
-        mState = STATE_UNPREPARED;
-        notifyListener_l(srcId, MEDIA2_ERROR, MEDIA2_ERROR_UNKNOWN, err);
-    }
-
-    sp<MetaData> meta = mPlayer->getFileMeta();
-    int32_t loop;
-    if (meta != NULL
-            && meta->findInt32(kKeyAutoLoop, &loop) && loop != 0) {
-        mAutoLoop = true;
-    }
-
-    mCondition.broadcast();
-}
-
-void NuPlayer2Driver::notifyFlagsChanged(int64_t /* srcId */, uint32_t flags) {
-    Mutex::Autolock autoLock(mLock);
-
-    mPlayerFlags = flags;
-}
-
-// Modular DRM
-status_t NuPlayer2Driver::prepareDrm(
-        int64_t srcId, const uint8_t uuid[16], const Vector<uint8_t> &drmSessionId)
-{
-    ALOGV("prepareDrm(%p) state: %d", this, mState);
-
-    // leaving the state verification for mediaplayer.cpp
-    status_t ret = mPlayer->prepareDrm(srcId, uuid, drmSessionId);
-
-    ALOGV("prepareDrm ret: %d", ret);
-
-    return ret;
-}
-
-status_t NuPlayer2Driver::releaseDrm(int64_t srcId)
-{
-    ALOGV("releaseDrm(%p) state: %d", this, mState);
-
-    // leaving the state verification for mediaplayer.cpp
-    status_t ret = mPlayer->releaseDrm(srcId);
-
-    ALOGV("releaseDrm ret: %d", ret);
-
-    return ret;
-}
-
-std::string NuPlayer2Driver::stateString(State state) {
-    const char *rval = NULL;
-    char rawbuffer[16];  // allows "%d"
-
-    switch (state) {
-        case STATE_IDLE: rval = "IDLE"; break;
-        case STATE_SET_DATASOURCE_PENDING: rval = "SET_DATASOURCE_PENDING"; break;
-        case STATE_UNPREPARED: rval = "UNPREPARED"; break;
-        case STATE_PREPARING: rval = "PREPARING"; break;
-        case STATE_PREPARED: rval = "PREPARED"; break;
-        case STATE_RUNNING: rval = "RUNNING"; break;
-        case STATE_PAUSED: rval = "PAUSED"; break;
-        case STATE_RESET_IN_PROGRESS: rval = "RESET_IN_PROGRESS"; break;
-        default:
-            // yes, this buffer is shared and vulnerable to races
-            snprintf(rawbuffer, sizeof(rawbuffer), "%d", state);
-            rval = rawbuffer;
-            break;
-    }
-
-    return rval;
-}
-
-}  // namespace android
diff --git a/media/libmediaplayer2/nuplayer2/NuPlayer2Driver.h b/media/libmediaplayer2/nuplayer2/NuPlayer2Driver.h
deleted file mode 100644
index c97e247..0000000
--- a/media/libmediaplayer2/nuplayer2/NuPlayer2Driver.h
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * Copyright 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <mediaplayer2/MediaPlayer2Interface.h>
-
-#include <media/MediaMetrics.h>
-#include <media/stagefright/foundation/ABase.h>
-#include <mediaplayer2/JObjectHolder.h>
-
-namespace android {
-
-struct ALooper;
-struct MediaClock;
-struct NuPlayer2;
-
-struct NuPlayer2Driver : public MediaPlayer2Interface {
-    explicit NuPlayer2Driver(pid_t pid, uid_t uid, const sp<JObjectHolder> &context);
-
-    virtual status_t initCheck() override;
-
-    virtual status_t setDataSource(const sp<DataSourceDesc> &dsd) override;
-    virtual status_t prepareNextDataSource(const sp<DataSourceDesc> &dsd) override;
-    virtual status_t playNextDataSource(int64_t srcId) override;
-
-    virtual status_t setVideoSurfaceTexture(const sp<ANativeWindowWrapper> &nww) override;
-
-    virtual status_t getBufferingSettings(
-            BufferingSettings* buffering /* nonnull */) override;
-    virtual status_t setBufferingSettings(const BufferingSettings& buffering) override;
-
-    virtual status_t prepareAsync() override;
-    virtual status_t start() override;
-    virtual status_t pause() override;
-    virtual bool isPlaying() override;
-    virtual status_t setPlaybackSettings(const AudioPlaybackRate &rate) override;
-    virtual status_t getPlaybackSettings(AudioPlaybackRate *rate) override;
-    virtual status_t setSyncSettings(const AVSyncSettings &sync, float videoFpsHint) override;
-    virtual status_t getSyncSettings(AVSyncSettings *sync, float *videoFps) override;
-    virtual status_t seekTo(
-            int64_t msec,
-            MediaPlayer2SeekMode mode = MediaPlayer2SeekMode::SEEK_PREVIOUS_SYNC) override;
-    virtual status_t getCurrentPosition(int64_t *msec) override;
-    virtual status_t getDuration(int64_t *msec) override;
-    virtual status_t reset() override;
-    virtual status_t notifyAt(int64_t mediaTimeUs) override;
-    virtual status_t setLooping(int loop) override;
-    virtual status_t invoke(const PlayerMessage &request, PlayerMessage *response) override;
-    virtual void setAudioSink(const sp<AudioSink> &audioSink) override;
-    virtual status_t setParameter(int key, const Parcel &request) override;
-    virtual status_t getParameter(int key, Parcel *reply) override;
-    virtual status_t getMetrics(char **buf, size_t *length) override;
-
-    virtual status_t dump(int fd, const Vector<String16> &args) const override;
-
-    virtual void onMessageReceived(const sp<AMessage> &msg) override;
-
-    void notifySetDataSourceCompleted(int64_t srcId, status_t err);
-    void notifyPrepareCompleted(int64_t srcId, status_t err);
-    void notifyResetComplete(int64_t srcId);
-    void notifySetSurfaceComplete(int64_t srcId);
-    void notifyDuration(int64_t srcId, int64_t durationUs);
-    void notifyMorePlayingTimeUs(int64_t srcId, int64_t timeUs);
-    void notifyMoreRebufferingTimeUs(int64_t srcId, int64_t timeUs);
-    void notifyRebufferingWhenExit(int64_t srcId, bool status);
-    void notifySeekComplete(int64_t srcId);
-    void notifyListener(int64_t srcId, int msg, int ext1 = 0, int ext2 = 0,
-                        const PlayerMessage *in = NULL);
-    void notifyFlagsChanged(int64_t srcId, uint32_t flags);
-
-    // Modular DRM
-    virtual status_t prepareDrm(
-            int64_t srcId, const uint8_t uuid[16], const Vector<uint8_t> &drmSessionId);
-    virtual status_t releaseDrm(int64_t srcId);
-
-protected:
-    virtual ~NuPlayer2Driver();
-
-private:
-    enum State {
-        STATE_IDLE,
-        STATE_SET_DATASOURCE_PENDING,
-        STATE_UNPREPARED,
-        STATE_PREPARING,
-        STATE_PREPARED,
-        STATE_RUNNING,
-        STATE_PAUSED,
-        STATE_RESET_IN_PROGRESS,
-    };
-
-    std::string stateString(State state);
-
-    enum {
-        kWhatNotifyListener,
-    };
-
-    mutable Mutex mLock;
-    Condition mCondition;
-
-    State mState;
-
-    status_t mAsyncResult;
-
-    // The following are protected through "mLock"
-    // >>>
-    int64_t mSrcId;
-    bool mSetSurfaceInProgress;
-    int64_t mDurationUs;
-    int64_t mPositionUs;
-    bool mSeekInProgress;
-    int64_t mPlayingTimeUs;
-    int64_t mRebufferingTimeUs;
-    int32_t mRebufferingEvents;
-    bool mRebufferingAtExit;
-    // <<<
-
-    sp<ALooper> mLooper;
-    sp<ALooper> mNuPlayer2Looper;
-    const sp<MediaClock> mMediaClock;
-    const sp<NuPlayer2> mPlayer;
-    sp<AudioSink> mAudioSink;
-    uint32_t mPlayerFlags;
-
-    mediametrics_handle_t mMetricsHandle;
-    int64_t mPlayerVersion;
-    uid_t mClientUid;
-
-    bool mAtEOS;
-    bool mLooping;
-    bool mAutoLoop;
-
-    void updateMetrics(const char *where);
-    void logMetrics(const char *where);
-
-    status_t start_l();
-    void notifyListener_l(int64_t srcId, int msg, int ext1 = 0, int ext2 = 0,
-                          const PlayerMessage *in = NULL);
-
-    DISALLOW_EVIL_CONSTRUCTORS(NuPlayer2Driver);
-};
-
-}  // namespace android
-
-
diff --git a/media/libmediaplayer2/nuplayer2/NuPlayer2Drm.cpp b/media/libmediaplayer2/nuplayer2/NuPlayer2Drm.cpp
deleted file mode 100644
index f41a431..0000000
--- a/media/libmediaplayer2/nuplayer2/NuPlayer2Drm.cpp
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- * Copyright 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-//#define LOG_NDEBUG 0
-#define LOG_TAG "NuPlayer2Drm"
-
-#include "NuPlayer2Drm.h"
-
-#include <media/NdkWrapper.h>
-#include <utils/Log.h>
-#include <sstream>
-
-namespace android {
-
-Vector<DrmUUID> NuPlayer2Drm::parsePSSH(const void *pssh, size_t psshsize)
-{
-    Vector<DrmUUID> drmSchemes, empty;
-    const int DATALEN_SIZE = 4;
-
-    // the format of the buffer is 1 or more of:
-    //    {
-    //        16 byte uuid
-    //        4 byte data length N
-    //        N bytes of data
-    //    }
-    // Determine the number of entries in the source data.
-    // Since we got the data from stagefright, we trust it is valid and properly formatted.
-
-    const uint8_t *data = (const uint8_t*)pssh;
-    size_t len = psshsize;
-    size_t numentries = 0;
-    while (len > 0) {
-        if (len < DrmUUID::UUID_SIZE) {
-            ALOGE("ParsePSSH: invalid PSSH data");
-            return empty;
-        }
-
-        const uint8_t *uuidPtr = data;
-
-        // skip uuid
-        data += DrmUUID::UUID_SIZE;
-        len -= DrmUUID::UUID_SIZE;
-
-        // get data length
-        if (len < DATALEN_SIZE) {
-            ALOGE("ParsePSSH: invalid PSSH data");
-            return empty;
-        }
-
-        uint32_t datalen = *((uint32_t*)data);
-        data += DATALEN_SIZE;
-        len -= DATALEN_SIZE;
-
-        if (len < datalen) {
-            ALOGE("ParsePSSH: invalid PSSH data");
-            return empty;
-        }
-
-        // skip the data
-        data += datalen;
-        len -= datalen;
-
-        DrmUUID _uuid(uuidPtr);
-        drmSchemes.add(_uuid);
-
-        ALOGV("ParsePSSH[%zu]: %s: %s", numentries,
-                _uuid.toHexString().string(),
-                DrmUUID::arrayToHex(data, datalen).string()
-             );
-
-        numentries++;
-    }
-
-    return drmSchemes;
-}
-
-Vector<DrmUUID> NuPlayer2Drm::getSupportedDrmSchemes(const void *pssh, size_t psshsize)
-{
-    Vector<DrmUUID> psshDRMs = parsePSSH(pssh, psshsize);
-
-    Vector<DrmUUID> supportedDRMs;
-    for (size_t i = 0; i < psshDRMs.size(); i++) {
-        DrmUUID uuid = psshDRMs[i];
-        if (AMediaDrmWrapper::isCryptoSchemeSupported(uuid.ptr(), NULL)) {
-            supportedDRMs.add(uuid);
-        }
-    }
-
-    ALOGV("getSupportedDrmSchemes: psshDRMs: %zu supportedDRMs: %zu",
-            psshDRMs.size(), supportedDRMs.size());
-
-    return supportedDRMs;
-}
-
-sp<ABuffer> NuPlayer2Drm::retrieveDrmInfo(const void *pssh, uint32_t psshsize)
-{
-    std::ostringstream buf;
-
-    // 1) PSSH bytes
-    buf.write(reinterpret_cast<const char *>(&psshsize), sizeof(psshsize));
-    buf.write(reinterpret_cast<const char *>(pssh), psshsize);
-
-    ALOGV("retrieveDrmInfo: MEDIA2_DRM_INFO  PSSH: size: %u %s", psshsize,
-            DrmUUID::arrayToHex((uint8_t*)pssh, psshsize).string());
-
-    // 2) supportedDRMs
-    Vector<DrmUUID> supportedDRMs = getSupportedDrmSchemes(pssh, psshsize);
-    uint32_t n = supportedDRMs.size();
-    buf.write(reinterpret_cast<char *>(&n), sizeof(n));
-    for (size_t i = 0; i < n; i++) {
-        DrmUUID uuid = supportedDRMs[i];
-        buf.write(reinterpret_cast<const char *>(&n), sizeof(n));
-        buf.write(reinterpret_cast<const char *>(uuid.ptr()), DrmUUID::UUID_SIZE);
-
-        ALOGV("retrieveDrmInfo: MEDIA2_DRM_INFO  supportedScheme[%zu] %s", i,
-                uuid.toHexString().string());
-    }
-
-    sp<ABuffer> drmInfoBuffer = ABuffer::CreateAsCopy(buf.str().c_str(), buf.tellp());
-    return drmInfoBuffer;
-}
-
-status_t NuPlayer2Drm::retrieveDrmInfo(PsshInfo *psshInfo, PlayerMessage *playerMsg)
-{
-    std::ostringstream pssh, drmInfo;
-
-    // 0) Generate PSSH bytes
-    for (size_t i = 0; i < psshInfo->numentries; i++) {
-        PsshEntry *entry = &psshInfo->entries[i];
-        uint32_t datalen = entry->datalen;
-        pssh.write(reinterpret_cast<const char *>(&entry->uuid), sizeof(entry->uuid));
-        pssh.write(reinterpret_cast<const char *>(&datalen), sizeof(datalen));
-        pssh.write(reinterpret_cast<const char *>(entry->data), datalen);
-    }
-
-    uint32_t psshSize = pssh.tellp();
-    std::string psshBase = pssh.str();
-    const auto* psshPtr = reinterpret_cast<const uint8_t*>(psshBase.c_str());
-    ALOGV("retrieveDrmInfo: MEDIA_DRM_INFO  PSSH: size: %u %s", psshSize,
-            DrmUUID::arrayToHex(psshPtr, psshSize).string());
-
-    // 1) Write PSSH bytes
-    playerMsg->add_values()->set_bytes_value(
-            reinterpret_cast<const char *>(pssh.str().c_str()), psshSize);
-
-    // 2) Write supportedDRMs
-    uint32_t numentries = psshInfo->numentries;
-    playerMsg->add_values()->set_int32_value(numentries);
-    for (size_t i = 0; i < numentries; i++) {
-        PsshEntry *entry = &psshInfo->entries[i];
-        playerMsg->add_values()->set_bytes_value(
-                reinterpret_cast<const char *>(&entry->uuid), sizeof(entry->uuid));
-        ALOGV("retrieveDrmInfo: MEDIA_DRM_INFO  supportedScheme[%zu] %s", i,
-                DrmUUID::arrayToHex((const uint8_t*)&entry->uuid, sizeof(AMediaUUID)).string());
-    }
-    return OK;
-}
-
-}   // namespace android
diff --git a/media/libmediaplayer2/nuplayer2/NuPlayer2Drm.h b/media/libmediaplayer2/nuplayer2/NuPlayer2Drm.h
deleted file mode 100644
index 968d1be..0000000
--- a/media/libmediaplayer2/nuplayer2/NuPlayer2Drm.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef NUPLAYER2_DRM_H_
-#define NUPLAYER2_DRM_H_
-
-#include <media/NdkMediaExtractor.h>
-#include <media/stagefright/foundation/ABuffer.h>
-
-#include <utils/String8.h>
-#include <utils/Vector.h>
-
-#include "mediaplayer2.pb.h"
-
-using android::media::MediaPlayer2Proto::PlayerMessage;
-
-namespace android {
-
-    struct DrmUUID {
-        static const int UUID_SIZE = 16;
-
-        DrmUUID() {
-            memset(this->uuid, 0, sizeof(uuid));
-        }
-
-        // to allow defining Vector/KeyedVector of UUID type
-        DrmUUID(const DrmUUID &a) {
-            memcpy(this->uuid, a.uuid, sizeof(uuid));
-        }
-
-        // to allow defining Vector/KeyedVector of UUID type
-        DrmUUID(const uint8_t uuid_in[UUID_SIZE]) {
-            memcpy(this->uuid, uuid_in, sizeof(uuid));
-        }
-
-        const uint8_t *ptr() const {
-            return uuid;
-        }
-
-        String8 toHexString() const {
-            return arrayToHex(uuid, UUID_SIZE);
-        }
-
-        static String8 toHexString(const uint8_t uuid_in[UUID_SIZE]) {
-            return arrayToHex(uuid_in, UUID_SIZE);
-        }
-
-        static String8 arrayToHex(const uint8_t *array, int bytes) {
-            String8 result;
-            for (int i = 0; i < bytes; i++) {
-                result.appendFormat("%02x", array[i]);
-            }
-
-            return result;
-        }
-
-    protected:
-        uint8_t uuid[UUID_SIZE];
-    };
-
-
-    struct NuPlayer2Drm {
-
-        // static helpers - internal
-
-    protected:
-        static Vector<DrmUUID> parsePSSH(const void *pssh, size_t psshsize);
-        static Vector<DrmUUID> getSupportedDrmSchemes(const void *pssh, size_t psshsize);
-
-        // static helpers - public
-
-    public:
-        static sp<ABuffer> retrieveDrmInfo(const void *pssh, uint32_t psshsize);
-        static status_t retrieveDrmInfo(PsshInfo *, PlayerMessage *);
-
-    };  // NuPlayer2Drm
-
-}   // android
-
-#endif     //NUPLAYER2_DRM_H_
diff --git a/media/libmediaplayer2/nuplayer2/NuPlayer2Renderer.cpp b/media/libmediaplayer2/nuplayer2/NuPlayer2Renderer.cpp
deleted file mode 100644
index fd459df..0000000
--- a/media/libmediaplayer2/nuplayer2/NuPlayer2Renderer.cpp
+++ /dev/null
@@ -1,2096 +0,0 @@
-/*
- * Copyright (C) 2010 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 "NuPlayer2Renderer"
-#include <utils/Log.h>
-
-#include "JWakeLock.h"
-#include "NuPlayer2Renderer.h"
-#include <algorithm>
-#include <cutils/properties.h>
-#include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/foundation/AMessage.h>
-#include <media/stagefright/foundation/AUtils.h>
-#include <media/stagefright/MediaClock.h>
-#include <media/stagefright/MediaCodecConstants.h>
-#include <media/stagefright/MediaDefs.h>
-#include <media/stagefright/MediaErrors.h>
-#include <media/stagefright/Utils.h>
-#include <media/stagefright/VideoFrameScheduler2.h>
-#include <media/MediaCodecBuffer.h>
-
-#include <inttypes.h>
-
-namespace android {
-
-/*
- * Example of common configuration settings in shell script form
-
-   #Turn offload audio off (use PCM for Play Music) -- AudioPolicyManager
-   adb shell setprop audio.offload.disable 1
-
-   #Allow offload audio with video (requires offloading to be enabled) -- AudioPolicyManager
-   adb shell setprop audio.offload.video 1
-
-   #Use audio callbacks for PCM data
-   adb shell setprop media.stagefright.audio.cbk 1
-
-   #Use deep buffer for PCM data with video (it is generally enabled for audio-only)
-   adb shell setprop media.stagefright.audio.deep 1
-
-   #Set size of buffers for pcm audio sink in msec (example: 1000 msec)
-   adb shell setprop media.stagefright.audio.sink 1000
-
- * These configurations take effect for the next track played (not the current track).
- */
-
-static inline bool getUseAudioCallbackSetting() {
-    return property_get_bool("media.stagefright.audio.cbk", false /* default_value */);
-}
-
-static inline int32_t getAudioSinkPcmMsSetting() {
-    return property_get_int32(
-            "media.stagefright.audio.sink", 500 /* default_value */);
-}
-
-// Maximum time in paused state when offloading audio decompression. When elapsed, the AudioSink
-// is closed to allow the audio DSP to power down.
-static const int64_t kOffloadPauseMaxUs = 10000000LL;
-
-// Maximum allowed delay from AudioSink, 1.5 seconds.
-static const int64_t kMaxAllowedAudioSinkDelayUs = 1500000LL;
-
-static const int64_t kMinimumAudioClockUpdatePeriodUs = 20 /* msec */ * 1000;
-
-// Default video frame display duration when only video exists.
-// Used to set max media time in MediaClock.
-static const int64_t kDefaultVideoFrameIntervalUs = 100000LL;
-
-// static
-const NuPlayer2::Renderer::PcmInfo NuPlayer2::Renderer::AUDIO_PCMINFO_INITIALIZER = {
-        AUDIO_CHANNEL_NONE,
-        AUDIO_OUTPUT_FLAG_NONE,
-        AUDIO_FORMAT_INVALID,
-        0, // mNumChannels
-        0 // mSampleRate
-};
-
-// static
-const int64_t NuPlayer2::Renderer::kMinPositionUpdateDelayUs = 100000LL;
-
-static audio_format_t constexpr audioFormatFromEncoding(int32_t pcmEncoding) {
-    switch (pcmEncoding) {
-    case kAudioEncodingPcmFloat:
-        return AUDIO_FORMAT_PCM_FLOAT;
-    case kAudioEncodingPcm16bit:
-        return AUDIO_FORMAT_PCM_16_BIT;
-    case kAudioEncodingPcm8bit:
-        return AUDIO_FORMAT_PCM_8_BIT;  // TODO: do we want to support this?
-    default:
-        ALOGE("%s: Invalid encoding: %d", __func__, pcmEncoding);
-        return AUDIO_FORMAT_INVALID;
-    }
-}
-
-NuPlayer2::Renderer::Renderer(
-        const sp<MediaPlayer2Interface::AudioSink> &sink,
-        const sp<MediaClock> &mediaClock,
-        const sp<AMessage> &notify,
-        const sp<JObjectHolder> &context,
-        uint32_t flags)
-    : mAudioSink(sink),
-      mUseVirtualAudioSink(false),
-      mNotify(notify),
-      mFlags(flags),
-      mNumFramesWritten(0),
-      mDrainAudioQueuePending(false),
-      mDrainVideoQueuePending(false),
-      mAudioQueueGeneration(0),
-      mVideoQueueGeneration(0),
-      mAudioDrainGeneration(0),
-      mVideoDrainGeneration(0),
-      mAudioEOSGeneration(0),
-      mMediaClock(mediaClock),
-      mPlaybackSettings(AUDIO_PLAYBACK_RATE_DEFAULT),
-      mAudioFirstAnchorTimeMediaUs(-1),
-      mAnchorTimeMediaUs(-1),
-      mAnchorNumFramesWritten(-1),
-      mVideoLateByUs(0LL),
-      mNextVideoTimeMediaUs(-1),
-      mHasAudio(false),
-      mHasVideo(false),
-      mNotifyCompleteAudio(false),
-      mNotifyCompleteVideo(false),
-      mSyncQueues(false),
-      mPaused(true),
-      mPauseDrainAudioAllowedUs(0),
-      mVideoSampleReceived(false),
-      mVideoRenderingStarted(false),
-      mVideoRenderingStartGeneration(0),
-      mAudioRenderingStartGeneration(0),
-      mRenderingDataDelivered(false),
-      mNextAudioClockUpdateTimeUs(-1),
-      mLastAudioMediaTimeUs(-1),
-      mAudioOffloadPauseTimeoutGeneration(0),
-      mAudioTornDown(false),
-      mCurrentOffloadInfo(AUDIO_INFO_INITIALIZER),
-      mCurrentPcmInfo(AUDIO_PCMINFO_INITIALIZER),
-      mTotalBuffersQueued(0),
-      mLastAudioBufferDrained(0),
-      mUseAudioCallback(false),
-      mWakeLock(new JWakeLock(context)) {
-    CHECK(mediaClock != NULL);
-    mMediaClock->setPlaybackRate(mPlaybackSettings.mSpeed);
-}
-
-NuPlayer2::Renderer::~Renderer() {
-    if (offloadingAudio()) {
-        mAudioSink->stop();
-        mAudioSink->flush();
-        mAudioSink->close();
-    }
-
-    // Try to avoid racing condition in case callback is still on.
-    Mutex::Autolock autoLock(mLock);
-    if (mUseAudioCallback) {
-        flushQueue(&mAudioQueue);
-        flushQueue(&mVideoQueue);
-    }
-    mWakeLock.clear();
-    mVideoScheduler.clear();
-    mNotify.clear();
-    mAudioSink.clear();
-}
-
-void NuPlayer2::Renderer::queueBuffer(
-        bool audio,
-        const sp<MediaCodecBuffer> &buffer,
-        const sp<AMessage> &notifyConsumed) {
-    sp<AMessage> msg = new AMessage(kWhatQueueBuffer, this);
-    msg->setInt32("queueGeneration", getQueueGeneration(audio));
-    msg->setInt32("audio", static_cast<int32_t>(audio));
-    msg->setObject("buffer", buffer);
-    msg->setMessage("notifyConsumed", notifyConsumed);
-    msg->post();
-}
-
-void NuPlayer2::Renderer::queueEOS(bool audio, status_t finalResult) {
-    CHECK_NE(finalResult, (status_t)OK);
-
-    sp<AMessage> msg = new AMessage(kWhatQueueEOS, this);
-    msg->setInt32("queueGeneration", getQueueGeneration(audio));
-    msg->setInt32("audio", static_cast<int32_t>(audio));
-    msg->setInt32("finalResult", finalResult);
-    msg->post();
-}
-
-status_t NuPlayer2::Renderer::setPlaybackSettings(const AudioPlaybackRate &rate) {
-    sp<AMessage> msg = new AMessage(kWhatConfigPlayback, this);
-    writeToAMessage(msg, rate);
-    sp<AMessage> response;
-    status_t err = msg->postAndAwaitResponse(&response);
-    if (err == OK && response != NULL) {
-        CHECK(response->findInt32("err", &err));
-    }
-    return err;
-}
-
-status_t NuPlayer2::Renderer::onConfigPlayback(const AudioPlaybackRate &rate /* sanitized */) {
-    if (rate.mSpeed <= 0.f) {
-        ALOGW("playback rate cannot be %f", rate.mSpeed);
-        return BAD_VALUE;
-    }
-
-    if (mAudioSink != NULL && mAudioSink->ready()) {
-        status_t err = mAudioSink->setPlaybackRate(rate);
-        if (err != OK) {
-            ALOGW("failed to get playback rate from audio sink, err(%d)", err);
-            return err;
-        }
-    }
-    mPlaybackSettings = rate;
-    mMediaClock->setPlaybackRate(mPlaybackSettings.mSpeed);
-    return OK;
-}
-
-status_t NuPlayer2::Renderer::getPlaybackSettings(AudioPlaybackRate *rate /* nonnull */) {
-    sp<AMessage> msg = new AMessage(kWhatGetPlaybackSettings, this);
-    sp<AMessage> response;
-    status_t err = msg->postAndAwaitResponse(&response);
-    if (err == OK && response != NULL) {
-        CHECK(response->findInt32("err", &err));
-        if (err == OK) {
-            readFromAMessage(response, rate);
-        }
-    }
-    return err;
-}
-
-status_t NuPlayer2::Renderer::onGetPlaybackSettings(AudioPlaybackRate *rate /* nonnull */) {
-    if (mAudioSink != NULL && mAudioSink->ready()) {
-        status_t err = mAudioSink->getPlaybackRate(rate);
-        if (err == OK) {
-            if (!isAudioPlaybackRateEqual(*rate, mPlaybackSettings)) {
-                ALOGW("correcting mismatch in internal/external playback rate, %f vs %f",
-                      rate->mSpeed, mPlaybackSettings.mSpeed);
-            }
-            // get playback settings used by audiosink, as it may be
-            // slightly off due to audiosink not taking small changes.
-            mPlaybackSettings = *rate;
-        }
-        return err;
-    }
-    *rate = mPlaybackSettings;
-    return OK;
-}
-
-status_t NuPlayer2::Renderer::setSyncSettings(const AVSyncSettings &sync, float videoFpsHint) {
-    sp<AMessage> msg = new AMessage(kWhatConfigSync, this);
-    writeToAMessage(msg, sync, videoFpsHint);
-    sp<AMessage> response;
-    status_t err = msg->postAndAwaitResponse(&response);
-    if (err == OK && response != NULL) {
-        CHECK(response->findInt32("err", &err));
-    }
-    return err;
-}
-
-status_t NuPlayer2::Renderer::onConfigSync(const AVSyncSettings &sync, float videoFpsHint __unused) {
-    if (sync.mSource != AVSYNC_SOURCE_DEFAULT) {
-        return BAD_VALUE;
-    }
-    // TODO: support sync sources
-    return INVALID_OPERATION;
-}
-
-status_t NuPlayer2::Renderer::getSyncSettings(AVSyncSettings *sync, float *videoFps) {
-    sp<AMessage> msg = new AMessage(kWhatGetSyncSettings, this);
-    sp<AMessage> response;
-    status_t err = msg->postAndAwaitResponse(&response);
-    if (err == OK && response != NULL) {
-        CHECK(response->findInt32("err", &err));
-        if (err == OK) {
-            readFromAMessage(response, sync, videoFps);
-        }
-    }
-    return err;
-}
-
-status_t NuPlayer2::Renderer::onGetSyncSettings(
-        AVSyncSettings *sync /* nonnull */, float *videoFps /* nonnull */) {
-    *sync = mSyncSettings;
-    *videoFps = -1.f;
-    return OK;
-}
-
-void NuPlayer2::Renderer::flush(bool audio, bool notifyComplete) {
-    {
-        Mutex::Autolock autoLock(mLock);
-        if (audio) {
-            mNotifyCompleteAudio |= notifyComplete;
-            clearAudioFirstAnchorTime_l();
-            ++mAudioQueueGeneration;
-            ++mAudioDrainGeneration;
-        } else {
-            mNotifyCompleteVideo |= notifyComplete;
-            ++mVideoQueueGeneration;
-            ++mVideoDrainGeneration;
-            mNextVideoTimeMediaUs = -1;
-        }
-
-        mMediaClock->clearAnchor();
-        mVideoLateByUs = 0;
-        mSyncQueues = false;
-    }
-
-    sp<AMessage> msg = new AMessage(kWhatFlush, this);
-    msg->setInt32("audio", static_cast<int32_t>(audio));
-    msg->post();
-}
-
-void NuPlayer2::Renderer::signalTimeDiscontinuity() {
-}
-
-void NuPlayer2::Renderer::signalDisableOffloadAudio() {
-    (new AMessage(kWhatDisableOffloadAudio, this))->post();
-}
-
-void NuPlayer2::Renderer::signalEnableOffloadAudio() {
-    (new AMessage(kWhatEnableOffloadAudio, this))->post();
-}
-
-void NuPlayer2::Renderer::pause() {
-    (new AMessage(kWhatPause, this))->post();
-}
-
-void NuPlayer2::Renderer::resume() {
-    (new AMessage(kWhatResume, this))->post();
-}
-
-void NuPlayer2::Renderer::setVideoFrameRate(float fps) {
-    sp<AMessage> msg = new AMessage(kWhatSetVideoFrameRate, this);
-    msg->setFloat("frame-rate", fps);
-    msg->post();
-}
-
-// Called on any threads without mLock acquired.
-status_t NuPlayer2::Renderer::getCurrentPosition(int64_t *mediaUs) {
-    status_t result = mMediaClock->getMediaTime(ALooper::GetNowUs(), mediaUs);
-    if (result == OK) {
-        return result;
-    }
-
-    // MediaClock has not started yet. Try to start it if possible.
-    {
-        Mutex::Autolock autoLock(mLock);
-        if (mAudioFirstAnchorTimeMediaUs == -1) {
-            return result;
-        }
-
-        AudioTimestamp ts;
-        status_t res = mAudioSink->getTimestamp(ts);
-        if (res != OK) {
-            return result;
-        }
-
-        // AudioSink has rendered some frames.
-        int64_t nowUs = ALooper::GetNowUs();
-        int64_t nowMediaUs = mAudioSink->getPlayedOutDurationUs(nowUs)
-                + mAudioFirstAnchorTimeMediaUs;
-        mMediaClock->updateAnchor(nowMediaUs, nowUs, -1);
-    }
-
-    return mMediaClock->getMediaTime(ALooper::GetNowUs(), mediaUs);
-}
-
-void NuPlayer2::Renderer::clearAudioFirstAnchorTime_l() {
-    mAudioFirstAnchorTimeMediaUs = -1;
-    mMediaClock->setStartingTimeMedia(-1);
-}
-
-void NuPlayer2::Renderer::setAudioFirstAnchorTimeIfNeeded_l(int64_t mediaUs) {
-    if (mAudioFirstAnchorTimeMediaUs == -1) {
-        mAudioFirstAnchorTimeMediaUs = mediaUs;
-        mMediaClock->setStartingTimeMedia(mediaUs);
-    }
-}
-
-// Called on renderer looper.
-void NuPlayer2::Renderer::clearAnchorTime() {
-    mMediaClock->clearAnchor();
-    mAnchorTimeMediaUs = -1;
-    mAnchorNumFramesWritten = -1;
-}
-
-void NuPlayer2::Renderer::setVideoLateByUs(int64_t lateUs) {
-    Mutex::Autolock autoLock(mLock);
-    mVideoLateByUs = lateUs;
-}
-
-int64_t NuPlayer2::Renderer::getVideoLateByUs() {
-    Mutex::Autolock autoLock(mLock);
-    return mVideoLateByUs;
-}
-
-status_t NuPlayer2::Renderer::openAudioSink(
-        const sp<AMessage> &format,
-        bool offloadOnly,
-        bool hasVideo,
-        uint32_t flags,
-        bool *isOffloaded,
-        bool isStreaming) {
-    sp<AMessage> msg = new AMessage(kWhatOpenAudioSink, this);
-    msg->setMessage("format", format);
-    msg->setInt32("offload-only", offloadOnly);
-    msg->setInt32("has-video", hasVideo);
-    msg->setInt32("flags", flags);
-    msg->setInt32("isStreaming", isStreaming);
-
-    sp<AMessage> response;
-    status_t postStatus = msg->postAndAwaitResponse(&response);
-
-    int32_t err;
-    if (postStatus != OK || response.get() == nullptr || !response->findInt32("err", &err)) {
-        err = INVALID_OPERATION;
-    } else if (err == OK && isOffloaded != NULL) {
-        int32_t offload;
-        CHECK(response->findInt32("offload", &offload));
-        *isOffloaded = (offload != 0);
-    }
-    return err;
-}
-
-void NuPlayer2::Renderer::closeAudioSink() {
-    sp<AMessage> msg = new AMessage(kWhatCloseAudioSink, this);
-
-    sp<AMessage> response;
-    msg->postAndAwaitResponse(&response);
-}
-
-void NuPlayer2::Renderer::changeAudioFormat(
-        const sp<AMessage> &format,
-        bool offloadOnly,
-        bool hasVideo,
-        uint32_t flags,
-        bool isStreaming,
-        const sp<AMessage> &notify) {
-    sp<AMessage> meta = new AMessage;
-    meta->setMessage("format", format);
-    meta->setInt32("offload-only", offloadOnly);
-    meta->setInt32("has-video", hasVideo);
-    meta->setInt32("flags", flags);
-    meta->setInt32("isStreaming", isStreaming);
-
-    sp<AMessage> msg = new AMessage(kWhatChangeAudioFormat, this);
-    msg->setInt32("queueGeneration", getQueueGeneration(true /* audio */));
-    msg->setMessage("notify", notify);
-    msg->setMessage("meta", meta);
-    msg->post();
-}
-
-void NuPlayer2::Renderer::onMessageReceived(const sp<AMessage> &msg) {
-    switch (msg->what()) {
-        case kWhatOpenAudioSink:
-        {
-            sp<AMessage> format;
-            CHECK(msg->findMessage("format", &format));
-
-            int32_t offloadOnly;
-            CHECK(msg->findInt32("offload-only", &offloadOnly));
-
-            int32_t hasVideo;
-            CHECK(msg->findInt32("has-video", &hasVideo));
-
-            uint32_t flags;
-            CHECK(msg->findInt32("flags", (int32_t *)&flags));
-
-            uint32_t isStreaming;
-            CHECK(msg->findInt32("isStreaming", (int32_t *)&isStreaming));
-
-            status_t err = onOpenAudioSink(format, offloadOnly, hasVideo, flags, isStreaming);
-
-            sp<AMessage> response = new AMessage;
-            response->setInt32("err", err);
-            response->setInt32("offload", offloadingAudio());
-
-            sp<AReplyToken> replyID;
-            CHECK(msg->senderAwaitsResponse(&replyID));
-            response->postReply(replyID);
-
-            break;
-        }
-
-        case kWhatCloseAudioSink:
-        {
-            sp<AReplyToken> replyID;
-            CHECK(msg->senderAwaitsResponse(&replyID));
-
-            onCloseAudioSink();
-
-            sp<AMessage> response = new AMessage;
-            response->postReply(replyID);
-            break;
-        }
-
-        case kWhatStopAudioSink:
-        {
-            mAudioSink->stop();
-            break;
-        }
-
-        case kWhatChangeAudioFormat:
-        {
-            int32_t queueGeneration;
-            CHECK(msg->findInt32("queueGeneration", &queueGeneration));
-
-            sp<AMessage> notify;
-            CHECK(msg->findMessage("notify", &notify));
-
-            if (offloadingAudio()) {
-                ALOGW("changeAudioFormat should NOT be called in offload mode");
-                notify->setInt32("err", INVALID_OPERATION);
-                notify->post();
-                break;
-            }
-
-            sp<AMessage> meta;
-            CHECK(msg->findMessage("meta", &meta));
-
-            if (queueGeneration != getQueueGeneration(true /* audio */)
-                    || mAudioQueue.empty()) {
-                onChangeAudioFormat(meta, notify);
-                break;
-            }
-
-            QueueEntry entry;
-            entry.mNotifyConsumed = notify;
-            entry.mMeta = meta;
-
-            Mutex::Autolock autoLock(mLock);
-            mAudioQueue.push_back(entry);
-            postDrainAudioQueue_l();
-
-            break;
-        }
-
-        case kWhatDrainAudioQueue:
-        {
-            mDrainAudioQueuePending = false;
-
-            int32_t generation;
-            CHECK(msg->findInt32("drainGeneration", &generation));
-            if (generation != getDrainGeneration(true /* audio */)) {
-                break;
-            }
-
-            if (onDrainAudioQueue()) {
-                uint32_t numFramesPlayed;
-                CHECK_EQ(mAudioSink->getPosition(&numFramesPlayed),
-                         (status_t)OK);
-
-                // Handle AudioTrack race when start is immediately called after flush.
-                uint32_t numFramesPendingPlayout =
-                    (mNumFramesWritten > numFramesPlayed ?
-                        mNumFramesWritten - numFramesPlayed : 0);
-
-                // This is how long the audio sink will have data to
-                // play back.
-                int64_t delayUs =
-                    mAudioSink->msecsPerFrame()
-                        * numFramesPendingPlayout * 1000ll;
-                if (mPlaybackSettings.mSpeed > 1.0f) {
-                    delayUs /= mPlaybackSettings.mSpeed;
-                }
-
-                // Let's give it more data after about half that time
-                // has elapsed.
-                delayUs /= 2;
-                // check the buffer size to estimate maximum delay permitted.
-                const int64_t maxDrainDelayUs = std::max(
-                        mAudioSink->getBufferDurationInUs(), (int64_t)500000 /* half second */);
-                ALOGD_IF(delayUs > maxDrainDelayUs, "postDrainAudioQueue long delay: %lld > %lld",
-                        (long long)delayUs, (long long)maxDrainDelayUs);
-                Mutex::Autolock autoLock(mLock);
-                postDrainAudioQueue_l(delayUs);
-            }
-            break;
-        }
-
-        case kWhatDrainVideoQueue:
-        {
-            int32_t generation;
-            CHECK(msg->findInt32("drainGeneration", &generation));
-            if (generation != getDrainGeneration(false /* audio */)) {
-                break;
-            }
-
-            mDrainVideoQueuePending = false;
-
-            onDrainVideoQueue();
-
-            postDrainVideoQueue();
-            break;
-        }
-
-        case kWhatPostDrainVideoQueue:
-        {
-            int32_t generation;
-            CHECK(msg->findInt32("drainGeneration", &generation));
-            if (generation != getDrainGeneration(false /* audio */)) {
-                break;
-            }
-
-            mDrainVideoQueuePending = false;
-            postDrainVideoQueue();
-            break;
-        }
-
-        case kWhatQueueBuffer:
-        {
-            onQueueBuffer(msg);
-            break;
-        }
-
-        case kWhatQueueEOS:
-        {
-            onQueueEOS(msg);
-            break;
-        }
-
-        case kWhatEOS:
-        {
-            int32_t generation;
-            CHECK(msg->findInt32("audioEOSGeneration", &generation));
-            if (generation != mAudioEOSGeneration) {
-                break;
-            }
-            status_t finalResult;
-            CHECK(msg->findInt32("finalResult", &finalResult));
-            notifyEOS(true /* audio */, finalResult);
-            break;
-        }
-
-        case kWhatConfigPlayback:
-        {
-            sp<AReplyToken> replyID;
-            CHECK(msg->senderAwaitsResponse(&replyID));
-            AudioPlaybackRate rate;
-            readFromAMessage(msg, &rate);
-            status_t err = onConfigPlayback(rate);
-            sp<AMessage> response = new AMessage;
-            response->setInt32("err", err);
-            response->postReply(replyID);
-            break;
-        }
-
-        case kWhatGetPlaybackSettings:
-        {
-            sp<AReplyToken> replyID;
-            CHECK(msg->senderAwaitsResponse(&replyID));
-            AudioPlaybackRate rate = AUDIO_PLAYBACK_RATE_DEFAULT;
-            status_t err = onGetPlaybackSettings(&rate);
-            sp<AMessage> response = new AMessage;
-            if (err == OK) {
-                writeToAMessage(response, rate);
-            }
-            response->setInt32("err", err);
-            response->postReply(replyID);
-            break;
-        }
-
-        case kWhatConfigSync:
-        {
-            sp<AReplyToken> replyID;
-            CHECK(msg->senderAwaitsResponse(&replyID));
-            AVSyncSettings sync;
-            float videoFpsHint;
-            readFromAMessage(msg, &sync, &videoFpsHint);
-            status_t err = onConfigSync(sync, videoFpsHint);
-            sp<AMessage> response = new AMessage;
-            response->setInt32("err", err);
-            response->postReply(replyID);
-            break;
-        }
-
-        case kWhatGetSyncSettings:
-        {
-            sp<AReplyToken> replyID;
-            CHECK(msg->senderAwaitsResponse(&replyID));
-
-            ALOGV("kWhatGetSyncSettings");
-            AVSyncSettings sync;
-            float videoFps = -1.f;
-            status_t err = onGetSyncSettings(&sync, &videoFps);
-            sp<AMessage> response = new AMessage;
-            if (err == OK) {
-                writeToAMessage(response, sync, videoFps);
-            }
-            response->setInt32("err", err);
-            response->postReply(replyID);
-            break;
-        }
-
-        case kWhatFlush:
-        {
-            onFlush(msg);
-            break;
-        }
-
-        case kWhatDisableOffloadAudio:
-        {
-            onDisableOffloadAudio();
-            break;
-        }
-
-        case kWhatEnableOffloadAudio:
-        {
-            onEnableOffloadAudio();
-            break;
-        }
-
-        case kWhatPause:
-        {
-            onPause();
-            break;
-        }
-
-        case kWhatResume:
-        {
-            onResume();
-            break;
-        }
-
-        case kWhatSetVideoFrameRate:
-        {
-            float fps;
-            CHECK(msg->findFloat("frame-rate", &fps));
-            onSetVideoFrameRate(fps);
-            break;
-        }
-
-        case kWhatAudioTearDown:
-        {
-            int32_t reason;
-            CHECK(msg->findInt32("reason", &reason));
-
-            onAudioTearDown((AudioTearDownReason)reason);
-            break;
-        }
-
-        case kWhatAudioOffloadPauseTimeout:
-        {
-            int32_t generation;
-            CHECK(msg->findInt32("drainGeneration", &generation));
-            if (generation != mAudioOffloadPauseTimeoutGeneration) {
-                break;
-            }
-            ALOGV("Audio Offload tear down due to pause timeout.");
-            onAudioTearDown(kDueToTimeout);
-            mWakeLock->release();
-            break;
-        }
-
-        default:
-            TRESPASS();
-            break;
-    }
-}
-
-void NuPlayer2::Renderer::postDrainAudioQueue_l(int64_t delayUs) {
-    if (mDrainAudioQueuePending || mSyncQueues || mUseAudioCallback) {
-        return;
-    }
-
-    if (mAudioQueue.empty()) {
-        return;
-    }
-
-    // FIXME: if paused, wait until AudioTrack stop() is complete before delivering data.
-    if (mPaused) {
-        const int64_t diffUs = mPauseDrainAudioAllowedUs - ALooper::GetNowUs();
-        if (diffUs > delayUs) {
-            delayUs = diffUs;
-        }
-    }
-
-    mDrainAudioQueuePending = true;
-    sp<AMessage> msg = new AMessage(kWhatDrainAudioQueue, this);
-    msg->setInt32("drainGeneration", mAudioDrainGeneration);
-    msg->post(delayUs);
-}
-
-void NuPlayer2::Renderer::prepareForMediaRenderingStart_l() {
-    mAudioRenderingStartGeneration = mAudioDrainGeneration;
-    mVideoRenderingStartGeneration = mVideoDrainGeneration;
-    mRenderingDataDelivered = false;
-}
-
-void NuPlayer2::Renderer::notifyIfMediaRenderingStarted_l() {
-    if (mVideoRenderingStartGeneration == mVideoDrainGeneration &&
-        mAudioRenderingStartGeneration == mAudioDrainGeneration) {
-        mRenderingDataDelivered = true;
-        if (mPaused) {
-            return;
-        }
-        mVideoRenderingStartGeneration = -1;
-        mAudioRenderingStartGeneration = -1;
-
-        sp<AMessage> notify = mNotify->dup();
-        notify->setInt32("what", kWhatMediaRenderingStart);
-        notify->post();
-    }
-}
-
-// static
-size_t NuPlayer2::Renderer::AudioSinkCallback(
-        MediaPlayer2Interface::AudioSink * /* audioSink */,
-        void *buffer,
-        size_t size,
-        void *cookie,
-        MediaPlayer2Interface::AudioSink::cb_event_t event) {
-    NuPlayer2::Renderer *me = (NuPlayer2::Renderer *)cookie;
-
-    switch (event) {
-        case MediaPlayer2Interface::AudioSink::CB_EVENT_FILL_BUFFER:
-        {
-            return me->fillAudioBuffer(buffer, size);
-            break;
-        }
-
-        case MediaPlayer2Interface::AudioSink::CB_EVENT_STREAM_END:
-        {
-            ALOGV("AudioSink::CB_EVENT_STREAM_END");
-            me->notifyEOSCallback();
-            break;
-        }
-
-        case MediaPlayer2Interface::AudioSink::CB_EVENT_TEAR_DOWN:
-        {
-            ALOGV("AudioSink::CB_EVENT_TEAR_DOWN");
-            me->notifyAudioTearDown(kDueToError);
-            break;
-        }
-    }
-
-    return 0;
-}
-
-void NuPlayer2::Renderer::notifyEOSCallback() {
-    Mutex::Autolock autoLock(mLock);
-
-    if (!mUseAudioCallback) {
-        return;
-    }
-
-    notifyEOS_l(true /* audio */, ERROR_END_OF_STREAM);
-}
-
-size_t NuPlayer2::Renderer::fillAudioBuffer(void *buffer, size_t size) {
-    Mutex::Autolock autoLock(mLock);
-
-    if (!mUseAudioCallback) {
-        return 0;
-    }
-
-    bool hasEOS = false;
-
-    size_t sizeCopied = 0;
-    bool firstEntry = true;
-    QueueEntry *entry;  // will be valid after while loop if hasEOS is set.
-    while (sizeCopied < size && !mAudioQueue.empty()) {
-        entry = &*mAudioQueue.begin();
-
-        if (entry->mBuffer == NULL) { // EOS
-            hasEOS = true;
-            mAudioQueue.erase(mAudioQueue.begin());
-            break;
-        }
-
-        if (firstEntry && entry->mOffset == 0) {
-            firstEntry = false;
-            int64_t mediaTimeUs;
-            CHECK(entry->mBuffer->meta()->findInt64("timeUs", &mediaTimeUs));
-            ALOGV("fillAudioBuffer: rendering audio at media time %.2f secs", mediaTimeUs / 1E6);
-            setAudioFirstAnchorTimeIfNeeded_l(mediaTimeUs);
-        }
-
-        size_t copy = entry->mBuffer->size() - entry->mOffset;
-        size_t sizeRemaining = size - sizeCopied;
-        if (copy > sizeRemaining) {
-            copy = sizeRemaining;
-        }
-
-        memcpy((char *)buffer + sizeCopied,
-               entry->mBuffer->data() + entry->mOffset,
-               copy);
-
-        entry->mOffset += copy;
-        if (entry->mOffset == entry->mBuffer->size()) {
-            entry->mNotifyConsumed->post();
-            mAudioQueue.erase(mAudioQueue.begin());
-            entry = NULL;
-        }
-        sizeCopied += copy;
-
-        notifyIfMediaRenderingStarted_l();
-    }
-
-    if (mAudioFirstAnchorTimeMediaUs >= 0) {
-        int64_t nowUs = ALooper::GetNowUs();
-        int64_t nowMediaUs =
-            mAudioFirstAnchorTimeMediaUs + mAudioSink->getPlayedOutDurationUs(nowUs);
-        // we don't know how much data we are queueing for offloaded tracks.
-        mMediaClock->updateAnchor(nowMediaUs, nowUs, INT64_MAX);
-    }
-
-    // for non-offloaded audio, we need to compute the frames written because
-    // there is no EVENT_STREAM_END notification. The frames written gives
-    // an estimate on the pending played out duration.
-    if (!offloadingAudio()) {
-        mNumFramesWritten += sizeCopied / mAudioSink->frameSize();
-    }
-
-    if (hasEOS) {
-        (new AMessage(kWhatStopAudioSink, this))->post();
-        // As there is currently no EVENT_STREAM_END callback notification for
-        // non-offloaded audio tracks, we need to post the EOS ourselves.
-        if (!offloadingAudio()) {
-            int64_t postEOSDelayUs = 0;
-            if (mAudioSink->needsTrailingPadding()) {
-                postEOSDelayUs = getPendingAudioPlayoutDurationUs(ALooper::GetNowUs());
-            }
-            ALOGV("fillAudioBuffer: notifyEOS_l "
-                    "mNumFramesWritten:%u  finalResult:%d  postEOSDelay:%lld",
-                    mNumFramesWritten, entry->mFinalResult, (long long)postEOSDelayUs);
-            notifyEOS_l(true /* audio */, entry->mFinalResult, postEOSDelayUs);
-        }
-    }
-    return sizeCopied;
-}
-
-void NuPlayer2::Renderer::drainAudioQueueUntilLastEOS() {
-    List<QueueEntry>::iterator it = mAudioQueue.begin(), itEOS = it;
-    bool foundEOS = false;
-    while (it != mAudioQueue.end()) {
-        int32_t eos;
-        QueueEntry *entry = &*it++;
-        if ((entry->mBuffer == nullptr && entry->mNotifyConsumed == nullptr)
-                || (entry->mNotifyConsumed->findInt32("eos", &eos) && eos != 0)) {
-            itEOS = it;
-            foundEOS = true;
-        }
-    }
-
-    if (foundEOS) {
-        // post all replies before EOS and drop the samples
-        for (it = mAudioQueue.begin(); it != itEOS; it++) {
-            if (it->mBuffer == nullptr) {
-                if (it->mNotifyConsumed == nullptr) {
-                    // delay doesn't matter as we don't even have an AudioTrack
-                    notifyEOS(true /* audio */, it->mFinalResult);
-                } else {
-                    // TAG for re-opening audio sink.
-                    onChangeAudioFormat(it->mMeta, it->mNotifyConsumed);
-                }
-            } else {
-                it->mNotifyConsumed->post();
-            }
-        }
-        mAudioQueue.erase(mAudioQueue.begin(), itEOS);
-    }
-}
-
-bool NuPlayer2::Renderer::onDrainAudioQueue() {
-    // do not drain audio during teardown as queued buffers may be invalid.
-    if (mAudioTornDown) {
-        return false;
-    }
-    // TODO: This call to getPosition checks if AudioTrack has been created
-    // in AudioSink before draining audio. If AudioTrack doesn't exist, then
-    // CHECKs on getPosition will fail.
-    // We still need to figure out why AudioTrack is not created when
-    // this function is called. One possible reason could be leftover
-    // audio. Another possible place is to check whether decoder
-    // has received INFO_FORMAT_CHANGED as the first buffer since
-    // AudioSink is opened there, and possible interactions with flush
-    // immediately after start. Investigate error message
-    // "vorbis_dsp_synthesis returned -135", along with RTSP.
-    uint32_t numFramesPlayed;
-    if (mAudioSink->getPosition(&numFramesPlayed) != OK) {
-        // When getPosition fails, renderer will not reschedule the draining
-        // unless new samples are queued.
-        // If we have pending EOS (or "eos" marker for discontinuities), we need
-        // to post these now as NuPlayer2Decoder might be waiting for it.
-        drainAudioQueueUntilLastEOS();
-
-        ALOGW("onDrainAudioQueue(): audio sink is not ready");
-        return false;
-    }
-
-#if 0
-    ssize_t numFramesAvailableToWrite =
-        mAudioSink->frameCount() - (mNumFramesWritten - numFramesPlayed);
-
-    if (numFramesAvailableToWrite == mAudioSink->frameCount()) {
-        ALOGI("audio sink underrun");
-    } else {
-        ALOGV("audio queue has %d frames left to play",
-             mAudioSink->frameCount() - numFramesAvailableToWrite);
-    }
-#endif
-
-    uint32_t prevFramesWritten = mNumFramesWritten;
-    while (!mAudioQueue.empty()) {
-        QueueEntry *entry = &*mAudioQueue.begin();
-
-        if (entry->mBuffer == NULL) {
-            if (entry->mNotifyConsumed != nullptr) {
-                // TAG for re-open audio sink.
-                onChangeAudioFormat(entry->mMeta, entry->mNotifyConsumed);
-                mAudioQueue.erase(mAudioQueue.begin());
-                continue;
-            }
-
-            // EOS
-            if (mPaused) {
-                // Do not notify EOS when paused.
-                // This is needed to avoid switch to next clip while in pause.
-                ALOGV("onDrainAudioQueue(): Do not notify EOS when paused");
-                return false;
-            }
-
-            int64_t postEOSDelayUs = 0;
-            if (mAudioSink->needsTrailingPadding()) {
-                postEOSDelayUs = getPendingAudioPlayoutDurationUs(ALooper::GetNowUs());
-            }
-            notifyEOS(true /* audio */, entry->mFinalResult, postEOSDelayUs);
-            mLastAudioMediaTimeUs = getDurationUsIfPlayedAtSampleRate(mNumFramesWritten);
-
-            mAudioQueue.erase(mAudioQueue.begin());
-            entry = NULL;
-            if (mAudioSink->needsTrailingPadding()) {
-                // If we're not in gapless playback (i.e. through setNextPlayer), we
-                // need to stop the track here, because that will play out the last
-                // little bit at the end of the file. Otherwise short files won't play.
-                mAudioSink->stop();
-                mNumFramesWritten = 0;
-            }
-            return false;
-        }
-
-        mLastAudioBufferDrained = entry->mBufferOrdinal;
-
-        // ignore 0-sized buffer which could be EOS marker with no data
-        if (entry->mOffset == 0 && entry->mBuffer->size() > 0) {
-            int64_t mediaTimeUs;
-            CHECK(entry->mBuffer->meta()->findInt64("timeUs", &mediaTimeUs));
-            ALOGV("onDrainAudioQueue: rendering audio at media time %.2f secs",
-                    mediaTimeUs / 1E6);
-            onNewAudioMediaTime(mediaTimeUs);
-        }
-
-        size_t copy = entry->mBuffer->size() - entry->mOffset;
-
-        ssize_t written = mAudioSink->write(entry->mBuffer->data() + entry->mOffset,
-                                            copy, false /* blocking */);
-        if (written < 0) {
-            // An error in AudioSink write. Perhaps the AudioSink was not properly opened.
-            if (written == WOULD_BLOCK) {
-                ALOGV("AudioSink write would block when writing %zu bytes", copy);
-            } else {
-                ALOGE("AudioSink write error(%zd) when writing %zu bytes", written, copy);
-                // This can only happen when AudioSink was opened with doNotReconnect flag set to
-                // true, in which case the NuPlayer2 will handle the reconnect.
-                notifyAudioTearDown(kDueToError);
-            }
-            break;
-        }
-
-        entry->mOffset += written;
-        size_t remainder = entry->mBuffer->size() - entry->mOffset;
-        if ((ssize_t)remainder < mAudioSink->frameSize()) {
-            if (remainder > 0) {
-                ALOGW("Corrupted audio buffer has fractional frames, discarding %zu bytes.",
-                        remainder);
-                entry->mOffset += remainder;
-                copy -= remainder;
-            }
-
-            entry->mNotifyConsumed->post();
-            mAudioQueue.erase(mAudioQueue.begin());
-
-            entry = NULL;
-        }
-
-        size_t copiedFrames = written / mAudioSink->frameSize();
-        mNumFramesWritten += copiedFrames;
-
-        {
-            Mutex::Autolock autoLock(mLock);
-            int64_t maxTimeMedia;
-            maxTimeMedia =
-                mAnchorTimeMediaUs +
-                        (int64_t)(max((long long)mNumFramesWritten - mAnchorNumFramesWritten, 0LL)
-                                * 1000LL * mAudioSink->msecsPerFrame());
-            mMediaClock->updateMaxTimeMedia(maxTimeMedia);
-
-            notifyIfMediaRenderingStarted_l();
-        }
-
-        if (written != (ssize_t)copy) {
-            // A short count was received from AudioSink::write()
-            //
-            // AudioSink write is called in non-blocking mode.
-            // It may return with a short count when:
-            //
-            // 1) Size to be copied is not a multiple of the frame size. Fractional frames are
-            //    discarded.
-            // 2) The data to be copied exceeds the available buffer in AudioSink.
-            // 3) An error occurs and data has been partially copied to the buffer in AudioSink.
-            // 4) AudioSink is an AudioCache for data retrieval, and the AudioCache is exceeded.
-
-            // (Case 1)
-            // Must be a multiple of the frame size.  If it is not a multiple of a frame size, it
-            // needs to fail, as we should not carry over fractional frames between calls.
-            CHECK_EQ(copy % mAudioSink->frameSize(), 0u);
-
-            // (Case 2, 3, 4)
-            // Return early to the caller.
-            // Beware of calling immediately again as this may busy-loop if you are not careful.
-            ALOGV("AudioSink write short frame count %zd < %zu", written, copy);
-            break;
-        }
-    }
-
-    // calculate whether we need to reschedule another write.
-    bool reschedule = !mAudioQueue.empty()
-            && (!mPaused
-                || prevFramesWritten != mNumFramesWritten); // permit pause to fill buffers
-    //ALOGD("reschedule:%d  empty:%d  mPaused:%d  prevFramesWritten:%u  mNumFramesWritten:%u",
-    //        reschedule, mAudioQueue.empty(), mPaused, prevFramesWritten, mNumFramesWritten);
-    return reschedule;
-}
-
-int64_t NuPlayer2::Renderer::getDurationUsIfPlayedAtSampleRate(uint32_t numFrames) {
-    int32_t sampleRate = offloadingAudio() ?
-            mCurrentOffloadInfo.sample_rate : mCurrentPcmInfo.mSampleRate;
-    if (sampleRate == 0) {
-        ALOGE("sampleRate is 0 in %s mode", offloadingAudio() ? "offload" : "non-offload");
-        return 0;
-    }
-    return (int64_t)(numFrames * 1000000LL / sampleRate);
-}
-
-// Calculate duration of pending samples if played at normal rate (i.e., 1.0).
-int64_t NuPlayer2::Renderer::getPendingAudioPlayoutDurationUs(int64_t nowUs) {
-    int64_t writtenAudioDurationUs = getDurationUsIfPlayedAtSampleRate(mNumFramesWritten);
-    if (mUseVirtualAudioSink) {
-        int64_t nowUs = ALooper::GetNowUs();
-        int64_t mediaUs;
-        if (mMediaClock->getMediaTime(nowUs, &mediaUs) != OK) {
-            return 0LL;
-        } else {
-            return writtenAudioDurationUs - (mediaUs - mAudioFirstAnchorTimeMediaUs);
-        }
-    }
-
-    const int64_t audioSinkPlayedUs = mAudioSink->getPlayedOutDurationUs(nowUs);
-    int64_t pendingUs = writtenAudioDurationUs - audioSinkPlayedUs;
-    if (pendingUs < 0) {
-        // This shouldn't happen unless the timestamp is stale.
-        ALOGW("%s: pendingUs %lld < 0, clamping to zero, potential resume after pause "
-                "writtenAudioDurationUs: %lld, audioSinkPlayedUs: %lld",
-                __func__, (long long)pendingUs,
-                (long long)writtenAudioDurationUs, (long long)audioSinkPlayedUs);
-        pendingUs = 0;
-    }
-    return pendingUs;
-}
-
-int64_t NuPlayer2::Renderer::getRealTimeUs(int64_t mediaTimeUs, int64_t nowUs) {
-    int64_t realUs;
-    if (mMediaClock->getRealTimeFor(mediaTimeUs, &realUs) != OK) {
-        // If failed to get current position, e.g. due to audio clock is
-        // not ready, then just play out video immediately without delay.
-        return nowUs;
-    }
-    return realUs;
-}
-
-void NuPlayer2::Renderer::onNewAudioMediaTime(int64_t mediaTimeUs) {
-    Mutex::Autolock autoLock(mLock);
-    // TRICKY: vorbis decoder generates multiple frames with the same
-    // timestamp, so only update on the first frame with a given timestamp
-    if (mediaTimeUs == mAnchorTimeMediaUs) {
-        return;
-    }
-    setAudioFirstAnchorTimeIfNeeded_l(mediaTimeUs);
-
-    // mNextAudioClockUpdateTimeUs is -1 if we're waiting for audio sink to start
-    if (mNextAudioClockUpdateTimeUs == -1) {
-        AudioTimestamp ts;
-        if (mAudioSink->getTimestamp(ts) == OK && ts.mPosition > 0) {
-            mNextAudioClockUpdateTimeUs = 0; // start our clock updates
-        }
-    }
-    int64_t nowUs = ALooper::GetNowUs();
-    if (mNextAudioClockUpdateTimeUs >= 0) {
-        if (nowUs >= mNextAudioClockUpdateTimeUs) {
-            int64_t nowMediaUs = mediaTimeUs - getPendingAudioPlayoutDurationUs(nowUs);
-            mMediaClock->updateAnchor(nowMediaUs, nowUs, mediaTimeUs);
-            mUseVirtualAudioSink = false;
-            mNextAudioClockUpdateTimeUs = nowUs + kMinimumAudioClockUpdatePeriodUs;
-        }
-    } else {
-        int64_t unused;
-        if ((mMediaClock->getMediaTime(nowUs, &unused) != OK)
-                && (getDurationUsIfPlayedAtSampleRate(mNumFramesWritten)
-                        > kMaxAllowedAudioSinkDelayUs)) {
-            // Enough data has been sent to AudioSink, but AudioSink has not rendered
-            // any data yet. Something is wrong with AudioSink, e.g., the device is not
-            // connected to audio out.
-            // Switch to system clock. This essentially creates a virtual AudioSink with
-            // initial latenty of getDurationUsIfPlayedAtSampleRate(mNumFramesWritten).
-            // This virtual AudioSink renders audio data starting from the very first sample
-            // and it's paced by system clock.
-            ALOGW("AudioSink stuck. ARE YOU CONNECTED TO AUDIO OUT? Switching to system clock.");
-            mMediaClock->updateAnchor(mAudioFirstAnchorTimeMediaUs, nowUs, mediaTimeUs);
-            mUseVirtualAudioSink = true;
-        }
-    }
-    mAnchorNumFramesWritten = mNumFramesWritten;
-    mAnchorTimeMediaUs = mediaTimeUs;
-}
-
-// Called without mLock acquired.
-void NuPlayer2::Renderer::postDrainVideoQueue() {
-    if (mDrainVideoQueuePending
-            || getSyncQueues()
-            || (mPaused && mVideoSampleReceived)) {
-        return;
-    }
-
-    if (mVideoQueue.empty()) {
-        return;
-    }
-
-    QueueEntry &entry = *mVideoQueue.begin();
-
-    sp<AMessage> msg = new AMessage(kWhatDrainVideoQueue, this);
-    msg->setInt32("drainGeneration", getDrainGeneration(false /* audio */));
-
-    if (entry.mBuffer == NULL) {
-        // EOS doesn't carry a timestamp.
-        msg->post();
-        mDrainVideoQueuePending = true;
-        return;
-    }
-
-    int64_t nowUs = ALooper::GetNowUs();
-    if (mFlags & FLAG_REAL_TIME) {
-        int64_t realTimeUs;
-        CHECK(entry.mBuffer->meta()->findInt64("timeUs", &realTimeUs));
-
-        realTimeUs = mVideoScheduler->schedule(realTimeUs * 1000) / 1000;
-
-        int64_t twoVsyncsUs = 2 * (mVideoScheduler->getVsyncPeriod() / 1000);
-
-        int64_t delayUs = realTimeUs - nowUs;
-
-        ALOGW_IF(delayUs > 500000, "unusually high delayUs: %lld", (long long)delayUs);
-        // post 2 display refreshes before rendering is due
-        msg->post(delayUs > twoVsyncsUs ? delayUs - twoVsyncsUs : 0);
-
-        mDrainVideoQueuePending = true;
-        return;
-    }
-
-    int64_t mediaTimeUs;
-    CHECK(entry.mBuffer->meta()->findInt64("timeUs", &mediaTimeUs));
-
-    {
-        Mutex::Autolock autoLock(mLock);
-        if (mAnchorTimeMediaUs < 0) {
-            mMediaClock->updateAnchor(mediaTimeUs, nowUs, mediaTimeUs);
-            mAnchorTimeMediaUs = mediaTimeUs;
-        }
-    }
-    mNextVideoTimeMediaUs = mediaTimeUs;
-    if (!mHasAudio) {
-        // smooth out videos >= 10fps
-        mMediaClock->updateMaxTimeMedia(mediaTimeUs + kDefaultVideoFrameIntervalUs);
-    }
-
-    if (!mVideoSampleReceived || mediaTimeUs < mAudioFirstAnchorTimeMediaUs) {
-        msg->post();
-    } else {
-        int64_t twoVsyncsUs = 2 * (mVideoScheduler->getVsyncPeriod() / 1000);
-
-        // post 2 display refreshes before rendering is due
-        mMediaClock->addTimer(msg, mediaTimeUs, -twoVsyncsUs);
-    }
-
-    mDrainVideoQueuePending = true;
-}
-
-void NuPlayer2::Renderer::onDrainVideoQueue() {
-    if (mVideoQueue.empty()) {
-        return;
-    }
-
-    QueueEntry *entry = &*mVideoQueue.begin();
-
-    if (entry->mBuffer == NULL) {
-        // EOS
-
-        notifyEOS(false /* audio */, entry->mFinalResult);
-
-        mVideoQueue.erase(mVideoQueue.begin());
-        entry = NULL;
-
-        setVideoLateByUs(0);
-        return;
-    }
-
-    int64_t nowUs = ALooper::GetNowUs();
-    int64_t realTimeUs;
-    int64_t mediaTimeUs = -1;
-    if (mFlags & FLAG_REAL_TIME) {
-        CHECK(entry->mBuffer->meta()->findInt64("timeUs", &realTimeUs));
-    } else {
-        CHECK(entry->mBuffer->meta()->findInt64("timeUs", &mediaTimeUs));
-
-        realTimeUs = getRealTimeUs(mediaTimeUs, nowUs);
-    }
-    realTimeUs = mVideoScheduler->schedule(realTimeUs * 1000) / 1000;
-
-    bool tooLate = false;
-
-    if (!mPaused) {
-        setVideoLateByUs(nowUs - realTimeUs);
-        tooLate = (mVideoLateByUs > 40000);
-
-        if (tooLate) {
-            ALOGV("video late by %lld us (%.2f secs)",
-                 (long long)mVideoLateByUs, mVideoLateByUs / 1E6);
-        } else {
-            int64_t mediaUs = 0;
-            mMediaClock->getMediaTime(realTimeUs, &mediaUs);
-            ALOGV("rendering video at media time %.2f secs",
-                    (mFlags & FLAG_REAL_TIME ? realTimeUs :
-                    mediaUs) / 1E6);
-
-            if (!(mFlags & FLAG_REAL_TIME)
-                    && mLastAudioMediaTimeUs != -1
-                    && mediaTimeUs > mLastAudioMediaTimeUs) {
-                // If audio ends before video, video continues to drive media clock.
-                // Also smooth out videos >= 10fps.
-                mMediaClock->updateMaxTimeMedia(mediaTimeUs + kDefaultVideoFrameIntervalUs);
-            }
-        }
-    } else {
-        setVideoLateByUs(0);
-        if (!mVideoSampleReceived && !mHasAudio) {
-            // This will ensure that the first frame after a flush won't be used as anchor
-            // when renderer is in paused state, because resume can happen any time after seek.
-            clearAnchorTime();
-        }
-    }
-
-    // Always render the first video frame while keeping stats on A/V sync.
-    if (!mVideoSampleReceived) {
-        realTimeUs = nowUs;
-        tooLate = false;
-    }
-
-    entry->mNotifyConsumed->setInt64("timestampNs", realTimeUs * 1000LL);
-    entry->mNotifyConsumed->setInt32("render", !tooLate);
-    entry->mNotifyConsumed->post();
-    mVideoQueue.erase(mVideoQueue.begin());
-    entry = NULL;
-
-    mVideoSampleReceived = true;
-
-    if (!mPaused) {
-        if (!mVideoRenderingStarted) {
-            mVideoRenderingStarted = true;
-            notifyVideoRenderingStart();
-        }
-        Mutex::Autolock autoLock(mLock);
-        notifyIfMediaRenderingStarted_l();
-    }
-}
-
-void NuPlayer2::Renderer::notifyVideoRenderingStart() {
-    sp<AMessage> notify = mNotify->dup();
-    notify->setInt32("what", kWhatVideoRenderingStart);
-    notify->post();
-}
-
-void NuPlayer2::Renderer::notifyEOS(bool audio, status_t finalResult, int64_t delayUs) {
-    Mutex::Autolock autoLock(mLock);
-    notifyEOS_l(audio, finalResult, delayUs);
-}
-
-void NuPlayer2::Renderer::notifyEOS_l(bool audio, status_t finalResult, int64_t delayUs) {
-    if (audio && delayUs > 0) {
-        sp<AMessage> msg = new AMessage(kWhatEOS, this);
-        msg->setInt32("audioEOSGeneration", mAudioEOSGeneration);
-        msg->setInt32("finalResult", finalResult);
-        msg->post(delayUs);
-        return;
-    }
-    sp<AMessage> notify = mNotify->dup();
-    notify->setInt32("what", kWhatEOS);
-    notify->setInt32("audio", static_cast<int32_t>(audio));
-    notify->setInt32("finalResult", finalResult);
-    notify->post(delayUs);
-
-    if (audio) {
-        // Video might outlive audio. Clear anchor to enable video only case.
-        mAnchorTimeMediaUs = -1;
-        mHasAudio = false;
-        if (mNextVideoTimeMediaUs >= 0) {
-            int64_t mediaUs = 0;
-            int64_t nowUs = ALooper::GetNowUs();
-            status_t result = mMediaClock->getMediaTime(nowUs, &mediaUs);
-            if (result == OK) {
-                if (mNextVideoTimeMediaUs > mediaUs) {
-                    mMediaClock->updateMaxTimeMedia(mNextVideoTimeMediaUs);
-                }
-            } else {
-                mMediaClock->updateAnchor(
-                        mNextVideoTimeMediaUs, nowUs,
-                        mNextVideoTimeMediaUs + kDefaultVideoFrameIntervalUs);
-            }
-        }
-    }
-}
-
-void NuPlayer2::Renderer::notifyAudioTearDown(AudioTearDownReason reason) {
-    sp<AMessage> msg = new AMessage(kWhatAudioTearDown, this);
-    msg->setInt32("reason", reason);
-    msg->post();
-}
-
-void NuPlayer2::Renderer::onQueueBuffer(const sp<AMessage> &msg) {
-    int32_t audio;
-    CHECK(msg->findInt32("audio", &audio));
-
-    if (dropBufferIfStale(audio, msg)) {
-        return;
-    }
-
-    if (audio) {
-        mHasAudio = true;
-    } else {
-        mHasVideo = true;
-    }
-
-    if (mHasVideo) {
-        if (mVideoScheduler == NULL) {
-            mVideoScheduler = new VideoFrameScheduler2();
-            mVideoScheduler->init();
-        }
-    }
-
-    sp<RefBase> obj;
-    CHECK(msg->findObject("buffer", &obj));
-    sp<MediaCodecBuffer> buffer = static_cast<MediaCodecBuffer *>(obj.get());
-
-    sp<AMessage> notifyConsumed;
-    CHECK(msg->findMessage("notifyConsumed", &notifyConsumed));
-
-    QueueEntry entry;
-    entry.mBuffer = buffer;
-    entry.mNotifyConsumed = notifyConsumed;
-    entry.mOffset = 0;
-    entry.mFinalResult = OK;
-    entry.mBufferOrdinal = ++mTotalBuffersQueued;
-
-    if (audio) {
-        Mutex::Autolock autoLock(mLock);
-        mAudioQueue.push_back(entry);
-        postDrainAudioQueue_l();
-    } else {
-        mVideoQueue.push_back(entry);
-        postDrainVideoQueue();
-    }
-
-    Mutex::Autolock autoLock(mLock);
-    if (!mSyncQueues || mAudioQueue.empty() || mVideoQueue.empty()) {
-        return;
-    }
-
-    sp<MediaCodecBuffer> firstAudioBuffer = (*mAudioQueue.begin()).mBuffer;
-    sp<MediaCodecBuffer> firstVideoBuffer = (*mVideoQueue.begin()).mBuffer;
-
-    if (firstAudioBuffer == NULL || firstVideoBuffer == NULL) {
-        // EOS signalled on either queue.
-        syncQueuesDone_l();
-        return;
-    }
-
-    int64_t firstAudioTimeUs;
-    int64_t firstVideoTimeUs;
-    CHECK(firstAudioBuffer->meta()
-            ->findInt64("timeUs", &firstAudioTimeUs));
-    CHECK(firstVideoBuffer->meta()
-            ->findInt64("timeUs", &firstVideoTimeUs));
-
-    int64_t diff = firstVideoTimeUs - firstAudioTimeUs;
-
-    ALOGV("queueDiff = %.2f secs", diff / 1E6);
-
-    if (diff > 100000LL) {
-        // Audio data starts More than 0.1 secs before video.
-        // Drop some audio.
-
-        (*mAudioQueue.begin()).mNotifyConsumed->post();
-        mAudioQueue.erase(mAudioQueue.begin());
-        return;
-    }
-
-    syncQueuesDone_l();
-}
-
-void NuPlayer2::Renderer::syncQueuesDone_l() {
-    if (!mSyncQueues) {
-        return;
-    }
-
-    mSyncQueues = false;
-
-    if (!mAudioQueue.empty()) {
-        postDrainAudioQueue_l();
-    }
-
-    if (!mVideoQueue.empty()) {
-        mLock.unlock();
-        postDrainVideoQueue();
-        mLock.lock();
-    }
-}
-
-void NuPlayer2::Renderer::onQueueEOS(const sp<AMessage> &msg) {
-    int32_t audio;
-    CHECK(msg->findInt32("audio", &audio));
-
-    if (dropBufferIfStale(audio, msg)) {
-        return;
-    }
-
-    int32_t finalResult;
-    CHECK(msg->findInt32("finalResult", &finalResult));
-
-    QueueEntry entry;
-    entry.mOffset = 0;
-    entry.mFinalResult = finalResult;
-
-    if (audio) {
-        Mutex::Autolock autoLock(mLock);
-        if (mAudioQueue.empty() && mSyncQueues) {
-            syncQueuesDone_l();
-        }
-        mAudioQueue.push_back(entry);
-        postDrainAudioQueue_l();
-    } else {
-        if (mVideoQueue.empty() && getSyncQueues()) {
-            Mutex::Autolock autoLock(mLock);
-            syncQueuesDone_l();
-        }
-        mVideoQueue.push_back(entry);
-        postDrainVideoQueue();
-    }
-}
-
-void NuPlayer2::Renderer::onFlush(const sp<AMessage> &msg) {
-    int32_t audio, notifyComplete;
-    CHECK(msg->findInt32("audio", &audio));
-
-    {
-        Mutex::Autolock autoLock(mLock);
-        if (audio) {
-            notifyComplete = mNotifyCompleteAudio;
-            mNotifyCompleteAudio = false;
-            mLastAudioMediaTimeUs = -1;
-
-            mHasAudio = false;
-            if (mNextVideoTimeMediaUs >= 0) {
-                int64_t nowUs = ALooper::GetNowUs();
-                mMediaClock->updateAnchor(
-                        mNextVideoTimeMediaUs, nowUs,
-                        mNextVideoTimeMediaUs + kDefaultVideoFrameIntervalUs);
-            }
-        } else {
-            notifyComplete = mNotifyCompleteVideo;
-            mNotifyCompleteVideo = false;
-            mVideoRenderingStarted = false;
-        }
-
-        // If we're currently syncing the queues, i.e. dropping audio while
-        // aligning the first audio/video buffer times and only one of the
-        // two queues has data, we may starve that queue by not requesting
-        // more buffers from the decoder. If the other source then encounters
-        // a discontinuity that leads to flushing, we'll never find the
-        // corresponding discontinuity on the other queue.
-        // Therefore we'll stop syncing the queues if at least one of them
-        // is flushed.
-        syncQueuesDone_l();
-    }
-    clearAnchorTime();
-
-    ALOGV("flushing %s", audio ? "audio" : "video");
-    if (audio) {
-        {
-            Mutex::Autolock autoLock(mLock);
-            flushQueue(&mAudioQueue);
-
-            ++mAudioDrainGeneration;
-            ++mAudioEOSGeneration;
-            prepareForMediaRenderingStart_l();
-
-            // the frame count will be reset after flush.
-            clearAudioFirstAnchorTime_l();
-        }
-
-        mDrainAudioQueuePending = false;
-
-        if (offloadingAudio()) {
-            mAudioSink->pause();
-            mAudioSink->flush();
-            if (!mPaused) {
-                mAudioSink->start();
-            }
-        } else {
-            mAudioSink->pause();
-            mAudioSink->flush();
-            // Call stop() to signal to the AudioSink to completely fill the
-            // internal buffer before resuming playback.
-            // FIXME: this is ignored after flush().
-            mAudioSink->stop();
-            if (mPaused) {
-                // Race condition: if renderer is paused and audio sink is stopped,
-                // we need to make sure that the audio track buffer fully drains
-                // before delivering data.
-                // FIXME: remove this if we can detect if stop() is complete.
-                const int delayUs = 2 * 50 * 1000; // (2 full mixer thread cycles at 50ms)
-                mPauseDrainAudioAllowedUs = ALooper::GetNowUs() + delayUs;
-            } else {
-                mAudioSink->start();
-            }
-            mNumFramesWritten = 0;
-        }
-        mNextAudioClockUpdateTimeUs = -1;
-    } else {
-        flushQueue(&mVideoQueue);
-
-        mDrainVideoQueuePending = false;
-
-        if (mVideoScheduler != NULL) {
-            mVideoScheduler->restart();
-        }
-
-        Mutex::Autolock autoLock(mLock);
-        ++mVideoDrainGeneration;
-        prepareForMediaRenderingStart_l();
-    }
-
-    mVideoSampleReceived = false;
-
-    if (notifyComplete) {
-        notifyFlushComplete(audio);
-    }
-}
-
-void NuPlayer2::Renderer::flushQueue(List<QueueEntry> *queue) {
-    while (!queue->empty()) {
-        QueueEntry *entry = &*queue->begin();
-
-        if (entry->mBuffer != NULL) {
-            entry->mNotifyConsumed->post();
-        } else if (entry->mNotifyConsumed != nullptr) {
-            // Is it needed to open audio sink now?
-            onChangeAudioFormat(entry->mMeta, entry->mNotifyConsumed);
-        }
-
-        queue->erase(queue->begin());
-        entry = NULL;
-    }
-}
-
-void NuPlayer2::Renderer::notifyFlushComplete(bool audio) {
-    sp<AMessage> notify = mNotify->dup();
-    notify->setInt32("what", kWhatFlushComplete);
-    notify->setInt32("audio", static_cast<int32_t>(audio));
-    notify->post();
-}
-
-bool NuPlayer2::Renderer::dropBufferIfStale(
-        bool audio, const sp<AMessage> &msg) {
-    int32_t queueGeneration;
-    CHECK(msg->findInt32("queueGeneration", &queueGeneration));
-
-    if (queueGeneration == getQueueGeneration(audio)) {
-        return false;
-    }
-
-    sp<AMessage> notifyConsumed;
-    if (msg->findMessage("notifyConsumed", &notifyConsumed)) {
-        notifyConsumed->post();
-    }
-
-    return true;
-}
-
-void NuPlayer2::Renderer::onAudioSinkChanged() {
-    if (offloadingAudio()) {
-        return;
-    }
-    CHECK(!mDrainAudioQueuePending);
-    mNumFramesWritten = 0;
-    mAnchorNumFramesWritten = -1;
-    uint32_t written;
-    if (mAudioSink->getFramesWritten(&written) == OK) {
-        mNumFramesWritten = written;
-    }
-}
-
-void NuPlayer2::Renderer::onDisableOffloadAudio() {
-    Mutex::Autolock autoLock(mLock);
-    mFlags &= ~FLAG_OFFLOAD_AUDIO;
-    ++mAudioDrainGeneration;
-    if (mAudioRenderingStartGeneration != -1) {
-        prepareForMediaRenderingStart_l();
-    }
-}
-
-void NuPlayer2::Renderer::onEnableOffloadAudio() {
-    Mutex::Autolock autoLock(mLock);
-    mFlags |= FLAG_OFFLOAD_AUDIO;
-    ++mAudioDrainGeneration;
-    if (mAudioRenderingStartGeneration != -1) {
-        prepareForMediaRenderingStart_l();
-    }
-}
-
-void NuPlayer2::Renderer::onPause() {
-    if (mPaused) {
-        return;
-    }
-
-    {
-        Mutex::Autolock autoLock(mLock);
-        // we do not increment audio drain generation so that we fill audio buffer during pause.
-        ++mVideoDrainGeneration;
-        prepareForMediaRenderingStart_l();
-        mPaused = true;
-        mMediaClock->setPlaybackRate(0.0);
-    }
-
-    mDrainAudioQueuePending = false;
-    mDrainVideoQueuePending = false;
-
-    // Note: audio data may not have been decoded, and the AudioSink may not be opened.
-    mAudioSink->pause();
-    startAudioOffloadPauseTimeout();
-
-    ALOGV("now paused audio queue has %zu entries, video has %zu entries",
-          mAudioQueue.size(), mVideoQueue.size());
-}
-
-void NuPlayer2::Renderer::onResume() {
-    if (!mPaused) {
-        return;
-    }
-
-    // Note: audio data may not have been decoded, and the AudioSink may not be opened.
-    cancelAudioOffloadPauseTimeout();
-    if (mAudioSink->ready()) {
-        status_t err = mAudioSink->start();
-        if (err != OK) {
-            ALOGE("cannot start AudioSink err %d", err);
-            notifyAudioTearDown(kDueToError);
-        }
-    }
-
-    {
-        Mutex::Autolock autoLock(mLock);
-        mPaused = false;
-        // rendering started message may have been delayed if we were paused.
-        if (mRenderingDataDelivered) {
-            notifyIfMediaRenderingStarted_l();
-        }
-        // configure audiosink as we did not do it when pausing
-        if (mAudioSink != NULL && mAudioSink->ready()) {
-            mAudioSink->setPlaybackRate(mPlaybackSettings);
-        }
-
-        mMediaClock->setPlaybackRate(mPlaybackSettings.mSpeed);
-
-        if (!mAudioQueue.empty()) {
-            postDrainAudioQueue_l();
-        }
-    }
-
-    if (!mVideoQueue.empty()) {
-        postDrainVideoQueue();
-    }
-}
-
-void NuPlayer2::Renderer::onSetVideoFrameRate(float fps) {
-    if (mVideoScheduler == NULL) {
-        mVideoScheduler = new VideoFrameScheduler2();
-    }
-    mVideoScheduler->init(fps);
-}
-
-int32_t NuPlayer2::Renderer::getQueueGeneration(bool audio) {
-    Mutex::Autolock autoLock(mLock);
-    return (audio ? mAudioQueueGeneration : mVideoQueueGeneration);
-}
-
-int32_t NuPlayer2::Renderer::getDrainGeneration(bool audio) {
-    Mutex::Autolock autoLock(mLock);
-    return (audio ? mAudioDrainGeneration : mVideoDrainGeneration);
-}
-
-bool NuPlayer2::Renderer::getSyncQueues() {
-    Mutex::Autolock autoLock(mLock);
-    return mSyncQueues;
-}
-
-void NuPlayer2::Renderer::onAudioTearDown(AudioTearDownReason reason) {
-    if (mAudioTornDown) {
-        return;
-    }
-    mAudioTornDown = true;
-
-    int64_t currentPositionUs;
-    sp<AMessage> notify = mNotify->dup();
-    if (getCurrentPosition(&currentPositionUs) == OK) {
-        notify->setInt64("positionUs", currentPositionUs);
-    }
-
-    mAudioSink->stop();
-    mAudioSink->flush();
-
-    notify->setInt32("what", kWhatAudioTearDown);
-    notify->setInt32("reason", reason);
-    notify->post();
-}
-
-void NuPlayer2::Renderer::startAudioOffloadPauseTimeout() {
-    if (offloadingAudio()) {
-        mWakeLock->acquire();
-        sp<AMessage> msg = new AMessage(kWhatAudioOffloadPauseTimeout, this);
-        msg->setInt32("drainGeneration", mAudioOffloadPauseTimeoutGeneration);
-        msg->post(kOffloadPauseMaxUs);
-    }
-}
-
-void NuPlayer2::Renderer::cancelAudioOffloadPauseTimeout() {
-    // We may have called startAudioOffloadPauseTimeout() without
-    // the AudioSink open and with offloadingAudio enabled.
-    //
-    // When we cancel, it may be that offloadingAudio is subsequently disabled, so regardless
-    // we always release the wakelock and increment the pause timeout generation.
-    //
-    // Note: The acquired wakelock prevents the device from suspending
-    // immediately after offload pause (in case a resume happens shortly thereafter).
-    mWakeLock->release(true);
-    ++mAudioOffloadPauseTimeoutGeneration;
-}
-
-status_t NuPlayer2::Renderer::onOpenAudioSink(
-        const sp<AMessage> &format,
-        bool offloadOnly,
-        bool hasVideo,
-        uint32_t flags,
-        bool isStreaming) {
-    ALOGV("openAudioSink: offloadOnly(%d) offloadingAudio(%d)",
-            offloadOnly, offloadingAudio());
-
-    bool audioSinkChanged = false;
-
-    int32_t numChannels;
-    CHECK(format->findInt32("channel-count", &numChannels));
-
-    int32_t channelMask;
-    if (!format->findInt32("channel-mask", &channelMask)) {
-        // signal to the AudioSink to derive the mask from count.
-        channelMask = CHANNEL_MASK_USE_CHANNEL_ORDER;
-    }
-
-    int32_t sampleRate;
-    CHECK(format->findInt32("sample-rate", &sampleRate));
-
-    // read pcm encoding from MediaCodec output format, if available
-    int32_t pcmEncoding;
-    audio_format_t audioFormat =
-            format->findInt32(KEY_PCM_ENCODING, &pcmEncoding) ?
-                    audioFormatFromEncoding(pcmEncoding) : AUDIO_FORMAT_PCM_16_BIT;
-
-    if (offloadingAudio()) {
-        AString mime;
-        CHECK(format->findString("mime", &mime));
-        status_t err = mapMimeToAudioFormat(audioFormat, mime.c_str());
-
-        if (err != OK) {
-            ALOGE("Couldn't map mime \"%s\" to a valid "
-                    "audio_format", mime.c_str());
-            onDisableOffloadAudio();
-        } else {
-            ALOGV("Mime \"%s\" mapped to audio_format 0x%x",
-                    mime.c_str(), audioFormat);
-
-            int avgBitRate = -1;
-            format->findInt32("bitrate", &avgBitRate);
-
-            int32_t aacProfile = -1;
-            if (audioFormat == AUDIO_FORMAT_AAC
-                    && format->findInt32("aac-profile", &aacProfile)) {
-                // Redefine AAC format as per aac profile
-                mapAACProfileToAudioFormat(
-                        audioFormat,
-                        aacProfile);
-            }
-
-            audio_offload_info_t offloadInfo = AUDIO_INFO_INITIALIZER;
-            offloadInfo.duration_us = -1;
-            format->findInt64(
-                    "durationUs", &offloadInfo.duration_us);
-            offloadInfo.sample_rate = sampleRate;
-            offloadInfo.channel_mask = channelMask;
-            offloadInfo.format = audioFormat;
-            offloadInfo.stream_type = AUDIO_STREAM_MUSIC;
-            offloadInfo.bit_rate = avgBitRate;
-            offloadInfo.has_video = hasVideo;
-            offloadInfo.is_streaming = isStreaming;
-
-            if (memcmp(&mCurrentOffloadInfo, &offloadInfo, sizeof(offloadInfo)) == 0) {
-                ALOGV("openAudioSink: no change in offload mode");
-                // no change from previous configuration, everything ok.
-                return OK;
-            }
-            mCurrentPcmInfo = AUDIO_PCMINFO_INITIALIZER;
-
-            ALOGV("openAudioSink: try to open AudioSink in offload mode");
-            uint32_t offloadFlags = flags;
-            offloadFlags |= AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD;
-            offloadFlags &= ~AUDIO_OUTPUT_FLAG_DEEP_BUFFER;
-            audioSinkChanged = true;
-            mAudioSink->close();
-
-            err = mAudioSink->open(
-                    sampleRate,
-                    numChannels,
-                    (audio_channel_mask_t)channelMask,
-                    audioFormat,
-                    &NuPlayer2::Renderer::AudioSinkCallback,
-                    this,
-                    (audio_output_flags_t)offloadFlags,
-                    &offloadInfo);
-
-            if (err == OK) {
-                err = mAudioSink->setPlaybackRate(mPlaybackSettings);
-            }
-
-            if (err == OK) {
-                // If the playback is offloaded to h/w, we pass
-                // the HAL some metadata information.
-                // We don't want to do this for PCM because it
-                // will be going through the AudioFlinger mixer
-                // before reaching the hardware.
-                // TODO
-                mCurrentOffloadInfo = offloadInfo;
-                if (!mPaused) { // for preview mode, don't start if paused
-                    err = mAudioSink->start();
-                }
-                ALOGV_IF(err == OK, "openAudioSink: offload succeeded");
-            }
-            if (err != OK) {
-                // Clean up, fall back to non offload mode.
-                mAudioSink->close();
-                onDisableOffloadAudio();
-                mCurrentOffloadInfo = AUDIO_INFO_INITIALIZER;
-                ALOGV("openAudioSink: offload failed");
-                if (offloadOnly) {
-                    notifyAudioTearDown(kForceNonOffload);
-                }
-            } else {
-                mUseAudioCallback = true;  // offload mode transfers data through callback
-                ++mAudioDrainGeneration;  // discard pending kWhatDrainAudioQueue message.
-            }
-        }
-    }
-    if (!offloadOnly && !offloadingAudio()) {
-        ALOGV("openAudioSink: open AudioSink in NON-offload mode");
-        uint32_t pcmFlags = flags;
-        pcmFlags &= ~AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD;
-
-        const PcmInfo info = {
-                (audio_channel_mask_t)channelMask,
-                (audio_output_flags_t)pcmFlags,
-                audioFormat,
-                numChannels,
-                sampleRate
-        };
-        if (memcmp(&mCurrentPcmInfo, &info, sizeof(info)) == 0) {
-            ALOGV("openAudioSink: no change in pcm mode");
-            // no change from previous configuration, everything ok.
-            return OK;
-        }
-
-        audioSinkChanged = true;
-        mAudioSink->close();
-        mCurrentOffloadInfo = AUDIO_INFO_INITIALIZER;
-        // Note: It is possible to set up the callback, but not use it to send audio data.
-        // This requires a fix in AudioSink to explicitly specify the transfer mode.
-        mUseAudioCallback = getUseAudioCallbackSetting();
-        if (mUseAudioCallback) {
-            ++mAudioDrainGeneration;  // discard pending kWhatDrainAudioQueue message.
-        }
-
-        // Compute the desired buffer size.
-        // For callback mode, the amount of time before wakeup is about half the buffer size.
-        const uint32_t frameCount =
-                (unsigned long long)sampleRate * getAudioSinkPcmMsSetting() / 1000;
-
-        // We should always be able to set our playback settings if the sink is closed.
-        LOG_ALWAYS_FATAL_IF(mAudioSink->setPlaybackRate(mPlaybackSettings) != OK,
-                "onOpenAudioSink: can't set playback rate on closed sink");
-        status_t err = mAudioSink->open(
-                    sampleRate,
-                    numChannels,
-                    (audio_channel_mask_t)channelMask,
-                    audioFormat,
-                    mUseAudioCallback ? &NuPlayer2::Renderer::AudioSinkCallback : NULL,
-                    mUseAudioCallback ? this : NULL,
-                    (audio_output_flags_t)pcmFlags,
-                    NULL,
-                    frameCount);
-        if (err != OK) {
-            ALOGW("openAudioSink: non offloaded open failed status: %d", err);
-            mAudioSink->close();
-            mCurrentPcmInfo = AUDIO_PCMINFO_INITIALIZER;
-            return err;
-        }
-        mCurrentPcmInfo = info;
-        if (!mPaused) { // for preview mode, don't start if paused
-            mAudioSink->start();
-        }
-    }
-    if (audioSinkChanged) {
-        onAudioSinkChanged();
-    }
-    mAudioTornDown = false;
-    return OK;
-}
-
-void NuPlayer2::Renderer::onCloseAudioSink() {
-    mAudioSink->close();
-    mCurrentOffloadInfo = AUDIO_INFO_INITIALIZER;
-    mCurrentPcmInfo = AUDIO_PCMINFO_INITIALIZER;
-}
-
-void NuPlayer2::Renderer::onChangeAudioFormat(
-        const sp<AMessage> &meta, const sp<AMessage> &notify) {
-    sp<AMessage> format;
-    CHECK(meta->findMessage("format", &format));
-
-    int32_t offloadOnly;
-    CHECK(meta->findInt32("offload-only", &offloadOnly));
-
-    int32_t hasVideo;
-    CHECK(meta->findInt32("has-video", &hasVideo));
-
-    uint32_t flags;
-    CHECK(meta->findInt32("flags", (int32_t *)&flags));
-
-    uint32_t isStreaming;
-    CHECK(meta->findInt32("isStreaming", (int32_t *)&isStreaming));
-
-    status_t err = onOpenAudioSink(format, offloadOnly, hasVideo, flags, isStreaming);
-
-    if (err != OK) {
-        notify->setInt32("err", err);
-    }
-    notify->post();
-}
-
-}  // namespace android
diff --git a/media/libmediaplayer2/nuplayer2/NuPlayer2Renderer.h b/media/libmediaplayer2/nuplayer2/NuPlayer2Renderer.h
deleted file mode 100644
index d065dee..0000000
--- a/media/libmediaplayer2/nuplayer2/NuPlayer2Renderer.h
+++ /dev/null
@@ -1,304 +0,0 @@
-/*
- * Copyright 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef NUPLAYER2_RENDERER_H_
-
-#define NUPLAYER2_RENDERER_H_
-
-#include <media/AudioResamplerPublic.h>
-#include <media/AVSyncSettings.h>
-#include <mediaplayer2/JObjectHolder.h>
-
-#include "NuPlayer2.h"
-
-namespace android {
-
-class  JWakeLock;
-struct MediaClock;
-class MediaCodecBuffer;
-struct VideoFrameSchedulerBase;
-
-struct NuPlayer2::Renderer : public AHandler {
-    enum Flags {
-        FLAG_REAL_TIME = 1,
-        FLAG_OFFLOAD_AUDIO = 2,
-    };
-    Renderer(const sp<MediaPlayer2Interface::AudioSink> &sink,
-             const sp<MediaClock> &mediaClock,
-             const sp<AMessage> &notify,
-             const sp<JObjectHolder> &context,
-             uint32_t flags = 0);
-
-    static size_t AudioSinkCallback(
-            MediaPlayer2Interface::AudioSink *audioSink,
-            void *data, size_t size, void *me,
-            MediaPlayer2Interface::AudioSink::cb_event_t event);
-
-    void queueBuffer(
-            bool audio,
-            const sp<MediaCodecBuffer> &buffer,
-            const sp<AMessage> &notifyConsumed);
-
-    void queueEOS(bool audio, status_t finalResult);
-
-    status_t setPlaybackSettings(const AudioPlaybackRate &rate /* sanitized */);
-    status_t getPlaybackSettings(AudioPlaybackRate *rate /* nonnull */);
-    status_t setSyncSettings(const AVSyncSettings &sync, float videoFpsHint);
-    status_t getSyncSettings(AVSyncSettings *sync /* nonnull */, float *videoFps /* nonnull */);
-
-    void flush(bool audio, bool notifyComplete);
-
-    void signalTimeDiscontinuity();
-
-    void signalDisableOffloadAudio();
-    void signalEnableOffloadAudio();
-
-    void pause();
-    void resume();
-
-    void setVideoFrameRate(float fps);
-
-    status_t getCurrentPosition(int64_t *mediaUs);
-    int64_t getVideoLateByUs();
-
-    status_t openAudioSink(
-            const sp<AMessage> &format,
-            bool offloadOnly,
-            bool hasVideo,
-            uint32_t flags,
-            bool *isOffloaded,
-            bool isStreaming);
-    void closeAudioSink();
-
-    // re-open audio sink after all pending audio buffers played.
-    void changeAudioFormat(
-            const sp<AMessage> &format,
-            bool offloadOnly,
-            bool hasVideo,
-            uint32_t flags,
-            bool isStreaming,
-            const sp<AMessage> &notify);
-
-    enum {
-        kWhatEOS                      = 'eos ',
-        kWhatFlushComplete            = 'fluC',
-        kWhatPosition                 = 'posi',
-        kWhatVideoRenderingStart      = 'vdrd',
-        kWhatMediaRenderingStart      = 'mdrd',
-        kWhatAudioTearDown            = 'adTD',
-        kWhatAudioOffloadPauseTimeout = 'aOPT',
-    };
-
-    enum AudioTearDownReason {
-        kDueToError = 0,   // Could restart with either offload or non-offload.
-        kDueToTimeout,
-        kForceNonOffload,  // Restart only with non-offload.
-    };
-
-protected:
-    virtual ~Renderer();
-
-    virtual void onMessageReceived(const sp<AMessage> &msg);
-
-private:
-    enum {
-        kWhatDrainAudioQueue     = 'draA',
-        kWhatDrainVideoQueue     = 'draV',
-        kWhatPostDrainVideoQueue = 'pDVQ',
-        kWhatQueueBuffer         = 'queB',
-        kWhatQueueEOS            = 'qEOS',
-        kWhatConfigPlayback      = 'cfPB',
-        kWhatConfigSync          = 'cfSy',
-        kWhatGetPlaybackSettings = 'gPbS',
-        kWhatGetSyncSettings     = 'gSyS',
-        kWhatFlush               = 'flus',
-        kWhatPause               = 'paus',
-        kWhatResume              = 'resm',
-        kWhatOpenAudioSink       = 'opnA',
-        kWhatCloseAudioSink      = 'clsA',
-        kWhatChangeAudioFormat   = 'chgA',
-        kWhatStopAudioSink       = 'stpA',
-        kWhatDisableOffloadAudio = 'noOA',
-        kWhatEnableOffloadAudio  = 'enOA',
-        kWhatSetVideoFrameRate   = 'sVFR',
-    };
-
-    // if mBuffer != nullptr, it's a buffer containing real data.
-    // else if mNotifyConsumed == nullptr, it's EOS.
-    // else it's a tag for re-opening audio sink in different format.
-    struct QueueEntry {
-        sp<MediaCodecBuffer> mBuffer;
-        sp<AMessage> mMeta;
-        sp<AMessage> mNotifyConsumed;
-        size_t mOffset;
-        status_t mFinalResult;
-        int32_t mBufferOrdinal;
-    };
-
-    static const int64_t kMinPositionUpdateDelayUs;
-
-    sp<MediaPlayer2Interface::AudioSink> mAudioSink;
-    bool mUseVirtualAudioSink;
-    sp<AMessage> mNotify;
-    Mutex mLock;
-    uint32_t mFlags;
-    List<QueueEntry> mAudioQueue;
-    List<QueueEntry> mVideoQueue;
-    uint32_t mNumFramesWritten;
-    sp<VideoFrameSchedulerBase> mVideoScheduler;
-
-    bool mDrainAudioQueuePending;
-    bool mDrainVideoQueuePending;
-    int32_t mAudioQueueGeneration;
-    int32_t mVideoQueueGeneration;
-    int32_t mAudioDrainGeneration;
-    int32_t mVideoDrainGeneration;
-    int32_t mAudioEOSGeneration;
-
-    const sp<MediaClock> mMediaClock;
-
-    AudioPlaybackRate mPlaybackSettings;
-    AVSyncSettings mSyncSettings;
-    float mVideoFpsHint;
-
-    int64_t mAudioFirstAnchorTimeMediaUs;
-    int64_t mAnchorTimeMediaUs;
-    int64_t mAnchorNumFramesWritten;
-    int64_t mVideoLateByUs;
-    int64_t mNextVideoTimeMediaUs;
-    bool mHasAudio;
-    bool mHasVideo;
-
-    bool mNotifyCompleteAudio;
-    bool mNotifyCompleteVideo;
-
-    bool mSyncQueues;
-
-    // modified on only renderer's thread.
-    bool mPaused;
-    int64_t mPauseDrainAudioAllowedUs; // time when we can drain/deliver audio in pause mode.
-
-    bool mVideoSampleReceived;
-    bool mVideoRenderingStarted;
-    int32_t mVideoRenderingStartGeneration;
-    int32_t mAudioRenderingStartGeneration;
-    bool mRenderingDataDelivered;
-
-    int64_t mNextAudioClockUpdateTimeUs;
-    // the media timestamp of last audio sample right before EOS.
-    int64_t mLastAudioMediaTimeUs;
-
-    int32_t mAudioOffloadPauseTimeoutGeneration;
-    bool mAudioTornDown;
-    audio_offload_info_t mCurrentOffloadInfo;
-
-    struct PcmInfo {
-        audio_channel_mask_t mChannelMask;
-        audio_output_flags_t mFlags;
-        audio_format_t mFormat;
-        int32_t mNumChannels;
-        int32_t mSampleRate;
-    };
-    PcmInfo mCurrentPcmInfo;
-    static const PcmInfo AUDIO_PCMINFO_INITIALIZER;
-
-    int32_t mTotalBuffersQueued;
-    int32_t mLastAudioBufferDrained;
-    bool mUseAudioCallback;
-
-    sp<JWakeLock> mWakeLock;
-
-    status_t getCurrentPositionOnLooper(int64_t *mediaUs);
-    status_t getCurrentPositionOnLooper(
-            int64_t *mediaUs, int64_t nowUs, bool allowPastQueuedVideo = false);
-    bool getCurrentPositionIfPaused_l(int64_t *mediaUs);
-    status_t getCurrentPositionFromAnchor(
-            int64_t *mediaUs, int64_t nowUs, bool allowPastQueuedVideo = false);
-
-    void notifyEOSCallback();
-    size_t fillAudioBuffer(void *buffer, size_t size);
-
-    bool onDrainAudioQueue();
-    void drainAudioQueueUntilLastEOS();
-    int64_t getPendingAudioPlayoutDurationUs(int64_t nowUs);
-    void postDrainAudioQueue_l(int64_t delayUs = 0);
-
-    void clearAnchorTime();
-    void clearAudioFirstAnchorTime_l();
-    void setAudioFirstAnchorTimeIfNeeded_l(int64_t mediaUs);
-    void setVideoLateByUs(int64_t lateUs);
-
-    void onNewAudioMediaTime(int64_t mediaTimeUs);
-    int64_t getRealTimeUs(int64_t mediaTimeUs, int64_t nowUs);
-
-    void onDrainVideoQueue();
-    void postDrainVideoQueue();
-
-    void prepareForMediaRenderingStart_l();
-    void notifyIfMediaRenderingStarted_l();
-
-    void onQueueBuffer(const sp<AMessage> &msg);
-    void onQueueEOS(const sp<AMessage> &msg);
-    void onFlush(const sp<AMessage> &msg);
-    void onAudioSinkChanged();
-    void onDisableOffloadAudio();
-    void onEnableOffloadAudio();
-    status_t onConfigPlayback(const AudioPlaybackRate &rate /* sanitized */);
-    status_t onGetPlaybackSettings(AudioPlaybackRate *rate /* nonnull */);
-    status_t onConfigSync(const AVSyncSettings &sync, float videoFpsHint);
-    status_t onGetSyncSettings(AVSyncSettings *sync /* nonnull */, float *videoFps /* nonnull */);
-
-    void onPause();
-    void onResume();
-    void onSetVideoFrameRate(float fps);
-    int32_t getQueueGeneration(bool audio);
-    int32_t getDrainGeneration(bool audio);
-    bool getSyncQueues();
-    void onAudioTearDown(AudioTearDownReason reason);
-    status_t onOpenAudioSink(
-            const sp<AMessage> &format,
-            bool offloadOnly,
-            bool hasVideo,
-            uint32_t flags,
-            bool isStreaming);
-    void onCloseAudioSink();
-    void onChangeAudioFormat(const sp<AMessage> &meta, const sp<AMessage> &notify);
-
-    void notifyEOS(bool audio, status_t finalResult, int64_t delayUs = 0);
-    void notifyEOS_l(bool audio, status_t finalResult, int64_t delayUs = 0);
-    void notifyFlushComplete(bool audio);
-    void notifyPosition();
-    void notifyVideoLateBy(int64_t lateByUs);
-    void notifyVideoRenderingStart();
-    void notifyAudioTearDown(AudioTearDownReason reason);
-
-    void flushQueue(List<QueueEntry> *queue);
-    bool dropBufferIfStale(bool audio, const sp<AMessage> &msg);
-    void syncQueuesDone_l();
-
-    bool offloadingAudio() const { return (mFlags & FLAG_OFFLOAD_AUDIO) != 0; }
-
-    void startAudioOffloadPauseTimeout();
-    void cancelAudioOffloadPauseTimeout();
-
-    int64_t getDurationUsIfPlayedAtSampleRate(uint32_t numFrames);
-
-    DISALLOW_EVIL_CONSTRUCTORS(Renderer);
-};
-
-} // namespace android
-
-#endif  // NUPLAYER2_RENDERER_H_
diff --git a/media/libmediaplayer2/nuplayer2/NuPlayer2Source.h b/media/libmediaplayer2/nuplayer2/NuPlayer2Source.h
deleted file mode 100644
index 9298a99..0000000
--- a/media/libmediaplayer2/nuplayer2/NuPlayer2Source.h
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- * Copyright 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef NUPLAYER2_SOURCE_H_
-
-#define NUPLAYER2_SOURCE_H_
-
-#include "NuPlayer2.h"
-
-#include <media/stagefright/foundation/AMessage.h>
-#include <media/stagefright/MetaData.h>
-#include <mediaplayer2/mediaplayer2.h>
-#include <utils/Vector.h>
-
-namespace android {
-
-struct ABuffer;
-struct AMediaCryptoWrapper;
-class MediaBuffer;
-
-struct NuPlayer2::Source : public AHandler {
-    enum Flags {
-        FLAG_CAN_PAUSE          = 1,
-        FLAG_CAN_SEEK_BACKWARD  = 2,  // the "10 sec back button"
-        FLAG_CAN_SEEK_FORWARD   = 4,  // the "10 sec forward button"
-        FLAG_CAN_SEEK           = 8,  // the "seek bar"
-        FLAG_DYNAMIC_DURATION   = 16,
-        FLAG_SECURE             = 32, // Secure codec is required.
-        FLAG_PROTECTED          = 64, // The screen needs to be protected (screenshot is disabled).
-    };
-
-    enum {
-        kWhatPrepared,
-        kWhatFlagsChanged,
-        kWhatVideoSizeChanged,
-        kWhatBufferingUpdate,
-        kWhatPauseOnBufferingStart,
-        kWhatResumeOnBufferingEnd,
-        kWhatCacheStats,
-        kWhatSubtitleData,
-        kWhatTimedTextData,
-        kWhatTimedMetaData,
-        kWhatQueueDecoderShutdown,
-        kWhatDrmNoLicense,
-        // Modular DRM
-        kWhatDrmInfo,
-    };
-
-    // The provides message is used to notify the player about various
-    // events.
-    explicit Source(const sp<AMessage> &notify)
-        : mNotify(notify) {
-    }
-
-    virtual status_t getBufferingSettings(
-            BufferingSettings* buffering /* nonnull */) = 0;
-    virtual status_t setBufferingSettings(const BufferingSettings& buffering) = 0;
-
-    virtual void prepareAsync(int64_t startTimeUs) = 0;
-
-    virtual void start() = 0;
-    virtual void stop() {}
-    virtual void pause() {}
-    virtual void resume() {}
-
-    // Explicitly disconnect the underling data source
-    virtual void disconnect() {}
-
-    // Returns OK iff more data was available,
-    // an error or ERROR_END_OF_STREAM if not.
-    virtual status_t feedMoreTSData() = 0;
-
-    // Returns non-NULL format when the specified track exists.
-    // When the format has "err" set to -EWOULDBLOCK, source needs more time to get valid meta data.
-    // Returns NULL if the specified track doesn't exist or is invalid;
-    virtual sp<AMessage> getFormat(bool audio);
-
-    virtual sp<MetaData> getFormatMeta(bool /* audio */) { return NULL; }
-    virtual sp<MetaData> getFileFormatMeta() const { return NULL; }
-
-    virtual status_t dequeueAccessUnit(
-            bool audio, sp<ABuffer> *accessUnit) = 0;
-
-    virtual status_t getDuration(int64_t * /* durationUs */) {
-        return INVALID_OPERATION;
-    }
-
-    virtual size_t getTrackCount() const {
-        return 0;
-    }
-
-    virtual sp<AMessage> getTrackInfo(size_t /* trackIndex */) const {
-        return NULL;
-    }
-
-    virtual ssize_t getSelectedTrack(media_track_type /* type */) const {
-        return INVALID_OPERATION;
-    }
-
-    virtual status_t selectTrack(size_t /* trackIndex */, bool /* select */, int64_t /* timeUs*/) {
-        return INVALID_OPERATION;
-    }
-
-    virtual status_t seekTo(
-            int64_t /* seekTimeUs */,
-            MediaPlayer2SeekMode /* mode */ = MediaPlayer2SeekMode::SEEK_PREVIOUS_SYNC) {
-        return INVALID_OPERATION;
-    }
-
-    virtual bool isRealTime() const {
-        return false;
-    }
-
-    virtual bool isStreaming() const {
-        return true;
-    }
-
-    virtual void setOffloadAudio(bool /* offload */) {}
-
-    // Modular DRM
-    virtual status_t prepareDrm(
-            const uint8_t /* uuid */[16], const Vector<uint8_t> & /* drmSessionId */,
-            sp<AMediaCryptoWrapper> * /* crypto */) {
-        return INVALID_OPERATION;
-    }
-
-    virtual status_t releaseDrm() {
-        return INVALID_OPERATION;
-    }
-
-protected:
-    virtual ~Source() {}
-
-    virtual void onMessageReceived(const sp<AMessage> &msg);
-
-    sp<AMessage> dupNotify() const { return mNotify->dup(); }
-
-    void notifyFlagsChanged(uint32_t flags);
-    void notifyVideoSizeChanged(const sp<AMessage> &format = NULL);
-    void notifyPrepared(status_t err = OK);
-    // Modular DRM
-    void notifyDrmInfo(const sp<ABuffer> &buffer);
-
-private:
-    sp<AMessage> mNotify;
-
-    DISALLOW_EVIL_CONSTRUCTORS(Source);
-};
-
-}  // namespace android
-
-#endif  // NUPLAYER2_SOURCE_H_
-
diff --git a/media/libmediaplayer2/nuplayer2/RTSPSource2.cpp b/media/libmediaplayer2/nuplayer2/RTSPSource2.cpp
deleted file mode 100644
index a70269e..0000000
--- a/media/libmediaplayer2/nuplayer2/RTSPSource2.cpp
+++ /dev/null
@@ -1,903 +0,0 @@
-/*
- * Copyright 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-//#define LOG_NDEBUG 0
-#define LOG_TAG "RTSPSource2"
-#include <utils/Log.h>
-
-#include "RTSPSource2.h"
-
-#include "AnotherPacketSource.h"
-#include "MyHandler.h"
-#include "SDPLoader.h"
-
-#include <media/MediaHTTPService.h>
-#include <media/stagefright/MediaDefs.h>
-#include <media/stagefright/MetaData.h>
-
-namespace android {
-
-const int64_t kNearEOSTimeoutUs = 2000000LL; // 2 secs
-
-// Default Buffer Underflow/Prepare/StartServer/Overflow Marks
-static const int kUnderflowMarkMs   =  1000;  // 1 second
-static const int kPrepareMarkMs     =  3000;  // 3 seconds
-//static const int kStartServerMarkMs =  5000;
-static const int kOverflowMarkMs    = 10000;  // 10 seconds
-
-NuPlayer2::RTSPSource2::RTSPSource2(
-        const sp<AMessage> &notify,
-        const sp<MediaHTTPService> &httpService,
-        const char *url,
-        const KeyedVector<String8, String8> *headers,
-        uid_t uid,
-        bool isSDP)
-    : Source(notify),
-      mHTTPService(httpService),
-      mURL(url),
-      mUID(uid),
-      mFlags(0),
-      mIsSDP(isSDP),
-      mState(DISCONNECTED),
-      mFinalResult(OK),
-      mDisconnectReplyID(0),
-      mBuffering(false),
-      mInPreparationPhase(true),
-      mEOSPending(false),
-      mSeekGeneration(0),
-      mEOSTimeoutAudio(0),
-      mEOSTimeoutVideo(0) {
-    mBufferingSettings.mInitialMarkMs = kPrepareMarkMs;
-    mBufferingSettings.mResumePlaybackMarkMs = kOverflowMarkMs;
-    if (headers) {
-        mExtraHeaders = *headers;
-
-        ssize_t index =
-            mExtraHeaders.indexOfKey(String8("x-hide-urls-from-log"));
-
-        if (index >= 0) {
-            mFlags |= kFlagIncognito;
-
-            mExtraHeaders.removeItemsAt(index);
-        }
-    }
-}
-
-NuPlayer2::RTSPSource2::~RTSPSource2() {
-    if (mLooper != NULL) {
-        mLooper->unregisterHandler(id());
-        mLooper->stop();
-    }
-}
-
-status_t NuPlayer2::RTSPSource2::getBufferingSettings(
-            BufferingSettings* buffering /* nonnull */) {
-    Mutex::Autolock _l(mBufferingSettingsLock);
-    *buffering = mBufferingSettings;
-    return OK;
-}
-
-status_t NuPlayer2::RTSPSource2::setBufferingSettings(const BufferingSettings& buffering) {
-    Mutex::Autolock _l(mBufferingSettingsLock);
-    mBufferingSettings = buffering;
-    return OK;
-}
-
-// TODO: fetch data starting from |startTimeUs|
-void NuPlayer2::RTSPSource2::prepareAsync(int64_t /* startTimeUs */) {
-    if (mIsSDP && mHTTPService == NULL) {
-        notifyPrepared(BAD_VALUE);
-        return;
-    }
-
-    if (mLooper == NULL) {
-        mLooper = new ALooper;
-        mLooper->setName("rtsp2");
-        mLooper->start();
-
-        mLooper->registerHandler(this);
-    }
-
-    CHECK(mHandler == NULL);
-    CHECK(mSDPLoader == NULL);
-
-    sp<AMessage> notify = new AMessage(kWhatNotify, this);
-
-    CHECK_EQ(mState, (int)DISCONNECTED);
-    mState = CONNECTING;
-
-    if (mIsSDP) {
-        mSDPLoader = new SDPLoader(notify,
-                (mFlags & kFlagIncognito) ? SDPLoader::kFlagIncognito : 0,
-                mHTTPService);
-
-        mSDPLoader->load(
-                mURL.c_str(), mExtraHeaders.isEmpty() ? NULL : &mExtraHeaders);
-    } else {
-        mHandler = new MyHandler(mURL.c_str(), notify, true /* uidValid */, mUID);
-        mLooper->registerHandler(mHandler);
-
-        mHandler->connect();
-    }
-
-    startBufferingIfNecessary();
-}
-
-void NuPlayer2::RTSPSource2::start() {
-}
-
-void NuPlayer2::RTSPSource2::stop() {
-    if (mLooper == NULL) {
-        return;
-    }
-    sp<AMessage> msg = new AMessage(kWhatDisconnect, this);
-
-    sp<AMessage> dummy;
-    msg->postAndAwaitResponse(&dummy);
-}
-
-status_t NuPlayer2::RTSPSource2::feedMoreTSData() {
-    Mutex::Autolock _l(mBufferingLock);
-    return mFinalResult;
-}
-
-sp<MetaData> NuPlayer2::RTSPSource2::getFormatMeta(bool audio) {
-    sp<AnotherPacketSource> source = getSource(audio);
-
-    if (source == NULL) {
-        return NULL;
-    }
-
-    return source->getFormat();
-}
-
-bool NuPlayer2::RTSPSource2::haveSufficientDataOnAllTracks() {
-    // We're going to buffer at least 2 secs worth data on all tracks before
-    // starting playback (both at startup and after a seek).
-
-    static const int64_t kMinDurationUs = 2000000LL;
-
-    int64_t mediaDurationUs = 0;
-    getDuration(&mediaDurationUs);
-    if ((mAudioTrack != NULL && mAudioTrack->isFinished(mediaDurationUs))
-            || (mVideoTrack != NULL && mVideoTrack->isFinished(mediaDurationUs))) {
-        return true;
-    }
-
-    status_t err;
-    int64_t durationUs;
-    if (mAudioTrack != NULL
-            && (durationUs = mAudioTrack->getBufferedDurationUs(&err))
-                    < kMinDurationUs
-            && err == OK) {
-        ALOGV("audio track doesn't have enough data yet. (%.2f secs buffered)",
-              durationUs / 1E6);
-        return false;
-    }
-
-    if (mVideoTrack != NULL
-            && (durationUs = mVideoTrack->getBufferedDurationUs(&err))
-                    < kMinDurationUs
-            && err == OK) {
-        ALOGV("video track doesn't have enough data yet. (%.2f secs buffered)",
-              durationUs / 1E6);
-        return false;
-    }
-
-    return true;
-}
-
-status_t NuPlayer2::RTSPSource2::dequeueAccessUnit(
-        bool audio, sp<ABuffer> *accessUnit) {
-    if (!stopBufferingIfNecessary()) {
-        return -EWOULDBLOCK;
-    }
-
-    sp<AnotherPacketSource> source = getSource(audio);
-
-    if (source == NULL) {
-        return -EWOULDBLOCK;
-    }
-
-    status_t finalResult;
-    if (!source->hasBufferAvailable(&finalResult)) {
-        if (finalResult == OK) {
-
-            // If other source already signaled EOS, this source should also return EOS
-            if (sourceReachedEOS(!audio)) {
-                return ERROR_END_OF_STREAM;
-            }
-
-            // If this source has detected near end, give it some time to retrieve more
-            // data before returning EOS
-            int64_t mediaDurationUs = 0;
-            getDuration(&mediaDurationUs);
-            if (source->isFinished(mediaDurationUs)) {
-                int64_t eosTimeout = audio ? mEOSTimeoutAudio : mEOSTimeoutVideo;
-                if (eosTimeout == 0) {
-                    setEOSTimeout(audio, ALooper::GetNowUs());
-                } else if ((ALooper::GetNowUs() - eosTimeout) > kNearEOSTimeoutUs) {
-                    setEOSTimeout(audio, 0);
-                    return ERROR_END_OF_STREAM;
-                }
-                return -EWOULDBLOCK;
-            }
-
-            if (!sourceNearEOS(!audio)) {
-                // We should not enter buffering mode
-                // if any of the sources already have detected EOS.
-                startBufferingIfNecessary();
-            }
-
-            return -EWOULDBLOCK;
-        }
-        return finalResult;
-    }
-
-    setEOSTimeout(audio, 0);
-
-    return source->dequeueAccessUnit(accessUnit);
-}
-
-sp<AnotherPacketSource> NuPlayer2::RTSPSource2::getSource(bool audio) {
-    if (mTSParser != NULL) {
-        sp<MediaSource> source = mTSParser->getSource(
-                audio ? ATSParser::AUDIO : ATSParser::VIDEO);
-
-        return static_cast<AnotherPacketSource *>(source.get());
-    }
-
-    return audio ? mAudioTrack : mVideoTrack;
-}
-
-void NuPlayer2::RTSPSource2::setEOSTimeout(bool audio, int64_t timeout) {
-    if (audio) {
-        mEOSTimeoutAudio = timeout;
-    } else {
-        mEOSTimeoutVideo = timeout;
-    }
-}
-
-status_t NuPlayer2::RTSPSource2::getDuration(int64_t *durationUs) {
-    *durationUs = -1LL;
-
-    int64_t audioDurationUs;
-    if (mAudioTrack != NULL
-            && mAudioTrack->getFormat()->findInt64(
-                kKeyDuration, &audioDurationUs)
-            && audioDurationUs > *durationUs) {
-        *durationUs = audioDurationUs;
-    }
-
-    int64_t videoDurationUs;
-    if (mVideoTrack != NULL
-            && mVideoTrack->getFormat()->findInt64(
-                kKeyDuration, &videoDurationUs)
-            && videoDurationUs > *durationUs) {
-        *durationUs = videoDurationUs;
-    }
-
-    return OK;
-}
-
-status_t NuPlayer2::RTSPSource2::seekTo(int64_t seekTimeUs, MediaPlayer2SeekMode mode) {
-    sp<AMessage> msg = new AMessage(kWhatPerformSeek, this);
-    msg->setInt32("generation", ++mSeekGeneration);
-    msg->setInt64("timeUs", seekTimeUs);
-    msg->setInt32("mode", mode);
-
-    sp<AMessage> response;
-    status_t err = msg->postAndAwaitResponse(&response);
-    if (err == OK && response != NULL) {
-        CHECK(response->findInt32("err", &err));
-    }
-
-    return err;
-}
-
-void NuPlayer2::RTSPSource2::performSeek(int64_t seekTimeUs) {
-    if (mState != CONNECTED) {
-        finishSeek(INVALID_OPERATION);
-        return;
-    }
-
-    mState = SEEKING;
-    mHandler->seek(seekTimeUs);
-    mEOSPending = false;
-}
-
-void NuPlayer2::RTSPSource2::schedulePollBuffering() {
-    sp<AMessage> msg = new AMessage(kWhatPollBuffering, this);
-    msg->post(1000000LL); // 1 second intervals
-}
-
-void NuPlayer2::RTSPSource2::checkBuffering(
-        bool *prepared, bool *underflow, bool *overflow, bool *startServer, bool *finished) {
-    size_t numTracks = mTracks.size();
-    size_t preparedCount, underflowCount, overflowCount, startCount, finishedCount;
-    preparedCount = underflowCount = overflowCount = startCount = finishedCount = 0;
-
-    size_t count = numTracks;
-    for (size_t i = 0; i < count; ++i) {
-        status_t finalResult;
-        TrackInfo *info = &mTracks.editItemAt(i);
-        sp<AnotherPacketSource> src = info->mSource;
-        if (src == NULL) {
-            --numTracks;
-            continue;
-        }
-        int64_t bufferedDurationUs = src->getBufferedDurationUs(&finalResult);
-
-        int64_t initialMarkUs;
-        int64_t maxRebufferingMarkUs;
-        {
-            Mutex::Autolock _l(mBufferingSettingsLock);
-            initialMarkUs = mBufferingSettings.mInitialMarkMs * 1000LL;
-            // TODO: maxRebufferingMarkUs could be larger than
-            // mBufferingSettings.mResumePlaybackMarkMs * 1000ll.
-            maxRebufferingMarkUs = mBufferingSettings.mResumePlaybackMarkMs * 1000LL;
-        }
-        // isFinished when duration is 0 checks for EOS result only
-        if (bufferedDurationUs > initialMarkUs
-                || src->isFinished(/* duration */ 0)) {
-            ++preparedCount;
-        }
-
-        if (src->isFinished(/* duration */ 0)) {
-            ++overflowCount;
-            ++finishedCount;
-        } else {
-            // TODO: redefine kUnderflowMarkMs to a fair value,
-            if (bufferedDurationUs < kUnderflowMarkMs * 1000) {
-                ++underflowCount;
-            }
-            if (bufferedDurationUs > maxRebufferingMarkUs) {
-                ++overflowCount;
-            }
-            int64_t startServerMarkUs =
-                    (kUnderflowMarkMs * 1000LL + maxRebufferingMarkUs) / 2;
-            if (bufferedDurationUs < startServerMarkUs) {
-                ++startCount;
-            }
-        }
-    }
-
-    *prepared    = (preparedCount == numTracks);
-    *underflow   = (underflowCount > 0);
-    *overflow    = (overflowCount == numTracks);
-    *startServer = (startCount > 0);
-    *finished    = (finishedCount > 0);
-}
-
-void NuPlayer2::RTSPSource2::onPollBuffering() {
-    bool prepared, underflow, overflow, startServer, finished;
-    checkBuffering(&prepared, &underflow, &overflow, &startServer, &finished);
-
-    if (prepared && mInPreparationPhase) {
-        mInPreparationPhase = false;
-        notifyPrepared();
-    }
-
-    if (!mInPreparationPhase && underflow) {
-        startBufferingIfNecessary();
-    }
-
-    if (haveSufficientDataOnAllTracks()) {
-        stopBufferingIfNecessary();
-    }
-
-    if (overflow && mHandler != NULL) {
-        mHandler->pause();
-    }
-
-    if (startServer && mHandler != NULL) {
-        mHandler->resume();
-    }
-
-    if (finished && mHandler != NULL) {
-        mHandler->cancelAccessUnitTimeoutCheck();
-    }
-
-    schedulePollBuffering();
-}
-
-void NuPlayer2::RTSPSource2::signalSourceEOS(status_t result) {
-    const bool audio = true;
-    const bool video = false;
-
-    sp<AnotherPacketSource> source = getSource(audio);
-    if (source != NULL) {
-        source->signalEOS(result);
-    }
-
-    source = getSource(video);
-    if (source != NULL) {
-        source->signalEOS(result);
-    }
-}
-
-bool NuPlayer2::RTSPSource2::sourceReachedEOS(bool audio) {
-    sp<AnotherPacketSource> source = getSource(audio);
-    status_t finalResult;
-    return (source != NULL &&
-            !source->hasBufferAvailable(&finalResult) &&
-            finalResult == ERROR_END_OF_STREAM);
-}
-
-bool NuPlayer2::RTSPSource2::sourceNearEOS(bool audio) {
-    sp<AnotherPacketSource> source = getSource(audio);
-    int64_t mediaDurationUs = 0;
-    getDuration(&mediaDurationUs);
-    return (source != NULL && source->isFinished(mediaDurationUs));
-}
-
-void NuPlayer2::RTSPSource2::onSignalEOS(const sp<AMessage> &msg) {
-    int32_t generation;
-    CHECK(msg->findInt32("generation", &generation));
-
-    if (generation != mSeekGeneration) {
-        return;
-    }
-
-    if (mEOSPending) {
-        signalSourceEOS(ERROR_END_OF_STREAM);
-        mEOSPending = false;
-    }
-}
-
-void NuPlayer2::RTSPSource2::postSourceEOSIfNecessary() {
-    const bool audio = true;
-    const bool video = false;
-    // If a source has detected near end, give it some time to retrieve more
-    // data before signaling EOS
-    if (sourceNearEOS(audio) || sourceNearEOS(video)) {
-        if (!mEOSPending) {
-            sp<AMessage> msg = new AMessage(kWhatSignalEOS, this);
-            msg->setInt32("generation", mSeekGeneration);
-            msg->post(kNearEOSTimeoutUs);
-            mEOSPending = true;
-        }
-    }
-}
-
-void NuPlayer2::RTSPSource2::onMessageReceived(const sp<AMessage> &msg) {
-    if (msg->what() == kWhatDisconnect) {
-        sp<AReplyToken> replyID;
-        CHECK(msg->senderAwaitsResponse(&replyID));
-
-        mDisconnectReplyID = replyID;
-        finishDisconnectIfPossible();
-        return;
-    } else if (msg->what() == kWhatPerformSeek) {
-        int32_t generation;
-        CHECK(msg->findInt32("generation", &generation));
-        CHECK(msg->senderAwaitsResponse(&mSeekReplyID));
-
-        if (generation != mSeekGeneration) {
-            // obsolete.
-            finishSeek(OK);
-            return;
-        }
-
-        int64_t seekTimeUs;
-        int32_t mode;
-        CHECK(msg->findInt64("timeUs", &seekTimeUs));
-        CHECK(msg->findInt32("mode", &mode));
-
-        // TODO: add "mode" to performSeek.
-        performSeek(seekTimeUs/*, (MediaPlayer2SeekMode)mode */);
-        return;
-    } else if (msg->what() == kWhatPollBuffering) {
-        onPollBuffering();
-        return;
-    } else if (msg->what() == kWhatSignalEOS) {
-        onSignalEOS(msg);
-        return;
-    }
-
-    CHECK_EQ(msg->what(), kWhatNotify);
-
-    int32_t what;
-    CHECK(msg->findInt32("what", &what));
-
-    switch (what) {
-        case MyHandler::kWhatConnected:
-        {
-            onConnected();
-
-            notifyVideoSizeChanged();
-
-            uint32_t flags = 0;
-
-            if (mHandler->isSeekable()) {
-                flags = FLAG_CAN_PAUSE
-                        | FLAG_CAN_SEEK
-                        | FLAG_CAN_SEEK_BACKWARD
-                        | FLAG_CAN_SEEK_FORWARD;
-            }
-
-            notifyFlagsChanged(flags);
-            schedulePollBuffering();
-            break;
-        }
-
-        case MyHandler::kWhatDisconnected:
-        {
-            onDisconnected(msg);
-            break;
-        }
-
-        case MyHandler::kWhatSeekDone:
-        {
-            mState = CONNECTED;
-            // Unblock seekTo here in case we attempted to seek in a live stream
-            finishSeek(OK);
-            break;
-        }
-
-        case MyHandler::kWhatSeekPaused:
-        {
-            sp<AnotherPacketSource> source = getSource(true /* audio */);
-            if (source != NULL) {
-                source->queueDiscontinuity(ATSParser::DISCONTINUITY_NONE,
-                        /* extra */ NULL,
-                        /* discard */ true);
-            }
-            source = getSource(false /* video */);
-            if (source != NULL) {
-                source->queueDiscontinuity(ATSParser::DISCONTINUITY_NONE,
-                        /* extra */ NULL,
-                        /* discard */ true);
-            };
-
-            status_t err = OK;
-            msg->findInt32("err", &err);
-
-            if (err == OK) {
-                int64_t timeUs;
-                CHECK(msg->findInt64("time", &timeUs));
-                mHandler->continueSeekAfterPause(timeUs);
-            } else {
-                finishSeek(err);
-            }
-            break;
-        }
-
-        case MyHandler::kWhatAccessUnit:
-        {
-            size_t trackIndex;
-            CHECK(msg->findSize("trackIndex", &trackIndex));
-
-            if (mTSParser == NULL) {
-                CHECK_LT(trackIndex, mTracks.size());
-            } else {
-                CHECK_EQ(trackIndex, 0u);
-            }
-
-            sp<ABuffer> accessUnit;
-            CHECK(msg->findBuffer("accessUnit", &accessUnit));
-
-            int32_t damaged;
-            if (accessUnit->meta()->findInt32("damaged", &damaged)
-                    && damaged) {
-                ALOGI("dropping damaged access unit.");
-                break;
-            }
-
-            if (mTSParser != NULL) {
-                size_t offset = 0;
-                status_t err = OK;
-                while (offset + 188 <= accessUnit->size()) {
-                    err = mTSParser->feedTSPacket(
-                            accessUnit->data() + offset, 188);
-                    if (err != OK) {
-                        break;
-                    }
-
-                    offset += 188;
-                }
-
-                if (offset < accessUnit->size()) {
-                    err = ERROR_MALFORMED;
-                }
-
-                if (err != OK) {
-                    signalSourceEOS(err);
-                }
-
-                postSourceEOSIfNecessary();
-                break;
-            }
-
-            TrackInfo *info = &mTracks.editItemAt(trackIndex);
-
-            sp<AnotherPacketSource> source = info->mSource;
-            if (source != NULL) {
-                uint32_t rtpTime;
-                CHECK(accessUnit->meta()->findInt32("rtp-time", (int32_t *)&rtpTime));
-
-                if (!info->mNPTMappingValid) {
-                    // This is a live stream, we didn't receive any normal
-                    // playtime mapping. We won't map to npt time.
-                    source->queueAccessUnit(accessUnit);
-                    break;
-                }
-
-                int64_t nptUs =
-                    ((double)rtpTime - (double)info->mRTPTime)
-                        / info->mTimeScale
-                        * 1000000LL
-                        + info->mNormalPlaytimeUs;
-
-                accessUnit->meta()->setInt64("timeUs", nptUs);
-
-                source->queueAccessUnit(accessUnit);
-            }
-            postSourceEOSIfNecessary();
-            break;
-        }
-
-        case MyHandler::kWhatEOS:
-        {
-            int32_t finalResult;
-            CHECK(msg->findInt32("finalResult", &finalResult));
-            CHECK_NE(finalResult, (status_t)OK);
-
-            if (mTSParser != NULL) {
-                signalSourceEOS(finalResult);
-            }
-
-            size_t trackIndex;
-            CHECK(msg->findSize("trackIndex", &trackIndex));
-            CHECK_LT(trackIndex, mTracks.size());
-
-            TrackInfo *info = &mTracks.editItemAt(trackIndex);
-            sp<AnotherPacketSource> source = info->mSource;
-            if (source != NULL) {
-                source->signalEOS(finalResult);
-            }
-
-            break;
-        }
-
-        case MyHandler::kWhatSeekDiscontinuity:
-        {
-            size_t trackIndex;
-            CHECK(msg->findSize("trackIndex", &trackIndex));
-            CHECK_LT(trackIndex, mTracks.size());
-
-            TrackInfo *info = &mTracks.editItemAt(trackIndex);
-            sp<AnotherPacketSource> source = info->mSource;
-            if (source != NULL) {
-                source->queueDiscontinuity(
-                        ATSParser::DISCONTINUITY_TIME,
-                        NULL,
-                        true /* discard */);
-            }
-
-            break;
-        }
-
-        case MyHandler::kWhatNormalPlayTimeMapping:
-        {
-            size_t trackIndex;
-            CHECK(msg->findSize("trackIndex", &trackIndex));
-            CHECK_LT(trackIndex, mTracks.size());
-
-            uint32_t rtpTime;
-            CHECK(msg->findInt32("rtpTime", (int32_t *)&rtpTime));
-
-            int64_t nptUs;
-            CHECK(msg->findInt64("nptUs", &nptUs));
-
-            TrackInfo *info = &mTracks.editItemAt(trackIndex);
-            info->mRTPTime = rtpTime;
-            info->mNormalPlaytimeUs = nptUs;
-            info->mNPTMappingValid = true;
-            break;
-        }
-
-        case SDPLoader::kWhatSDPLoaded:
-        {
-            onSDPLoaded(msg);
-            break;
-        }
-
-        default:
-            TRESPASS();
-    }
-}
-
-void NuPlayer2::RTSPSource2::onConnected() {
-    CHECK(mAudioTrack == NULL);
-    CHECK(mVideoTrack == NULL);
-
-    size_t numTracks = mHandler->countTracks();
-    for (size_t i = 0; i < numTracks; ++i) {
-        int32_t timeScale;
-        sp<MetaData> format = mHandler->getTrackFormat(i, &timeScale);
-
-        const char *mime;
-        CHECK(format->findCString(kKeyMIMEType, &mime));
-
-        if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_MPEG2TS)) {
-            // Very special case for MPEG2 Transport Streams.
-            CHECK_EQ(numTracks, 1u);
-
-            mTSParser = new ATSParser;
-            return;
-        }
-
-        bool isAudio = !strncasecmp(mime, "audio/", 6);
-        bool isVideo = !strncasecmp(mime, "video/", 6);
-
-        TrackInfo info;
-        info.mTimeScale = timeScale;
-        info.mRTPTime = 0;
-        info.mNormalPlaytimeUs = 0LL;
-        info.mNPTMappingValid = false;
-
-        if ((isAudio && mAudioTrack == NULL)
-                || (isVideo && mVideoTrack == NULL)) {
-            sp<AnotherPacketSource> source = new AnotherPacketSource(format);
-
-            if (isAudio) {
-                mAudioTrack = source;
-            } else {
-                mVideoTrack = source;
-            }
-
-            info.mSource = source;
-        }
-
-        mTracks.push(info);
-    }
-
-    mState = CONNECTED;
-}
-
-void NuPlayer2::RTSPSource2::onSDPLoaded(const sp<AMessage> &msg) {
-    status_t err;
-    CHECK(msg->findInt32("result", &err));
-
-    mSDPLoader.clear();
-
-    if (mDisconnectReplyID != 0) {
-        err = UNKNOWN_ERROR;
-    }
-
-    if (err == OK) {
-        sp<ASessionDescription> desc;
-        sp<RefBase> obj;
-        CHECK(msg->findObject("description", &obj));
-        desc = static_cast<ASessionDescription *>(obj.get());
-
-        AString rtspUri;
-        if (!desc->findAttribute(0, "a=control", &rtspUri)) {
-            ALOGE("Unable to find url in SDP");
-            err = UNKNOWN_ERROR;
-        } else {
-            sp<AMessage> notify = new AMessage(kWhatNotify, this);
-
-            mHandler = new MyHandler(rtspUri.c_str(), notify, true /* uidValid */, mUID);
-            mLooper->registerHandler(mHandler);
-
-            mHandler->loadSDP(desc);
-        }
-    }
-
-    if (err != OK) {
-        if (mState == CONNECTING) {
-            // We're still in the preparation phase, signal that it
-            // failed.
-            notifyPrepared(err);
-        }
-
-        mState = DISCONNECTED;
-        setError(err);
-
-        if (mDisconnectReplyID != 0) {
-            finishDisconnectIfPossible();
-        }
-    }
-}
-
-void NuPlayer2::RTSPSource2::onDisconnected(const sp<AMessage> &msg) {
-    if (mState == DISCONNECTED) {
-        return;
-    }
-
-    status_t err;
-    CHECK(msg->findInt32("result", &err));
-    CHECK_NE(err, (status_t)OK);
-
-    mLooper->unregisterHandler(mHandler->id());
-    mHandler.clear();
-
-    if (mState == CONNECTING) {
-        // We're still in the preparation phase, signal that it
-        // failed.
-        notifyPrepared(err);
-    }
-
-    mState = DISCONNECTED;
-    setError(err);
-
-    if (mDisconnectReplyID != 0) {
-        finishDisconnectIfPossible();
-    }
-}
-
-void NuPlayer2::RTSPSource2::finishDisconnectIfPossible() {
-    if (mState != DISCONNECTED) {
-        if (mHandler != NULL) {
-            mHandler->disconnect();
-        } else if (mSDPLoader != NULL) {
-            mSDPLoader->cancel();
-        }
-        return;
-    }
-
-    (new AMessage)->postReply(mDisconnectReplyID);
-    mDisconnectReplyID = 0;
-}
-
-void NuPlayer2::RTSPSource2::setError(status_t err) {
-    Mutex::Autolock _l(mBufferingLock);
-    mFinalResult = err;
-}
-
-void NuPlayer2::RTSPSource2::startBufferingIfNecessary() {
-    Mutex::Autolock _l(mBufferingLock);
-
-    if (!mBuffering) {
-        mBuffering = true;
-
-        sp<AMessage> notify = dupNotify();
-        notify->setInt32("what", kWhatPauseOnBufferingStart);
-        notify->post();
-    }
-}
-
-bool NuPlayer2::RTSPSource2::stopBufferingIfNecessary() {
-    Mutex::Autolock _l(mBufferingLock);
-
-    if (mBuffering) {
-        if (!haveSufficientDataOnAllTracks()) {
-            return false;
-        }
-
-        mBuffering = false;
-
-        sp<AMessage> notify = dupNotify();
-        notify->setInt32("what", kWhatResumeOnBufferingEnd);
-        notify->post();
-    }
-
-    return true;
-}
-
-void NuPlayer2::RTSPSource2::finishSeek(status_t err) {
-    if (mSeekReplyID == NULL) {
-        return;
-    }
-    sp<AMessage> seekReply = new AMessage;
-    seekReply->setInt32("err", err);
-    seekReply->postReply(mSeekReplyID);
-    mSeekReplyID = NULL;
-}
-
-}  // namespace android
diff --git a/media/libmediaplayer2/nuplayer2/RTSPSource2.h b/media/libmediaplayer2/nuplayer2/RTSPSource2.h
deleted file mode 100644
index e5f1716..0000000
--- a/media/libmediaplayer2/nuplayer2/RTSPSource2.h
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * Copyright 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef RTSP_SOURCE2_H_
-
-#define RTSP_SOURCE2_H_
-
-#include "NuPlayer2Source.h"
-
-#include "ATSParser.h"
-
-namespace android {
-
-struct ALooper;
-struct AReplyToken;
-struct AnotherPacketSource;
-struct MyHandler;
-struct SDPLoader;
-
-struct NuPlayer2::RTSPSource2 : public NuPlayer2::Source {
-    RTSPSource2(
-            const sp<AMessage> &notify,
-            const sp<MediaHTTPService> &httpService,
-            const char *url,
-            const KeyedVector<String8, String8> *headers,
-            uid_t uid = 0,
-            bool isSDP = false);
-
-    virtual status_t getBufferingSettings(
-            BufferingSettings* buffering /* nonnull */) override;
-    virtual status_t setBufferingSettings(const BufferingSettings& buffering) override;
-
-    virtual void prepareAsync(int64_t startTimeUs);
-    virtual void start();
-    virtual void stop();
-
-    virtual status_t feedMoreTSData();
-
-    virtual status_t dequeueAccessUnit(bool audio, sp<ABuffer> *accessUnit);
-
-    virtual status_t getDuration(int64_t *durationUs);
-    virtual status_t seekTo(
-            int64_t seekTimeUs,
-            MediaPlayer2SeekMode mode = MediaPlayer2SeekMode::SEEK_PREVIOUS_SYNC) override;
-
-    void onMessageReceived(const sp<AMessage> &msg);
-
-protected:
-    virtual ~RTSPSource2();
-
-    virtual sp<MetaData> getFormatMeta(bool audio);
-
-private:
-    enum {
-        kWhatNotify          = 'noti',
-        kWhatDisconnect      = 'disc',
-        kWhatPerformSeek     = 'seek',
-        kWhatPollBuffering   = 'poll',
-        kWhatSignalEOS       = 'eos ',
-    };
-
-    enum State {
-        DISCONNECTED,
-        CONNECTING,
-        CONNECTED,
-        SEEKING,
-    };
-
-    enum Flags {
-        // Don't log any URLs.
-        kFlagIncognito = 1,
-    };
-
-    struct TrackInfo {
-        sp<AnotherPacketSource> mSource;
-
-        int32_t mTimeScale;
-        uint32_t mRTPTime;
-        int64_t mNormalPlaytimeUs;
-        bool mNPTMappingValid;
-    };
-
-    sp<MediaHTTPService> mHTTPService;
-    AString mURL;
-    KeyedVector<String8, String8> mExtraHeaders;
-    uid_t mUID;
-    uint32_t mFlags;
-    bool mIsSDP;
-    State mState;
-    status_t mFinalResult;
-    sp<AReplyToken> mDisconnectReplyID;
-    Mutex mBufferingLock;
-    bool mBuffering;
-    bool mInPreparationPhase;
-    bool mEOSPending;
-
-    Mutex mBufferingSettingsLock;
-    BufferingSettings mBufferingSettings;
-
-    sp<ALooper> mLooper;
-    sp<MyHandler> mHandler;
-    sp<SDPLoader> mSDPLoader;
-
-    Vector<TrackInfo> mTracks;
-    sp<AnotherPacketSource> mAudioTrack;
-    sp<AnotherPacketSource> mVideoTrack;
-
-    sp<ATSParser> mTSParser;
-
-    int32_t mSeekGeneration;
-
-    int64_t mEOSTimeoutAudio;
-    int64_t mEOSTimeoutVideo;
-
-    sp<AReplyToken> mSeekReplyID;
-
-    sp<AnotherPacketSource> getSource(bool audio);
-
-    void onConnected();
-    void onSDPLoaded(const sp<AMessage> &msg);
-    void onDisconnected(const sp<AMessage> &msg);
-    void finishDisconnectIfPossible();
-
-    void performSeek(int64_t seekTimeUs);
-    void schedulePollBuffering();
-    void checkBuffering(
-            bool *prepared,
-            bool *underflow,
-            bool *overflow,
-            bool *startServer,
-            bool *finished);
-    void onPollBuffering();
-
-    bool haveSufficientDataOnAllTracks();
-
-    void setEOSTimeout(bool audio, int64_t timeout);
-    void setError(status_t err);
-    void startBufferingIfNecessary();
-    bool stopBufferingIfNecessary();
-    void finishSeek(status_t err);
-
-    void postSourceEOSIfNecessary();
-    void signalSourceEOS(status_t result);
-    void onSignalEOS(const sp<AMessage> &msg);
-
-    bool sourceNearEOS(bool audio);
-    bool sourceReachedEOS(bool audio);
-
-    DISALLOW_EVIL_CONSTRUCTORS(RTSPSource2);
-};
-
-}  // namespace android
-
-#endif  // RTSP_SOURCE2_H_
diff --git a/media/libmediaplayerservice/Android.bp b/media/libmediaplayerservice/Android.bp
index 6709585..5301f5c 100644
--- a/media/libmediaplayerservice/Android.bp
+++ b/media/libmediaplayerservice/Android.bp
@@ -7,6 +7,7 @@
         "MediaPlayerService.cpp",
         "MediaRecorderClient.cpp",
         "MetadataRetrieverClient.cpp",
+        "StagefrightMetadataRetriever.cpp",
         "StagefrightRecorder.cpp",
         "TestPlayerStub.cpp",
     ],
@@ -21,11 +22,14 @@
         "libcodec2_client",
         "libcrypto",
         "libcutils",
+        "libdatasource",
         "libdl",
+        "libdrmframework",
         "libgui",
         "libhidlbase",
         "liblog",
         "libmedia",
+        "libmedia_codeclist",
         "libmedia_omx",
         "libmediadrm",
         "libmediametrics",
@@ -44,6 +48,7 @@
     ],
 
     static_libs: [
+        "libplayerservice_datasource",
         "libstagefright_nuplayer",
         "libstagefright_rtsp",
         "libstagefright_timedtext",
diff --git a/media/libmediaplayerservice/MediaPlayerFactory.cpp b/media/libmediaplayerservice/MediaPlayerFactory.cpp
index 1376ccc..05f7365 100644
--- a/media/libmediaplayerservice/MediaPlayerFactory.cpp
+++ b/media/libmediaplayerservice/MediaPlayerFactory.cpp
@@ -20,9 +20,9 @@
 #include <utils/Log.h>
 
 #include <cutils/properties.h>
+#include <datasource/FileSource.h>
 #include <media/DataSource.h>
 #include <media/IMediaPlayer.h>
-#include <media/stagefright/FileSource.h>
 #include <media/stagefright/foundation/ADebug.h>
 #include <utils/Errors.h>
 #include <utils/misc.h>
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index dfd3933..46c130f 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -48,6 +48,7 @@
 #include <utils/Vector.h>
 
 #include <codec2/hidl/client.h>
+#include <datasource/HTTPBase.h>
 #include <media/IMediaHTTPService.h>
 #include <media/IRemoteDisplay.h>
 #include <media/IRemoteDisplayClient.h>
@@ -61,6 +62,7 @@
 #include <media/stagefright/MediaCodecList.h>
 #include <media/stagefright/MediaErrors.h>
 #include <media/stagefright/Utils.h>
+#include <media/stagefright/FoundationUtils.h>
 #include <media/stagefright/foundation/ADebug.h>
 #include <media/stagefright/foundation/ALooperRoster.h>
 #include <media/stagefright/SurfaceUtils.h>
@@ -80,7 +82,6 @@
 #include "TestPlayerStub.h"
 #include "nuplayer/NuPlayerDriver.h"
 
-#include "HTTPBase.h"
 
 static const int kDumpLockRetries = 50;
 static const int kDumpLockSleepUs = 20000;
diff --git a/media/libmediaplayerservice/MediaPlayerService.h b/media/libmediaplayerservice/MediaPlayerService.h
index 49688ce..2562b8f 100644
--- a/media/libmediaplayerservice/MediaPlayerService.h
+++ b/media/libmediaplayerservice/MediaPlayerService.h
@@ -26,10 +26,12 @@
 #include <utils/String8.h>
 #include <utils/Vector.h>
 
+#include <media/AudioSystem.h>
 #include <media/MediaPlayerInterface.h>
 #include <media/Metadata.h>
 #include <media/stagefright/foundation/ABase.h>
 
+
 #include <system/audio.h>
 
 namespace android {
diff --git a/media/libmediaplayerservice/MetadataRetrieverClient.cpp b/media/libmediaplayerservice/MetadataRetrieverClient.cpp
index 40b17bf..4dbab0a 100644
--- a/media/libmediaplayerservice/MetadataRetrieverClient.cpp
+++ b/media/libmediaplayerservice/MetadataRetrieverClient.cpp
@@ -37,6 +37,7 @@
 #include <media/MediaPlayerInterface.h>
 #include <media/stagefright/InterfaceUtils.h>
 #include <media/stagefright/Utils.h>
+#include <media/stagefright/FoundationUtils.h>
 #include <private/media/VideoFrame.h>
 #include "MetadataRetrieverClient.h"
 #include "StagefrightMetadataRetriever.h"
diff --git a/media/libstagefright/StagefrightMetadataRetriever.cpp b/media/libmediaplayerservice/StagefrightMetadataRetriever.cpp
similarity index 98%
rename from media/libstagefright/StagefrightMetadataRetriever.cpp
rename to media/libmediaplayerservice/StagefrightMetadataRetriever.cpp
index fa3d372..1aae241 100644
--- a/media/libstagefright/StagefrightMetadataRetriever.cpp
+++ b/media/libmediaplayerservice/StagefrightMetadataRetriever.cpp
@@ -22,14 +22,14 @@
 #include <utils/Log.h>
 #include <cutils/properties.h>
 
-#include "include/FrameDecoder.h"
-#include "include/StagefrightMetadataRetriever.h"
+#include "StagefrightMetadataRetriever.h"
+#include "FrameDecoder.h"
 
+#include <datasource/PlayerServiceDataSourceFactory.h>
+#include <datasource/PlayerServiceFileSource.h>
 #include <media/IMediaHTTPService.h>
 #include <media/stagefright/foundation/ADebug.h>
 #include <media/stagefright/foundation/AMessage.h>
-#include <media/stagefright/DataSourceFactory.h>
-#include <media/stagefright/FileSource.h>
 #include <media/stagefright/MediaCodecList.h>
 #include <media/stagefright/MediaDefs.h>
 #include <media/stagefright/MediaErrors.h>
@@ -63,7 +63,8 @@
     ALOGV("setDataSource(%s)", uri);
 
     clearMetadata();
-    mSource = DataSourceFactory::CreateFromURI(httpService, uri, headers);
+    mSource = PlayerServiceDataSourceFactory::getInstance()->CreateFromURI(
+            httpService, uri, headers);
 
     if (mSource == NULL) {
         ALOGE("Unable to create data source for '%s'.", uri);
@@ -91,7 +92,7 @@
     ALOGV("setDataSource(%d, %" PRId64 ", %" PRId64 ")", fd, offset, length);
 
     clearMetadata();
-    mSource = new FileSource(fd, offset, length);
+    mSource = new PlayerServiceFileSource(fd, offset, length);
 
     status_t err;
     if ((err = mSource->initCheck()) != OK) {
diff --git a/media/libstagefright/include/StagefrightMetadataRetriever.h b/media/libmediaplayerservice/StagefrightMetadataRetriever.h
similarity index 100%
rename from media/libstagefright/include/StagefrightMetadataRetriever.h
rename to media/libmediaplayerservice/StagefrightMetadataRetriever.h
diff --git a/media/libmediaplayerservice/datasource/Android.bp b/media/libmediaplayerservice/datasource/Android.bp
new file mode 100644
index 0000000..71fa50b
--- /dev/null
+++ b/media/libmediaplayerservice/datasource/Android.bp
@@ -0,0 +1,43 @@
+cc_library_static {
+    name: "libplayerservice_datasource",
+
+    srcs: [
+        "PlayerServiceDataSourceFactory.cpp",
+        "PlayerServiceFileSource.cpp",
+        "PlayerServiceMediaHTTP.cpp",
+    ],
+
+    header_libs: [
+        "media_ndk_headers",
+        "libmedia_headers",
+    ],
+
+    shared_libs: [
+        "libdatasource",
+        "libdrmframework",
+        "liblog",
+        "libutils",
+    ],
+
+    local_include_dirs: [
+        "include",
+    ],
+
+    export_include_dirs: [
+        "include",
+    ],
+
+    cflags: [
+        "-Werror",
+        "-Wno-error=deprecated-declarations",
+        "-Wall",
+    ],
+
+    sanitize: {
+        misc_undefined: [
+            "unsigned-integer-overflow",
+            "signed-integer-overflow",
+        ],
+        cfi: true,
+    },
+}
diff --git a/media/libmediaplayerservice/datasource/PlayerServiceDataSourceFactory.cpp b/media/libmediaplayerservice/datasource/PlayerServiceDataSourceFactory.cpp
new file mode 100644
index 0000000..ef946e9
--- /dev/null
+++ b/media/libmediaplayerservice/datasource/PlayerServiceDataSourceFactory.cpp
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+//#define LOG_NDEBUG 0
+#define LOG_TAG "PlayerServuceDataSourceFactory"
+
+
+#include <datasource/PlayerServiceDataSourceFactory.h>
+#include <datasource/PlayerServiceFileSource.h>
+#include <datasource/PlayerServiceMediaHTTP.h>
+#include <media/MediaHTTPConnection.h>
+#include <media/MediaHTTPService.h>
+
+namespace android {
+
+// static
+sp<PlayerServiceDataSourceFactory> PlayerServiceDataSourceFactory::sInstance;
+// static
+Mutex PlayerServiceDataSourceFactory::sInstanceLock;
+
+// static
+sp<PlayerServiceDataSourceFactory> PlayerServiceDataSourceFactory::getInstance() {
+    Mutex::Autolock l(sInstanceLock);
+    if (!sInstance) {
+        sInstance = new PlayerServiceDataSourceFactory();
+    }
+    return sInstance;
+}
+
+sp<DataSource> PlayerServiceDataSourceFactory::CreateMediaHTTP(
+        const sp<MediaHTTPService> &httpService) {
+    if (httpService == NULL) {
+        return NULL;
+    }
+
+    sp<MediaHTTPConnection> conn = httpService->makeHTTPConnection();
+    if (conn == NULL) {
+        ALOGE("Failed to make http connection from http service!");
+        return NULL;
+    } else {
+        return new PlayerServiceMediaHTTP(conn);
+    }
+}
+
+sp<DataSource> PlayerServiceDataSourceFactory::CreateFileSource(const char *uri) {
+    return new PlayerServiceFileSource(uri);
+}
+
+}  // namespace android
diff --git a/media/libstagefright/FileSource.cpp b/media/libmediaplayerservice/datasource/PlayerServiceFileSource.cpp
similarity index 84%
rename from media/libstagefright/FileSource.cpp
rename to media/libmediaplayerservice/datasource/PlayerServiceFileSource.cpp
index aee7fd8..1580891 100644
--- a/media/libstagefright/FileSource.cpp
+++ b/media/libmediaplayerservice/datasource/PlayerServiceFileSource.cpp
@@ -15,18 +15,17 @@
  */
 
 //#define LOG_NDEBUG 0
-#define LOG_TAG "FileSource"
+#define LOG_TAG "PlayerServiceFileSource"
 #include <utils/Log.h>
 
+#include <datasource/PlayerServiceFileSource.h>
 #include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/FileSource.h>
-#include <media/stagefright/Utils.h>
 #include <private/android_filesystem_config.h>
 
 namespace android {
 
-FileSource::FileSource(const char *filename)
-    : ClearFileSource(filename),
+PlayerServiceFileSource::PlayerServiceFileSource(const char *filename)
+    : FileSource(filename),
       mDecryptHandle(NULL),
       mDrmManagerClient(NULL),
       mDrmBufOffset(0),
@@ -34,8 +33,8 @@
       mDrmBuf(NULL){
 }
 
-FileSource::FileSource(int fd, int64_t offset, int64_t length)
-    : ClearFileSource(fd, offset, length),
+PlayerServiceFileSource::PlayerServiceFileSource(int fd, int64_t offset, int64_t length)
+    : FileSource(fd, offset, length),
       mDecryptHandle(NULL),
       mDrmManagerClient(NULL),
       mDrmBufOffset(0),
@@ -43,7 +42,7 @@
       mDrmBuf(NULL) {
 }
 
-FileSource::~FileSource() {
+PlayerServiceFileSource::~PlayerServiceFileSource() {
     if (mDrmBuf != NULL) {
         delete[] mDrmBuf;
         mDrmBuf = NULL;
@@ -62,7 +61,7 @@
     }
 }
 
-ssize_t FileSource::readAt(off64_t offset, void *data, size_t size) {
+ssize_t PlayerServiceFileSource::readAt(off64_t offset, void *data, size_t size) {
     if (mFd < 0) {
         return NO_INIT;
     }
@@ -87,7 +86,7 @@
     }
 }
 
-sp<DecryptHandle> FileSource::DrmInitialization(const char *mime) {
+sp<DecryptHandle> PlayerServiceFileSource::DrmInitialization(const char *mime) {
     if (getuid() == AID_MEDIA_EX) return nullptr; // no DRM in media extractor
     if (mDrmManagerClient == NULL) {
         mDrmManagerClient = new DrmManagerClient();
@@ -110,7 +109,7 @@
     return mDecryptHandle;
 }
 
-ssize_t FileSource::readAtDRM_l(off64_t offset, void *data, size_t size) {
+ssize_t PlayerServiceFileSource::readAtDRM_l(off64_t offset, void *data, size_t size) {
     size_t DRM_CACHE_SIZE = 1024;
     if (mDrmBuf == NULL) {
         mDrmBuf = new unsigned char[DRM_CACHE_SIZE];
@@ -141,7 +140,7 @@
 }
 
 /* static */
-bool FileSource::requiresDrm(int fd, int64_t offset, int64_t length, const char *mime) {
+bool PlayerServiceFileSource::requiresDrm(int fd, int64_t offset, int64_t length, const char *mime) {
     std::unique_ptr<DrmManagerClient> drmClient(new DrmManagerClient());
     sp<DecryptHandle> decryptHandle =
             drmClient->openDecryptSession(fd, offset, length, mime);
diff --git a/media/libstagefright/http/MediaHTTP.cpp b/media/libmediaplayerservice/datasource/PlayerServiceMediaHTTP.cpp
similarity index 78%
rename from media/libstagefright/http/MediaHTTP.cpp
rename to media/libmediaplayerservice/datasource/PlayerServiceMediaHTTP.cpp
index 0fba3dc..0124720 100644
--- a/media/libstagefright/http/MediaHTTP.cpp
+++ b/media/libmediaplayerservice/datasource/PlayerServiceMediaHTTP.cpp
@@ -15,32 +15,32 @@
  */
 
 //#define LOG_NDEBUG 0
-#define LOG_TAG "MediaHTTP"
+#define LOG_TAG "PlayerServiceMediaHTTP"
 #include <utils/Log.h>
 
-#include <media/stagefright/MediaHTTP.h>
+#include <datasource/PlayerServiceMediaHTTP.h>
 
 #include <binder/IServiceManager.h>
 #include <media/stagefright/foundation/ADebug.h>
 #include <media/stagefright/foundation/ALooper.h>
-#include <media/stagefright/Utils.h>
+#include <media/stagefright/FoundationUtils.h>
 
 #include <media/MediaHTTPConnection.h>
 
 namespace android {
 
-MediaHTTP::MediaHTTP(const sp<MediaHTTPConnection> &conn)
-    : ClearMediaHTTP(conn),
+PlayerServiceMediaHTTP::PlayerServiceMediaHTTP(const sp<MediaHTTPConnection> &conn)
+    : MediaHTTP(conn),
       mDrmManagerClient(NULL) {
 }
 
-MediaHTTP::~MediaHTTP() {
+PlayerServiceMediaHTTP::~PlayerServiceMediaHTTP() {
     clearDRMState_l();
 }
 
 // DRM...
 
-sp<DecryptHandle> MediaHTTP::DrmInitialization(const char* mime) {
+sp<DecryptHandle> PlayerServiceMediaHTTP::DrmInitialization(const char* mime) {
     if (mDrmManagerClient == NULL) {
         mDrmManagerClient = new DrmManagerClient();
     }
@@ -62,7 +62,7 @@
     return mDecryptHandle;
 }
 
-void MediaHTTP::clearDRMState_l() {
+void PlayerServiceMediaHTTP::clearDRMState_l() {
     if (mDecryptHandle != NULL) {
         // To release mDecryptHandle
         CHECK(mDrmManagerClient);
diff --git a/media/libmediaplayerservice/datasource/include/datasource/PlayerServiceDataSourceFactory.h b/media/libmediaplayerservice/datasource/include/datasource/PlayerServiceDataSourceFactory.h
new file mode 100644
index 0000000..7d58c5c
--- /dev/null
+++ b/media/libmediaplayerservice/datasource/include/datasource/PlayerServiceDataSourceFactory.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef PLAYER_SERVICE_DATA_SOURCE_FACTORY_H_
+
+#define PLAYER_SERVICE_DATA_SOURCE_FACTORY_H_
+
+#include <datasource/DataSourceFactory.h>
+#include <media/DataSource.h>
+#include <sys/types.h>
+#include <utils/RefBase.h>
+
+namespace android {
+
+struct MediaHTTPService;
+class String8;
+struct HTTPBase;
+
+class PlayerServiceDataSourceFactory : public DataSourceFactory {
+public:
+    static sp<PlayerServiceDataSourceFactory> getInstance();
+    virtual sp<DataSource> CreateMediaHTTP(const sp<MediaHTTPService> &httpService);
+
+protected:
+    virtual sp<DataSource> CreateFileSource(const char *uri);
+
+private:
+    static sp<PlayerServiceDataSourceFactory> sInstance;
+    static Mutex sInstanceLock;
+    PlayerServiceDataSourceFactory() {};
+};
+
+}  // namespace android
+
+#endif  // PLAYER_SERVICE_DATA_SOURCE_FACTORY_H_
diff --git a/media/libstagefright/include/media/stagefright/FileSource.h b/media/libmediaplayerservice/datasource/include/datasource/PlayerServiceFileSource.h
similarity index 65%
rename from media/libstagefright/include/media/stagefright/FileSource.h
rename to media/libmediaplayerservice/datasource/include/datasource/PlayerServiceFileSource.h
index b610eef..08a013e 100644
--- a/media/libstagefright/include/media/stagefright/FileSource.h
+++ b/media/libmediaplayerservice/datasource/include/datasource/PlayerServiceFileSource.h
@@ -14,24 +14,26 @@
  * limitations under the License.
  */
 
-#ifndef FILE_SOURCE_H_
+#ifndef PLAYER_SERVICE_FILE_SOURCE_H_
 
-#define FILE_SOURCE_H_
+#define PLAYER_SERVICE_FILE_SOURCE_H_
 
 #include <stdio.h>
 
-#include <media/stagefright/ClearFileSource.h>
+#include <datasource/FileSource.h>
 #include <media/stagefright/MediaErrors.h>
 #include <utils/threads.h>
 #include <drm/DrmManagerClient.h>
 
 namespace android {
 
-class FileSource : public ClearFileSource {
+// FileSource implementation which works on MediaPlayerService.
+// Supports OMA(forword-lock) files.
+class PlayerServiceFileSource : public FileSource {
 public:
-    FileSource(const char *filename);
-    // FileSource takes ownership and will close the fd
-    FileSource(int fd, int64_t offset, int64_t length);
+    PlayerServiceFileSource(const char *filename);
+    // PlayerServiceFileSource takes ownership and will close the fd
+    PlayerServiceFileSource(int fd, int64_t offset, int64_t length);
 
     virtual ssize_t readAt(off64_t offset, void *data, size_t size);
 
@@ -40,7 +42,7 @@
     static bool requiresDrm(int fd, int64_t offset, int64_t length, const char *mime);
 
 protected:
-    virtual ~FileSource();
+    virtual ~PlayerServiceFileSource();
 
 private:
     /*for DRM*/
@@ -52,11 +54,11 @@
 
     ssize_t readAtDRM_l(off64_t offset, void *data, size_t size);
 
-    FileSource(const FileSource &);
-    FileSource &operator=(const FileSource &);
+    PlayerServiceFileSource(const PlayerServiceFileSource &);
+    PlayerServiceFileSource &operator=(const PlayerServiceFileSource &);
 };
 
 }  // namespace android
 
-#endif  // FILE_SOURCE_H_
+#endif  // PLAYER_SERVICE_FILE_SOURCE_H_
 
diff --git a/media/libstagefright/include/media/stagefright/MediaHTTP.h b/media/libmediaplayerservice/datasource/include/datasource/PlayerServiceMediaHTTP.h
similarity index 67%
rename from media/libstagefright/include/media/stagefright/MediaHTTP.h
rename to media/libmediaplayerservice/datasource/include/datasource/PlayerServiceMediaHTTP.h
index acaa6c4..0032cd7 100644
--- a/media/libstagefright/include/media/stagefright/MediaHTTP.h
+++ b/media/libmediaplayerservice/datasource/include/datasource/PlayerServiceMediaHTTP.h
@@ -14,22 +14,24 @@
  * limitations under the License.
  */
 
-#ifndef MEDIA_HTTP_H_
+#ifndef PLAYER_SERVICE_MEDIA_HTTP_H_
 
-#define MEDIA_HTTP_H_
+#define PLAYER_SERVICE_MEDIA_HTTP_H_
 
+#include <datasource/MediaHTTP.h>
 #include <media/stagefright/foundation/AString.h>
-#include <media/stagefright/ClearMediaHTTP.h>
 
 namespace android {
 
 struct MediaHTTPConnection;
 
-struct MediaHTTP : public ClearMediaHTTP {
-    MediaHTTP(const sp<MediaHTTPConnection> &conn);
+// MediaHTTP implementation which works on MediaPlayerService.
+// Supports OMA(forword-lock) stream.
+struct PlayerServiceMediaHTTP : public MediaHTTP {
+    PlayerServiceMediaHTTP(const sp<MediaHTTPConnection> &conn);
 
 protected:
-    virtual ~MediaHTTP();
+    virtual ~PlayerServiceMediaHTTP();
 
     virtual sp<DecryptHandle> DrmInitialization(const char* mime);
 
@@ -39,9 +41,9 @@
 
     void clearDRMState_l();
 
-    DISALLOW_EVIL_CONSTRUCTORS(MediaHTTP);
+    DISALLOW_EVIL_CONSTRUCTORS(PlayerServiceMediaHTTP);
 };
 
 }  // namespace android
 
-#endif  // MEDIA_HTTP_H_
+#endif  // PLAYER_SERVICE_MEDIA_HTTP_H_
diff --git a/media/libmediaplayerservice/include/MediaPlayerInterface.h b/media/libmediaplayerservice/include/MediaPlayerInterface.h
index 0ad4d04..436cb31 100644
--- a/media/libmediaplayerservice/include/MediaPlayerInterface.h
+++ b/media/libmediaplayerservice/include/MediaPlayerInterface.h
@@ -27,7 +27,6 @@
 
 #include <media/mediaplayer.h>
 #include <media/AudioResamplerPublic.h>
-#include <media/AudioSystem.h>
 #include <media/AudioTimestamp.h>
 #include <media/AVSyncSettings.h>
 #include <media/BufferingSettings.h>
diff --git a/media/libmediaplayerservice/nuplayer/Android.bp b/media/libmediaplayerservice/nuplayer/Android.bp
index 23a19e7..c8f48a2 100644
--- a/media/libmediaplayerservice/nuplayer/Android.bp
+++ b/media/libmediaplayerservice/nuplayer/Android.bp
@@ -18,6 +18,7 @@
     ],
 
     header_libs: [
+        "libmediadrm_headers",
         "media_plugin_headers",
     ],
 
@@ -45,6 +46,7 @@
 
     shared_libs: [
         "libbinder",
+        "libdatasource",
         "libui",
         "libgui",
         "libmedia",
@@ -52,6 +54,10 @@
         "libpowermanager",
     ],
 
+    static_libs: [
+        "libplayerservice_datasource",
+    ],
+
     name: "libstagefright_nuplayer",
 
     sanitize: {
diff --git a/media/libmediaplayerservice/nuplayer/GenericSource.cpp b/media/libmediaplayerservice/nuplayer/GenericSource.cpp
index 4653711..00e3443 100644
--- a/media/libmediaplayerservice/nuplayer/GenericSource.cpp
+++ b/media/libmediaplayerservice/nuplayer/GenericSource.cpp
@@ -23,6 +23,10 @@
 #include "AnotherPacketSource.h"
 #include <binder/IServiceManager.h>
 #include <cutils/properties.h>
+#include <datasource/PlayerServiceDataSourceFactory.h>
+#include <datasource/PlayerServiceFileSource.h>
+#include <datasource/HTTPBase.h>
+#include <datasource/NuCachedSource2.h>
 #include <media/DataSource.h>
 #include <media/MediaBufferHolder.h>
 #include <media/MediaSource.h>
@@ -31,8 +35,6 @@
 #include <media/stagefright/foundation/ABuffer.h>
 #include <media/stagefright/foundation/ADebug.h>
 #include <media/stagefright/foundation/AMessage.h>
-#include <media/stagefright/DataSourceFactory.h>
-#include <media/stagefright/FileSource.h>
 #include <media/stagefright/InterfaceUtils.h>
 #include <media/stagefright/MediaBuffer.h>
 #include <media/stagefright/MediaClock.h>
@@ -41,8 +43,6 @@
 #include <media/stagefright/MediaExtractorFactory.h>
 #include <media/stagefright/MetaData.h>
 #include <media/stagefright/Utils.h>
-#include "../../libstagefright/include/NuCachedSource2.h"
-#include "../../libstagefright/include/HTTPBase.h"
 
 namespace android {
 
@@ -385,7 +385,8 @@
             if (!strncasecmp("http://", uri, 7) || !strncasecmp("https://", uri, 8)) {
                 sp<DataSource> httpSource;
                 mDisconnectLock.unlock();
-                httpSource = DataSourceFactory::CreateMediaHTTP(mHTTPService);
+                httpSource = PlayerServiceDataSourceFactory::getInstance()
+                        ->CreateMediaHTTP(mHTTPService);
                 if (httpSource == NULL) {
                     ALOGE("Failed to create http source!");
                     notifyPreparedAndCleanup(UNKNOWN_ERROR);
@@ -401,9 +402,9 @@
             mLock.unlock();
             mDisconnectLock.unlock();
             // This might take long time if connection has some issue.
-            sp<DataSource> dataSource = DataSourceFactory::CreateFromURI(
-                   mHTTPService, uri, &mUriHeaders, &contentType,
-                   static_cast<HTTPBase *>(mHttpSource.get()));
+            sp<DataSource> dataSource = PlayerServiceDataSourceFactory::getInstance()
+                    ->CreateFromURI(mHTTPService, uri, &mUriHeaders, &contentType,
+                            static_cast<HTTPBase *>(mHttpSource.get()));
             mDisconnectLock.lock();
             mLock.lock();
             if (!mDisconnected) {
@@ -411,7 +412,8 @@
             }
         } else {
             if (property_get_bool("media.stagefright.extractremote", true) &&
-                    !FileSource::requiresDrm(mFd, mOffset, mLength, nullptr /* mime */)) {
+                    !PlayerServiceFileSource::requiresDrm(
+                            mFd, mOffset, mLength, nullptr /* mime */)) {
                 sp<IBinder> binder =
                         defaultServiceManager()->getService(String16("media.extractor"));
                 if (binder != nullptr) {
@@ -438,7 +440,7 @@
             }
             if (mDataSource == nullptr) {
                 ALOGD("FileSource local");
-                mDataSource = new FileSource(mFd, mOffset, mLength);
+                mDataSource = new PlayerServiceFileSource(mFd, mOffset, mLength);
             }
             // TODO: close should always be done on mFd, see the lines following
             // CreateDataSourceFromIDataSource above,
@@ -782,7 +784,7 @@
         return;
     }
 
-    int64_t nextSubTimeUs;
+    int64_t nextSubTimeUs = 0;
     readBuffer(type, -1, MediaPlayerSeekMode::SEEK_PREVIOUS_SYNC /* mode */, &nextSubTimeUs);
 
     sp<ABuffer> buffer;
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.h b/media/libmediaplayerservice/nuplayer/NuPlayer.h
index 9f5be06..0e58ec2 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.h
@@ -19,7 +19,7 @@
 #define NU_PLAYER_H_
 
 #include <media/AudioResamplerPublic.h>
-#include <media/ICrypto.h>
+#include <mediadrm/ICrypto.h>
 #include <media/MediaPlayerInterface.h>
 #include <media/stagefright/foundation/AHandler.h>
 
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
index 2f0da2d..bd2b884 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
@@ -28,7 +28,7 @@
 #include "NuPlayerSource.h"
 
 #include <cutils/properties.h>
-#include <media/ICrypto.h>
+#include <mediadrm/ICrypto.h>
 #include <media/MediaBufferHolder.h>
 #include <media/MediaCodecBuffer.h>
 #include <media/stagefright/foundation/ABuffer.h>
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoderPassThrough.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDecoderPassThrough.cpp
index 0997e7d..793014e 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoderPassThrough.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoderPassThrough.cpp
@@ -24,7 +24,7 @@
 #include "NuPlayerRenderer.h"
 #include "NuPlayerSource.h"
 
-#include <media/ICrypto.h>
+#include <mediadrm/ICrypto.h>
 #include <media/MediaCodecBuffer.h>
 #include <media/stagefright/foundation/ABuffer.h>
 #include <media/stagefright/foundation/ADebug.h>
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
index 865cb2a..95c973a 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
@@ -33,6 +33,7 @@
 #include <media/stagefright/MediaClock.h>
 #include <media/stagefright/MetaData.h>
 #include <media/stagefright/Utils.h>
+#include <media/stagefright/FoundationUtils.h>
 
 #include <media/IMediaAnalyticsService.h>
 
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDrm.h b/media/libmediaplayerservice/nuplayer/NuPlayerDrm.h
index 50f69ff..4360656 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDrm.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDrm.h
@@ -18,8 +18,8 @@
 #define NUPLAYER_DRM_H_
 
 #include <binder/Parcel.h>
-#include <media/ICrypto.h>
-#include <media/IDrm.h>
+#include <mediadrm/ICrypto.h>
+#include <mediadrm/IDrm.h>
 #include <media/stagefright/MetaData.h> // for CryptInfo
 
 
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerSource.h b/media/libmediaplayerservice/nuplayer/NuPlayerSource.h
index 9f5ef78..f137c52 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerSource.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerSource.h
@@ -20,7 +20,7 @@
 
 #include "NuPlayer.h"
 
-#include <media/ICrypto.h>
+#include <mediadrm/ICrypto.h>
 #include <media/mediaplayer.h>
 #include <media/stagefright/foundation/AMessage.h>
 #include <media/stagefright/MetaData.h>
diff --git a/media/libnbaio/Android.bp b/media/libnbaio/Android.bp
index a4df38d..04ddcff 100644
--- a/media/libnbaio/Android.bp
+++ b/media/libnbaio/Android.bp
@@ -1,4 +1,3 @@
-
 cc_defaults {
     name: "libnbaio_mono_defaults",
     srcs: [
@@ -9,20 +8,27 @@
     header_libs: [
         "libaudioclient_headers",
         "libaudio_system_headers",
-        "libmedia_headers",
     ],
     export_header_lib_headers: [
         "libaudioclient_headers",
-        "libmedia_headers",
     ],
 
     shared_libs: [
         "libaudioutils",
+        "libcutils",
         "liblog",
         "libutils",
     ],
+    export_shared_lib_headers: [
+        "libaudioutils",
+    ],
 
     export_include_dirs: ["include_mono"],
+
+    cflags: [
+        "-Werror",
+        "-Wall",
+    ],
 }
 
 // libnbaio_mono is the part of libnbaio that is available for vendors to use. Vendor modules can't
@@ -53,20 +59,7 @@
     // ],
     // static_libs: ["libsndfile"],
 
-    shared_libs: [
-        "libaudioutils",
-        "libbinder",
-        "libcutils",
-        "liblog",
-        "libutils",
-    ],
-
-    cflags: [
-        "-Werror",
-        "-Wall",
-    ],
-
-    include_dirs: ["system/media/audio_utils/include"],
+    header_libs: ["libaudiohal_headers"],
 
     export_include_dirs: ["include"],
 }
diff --git a/media/libnbaio/include_mono/media/nbaio/MonoPipe.h b/media/libnbaio/include_mono/media/nbaio/MonoPipe.h
index c51d0fe..926d84a 100644
--- a/media/libnbaio/include_mono/media/nbaio/MonoPipe.h
+++ b/media/libnbaio/include_mono/media/nbaio/MonoPipe.h
@@ -19,7 +19,7 @@
 
 #include <time.h>
 #include <audio_utils/fifo.h>
-#include <media/SingleStateQueue.h>
+#include <media/nbaio/SingleStateQueue.h>
 #include <media/nbaio/NBAIO.h>
 
 namespace android {
diff --git a/media/libmedia/include/media/SingleStateQueue.h b/media/libnbaio/include_mono/media/nbaio/SingleStateQueue.h
similarity index 100%
rename from media/libmedia/include/media/SingleStateQueue.h
rename to media/libnbaio/include_mono/media/nbaio/SingleStateQueue.h
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index 369e13f..cfefe11 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -2410,7 +2410,7 @@
         }
         rate = (OMX_U32)(rateFloat * 65536.0f + 0.5f);
     } else {
-        if (rateFloat > UINT_MAX) {
+        if (rateFloat > static_cast<float>(UINT_MAX)) {
             return BAD_VALUE;
         }
         rate = (OMX_U32)(rateFloat);
@@ -3316,6 +3316,7 @@
     { MEDIA_MIMETYPE_VIDEO_VP9, OMX_VIDEO_CodingVP9 },
     { MEDIA_MIMETYPE_VIDEO_DOLBY_VISION, OMX_VIDEO_CodingDolbyVision },
     { MEDIA_MIMETYPE_IMAGE_ANDROID_HEIC, OMX_VIDEO_CodingImageHEIC },
+    { MEDIA_MIMETYPE_VIDEO_AV1, OMX_VIDEO_CodingAV1 },
 };
 
 static status_t GetVideoCodingTypeFromMime(
diff --git a/media/libstagefright/Android.bp b/media/libstagefright/Android.bp
index 9170805..59cc24b 100644
--- a/media/libstagefright/Android.bp
+++ b/media/libstagefright/Android.bp
@@ -19,8 +19,10 @@
         ],
         cfi: true,
     },
-
-    shared_libs: ["libmedia"],
+    shared_libs: [
+        "libstagefright_foundation",
+        "libutils"
+    ],
 }
 
 cc_library_static {
@@ -58,10 +60,14 @@
         "-Wall",
     ],
 
+    header_libs: [
+        "libmediadrm_headers",
+    ],
+
     shared_libs: [
         "libgui",
         "liblog",
-        "libmedia_omx",
+        "libmedia_codeclist",
         "libstagefright_foundation",
         "libui",
         "libutils",
@@ -121,7 +127,6 @@
         "ACodecBufferChannel.cpp",
         "AHierarchicalStateMachine.cpp",
         "AMRWriter.cpp",
-        "AudioPlayer.cpp",
         "AudioSource.cpp",
         "BufferImpl.cpp",
         "CallbackDataSource.cpp",
@@ -129,13 +134,7 @@
         "CameraSource.cpp",
         "CameraSourceTimeLapse.cpp",
         "DataConverter.cpp",
-        "DataSourceBase.cpp",
-        "DataSourceFactory.cpp",
-        "DataURISource.cpp",
-        "ClearFileSource.cpp",
-        "FileSource.cpp",
         "FrameDecoder.cpp",
-        "HTTPBase.cpp",
         "HevcUtils.cpp",
         "InterfaceUtils.cpp",
         "JPEGSource.cpp",
@@ -152,10 +151,7 @@
         "MediaSource.cpp",
         "MediaSync.cpp",
         "MediaTrack.cpp",
-        "http/ClearMediaHTTP.cpp",
-        "http/MediaHTTP.cpp",
         "MediaMuxer.cpp",
-        "NuCachedSource2.cpp",
         "NuMediaExtractor.cpp",
         "OggWriter.cpp",
         "OMXClient.cpp",
@@ -165,11 +161,10 @@
         "SimpleDecodingSource.cpp",
         "SkipCutBuffer.cpp",
         "StagefrightMediaScanner.cpp",
-        "StagefrightMetadataRetriever.cpp",
         "StagefrightPluginLoader.cpp",
         "SurfaceUtils.cpp",
-        "Utils.cpp",
         "ThrottledSource.cpp",
+        "Utils.cpp",
         "VideoFrameSchedulerBase.cpp",
         "VideoFrameScheduler.cpp",
     ],
@@ -180,12 +175,13 @@
         "libbinder",
         "libcamera_client",
         "libcutils",
+        "libdatasource",
         "libdl",
         "libdl_android",
-        "libdrmframework",
         "libgui",
         "liblog",
         "libmedia",
+        "libmedia_codeclist",
         "libmedia_omx",
         "libmedia_omx_client",
         "libaudioclient",
@@ -207,6 +203,7 @@
     ],
 
     static_libs: [
+        "libstagefright_esds",
         "libstagefright_color_conversion",
         "libyuv_static",
         "libstagefright_mediafilter",
@@ -214,13 +211,12 @@
         "libstagefright_timedtext",
         "libogg",
         "libwebm",
-        "libstagefright_esds",
         "libstagefright_id3",
-        "libFLAC",
     ],
 
     header_libs:[
-        "libnativeloader-dummy-headers",
+        "libmediadrm_headers",
+        "libnativeloader-headers",
         "libstagefright_xmlparser_headers",
         "media_ndk_headers",
     ],
@@ -260,63 +256,3 @@
         ],
     },
 }
-
-cc_library_static {
-    name: "libstagefright_player2",
-
-    srcs: [
-        "ClearFileSource.cpp",
-        "DataURISource.cpp",
-        "DataSourceBase.cpp",
-        "HTTPBase.cpp",
-        "HevcUtils.cpp",
-        "MediaClock.cpp",
-        "MediaSource.cpp",
-        "NdkUtils.cpp",
-        "Utils.cpp",
-        "VideoFrameSchedulerBase.cpp",
-        "VideoFrameScheduler2.cpp",
-        "http/ClearMediaHTTP.cpp",
-    ],
-
-    shared_libs: [
-        "libgui",
-        "liblog",
-        "libnetd_client",
-        "libutils",
-        "libstagefright_foundation",
-        "libandroid",
-    ],
-
-    static_libs: [
-        "libmedia_player2_util",
-        "libmedia2_jni_core",
-    ],
-
-    export_include_dirs: [
-        "include",
-    ],
-
-    cflags: [
-        "-Wno-multichar",
-        "-Werror",
-        "-Wno-error=deprecated-declarations",
-        "-Wall",
-    ],
-
-    product_variables: {
-        debuggable: {
-            // enable experiments only in userdebug and eng builds
-            cflags: ["-DENABLE_STAGEFRIGHT_EXPERIMENTS"],
-        },
-    },
-
-    sanitize: {
-        cfi: true,
-        misc_undefined: [
-            "unsigned-integer-overflow",
-            "signed-integer-overflow",
-        ],
-    },
-}
-
diff --git a/media/libstagefright/BufferImpl.cpp b/media/libstagefright/BufferImpl.cpp
index b760273..f73b625 100644
--- a/media/libstagefright/BufferImpl.cpp
+++ b/media/libstagefright/BufferImpl.cpp
@@ -21,7 +21,7 @@
 #include <binder/IMemory.h>
 #include <media/stagefright/foundation/ABuffer.h>
 #include <media/stagefright/foundation/AMessage.h>
-#include <media/ICrypto.h>
+#include <mediadrm/ICrypto.h>
 #include <utils/NativeHandle.h>
 
 #include "include/SecureBuffer.h"
diff --git a/media/libstagefright/CodecBase.cpp b/media/libstagefright/CodecBase.cpp
index d0610b2..97f38f8 100644
--- a/media/libstagefright/CodecBase.cpp
+++ b/media/libstagefright/CodecBase.cpp
@@ -18,7 +18,7 @@
 #define LOG_TAG "CodecBase"
 
 #include <android/hardware/cas/native/1.0/IDescrambler.h>
-#include <media/ICrypto.h>
+#include <mediadrm/ICrypto.h>
 #include <media/stagefright/CodecBase.h>
 #include <utils/Log.h>
 
diff --git a/media/libstagefright/DataSourceBase.cpp b/media/libstagefright/DataSourceBase.cpp
deleted file mode 100644
index 8f47ee5..0000000
--- a/media/libstagefright/DataSourceBase.cpp
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Copyright (C) 2009 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 "DataSourceBase"
-
-#include <media/DataSourceBase.h>
-#include <media/stagefright/foundation/ByteUtils.h>
-#include <media/stagefright/MediaErrors.h>
-#include <utils/String8.h>
-
-namespace android {
-
-bool DataSourceBase::getUInt16(off64_t offset, uint16_t *x) {
-    *x = 0;
-
-    uint8_t byte[2];
-    if (readAt(offset, byte, 2) != 2) {
-        return false;
-    }
-
-    *x = (byte[0] << 8) | byte[1];
-
-    return true;
-}
-
-bool DataSourceBase::getUInt24(off64_t offset, uint32_t *x) {
-    *x = 0;
-
-    uint8_t byte[3];
-    if (readAt(offset, byte, 3) != 3) {
-        return false;
-    }
-
-    *x = (byte[0] << 16) | (byte[1] << 8) | byte[2];
-
-    return true;
-}
-
-bool DataSourceBase::getUInt32(off64_t offset, uint32_t *x) {
-    *x = 0;
-
-    uint32_t tmp;
-    if (readAt(offset, &tmp, 4) != 4) {
-        return false;
-    }
-
-    *x = ntohl(tmp);
-
-    return true;
-}
-
-bool DataSourceBase::getUInt64(off64_t offset, uint64_t *x) {
-    *x = 0;
-
-    uint64_t tmp;
-    if (readAt(offset, &tmp, 8) != 8) {
-        return false;
-    }
-
-    *x = ntoh64(tmp);
-
-    return true;
-}
-
-bool DataSourceBase::getUInt16Var(off64_t offset, uint16_t *x, size_t size) {
-    if (size == 2) {
-        return getUInt16(offset, x);
-    }
-    if (size == 1) {
-        uint8_t tmp;
-        if (readAt(offset, &tmp, 1) == 1) {
-            *x = tmp;
-            return true;
-        }
-    }
-    return false;
-}
-
-bool DataSourceBase::getUInt32Var(off64_t offset, uint32_t *x, size_t size) {
-    if (size == 4) {
-        return getUInt32(offset, x);
-    }
-    if (size == 2) {
-        uint16_t tmp;
-        if (getUInt16(offset, &tmp)) {
-            *x = tmp;
-            return true;
-        }
-    }
-    return false;
-}
-
-bool DataSourceBase::getUInt64Var(off64_t offset, uint64_t *x, size_t size) {
-    if (size == 8) {
-        return getUInt64(offset, x);
-    }
-    if (size == 4) {
-        uint32_t tmp;
-        if (getUInt32(offset, &tmp)) {
-            *x = tmp;
-            return true;
-        }
-    }
-    return false;
-}
-
-status_t DataSourceBase::getSize(off64_t *size) {
-    *size = 0;
-
-    return ERROR_UNSUPPORTED;
-}
-
-bool DataSourceBase::getUri(char *uriString __unused, size_t bufferSize __unused) {
-    return false;
-}
-
-}  // namespace android
diff --git a/media/libstagefright/FrameDecoder.cpp b/media/libstagefright/FrameDecoder.cpp
index 18a6bd8..08f690b 100644
--- a/media/libstagefright/FrameDecoder.cpp
+++ b/media/libstagefright/FrameDecoder.cpp
@@ -22,7 +22,7 @@
 #include <binder/MemoryHeapBase.h>
 #include <gui/Surface.h>
 #include <inttypes.h>
-#include <media/ICrypto.h>
+#include <mediadrm/ICrypto.h>
 #include <media/IMediaSource.h>
 #include <media/MediaCodecBuffer.h>
 #include <media/stagefright/foundation/avc_utils.h>
@@ -725,12 +725,6 @@
     }
     converter.setSrcColorSpace(standard, range, transfer);
 
-    int32_t dstLeft, dstTop, dstRight, dstBottom;
-    dstLeft = mTilesDecoded % mGridCols * width;
-    dstTop = mTilesDecoded / mGridCols * height;
-    dstRight = dstLeft + width - 1;
-    dstBottom = dstTop + height - 1;
-
     int32_t crop_left, crop_top, crop_right, crop_bottom;
     if (!outputFormat->findRect("crop", &crop_left, &crop_top, &crop_right, &crop_bottom)) {
         crop_left = crop_top = 0;
@@ -738,15 +732,25 @@
         crop_bottom = height - 1;
     }
 
+    int32_t crop_width, crop_height;
+    crop_width = crop_right - crop_left + 1;
+    crop_height = crop_bottom - crop_top + 1;
+
+    int32_t dstLeft, dstTop, dstRight, dstBottom;
+    dstLeft = mTilesDecoded % mGridCols * crop_width;
+    dstTop = mTilesDecoded / mGridCols * crop_height;
+    dstRight = dstLeft + crop_width - 1;
+    dstBottom = dstTop + crop_height - 1;
+
     // apply crop on bottom-right
     // TODO: need to move this into the color converter itself.
     if (dstRight >= mWidth) {
-        crop_right = mWidth - dstLeft - 1;
-        dstRight = dstLeft + crop_right;
+        crop_right = crop_left + mWidth - dstLeft - 1;
+        dstRight = mWidth - 1;
     }
     if (dstBottom >= mHeight) {
-        crop_bottom = mHeight - dstTop - 1;
-        dstBottom = dstTop + crop_bottom;
+        crop_bottom = crop_top + mHeight - dstTop - 1;
+        dstBottom = mHeight - 1;
     }
 
     *done = (++mTilesDecoded >= mTargetTiles);
diff --git a/media/libstagefright/MediaClock.cpp b/media/libstagefright/MediaClock.cpp
index 4f9bc6d..24608a7 100644
--- a/media/libstagefright/MediaClock.cpp
+++ b/media/libstagefright/MediaClock.cpp
@@ -281,7 +281,7 @@
             it = mTimers.erase(it);
         } else {
             if (mPlaybackRate != 0.0
-                && (double)diffMediaUs < INT64_MAX * (double)mPlaybackRate) {
+                && (double)diffMediaUs < (double)INT64_MAX * (double)mPlaybackRate) {
                 int64_t targetRealUs = diffMediaUs / (double)mPlaybackRate;
                 if (targetRealUs < nextLapseRealUs) {
                     nextLapseRealUs = targetRealUs;
diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp
index eceb84e..3d6ebc3 100644
--- a/media/libstagefright/MediaCodec.cpp
+++ b/media/libstagefright/MediaCodec.cpp
@@ -35,7 +35,7 @@
 #include <cutils/properties.h>
 #include <gui/BufferQueue.h>
 #include <gui/Surface.h>
-#include <media/ICrypto.h>
+#include <mediadrm/ICrypto.h>
 #include <media/IOMX.h>
 #include <media/IResourceManagerService.h>
 #include <media/MediaCodecBuffer.h>
diff --git a/media/libstagefright/MediaCodecList.cpp b/media/libstagefright/MediaCodecList.cpp
index 3d58d4b..a267f7e 100644
--- a/media/libstagefright/MediaCodecList.cpp
+++ b/media/libstagefright/MediaCodecList.cpp
@@ -170,6 +170,7 @@
 sp<IMediaCodecList> MediaCodecList::sRemoteList;
 
 sp<MediaCodecList::BinderDeathObserver> MediaCodecList::sBinderDeathObserver;
+sp<IBinder> MediaCodecList::sMediaPlayer;  // kept since linked to death
 
 void MediaCodecList::BinderDeathObserver::binderDied(const wp<IBinder> &who __unused) {
     Mutex::Autolock _l(sRemoteInitMutex);
@@ -181,15 +182,14 @@
 sp<IMediaCodecList> MediaCodecList::getInstance() {
     Mutex::Autolock _l(sRemoteInitMutex);
     if (sRemoteList == nullptr) {
-        sp<IBinder> binder =
-            defaultServiceManager()->getService(String16("media.player"));
+        sMediaPlayer = defaultServiceManager()->getService(String16("media.player"));
         sp<IMediaPlayerService> service =
-            interface_cast<IMediaPlayerService>(binder);
+            interface_cast<IMediaPlayerService>(sMediaPlayer);
         if (service.get() != nullptr) {
             sRemoteList = service->getCodecList();
             if (sRemoteList != nullptr) {
                 sBinderDeathObserver = new BinderDeathObserver();
-                binder->linkToDeath(sBinderDeathObserver.get());
+                sMediaPlayer->linkToDeath(sBinderDeathObserver.get());
             }
         }
         if (sRemoteList == nullptr) {
diff --git a/media/libstagefright/MediaCodecListOverrides.cpp b/media/libstagefright/MediaCodecListOverrides.cpp
index dd7c3e6..b027a97 100644
--- a/media/libstagefright/MediaCodecListOverrides.cpp
+++ b/media/libstagefright/MediaCodecListOverrides.cpp
@@ -22,7 +22,7 @@
 
 #include <cutils/properties.h>
 #include <gui/Surface.h>
-#include <media/ICrypto.h>
+#include <mediadrm/ICrypto.h>
 #include <media/IMediaCodecList.h>
 #include <media/MediaCodecInfo.h>
 #include <media/MediaResourcePolicy.h>
diff --git a/media/libstagefright/MediaCodecSource.cpp b/media/libstagefright/MediaCodecSource.cpp
index 50e454c..7243b82 100644
--- a/media/libstagefright/MediaCodecSource.cpp
+++ b/media/libstagefright/MediaCodecSource.cpp
@@ -22,7 +22,7 @@
 
 #include <gui/IGraphicBufferProducer.h>
 #include <gui/Surface.h>
-#include <media/ICrypto.h>
+#include <mediadrm/ICrypto.h>
 #include <media/MediaBufferHolder.h>
 #include <media/MediaCodecBuffer.h>
 #include <media/MediaSource.h>
diff --git a/media/libstagefright/NdkUtils.cpp b/media/libstagefright/NdkUtils.cpp
deleted file mode 100644
index 904fe72..0000000
--- a/media/libstagefright/NdkUtils.cpp
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2018 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
-
-#include <media/stagefright/NdkUtils.h>
-#include <media/stagefright/Utils.h>
-#include <media/stagefright/foundation/AMessage.h>
-
-namespace android {
-
-sp<MetaData> convertMediaFormatWrapperToMetaData(const sp<AMediaFormatWrapper> &fmt) {
-    sp<AMessage> msg = fmt->toAMessage();
-    sp<MetaData> meta = new MetaData;
-    convertMessageToMetaData(msg, meta);
-    return meta;
-}
-
-}  // namespace android
-
diff --git a/media/libstagefright/NuMediaExtractor.cpp b/media/libstagefright/NuMediaExtractor.cpp
index 680d426..66fb4b0 100644
--- a/media/libstagefright/NuMediaExtractor.cpp
+++ b/media/libstagefright/NuMediaExtractor.cpp
@@ -22,13 +22,13 @@
 
 #include "include/ESDS.h"
 
+#include <datasource/DataSourceFactory.h>
+#include <datasource/FileSource.h>
 #include <media/DataSource.h>
 #include <media/MediaSource.h>
 #include <media/stagefright/foundation/ABuffer.h>
 #include <media/stagefright/foundation/ADebug.h>
 #include <media/stagefright/foundation/AMessage.h>
-#include <media/stagefright/DataSourceFactory.h>
-#include <media/stagefright/FileSource.h>
 #include <media/stagefright/MediaBuffer.h>
 #include <media/stagefright/MediaDefs.h>
 #include <media/stagefright/MediaErrors.h>
@@ -36,6 +36,7 @@
 #include <media/stagefright/MediaExtractorFactory.h>
 #include <media/stagefright/MetaData.h>
 #include <media/stagefright/Utils.h>
+#include <media/stagefright/FoundationUtils.h>
 
 namespace android {
 
@@ -81,7 +82,7 @@
     }
 
     sp<DataSource> dataSource =
-        DataSourceFactory::CreateFromURI(httpService, path, headers);
+        DataSourceFactory::getInstance()->CreateFromURI(httpService, path, headers);
 
     if (dataSource == NULL) {
         return -ENOENT;
diff --git a/media/libstagefright/SimpleDecodingSource.cpp b/media/libstagefright/SimpleDecodingSource.cpp
index babdc7a..b809848 100644
--- a/media/libstagefright/SimpleDecodingSource.cpp
+++ b/media/libstagefright/SimpleDecodingSource.cpp
@@ -20,7 +20,7 @@
 
 #include <gui/Surface.h>
 
-#include <media/ICrypto.h>
+#include <mediadrm/ICrypto.h>
 #include <media/MediaCodecBuffer.h>
 #include <media/stagefright/MediaDefs.h>
 #include <media/stagefright/foundation/ALooper.h>
diff --git a/media/libstagefright/Utils.cpp b/media/libstagefright/Utils.cpp
index 135151f..c20dfe2 100644
--- a/media/libstagefright/Utils.cpp
+++ b/media/libstagefright/Utils.cpp
@@ -1806,7 +1806,7 @@
     if (msg->findInt32("frame-rate", &fps) && fps > 0) {
         meta->setInt32(kKeyFrameRate, fps);
     } else if (msg->findFloat("frame-rate", &fpsFloat)
-            && fpsFloat >= 1 && fpsFloat <= INT32_MAX) {
+            && fpsFloat >= 1 && static_cast<int32_t>(fpsFloat) <= INT32_MAX) {
         // truncate values to distinguish between e.g. 24 vs 23.976 fps
         meta->setInt32(kKeyFrameRate, (int32_t)fpsFloat);
     }
@@ -1895,22 +1895,6 @@
 #endif
 }
 
-AString MakeUserAgent() {
-    AString ua;
-    ua.append("stagefright/1.2 (Linux;Android ");
-
-#if (PROPERTY_VALUE_MAX < 8)
-#error "PROPERTY_VALUE_MAX must be at least 8"
-#endif
-
-    char value[PROPERTY_VALUE_MAX];
-    property_get("ro.build.version.release", value, "Unknown");
-    ua.append(value);
-    ua.append(")");
-
-    return ua;
-}
-
 status_t sendMetaDataToHal(sp<MediaPlayerBase::AudioSink>& sink,
                            const sp<MetaData>& meta)
 {
@@ -2099,39 +2083,6 @@
     return AudioSystem::isOffloadSupported(info);
 }
 
-AString uriDebugString(const AString &uri, bool incognito) {
-    if (incognito) {
-        return AString("<URI suppressed>");
-    }
-
-    if (property_get_bool("media.stagefright.log-uri", false)) {
-        return uri;
-    }
-
-    // find scheme
-    AString scheme;
-    const char *chars = uri.c_str();
-    for (size_t i = 0; i < uri.size(); i++) {
-        const char c = chars[i];
-        if (!isascii(c)) {
-            break;
-        } else if (isalpha(c)) {
-            continue;
-        } else if (i == 0) {
-            // first character must be a letter
-            break;
-        } else if (isdigit(c) || c == '+' || c == '.' || c =='-') {
-            continue;
-        } else if (c != ':') {
-            break;
-        }
-        scheme = AString(uri, 0, i);
-        scheme.append("://<suppressed>");
-        return scheme;
-    }
-    return AString("<no-scheme URI suppressed>");
-}
-
 HLSTime::HLSTime(const sp<AMessage>& meta) :
     mSeq(-1),
     mTimeUs(-1LL),
@@ -2230,36 +2181,4 @@
     }
 }
 
-AString nameForFd(int fd) {
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-    AString result;
-    snprintf(buffer, SIZE, "/proc/%d/fd/%d", getpid(), fd);
-    struct stat s;
-    if (lstat(buffer, &s) == 0) {
-        if ((s.st_mode & S_IFMT) == S_IFLNK) {
-            char linkto[256];
-            int len = readlink(buffer, linkto, sizeof(linkto));
-            if(len > 0) {
-                if(len > 255) {
-                    linkto[252] = '.';
-                    linkto[253] = '.';
-                    linkto[254] = '.';
-                    linkto[255] = 0;
-                } else {
-                    linkto[len] = 0;
-                }
-                result.append(linkto);
-            }
-        } else {
-            result.append("unexpected type for ");
-            result.append(buffer);
-        }
-    } else {
-        result.append("couldn't open ");
-        result.append(buffer);
-    }
-    return result;
-}
-
 }  // namespace android
diff --git a/media/libstagefright/VideoFrameScheduler2.cpp b/media/libstagefright/VideoFrameScheduler2.cpp
deleted file mode 100644
index 23671f2..0000000
--- a/media/libstagefright/VideoFrameScheduler2.cpp
+++ /dev/null
@@ -1,305 +0,0 @@
-/*
- * Copyright (C) 2018 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 "VideoFrameScheduler2"
-#include <utils/Log.h>
-#define ATRACE_TAG ATRACE_TAG_VIDEO
-#include <utils/Mutex.h>
-#include <utils/Thread.h>
-#include <utils/Trace.h>
-
-#include <algorithm>
-#include <jni.h>
-#include <math.h>
-
-#include <android/choreographer.h>
-#include <android/looper.h>
-#include <media/stagefright/VideoFrameScheduler2.h>
-#include <mediaplayer2/JavaVMHelper.h>
-
-#include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/foundation/AUtils.h>
-
-namespace android {
-
-static void getVsyncOffset(nsecs_t* appVsyncOffsetPtr, nsecs_t* sfVsyncOffsetPtr);
-
-/* ======================================================================= */
-/*                               VsyncTracker                              */
-/* ======================================================================= */
-
-class VsyncTracker : public RefBase{
-public:
-    VsyncTracker();
-    ~VsyncTracker() {}
-    nsecs_t getVsyncPeriod();
-    nsecs_t getVsyncTime(nsecs_t periodOffset);
-    void addSample(nsecs_t timestamp);
-
-private:
-    static const int kMaxSamples = 32;
-    static const int kMinSamplesForUpdate = 6;
-    int mNumSamples;
-    int mFirstSample;
-    nsecs_t mReferenceTime;
-    nsecs_t mPhase;
-    nsecs_t mPeriod;
-    nsecs_t mTimestampSamples[kMaxSamples];
-    Mutex mLock;
-
-    void updateModelLocked();
-};
-
-VsyncTracker::VsyncTracker()
-    : mNumSamples(0),
-      mFirstSample(0),
-      mReferenceTime(0),
-      mPhase(0),
-      mPeriod(0) {
-    for (int i = 0; i < kMaxSamples; i++) {
-        mTimestampSamples[i] = 0;
-    }
-}
-
-nsecs_t VsyncTracker::getVsyncPeriod() {
-    Mutex::Autolock dataLock(mLock);
-    return mPeriod;
-}
-
-nsecs_t VsyncTracker::getVsyncTime(nsecs_t periodOffset) {
-    Mutex::Autolock dataLock(mLock);
-    const nsecs_t now = systemTime();
-    nsecs_t phase = mReferenceTime + mPhase;
-
-    // result = (((now - phase) / mPeriod) + periodOffset + 1) * mPeriod + phase
-    // prevent overflow
-    nsecs_t result = (now - phase) / mPeriod;
-    if (result > LONG_LONG_MAX - periodOffset - 1) {
-        return LONG_LONG_MAX;
-    } else {
-        result += periodOffset + 1;
-    }
-    if (result > LONG_LONG_MAX / mPeriod) {
-        return LONG_LONG_MAX;
-    } else {
-        result *= mPeriod;
-    }
-    if (result > LONG_LONG_MAX - phase) {
-        return LONG_LONG_MAX;
-    } else {
-        result += phase;
-    }
-
-    return result;
-}
-
-void VsyncTracker::addSample(nsecs_t timestamp) {
-    Mutex::Autolock dataLock(mLock);
-    if (mNumSamples == 0) {
-        mPhase = 0;
-        mReferenceTime = timestamp;
-    }
-    int idx = (mFirstSample + mNumSamples) % kMaxSamples;
-    mTimestampSamples[idx] = timestamp;
-    if (mNumSamples < kMaxSamples) {
-        mNumSamples++;
-    } else {
-        mFirstSample = (mFirstSample + 1) % kMaxSamples;
-    }
-    updateModelLocked();
-}
-
-void VsyncTracker::updateModelLocked() {
-    if (mNumSamples < kMinSamplesForUpdate) {
-        return;
-    }
-    nsecs_t durationSum = 0;
-    nsecs_t minDuration = LONG_MAX;
-    nsecs_t maxDuration = 0;
-
-    for (int i = 1; i < mNumSamples; i++) {
-        int idx = (mFirstSample + i) % kMaxSamples;
-        int prev = (idx + kMaxSamples - 1) % kMaxSamples;
-        long duration = mTimestampSamples[idx] - mTimestampSamples[prev];
-        durationSum += duration;
-        if (minDuration > duration) { minDuration = duration; }
-        if (maxDuration < duration) { maxDuration = duration; }
-    }
-
-    durationSum -= (minDuration + maxDuration);
-    mPeriod = durationSum / (mNumSamples - 3);
-
-    double sampleAvgX = 0.0;
-    double sampleAvgY = 0.0;
-    double scale = 2.0 * M_PI / (double) mPeriod;
-
-    for (int i = 1; i < mNumSamples; i++) {
-        int idx = (mFirstSample + i) % kMaxSamples;
-        long sample = mTimestampSamples[idx] - mReferenceTime;
-        double samplePhase = (double) (sample % mPeriod) * scale;
-        sampleAvgX += cos(samplePhase);
-        sampleAvgY += sin(samplePhase);
-    }
-
-    sampleAvgX /= (double) mNumSamples - 1.0;
-    sampleAvgY /= (double) mNumSamples - 1.0;
-    mPhase = (long) (atan2(sampleAvgY, sampleAvgX) / scale);
-}
-
-static void frameCallback(int64_t frameTimeNanos, void* data) {
-    if (data == NULL) {
-        return;
-    }
-    sp<VsyncTracker> vsyncTracker(static_cast<VsyncTracker*>(data));
-    vsyncTracker->addSample(frameTimeNanos);
-    AChoreographer_postFrameCallback64(AChoreographer_getInstance(),
-            frameCallback, static_cast<void*>(vsyncTracker.get()));
-}
-
-/* ======================================================================= */
-/*                                   JNI                                   */
-/* ======================================================================= */
-
-static void getVsyncOffset(nsecs_t* appVsyncOffsetPtr, nsecs_t* sfVsyncOffsetPtr) {
-    static const nsecs_t kOneMillisecInNanosec = 1000000;
-    static const nsecs_t kOneSecInNanosec = kOneMillisecInNanosec * 1000;
-
-    JNIEnv *env = JavaVMHelper::getJNIEnv();
-    jclass jDisplayManagerGlobalCls = env->FindClass(
-            "android/hardware/display/DisplayManagerGlobal");
-    jclass jDisplayCls = env->FindClass("android/view/Display");
-
-    jmethodID jGetInstance = env->GetStaticMethodID(jDisplayManagerGlobalCls,
-            "getInstance", "()Landroid/hardware/display/DisplayManagerGlobal;");
-    jobject javaDisplayManagerGlobalObj = env->CallStaticObjectMethod(
-            jDisplayManagerGlobalCls, jGetInstance);
-
-    jfieldID jDEFAULT_DISPLAY = env->GetStaticFieldID(jDisplayCls, "DEFAULT_DISPLAY", "I");
-    jint DEFAULT_DISPLAY = env->GetStaticIntField(jDisplayCls, jDEFAULT_DISPLAY);
-
-    jmethodID jgetRealDisplay = env->GetMethodID(jDisplayManagerGlobalCls,
-            "getRealDisplay", "(I)Landroid/view/Display;");
-    jobject javaDisplayObj = env->CallObjectMethod(
-            javaDisplayManagerGlobalObj, jgetRealDisplay, DEFAULT_DISPLAY);
-
-    jmethodID jGetRefreshRate = env->GetMethodID(jDisplayCls, "getRefreshRate", "()F");
-    jfloat javaRefreshRate = env->CallFloatMethod(javaDisplayObj, jGetRefreshRate);
-    nsecs_t vsyncPeriod = (nsecs_t) (kOneSecInNanosec / (float) javaRefreshRate);
-
-    jmethodID jGetAppVsyncOffsetNanos = env->GetMethodID(
-            jDisplayCls, "getAppVsyncOffsetNanos", "()J");
-    jlong javaAppVsyncOffset = env->CallLongMethod(javaDisplayObj, jGetAppVsyncOffsetNanos);
-    *appVsyncOffsetPtr = (nsecs_t) javaAppVsyncOffset;
-
-    jmethodID jGetPresentationDeadlineNanos = env->GetMethodID(
-            jDisplayCls, "getPresentationDeadlineNanos", "()J");
-    jlong javaPresentationDeadline = env->CallLongMethod(
-            javaDisplayObj, jGetPresentationDeadlineNanos);
-
-    *sfVsyncOffsetPtr = vsyncPeriod - ((nsecs_t) javaPresentationDeadline - kOneMillisecInNanosec);
-}
-
-/* ======================================================================= */
-/*                          Choreographer Thread                           */
-/* ======================================================================= */
-
-struct ChoreographerThread : public Thread {
-    ChoreographerThread(bool canCallJava);
-    status_t init(void* data);
-    virtual status_t readyToRun() override;
-    virtual bool threadLoop() override;
-
-protected:
-    virtual ~ChoreographerThread() {}
-
-private:
-    DISALLOW_EVIL_CONSTRUCTORS(ChoreographerThread);
-    void* mData;
-};
-
-ChoreographerThread::ChoreographerThread(bool canCallJava) : Thread(canCallJava) {
-}
-
-status_t ChoreographerThread::init(void* data) {
-    if (data == NULL) {
-        return NO_INIT;
-    }
-    mData = data;
-    return OK;
-}
-
-status_t ChoreographerThread::readyToRun() {
-    ALooper_prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS);
-    if (AChoreographer_getInstance() == NULL) {
-        return NO_INIT;
-    }
-    AChoreographer_postFrameCallback64(AChoreographer_getInstance(), frameCallback, mData);
-    return OK;
-}
-
-bool ChoreographerThread::threadLoop() {
-    ALooper_pollOnce(-1, nullptr, nullptr, nullptr);
-    return true;
-}
-
-/* ======================================================================= */
-/*                             Frame Scheduler                             */
-/* ======================================================================= */
-
-VideoFrameScheduler2::VideoFrameScheduler2() : VideoFrameSchedulerBase() {
-
-    getVsyncOffset(&mAppVsyncOffset, &mSfVsyncOffset);
-
-    Mutex::Autolock threadLock(mLock);
-    mChoreographerThread = new ChoreographerThread(true);
-
-    mVsyncTracker = new VsyncTracker();
-    if (mChoreographerThread->init(static_cast<void*>(mVsyncTracker.get())) != OK) {
-        mChoreographerThread.clear();
-    }
-    if (mChoreographerThread != NULL && mChoreographerThread->run("Choreographer") != OK) {
-        mChoreographerThread.clear();
-    }
-}
-
-void VideoFrameScheduler2::updateVsync() {
-    mVsyncTime = 0;
-    mVsyncPeriod = 0;
-
-    if (mVsyncTracker != NULL) {
-        mVsyncPeriod = mVsyncTracker->getVsyncPeriod();
-        mVsyncTime = mVsyncTracker->getVsyncTime(mSfVsyncOffset - mAppVsyncOffset);
-    }
-    mVsyncRefreshAt = systemTime(SYSTEM_TIME_MONOTONIC) + kVsyncRefreshPeriod;
-}
-
-void VideoFrameScheduler2::release() {
-    // Do not change order
-    {
-        Mutex::Autolock threadLock(mLock);
-        mChoreographerThread->requestExitAndWait();
-        mChoreographerThread.clear();
-    }
-
-    mVsyncTracker.clear();
-}
-
-VideoFrameScheduler2::~VideoFrameScheduler2() {
-    release();
-}
-
-} // namespace android
diff --git a/media/libstagefright/bqhelper/Android.bp b/media/libstagefright/bqhelper/Android.bp
index db67034..6719bab 100644
--- a/media/libstagefright/bqhelper/Android.bp
+++ b/media/libstagefright/bqhelper/Android.bp
@@ -27,7 +27,6 @@
         "libcutils",
         "libhidlbase",
         "libhidlmemory",
-        "libhidltransport",
         "liblog",
         "libstagefright_foundation",
         "libui",
@@ -39,7 +38,6 @@
         "android.hidl.token@1.0-utils",
         "libbase",
         "libEGL",
-        "libhwbinder",
         "libnativewindow",
         "libvndksupport",
     ],
diff --git a/media/libstagefright/codecs/mp3dec/src/pv_mp3dec_fxd_op_c_equivalent.h b/media/libstagefright/codecs/mp3dec/src/pv_mp3dec_fxd_op_c_equivalent.h
index adb0dd4..f9d91b1 100644
--- a/media/libstagefright/codecs/mp3dec/src/pv_mp3dec_fxd_op_c_equivalent.h
+++ b/media/libstagefright/codecs/mp3dec/src/pv_mp3dec_fxd_op_c_equivalent.h
@@ -44,7 +44,7 @@
 #endif
 
 #include "pvmp3_audio_type_defs.h"
-#define Qfmt_31(a)   (Int32)((float)(a)*0x7FFFFFFF)
+#define Qfmt_31(a)   (Int32)((float)(a)*(float)0x7FFFFFFF)
 
 #define Qfmt15(x)   (Int16)((x)*((Int32)1<<15) + ((x)>=0?0.5F:-0.5F))
 
diff --git a/media/libstagefright/codecs/mp3dec/src/pvmp3_alias_reduction.cpp b/media/libstagefright/codecs/mp3dec/src/pvmp3_alias_reduction.cpp
index af738ba..a4f798e 100644
--- a/media/libstagefright/codecs/mp3dec/src/pvmp3_alias_reduction.cpp
+++ b/media/libstagefright/codecs/mp3dec/src/pvmp3_alias_reduction.cpp
@@ -169,7 +169,7 @@
 
     int32 i, j;
 
-    *used_freq_lines = fxp_mul32_Q32(*used_freq_lines << 16, (int32)(0x7FFFFFFF / (float)18 - 1.0f)) >> 15;
+    *used_freq_lines = fxp_mul32_Q32(*used_freq_lines << 16, (int32)((float)0x7FFFFFFF / 18.0f - 1.0f)) >> 15;
 
 
     if (gr_info->window_switching_flag &&  gr_info->block_type == 2)
diff --git a/media/libstagefright/codecs/mp3dec/src/pvmp3_dct_9.cpp b/media/libstagefright/codecs/mp3dec/src/pvmp3_dct_9.cpp
index bbb247d..9cd0e91 100644
--- a/media/libstagefright/codecs/mp3dec/src/pvmp3_dct_9.cpp
+++ b/media/libstagefright/codecs/mp3dec/src/pvmp3_dct_9.cpp
@@ -77,7 +77,7 @@
 ; Include all pre-processor statements here. Include conditional
 ; compile variables also.
 ----------------------------------------------------------------------------*/
-#define Qfmt31(a)   (int32)((a)*(0x7FFFFFFF))
+#define Qfmt31(a)   (int32)((a)*((float)0x7FFFFFFF))
 
 #define cos_pi_9    Qfmt31( 0.93969262078591f)
 #define cos_2pi_9   Qfmt31( 0.76604444311898f)
diff --git a/media/libstagefright/codecs/vorbis/dec/SoftVorbis.cpp b/media/libstagefright/codecs/vorbis/dec/SoftVorbis.cpp
index 1293a74..08e20cc 100644
--- a/media/libstagefright/codecs/vorbis/dec/SoftVorbis.cpp
+++ b/media/libstagefright/codecs/vorbis/dec/SoftVorbis.cpp
@@ -572,16 +572,17 @@
 }
 
 void SoftVorbis::onPortFlushCompleted(OMX_U32 portIndex) {
-    if (portIndex == 0 && mState != NULL) {
-        // Make sure that the next buffer output does not still
-        // depend on fragments from the last one decoded.
-
+    if (portIndex == 0) {
         mInputBufferCount = 0;
         mNumFramesOutput = 0;
         mSawInputEos = false;
         mSignalledOutputEos = false;
         mNumFramesLeftOnPage = -1;
-        vorbis_dsp_restart(mState);
+        if (mState != NULL) {
+            // Make sure that the next buffer output does not still
+            // depend on fragments from the last one decoded.
+            vorbis_dsp_restart(mState);
+        }
     }
 }
 
@@ -603,6 +604,7 @@
     mSawInputEos = false;
     mSignalledOutputEos = false;
     mSignalledError = false;
+    mNumFramesLeftOnPage = -1;
     mOutputPortSettingsChange = NONE;
 }
 
diff --git a/media/libstagefright/colorconversion/SoftwareRenderer.cpp b/media/libstagefright/colorconversion/SoftwareRenderer.cpp
index 359df3d..4711315 100644
--- a/media/libstagefright/colorconversion/SoftwareRenderer.cpp
+++ b/media/libstagefright/colorconversion/SoftwareRenderer.cpp
@@ -31,9 +31,14 @@
 
 namespace android {
 
-static int ALIGN(int x, int y) {
-    // y must be a power of 2.
-    return (x + y - 1) & ~(y - 1);
+inline void initDstYUV(
+        const android_ycbcr &ycbcr, int32_t cropTop, int32_t cropLeft,
+        uint8_t **dst_y, uint8_t **dst_u, uint8_t **dst_v) {
+    *dst_y = (uint8_t *)ycbcr.y + cropTop * ycbcr.ystride + cropLeft;
+
+    int32_t c_offset = (cropTop / 2) * ycbcr.cstride + cropLeft / 2;
+    *dst_v = (uint8_t *)ycbcr.cr + c_offset;
+    *dst_u = (uint8_t *)ycbcr.cb + c_offset;
 }
 
 SoftwareRenderer::SoftwareRenderer(
@@ -269,10 +274,21 @@
 
     Rect bounds(mCropWidth, mCropHeight);
 
-    void *dst;
-    CHECK_EQ(0, mapper.lock(buf->handle,
-            GRALLOC_USAGE_SW_READ_NEVER | GRALLOC_USAGE_SW_WRITE_RARELY,
-            bounds, &dst));
+    void *dst = NULL;
+    struct android_ycbcr ycbcr;
+    if ( !mConverter &&
+         (mColorFormat == OMX_COLOR_FormatYUV420Planar ||
+         mColorFormat == OMX_COLOR_FormatYUV420SemiPlanar ||
+         mColorFormat == OMX_TI_COLOR_FormatYUV420PackedSemiPlanar ||
+         mColorFormat == OMX_COLOR_FormatYUV420Planar16)) {
+        CHECK_EQ(0, mapper.lockYCbCr(buf->handle,
+                GRALLOC_USAGE_SW_READ_NEVER | GRALLOC_USAGE_SW_WRITE_RARELY,
+                bounds, &ycbcr));
+    } else {
+        CHECK_EQ(0, mapper.lock(buf->handle,
+                GRALLOC_USAGE_SW_READ_NEVER | GRALLOC_USAGE_SW_WRITE_RARELY,
+                bounds, &dst));
+    }
 
     // TODO move the other conversions also into ColorConverter, and
     // fix cropping issues (when mCropLeft/Top != 0 or mWidth != mCropWidth)
@@ -289,22 +305,14 @@
         const uint8_t *src_u = (const uint8_t *)data + mStride * mHeight + mCropTop * mStride / 4;
         const uint8_t *src_v = (const uint8_t *)src_u + mStride * mHeight / 4;
 
-        uint8_t *dst_y = (uint8_t *)dst;
-        size_t dst_y_size = buf->stride * buf->height;
-        size_t dst_c_stride = ALIGN(buf->stride / 2, 16);
-        size_t dst_c_size = dst_c_stride * buf->height / 2;
-        uint8_t *dst_v = dst_y + dst_y_size;
-        uint8_t *dst_u = dst_v + dst_c_size;
-
-        dst_y += mCropTop * buf->stride + mCropLeft;
-        dst_v += (mCropTop/2) * dst_c_stride + mCropLeft/2;
-        dst_u += (mCropTop/2) * dst_c_stride + mCropLeft/2;
+        uint8_t *dst_y, *dst_u, *dst_v;
+        initDstYUV(ycbcr, mCropTop, mCropLeft, &dst_y, &dst_u, &dst_v);
 
         for (int y = 0; y < mCropHeight; ++y) {
             memcpy(dst_y, src_y, mCropWidth);
 
             src_y += mStride;
-            dst_y += buf->stride;
+            dst_y += ycbcr.ystride;
         }
 
         for (int y = 0; y < (mCropHeight + 1) / 2; ++y) {
@@ -313,24 +321,16 @@
 
             src_u += mStride / 2;
             src_v += mStride / 2;
-            dst_u += dst_c_stride;
-            dst_v += dst_c_stride;
+            dst_u += ycbcr.cstride;
+            dst_v += ycbcr.cstride;
         }
     } else if (mColorFormat == OMX_COLOR_FormatYUV420Planar16) {
         const uint8_t *src_y = (const uint8_t *)data + mCropTop * mStride + mCropLeft * 2;
         const uint8_t *src_u = (const uint8_t *)data + mStride * mHeight + mCropTop * mStride / 4;
         const uint8_t *src_v = (const uint8_t *)src_u + mStride * mHeight / 4;
 
-        uint8_t *dst_y = (uint8_t *)dst;
-        size_t dst_y_size = buf->stride * buf->height;
-        size_t dst_c_stride = ALIGN(buf->stride / 2, 16);
-        size_t dst_c_size = dst_c_stride * buf->height / 2;
-        uint8_t *dst_v = dst_y + dst_y_size;
-        uint8_t *dst_u = dst_v + dst_c_size;
-
-        dst_y += mCropTop * buf->stride + mCropLeft;
-        dst_v += (mCropTop / 2) * dst_c_stride + mCropLeft / 2;
-        dst_u += (mCropTop / 2) * dst_c_stride + mCropLeft / 2;
+        uint8_t *dst_y, *dst_u, *dst_v;
+        initDstYUV(ycbcr, mCropTop, mCropLeft, &dst_y, &dst_u, &dst_v);
 
         for (int y = 0; y < mCropHeight; ++y) {
             for (int x = 0; x < mCropWidth; ++x) {
@@ -338,7 +338,7 @@
             }
 
             src_y += mStride;
-            dst_y += buf->stride;
+            dst_y += ycbcr.ystride;
         }
 
         for (int y = 0; y < (mCropHeight + 1) / 2; ++y) {
@@ -349,8 +349,8 @@
 
             src_u += mStride / 2;
             src_v += mStride / 2;
-            dst_u += dst_c_stride;
-            dst_v += dst_c_stride;
+            dst_u += ycbcr.cstride;
+            dst_v += ycbcr.cstride;
         }
     } else if (mColorFormat == OMX_TI_COLOR_FormatYUV420PackedSemiPlanar
             || mColorFormat == OMX_COLOR_FormatYUV420SemiPlanar) {
@@ -361,23 +361,14 @@
         src_y += mCropLeft + mCropTop * mWidth;
         src_uv += (mCropLeft + mCropTop * mWidth) / 2;
 
-        uint8_t *dst_y = (uint8_t *)dst;
-
-        size_t dst_y_size = buf->stride * buf->height;
-        size_t dst_c_stride = ALIGN(buf->stride / 2, 16);
-        size_t dst_c_size = dst_c_stride * buf->height / 2;
-        uint8_t *dst_v = dst_y + dst_y_size;
-        uint8_t *dst_u = dst_v + dst_c_size;
-
-        dst_y += mCropTop * buf->stride + mCropLeft;
-        dst_v += (mCropTop/2) * dst_c_stride + mCropLeft/2;
-        dst_u += (mCropTop/2) * dst_c_stride + mCropLeft/2;
+        uint8_t *dst_y, *dst_u, *dst_v;
+        initDstYUV(ycbcr, mCropTop, mCropLeft, &dst_y, &dst_u, &dst_v);
 
         for (int y = 0; y < mCropHeight; ++y) {
             memcpy(dst_y, src_y, mCropWidth);
 
             src_y += mWidth;
-            dst_y += buf->stride;
+            dst_y += ycbcr.ystride;
         }
 
         for (int y = 0; y < (mCropHeight + 1) / 2; ++y) {
@@ -388,8 +379,8 @@
             }
 
             src_uv += mWidth;
-            dst_u += dst_c_stride;
-            dst_v += dst_c_stride;
+            dst_u += ycbcr.cstride;
+            dst_v += ycbcr.cstride;
         }
     } else if (mColorFormat == OMX_COLOR_Format24bitRGB888) {
         uint8_t* srcPtr = (uint8_t*)data + mWidth * mCropTop * 3 + mCropLeft * 3;
diff --git a/media/libstagefright/filters/Android.bp b/media/libstagefright/filters/Android.bp
index 7a67e55..88f30c4 100644
--- a/media/libstagefright/filters/Android.bp
+++ b/media/libstagefright/filters/Android.bp
@@ -8,7 +8,7 @@
         "MediaFilter.cpp",
         "RSFilter.cpp",
         "SaturationFilter.cpp",
-        "saturationARGB.rs",
+        "saturationARGB.rscript",
         "SimpleFilter.cpp",
         "ZeroFilter.cpp",
     ],
@@ -23,6 +23,10 @@
         "-Wall",
     ],
 
+    header_libs: [
+        "libmediadrm_headers",
+    ],
+
     shared_libs: [
         "libgui",
         "libmedia",
diff --git a/media/libstagefright/filters/saturation.rs b/media/libstagefright/filters/saturation.rscript
similarity index 100%
rename from media/libstagefright/filters/saturation.rs
rename to media/libstagefright/filters/saturation.rscript
diff --git a/media/libstagefright/filters/saturationARGB.rs b/media/libstagefright/filters/saturationARGB.rscript
similarity index 100%
rename from media/libstagefright/filters/saturationARGB.rs
rename to media/libstagefright/filters/saturationARGB.rscript
diff --git a/media/libstagefright/foundation/AString.cpp b/media/libstagefright/foundation/AString.cpp
index fb51cc5..a8adff5 100644
--- a/media/libstagefright/foundation/AString.cpp
+++ b/media/libstagefright/foundation/AString.cpp
@@ -365,8 +365,6 @@
 // static
 AString AString::FromParcel(const Parcel &parcel) {
     size_t size = static_cast<size_t>(parcel.readInt32());
-    // The static analyzer incorrectly reports a false-positive here in c++17.
-    // https://bugs.llvm.org/show_bug.cgi?id=38176 . NOLINTNEXTLINE
     return AString(static_cast<const char *>(parcel.readInplace(size)), size);
 }
 
diff --git a/media/libstagefright/foundation/Android.bp b/media/libstagefright/foundation/Android.bp
index 533cd72..b95f054 100644
--- a/media/libstagefright/foundation/Android.bp
+++ b/media/libstagefright/foundation/Android.bp
@@ -65,6 +65,7 @@
         "AudioPresentationInfo.cpp",
         "ByteUtils.cpp",
         "ColorUtils.cpp",
+        "FoundationUtils.cpp",
         "MediaBuffer.cpp",
         "MediaBufferBase.cpp",
         "MediaBufferGroup.cpp",
diff --git a/media/libstagefright/foundation/FoundationUtils.cpp b/media/libstagefright/foundation/FoundationUtils.cpp
new file mode 100644
index 0000000..8285e4c
--- /dev/null
+++ b/media/libstagefright/foundation/FoundationUtils.cpp
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2009 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 "FoundationUtils"
+#include <utils/Log.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include <cutils/properties.h>
+#include <media/stagefright/foundation/AString.h>
+
+namespace android {
+
+AString uriDebugString(const AString &uri, bool incognito) {
+    if (incognito) {
+        return AString("<URI suppressed>");
+    }
+
+    if (property_get_bool("media.stagefright.log-uri", false)) {
+        return uri;
+    }
+
+    // find scheme
+    AString scheme;
+    const char *chars = uri.c_str();
+    for (size_t i = 0; i < uri.size(); i++) {
+        const char c = chars[i];
+        if (!isascii(c)) {
+            break;
+        } else if (isalpha(c)) {
+            continue;
+        } else if (i == 0) {
+            // first character must be a letter
+            break;
+        } else if (isdigit(c) || c == '+' || c == '.' || c =='-') {
+            continue;
+        } else if (c != ':') {
+            break;
+        }
+        scheme = AString(uri, 0, i);
+        scheme.append("://<suppressed>");
+        return scheme;
+    }
+    return AString("<no-scheme URI suppressed>");
+}
+
+AString MakeUserAgent() {
+    AString ua;
+    ua.append("stagefright/1.2 (Linux;Android ");
+
+#if (PROPERTY_VALUE_MAX < 8)
+#error "PROPERTY_VALUE_MAX must be at least 8"
+#endif
+
+    char value[PROPERTY_VALUE_MAX];
+    property_get("ro.build.version.release", value, "Unknown");
+    ua.append(value);
+    ua.append(")");
+
+    return ua;
+}
+
+AString nameForFd(int fd) {
+    const size_t SIZE = 256;
+    char buffer[SIZE];
+    AString result;
+    snprintf(buffer, SIZE, "/proc/%d/fd/%d", getpid(), fd);
+    struct stat s;
+    if (lstat(buffer, &s) == 0) {
+        if ((s.st_mode & S_IFMT) == S_IFLNK) {
+            char linkto[256];
+            int len = readlink(buffer, linkto, sizeof(linkto));
+            if(len > 0) {
+                if(len > 255) {
+                    linkto[252] = '.';
+                    linkto[253] = '.';
+                    linkto[254] = '.';
+                    linkto[255] = 0;
+                } else {
+                    linkto[len] = 0;
+                }
+                result.append(linkto);
+            }
+        } else {
+            result.append("unexpected type for ");
+            result.append(buffer);
+        }
+    } else {
+        result.append("couldn't open ");
+        result.append(buffer);
+    }
+    return result;
+}
+
+}  // namespace android
diff --git a/media/libstagefright/httplive/Android.bp b/media/libstagefright/httplive/Android.bp
index c0ee14e..12e7ca6 100644
--- a/media/libstagefright/httplive/Android.bp
+++ b/media/libstagefright/httplive/Android.bp
@@ -31,6 +31,7 @@
         "liblog",
         "libcrypto",
         "libcutils",
+        "libdatasource",
         "libmedia",
         "libmediandk",
         "libstagefright",
diff --git a/media/libstagefright/httplive/HTTPDownloader.cpp b/media/libstagefright/httplive/HTTPDownloader.cpp
index c7e92cd..68f1de9 100644
--- a/media/libstagefright/httplive/HTTPDownloader.cpp
+++ b/media/libstagefright/httplive/HTTPDownloader.cpp
@@ -21,13 +21,13 @@
 #include "HTTPDownloader.h"
 #include "M3UParser.h"
 
+#include <datasource/MediaHTTP.h>
+#include <datasource/FileSource.h>
 #include <media/DataSource.h>
 #include <media/MediaHTTPConnection.h>
 #include <media/MediaHTTPService.h>
 #include <media/stagefright/foundation/ABuffer.h>
 #include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/ClearMediaHTTP.h>
-#include <media/stagefright/ClearFileSource.h>
 #include <openssl/aes.h>
 #include <openssl/md5.h>
 #include <utils/Mutex.h>
@@ -38,7 +38,7 @@
 HTTPDownloader::HTTPDownloader(
         const sp<MediaHTTPService> &httpService,
         const KeyedVector<String8, String8> &headers) :
-    mHTTPDataSource(new ClearMediaHTTP(httpService->makeHTTPConnection())),
+    mHTTPDataSource(new MediaHTTP(httpService->makeHTTPConnection())),
     mExtraHeaders(headers),
     mDisconnecting(false) {
 }
@@ -91,7 +91,7 @@
 
     if (reconnect) {
         if (!strncasecmp(url, "file://", 7)) {
-            mDataSource = new ClearFileSource(url + 7);
+            mDataSource = new FileSource(url + 7);
         } else if (strncasecmp(url, "http://", 7)
                 && strncasecmp(url, "https://", 8)) {
             return ERROR_UNSUPPORTED;
diff --git a/media/libstagefright/httplive/LiveSession.cpp b/media/libstagefright/httplive/LiveSession.cpp
index 9cf97c7..3bad015 100644
--- a/media/libstagefright/httplive/LiveSession.cpp
+++ b/media/libstagefright/httplive/LiveSession.cpp
@@ -34,6 +34,7 @@
 #include <media/stagefright/MediaDefs.h>
 #include <media/stagefright/MetaData.h>
 #include <media/stagefright/Utils.h>
+#include <media/stagefright/FoundationUtils.h>
 
 #include <utils/Mutex.h>
 
diff --git a/media/libstagefright/httplive/M3UParser.cpp b/media/libstagefright/httplive/M3UParser.cpp
index cb97a3c..e0324e3 100644
--- a/media/libstagefright/httplive/M3UParser.cpp
+++ b/media/libstagefright/httplive/M3UParser.cpp
@@ -27,6 +27,7 @@
 #include <media/stagefright/MediaDefs.h>
 #include <media/stagefright/MediaErrors.h>
 #include <media/stagefright/Utils.h>
+#include <media/stagefright/FoundationUtils.h>
 #include <media/mediaplayer.h>
 
 namespace android {
diff --git a/media/libstagefright/httplive/PlaylistFetcher.cpp b/media/libstagefright/httplive/PlaylistFetcher.cpp
index 635ecfe..4d0848a 100644
--- a/media/libstagefright/httplive/PlaylistFetcher.cpp
+++ b/media/libstagefright/httplive/PlaylistFetcher.cpp
@@ -28,17 +28,18 @@
 #include "mpeg2ts/AnotherPacketSource.h"
 #include "mpeg2ts/HlsSampleDecryptor.h"
 
+#include <datasource/DataURISource.h>
 #include <media/stagefright/foundation/ABitReader.h>
 #include <media/stagefright/foundation/ABuffer.h>
 #include <media/stagefright/foundation/ADebug.h>
 #include <media/stagefright/foundation/ByteUtils.h>
 #include <media/stagefright/foundation/MediaKeys.h>
 #include <media/stagefright/foundation/avc_utils.h>
-#include <media/stagefright/DataURISource.h>
 #include <media/stagefright/MediaDefs.h>
 #include <media/stagefright/MetaData.h>
 #include <media/stagefright/MetaDataUtils.h>
 #include <media/stagefright/Utils.h>
+#include <media/stagefright/FoundationUtils.h>
 
 #include <ctype.h>
 #include <inttypes.h>
diff --git a/media/libstagefright/id3/Android.bp b/media/libstagefright/id3/Android.bp
index 7151d07..c8173cf 100644
--- a/media/libstagefright/id3/Android.bp
+++ b/media/libstagefright/id3/Android.bp
@@ -4,6 +4,7 @@
     srcs: ["ID3.cpp"],
 
     header_libs: [
+        "libmedia_headers",
         "media_ndk_headers",
     ],
 
@@ -33,6 +34,7 @@
     ],
 
     shared_libs: [
+        "libdatasource",
         "libstagefright",
         "libutils",
         "liblog",
diff --git a/media/libstagefright/id3/testid3.cpp b/media/libstagefright/id3/testid3.cpp
index 86e6adf..9984d85 100644
--- a/media/libstagefright/id3/testid3.cpp
+++ b/media/libstagefright/id3/testid3.cpp
@@ -22,7 +22,7 @@
 #include <dirent.h>
 
 #include <binder/ProcessState.h>
-#include <media/stagefright/FileSource.h>
+#include <datasource/FileSource.h>
 #include <media/stagefright/foundation/ADebug.h>
 
 #define MAXPATHLEN 256
diff --git a/media/libstagefright/include/ACodecBufferChannel.h b/media/libstagefright/include/ACodecBufferChannel.h
index 7c01e45..3a087d1 100644
--- a/media/libstagefright/include/ACodecBufferChannel.h
+++ b/media/libstagefright/include/ACodecBufferChannel.h
@@ -25,7 +25,7 @@
 
 #include <media/openmax/OMX_Types.h>
 #include <media/stagefright/CodecBase.h>
-#include <media/ICrypto.h>
+#include <mediadrm/ICrypto.h>
 #include <media/IOMX.h>
 
 namespace android {
diff --git a/media/libstagefright/include/SecureBuffer.h b/media/libstagefright/include/SecureBuffer.h
index cf7933a..c45e0e5 100644
--- a/media/libstagefright/include/SecureBuffer.h
+++ b/media/libstagefright/include/SecureBuffer.h
@@ -18,7 +18,7 @@
 
 #define SECURE_BUFFER_H_
 
-#include <media/ICrypto.h>
+#include <mediadrm/ICrypto.h>
 #include <media/MediaCodecBuffer.h>
 
 namespace android {
diff --git a/media/libstagefright/include/media/stagefright/DataSourceBase.h b/media/libstagefright/include/media/stagefright/DataSourceBase.h
index af5b83d..c607c91 100644
--- a/media/libstagefright/include/media/stagefright/DataSourceBase.h
+++ b/media/libstagefright/include/media/stagefright/DataSourceBase.h
@@ -18,6 +18,8 @@
 
 #define DATA_SOURCE_BASE_H_
 
+#include <media/stagefright/foundation/ByteUtils.h>
+#include <media/stagefright/MediaErrors.h>
 #include <sys/types.h>
 #include <utils/Errors.h>
 
@@ -45,20 +47,106 @@
     virtual ssize_t readAt(off64_t offset, void *data, size_t size) = 0;
 
     // Convenience methods:
-    bool getUInt16(off64_t offset, uint16_t *x);
-    bool getUInt24(off64_t offset, uint32_t *x); // 3 byte int, returned as a 32-bit int
-    bool getUInt32(off64_t offset, uint32_t *x);
-    bool getUInt64(off64_t offset, uint64_t *x);
+    bool getUInt16(off64_t offset, uint16_t *x) {
+        *x = 0;
+
+        uint8_t byte[2];
+        if (readAt(offset, byte, 2) != 2) {
+            return false;
+        }
+
+        *x = (byte[0] << 8) | byte[1];
+
+        return true;
+    }
+    // 3 byte int, returned as a 32-bit int
+    bool getUInt24(off64_t offset, uint32_t *x) {
+        *x = 0;
+
+        uint8_t byte[3];
+        if (readAt(offset, byte, 3) != 3) {
+            return false;
+        }
+
+        *x = (byte[0] << 16) | (byte[1] << 8) | byte[2];
+
+        return true;
+    }
+    bool getUInt32(off64_t offset, uint32_t *x) {
+        *x = 0;
+
+        uint32_t tmp;
+        if (readAt(offset, &tmp, 4) != 4) {
+            return false;
+        }
+
+        *x = ntohl(tmp);
+
+        return true;
+    }
+    bool getUInt64(off64_t offset, uint64_t *x) {
+        *x = 0;
+
+        uint64_t tmp;
+        if (readAt(offset, &tmp, 8) != 8) {
+            return false;
+        }
+
+        *x = ntoh64(tmp);
+
+        return true;
+    }
 
     // read either int<N> or int<2N> into a uint<2N>_t, size is the int size in bytes.
-    bool getUInt16Var(off64_t offset, uint16_t *x, size_t size);
-    bool getUInt32Var(off64_t offset, uint32_t *x, size_t size);
-    bool getUInt64Var(off64_t offset, uint64_t *x, size_t size);
+    bool getUInt16Var(off64_t offset, uint16_t *x, size_t size) {
+        if (size == 2) {
+            return getUInt16(offset, x);
+        }
+        if (size == 1) {
+            uint8_t tmp;
+            if (readAt(offset, &tmp, 1) == 1) {
+                *x = tmp;
+                return true;
+            }
+        }
+        return false;
+    }
+    bool getUInt32Var(off64_t offset, uint32_t *x, size_t size) {
+        if (size == 4) {
+            return getUInt32(offset, x);
+        }
+        if (size == 2) {
+            uint16_t tmp;
+            if (getUInt16(offset, &tmp)) {
+                *x = tmp;
+                return true;
+            }
+        }
+        return false;
+    }
+    bool getUInt64Var(off64_t offset, uint64_t *x, size_t size) {
+        if (size == 8) {
+            return getUInt64(offset, x);
+        }
+        if (size == 4) {
+            uint32_t tmp;
+            if (getUInt32(offset, &tmp)) {
+                *x = tmp;
+                return true;
+            }
+        }
+        return false;
+    }
 
     // May return ERROR_UNSUPPORTED.
-    virtual status_t getSize(off64_t *size);
+    virtual status_t getSize(off64_t *size) {
+        *size = 0;
+        return ERROR_UNSUPPORTED;
+    }
 
-    virtual bool getUri(char *uriString, size_t bufferSize);
+    virtual bool getUri(char * /*uriString*/, size_t /*bufferSize*/) {
+        return false;
+    }
 
     virtual uint32_t flags() {
         return 0;
diff --git a/media/libstagefright/include/media/stagefright/NdkUtils.h b/media/libstagefright/include/media/stagefright/FoundationUtils.h
similarity index 66%
rename from media/libstagefright/include/media/stagefright/NdkUtils.h
rename to media/libstagefright/include/media/stagefright/FoundationUtils.h
index a68884a..1548981 100644
--- a/media/libstagefright/include/media/stagefright/NdkUtils.h
+++ b/media/libstagefright/include/media/stagefright/FoundationUtils.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2018 The Android Open Source Project
+ * 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.
@@ -14,18 +14,19 @@
  * limitations under the License.
  */
 
-#ifndef NDK_UTILS_H_
+#ifndef FOUNDATION_UTILS_H_
 
-#define NDK_UTILS_H_
+#define FOUNDATION_UTILS_H_
 
-#include <media/stagefright/MetaData.h>
-#include <media/NdkWrapper.h>
+#include <media/stagefright/foundation/AString.h>
 
 namespace android {
 
-sp<MetaData> convertMediaFormatWrapperToMetaData(
-        const sp<AMediaFormatWrapper> &fmt);
+AString MakeUserAgent();
 
+AString uriDebugString(const AString &uri, bool incognito = false);
+
+AString nameForFd(int fd);
 }  // namespace android
 
-#endif  // NDK_UTILS_H_
+#endif  // FOUNDATION_UTILS_H_
diff --git a/media/libstagefright/include/media/stagefright/MediaCodecList.h b/media/libstagefright/include/media/stagefright/MediaCodecList.h
index e44b0a4..e681d25 100644
--- a/media/libstagefright/include/media/stagefright/MediaCodecList.h
+++ b/media/libstagefright/include/media/stagefright/MediaCodecList.h
@@ -83,6 +83,7 @@
     };
 
     static sp<BinderDeathObserver> sBinderDeathObserver;
+    static sp<IBinder> sMediaPlayer;
 
     static sp<IMediaCodecList> sCodecList;
     static sp<IMediaCodecList> sRemoteList;
diff --git a/media/libstagefright/include/media/stagefright/MediaErrors.h b/media/libstagefright/include/media/stagefright/MediaErrors.h
index 09639e2..6f48c5d 100644
--- a/media/libstagefright/include/media/stagefright/MediaErrors.h
+++ b/media/libstagefright/include/media/stagefright/MediaErrors.h
@@ -99,7 +99,13 @@
     ERROR_CAS_DEVICE_REVOKED                 = CAS_ERROR_BASE - 9,
     ERROR_CAS_RESOURCE_BUSY                  = CAS_ERROR_BASE - 10,
     ERROR_CAS_INSUFFICIENT_OUTPUT_PROTECTION = CAS_ERROR_BASE - 11,
-    ERROR_CAS_LAST_USED_ERRORCODE            = CAS_ERROR_BASE - 11,
+    ERROR_CAS_NEED_ACTIVATION                = CAS_ERROR_BASE - 12,
+    ERROR_CAS_NEED_PAIRING                   = CAS_ERROR_BASE - 13,
+    ERROR_CAS_NO_CARD                        = CAS_ERROR_BASE - 14,
+    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_VENDOR_MAX                     = CAS_ERROR_BASE - 500,
     ERROR_CAS_VENDOR_MIN                     = CAS_ERROR_BASE - 999,
diff --git a/media/libstagefright/include/media/stagefright/Utils.h b/media/libstagefright/include/media/stagefright/Utils.h
index e8e0a11..2b9b759 100644
--- a/media/libstagefright/include/media/stagefright/Utils.h
+++ b/media/libstagefright/include/media/stagefright/Utils.h
@@ -41,8 +41,6 @@
 // TODO: combine this with avc_utils::getNextNALUnit
 const uint8_t *findNextNalStartCode(const uint8_t *data, size_t length);
 
-AString MakeUserAgent();
-
 // Convert a MIME type to a AudioSystem::audio_format
 status_t mapMimeToAudioFormat(audio_format_t& format, const char* mime);
 
@@ -60,8 +58,6 @@
 bool canOffloadStream(const sp<MetaData>& meta, bool hasVideo,
                       bool isStreaming, audio_stream_type_t streamType);
 
-AString uriDebugString(const AString &uri, bool incognito = false);
-
 struct HLSTime {
     int32_t mSeq;
     int64_t mTimeUs;
@@ -85,7 +81,6 @@
 void writeToAMessage(const sp<AMessage> &msg, const BufferingSettings &buffering);
 void readFromAMessage(const sp<AMessage> &msg, BufferingSettings *buffering /* nonnull */);
 
-AString nameForFd(int fd);
 }  // namespace android
 
 #endif  // UTILS_H_
diff --git a/media/libstagefright/omx/Android.bp b/media/libstagefright/omx/Android.bp
index 7d03d98..7d612b4 100644
--- a/media/libstagefright/omx/Android.bp
+++ b/media/libstagefright/omx/Android.bp
@@ -45,7 +45,6 @@
         "libdl",
         "libhidlbase",
         "libhidlmemory",
-        "libhidltransport",
         "libvndksupport",
         "android.hardware.media.omx@1.0",
         "android.hardware.graphics.bufferqueue@1.0",
diff --git a/media/libstagefright/omx/tests/Android.bp b/media/libstagefright/omx/tests/Android.bp
index 569fa88..eb01543 100644
--- a/media/libstagefright/omx/tests/Android.bp
+++ b/media/libstagefright/omx/tests/Android.bp
@@ -7,6 +7,7 @@
     shared_libs: [
         "libstagefright",
         "libbinder",
+        "libdatasource",
         "libmedia",
         "libmedia_omx",
         "libutils",
diff --git a/media/libstagefright/omx/tests/OMXHarness.cpp b/media/libstagefright/omx/tests/OMXHarness.cpp
index cc8c234..6848a83 100644
--- a/media/libstagefright/omx/tests/OMXHarness.cpp
+++ b/media/libstagefright/omx/tests/OMXHarness.cpp
@@ -27,13 +27,13 @@
 #include <binder/ProcessState.h>
 #include <binder/IServiceManager.h>
 #include <cutils/properties.h>
+#include <datasource/DataSourceFactory.h>
 #include <media/DataSource.h>
 #include <media/IMediaHTTPService.h>
 #include <media/MediaSource.h>
 #include <media/OMXBuffer.h>
 #include <media/stagefright/foundation/ADebug.h>
 #include <media/stagefright/foundation/ALooper.h>
-#include <media/stagefright/DataSourceFactory.h>
 #include <media/stagefright/InterfaceUtils.h>
 #include <media/stagefright/MediaBuffer.h>
 #include <media/stagefright/MediaDefs.h>
@@ -278,7 +278,7 @@
 
 static sp<IMediaExtractor> CreateExtractorFromURI(const char *uri) {
     sp<DataSource> source =
-        DataSourceFactory::CreateFromURI(NULL /* httpService */, uri);
+        DataSourceFactory::getInstance()->CreateFromURI(NULL /* httpService */, uri);
 
     if (source == NULL) {
         return NULL;
diff --git a/media/libstagefright/rtsp/ARTSPConnection.cpp b/media/libstagefright/rtsp/ARTSPConnection.cpp
index 789e62a..bb66f4c 100644
--- a/media/libstagefright/rtsp/ARTSPConnection.cpp
+++ b/media/libstagefright/rtsp/ARTSPConnection.cpp
@@ -21,12 +21,14 @@
 #include "ARTSPConnection.h"
 #include "NetworkUtils.h"
 
+#include <datasource/HTTPBase.h>
 #include <media/stagefright/foundation/ABuffer.h>
 #include <media/stagefright/foundation/ADebug.h>
 #include <media/stagefright/foundation/AMessage.h>
 #include <media/stagefright/foundation/base64.h>
 #include <media/stagefright/MediaErrors.h>
 #include <media/stagefright/Utils.h>
+#include <media/stagefright/FoundationUtils.h>
 
 #include <arpa/inet.h>
 #include <fcntl.h>
@@ -34,7 +36,6 @@
 #include <openssl/md5.h>
 #include <sys/socket.h>
 
-#include "include/HTTPBase.h"
 
 namespace android {
 
@@ -953,7 +954,7 @@
     CHECK_GE(space2, 0);
 
     method->setTo(request, 0, space1);
-    url->setTo(request, space1 + 1, space2 - space1);
+    url->setTo(request, space1 + 1, space2 - space1 - 1);
 }
 
 void ARTSPConnection::addAuthentication(AString *request) {
diff --git a/media/libstagefright/rtsp/Android.bp b/media/libstagefright/rtsp/Android.bp
index 9bc9c89..a5a895e 100644
--- a/media/libstagefright/rtsp/Android.bp
+++ b/media/libstagefright/rtsp/Android.bp
@@ -21,6 +21,7 @@
 
     shared_libs: [
         "libcrypto",
+        "libdatasource",
         "libmedia",
     ],
 
diff --git a/media/libstagefright/rtsp/MyHandler.h b/media/libstagefright/rtsp/MyHandler.h
index 48bc8ce..9c30623 100644
--- a/media/libstagefright/rtsp/MyHandler.h
+++ b/media/libstagefright/rtsp/MyHandler.h
@@ -36,18 +36,19 @@
 #include <ctype.h>
 #include <cutils/properties.h>
 
+#include <datasource/HTTPBase.h>
 #include <media/stagefright/foundation/ABuffer.h>
 #include <media/stagefright/foundation/ADebug.h>
 #include <media/stagefright/foundation/ALooper.h>
 #include <media/stagefright/foundation/AMessage.h>
 #include <media/stagefright/MediaErrors.h>
 #include <media/stagefright/Utils.h>
+#include <media/stagefright/FoundationUtils.h>
 
 #include <arpa/inet.h>
 #include <sys/socket.h>
 #include <netdb.h>
 
-#include "HTTPBase.h"
 
 #if LOG_NDEBUG
 #define UNUSED_UNLESS_VERBOSE(x) (void)(x)
diff --git a/media/libstagefright/rtsp/SDPLoader.cpp b/media/libstagefright/rtsp/SDPLoader.cpp
index 665d51a..e236267 100644
--- a/media/libstagefright/rtsp/SDPLoader.cpp
+++ b/media/libstagefright/rtsp/SDPLoader.cpp
@@ -22,12 +22,13 @@
 
 #include "ASessionDescription.h"
 
+#include <datasource/MediaHTTP.h>
 #include <media/MediaHTTPConnection.h>
 #include <media/MediaHTTPService.h>
-#include <media/stagefright/ClearMediaHTTP.h>
 #include <media/stagefright/foundation/ABuffer.h>
 #include <media/stagefright/foundation/ADebug.h>
 #include <media/stagefright/Utils.h>
+#include <media/stagefright/FoundationUtils.h>
 
 #define DEFAULT_SDP_SIZE 100000
 
@@ -41,7 +42,7 @@
       mFlags(flags),
       mNetLooper(new ALooper),
       mCancelled(false),
-      mHTTPDataSource(new ClearMediaHTTP(httpService->makeHTTPConnection())) {
+      mHTTPDataSource(new MediaHTTP(httpService->makeHTTPConnection())) {
     mNetLooper->setName("sdp net");
     mNetLooper->start(false /* runOnCallingThread */,
                       false /* canCallJava */,
diff --git a/media/libstagefright/timedtext/Android.bp b/media/libstagefright/timedtext/Android.bp
index 6935655..4f4ceb1 100644
--- a/media/libstagefright/timedtext/Android.bp
+++ b/media/libstagefright/timedtext/Android.bp
@@ -23,32 +23,4 @@
     shared_libs: ["libmedia"],
 }
 
-cc_library_static {
-    name: "libstagefright_timedtext2",
 
-    srcs: ["TextDescriptions2.cpp"],
-
-    static_libs: [
-        "libmediaplayer2-protos",
-        "libprotobuf-cpp-lite",
-    ],
-
-    cflags: [
-        "-Wno-multichar",
-        "-Werror",
-        "-Wall",
-    ],
-
-    sanitize: {
-        misc_undefined: [
-            "signed-integer-overflow",
-        ],
-        cfi: true,
-    },
-
-    include_dirs: [
-        "frameworks/av/media/libstagefright",
-    ],
-
-    shared_libs: ["libmedia"],
-}
diff --git a/media/libstagefright/timedtext/TextDescriptions2.cpp b/media/libstagefright/timedtext/TextDescriptions2.cpp
deleted file mode 100644
index f48eacc..0000000
--- a/media/libstagefright/timedtext/TextDescriptions2.cpp
+++ /dev/null
@@ -1,188 +0,0 @@
-/*
- * Copyright (C) 2018 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.
- */
-
-#include "TextDescriptions2.h"
-#include <media/stagefright/foundation/ByteUtils.h>
-#include <media/stagefright/MediaErrors.h>
-
-namespace android {
-
-TextDescriptions2::TextDescriptions2() {
-}
-
-status_t TextDescriptions2::getPlayerMessageOfDescriptions(
-        const uint8_t *data, ssize_t size,
-        uint32_t flags, int timeMs, PlayerMessage *playerMsg) {
-    if (flags & IN_BAND_TEXT_3GPP) {
-        if (flags & GLOBAL_DESCRIPTIONS) {
-            return extract3GPPGlobalDescriptions(data, size, playerMsg);
-        } else if (flags & LOCAL_DESCRIPTIONS) {
-            return extract3GPPLocalDescriptions(data, size, timeMs, playerMsg);
-        }
-    } else if (flags & OUT_OF_BAND_TEXT_SRT) {
-        if (flags & LOCAL_DESCRIPTIONS) {
-            return extractSRTLocalDescriptions(data, size, timeMs, playerMsg);
-        }
-    }
-
-    return ERROR_UNSUPPORTED;
-}
-
-// Parse the SRT text sample, and store the timing and text sample in a PlayerMessage.
-// The PlayerMessage will be sent to MediaPlayer2.java through event, and will be
-// parsed in TimedText.java.
-status_t TextDescriptions2::extractSRTLocalDescriptions(
-        const uint8_t *data, ssize_t size, int timeMs, PlayerMessage *playerMsg) {
-    playerMsg->add_values()->set_int32_value(KEY_LOCAL_SETTING);
-    playerMsg->add_values()->set_int32_value(KEY_START_TIME);
-    playerMsg->add_values()->set_int32_value(timeMs);
-
-    playerMsg->add_values()->set_int32_value(KEY_STRUCT_TEXT);
-    playerMsg->add_values()->set_bytes_value(data, size);
-
-    return OK;
-}
-
-// Extract the local 3GPP display descriptions. 3GPP local descriptions
-// are appended to the text sample if any.
-status_t TextDescriptions2::extract3GPPLocalDescriptions(
-        const uint8_t *data, ssize_t size,
-        int timeMs, PlayerMessage *playerMsg) {
-
-    playerMsg->add_values()->set_int32_value(KEY_LOCAL_SETTING);
-
-    // write start time to display this text sample
-    playerMsg->add_values()->set_int32_value(KEY_START_TIME);
-    playerMsg->add_values()->set_int32_value(timeMs);
-
-    if (size < 2) {
-        return OK;
-    }
-    ssize_t textLen = (*data) << 8 | (*(data + 1));
-
-    if (size < textLen + 2) {
-        return OK;
-    }
-
-    // write text sample length and text sample itself
-    playerMsg->add_values()->set_int32_value(KEY_STRUCT_TEXT);
-    playerMsg->add_values()->set_bytes_value(data + 2, textLen);
-
-    if (size > textLen + 2) {
-        data += (textLen + 2);
-        size -= (textLen + 2);
-    } else {
-        return OK;
-    }
-
-    while (size >= 8) {
-        const uint8_t *tmpData = data;
-        ssize_t chunkSize = U32_AT(tmpData);      // size includes size and type
-        uint32_t chunkType = U32_AT(tmpData + 4);
-
-        if (chunkSize <= 8 || chunkSize > size) {
-            return OK;
-        }
-
-        size_t remaining = chunkSize - 8;
-
-        tmpData += 8;
-
-        switch(chunkType) {
-            // 'tbox' box to indicate the position of the text with values
-            // of top, left, bottom and right
-            case FOURCC('t', 'b', 'o', 'x'):
-            {
-                if (remaining < 8) {
-                    return OK;
-                }
-                playerMsg->add_values()->set_int32_value(KEY_STRUCT_TEXT_POS);
-                playerMsg->add_values()->set_int32_value(U16_AT(tmpData));
-                playerMsg->add_values()->set_int32_value(U16_AT(tmpData + 2));
-                playerMsg->add_values()->set_int32_value(U16_AT(tmpData + 4));
-                playerMsg->add_values()->set_int32_value(U16_AT(tmpData + 6));
-
-                tmpData += 8;
-                remaining -= 8;
-                break;
-            }
-            default:
-            {
-                break;
-            }
-        }
-
-        data += chunkSize;
-        size -= chunkSize;
-    }
-
-    return OK;
-}
-
-// To extract box 'tx3g' defined in 3GPP TS 26.245, and store it in a PlayerMessage
-status_t TextDescriptions2::extract3GPPGlobalDescriptions(
-        const uint8_t *data, ssize_t size, PlayerMessage *playerMsg) {
-
-    playerMsg->add_values()->set_int32_value(KEY_GLOBAL_SETTING);
-
-    while (size >= 8) {
-        ssize_t chunkSize = U32_AT(data);
-        uint32_t chunkType = U32_AT(data + 4);
-        const uint8_t *tmpData = data;
-        tmpData += 8;
-        size_t remaining = size - 8;
-
-        if (size < chunkSize) {
-            return OK;
-        }
-        switch(chunkType) {
-            case FOURCC('t', 'x', '3', 'g'):
-            {
-                if (remaining < 18) {
-                    return OK;
-                }
-                // Skip DISPLAY_FLAGS, STRUCT_JUSTIFICATION, and BACKGROUND_COLOR_RGBA
-                tmpData += 18;
-                remaining -= 18;
-
-                if (remaining < 8) {
-                    return OK;
-                }
-                playerMsg->add_values()->set_int32_value(KEY_STRUCT_TEXT_POS);
-                playerMsg->add_values()->set_int32_value(U16_AT(tmpData));
-                playerMsg->add_values()->set_int32_value(U16_AT(tmpData + 2));
-                playerMsg->add_values()->set_int32_value(U16_AT(tmpData + 4));
-                playerMsg->add_values()->set_int32_value(U16_AT(tmpData + 6));
-
-                tmpData += 8;
-                remaining -= 18;
-                // Ignore remaining data.
-                break;
-            }
-            default:
-            {
-                break;
-            }
-        }
-
-        data += chunkSize;
-        size -= chunkSize;
-    }
-
-    return OK;
-}
-
-}  // namespace android
diff --git a/media/libstagefright/timedtext/TextDescriptions2.h b/media/libstagefright/timedtext/TextDescriptions2.h
deleted file mode 100644
index 7c7d2d0..0000000
--- a/media/libstagefright/timedtext/TextDescriptions2.h
+++ /dev/null
@@ -1,88 +0,0 @@
- /*
- * Copyright (C) 2018 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 TEXT_DESCRIPTIONS2_H_
-
-#define TEXT_DESCRIPTIONS2_H_
-
-#include <binder/Parcel.h>
-#include <media/stagefright/foundation/ABase.h>
-
-#include "mediaplayer2.pb.h"
-
-using android::media::MediaPlayer2Proto::PlayerMessage;
-
-namespace android {
-
-class TextDescriptions2 {
-public:
-    enum {
-        IN_BAND_TEXT_3GPP             = 0x01,
-        OUT_OF_BAND_TEXT_SRT          = 0x02,
-
-        GLOBAL_DESCRIPTIONS           = 0x100,
-        LOCAL_DESCRIPTIONS            = 0x200,
-    };
-
-    static status_t getPlayerMessageOfDescriptions(
-            const uint8_t *data, ssize_t size,
-            uint32_t flags, int timeMs, PlayerMessage *playerMsg);
-private:
-    TextDescriptions2();
-
-    enum {
-        // These keys must be in sync with the keys in TimedText.java
-        KEY_DISPLAY_FLAGS                 = 1, // int
-        KEY_STYLE_FLAGS                   = 2, // int
-        KEY_BACKGROUND_COLOR_RGBA         = 3, // int
-        KEY_HIGHLIGHT_COLOR_RGBA          = 4, // int
-        KEY_SCROLL_DELAY                  = 5, // int
-        KEY_WRAP_TEXT                     = 6, // int
-        KEY_START_TIME                    = 7, // int
-        KEY_STRUCT_BLINKING_TEXT_LIST     = 8, // List<CharPos>
-        KEY_STRUCT_FONT_LIST              = 9, // List<Font>
-        KEY_STRUCT_HIGHLIGHT_LIST         = 10, // List<CharPos>
-        KEY_STRUCT_HYPER_TEXT_LIST        = 11, // List<HyperText>
-        KEY_STRUCT_KARAOKE_LIST           = 12, // List<Karaoke>
-        KEY_STRUCT_STYLE_LIST             = 13, // List<Style>
-        KEY_STRUCT_TEXT_POS               = 14, // TextPos
-        KEY_STRUCT_JUSTIFICATION          = 15, // Justification
-        KEY_STRUCT_TEXT                   = 16, // Text
-
-        KEY_GLOBAL_SETTING                = 101,
-        KEY_LOCAL_SETTING                 = 102,
-        KEY_START_CHAR                    = 103,
-        KEY_END_CHAR                      = 104,
-        KEY_FONT_ID                       = 105,
-        KEY_FONT_SIZE                     = 106,
-        KEY_TEXT_COLOR_RGBA               = 107,
-    };
-
-    static status_t extractSRTLocalDescriptions(
-            const uint8_t *data, ssize_t size,
-            int timeMs, PlayerMessage *playerMsg);
-    static status_t extract3GPPGlobalDescriptions(
-            const uint8_t *data, ssize_t size,
-            PlayerMessage *playerMsg);
-    static status_t extract3GPPLocalDescriptions(
-            const uint8_t *data, ssize_t size,
-            int timeMs, PlayerMessage *playerMsg);
-
-    DISALLOW_EVIL_CONSTRUCTORS(TextDescriptions2);
-};
-
-}  // namespace android
-#endif  // TEXT_DESCRIPTIONS2_H_
diff --git a/media/libstagefright/webm/Android.bp b/media/libstagefright/webm/Android.bp
index 64ecc2d..2cebe8f 100644
--- a/media/libstagefright/webm/Android.bp
+++ b/media/libstagefright/webm/Android.bp
@@ -27,12 +27,14 @@
     include_dirs: ["frameworks/av/include"],
 
     shared_libs: [
+        "libdatasource",
         "libstagefright_foundation",
         "libutils",
         "liblog",
     ],
 
     header_libs: [
+        "libmedia_headers",
         "media_ndk_headers",
     ],
 }
diff --git a/media/libstagefright/webm/WebmFrameThread.h b/media/libstagefright/webm/WebmFrameThread.h
index 1ddaf9a..2dde20a 100644
--- a/media/libstagefright/webm/WebmFrameThread.h
+++ b/media/libstagefright/webm/WebmFrameThread.h
@@ -20,8 +20,8 @@
 #include "WebmFrame.h"
 #include "LinkedBlockingQueue.h"
 
+#include <datasource/FileSource.h>
 #include <media/MediaSource.h>
-#include <media/stagefright/FileSource.h>
 
 #include <utils/List.h>
 #include <utils/Errors.h>
diff --git a/media/libstagefright/xmlparser/MediaCodecsXmlParser.cpp b/media/libstagefright/xmlparser/MediaCodecsXmlParser.cpp
index 9783e9b..d905b8d 100644
--- a/media/libstagefright/xmlparser/MediaCodecsXmlParser.cpp
+++ b/media/libstagefright/xmlparser/MediaCodecsXmlParser.cpp
@@ -1269,7 +1269,7 @@
 void MediaCodecsXmlParser::Impl::State::addDetail(
         const std::string &key, const std::string &value) {
     CHECK(inType());
-    ALOGI("limit: %s = %s", key.c_str(), value.c_str());
+    ALOGV("limit: %s = %s", key.c_str(), value.c_str());
     const StringSet &variants = mVariantsStack.back();
     if (variants.empty()) {
         type()[key] = value;
diff --git a/media/mtp/MtpServer.cpp b/media/mtp/MtpServer.cpp
index ca8cb78..a291939 100644
--- a/media/mtp/MtpServer.cpp
+++ b/media/mtp/MtpServer.cpp
@@ -42,6 +42,7 @@
 #include "MtpServer.h"
 #include "MtpStorage.h"
 #include "MtpStringBuffer.h"
+#include "android-base/strings.h"
 
 namespace android {
 
@@ -955,6 +956,11 @@
     if (!mData.getString(modified)) return MTP_RESPONSE_INVALID_PARAMETER;     // date modified
     // keywords follow
 
+    int type = storage->getType();
+    if (type == MTP_STORAGE_REMOVABLE_RAM) {
+        std::string str = android::base::Trim((const char*)name);
+        name.set(str.c_str());
+    }
     ALOGV("name: %s format: 0x%04X (%s)\n", (const char*)name, format,
           MtpDebug::getFormatCodeName(format));
     time_t modifiedTime;
diff --git a/media/mtp/PosixAsyncIO.cpp b/media/mtp/PosixAsyncIO.cpp
index 72c07cc..8205e3b 100644
--- a/media/mtp/PosixAsyncIO.cpp
+++ b/media/mtp/PosixAsyncIO.cpp
@@ -47,10 +47,10 @@
         CHECK(aiocbp->queued);
         int ret;
         if (aiocbp->read) {
-            ret = TEMP_FAILURE_RETRY(pread(aiocbp->aio_fildes,
+            ret = TEMP_FAILURE_RETRY(pread64(aiocbp->aio_fildes,
                     aiocbp->aio_buf, aiocbp->aio_nbytes, aiocbp->aio_offset));
         } else {
-            ret = TEMP_FAILURE_RETRY(pwrite(aiocbp->aio_fildes,
+            ret = TEMP_FAILURE_RETRY(pwrite64(aiocbp->aio_fildes,
                aiocbp->aio_buf, aiocbp->aio_nbytes, aiocbp->aio_offset));
         }
         {
@@ -139,7 +139,7 @@
     return 0;
 }
 
-void aio_prepare(struct aiocb *aiocbp, void* buf, size_t count, off_t offset) {
+void aio_prepare(struct aiocb *aiocbp, void* buf, size_t count, off64_t offset) {
     aiocbp->aio_buf = buf;
     aiocbp->aio_offset = offset;
     aiocbp->aio_nbytes = count;
diff --git a/media/mtp/PosixAsyncIO.h b/media/mtp/PosixAsyncIO.h
index 2bb5735..2bcae4c 100644
--- a/media/mtp/PosixAsyncIO.h
+++ b/media/mtp/PosixAsyncIO.h
@@ -32,7 +32,7 @@
     int aio_fildes;
     void *aio_buf;
 
-    off_t aio_offset;
+    off64_t aio_offset;
     size_t aio_nbytes;
 
     // Used internally
@@ -61,7 +61,7 @@
 ssize_t aio_return(struct aiocb *);
 
 // Helper method for setting aiocb members
-void aio_prepare(struct aiocb *, void*, size_t, off_t);
+void aio_prepare(struct aiocb *, void*, size_t, off64_t);
 
 #endif // POSIXASYNCIO_H
 
diff --git a/media/ndk/Android.bp b/media/ndk/Android.bp
index a3cabd8..aac6d71 100644
--- a/media/ndk/Android.bp
+++ b/media/ndk/Android.bp
@@ -54,7 +54,6 @@
     ],
 
     include_dirs: [
-        "bionic/libc/private",
         "frameworks/base/core/jni",
         "frameworks/native/include/media/openmax",
         "system/media/camera/include",
@@ -70,16 +69,21 @@
         "libgrallocusage",
     ],
 
+    header_libs: [
+        "libmediadrm_headers",
+    ],
+
     shared_libs: [
         "android.hardware.graphics.bufferqueue@1.0",
         "android.hidl.token@1.0-utils",
         "libandroid_runtime_lazy",
         "libbase",
         "libbinder",
+        "libdatasource",
         "libmedia",
+        "libmediadrm",
         "libmedia_omx",
         "libmedia_jni_utils",
-        "libmediadrm",
         "libstagefright",
         "libstagefright_foundation",
         "liblog",
@@ -90,7 +94,6 @@
         "libhidlbase",
         "libgui",
         "libui",
-        "libmedia2_jni_core",
         "libmediandk_utils",
     ],
 
@@ -146,6 +149,10 @@
         "-Wall",
     ],
 
+    header_libs: [
+        "libmedia_headers",
+    ],
+
     shared_libs: [
     ],
 
diff --git a/media/ndk/NdkMediaCodec.cpp b/media/ndk/NdkMediaCodec.cpp
index e041533..af21a99 100644
--- a/media/ndk/NdkMediaCodec.cpp
+++ b/media/ndk/NdkMediaCodec.cpp
@@ -250,8 +250,8 @@
                          ALOGE("CB_ERROR: err is expected.");
                          break;
                      }
-                     if (!msg->findInt32("action", &actionCode)) {
-                         ALOGE("CB_ERROR: action is expected.");
+                     if (!msg->findInt32("actionCode", &actionCode)) {
+                         ALOGE("CB_ERROR: actionCode is expected.");
                          break;
                      }
                      msg->findString("detail", &detail);
diff --git a/media/ndk/NdkMediaCrypto.cpp b/media/ndk/NdkMediaCrypto.cpp
index ce2c660..792fc00 100644
--- a/media/ndk/NdkMediaCrypto.cpp
+++ b/media/ndk/NdkMediaCrypto.cpp
@@ -27,8 +27,8 @@
 #include <utils/Log.h>
 #include <utils/StrongPointer.h>
 #include <binder/IServiceManager.h>
-#include <media/ICrypto.h>
-#include <media/IMediaDrmService.h>
+#include <mediadrm/ICrypto.h>
+#include <mediadrm/IMediaDrmService.h>
 #include <android_util_Binder.h>
 
 #include <jni.h>
diff --git a/media/ndk/NdkMediaCryptoPriv.h b/media/ndk/NdkMediaCryptoPriv.h
index 14ea928..8664d95 100644
--- a/media/ndk/NdkMediaCryptoPriv.h
+++ b/media/ndk/NdkMediaCryptoPriv.h
@@ -30,7 +30,7 @@
 
 #include <sys/types.h>
 #include <utils/StrongPointer.h>
-#include <media/ICrypto.h>
+#include <mediadrm/ICrypto.h>
 
 using namespace android;
 
diff --git a/media/ndk/NdkMediaDataSource.cpp b/media/ndk/NdkMediaDataSource.cpp
index 7979c2f..c1d4686 100644
--- a/media/ndk/NdkMediaDataSource.cpp
+++ b/media/ndk/NdkMediaDataSource.cpp
@@ -26,18 +26,16 @@
 #include <android_runtime/AndroidRuntime.h>
 #include <android_util_Binder.h>
 #include <cutils/properties.h>
-#include <utils/Log.h>
-#include <utils/StrongPointer.h>
+#include <datasource/DataSourceFactory.h>
+#include <datasource/HTTPBase.h>
+#include <datasource/NuCachedSource2.h>
 #include <media/IMediaHTTPService.h>
 #include <media/NdkMediaError.h>
 #include <media/NdkMediaDataSource.h>
-#include <media/stagefright/DataSourceFactory.h>
 #include <media/stagefright/InterfaceUtils.h>
-#include <mediaplayer2/JavaVMHelper.h>
-#include <mediaplayer2/JMedia2HTTPService.h>
+#include <utils/Log.h>
+#include <utils/StrongPointer.h>
 
-#include "../../libstagefright/include/HTTPBase.h"
-#include "../../libstagefright/include/NuCachedSource2.h"
 #include "NdkMediaDataSourceCallbacksPriv.h"
 
 
@@ -120,18 +118,11 @@
     return size >= 0 ? OK : UNKNOWN_ERROR;
 }
 
-static sp<MediaHTTPService> createMediaHttpServiceFromJavaObj(JNIEnv *env, jobject obj, int version) {
+static sp<MediaHTTPService> createMediaHttpServiceFromJavaObj(JNIEnv *env, jobject obj) {
     if (obj == NULL) {
         return NULL;
     }
-    switch (version) {
-        case 1:
-            return interface_cast<IMediaHTTPService>(ibinderForJavaObject(env, obj));
-        case 2:
-            return new JMedia2HTTPService(env, obj);
-        default:
-            return NULL;
-    }
+    return interface_cast<IMediaHTTPService>(ibinderForJavaObject(env, obj));
 }
 
 static sp<MediaHTTPService> createMediaHttpServiceTemplate(
@@ -139,8 +130,7 @@
         const char *uri,
         const char *clazz,
         const char *method,
-        const char *signature,
-        int version) {
+        const char *signature) {
     jobject service = NULL;
     if (env == NULL) {
         ALOGE("http service must be created from Java thread");
@@ -167,34 +157,22 @@
     env->DeleteLocalRef(juri);
 
     env->ExceptionClear();
-    sp<MediaHTTPService> httpService = createMediaHttpServiceFromJavaObj(env, service, version);
+    sp<MediaHTTPService> httpService = createMediaHttpServiceFromJavaObj(env, service);
     return httpService;
 
 }
 
-sp<MediaHTTPService> createMediaHttpService(const char *uri, int version) {
+sp<MediaHTTPService> createMediaHttpService(const char *uri) {
 
     JNIEnv *env;
     const char *clazz, *method, *signature;
 
-    switch (version) {
-        case 1:
-            env = AndroidRuntime::getJNIEnv();
-            clazz = "android/media/MediaHTTPService";
-            method = "createHttpServiceBinderIfNecessary";
-            signature = "(Ljava/lang/String;)Landroid/os/IBinder;";
-            break;
-        case 2:
-            env = JavaVMHelper::getJNIEnv();
-            clazz = "android/media/Media2HTTPService";
-            method = "createHTTPService";
-            signature = "(Ljava/lang/String;)Landroid/media/Media2HTTPService;";
-            break;
-        default:
-            return NULL;
-    }
+    env = AndroidRuntime::getJNIEnv();
+    clazz = "android/media/MediaHTTPService";
+    method = "createHttpServiceBinderIfNecessary";
+    signature = "(Ljava/lang/String;)Landroid/os/IBinder;";
 
-    return createMediaHttpServiceTemplate(env, uri, clazz, method, signature, version);
+    return createMediaHttpServiceTemplate(env, uri, clazz, method, signature);
 
 }
 
@@ -216,7 +194,7 @@
         int numheaders,
         const char * const *key_values) {
 
-    sp<MediaHTTPService> service = createMediaHttpService(uri, /* version = */ 1);
+    sp<MediaHTTPService> service = createMediaHttpService(uri);
     KeyedVector<String8, String8> headers;
     for (int i = 0; i < numheaders; ++i) {
         String8 key8(key_values[i * 2]);
@@ -224,7 +202,7 @@
         headers.add(key8, value8);
     }
 
-    sp<DataSource> source = DataSourceFactory::CreateFromURI(service, uri, &headers);
+    sp<DataSource> source = DataSourceFactory::getInstance()->CreateFromURI(service, uri, &headers);
     if (source == NULL) {
         ALOGE("AMediaDataSource_newUri source is null");
         return NULL;
diff --git a/media/ndk/NdkMediaDataSourcePriv.h b/media/ndk/NdkMediaDataSourcePriv.h
index 16ff974..ddcd7da 100644
--- a/media/ndk/NdkMediaDataSourcePriv.h
+++ b/media/ndk/NdkMediaDataSourcePriv.h
@@ -62,7 +62,7 @@
 
 };
 
-sp<MediaHTTPService> createMediaHttpService(const char *uri, int version);
+sp<MediaHTTPService> createMediaHttpService(const char *uri);
 
 #endif // _NDK_MEDIA_DATASOURCE_PRIV_H
 
diff --git a/media/ndk/NdkMediaDrm.cpp b/media/ndk/NdkMediaDrm.cpp
index cd5a23a..842216c 100644
--- a/media/ndk/NdkMediaDrm.cpp
+++ b/media/ndk/NdkMediaDrm.cpp
@@ -29,12 +29,12 @@
 
 #include <android-base/properties.h>
 #include <binder/PermissionController.h>
-#include <media/IDrm.h>
-#include <media/IDrmClient.h>
+#include <mediadrm/IDrm.h>
+#include <mediadrm/IDrmClient.h>
 #include <media/stagefright/MediaErrors.h>
 #include <binder/IServiceManager.h>
-#include <media/IMediaDrmService.h>
 #include <media/NdkMediaCrypto.h>
+#include <mediadrm/IMediaDrmService.h>
 
 
 using namespace android;
diff --git a/media/ndk/NdkMediaExtractor.cpp b/media/ndk/NdkMediaExtractor.cpp
index c83b255..0da0740 100644
--- a/media/ndk/NdkMediaExtractor.cpp
+++ b/media/ndk/NdkMediaExtractor.cpp
@@ -89,7 +89,7 @@
 
     ALOGV("setDataSource(%s)", uri);
 
-    sp<MediaHTTPService> httpService = createMediaHttpService(uri, /* version = */ 1);
+    sp<MediaHTTPService> httpService = createMediaHttpService(uri);
     if (httpService == NULL) {
         ALOGE("can't create http service");
         return AMEDIA_ERROR_UNSUPPORTED;
diff --git a/media/ndk/include/media/NdkImage.h b/media/ndk/include/media/NdkImage.h
index 3e60de0..62b8624 100644
--- a/media/ndk/include/media/NdkImage.h
+++ b/media/ndk/include/media/NdkImage.h
@@ -570,6 +570,8 @@
  * return {@link AMEDIA_ERROR_INVALID_OBJECT}. Application still needs to call this method on those
  * {@link AImage} objects to fully delete the {@link AImage} object from memory.</p>
  *
+ * Available since API level 24.
+ *
  * @param image The {@link AImage} to be deleted.
  */
 void AImage_delete(AImage* image) __INTRODUCED_IN(24);
@@ -577,6 +579,8 @@
 /**
  * Query the width of the input {@link AImage}.
  *
+ * Available since API level 24.
+ *
  * @param image the {@link AImage} of interest.
  * @param width the width of the image will be filled here if the method call succeeeds.
  *
@@ -591,6 +595,8 @@
 /**
  * Query the height of the input {@link AImage}.
  *
+ * Available since API level 24.
+ *
  * @param image the {@link AImage} of interest.
  * @param height the height of the image will be filled here if the method call succeeeds.
  *
@@ -607,6 +613,8 @@
  *
  * <p>The format value will be one of AIMAGE_FORMAT_* enum value.</p>
  *
+ * Available since API level 24.
+ *
  * @param image the {@link AImage} of interest.
  * @param format the format of the image will be filled here if the method call succeeeds.
  *
@@ -624,6 +632,8 @@
  * <p>The crop rectangle specifies the region of valid pixels in the image, using coordinates in the
  * largest-resolution plane.</p>
  *
+ * Available since API level 24.
+ *
  * @param image the {@link AImage} of interest.
  * @param rect the cropped rectangle of the image will be filled here if the method call succeeeds.
  *
@@ -648,6 +658,8 @@
  * {@link ACameraCaptureSession_captureCallbacks#onCaptureCompleted} callback.
  * </p>
  *
+ * Available since API level 24.
+ *
  * @param image the {@link AImage} of interest.
  * @param timestampNs the timestamp of the image will be filled here if the method call succeeeds.
  *
@@ -665,6 +677,8 @@
  * <p>The number of plane of an {@link AImage} is determined by its format, which can be queried by
  * {@link AImage_getFormat} method.</p>
  *
+ * Available since API level 24.
+ *
  * @param image the {@link AImage} of interest.
  * @param numPlanes the number of planes of the image will be filled here if the method call
  *         succeeeds.
@@ -687,6 +701,8 @@
  * being returned.
  * For formats where pixel stride is well defined, the pixel stride is always greater than 0.</p>
  *
+ * Available since API level 24.
+ *
  * @param image the {@link AImage} of interest.
  * @param planeIdx the index of the plane. Must be less than the number of planes of input image.
  * @param pixelStride the pixel stride of the image will be filled here if the method call succeeeds.
@@ -714,6 +730,8 @@
  * being returned.
  * For formats where row stride is well defined, the row stride is always greater than 0.</p>
  *
+ * Available since API level 24.
+ *
  * @param image the {@link AImage} of interest.
  * @param planeIdx the index of the plane. Must be less than the number of planes of input image.
  * @param rowStride the row stride of the image will be filled here if the method call succeeeds.
@@ -739,6 +757,8 @@
  * pointer from previous AImage_getPlaneData call becomes invalid. Do NOT use it after the
  * {@link AImage} or the parent {@link AImageReader} is deleted.</p>
  *
+ * Available since API level 24.
+ *
  * @param image the {@link AImage} of interest.
  * @param planeIdx the index of the plane. Must be less than the number of planes of input image.
  * @param data the data pointer of the image will be filled here if the method call succeeeds.
@@ -769,6 +789,8 @@
  * signal the release of the hardware buffer back to the {@link AImageReader}'s queue using
  * releaseFenceFd.</p>
  *
+ * Available since API level 26.
+ *
  * @param image The {@link AImage} to be deleted.
  * @param releaseFenceFd A sync fence fd defined in {@link sync.h}, which signals the release of
  *         underlying {@link AHardwareBuffer}.
@@ -794,6 +816,8 @@
  * {@link AImageReader_setBufferRemovedListener} to be notified when the buffer is no longer used
  * by {@link AImageReader}.</p>
  *
+ * Available since API level 26.
+ *
  * @param image the {@link AImage} of interest.
  * @param outBuffer The memory area pointed to by buffer will contain the acquired AHardwareBuffer
  *         handle.
diff --git a/media/ndk/include/media/NdkImageReader.h b/media/ndk/include/media/NdkImageReader.h
index e5d863c..600ffc9 100644
--- a/media/ndk/include/media/NdkImageReader.h
+++ b/media/ndk/include/media/NdkImageReader.h
@@ -67,6 +67,8 @@
  * The valid sizes and formats depend on the source of the image data.
  * </p>
  *
+ * Available since API level 24.
+ *
  * @param width The default width in pixels of the Images that this reader will produce.
  * @param height The default height in pixels of the Images that this reader will produce.
  * @param format The format of the Image that this reader will produce. This must be one of the
@@ -101,6 +103,8 @@
  * making any of data pointers obtained from {@link AImage_getPlaneData} invalid. Do NOT access
  * the reader object or any of those data pointers after this method returns.</p>
  *
+ * Available since API level 24.
+ *
  * @param reader The image reader to be deleted.
  */
 void AImageReader_delete(AImageReader* reader) __INTRODUCED_IN(24);
@@ -108,6 +112,8 @@
 /**
  * Get a {@link ANativeWindow} that can be used to produce {@link AImage} for this image reader.
  *
+ * Available since API level 24.
+ *
  * @param reader The image reader of interest.
  * @param window The output {@link ANativeWindow} will be filled here if the method call succeeds.
  *                The {@link ANativeWindow} is managed by this image reader. Do NOT call
@@ -126,6 +132,8 @@
  * {@link ANativeWindow}. If so, the actual width of the images can be found using
  * {@link AImage_getWidth}.</p>
  *
+ * Available since API level 24.
+ *
  * @param reader The image reader of interest.
  * @param width the default width of the reader will be filled here if the method call succeeeds.
  *
@@ -142,6 +150,8 @@
  * {@link ANativeWindow}. If so, the actual height of the images can be found using
  * {@link AImage_getHeight}.</p>
  *
+ * Available since API level 24.
+ *
  * @param reader The image reader of interest.
  * @param height the default height of the reader will be filled here if the method call succeeeds.
  *
@@ -154,6 +164,8 @@
 /**
  * Query the format of the {@link AImage} generated by this reader.
  *
+ * Available since API level 24.
+ *
  * @param reader The image reader of interest.
  * @param format the fromat of the reader will be filled here if the method call succeeeds. The
  *                value will be one of the AIMAGE_FORMAT_* enum value defiend in {@link NdkImage.h}.
@@ -167,6 +179,8 @@
 /**
  * Query the maximum number of concurrently acquired {@link AImage}s of this reader.
  *
+ * Available since API level 24.
+ *
  * @param reader The image reader of interest.
  * @param maxImages the maximum number of concurrently acquired images of the reader will be filled
  *                here if the method call succeeeds.
@@ -197,6 +211,8 @@
  * {@link AImage_delete}.
  * </p>
  *
+ * Available since API level 24.
+ *
  * @param reader The image reader of interest.
  * @param image the acquired {@link AImage} will be filled here if the method call succeeeds.
  *
@@ -214,7 +230,6 @@
 media_status_t AImageReader_acquireNextImage(AImageReader* reader, /*out*/AImage** image) __INTRODUCED_IN(24);
 
 /**
-
  * Acquire the latest {@link AImage} from the image reader's queue, dropping older images.
  *
  * <p>
@@ -241,6 +256,8 @@
  * {@link AImage_delete}.
  * </p>
  *
+ * Available since API level 24.
+ *
  * @param reader The image reader of interest.
  * @param image the acquired {@link AImage} will be filled here if the method call succeeeds.
  *
@@ -290,6 +307,8 @@
  *
  * Calling this method will replace previously registered listeners.
  *
+ * Available since API level 24.
+ *
  * @param reader The image reader of interest.
  * @param listener The {@link AImageReader_ImageListener} to be registered. Set this to NULL if
  *                 the application no longer needs to listen to new images.
@@ -356,6 +375,9 @@
  *   {@link AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE}, or combined</td>
  * </tr>
  * </table>
+ *
+ * Available since API level 26.
+ *
  * @return <ul>
  *         <li>{@link AMEDIA_OK} if the method call succeeds.</li>
  *         <li>{@link AMEDIA_ERROR_INVALID_PARAMETER} if reader is NULL, or one or more of width,
@@ -377,6 +399,8 @@
  * additional parameter for the sync fence. All other parameters and the return values are
  * identical to those passed to {@link AImageReader_acquireNextImage}.</p>
  *
+ * Available since API level 26.
+ *
  * @param acquireFenceFd A sync fence fd defined in {@link sync.h}, which is used to signal when the
  *         buffer is ready to consume. When synchronization fence is not needed, fence will be set
  *         to -1 and the {@link AImage} returned is ready for use immediately. Otherwise, user shall
@@ -397,6 +421,8 @@
  * additional parameter for the sync fence. All other parameters and the return values are
  * identical to those passed to {@link AImageReader_acquireLatestImage}.</p>
  *
+ * Available since API level 26.
+ *
  * @param acquireFenceFd A sync fence fd defined in {@link sync.h}, which is used to signal when the
  *         buffer is ready to consume. When synchronization fence is not needed, fence will be set
  *         to -1 and the {@link AImage} returned is ready for use immediately. Otherwise, user shall
@@ -408,6 +434,7 @@
  */
 media_status_t AImageReader_acquireLatestImageAsync(
         AImageReader* reader, /*out*/AImage** image, /*out*/int* acquireFenceFd) __INTRODUCED_IN(26);
+
 /**
  * Signature of the callback which is called when {@link AImageReader} is about to remove a buffer.
  *
@@ -451,6 +478,8 @@
  *
  * <p>Note that calling this method will replace previously registered listeners.</p>
  *
+ * Available since API level 26.
+ *
  * @param reader The image reader of interest.
  * @param listener the {@link AImageReader_BufferRemovedListener} to be registered. Set this to
  * NULL if application no longer needs to listen to buffer removed events.
diff --git a/media/ndk/include/media/NdkMediaCodec.h b/media/ndk/include/media/NdkMediaCodec.h
index b3ee853..1823fbc 100644
--- a/media/ndk/include/media/NdkMediaCodec.h
+++ b/media/ndk/include/media/NdkMediaCodec.h
@@ -127,27 +127,37 @@
  * Create codec by name. Use this if you know the exact codec you want to use.
  * When configuring, you will need to specify whether to use the codec as an
  * encoder or decoder.
+ *
+ * Available since API level 21.
  */
 AMediaCodec* AMediaCodec_createCodecByName(const char *name) __INTRODUCED_IN(21);
 
 /**
  * Create codec by mime type. Most applications will use this, specifying a
  * mime type obtained from media extractor.
+ *
+ * Available since API level 21.
  */
 AMediaCodec* AMediaCodec_createDecoderByType(const char *mime_type) __INTRODUCED_IN(21);
 
 /**
  * Create encoder by name.
+ *
+ * Available since API level 21.
  */
 AMediaCodec* AMediaCodec_createEncoderByType(const char *mime_type) __INTRODUCED_IN(21);
 
 /**
- * delete the codec and free its resources
+ * Delete the codec and free its resources.
+ *
+ * Available since API level 21.
  */
 media_status_t AMediaCodec_delete(AMediaCodec*) __INTRODUCED_IN(21);
 
 /**
  * Configure the codec. For decoding you would typically get the format from an extractor.
+ *
+ * Available since API level 21.
  */
 media_status_t AMediaCodec_configure(
         AMediaCodec*,
@@ -159,29 +169,39 @@
 /**
  * Start the codec. A codec must be configured before it can be started, and must be started
  * before buffers can be sent to it.
+ *
+ * Available since API level 21.
  */
 media_status_t AMediaCodec_start(AMediaCodec*) __INTRODUCED_IN(21);
 
 /**
  * Stop the codec.
+ *
+ * Available since API level 21.
  */
 media_status_t AMediaCodec_stop(AMediaCodec*) __INTRODUCED_IN(21);
 
 /*
  * Flush the codec's input and output. All indices previously returned from calls to
  * AMediaCodec_dequeueInputBuffer and AMediaCodec_dequeueOutputBuffer become invalid.
+ *
+ * Available since API level 21.
  */
 media_status_t AMediaCodec_flush(AMediaCodec*) __INTRODUCED_IN(21);
 
 /**
  * Get an input buffer. The specified buffer index must have been previously obtained from
  * dequeueInputBuffer, and not yet queued.
+ *
+ * Available since API level 21.
  */
 uint8_t* AMediaCodec_getInputBuffer(AMediaCodec*, size_t idx, size_t *out_size) __INTRODUCED_IN(21);
 
 /**
  * Get an output buffer. The specified buffer index must have been previously obtained from
  * dequeueOutputBuffer, and not yet queued.
+ *
+ * Available since API level 21.
  */
 uint8_t* AMediaCodec_getOutputBuffer(AMediaCodec*, size_t idx, size_t *out_size) __INTRODUCED_IN(21);
 
@@ -189,6 +209,8 @@
  * Get the index of the next available input buffer. An app will typically use this with
  * getInputBuffer() to get a pointer to the buffer, then copy the data to be encoded or decoded
  * into the buffer before passing it to the codec.
+ *
+ * Available since API level 21.
  */
 ssize_t AMediaCodec_dequeueInputBuffer(AMediaCodec*, int64_t timeoutUs) __INTRODUCED_IN(21);
 
@@ -218,6 +240,8 @@
 
 /**
  * Send the specified buffer to the codec for processing.
+ *
+ * Available since API level 21.
  */
 media_status_t AMediaCodec_queueInputBuffer(AMediaCodec*, size_t idx,
                                             _off_t_compat offset, size_t size,
@@ -225,6 +249,8 @@
 
 /**
  * Send the specified buffer to the codec for processing.
+ *
+ * Available since API level 21.
  */
 media_status_t AMediaCodec_queueSecureInputBuffer(AMediaCodec*, size_t idx,
                                                   _off_t_compat offset,
@@ -235,15 +261,23 @@
 
 /**
  * Get the index of the next available buffer of processed data.
+ *
+ * Available since API level 21.
  */
 ssize_t AMediaCodec_dequeueOutputBuffer(AMediaCodec*, AMediaCodecBufferInfo *info,
         int64_t timeoutUs) __INTRODUCED_IN(21);
+
+/**
+ * Available since API level 21.
+ */
 AMediaFormat* AMediaCodec_getOutputFormat(AMediaCodec*) __INTRODUCED_IN(21);
 
 /**
  * If you are done with a buffer, use this call to return the buffer to
  * the codec. If you previously specified a surface when configuring this
  * video decoder you can optionally render the buffer.
+ *
+ * Available since API level 21.
  */
 media_status_t AMediaCodec_releaseOutputBuffer(AMediaCodec*, size_t idx, bool render) __INTRODUCED_IN(21);
 
@@ -256,6 +290,8 @@
  *  to ImageReader (software readable) output.
  *
  * For more details, see the Java documentation for MediaCodec.setOutputSurface.
+ *
+ * Available since API level 21.
  */
 media_status_t AMediaCodec_setOutputSurface(AMediaCodec*, ANativeWindow* surface) __INTRODUCED_IN(21);
 
@@ -266,6 +302,8 @@
  * this call will simply return the buffer to the codec.
  *
  * For more details, see the Java documentation for MediaCodec.releaseOutputBuffer.
+ *
+ * Available since API level 21.
  */
 media_status_t AMediaCodec_releaseOutputBufferAtTime(
         AMediaCodec *mData, size_t idx, int64_t timestampNs) __INTRODUCED_IN(21);
@@ -282,6 +320,8 @@
  * ANativeWindow_release() when done.
  *
  * For more details, see the Java documentation for MediaCodec.createInputSurface.
+ *
+ * Available since API level 26.
  */
 media_status_t AMediaCodec_createInputSurface(
         AMediaCodec *mData, ANativeWindow **surface) __INTRODUCED_IN(26);
@@ -298,6 +338,8 @@
  * ANativeWindow_release() when done.
  *
  * For more details, see the Java documentation for MediaCodec.createPersistentInputSurface.
+ *
+ * Available since API level 26.
  */
 media_status_t AMediaCodec_createPersistentInputSurface(
         ANativeWindow **surface) __INTRODUCED_IN(26);
@@ -311,6 +353,8 @@
  * AMediaCodec_configure(..); and before AMediaCodec_start() has been called.
  *
  * For more details, see the Java documentation for MediaCodec.setInputSurface.
+ *
+ * Available since API level 26.
  */
 media_status_t AMediaCodec_setInputSurface(
         AMediaCodec *mData, ANativeWindow *surface) __INTRODUCED_IN(26);
@@ -322,6 +366,8 @@
  * after AMediaCodec_start() has been called.
  *
  * NOTE: Some of these parameter changes may silently fail to apply.
+ *
+ * Available since API level 26.
  */
 media_status_t AMediaCodec_setParameters(
         AMediaCodec *mData, const AMediaFormat* params) __INTRODUCED_IN(26);
@@ -339,6 +385,8 @@
  * Returns AMEDIA_OK when completed succesfully.
  *
  * For more details, see the Java documentation for MediaCodec.signalEndOfInputStream.
+ *
+ * Available since API level 26.
  */
 media_status_t AMediaCodec_signalEndOfInputStream(AMediaCodec *mData) __INTRODUCED_IN(26);
 
@@ -349,6 +397,8 @@
 /**
  * Get format of the buffer. The specified buffer index must have been previously obtained from
  * dequeueOutputBuffer.
+ *
+ * Available since API level 28.
  */
 AMediaFormat* AMediaCodec_getBufferFormat(AMediaCodec*, size_t index) __INTRODUCED_IN(28);
 
@@ -356,11 +406,15 @@
  * Get the component name. If the codec was created by createDecoderByType
  * or createEncoderByType, what component is chosen is not known beforehand.
  * Caller shall call AMediaCodec_releaseName to free the returned pointer.
+ *
+ * Available since API level 28.
  */
 media_status_t AMediaCodec_getName(AMediaCodec*, char** out_name) __INTRODUCED_IN(28);
 
 /**
  * Free the memory pointed by name which is returned by AMediaCodec_getName.
+ *
+ * Available since API level 28.
  */
 void AMediaCodec_releaseName(AMediaCodec*, char* name) __INTRODUCED_IN(28);
 
@@ -382,6 +436,8 @@
  * All callbacks are fired on one NDK internal thread.
  * AMediaCodec_setAsyncNotifyCallback should not be called on the callback thread.
  * No heavy duty task should be performed on callback thread.
+ *
+ * Available since API level 28.
  */
 media_status_t AMediaCodec_setAsyncNotifyCallback(
         AMediaCodec*,
@@ -390,6 +446,8 @@
 
 /**
  * Release the crypto if applicable.
+ *
+ * Available since API level 28.
  */
 media_status_t AMediaCodec_releaseCrypto(AMediaCodec*) __INTRODUCED_IN(28);
 
@@ -397,12 +455,16 @@
  * Call this after AMediaCodec_configure() returns successfully to get the input
  * format accepted by the codec. Do this to determine what optional configuration
  * parameters were supported by the codec.
+ *
+ * Available since API level 28.
  */
 AMediaFormat* AMediaCodec_getInputFormat(AMediaCodec*) __INTRODUCED_IN(28);
 
 /**
  * Returns true if the codec cannot proceed further, but can be recovered by stopping,
  * configuring, and starting again.
+ *
+ * Available since API level 28.
  */
 bool AMediaCodecActionCode_isRecoverable(int32_t actionCode) __INTRODUCED_IN(28);
 
@@ -410,6 +472,8 @@
  * Returns true if the codec error is a transient issue, perhaps due to
  * resource constraints, and that the method (or encoding/decoding) may be
  * retried at a later time.
+ *
+ * Available since API level 28.
  */
 bool AMediaCodecActionCode_isTransient(int32_t actionCode) __INTRODUCED_IN(28);
 
@@ -440,6 +504,8 @@
  * numBytesOfClearData can be null to indicate that all data is encrypted.
  * This information encapsulates per-sample metadata as outlined in
  * ISO/IEC FDIS 23001-7:2011 "Common encryption in ISO base media file format files".
+ *
+ * Available since API level 21.
  */
 AMediaCodecCryptoInfo *AMediaCodecCryptoInfo_new(
         int numsubsamples,
@@ -450,13 +516,17 @@
         size_t *encryptedbytes) __INTRODUCED_IN(21);
 
 /**
- * delete an AMediaCodecCryptoInfo created previously with AMediaCodecCryptoInfo_new, or
- * obtained from AMediaExtractor
+ * Delete an AMediaCodecCryptoInfo created previously with AMediaCodecCryptoInfo_new, or
+ * obtained from AMediaExtractor.
+ *
+ * Available since API level 21.
  */
 media_status_t AMediaCodecCryptoInfo_delete(AMediaCodecCryptoInfo*) __INTRODUCED_IN(21);
 
 /**
- * Set the crypto pattern on an AMediaCryptoInfo object
+ * Set the crypto pattern on an AMediaCryptoInfo object.
+ *
+ * Available since API level 21.
  */
 void AMediaCodecCryptoInfo_setPattern(
         AMediaCodecCryptoInfo *info,
@@ -464,32 +534,44 @@
 
 /**
  * The number of subsamples that make up the buffer's contents.
+ *
+ * Available since API level 21.
  */
 size_t AMediaCodecCryptoInfo_getNumSubSamples(AMediaCodecCryptoInfo*) __INTRODUCED_IN(21);
 
 /**
- * A 16-byte opaque key
+ * A 16-byte opaque key.
+ *
+ * Available since API level 21.
  */
 media_status_t AMediaCodecCryptoInfo_getKey(AMediaCodecCryptoInfo*, uint8_t *dst) __INTRODUCED_IN(21);
 
 /**
- * A 16-byte initialization vector
+ * A 16-byte initialization vector.
+ *
+ * Available since API level 21.
  */
 media_status_t AMediaCodecCryptoInfo_getIV(AMediaCodecCryptoInfo*, uint8_t *dst) __INTRODUCED_IN(21);
 
 /**
  * The type of encryption that has been applied,
  * one of AMEDIACODECRYPTOINFO_MODE_CLEAR or AMEDIACODECRYPTOINFO_MODE_AES_CTR.
+ *
+ * Available since API level 21.
  */
 cryptoinfo_mode_t AMediaCodecCryptoInfo_getMode(AMediaCodecCryptoInfo*) __INTRODUCED_IN(21);
 
 /**
  * The number of leading unencrypted bytes in each subsample.
+ *
+ * Available since API level 21.
  */
 media_status_t AMediaCodecCryptoInfo_getClearBytes(AMediaCodecCryptoInfo*, size_t *dst) __INTRODUCED_IN(21);
 
 /**
  * The number of trailing encrypted bytes in each subsample.
+ *
+ * Available since API level 21.
  */
 media_status_t AMediaCodecCryptoInfo_getEncryptedBytes(AMediaCodecCryptoInfo*, size_t *dst) __INTRODUCED_IN(21);
 
diff --git a/media/ndk/include/media/NdkMediaCrypto.h b/media/ndk/include/media/NdkMediaCrypto.h
index bcdf9a0..3fa07c7 100644
--- a/media/ndk/include/media/NdkMediaCrypto.h
+++ b/media/ndk/include/media/NdkMediaCrypto.h
@@ -49,12 +49,24 @@
 
 #if __ANDROID_API__ >= 21
 
+/**
+ * Available since API level 21.
+ */
 bool AMediaCrypto_isCryptoSchemeSupported(const AMediaUUID uuid) __INTRODUCED_IN(21);
 
+/**
+ * Available since API level 21.
+ */
 bool AMediaCrypto_requiresSecureDecoderComponent(const char *mime) __INTRODUCED_IN(21);
 
+/**
+ * Available since API level 21.
+ */
 AMediaCrypto* AMediaCrypto_new(const AMediaUUID uuid, const void *initData, size_t initDataSize) __INTRODUCED_IN(21);
 
+/**
+ * Available since API level 21.
+ */
 void AMediaCrypto_delete(AMediaCrypto* crypto) __INTRODUCED_IN(21);
 
 #endif /* __ANDROID_API__ >= 21 */
diff --git a/media/ndk/include/media/NdkMediaDataSource.h b/media/ndk/include/media/NdkMediaDataSource.h
index 16b1eb3..0577df2 100644
--- a/media/ndk/include/media/NdkMediaDataSource.h
+++ b/media/ndk/include/media/NdkMediaDataSource.h
@@ -88,6 +88,8 @@
 /**
  * Create new media data source. Returns NULL if memory allocation
  * for the new data source object fails.
+ *
+ * Available since API level 28.
  */
 AMediaDataSource* AMediaDataSource_new() __INTRODUCED_IN(28);
 
@@ -116,6 +118,7 @@
  * ...
  * key_values[(numheaders - 1) * 2]:key_values[(numheaders - 1) * 2 + 1]
  *
+ * Available since API level 29.
  */
 AMediaDataSource* AMediaDataSource_newUri(const char *uri,
         int numheaders,
@@ -125,12 +128,16 @@
 
 /**
  * Delete a previously created media data source.
+ *
+ * Available since API level 28.
  */
 void AMediaDataSource_delete(AMediaDataSource*) __INTRODUCED_IN(28);
 
 /**
  * Set an user provided opaque handle. This opaque handle is passed as
  * the first argument to the data source callbacks.
+ *
+ * Available since API level 28.
  */
 void AMediaDataSource_setUserdata(
         AMediaDataSource*, void *userdata) __INTRODUCED_IN(28);
@@ -145,6 +152,8 @@
  *
  * Please refer to the definition of AMediaDataSourceReadAt for
  * additional details.
+ *
+ * Available since API level 28.
  */
 void AMediaDataSource_setReadAt(
         AMediaDataSource*,
@@ -156,6 +165,8 @@
  *
  * Please refer to the definition of AMediaDataSourceGetSize for
  * additional details.
+ *
+ * Available since API level 28.
  */
 void AMediaDataSource_setGetSize(
         AMediaDataSource*,
@@ -167,6 +178,8 @@
  *
  * Please refer to the definition of AMediaDataSourceClose for
  * additional details.
+ *
+ * Available since API level 28.
  */
 void AMediaDataSource_setClose(
         AMediaDataSource*,
@@ -181,6 +194,8 @@
  *
  * Please refer to the definition of AMediaDataSourceClose for
  * additional details.
+ *
+ * Available since API level 29.
  */
 void AMediaDataSource_close(AMediaDataSource*) __INTRODUCED_IN(29);
 
@@ -191,6 +206,8 @@
  *
  * Please refer to the definition of AMediaDataSourceGetAvailableSize
  * for additional details.
+ *
+ * Available since API level 29.
  */
 void AMediaDataSource_setGetAvailableSize(
         AMediaDataSource*,
diff --git a/media/ndk/include/media/NdkMediaDrm.h b/media/ndk/include/media/NdkMediaDrm.h
index 2e438d9..31f5c7d 100644
--- a/media/ndk/include/media/NdkMediaDrm.h
+++ b/media/ndk/include/media/NdkMediaDrm.h
@@ -174,41 +174,53 @@
  * uuid identifies the universal unique ID of the crypto scheme. uuid must be 16 bytes.
  * mimeType is the MIME type of the media container, e.g. "video/mp4".  If mimeType
  * is not known or required, it can be provided as NULL.
+ *
+ * Available since API level 21.
  */
 bool AMediaDrm_isCryptoSchemeSupported(const uint8_t *uuid,
         const char *mimeType) __INTRODUCED_IN(21);
 
 /**
- * Create a MediaDrm instance from a UUID
+ * Create a MediaDrm instance from a UUID.
  * uuid identifies the universal unique ID of the crypto scheme. uuid must be 16 bytes.
+ *
+ * Available since API level 21.
  */
 AMediaDrm* AMediaDrm_createByUUID(const uint8_t *uuid) __INTRODUCED_IN(21);
 
 /**
- * Release a MediaDrm object
+ * Release a MediaDrm object.
+ *
+ * Available since API level 21.
  */
 void AMediaDrm_release(AMediaDrm *) __INTRODUCED_IN(21);
 
 /**
- * Register a callback to be invoked when an event occurs
+ * Register a callback to be invoked when an event occurs.
  *
- * listener is the callback that will be invoked on event
+ * listener is the callback that will be invoked on event.
+ *
+ * Available since API level 21.
  */
 media_status_t AMediaDrm_setOnEventListener(AMediaDrm *,
         AMediaDrmEventListener listener) __INTRODUCED_IN(21);
 
 /**
- * Register a callback to be invoked when an expiration update event occurs
+ * Register a callback to be invoked when an expiration update event occurs.
  *
- * listener is the callback that will be invoked on event
+ * listener is the callback that will be invoked on event.
+ *
+ * Available since API level 29.
  */
 media_status_t AMediaDrm_setOnExpirationUpdateListener(AMediaDrm *,
         AMediaDrmExpirationUpdateListener listener) __INTRODUCED_IN(29);
 
 /**
- * Register a callback to be invoked when a key status change event occurs
+ * Register a callback to be invoked when a key status change event occurs.
  *
- * listener is the callback that will be invoked on event
+ * listener is the callback that will be invoked on event.
+ *
+ * Available since API level 29.
  */
 media_status_t AMediaDrm_setOnKeysChangeListener(AMediaDrm *,
         AMediaDrmKeysChangeListener listener) __INTRODUCED_IN(29);
@@ -216,8 +228,10 @@
 /**
  * Open a new session with the MediaDrm object.  A session ID is returned.
  *
- * returns MEDIADRM_NOT_PROVISIONED_ERROR if provisioning is needed
- * returns MEDIADRM_RESOURCE_BUSY_ERROR if required resources are in use
+ * Returns MEDIADRM_NOT_PROVISIONED_ERROR if provisioning is needed.
+ * Returns MEDIADRM_RESOURCE_BUSY_ERROR if required resources are in use.
+ *
+ * Available since API level 21.
  */
 media_status_t AMediaDrm_openSession(AMediaDrm *,
         AMediaDrmSessionId *sessionId) __INTRODUCED_IN(21);
@@ -225,6 +239,8 @@
 /**
  * Close a session on the MediaDrm object that was previously opened
  * with AMediaDrm_openSession.
+ *
+ * Available since API level 21.
  */
 media_status_t AMediaDrm_closeSession(AMediaDrm *,
         const AMediaDrmSessionId *sessionId) __INTRODUCED_IN(21);
@@ -272,9 +288,11 @@
  *       MediaDrm object is released.
  *   2. keyRequestSize will be set to the size of the request
  *
- * returns MEDIADRM_NOT_PROVISIONED_ERROR if reprovisioning is needed, due to a
+ * Returns MEDIADRM_NOT_PROVISIONED_ERROR if reprovisioning is needed, due to a
  * problem with the device certificate.
-*/
+ *
+ * Available since API level 21.
+ */
 media_status_t AMediaDrm_getKeyRequest(AMediaDrm *, const AMediaDrmScope *scope,
         const uint8_t *init, size_t initSize, const char *mimeType, AMediaDrmKeyType keyType,
         const AMediaDrmKeyValue *optionalParameters, size_t numOptionalParameters,
@@ -295,8 +313,9 @@
  *
  * response points to the opaque response from the server
  * responseSize should be set to the size of the response in bytes
+ *
+ * Available since API level 21.
  */
-
 media_status_t AMediaDrm_provideKeyResponse(AMediaDrm *, const AMediaDrmScope *scope,
         const uint8_t *response, size_t responseSize,
         AMediaDrmKeySetId *keySetId) __INTRODUCED_IN(21);
@@ -305,8 +324,10 @@
  * Restore persisted offline keys into a new session.  keySetId identifies the
  * keys to load, obtained from a prior call to AMediaDrm_provideKeyResponse.
  *
- * sessionId is the session ID for the DRM session
- * keySetId identifies the saved key set to restore
+ * sessionId is the session ID for the DRM session.
+ * keySetId identifies the saved key set to restore.
+ *
+ * Available since API level 21.
  */
 media_status_t AMediaDrm_restoreKeys(AMediaDrm *, const AMediaDrmSessionId *sessionId,
         const AMediaDrmKeySetId *keySetId) __INTRODUCED_IN(21);
@@ -314,7 +335,9 @@
 /**
  * Remove the current keys from a session.
  *
- * keySetId identifies keys to remove
+ * keySetId identifies keys to remove.
+ *
+ * Available since API level 21.
  */
 media_status_t AMediaDrm_removeKeys(AMediaDrm *,
         const AMediaDrmSessionId *keySetId) __INTRODUCED_IN(21);
@@ -331,6 +354,8 @@
  * to the number of entries written to the array.  If the number of {key, value} pairs
  * to be returned is greater than *numPairs, MEDIADRM_SHORT_BUFFER will be returned
  * and numPairs will be set to the number of pairs available.
+ *
+ * Available since API level 21.
  */
 media_status_t AMediaDrm_queryKeyStatus(AMediaDrm *, const AMediaDrmSessionId *sessionId,
         AMediaDrmKeyValue *keyValuePairs, size_t *numPairs) __INTRODUCED_IN(21);
@@ -350,6 +375,8 @@
  *    3. serverUrl will reference a NULL terminated string containing the URL
  *       the provisioning request should be sent to.  It will remain accessible until
  *       the next call to getProvisionRequest.
+ *
+ * Available since API level 21.
  */
 media_status_t AMediaDrm_getProvisionRequest(AMediaDrm *, const uint8_t **provisionRequest,
         size_t *provisionRequestSize, const char **serverUrl) __INTRODUCED_IN(21);
@@ -363,8 +390,10 @@
  *   DRM engine plugin.
  * responseSize is the length of the provisioning response in bytes.
  *
- * returns MEDIADRM_DEVICE_REVOKED_ERROR if the response indicates that the
+ * Returns MEDIADRM_DEVICE_REVOKED_ERROR if the response indicates that the
  * server rejected the request
+ *
+ * Available since API level 21.
  */
 media_status_t AMediaDrm_provideProvisionResponse(AMediaDrm *,
         const uint8_t *response, size_t responseSize) __INTRODUCED_IN(21);
@@ -390,6 +419,8 @@
  * If *numSecureStops is too small for the number of secure stops available,
  * MEDIADRM_SHORT_BUFFER will be returned and *numSecureStops will be set to the
  * number required.
+ *
+ * Available since API level 21.
  */
 media_status_t AMediaDrm_getSecureStops(AMediaDrm *,
         AMediaDrmSecureStop *secureStops, size_t *numSecureStops) __INTRODUCED_IN(21);
@@ -399,6 +430,8 @@
  * the message, remove the SecureStops identified in the response.
  *
  * ssRelease is the server response indicating which secure stops to release
+ *
+ * Available since API level 21.
  */
 media_status_t AMediaDrm_releaseSecureStops(AMediaDrm *,
         const AMediaDrmSecureStop *ssRelease) __INTRODUCED_IN(21);
@@ -432,6 +465,8 @@
  * On return, propertyValue will be set to point to the property value.  The
  * memory that the value resides in is owned by the NDK MediaDrm API and
  * will remain valid until the next call to AMediaDrm_getPropertyString.
+ *
+ * Available since API level 21.
  */
 media_status_t AMediaDrm_getPropertyString(AMediaDrm *, const char *propertyName,
         const char **propertyValue) __INTRODUCED_IN(21);
@@ -447,18 +482,24 @@
  * On return, *propertyValue will be set to point to the property value.  The
  * memory that the value resides in is owned by the NDK MediaDrm API and
  * will remain valid until the next call to AMediaDrm_getPropertyByteArray.
+ *
+ * Available since API level 21.
  */
 media_status_t AMediaDrm_getPropertyByteArray(AMediaDrm *, const char *propertyName,
         AMediaDrmByteArray *propertyValue) __INTRODUCED_IN(21);
 
 /**
  * Set a DRM engine plugin String property value.
+ *
+ * Available since API level 21.
  */
 media_status_t AMediaDrm_setPropertyString(AMediaDrm *, const char *propertyName,
         const char *value) __INTRODUCED_IN(21);
 
 /**
  * Set a DRM engine plugin byte array property value.
+ *
+ * Available since API level 21.
  */
 media_status_t AMediaDrm_setPropertyByteArray(AMediaDrm *, const char *propertyName,
         const uint8_t *value, size_t valueSize) __INTRODUCED_IN(21);
@@ -487,6 +528,8 @@
  * ensure that the output buffer is large enough to accept dataSize bytes. The key
  * to use is identified by the 16 byte keyId.  The key must have been loaded into
  * the session using provideKeyResponse.
+ *
+ * Available since API level 21.
  */
 media_status_t AMediaDrm_encrypt(AMediaDrm *, const AMediaDrmSessionId *sessionId,
         const char *cipherAlgorithm, uint8_t *keyId, uint8_t *iv,
@@ -498,6 +541,8 @@
  * ensure that the output buffer is large enough to accept dataSize bytes.  The key
  * to use is identified by the 16 byte keyId.  The key must have been loaded into
  * the session using provideKeyResponse.
+ *
+ * Available since API level 21.
  */
 media_status_t AMediaDrm_decrypt(AMediaDrm *, const AMediaDrmSessionId *sessionId,
         const char *cipherAlgorithm, uint8_t *keyId, uint8_t *iv,
@@ -511,6 +556,8 @@
  * *signatureSize is set to the buffer size required.  The key to use is identified
  * by the 16 byte keyId.  The key must have been loaded into the session using
  * provideKeyResponse.
+ *
+ * Available since API level 21.
  */
 media_status_t AMediaDrm_sign(AMediaDrm *, const AMediaDrmSessionId *sessionId,
         const char *macAlgorithm, uint8_t *keyId, uint8_t *message, size_t messageSize,
@@ -522,6 +569,8 @@
  * if the signature matches, otherwise MEDAIDRM_VERIFY_FAILED is returned. The key to
  * use is identified by the 16 byte keyId.  The key must have been loaded into the
  * session using provideKeyResponse.
+ *
+ * Available since API level 21.
  */
 media_status_t AMediaDrm_verify(AMediaDrm *, const AMediaDrmSessionId *sessionId,
         const char *macAlgorithm, uint8_t *keyId, const uint8_t *message, size_t messageSize,
diff --git a/media/ndk/include/media/NdkMediaExtractor.h b/media/ndk/include/media/NdkMediaExtractor.h
index e3d9fe6..14319c4 100644
--- a/media/ndk/include/media/NdkMediaExtractor.h
+++ b/media/ndk/include/media/NdkMediaExtractor.h
@@ -52,23 +52,31 @@
 #if __ANDROID_API__ >= 21
 
 /**
- * Create new media extractor
+ * Create new media extractor.
+ *
+ * Available since API level 21.
  */
 AMediaExtractor* AMediaExtractor_new() __INTRODUCED_IN(21);
 
 /**
- * Delete a previously created media extractor
+ * Delete a previously created media extractor.
+ *
+ * Available since API level 21.
  */
 media_status_t AMediaExtractor_delete(AMediaExtractor*) __INTRODUCED_IN(21);
 
 /**
- *  Set the file descriptor from which the extractor will read.
+ * Set the file descriptor from which the extractor will read.
+ *
+ * Available since API level 21.
  */
 media_status_t AMediaExtractor_setDataSourceFd(AMediaExtractor*, int fd, off64_t offset,
         off64_t length) __INTRODUCED_IN(21);
 
 /**
  * Set the URI from which the extractor will read.
+ *
+ * Available since API level 21.
  */
 media_status_t AMediaExtractor_setDataSource(AMediaExtractor*,
         const char *location) __INTRODUCED_IN(21);
@@ -77,6 +85,8 @@
 
 /**
  * Set the custom data source implementation from which the extractor will read.
+ *
+ * Available since API level 28.
  */
 media_status_t AMediaExtractor_setDataSourceCustom(AMediaExtractor*,
         AMediaDataSource *src) __INTRODUCED_IN(28);
@@ -85,11 +95,15 @@
 
 /**
  * Return the number of tracks in the previously specified media file
+ *
+ * Available since API level 21.
  */
 size_t AMediaExtractor_getTrackCount(AMediaExtractor*) __INTRODUCED_IN(21);
 
 /**
  * Return the format of the specified track. The caller must free the returned format
+ *
+ * Available since API level 21.
  */
 AMediaFormat* AMediaExtractor_getTrackFormat(AMediaExtractor*, size_t idx) __INTRODUCED_IN(21);
 
@@ -98,41 +112,55 @@
  * getSampleTime only retrieve information for the subset of tracks selected.
  * Selecting the same track multiple times has no effect, the track is
  * only selected once.
+ *
+ * Available since API level 21.
  */
 media_status_t AMediaExtractor_selectTrack(AMediaExtractor*, size_t idx) __INTRODUCED_IN(21);
 
 /**
  * Unselect the specified track. Subsequent calls to readSampleData, getSampleTrackIndex and
- * getSampleTime only retrieve information for the subset of tracks selected..
+ * getSampleTime only retrieve information for the subset of tracks selected.
+ *
+ * Available since API level 21.
  */
 media_status_t AMediaExtractor_unselectTrack(AMediaExtractor*, size_t idx) __INTRODUCED_IN(21);
 
 /**
  * Read the current sample.
+ *
+ * Available since API level 21.
  */
 ssize_t AMediaExtractor_readSampleData(AMediaExtractor*,
         uint8_t *buffer, size_t capacity) __INTRODUCED_IN(21);
 
 /**
  * Read the current sample's flags.
+ *
+ * Available since API level 21.
  */
 uint32_t AMediaExtractor_getSampleFlags(AMediaExtractor*) __INTRODUCED_IN(21);
 
 /**
  * Returns the track index the current sample originates from (or -1
  * if no more samples are available)
+ *
+ * Available since API level 21.
  */
 int AMediaExtractor_getSampleTrackIndex(AMediaExtractor*) __INTRODUCED_IN(21);
 
 /**
  * Returns the current sample's presentation time in microseconds.
  * or -1 if no more samples are available.
+ *
+ * Available since API level 21.
  */
 int64_t AMediaExtractor_getSampleTime(AMediaExtractor*) __INTRODUCED_IN(21);
 
 /**
  * Advance to the next sample. Returns false if no more sample data
  * is available (end of stream).
+ *
+ * Available since API level 21.
  */
 bool AMediaExtractor_advance(AMediaExtractor*) __INTRODUCED_IN(21);
 
@@ -143,7 +171,7 @@
 } SeekMode;
 
 /**
- *
+ * Available since API level 21.
  */
 media_status_t AMediaExtractor_seekTo(AMediaExtractor*,
         int64_t seekPosUs, SeekMode mode) __INTRODUCED_IN(21);
@@ -167,10 +195,14 @@
 
 /**
  * Get the PSSH info if present.
+ *
+ * Available since API level 21.
  */
 PsshInfo* AMediaExtractor_getPsshInfo(AMediaExtractor*) __INTRODUCED_IN(21);
 
-
+/**
+ * Available since API level 21.
+ */
 AMediaCodecCryptoInfo *AMediaExtractor_getSampleCryptoInfo(AMediaExtractor *) __INTRODUCED_IN(21);
 
 enum {
@@ -186,6 +218,8 @@
  *
  * This function will always return a format; however, the format could be empty
  * (no key-value pairs) if the media container does not provide format information.
+ *
+ * Available since API level 28.
  */
 AMediaFormat* AMediaExtractor_getFileFormat(AMediaExtractor*) __INTRODUCED_IN(28);
 
@@ -198,6 +232,7 @@
  * uint8_t *buf = new uint8_t[sampleSize];
  * AMediaExtractor_readSampleData(ex, buf, sampleSize);
  *
+ * Available since API level 28.
  */
 ssize_t AMediaExtractor_getSampleSize(AMediaExtractor*) __INTRODUCED_IN(28);
 
@@ -211,6 +246,8 @@
  * Returns -1 when the extractor is not reading from a network data source, or when the
  * cached duration cannot be calculated (bitrate, duration, and file size information
  * not available).
+ *
+ * Available since API level 28.
  */
 int64_t AMediaExtractor_getCachedDuration(AMediaExtractor *) __INTRODUCED_IN(28);
 
@@ -222,6 +259,8 @@
  * Returns AMEDIA_OK on success or AMEDIA_ERROR_* to indicate failure reason.
  * Existing key-value pairs in |fmt| would be removed if this API returns AMEDIA_OK.
  * The contents of |fmt| is undefined if this API returns AMEDIA_ERROR_*.
+ *
+ * Available since API level 28.
  */
 media_status_t AMediaExtractor_getSampleFormat(AMediaExtractor *ex,
         AMediaFormat *fmt) __INTRODUCED_IN(28);
diff --git a/media/ndk/include/media/NdkMediaFormat.h b/media/ndk/include/media/NdkMediaFormat.h
index fd43f36..41c2378 100644
--- a/media/ndk/include/media/NdkMediaFormat.h
+++ b/media/ndk/include/media/NdkMediaFormat.h
@@ -48,40 +48,78 @@
 
 #if __ANDROID_API__ >= 21
 
+/**
+ * Available since API level 21.
+ */
 AMediaFormat *AMediaFormat_new() __INTRODUCED_IN(21);
+
+/**
+ * Available since API level 21.
+ */
 media_status_t AMediaFormat_delete(AMediaFormat*) __INTRODUCED_IN(21);
 
 /**
  * Human readable representation of the format. The returned string is owned by the format,
  * and remains valid until the next call to toString, or until the format is deleted.
+ *
+ * Available since API level 21.
  */
 const char* AMediaFormat_toString(AMediaFormat*) __INTRODUCED_IN(21);
 
+/**
+ * Available since API level 21.
+ */
 bool AMediaFormat_getInt32(AMediaFormat*, const char *name, int32_t *out) __INTRODUCED_IN(21);
+/**
+ * Available since API level 21.
+ */
 bool AMediaFormat_getInt64(AMediaFormat*, const char *name, int64_t *out) __INTRODUCED_IN(21);
+/**
+ * Available since API level 21.
+ */
 bool AMediaFormat_getFloat(AMediaFormat*, const char *name, float *out) __INTRODUCED_IN(21);
+/**
+ * Available since API level 21.
+ */
 bool AMediaFormat_getSize(AMediaFormat*, const char *name, size_t *out) __INTRODUCED_IN(21);
 /**
  * The returned data is owned by the format and remains valid as long as the named entry
  * is part of the format.
+ *
+ * Available since API level 21.
  */
 bool AMediaFormat_getBuffer(AMediaFormat*, const char *name, void** data, size_t *size) __INTRODUCED_IN(21);
 /**
  * The returned string is owned by the format, and remains valid until the next call to getString,
  * or until the format is deleted.
+ *
+ * Available since API level 21.
  */
 bool AMediaFormat_getString(AMediaFormat*, const char *name, const char **out) __INTRODUCED_IN(21);
 
 
+/**
+ * Available since API level 21.
+ */
 void AMediaFormat_setInt32(AMediaFormat*, const char* name, int32_t value) __INTRODUCED_IN(21);
+/**
+ * Available since API level 21.
+ */
 void AMediaFormat_setInt64(AMediaFormat*, const char* name, int64_t value) __INTRODUCED_IN(21);
+/**
+ * Available since API level 21.
+ */
 void AMediaFormat_setFloat(AMediaFormat*, const char* name, float value) __INTRODUCED_IN(21);
 /**
  * The provided string is copied into the format.
+ *
+ * Available since API level 21.
  */
 void AMediaFormat_setString(AMediaFormat*, const char* name, const char* value) __INTRODUCED_IN(21);
 /**
  * The provided data is copied into the format.
+ *
+ * Available since API level 21.
  */
 void AMediaFormat_setBuffer(AMediaFormat*, const char* name, const void* data, size_t size) __INTRODUCED_IN(21);
 
@@ -155,24 +193,43 @@
 #endif /* __ANDROID_API__ >= 21 */
 
 #if __ANDROID_API__ >= 28
+/**
+ * Available since API level 28.
+ */
 bool AMediaFormat_getDouble(AMediaFormat*, const char *name, double *out) __INTRODUCED_IN(28);
+/**
+ * Available since API level 28.
+ */
 bool AMediaFormat_getRect(AMediaFormat*, const char *name,
         int32_t *left, int32_t *top, int32_t *right, int32_t *bottom) __INTRODUCED_IN(28);
 
+/**
+ * Available since API level 28.
+ */
 void AMediaFormat_setDouble(AMediaFormat*, const char* name, double value) __INTRODUCED_IN(28);
+/**
+ * Available since API level 28.
+ */
 void AMediaFormat_setSize(AMediaFormat*, const char* name, size_t value) __INTRODUCED_IN(28);
+/**
+ * Available since API level 28.
+ */
 void AMediaFormat_setRect(AMediaFormat*, const char* name,
         int32_t left, int32_t top, int32_t right, int32_t bottom) __INTRODUCED_IN(28);
 #endif /* __ANDROID_API__ >= 28 */
 
 #if __ANDROID_API__ >= 29
 /**
- * remove all key/value pairs from the given AMediaFormat
+ * Remove all key/value pairs from the given AMediaFormat.
+ *
+ * Available since API level 29.
  */
 void AMediaFormat_clear(AMediaFormat*) __INTRODUCED_IN(29);
 
 /**
- * copy one AMediaFormat to another
+ * Copy one AMediaFormat to another.
+ *
+ * Available since API level 29.
  */
 media_status_t AMediaFormat_copy(AMediaFormat *to, AMediaFormat *from) __INTRODUCED_IN(29);
 
diff --git a/media/ndk/include/media/NdkMediaMuxer.h b/media/ndk/include/media/NdkMediaMuxer.h
index 7393867..3fdeea4 100644
--- a/media/ndk/include/media/NdkMediaMuxer.h
+++ b/media/ndk/include/media/NdkMediaMuxer.h
@@ -56,12 +56,16 @@
 #if __ANDROID_API__ >= 21
 
 /**
- * Create new media muxer
+ * Create new media muxer.
+ *
+ * Available since API level 21.
  */
 AMediaMuxer* AMediaMuxer_new(int fd, OutputFormat format) __INTRODUCED_IN(21);
 
 /**
- * Delete a previously created media muxer
+ * Delete a previously created media muxer.
+ *
+ * Available since API level 21.
  */
 media_status_t AMediaMuxer_delete(AMediaMuxer*) __INTRODUCED_IN(21);
 
@@ -75,6 +79,8 @@
  * Both values are specified in degrees.
  * Latitude must be in the range [-90, 90].
  * Longitude must be in the range [-180, 180].
+ *
+ * Available since API level 21.
  */
 media_status_t AMediaMuxer_setLocation(AMediaMuxer*,
         float latitude, float longitude) __INTRODUCED_IN(21);
@@ -90,6 +96,8 @@
  * during playback.
  * The angle is specified in degrees, clockwise.
  * The supported angles are 0, 90, 180, and 270 degrees.
+ *
+ * Available since API level 21.
  */
 media_status_t AMediaMuxer_setOrientationHint(AMediaMuxer*, int degrees) __INTRODUCED_IN(21);
 
@@ -97,18 +105,24 @@
  * Adds a track with the specified format.
  * Returns the index of the new track or a negative value in case of failure,
  * which can be interpreted as a media_status_t.
+ *
+ * Available since API level 21.
  */
 ssize_t AMediaMuxer_addTrack(AMediaMuxer*, const AMediaFormat* format) __INTRODUCED_IN(21);
 
 /**
  * Start the muxer. Should be called after AMediaMuxer_addTrack and
  * before AMediaMuxer_writeSampleData.
+ *
+ * Available since API level 21.
  */
 media_status_t AMediaMuxer_start(AMediaMuxer*) __INTRODUCED_IN(21);
 
 /**
  * Stops the muxer.
  * Once the muxer stops, it can not be restarted.
+ *
+ * Available since API level 21.
  */
 media_status_t AMediaMuxer_stop(AMediaMuxer*) __INTRODUCED_IN(21);
 
@@ -118,6 +132,8 @@
  * the right tracks. Also, it needs to make sure the samples for each track
  * are written in chronological order (e.g. in the order they are provided
  * by the encoder.)
+ *
+ * Available since API level 21.
  */
 media_status_t AMediaMuxer_writeSampleData(AMediaMuxer *muxer,
         size_t trackIdx, const uint8_t *data,
diff --git a/media/tests/benchmark/.clang-format b/media/tests/benchmark/.clang-format
new file mode 100644
index 0000000..bf1e355
--- /dev/null
+++ b/media/tests/benchmark/.clang-format
@@ -0,0 +1,13 @@
+BasedOnStyle: Google
+Standard: Cpp11
+AccessModifierOffset: -2
+AllowShortFunctionsOnASingleLine: Inline
+ColumnLimit: 100
+CommentPragmas: NOLINT:.*
+DerivePointerAlignment: false
+IncludeBlocks: Preserve
+IndentWidth: 4
+ContinuationIndentWidth: 8
+PointerAlignment: Right
+TabWidth: 4
+UseTab: Never
diff --git a/media/libstagefright/include/media/stagefright/NdkUtils.h b/media/tests/benchmark/Android.bp
similarity index 62%
copy from media/libstagefright/include/media/stagefright/NdkUtils.h
copy to media/tests/benchmark/Android.bp
index a68884a..de408dd 100644
--- a/media/libstagefright/include/media/stagefright/NdkUtils.h
+++ b/media/tests/benchmark/Android.bp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2018 The Android Open Source Project
+ * 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.
@@ -14,18 +14,8 @@
  * limitations under the License.
  */
 
-#ifndef NDK_UTILS_H_
-
-#define NDK_UTILS_H_
-
-#include <media/stagefright/MetaData.h>
-#include <media/NdkWrapper.h>
-
-namespace android {
-
-sp<MetaData> convertMediaFormatWrapperToMetaData(
-        const sp<AMediaFormatWrapper> &fmt);
-
-}  // namespace android
-
-#endif  // NDK_UTILS_H_
+subdirs = [
+    "src",
+    "tests",
+    "MediaBenchmarkTest",
+]
diff --git a/media/tests/benchmark/MediaBenchmarkTest/Android.bp b/media/tests/benchmark/MediaBenchmarkTest/Android.bp
new file mode 100644
index 0000000..91b03f1
--- /dev/null
+++ b/media/tests/benchmark/MediaBenchmarkTest/Android.bp
@@ -0,0 +1,50 @@
+/*
+ * 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.
+ */
+
+android_test {
+    name: "MediaBenchmarkTest",
+
+    // Include all the test code
+    srcs: ["src/androidTest/**/*.java"],
+
+    sdk_version: "system_current",
+
+    resource_dirs: ["res"],
+
+    libs: [
+        "android.test.runner",
+        "android.test.base",
+    ],
+
+    static_libs: [
+        "libMediaBenchmark",
+        "junit",
+        "androidx.test.runner",
+    ],
+}
+
+android_library {
+    name: "libMediaBenchmark",
+
+    // Include all the libraries
+    srcs: ["src/main/**/*.java"],
+
+    sdk_version: "system_current",
+
+    static_libs: [
+        "androidx.test.core",
+    ],
+}
diff --git a/media/tests/benchmark/MediaBenchmarkTest/AndroidManifest.xml b/media/tests/benchmark/MediaBenchmarkTest/AndroidManifest.xml
new file mode 100644
index 0000000..eea9914
--- /dev/null
+++ b/media/tests/benchmark/MediaBenchmarkTest/AndroidManifest.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * 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.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    package="com.android.media.benchmark">
+    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+    <uses-permission android:name="android.permission.READ_INTERNAL_STORAGE" />
+    <uses-permission android:name="android.permission.WRITE_INTERNAL_STORAGE" />
+
+    <application
+        tools:ignore="AllowBackup,GoogleAppIndexingWarning,MissingApplicationIcon"
+        tools:remove="android:appComponentFactory">
+    </application>
+
+    <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
+            android:targetPackage="com.android.media.benchmark"
+            android:label="Benchmark Media Test"/>
+</manifest>
\ No newline at end of file
diff --git a/media/tests/benchmark/MediaBenchmarkTest/AndroidTest.xml b/media/tests/benchmark/MediaBenchmarkTest/AndroidTest.xml
new file mode 100644
index 0000000..89d6ce2
--- /dev/null
+++ b/media/tests/benchmark/MediaBenchmarkTest/AndroidTest.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2018 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Runs Media Benchmark Tests">
+    <target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup">
+        <option name="test-file-name" value="MediaBenchmarkTest.apk" />
+    </target_preparer>
+
+    <option name="test-tag" value="MediaBenchmarkTest" />
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="com.android.media.benchmark" />
+        <option name="runner" value="androidx.test.runner.AndroidJUnitRunner" />
+        <option name="hidden-api-checks" value="false"/>
+    </test>
+</configuration>
diff --git a/media/tests/benchmark/MediaBenchmarkTest/build.gradle b/media/tests/benchmark/MediaBenchmarkTest/build.gradle
new file mode 100644
index 0000000..b0ee692
--- /dev/null
+++ b/media/tests/benchmark/MediaBenchmarkTest/build.gradle
@@ -0,0 +1,64 @@
+/*
+ * 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.
+ */
+
+buildscript {
+    repositories {
+        google()
+        jcenter()
+    }
+    dependencies {
+        classpath 'com.android.tools.build:gradle:3.5.0'
+    }
+}
+
+apply plugin: 'com.android.application'
+
+android {
+    compileSdkVersion 29
+    defaultConfig {
+        applicationId "com.android.media.benchmark"
+        minSdkVersion 21
+        targetSdkVersion 29
+        versionCode 1
+        versionName "1.0"
+        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
+    }
+    sourceSets {
+        main {
+            java.srcDirs 'src/main/java'
+            res.srcDirs 'res'
+            manifest.srcFile 'AndroidManifest.xml'
+        }
+        androidTest {
+            java.srcDirs  'src/androidTest/java'
+            res.srcDirs 'res'
+            manifest.srcFile 'AndroidManifest.xml'
+        }
+    }
+}
+
+repositories {
+    google()
+    jcenter()
+}
+
+dependencies {
+    implementation fileTree(dir: 'libs', include: ['*.jar'])
+    implementation 'androidx.appcompat:appcompat:1.1.0'
+    testImplementation 'junit:junit:4.12'
+    androidTestImplementation 'androidx.test:runner:1.2.0'
+    androidTestImplementation 'androidx.test.ext:junit:1.1.1'
+}
\ No newline at end of file
diff --git a/media/tests/benchmark/MediaBenchmarkTest/res/values/strings.xml b/media/tests/benchmark/MediaBenchmarkTest/res/values/strings.xml
new file mode 100644
index 0000000..24dbccc
--- /dev/null
+++ b/media/tests/benchmark/MediaBenchmarkTest/res/values/strings.xml
@@ -0,0 +1,4 @@
+<resources>
+    <string name="input_file_path">/data/local/tmp/MediaBenchmark/res/</string>
+    <string name="output_file_path">/data/local/tmp/MediaBenchmark/output/</string>
+</resources>
diff --git a/media/tests/benchmark/MediaBenchmarkTest/src/androidTest/java/com/android/media/benchmark/tests/DecoderTest.java b/media/tests/benchmark/MediaBenchmarkTest/src/androidTest/java/com/android/media/benchmark/tests/DecoderTest.java
new file mode 100644
index 0000000..be2633d
--- /dev/null
+++ b/media/tests/benchmark/MediaBenchmarkTest/src/androidTest/java/com/android/media/benchmark/tests/DecoderTest.java
@@ -0,0 +1,197 @@
+/*
+ * 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.
+ */
+
+package com.android.media.benchmark.tests;
+
+import android.content.Context;
+import android.media.MediaCodec;
+import android.media.MediaFormat;
+import android.util.Log;
+
+import androidx.test.platform.app.InstrumentationRegistry;
+
+import com.android.media.benchmark.R;
+import com.android.media.benchmark.library.CodecUtils;
+import com.android.media.benchmark.library.Decoder;
+import com.android.media.benchmark.library.Extractor;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import java.io.File;
+import java.io.FileDescriptor;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+
+@RunWith(Parameterized.class)
+public class DecoderTest {
+    private static final Context mContext =
+            InstrumentationRegistry.getInstrumentation().getTargetContext();
+    private static final String mInputFilePath = mContext.getString(R.string.input_file_path);
+    private static final String mOutputFilePath = mContext.getString(R.string.output_file_path);
+    private static final String TAG = "DecoderTest";
+    private static final long PER_TEST_TIMEOUT_MS = 60000;
+    private static final boolean DEBUG = false;
+    private static final boolean WRITE_OUTPUT = false;
+    private String mInputFile;
+    private boolean mAsyncMode;
+
+    public DecoderTest(String inputFile, boolean asyncMode) {
+        this.mInputFile = inputFile;
+        this.mAsyncMode = asyncMode;
+    }
+
+    @Parameterized.Parameters
+    public static Collection<Object[]> input() {
+        return Arrays.asList(new Object[][]{
+                //Audio Sync Test
+                {"bbb_44100hz_2ch_128kbps_aac_30sec.mp4", false},
+                {"bbb_44100hz_2ch_128kbps_mp3_30sec.mp3", false},
+                {"bbb_8000hz_1ch_8kbps_amrnb_30sec.3gp", false},
+                {"bbb_16000hz_1ch_9kbps_amrwb_30sec.3gp", false},
+                {"bbb_44100hz_2ch_80kbps_vorbis_30sec.mp4", false},
+                {"bbb_44100hz_2ch_600kbps_flac_30sec.mp4", false},
+                {"bbb_48000hz_2ch_100kbps_opus_30sec.webm", false},
+                // Audio Async Test
+                {"bbb_44100hz_2ch_128kbps_aac_30sec.mp4", true},
+                {"bbb_44100hz_2ch_128kbps_mp3_30sec.mp3", true},
+                {"bbb_8000hz_1ch_8kbps_amrnb_30sec.3gp", true},
+                {"bbb_16000hz_1ch_9kbps_amrwb_30sec.3gp", true},
+                {"bbb_44100hz_2ch_80kbps_vorbis_30sec.mp4", true},
+                {"bbb_44100hz_2ch_600kbps_flac_30sec.mp4", true},
+                {"bbb_48000hz_2ch_100kbps_opus_30sec.webm", true},
+                // Video Sync Test
+                {"crowd_1920x1080_25fps_4000kbps_vp9.webm", false},
+                {"crowd_1920x1080_25fps_4000kbps_vp8.webm", false},
+                {"crowd_1920x1080_25fps_4000kbps_av1.webm", false},
+                {"crowd_1920x1080_25fps_7300kbps_mpeg2.mp4", false},
+                {"crowd_1920x1080_25fps_6000kbps_mpeg4.mp4", false},
+                {"crowd_352x288_25fps_6000kbps_h263.3gp", false},
+                {"crowd_1920x1080_25fps_6700kbps_h264.ts", false},
+                {"crowd_1920x1080_25fps_4000kbps_h265.mkv", false},
+                // Video Async Test
+                {"crowd_1920x1080_25fps_4000kbps_vp9.webm", true},
+                {"crowd_1920x1080_25fps_4000kbps_vp8.webm", true},
+                {"crowd_1920x1080_25fps_4000kbps_av1.webm", true},
+                {"crowd_1920x1080_25fps_7300kbps_mpeg2.mp4", true},
+                {"crowd_1920x1080_25fps_6000kbps_mpeg4.mp4", true},
+                {"crowd_352x288_25fps_6000kbps_h263.3gp", true},
+                {"crowd_1920x1080_25fps_6700kbps_h264.ts", true},
+                {"crowd_1920x1080_25fps_4000kbps_h265.mkv", true}});
+    }
+
+    @Test(timeout = PER_TEST_TIMEOUT_MS)
+    public void testDecoder() throws IOException {
+        File inputFile = new File(mInputFilePath + mInputFile);
+        if (inputFile.exists()) {
+            FileInputStream fileInput = new FileInputStream(inputFile);
+            FileDescriptor fileDescriptor = fileInput.getFD();
+            Extractor extractor = new Extractor();
+            int trackCount = extractor.setUpExtractor(fileDescriptor);
+            ArrayList<ByteBuffer> inputBuffer = new ArrayList<>();
+            ArrayList<MediaCodec.BufferInfo> frameInfo = new ArrayList<>();
+            if (trackCount <= 0) {
+                Log.e(TAG, "Extraction failed. No tracks for file: " + mInputFile);
+                return;
+            }
+            for (int currentTrack = 0; currentTrack < trackCount; currentTrack++) {
+                extractor.selectExtractorTrack(currentTrack);
+                MediaFormat format = extractor.getFormat(currentTrack);
+                String mime = format.getString(MediaFormat.KEY_MIME);
+                ArrayList<String> mediaCodecs = CodecUtils.selectCodecs(mime, false);
+                if (mediaCodecs.size() <= 0) {
+                    Log.e(TAG,
+                            "No suitable codecs found for file: " + mInputFile
+                                    + " track : " + currentTrack + " mime: " + mime);
+                    continue;
+                }
+                // Get samples from extractor
+                int sampleSize;
+                do {
+                    sampleSize = extractor.getFrameSample();
+                    MediaCodec.BufferInfo bufInfo = new MediaCodec.BufferInfo();
+                    MediaCodec.BufferInfo info = extractor.getBufferInfo();
+                    ByteBuffer dataBuffer = ByteBuffer.allocate(info.size);
+                    dataBuffer.put(extractor.getFrameBuffer().array(), 0, info.size);
+                    bufInfo.set(info.offset, info.size, info.presentationTimeUs, info.flags);
+                    inputBuffer.add(dataBuffer);
+                    frameInfo.add(bufInfo);
+                    if (DEBUG) {
+                        Log.d(TAG,
+                                "Extracted bufInfo: flag = " + bufInfo.flags + " timestamp = "
+                                        + bufInfo.presentationTimeUs + " size = " + bufInfo.size);
+                    }
+                } while (sampleSize > 0);
+                for (String codecName : mediaCodecs) {
+                    FileOutputStream decodeOutputStream = null;
+                    if (WRITE_OUTPUT) {
+                        if (!Paths.get(mOutputFilePath).toFile().exists()) {
+                            Files.createDirectories(Paths.get(mOutputFilePath));
+                        }
+                        File outFile = new File(mOutputFilePath + "decoder.out");
+                        if (outFile.exists()) {
+                            if (!outFile.delete()) {
+                                Log.e(TAG, " Unable to delete existing file" + outFile.toString());
+                            }
+                        }
+                        if (outFile.createNewFile()) {
+                            decodeOutputStream = new FileOutputStream(outFile);
+                        } else {
+                            Log.e(TAG, "Unable to create file: " + outFile.toString());
+                        }
+                    }
+                    Decoder decoder = new Decoder();
+                    decoder.setupDecoder(decodeOutputStream);
+                    int status =
+                            decoder.decode(inputBuffer, frameInfo, mAsyncMode, format, codecName);
+                    decoder.deInitCodec();
+                    if (status == 0) {
+                        decoder.dumpStatistics(
+                                mInputFile + " " + codecName, extractor.getClipDuration());
+                        Log.i(TAG,
+                                "Decoding Successful for file: " + mInputFile
+                                        + " with codec: " + codecName);
+                    } else {
+                        Log.e(TAG,
+                                "Decoder returned error " + status + " for file: " + mInputFile
+                                        + " with codec: " + codecName);
+                    }
+                    decoder.resetDecoder();
+                    if (decodeOutputStream != null) {
+                        decodeOutputStream.close();
+                    }
+                }
+                extractor.unselectExtractorTrack(currentTrack);
+                inputBuffer.clear();
+                frameInfo.clear();
+            }
+            extractor.deinitExtractor();
+            fileInput.close();
+        } else {
+            Log.w(TAG,
+                    "Warning: Test Skipped. Cannot find " + mInputFile + " in directory "
+                            + mInputFilePath);
+        }
+    }
+}
diff --git a/media/tests/benchmark/MediaBenchmarkTest/src/androidTest/java/com/android/media/benchmark/tests/EncoderTest.java b/media/tests/benchmark/MediaBenchmarkTest/src/androidTest/java/com/android/media/benchmark/tests/EncoderTest.java
new file mode 100644
index 0000000..9db9c84
--- /dev/null
+++ b/media/tests/benchmark/MediaBenchmarkTest/src/androidTest/java/com/android/media/benchmark/tests/EncoderTest.java
@@ -0,0 +1,272 @@
+/*
+ * 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.
+ */
+
+package com.android.media.benchmark.tests;
+
+import android.content.Context;
+import android.media.MediaCodec;
+import android.media.MediaFormat;
+import android.util.Log;
+
+import androidx.test.platform.app.InstrumentationRegistry;
+
+import com.android.media.benchmark.R;
+import com.android.media.benchmark.library.CodecUtils;
+import com.android.media.benchmark.library.Decoder;
+import com.android.media.benchmark.library.Encoder;
+import com.android.media.benchmark.library.Extractor;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import java.io.File;
+import java.io.FileDescriptor;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.nio.ByteBuffer;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+
+@RunWith(Parameterized.class)
+public class EncoderTest {
+    private static final Context mContext =
+            InstrumentationRegistry.getInstrumentation().getTargetContext();
+    private static final String mInputFilePath = mContext.getString(R.string.input_file_path);
+    private static final String mOutputFilePath = mContext.getString(R.string.output_file_path);
+    private static final String TAG = "EncoderTest";
+    private static final long PER_TEST_TIMEOUT_MS = 120000;
+    private static final boolean DEBUG = false;
+    private static final boolean WRITE_OUTPUT = false;
+    private static final int ENCODE_DEFAULT_FRAME_RATE = 25;
+    private static final int ENCODE_DEFAULT_BIT_RATE = 8000000 /* 8 Mbps */;
+    private static final int ENCODE_MIN_BIT_RATE = 600000 /* 600 Kbps */;
+
+    private String mInputFile;
+
+    @Parameterized.Parameters
+    public static Collection<Object[]> inputFiles() {
+        return Arrays.asList(new Object[][]{
+                // Audio Test
+                {"bbb_44100hz_2ch_128kbps_aac_30sec.mp4"},
+                {"bbb_8000hz_1ch_8kbps_amrnb_30sec.3gp"},
+                {"bbb_16000hz_1ch_9kbps_amrwb_30sec.3gp"},
+                {"bbb_44100hz_2ch_600kbps_flac_30sec.mp4"},
+                {"bbb_48000hz_2ch_100kbps_opus_30sec.webm"},
+                // Video Test
+                {"crowd_1920x1080_25fps_4000kbps_vp8.webm"},
+                {"crowd_1920x1080_25fps_6700kbps_h264.ts"},
+                {"crowd_1920x1080_25fps_4000kbps_h265.mkv"},
+                {"crowd_1920x1080_25fps_4000kbps_vp9.webm"},
+                {"crowd_176x144_25fps_6000kbps_mpeg4.mp4"},
+                {"crowd_176x144_25fps_6000kbps_h263.3gp"}});
+    }
+
+    public EncoderTest(String inputFileName) {
+        this.mInputFile = inputFileName;
+    }
+
+    @Test(timeout = PER_TEST_TIMEOUT_MS)
+    public void sampleEncoderTest() throws Exception {
+        int status;
+        int frameSize;
+
+        //Parameters for video
+        int width = 0;
+        int height = 0;
+        int profile = 0;
+        int level = 0;
+        int frameRate = 0;
+
+        //Parameters for audio
+        int bitRate = 0;
+        int sampleRate = 0;
+        int numChannels = 0;
+
+        File inputFile = new File(mInputFilePath + mInputFile);
+        if (inputFile.exists()) {
+            FileInputStream fileInput = new FileInputStream(inputFile);
+            FileDescriptor fileDescriptor = fileInput.getFD();
+            Extractor extractor = new Extractor();
+            int trackCount = extractor.setUpExtractor(fileDescriptor);
+            if (trackCount <= 0) {
+                Log.e(TAG, "Extraction failed. No tracks for file: " + mInputFile);
+                return;
+            }
+            ArrayList<ByteBuffer> inputBuffer = new ArrayList<>();
+            ArrayList<MediaCodec.BufferInfo> frameInfo = new ArrayList<>();
+            for (int currentTrack = 0; currentTrack < trackCount; currentTrack++) {
+                extractor.selectExtractorTrack(currentTrack);
+                MediaFormat format = extractor.getFormat(currentTrack);
+                // Get samples from extractor
+                int sampleSize;
+                do {
+                    sampleSize = extractor.getFrameSample();
+                    MediaCodec.BufferInfo bufInfo = new MediaCodec.BufferInfo();
+                    MediaCodec.BufferInfo info = extractor.getBufferInfo();
+                    ByteBuffer dataBuffer = ByteBuffer.allocate(info.size);
+                    dataBuffer.put(extractor.getFrameBuffer().array(), 0, info.size);
+                    bufInfo.set(info.offset, info.size, info.presentationTimeUs, info.flags);
+                    inputBuffer.add(dataBuffer);
+                    frameInfo.add(bufInfo);
+                    if (DEBUG) {
+                        Log.d(TAG, "Extracted bufInfo: flag = " + bufInfo.flags + " timestamp = " +
+                                bufInfo.presentationTimeUs + " size = " + bufInfo.size);
+                    }
+                } while (sampleSize > 0);
+
+                int tid = android.os.Process.myTid();
+                File decodedFile = new File(mContext.getFilesDir() + "/decoder_" + tid + ".out");
+                FileOutputStream decodeOutputStream = new FileOutputStream(decodedFile);
+                Decoder decoder = new Decoder();
+                decoder.setupDecoder(decodeOutputStream);
+                status = decoder.decode(inputBuffer, frameInfo, false, format, "");
+                if (status == 0) {
+                    Log.i(TAG, "Decoding complete.");
+                } else {
+                    Log.e(TAG, "Decode returned error. Encoding did not take place." + status);
+                    return;
+                }
+                decoder.deInitCodec();
+                extractor.unselectExtractorTrack(currentTrack);
+                inputBuffer.clear();
+                frameInfo.clear();
+                if (decodeOutputStream != null) {
+                    decodeOutputStream.close();
+                }
+                String mime = format.getString(MediaFormat.KEY_MIME);
+                ArrayList<String> mediaCodecs = CodecUtils.selectCodecs(mime, true);
+                if (mediaCodecs.size() <= 0) {
+                    Log.e(TAG, "No suitable codecs found for file: " + mInputFile + " track : " +
+                            currentTrack + " mime: " + mime);
+                    return;
+                }
+                Boolean[] encodeMode = {true, false};
+                /* Encoding the decoder's output */
+                for (Boolean asyncMode : encodeMode) {
+                    for (String codecName : mediaCodecs) {
+                        FileOutputStream encodeOutputStream = null;
+                        if (WRITE_OUTPUT) {
+                            File outEncodeFile = new File(mOutputFilePath + "encoder.out");
+                            if (outEncodeFile.exists()) {
+                                if (!outEncodeFile.delete()) {
+                                    Log.e(TAG, "Unable to delete existing file" +
+                                            decodedFile.toString());
+                                }
+                            }
+                            if (outEncodeFile.createNewFile()) {
+                                encodeOutputStream = new FileOutputStream(outEncodeFile);
+                            } else {
+                                Log.e(TAG, "Unable to create file to write encoder output: " +
+                                        outEncodeFile.toString());
+                            }
+                        }
+                        File rawFile =
+                                new File(mContext.getFilesDir() + "/decoder_" + tid + ".out");
+                        if (rawFile.exists()) {
+                            if (DEBUG) {
+                                Log.i(TAG, "Path of decoded input file: " + rawFile.toString());
+                            }
+                            FileInputStream eleStream = new FileInputStream(rawFile);
+                            if (mime.startsWith("video/")) {
+                                width = format.getInteger(MediaFormat.KEY_WIDTH);
+                                height = format.getInteger(MediaFormat.KEY_HEIGHT);
+                                if (format.containsKey(MediaFormat.KEY_FRAME_RATE)) {
+                                    frameRate = format.getInteger(MediaFormat.KEY_FRAME_RATE);
+                                } else if (frameRate <= 0) {
+                                    frameRate = ENCODE_DEFAULT_FRAME_RATE;
+                                }
+                                if (format.containsKey(MediaFormat.KEY_BIT_RATE)) {
+                                    bitRate = format.getInteger(MediaFormat.KEY_BIT_RATE);
+                                } else if (bitRate <= 0) {
+                                    if (mime.contains("video/3gpp") ||
+                                            mime.contains("video/mp4v-es")) {
+                                        bitRate = ENCODE_MIN_BIT_RATE;
+                                    } else {
+                                        bitRate = ENCODE_DEFAULT_BIT_RATE;
+                                    }
+                                }
+                                if (format.containsKey(MediaFormat.KEY_PROFILE)) {
+                                    profile = format.getInteger(MediaFormat.KEY_PROFILE);
+                                }
+                                if (format.containsKey(MediaFormat.KEY_PROFILE)) {
+                                    level = format.getInteger(MediaFormat.KEY_LEVEL);
+                                }
+                            } else {
+                                sampleRate = format.getInteger(MediaFormat.KEY_SAMPLE_RATE);
+                                numChannels = format.getInteger(MediaFormat.KEY_CHANNEL_COUNT);
+                                bitRate = sampleRate * numChannels * 16;
+                            }
+                            /*Setup Encode Format*/
+                            MediaFormat encodeFormat;
+                            if (mime.startsWith("video/")) {
+                                frameSize = width * height * 3 / 2;
+                                encodeFormat = MediaFormat.createVideoFormat(mime, width, height);
+                                encodeFormat.setInteger(MediaFormat.KEY_FRAME_RATE, frameRate);
+                                encodeFormat.setInteger(MediaFormat.KEY_BIT_RATE, bitRate);
+                                encodeFormat.setInteger(MediaFormat.KEY_PROFILE, profile);
+                                encodeFormat.setInteger(MediaFormat.KEY_LEVEL, level);
+                                encodeFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 1);
+                                encodeFormat.setInteger(MediaFormat.KEY_MAX_INPUT_SIZE, frameSize);
+                            } else {
+                                encodeFormat = MediaFormat
+                                        .createAudioFormat(mime, sampleRate, numChannels);
+                                encodeFormat.setInteger(MediaFormat.KEY_BIT_RATE, bitRate);
+                                frameSize = 4096;
+                            }
+                            Encoder encoder = new Encoder();
+                            encoder.setupEncoder(encodeOutputStream, eleStream);
+                            status = encoder.encode(codecName, encodeFormat, mime, frameRate,
+                                    sampleRate, frameSize, asyncMode);
+                            encoder.deInitEncoder();
+                            if (status == 0) {
+                                encoder.dumpStatistics(mInputFile + "with " + codecName + " for " +
+                                        "aSyncMode = " + asyncMode, extractor.getClipDuration());
+                                Log.i(TAG, "Encoding complete for file: " + mInputFile +
+                                        " with codec: " + codecName + " for aSyncMode = " +
+                                        asyncMode);
+                            } else {
+                                Log.e(TAG,
+                                        codecName + " encoder returned error " + status + " for " +
+                                                "file:" + " " + mInputFile);
+                            }
+                            encoder.resetEncoder();
+                            eleStream.close();
+                            if (encodeOutputStream != null) {
+                                encodeOutputStream.close();
+                            }
+                        }
+                    }
+                }
+                //Cleanup temporary input file
+                if (decodedFile.exists()) {
+                    if (decodedFile.delete()) {
+                        Log.i(TAG, "Successfully deleted decoded file");
+                    } else {
+                        Log.e(TAG, "Unable to delete decoded file");
+                    }
+                }
+            }
+            extractor.deinitExtractor();
+            fileInput.close();
+        } else {
+            Log.w(TAG, "Warning: Test Skipped. Cannot find " + mInputFile + " in directory " +
+                    mInputFilePath);
+        }
+    }
+}
diff --git a/media/tests/benchmark/MediaBenchmarkTest/src/androidTest/java/com/android/media/benchmark/tests/ExtractorTest.java b/media/tests/benchmark/MediaBenchmarkTest/src/androidTest/java/com/android/media/benchmark/tests/ExtractorTest.java
new file mode 100644
index 0000000..a02011c
--- /dev/null
+++ b/media/tests/benchmark/MediaBenchmarkTest/src/androidTest/java/com/android/media/benchmark/tests/ExtractorTest.java
@@ -0,0 +1,92 @@
+/*
+ * 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.
+ */
+
+package com.android.media.benchmark.tests;
+
+import com.android.media.benchmark.R;
+import com.android.media.benchmark.library.Extractor;
+
+import android.content.Context;
+import android.util.Log;
+
+import androidx.test.platform.app.InstrumentationRegistry;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import java.io.File;
+import java.io.FileDescriptor;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Collection;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+
+@RunWith(Parameterized.class)
+public class ExtractorTest {
+    private static Context mContext =
+            InstrumentationRegistry.getInstrumentation().getTargetContext();
+    private static final String mInputFilePath = mContext.getString(R.string.input_file_path);
+    private static final String TAG = "ExtractorTest";
+    private String mInputFileName;
+    private int mTrackId;
+
+    @Parameterized.Parameters
+    public static Collection<Object[]> inputFiles() {
+        return Arrays.asList(new Object[][]{/* Parameters: filename, trackId*/
+                {"crowd_1920x1080_25fps_6000kbps_mpeg4.mp4", 0},
+                {"crowd_1920x1080_25fps_6700kbps_h264.ts", 0},
+                {"crowd_1920x1080_25fps_7300kbps_mpeg2.mp4", 0},
+                {"crowd_1920x1080_25fps_4000kbps_av1.webm", 0},
+                {"crowd_1920x1080_25fps_4000kbps_h265.mkv", 0},
+                {"crowd_1920x1080_25fps_4000kbps_vp8.webm", 0},
+                {"bbb_44100hz_2ch_128kbps_aac_5mins.mp4", 0},
+                {"bbb_44100hz_2ch_128kbps_mp3_5mins.mp3", 0},
+                {"bbb_44100hz_2ch_600kbps_flac_5mins.flac", 0},
+                {"bbb_8000hz_1ch_8kbps_amrnb_5mins.3gp", 0},
+                {"bbb_16000hz_1ch_9kbps_amrwb_5mins.3gp", 0},
+                {"bbb_44100hz_2ch_80kbps_vorbis_5mins.mp4", 0},
+                {"bbb_48000hz_2ch_100kbps_opus_5mins.webm", 0}});
+    }
+
+    public ExtractorTest(String filename, int track) {
+        this.mInputFileName = filename;
+        this.mTrackId = track;
+    }
+
+    @Test
+    public void sampleExtractTest() throws IOException {
+        int status = -1;
+        File inputFile = new File(mInputFilePath + mInputFileName);
+        if (inputFile.exists()) {
+            FileInputStream fileInput = new FileInputStream(inputFile);
+            FileDescriptor fileDescriptor = fileInput.getFD();
+            Extractor extractor = new Extractor();
+            extractor.setUpExtractor(fileDescriptor);
+            status = extractor.extractSample(mTrackId);
+            extractor.deinitExtractor();
+            extractor.dumpStatistics(mInputFileName);
+            fileInput.close();
+        } else {
+            Log.e(TAG, "Cannot find " + mInputFileName + " in directory " + mInputFilePath);
+        }
+        assertThat(status, is(equalTo(0)));
+    }
+}
diff --git a/media/tests/benchmark/MediaBenchmarkTest/src/androidTest/java/com/android/media/benchmark/tests/MuxerTest.java b/media/tests/benchmark/MediaBenchmarkTest/src/androidTest/java/com/android/media/benchmark/tests/MuxerTest.java
new file mode 100644
index 0000000..8c3080c
--- /dev/null
+++ b/media/tests/benchmark/MediaBenchmarkTest/src/androidTest/java/com/android/media/benchmark/tests/MuxerTest.java
@@ -0,0 +1,152 @@
+/*
+ * 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.
+ */
+package com.android.media.benchmark.tests;
+
+import com.android.media.benchmark.R;
+import com.android.media.benchmark.library.Extractor;
+import com.android.media.benchmark.library.Muxer;
+
+import androidx.test.platform.app.InstrumentationRegistry;
+
+import android.content.Context;
+import android.media.MediaCodec;
+import android.media.MediaFormat;
+import android.media.MediaMuxer;
+import android.util.Log;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import java.io.File;
+import java.io.FileDescriptor;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Hashtable;
+import java.util.Map;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+
+@RunWith(Parameterized.class)
+public class MuxerTest {
+    private static Context mContext =
+            InstrumentationRegistry.getInstrumentation().getTargetContext();
+    private static final String mInputFilePath = mContext.getString(R.string.input_file_path);
+    private static final String TAG = "MuxerTest";
+    private static final Map<String, Integer> mMapFormat = new Hashtable<String, Integer>() {
+        {
+            put("mp4", MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4);
+            put("webm", MediaMuxer.OutputFormat.MUXER_OUTPUT_WEBM);
+            put("3gpp", MediaMuxer.OutputFormat.MUXER_OUTPUT_3GPP);
+            put("ogg", MediaMuxer.OutputFormat.MUXER_OUTPUT_OGG);
+        }
+    };
+    private String mInputFileName;
+    private String mFormat;
+
+    @Parameterized.Parameters
+    public static Collection<Object[]> inputFiles() {
+        return Arrays.asList(new Object[][]{
+                /* Parameters: filename, format */
+                {"crowd_1920x1080_25fps_4000kbps_vp8.webm", "webm"},
+                {"crowd_1920x1080_25fps_4000kbps_vp9.webm", "webm"},
+                {"crowd_1920x1080_25fps_6000kbps_mpeg4.mp4", "mp4"},
+                {"crowd_352x288_25fps_6000kbps_h263.3gp", "mp4"},
+                {"crowd_1920x1080_25fps_6700kbps_h264.ts", "mp4"},
+                {"crowd_1920x1080_25fps_4000kbps_h265.mkv", "mp4"},
+                {"crowd_1920x1080_25fps_6000kbps_mpeg4.mp4", "3gpp"},
+                {"crowd_352x288_25fps_6000kbps_h263.3gp", "3gpp"},
+                {"crowd_1920x1080_25fps_6700kbps_h264.ts", "3gpp"},
+                {"crowd_1920x1080_25fps_4000kbps_h265.mkv", "3gpp"},
+                {"bbb_48000hz_2ch_100kbps_opus_5mins.webm", "ogg"},
+                {"bbb_44100hz_2ch_80kbps_vorbis_5mins.mp4", "webm"},
+                {"bbb_48000hz_2ch_100kbps_opus_5mins.webm", "webm"},
+                {"bbb_44100hz_2ch_128kbps_aac_5mins.mp4", "mp4"},
+                {"bbb_8000hz_1ch_8kbps_amrnb_5mins.3gp", "mp4"},
+                {"bbb_16000hz_1ch_9kbps_amrwb_5mins.3gp", "mp4"},
+                {"bbb_44100hz_2ch_128kbps_aac_5mins.mp4", "3gpp"},
+                {"bbb_8000hz_1ch_8kbps_amrnb_5mins.3gp", "3gpp"},
+                {"bbb_16000hz_1ch_9kbps_amrwb_5mins.3gp", "3gpp"}});
+    }
+
+    public MuxerTest(String filename, String outputFormat) {
+        this.mInputFileName = filename;
+        this.mFormat = outputFormat;
+    }
+
+    @Test
+    public void sampleMuxerTest() throws IOException {
+        int status = -1;
+        File inputFile = new File(mInputFilePath + mInputFileName);
+        if (inputFile.exists()) {
+            FileInputStream fileInput = new FileInputStream(inputFile);
+            FileDescriptor fileDescriptor = fileInput.getFD();
+            ArrayList<ByteBuffer> inputBuffer = new ArrayList<>();
+            ArrayList<MediaCodec.BufferInfo> inputBufferInfo = new ArrayList<>();
+            Extractor extractor = new Extractor();
+            int trackCount = extractor.setUpExtractor(fileDescriptor);
+            for (int currentTrack = 0; currentTrack < trackCount; currentTrack++) {
+                extractor.selectExtractorTrack(currentTrack);
+                while (true) {
+                    int sampleSize = extractor.getFrameSample();
+                    MediaCodec.BufferInfo bufferInfo = extractor.getBufferInfo();
+                    MediaCodec.BufferInfo tempBufferInfo = new MediaCodec.BufferInfo();
+                    tempBufferInfo
+                            .set(bufferInfo.offset, bufferInfo.size, bufferInfo.presentationTimeUs,
+                                    bufferInfo.flags);
+                    inputBufferInfo.add(tempBufferInfo);
+                    ByteBuffer tempSampleBuffer = ByteBuffer.allocate(tempBufferInfo.size);
+                    tempSampleBuffer.put(extractor.getFrameBuffer().array(), 0, bufferInfo.size);
+                    inputBuffer.add(tempSampleBuffer);
+                    if (sampleSize < 0) {
+                        break;
+                    }
+                }
+                MediaFormat format = extractor.getFormat(currentTrack);
+                int outputFormat = mMapFormat.getOrDefault(mFormat, -1);
+                if (outputFormat != -1) {
+                    Muxer muxer = new Muxer();
+                    int trackIndex = muxer.setUpMuxer(mContext, outputFormat, format);
+                    status = muxer.mux(trackIndex, inputBuffer, inputBufferInfo);
+                    if (status != 0) {
+                        Log.e(TAG, "Cannot perform write operation for " + mInputFileName);
+                    }
+                    muxer.deInitMuxer();
+                    muxer.dumpStatistics(mInputFileName, extractor.getClipDuration());
+                    muxer.resetMuxer();
+                    extractor.unselectExtractorTrack(currentTrack);
+                    inputBufferInfo.clear();
+                    inputBuffer.clear();
+                } else {
+                    Log.e(TAG, "Test failed for " + mInputFileName + ". Returned invalid " +
+                            "output format for given " + mFormat + " format.");
+                }
+            }
+            extractor.deinitExtractor();
+            fileInput.close();
+        } else {
+            Log.w(TAG, "Warning: Test Skipped. Cannot find " + mInputFileName + " in directory " +
+                    mInputFilePath);
+        }
+        assertThat(status, is(equalTo(0)));
+    }
+}
diff --git a/media/tests/benchmark/MediaBenchmarkTest/src/main/java/com/android/media/benchmark/library/CodecUtils.java b/media/tests/benchmark/MediaBenchmarkTest/src/main/java/com/android/media/benchmark/library/CodecUtils.java
new file mode 100644
index 0000000..08035c9
--- /dev/null
+++ b/media/tests/benchmark/MediaBenchmarkTest/src/main/java/com/android/media/benchmark/library/CodecUtils.java
@@ -0,0 +1,39 @@
+package com.android.media.benchmark.library;
+
+import android.media.MediaCodecInfo;
+import android.media.MediaCodecList;
+import android.os.Build;
+
+import java.util.ArrayList;
+
+public class CodecUtils {
+    private CodecUtils() {}
+
+    /**
+     * Queries the MediaCodecList and returns codec names of supported codecs.
+     *
+     * @param mimeType  Mime type of input
+     * @param isEncoder Specifies encoder or decoder
+     * @return ArrayList of codec names
+     */
+    public static ArrayList<String> selectCodecs(String mimeType, boolean isEncoder) {
+        MediaCodecList codecList = new MediaCodecList(MediaCodecList.REGULAR_CODECS);
+        MediaCodecInfo[] codecInfos = codecList.getCodecInfos();
+        ArrayList<String> supportedCodecs = new ArrayList<>();
+        for (MediaCodecInfo codecInfo : codecInfos) {
+            if (isEncoder != codecInfo.isEncoder()) {
+                continue;
+            }
+            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q && codecInfo.isAlias()) {
+                continue;
+            }
+            String[] types = codecInfo.getSupportedTypes();
+            for (String type : types) {
+                if (type.equalsIgnoreCase(mimeType)) {
+                    supportedCodecs.add(codecInfo.getName());
+                }
+            }
+        }
+        return supportedCodecs;
+    }
+}
diff --git a/media/tests/benchmark/MediaBenchmarkTest/src/main/java/com/android/media/benchmark/library/Decoder.java b/media/tests/benchmark/MediaBenchmarkTest/src/main/java/com/android/media/benchmark/library/Decoder.java
new file mode 100644
index 0000000..2cd27c2
--- /dev/null
+++ b/media/tests/benchmark/MediaBenchmarkTest/src/main/java/com/android/media/benchmark/library/Decoder.java
@@ -0,0 +1,301 @@
+/*
+ * 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.
+ */
+
+package com.android.media.benchmark.library;
+
+import android.media.MediaCodec;
+import android.media.MediaCodec.BufferInfo;
+import android.media.MediaFormat;
+import android.util.Log;
+
+import androidx.annotation.NonNull;
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+
+public class Decoder {
+    private static final String TAG = "Decoder";
+    private static final boolean DEBUG = false;
+    private static final int kQueueDequeueTimeoutUs = 1000;
+
+    private final Object mLock = new Object();
+    private MediaCodec mCodec;
+    private ArrayList<BufferInfo> mInputBufferInfo;
+    private Stats mStats;
+
+    private boolean mSawInputEOS;
+    private boolean mSawOutputEOS;
+    private boolean mSignalledError;
+
+    private int mNumOutputFrame;
+    private int mIndex;
+
+    private ArrayList<ByteBuffer> mInputBuffer;
+    private FileOutputStream mOutputStream;
+
+    public Decoder() { mStats = new Stats(); }
+
+    /**
+     * Setup of decoder
+     *
+     * @param outputStream Will dump the output in this stream if not null.
+     */
+    public void setupDecoder(FileOutputStream outputStream) {
+        mSignalledError = false;
+        mOutputStream = outputStream;
+    }
+
+    private MediaCodec createCodec(String codecName, MediaFormat format) throws IOException {
+        String mime = format.getString(MediaFormat.KEY_MIME);
+        try {
+            MediaCodec codec;
+            if (codecName.isEmpty()) {
+                Log.i(TAG, "File mime type: " + mime);
+                if (mime != null) {
+                    codec = MediaCodec.createDecoderByType(mime);
+                    Log.i(TAG, "Decoder created for mime type " + mime);
+                    return codec;
+                } else {
+                    Log.e(TAG, "Mime type is null, please specify a mime type to create decoder");
+                    return null;
+                }
+            } else {
+                codec = MediaCodec.createByCodecName(codecName);
+                Log.i(TAG, "Decoder created with codec name: " + codecName + " mime: " + mime);
+                return codec;
+            }
+        } catch (IllegalArgumentException ex) {
+            ex.printStackTrace();
+            Log.e(TAG, "Failed to create decoder for " + codecName + " mime:" + mime);
+            return null;
+        }
+    }
+
+    /**
+     * Decodes the given input buffer,
+     * provided valid list of buffer info and format are passed as inputs.
+     *
+     * @param inputBuffer     Decode the provided list of ByteBuffers
+     * @param inputBufferInfo List of buffer info corresponding to provided input buffers
+     * @param asyncMode       Will run on async implementation if true
+     * @param format          For creating the decoder if codec name is empty and configuring it
+     * @param codecName       Will create the decoder with codecName
+     * @return 0 if decode was successful , -1 for fail, -2 for decoder not created
+     * @throws IOException if the codec cannot be created.
+     */
+    public int decode(@NonNull ArrayList<ByteBuffer> inputBuffer,
+            @NonNull ArrayList<BufferInfo> inputBufferInfo, final boolean asyncMode,
+            @NonNull MediaFormat format, String codecName) throws IOException {
+        mInputBuffer = new ArrayList<>(inputBuffer.size());
+        mInputBuffer.addAll(inputBuffer);
+        mInputBufferInfo = new ArrayList<>(inputBufferInfo.size());
+        mInputBufferInfo.addAll(inputBufferInfo);
+        mSawInputEOS = false;
+        mSawOutputEOS = false;
+        mNumOutputFrame = 0;
+        mIndex = 0;
+        long sTime = mStats.getCurTime();
+        mCodec = createCodec(codecName, format);
+        if (mCodec == null) {
+            return -2;
+        }
+        if (asyncMode) {
+            mCodec.setCallback(new MediaCodec.Callback() {
+                @Override
+                public void onInputBufferAvailable(
+                        @NonNull MediaCodec mediaCodec, int inputBufferId) {
+                    try {
+                        mStats.addInputTime();
+                        onInputAvailable(inputBufferId, mediaCodec);
+                    } catch (Exception e) {
+                        e.printStackTrace();
+                        Log.e(TAG, e.toString());
+                    }
+                }
+
+                @Override
+                public void onOutputBufferAvailable(@NonNull MediaCodec mediaCodec,
+                        int outputBufferId, @NonNull MediaCodec.BufferInfo bufferInfo) {
+                    mStats.addOutputTime();
+                    onOutputAvailable(mediaCodec, outputBufferId, bufferInfo);
+                    if (mSawOutputEOS) {
+                        Log.i(TAG, "Saw output EOS");
+                        synchronized (mLock) { mLock.notify(); }
+                    }
+                }
+
+                @Override
+                public void onOutputFormatChanged(
+                        @NonNull MediaCodec mediaCodec, @NonNull MediaFormat format) {
+                    Log.i(TAG, "Output format changed. Format: " + format.toString());
+                }
+
+                @Override
+                public void onError(
+                        @NonNull MediaCodec mediaCodec, @NonNull MediaCodec.CodecException e) {
+                    mSignalledError = true;
+                    Log.e(TAG, "Codec Error: " + e.toString());
+                    e.printStackTrace();
+                    synchronized (mLock) { mLock.notify(); }
+                }
+            });
+        }
+        int isEncoder = 0;
+        if (DEBUG) {
+            Log.d(TAG, "Media Format : " + format.toString());
+        }
+        mCodec.configure(format, null, null, isEncoder);
+        mCodec.start();
+        Log.i(TAG, "Codec started ");
+        long eTime = mStats.getCurTime();
+        mStats.setInitTime(mStats.getTimeDiff(sTime, eTime));
+        mStats.setStartTime();
+        if (asyncMode) {
+            try {
+                synchronized (mLock) { mLock.wait(); }
+                if (mSignalledError) {
+                    return -1;
+                }
+            } catch (InterruptedException e) {
+                e.printStackTrace();
+            }
+        } else {
+            while (!mSawOutputEOS && !mSignalledError) {
+                /* Queue input data */
+                if (!mSawInputEOS) {
+                    int inputBufferId = mCodec.dequeueInputBuffer(kQueueDequeueTimeoutUs);
+                    if (inputBufferId < 0 && inputBufferId != MediaCodec.INFO_TRY_AGAIN_LATER) {
+                        Log.e(TAG,
+                                "MediaCodec.dequeueInputBuffer "
+                                        + " returned invalid index : " + inputBufferId);
+                        return -1;
+                    }
+                    mStats.addInputTime();
+                    onInputAvailable(inputBufferId, mCodec);
+                }
+                /* Dequeue output data */
+                BufferInfo outputBufferInfo = new BufferInfo();
+                int outputBufferId =
+                        mCodec.dequeueOutputBuffer(outputBufferInfo, kQueueDequeueTimeoutUs);
+                if (outputBufferId < 0) {
+                    if (outputBufferId == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
+                        MediaFormat outFormat = mCodec.getOutputFormat();
+                        Log.i(TAG, "Output format changed. Format: " + outFormat.toString());
+                    } else if (outputBufferId == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) {
+                        Log.i(TAG, "Ignoring deprecated flag: INFO_OUTPUT_BUFFERS_CHANGED");
+                    } else if (outputBufferId != MediaCodec.INFO_TRY_AGAIN_LATER) {
+                        Log.e(TAG,
+                                "MediaCodec.dequeueOutputBuffer"
+                                        + " returned invalid index " + outputBufferId);
+                        return -1;
+                    }
+                } else {
+                    mStats.addOutputTime();
+                    if (DEBUG) {
+                        Log.d(TAG, "Dequeue O/P buffer with BufferID " + outputBufferId);
+                    }
+                    onOutputAvailable(mCodec, outputBufferId, outputBufferInfo);
+                }
+                if (outputBufferInfo.flags == MediaCodec.BUFFER_FLAG_END_OF_STREAM) {
+                    Log.i(TAG, "Saw output EOS");
+                }
+            }
+        }
+        mInputBuffer.clear();
+        mInputBufferInfo.clear();
+        return 0;
+    }
+
+    /**
+     * Stops the codec and releases codec resources.
+     */
+    public void deInitCodec() {
+        long sTime = mStats.getCurTime();
+        if (mCodec != null) {
+            mCodec.stop();
+            mCodec.release();
+            mCodec = null;
+        }
+        long eTime = mStats.getCurTime();
+        mStats.setDeInitTime(mStats.getTimeDiff(sTime, eTime));
+    }
+
+    /**
+     * Prints out the statistics in the information log
+     *
+     * @param inputReference The operation being performed, in this case decode
+     * @param durationUs     Duration of the clip in microseconds
+     */
+    public void dumpStatistics(String inputReference, long durationUs) {
+        String operation = "decode";
+        mStats.dumpStatistics(operation, inputReference, durationUs);
+    }
+
+    /**
+     * Resets the stats
+     */
+    public void resetDecoder() { mStats.reset(); }
+
+    private void onInputAvailable(int inputBufferId, MediaCodec mediaCodec) {
+        if ((inputBufferId >= 0) && !mSawInputEOS) {
+            ByteBuffer inputCodecBuffer = mediaCodec.getInputBuffer(inputBufferId);
+            BufferInfo bufInfo = mInputBufferInfo.get(mIndex);
+            inputCodecBuffer.put(mInputBuffer.get(mIndex).array());
+            mIndex++;
+            if (bufInfo.flags == MediaCodec.BUFFER_FLAG_END_OF_STREAM) {
+                mSawInputEOS = true;
+                Log.i(TAG, "Saw input EOS");
+            }
+            mStats.addFrameSize(bufInfo.size);
+            mediaCodec.queueInputBuffer(inputBufferId, bufInfo.offset, bufInfo.size,
+                    bufInfo.presentationTimeUs, bufInfo.flags);
+            if (DEBUG) {
+                Log.d(TAG,
+                        "Codec Input: "
+                                + "flag = " + bufInfo.flags + " timestamp = "
+                                + bufInfo.presentationTimeUs + " size = " + bufInfo.size);
+            }
+        }
+    }
+
+    private void onOutputAvailable(
+            MediaCodec mediaCodec, int outputBufferId, BufferInfo outputBufferInfo) {
+        if (mSawOutputEOS || outputBufferId < 0) {
+            return;
+        }
+        mNumOutputFrame++;
+        if (DEBUG) {
+            Log.d(TAG,
+                    "In OutputBufferAvailable ,"
+                            + " output frame number = " + mNumOutputFrame);
+        }
+        if (mOutputStream != null) {
+            try {
+                ByteBuffer outputBuffer = mediaCodec.getOutputBuffer(outputBufferId);
+                byte[] bytesOutput = new byte[outputBuffer.remaining()];
+                outputBuffer.get(bytesOutput);
+                mOutputStream.write(bytesOutput);
+            } catch (IOException e) {
+                e.printStackTrace();
+                Log.d(TAG, "Error Dumping File: Exception " + e.toString());
+            }
+        }
+        mediaCodec.releaseOutputBuffer(outputBufferId, false);
+        mSawOutputEOS = (outputBufferInfo.flags == MediaCodec.BUFFER_FLAG_END_OF_STREAM);
+    }
+}
diff --git a/media/tests/benchmark/MediaBenchmarkTest/src/main/java/com/android/media/benchmark/library/Encoder.java b/media/tests/benchmark/MediaBenchmarkTest/src/main/java/com/android/media/benchmark/library/Encoder.java
new file mode 100644
index 0000000..03db294
--- /dev/null
+++ b/media/tests/benchmark/MediaBenchmarkTest/src/main/java/com/android/media/benchmark/library/Encoder.java
@@ -0,0 +1,349 @@
+/*
+ * 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.
+ */
+
+package com.android.media.benchmark.library;
+
+import android.media.MediaCodec;
+import android.media.MediaCodec.CodecException;
+import android.media.MediaFormat;
+import android.util.Log;
+
+import androidx.annotation.NonNull;
+
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+public class Encoder {
+    private static final int ENCODE_DEFAULT_MAX_INPUT_SIZE = 3840;
+    private static final String TAG = "Encoder";
+    private static final boolean DEBUG = false;
+    private static final int kQueueDequeueTimeoutUs = 1000;
+
+    private final Object mLock = new Object();
+    private MediaCodec mCodec;
+    private String mMime;
+    private Stats mStats;
+
+    private int mOffset;
+    private int mFrameSize;
+    private int mNumInputFrame;
+    private int mNumFrames;
+    private int mFrameRate;
+    private int mSampleRate;
+    private long mInputBufferSize;
+
+    private boolean mSawInputEOS;
+    private boolean mSawOutputEOS;
+    private boolean mSignalledError;
+
+    private FileInputStream mInputStream;
+    private FileOutputStream mOutputStream;
+
+    public Encoder() {
+        mStats = new Stats();
+        mNumInputFrame = 0;
+        mSawInputEOS = false;
+        mSawOutputEOS = false;
+        mSignalledError = false;
+    }
+
+    /**
+     * Setup of encoder
+     *
+     * @param encoderOutputStream Will dump the encoder output in this stream if not null.
+     * @param fileInputStream     Will read the decoded output from this stream
+     */
+    public void setupEncoder(FileOutputStream encoderOutputStream,
+                             FileInputStream fileInputStream) {
+        this.mInputStream = fileInputStream;
+        this.mOutputStream = encoderOutputStream;
+    }
+
+    private MediaCodec createCodec(String codecName, String mime) throws IOException {
+        try {
+            MediaCodec codec;
+            if (codecName.isEmpty()) {
+                Log.i(TAG, "Mime type: " + mime);
+                if (mime != null) {
+                    codec = MediaCodec.createEncoderByType(mime);
+                    Log.i(TAG, "Encoder created for mime type " + mime);
+                    return codec;
+                } else {
+                    Log.e(TAG, "Mime type is null, please specify a mime type to create encoder");
+                    return null;
+                }
+            } else {
+                codec = MediaCodec.createByCodecName(codecName);
+                Log.i(TAG, "Encoder created with codec name: " + codecName + " and mime: " + mime);
+                return codec;
+            }
+        } catch (IllegalArgumentException ex) {
+            ex.printStackTrace();
+            Log.e(TAG, "Failed to create encoder for " + codecName + " mime: " + mime);
+            return null;
+        }
+    }
+
+    /**
+     * Encodes the given raw input file and measures the performance of encode operation,
+     * provided a valid list of parameters are passed as inputs.
+     *
+     * @param codecName    Will create the encoder with codecName
+     * @param mime         For creating encode format
+     * @param encodeFormat Format of the output data
+     * @param frameSize    Size of the frame
+     * @param asyncMode    Will run on async implementation if true
+     * @return 0 if encode was successful , -1 for fail, -2 for encoder not created
+     * @throws IOException If the codec cannot be created.
+     */
+    public int encode(String codecName, MediaFormat encodeFormat, String mime, int frameRate,
+                      int sampleRate, int frameSize, boolean asyncMode) throws IOException {
+        mInputBufferSize = mInputStream.getChannel().size();
+        mMime = mime;
+        mOffset = 0;
+        mFrameRate = frameRate;
+        mSampleRate = sampleRate;
+        long sTime = mStats.getCurTime();
+        mCodec = createCodec(codecName, mime);
+        if (mCodec == null) {
+            return -2;
+        }
+        /*Configure Codec*/
+        try {
+            mCodec.configure(encodeFormat, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
+        } catch (IllegalArgumentException | IllegalStateException | MediaCodec.CryptoException e) {
+            Log.e(TAG, "Failed to configure " + mCodec.getName() + " encoder.");
+            e.printStackTrace();
+            return -2;
+        }
+        if (mMime.startsWith("video/")) {
+            mFrameSize = frameSize;
+        } else {
+            int maxInputSize = ENCODE_DEFAULT_MAX_INPUT_SIZE;
+            MediaFormat format = mCodec.getInputFormat();
+            if (format.containsKey(MediaFormat.KEY_MAX_INPUT_SIZE)) {
+                maxInputSize = format.getInteger(MediaFormat.KEY_MAX_INPUT_SIZE);
+            }
+            mFrameSize = frameSize;
+            if (mFrameSize > maxInputSize && maxInputSize > 0) {
+                mFrameSize = maxInputSize;
+            }
+        }
+        mNumFrames = (int) ((mInputBufferSize + mFrameSize - 1) / mFrameSize);
+        if (asyncMode) {
+            mCodec.setCallback(new MediaCodec.Callback() {
+                @Override
+                public void onInputBufferAvailable(@NonNull MediaCodec mediaCodec,
+                                                   int inputBufferId) {
+                    try {
+                        mStats.addInputTime();
+                        onInputAvailable(mediaCodec, inputBufferId);
+                    } catch (Exception e) {
+                        e.printStackTrace();
+                        Log.e(TAG, e.toString());
+                    }
+                }
+
+                @Override
+                public void onOutputBufferAvailable(@NonNull MediaCodec mediaCodec,
+                                                    int outputBufferId,
+                                                    @NonNull MediaCodec.BufferInfo bufferInfo) {
+                    mStats.addOutputTime();
+                    onOutputAvailable(mediaCodec, outputBufferId, bufferInfo);
+                    if (mSawOutputEOS) {
+                        Log.i(TAG, "Saw output EOS");
+                        synchronized (mLock) { mLock.notify(); }
+                    }
+                }
+
+                @Override
+                public void onError(@NonNull MediaCodec mediaCodec, @NonNull CodecException e) {
+                    mediaCodec.stop();
+                    mediaCodec.release();
+                    Log.e(TAG, "CodecError: " + e.toString());
+                    e.printStackTrace();
+                }
+
+                @Override
+                public void onOutputFormatChanged(@NonNull MediaCodec mediaCodec,
+                                                  @NonNull MediaFormat format) {
+                    Log.i(TAG, "Output format changed. Format: " + format.toString());
+                }
+            });
+        }
+        mCodec.start();
+        long eTime = mStats.getCurTime();
+        mStats.setInitTime(mStats.getTimeDiff(sTime, eTime));
+        mStats.setStartTime();
+        if (asyncMode) {
+            try {
+                synchronized (mLock) { mLock.wait(); }
+                if (mSignalledError) {
+                    return -1;
+                }
+            } catch (InterruptedException e) {
+                e.printStackTrace();
+            }
+        } else {
+            while (!mSawOutputEOS && !mSignalledError) {
+                /* Queue input data */
+                if (!mSawInputEOS) {
+                    int inputBufferId = mCodec.dequeueInputBuffer(kQueueDequeueTimeoutUs);
+                    if (inputBufferId < 0 && inputBufferId != MediaCodec.INFO_TRY_AGAIN_LATER) {
+                        Log.e(TAG, "MediaCodec.dequeueInputBuffer " + "returned invalid index : " +
+                                inputBufferId);
+                        return -1;
+                    }
+                    mStats.addInputTime();
+                    onInputAvailable(mCodec, inputBufferId);
+                }
+                /* Dequeue output data */
+                MediaCodec.BufferInfo outputBufferInfo = new MediaCodec.BufferInfo();
+                int outputBufferId =
+                        mCodec.dequeueOutputBuffer(outputBufferInfo, kQueueDequeueTimeoutUs);
+                if (outputBufferId < 0) {
+                    if (outputBufferId == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
+                        MediaFormat outFormat = mCodec.getOutputFormat();
+                        Log.i(TAG, "Output format changed. Format: " + outFormat.toString());
+                    } else if (outputBufferId != MediaCodec.INFO_TRY_AGAIN_LATER) {
+                        Log.e(TAG, "MediaCodec.dequeueOutputBuffer" + " returned invalid index " +
+                                outputBufferId);
+                        return -1;
+                    }
+                } else {
+                    mStats.addOutputTime();
+                    if (DEBUG) {
+                        Log.d(TAG, "Dequeue O/P buffer with BufferID " + outputBufferId);
+                    }
+                    onOutputAvailable(mCodec, outputBufferId, outputBufferInfo);
+                }
+            }
+        }
+        return 0;
+    }
+
+    private void onOutputAvailable(MediaCodec mediaCodec, int outputBufferId,
+                                   MediaCodec.BufferInfo outputBufferInfo) {
+        if (mSawOutputEOS || outputBufferId < 0) {
+            if (mSawOutputEOS) {
+                Log.i(TAG, "Saw output EOS");
+            }
+            return;
+        }
+        ByteBuffer outputBuffer = mediaCodec.getOutputBuffer(outputBufferId);
+        if (mOutputStream != null) {
+            try {
+
+                byte[] bytesOutput = new byte[outputBuffer.remaining()];
+                outputBuffer.get(bytesOutput);
+                mOutputStream.write(bytesOutput);
+            } catch (IOException e) {
+                e.printStackTrace();
+                Log.d(TAG, "Error Dumping File: Exception " + e.toString());
+                return;
+            }
+        }
+        mStats.addFrameSize(outputBuffer.remaining());
+        mediaCodec.releaseOutputBuffer(outputBufferId, false);
+        mSawOutputEOS = (outputBufferInfo.flags == MediaCodec.BUFFER_FLAG_END_OF_STREAM);
+    }
+
+    private void onInputAvailable(MediaCodec mediaCodec, int inputBufferId) throws IOException {
+        if (mSawOutputEOS || inputBufferId < 0) {
+            if (mSawOutputEOS) {
+                Log.i(TAG, "Saw input EOS");
+            }
+            return;
+        }
+        if (mInputBufferSize < mOffset) {
+            Log.e(TAG, "Out of bound access of input buffer");
+            mSignalledError = true;
+            return;
+        }
+        ByteBuffer inputBuffer = mCodec.getInputBuffer(inputBufferId);
+        if (inputBuffer == null) {
+            mSignalledError = true;
+            return;
+        }
+        int bufSize = inputBuffer.capacity();
+        int bytesRead = mFrameSize;
+        if (mInputBufferSize - mOffset < mFrameSize) {
+            bytesRead = (int) (mInputBufferSize - mOffset);
+        }
+        if (bufSize < bytesRead) {
+            mSignalledError = true;
+            return;
+        }
+        byte[] inputArray = new byte[bytesRead];
+        mInputStream.read(inputArray, 0, bytesRead);
+        inputBuffer.put(inputArray);
+        int flag = 0;
+        if (mNumInputFrame >= mNumFrames - 1 || bytesRead == 0) {
+            Log.i(TAG, "Sending EOS on input last frame");
+            mSawInputEOS = true;
+            flag = MediaCodec.BUFFER_FLAG_END_OF_STREAM;
+        }
+        int presentationTimeUs;
+        if (mMime.startsWith("video/")) {
+            presentationTimeUs = mNumInputFrame * (1000000 / mFrameRate);
+        } else {
+            presentationTimeUs = mNumInputFrame * mFrameSize * 1000000 / mSampleRate;
+        }
+        mediaCodec.queueInputBuffer(inputBufferId, 0, bytesRead, presentationTimeUs, flag);
+        mNumInputFrame++;
+        mOffset += bytesRead;
+    }
+
+    /**
+     * Stops the codec and releases codec resources.
+     */
+    public void deInitEncoder() {
+        long sTime = mStats.getCurTime();
+        if (mCodec != null) {
+            mCodec.stop();
+            mCodec.release();
+            mCodec = null;
+        }
+        long eTime = mStats.getCurTime();
+        mStats.setDeInitTime(mStats.getTimeDiff(sTime, eTime));
+    }
+
+    /**
+     * Prints out the statistics in the information log
+     *
+     * @param inputReference The operation being performed, in this case encode
+     * @param durationUs     Duration of the clip in microseconds
+     */
+    public void dumpStatistics(String inputReference, long durationUs) {
+        String operation = "encode";
+        mStats.dumpStatistics(operation, inputReference, durationUs);
+    }
+
+    /**
+     * Resets the stats
+     */
+    public void resetEncoder() {
+        mOffset = 0;
+        mInputBufferSize = 0;
+        mNumInputFrame = 0;
+        mSawInputEOS = false;
+        mSawOutputEOS = false;
+        mSignalledError = false;
+        mStats.reset();
+    }
+}
diff --git a/media/tests/benchmark/MediaBenchmarkTest/src/main/java/com/android/media/benchmark/library/Extractor.java b/media/tests/benchmark/MediaBenchmarkTest/src/main/java/com/android/media/benchmark/library/Extractor.java
new file mode 100644
index 0000000..459e2a9
--- /dev/null
+++ b/media/tests/benchmark/MediaBenchmarkTest/src/main/java/com/android/media/benchmark/library/Extractor.java
@@ -0,0 +1,175 @@
+/*
+ * 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.
+ */
+
+package com.android.media.benchmark.library;
+
+import android.media.MediaCodec;
+import android.media.MediaExtractor;
+import android.media.MediaFormat;
+import android.util.Log;
+
+import java.io.FileDescriptor;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+public class Extractor {
+    private static final String TAG = "Extractor";
+    private static final int kMaxBufSize = 1024 * 1024 * 16;
+    private MediaExtractor mExtractor;
+    private ByteBuffer mFrameBuffer;
+    private MediaCodec.BufferInfo mBufferInfo;
+    private Stats mStats;
+    private long mDurationUs;
+
+    public Extractor() {
+        mFrameBuffer = ByteBuffer.allocate(kMaxBufSize);
+        mBufferInfo = new MediaCodec.BufferInfo();
+        mStats = new Stats();
+    }
+
+    /**
+     * Creates a Media Extractor and sets data source(FileDescriptor)to use
+     *
+     * @param fileDescriptor FileDescriptor for the file which is to be extracted
+     * @return TrackCount of the sample
+     * @throws IOException If FileDescriptor is null
+     */
+    public int setUpExtractor(FileDescriptor fileDescriptor) throws IOException {
+        long sTime = mStats.getCurTime();
+        mExtractor = new MediaExtractor();
+        mExtractor.setDataSource(fileDescriptor);
+        long eTime = mStats.getCurTime();
+        long timeTaken = mStats.getTimeDiff(sTime, eTime);
+        mStats.setInitTime(timeTaken);
+        return mExtractor.getTrackCount();
+    }
+
+    /**
+     * Returns the track format of the specified index
+     *
+     * @param trackID Index of the track
+     * @return Format of the track
+     */
+    public MediaFormat getFormat(int trackID) { return mExtractor.getTrackFormat(trackID); }
+
+    /**
+     * Returns the extracted buffer for the input clip
+     */
+    public ByteBuffer getFrameBuffer() { return this.mFrameBuffer; }
+
+    /**
+     * Returns the information of buffer related to sample
+     */
+    public MediaCodec.BufferInfo getBufferInfo() { return this.mBufferInfo; }
+
+    /**
+     * Returns the duration of the sample
+     */
+    public long getClipDuration() { return this.mDurationUs; }
+
+    /**
+     * Retrieve the current sample and store it in the byte buffer
+     * Also, sets the information related to extracted sample and store it in buffer info
+     *
+     * @return Sample size of the extracted sample
+     */
+    public int getFrameSample() {
+        int sampleSize = mExtractor.readSampleData(mFrameBuffer, 0);
+        if (sampleSize < 0) {
+            mBufferInfo.flags = MediaCodec.BUFFER_FLAG_END_OF_STREAM;
+            mBufferInfo.size = 0;
+        } else {
+            mBufferInfo.size = sampleSize;
+            mBufferInfo.offset = 0;
+            mBufferInfo.flags = mExtractor.getSampleFlags();
+            mBufferInfo.presentationTimeUs = mExtractor.getSampleTime();
+            mExtractor.advance();
+        }
+        return sampleSize;
+    }
+
+    /**
+     * Setup the track format and get the duration of the sample
+     * Track is selected here for extraction
+     *
+     * @param trackId Track index to be selected
+     * @return 0 for valid track, otherwise -1
+     */
+    public int selectExtractorTrack(int trackId) {
+        MediaFormat trackFormat = mExtractor.getTrackFormat(trackId);
+        mDurationUs = trackFormat.getLong(MediaFormat.KEY_DURATION);
+        if (mDurationUs < 0) {
+            Log.e(TAG, "Invalid Clip");
+            return -1;
+        }
+        mExtractor.selectTrack(trackId);
+        return 0;
+    }
+
+    /**
+     * Unselect the track
+     *
+     * @param trackId Track Index to be unselected
+     */
+    public void unselectExtractorTrack(int trackId) { mExtractor.unselectTrack(trackId); }
+
+    /**
+     * Free up the resources
+     */
+    public void deinitExtractor() {
+        long sTime = mStats.getCurTime();
+        mExtractor.release();
+        long eTime = mStats.getCurTime();
+        long timeTaken = mStats.getTimeDiff(sTime, eTime);
+        mStats.setDeInitTime(timeTaken);
+    }
+
+    /**
+     * Performs extract operation
+     *
+     * @param currentTrack Track index to be extracted
+     * @return Status as 0 if extraction is successful, -1 otherwise
+     */
+    public int extractSample(int currentTrack) {
+        int status;
+        status = selectExtractorTrack(currentTrack);
+        if (status == -1) {
+            Log.e(TAG, "Failed to select track");
+            return -1;
+        }
+        mStats.setStartTime();
+        while (true) {
+            int readSampleSize = getFrameSample();
+            if (readSampleSize <= 0) {
+                break;
+            }
+            mStats.addOutputTime();
+            mStats.addFrameSize(readSampleSize);
+        }
+        unselectExtractorTrack(currentTrack);
+        return 0;
+    }
+
+    /**
+     * Write the benchmark logs for the given input file
+     *
+     * @param inputReference Name of the input file
+     */
+    public void dumpStatistics(String inputReference) {
+        String operation = "extract";
+        mStats.dumpStatistics(operation, inputReference, mDurationUs);
+    }
+}
diff --git a/media/tests/benchmark/MediaBenchmarkTest/src/main/java/com/android/media/benchmark/library/Muxer.java b/media/tests/benchmark/MediaBenchmarkTest/src/main/java/com/android/media/benchmark/library/Muxer.java
new file mode 100644
index 0000000..49eaa1c
--- /dev/null
+++ b/media/tests/benchmark/MediaBenchmarkTest/src/main/java/com/android/media/benchmark/library/Muxer.java
@@ -0,0 +1,110 @@
+/*
+ * 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.
+ */
+package com.android.media.benchmark.library;
+
+import android.content.Context;
+import android.media.MediaCodec;
+import android.media.MediaFormat;
+import android.media.MediaMuxer;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+
+public class Muxer {
+    private Stats mStats;
+    private MediaMuxer mMuxer;
+
+    /**
+     * Creates a Media Muxer for the specified path
+     *
+     * @param context      App context to specify the output file path
+     * @param outputFormat Format of the output media file
+     * @param trackFormat  Format of the current track
+     * @return Returns the track index of the newly added track, -1 otherwise
+     */
+    public int setUpMuxer(Context context, int outputFormat, MediaFormat trackFormat) {
+        try {
+            mStats = new Stats();
+            long sTime = mStats.getCurTime();
+            mMuxer = new MediaMuxer(context.getFilesDir().getPath() + "/mux.out.", outputFormat);
+            int trackIndex = mMuxer.addTrack(trackFormat);
+            mMuxer.start();
+            long eTime = mStats.getCurTime();
+            long timeTaken = mStats.getTimeDiff(sTime, eTime);
+            mStats.setInitTime(timeTaken);
+            return trackIndex;
+        } catch (IllegalArgumentException | IOException e) {
+            e.printStackTrace();
+            return -1;
+        }
+    }
+
+    /**
+     * Performs the Mux operation
+     *
+     * @param trackIndex           Track index of the sample
+     * @param inputExtractedBuffer Buffer containing encoded samples
+     * @param inputBufferInfo      Buffer information related to these samples
+     * @return Returns Status as 0 if write operation is successful, -1 otherwise
+     */
+    public int mux(int trackIndex, ArrayList<ByteBuffer> inputExtractedBuffer,
+                   ArrayList<MediaCodec.BufferInfo> inputBufferInfo) {
+        mStats.setStartTime();
+        for (int sampleCount = 0; sampleCount < inputExtractedBuffer.size(); sampleCount++) {
+            try {
+                mMuxer.writeSampleData(trackIndex, inputExtractedBuffer.get(sampleCount),
+                        inputBufferInfo.get(sampleCount));
+                mStats.addOutputTime();
+                mStats.addFrameSize(inputBufferInfo.get(sampleCount).size);
+            } catch (IllegalArgumentException | IllegalStateException e) {
+                e.printStackTrace();
+                return -1;
+            }
+        }
+        return 0;
+    }
+
+    /**
+     * Stops the muxer and free up the resources
+     */
+    public void deInitMuxer() {
+        long sTime = mStats.getCurTime();
+        mMuxer.stop();
+        mMuxer.release();
+        long eTime = mStats.getCurTime();
+        long timeTaken = mStats.getTimeDiff(sTime, eTime);
+        mStats.setDeInitTime(timeTaken);
+    }
+
+    /**
+     * Resets the stats
+     */
+    public void resetMuxer() {
+        mStats.reset();
+    }
+
+    /**
+     * Write the benchmark logs for the given input file
+     *
+     * @param inputReference Name of the input file
+     * @param clipDuration   Duration of the given inputReference file
+     */
+    public void dumpStatistics(String inputReference, long clipDuration) {
+        String operation = "mux";
+        mStats.dumpStatistics(operation, inputReference, clipDuration);
+    }
+}
diff --git a/media/tests/benchmark/MediaBenchmarkTest/src/main/java/com/android/media/benchmark/library/Stats.java b/media/tests/benchmark/MediaBenchmarkTest/src/main/java/com/android/media/benchmark/library/Stats.java
new file mode 100644
index 0000000..18ab5be
--- /dev/null
+++ b/media/tests/benchmark/MediaBenchmarkTest/src/main/java/com/android/media/benchmark/library/Stats.java
@@ -0,0 +1,138 @@
+/*
+ * 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.
+ */
+
+package com.android.media.benchmark.library;
+
+import android.util.Log;
+
+import java.util.ArrayList;
+
+/**
+ * Measures Performance.
+ */
+public class Stats {
+    private static final String TAG = "Stats";
+    private long mInitTimeNs;
+    private long mDeInitTimeNs;
+    private long mStartTimeNs;
+    private ArrayList<Integer> mFrameSizes;
+    private ArrayList<Long> mInputTimer;
+    private ArrayList<Long> mOutputTimer;
+
+    public Stats() {
+        mFrameSizes = new ArrayList<>();
+        mInputTimer = new ArrayList<>();
+        mOutputTimer = new ArrayList<>();
+        mInitTimeNs = 0;
+        mDeInitTimeNs = 0;
+    }
+
+    public long getCurTime() { return System.nanoTime(); }
+
+    public void setInitTime(long initTime) { mInitTimeNs = initTime; }
+
+    public void setDeInitTime(long deInitTime) { mDeInitTimeNs = deInitTime; }
+
+    public void setStartTime() { mStartTimeNs = System.nanoTime(); }
+
+    public void addFrameSize(int size) { mFrameSizes.add(size); }
+
+    public void addInputTime() { mInputTimer.add(System.nanoTime()); }
+
+    public void addOutputTime() { mOutputTimer.add(System.nanoTime()); }
+
+    public void reset() {
+        if (mFrameSizes.size() != 0) {
+            mFrameSizes.clear();
+        }
+
+        if (mInputTimer.size() != 0) {
+            mInputTimer.clear();
+        }
+
+        if (mOutputTimer.size() != 0) {
+            mOutputTimer.clear();
+        }
+    }
+
+    public long getInitTime() { return mInitTimeNs; }
+
+    public long getDeInitTime() { return mDeInitTimeNs; }
+
+    public long getTimeDiff(long sTime, long eTime) { return (eTime - sTime); }
+
+    private long getTotalTime() {
+        if (mOutputTimer.size() == 0) {
+            return -1;
+        }
+        long lastTime = mOutputTimer.get(mOutputTimer.size() - 1);
+        return lastTime - mStartTimeNs;
+    }
+
+    private long getTotalSize() {
+        long totalSize = 0;
+        for (long size : mFrameSizes) {
+            totalSize += size;
+        }
+        return totalSize;
+    }
+
+    /**
+     * Dumps the stats of the operation for a given input media.
+     * <p>
+     * \param operation      describes the operation performed on the input media
+     * (i.e. extract/mux/decode/encode)
+     * \param inputReference input media
+     * \param durationUs    is a duration of the input media in microseconds.
+     */
+    public void dumpStatistics(String operation, String inputReference, long durationUs) {
+        if (mOutputTimer.size() == 0) {
+            Log.e(TAG, "No output produced");
+            return;
+        }
+        long totalTimeTakenNs = getTotalTime();
+        long timeTakenPerSec = (totalTimeTakenNs * 1000000) / durationUs;
+        long timeToFirstFrameNs = mOutputTimer.get(0) - mStartTimeNs;
+        long size = getTotalSize();
+        // get min and max output intervals.
+        long intervalNs;
+        long minTimeTakenNs = Long.MAX_VALUE;
+        long maxTimeTakenNs = 0;
+        long prevIntervalNs = mStartTimeNs;
+        for (int idx = 0; idx < mOutputTimer.size() - 1; idx++) {
+            intervalNs = mOutputTimer.get(idx) - prevIntervalNs;
+            prevIntervalNs = mOutputTimer.get(idx);
+            if (minTimeTakenNs > intervalNs) {
+                minTimeTakenNs = intervalNs;
+            } else if (maxTimeTakenNs < intervalNs) {
+                maxTimeTakenNs = intervalNs;
+            }
+        }
+        // Print the Stats
+        Log.i(TAG, "Input Reference : " + inputReference);
+        Log.i(TAG, "Setup Time in nano sec : " + mInitTimeNs);
+        Log.i(TAG, "Average Time in nano sec : " + totalTimeTakenNs / mOutputTimer.size());
+        Log.i(TAG, "Time to first frame in nano sec : " + timeToFirstFrameNs);
+        Log.i(TAG, "Time taken (in nano sec) to " + operation + " 1 sec of content : " +
+                timeTakenPerSec);
+        Log.i(TAG, "Total bytes " + operation + "ed : " + size);
+        Log.i(TAG, "Number of bytes " + operation + "ed per second : " +
+                (size * 1000000000) / totalTimeTakenNs);
+        Log.i(TAG, "Minimum Time in nano sec : " + minTimeTakenNs);
+        Log.i(TAG, "Maximum Time in nano sec : " + maxTimeTakenNs);
+        Log.i(TAG, "Destroy Time in nano sec : " + mDeInitTimeNs);
+    }
+}
\ No newline at end of file
diff --git a/media/tests/benchmark/README.md b/media/tests/benchmark/README.md
new file mode 100644
index 0000000..487ddb8
--- /dev/null
+++ b/media/tests/benchmark/README.md
@@ -0,0 +1,122 @@
+# Benchmark tests
+
+Benchmark app analyses the time taken by MediaCodec, MediaExtractor and MediaMuxer for given set of inputs. It is used to benchmark these modules on android devices.
+Benchmark results are emitted to logcat.
+
+This page describes steps to run the NDK and SDK layer test.
+
+Run the following steps to build the test suite:
+```
+mmm frameworks/av/media/tests/benchmark/
+```
+
+# NDK
+
+To run the test suite for measuring performance of the native layer, follow the following steps:
+
+The binaries will be created in the following path : ${OUT}/data/nativetest64/
+
+adb push $(OUT)/data/nativetest64/* /data/local/tmp/
+
+Eg. adb push $(OUT)/data/nativetest64/extractorTest/extractorTest /data/local/tmp/
+
+To run the binary, follow the commands mentioned below under each module.
+
+The resource file for the tests is taken from [here](https://drive.google.com/open?id=1ghMr17BBJ7n0pqbm7oREiTN_MNemJUqy)
+
+Download the MediaBenchmark.zip file, unzip and push it to /data/local/tmp/ on the device.
+
+```
+unzip MediaBenchmark.zip
+adb push MediaBenchmark /data/local/tmp
+```
+
+## Extractor
+
+The test extracts elementary stream and benchmarks the extractors available in NDK.
+
+The resource files are assumed to be at /data/local/tmp/MediaBenchmark/res/. You can use a different location, but you have to modify the rest of the instructions to replace /data/local/tmp/MediaBenchmark/res/ with wherever you chose to put the files.
+
+The path to these files on the device is required to be given for the test.
+
+```
+adb shell /data/local/tmp/extractorTest -P /data/local/tmp/MediaBenchmark/res/
+```
+
+## Decoder
+
+The test decodes input stream and benchmarks the decoders available in NDK.
+
+Setup steps are same as extractor.
+
+```
+adb shell /data/local/tmp/decoderTest -P /data/local/tmp/MediaBenchmark/res/
+```
+
+## Muxer
+
+The test muxes elementary stream and benchmarks the muxers available in NDK.
+
+Setup steps are same as extractor.
+
+```
+adb shell /data/local/tmp/muxerTest -P /data/local/tmp/MediaBenchmark/res/
+```
+
+## Encoder
+
+The test encodes input stream and benchmarks the encoders available in NDK.
+
+Setup steps are same as extractor.
+
+```
+adb shell /data/local/tmp/encoderTest -P /data/local/tmp/MediaBenchmark/res/
+```
+
+# SDK
+
+To run the test suite for measuring performance of the SDK APIs, follow the following steps:
+
+The apk will be created at the following path:
+${OUT}/testcases/MediaBenchmarkApp/arm64/
+
+To get the resorce files for the test follow instructions given in [NDK](#NDK)
+
+For installing the apk, run the command:
+```
+adb install -f -r ${OUT}/testcases/MediaBenchmarkApp/arm64/MediaBenchmarkApp.apk
+```
+
+For running all the tests, run the command:
+```
+adb shell am instrument -w -r -e package com.android.media.benchmark.tests com.android.media.benchmark/androidx.test.runner.AndroidJUnitRunner
+```
+
+## Extractor
+
+The test extracts elementary stream and benchmarks the extractors available in SDK.
+```
+adb shell am instrument -w -r -e class 'com.android.media.benchmark.tests.ExtractorTest' com.android.media.benchmark/androidx.test.runner.AndroidJUnitRunner
+```
+
+## Decoder
+
+The test decodes input stream and benchmarks the decoders available in SDK.
+```
+adb shell am instrument -w -r -e class 'com.android.media.benchmark.tests.DecoderTest' com.android.media.benchmark/androidx.test.runner.AndroidJUnitRunner
+```
+
+## Muxer
+
+The test muxes elementary stream and benchmarks different writers available in SDK.
+```
+adb shell am instrument -w -r -e class 'com.android.media.benchmark.tests.MuxerTest' com.android.media.benchmark/androidx.test.runner.AndroidJUnitRunner
+```
+
+## Encoder
+
+The test encodes input stream and benchmarks the encoders available in SDK.
+```
+adb shell am instrument -w -r -e class 'com.android.media.benchmark.tests.EncoderTest' com.android.media.benchmark/androidx.test.runner.AndroidJUnitRunner
+
+```
diff --git a/media/tests/benchmark/src/native/common/Android.bp b/media/tests/benchmark/src/native/common/Android.bp
new file mode 100644
index 0000000..1da0102
--- /dev/null
+++ b/media/tests/benchmark/src/native/common/Android.bp
@@ -0,0 +1,73 @@
+/*
+ * 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_library_static {
+    name: "libmediabenchmark_common",
+    defaults: [
+        "libmediabenchmark-defaults",
+        "libmediabenchmark_soft_sanitize_all-defaults",
+    ],
+
+    srcs: [
+        "BenchmarkCommon.cpp",
+        "Stats.cpp",
+    ],
+
+    export_include_dirs: ["."],
+
+    ldflags: ["-Wl,-Bsymbolic"]
+}
+
+cc_defaults {
+    name: "libmediabenchmark_common-defaults",
+
+    defaults: [
+        "libmediabenchmark-defaults",
+    ],
+
+    static_libs: [
+        "libmediabenchmark_common",
+    ],
+}
+
+cc_defaults {
+    name: "libmediabenchmark-defaults",
+
+    shared_libs: [
+        "libmediandk",
+        "liblog",
+        "libutils",
+    ],
+
+    cflags: [
+        "-Wall",
+        "-Werror",
+    ]
+}
+
+// public dependency for native implementation
+// to be used by code under media/benchmark/* only
+cc_defaults {
+    name: "libmediabenchmark_soft_sanitize_all-defaults",
+
+    sanitize: {
+        misc_undefined: [
+            "unsigned-integer-overflow",
+            "signed-integer-overflow",
+        ],
+        cfi: true,
+    }
+}
diff --git a/media/tests/benchmark/src/native/common/BenchmarkCommon.cpp b/media/tests/benchmark/src/native/common/BenchmarkCommon.cpp
new file mode 100644
index 0000000..5bdb48a
--- /dev/null
+++ b/media/tests/benchmark/src/native/common/BenchmarkCommon.cpp
@@ -0,0 +1,102 @@
+/*
+ * 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 "BenchmarkCommon"
+
+#include "BenchmarkCommon.h"
+#include <iostream>
+
+void CallBackHandle::ioThread() {
+    ALOGV("In %s mIsDone : %d, mSawError : %d ", __func__, mIsDone, mSawError);
+    while (!mIsDone && !mSawError) {
+        auto task = mIOQueue.pop();
+        task();
+    }
+}
+
+void OnInputAvailableCB(AMediaCodec *codec, void *userdata, int32_t index) {
+    ALOGV("OnInputAvailableCB: index(%d)", index);
+    CallBackHandle *self = (CallBackHandle *)userdata;
+    self->getStats()->addInputTime();
+    self->mIOQueue.push([self, codec, index]() { self->onInputAvailable(codec, index); });
+}
+
+void OnOutputAvailableCB(AMediaCodec *codec, void *userdata, int32_t index,
+                         AMediaCodecBufferInfo *bufferInfo) {
+    ALOGV("OnOutputAvailableCB: index(%d), (%d, %d, %lld, 0x%x)", index, bufferInfo->offset,
+          bufferInfo->size, (long long)bufferInfo->presentationTimeUs, bufferInfo->flags);
+    CallBackHandle *self = (CallBackHandle *)userdata;
+    self->getStats()->addOutputTime();
+    AMediaCodecBufferInfo bufferInfoCopy = *bufferInfo;
+    self->mIOQueue.push([self, codec, index, bufferInfoCopy]() {
+        AMediaCodecBufferInfo bc = bufferInfoCopy;
+        self->onOutputAvailable(codec, index, &bc);
+    });
+}
+
+void OnFormatChangedCB(AMediaCodec *codec, void *userdata, AMediaFormat *format) {
+    ALOGV("OnFormatChangedCB: format(%s)", AMediaFormat_toString(format));
+    CallBackHandle *self = (CallBackHandle *)userdata;
+    self->mIOQueue.push([self, codec, format]() { self->onFormatChanged(codec, format); });
+}
+
+void OnErrorCB(AMediaCodec *codec, void *userdata, media_status_t err, int32_t actionCode,
+               const char *detail) {
+    (void)codec;
+    ALOGV("OnErrorCB: err(%d), actionCode(%d), detail(%s)", err, actionCode, detail);
+    CallBackHandle *self = (CallBackHandle *)userdata;
+    self->mSawError = true;
+}
+
+AMediaCodec *createMediaCodec(AMediaFormat *format, const char *mime, string codecName,
+                              bool isEncoder) {
+    ALOGV("In %s", __func__);
+    if (!mime) {
+        ALOGE("Please specify a mime type to create codec");
+        return nullptr;
+    }
+
+    AMediaCodec *codec;
+    if (!codecName.empty()) {
+        codec = AMediaCodec_createCodecByName(codecName.c_str());
+        if (!codec) {
+            ALOGE("Unable to create codec by name: %s", codecName.c_str());
+            return nullptr;
+        }
+    } else {
+        if (isEncoder) {
+            codec = AMediaCodec_createEncoderByType(mime);
+        } else {
+            codec = AMediaCodec_createDecoderByType(mime);
+        }
+        if (!codec) {
+            ALOGE("Unable to create codec by mime: %s", mime);
+            return nullptr;
+        }
+    }
+
+    /* Configure codec with the given format*/
+    const char *s = AMediaFormat_toString(format);
+    ALOGV("Input format: %s\n", s);
+
+    media_status_t status = AMediaCodec_configure(codec, format, nullptr, nullptr, isEncoder);
+    if (status != AMEDIA_OK) {
+        ALOGE("AMediaCodec_configure failed %d", status);
+        return nullptr;
+    }
+    return codec;
+}
\ No newline at end of file
diff --git a/media/tests/benchmark/src/native/common/BenchmarkCommon.h b/media/tests/benchmark/src/native/common/BenchmarkCommon.h
new file mode 100644
index 0000000..df16baf
--- /dev/null
+++ b/media/tests/benchmark/src/native/common/BenchmarkCommon.h
@@ -0,0 +1,127 @@
+/*
+ * 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 __BENCHMARK_COMMON_H__
+#define __BENCHMARK_COMMON_H__
+
+#include <utils/Log.h>
+
+#include <inttypes.h>
+#include <mutex>
+#include <queue>
+#include <thread>
+
+#include <media/NdkMediaCodec.h>
+#include <media/NdkMediaError.h>
+
+#include "Stats.h"
+
+using namespace std;
+
+constexpr uint32_t kQueueDequeueTimeoutUs = 1000;
+constexpr uint32_t kMaxCSDStrlen = 16;
+constexpr uint32_t kMaxBufferSize = 1024 * 1024 * 16;
+
+template <typename T>
+class CallBackQueue {
+  public:
+    CallBackQueue() {}
+    ~CallBackQueue() {}
+
+    void push(T elem) {
+        bool needsNotify = false;
+        {
+            lock_guard<mutex> lock(mMutex);
+            needsNotify = mQueue.empty();
+            mQueue.push(move(elem));
+        }
+        if (needsNotify) mQueueNotEmptyCondition.notify_one();
+    }
+
+    T pop() {
+        unique_lock<mutex> lock(mMutex);
+        if (mQueue.empty()) {
+            mQueueNotEmptyCondition.wait(lock, [this]() { return !mQueue.empty(); });
+        }
+        auto result = mQueue.front();
+        mQueue.pop();
+        return result;
+    }
+
+  private:
+    mutex mMutex;
+    queue<T> mQueue;
+    condition_variable mQueueNotEmptyCondition;
+};
+
+class CallBackHandle {
+  public:
+    CallBackHandle() : mSawError(false), mIsDone(false), mStats(nullptr) {
+        mStats = new Stats();
+    }
+
+    virtual ~CallBackHandle() {
+        if (mIOThread.joinable()) mIOThread.join();
+        if (mStats) delete mStats;
+    }
+
+    void ioThread();
+
+    // Implementation in child class (Decoder/Encoder)
+    virtual void onInputAvailable(AMediaCodec *codec, int32_t index) {
+        (void)codec;
+        (void)index;
+    }
+    virtual void onFormatChanged(AMediaCodec *codec, AMediaFormat *format) {
+        (void)codec;
+        (void)format;
+    }
+    virtual void onOutputAvailable(AMediaCodec *codec, int32_t index,
+                                   AMediaCodecBufferInfo *bufferInfo) {
+        (void)codec;
+        (void)index;
+        (void)bufferInfo;
+    }
+
+    Stats *getStats() { return mStats; }
+
+    // Keep a queue of all function callbacks.
+    typedef function<void()> IOTask;
+    CallBackQueue<IOTask> mIOQueue;
+    thread mIOThread;
+    bool mSawError;
+    bool mIsDone;
+
+  protected:
+    Stats *mStats;
+};
+
+// Async API's callback
+void OnInputAvailableCB(AMediaCodec *codec, void *userdata, int32_t index);
+
+void OnOutputAvailableCB(AMediaCodec *codec, void *userdata, int32_t index,
+                         AMediaCodecBufferInfo *bufferInfo);
+
+void OnFormatChangedCB(AMediaCodec *codec, void *userdata, AMediaFormat *format);
+
+void OnErrorCB(AMediaCodec *codec, void * /* userdata */, media_status_t err, int32_t actionCode,
+               const char *detail);
+
+// Utility to create and configure AMediaCodec
+AMediaCodec *createMediaCodec(AMediaFormat *format, const char *mime, string codecName,
+                              bool isEncoder);
+
+#endif  // __BENCHMARK_COMMON_H__
diff --git a/media/tests/benchmark/src/native/common/Stats.cpp b/media/tests/benchmark/src/native/common/Stats.cpp
new file mode 100644
index 0000000..6bcd3ce
--- /dev/null
+++ b/media/tests/benchmark/src/native/common/Stats.cpp
@@ -0,0 +1,67 @@
+/*
+ * 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 "Stats"
+
+#include <iostream>
+#include <stdint.h>
+#include <utils/Log.h>
+
+#include "Stats.h"
+
+/**
+ * Dumps the stats of the operation for a given input media.
+ *
+ * \param operation      describes the operation performed on the input media
+ *                       (i.e. extract/mux/decode/encode)
+ * \param inputReference input media
+ * \param duarationUs    is a duration of the input media in microseconds.
+ */
+void Stats::dumpStatistics(std::string operation, std::string inputReference, int64_t duarationUs) {
+    ALOGV("In %s", __func__);
+    if (!mOutputTimer.size()) {
+        ALOGE("No output produced");
+        return;
+    }
+    nsecs_t totalTimeTakenNs = getTotalTime();
+    nsecs_t timeTakenPerSec = (totalTimeTakenNs * 1000000) / duarationUs;
+    nsecs_t timeToFirstFrameNs = *mOutputTimer.begin() - mStartTimeNs;
+    int32_t size = std::accumulate(mFrameSizes.begin(), mFrameSizes.end(), 0);
+    // get min and max output intervals.
+    nsecs_t intervalNs;
+    nsecs_t minTimeTakenNs = INT64_MAX;
+    nsecs_t maxTimeTakenNs = 0;
+    nsecs_t prevIntervalNs = mStartTimeNs;
+    for (int32_t idx = 0; idx < mOutputTimer.size() - 1; idx++) {
+        intervalNs = mOutputTimer.at(idx) - prevIntervalNs;
+        prevIntervalNs = mOutputTimer.at(idx);
+        if (minTimeTakenNs > intervalNs) minTimeTakenNs = intervalNs;
+        else if (maxTimeTakenNs < intervalNs) maxTimeTakenNs = intervalNs;
+    }
+
+    // Print the Stats
+    std::cout << "Input Reference : " << inputReference << endl;
+    std::cout << "Setup Time in nano sec : " << mInitTimeNs << endl;
+    std::cout << "Average Time in nano sec : " << totalTimeTakenNs / mOutputTimer.size() << endl;
+    std::cout << "Time to first frame in nano sec : " << timeToFirstFrameNs << endl;
+    std::cout << "Time taken (in nano sec) to " << operation
+              << " 1 sec of content : " << timeTakenPerSec << endl;
+    std::cout << "Total bytes " << operation << "ed : " << size << endl;
+    std::cout << "Minimum Time in nano sec : " << minTimeTakenNs << endl;
+    std::cout << "Maximum Time in nano sec : " << maxTimeTakenNs << endl;
+    std::cout << "Destroy Time in nano sec : " << mDeInitTimeNs << endl;
+}
diff --git a/media/tests/benchmark/src/native/common/Stats.h b/media/tests/benchmark/src/native/common/Stats.h
new file mode 100644
index 0000000..024319a
--- /dev/null
+++ b/media/tests/benchmark/src/native/common/Stats.h
@@ -0,0 +1,84 @@
+/*
+ * 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 __STATS_H__
+#define __STATS_H__
+
+#include <sys/time.h>
+#include <algorithm>
+#include <numeric>
+#include <vector>
+#include <utils/Timers.h>
+
+using namespace std;
+
+class Stats {
+  public:
+    Stats() {
+        mInitTimeNs = 0;
+        mDeInitTimeNs = 0;
+    }
+
+    ~Stats() {
+        reset();
+    }
+
+  private:
+    nsecs_t mInitTimeNs;
+    nsecs_t mDeInitTimeNs;
+    nsecs_t mStartTimeNs;
+    std::vector<int32_t> mFrameSizes;
+    std::vector<nsecs_t> mInputTimer;
+    std::vector<nsecs_t> mOutputTimer;
+
+  public:
+    nsecs_t getCurTime() { return systemTime(CLOCK_MONOTONIC); }
+
+    void setInitTime(nsecs_t initTime) { mInitTimeNs = initTime; }
+
+    void setDeInitTime(nsecs_t deInitTime) { mDeInitTimeNs = deInitTime; }
+
+    void setStartTime() { mStartTimeNs = systemTime(CLOCK_MONOTONIC); }
+
+    void addFrameSize(int32_t size) { mFrameSizes.push_back(size); }
+
+    void addInputTime() { mInputTimer.push_back(systemTime(CLOCK_MONOTONIC)); }
+
+    void addOutputTime() { mOutputTimer.push_back(systemTime(CLOCK_MONOTONIC)); }
+
+    void reset() {
+        if (!mFrameSizes.empty()) mFrameSizes.clear();
+        if (!mInputTimer.empty()) mInputTimer.clear();
+        if (!mOutputTimer.empty()) mOutputTimer.clear();
+    }
+
+    std::vector<nsecs_t> getOutputTimer() { return mOutputTimer; }
+
+    nsecs_t getInitTime() { return mInitTimeNs; }
+
+    nsecs_t getDeInitTime() { return mDeInitTimeNs; }
+
+    nsecs_t getTimeDiff(nsecs_t sTime, nsecs_t eTime) { return (eTime - sTime); }
+
+    nsecs_t getTotalTime() {
+        if (mOutputTimer.empty()) return -1;
+        return (*(mOutputTimer.end() - 1) - mStartTimeNs);
+    }
+
+    void dumpStatistics(std::string operation, std::string inputReference, int64_t duarationUs);
+};
+
+#endif  // __STATS_H__
diff --git a/media/tests/benchmark/src/native/decoder/Android.bp b/media/tests/benchmark/src/native/decoder/Android.bp
new file mode 100644
index 0000000..b6286d4
--- /dev/null
+++ b/media/tests/benchmark/src/native/decoder/Android.bp
@@ -0,0 +1,31 @@
+/*
+ * 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_library_static {
+    name: "libmediabenchmark_decoder",
+    defaults: [
+        "libmediabenchmark_common-defaults",
+        "libmediabenchmark_soft_sanitize_all-defaults",
+    ],
+
+    srcs: ["Decoder.cpp"],
+
+    static_libs: ["libmediabenchmark_extractor"],
+
+    export_include_dirs: ["."],
+
+    ldflags: ["-Wl,-Bsymbolic"]
+}
diff --git a/media/tests/benchmark/src/native/decoder/Decoder.cpp b/media/tests/benchmark/src/native/decoder/Decoder.cpp
new file mode 100644
index 0000000..ef84537
--- /dev/null
+++ b/media/tests/benchmark/src/native/decoder/Decoder.cpp
@@ -0,0 +1,232 @@
+/*
+ * 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 "decoder"
+
+#include <iostream>
+
+#include "Decoder.h"
+
+tuple<ssize_t, uint32_t, int64_t> readSampleData(uint8_t *inputBuffer, int32_t &offset,
+                                                 vector<AMediaCodecBufferInfo> &frameInfo,
+                                                 uint8_t *buf, int32_t frameID, size_t bufSize) {
+    ALOGV("In %s", __func__);
+    if (frameID == (int32_t)frameInfo.size()) {
+        return make_tuple(0, AMEDIACODEC_BUFFER_FLAG_END_OF_STREAM, 0);
+    }
+    uint32_t flags = frameInfo[frameID].flags;
+    int64_t timestamp = frameInfo[frameID].presentationTimeUs;
+    ssize_t bytesCount = frameInfo[frameID].size;
+    if (bufSize < bytesCount) {
+        ALOGE("Error : insufficient resource");
+        return make_tuple(0, AMEDIACODEC_ERROR_INSUFFICIENT_RESOURCE, 0);
+    }
+
+    memcpy(buf, inputBuffer + offset, bytesCount);
+    offset += bytesCount;
+    return make_tuple(bytesCount, flags, timestamp);
+}
+
+void Decoder::onInputAvailable(AMediaCodec *mediaCodec, int32_t bufIdx) {
+    ALOGV("In %s", __func__);
+    if (mediaCodec == mCodec && mediaCodec) {
+        if (mSawInputEOS || bufIdx < 0) return;
+        if (mSignalledError) {
+            CallBackHandle::mSawError = true;
+            mDecoderDoneCondition.notify_one();
+            return;
+        }
+
+        size_t bufSize;
+        uint8_t *buf = AMediaCodec_getInputBuffer(mCodec, bufIdx, &bufSize);
+        if (!buf) {
+            mSignalledError = true;
+            mDecoderDoneCondition.notify_one();
+            return;
+        }
+
+        ssize_t bytesRead = 0;
+        uint32_t flag = 0;
+        int64_t presentationTimeUs = 0;
+        tie(bytesRead, flag, presentationTimeUs) = readSampleData(
+                mInputBuffer, mOffset, mFrameMetaData, buf, mNumInputFrame, bufSize);
+        if (flag == AMEDIACODEC_ERROR_INSUFFICIENT_RESOURCE) {
+            mSignalledError = true;
+            mDecoderDoneCondition.notify_one();
+            return;
+        }
+
+        if (flag == AMEDIACODEC_BUFFER_FLAG_END_OF_STREAM) mSawInputEOS = true;
+        ALOGV("%s bytesRead : %zd presentationTimeUs : %" PRId64 " mSawInputEOS : %s", __FUNCTION__,
+              bytesRead, presentationTimeUs, mSawInputEOS ? "TRUE" : "FALSE");
+
+        int status = AMediaCodec_queueInputBuffer(mCodec, bufIdx, 0 /* offset */, bytesRead,
+                                                  presentationTimeUs, flag);
+        if (AMEDIA_OK != status) {
+            mSignalledError = true;
+            mDecoderDoneCondition.notify_one();
+            return;
+        }
+        mStats->addFrameSize(bytesRead);
+        mNumInputFrame++;
+    }
+}
+
+void Decoder::onOutputAvailable(AMediaCodec *mediaCodec, int32_t bufIdx,
+                                AMediaCodecBufferInfo *bufferInfo) {
+    ALOGV("In %s", __func__);
+    if (mediaCodec == mCodec && mediaCodec) {
+        if (mSawOutputEOS || bufIdx < 0) return;
+        if (mSignalledError) {
+            CallBackHandle::mSawError = true;
+            mDecoderDoneCondition.notify_one();
+            return;
+        }
+
+        if (mOutFp != nullptr) {
+            size_t bufSize;
+            uint8_t *buf = AMediaCodec_getOutputBuffer(mCodec, bufIdx, &bufSize);
+            if (buf) {
+                fwrite(buf, sizeof(char), bufferInfo->size, mOutFp);
+                ALOGV("bytes written into file  %d\n", bufferInfo->size);
+            }
+        }
+
+        AMediaCodec_releaseOutputBuffer(mCodec, bufIdx, false);
+        mSawOutputEOS = (0 != (bufferInfo->flags & AMEDIACODEC_BUFFER_FLAG_END_OF_STREAM));
+        mNumOutputFrame++;
+        ALOGV("%s index : %d  mSawOutputEOS : %s count : %u", __FUNCTION__, bufIdx,
+              mSawOutputEOS ? "TRUE" : "FALSE", mNumOutputFrame);
+
+        if (mSawOutputEOS) {
+            CallBackHandle::mIsDone = true;
+            mDecoderDoneCondition.notify_one();
+        }
+    }
+}
+
+void Decoder::onFormatChanged(AMediaCodec *mediaCodec, AMediaFormat *format) {
+    ALOGV("In %s", __func__);
+    if (mediaCodec == mCodec && mediaCodec) {
+        ALOGV("%s { %s }", __FUNCTION__, AMediaFormat_toString(format));
+        mFormat = format;
+    }
+}
+
+void Decoder::setupDecoder() {
+    if (!mFormat) mFormat = mExtractor->getFormat();
+}
+
+int32_t Decoder::decode(uint8_t *inputBuffer, vector<AMediaCodecBufferInfo> &frameInfo,
+                        string &codecName, bool asyncMode, FILE *outFp) {
+    ALOGV("In %s", __func__);
+    mInputBuffer = inputBuffer;
+    mFrameMetaData = frameInfo;
+    mOffset = 0;
+    mOutFp = outFp;
+
+    const char *mime = nullptr;
+    AMediaFormat_getString(mFormat, AMEDIAFORMAT_KEY_MIME, &mime);
+    if (!mime) return AMEDIA_ERROR_INVALID_OBJECT;
+
+    int64_t sTime = mStats->getCurTime();
+    mCodec = createMediaCodec(mFormat, mime, codecName, false /*isEncoder*/);
+    if (!mCodec) return AMEDIA_ERROR_INVALID_OBJECT;
+
+    if (asyncMode) {
+        AMediaCodecOnAsyncNotifyCallback aCB = {OnInputAvailableCB, OnOutputAvailableCB,
+                                                OnFormatChangedCB, OnErrorCB};
+        AMediaCodec_setAsyncNotifyCallback(mCodec, aCB, this);
+
+        mIOThread = thread(&CallBackHandle::ioThread, this);
+    }
+
+    AMediaCodec_start(mCodec);
+    int64_t eTime = mStats->getCurTime();
+    int64_t timeTaken = mStats->getTimeDiff(sTime, eTime);
+    mStats->setInitTime(timeTaken);
+
+    mStats->setStartTime();
+    if (!asyncMode) {
+        while (!mSawOutputEOS && !mSignalledError) {
+            /* Queue input data */
+            if (!mSawInputEOS) {
+                ssize_t inIdx = AMediaCodec_dequeueInputBuffer(mCodec, kQueueDequeueTimeoutUs);
+                if (inIdx < 0 && inIdx != AMEDIACODEC_INFO_TRY_AGAIN_LATER) {
+                    ALOGE("AMediaCodec_dequeueInputBuffer returned invalid index %zd\n", inIdx);
+                    return AMEDIA_ERROR_IO;
+                } else if (inIdx >= 0) {
+                    mStats->addInputTime();
+                    onInputAvailable(mCodec, inIdx);
+                }
+            }
+
+            /* Dequeue output data */
+            AMediaCodecBufferInfo info;
+            ssize_t outIdx = AMediaCodec_dequeueOutputBuffer(mCodec, &info, kQueueDequeueTimeoutUs);
+            if (outIdx == AMEDIACODEC_INFO_OUTPUT_FORMAT_CHANGED) {
+                mFormat = AMediaCodec_getOutputFormat(mCodec);
+                const char *s = AMediaFormat_toString(mFormat);
+                ALOGI("Output format: %s\n", s);
+            } else if (outIdx >= 0) {
+                mStats->addOutputTime();
+                onOutputAvailable(mCodec, outIdx, &info);
+            } else if (!(outIdx == AMEDIACODEC_INFO_TRY_AGAIN_LATER ||
+                         outIdx == AMEDIACODEC_INFO_OUTPUT_BUFFERS_CHANGED)) {
+                ALOGE("AMediaCodec_dequeueOutputBuffer returned invalid index %zd\n", outIdx);
+                return AMEDIA_ERROR_IO;
+            }
+        }
+    } else {
+        unique_lock<mutex> lock(mMutex);
+        mDecoderDoneCondition.wait(lock, [this]() { return (mSawOutputEOS || mSignalledError); });
+    }
+
+    if (codecName.empty()) {
+        char *decName;
+        AMediaCodec_getName(mCodec, &decName);
+        codecName.assign(decName);
+        AMediaCodec_releaseName(mCodec, decName);
+    }
+    return AMEDIA_OK;
+}
+
+void Decoder::deInitCodec() {
+    int64_t sTime = mStats->getCurTime();
+    if (mFormat) {
+        AMediaFormat_delete(mFormat);
+        mFormat = nullptr;
+    }
+    if (!mCodec) return;
+    AMediaCodec_stop(mCodec);
+    AMediaCodec_delete(mCodec);
+    int64_t eTime = mStats->getCurTime();
+    int64_t timeTaken = mStats->getTimeDiff(sTime, eTime);
+    mStats->setDeInitTime(timeTaken);
+}
+
+void Decoder::dumpStatistics(string inputReference) {
+    int64_t durationUs = mExtractor->getClipDuration();
+    string operation = "decode";
+    mStats->dumpStatistics(operation, inputReference, durationUs);
+}
+
+void Decoder::resetDecoder() {
+    if (mStats) mStats->reset();
+    if (mInputBuffer) mInputBuffer = nullptr;
+    if (!mFrameMetaData.empty()) mFrameMetaData.clear();
+}
diff --git a/media/tests/benchmark/src/native/decoder/Decoder.h b/media/tests/benchmark/src/native/decoder/Decoder.h
new file mode 100644
index 0000000..7630e7b
--- /dev/null
+++ b/media/tests/benchmark/src/native/decoder/Decoder.h
@@ -0,0 +1,101 @@
+/*
+ * 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 __DECODER_H__
+#define __DECODER_H__
+
+#include <chrono>
+#include <condition_variable>
+#include <mutex>
+#include <queue>
+#include <thread>
+
+#include "BenchmarkCommon.h"
+#include "Extractor.h"
+#include "Stats.h"
+
+class Decoder : public CallBackHandle {
+  public:
+    Decoder()
+        : mCodec(nullptr),
+          mFormat(nullptr),
+          mExtractor(nullptr),
+          mNumInputFrame(0),
+          mNumOutputFrame(0),
+          mSawInputEOS(false),
+          mSawOutputEOS(false),
+          mSignalledError(false),
+          mInputBuffer(nullptr),
+          mOutFp(nullptr) {
+        mExtractor = new Extractor();
+    }
+
+    virtual ~Decoder() {
+        if (mExtractor) delete mExtractor;
+    }
+
+    Extractor *getExtractor() { return mExtractor; }
+
+    // Decoder related utilities
+    void setupDecoder();
+
+    void deInitCodec();
+
+    void resetDecoder();
+
+    // Async callback APIs
+    void onInputAvailable(AMediaCodec *codec, int32_t index) override;
+
+    void onFormatChanged(AMediaCodec *codec, AMediaFormat *format) override;
+
+    void onOutputAvailable(AMediaCodec *codec, int32_t index,
+                           AMediaCodecBufferInfo *bufferInfo) override;
+
+    // Process the frames and give decoded output
+    int32_t decode(uint8_t *inputBuffer, vector<AMediaCodecBufferInfo> &frameInfo,
+                   string &codecName, bool asyncMode, FILE *outFp = nullptr);
+
+    void dumpStatistics(string inputReference);
+
+  private:
+    AMediaCodec *mCodec;
+    AMediaFormat *mFormat;
+
+    Extractor *mExtractor;
+
+    int32_t mNumInputFrame;
+    int32_t mNumOutputFrame;
+
+    bool mSawInputEOS;
+    bool mSawOutputEOS;
+    bool mSignalledError;
+
+    int32_t mOffset;
+    uint8_t *mInputBuffer;
+    vector<AMediaCodecBufferInfo> mFrameMetaData;
+    FILE *mOutFp;
+
+    /* Asynchronous locks */
+    mutex mMutex;
+    condition_variable mDecoderDoneCondition;
+};
+
+// Read input samples
+tuple<ssize_t, uint32_t, int64_t> readSampleData(uint8_t *inputBuffer, int32_t &offset,
+                                                 vector<AMediaCodecBufferInfo> &frameSizes,
+                                                 uint8_t *buf, int32_t frameID, size_t bufSize);
+
+#endif  // __DECODER_H__
diff --git a/media/tests/benchmark/src/native/encoder/Android.bp b/media/tests/benchmark/src/native/encoder/Android.bp
new file mode 100644
index 0000000..239f378
--- /dev/null
+++ b/media/tests/benchmark/src/native/encoder/Android.bp
@@ -0,0 +1,33 @@
+/*
+ * 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_library_static {
+    name: "libmediabenchmark_encoder",
+    defaults: [
+        "libmediabenchmark_common-defaults",
+        "libmediabenchmark_soft_sanitize_all-defaults",
+    ],
+
+    srcs: ["Encoder.cpp"],
+
+    static_libs: ["libmediabenchmark_extractor",
+                  "libmediabenchmark_decoder",
+    ],
+
+    export_include_dirs: ["."],
+
+    ldflags: ["-Wl,-Bsymbolic"]
+}
diff --git a/media/tests/benchmark/src/native/encoder/Encoder.cpp b/media/tests/benchmark/src/native/encoder/Encoder.cpp
new file mode 100644
index 0000000..5fdf9e3
--- /dev/null
+++ b/media/tests/benchmark/src/native/encoder/Encoder.cpp
@@ -0,0 +1,273 @@
+/*
+ * 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 "encoder"
+
+#include <fstream>
+
+#include "Encoder.h"
+
+void Encoder::onInputAvailable(AMediaCodec *mediaCodec, int32_t bufIdx) {
+    ALOGV("In %s", __func__);
+    if (mediaCodec == mCodec && mediaCodec) {
+        if (mSawInputEOS || bufIdx < 0) return;
+        if (mSignalledError) {
+            CallBackHandle::mSawError = true;
+            mEncoderDoneCondition.notify_one();
+            return;
+        }
+
+        size_t bufSize = 0;
+        char *buf = (char *)AMediaCodec_getInputBuffer(mCodec, bufIdx, &bufSize);
+        if (!buf) {
+            mSignalledError = true;
+            mEncoderDoneCondition.notify_one();
+            return;
+        }
+
+        if (mInputBufferSize < mOffset) {
+            ALOGE("Out of bound access of input buffer\n");
+            mSignalledError = true;
+            mEncoderDoneCondition.notify_one();
+            return;
+        }
+        size_t bytesRead = mParams.frameSize;
+        if (mInputBufferSize - mOffset < mParams.frameSize) {
+            bytesRead = mInputBufferSize - mOffset;
+        }
+        if (bufSize < bytesRead) {
+            ALOGE("bytes to read %zu bufSize %zu \n", bytesRead, bufSize);
+            mSignalledError = true;
+            mEncoderDoneCondition.notify_one();
+            return;
+        }
+        if (bytesRead < mParams.frameSize && mNumInputFrame < mParams.numFrames - 1) {
+            ALOGE("Partial frame at frameID %d bytesRead %zu frameSize %d total numFrames %d\n",
+                  mNumInputFrame, bytesRead, mParams.frameSize, mParams.numFrames);
+            mSignalledError = true;
+            mEncoderDoneCondition.notify_one();
+            return;
+        }
+        mEleStream->read(buf, bytesRead);
+        size_t bytesgcount = mEleStream->gcount();
+        if (bytesgcount != bytesRead) {
+            ALOGE("bytes to read %zu actual bytes read %zu \n", bytesRead, bytesgcount);
+            mSignalledError = true;
+            mEncoderDoneCondition.notify_one();
+            return;
+        }
+
+        uint32_t flag = 0;
+        if (mNumInputFrame == mParams.numFrames - 1 || bytesRead == 0) {
+            ALOGD("Sending EOS on input Last frame\n");
+            flag |= AMEDIACODEC_BUFFER_FLAG_END_OF_STREAM;
+        }
+
+        uint64_t presentationTimeUs;
+        if (!strncmp(mMime, "video/", 6)) {
+            presentationTimeUs = mNumInputFrame * (1000000 / mParams.frameRate);
+        } else {
+            presentationTimeUs =
+                    (uint64_t)mNumInputFrame * mParams.frameSize * 1000000 / mParams.sampleRate;
+        }
+
+        if (flag == AMEDIACODEC_BUFFER_FLAG_END_OF_STREAM) mSawInputEOS = true;
+        ALOGV("%s bytesRead : %zd presentationTimeUs : %" PRIu64 " mSawInputEOS : %s", __FUNCTION__,
+              bytesRead, presentationTimeUs, mSawInputEOS ? "TRUE" : "FALSE");
+
+        int status = AMediaCodec_queueInputBuffer(mCodec, bufIdx, 0 /* offset */, bytesRead,
+                                                  presentationTimeUs, flag);
+        if (AMEDIA_OK != status) {
+            mSignalledError = true;
+            mEncoderDoneCondition.notify_one();
+            return;
+        }
+        mNumInputFrame++;
+        mOffset += bytesRead;
+    }
+}
+
+void Encoder::onOutputAvailable(AMediaCodec *mediaCodec, int32_t bufIdx,
+                                AMediaCodecBufferInfo *bufferInfo) {
+    ALOGV("In %s", __func__);
+    if (mediaCodec == mCodec && mediaCodec) {
+        if (mSawOutputEOS || bufIdx < 0) return;
+        if (mSignalledError) {
+            CallBackHandle::mSawError = true;
+            mEncoderDoneCondition.notify_one();
+            return;
+        }
+
+        mStats->addFrameSize(bufferInfo->size);
+        AMediaCodec_releaseOutputBuffer(mCodec, bufIdx, false);
+        mSawOutputEOS = (0 != (bufferInfo->flags & AMEDIACODEC_BUFFER_FLAG_END_OF_STREAM));
+        mNumOutputFrame++;
+        ALOGV("%s index : %d  mSawOutputEOS : %s count : %u", __FUNCTION__, bufIdx,
+              mSawOutputEOS ? "TRUE" : "FALSE", mNumOutputFrame);
+        if (mSawOutputEOS) {
+            CallBackHandle::mIsDone = true;
+            mEncoderDoneCondition.notify_one();
+        }
+    }
+}
+
+void Encoder::onFormatChanged(AMediaCodec *mediaCodec, AMediaFormat *format) {
+    ALOGV("In %s", __func__);
+    if (mediaCodec == mCodec && mediaCodec) {
+        ALOGV("%s { %s }", __FUNCTION__, AMediaFormat_toString(format));
+        mFormat = format;
+    }
+}
+
+void Encoder::setupEncoder() {
+    if (!mFormat) mFormat = AMediaFormat_new();
+}
+
+void Encoder::deInitCodec() {
+    int64_t sTime = mStats->getCurTime();
+    if (mFormat) {
+        AMediaFormat_delete(mFormat);
+        mFormat = nullptr;
+    }
+    AMediaCodec_stop(mCodec);
+    AMediaCodec_delete(mCodec);
+    int64_t eTime = mStats->getCurTime();
+    int64_t timeTaken = mStats->getTimeDiff(sTime, eTime);
+    mStats->setDeInitTime(timeTaken);
+}
+
+void Encoder::resetEncoder() {
+    if (mStats) mStats->reset();
+    if (mEleStream) mEleStream = nullptr;
+    if (mMime) mMime = nullptr;
+    mInputBufferSize = 0;
+    memset(&mParams, 0, sizeof mParams);
+}
+
+void Encoder::dumpStatistics(string inputReference, int64_t durationUs) {
+    string operation = "encode";
+    mStats->dumpStatistics(operation, inputReference, durationUs);
+}
+
+int32_t Encoder::encode(string &codecName, ifstream &eleStream, size_t eleSize,
+                        bool asyncMode, encParameter encParams, char *mime) {
+    ALOGV("In %s", __func__);
+    mEleStream = &eleStream;
+    mInputBufferSize = eleSize;
+    mParams = encParams;
+    mOffset = 0;
+    mMime = mime;
+    AMediaFormat_setString(mFormat, AMEDIAFORMAT_KEY_MIME, mMime);
+
+    // Set Format
+    if (!strncmp(mMime, "video/", 6)) {
+        AMediaFormat_setInt32(mFormat, AMEDIAFORMAT_KEY_WIDTH, mParams.width);
+        AMediaFormat_setInt32(mFormat, AMEDIAFORMAT_KEY_HEIGHT, mParams.height);
+        AMediaFormat_setInt32(mFormat, AMEDIAFORMAT_KEY_FRAME_RATE, mParams.frameRate);
+        AMediaFormat_setInt32(mFormat, AMEDIAFORMAT_KEY_BIT_RATE, mParams.bitrate);
+        AMediaFormat_setInt32(mFormat, AMEDIAFORMAT_KEY_I_FRAME_INTERVAL, 1);
+        if (mParams.profile && mParams.level) {
+            AMediaFormat_setInt32(mFormat, AMEDIAFORMAT_KEY_PROFILE, mParams.profile);
+            AMediaFormat_setInt32(mFormat, AMEDIAFORMAT_KEY_LEVEL, mParams.level);
+        }
+    } else {
+        AMediaFormat_setInt32(mFormat, AMEDIAFORMAT_KEY_SAMPLE_RATE, mParams.sampleRate);
+        AMediaFormat_setInt32(mFormat, AMEDIAFORMAT_KEY_CHANNEL_COUNT, mParams.numChannels);
+        AMediaFormat_setInt32(mFormat, AMEDIAFORMAT_KEY_BIT_RATE, mParams.bitrate);
+    }
+    const char *s = AMediaFormat_toString(mFormat);
+    ALOGV("Input format: %s\n", s);
+
+    int64_t sTime = mStats->getCurTime();
+    mCodec = createMediaCodec(mFormat, mMime, codecName, true /*isEncoder*/);
+    if (!mCodec) return AMEDIA_ERROR_INVALID_OBJECT;
+    int64_t eTime = mStats->getCurTime();
+    int64_t timeTaken = mStats->getTimeDiff(sTime, eTime);
+
+    if (!strncmp(mMime, "video/", 6)) {
+        mParams.frameSize = mParams.width * mParams.height * 3 / 2;
+    } else {
+        mParams.frameSize = 4096;
+        // Get mInputMaxBufSize
+        AMediaFormat *inputFormat = AMediaCodec_getInputFormat(mCodec);
+        AMediaFormat_getInt32(inputFormat, AMEDIAFORMAT_KEY_MAX_INPUT_SIZE, &mParams.maxFrameSize);
+        if (mParams.maxFrameSize < 0) {
+            ALOGE("Invalid mParams.maxFrameSize %d\n", mParams.maxFrameSize);
+            return AMEDIA_ERROR_INVALID_PARAMETER;
+        }
+        if (mParams.frameSize > mParams.maxFrameSize) {
+            mParams.frameSize = mParams.maxFrameSize;
+        }
+    }
+    mParams.numFrames = (mInputBufferSize + mParams.frameSize - 1) / mParams.frameSize;
+
+    sTime = mStats->getCurTime();
+    if (asyncMode) {
+        AMediaCodecOnAsyncNotifyCallback aCB = {OnInputAvailableCB, OnOutputAvailableCB,
+                                                OnFormatChangedCB, OnErrorCB};
+        AMediaCodec_setAsyncNotifyCallback(mCodec, aCB, this);
+        mIOThread = thread(&CallBackHandle::ioThread, this);
+    }
+    AMediaCodec_start(mCodec);
+    eTime = mStats->getCurTime();
+    timeTaken += mStats->getTimeDiff(sTime, eTime);
+    mStats->setInitTime(timeTaken);
+
+    mStats->setStartTime();
+    if (!asyncMode) {
+        while (!mSawOutputEOS && !mSignalledError) {
+            // Queue input data
+            if (!mSawInputEOS) {
+                ssize_t inIdx = AMediaCodec_dequeueInputBuffer(mCodec, kQueueDequeueTimeoutUs);
+                if (inIdx < 0 && inIdx != AMEDIACODEC_INFO_TRY_AGAIN_LATER) {
+                    ALOGE("AMediaCodec_dequeueInputBuffer returned invalid index %zd\n", inIdx);
+                    return AMEDIA_ERROR_IO;
+                } else if (inIdx >= 0) {
+                    mStats->addInputTime();
+                    onInputAvailable(mCodec, inIdx);
+                }
+            }
+
+            // Dequeue output data
+            AMediaCodecBufferInfo info;
+            ssize_t outIdx = AMediaCodec_dequeueOutputBuffer(mCodec, &info, kQueueDequeueTimeoutUs);
+            if (outIdx == AMEDIACODEC_INFO_OUTPUT_FORMAT_CHANGED) {
+                mFormat = AMediaCodec_getOutputFormat(mCodec);
+                const char *s = AMediaFormat_toString(mFormat);
+                ALOGI("Output format: %s\n", s);
+            } else if (outIdx >= 0) {
+                mStats->addOutputTime();
+                onOutputAvailable(mCodec, outIdx, &info);
+            } else if (!(outIdx == AMEDIACODEC_INFO_TRY_AGAIN_LATER ||
+                         outIdx == AMEDIACODEC_INFO_OUTPUT_BUFFERS_CHANGED)) {
+                ALOGE("AMediaCodec_dequeueOutputBuffer returned invalid index %zd\n", outIdx);
+                return AMEDIA_ERROR_IO;
+            }
+        }
+    } else {
+        unique_lock<mutex> lock(mMutex);
+        mEncoderDoneCondition.wait(lock, [this]() { return (mSawOutputEOS || mSignalledError); });
+    }
+
+    if (codecName.empty()) {
+        char *encName;
+        AMediaCodec_getName(mCodec, &encName);
+        codecName.assign(encName);
+        AMediaCodec_releaseName(mCodec, encName);
+    }
+    return AMEDIA_OK;
+}
diff --git a/media/tests/benchmark/src/native/encoder/Encoder.h b/media/tests/benchmark/src/native/encoder/Encoder.h
new file mode 100644
index 0000000..75d9941
--- /dev/null
+++ b/media/tests/benchmark/src/native/encoder/Encoder.h
@@ -0,0 +1,97 @@
+/*
+ * 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 __ENCODER_H__
+#define __ENCODER_H__
+
+#include <chrono>
+#include <condition_variable>
+#include <mutex>
+#include <queue>
+#include <thread>
+
+#include "BenchmarkCommon.h"
+#include "Stats.h"
+
+struct encParameter {
+    int32_t bitrate = -1;
+    int32_t numFrames = -1;
+    int32_t frameSize = -1;
+    int32_t sampleRate = 0;
+    int32_t numChannels = 0;
+    int32_t maxFrameSize = -1;
+    int32_t width = 0;
+    int32_t height = 0;
+    int32_t frameRate = -1;
+    int32_t profile = 0;
+    int32_t level = 0;
+};
+
+class Encoder : public CallBackHandle {
+  public:
+    Encoder()
+        : mCodec(nullptr),
+          mFormat(nullptr),
+          mNumInputFrame(0),
+          mNumOutputFrame(0),
+          mSawInputEOS(false),
+          mSawOutputEOS(false),
+          mSignalledError(false) {}
+
+    virtual ~Encoder() {}
+
+    // Encoder related utilities
+    void setupEncoder();
+
+    void deInitCodec();
+
+    void resetEncoder();
+
+    // Async callback APIs
+    void onInputAvailable(AMediaCodec *codec, int32_t index) override;
+
+    void onFormatChanged(AMediaCodec *codec, AMediaFormat *format) override;
+
+    void onOutputAvailable(AMediaCodec *codec, int32_t index,
+                           AMediaCodecBufferInfo *bufferInfo) override;
+
+    // Process the frames and give encoded output
+    int32_t encode(std::string &codecName, std::ifstream &eleStream, size_t eleSize, bool asyncMode,
+                   encParameter encParams, char *mime);
+
+    void dumpStatistics(string inputReference, int64_t durationUs);
+
+  private:
+    AMediaCodec *mCodec;
+    AMediaFormat *mFormat;
+
+    int32_t mNumInputFrame;
+    int32_t mNumOutputFrame;
+    bool mSawInputEOS;
+    bool mSawOutputEOS;
+    bool mSignalledError;
+
+    char *mMime;
+    int32_t mOffset;
+    std::ifstream *mEleStream;
+    size_t mInputBufferSize;
+    encParameter mParams;
+
+    // Asynchronous locks
+    std::mutex mMutex;
+    std::condition_variable mEncoderDoneCondition;
+};
+#endif  // __ENCODER_H__
diff --git a/media/libstagefright/include/media/stagefright/NdkUtils.h b/media/tests/benchmark/src/native/extractor/Android.bp
similarity index 62%
copy from media/libstagefright/include/media/stagefright/NdkUtils.h
copy to media/tests/benchmark/src/native/extractor/Android.bp
index a68884a..dfd0d49 100644
--- a/media/libstagefright/include/media/stagefright/NdkUtils.h
+++ b/media/tests/benchmark/src/native/extractor/Android.bp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2018 The Android Open Source Project
+ * 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.
@@ -14,18 +14,16 @@
  * limitations under the License.
  */
 
-#ifndef NDK_UTILS_H_
+cc_library_static {
+    name: "libmediabenchmark_extractor",
+    defaults: [
+        "libmediabenchmark_common-defaults",
+        "libmediabenchmark_soft_sanitize_all-defaults",
+    ],
 
-#define NDK_UTILS_H_
+    srcs: ["Extractor.cpp"],
 
-#include <media/stagefright/MetaData.h>
-#include <media/NdkWrapper.h>
+    export_include_dirs: ["."],
 
-namespace android {
-
-sp<MetaData> convertMediaFormatWrapperToMetaData(
-        const sp<AMediaFormatWrapper> &fmt);
-
-}  // namespace android
-
-#endif  // NDK_UTILS_H_
+    ldflags: ["-Wl,-Bsymbolic"]
+}
diff --git a/media/tests/benchmark/src/native/extractor/Extractor.cpp b/media/tests/benchmark/src/native/extractor/Extractor.cpp
new file mode 100644
index 0000000..b4cad0b
--- /dev/null
+++ b/media/tests/benchmark/src/native/extractor/Extractor.cpp
@@ -0,0 +1,135 @@
+/*
+ * 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 "extractor"
+
+#include <iostream>
+
+#include "Extractor.h"
+
+int32_t Extractor::initExtractor(int32_t fd, size_t fileSize) {
+    mStats = new Stats();
+
+    mFrameBuf = (uint8_t *)calloc(kMaxBufferSize, sizeof(uint8_t));
+    if (!mFrameBuf) return -1;
+
+    int64_t sTime = mStats->getCurTime();
+
+    mExtractor = AMediaExtractor_new();
+    if (!mExtractor) return AMEDIACODEC_ERROR_INSUFFICIENT_RESOURCE;
+    media_status_t status = AMediaExtractor_setDataSourceFd(mExtractor, fd, 0, fileSize);
+    if (status != AMEDIA_OK) return status;
+
+    int64_t eTime = mStats->getCurTime();
+    int64_t timeTaken = mStats->getTimeDiff(sTime, eTime);
+    mStats->setInitTime(timeTaken);
+
+    return AMediaExtractor_getTrackCount(mExtractor);
+}
+
+void *Extractor::getCSDSample(AMediaCodecBufferInfo &frameInfo, int32_t csdIndex) {
+    char csdName[kMaxCSDStrlen];
+    void *csdBuffer = nullptr;
+    frameInfo.presentationTimeUs = 0;
+    frameInfo.flags = AMEDIACODEC_BUFFER_FLAG_CODEC_CONFIG;
+    snprintf(csdName, sizeof(csdName), "csd-%d", csdIndex);
+
+    size_t size;
+    bool csdFound = AMediaFormat_getBuffer(mFormat, csdName, &csdBuffer, &size);
+    if (!csdFound) return nullptr;
+    frameInfo.size = (int32_t)size;
+    mStats->addFrameSize(frameInfo.size);
+
+    return csdBuffer;
+}
+
+int32_t Extractor::getFrameSample(AMediaCodecBufferInfo &frameInfo) {
+    int32_t size = AMediaExtractor_readSampleData(mExtractor, mFrameBuf, kMaxBufferSize);
+    if (size < 0) return -1;
+
+    frameInfo.flags = AMediaExtractor_getSampleFlags(mExtractor);
+    frameInfo.size = size;
+    mStats->addFrameSize(frameInfo.size);
+    frameInfo.presentationTimeUs = AMediaExtractor_getSampleTime(mExtractor);
+    AMediaExtractor_advance(mExtractor);
+
+    return 0;
+}
+
+int32_t Extractor::setupTrackFormat(int32_t trackId) {
+    AMediaExtractor_selectTrack(mExtractor, trackId);
+    mFormat = AMediaExtractor_getTrackFormat(mExtractor, trackId);
+    if (!mFormat) return AMEDIA_ERROR_INVALID_OBJECT;
+
+    bool durationFound = AMediaFormat_getInt64(mFormat, AMEDIAFORMAT_KEY_DURATION, &mDurationUs);
+    if (!durationFound) return AMEDIA_ERROR_INVALID_OBJECT;
+
+    return AMEDIA_OK;
+}
+
+int32_t Extractor::extract(int32_t trackId) {
+    int32_t status = setupTrackFormat(trackId);
+    if (status != AMEDIA_OK) return status;
+
+    int32_t idx = 0;
+    AMediaCodecBufferInfo frameInfo;
+    while (1) {
+        memset(&frameInfo, 0, sizeof(AMediaCodecBufferInfo));
+        void *csdBuffer = getCSDSample(frameInfo, idx);
+        if (!csdBuffer || !frameInfo.size) break;
+        idx++;
+    }
+
+    mStats->setStartTime();
+    while (1) {
+        int32_t status = getFrameSample(frameInfo);
+        if (status || !frameInfo.size) break;
+        mStats->addOutputTime();
+    }
+
+    if (mFormat) {
+        AMediaFormat_delete(mFormat);
+        mFormat = nullptr;
+    }
+
+    AMediaExtractor_unselectTrack(mExtractor, trackId);
+
+    return AMEDIA_OK;
+}
+
+void Extractor::dumpStatistics(string inputReference) {
+    string operation = "extract";
+    mStats->dumpStatistics(operation, inputReference, mDurationUs);
+}
+
+void Extractor::deInitExtractor() {
+    if (mFrameBuf) {
+        free(mFrameBuf);
+        mFrameBuf = nullptr;
+    }
+
+    int64_t sTime = mStats->getCurTime();
+    if (mExtractor) {
+        // TODO: (b/140128505) Multiple calls result in DoS.
+        // Uncomment call to AMediaExtractor_delete() once this is resolved
+        // AMediaExtractor_delete(mExtractor);
+        mExtractor = nullptr;
+    }
+    int64_t eTime = mStats->getCurTime();
+    int64_t deInitTime = mStats->getTimeDiff(sTime, eTime);
+    mStats->setDeInitTime(deInitTime);
+}
diff --git a/media/tests/benchmark/src/native/extractor/Extractor.h b/media/tests/benchmark/src/native/extractor/Extractor.h
new file mode 100644
index 0000000..4c39a72
--- /dev/null
+++ b/media/tests/benchmark/src/native/extractor/Extractor.h
@@ -0,0 +1,66 @@
+/*
+ * 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_H__
+#define __EXTRACTOR_H__
+
+#include <media/NdkMediaExtractor.h>
+
+#include "BenchmarkCommon.h"
+#include "Stats.h"
+
+class Extractor {
+  public:
+    Extractor()
+        : mFormat(nullptr),
+          mExtractor(nullptr),
+          mStats(nullptr),
+          mFrameBuf{nullptr},
+          mDurationUs{0} {}
+
+    ~Extractor() {
+        if (mStats) delete mStats;
+    }
+
+    int32_t initExtractor(int32_t fd, size_t fileSize);
+
+    int32_t setupTrackFormat(int32_t trackId);
+
+    void *getCSDSample(AMediaCodecBufferInfo &frameInfo, int32_t csdIndex);
+
+    int32_t getFrameSample(AMediaCodecBufferInfo &frameInfo);
+
+    int32_t extract(int32_t trackId);
+
+    void dumpStatistics(std::string inputReference);
+
+    void deInitExtractor();
+
+    AMediaFormat *getFormat() { return mFormat; }
+
+    uint8_t *getFrameBuf() { return mFrameBuf; }
+
+    int64_t getClipDuration() { return mDurationUs; }
+
+  private:
+    AMediaFormat *mFormat;
+    AMediaExtractor *mExtractor;
+    Stats *mStats;
+    uint8_t *mFrameBuf;
+    int64_t mDurationUs;
+};
+
+#endif  // __EXTRACTOR_H__
\ No newline at end of file
diff --git a/media/tests/benchmark/src/native/muxer/Android.bp b/media/tests/benchmark/src/native/muxer/Android.bp
new file mode 100644
index 0000000..f669d4a
--- /dev/null
+++ b/media/tests/benchmark/src/native/muxer/Android.bp
@@ -0,0 +1,31 @@
+/*
+ * 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_library_static {
+    name: "libmediabenchmark_muxer",
+    defaults: [
+        "libmediabenchmark_common-defaults",
+        "libmediabenchmark_soft_sanitize_all-defaults",
+    ],
+
+    srcs: ["Muxer.cpp"],
+
+    static_libs: ["libmediabenchmark_extractor"],
+
+    export_include_dirs: ["."],
+
+    ldflags: ["-Wl,-Bsymbolic"]
+}
diff --git a/media/tests/benchmark/src/native/muxer/Muxer.cpp b/media/tests/benchmark/src/native/muxer/Muxer.cpp
new file mode 100644
index 0000000..b297a66
--- /dev/null
+++ b/media/tests/benchmark/src/native/muxer/Muxer.cpp
@@ -0,0 +1,90 @@
+/*
+ * 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 "muxer"
+
+#include <fstream>
+#include <iostream>
+
+#include "Muxer.h"
+
+int32_t Muxer::initMuxer(int32_t fd, MUXER_OUTPUT_T outputFormat) {
+    if (!mFormat) mFormat = mExtractor->getFormat();
+    if (!mStats) mStats = new Stats();
+
+    int64_t sTime = mStats->getCurTime();
+    mMuxer = AMediaMuxer_new(fd, (OutputFormat)outputFormat);
+    if (!mMuxer) {
+        cout << "[   WARN   ] Test Skipped. Unable to create muxer \n";
+        return AMEDIA_ERROR_INVALID_OBJECT;
+    }
+    /*
+     * AMediaMuxer_addTrack returns the index of the new track or a negative value
+     * in case of failure, which can be interpreted as a media_status_t.
+     */
+    ssize_t index = AMediaMuxer_addTrack(mMuxer, mFormat);
+    if (index < 0) {
+        cout << "[   WARN   ] Test Skipped. Format not supported \n";
+        return index;
+    }
+    AMediaMuxer_start(mMuxer);
+    int64_t eTime = mStats->getCurTime();
+    int64_t timeTaken = mStats->getTimeDiff(sTime, eTime);
+    mStats->setInitTime(timeTaken);
+    return AMEDIA_OK;
+}
+
+void Muxer::deInitMuxer() {
+    int64_t sTime = mStats->getCurTime();
+    if (mFormat) {
+        AMediaFormat_delete(mFormat);
+        mFormat = nullptr;
+    }
+    if (!mMuxer) return;
+    AMediaMuxer_stop(mMuxer);
+    AMediaMuxer_delete(mMuxer);
+    int64_t eTime = mStats->getCurTime();
+    int64_t timeTaken = mStats->getTimeDiff(sTime, eTime);
+    mStats->setDeInitTime(timeTaken);
+}
+
+void Muxer::resetMuxer() {
+    if (mStats) mStats->reset();
+}
+
+void Muxer::dumpStatistics(string inputReference) {
+    string operation = "mux";
+    mStats->dumpStatistics(operation, inputReference, mExtractor->getClipDuration());
+}
+
+int32_t Muxer::mux(uint8_t *inputBuffer, vector<AMediaCodecBufferInfo> &frameInfos) {
+    // Mux frame data
+    size_t frameIdx = 0;
+    mStats->setStartTime();
+    while (frameIdx < frameInfos.size()) {
+        AMediaCodecBufferInfo info = frameInfos.at(frameIdx);
+        media_status_t status = AMediaMuxer_writeSampleData(mMuxer, 0, inputBuffer, &info);
+        if (status != 0) {
+            ALOGE("Error in AMediaMuxer_writeSampleData");
+            return status;
+        }
+        mStats->addOutputTime();
+        mStats->addFrameSize(info.size);
+        frameIdx++;
+    }
+    return AMEDIA_OK;
+}
diff --git a/media/tests/benchmark/src/native/muxer/Muxer.h b/media/tests/benchmark/src/native/muxer/Muxer.h
new file mode 100644
index 0000000..eee3146
--- /dev/null
+++ b/media/tests/benchmark/src/native/muxer/Muxer.h
@@ -0,0 +1,63 @@
+/*
+ * 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 __MUXER_H__
+#define __MUXER_H__
+
+#include <media/NdkMediaMuxer.h>
+
+#include "BenchmarkCommon.h"
+#include "Stats.h"
+#include "Extractor.h"
+
+typedef enum {
+    MUXER_OUTPUT_FORMAT_MPEG_4 = 0,
+    MUXER_OUTPUT_FORMAT_WEBM = 1,
+    MUXER_OUTPUT_FORMAT_3GPP = 2,
+    MUXER_OUTPUT_FORMAT_OGG = 4,
+    MUXER_OUTPUT_FORMAT_INVALID = 5,
+} MUXER_OUTPUT_T;
+
+class Muxer {
+  public:
+    Muxer() : mFormat(nullptr), mMuxer(nullptr), mStats(nullptr) { mExtractor = new Extractor(); }
+
+    virtual ~Muxer() {
+        if (mStats) delete mStats;
+        if (mExtractor) delete mExtractor;
+    }
+
+    Stats *getStats() { return mStats; }
+    Extractor *getExtractor() { return mExtractor; }
+
+    /* Muxer related utilities */
+    int32_t initMuxer(int32_t fd, MUXER_OUTPUT_T outputFormat);
+    void deInitMuxer();
+    void resetMuxer();
+
+    /* Process the frames and give Muxed output */
+    int32_t mux(uint8_t *inputBuffer, vector<AMediaCodecBufferInfo> &frameSizes);
+
+    void dumpStatistics(string inputReference);
+
+  private:
+    AMediaFormat *mFormat;
+    AMediaMuxer *mMuxer;
+    Extractor *mExtractor;
+    Stats *mStats;
+};
+
+#endif  // __MUXER_H__
diff --git a/media/tests/benchmark/tests/Android.bp b/media/tests/benchmark/tests/Android.bp
new file mode 100644
index 0000000..24fd68c
--- /dev/null
+++ b/media/tests/benchmark/tests/Android.bp
@@ -0,0 +1,77 @@
+/*
+ * 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: "extractorTest",
+    gtest: true,
+    defaults: [
+        "libmediabenchmark_common-defaults",
+        "libmediabenchmark_soft_sanitize_all-defaults",
+    ],
+
+    srcs: ["ExtractorTest.cpp"],
+
+    static_libs: ["libmediabenchmark_extractor"]
+}
+
+cc_test {
+    name: "decoderTest",
+    gtest: true,
+    defaults: [
+        "libmediabenchmark_common-defaults",
+        "libmediabenchmark_soft_sanitize_all-defaults",
+    ],
+
+    srcs: ["DecoderTest.cpp"],
+
+    static_libs: [
+        "libmediabenchmark_extractor",
+        "libmediabenchmark_decoder",
+    ],
+}
+
+cc_test {
+    name: "muxerTest",
+    gtest: true,
+    defaults: [
+        "libmediabenchmark_common-defaults",
+        "libmediabenchmark_soft_sanitize_all-defaults",
+    ],
+
+    srcs: ["MuxerTest.cpp"],
+
+    static_libs: [
+        "libmediabenchmark_extractor",
+        "libmediabenchmark_muxer",
+    ],
+}
+
+cc_test {
+    name: "encoderTest",
+    gtest: true,
+    defaults: [
+        "libmediabenchmark_common-defaults",
+        "libmediabenchmark_soft_sanitize_all-defaults",
+    ],
+
+    srcs: ["EncoderTest.cpp"],
+
+    static_libs: [
+        "libmediabenchmark_extractor",
+        "libmediabenchmark_decoder",
+        "libmediabenchmark_encoder",
+    ],
+}
diff --git a/media/tests/benchmark/tests/BenchmarkTestEnvironment.h b/media/tests/benchmark/tests/BenchmarkTestEnvironment.h
new file mode 100644
index 0000000..ae2eee1
--- /dev/null
+++ b/media/tests/benchmark/tests/BenchmarkTestEnvironment.h
@@ -0,0 +1,73 @@
+/*
+ * 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 __BENCHMARK_TEST_ENVIRONMENT_H__
+#define __BENCHMARK_TEST_ENVIRONMENT_H__
+
+#include <gtest/gtest.h>
+
+#include <getopt.h>
+
+using namespace std;
+
+class BenchmarkTestEnvironment : public ::testing::Environment {
+  public:
+    BenchmarkTestEnvironment() : res("/sdcard/media/") {}
+
+    // Parses the command line argument
+    int initFromOptions(int argc, char **argv);
+
+    void setRes(const char *_res) { res = _res; }
+
+    const string getRes() const { return res; }
+
+  private:
+    string res;
+};
+
+int BenchmarkTestEnvironment::initFromOptions(int argc, char **argv) {
+    static struct option options[] = {{"path", 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  // __BENCHMARK_TEST_ENVIRONMENT_H__
diff --git a/media/tests/benchmark/tests/DecoderTest.cpp b/media/tests/benchmark/tests/DecoderTest.cpp
new file mode 100644
index 0000000..242178f
--- /dev/null
+++ b/media/tests/benchmark/tests/DecoderTest.cpp
@@ -0,0 +1,202 @@
+/*
+ * 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 "decoderTest"
+
+#include <fstream>
+#include <iostream>
+#include <limits>
+
+#include "Decoder.h"
+#include "BenchmarkTestEnvironment.h"
+
+static BenchmarkTestEnvironment *gEnv = nullptr;
+
+class DecoderTest : public ::testing::TestWithParam<tuple<string, string, bool>> {};
+
+TEST_P(DecoderTest, Decode) {
+    ALOGV("Decode the samples given by extractor");
+    tuple<string /* InputFile */, string /* CodecName */, bool /* asyncMode */> params = GetParam();
+
+    string inputFile = gEnv->getRes() + get<0>(params);
+    FILE *inputFp = fopen(inputFile.c_str(), "rb");
+    if (!inputFp) {
+        cout << "[   WARN   ] Test Skipped. Unable to open input file for reading \n";
+        return;
+    }
+
+    Decoder *decoder = new Decoder();
+    Extractor *extractor = decoder->getExtractor();
+    if (!extractor) {
+        cout << "[   WARN   ] Test Skipped. Extractor creation failed \n";
+        return;
+    }
+
+    // Read file properties
+    fseek(inputFp, 0, SEEK_END);
+    size_t fileSize = ftell(inputFp);
+    fseek(inputFp, 0, SEEK_SET);
+    int32_t fd = fileno(inputFp);
+
+    int32_t trackCount = extractor->initExtractor(fd, fileSize);
+    if (trackCount <= 0) {
+        cout << "[   WARN   ] Test Skipped. initExtractor failed\n";
+        return;
+    }
+    for (int curTrack = 0; curTrack < trackCount; curTrack++) {
+        int32_t status = extractor->setupTrackFormat(curTrack);
+        if (status != 0) {
+            cout << "[   WARN   ] Test Skipped. Track Format invalid \n";
+            return;
+        }
+
+        uint8_t *inputBuffer = (uint8_t *)malloc(kMaxBufferSize);
+        if (!inputBuffer) {
+            cout << "[   WARN   ] Test Skipped. Insufficient memory \n";
+            return;
+        }
+        vector<AMediaCodecBufferInfo> frameInfo;
+        AMediaCodecBufferInfo info;
+        uint32_t inputBufferOffset = 0;
+
+        // Get frame data
+        while (1) {
+            status = extractor->getFrameSample(info);
+            if (status || !info.size) break;
+            // copy the meta data and buffer to be passed to decoder
+            if (inputBufferOffset + info.size > kMaxBufferSize) {
+                cout << "[   WARN   ] Test Skipped. Memory allocated not sufficient\n";
+                free(inputBuffer);
+                return;
+            }
+            memcpy(inputBuffer + inputBufferOffset, extractor->getFrameBuf(), info.size);
+            frameInfo.push_back(info);
+            inputBufferOffset += info.size;
+        }
+
+        string codecName = get<1>(params);
+        bool asyncMode = get<2>(params);
+        decoder->setupDecoder();
+        status = decoder->decode(inputBuffer, frameInfo, codecName, asyncMode);
+        if (status != AMEDIA_OK) {
+            cout << "[   WARN   ] Test Skipped. Decode returned error \n";
+            free(inputBuffer);
+            return;
+        }
+        decoder->deInitCodec();
+        cout << "codec : " << codecName << endl;
+        string inputReference = get<0>(params);
+        decoder->dumpStatistics(inputReference);
+        free(inputBuffer);
+        decoder->resetDecoder();
+    }
+    fclose(inputFp);
+    extractor->deInitExtractor();
+    delete decoder;
+}
+
+// TODO: (b/140549596)
+// Add wav files
+INSTANTIATE_TEST_SUITE_P(
+        AudioDecoderSyncTest, DecoderTest,
+        ::testing::Values(make_tuple("bbb_44100hz_2ch_128kbps_aac_30sec.mp4", "", false),
+                          make_tuple("bbb_44100hz_2ch_128kbps_mp3_30sec.mp3", "", false),
+                          make_tuple("bbb_8000hz_1ch_8kbps_amrnb_30sec.3gp", "", false),
+                          make_tuple("bbb_16000hz_1ch_9kbps_amrwb_30sec.3gp", "", false),
+                          make_tuple("bbb_44100hz_2ch_80kbps_vorbis_30sec.mp4", "", false),
+                          make_tuple("bbb_44100hz_2ch_600kbps_flac_30sec.mp4", "", false),
+                          make_tuple("bbb_48000hz_2ch_100kbps_opus_30sec.webm", "", false)));
+
+INSTANTIATE_TEST_SUITE_P(
+        AudioDecoderAsyncTest, DecoderTest,
+        ::testing::Values(make_tuple("bbb_44100hz_2ch_128kbps_aac_30sec.mp4", "", true),
+                          make_tuple("bbb_44100hz_2ch_128kbps_mp3_30sec.mp3", "", true),
+                          make_tuple("bbb_8000hz_1ch_8kbps_amrnb_30sec.3gp", "", true),
+                          make_tuple("bbb_16000hz_1ch_9kbps_amrwb_30sec.3gp", "", true),
+                          make_tuple("bbb_44100hz_2ch_80kbps_vorbis_30sec.mp4", "", true),
+                          make_tuple("bbb_44100hz_2ch_600kbps_flac_30sec.mp4", "", true),
+                          make_tuple("bbb_48000hz_2ch_100kbps_opus_30sec.webm", "", true)));
+
+INSTANTIATE_TEST_SUITE_P(VideDecoderSyncTest, DecoderTest,
+                         ::testing::Values(
+                                 // Hardware codecs
+                                 make_tuple("crowd_1920x1080_25fps_4000kbps_vp9.webm", "", false),
+                                 make_tuple("crowd_1920x1080_25fps_4000kbps_vp8.webm", "", false),
+                                 make_tuple("crowd_1920x1080_25fps_4000kbps_av1.webm", "", false),
+                                 make_tuple("crowd_1920x1080_25fps_7300kbps_mpeg2.mp4", "", false),
+                                 make_tuple("crowd_1920x1080_25fps_6000kbps_mpeg4.mp4", "", false),
+                                 make_tuple("crowd_352x288_25fps_6000kbps_h263.3gp", "", false),
+                                 make_tuple("crowd_1920x1080_25fps_6700kbps_h264.ts", "", false),
+                                 make_tuple("crowd_1920x1080_25fps_4000kbps_h265.mkv", "", false),
+                                 // Software codecs
+                                 make_tuple("crowd_1920x1080_25fps_4000kbps_vp9.webm",
+                                            "c2.android.vp9.decoder", false),
+                                 make_tuple("crowd_1920x1080_25fps_4000kbps_vp8.webm",
+                                            "c2.android.vp8.decoder", false),
+                                 make_tuple("crowd_1920x1080_25fps_4000kbps_av1.webm",
+                                            "c2.android.av1.decoder", false),
+                                 make_tuple("crowd_1920x1080_25fps_7300kbps_mpeg2.mp4",
+                                            "c2.android.mpeg2.decoder", false),
+                                 make_tuple("crowd_1920x1080_25fps_6000kbps_mpeg4.mp4",
+                                            "c2.android.mpeg4.decoder", false),
+                                 make_tuple("crowd_352x288_25fps_6000kbps_h263.3gp",
+                                            "c2.android.h263.decoder", false),
+                                 make_tuple("crowd_1920x1080_25fps_6700kbps_h264.ts",
+                                            "c2.android.avc.decoder", false),
+                                 make_tuple("crowd_1920x1080_25fps_4000kbps_h265.mkv",
+                                            "c2.android.hevc.decoder", false)));
+
+INSTANTIATE_TEST_SUITE_P(VideoDecoderAsyncTest, DecoderTest,
+                         ::testing::Values(
+                                 // Hardware codecs
+                                 make_tuple("crowd_1920x1080_25fps_4000kbps_vp9.webm", "", true),
+                                 make_tuple("crowd_1920x1080_25fps_4000kbps_vp8.webm", "", true),
+                                 make_tuple("crowd_1920x1080_25fps_4000kbps_av1.webm", "", true),
+                                 make_tuple("crowd_1920x1080_25fps_7300kbps_mpeg2.mp4", "", true),
+                                 make_tuple("crowd_1920x1080_25fps_6000kbps_mpeg4.mp4", "", true),
+                                 make_tuple("crowd_352x288_25fps_6000kbps_h263.3gp", "", true),
+                                 make_tuple("crowd_1920x1080_25fps_6700kbps_h264.ts", "", true),
+                                 make_tuple("crowd_1920x1080_25fps_4000kbps_h265.mkv", "", true),
+                                 // Software codecs
+                                 make_tuple("crowd_1920x1080_25fps_4000kbps_vp9.webm",
+                                            "c2.android.vp9.decoder", true),
+                                 make_tuple("crowd_1920x1080_25fps_4000kbps_vp8.webm",
+                                            "c2.android.vp8.decoder", true),
+                                 make_tuple("crowd_1920x1080_25fps_4000kbps_av1.webm",
+                                            "c2.android.av1.decoder", true),
+                                 make_tuple("crowd_1920x1080_25fps_7300kbps_mpeg2.mp4",
+                                            "c2.android.mpeg2.decoder", true),
+                                 make_tuple("crowd_1920x1080_25fps_6000kbps_mpeg4.mp4",
+                                            "c2.android.mpeg4.decoder", true),
+                                 make_tuple("crowd_352x288_25fps_6000kbps_h263.3gp",
+                                            "c2.android.h263.decoder", true),
+                                 make_tuple("crowd_1920x1080_25fps_6700kbps_h264.ts",
+                                            "c2.android.avc.decoder", true),
+                                 make_tuple("crowd_1920x1080_25fps_4000kbps_h265.mkv",
+                                            "c2.android.hevc.decoder", true)));
+
+int main(int argc, char **argv) {
+    gEnv = new BenchmarkTestEnvironment();
+    ::testing::AddGlobalTestEnvironment(gEnv);
+    ::testing::InitGoogleTest(&argc, argv);
+    int status = gEnv->initFromOptions(argc, argv);
+    if (status == 0) {
+        status = RUN_ALL_TESTS();
+        ALOGD("Decoder Test result = %d\n", status);
+    }
+    return status;
+}
\ No newline at end of file
diff --git a/media/tests/benchmark/tests/EncoderTest.cpp b/media/tests/benchmark/tests/EncoderTest.cpp
new file mode 100644
index 0000000..9f42c64
--- /dev/null
+++ b/media/tests/benchmark/tests/EncoderTest.cpp
@@ -0,0 +1,235 @@
+/*
+ * 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 "encoderTest"
+
+#include <fstream>
+
+#include "BenchmarkTestEnvironment.h"
+#include "Encoder.h"
+#include "Decoder.h"
+
+static BenchmarkTestEnvironment *gEnv = nullptr;
+
+class EncoderTest : public ::testing::TestWithParam<tuple<string, string, bool>> {};
+
+TEST_P(EncoderTest, Encode) {
+    ALOGD("Encode test for all codecs");
+    tuple<string /* InputFile */, string /* CodecName */, bool /* asyncMode */> params = GetParam();
+
+    string inputFile = gEnv->getRes() + get<0>(params);
+    FILE *inputFp = fopen(inputFile.c_str(), "rb");
+    if (!inputFp) {
+        cout << "[   WARN   ] Test Skipped. Unable to open input file for reading \n";
+        return;
+    }
+
+    Decoder *decoder = new Decoder();
+    Extractor *extractor = decoder->getExtractor();
+    if (!extractor) {
+        cout << "[   WARN   ] Test Skipped. Extractor creation failed \n";
+        return;
+    }
+    // Read file properties
+    fseek(inputFp, 0, SEEK_END);
+    size_t fileSize = ftell(inputFp);
+    fseek(inputFp, 0, SEEK_SET);
+    int32_t fd = fileno(inputFp);
+
+    int32_t trackCount = extractor->initExtractor(fd, fileSize);
+    if (trackCount <= 0) {
+        cout << "[   WARN   ] Test Skipped. initExtractor failed\n";
+        return;
+    }
+
+    Encoder *encoder = new Encoder();
+    for (int curTrack = 0; curTrack < trackCount; curTrack++) {
+        int32_t status = extractor->setupTrackFormat(curTrack);
+        if (status != 0) {
+            cout << "[   WARN   ] Test Skipped. Track Format invalid \n";
+            return;
+        }
+
+        uint8_t *inputBuffer = (uint8_t *)malloc(kMaxBufferSize);
+        if (!inputBuffer) {
+            cout << "[   WARN   ] Test Skipped. Insufficient memory \n";
+            return;
+        }
+        vector<AMediaCodecBufferInfo> frameInfo;
+        AMediaCodecBufferInfo info;
+        uint32_t inputBufferOffset = 0;
+
+        // Get frame data
+        while (1) {
+            status = extractor->getFrameSample(info);
+            if (status || !info.size) break;
+            // copy the meta data and buffer to be passed to decoder
+            if (inputBufferOffset + info.size > kMaxBufferSize) {
+                cout << "[   WARN   ] Test Skipped. Memory allocated not sufficient\n";
+                free(inputBuffer);
+                return;
+            }
+            memcpy(inputBuffer + inputBufferOffset, extractor->getFrameBuf(), info.size);
+            frameInfo.push_back(info);
+            inputBufferOffset += info.size;
+        }
+
+        string decName = "";
+        string outputFileName = "decode.out";
+        FILE *outFp = fopen(outputFileName.c_str(), "wb");
+        if (outFp == nullptr) {
+            ALOGE("Unable to open output file for writing");
+            return;
+        }
+        decoder->setupDecoder();
+        status = decoder->decode(inputBuffer, frameInfo, decName, false /*asyncMode */, outFp);
+        if (status != AMEDIA_OK) {
+            cout << "[   WARN   ] Test Skipped. Decode returned error \n";
+            return;
+        }
+
+        ifstream eleStream;
+        eleStream.open(outputFileName.c_str(), ifstream::binary | ifstream::ate);
+        ASSERT_EQ(eleStream.is_open(), true) << outputFileName.c_str() << " - file not found";
+        size_t eleSize = eleStream.tellg();
+        eleStream.seekg(0, ifstream::beg);
+
+        AMediaFormat *format = extractor->getFormat();
+        const char *mime = nullptr;
+        AMediaFormat_getString(format, AMEDIAFORMAT_KEY_MIME, &mime);
+        if (!mime) {
+            ALOGE("Error in AMediaFormat_getString");
+            return;
+        }
+        // Get encoder params
+        encParameter encParams;
+        if (!strncmp(mime, "video/", 6)) {
+            AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_WIDTH, &encParams.width);
+            AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_HEIGHT, &encParams.height);
+            AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_FRAME_RATE, &encParams.frameRate);
+            AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_BIT_RATE, &encParams.bitrate);
+            if (encParams.bitrate <= 0 || encParams.frameRate <= 0) {
+                encParams.frameRate = 25;
+                if (!strcmp(mime, "video/3gpp") || !strcmp(mime, "video/mp4v-es")) {
+                    encParams.bitrate = 600000 /* 600 Kbps */;
+                } else {
+                    encParams.bitrate = 8000000 /* 8 Mbps */;
+                }
+            }
+            AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_PROFILE, &encParams.profile);
+            AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_LEVEL, &encParams.level);
+        } else {
+            AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_SAMPLE_RATE, &encParams.sampleRate);
+            AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_CHANNEL_COUNT, &encParams.numChannels);
+            encParams.bitrate =
+                    encParams.sampleRate * encParams.numChannels * 16 /* bitsPerSample */;
+        }
+
+        encoder->setupEncoder();
+        string codecName = get<1>(params);
+        bool asyncMode = get<2>(params);
+        status = encoder->encode(codecName, eleStream, eleSize, asyncMode, encParams, (char *)mime);
+        ASSERT_EQ(status, 0);
+        encoder->deInitCodec();
+        cout << "codec : " << codecName << endl;
+        string inputReference = get<0>(params);
+        encoder->dumpStatistics(inputReference, extractor->getClipDuration());
+        eleStream.close();
+        if (outFp) fclose(outFp);
+
+        if (format) {
+            AMediaFormat_delete(format);
+            format = nullptr;
+        }
+        encoder->resetEncoder();
+        decoder->deInitCodec();
+        free(inputBuffer);
+        decoder->resetDecoder();
+    }
+    delete encoder;
+    fclose(inputFp);
+    extractor->deInitExtractor();
+    delete decoder;
+}
+
+INSTANTIATE_TEST_SUITE_P(
+        AudioEncoderSyncTest, EncoderTest,
+        ::testing::Values(make_tuple("bbb_44100hz_2ch_128kbps_aac_30sec.mp4", "", false),
+                          make_tuple("bbb_8000hz_1ch_8kbps_amrnb_30sec.3gp", "", false),
+                          make_tuple("bbb_16000hz_1ch_9kbps_amrwb_30sec.3gp", "", false),
+                          make_tuple("bbb_44100hz_2ch_600kbps_flac_30sec.mp4", "", false),
+                          make_tuple("bbb_48000hz_2ch_100kbps_opus_30sec.webm", "", false)));
+
+INSTANTIATE_TEST_SUITE_P(
+        AudioEncoderAsyncTest, EncoderTest,
+        ::testing::Values(make_tuple("bbb_44100hz_2ch_128kbps_aac_30sec.mp4", "", true),
+                          make_tuple("bbb_8000hz_1ch_8kbps_amrnb_30sec.3gp", "", true),
+                          make_tuple("bbb_16000hz_1ch_9kbps_amrwb_30sec.3gp", "", true),
+                          make_tuple("bbb_44100hz_2ch_600kbps_flac_30sec.mp4", "", true),
+                          make_tuple("bbb_48000hz_2ch_100kbps_opus_30sec.webm", "", true)));
+
+INSTANTIATE_TEST_SUITE_P(VideEncoderSyncTest, EncoderTest,
+                         ::testing::Values(
+                                 // Hardware codecs
+                                 make_tuple("crowd_1920x1080_25fps_4000kbps_vp8.webm", "", false),
+                                 make_tuple("crowd_1920x1080_25fps_6700kbps_h264.ts", "", false),
+                                 make_tuple("crowd_1920x1080_25fps_4000kbps_h265.mkv", "", false),
+                                 // Software codecs
+                                 make_tuple("crowd_1920x1080_25fps_4000kbps_vp9.webm",
+                                            "c2.android.vp9.encoder", false),
+                                 make_tuple("crowd_1920x1080_25fps_4000kbps_vp8.webm",
+                                            "c2.android.vp8.encoder", false),
+                                 make_tuple("crowd_176x144_25fps_6000kbps_mpeg4.mp4",
+                                            "c2.android.mpeg4.encoder", false),
+                                 make_tuple("crowd_176x144_25fps_6000kbps_h263.3gp",
+                                            "c2.android.h263.encoder", false),
+                                 make_tuple("crowd_1920x1080_25fps_6700kbps_h264.ts",
+                                            "c2.android.avc.encoder", false),
+                                 make_tuple("crowd_1920x1080_25fps_4000kbps_h265.mkv",
+                                            "c2.android.hevc.encoder", false)));
+
+INSTANTIATE_TEST_SUITE_P(VideoEncoderAsyncTest, EncoderTest,
+                         ::testing::Values(
+                                 // Hardware codecs
+                                 make_tuple("crowd_1920x1080_25fps_4000kbps_vp8.webm", "", true),
+                                 make_tuple("crowd_1920x1080_25fps_6700kbps_h264.ts", "", true),
+                                 make_tuple("crowd_1920x1080_25fps_4000kbps_h265.mkv", "", true),
+                                 // Software codecs
+                                 make_tuple("crowd_1920x1080_25fps_4000kbps_vp9.webm",
+                                            "c2.android.vp9.encoder", true),
+                                 make_tuple("crowd_1920x1080_25fps_4000kbps_vp8.webm",
+                                            "c2.android.vp8.encoder", true),
+                                 make_tuple("crowd_176x144_25fps_6000kbps_mpeg4.mp4",
+                                            "c2.android.mpeg4.encoder", true),
+                                 make_tuple("crowd_176x144_25fps_6000kbps_h263.3gp",
+                                            "c2.android.h263.encoder", true),
+                                 make_tuple("crowd_1920x1080_25fps_6700kbps_h264.ts",
+                                            "c2.android.avc.encoder", true),
+                                 make_tuple("crowd_1920x1080_25fps_4000kbps_h265.mkv",
+                                            "c2.android.hevc.encoder", true)));
+
+int main(int argc, char **argv) {
+    gEnv = new BenchmarkTestEnvironment();
+    ::testing::AddGlobalTestEnvironment(gEnv);
+    ::testing::InitGoogleTest(&argc, argv);
+    int status = gEnv->initFromOptions(argc, argv);
+    if (status == 0) {
+        status = RUN_ALL_TESTS();
+        ALOGD("Encoder Test result = %d\n", status);
+    }
+    return status;
+}
diff --git a/media/tests/benchmark/tests/ExtractorTest.cpp b/media/tests/benchmark/tests/ExtractorTest.cpp
new file mode 100644
index 0000000..dd0d711
--- /dev/null
+++ b/media/tests/benchmark/tests/ExtractorTest.cpp
@@ -0,0 +1,94 @@
+/*
+ * 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 "extractorTest"
+
+#include <gtest/gtest.h>
+
+#include "Extractor.h"
+#include "BenchmarkTestEnvironment.h"
+
+static BenchmarkTestEnvironment *gEnv = nullptr;
+
+class ExtractorTest : public ::testing::TestWithParam<pair<string, int32_t>> {};
+
+TEST_P(ExtractorTest, Extract) {
+    Extractor *extractObj = new Extractor();
+
+    string inputFile = gEnv->getRes() + GetParam().first;
+    FILE *inputFp = fopen(inputFile.c_str(), "rb");
+    if (!inputFp) {
+        cout << "[   WARN   ] Test Skipped. Unable to open input file for reading \n";
+        return;
+    }
+
+    // Read file properties
+    size_t fileSize = 0;
+    fseek(inputFp, 0, SEEK_END);
+    fileSize = ftell(inputFp);
+    fseek(inputFp, 0, SEEK_SET);
+    int32_t fd = fileno(inputFp);
+
+    int32_t trackCount = extractObj->initExtractor(fd, fileSize);
+    if (trackCount <= 0) {
+        cout << "[   WARN   ] Test Skipped. initExtractor failed\n";
+        return;
+    }
+
+    int32_t trackID = GetParam().second;
+    int32_t status = extractObj->extract(trackID);
+    if (status != AMEDIA_OK) {
+        cout << "[   WARN   ] Test Skipped. Extraction failed \n";
+        return;
+    }
+
+    extractObj->deInitExtractor();
+
+    extractObj->dumpStatistics(GetParam().first);
+
+    fclose(inputFp);
+    delete extractObj;
+}
+
+INSTANTIATE_TEST_SUITE_P(ExtractorTestAll, ExtractorTest,
+                         ::testing::Values(make_pair("crowd_1920x1080_25fps_4000kbps_vp9.webm", 0),
+                                           make_pair("crowd_1920x1080_25fps_6000kbps_h263.3gp", 0),
+                                           make_pair("crowd_1920x1080_25fps_6000kbps_mpeg4.mp4", 0),
+                                           make_pair("crowd_1920x1080_25fps_6700kbps_h264.ts", 0),
+                                           make_pair("crowd_1920x1080_25fps_7300kbps_mpeg2.mp4", 0),
+                                           make_pair("crowd_1920x1080_25fps_4000kbps_av1.webm", 0),
+                                           make_pair("crowd_1920x1080_25fps_4000kbps_h265.mkv", 0),
+                                           make_pair("crowd_1920x1080_25fps_4000kbps_vp8.webm", 0),
+                                           make_pair("bbb_44100hz_2ch_128kbps_aac_5mins.mp4", 0),
+                                           make_pair("bbb_44100hz_2ch_128kbps_mp3_5mins.mp3", 0),
+                                           make_pair("bbb_44100hz_2ch_600kbps_flac_5mins.flac", 0),
+                                           make_pair("bbb_8000hz_1ch_8kbps_amrnb_5mins.3gp", 0),
+                                           make_pair("bbb_16000hz_1ch_9kbps_amrwb_5mins.3gp", 0),
+                                           make_pair("bbb_44100hz_2ch_80kbps_vorbis_5mins.mp4", 0),
+                                           make_pair("bbb_48000hz_2ch_100kbps_opus_5mins.webm", 0)));
+
+int main(int argc, char **argv) {
+    gEnv = new BenchmarkTestEnvironment();
+    ::testing::AddGlobalTestEnvironment(gEnv);
+    ::testing::InitGoogleTest(&argc, argv);
+    int status = gEnv->initFromOptions(argc, argv);
+    if (status == 0) {
+        status = RUN_ALL_TESTS();
+        ALOGD(" Extractor Test result = %d\n", status);
+    }
+    return status;
+}
diff --git a/media/tests/benchmark/tests/MuxerTest.cpp b/media/tests/benchmark/tests/MuxerTest.cpp
new file mode 100644
index 0000000..e814f90
--- /dev/null
+++ b/media/tests/benchmark/tests/MuxerTest.cpp
@@ -0,0 +1,181 @@
+
+/*
+ * 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 "muxerTest"
+
+#include <fstream>
+#include <iostream>
+
+#include "Muxer.h"
+#include "BenchmarkTestEnvironment.h"
+
+#define OUTPUT_FILE_NAME "/data/local/tmp/mux.out"
+
+static BenchmarkTestEnvironment *gEnv = nullptr;
+
+class MuxerTest : public ::testing::TestWithParam<pair<string, string>> {};
+
+static MUXER_OUTPUT_T getMuxerOutFormat(string fmt) {
+    static const struct {
+        string name;
+        MUXER_OUTPUT_T value;
+    } kFormatMaps[] = {{"mp4", MUXER_OUTPUT_FORMAT_MPEG_4},
+                       {"webm", MUXER_OUTPUT_FORMAT_WEBM},
+                       {"3gpp", MUXER_OUTPUT_FORMAT_3GPP},
+                       {"ogg", MUXER_OUTPUT_FORMAT_OGG}};
+
+    MUXER_OUTPUT_T format = MUXER_OUTPUT_FORMAT_INVALID;
+    for (size_t i = 0; i < sizeof(kFormatMaps) / sizeof(kFormatMaps[0]); ++i) {
+        if (!fmt.compare(kFormatMaps[i].name)) {
+            format = kFormatMaps[i].value;
+            break;
+        }
+    }
+    return format;
+}
+
+TEST_P(MuxerTest, Mux) {
+    ALOGV("Mux the samples given by extractor");
+    string inputFile = gEnv->getRes() + GetParam().first;
+    FILE *inputFp = fopen(inputFile.c_str(), "rb");
+    if (!inputFp) {
+        cout << "[   WARN   ] Test Skipped. Unable to open input file for reading \n";
+        return;
+    }
+    string fmt = GetParam().second;
+    MUXER_OUTPUT_T outputFormat = getMuxerOutFormat(fmt);
+    if (outputFormat == MUXER_OUTPUT_FORMAT_INVALID) {
+        ALOGE("output format is MUXER_OUTPUT_FORMAT_INVALID");
+        return;
+    }
+
+    Muxer *muxerObj = new Muxer();
+    Extractor *extractor = muxerObj->getExtractor();
+    if (!extractor) {
+        cout << "[   WARN   ] Test Skipped. Extractor creation failed \n";
+        return;
+    }
+
+    // Read file properties
+    size_t fileSize = 0;
+    fseek(inputFp, 0, SEEK_END);
+    fileSize = ftell(inputFp);
+    fseek(inputFp, 0, SEEK_SET);
+    int32_t fd = fileno(inputFp);
+
+    int32_t trackCount = extractor->initExtractor(fd, fileSize);
+    if (trackCount <= 0) {
+        cout << "[   WARN   ] Test Skipped. initExtractor failed\n";
+        return;
+    }
+
+    for (int curTrack = 0; curTrack < trackCount; curTrack++) {
+        int32_t status = extractor->setupTrackFormat(curTrack);
+        if (status != 0) {
+            cout << "[   WARN   ] Test Skipped. Track Format invalid \n";
+            return;
+        }
+
+        uint8_t *inputBuffer = (uint8_t *)malloc(kMaxBufferSize);
+        if (!inputBuffer) {
+            std::cout << "[   WARN   ] Test Skipped. Insufficient memory \n";
+            return;
+        }
+        // AMediaCodecBufferInfo : <size of frame> <flags> <presentationTimeUs> <offset>
+        vector<AMediaCodecBufferInfo> frameInfos;
+        AMediaCodecBufferInfo info;
+        uint32_t inputBufferOffset = 0;
+
+        // Get Frame Data
+        while (1) {
+            status = extractor->getFrameSample(info);
+            if (status || !info.size) break;
+            // copy the meta data and buffer to be passed to muxer
+            if (inputBufferOffset + info.size > kMaxBufferSize) {
+                cout << "[   WARN   ] Test Skipped. Memory allocated not sufficient\n";
+                free(inputBuffer);
+                return;
+            }
+            memcpy(inputBuffer + inputBufferOffset, extractor->getFrameBuf(), info.size);
+            info.offset = inputBufferOffset;
+            frameInfos.push_back(info);
+            inputBufferOffset += info.size;
+        }
+
+        string outputFileName = OUTPUT_FILE_NAME;
+        FILE *outputFp = fopen(outputFileName.c_str(), "w+b");
+        if (!outputFp) {
+            cout << "[   WARN   ] Test Skipped. Unable to open output file for writing \n";
+            return;
+        }
+        int32_t fd = fileno(outputFp);
+        status = muxerObj->initMuxer(fd, outputFormat);
+        if (status != 0) {
+            cout << "[   WARN   ] Test Skipped. initMuxer failed\n";
+            return;
+        }
+
+        status = muxerObj->mux(inputBuffer, frameInfos);
+        if (status != 0) {
+            cout << "[   WARN   ] Test Skipped. Mux failed \n";
+            return;
+        }
+        muxerObj->deInitMuxer();
+        muxerObj->dumpStatistics(GetParam().first + "." + fmt.c_str());
+        free(inputBuffer);
+        fclose(outputFp);
+        muxerObj->resetMuxer();
+    }
+    fclose(inputFp);
+    extractor->deInitExtractor();
+    delete muxerObj;
+}
+
+INSTANTIATE_TEST_SUITE_P(
+        MuxerTestAll, MuxerTest,
+        ::testing::Values(make_pair("crowd_1920x1080_25fps_4000kbps_vp8.webm", "webm"),
+                          make_pair("crowd_1920x1080_25fps_4000kbps_vp9.webm", "webm"),
+                          make_pair("crowd_1920x1080_25fps_6000kbps_mpeg4.mp4", "mp4"),
+                          make_pair("crowd_352x288_25fps_6000kbps_h263.3gp", "mp4"),
+                          make_pair("crowd_1920x1080_25fps_6700kbps_h264.ts", "mp4"),
+                          make_pair("crowd_1920x1080_25fps_4000kbps_h265.mkv", "mp4"),
+                          make_pair("crowd_1920x1080_25fps_6000kbps_mpeg4.mp4", "3gpp"),
+                          make_pair("crowd_352x288_25fps_6000kbps_h263.3gp", "3gpp"),
+                          make_pair("crowd_1920x1080_25fps_6700kbps_h264.ts", "3gpp"),
+                          make_pair("crowd_1920x1080_25fps_4000kbps_h265.mkv", "3gpp"),
+                          make_pair("bbb_48000hz_2ch_100kbps_opus_5mins.webm", "ogg"),
+                          make_pair("bbb_44100hz_2ch_80kbps_vorbis_5mins.mp4", "webm"),
+                          make_pair("bbb_48000hz_2ch_100kbps_opus_5mins.webm", "webm"),
+                          make_pair("bbb_44100hz_2ch_128kbps_aac_5mins.mp4", "mp4"),
+                          make_pair("bbb_8000hz_1ch_8kbps_amrnb_5mins.3gp", "mp4"),
+                          make_pair("bbb_16000hz_1ch_9kbps_amrwb_5mins.3gp", "mp4"),
+                          make_pair("bbb_44100hz_2ch_128kbps_aac_5mins.mp4", "3gpp"),
+                          make_pair("bbb_8000hz_1ch_8kbps_amrnb_5mins.3gp", "3gpp"),
+                          make_pair("bbb_16000hz_1ch_9kbps_amrwb_5mins.3gp", "3gpp")));
+
+int main(int argc, char **argv) {
+    gEnv = new BenchmarkTestEnvironment();
+    ::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/utils/Android.bp b/media/utils/Android.bp
index e2cd4e3..8a9039c 100644
--- a/media/utils/Android.bp
+++ b/media/utils/Android.bp
@@ -25,12 +25,14 @@
         "ServiceUtilities.cpp",
         "TimeCheck.cpp",
     ],
+    static_libs: [
+        "libc_malloc_debug_backtrace",
+    ],
     shared_libs: [
         "libbinder",
         "libcutils",
         "liblog",
         "libutils",
-        "libmemunreachable",
         "libhidlbase",
         "android.hardware.graphics.bufferqueue@1.0",
         "android.hidl.token@1.0-utils",
@@ -44,16 +46,11 @@
         "-Werror",
     ],
 
-    product_variables: {
-        product_is_iot: {
-            cflags: ["-DTARGET_ANDROID_THINGS"],
-        },
-    },
-
-    include_dirs: [
-        // For android_mallopt definitions.
-        "bionic/libc/private"
+    header_libs: [
+        "bionic_libc_platform_headers",
+        "libmedia_headers",
     ],
+
     local_include_dirs: ["include"],
     export_include_dirs: ["include"],
 }
diff --git a/media/utils/MemoryLeakTrackUtil.cpp b/media/utils/MemoryLeakTrackUtil.cpp
index 2988b52..6166859 100644
--- a/media/utils/MemoryLeakTrackUtil.cpp
+++ b/media/utils/MemoryLeakTrackUtil.cpp
@@ -22,7 +22,7 @@
 #include "media/MemoryLeakTrackUtil.h"
 #include <sstream>
 
-#include <bionic_malloc.h>
+#include <bionic/malloc.h>
 
 /*
  * The code here originally resided in MediaPlayerService.cpp
diff --git a/media/utils/ServiceUtilities.cpp b/media/utils/ServiceUtilities.cpp
index bc8fff6..02141a8 100644
--- a/media/utils/ServiceUtilities.cpp
+++ b/media/utils/ServiceUtilities.cpp
@@ -179,18 +179,7 @@
     // IMPORTANT: Use PermissionCache - not a runtime permission and may not change.
     bool ok = PermissionCache::checkCallingPermission(sModifyDefaultAudioEffectsAllowed);
 
-#ifdef TARGET_ANDROID_THINGS
-    if (!ok) {
-        // Use a secondary permission on Android Things to allow a more lenient level of protection.
-        static const String16 sModifyDefaultAudioEffectsAndroidThingsAllowed(
-                "com.google.android.things.permission.MODIFY_DEFAULT_AUDIO_EFFECTS");
-        ok = PermissionCache::checkCallingPermission(
-                sModifyDefaultAudioEffectsAndroidThingsAllowed);
-    }
-    if (!ok) ALOGE("com.google.android.things.permission.MODIFY_DEFAULT_AUDIO_EFFECTS");
-#else
     if (!ok) ALOGE("android.permission.MODIFY_DEFAULT_AUDIO_EFFECTS");
-#endif
     return ok;
 }
 
diff --git a/media/utils/TimeCheck.cpp b/media/utils/TimeCheck.cpp
index 59cf4ef..265a232 100644
--- a/media/utils/TimeCheck.cpp
+++ b/media/utils/TimeCheck.cpp
@@ -16,8 +16,8 @@
 
 
 #include <utils/Log.h>
-#include <media/TimeCheck.h>
-#include <media/EventLog.h>
+#include <mediautils/TimeCheck.h>
+#include <mediautils/EventLog.h>
 
 namespace android {
 
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index d38190d..8591efd 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -810,7 +810,33 @@
                     continue;
                 }
 
-                size_t frameCount = std::lcm(thread->frameCount(), secondaryThread->frameCount());
+                size_t sourceFrameCount = thread->frameCount() * output.sampleRate
+                                          / thread->sampleRate();
+                size_t sinkFrameCount = secondaryThread->frameCount() * output.sampleRate
+                                          / secondaryThread->sampleRate();
+                // If the secondary output has just been opened, the first secondaryThread write
+                // will not block as it will fill the empty startup buffer of the HAL,
+                // so a second sink buffer needs to be ready for the immediate next blocking write.
+                // Additionally, have a margin of one main thread buffer as the scheduling jitter
+                // can reorder the writes (eg if thread A&B have the same write intervale,
+                // the scheduler could schedule AB...BA)
+                size_t frameCountToBeReady = 2 * sinkFrameCount + sourceFrameCount;
+                // Total secondary output buffer must be at least as the read frames plus
+                // the margin of a few buffers on both sides in case the
+                // threads scheduling has some jitter.
+                // That value should not impact latency as the secondary track is started before
+                // its buffer is full, see frameCountToBeReady.
+                size_t frameCount = frameCountToBeReady + 2 * (sourceFrameCount + sinkFrameCount);
+                // The frameCount should also not be smaller than the secondary thread min frame
+                // count
+                size_t minFrameCount = AudioSystem::calculateMinFrameCount(
+                            [&] { Mutex::Autolock _l(secondaryThread->mLock);
+                                  return secondaryThread->latency_l(); }(),
+                            secondaryThread->mNormalFrameCount,
+                            secondaryThread->mSampleRate,
+                            output.sampleRate,
+                            input.speed);
+                frameCount = std::max(frameCount, minFrameCount);
 
                 using namespace std::chrono_literals;
                 auto inChannelMask = audio_channel_mask_out_to_in(input.config.channel_mask);
@@ -843,7 +869,8 @@
                                                                patchRecord->buffer(),
                                                                patchRecord->bufferSize(),
                                                                outputFlags,
-                                                               0ns /* timeout */);
+                                                               0ns /* timeout */,
+                                                               frameCountToBeReady);
                 status = patchTrack->initCheck();
                 if (status != NO_ERROR) {
                     ALOGE("Secondary output patchTrack init failed: %d", status);
@@ -1357,8 +1384,8 @@
         String8(AudioParameter::keyFrameCount),
         String8(AudioParameter::keyInputSource),
         String8(AudioParameter::keyMonoOutput),
-        String8(AudioParameter::keyStreamConnect),
-        String8(AudioParameter::keyStreamDisconnect),
+        String8(AudioParameter::keyDeviceConnect),
+        String8(AudioParameter::keyDeviceDisconnect),
         String8(AudioParameter::keyStreamSupportedFormats),
         String8(AudioParameter::keyStreamSupportedChannels),
         String8(AudioParameter::keyStreamSupportedSamplingRates),
@@ -1543,7 +1570,7 @@
     proposed.format = format;
 
     sp<DeviceHalInterface> dev = mPrimaryHardwareDev->hwDevice();
-    size_t frames;
+    size_t frames = 0;
     for (;;) {
         // Note: config is currently a const parameter for get_input_buffer_size()
         // but we use a copy from proposed in case config changes from the call.
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index 72e669a..d639f26 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -547,6 +547,16 @@
         bool        mute;
     };
 
+    // Abstraction for the Audio Source for the RecordThread (HAL or PassthruPatchRecord).
+    struct Source
+    {
+        virtual ~Source() = default;
+        // The following methods have the same signatures as in StreamHalInterface.
+        virtual status_t read(void *buffer, size_t bytes, size_t *read) = 0;
+        virtual status_t getCapturePosition(int64_t *frames, int64_t *time) = 0;
+        virtual status_t standby() = 0;
+    };
+
     // --- PlaybackThread ---
 #ifdef FLOAT_EFFECT_CHAIN
 #define EFFECT_BUFFER_FORMAT AUDIO_FORMAT_PCM_FLOAT
@@ -749,7 +759,7 @@
     // For emphasis, we could also make all pointers to them be "const *",
     // but that would clutter the code unnecessarily.
 
-    struct AudioStreamIn {
+    struct AudioStreamIn : public Source {
         AudioHwDevice* const audioHwDev;
         sp<StreamInHalInterface> stream;
         audio_input_flags_t flags;
@@ -758,6 +768,13 @@
 
         AudioStreamIn(AudioHwDevice *dev, sp<StreamInHalInterface> in, audio_input_flags_t flags) :
             audioHwDev(dev), stream(in), flags(flags) {}
+        status_t read(void *buffer, size_t bytes, size_t *read) override {
+            return stream->read(buffer, bytes, read);
+        }
+        status_t getCapturePosition(int64_t *frames, int64_t *time) override {
+            return stream->getCapturePosition(frames, time);
+        }
+        status_t standby() override { return stream->standby(); }
     };
 
     struct TeePatch {
diff --git a/services/audioflinger/FastMixer.cpp b/services/audioflinger/FastMixer.cpp
index c5b9953..3eacc8c 100644
--- a/services/audioflinger/FastMixer.cpp
+++ b/services/audioflinger/FastMixer.cpp
@@ -105,13 +105,8 @@
     return mSQ.poll();
 }
 
-void FastMixer::setNBLogWriter(NBLog::Writer *logWriter)
+void FastMixer::setNBLogWriter(NBLog::Writer *logWriter __unused)
 {
-    // FIXME If mMixer is set or changed prior to this, we don't inform correctly.
-    //       Should cache logWriter and re-apply it at the assignment to mMixer.
-    if (mMixer != NULL) {
-        mMixer->setNBLogWriter(logWriter);
-    }
 }
 
 void FastMixer::onIdle()
diff --git a/services/audioflinger/FastThread.cpp b/services/audioflinger/FastThread.cpp
index 04b32c2..8b7a124 100644
--- a/services/audioflinger/FastThread.cpp
+++ b/services/audioflinger/FastThread.cpp
@@ -124,7 +124,7 @@
             mDumpState = next->mDumpState != NULL ? next->mDumpState : mDummyDumpState;
             tlNBLogWriter = next->mNBLogWriter != NULL ?
                     next->mNBLogWriter : mDummyNBLogWriter.get();
-            setNBLogWriter(tlNBLogWriter); // FastMixer informs its AudioMixer, FastCapture ignores
+            setNBLogWriter(tlNBLogWriter); // This is used for debugging only
 
             // We want to always have a valid reference to the previous (non-idle) state.
             // However, the state queue only guarantees access to current and previous states.
diff --git a/services/audioflinger/PatchPanel.cpp b/services/audioflinger/PatchPanel.cpp
index edb331d..18cb53b 100644
--- a/services/audioflinger/PatchPanel.cpp
+++ b/services/audioflinger/PatchPanel.cpp
@@ -483,19 +483,6 @@
         // Fast mode is not available in this case.
         inputFlags = (audio_input_flags_t) (inputFlags & ~AUDIO_INPUT_FLAG_FAST);
     }
-    sp<RecordThread::PatchRecord> tempRecordTrack = new (std::nothrow) RecordThread::PatchRecord(
-                                             mRecord.thread().get(),
-                                             sampleRate,
-                                             inChannelMask,
-                                             format,
-                                             frameCount,
-                                             NULL,
-                                             (size_t)0 /* bufferSize */,
-                                             inputFlags);
-    status = mRecord.checkTrack(tempRecordTrack.get());
-    if (status != NO_ERROR) {
-        return status;
-    }
 
     audio_output_flags_t outputFlags = mAudioPatch.sinks[0].config_mask & AUDIO_PORT_CONFIG_FLAGS ?
             mAudioPatch.sinks[0].flags.output : AUDIO_OUTPUT_FLAG_NONE;
@@ -512,9 +499,34 @@
         outputFlags = (audio_output_flags_t) (outputFlags & ~AUDIO_OUTPUT_FLAG_FAST);
     }
 
+    sp<RecordThread::PatchRecord> tempRecordTrack;
+    if ((inputFlags & AUDIO_INPUT_FLAG_DIRECT) && (outputFlags & AUDIO_OUTPUT_FLAG_DIRECT)) {
+        tempRecordTrack = new RecordThread::PassthruPatchRecord(
+                                                 mRecord.thread().get(),
+                                                 sampleRate,
+                                                 inChannelMask,
+                                                 format,
+                                                 frameCount,
+                                                 inputFlags);
+    } else {
+        tempRecordTrack = new RecordThread::PatchRecord(
+                                                 mRecord.thread().get(),
+                                                 sampleRate,
+                                                 inChannelMask,
+                                                 format,
+                                                 frameCount,
+                                                 nullptr,
+                                                 (size_t)0 /* bufferSize */,
+                                                 inputFlags);
+    }
+    status = mRecord.checkTrack(tempRecordTrack.get());
+    if (status != NO_ERROR) {
+        return status;
+    }
+
     // create a special playback track to render to playback thread.
     // this track is given the same buffer as the PatchRecord buffer
-    sp<PlaybackThread::PatchTrack> tempPatchTrack = new (std::nothrow) PlaybackThread::PatchTrack(
+    sp<PlaybackThread::PatchTrack> tempPatchTrack = new PlaybackThread::PatchTrack(
                                            mPlayback.thread().get(),
                                            streamType,
                                            sampleRate,
diff --git a/services/audioflinger/PlaybackTracks.h b/services/audioflinger/PlaybackTracks.h
index a093893..1ff03c4 100644
--- a/services/audioflinger/PlaybackTracks.h
+++ b/services/audioflinger/PlaybackTracks.h
@@ -74,7 +74,10 @@
                                 uid_t uid,
                                 audio_output_flags_t flags,
                                 track_type type,
-                                audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE);
+                                audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE,
+                                /** default behaviour is to start when there are as many frames
+                                  * ready as possible (aka. Buffer is full). */
+                                size_t frameCountToBeReady = SIZE_MAX);
     virtual             ~Track();
     virtual status_t    initCheck() const;
 
@@ -263,11 +266,11 @@
     };
     sp<AudioVibrationController> mAudioVibrationController;
     sp<os::ExternalVibration>    mExternalVibration;
+    /** How many frames should be in the buffer before the track is considered ready */
+    const size_t        mFrameCountToBeReady;
 
 private:
     void                interceptBuffer(const AudioBufferProvider::Buffer& buffer);
-    /** Write the source data in the buffer provider. @return written frame count. */
-    size_t              writeFrames(AudioBufferProvider* dest, const void* src, size_t frameCount);
     template <class F>
     void                forEachTeePatchTrack(F f) {
         for (auto& tp : mTeePatches) { f(tp.patchTrack); }
@@ -384,9 +387,15 @@
                                    void *buffer,
                                    size_t bufferSize,
                                    audio_output_flags_t flags,
-                                   const Timeout& timeout = {});
+                                   const Timeout& timeout = {},
+                                   size_t frameCountToBeReady = 1 /** Default behaviour is to start
+                                                                    *  as soon as possible to have
+                                                                    *  the lowest possible latency
+                                                                    *  even if it might glitch. */);
     virtual             ~PatchTrack();
 
+            size_t      framesReady() const override;
+
     virtual status_t    start(AudioSystem::sync_event_t event =
                                     AudioSystem::SYNC_EVENT_NONE,
                              audio_session_t triggerSession = AUDIO_SESSION_NONE);
@@ -402,5 +411,4 @@
 
 private:
             void restartIfDisabled();
-
 };  // end of PatchTrack
diff --git a/services/audioflinger/RecordTracks.h b/services/audioflinger/RecordTracks.h
index c8397cd..d5257bd 100644
--- a/services/audioflinger/RecordTracks.h
+++ b/services/audioflinger/RecordTracks.h
@@ -167,6 +167,8 @@
                 const Timeout& timeout = {});
     virtual             ~PatchRecord();
 
+    virtual Source* getSource() { return nullptr; }
+
     // AudioBufferProvider interface
     virtual status_t getNextBuffer(AudioBufferProvider::Buffer* buffer);
     virtual void releaseBuffer(AudioBufferProvider::Buffer* buffer);
@@ -175,4 +177,71 @@
     virtual status_t    obtainBuffer(Proxy::Buffer *buffer,
                                      const struct timespec *timeOut = NULL);
     virtual void        releaseBuffer(Proxy::Buffer *buffer);
+
+    size_t writeFrames(const void* src, size_t frameCount, size_t frameSize) {
+        return writeFrames(this, src, frameCount, frameSize);
+    }
+
+protected:
+    /** Write the source data into the buffer provider. @return written frame count. */
+    static size_t writeFrames(AudioBufferProvider* dest, const void* src,
+            size_t frameCount, size_t frameSize);
+
 };  // end of PatchRecord
+
+class PassthruPatchRecord : public PatchRecord, public Source {
+public:
+    PassthruPatchRecord(RecordThread *recordThread,
+                        uint32_t sampleRate,
+                        audio_channel_mask_t channelMask,
+                        audio_format_t format,
+                        size_t frameCount,
+                        audio_input_flags_t flags);
+
+    Source* getSource() override { return static_cast<Source*>(this); }
+
+    // Source interface
+    status_t read(void *buffer, size_t bytes, size_t *read) override;
+    status_t getCapturePosition(int64_t *frames, int64_t *time) override;
+    status_t standby() override;
+
+    // AudioBufferProvider interface
+    // This interface is used by RecordThread to pass the data obtained
+    // from HAL or other source to the client. PassthruPatchRecord receives
+    // the data in 'obtainBuffer' so these calls are stubbed out.
+    status_t getNextBuffer(AudioBufferProvider::Buffer* buffer) override;
+    void releaseBuffer(AudioBufferProvider::Buffer* buffer) override;
+
+    // PatchProxyBufferProvider interface
+    // This interface is used from DirectOutputThread to acquire data from HAL.
+    bool producesBufferOnDemand() const override { return true; }
+    status_t obtainBuffer(Proxy::Buffer *buffer, const struct timespec *timeOut = nullptr) override;
+    void releaseBuffer(Proxy::Buffer *buffer) override;
+
+private:
+    // This is to use with PatchRecord::writeFrames
+    struct PatchRecordAudioBufferProvider : public AudioBufferProvider {
+        explicit PatchRecordAudioBufferProvider(PassthruPatchRecord& passthru) :
+                mPassthru(passthru) {}
+        status_t getNextBuffer(AudioBufferProvider::Buffer* buffer) override {
+            return mPassthru.PatchRecord::getNextBuffer(buffer);
+        }
+        void releaseBuffer(AudioBufferProvider::Buffer* buffer) override {
+            return mPassthru.PatchRecord::releaseBuffer(buffer);
+        }
+    private:
+        PassthruPatchRecord& mPassthru;
+    };
+
+    sp<StreamInHalInterface> obtainStream(sp<ThreadBase>* thread);
+
+    PatchRecordAudioBufferProvider mPatchRecordAudioBufferProvider;
+    std::unique_ptr<void, decltype(free)*> mSinkBuffer;  // frame size aligned continuous buffer
+    std::unique_ptr<void, decltype(free)*> mStubBuffer;  // buffer used for AudioBufferProvider
+    size_t mUnconsumedFrames = 0;
+    std::mutex mReadLock;
+    std::condition_variable mReadCV;
+    size_t mReadBytes = 0; // GUARDED_BY(mReadLock)
+    status_t mReadError = NO_ERROR; // GUARDED_BY(mReadLock)
+    int64_t mLastReadFrames = 0;  // accessed on RecordThread only
+};
diff --git a/services/audioflinger/SpdifStreamOut.cpp b/services/audioflinger/SpdifStreamOut.cpp
index a44ab2a..c7aba79 100644
--- a/services/audioflinger/SpdifStreamOut.cpp
+++ b/services/audioflinger/SpdifStreamOut.cpp
@@ -59,6 +59,7 @@
     // TODO Move this into the audio_utils as a static method.
     switch(config->format) {
         case AUDIO_FORMAT_E_AC3:
+        case AUDIO_FORMAT_E_AC3_JOC:
             mRateMultiplier = 4;
             break;
         case AUDIO_FORMAT_AC3:
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index bd9bf7b..ac892a5 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -2953,9 +2953,11 @@
             ALOG_ASSERT(mCallbackThread != 0);
             mCallbackThread->setWriteBlocked(mWriteAckSequence);
         }
+        ATRACE_BEGIN("write");
         // FIXME We should have an implementation of timestamps for direct output threads.
         // They are used e.g for multichannel PCM playback over HDMI.
         bytesWritten = mOutput->write((char *)mSinkBuffer + offset, mBytesRemaining);
+        ATRACE_END();
 
         if (mUseAsyncWrite &&
                 ((bytesWritten < 0) || (bytesWritten == (ssize_t)mBytesRemaining))) {
@@ -5301,11 +5303,11 @@
         return false;
     }
     // Check validity as we don't call AudioMixer::create() here.
-    if (!AudioMixer::isValidFormat(format)) {
+    if (!mAudioMixer->isValidFormat(format)) {
         ALOGW("%s: invalid format: %#x", __func__, format);
         return false;
     }
-    if (!AudioMixer::isValidChannelMask(channelMask)) {
+    if (!mAudioMixer->isValidChannelMask(channelMask)) {
         ALOGW("%s: invalid channelMask: %#x", __func__, channelMask);
         return false;
     }
@@ -5658,10 +5660,17 @@
             minFrames = 1;
         }
 
-        if ((track->framesReady() >= minFrames) && track->isReady() && !track->isPaused() &&
+        const size_t framesReady = track->framesReady();
+        const int trackId = track->id();
+        if (ATRACE_ENABLED()) {
+            std::string traceName("nRdy");
+            traceName += std::to_string(trackId);
+            ATRACE_INT(traceName.c_str(), framesReady);
+        }
+        if ((framesReady >= minFrames) && track->isReady() && !track->isPaused() &&
                 !track->isStopping_2() && !track->isStopped())
         {
-            ALOGVV("track(%d) s=%08x [OK]", track->id(), cblk->mServer);
+            ALOGVV("track(%d) s=%08x [OK]", trackId, cblk->mServer);
 
             if (track->mFillingUpStatus == Track::FS_FILLED) {
                 track->mFillingUpStatus = Track::FS_ACTIVE;
@@ -5738,7 +5747,7 @@
                 // fill a buffer, then remove it from active list.
                 // Only consider last track started for mixer state control
                 if (--(track->mRetryCount) <= 0) {
-                    ALOGV("BUFFER TIMEOUT: remove track(%d) from active list", track->id());
+                    ALOGV("BUFFER TIMEOUT: remove track(%d) from active list", trackId);
                     tracksToRemove->add(track);
                     // indicate to client process that the track was disabled because of underrun;
                     // it will then automatically call start() when data is available
@@ -5746,7 +5755,7 @@
                 } else if (last) {
                     ALOGW("pause because of UNDERRUN, framesReady = %zu,"
                             "minFrames = %u, mFormat = %#x",
-                            track->framesReady(), minFrames, mFormat);
+                            framesReady, minFrames, mFormat);
                     mixerStatus = MIXER_TRACKS_ENABLED;
                     if (mHwSupportsPause && !mHwPaused && !mStandby) {
                         doHwPause = true;
@@ -6354,7 +6363,9 @@
             }
         }
         // compute volume for this track
-        processVolume_l(track, last);
+        if (track->isReady()) {  // check ready to prevent premature start.
+            processVolume_l(track, last);
+        }
     }
 
     // make sure the pause/flush/resume sequence is executed in the right order.
@@ -6668,6 +6679,7 @@
                                          ) :
     ThreadBase(audioFlinger, id, outDevice, inDevice, RECORD, systemReady),
     mInput(input),
+    mSource(mInput),
     mActiveTracks(&this->mLocalLog),
     mRsmpInBuffer(NULL),
     // mRsmpInFrames, mRsmpInFramesP2, and mRsmpInFramesOA are set by readInputParameters_l()
@@ -7120,7 +7132,7 @@
         } else {
             ATRACE_BEGIN("read");
             size_t bytesRead;
-            status_t result = mInput->stream->read(
+            status_t result = mSource->read(
                     (uint8_t*)mRsmpInBuffer + rear * mFrameSize, mBufferSize, &bytesRead);
             ATRACE_END();
             if (result < 0) {
@@ -7142,7 +7154,7 @@
             int64_t position, time;
             if (mStandby) {
                 mTimestampVerifier.discontinuity();
-            } else if (mInput->stream->getCapturePosition(&position, &time) == NO_ERROR
+            } else if (mSource->getCapturePosition(&position, &time) == NO_ERROR
                     && time > mTimestamp.mTimeNs[ExtendedTimestamp::LOCATION_KERNEL]) {
 
                 mTimestampVerifier.add(position, time, mSampleRate);
@@ -7423,7 +7435,7 @@
             sq->end(false /*didModify*/);
         }
     }
-    status_t result = mInput->stream->standby();
+    status_t result = mSource->standby();
     ALOGE_IF(result != OK, "Error when putting input stream into standby: %d", result);
 
     // If going into standby, flush the pipe source.
@@ -8409,11 +8421,17 @@
 {
     Mutex::Autolock _l(mLock);
     mTracks.add(record);
+    if (record->getSource()) {
+        mSource = record->getSource();
+    }
 }
 
 void AudioFlinger::RecordThread::deletePatchTrack(const sp<PatchRecord>& record)
 {
     Mutex::Autolock _l(mLock);
+    if (mSource == record->getSource()) {
+        mSource = mInput;
+    }
     destroyTrack_l(record);
 }
 
diff --git a/services/audioflinger/Threads.h b/services/audioflinger/Threads.h
index 87bebf3..0a473d5 100644
--- a/services/audioflinger/Threads.h
+++ b/services/audioflinger/Threads.h
@@ -1647,6 +1647,7 @@
             void    checkBtNrec_l();
 
             AudioStreamIn                       *mInput;
+            Source                              *mSource;
             SortedVector < sp<RecordTrack> >    mTracks;
             // mActiveTracks has dual roles:  it indicates the current active track(s), and
             // is used together with mStartStopCond to indicate start()/stop() progress
diff --git a/services/audioflinger/TrackBase.h b/services/audioflinger/TrackBase.h
index 65589e2..52e7d59 100644
--- a/services/audioflinger/TrackBase.h
+++ b/services/audioflinger/TrackBase.h
@@ -327,6 +327,7 @@
 
     virtual ~PatchProxyBufferProvider() {}
 
+    virtual bool        producesBufferOnDemand() const = 0;
     virtual status_t    obtainBuffer(Proxy::Buffer* buffer,
                                      const struct timespec *requested = NULL) = 0;
     virtual void        releaseBuffer(Proxy::Buffer* buffer) = 0;
@@ -349,6 +350,8 @@
                             mPeerProxy = nullptr;
                         }
 
+            bool        producesBufferOnDemand() const override { return false; }
+
 protected:
     const sp<ClientProxy>       mProxy;
     sp<RefBase>                 mPeerReferenceHold;   // keeps mPeerProxy alive during access.
diff --git a/services/audioflinger/Tracks.cpp b/services/audioflinger/Tracks.cpp
index 2a5a713..e4402bd 100644
--- a/services/audioflinger/Tracks.cpp
+++ b/services/audioflinger/Tracks.cpp
@@ -18,12 +18,14 @@
 
 #define LOG_TAG "AudioFlinger"
 //#define LOG_NDEBUG 0
+#define ATRACE_TAG ATRACE_TAG_AUDIO
 
 #include "Configuration.h"
 #include <linux/futex.h>
 #include <math.h>
 #include <sys/syscall.h>
 #include <utils/Log.h>
+#include <utils/Trace.h>
 
 #include <private/media/AudioTrackShared.h>
 
@@ -511,7 +513,8 @@
             uid_t uid,
             audio_output_flags_t flags,
             track_type type,
-            audio_port_handle_t portId)
+            audio_port_handle_t portId,
+            size_t frameCountToBeReady)
     :   TrackBase(thread, client, attr, sampleRate, format, channelMask, frameCount,
                   (sharedBuffer != 0) ? sharedBuffer->pointer() : buffer,
                   (sharedBuffer != 0) ? sharedBuffer->size() : bufferSize,
@@ -530,6 +533,7 @@
     mVolumeHandler(new media::VolumeHandler(sampleRate)),
     mOpPlayAudioMonitor(OpPlayAudioMonitor::createIfNeeded(uid, attr, id(), streamType)),
     // mSinkTimestamp
+    mFrameCountToBeReady(frameCountToBeReady),
     mFastIndex(-1),
     mCachedVolume(1.0),
     /* The track might not play immediately after being active, similarly as if its volume was 0.
@@ -820,16 +824,9 @@
     }
     for (auto& teePatch : mTeePatches) {
         RecordThread::PatchRecord* patchRecord = teePatch.patchRecord.get();
-
-        size_t framesWritten = writeFrames(patchRecord, sourceBuffer.i8, frameCount);
-        // On buffer wrap, the buffer frame count will be less than requested,
-        // when this happens a second buffer needs to be used to write the leftover audio
-        size_t framesLeft = frameCount - framesWritten;
-        if (framesWritten != 0 && framesLeft != 0) {
-            framesWritten +=
-                writeFrames(patchRecord, sourceBuffer.i8 + framesWritten * mFrameSize, framesLeft);
-            framesLeft = frameCount - framesWritten;
-        }
+        const size_t framesWritten = patchRecord->writeFrames(
+                sourceBuffer.i8, frameCount, mFrameSize);
+        const size_t framesLeft = frameCount - framesWritten;
         ALOGW_IF(framesLeft != 0, "%s(%d) PatchRecord %d can not provide big enough "
                  "buffer %zu/%zu, dropping %zu frames", __func__, mId, patchRecord->mId,
                  framesWritten, frameCount, framesLeft);
@@ -837,30 +834,10 @@
     auto spent = ceil<std::chrono::microseconds>(std::chrono::steady_clock::now() - start);
     using namespace std::chrono_literals;
     // Average is ~20us per track, this should virtually never be logged (Logging takes >200us)
-    ALOGD_IF(spent > 200us, "%s: took %lldus to intercept %zu tracks", __func__,
+    ALOGD_IF(spent > 500us, "%s: took %lldus to intercept %zu tracks", __func__,
              spent.count(), mTeePatches.size());
 }
 
-size_t AudioFlinger::PlaybackThread::Track::writeFrames(AudioBufferProvider* dest,
-                                                        const void* src,
-                                                        size_t frameCount) {
-    AudioBufferProvider::Buffer patchBuffer;
-    patchBuffer.frameCount = frameCount;
-    auto status = dest->getNextBuffer(&patchBuffer);
-    if (status != NO_ERROR) {
-       ALOGW("%s PathRecord getNextBuffer failed with error %d: %s",
-             __func__, status, strerror(-status));
-       return 0;
-    }
-    ALOG_ASSERT(patchBuffer.frameCount <= frameCount);
-    memcpy(patchBuffer.raw, src, patchBuffer.frameCount * mFrameSize);
-    auto framesWritten = patchBuffer.frameCount;
-    dest->releaseBuffer(&patchBuffer);
-    return framesWritten;
-}
-
-// releaseBuffer() is not overridden
-
 // ExtendedAudioBufferProvider interface
 
 // framesReady() may return an approximation of the number of frames if called
@@ -910,8 +887,12 @@
         return true;
     }
 
-    if (framesReady() >= mServerProxy->getBufferSizeInFrames() ||
-            (mCblk->mFlags & CBLK_FORCEREADY)) {
+    size_t bufferSizeInFrames = mServerProxy->getBufferSizeInFrames();
+    size_t framesToBeReady = std::min(mFrameCountToBeReady, bufferSizeInFrames);
+
+    if (framesReady() >= framesToBeReady || (mCblk->mFlags & CBLK_FORCEREADY)) {
+        ALOGV("%s(%d): consider track ready with %zu/%zu, target was %zu)",
+              __func__, mId, framesReady(), bufferSizeInFrames, framesToBeReady);
         mFillingUpStatus = FS_FILLED;
         android_atomic_and(~CBLK_FORCEREADY, &mCblk->mFlags);
         return true;
@@ -1413,6 +1394,7 @@
 
 void AudioFlinger::PlaybackThread::Track::disable()
 {
+    // TODO(b/142394888): the filling status should also be reset to filling
     signalClientFlag(CBLK_DISABLED);
 }
 
@@ -1790,12 +1772,14 @@
                                                      void *buffer,
                                                      size_t bufferSize,
                                                      audio_output_flags_t flags,
-                                                     const Timeout& timeout)
+                                                     const Timeout& timeout,
+                                                     size_t frameCountToBeReady)
     :   Track(playbackThread, NULL, streamType,
               audio_attributes_t{} /* currently unused for patch track */,
               sampleRate, format, channelMask, frameCount,
               buffer, bufferSize, nullptr /* sharedBuffer */,
-              AUDIO_SESSION_NONE, getpid(), AID_AUDIOSERVER, flags, TYPE_PATCH),
+              AUDIO_SESSION_NONE, getpid(), AID_AUDIOSERVER, flags, TYPE_PATCH,
+              AUDIO_PORT_HANDLE_NONE, frameCountToBeReady),
         PatchTrackBase(new ClientProxy(mCblk, mBuffer, frameCount, mFrameSize, true, true),
                        *playbackThread, timeout)
 {
@@ -1810,6 +1794,15 @@
     ALOGV("%s(%d)", __func__, mId);
 }
 
+size_t AudioFlinger::PlaybackThread::PatchTrack::framesReady() const
+{
+    if (mPeerProxy && mPeerProxy->producesBufferOnDemand()) {
+        return std::numeric_limits<size_t>::max();
+    } else {
+        return Track::framesReady();
+    }
+}
+
 status_t AudioFlinger::PlaybackThread::PatchTrack::start(AudioSystem::sync_event_t event,
                                                          audio_session_t triggerSession)
 {
@@ -1828,9 +1821,19 @@
     ALOG_ASSERT(mPeerProxy != 0, "%s(%d): called without peer proxy", __func__, mId);
     Proxy::Buffer buf;
     buf.mFrameCount = buffer->frameCount;
+    if (ATRACE_ENABLED()) {
+        std::string traceName("PTnReq");
+        traceName += std::to_string(id());
+        ATRACE_INT(traceName.c_str(), buf.mFrameCount);
+    }
     status_t status = mPeerProxy->obtainBuffer(&buf, &mPeerTimeout);
     ALOGV_IF(status != NO_ERROR, "%s(%d): getNextBuffer status %d", __func__, mId, status);
     buffer->frameCount = buf.mFrameCount;
+    if (ATRACE_ENABLED()) {
+        std::string traceName("PTnObt");
+        traceName += std::to_string(id());
+        ATRACE_INT(traceName.c_str(), buf.mFrameCount);
+    }
     if (buf.mFrameCount == 0) {
         return WOULD_BLOCK;
     }
@@ -1869,7 +1872,6 @@
 {
     mProxy->releaseBuffer(buffer);
     restartIfDisabled();
-    android_atomic_or(CBLK_FORCEREADY, &mCblk->mFlags);
 }
 
 void AudioFlinger::PlaybackThread::PatchTrack::restartIfDisabled()
@@ -2392,6 +2394,39 @@
     ALOGV("%s(%d)", __func__, mId);
 }
 
+static size_t writeFramesHelper(
+        AudioBufferProvider* dest, const void* src, size_t frameCount, size_t frameSize)
+{
+    AudioBufferProvider::Buffer patchBuffer;
+    patchBuffer.frameCount = frameCount;
+    auto status = dest->getNextBuffer(&patchBuffer);
+    if (status != NO_ERROR) {
+       ALOGW("%s PathRecord getNextBuffer failed with error %d: %s",
+             __func__, status, strerror(-status));
+       return 0;
+    }
+    ALOG_ASSERT(patchBuffer.frameCount <= frameCount);
+    memcpy(patchBuffer.raw, src, patchBuffer.frameCount * frameSize);
+    size_t framesWritten = patchBuffer.frameCount;
+    dest->releaseBuffer(&patchBuffer);
+    return framesWritten;
+}
+
+// static
+size_t AudioFlinger::RecordThread::PatchRecord::writeFrames(
+        AudioBufferProvider* dest, const void* src, size_t frameCount, size_t frameSize)
+{
+    size_t framesWritten = writeFramesHelper(dest, src, frameCount, frameSize);
+    // On buffer wrap, the buffer frame count will be less than requested,
+    // when this happens a second buffer needs to be used to write the leftover audio
+    const size_t framesLeft = frameCount - framesWritten;
+    if (framesWritten != 0 && framesLeft != 0) {
+        framesWritten += writeFramesHelper(dest, (const char*)src + framesWritten * frameSize,
+                        framesLeft, frameSize);
+    }
+    return framesWritten;
+}
+
 // AudioBufferProvider interface
 status_t AudioFlinger::RecordThread::PatchRecord::getNextBuffer(
                                                   AudioBufferProvider::Buffer* buffer)
@@ -2403,6 +2438,11 @@
     ALOGV_IF(status != NO_ERROR,
              "%s(%d): mPeerProxy->obtainBuffer status %d", __func__, mId, status);
     buffer->frameCount = buf.mFrameCount;
+    if (ATRACE_ENABLED()) {
+        std::string traceName("PRnObt");
+        traceName += std::to_string(id());
+        ATRACE_INT(traceName.c_str(), buf.mFrameCount);
+    }
     if (buf.mFrameCount == 0) {
         return WOULD_BLOCK;
     }
@@ -2431,6 +2471,180 @@
     mProxy->releaseBuffer(buffer);
 }
 
+#undef LOG_TAG
+#define LOG_TAG "AF::PthrPatchRecord"
+
+static std::unique_ptr<void, decltype(free)*> allocAligned(size_t alignment, size_t size)
+{
+    void *ptr = nullptr;
+    (void)posix_memalign(&ptr, alignment, size);
+    return std::unique_ptr<void, decltype(free)*>(ptr, free);
+}
+
+AudioFlinger::RecordThread::PassthruPatchRecord::PassthruPatchRecord(
+        RecordThread *recordThread,
+        uint32_t sampleRate,
+        audio_channel_mask_t channelMask,
+        audio_format_t format,
+        size_t frameCount,
+        audio_input_flags_t flags)
+        : PatchRecord(recordThread, sampleRate, channelMask, format, frameCount,
+                nullptr /*buffer*/, 0 /*bufferSize*/, flags),
+          mPatchRecordAudioBufferProvider(*this),
+          mSinkBuffer(allocAligned(32, mFrameCount * mFrameSize)),
+          mStubBuffer(allocAligned(32, mFrameCount * mFrameSize))
+{
+    memset(mStubBuffer.get(), 0, mFrameCount * mFrameSize);
+}
+
+sp<StreamInHalInterface> AudioFlinger::RecordThread::PassthruPatchRecord::obtainStream(
+        sp<ThreadBase>* thread)
+{
+    *thread = mThread.promote();
+    if (!*thread) return nullptr;
+    RecordThread *recordThread = static_cast<RecordThread*>((*thread).get());
+    Mutex::Autolock _l(recordThread->mLock);
+    return recordThread->mInput ? recordThread->mInput->stream : nullptr;
+}
+
+// PatchProxyBufferProvider methods are called on DirectOutputThread
+status_t AudioFlinger::RecordThread::PassthruPatchRecord::obtainBuffer(
+        Proxy::Buffer* buffer, const struct timespec* timeOut)
+{
+    if (mUnconsumedFrames) {
+        buffer->mFrameCount = std::min(buffer->mFrameCount, mUnconsumedFrames);
+        // mUnconsumedFrames is decreased in releaseBuffer to use actual frame consumption figure.
+        return PatchRecord::obtainBuffer(buffer, timeOut);
+    }
+
+    // Otherwise, execute a read from HAL and write into the buffer.
+    nsecs_t startTimeNs = 0;
+    if (timeOut && (timeOut->tv_sec != 0 || timeOut->tv_nsec != 0) && timeOut->tv_sec != INT_MAX) {
+        // Will need to correct timeOut by elapsed time.
+        startTimeNs = systemTime();
+    }
+    const size_t framesToRead = std::min(buffer->mFrameCount, mFrameCount);
+    buffer->mFrameCount = 0;
+    buffer->mRaw = nullptr;
+    sp<ThreadBase> thread;
+    sp<StreamInHalInterface> stream = obtainStream(&thread);
+    if (!stream) return NO_INIT;  // If there is no stream, RecordThread is not reading.
+
+    status_t result = NO_ERROR;
+    size_t bytesRead = 0;
+    {
+        ATRACE_NAME("read");
+        result = stream->read(mSinkBuffer.get(), framesToRead * mFrameSize, &bytesRead);
+        if (result != NO_ERROR) goto stream_error;
+        if (bytesRead == 0) return NO_ERROR;
+    }
+
+    {
+        std::lock_guard<std::mutex> lock(mReadLock);
+        mReadBytes += bytesRead;
+        mReadError = NO_ERROR;
+    }
+    mReadCV.notify_one();
+    // writeFrames handles wraparound and should write all the provided frames.
+    // If it couldn't, there is something wrong with the client/server buffer of the software patch.
+    buffer->mFrameCount = writeFrames(
+            &mPatchRecordAudioBufferProvider,
+            mSinkBuffer.get(), bytesRead / mFrameSize, mFrameSize);
+    ALOGW_IF(buffer->mFrameCount < bytesRead / mFrameSize,
+            "Lost %zu frames obtained from HAL", bytesRead / mFrameSize - buffer->mFrameCount);
+    mUnconsumedFrames = buffer->mFrameCount;
+    struct timespec newTimeOut;
+    if (startTimeNs) {
+        // Correct the timeout by elapsed time.
+        nsecs_t newTimeOutNs = audio_utils_ns_from_timespec(timeOut) - (systemTime() - startTimeNs);
+        if (newTimeOutNs < 0) newTimeOutNs = 0;
+        newTimeOut.tv_sec = newTimeOutNs / NANOS_PER_SECOND;
+        newTimeOut.tv_nsec = newTimeOutNs - newTimeOut.tv_sec * NANOS_PER_SECOND;
+        timeOut = &newTimeOut;
+    }
+    return PatchRecord::obtainBuffer(buffer, timeOut);
+
+stream_error:
+    stream->standby();
+    {
+        std::lock_guard<std::mutex> lock(mReadLock);
+        mReadError = result;
+    }
+    mReadCV.notify_one();
+    return result;
+}
+
+void AudioFlinger::RecordThread::PassthruPatchRecord::releaseBuffer(Proxy::Buffer* buffer)
+{
+    if (buffer->mFrameCount <= mUnconsumedFrames) {
+        mUnconsumedFrames -= buffer->mFrameCount;
+    } else {
+        ALOGW("Write side has consumed more frames than we had: %zu > %zu",
+                buffer->mFrameCount, mUnconsumedFrames);
+        mUnconsumedFrames = 0;
+    }
+    PatchRecord::releaseBuffer(buffer);
+}
+
+// AudioBufferProvider and Source methods are called on RecordThread
+// 'read' emulates actual audio data with 0's. This is OK as 'getNextBuffer'
+// and 'releaseBuffer' are stubbed out and ignore their input.
+// It's not possible to retrieve actual data here w/o blocking 'obtainBuffer'
+// until we copy it.
+status_t AudioFlinger::RecordThread::PassthruPatchRecord::read(
+        void* buffer, size_t bytes, size_t* read)
+{
+    bytes = std::min(bytes, mFrameCount * mFrameSize);
+    {
+        std::unique_lock<std::mutex> lock(mReadLock);
+        mReadCV.wait(lock, [&]{ return mReadError != NO_ERROR || mReadBytes != 0; });
+        if (mReadError != NO_ERROR) {
+            mLastReadFrames = 0;
+            return mReadError;
+        }
+        *read = std::min(bytes, mReadBytes);
+        mReadBytes -= *read;
+    }
+    mLastReadFrames = *read / mFrameSize;
+    memset(buffer, 0, *read);
+    return 0;
+}
+
+status_t AudioFlinger::RecordThread::PassthruPatchRecord::getCapturePosition(
+        int64_t* frames, int64_t* time)
+{
+    sp<ThreadBase> thread;
+    sp<StreamInHalInterface> stream = obtainStream(&thread);
+    return stream ? stream->getCapturePosition(frames, time) : NO_INIT;
+}
+
+status_t AudioFlinger::RecordThread::PassthruPatchRecord::standby()
+{
+    // RecordThread issues 'standby' command in two major cases:
+    // 1. Error on read--this case is handled in 'obtainBuffer'.
+    // 2. Track is stopping--as PassthruPatchRecord assumes continuous
+    //    output, this can only happen when the software patch
+    //    is being torn down. In this case, the RecordThread
+    //    will terminate and close the HAL stream.
+    return 0;
+}
+
+// As the buffer gets filled in obtainBuffer, here we only simulate data consumption.
+status_t AudioFlinger::RecordThread::PassthruPatchRecord::getNextBuffer(
+        AudioBufferProvider::Buffer* buffer)
+{
+    buffer->frameCount = mLastReadFrames;
+    buffer->raw = buffer->frameCount != 0 ? mStubBuffer.get() : nullptr;
+    return NO_ERROR;
+}
+
+void AudioFlinger::RecordThread::PassthruPatchRecord::releaseBuffer(
+        AudioBufferProvider::Buffer* buffer)
+{
+    buffer->frameCount = 0;
+    buffer->raw = nullptr;
+}
+
 // ----------------------------------------------------------------------------
 #undef LOG_TAG
 #define LOG_TAG "AF::MmapTrack"
diff --git a/services/audiopolicy/audio_policy.conf b/services/audiopolicy/audio_policy.conf
deleted file mode 100644
index 9b83fef..0000000
--- a/services/audiopolicy/audio_policy.conf
+++ /dev/null
@@ -1,145 +0,0 @@
-#
-# Template audio policy configuration file
-#
-
-# Global configuration section:
-# - before audio HAL version 3.0:
-#   lists input and output devices always present on the device
-#   as well as the output device selected by default.
-#   Devices are designated by a string that corresponds to the enum in audio.h
-#
-#  global_configuration {
-#    attached_output_devices AUDIO_DEVICE_OUT_SPEAKER
-#    default_output_device AUDIO_DEVICE_OUT_SPEAKER
-#    attached_input_devices AUDIO_DEVICE_IN_BUILTIN_MIC|AUDIO_DEVICE_IN_REMOTE_SUBMIX
-#  }
-#
-# - after and including audio HAL 3.0 the global_configuration section is included in each
-#   hardware module section.
-#   it also includes the audio HAL version of this hw module:
-#  global_configuration {
-#    ...
-#     audio_hal_version <major.minor>  # audio HAL version in e.g. 3.0
-#  }
-#   other attributes (attached devices, default device) have to be included in the
-#   global_configuration section of each hardware module
-
-
-# audio hardware module section: contains descriptors for all audio hw modules present on the
-# device. Each hw module node is named after the corresponding hw module library base name.
-# For instance, "primary" corresponds to audio.primary.<device>.so.
-# The "primary" module is mandatory and must include at least one output with
-# AUDIO_OUTPUT_FLAG_PRIMARY flag.
-# Each module descriptor contains one or more output profile descriptors and zero or more
-# input profile descriptors. Each profile lists all the parameters supported by a given output
-# or input stream category.
-# The "channel_masks", "formats", "devices" and "flags" are specified using strings corresponding
-# to enums in audio.h and audio_policy.h. They are concatenated by use of "|" without space or "\n".
-#
-# For audio HAL version posterior to 3.0 the following sections or sub sections can be present in
-# a hw module section:
-# - A "global_configuration" section: see above
-# - Optionally a "devices" section:
-#   This section contains descriptors for audio devices with attributes like an address or a
-#   gain controller. The syntax for the devices section and device descriptor is as follows:
-#    devices {
-#      <device name> {              # <device name>: any string without space
-#        type <device type>         # <device type> e.g. AUDIO_DEVICE_OUT_SPEAKER
-#        address <address>          # optional: device address, char string less than 64 in length
-#      }
-#    }
-# - one or more "gains" sections can be present in a device descriptor section.
-#   If present, they describe the capabilities of gain controllers attached to this input or
-#   output device. e.g. :
-#   <device name> {                  # <device name>: any string without space
-#     type <device type>             # <device type> e.g. AUDIO_DEVICE_OUT_SPEAKER
-#     address <address>              # optional: device address, char string less than 64 in length
-#     gains {
-#       <gain name> {
-#         mode <gain modes supported>              # e.g. AUDIO_GAIN_MODE_CHANNELS
-#         channel_mask <controlled channels>       # needed if mode AUDIO_GAIN_MODE_CHANNELS
-#         min_value_mB <min value in millibel>
-#         max_value_mB <max value in millibel>
-#         default_value_mB <default value in millibel>
-#         step_value_mB <step value in millibel>
-#         min_ramp_ms <min duration in ms>         # needed if mode AUDIO_GAIN_MODE_RAMP
-#         max_ramp_ms <max duration ms>            # needed if mode AUDIO_GAIN_MODE_RAMP
-#       }
-#     }
-#   }
-# - when a device descriptor is present, output and input profiles can refer to this device by
-# its name in their "devices" section instead of specifying a device type. e.g. :
-#   outputs {
-#     primary {
-#       sampling_rates 44100
-#       channel_masks AUDIO_CHANNEL_OUT_STEREO
-#       formats AUDIO_FORMAT_PCM_16_BIT
-#       devices <device name>
-#       flags AUDIO_OUTPUT_FLAG_PRIMARY
-#     }
-#   }
-# sample audio_policy.conf file below
-
-audio_hw_modules {
-  primary {
-    global_configuration {
-      attached_output_devices AUDIO_DEVICE_OUT_SPEAKER
-      default_output_device AUDIO_DEVICE_OUT_SPEAKER
-      attached_input_devices AUDIO_DEVICE_IN_BUILTIN_MIC
-      audio_hal_version 3.0
-    }
-    devices {
-      speaker {
-        type AUDIO_DEVICE_OUT_SPEAKER
-        gains {
-          gain_1 {
-            mode AUDIO_GAIN_MODE_JOINT
-            min_value_mB -8400
-            max_value_mB 4000
-            default_value_mB 0
-            step_value_mB 100
-          }
-        }
-      }
-    }
-    outputs {
-      primary {
-        sampling_rates 48000
-        channel_masks AUDIO_CHANNEL_OUT_STEREO
-        formats AUDIO_FORMAT_PCM_16_BIT
-        devices speaker
-        flags AUDIO_OUTPUT_FLAG_PRIMARY
-      }
-    }
-    inputs {
-      primary {
-        sampling_rates 8000|16000
-        channel_masks AUDIO_CHANNEL_IN_MONO
-        formats AUDIO_FORMAT_PCM_16_BIT
-        devices AUDIO_DEVICE_IN_BUILTIN_MIC
-      }
-    }
-  }
-  r_submix {
-    global_configuration {
-      attached_input_devices AUDIO_DEVICE_IN_REMOTE_SUBMIX
-      audio_hal_version 2.0
-    }
-    outputs {
-      submix {
-        sampling_rates 48000
-        channel_masks AUDIO_CHANNEL_OUT_STEREO
-        formats AUDIO_FORMAT_PCM_16_BIT
-        devices AUDIO_DEVICE_OUT_REMOTE_SUBMIX
-      }
-    }
-    inputs {
-      submix {
-        sampling_rates 48000
-        channel_masks AUDIO_CHANNEL_IN_STEREO
-        formats AUDIO_FORMAT_PCM_16_BIT
-        devices AUDIO_DEVICE_IN_REMOTE_SUBMIX
-      }
-    }
-  }
-}
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioPolicyConfig.h b/services/audiopolicy/common/managerdefinitions/include/AudioPolicyConfig.h
index 2264d8f..0776a8d 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioPolicyConfig.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioPolicyConfig.h
@@ -40,7 +40,8 @@
                       DeviceVector &availableOutputDevices,
                       DeviceVector &availableInputDevices,
                       sp<DeviceDescriptor> &defaultOutputDevice)
-        : mHwModules(hwModules),
+        : mEngineLibraryNameSuffix(kDefaultEngineLibraryNameSuffix),
+          mHwModules(hwModules),
           mAvailableOutputDevices(availableOutputDevices),
           mAvailableInputDevices(availableInputDevices),
           mDefaultOutputDevice(defaultOutputDevice),
@@ -55,6 +56,14 @@
         mSource = file;
     }
 
+    const std::string& getEngineLibraryNameSuffix() const {
+        return mEngineLibraryNameSuffix;
+    }
+
+    void setEngineLibraryNameSuffix(const std::string& suffix) {
+        mEngineLibraryNameSuffix = suffix;
+    }
+
     void setHwModules(const HwModuleCollection &hwModules)
     {
         mHwModules = hwModules;
@@ -108,6 +117,7 @@
     void setDefault(void)
     {
         mSource = "AudioPolicyConfig::setDefault";
+        mEngineLibraryNameSuffix = kDefaultEngineLibraryNameSuffix;
         mDefaultOutputDevice = new DeviceDescriptor(AUDIO_DEVICE_OUT_SPEAKER);
         mDefaultOutputDevice->addAudioProfile(AudioProfile::createFullDynamic());
         sp<DeviceDescriptor> defaultInputDevice = new DeviceDescriptor(AUDIO_DEVICE_IN_BUILTIN_MIC);
@@ -167,7 +177,10 @@
     }
 
 private:
+    static const constexpr char* const kDefaultEngineLibraryNameSuffix = "default";
+
     std::string mSource;
+    std::string mEngineLibraryNameSuffix;
     HwModuleCollection &mHwModules; /**< Collection of Module, with Profiles, i.e. Mix Ports. */
     DeviceVector &mAvailableOutputDevices;
     DeviceVector &mAvailableInputDevices;
diff --git a/services/audiopolicy/common/managerdefinitions/include/audio_policy_conf.h b/services/audiopolicy/common/managerdefinitions/include/audio_policy_conf.h
deleted file mode 100644
index 0a27947..0000000
--- a/services/audiopolicy/common/managerdefinitions/include/audio_policy_conf.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2012 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.
- */
-
-#pragma once
-
-
-/////////////////////////////////////////////////
-//      Definitions for audio policy configuration file (audio_policy.conf)
-/////////////////////////////////////////////////
-
-#define AUDIO_HARDWARE_MODULE_ID_MAX_LEN 32
-
-#define AUDIO_POLICY_CONFIG_FILE "/system/etc/audio_policy.conf"
-#define AUDIO_POLICY_VENDOR_CONFIG_FILE "/vendor/etc/audio_policy.conf"
-
-// global configuration
-#define GLOBAL_CONFIG_TAG "global_configuration"
-
-#define ATTACHED_OUTPUT_DEVICES_TAG "attached_output_devices"
-#define DEFAULT_OUTPUT_DEVICE_TAG "default_output_device"
-#define ATTACHED_INPUT_DEVICES_TAG "attached_input_devices"
-#define SPEAKER_DRC_ENABLED_TAG "speaker_drc_enabled"
-#define AUDIO_HAL_VERSION_TAG "audio_hal_version"
-
-// hw modules descriptions
-#define AUDIO_HW_MODULE_TAG "audio_hw_modules"
-
-#define OUTPUTS_TAG "outputs"
-#define INPUTS_TAG "inputs"
-
-#define SAMPLING_RATES_TAG "sampling_rates"
-#define FORMATS_TAG "formats"
-#define CHANNELS_TAG "channel_masks"
-#define DEVICES_TAG "devices"
-#define FLAGS_TAG "flags"
-
-#define APM_DEVICES_TAG "devices"
-#define APM_DEVICE_TYPE "type"
-#define APM_DEVICE_ADDRESS "address"
-
-#define MIXERS_TAG "mixers"
-#define MIXER_TYPE "type"
-#define MIXER_TYPE_MUX "mux"
-#define MIXER_TYPE_MIX "mix"
-
-#define GAINS_TAG "gains"
-#define GAIN_MODE "mode"
-#define GAIN_CHANNELS "channel_mask"
-#define GAIN_MIN_VALUE "min_value_mB"
-#define GAIN_MAX_VALUE "max_value_mB"
-#define GAIN_DEFAULT_VALUE "default_value_mB"
-#define GAIN_STEP_VALUE "step_value_mB"
-#define GAIN_MIN_RAMP_MS "min_ramp_ms"
-#define GAIN_MAX_RAMP_MS "max_ramp_ms"
-
-#define DYNAMIC_VALUE_TAG "dynamic" // special value for "channel_masks", "sampling_rates" and
-                                    // "formats" in outputs descriptors indicating that supported
-                                    // values should be queried after opening the output.
diff --git a/services/audiopolicy/common/managerdefinitions/src/IOProfile.cpp b/services/audiopolicy/common/managerdefinitions/src/IOProfile.cpp
index fe2eaee..f755fcd 100644
--- a/services/audiopolicy/common/managerdefinitions/src/IOProfile.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/IOProfile.cpp
@@ -79,7 +79,10 @@
         }
     }
 
-    if (isPlaybackThread && (getFlags() & flags) != flags) {
+    const uint32_t mustMatchOutputFlags =
+            AUDIO_OUTPUT_FLAG_DIRECT|AUDIO_OUTPUT_FLAG_HW_AV_SYNC|AUDIO_OUTPUT_FLAG_MMAP_NOIRQ;
+    if (isPlaybackThread && (((getFlags() ^ flags) & mustMatchOutputFlags)
+                    || (getFlags() & flags) != flags)) {
         return false;
     }
     // The only input flag that is allowed to be different is the fast flag.
diff --git a/services/audiopolicy/config/Android.bp b/services/audiopolicy/config/Android.bp
new file mode 100644
index 0000000..4b5e788
--- /dev/null
+++ b/services/audiopolicy/config/Android.bp
@@ -0,0 +1,101 @@
+/*
+ * 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.
+ */
+
+soong_namespace {
+}
+
+prebuilt_etc {
+    name: "a2dp_in_audio_policy_configuration.xml",
+    vendor: true,
+    src: ":a2dp_in_audio_policy_configuration",
+}
+prebuilt_etc {
+    name: "a2dp_audio_policy_configuration.xml",
+    vendor: true,
+    src: ":a2dp_audio_policy_configuration",
+}
+prebuilt_etc {
+    name: "audio_policy_configuration.xml",
+    vendor: true,
+    src: ":audio_policy_configuration_generic",
+}
+prebuilt_etc {
+    name: "r_submix_audio_policy_configuration.xml",
+    vendor: true,
+    src: ":r_submix_audio_policy_configuration",
+}
+prebuilt_etc {
+    name: "audio_policy_volumes.xml",
+    vendor: true,
+    src: ":audio_policy_volumes",
+}
+prebuilt_etc {
+    name: "default_volume_tables.xml",
+    vendor: true,
+    src: ":default_volume_tables",
+}
+prebuilt_etc {
+    name: "surround_sound_configuration_5_0.xml",
+    vendor: true,
+    src: ":surround_sound_configuration_5_0",
+}
+prebuilt_etc {
+    name: "usb_audio_policy_configuration.xml",
+    vendor: true,
+    src: ":usb_audio_policy_configuration",
+}
+prebuilt_etc {
+    name: "primary_audio_policy_configuration.xml",
+    src: ":primary_audio_policy_configuration",
+    vendor: true,
+}
+
+filegroup {
+    name: "a2dp_in_audio_policy_configuration",
+    srcs: ["a2dp_in_audio_policy_configuration.xml"],
+}
+filegroup {
+    name: "a2dp_audio_policy_configuration",
+    srcs: ["a2dp_audio_policy_configuration.xml"],
+}
+filegroup {
+    name: "primary_audio_policy_configuration",
+    srcs: ["primary_audio_policy_configuration.xml"],
+}
+filegroup {
+    name: "surround_sound_configuration_5_0",
+    srcs: ["surround_sound_configuration_5_0.xml"],
+}
+filegroup {
+    name: "default_volume_tables",
+    srcs: ["default_volume_tables.xml"],
+}
+filegroup {
+    name: "audio_policy_volumes",
+    srcs: ["audio_policy_volumes.xml"],
+}
+filegroup {
+    name: "audio_policy_configuration_generic",
+    srcs: ["audio_policy_configuration_generic.xml"],
+}
+filegroup {
+    name: "usb_audio_policy_configuration",
+    srcs: ["usb_audio_policy_configuration.xml"],
+}
+filegroup {
+    name: "r_submix_audio_policy_configuration",
+    srcs: ["r_submix_audio_policy_configuration.xml"],
+}
diff --git a/services/audiopolicy/engine/common/include/EngineBase.h b/services/audiopolicy/engine/common/include/EngineBase.h
index cedc78f..fca9a60 100644
--- a/services/audiopolicy/engine/common/include/EngineBase.h
+++ b/services/audiopolicy/engine/common/include/EngineBase.h
@@ -17,18 +17,18 @@
 #pragma once
 
 #include <EngineConfig.h>
-#include <AudioPolicyManagerInterface.h>
+#include <EngineInterface.h>
 #include <ProductStrategy.h>
 #include <VolumeGroup.h>
 
 namespace android {
 namespace audio_policy {
 
-class EngineBase : public AudioPolicyManagerInterface
+class EngineBase : public EngineInterface
 {
 public:
     ///
-    /// from AudioPolicyManagerInterface
+    /// from EngineInterface
     ///
     android::status_t initCheck() override;
 
diff --git a/services/audiopolicy/engine/common/include/ProductStrategy.h b/services/audiopolicy/engine/common/include/ProductStrategy.h
index 1a2a198..c538f52 100644
--- a/services/audiopolicy/engine/common/include/ProductStrategy.h
+++ b/services/audiopolicy/engine/common/include/ProductStrategy.h
@@ -19,7 +19,6 @@
 #include "VolumeGroup.h"
 
 #include <system/audio.h>
-#include <AudioPolicyManagerInterface.h>
 #include <utils/RefBase.h>
 #include <HandleGenerator.h>
 #include <string>
@@ -27,6 +26,7 @@
 #include <map>
 #include <utils/Errors.h>
 #include <utils/String8.h>
+#include <media/AudioAttributes.h>
 
 namespace android {
 
diff --git a/services/audiopolicy/engine/common/include/VolumeCurve.h b/services/audiopolicy/engine/common/include/VolumeCurve.h
index 54314e3..d3d0904 100644
--- a/services/audiopolicy/engine/common/include/VolumeCurve.h
+++ b/services/audiopolicy/engine/common/include/VolumeCurve.h
@@ -18,7 +18,6 @@
 
 #include "IVolumeCurves.h"
 #include <policy.h>
-#include <AudioPolicyManagerInterface.h>
 #include <utils/RefBase.h>
 #include <HandleGenerator.h>
 #include <utils/String8.h>
diff --git a/services/audiopolicy/engine/common/include/VolumeGroup.h b/services/audiopolicy/engine/common/include/VolumeGroup.h
index c34b406..5378f64 100644
--- a/services/audiopolicy/engine/common/include/VolumeGroup.h
+++ b/services/audiopolicy/engine/common/include/VolumeGroup.h
@@ -16,7 +16,6 @@
 
 #pragma once
 
-#include <AudioPolicyManagerInterface.h>
 #include <VolumeCurve.h>
 #include <system/audio.h>
 #include <utils/RefBase.h>
diff --git a/services/audiopolicy/engine/common/src/EngineBase.cpp b/services/audiopolicy/engine/common/src/EngineBase.cpp
index 07a7e65..840eb34 100644
--- a/services/audiopolicy/engine/common/src/EngineBase.cpp
+++ b/services/audiopolicy/engine/common/src/EngineBase.cpp
@@ -39,7 +39,7 @@
 {
     ALOGV("setPhoneState() state %d", state);
 
-    if (state < 0 || state >= AUDIO_MODE_CNT) {
+    if (state < 0 || uint32_t(state) >= AUDIO_MODE_CNT) {
         ALOGW("setPhoneState() invalid state %d", state);
         return BAD_VALUE;
     }
diff --git a/services/audiopolicy/engine/common/src/ProductStrategy.cpp b/services/audiopolicy/engine/common/src/ProductStrategy.cpp
index f74f190..ac3e462 100644
--- a/services/audiopolicy/engine/common/src/ProductStrategy.cpp
+++ b/services/audiopolicy/engine/common/src/ProductStrategy.cpp
@@ -19,6 +19,7 @@
 
 #include "ProductStrategy.h"
 
+#include <media/AudioProductStrategy.h>
 #include <media/TypeConverter.h>
 #include <utils/String8.h>
 #include <cstdint>
diff --git a/services/audiopolicy/engine/config/Android.bp b/services/audiopolicy/engine/config/Android.bp
index 6e72f2a..885b5fa 100644
--- a/services/audiopolicy/engine/config/Android.bp
+++ b/services/audiopolicy/engine/config/Android.bp
@@ -3,7 +3,6 @@
     export_include_dirs: ["include"],
     include_dirs: [
         "external/libxml2/include",
-        "external/icu/icu4c/source/common",
     ],
     srcs: [
         "src/EngineConfig.cpp",
diff --git a/services/audiopolicy/engine/config/src/EngineConfig.cpp b/services/audiopolicy/engine/config/src/EngineConfig.cpp
index 1ad7739..d47fbd2 100644
--- a/services/audiopolicy/engine/config/src/EngineConfig.cpp
+++ b/services/audiopolicy/engine/config/src/EngineConfig.cpp
@@ -32,9 +32,9 @@
 #include <istream>
 
 #include <cstdint>
+#include <stdarg.h>
 #include <string>
 
-
 namespace android {
 
 using utilities::convertTo;
@@ -603,7 +603,39 @@
     return NO_ERROR;
 }
 
+namespace {
+
+class XmlErrorHandler {
+public:
+    XmlErrorHandler() {
+        xmlSetGenericErrorFunc(this, &xmlErrorHandler);
+    }
+    XmlErrorHandler(const XmlErrorHandler&) = delete;
+    XmlErrorHandler(XmlErrorHandler&&) = delete;
+    XmlErrorHandler& operator=(const XmlErrorHandler&) = delete;
+    XmlErrorHandler& operator=(XmlErrorHandler&&) = delete;
+    ~XmlErrorHandler() {
+        xmlSetGenericErrorFunc(NULL, NULL);
+        if (!mErrorMessage.empty()) {
+            ALOG(LOG_ERROR, "libxml2", "%s", mErrorMessage.c_str());
+        }
+    }
+    static void xmlErrorHandler(void* ctx, const char* msg, ...) {
+        char buffer[256];
+        va_list args;
+        va_start(args, msg);
+        vsnprintf(buffer, sizeof(buffer), msg, args);
+        va_end(args);
+        static_cast<XmlErrorHandler*>(ctx)->mErrorMessage += buffer;
+    }
+private:
+    std::string mErrorMessage;
+};
+
+}  // namespace
+
 ParsingResult parse(const char* path) {
+    XmlErrorHandler errorHandler;
     xmlDocPtr doc;
     doc = xmlParseFile(path);
     if (doc == NULL) {
@@ -641,6 +673,7 @@
 }
 
 android::status_t parseLegacyVolumeFile(const char* path, VolumeGroups &volumeGroups) {
+    XmlErrorHandler errorHandler;
     xmlDocPtr doc;
     doc = xmlParseFile(path);
     if (doc == NULL) {
diff --git a/services/audiopolicy/engine/interface/AudioPolicyManagerInterface.h b/services/audiopolicy/engine/interface/EngineInterface.h
similarity index 97%
rename from services/audiopolicy/engine/interface/AudioPolicyManagerInterface.h
rename to services/audiopolicy/engine/interface/EngineInterface.h
index b7fd031..0c58a7c 100644
--- a/services/audiopolicy/engine/interface/AudioPolicyManagerInterface.h
+++ b/services/audiopolicy/engine/interface/EngineInterface.h
@@ -38,7 +38,7 @@
 /**
  * This interface is dedicated to the policy manager that a Policy Engine shall implement.
  */
-class AudioPolicyManagerInterface
+class EngineInterface
 {
 public:
     /**
@@ -295,7 +295,13 @@
     virtual void dump(String8 *dst) const = 0;
 
 protected:
-    virtual ~AudioPolicyManagerInterface() {}
+    virtual ~EngineInterface() {}
 };
 
+__attribute__((visibility("default")))
+extern "C" EngineInterface* createEngineInstance();
+
+__attribute__((visibility("default")))
+extern "C" void destroyEngineInstance(EngineInterface *engine);
+
 } // namespace android
diff --git a/services/audiopolicy/engineconfigurable/config/Android.bp b/services/audiopolicy/engineconfigurable/config/Android.bp
new file mode 100644
index 0000000..fe3eae0
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/config/Android.bp
@@ -0,0 +1,31 @@
+/*
+ * 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.
+ */
+
+// Root soong_namespace for common components
+
+prebuilt_etc {
+    name: "audio_policy_engine_criteria.xml",
+    vendor: true,
+    src: ":audio_policy_engine_criteria",
+}
+filegroup {
+    name: "audio_policy_engine_criterion_types_template",
+    srcs: ["example/common/audio_policy_engine_criterion_types.xml.in"],
+}
+filegroup {
+    name: "audio_policy_engine_criteria",
+    srcs: ["example/common/audio_policy_engine_criteria.xml"],
+}
diff --git a/services/audiopolicy/engineconfigurable/config/example/Android.mk b/services/audiopolicy/engineconfigurable/config/example/Android.mk
deleted file mode 100644
index a0f1a90..0000000
--- a/services/audiopolicy/engineconfigurable/config/example/Android.mk
+++ /dev/null
@@ -1,151 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-
-ifdef BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION
-
-TOOLS := frameworks/av/services/audiopolicy/engineconfigurable/tools
-PROVISION_CRITERION_TYPES := $(TOOLS)/provision_criterion_types_from_android_headers.mk
-
-##################################################################
-# CONFIGURATION TOP FILE
-##################################################################
-
-ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION), phone_configurable)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := audio_policy_engine_configuration.xml
-
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_CLASS := ETC
-LOCAL_VENDOR_MODULE := true
-LOCAL_SRC_FILES := phone/$(LOCAL_MODULE)
-
-LOCAL_REQUIRED_MODULES := \
-    audio_policy_engine_product_strategies.xml  \
-    audio_policy_engine_stream_volumes.xml \
-    audio_policy_engine_default_stream_volumes.xml \
-    audio_policy_engine_criteria.xml \
-    audio_policy_engine_criterion_types.xml
-
-include $(BUILD_PREBUILT)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := audio_policy_engine_product_strategies.xml
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_CLASS := ETC
-LOCAL_VENDOR_MODULE := true
-LOCAL_SRC_FILES := phone/$(LOCAL_MODULE)
-include $(BUILD_PREBUILT)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := audio_policy_engine_stream_volumes.xml
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_CLASS := ETC
-LOCAL_VENDOR_MODULE := true
-LOCAL_SRC_FILES := phone/$(LOCAL_MODULE)
-include $(BUILD_PREBUILT)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := audio_policy_engine_default_stream_volumes.xml
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_CLASS := ETC
-LOCAL_VENDOR_MODULE := true
-LOCAL_SRC_FILES := phone/$(LOCAL_MODULE)
-include $(BUILD_PREBUILT)
-
-endif # ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION), phone_configurable)
-
-
-ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),$(filter $(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),automotive_configurable caremu_configurable))
-
-##################################################################
-# AUTOMOTIVE CONFIGURATION TOP FILE
-##################################################################
-include $(CLEAR_VARS)
-LOCAL_MODULE := audio_policy_engine_configuration.xml
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_CLASS := ETC
-LOCAL_VENDOR_MODULE := true
-LOCAL_SRC_FILES := automotive/$(LOCAL_MODULE)
-
-LOCAL_REQUIRED_MODULES := \
-    audio_policy_engine_product_strategies.xml \
-    audio_policy_engine_criteria.xml \
-    audio_policy_engine_criterion_types.xml \
-    audio_policy_engine_volumes.xml
-
-include $(BUILD_PREBUILT)
-
-endif #ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),$(filter $(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),automotive_configurable caremu_configurable))
-
-ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION), automotive_configurable)
-
-##################################################################
-# CONFIGURATION FILES
-##################################################################
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := audio_policy_engine_product_strategies.xml
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_CLASS := ETC
-LOCAL_VENDOR_MODULE := true
-LOCAL_SRC_FILES := automotive/$(LOCAL_MODULE)
-include $(BUILD_PREBUILT)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := audio_policy_engine_volumes.xml
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_CLASS := ETC
-LOCAL_VENDOR_MODULE := true
-LOCAL_SRC_FILES := automotive/$(LOCAL_MODULE)
-include $(BUILD_PREBUILT)
-
-endif #ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION), automotive_configurable)
-
-ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION), caremu_configurable)
-
-##################################################################
-# CONFIGURATION FILES
-##################################################################
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := audio_policy_engine_product_strategies.xml
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_CLASS := ETC
-LOCAL_VENDOR_MODULE := true
-LOCAL_SRC_FILES := caremu/$(LOCAL_MODULE)
-include $(BUILD_PREBUILT)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := audio_policy_engine_volumes.xml
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_CLASS := ETC
-LOCAL_VENDOR_MODULE := true
-LOCAL_SRC_FILES := caremu/$(LOCAL_MODULE)
-include $(BUILD_PREBUILT)
-
-endif #ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION), caremu_configurable)
-
-ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),$(filter $(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),phone_configurable automotive_configurable caremu_configurable))
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := audio_policy_engine_criteria.xml
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_CLASS := ETC
-LOCAL_VENDOR_MODULE := true
-LOCAL_SRC_FILES := common/$(LOCAL_MODULE)
-include $(BUILD_PREBUILT)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := audio_policy_engine_criterion_types.xml
-LOCAL_MODULE_CLASS := ETC
-LOCAL_VENDOR_MODULE := true
-LOCAL_ADDITIONAL_DEPENDENCIES := $(TARGET_OUT_VENDOR_ETC)/primary_audio_policy_configuration.xml
-ANDROID_AUDIO_BASE_HEADER_FILE := system/media/audio/include/system/audio-base.h
-AUDIO_POLICY_CONFIGURATION_FILE := $(TARGET_OUT_VENDOR_ETC)/audio_policy_configuration.xml
-CRITERION_TYPES_FILE := $(LOCAL_PATH)/common/$(LOCAL_MODULE).in
-
-include $(PROVISION_CRITERION_TYPES)
-
-endif #ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),$(filter $(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),phone_configurable automotive_configurable caremu_configurable))
-
-endif #ifdef BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION
diff --git a/services/audiopolicy/engineconfigurable/config/example/automotive/Android.bp b/services/audiopolicy/engineconfigurable/config/example/automotive/Android.bp
new file mode 100644
index 0000000..f913a14
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/config/example/automotive/Android.bp
@@ -0,0 +1,94 @@
+/*
+ * 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.
+ */
+
+// Import this namespace in order to use AOSP Automotive configuration example
+
+soong_namespace {
+    imports: [
+        "frameworks/av/services/audiopolicy/config",
+    ],
+}
+
+prebuilt_etc {
+    name: "audio_policy_engine_configuration.xml",
+    vendor: true,
+    src: ":audio_policy_engine_configuration",
+    required: [
+        ":audio_policy_engine_criterion_types.xml",
+        ":audio_policy_engine_criteria.xml",
+        ":audio_policy_engine_product_strategies.xml",
+        ":audio_policy_engine_volumes.xml",
+    ],
+}
+prebuilt_etc {
+    name: "audio_policy_engine_product_strategies.xml",
+    vendor: true,
+    src: "audio_policy_engine_product_strategies.xml",
+}
+prebuilt_etc {
+    name: "audio_policy_engine_volumes.xml",
+    vendor: true,
+    src: ":audio_policy_engine_volumes",
+}
+prebuilt_etc {
+    name: "audio_policy_engine_criterion_types.xml",
+    vendor: true,
+    src: ":audio_policy_engine_criterion_types",
+}
+
+//
+// Generate audio_policy_engine criterion type file => provides device addresses criterion type
+//
+genrule {
+    name: "audio_policy_engine_criterion_types",
+    defaults: ["buildpolicycriteriontypesrule"],
+    srcs: [
+        ":audio_policy_configuration_top_file",
+        ":audio_policy_configuration_files",
+    ],
+}
+filegroup {
+    name: "audio_policy_configuration_files",
+    srcs: [
+        ":r_submix_audio_policy_configuration",
+        ":default_volume_tables",
+        ":audio_policy_volumes",
+        ":surround_sound_configuration_5_0",
+        ":primary_audio_policy_configuration",
+    ],
+}
+filegroup {
+    name : "audio_policy_configuration_top_file",
+    srcs: [":audio_policy_configuration_generic"],
+}
+filegroup {
+    name: "audio_policy_engine_configuration",
+    srcs: ["audio_policy_engine_configuration.xml"],
+}
+filegroup {
+    name: "audio_policy_engine_volumes",
+    srcs: ["audio_policy_engine_volumes.xml"],
+}
+filegroup {
+    name: "audio_policy_engine_configuration_files",
+    srcs: [
+        ":audio_policy_engine_configuration",
+        "audio_policy_engine_product_strategies.xml",
+        ":audio_policy_engine_volumes",
+        ":audio_policy_engine_criterion_types",
+        ":audio_policy_engine_criteria",
+    ],
+}
diff --git a/services/audiopolicy/engineconfigurable/config/example/caremu/Android.bp b/services/audiopolicy/engineconfigurable/config/example/caremu/Android.bp
new file mode 100644
index 0000000..fae6b7b
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/config/example/caremu/Android.bp
@@ -0,0 +1,82 @@
+/*
+ * 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.
+ */
+
+// Import this namespace in order to use AOSP Car Emulator configuration example
+
+soong_namespace {
+    imports: [
+        "frameworks/av/services/audiopolicy/engineconfigurable/config/example/automotive",
+        "frameworks/av/services/audiopolicy/config",
+    ],
+}
+
+prebuilt_etc {
+    name: "audio_policy_engine_configuration.xml",
+    vendor: true,
+    src: ":audio_policy_engine_configuration",
+    required: [
+        "audio_policy_engine_criterion_types.xml",
+        "audio_policy_engine_criteria.xml",
+        "audio_policy_engine_product_strategies.xml",
+        ":audio_policy_engine_volumes.xml",
+    ],
+}
+prebuilt_etc {
+    name: "audio_policy_engine_product_strategies.xml",
+    vendor: true,
+    src: "audio_policy_engine_product_strategies.xml",
+}
+prebuilt_etc {
+    name: "audio_policy_engine_criterion_types.xml",
+    vendor: true,
+    src: ":audio_policy_engine_criterion_types",
+}
+
+//
+// Generate audio_policy_engine criterion type file => provides device addresses criterion type
+//
+genrule {
+    name: "audio_policy_engine_criterion_types",
+    defaults: ["buildpolicycriteriontypesrule"],
+    srcs: [
+        ":audio_policy_configuration_top_file",
+        ":audio_policy_configuration_files",
+    ],
+}
+filegroup {
+    name: "audio_policy_configuration_files",
+    srcs: [
+        ":r_submix_audio_policy_configuration",
+        ":default_volume_tables",
+        ":audio_policy_volumes",
+        ":surround_sound_configuration_5_0",
+        ":primary_audio_policy_configuration",
+    ],
+}
+filegroup {
+    name : "audio_policy_configuration_top_file",
+    srcs: [":audio_policy_configuration_generic"],
+}
+filegroup {
+    name: "audio_policy_engine_configuration_files",
+    srcs: [
+        ":audio_policy_engine_configuration",
+        "audio_policy_engine_product_strategies.xml",
+        ":audio_policy_engine_volumes",
+        ":audio_policy_engine_criterion_types",
+        ":audio_policy_engine_criteria",
+    ],
+}
diff --git a/services/audiopolicy/engineconfigurable/config/example/phone/Android.bp b/services/audiopolicy/engineconfigurable/config/example/phone/Android.bp
new file mode 100644
index 0000000..94d33bd
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/config/example/phone/Android.bp
@@ -0,0 +1,104 @@
+/*
+ * 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.
+ */
+
+// Import this namespace in order to use AOSP Phone configuration example
+
+soong_namespace {
+    imports: [
+        "frameworks/av/services/audiopolicy/config",
+    ],
+}
+
+prebuilt_etc {
+    name: "audio_policy_engine_configuration.xml",
+    vendor: true,
+    src: ":audio_policy_engine_configuration",
+    required: [
+        ":audio_policy_engine_criterion_types.xml",
+        ":audio_policy_engine_criteria.xml",
+        ":audio_policy_engine_product_strategies.xml",
+        ":audio_policy_engine_volumes.xml",
+    ],
+}
+prebuilt_etc {
+    name: "audio_policy_engine_product_strategies.xml",
+    vendor: true,
+    src: "audio_policy_engine_product_strategies.xml",
+}
+prebuilt_etc {
+    name: "audio_policy_engine_stream_volumes.xml",
+    vendor: true,
+    src: ":audio_policy_engine_stream_volumes",
+}
+prebuilt_etc {
+    name: "audio_policy_engine_default_stream_volumes.xml",
+    vendor: true,
+    src: ":audio_policy_engine_default_stream_volumes",
+}
+prebuilt_etc {
+    name: "audio_policy_engine_criterion_types.xml",
+    vendor: true,
+    src: ":audio_policy_engine_criterion_types",
+}
+
+//
+// Generate audio_policy_engine criterion type file => provides device addresses criterion type
+//
+genrule {
+    name: "audio_policy_engine_criterion_types",
+    defaults: ["buildpolicycriteriontypesrule"],
+    srcs: [
+        ":audio_policy_configuration_top_file",
+        ":audio_policy_configuration_files",
+    ],
+}
+filegroup {
+    name: "audio_policy_configuration_files",
+    srcs: [
+        ":r_submix_audio_policy_configuration",
+        ":default_volume_tables",
+        ":audio_policy_volumes",
+        ":surround_sound_configuration_5_0",
+        ":primary_audio_policy_configuration",
+    ],
+}
+filegroup {
+    name : "audio_policy_configuration_top_file",
+    srcs: [":audio_policy_configuration_generic"],
+}
+filegroup {
+    name: "audio_policy_engine_configuration",
+    srcs: ["audio_policy_engine_configuration.xml"],
+}
+filegroup {
+    name: "audio_policy_engine_stream_volumes",
+    srcs: ["audio_policy_engine_stream_volumes.xml"],
+}
+filegroup {
+    name: "audio_policy_engine_default_stream_volumes",
+    srcs: ["audio_policy_engine_default_stream_volumes.xml"],
+}
+filegroup {
+    name: "audio_policy_engine_configuration_files",
+    srcs: [
+        ":audio_policy_engine_configuration",
+        "audio_policy_engine_product_strategies.xml",
+        ":audio_policy_engine_stream_volumes",
+        ":audio_policy_engine_default_stream_volumes",
+        ":audio_policy_engine_criterion_types",
+        ":audio_policy_engine_criteria",
+    ],
+}
diff --git a/services/audiopolicy/engineconfigurable/include/AudioPolicyEngineInstance.h b/services/audiopolicy/engineconfigurable/include/AudioPolicyEngineInstance.h
index efc69da..f52de21 100644
--- a/services/audiopolicy/engineconfigurable/include/AudioPolicyEngineInstance.h
+++ b/services/audiopolicy/engineconfigurable/include/AudioPolicyEngineInstance.h
@@ -16,7 +16,7 @@
 
 #pragma once
 
-class AudioPolicyManagerInterface;
+class EngineInterface;
 class AudioPolicyPluginInterface;
 
 namespace android {
@@ -69,7 +69,7 @@
  * Compile time error will claim if invalid interface is requested.
  */
 template <>
-AudioPolicyManagerInterface *EngineInstance::queryInterface() const;
+EngineInterface *EngineInstance::queryInterface() const;
 
 template <>
 AudioPolicyPluginInterface *EngineInstance::queryInterface() const;
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/Android.bp b/services/audiopolicy/engineconfigurable/parameter-framework/Android.bp
new file mode 100644
index 0000000..a0b874a
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/Android.bp
@@ -0,0 +1,73 @@
+/*
+ * 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.
+ */
+
+// Root soong_namespace for common components
+
+prebuilt_etc {
+    name: "PolicyClass.xml",
+    vendor: true,
+    src: ":PolicyClass",
+    sub_dir: "parameter-framework/Structure/Policy",
+}
+prebuilt_etc {
+    name: "PolicySubsystem.xml",
+    vendor: true,
+    src: ":PolicySubsystem",
+    sub_dir: "parameter-framework/Structure/Policy",
+}
+prebuilt_etc {
+    name: "PolicySubsystem-CommonTypes.xml",
+    vendor: true,
+    src: ":PolicySubsystem-CommonTypes",
+    sub_dir: "parameter-framework/Structure/Policy",
+}
+
+filegroup {
+    name: "product_strategies_structure_template",
+    srcs: ["examples/common/Structure/ProductStrategies.xml.in"],
+}
+filegroup {
+    name: "PolicySubsystem",
+    srcs: ["examples/common/Structure/PolicySubsystem.xml"],
+}
+filegroup {
+    name: "PolicySubsystem-no-strategy",
+    srcs: ["examples/common/Structure/PolicySubsystem-no-strategy.xml"],
+}
+filegroup {
+    name: "PolicySubsystem-CommonTypes",
+    srcs: ["examples/common/Structure/PolicySubsystem-CommonTypes.xml"],
+}
+filegroup {
+    name: "PolicyClass",
+    srcs: ["examples/common/Structure/PolicyClass.xml"],
+}
+filegroup {
+    name: "volumes.pfw",
+    srcs: ["examples/Settings/volumes.pfw"],
+}
+filegroup {
+    name: "device_for_input_source.pfw",
+    srcs: ["examples/Settings/device_for_input_source.pfw"],
+}
+filegroup {
+    name: "ParameterFrameworkConfigurationPolicy.userdebug.xml",
+    srcs: ["examples/ParameterFrameworkConfigurationPolicy.userdebug.xml"],
+}
+filegroup {
+    name: "ParameterFrameworkConfigurationPolicy.user.xml",
+    srcs: ["examples/ParameterFrameworkConfigurationPolicy.user.xml"],
+}
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Android.mk b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Android.mk
deleted file mode 100644
index 19f93b3..0000000
--- a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Android.mk
+++ /dev/null
@@ -1,187 +0,0 @@
-################################################################################################
-#
-# @NOTE:
-# Audio Policy Engine configurable example for generic device build
-#
-# Any vendor shall have its own configuration within the corresponding device folder
-#
-################################################################################################
-
-LOCAL_PATH := $(call my-dir)
-
-ifdef BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION
-
-ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),$(filter $(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),phone_configurable automotive_configurable caremu_configurable no-output_configurable no-input_configurable))
-
-PFW_CORE := external/parameter-framework
-#@TODO: upstream new domain generator
-#BUILD_PFW_SETTINGS := $(PFW_CORE)/support/android/build_pfw_settings.mk
-PFW_DEFAULT_SCHEMAS_DIR := $(PFW_CORE)/upstream/schemas
-PFW_SCHEMAS_DIR := $(PFW_DEFAULT_SCHEMAS_DIR)
-
-TOOLS := frameworks/av/services/audiopolicy/engineconfigurable/tools
-BUILD_PFW_SETTINGS := $(TOOLS)/build_audio_pfw_settings.mk
-
-PROVISION_STRATEGIES_STRUCTURE := $(TOOLS)/provision_strategies_structure.mk
-
-endif
-
-##################################################################
-# CONFIGURATION FILES
-##################################################################
-######### Policy PFW top level file #########
-
-ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),$(filter $(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),phone_configurable automotive_configurable caremu_configurable))
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := ParameterFrameworkConfigurationPolicy.xml
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_CLASS := ETC
-LOCAL_VENDOR_MODULE := true
-LOCAL_MODULE_RELATIVE_PATH := parameter-framework
-LOCAL_SRC_FILES := $(LOCAL_MODULE).in
-LOCAL_REQUIRED_MODULES := \
-    PolicySubsystem.xml \
-    PolicyClass.xml
-
-# external/parameter-framework prevents from using debug interface
-AUDIO_PATTERN = @TUNING_ALLOWED@
-ifeq ($(TARGET_BUILD_VARIANT),user)
-AUDIO_VALUE = false
-else
-AUDIO_VALUE = true
-endif
-
-LOCAL_POST_INSTALL_CMD := $(hide) sed -i -e 's|$(AUDIO_PATTERN)|$(AUDIO_VALUE)|g' $(TARGET_OUT_VENDOR_ETC)/$(LOCAL_MODULE_RELATIVE_PATH)/$(LOCAL_MODULE)
-
-include $(BUILD_PREBUILT)
-
-########## Policy PFW Common Structures #########
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := PolicySubsystem.xml
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_CLASS := ETC
-LOCAL_VENDOR_MODULE := true
-LOCAL_REQUIRED_MODULES := \
-    PolicySubsystem-CommonTypes.xml \
-    ProductStrategies.xml
-
-LOCAL_MODULE_RELATIVE_PATH := parameter-framework/Structure/Policy
-LOCAL_SRC_FILES := common/Structure/$(LOCAL_MODULE)
-include $(BUILD_PREBUILT)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := PolicySubsystem-CommonTypes.xml
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_CLASS := ETC
-LOCAL_VENDOR_MODULE := true
-LOCAL_MODULE_RELATIVE_PATH := parameter-framework/Structure/Policy
-LOCAL_SRC_FILES := common/Structure/$(LOCAL_MODULE)
-include $(BUILD_PREBUILT)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := PolicyClass.xml
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_CLASS := ETC
-LOCAL_VENDOR_MODULE := true
-LOCAL_MODULE_RELATIVE_PATH := parameter-framework/Structure/Policy
-LOCAL_SRC_FILES := common/Structure/$(LOCAL_MODULE)
-include $(BUILD_PREBUILT)
-
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := ProductStrategies.xml
-LOCAL_MODULE_CLASS := ETC
-LOCAL_VENDOR_MODULE := true
-LOCAL_MODULE_RELATIVE_PATH := parameter-framework/Structure/Policy
-
-AUDIO_POLICY_ENGINE_CONFIGURATION_FILE := \
-    $(TARGET_OUT_VENDOR_ETC)/audio_policy_engine_configuration.xml
-STRATEGIES_STRUCTURE_FILE := $(LOCAL_PATH)/common/Structure/$(LOCAL_MODULE).in
-
-include $(PROVISION_STRATEGIES_STRUCTURE)
-
-endif #ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),$(filter $(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),phone_configurable automotive_configurable caremu_configurable))
-
-########## Policy PFW Example Structures #########
-ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),$(filter $(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),no-output_configurable no-input_configurable))
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := PolicySubsystem.xml
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_CLASS := ETC
-LOCAL_VENDOR_MODULE := true
-LOCAL_REQUIRED_MODULES := PolicySubsystem-CommonTypes.xml
-
-LOCAL_MODULE_RELATIVE_PATH := parameter-framework/Structure/Policy
-LOCAL_SRC_FILES := common/Structure/$(LOCAL_MODULE)
-include $(BUILD_PREBUILT)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := ParameterFrameworkConfigurationPolicy-no-strategy.xml
-LOCAL_MODULE_STEM := ParameterFrameworkConfigurationPolicy.xml
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_CLASS := ETC
-LOCAL_VENDOR_MODULE := true
-LOCAL_MODULE_RELATIVE_PATH := parameter-framework
-LOCAL_SRC_FILES := $(LOCAL_MODULE).in
-LOCAL_REQUIRED_MODULES := \
-    PolicySubsystem.xml \
-    PolicyClass.xml
-AUDIO_VALUE = false
-LOCAL_POST_INSTALL_CMD := $(hide) sed -i -e 's|$(AUDIO_PATTERN)|$(AUDIO_VALUE)|g' $(TARGET_OUT_VENDOR_ETC)/$(LOCAL_MODULE_RELATIVE_PATH)/$(LOCAL_MODULE)
-
-include $(BUILD_PREBUILT)
-
-endif # ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),$(filter $(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),no-output_configurable no-input_configurable))
-
-######### Policy PFW Settings - No Output #########
-ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),no-output_configurable)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := parameter-framework.policy
-LOCAL_MODULE_STEM := PolicyConfigurableDomains-NoOutputDevice.xml
-LOCAL_MODULE_CLASS := ETC
-LOCAL_VENDOR_MODULE := true
-LOCAL_MODULE_RELATIVE_PATH := parameter-framework/Settings/Policy
-
-PFW_TOPLEVEL_FILE := $(TARGET_OUT_VENDOR_ETC)/parameter-framework/ParameterFrameworkConfigurationPolicy.xml
-PFW_CRITERION_TYPES_FILE := $(TARGET_OUT_VENDOR_ETC)/audio_policy_engine_criterion_types.xml
-PFW_CRITERIA_FILE := $(TARGET_OUT_VENDOR_ETC)/audio_policy_engine_criteria.xml
-PFW_EDD_FILES := \
-        $(LOCAL_PATH)/SettingsNoOutput/device_for_strategies.pfw \
-        $(LOCAL_PATH)/Settings/device_for_input_source.pfw \
-        $(LOCAL_PATH)/Settings/volumes.pfw        
-LOCAL_REQUIRED_MODULES := libpolicy-subsystem
-include $(BUILD_PFW_SETTINGS)
-
-endif # ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),no-output_configurable)
-######### Policy PFW Settings - No Input #########
-ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),no-input_configurable)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := parameter-framework.policy
-LOCAL_MODULE_STEM := PolicyConfigurableDomains-NoInputDevice.xml
-LOCAL_MODULE_CLASS := ETC
-LOCAL_VENDOR_MODULE := true
-LOCAL_MODULE_RELATIVE_PATH := parameter-framework/Settings/Policy
-
-PFW_TOPLEVEL_FILE := $(TARGET_OUT_VENDOR_ETC)/parameter-framework/ParameterFrameworkConfigurationPolicy.xml
-PFW_CRITERION_TYPES_FILE := $(TARGET_OUT_VENDOR_ETC)/audio_policy_engine_criterion_types.xml
-PFW_CRITERIA_FILE := $(TARGET_OUT_VENDOR_ETC)/audio_policy_engine_criteria.xml
-PFW_EDD_FILES := \
-        $(LOCAL_PATH)/SettingsNoInput/device_for_input_source.pfw \
-        $(LOCAL_PATH)/Settings/volumes.pfw
-LOCAL_REQUIRED_MODULES := libpolicy-subsystem
-include $(BUILD_PFW_SETTINGS)
-
-endif #ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),no-input_configurable)
-#######################################################################
-# Recursive call sub-folder Android.mk
-#######################################################################
-
-include $(call all-makefiles-under,$(LOCAL_PATH))
-
-endif #ifdef BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION
-
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Car/Android.bp b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Car/Android.bp
new file mode 100644
index 0000000..5078268
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Car/Android.bp
@@ -0,0 +1,91 @@
+/*
+ * 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.
+ */
+
+// Import this namespace in order to use AOSP Automotive configuration example
+
+soong_namespace {
+    imports: [
+        "frameworks/av/services/audiopolicy/engineconfigurable/config/example/automotive",
+        "frameworks/av/services/audiopolicy/config",
+    ],
+}
+
+//
+// Generate Audio Policy Parameter Framework Product Strategies Structure file from template
+//
+prebuilt_etc {
+    name: "ProductStrategies.xml",
+    vendor: true,
+    src: ":buildstrategiesstructure_gen",
+    sub_dir: "parameter-framework/Structure/Policy",
+    required: ["libpolicy-subsystem"],
+}
+genrule {
+    name: "buildstrategiesstructure_gen",
+    defaults: ["buildstrategiesstructurerule"],
+    srcs: [
+        ":audio_policy_engine_configuration_files",
+    ],
+}
+
+//
+// Generate Audio Policy Parameter Framework Configurable Domains
+//
+prebuilt_etc {
+    name: "parameter-framework.policy",
+    filename_from_src: true,
+    vendor: true,
+    src: ":domaingeneratorpolicyrule_gen",
+    sub_dir: "parameter-framework/Settings/Policy",
+    required: [
+        "ProductStrategies.xml",
+        "PolicyClass.xml",
+        "PolicySubsystem.xml",
+        "PolicySubsystem-CommonTypes.xml",
+    ],
+}
+genrule {
+    name: "domaingeneratorpolicyrule_gen",
+    defaults: ["domaingeneratorpolicyrule"],
+    srcs: [
+        ":audio_policy_pfw_toplevel",
+        ":audio_policy_pfw_structure_files",
+        ":audio_policy_engine_criterion_types",
+        ":edd_files",
+    ],
+}
+filegroup {
+    name: "edd_files",
+    srcs: [
+        ":device_for_input_source.pfw",
+        ":volumes.pfw",
+        "Settings/device_for_product_strategies.pfw",
+    ],
+}
+// This is for Settings generation, must use socket port, so userdebug version is required
+filegroup {
+    name: "audio_policy_pfw_toplevel",
+    srcs: [":ParameterFrameworkConfigurationPolicy.userdebug.xml"],
+}
+filegroup {
+    name: "audio_policy_pfw_structure_files",
+    srcs: [
+        ":PolicyClass",
+        ":PolicySubsystem",
+        ":PolicySubsystem-CommonTypes",
+        ":buildstrategiesstructure_gen",
+    ],
+}
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Car/Android.mk b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Car/Android.mk
deleted file mode 100644
index 7304ec2..0000000
--- a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Car/Android.mk
+++ /dev/null
@@ -1,47 +0,0 @@
-################################################################################################
-#
-# @NOTE:
-# Audio Policy Engine configurable example for generic device build
-#
-# Any vendor shall have its own configuration within the corresponding device folder
-#
-################################################################################################
-
-ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION), automotive_configurable)
-LOCAL_PATH := $(call my-dir)
-
-PFW_CORE := external/parameter-framework
-PFW_DEFAULT_SCHEMAS_DIR := $(PFW_CORE)/upstream/schemas
-PFW_SCHEMAS_DIR := $(PFW_DEFAULT_SCHEMAS_DIR)
-
-TOOLS := frameworks/av/services/audiopolicy/engineconfigurable/tools
-BUILD_PFW_SETTINGS := $(TOOLS)/build_audio_pfw_settings.mk
-
-
-##################################################################
-# CONFIGURATION FILES
-##################################################################
-
-########## Policy PFW Structures #########
-######### Policy PFW Settings #########
-include $(CLEAR_VARS)
-LOCAL_MODULE := parameter-framework.policy
-LOCAL_MODULE_STEM := PolicyConfigurableDomains.xml
-LOCAL_MODULE_CLASS := ETC
-LOCAL_VENDOR_MODULE := true
-LOCAL_MODULE_RELATIVE_PATH := parameter-framework/Settings/Policy
-LOCAL_REQUIRED_MODULES := libpolicy-subsystem
-
-PFW_EDD_FILES := \
-    $(LOCAL_PATH)/Settings/device_for_product_strategies.pfw \
-    $(LOCAL_PATH)/../Settings/device_for_input_source.pfw \
-    $(LOCAL_PATH)/../Settings/volumes.pfw
-
-PFW_CRITERION_TYPES_FILE := $(TARGET_OUT_VENDOR_ETC)/audio_policy_engine_criterion_types.xml
-PFW_CRITERIA_FILE := $(TARGET_OUT_VENDOR_ETC)/audio_policy_engine_criteria.xml
-PFW_TOPLEVEL_FILE := $(TARGET_OUT_VENDOR_ETC)/parameter-framework/ParameterFrameworkConfigurationPolicy.xml
-PFW_SCHEMAS_DIR := $(PFW_DEFAULT_SCHEMAS_DIR)
-
-include $(BUILD_PFW_SETTINGS)
-
-endif #ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION), automotive_configurable)
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/CarEmu/Android.bp b/services/audiopolicy/engineconfigurable/parameter-framework/examples/CarEmu/Android.bp
new file mode 100644
index 0000000..0917440
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/CarEmu/Android.bp
@@ -0,0 +1,92 @@
+/*
+ * 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.
+ */
+
+// Import this namespace in order to use AOSP Car Emulator configuration example
+
+soong_namespace {
+    imports: [
+        "frameworks/av/services/audiopolicy/engineconfigurable/config/example/caremu",
+        "frameworks/av/services/audiopolicy/engineconfigurable/parameter-framework/examples/Car",
+        "frameworks/av/services/audiopolicy/config",
+    ],
+}
+
+//
+// Generate Audio Policy Parameter Framework Product Strategies Structure file from template
+//
+prebuilt_etc {
+    name: "ProductStrategies.xml",
+    vendor: true,
+    src: ":buildstrategiesstructure_gen",
+    sub_dir: "parameter-framework/Structure/Policy",
+    required: ["libpolicy-subsystem"],
+}
+genrule {
+    name: "buildstrategiesstructure_gen",
+    defaults: ["buildstrategiesstructurerule"],
+    srcs: [
+        ":audio_policy_engine_configuration_files",
+    ],
+}
+
+//
+// Generate Audio Policy Parameter Framework Configurable Domains
+//
+prebuilt_etc {
+    name: "parameter-framework.policy",
+    filename_from_src: true,
+    vendor: true,
+    src: ":domaingeneratorpolicyrule_gen",
+    sub_dir: "parameter-framework/Settings/Policy",
+    required: [
+        "ProductStrategies.xml",
+        "PolicyClass.xml",
+        "PolicySubsystem.xml",
+        "PolicySubsystem-CommonTypes.xml",
+    ],
+}
+genrule {
+    name: "domaingeneratorpolicyrule_gen",
+    defaults: ["domaingeneratorpolicyrule"],
+    srcs: [
+        ":audio_policy_pfw_toplevel",
+        ":audio_policy_pfw_structure_files",
+        ":audio_policy_engine_criterion_types",
+        ":edd_files",
+    ],
+}
+filegroup {
+    name: "edd_files",
+    srcs: [
+        ":device_for_input_source.pfw",
+        ":volumes.pfw",
+        "Settings/device_for_product_strategies.pfw",
+    ],
+}
+// This is for Settings generation, must use socket port, so userdebug version is required
+filegroup {
+    name: "audio_policy_pfw_toplevel",
+    srcs: [":ParameterFrameworkConfigurationPolicy.userdebug.xml"],
+}
+filegroup {
+    name: "audio_policy_pfw_structure_files",
+    srcs: [
+        ":PolicyClass",
+        ":PolicySubsystem",
+        ":PolicySubsystem-CommonTypes",
+        ":buildstrategiesstructure_gen",
+    ],
+}
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/CarEmu/Android.mk b/services/audiopolicy/engineconfigurable/parameter-framework/examples/CarEmu/Android.mk
deleted file mode 100644
index f5eb7d1..0000000
--- a/services/audiopolicy/engineconfigurable/parameter-framework/examples/CarEmu/Android.mk
+++ /dev/null
@@ -1,46 +0,0 @@
-################################################################################################
-#
-# @NOTE:
-# Audio Policy Engine configurable example for generic device build
-#
-# Any vendor shall have its own configuration within the corresponding device folder
-#
-################################################################################################
-
-ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION), caremu_configurable)
-LOCAL_PATH := $(call my-dir)
-
-PFW_CORE := external/parameter-framework
-PFW_DEFAULT_SCHEMAS_DIR := $(PFW_CORE)/upstream/schemas
-PFW_SCHEMAS_DIR := $(PFW_DEFAULT_SCHEMAS_DIR)
-
-TOOLS := frameworks/av/services/audiopolicy/engineconfigurable/tools
-BUILD_PFW_SETTINGS := $(TOOLS)/build_audio_pfw_settings.mk
-
-
-##################################################################
-# CONFIGURATION FILES
-##################################################################
-
-########## Policy PFW Structures #########
-######### Policy PFW Settings #########
-include $(CLEAR_VARS)
-LOCAL_MODULE := parameter-framework.policy
-LOCAL_MODULE_STEM := PolicyConfigurableDomains.xml
-LOCAL_MODULE_CLASS := ETC
-LOCAL_VENDOR_MODULE := true
-LOCAL_MODULE_RELATIVE_PATH := parameter-framework/Settings/Policy
-LOCAL_REQUIRED_MODULES := libpolicy-subsystem
-
-PFW_EDD_FILES := \
-    $(LOCAL_PATH)/Settings/device_for_product_strategies.pfw \
-    $(LOCAL_PATH)/../Settings/device_for_input_source.pfw \
-    $(LOCAL_PATH)/../Settings/volumes.pfw
-PFW_CRITERION_TYPES_FILE := $(TARGET_OUT_VENDOR_ETC)/audio_policy_engine_criterion_types.xml
-PFW_CRITERIA_FILE := $(TARGET_OUT_VENDOR_ETC)/audio_policy_engine_criteria.xml
-PFW_TOPLEVEL_FILE := $(TARGET_OUT_VENDOR_ETC)/parameter-framework/ParameterFrameworkConfigurationPolicy.xml
-PFW_SCHEMAS_DIR := $(PFW_DEFAULT_SCHEMAS_DIR)
-
-include $(BUILD_PFW_SETTINGS)
-
-endif #ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION), caremu_configurable)
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/ParameterFrameworkConfigurationPolicy.xml.in b/services/audiopolicy/engineconfigurable/parameter-framework/examples/ParameterFrameworkConfigurationPolicy.user.xml
similarity index 81%
copy from services/audiopolicy/engineconfigurable/parameter-framework/examples/ParameterFrameworkConfigurationPolicy.xml.in
copy to services/audiopolicy/engineconfigurable/parameter-framework/examples/ParameterFrameworkConfigurationPolicy.user.xml
index 1be67dd..c5960cb 100644
--- a/services/audiopolicy/engineconfigurable/parameter-framework/examples/ParameterFrameworkConfigurationPolicy.xml.in
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/ParameterFrameworkConfigurationPolicy.user.xml
@@ -1,7 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <ParameterFrameworkConfiguration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-    SystemClassName="Policy" ServerPort="unix:///dev/socket/audioserver/policy_debug"
-    TuningAllowed="@TUNING_ALLOWED@">
+    SystemClassName="Policy" TuningAllowed="false">
 
     <SubsystemPlugins>
         <Location Folder="">
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/ParameterFrameworkConfigurationPolicy.xml.in b/services/audiopolicy/engineconfigurable/parameter-framework/examples/ParameterFrameworkConfigurationPolicy.userdebug.xml
similarity index 93%
rename from services/audiopolicy/engineconfigurable/parameter-framework/examples/ParameterFrameworkConfigurationPolicy.xml.in
rename to services/audiopolicy/engineconfigurable/parameter-framework/examples/ParameterFrameworkConfigurationPolicy.userdebug.xml
index 1be67dd..1b7d7d8 100644
--- a/services/audiopolicy/engineconfigurable/parameter-framework/examples/ParameterFrameworkConfigurationPolicy.xml.in
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/ParameterFrameworkConfigurationPolicy.userdebug.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <ParameterFrameworkConfiguration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     SystemClassName="Policy" ServerPort="unix:///dev/socket/audioserver/policy_debug"
-    TuningAllowed="@TUNING_ALLOWED@">
+    TuningAllowed="true">
 
     <SubsystemPlugins>
         <Location Folder="">
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Android.bp b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Android.bp
new file mode 100644
index 0000000..11e220b
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Android.bp
@@ -0,0 +1,100 @@
+/*
+ * 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.
+ */
+
+// Import this namespace in order to use AOSP Phone configuration example
+
+soong_namespace {
+    imports: [
+        "frameworks/av/services/audiopolicy/engineconfigurable/config/example/phone",
+        "frameworks/av/services/audiopolicy/config",
+    ],
+}
+
+//
+// Generate Audio Policy Parameter Framework Product Strategies Structure file from template
+//
+prebuilt_etc {
+    name: "ProductStrategies.xml",
+    vendor: true,
+    src: ":buildstrategiesstructure_gen",
+    sub_dir: "parameter-framework/Structure/Policy",
+    required: ["libpolicy-subsystem"],
+}
+genrule {
+    name: "buildstrategiesstructure_gen",
+    defaults: ["buildstrategiesstructurerule"],
+    srcs: [
+        ":audio_policy_engine_configuration_files",
+    ],
+}
+
+//
+// Generate Audio Policy Parameter Framework Configurable Domains
+//
+prebuilt_etc {
+    name: "parameter-framework.policy",
+    filename_from_src: true,
+    vendor: true,
+    src: ":domaingeneratorpolicyrule_gen",
+    sub_dir: "parameter-framework/Settings/Policy",
+    required: [
+        "ProductStrategies.xml",
+        "PolicyClass.xml",
+        "PolicySubsystem.xml",
+        "PolicySubsystem-CommonTypes.xml",
+    ],
+}
+genrule {
+    name: "domaingeneratorpolicyrule_gen",
+    defaults: ["domaingeneratorpolicyrule"],
+    srcs: [
+        ":audio_policy_pfw_toplevel",
+        ":audio_policy_pfw_structure_files",
+        ":audio_policy_engine_criterion_types",
+        ":edd_files",
+    ],
+}
+filegroup {
+    name: "edd_files",
+    srcs: [
+        ":device_for_input_source.pfw",
+        ":volumes.pfw",
+        "Settings/device_for_product_strategy_media.pfw",
+        "Settings/device_for_product_strategy_accessibility.pfw",
+        "Settings/device_for_product_strategy_dtmf.pfw",
+        "Settings/device_for_product_strategy_enforced_audible.pfw",
+        "Settings/device_for_product_strategy_phone.pfw",
+        "Settings/device_for_product_strategy_sonification.pfw",
+        "Settings/device_for_product_strategy_sonification_respectful.pfw",
+        "Settings/device_for_product_strategy_transmitted_through_speaker.pfw",
+        "Settings/device_for_product_strategy_rerouting.pfw",
+        "Settings/device_for_product_strategy_patch.pfw",
+    ],
+}
+// This is for Settings generation, must use socket port, so userdebug version is required
+filegroup {
+    name: "audio_policy_pfw_toplevel",
+    srcs: [":ParameterFrameworkConfigurationPolicy.userdebug.xml"],
+}
+filegroup {
+    name: "audio_policy_pfw_structure_files",
+    srcs: [
+        ":PolicyClass",
+        ":PolicySubsystem",
+        ":PolicySubsystem-CommonTypes",
+        ":buildstrategiesstructure_gen",
+    ],
+}
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Android.mk b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Android.mk
deleted file mode 100644
index 0b20781..0000000
--- a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Android.mk
+++ /dev/null
@@ -1,54 +0,0 @@
-################################################################################################
-#
-# @NOTE:
-# Audio Policy Engine configurable example for generic device build
-#
-# Any vendor shall have its own configuration within the corresponding device folder
-#
-################################################################################################
-
-ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION), phone_configurable)
-
-LOCAL_PATH := $(call my-dir)
-
-PFW_CORE := external/parameter-framework
-PFW_DEFAULT_SCHEMAS_DIR := $(PFW_CORE)/upstream/schemas
-PFW_SCHEMAS_DIR := $(PFW_DEFAULT_SCHEMAS_DIR)
-
-TOOLS := frameworks/av/services/audiopolicy/engineconfigurable/tools
-BUILD_PFW_SETTINGS := $(TOOLS)/build_audio_pfw_settings.mk
-
-##################################################################
-# CONFIGURATION FILES
-##################################################################
-########## Policy PFW Structures #########
-######### Policy PFW Settings #########
-include $(CLEAR_VARS)
-LOCAL_MODULE := parameter-framework.policy
-LOCAL_MODULE_STEM := PolicyConfigurableDomains.xml
-LOCAL_MODULE_CLASS := ETC
-LOCAL_VENDOR_MODULE := true
-LOCAL_MODULE_RELATIVE_PATH := parameter-framework/Settings/Policy
-LOCAL_REQUIRED_MODULES := libpolicy-subsystem
-
-PFW_EDD_FILES := \
-        $(LOCAL_PATH)/../Settings/device_for_input_source.pfw \
-        $(LOCAL_PATH)/../Settings/volumes.pfw \
-        $(LOCAL_PATH)/Settings/device_for_product_strategy_media.pfw \
-        $(LOCAL_PATH)/Settings/device_for_product_strategy_accessibility.pfw \
-        $(LOCAL_PATH)/Settings/device_for_product_strategy_dtmf.pfw \
-        $(LOCAL_PATH)/Settings/device_for_product_strategy_enforced_audible.pfw \
-        $(LOCAL_PATH)/Settings/device_for_product_strategy_phone.pfw \
-        $(LOCAL_PATH)/Settings/device_for_product_strategy_sonification.pfw \
-        $(LOCAL_PATH)/Settings/device_for_product_strategy_sonification_respectful.pfw \
-        $(LOCAL_PATH)/Settings/device_for_product_strategy_transmitted_through_speaker.pfw \
-        $(LOCAL_PATH)/Settings/device_for_product_strategy_rerouting.pfw \
-        $(LOCAL_PATH)/Settings/device_for_product_strategy_patch.pfw
-PFW_CRITERION_TYPES_FILE := $(TARGET_OUT_VENDOR_ETC)/audio_policy_engine_criterion_types.xml
-PFW_CRITERIA_FILE := $(TARGET_OUT_VENDOR_ETC)/audio_policy_engine_criteria.xml
-PFW_TOPLEVEL_FILE := $(TARGET_OUT_VENDOR_ETC)/parameter-framework/ParameterFrameworkConfigurationPolicy.xml
-PFW_SCHEMAS_DIR := $(PFW_DEFAULT_SCHEMAS_DIR)
-
-include $(BUILD_PFW_SETTINGS)
-
-endif #ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION), phone_configurable)
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_input_source.pfw b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_input_source.pfw
index a990879..9e0957c 100644
--- a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_input_source.pfw
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_input_source.pfw
@@ -18,7 +18,6 @@
 				loopback = 0
 				ip = 0
 				bus = 0
-				stub = 0
 			component: /Policy/policy/input_sources/mic/applicable_input_device/mask
 				communication = 0
 				ambient = 0
@@ -36,7 +35,6 @@
 				loopback = 0
 				ip = 0
 				bus = 0
-				stub = 0
 			component: /Policy/policy/input_sources/voice_downlink/applicable_input_device/mask
 				communication = 0
 				ambient = 0
@@ -58,7 +56,6 @@
 				loopback = 0
 				ip = 0
 				bus = 0
-				stub = 0
 			component: /Policy/policy/input_sources/voice_call/applicable_input_device/mask
 				communication = 0
 				ambient = 0
@@ -80,7 +77,6 @@
 				loopback = 0
 				ip = 0
 				bus = 0
-				stub = 0
 			component: /Policy/policy/input_sources/voice_uplink/applicable_input_device/mask
 				communication = 0
 				ambient = 0
@@ -102,7 +98,6 @@
 				loopback = 0
 				ip = 0
 				bus = 0
-				stub = 0
 			component: /Policy/policy/input_sources/camcorder/applicable_input_device/mask
 				communication = 0
 				ambient = 0
@@ -123,7 +118,6 @@
 				loopback = 0
 				ip = 0
 				bus = 0
-				stub = 0
 			component: /Policy/policy/input_sources/voice_recognition/applicable_input_device/mask
 				communication = 0
 				ambient = 0
@@ -142,7 +136,6 @@
 				loopback = 0
 				ip = 0
 				bus = 0
-				stub = 0
 			component: /Policy/policy/input_sources/voice_communication/applicable_input_device/mask
 				communication = 0
 				ambient = 0
@@ -160,7 +153,6 @@
 				loopback = 0
 				ip = 0
 				bus = 0
-				stub = 0
 			component: /Policy/policy/input_sources/remote_submix/applicable_input_device/mask
 				communication = 0
 				ambient = 0
@@ -182,7 +174,6 @@
 				loopback = 0
 				ip = 0
 				bus = 0
-				stub = 0
 			component: /Policy/policy/input_sources/hotword/applicable_input_device/mask
 				communication = 0
 				ambient = 0
@@ -201,7 +192,6 @@
 				loopback = 0
 				ip = 0
 				bus = 0
-				stub = 0
 			component: /Policy/policy/input_sources/unprocessed/applicable_input_device/mask
 				communication = 0
 				ambient = 0
@@ -220,7 +210,6 @@
 				loopback = 0
 				ip = 0
 				bus = 0
-				stub = 0
 			component: /Policy/policy/input_sources/fm_tuner/applicable_input_device/mask
 				communication = 0
 				ambient = 0
@@ -242,7 +231,6 @@
 				loopback = 0
 				ip = 0
 				bus = 0
-				stub = 0
 
 	domain: DefaultAndMic
 		conf: A2dp
@@ -255,12 +243,14 @@
 					usb_device = 0
 					builtin_mic = 0
 					bluetooth_sco_headset = 0
+					stub = 0
 				component: mic/applicable_input_device/mask/
 					bluetooth_a2dp = 1
 					wired_headset = 0
 					usb_device = 0
 					builtin_mic = 0
 					bluetooth_sco_headset = 0
+					stub = 0
 
 		conf: Sco
 			AvailableInputDevices Includes BluetoothScoHeadset
@@ -273,12 +263,14 @@
 					usb_device = 0
 					builtin_mic = 0
 					bluetooth_sco_headset = 1
+					stub = 0
 				component: mic/applicable_input_device/mask/
 					bluetooth_a2dp = 0
 					wired_headset = 0
 					usb_device = 0
 					builtin_mic = 0
 					bluetooth_sco_headset = 1
+					stub = 0
 
 		conf: WiredHeadset
 			AvailableInputDevices Includes WiredHeadset
@@ -290,12 +282,14 @@
 					usb_device = 0
 					builtin_mic = 0
 					bluetooth_sco_headset = 0
+					stub = 0
 				component: mic/applicable_input_device/mask/
 					bluetooth_a2dp = 0
 					wired_headset = 1
 					usb_device = 0
 					builtin_mic = 0
 					bluetooth_sco_headset = 0
+					stub = 0
 
 		conf: UsbDevice
 			AvailableInputDevices Includes UsbDevice
@@ -307,12 +301,14 @@
 					usb_device = 1
 					builtin_mic = 0
 					bluetooth_sco_headset = 0
+					stub = 0
 				component: mic/applicable_input_device/mask/
 					bluetooth_a2dp = 0
 					wired_headset = 0
 					usb_device = 1
 					builtin_mic = 0
 					bluetooth_sco_headset = 0
+					stub = 0
 
 		conf: BuiltinMic
 			AvailableInputDevices Includes BuiltinMic
@@ -324,12 +320,33 @@
 					usb_device = 0
 					builtin_mic = 1
 					bluetooth_sco_headset = 0
+					stub = 0
 				component: mic/applicable_input_device/mask/
 					bluetooth_a2dp = 0
 					wired_headset = 0
 					usb_device = 0
 					builtin_mic = 1
 					bluetooth_sco_headset = 0
+					stub = 0
+
+		conf: Stub
+			AvailableInputDevices Includes Default
+
+			component: /Policy/policy/input_sources
+				component: default/applicable_input_device/mask/
+					bluetooth_a2dp = 0
+					wired_headset = 0
+					usb_device = 0
+					builtin_mic = 0
+					bluetooth_sco_headset = 0
+					stub = 1
+				component: mic/applicable_input_device/mask/
+					bluetooth_a2dp = 0
+					wired_headset = 0
+					usb_device = 0
+					builtin_mic = 0
+					bluetooth_sco_headset = 0
+					stub = 1
 
 		conf: Default
 			component: /Policy/policy/input_sources
@@ -339,12 +356,14 @@
 					usb_device = 0
 					builtin_mic = 0
 					bluetooth_sco_headset = 0
+					stub = 0
 				component: mic/applicable_input_device/mask/
 					bluetooth_a2dp = 0
 					wired_headset = 0
 					usb_device = 0
 					builtin_mic = 0
 					bluetooth_sco_headset = 0
+					stub = 0
 
 	domain: VoiceUplinkAndVoiceDownlinkAndVoiceCall
 		conf: VoiceCall
@@ -354,12 +373,29 @@
 				voice_downlink/applicable_input_device/mask/telephony_rx = 1
 				voice_call/applicable_input_device/mask/telephony_rx = 1
 				voice_uplink/applicable_input_device/mask/telephony_rx = 1
+				voice_downlink/applicable_input_device/mask/stub = 0
+				voice_call/applicable_input_device/mask/stub = 0
+				voice_uplink/applicable_input_device/mask/stub = 0
+
+		conf: Stub
+			AvailableInputDevices Includes Default
+
+			component: /Policy/policy/input_sources
+				voice_downlink/applicable_input_device/mask/telephony_rx = 0
+				voice_call/applicable_input_device/mask/telephony_rx = 0
+				voice_uplink/applicable_input_device/mask/telephony_rx = 0
+				voice_downlink/applicable_input_device/mask/stub = 1
+				voice_call/applicable_input_device/mask/stub = 1
+				voice_uplink/applicable_input_device/mask/stub = 1
 
 		conf: Default
 			component: /Policy/policy/input_sources
 				voice_downlink/applicable_input_device/mask/telephony_rx = 0
 				voice_call/applicable_input_device/mask/telephony_rx = 0
 				voice_uplink/applicable_input_device/mask/telephony_rx = 0
+				voice_downlink/applicable_input_device/mask/stub = 0
+				voice_call/applicable_input_device/mask/stub = 0
+				voice_uplink/applicable_input_device/mask/stub = 0
 
 	domain: Camcorder
 		conf: BackMic
@@ -368,6 +404,7 @@
 			component: /Policy/policy/input_sources/camcorder/applicable_input_device/mask
 				back_mic = 1
 				builtin_mic = 0
+				stub = 0
 
 		conf: BuiltinMic
 			AvailableInputDevices Includes BuiltinMic
@@ -375,11 +412,21 @@
 			component: /Policy/policy/input_sources/camcorder/applicable_input_device/mask
 				back_mic = 0
 				builtin_mic = 1
+				stub = 0
+
+		conf: Stub
+			AvailableInputDevices Includes Default
+
+			component: /Policy/policy/input_sources/camcorder/applicable_input_device/mask
+				back_mic = 0
+				builtin_mic = 0
+				stub = 1
 
 		conf: Default
 			component: /Policy/policy/input_sources/camcorder/applicable_input_device/mask
 				back_mic = 0
 				builtin_mic = 0
+				stub = 0
 
 	domain: VoiceRecognitionAndUnprocessedAndHotword
 		conf: ScoHeadset
@@ -392,16 +439,19 @@
 					wired_headset = 0
 					usb_device = 0
 					builtin_mic = 0
+					stub = 0
 				component: unprocessed/applicable_input_device/mask
 					bluetooth_sco_headset = 1
 					wired_headset = 0
 					usb_device = 0
 					builtin_mic = 0
+					stub = 0
 				component: hotword/applicable_input_device/mask
 					bluetooth_sco_headset = 1
 					wired_headset = 0
 					usb_device = 0
 					builtin_mic = 0
+					stub = 0
 
 		conf: WiredHeadset
 			AvailableInputDevices Includes WiredHeadset
@@ -411,17 +461,20 @@
 					bluetooth_sco_headset = 0
 					wired_headset = 1
 					usb_device = 0
+					stub = 0
 					builtin_mic = 0
 				component: unprocessed/applicable_input_device/mask
 					bluetooth_sco_headset = 0
 					wired_headset = 1
 					usb_device = 0
 					builtin_mic = 0
+					stub = 0
 				component: hotword/applicable_input_device/mask
 					bluetooth_sco_headset = 0
 					wired_headset = 1
 					usb_device = 0
 					builtin_mic = 0
+					stub = 0
 
 		conf: UsbDevice
 			AvailableInputDevices Includes UsbDevice
@@ -432,16 +485,19 @@
 					wired_headset = 0
 					usb_device = 1
 					builtin_mic = 0
+					stub = 0
 				component: unprocessed/applicable_input_device/mask
 					bluetooth_sco_headset = 0
 					wired_headset = 0
 					usb_device = 1
 					builtin_mic = 0
+					stub = 0
 				component: hotword/applicable_input_device/mask
 					bluetooth_sco_headset = 0
 					wired_headset = 0
 					usb_device = 1
 					builtin_mic = 0
+					stub = 0
 
 		conf: BuiltinMic
 			AvailableInputDevices Includes BuiltinMic
@@ -452,17 +508,42 @@
 					wired_headset = 0
 					usb_device = 0
 					builtin_mic = 1
+					stub = 0
 				component: unprocessed/applicable_input_device/mask
 					bluetooth_sco_headset = 0
 					wired_headset = 0
 					usb_device = 0
 					builtin_mic = 1
+					stub = 0
 				component: hotword/applicable_input_device/mask
 					bluetooth_sco_headset = 0
 					wired_headset = 0
 					usb_device = 0
 					builtin_mic = 1
+					stub = 0
 
+		conf: Stub
+			AvailableInputDevices Includes Default
+
+			component: /Policy/policy/input_sources
+				component: voice_recognition/applicable_input_device/mask
+					bluetooth_sco_headset = 0
+					wired_headset = 0
+					usb_device = 0
+					builtin_mic = 0
+					stub = 1
+				component: unprocessed/applicable_input_device/mask
+					bluetooth_sco_headset = 0
+					wired_headset = 0
+					usb_device = 0
+					builtin_mic = 0
+					stub = 1
+				component: hotword/applicable_input_device/mask
+					bluetooth_sco_headset = 0
+					wired_headset = 0
+					usb_device = 0
+					builtin_mic = 0
+					stub = 1
 		conf: Default
 			component: /Policy/policy/input_sources
 				component: voice_recognition/applicable_input_device/mask
@@ -470,16 +551,19 @@
 					wired_headset = 0
 					usb_device = 0
 					builtin_mic = 0
+					stub = 0
 				component: unprocessed/applicable_input_device/mask
 					bluetooth_sco_headset = 0
 					wired_headset = 0
 					usb_device = 0
 					builtin_mic = 0
+					stub = 0
 				component: hotword/applicable_input_device/mask
 					bluetooth_sco_headset = 0
 					wired_headset = 0
 					usb_device = 0
 					builtin_mic = 0
+					stub = 0
 
 	domain: VoiceCommunication
 		conf: ScoHeadset
@@ -495,6 +579,7 @@
 				usb_device = 0
 				builtin_mic = 0
 				back_mic = 0
+				stub = 0
 
 		conf: WiredHeadset
 			ForceUseForCommunication Is ForceNone
@@ -506,6 +591,7 @@
 				usb_device = 0
 				builtin_mic = 0
 				back_mic = 0
+				stub = 0
 
 		conf: UsbDevice
 			ForceUseForCommunication Is ForceNone
@@ -517,6 +603,7 @@
 				usb_device = 1
 				builtin_mic = 0
 				back_mic = 0
+				stub = 0
 
 		conf: BuiltinMic
 			AvailableInputDevices Includes BuiltinMic
@@ -532,6 +619,7 @@
 				usb_device = 0
 				builtin_mic = 1
 				back_mic = 0
+				stub = 0
 
 		conf: BackMic
 			ForceUseForCommunication Is ForceSpeaker
@@ -543,6 +631,7 @@
 				usb_device = 0
 				builtin_mic = 0
 				back_mic = 1
+				stub = 0
 
 		conf: Default
 			#
@@ -554,6 +643,7 @@
 				usb_device = 0
 				builtin_mic = 1
 				back_mic = 0
+				stub = 0
 
 	domain: RemoteSubmix
 		conf: RemoteSubmix
@@ -561,10 +651,19 @@
 
 			component: /Policy/policy/input_sources/remote_submix/applicable_input_device/mask
 				remote_submix = 1
+				stub = 0
+
+		conf: Stub
+			AvailableInputDevices Includes Default
+
+			component: /Policy/policy/input_sources/remote_submix/applicable_input_device/mask
+				remote_submix = 0
+				stub = 1
 
 		conf: Default
 			component: /Policy/policy/input_sources/remote_submix/applicable_input_device/mask
 				remote_submix = 0
+				stub = 0
 
 	domain: FmTuner
 		conf: FmTuner
@@ -572,8 +671,29 @@
 
 			component: /Policy/policy/input_sources/fm_tuner/applicable_input_device/mask
 				fm_tuner = 1
+				stub = 0
+
+		conf: Stub
+			AvailableInputDevices Includes Default
+
+			component: /Policy/policy/input_sources/fm_tuner/applicable_input_device/mask
+				fm_tuner = 0
+				stub = 1
 
 		conf: Default
 			component: /Policy/policy/input_sources/fm_tuner/applicable_input_device/mask
 				fm_tuner = 0
+				stub = 0
+
+	domain: Voice
+		conf: Stub
+			AvailableInputDevices Includes Default
+
+			/Policy/policy/input_sources/echo_reference/applicable_input_device/mask/stub = 1
+			/Policy/policy/input_sources/voice_performance/applicable_input_device/mask/stub = 1
+
+		conf: Default
+			/Policy/policy/input_sources/echo_reference/applicable_input_device/mask/stub = 0
+			/Policy/policy/input_sources/voice_performance/applicable_input_device/mask/stub = 0
+
 
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/SettingsNoInput/Android.bp b/services/audiopolicy/engineconfigurable/parameter-framework/examples/SettingsNoInput/Android.bp
new file mode 100644
index 0000000..ffd494e
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/SettingsNoInput/Android.bp
@@ -0,0 +1,73 @@
+/*
+ * 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.
+ */
+
+// Import this namespace in order to use AOSP No Input configuration example
+
+soong_namespace {
+    imports: [
+        "frameworks/av/services/audiopolicy/engineconfigurable/config/example/phone",
+        "frameworks/av/services/audiopolicy/config",
+    ],
+}
+
+prebuilt_etc {
+    name: "parameter-framework.policy",
+    filename_from_src: true,
+    vendor: true,
+    src: ":domaingeneratorpolicyrule_gen",
+    sub_dir: "parameter-framework/Settings/Policy",
+    required: [
+        "PolicyClass.xml",
+        "PolicySubsystem.xml",
+        "PolicySubsystem-CommonTypes.xml",
+    ],
+}
+
+genrule {
+    name: "domaingeneratorpolicyrule_gen",
+    defaults: ["domaingeneratorpolicyrule"],
+    srcs: [
+        ":audio_policy_pfw_toplevel",
+        ":audio_policy_pfw_structure_files",
+        ":audio_policy_engine_criterion_types",
+        ":edd_files",
+    ],
+}
+filegroup {
+    name: "audio_policy_pfw_toplevel",
+    srcs: [":ParameterFrameworkConfigurationPolicy.userdebug.xml"],
+}
+filegroup {
+    name: "audio_policy_pfw_structure_files",
+    srcs: [
+        ":PolicyClass",
+        ":PolicySubsystem",
+        ":PolicySubsystem-CommonTypes",
+    ],
+}
+filegroup {
+    name: "edd_files",
+    srcs: [
+        "device_for_input_source.pfw",
+        ":volumes.pfw",
+    ],
+}
+prebuilt_etc {
+    name: "PolicySubsystem.xml",
+    vendor: true,
+    src: ":PolicySubsystem-no-strategy",
+    sub_dir: "parameter-framework/Structure/Policy",
+}
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/SettingsNoOutput/Android.bp b/services/audiopolicy/engineconfigurable/parameter-framework/examples/SettingsNoOutput/Android.bp
new file mode 100644
index 0000000..6fca048
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/SettingsNoOutput/Android.bp
@@ -0,0 +1,73 @@
+/*
+ * 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.
+ */
+
+// Import this namespace in order to use AOSP No output configuration example
+
+soong_namespace {
+    imports: [
+        "frameworks/av/services/audiopolicy/engineconfigurable/config/example/phone",
+        "frameworks/av/services/audiopolicy/config",
+    ],
+}
+
+prebuilt_etc {
+    name: "parameter-framework.policy",
+    filename_from_src: true,
+    vendor: true,
+    src: ":domaingeneratorpolicyrule_gen",
+    sub_dir: "parameter-framework/Settings/Policy",
+    required: [
+        "PolicyClass.xml",
+        "PolicySubsystem.xml",
+        "PolicySubsystem-CommonTypes.xml",
+    ],
+}
+genrule {
+    name: "domaingeneratorpolicyrule_gen",
+    defaults: ["domaingeneratorpolicyrule"],
+    srcs: [
+        ":audio_policy_pfw_toplevel",
+        ":audio_policy_pfw_structure_files",
+        ":audio_policy_engine_criterion_types",
+        ":edd_files",
+    ],
+}
+filegroup {
+    name: "audio_policy_pfw_toplevel",
+    srcs: [":ParameterFrameworkConfigurationPolicy.userdebug.xml"],
+}
+filegroup {
+    name: "audio_policy_pfw_structure_files",
+    srcs: [
+        ":PolicyClass",
+        ":PolicySubsystem",
+        ":PolicySubsystem-CommonTypes",
+    ],
+}
+filegroup {
+    name: "edd_files",
+    srcs: [
+        "device_for_strategies.pfw",
+        ":volumes.pfw",
+        ":device_for_input_source.pfw",
+    ],
+}
+prebuilt_etc {
+    name: "PolicySubsystem.xml",
+    vendor: true,
+    src: ":PolicySubsystem-no-strategy",
+    sub_dir: "parameter-framework/Structure/Policy",
+}
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/common/Structure/PolicySubsystem.xml b/services/audiopolicy/engineconfigurable/parameter-framework/examples/common/Structure/PolicySubsystem.xml
index b55ce2c..585ce87 100644
--- a/services/audiopolicy/engineconfigurable/parameter-framework/examples/common/Structure/PolicySubsystem.xml
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/common/Structure/PolicySubsystem.xml
@@ -73,10 +73,13 @@
                                             Mapping="Name:AUDIO_SOURCE_REMOTE_SUBMIX"/>
             <Component Name="unprocessed" Type="InputSource"
                                             Mapping="Name:AUDIO_SOURCE_UNPROCESSED"/>
+            <Component Name="voice_performance" Type="InputSource"
+                                            Mapping="Name:AUDIO_SOURCE_VOICE_PERFORMANCE"/>
+            <Component Name="echo_reference" Type="InputSource"
+                                            Mapping="Name:AUDIO_SOURCE_ECHO_REFERENCE"/>
             <Component Name="fm_tuner" Type="InputSource" Mapping="Name:AUDIO_SOURCE_FM_TUNER"/>
             <Component Name="hotword" Type="InputSource" Mapping="Name:AUDIO_SOURCE_HOTWORD"/>
         </ComponentType>
-
         <!--#################### INPUT SOURCE END ####################-->
     </ComponentLibrary>
 
diff --git a/services/audiopolicy/engineconfigurable/src/Engine.cpp b/services/audiopolicy/engineconfigurable/src/Engine.cpp
index cb45fcf..3987294 100644
--- a/services/audiopolicy/engineconfigurable/src/Engine.cpp
+++ b/services/audiopolicy/engineconfigurable/src/Engine.cpp
@@ -33,6 +33,8 @@
 #include <AudioIODescriptorInterface.h>
 #include <ParameterManagerWrapper.h>
 
+#include <media/TypeConverter.h>
+
 using std::string;
 using std::map;
 
@@ -244,9 +246,9 @@
     }
     if (devices == AUDIO_DEVICE_NONE ||
             (devices & availableOutputDevicesType) == AUDIO_DEVICE_NONE) {
-        devices = getApmObserver()->getDefaultOutputDevice()->type();
-        ALOGE_IF(devices == AUDIO_DEVICE_NONE, "%s: no valid default device defined", __FUNCTION__);
-        return DeviceVector(getApmObserver()->getDefaultOutputDevice());
+        auto defaultDevice = getApmObserver()->getDefaultOutputDevice();
+        ALOG_ASSERT(defaultDevice != nullptr, "no valid default device defined");
+        return DeviceVector(defaultDevice);
     }
     if (/*device_distinguishes_on_address(devices)*/ devices == AUDIO_DEVICE_OUT_BUS) {
         // We do expect only one device for these types of devices
@@ -254,6 +256,14 @@
         // If this criterion is not wished, need to ensure this device is available
         const String8 address(productStrategies.getDeviceAddressForProductStrategy(ps).c_str());
         ALOGV("%s:device 0x%x %s %d", __FUNCTION__, devices, address.c_str(), ps);
+        auto busDevice = availableOutputDevices.getDevice(devices, address, AUDIO_FORMAT_DEFAULT);
+        if (busDevice == nullptr) {
+            ALOGE("%s:unavailable device 0x%x %s, fallback on default", __func__, devices,
+                  address.c_str());
+            auto defaultDevice = getApmObserver()->getDefaultOutputDevice();
+            ALOG_ASSERT(defaultDevice != nullptr, "Default Output Device NOT available");
+            return DeviceVector(defaultDevice);
+        }
         return DeviceVector(availableOutputDevices.getDevice(devices,
                                                              address,
                                                              AUDIO_FORMAT_DEFAULT));
@@ -361,7 +371,7 @@
 }
 
 template <>
-AudioPolicyManagerInterface *Engine::queryInterface()
+EngineInterface *Engine::queryInterface()
 {
     return this;
 }
diff --git a/services/audiopolicy/engineconfigurable/src/Engine.h b/services/audiopolicy/engineconfigurable/src/Engine.h
index 4662e7e..3b371d8 100644
--- a/services/audiopolicy/engineconfigurable/src/Engine.h
+++ b/services/audiopolicy/engineconfigurable/src/Engine.h
@@ -17,7 +17,7 @@
 #pragma once
 
 #include "EngineBase.h"
-#include <AudioPolicyManagerInterface.h>
+#include <EngineInterface.h>
 #include <AudioPolicyPluginInterface.h>
 #include "Collection.h"
 
diff --git a/services/audiopolicy/engineconfigurable/src/EngineInstance.cpp b/services/audiopolicy/engineconfigurable/src/EngineInstance.cpp
index 2442590..b127796 100644
--- a/services/audiopolicy/engineconfigurable/src/EngineInstance.cpp
+++ b/services/audiopolicy/engineconfigurable/src/EngineInstance.cpp
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#include <AudioPolicyManagerInterface.h>
+#include <EngineInterface.h>
 #include <AudioPolicyPluginInterface.h>
 #include "AudioPolicyEngineInstance.h"
 #include "Engine.h"
@@ -45,9 +45,9 @@
 }
 
 template <>
-AudioPolicyManagerInterface *EngineInstance::queryInterface() const
+EngineInterface *EngineInstance::queryInterface() const
 {
-    return getEngine()->queryInterface<AudioPolicyManagerInterface>();
+    return getEngine()->queryInterface<EngineInterface>();
 }
 
 template <>
@@ -57,5 +57,16 @@
 }
 
 } // namespace audio_policy
+
+extern "C" EngineInterface* createEngineInstance()
+{
+    return audio_policy::EngineInstance::getInstance()->queryInterface<EngineInterface>();
+}
+
+extern "C" void destroyEngineInstance(EngineInterface*)
+{
+    // The engine is a singleton.
+}
+
 } // namespace android
 
diff --git a/services/audiopolicy/engineconfigurable/tools/Android.bp b/services/audiopolicy/engineconfigurable/tools/Android.bp
index 8c16972..d9e97af 100644
--- a/services/audiopolicy/engineconfigurable/tools/Android.bp
+++ b/services/audiopolicy/engineconfigurable/tools/Android.bp
@@ -16,14 +16,17 @@
     name: "tools_default",
     version: {
         py2: {
-            enabled: true,
+            enabled: false,
         },
         py3: {
-            enabled: false,
+            enabled: true,
         },
     },
 }
 
+//##################################################################################################
+// Tools for audio policy engine criterion type configuration file
+//
 python_binary_host {
     name: "buildPolicyCriterionTypes.py",
     main: "buildPolicyCriterionTypes.py",
@@ -33,6 +36,30 @@
     defaults: ["tools_default"],
 }
 
+genrule_defaults {
+    name: "buildpolicycriteriontypesrule",
+    tools: ["buildPolicyCriterionTypes.py"],
+    cmd: "cp $(locations :audio_policy_configuration_files) $(genDir)/. && " +
+         "cp $(location :audio_policy_configuration_top_file) $(genDir)/audio_policy_configuration.xml && " +
+         "$(location buildPolicyCriterionTypes.py) " +
+         // @todo update if 1428659 is merged "--androidaudiobaseheader $(location :android_audio_base_header_file) " +
+         " --androidaudiobaseheader system/media/audio/include/system/audio-base.h " +
+         "--audiopolicyconfigurationfile $(genDir)/audio_policy_configuration.xml " +
+         "--criteriontypes $(location :audio_policy_engine_criterion_types_template) " +
+         "--outputfile $(out)",
+    srcs: [
+        // The commented inputs must be provided to use this genrule_defaults
+        // @todo uncomment if 1428659 is merged":android_audio_base_header_file",
+        ":audio_policy_engine_criterion_types_template",
+        // ":audio_policy_configuration_top_file",
+        // ":audio_policy_configuration_files",
+    ],
+    out: ["audio_policy_engine_criterion_types.xml"],
+}
+
+//##################################################################################################
+// Tools for audio policy engine parameter framework configurable domains
+//
 python_binary_host {
     name: "domainGeneratorPolicy.py",
     main: "domainGeneratorPolicy.py",
@@ -50,6 +77,38 @@
     ],
 }
 
+genrule_defaults {
+    name: "domaingeneratorpolicyrule",
+    tools: [
+        "domainGeneratorPolicy.py",
+        "domainGeneratorConnector",
+    ],
+    cmd: "mkdir -p $(genDir)/Structure/Policy && " +
+         "cp $(locations :audio_policy_pfw_structure_files) $(genDir)/Structure/Policy && " +
+         "cp $(location :audio_policy_pfw_toplevel) $(genDir)/top_level && " +
+         "$(location domainGeneratorPolicy.py) " +
+         "--validate " +
+         "--domain-generator-tool $(location domainGeneratorConnector) " +
+         "--toplevel-config $(genDir)/top_level " +
+         "--criteria $(location :audio_policy_engine_criteria) " +
+         "--criteriontypes $(location :audio_policy_engine_criterion_types) " +
+         "--add-edds $(locations :edd_files) " +
+         "--schemas-dir external/parameter-framework/upstream/schemas " +
+         " > $(out)",
+    srcs: [
+        // The commented inputs must be provided to use this genrule_defaults
+        // ":audio_policy_pfw_toplevel",
+        // ":audio_policy_pfw_structure_files",
+        ":audio_policy_engine_criteria",
+        // ":audio_policy_engine_criterion_types",
+        // ":edd_files",
+    ],
+    out: ["PolicyConfigurableDomains.xml"],
+}
+
+//##################################################################################################
+// Tools for policy parameter-framework product strategies structure file generation
+//
 python_binary_host {
     name: "buildStrategiesStructureFile.py",
     main: "buildStrategiesStructureFile.py",
@@ -58,3 +117,19 @@
     ],
     defaults: ["tools_default"],
 }
+
+genrule_defaults {
+    name: "buildstrategiesstructurerule",
+    tools: ["buildStrategiesStructureFile.py"],
+    cmd: "cp $(locations :audio_policy_engine_configuration_files) $(genDir) && ls -l $(genDir) &&"+
+         "$(location buildStrategiesStructureFile.py) " +
+         "--audiopolicyengineconfigurationfile $(genDir)/audio_policy_engine_configuration.xml "+
+         "--productstrategiesstructurefile $(location :product_strategies_structure_template) " +
+         "--outputfile $(out)",
+    srcs: [
+        // The commented inputs must be provided to use this genrule_defaults
+        // ":audio_policy_engine_configuration_files",
+        ":product_strategies_structure_template",
+    ],
+    out: ["ProductStrategies.xml"],
+}
diff --git a/services/audiopolicy/engineconfigurable/tools/buildPolicyCriterionTypes.py b/services/audiopolicy/engineconfigurable/tools/buildPolicyCriterionTypes.py
index a63c858..b8b60c1 100755
--- a/services/audiopolicy/engineconfigurable/tools/buildPolicyCriterionTypes.py
+++ b/services/audiopolicy/engineconfigurable/tools/buildPolicyCriterionTypes.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/python3
 
 #
 # Copyright 2018, The Android Open Source Project
@@ -19,10 +19,8 @@
 import argparse
 import re
 import sys
-import tempfile
 import os
 import logging
-import subprocess
 import xml.etree.ElementTree as ET
 import xml.etree.ElementInclude as EI
 import xml.dom.minidom as MINIDOM
@@ -49,33 +47,35 @@
 
 def parseArgs():
     argparser = argparse.ArgumentParser(description="Parameter-Framework XML \
-        audio criterion type file generator.\n\
-        Exit with the number of (recoverable or not) error that occured.")
+                                        audio criterion type file generator.\n\
+                                        Exit with the number of (recoverable or not) \
+                                        error that occured.")
     argparser.add_argument('--androidaudiobaseheader',
-            help="Android Audio Base C header file, Mandatory.",
-            metavar="ANDROID_AUDIO_BASE_HEADER",
-            type=argparse.FileType('r'),
-            required=True)
+                           help="Android Audio Base C header file, Mandatory.",
+                           metavar="ANDROID_AUDIO_BASE_HEADER",
+                           type=argparse.FileType('r'),
+                           required=True)
     argparser.add_argument('--audiopolicyconfigurationfile',
-            help="Android Audio Policy Configuration file, Mandatory.",
-            metavar="(AUDIO_POLICY_CONFIGURATION_FILE)",
-            type=argparse.FileType('r'),
-            required=True)
+                           help="Android Audio Policy Configuration file, Mandatory.",
+                           metavar="(AUDIO_POLICY_CONFIGURATION_FILE)",
+                           type=argparse.FileType('r'),
+                           required=True)
     argparser.add_argument('--criteriontypes',
-            help="Criterion types XML base file, in \
-            '<criterion_types> \
-                <criterion_type name="" type=<inclusive|exclusive> values=<value1,value2,...>/>' \
-        format. Mandatory.",
-            metavar="CRITERION_TYPE_FILE",
-            type=argparse.FileType('r'),
-            required=True)
+                           help="Criterion types XML base file, in \
+                           '<criterion_types> \
+                               <criterion_type name="" type=<inclusive|exclusive> \
+                               values=<value1,value2,...>/>' \
+                           format. Mandatory.",
+                           metavar="CRITERION_TYPE_FILE",
+                           type=argparse.FileType('r'),
+                           required=True)
     argparser.add_argument('--outputfile',
-            help="Criterion types outputfile file. Mandatory.",
-            metavar="CRITERION_TYPE_OUTPUT_FILE",
-            type=argparse.FileType('w'),
-            required=True)
+                           help="Criterion types outputfile file. Mandatory.",
+                           metavar="CRITERION_TYPE_OUTPUT_FILE",
+                           type=argparse.FileType('w'),
+                           required=True)
     argparser.add_argument('--verbose',
-            action='store_true')
+                           action='store_true')
 
     return argparser.parse_args()
 
@@ -120,7 +120,7 @@
     reparsed = MINIDOM.parseString(xmlstr)
     prettyXmlStr = reparsed.toprettyxml(newl='\r\n')
     prettyXmlStr = os.linesep.join([s for s in prettyXmlStr.splitlines() if s.strip()])
-    outputFile.write(prettyXmlStr.encode('utf-8'))
+    outputFile.write(prettyXmlStr)
 
 def capitalizeLine(line):
     return ' '.join((w.capitalize() for w in line.split(' ')))
@@ -137,30 +137,30 @@
     #
     address_criteria_mapping_table = {
         'sink' : "OutputDevicesAddressesType",
-        'source' : "InputDevicesAddressesType" }
+        'source' : "InputDevicesAddressesType"}
 
     address_criteria = {
         'OutputDevicesAddressesType' : [],
-        'InputDevicesAddressesType' : [] }
+        'InputDevicesAddressesType' : []}
 
-    oldWorkingDir = os.getcwd()
-    print "Current working directory %s" % oldWorkingDir
+    old_working_dir = os.getcwd()
+    print("Current working directory %s" % old_working_dir)
 
-    newDir = os.path.join(oldWorkingDir , audiopolicyconfigurationfile.name)
+    new_dir = os.path.join(old_working_dir, audiopolicyconfigurationfile.name)
 
     policy_in_tree = ET.parse(audiopolicyconfigurationfile)
-    os.chdir(os.path.dirname(os.path.normpath(newDir)))
+    os.chdir(os.path.dirname(os.path.normpath(new_dir)))
 
-    print "new working directory %s" % os.getcwd()
+    print("new working directory %s" % os.getcwd())
 
     policy_root = policy_in_tree.getroot()
     EI.include(policy_root)
 
-    os.chdir(oldWorkingDir)
+    os.chdir(old_working_dir)
 
     for device in policy_root.iter('devicePort'):
         for key in address_criteria_mapping_table.keys():
-            if device.get('role') == key and device.get('address') :
+            if device.get('role') == key and device.get('address'):
                 logging.info("{}: <{}>".format(key, device.get('address')))
                 address_criteria[address_criteria_mapping_table[key]].append(device.get('address'))
 
@@ -188,15 +188,15 @@
     all_criteria = {
         'AndroidModeType' : {},
         'OutputDevicesMaskType' : {},
-        'InputDevicesMaskType' : {} }
+        'InputDevicesMaskType' : {}}
 
     #
     # _CNT, _MAX, _ALL and _NONE are prohibited values as ther are just helpers for enum users.
     #
-    ignored_values = [ 'CNT', 'MAX', 'ALL', 'NONE' ]
+    ignored_values = ['CNT', 'MAX', 'ALL', 'NONE']
 
     criteria_pattern = re.compile(
-        r"\s*(?P<type>(?:"+'|'.join(criterion_mapping_table.keys()) + "))\_" \
+        r"\s*(?P<type>(?:"+'|'.join(criterion_mapping_table.keys()) + "))_" \
         r"(?P<literal>(?!" + '|'.join(ignored_values) + ")\w*)\s*=\s*" \
         r"(?P<values>(?:0[xX])?[0-9a-fA-F]+)")
 
@@ -221,7 +221,7 @@
                 logging.info("criterion {} duplicated values:".format(criterion_name))
                 logging.info("{}:{}".format(numerical_value, literal))
                 logging.info("KEEPING LATEST")
-                for key in all_criteria[criterion_name].keys():
+                for key in list(all_criteria[criterion_name]):
                     if all_criteria[criterion_name][key] == int(numerical_value, 0):
                         del all_criteria[criterion_name][key]
 
diff --git a/services/audiopolicy/engineconfigurable/tools/buildStrategiesStructureFile.py b/services/audiopolicy/engineconfigurable/tools/buildStrategiesStructureFile.py
index af40602..f69d346 100755
--- a/services/audiopolicy/engineconfigurable/tools/buildStrategiesStructureFile.py
+++ b/services/audiopolicy/engineconfigurable/tools/buildStrategiesStructureFile.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/python3
 
 #
 # Copyright 2019, The Android Open Source Project
@@ -17,16 +17,12 @@
 #
 
 import argparse
-import re
 import sys
-import tempfile
 import os
 import logging
-import subprocess
 import xml.etree.ElementTree as ET
 import xml.etree.ElementInclude as EI
 import xml.dom.minidom as MINIDOM
-from collections import OrderedDict
 
 #
 # Helper script that helps to feed at build time the XML Product Strategies Structure file file used
@@ -46,33 +42,34 @@
 
 def parseArgs():
     argparser = argparse.ArgumentParser(description="Parameter-Framework XML \
-        product strategies structure file generator.\n\
-        Exit with the number of (recoverable or not) error that occured.")
+                                        product strategies structure file generator.\n\
+                                        Exit with the number of (recoverable or not) \
+                                        error that occured.")
     argparser.add_argument('--audiopolicyengineconfigurationfile',
-            help="Android Audio Policy Engine Configuration file, Mandatory.",
-            metavar="(AUDIO_POLICY_ENGINE_CONFIGURATION_FILE)",
-            type=argparse.FileType('r'),
-            required=True)
+                           help="Android Audio Policy Engine Configuration file, Mandatory.",
+                           metavar="(AUDIO_POLICY_ENGINE_CONFIGURATION_FILE)",
+                           type=argparse.FileType('r'),
+                           required=True)
     argparser.add_argument('--productstrategiesstructurefile',
-            help="Product Strategies Structure XML base file, Mandatory.",
-            metavar="STRATEGIES_STRUCTURE_FILE",
-            type=argparse.FileType('r'),
-            required=True)
+                           help="Product Strategies Structure XML base file, Mandatory.",
+                           metavar="STRATEGIES_STRUCTURE_FILE",
+                           type=argparse.FileType('r'),
+                           required=True)
     argparser.add_argument('--outputfile',
-            help="Product Strategies Structure output file, Mandatory.",
-            metavar="STRATEGIES_STRUCTURE_OUTPUT_FILE",
-            type=argparse.FileType('w'),
-            required=True)
+                           help="Product Strategies Structure output file, Mandatory.",
+                           metavar="STRATEGIES_STRUCTURE_OUTPUT_FILE",
+                           type=argparse.FileType('w'),
+                           required=True)
     argparser.add_argument('--verbose',
-            action='store_true')
+                           action='store_true')
 
     return argparser.parse_args()
 
 
-def generateXmlStructureFile(strategies, strategyStructureInFile, outputFile):
+def generateXmlStructureFile(strategies, strategy_structure_in_file, output_file):
 
-    logging.info("Importing strategyStructureInFile {}".format(strategyStructureInFile))
-    strategies_in_tree = ET.parse(strategyStructureInFile)
+    logging.info("Importing strategy_structure_in_file {}".format(strategy_structure_in_file))
+    strategies_in_tree = ET.parse(strategy_structure_in_file)
 
     strategies_root = strategies_in_tree.getroot()
     strategy_components = strategies_root.find('ComponentType')
@@ -80,13 +77,15 @@
     for strategy_name in strategies:
         context_mapping = "".join(map(str, ["Name:", strategy_name]))
         strategy_pfw_name = strategy_name.replace('STRATEGY_', '').lower()
-        strategy_component_node = ET.SubElement(strategy_components, "Component", Name=strategy_pfw_name, Type="ProductStrategy", Mapping=context_mapping)
+        ET.SubElement(strategy_components, "Component",
+                      Name=strategy_pfw_name, Type="ProductStrategy",
+                      Mapping=context_mapping)
 
     xmlstr = ET.tostring(strategies_root, encoding='utf8', method='xml')
     reparsed = MINIDOM.parseString(xmlstr)
     prettyXmlStr = reparsed.toprettyxml(newl='\r\n')
     prettyXmlStr = os.linesep.join([s for s in prettyXmlStr.splitlines() if s.strip()])
-    outputFile.write(prettyXmlStr.encode('utf-8'))
+    output_file.write(prettyXmlStr)
 
 def capitalizeLine(line):
     return ' '.join((w.capitalize() for w in line.split(' ')))
@@ -97,26 +96,27 @@
 #
 def parseAndroidAudioPolicyEngineConfigurationFile(audiopolicyengineconfigurationfile):
 
-    logging.info("Checking Audio Policy Engine Configuration file {}".format(audiopolicyengineconfigurationfile))
+    logging.info("Checking Audio Policy Engine Configuration file {}".format(
+        audiopolicyengineconfigurationfile))
     #
     # extract all product strategies name from audio policy engine configuration file
     #
     strategy_names = []
 
-    oldWorkingDir = os.getcwd()
-    print "Current working directory %s" % oldWorkingDir
+    old_working_dir = os.getcwd()
+    print("Current working directory %s" % old_working_dir)
 
-    newDir = os.path.join(oldWorkingDir , audiopolicyengineconfigurationfile.name)
+    new_dir = os.path.join(old_working_dir, audiopolicyengineconfigurationfile.name)
 
     policy_engine_in_tree = ET.parse(audiopolicyengineconfigurationfile)
-    os.chdir(os.path.dirname(os.path.normpath(newDir)))
+    os.chdir(os.path.dirname(os.path.normpath(new_dir)))
 
-    print "new working directory %s" % os.getcwd()
+    print("new working directory %s" % os.getcwd())
 
     policy_engine_root = policy_engine_in_tree.getroot()
     EI.include(policy_engine_root)
 
-    os.chdir(oldWorkingDir)
+    os.chdir(old_working_dir)
 
     for strategy in policy_engine_root.iter('ProductStrategy'):
         strategy_names.append(strategy.get('name'))
@@ -128,7 +128,8 @@
     logging.root.setLevel(logging.INFO)
     args = parseArgs()
 
-    strategies = parseAndroidAudioPolicyEngineConfigurationFile(args.audiopolicyengineconfigurationfile)
+    strategies = parseAndroidAudioPolicyEngineConfigurationFile(
+        args.audiopolicyengineconfigurationfile)
 
     product_strategies_structure = args.productstrategiesstructurefile
 
diff --git a/services/audiopolicy/engineconfigurable/tools/build_audio_pfw_settings.mk b/services/audiopolicy/engineconfigurable/tools/build_audio_pfw_settings.mk
deleted file mode 100644
index ac60ef7..0000000
--- a/services/audiopolicy/engineconfigurable/tools/build_audio_pfw_settings.mk
+++ /dev/null
@@ -1,38 +0,0 @@
-LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_TAGS := optional
-LOCAL_ADDITIONAL_DEPENDENCIES += \
-    $(HOST_OUT_EXECUTABLES)/domainGeneratorPolicy.py \
-    $(PFW_TOPLEVEL_FILE) $(PFW_CRITERIA_FILE) $(PFW_CRITERION_TYPES_FILE)
-
-include $(BUILD_SYSTEM)/base_rules.mk
-
-$(LOCAL_BUILT_MODULE): MY_CRITERION_TYPES_FILE := $(PFW_CRITERION_TYPES_FILE)
-$(LOCAL_BUILT_MODULE): MY_TOOL := $(HOST_OUT_EXECUTABLES)/domainGeneratorPolicy.py
-$(LOCAL_BUILT_MODULE): MY_TOPLEVEL_FILE := $(PFW_TOPLEVEL_FILE)
-$(LOCAL_BUILT_MODULE): MY_CRITERIA_FILE := $(PFW_CRITERIA_FILE)
-$(LOCAL_BUILT_MODULE): MY_TUNING_FILE := $(PFW_TUNING_FILE)
-$(LOCAL_BUILT_MODULE): MY_EDD_FILES := $(PFW_EDD_FILES)
-$(LOCAL_BUILT_MODULE): MY_DOMAIN_FILES := $(PFW_DOMAIN_FILES)
-$(LOCAL_BUILT_MODULE): MY_SCHEMAS_DIR := $(PFW_SCHEMAS_DIR)
-$(LOCAL_BUILT_MODULE): MY_CRITERION_TYPES_FILE := $(PFW_CRITERION_TYPES_FILE)
-$(LOCAL_BUILT_MODULE): $(LOCAL_ADDITIONAL_DEPENDENCIES)
-
-	"$(MY_TOOL)" --validate \
-		--toplevel-config "$(MY_TOPLEVEL_FILE)" \
-		--criteria "$(MY_CRITERIA_FILE)" \
-		--criteriontypes "$(MY_CRITERION_TYPES_FILE)" \
-		--initial-settings $(MY_TUNING_FILE) \
-		--add-edds $(MY_EDD_FILES) \
-		--add-domains $(MY_DOMAIN_FILES) \
-		--schemas-dir $(MY_SCHEMAS_DIR) > "$@"
-
-
-# Clear variables for further use
-PFW_TOPLEVEL_FILE :=
-PFW_STRUCTURE_FILES :=
-PFW_CRITERIA_FILE :=
-PFW_CRITERION_TYPES_FILE :=
-PFW_TUNING_FILE :=
-PFW_EDD_FILES :=
-PFW_DOMAIN_FILES :=
-PFW_SCHEMAS_DIR := $(PFW_DEFAULT_SCHEMAS_DIR)
diff --git a/services/audiopolicy/engineconfigurable/tools/domainGeneratorPolicy.py b/services/audiopolicy/engineconfigurable/tools/domainGeneratorPolicy.py
index 4dec9a2..b0c4b66 100755
--- a/services/audiopolicy/engineconfigurable/tools/domainGeneratorPolicy.py
+++ b/services/audiopolicy/engineconfigurable/tools/domainGeneratorPolicy.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/python3
 
 #
 # Copyright 2018, The Android Open Source Project
@@ -16,12 +16,7 @@
 # limitations under the License.
 #
 
-import EddParser
-from PFWScriptGenerator import PfwScriptTranslator
-import hostConfig
-
 import argparse
-import re
 import sys
 import tempfile
 import os
@@ -29,6 +24,10 @@
 import subprocess
 import xml.etree.ElementTree as ET
 
+import EddParser
+from PFWScriptGenerator import PfwScriptTranslator
+import hostConfig
+
 #
 # In order to build the XML Settings file at build time, an instance of the parameter-framework
 # shall be started and fed with all the criterion types/criteria that will be used by
@@ -39,61 +38,67 @@
 
 def parseArgs():
     argparser = argparse.ArgumentParser(description="Parameter-Framework XML \
-        Settings file generator.\n\
-        Exit with the number of (recoverable or not) error that occured.")
+                                        Settings file generator.\n\
+                                        Exit with the number of (recoverable or not) \
+                                        error that occured.")
+    argparser.add_argument('--domain-generator-tool',
+                           help="ParameterFramework domain generator tool. Mandatory.",
+                           metavar="PFW_DOMAIN_GENERATOR_TOOL",
+                           required=True)
     argparser.add_argument('--toplevel-config',
-            help="Top-level parameter-framework configuration file. Mandatory.",
-            metavar="TOPLEVEL_CONFIG_FILE",
-            required=True)
+                           help="Top-level parameter-framework configuration file. Mandatory.",
+                           metavar="TOPLEVEL_CONFIG_FILE",
+                           required=True)
     argparser.add_argument('--criteria',
-            help="Criteria file, in XML format: \
-                  in '<criteria> \
-                          <criterion name="" type=""/> \
-                      </criteria>' \
-        format. Mandatory.",
-            metavar="CRITERIA_FILE",
-            type=argparse.FileType('r'),
-            required=True)
+                           help="Criteria file, in XML format: \
+                                 in '<criteria> \
+                                         <criterion name="" type=""/> \
+                                     </criteria>' \
+                           format. Mandatory.",
+                           metavar="CRITERIA_FILE",
+                           type=argparse.FileType('r'),
+                           required=True)
     argparser.add_argument('--criteriontypes',
-            help="Criterion types XML file, in \
-            '<criterion_types> \
-                <criterion_type name="" type=<inclusive|exclusive> values=<value1,value2,...>/> \
-             </criterion_types>' \
-        format. Mandatory.",
-            metavar="CRITERION_TYPE_FILE",
-            type=argparse.FileType('r'),
-            required=False)
+                           help="Criterion types XML file, in \
+                           '<criterion_types> \
+                               <criterion_type name="" type=<inclusive|exclusive> \
+                                               values=<value1,value2,...>/> \
+                            </criterion_types>' \
+                           format. Mandatory.",
+                           metavar="CRITERION_TYPE_FILE",
+                           type=argparse.FileType('r'),
+                           required=False)
     argparser.add_argument('--initial-settings',
-            help="Initial XML settings file (containing a \
-        <ConfigurableDomains>  tag",
-            nargs='?',
-            default=None,
-            metavar="XML_SETTINGS_FILE")
+                           help="Initial XML settings file (containing a \
+                           <ConfigurableDomains>  tag",
+                           nargs='?',
+                           default=None,
+                           metavar="XML_SETTINGS_FILE")
     argparser.add_argument('--add-domains',
-            help="List of single domain files (each containing a single \
-        <ConfigurableDomain> tag",
-            metavar="XML_DOMAIN_FILE",
-            nargs='*',
-            dest='xml_domain_files',
-            default=[])
+                           help="List of single domain files (each containing a single \
+                           <ConfigurableDomain> tag",
+                           metavar="XML_DOMAIN_FILE",
+                           nargs='*',
+                           dest='xml_domain_files',
+                           default=[])
     argparser.add_argument('--add-edds',
-            help="List of files in EDD syntax (aka \".pfw\" files)",
-            metavar="EDD_FILE",
-            type=argparse.FileType('r'),
-            nargs='*',
-            default=[],
-            dest='edd_files')
+                           help="List of files in EDD syntax (aka \".pfw\" files)",
+                           metavar="EDD_FILE",
+                           type=argparse.FileType('r'),
+                           nargs='*',
+                           default=[],
+                           dest='edd_files')
     argparser.add_argument('--schemas-dir',
-            help="Directory of parameter-framework XML Schemas for generation \
-        validation",
-            default=None)
+                           help="Directory of parameter-framework XML Schemas for generation \
+                           validation",
+                           default=None)
     argparser.add_argument('--target-schemas-dir',
-            help="Ignored. Kept for retro-compatibility")
+                           help="Ignored. Kept for retro-compatibility")
     argparser.add_argument('--validate',
-            help="Validate the settings against XML schemas",
-            action='store_true')
+                           help="Validate the settings against XML schemas",
+                           action='store_true')
     argparser.add_argument('--verbose',
-            action='store_true')
+                           action='store_true')
 
     return argparser.parse_args()
 
@@ -112,7 +117,6 @@
     logging.info("Importing criterionTypesFile {}".format(criterionTypesFile))
 
     criteria_root = criteria_tree.getroot()
-    criterion_types_root = criterion_types_tree.getroot()
 
     all_criteria = []
     for criterion in criteria_root.findall('criterion'):
@@ -165,7 +169,7 @@
 
         try:
             root.propagate()
-        except EddParser.MyPropagationError, ex :
+        except EddParser.MyPropagationError as ex:
             logging.critical(str(ex))
             logging.info("EXIT ON FAILURE")
             exit(1)
@@ -179,32 +183,32 @@
 # It takes as input the collection of criteria, the domains and the simplified settings read from
 # pfw.
 #
-def generateDomainCommands(logging, all_criteria, initial_settings, xml_domain_files, parsed_edds):
-        # create and inject all the criteria
-        logging.info("Creating all criteria")
-        for criterion in all_criteria:
-            yield ["createSelectionCriterion", criterion['inclusive'],
-                   criterion['name']] + criterion['values']
+def generateDomainCommands(logger, all_criteria, initial_settings, xml_domain_files, parsed_edds):
+    # create and inject all the criteria
+    logger.info("Creating all criteria")
+    for criterion in all_criteria:
+        yield ["createSelectionCriterion", criterion['inclusive'],
+               criterion['name']] + criterion['values']
 
-        yield ["start"]
+    yield ["start"]
 
-        # Import initial settings file
-        if initial_settings:
-            logging.info("Importing initial settings file {}".format(initial_settings))
-            yield ["importDomainsWithSettingsXML", initial_settings]
+    # Import initial settings file
+    if initial_settings:
+        logger.info("Importing initial settings file {}".format(initial_settings))
+        yield ["importDomainsWithSettingsXML", initial_settings]
 
-        # Import each standalone domain files
-        for domain_file in xml_domain_files:
-            logging.info("Importing single domain file {}".format(domain_file))
-            yield ["importDomainWithSettingsXML", domain_file]
+    # Import each standalone domain files
+    for domain_file in xml_domain_files:
+        logger.info("Importing single domain file {}".format(domain_file))
+        yield ["importDomainWithSettingsXML", domain_file]
 
-        # Generate the script for each EDD file
-        for filename, parsed_edd in parsed_edds:
-            logging.info("Translating and injecting EDD file {}".format(filename))
-            translator = PfwScriptTranslator()
-            parsed_edd.translate(translator)
-            for command in translator.getScript():
-                yield command
+    # Generate the script for each EDD file
+    for filename, parsed_edd in parsed_edds:
+        logger.info("Translating and injecting EDD file {}".format(filename))
+        translator = PfwScriptTranslator()
+        parsed_edd.translate(translator)
+        for command in translator.getScript():
+            yield command
 
 #
 # Entry point of the domain generator.
@@ -232,30 +236,29 @@
                                                        prefix="TMPdomainGeneratorPFConfig_")
 
     install_path = os.path.dirname(os.path.realpath(args.toplevel_config))
-    hostConfig.configure(
-            infile=args.toplevel_config,
-            outfile=fake_toplevel_config,
-            structPath=install_path)
+    hostConfig.configure(infile=args.toplevel_config,
+                         outfile=fake_toplevel_config,
+                         structPath=install_path)
     fake_toplevel_config.close()
 
     # Create the connector. Pipe its input to us in order to write commands;
     # connect its output to stdout in order to have it dump the domains
     # there; connect its error output to stderr.
-    connector = subprocess.Popen(["domainGeneratorConnector",
-                            fake_toplevel_config.name,
-                            'verbose' if args.verbose else 'no-verbose',
-                            'validate' if args.validate else 'no-validate',
-                            args.schemas_dir],
-                           stdout=sys.stdout, stdin=subprocess.PIPE, stderr=sys.stderr)
+    connector = subprocess.Popen([args.domain_generator_tool,
+                                  fake_toplevel_config.name,
+                                  'verbose' if args.verbose else 'no-verbose',
+                                  'validate' if args.validate else 'no-validate',
+                                  args.schemas_dir],
+                                 stdout=sys.stdout, stdin=subprocess.PIPE, stderr=sys.stderr)
 
     initial_settings = None
     if args.initial_settings:
         initial_settings = os.path.realpath(args.initial_settings)
 
     for command in generateDomainCommands(logging, all_criteria, initial_settings,
-                                       args.xml_domain_files, parsed_edds):
-        connector.stdin.write('\0'.join(command))
-        connector.stdin.write("\n")
+                                          args.xml_domain_files, parsed_edds):
+        connector.stdin.write('\0'.join(command).encode('utf-8'))
+        connector.stdin.write("\n".encode('utf-8'))
 
     # Closing the connector's input triggers the domain generation
     connector.stdin.close()
diff --git a/services/audiopolicy/engineconfigurable/tools/provision_criterion_types_from_android_headers.mk b/services/audiopolicy/engineconfigurable/tools/provision_criterion_types_from_android_headers.mk
deleted file mode 100644
index dab5a0f..0000000
--- a/services/audiopolicy/engineconfigurable/tools/provision_criterion_types_from_android_headers.mk
+++ /dev/null
@@ -1,25 +0,0 @@
-LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_TAGS := optional
-LOCAL_ADDITIONAL_DEPENDENCIES += \
-    $(HOST_OUT_EXECUTABLES)/buildPolicyCriterionTypes.py \
-    $(CRITERION_TYPES_FILE) $(AUDIO_POLICY_CONFIGURATION_FILE) \
-    $(ANDROID_AUDIO_BASE_HEADER_FILE)
-
-include $(BUILD_SYSTEM)/base_rules.mk
-
-$(LOCAL_BUILT_MODULE): MY_CRITERION_TYPES_FILE := $(CRITERION_TYPES_FILE)
-$(LOCAL_BUILT_MODULE): MY_ANDROID_AUDIO_BASE_HEADER_FILE := $(ANDROID_AUDIO_BASE_HEADER_FILE)
-$(LOCAL_BUILT_MODULE): MY_AUDIO_POLICY_CONFIGURATION_FILE := $(AUDIO_POLICY_CONFIGURATION_FILE)
-$(LOCAL_BUILT_MODULE): MY_CRITERION_TOOL := $(HOST_OUT_EXECUTABLES)/buildPolicyCriterionTypes.py
-$(LOCAL_BUILT_MODULE): $(LOCAL_ADDITIONAL_DEPENDENCIES)
-
-	"$(MY_CRITERION_TOOL)" \
-		--androidaudiobaseheader "$(MY_ANDROID_AUDIO_BASE_HEADER_FILE)" \
-		--audiopolicyconfigurationfile "$(MY_AUDIO_POLICY_CONFIGURATION_FILE)" \
-		--criteriontypes "$(MY_CRITERION_TYPES_FILE)" \
-		--outputfile "$(@)"
-
-# Clear variables for further use
-CRITERION_TYPES_FILE :=
-ANDROID_AUDIO_BASE_HEADER_FILE :=
-AUDIO_POLICY_CONFIGURATION_FILE :=
diff --git a/services/audiopolicy/engineconfigurable/tools/provision_strategies_structure.mk b/services/audiopolicy/engineconfigurable/tools/provision_strategies_structure.mk
deleted file mode 100644
index f2b1a19..0000000
--- a/services/audiopolicy/engineconfigurable/tools/provision_strategies_structure.mk
+++ /dev/null
@@ -1,21 +0,0 @@
-LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_TAGS := optional
-LOCAL_ADDITIONAL_DEPENDENCIES += \
-    $(HOST_OUT_EXECUTABLES)/buildStrategiesStructureFile.py \
-    $(STRATEGIES_STRUCTURE_FILE) $(AUDIO_POLICY_ENGINE_CONFIGURATION_FILE)
-
-include $(BUILD_SYSTEM)/base_rules.mk
-
-$(LOCAL_BUILT_MODULE): MY_STRATEGIES_STRUCTURE_FILE := $(STRATEGIES_STRUCTURE_FILE)
-$(LOCAL_BUILT_MODULE): MY_AUDIO_POLICY_ENGINE_CONFIGURATION_FILE := $(AUDIO_POLICY_ENGINE_CONFIGURATION_FILE)
-$(LOCAL_BUILT_MODULE): MY_PROVISION_TOOL := $(HOST_OUT_EXECUTABLES)/buildStrategiesStructureFile.py
-$(LOCAL_BUILT_MODULE): $(LOCAL_ADDITIONAL_DEPENDENCIES)
-
-	"$(MY_PROVISION_TOOL)" \
-		--audiopolicyengineconfigurationfile "$(MY_AUDIO_POLICY_ENGINE_CONFIGURATION_FILE)" \
-		--productstrategiesstructurefile "$(MY_STRATEGIES_STRUCTURE_FILE)" \
-		--outputfile "$(@)"
-
-# Clear variables for further use
-STRATEGIES_STRUCTURE_FILE :=
-AUDIO_POLICY_ENGINE_CONFIGURATION_FILE :=
diff --git a/services/audiopolicy/enginedefault/Android.bp b/services/audiopolicy/enginedefault/Android.bp
index 7b42c6a..2b9cf09 100644
--- a/services/audiopolicy/enginedefault/Android.bp
+++ b/services/audiopolicy/enginedefault/Android.bp
@@ -1,16 +1,15 @@
 cc_library_shared {
     name: "libaudiopolicyenginedefault",
-    export_include_dirs: ["include"],
     srcs: [
         "src/Engine.cpp",
         "src/EngineInstance.cpp",
     ],
     cflags: [
+        "-fvisibility=hidden",
         "-Wall",
         "-Werror",
         "-Wextra",
     ],
-    local_include_dirs: ["include"],
     header_libs: [
         "libbase_headers",
         "libaudiopolicycommon",
diff --git a/services/audiopolicy/enginedefault/config/example/Android.bp b/services/audiopolicy/enginedefault/config/example/Android.bp
new file mode 100644
index 0000000..0bfcaa1
--- /dev/null
+++ b/services/audiopolicy/enginedefault/config/example/Android.bp
@@ -0,0 +1,46 @@
+/*
+ * 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.
+ */
+
+// Import this namespace in order to use AOSP Phone with Default Engine configuration example
+
+soong_namespace {
+}
+
+prebuilt_etc {
+    name: "audio_policy_engine_configuration.xml",
+    vendor: true,
+    src: "phone/audio_policy_engine_configuration.xml",
+    required: [
+        ":audio_policy_engine_stream_volumes.xml",
+        ":audio_policy_engine_default_stream_volumes.xml",
+        ":audio_policy_engine_product_strategies.xml",
+    ],
+}
+prebuilt_etc {
+    name: "audio_policy_engine_product_strategies.xml",
+    vendor: true,
+    src: "phone/audio_policy_engine_product_strategies.xml",
+}
+prebuilt_etc {
+    name: "audio_policy_engine_stream_volumes.xml",
+    vendor: true,
+    src: "phone/audio_policy_engine_stream_volumes.xml",
+}
+prebuilt_etc {
+    name: "audio_policy_engine_default_stream_volumes.xml",
+    vendor: true,
+    src: "phone/audio_policy_engine_default_stream_volumes.xml",
+}
diff --git a/services/audiopolicy/enginedefault/config/example/Android.mk b/services/audiopolicy/enginedefault/config/example/Android.mk
deleted file mode 100644
index 0badac8..0000000
--- a/services/audiopolicy/enginedefault/config/example/Android.mk
+++ /dev/null
@@ -1,48 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-
-##################################################################
-# CONFIGURATION TOP FILE
-##################################################################
-
-ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION), phone_default)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := audio_policy_engine_configuration.xml
-
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_CLASS := ETC
-LOCAL_VENDOR_MODULE := true
-LOCAL_SRC_FILES := phone/$(LOCAL_MODULE)
-
-LOCAL_REQUIRED_MODULES := \
-    audio_policy_engine_product_strategies.xml \
-    audio_policy_engine_stream_volumes.xml \
-    audio_policy_engine_default_stream_volumes.xml
-
-include $(BUILD_PREBUILT)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := audio_policy_engine_product_strategies.xml
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_CLASS := ETC
-LOCAL_VENDOR_MODULE := true
-LOCAL_SRC_FILES := phone/$(LOCAL_MODULE)
-include $(BUILD_PREBUILT)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := audio_policy_engine_stream_volumes.xml
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_CLASS := ETC
-LOCAL_VENDOR_MODULE := true
-LOCAL_SRC_FILES := phone/$(LOCAL_MODULE)
-include $(BUILD_PREBUILT)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := audio_policy_engine_default_stream_volumes.xml
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_CLASS := ETC
-LOCAL_VENDOR_MODULE := true
-LOCAL_SRC_FILES := phone/$(LOCAL_MODULE)
-include $(BUILD_PREBUILT)
-
-endif # ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION), phone_default)
diff --git a/services/audiopolicy/enginedefault/include/AudioPolicyEngineInstance.h b/services/audiopolicy/enginedefault/include/AudioPolicyEngineInstance.h
deleted file mode 100644
index 1e329f0..0000000
--- a/services/audiopolicy/enginedefault/include/AudioPolicyEngineInstance.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (C) 2015 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.
- */
-
-#pragma once
-
-class AudioPolicyManagerInterface;
-
-namespace android
-{
-namespace audio_policy
-{
-
-class Engine;
-
-class EngineInstance
-{
-protected:
-    EngineInstance();
-
-public:
-    virtual ~EngineInstance();
-
-    /**
-     * Get Audio Policy Engine instance.
-     *
-     * @return pointer to Route Manager Instance object.
-     */
-    static EngineInstance *getInstance();
-
-    /**
-     * Interface query.
-     * The first client of an interface of the policy engine will start the singleton.
-     *
-     * @tparam RequestedInterface: interface that the client is wishing to retrieve.
-     *
-     * @return interface handle.
-     */
-    template <class RequestedInterface>
-    RequestedInterface *queryInterface() const;
-
-protected:
-    /**
-     * Get Audio Policy Engine instance.
-     *
-     * @return Audio Policy Engine singleton.
-     */
-    Engine *getEngine() const;
-
-private:
-    /* Copy facilities are put private to disable copy. */
-    EngineInstance(const EngineInstance &object);
-    EngineInstance &operator=(const EngineInstance &object);
-};
-
-/**
- * Limit template instantation to supported type interfaces.
- * Compile time error will claim if invalid interface is requested.
- */
-template <>
-AudioPolicyManagerInterface *EngineInstance::queryInterface() const;
-
-} // namespace audio_policy
-} // namespace android
diff --git a/services/audiopolicy/enginedefault/src/Engine.cpp b/services/audiopolicy/enginedefault/src/Engine.cpp
index 04170ac..c602f3a 100644
--- a/services/audiopolicy/enginedefault/src/Engine.cpp
+++ b/services/audiopolicy/enginedefault/src/Engine.cpp
@@ -762,12 +762,6 @@
                                            AUDIO_FORMAT_DEFAULT);
 }
 
-template <>
-AudioPolicyManagerInterface *Engine::queryInterface()
-{
-    return this;
-}
-
 } // namespace audio_policy
 } // namespace android
 
diff --git a/services/audiopolicy/enginedefault/src/Engine.h b/services/audiopolicy/enginedefault/src/Engine.h
index d5dfacc..62938cf 100644
--- a/services/audiopolicy/enginedefault/src/Engine.h
+++ b/services/audiopolicy/enginedefault/src/Engine.h
@@ -17,7 +17,7 @@
 #pragma once
 
 #include "EngineBase.h"
-#include "AudioPolicyManagerInterface.h"
+#include "EngineInterface.h"
 #include <AudioGain.h>
 #include <policy.h>
 
@@ -48,12 +48,9 @@
     Engine();
     virtual ~Engine() = default;
 
-    template <class RequestedInterface>
-    RequestedInterface *queryInterface();
-
 private:
     ///
-    /// from EngineBase, so from AudioPolicyManagerInterface
+    /// from EngineBase, so from EngineInterface
     ///
     status_t setForceUse(audio_policy_force_use_t usage,
                          audio_policy_forced_cfg_t config) override;
diff --git a/services/audiopolicy/enginedefault/src/EngineInstance.cpp b/services/audiopolicy/enginedefault/src/EngineInstance.cpp
index 17e9832..eeb3758 100644
--- a/services/audiopolicy/enginedefault/src/EngineInstance.cpp
+++ b/services/audiopolicy/enginedefault/src/EngineInstance.cpp
@@ -14,41 +14,21 @@
  * limitations under the License.
  */
 
-#include <AudioPolicyManagerInterface.h>
-#include "AudioPolicyEngineInstance.h"
+#include <EngineInterface.h>
 #include "Engine.h"
 
-namespace android
-{
-namespace audio_policy
-{
+namespace android {
+namespace audio_policy {
 
-EngineInstance::EngineInstance()
+extern "C" EngineInterface* createEngineInstance()
 {
+    return new (std::nothrow) Engine();
 }
 
-EngineInstance *EngineInstance::getInstance()
+extern "C" void destroyEngineInstance(EngineInterface *engine)
 {
-    static EngineInstance instance;
-    return &instance;
-}
-
-EngineInstance::~EngineInstance()
-{
-}
-
-Engine *EngineInstance::getEngine() const
-{
-    static Engine engine;
-    return &engine;
-}
-
-template <>
-AudioPolicyManagerInterface *EngineInstance::queryInterface() const
-{
-    return getEngine()->queryInterface<AudioPolicyManagerInterface>();
+    delete static_cast<Engine*>(engine);
 }
 
 } // namespace audio_policy
 } // namespace android
-
diff --git a/services/audiopolicy/manager/AudioPolicyFactory.cpp b/services/audiopolicy/manager/AudioPolicyFactory.cpp
index 7aff6a9..476a1ec 100644
--- a/services/audiopolicy/manager/AudioPolicyFactory.cpp
+++ b/services/audiopolicy/manager/AudioPolicyFactory.cpp
@@ -21,7 +21,13 @@
 extern "C" AudioPolicyInterface* createAudioPolicyManager(
         AudioPolicyClientInterface *clientInterface)
 {
-    return new AudioPolicyManager(clientInterface);
+    AudioPolicyManager *apm = new AudioPolicyManager(clientInterface);
+    status_t status = apm->initialize();
+    if (status != NO_ERROR) {
+        delete apm;
+        apm = nullptr;
+    }
+    return apm;
 }
 
 extern "C" void destroyAudioPolicyManager(AudioPolicyInterface *interface)
diff --git a/services/audiopolicy/managerdefault/Android.bp b/services/audiopolicy/managerdefault/Android.bp
new file mode 100644
index 0000000..8fbeff9
--- /dev/null
+++ b/services/audiopolicy/managerdefault/Android.bp
@@ -0,0 +1,43 @@
+cc_library_shared {
+    name: "libaudiopolicymanagerdefault",
+
+    srcs: [
+        "AudioPolicyManager.cpp",
+        "EngineLibrary.cpp",
+    ],
+
+    export_include_dirs: ["."],
+
+    shared_libs: [
+        "libcutils",
+        "libdl",
+        "libutils",
+        "liblog",
+        "libaudiopolicy",
+        "libsoundtrigger",
+        "libmedia_helper",
+        "libmediametrics",
+        "libbinder",
+        "libhidlbase",
+        "libxml2",
+        // The default audio policy engine is always present in the system image.
+        // libaudiopolicyengineconfigurable can be built in addition by specifying
+        // a dependency on it in the device makefile. There will be no build time
+        // conflict with libaudiopolicyenginedefault.
+        "libaudiopolicyenginedefault",
+    ],
+
+    header_libs: [
+        "libaudiopolicycommon",
+        "libaudiopolicyengine_interface_headers",
+        "libaudiopolicymanager_interface_headers",
+    ],
+
+    static_libs: ["libaudiopolicycomponents"],
+
+    cflags: [
+        "-Wall",
+        "-Werror",
+    ],
+
+}
diff --git a/services/audiopolicy/managerdefault/Android.mk b/services/audiopolicy/managerdefault/Android.mk
deleted file mode 100644
index 684fc9f..0000000
--- a/services/audiopolicy/managerdefault/Android.mk
+++ /dev/null
@@ -1,56 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:= AudioPolicyManager.cpp
-
-LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)
-
-LOCAL_SHARED_LIBRARIES := \
-    libcutils \
-    libutils \
-    liblog \
-    libaudiopolicy \
-    libsoundtrigger
-
-ifeq ($(USE_CONFIGURABLE_AUDIO_POLICY), 1)
-
-ifneq ($(USE_XML_AUDIO_POLICY_CONF), 1)
-$(error Configurable policy does not support legacy conf file)
-endif #ifneq ($(USE_XML_AUDIO_POLICY_CONF), 1)
-
-LOCAL_SHARED_LIBRARIES += libaudiopolicyengineconfigurable
-
-else
-
-LOCAL_SHARED_LIBRARIES += libaudiopolicyenginedefault
-
-endif # ifeq ($(USE_CONFIGURABLE_AUDIO_POLICY), 1)
-
-LOCAL_C_INCLUDES += \
-    $(call include-path-for, audio-utils)
-
-LOCAL_HEADER_LIBRARIES := \
-    libaudiopolicycommon \
-    libaudiopolicyengine_interface_headers \
-    libaudiopolicymanager_interface_headers
-
-LOCAL_STATIC_LIBRARIES := \
-    libaudiopolicycomponents
-
-LOCAL_SHARED_LIBRARIES += libmedia_helper
-LOCAL_SHARED_LIBRARIES += libmediametrics
-
-LOCAL_SHARED_LIBRARIES += libbinder libhidlbase libxml2
-
-ifeq ($(USE_XML_AUDIO_POLICY_CONF), 1)
-LOCAL_CFLAGS += -DUSE_XML_AUDIO_POLICY_CONF
-endif #ifeq ($(USE_XML_AUDIO_POLICY_CONF), 1)
-
-LOCAL_CFLAGS += -Wall -Werror
-
-LOCAL_MULTILIB := $(AUDIOSERVER_MULTILIB)
-
-LOCAL_MODULE:= libaudiopolicymanagerdefault
-
-include $(BUILD_SHARED_LIBRARY)
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index c048de3..b0b63d9 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -42,15 +42,12 @@
 #include <set>
 #include <unordered_set>
 #include <vector>
-#include <AudioPolicyManagerInterface.h>
-#include <AudioPolicyEngineInstance.h>
 #include <cutils/properties.h>
 #include <utils/Log.h>
 #include <media/AudioParameter.h>
 #include <private/android_filesystem_config.h>
 #include <soundtrigger/SoundTrigger.h>
 #include <system/audio.h>
-#include <audio_policy_conf.h>
 #include "AudioPolicyManager.h"
 #include <Serializer.h>
 #include "TypeConverter.h"
@@ -97,7 +94,7 @@
 {
     AudioParameter param(device->address());
     const String8 key(state == AUDIO_POLICY_DEVICE_STATE_AVAILABLE ?
-                AudioParameter::keyStreamConnect : AudioParameter::keyStreamDisconnect);
+                AudioParameter::keyDeviceConnect : AudioParameter::keyDeviceDisconnect);
     param.addInt(key, device->type());
     mpClientInterface->setParameters(AUDIO_IO_HANDLE_NONE, param.toString());
 }
@@ -475,6 +472,10 @@
     std::unordered_set<audio_format_t> formatSet;
     sp<HwModule> primaryModule =
             mHwModules.getModuleFromName(AUDIO_HARDWARE_MODULE_ID_PRIMARY);
+    if (primaryModule == nullptr) {
+        ALOGE("%s() unable to get primary module", __func__);
+        return NO_INIT;
+    }
     DeviceVector declaredDevices = primaryModule->getDeclaredDevices().getDevicesFromTypeMask(
             AUDIO_DEVICE_OUT_ALL_A2DP);
     for (const auto& device : declaredDevices) {
@@ -839,7 +840,7 @@
         // if explicitly requested
         static const uint32_t kRelevantFlags =
                 (AUDIO_OUTPUT_FLAG_HW_AV_SYNC | AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD |
-                 AUDIO_OUTPUT_FLAG_VOIP_RX);
+                 AUDIO_OUTPUT_FLAG_VOIP_RX | AUDIO_OUTPUT_FLAG_MMAP_NOIRQ);
         flags =
             (audio_output_flags_t)((flags & kRelevantFlags) | AUDIO_OUTPUT_FLAG_DIRECT);
     }
@@ -1085,8 +1086,9 @@
     }
 
     audio_config_base_t clientConfig = {.sample_rate = config->sample_rate,
+        .channel_mask = config->channel_mask,
         .format = config->format,
-        .channel_mask = config->channel_mask };
+    };
     *portId = AudioPort::getNextUniqueId();
 
     sp<TrackClientDescriptor> clientDesc =
@@ -2239,16 +2241,22 @@
         return status;
     }
 
-  // increment activity count before calling getNewInputDevice() below as only active sessions
+    // increment activity count before calling getNewInputDevice() below as only active sessions
     // are considered for device selection
     inputDesc->setClientActive(client, true);
 
     // indicate active capture to sound trigger service if starting capture from a mic on
     // primary HW module
     sp<DeviceDescriptor> device = getNewInputDevice(inputDesc);
-    setInputDevice(input, device, true /* force */);
+    if (device != nullptr) {
+        status = setInputDevice(input, device, true /* force */);
+    } else {
+        ALOGW("%s no new input device can be found for descriptor %d",
+                __FUNCTION__, inputDesc->getId());
+        status = BAD_VALUE;
+    }
 
-    if (inputDesc->activeCount()  == 1) {
+    if (status == NO_ERROR && inputDesc->activeCount() == 1) {
         sp<AudioPolicyMix> policyMix = inputDesc->mPolicyMix.promote();
         // if input maps to a dynamic policy with an activity listener, notify of state change
         if ((policyMix != NULL)
@@ -2279,11 +2287,16 @@
                         address, "remote-submix", AUDIO_FORMAT_DEFAULT);
             }
         }
+    } else if (status != NO_ERROR) {
+        // Restore client activity state.
+        inputDesc->setClientActive(client, false);
+        inputDesc->stop();
     }
 
-    ALOGV("%s input %d source = %d exit", __FUNCTION__, input, client->source());
+    ALOGV("%s input %d source = %d status = %d exit",
+            __FUNCTION__, input, client->source(), status);
 
-    return NO_ERROR;
+    return status;
 }
 
 status_t AudioPolicyManager::stopInput(audio_port_handle_t portId)
@@ -4294,17 +4307,8 @@
         : AudioPolicyManager(clientInterface, false /*forTesting*/)
 {
     loadConfig();
-    initialize();
 }
 
-//  This check is to catch any legacy platform updating to Q without having
-//  switched to XML since its deprecation on O.
-// TODO: after Q release, remove this check and flag as XML is now the only
-//        option and all legacy platform should have transitioned to XML.
-#ifndef USE_XML_AUDIO_POLICY_CONF
-#error Audio policy no longer supports legacy .conf configuration format
-#endif
-
 void AudioPolicyManager::loadConfig() {
     if (deserializeAudioPolicyXmlConfig(getConfig()) != NO_ERROR) {
         ALOGE("could not load audio policy configuration file, setting defaults");
@@ -4313,17 +4317,18 @@
 }
 
 status_t AudioPolicyManager::initialize() {
-    // Once policy config has been parsed, retrieve an instance of the engine and initialize it.
-    audio_policy::EngineInstance *engineInstance = audio_policy::EngineInstance::getInstance();
-    if (!engineInstance) {
-        ALOGE("%s:  Could not get an instance of policy engine", __FUNCTION__);
-        return NO_INIT;
-    }
-    // Retrieve the Policy Manager Interface
-    mEngine = engineInstance->queryInterface<AudioPolicyManagerInterface>();
-    if (mEngine == NULL) {
-        ALOGE("%s: Failed to get Policy Engine Interface", __FUNCTION__);
-        return NO_INIT;
+    {
+        auto engLib = EngineLibrary::load(
+                        "libaudiopolicyengine" + getConfig().getEngineLibraryNameSuffix() + ".so");
+        if (!engLib) {
+            ALOGE("%s: Failed to load the engine library", __FUNCTION__);
+            return NO_INIT;
+        }
+        mEngine = engLib->createEngine();
+        if (mEngine == nullptr) {
+            ALOGE("%s: Failed to instantiate the APM engine", __FUNCTION__);
+            return NO_INIT;
+        }
     }
     mEngine->setObserver(this);
     status_t status = mEngine->initCheck();
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.h b/services/audiopolicy/managerdefault/AudioPolicyManager.h
index 612bd8f..5f651cc 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.h
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.h
@@ -34,7 +34,6 @@
 #include <media/PatchBuilder.h>
 #include "AudioPolicyInterface.h"
 
-#include <AudioPolicyManagerInterface.h>
 #include <AudioPolicyManagerObserver.h>
 #include <AudioGain.h>
 #include <AudioPolicyConfig.h>
@@ -49,6 +48,7 @@
 #include <AudioPolicyMix.h>
 #include <EffectDescriptor.h>
 #include <SoundTriggerSession.h>
+#include "EngineLibrary.h"
 #include "TypeConverter.h"
 
 namespace android {
@@ -307,6 +307,8 @@
             return volumeGroup != VOLUME_GROUP_NONE ? NO_ERROR : BAD_VALUE;
         }
 
+        status_t initialize();
+
 protected:
         // A constructor that allows more fine-grained control over initialization process,
         // used in automatic tests.
@@ -321,7 +323,6 @@
         //   - initialize.
         AudioPolicyConfig& getConfig() { return mConfig; }
         void loadConfig();
-        status_t initialize();
 
         // From AudioPolicyManagerObserver
         virtual const AudioPatchCollection &getAudioPatches() const
@@ -752,7 +753,7 @@
         uint32_t nextAudioPortGeneration();
 
         // Audio Policy Engine Interface.
-        AudioPolicyManagerInterface *mEngine;
+        EngineInstance mEngine;
 
         // Surround formats that are enabled manually. Taken into account when
         // "encoded surround" is forced into "manual" mode.
diff --git a/services/audiopolicy/managerdefault/EngineLibrary.cpp b/services/audiopolicy/managerdefault/EngineLibrary.cpp
new file mode 100644
index 0000000..ef699aa
--- /dev/null
+++ b/services/audiopolicy/managerdefault/EngineLibrary.cpp
@@ -0,0 +1,78 @@
+/*
+ * Copyright 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_TAG "APM_EngineLoader"
+
+#include <dlfcn.h>
+#include <utils/Log.h>
+
+#include "EngineLibrary.h"
+
+namespace android {
+
+// static
+std::shared_ptr<EngineLibrary> EngineLibrary::load(std::string libraryPath)
+{
+    std::shared_ptr<EngineLibrary> engLib(new EngineLibrary());
+    return engLib->init(std::move(libraryPath)) ? engLib : nullptr;
+}
+
+EngineLibrary::~EngineLibrary()
+{
+    close();
+}
+
+bool EngineLibrary::init(std::string libraryPath)
+{
+    mLibraryHandle = dlopen(libraryPath.c_str(), 0);
+    if (mLibraryHandle == nullptr) {
+        ALOGE("Could not dlopen %s: %s", libraryPath.c_str(), dlerror());
+        return false;
+    }
+    mCreateEngineInstance = (EngineInterface* (*)())dlsym(mLibraryHandle, "createEngineInstance");
+    mDestroyEngineInstance = (void (*)(EngineInterface*))dlsym(
+            mLibraryHandle, "destroyEngineInstance");
+    if (mCreateEngineInstance == nullptr || mDestroyEngineInstance == nullptr) {
+        ALOGE("Could not find engine interface functions in %s", libraryPath.c_str());
+        close();
+        return false;
+    }
+    ALOGD("Loaded engine from %s", libraryPath.c_str());
+    return true;
+}
+
+EngineInstance EngineLibrary::createEngine()
+{
+    if (mCreateEngineInstance == nullptr || mDestroyEngineInstance == nullptr) {
+        return EngineInstance();
+    }
+    return EngineInstance(mCreateEngineInstance(),
+            [lib = shared_from_this(), destroy = mDestroyEngineInstance] (EngineInterface* e) {
+                destroy(e);
+            });
+}
+
+void EngineLibrary::close()
+{
+    if (mLibraryHandle != nullptr) {
+        dlclose(mLibraryHandle);
+    }
+    mLibraryHandle = nullptr;
+    mCreateEngineInstance = nullptr;
+    mDestroyEngineInstance = nullptr;
+}
+
+}  // namespace android
diff --git a/services/audiopolicy/managerdefault/EngineLibrary.h b/services/audiopolicy/managerdefault/EngineLibrary.h
new file mode 100644
index 0000000..f143916
--- /dev/null
+++ b/services/audiopolicy/managerdefault/EngineLibrary.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright 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.
+ */
+
+#pragma once
+
+#include <functional>
+#include <memory>
+#include <string>
+
+#include <EngineInterface.h>
+
+namespace android {
+
+using EngineInstance = std::unique_ptr<EngineInterface, std::function<void (EngineInterface*)>>;
+
+class EngineLibrary : public std::enable_shared_from_this<EngineLibrary> {
+public:
+    static std::shared_ptr<EngineLibrary> load(std::string libraryPath);
+    ~EngineLibrary();
+
+    EngineLibrary(const EngineLibrary&) = delete;
+    EngineLibrary(EngineLibrary&&) = delete;
+    EngineLibrary& operator=(const EngineLibrary&) = delete;
+    EngineLibrary& operator=(EngineLibrary&&) = delete;
+
+    EngineInstance createEngine();
+
+private:
+    EngineLibrary() = default;
+    bool init(std::string libraryPath);
+    void close();
+
+    void *mLibraryHandle = nullptr;
+    EngineInterface* (*mCreateEngineInstance)() = nullptr;
+    void (*mDestroyEngineInstance)(EngineInterface*) = nullptr;
+};
+
+}  // namespace android
diff --git a/services/audiopolicy/service/AudioPolicyService.cpp b/services/audiopolicy/service/AudioPolicyService.cpp
index a6cda20..90939ce 100644
--- a/services/audiopolicy/service/AudioPolicyService.cpp
+++ b/services/audiopolicy/service/AudioPolicyService.cpp
@@ -29,7 +29,6 @@
 #include <utils/Log.h>
 #include <cutils/properties.h>
 #include <binder/IPCThreadState.h>
-#include <binder/ActivityManager.h>
 #include <binder/PermissionController.h>
 #include <binder/IResultReceiver.h>
 #include <utils/String16.h>
@@ -844,28 +843,26 @@
 // -----------  AudioPolicyService::UidPolicy implementation ----------
 
 void AudioPolicyService::UidPolicy::registerSelf() {
-    ActivityManager am;
-    am.registerUidObserver(this, ActivityManager::UID_OBSERVER_GONE
+    status_t res = mAm.linkToDeath(this);
+    mAm.registerUidObserver(this, ActivityManager::UID_OBSERVER_GONE
             | ActivityManager::UID_OBSERVER_IDLE
             | ActivityManager::UID_OBSERVER_ACTIVE
             | ActivityManager::UID_OBSERVER_PROCSTATE,
             ActivityManager::PROCESS_STATE_UNKNOWN,
             String16("audioserver"));
-    status_t res = am.linkToDeath(this);
     if (!res) {
         Mutex::Autolock _l(mLock);
         mObserverRegistered = true;
     } else {
         ALOGE("UidPolicy::registerSelf linkToDeath failed: %d", res);
 
-        am.unregisterUidObserver(this);
+        mAm.unregisterUidObserver(this);
     }
 }
 
 void AudioPolicyService::UidPolicy::unregisterSelf() {
-    ActivityManager am;
-    am.unlinkToDeath(this);
-    am.unregisterUidObserver(this);
+    mAm.unlinkToDeath(this);
+    mAm.unregisterUidObserver(this);
     Mutex::Autolock _l(mLock);
     mObserverRegistered = false;
 }
diff --git a/services/audiopolicy/service/AudioPolicyService.h b/services/audiopolicy/service/AudioPolicyService.h
index e467f70..74aea0d 100644
--- a/services/audiopolicy/service/AudioPolicyService.h
+++ b/services/audiopolicy/service/AudioPolicyService.h
@@ -23,6 +23,7 @@
 #include <utils/String8.h>
 #include <utils/Vector.h>
 #include <utils/SortedVector.h>
+#include <binder/ActivityManager.h>
 #include <binder/BinderService.h>
 #include <binder/IUidObserver.h>
 #include <system/audio.h>
@@ -387,6 +388,7 @@
 
         wp<AudioPolicyService> mService;
         Mutex mLock;
+        ActivityManager mAm;
         bool mObserverRegistered;
         std::unordered_map<uid_t, std::pair<bool, int>> mOverrideUids;
         std::unordered_map<uid_t, std::pair<bool, int>> mCachedUids;
diff --git a/services/audiopolicy/tests/audiopolicymanager_tests.cpp b/services/audiopolicy/tests/audiopolicymanager_tests.cpp
index de5670c..e10a716 100644
--- a/services/audiopolicy/tests/audiopolicymanager_tests.cpp
+++ b/services/audiopolicy/tests/audiopolicymanager_tests.cpp
@@ -30,7 +30,16 @@
 
 using namespace android;
 
-TEST(AudioPolicyManagerTestInit, Failure) {
+TEST(AudioPolicyManagerTestInit, EngineFailure) {
+    AudioPolicyTestClient client;
+    AudioPolicyTestManager manager(&client);
+    manager.getConfig().setDefault();
+    manager.getConfig().setEngineLibraryNameSuffix("non-existent");
+    ASSERT_EQ(NO_INIT, manager.initialize());
+    ASSERT_EQ(NO_INIT, manager.initCheck());
+}
+
+TEST(AudioPolicyManagerTestInit, ClientFailure) {
     AudioPolicyTestClient client;
     AudioPolicyTestManager manager(&client);
     manager.getConfig().setDefault();
diff --git a/services/camera/libcameraservice/Android.bp b/services/camera/libcameraservice/Android.bp
index 1c1f5e6..c50a3c6 100644
--- a/services/camera/libcameraservice/Android.bp
+++ b/services/camera/libcameraservice/Android.bp
@@ -69,6 +69,10 @@
         "utils/LatencyHistogram.cpp",
     ],
 
+    header_libs: [
+        "libmediadrm_headers"
+    ],
+
     shared_libs: [
         "libbase",
         "libdl",
@@ -86,10 +90,9 @@
         "libfmq",
         "libgui",
         "libhardware",
-        "libhwbinder",
         "libhidlbase",
-        "libhidltransport",
         "libjpeg",
+        "libmedia_codeclist",
         "libmedia_omx",
         "libmemunreachable",
         "libsensorprivacy",
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index b20c9a4..06c6996 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -2640,14 +2640,13 @@
 void CameraService::UidPolicy::registerSelf() {
     Mutex::Autolock _l(mUidLock);
 
-    ActivityManager am;
     if (mRegistered) return;
-    am.registerUidObserver(this, ActivityManager::UID_OBSERVER_GONE
+    status_t res = mAm.linkToDeath(this);
+    mAm.registerUidObserver(this, ActivityManager::UID_OBSERVER_GONE
             | ActivityManager::UID_OBSERVER_IDLE
             | ActivityManager::UID_OBSERVER_ACTIVE | ActivityManager::UID_OBSERVER_PROCSTATE,
             ActivityManager::PROCESS_STATE_UNKNOWN,
             String16("cameraserver"));
-    status_t res = am.linkToDeath(this);
     if (res == OK) {
         mRegistered = true;
         ALOGV("UidPolicy: Registered with ActivityManager");
@@ -2657,9 +2656,8 @@
 void CameraService::UidPolicy::unregisterSelf() {
     Mutex::Autolock _l(mUidLock);
 
-    ActivityManager am;
-    am.unregisterUidObserver(this);
-    am.unlinkToDeath(this);
+    mAm.unregisterUidObserver(this);
+    mAm.unlinkToDeath(this);
     mRegistered = false;
     mActiveUids.clear();
     ALOGV("UidPolicy: Unregistered with ActivityManager");
diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h
index 22842a1..8bb78cd 100644
--- a/services/camera/libcameraservice/CameraService.h
+++ b/services/camera/libcameraservice/CameraService.h
@@ -25,6 +25,7 @@
 #include <cutils/multiuser.h>
 #include <utils/Vector.h>
 #include <utils/KeyedVector.h>
+#include <binder/ActivityManager.h>
 #include <binder/AppOpsManager.h>
 #include <binder/BinderService.h>
 #include <binder/IAppOpsCallback.h>
@@ -571,6 +572,7 @@
 
         Mutex mUidLock;
         bool mRegistered;
+        ActivityManager mAm;
         wp<CameraService> mService;
         std::unordered_set<uid_t> mActiveUids;
         // Monitored uid map to cached procState and refCount pair
diff --git a/services/camera/libcameraservice/api2/HeicCompositeStream.cpp b/services/camera/libcameraservice/api2/HeicCompositeStream.cpp
index 052112a..d21641c 100644
--- a/services/camera/libcameraservice/api2/HeicCompositeStream.cpp
+++ b/services/camera/libcameraservice/api2/HeicCompositeStream.cpp
@@ -28,7 +28,7 @@
 #include <utils/Log.h>
 #include <utils/Trace.h>
 
-#include <media/ICrypto.h>
+#include <mediadrm/ICrypto.h>
 #include <media/MediaCodecBuffer.h>
 #include <media/stagefright/foundation/ABuffer.h>
 #include <media/stagefright/foundation/AMessage.h>
diff --git a/services/camera/libcameraservice/common/CameraProviderManager.h b/services/camera/libcameraservice/common/CameraProviderManager.h
index 3a4655c..954c0d9 100644
--- a/services/camera/libcameraservice/common/CameraProviderManager.h
+++ b/services/camera/libcameraservice/common/CameraProviderManager.h
@@ -273,6 +273,7 @@
     bool isLogicalCamera(const std::string& id, std::vector<std::string>* physicalCameraIds);
 
     bool isPublicallyHiddenSecureCamera(const std::string& id) const;
+
     bool isHiddenPhysicalCamera(const std::string& cameraId) const;
 
     static const float kDepthARTolerance;
diff --git a/services/camera/libcameraservice/tests/Android.mk b/services/camera/libcameraservice/tests/Android.mk
index b4e7c32..ec5e876 100644
--- a/services/camera/libcameraservice/tests/Android.mk
+++ b/services/camera/libcameraservice/tests/Android.mk
@@ -23,7 +23,6 @@
     libcameraservice \
     libhidlbase \
     liblog \
-    libhidltransport \
     libcamera_client \
     libcamera_metadata \
     libutils \
diff --git a/services/mediaanalytics/Android.bp b/services/mediaanalytics/Android.bp
index 72f4b52..c27aced 100644
--- a/services/mediaanalytics/Android.bp
+++ b/services/mediaanalytics/Android.bp
@@ -50,7 +50,7 @@
         "frameworks/av/media/libstagefright/rtsp",
         "frameworks/av/media/libstagefright/webm",
         "frameworks/av/include/media",
-        "frameworks/av/include/camera",
+        "frameworks/av/camera/include/camera",
         "frameworks/native/include/media/openmax",
         "frameworks/native/include/media/hardware",
         "external/tremolo/Tremolo",
diff --git a/services/mediaanalytics/statsd_audiopolicy.cpp b/services/mediaanalytics/statsd_audiopolicy.cpp
index 06c4dde..95cb274 100644
--- a/services/mediaanalytics/statsd_audiopolicy.cpp
+++ b/services/mediaanalytics/statsd_audiopolicy.cpp
@@ -60,14 +60,14 @@
         metrics_proto.set_status(status);
     }
     //string char kAudioPolicyRqstSrc[] = "android.media.audiopolicy.rqst.src";
-    char *rqst_src = NULL;
-    if (item->getCString("android.media.audiopolicy.rqst.src", &rqst_src)) {
-        metrics_proto.set_request_source(rqst_src);
+    std::string rqst_src;
+    if (item->getString("android.media.audiopolicy.rqst.src", &rqst_src)) {
+        metrics_proto.set_request_source(std::move(rqst_src));
     }
     //string char kAudioPolicyRqstPkg[] = "android.media.audiopolicy.rqst.pkg";
-    char *rqst_pkg = NULL;
-    if (item->getCString("android.media.audiopolicy.rqst.pkg", &rqst_pkg)) {
-        metrics_proto.set_request_package(rqst_pkg);
+    std::string rqst_pkg;
+    if (item->getString("android.media.audiopolicy.rqst.pkg", &rqst_pkg)) {
+        metrics_proto.set_request_package(std::move(rqst_pkg));
     }
     //int32 char kAudioPolicyRqstSession[] = "android.media.audiopolicy.rqst.session";
     int32_t rqst_session = -1;
@@ -75,20 +75,20 @@
         metrics_proto.set_request_session(rqst_session);
     }
     //string char kAudioPolicyRqstDevice[] = "android.media.audiopolicy.rqst.device";
-    char *rqst_device = NULL;
-    if (item->getCString("android.media.audiopolicy.rqst.device", &rqst_device)) {
-        metrics_proto.set_request_device(rqst_device);
+    std::string rqst_device;
+    if (item->getString("android.media.audiopolicy.rqst.device", &rqst_device)) {
+        metrics_proto.set_request_device(std::move(rqst_device));
     }
 
     //string char kAudioPolicyActiveSrc[] = "android.media.audiopolicy.active.src";
-    char *active_src = NULL;
-    if (item->getCString("android.media.audiopolicy.active.src", &active_src)) {
-        metrics_proto.set_active_source(active_src);
+    std::string active_src;
+    if (item->getString("android.media.audiopolicy.active.src", &active_src)) {
+        metrics_proto.set_active_source(std::move(active_src));
     }
     //string char kAudioPolicyActivePkg[] = "android.media.audiopolicy.active.pkg";
-    char *active_pkg = NULL;
-    if (item->getCString("android.media.audiopolicy.active.pkg", &active_pkg)) {
-        metrics_proto.set_active_package(active_pkg);
+    std::string active_pkg;
+    if (item->getString("android.media.audiopolicy.active.pkg", &active_pkg)) {
+        metrics_proto.set_active_package(std::move(active_pkg));
     }
     //int32 char kAudioPolicyActiveSession[] = "android.media.audiopolicy.active.session";
     int32_t active_session = -1;
@@ -96,9 +96,9 @@
         metrics_proto.set_active_session(active_session);
     }
     //string char kAudioPolicyActiveDevice[] = "android.media.audiopolicy.active.device";
-    char *active_device = NULL;
-    if (item->getCString("android.media.audiopolicy.active.device", &active_device)) {
-        metrics_proto.set_active_device(active_device);
+    std::string active_device;
+    if (item->getString("android.media.audiopolicy.active.device", &active_device)) {
+        metrics_proto.set_active_device(std::move(active_device));
     }
 
 
@@ -119,14 +119,6 @@
         ALOGV("NOT sending: private data (len=%zu)", strlen(serialized.c_str()));
     }
 
-    // must free the strings that we were given
-    free(rqst_src);
-    free(rqst_pkg);
-    free(rqst_device);
-    free(active_src);
-    free(active_pkg);
-    free(active_device);
-
     return true;
 }
 
diff --git a/services/mediaanalytics/statsd_audiorecord.cpp b/services/mediaanalytics/statsd_audiorecord.cpp
index c9edb27..7c7a62c 100644
--- a/services/mediaanalytics/statsd_audiorecord.cpp
+++ b/services/mediaanalytics/statsd_audiorecord.cpp
@@ -54,14 +54,14 @@
 
     // flesh out the protobuf we'll hand off with our data
     //
-    char *encoding = NULL;
-    if (item->getCString("android.media.audiorecord.encoding", &encoding)) {
-        metrics_proto.set_encoding(encoding);
+    std::string encoding;
+    if (item->getString("android.media.audiorecord.encoding", &encoding)) {
+        metrics_proto.set_encoding(std::move(encoding));
     }
 
-    char *source = NULL;
-    if (item->getCString("android.media.audiorecord.source", &source)) {
-        metrics_proto.set_source(source);
+    std::string source;
+    if (item->getString("android.media.audiorecord.source", &source)) {
+        metrics_proto.set_source(std::move(source));
     }
 
     int32_t latency = -1;
@@ -101,11 +101,11 @@
         metrics_proto.set_error_code(errcode);
     }
 
-    char *errfunc = NULL;
-    if (item->getCString("android.media.audiorecord.errfunc", &errfunc)) {
-        metrics_proto.set_error_function(errfunc);
-    } else if (item->getCString("android.media.audiorecord.lastError.at", &errfunc)) {
-        metrics_proto.set_error_function(errfunc);
+    std::string errfunc;
+    if (item->getString("android.media.audiorecord.errfunc", &errfunc)) {
+        metrics_proto.set_error_function(std::move(errfunc));
+    } else if (item->getString("android.media.audiorecord.lastError.at", &errfunc)) {
+        metrics_proto.set_error_function(std::move(errfunc));
     }
 
     // portId (int32)
@@ -119,9 +119,9 @@
         metrics_proto.set_frame_count(frameCount);
     }
     // attributes (string)
-    char *attributes = NULL;
-    if (item->getCString("android.media.audiorecord.attributes", &attributes)) {
-        metrics_proto.set_attributes(attributes);
+    std::string attributes;
+    if (item->getString("android.media.audiorecord.attributes", &attributes)) {
+        metrics_proto.set_attributes(std::move(attributes));
     }
     // channelMask (int64)
     int64_t channelMask = -1;
@@ -152,12 +152,6 @@
         ALOGV("NOT sending: private data (len=%zu)", strlen(serialized.c_str()));
     }
 
-    // must free the strings that we were given
-    free(encoding);
-    free(source);
-    free(errfunc);
-    free(attributes);
-
     return true;
 }
 
diff --git a/services/mediaanalytics/statsd_audiothread.cpp b/services/mediaanalytics/statsd_audiothread.cpp
index 8232424..e9d6b17 100644
--- a/services/mediaanalytics/statsd_audiothread.cpp
+++ b/services/mediaanalytics/statsd_audiothread.cpp
@@ -56,9 +56,9 @@
 
     // flesh out the protobuf we'll hand off with our data
     //
-    char *mytype = NULL;
-    if (item->getCString(MM_PREFIX "type", &mytype)) {
-        metrics_proto.set_type(mytype);
+    std::string mytype;
+    if (item->getString(MM_PREFIX "type", &mytype)) {
+        metrics_proto.set_type(std::move(mytype));
     }
     int32_t framecount = -1;
     if (item->getInt32(MM_PREFIX "framecount", &framecount)) {
@@ -68,17 +68,17 @@
     if (item->getInt32(MM_PREFIX "samplerate", &samplerate)) {
         metrics_proto.set_samplerate(samplerate);
     }
-    char *workhist = NULL;
-    if (item->getCString(MM_PREFIX "workMs.hist", &workhist)) {
-        metrics_proto.set_work_millis_hist(workhist);
+    std::string workhist;
+    if (item->getString(MM_PREFIX "workMs.hist", &workhist)) {
+        metrics_proto.set_work_millis_hist(std::move(workhist));
     }
-    char *latencyhist = NULL;
-    if (item->getCString(MM_PREFIX "latencyMs.hist", &latencyhist)) {
-        metrics_proto.set_latency_millis_hist(latencyhist);
+    std::string latencyhist;
+    if (item->getString(MM_PREFIX "latencyMs.hist", &latencyhist)) {
+        metrics_proto.set_latency_millis_hist(std::move(latencyhist));
     }
-    char *warmuphist = NULL;
-    if (item->getCString(MM_PREFIX "warmupMs.hist", &warmuphist)) {
-        metrics_proto.set_warmup_millis_hist(warmuphist);
+    std::string warmuphist;
+    if (item->getString(MM_PREFIX "warmupMs.hist", &warmuphist)) {
+        metrics_proto.set_warmup_millis_hist(std::move(warmuphist));
     }
     int64_t underruns = -1;
     if (item->getInt64(MM_PREFIX "underruns", &underruns)) {
@@ -108,9 +108,9 @@
         metrics_proto.set_port_id(port_id);
     }
     // item->setCString(MM_PREFIX "type", threadTypeToString(mType));
-    char *type = NULL;
-    if (item->getCString(MM_PREFIX "type", &type)) {
-        metrics_proto.set_type(type);
+    std::string type;
+    if (item->getString(MM_PREFIX "type", &type)) {
+        metrics_proto.set_type(std::move(type));
     }
     // item->setInt32(MM_PREFIX "sampleRate", (int32_t)mSampleRate);
     int32_t sample_rate = -1;
@@ -123,9 +123,9 @@
         metrics_proto.set_channel_mask(channel_mask);
     }
     // item->setCString(MM_PREFIX "encoding", toString(mFormat).c_str());
-    char *encoding = NULL;
-    if (item->getCString(MM_PREFIX "encoding", &encoding)) {
-        metrics_proto.set_encoding(encoding);
+    std::string encoding;
+    if (item->getString(MM_PREFIX "encoding", &encoding)) {
+        metrics_proto.set_encoding(std::move(encoding));
     }
     // item->setInt32(MM_PREFIX "frameCount", (int32_t)mFrameCount);
     int32_t frame_count = -1;
@@ -133,14 +133,14 @@
         metrics_proto.set_frame_count(frame_count);
     }
     // item->setCString(MM_PREFIX "outDevice", toString(mOutDevice).c_str());
-    char *outDevice = NULL;
-    if (item->getCString(MM_PREFIX "outDevice", &outDevice)) {
-        metrics_proto.set_output_device(outDevice);
+    std::string outDevice;
+    if (item->getString(MM_PREFIX "outDevice", &outDevice)) {
+        metrics_proto.set_output_device(std::move(outDevice));
     }
     // item->setCString(MM_PREFIX "inDevice", toString(mInDevice).c_str());
-    char *inDevice = NULL;
-    if (item->getCString(MM_PREFIX "inDevice", &inDevice)) {
-        metrics_proto.set_input_device(inDevice);
+    std::string inDevice;
+    if (item->getString(MM_PREFIX "inDevice", &inDevice)) {
+        metrics_proto.set_input_device(std::move(inDevice));
     }
     // item->setDouble(MM_PREFIX "ioJitterMs.mean", mIoJitterMs.getMean());
     double iojitters_ms_mean = -1;
@@ -201,16 +201,6 @@
         ALOGV("NOT sending: private data (len=%zu)", strlen(serialized.c_str()));
     }
 
-    // must free the strings that we were given
-    free(mytype);
-    free(workhist);
-    free(latencyhist);
-    free(warmuphist);
-    free(type);
-    free(encoding);
-    free(inDevice);
-    free(outDevice);
-
     return true;
 }
 
diff --git a/services/mediaanalytics/statsd_audiotrack.cpp b/services/mediaanalytics/statsd_audiotrack.cpp
index f250ced..57cda99 100644
--- a/services/mediaanalytics/statsd_audiotrack.cpp
+++ b/services/mediaanalytics/statsd_audiotrack.cpp
@@ -57,23 +57,23 @@
 
     // static constexpr char kAudioTrackStreamType[] = "android.media.audiotrack.streamtype";
     // optional string streamType;
-    char *streamtype = NULL;
-    if (item->getCString("android.media.audiotrack.streamtype", &streamtype)) {
-        metrics_proto.set_stream_type(streamtype);
+    std::string streamtype;
+    if (item->getString("android.media.audiotrack.streamtype", &streamtype)) {
+        metrics_proto.set_stream_type(std::move(streamtype));
     }
 
     // static constexpr char kAudioTrackContentType[] = "android.media.audiotrack.type";
     // optional string contentType;
-    char *contenttype = NULL;
-    if (item->getCString("android.media.audiotrack.type", &contenttype)) {
-        metrics_proto.set_content_type(contenttype);
+    std::string contenttype;
+    if (item->getString("android.media.audiotrack.type", &contenttype)) {
+        metrics_proto.set_content_type(std::move(contenttype));
     }
 
     // static constexpr char kAudioTrackUsage[] = "android.media.audiotrack.usage";
     // optional string trackUsage;
-    char *trackusage = NULL;
-    if (item->getCString("android.media.audiotrack.usage", &trackusage)) {
-        metrics_proto.set_track_usage(trackusage);
+    std::string trackusage;
+    if (item->getString("android.media.audiotrack.usage", &trackusage)) {
+        metrics_proto.set_track_usage(std::move(trackusage));
     }
 
     // static constexpr char kAudioTrackSampleRate[] = "android.media.audiotrack.samplerate";
@@ -111,9 +111,9 @@
         metrics_proto.set_port_id(port_id);
     }
     // encoding (string)
-    char *encoding = NULL;
-    if (item->getCString("android.media.audiotrack.encoding", &encoding)) {
-        metrics_proto.set_encoding(encoding);
+    std::string encoding;
+    if (item->getString("android.media.audiotrack.encoding", &encoding)) {
+        metrics_proto.set_encoding(std::move(encoding));
     }
     // frameCount (int32)
     int32_t frame_count = -1;
@@ -121,9 +121,9 @@
         metrics_proto.set_frame_count(frame_count);
     }
     // attributes (string)
-    char *attributes = NULL;
-    if (item->getCString("android.media.audiotrack.attributes", &attributes)) {
-        metrics_proto.set_attributes(attributes);
+    std::string attributes;
+    if (item->getString("android.media.audiotrack.attributes", &attributes)) {
+        metrics_proto.set_attributes(std::move(attributes));
     }
 
     std::string serialized;
@@ -143,13 +143,6 @@
         ALOGV("NOT sending: private data (len=%zu)", strlen(serialized.c_str()));
     }
 
-    // must free the strings that we were given
-    free(streamtype);
-    free(contenttype);
-    free(trackusage);
-    free(encoding);
-    free(attributes);
-
     return true;
 }
 
diff --git a/services/mediaanalytics/statsd_codec.cpp b/services/mediaanalytics/statsd_codec.cpp
index dc8e4ef..bf82e50 100644
--- a/services/mediaanalytics/statsd_codec.cpp
+++ b/services/mediaanalytics/statsd_codec.cpp
@@ -55,19 +55,19 @@
     // flesh out the protobuf we'll hand off with our data
     //
     // android.media.mediacodec.codec   string
-    char *codec = NULL;
-    if (item->getCString("android.media.mediacodec.codec", &codec)) {
-        metrics_proto.set_codec(codec);
+    std::string codec;
+    if (item->getString("android.media.mediacodec.codec", &codec)) {
+        metrics_proto.set_codec(std::move(codec));
     }
     // android.media.mediacodec.mime    string
-    char *mime = NULL;
-    if (item->getCString("android.media.mediacodec.mime", &mime)) {
-        metrics_proto.set_mime(mime);
+    std::string mime;
+    if (item->getString("android.media.mediacodec.mime", &mime)) {
+        metrics_proto.set_mime(std::move(mime));
     }
     // android.media.mediacodec.mode    string
-    char *mode = NULL;
-    if ( item->getCString("android.media.mediacodec.mode", &mode)) {
-        metrics_proto.set_mode(mode);
+    std::string mode;
+    if ( item->getString("android.media.mediacodec.mode", &mode)) {
+        metrics_proto.set_mode(std::move(mode));
     }
     // android.media.mediacodec.encoder int32
     int32_t encoder = -1;
@@ -125,9 +125,9 @@
         metrics_proto.set_error_code(errcode);
     }
     // android.media.mediacodec.errstate        string
-    char *errstate = NULL;
-    if ( item->getCString("android.media.mediacodec.errstate", &errstate)) {
-        metrics_proto.set_error_state(errstate);
+    std::string errstate;
+    if ( item->getString("android.media.mediacodec.errstate", &errstate)) {
+        metrics_proto.set_error_state(std::move(errstate));
     }
     // android.media.mediacodec.latency.max  int64
     int64_t latency_max = -1;
@@ -173,12 +173,6 @@
         ALOGV("NOT sending: private data (len=%zu)", strlen(serialized.c_str()));
     }
 
-    // must free the strings that we were given
-    free(codec);
-    free(mime);
-    free(mode);
-    free(errstate);
-
     return true;
 }
 
diff --git a/services/mediaanalytics/statsd_extractor.cpp b/services/mediaanalytics/statsd_extractor.cpp
index 395c912..d84930c 100644
--- a/services/mediaanalytics/statsd_extractor.cpp
+++ b/services/mediaanalytics/statsd_extractor.cpp
@@ -56,14 +56,14 @@
     //
 
     // android.media.mediaextractor.fmt         string
-    char *fmt = NULL;
-    if (item->getCString("android.media.mediaextractor.fmt", &fmt)) {
-        metrics_proto.set_format(fmt);
+    std::string fmt;
+    if (item->getString("android.media.mediaextractor.fmt", &fmt)) {
+        metrics_proto.set_format(std::move(fmt));
     }
     // android.media.mediaextractor.mime        string
-    char *mime = NULL;
-    if (item->getCString("android.media.mediaextractor.mime", &mime)) {
-        metrics_proto.set_mime(mime);
+    std::string mime;
+    if (item->getString("android.media.mediaextractor.mime", &mime)) {
+        metrics_proto.set_mime(std::move(mime));
     }
     // android.media.mediaextractor.ntrk        int32
     int32_t ntrk = -1;
@@ -88,10 +88,6 @@
         ALOGV("NOT sending: private data (len=%zu)", strlen(serialized.c_str()));
     }
 
-    // must free the strings that we were given
-    free(fmt);
-    free(mime);
-
     return true;
 }
 
diff --git a/services/mediaanalytics/statsd_nuplayer.cpp b/services/mediaanalytics/statsd_nuplayer.cpp
index 5ec118a..e6e0f2c 100644
--- a/services/mediaanalytics/statsd_nuplayer.cpp
+++ b/services/mediaanalytics/statsd_nuplayer.cpp
@@ -62,13 +62,13 @@
     // differentiate between nuplayer and nuplayer2
     metrics_proto.set_whichplayer(item->getKey().c_str());
 
-    char *video_mime = NULL;
-    if (item->getCString("android.media.mediaplayer.video.mime", &video_mime)) {
-        metrics_proto.set_video_mime(video_mime);
+    std::string video_mime;
+    if (item->getString("android.media.mediaplayer.video.mime", &video_mime)) {
+        metrics_proto.set_video_mime(std::move(video_mime));
     }
-    char *video_codec = NULL;
-    if (item->getCString("android.media.mediaplayer.video.codec", &video_codec)) {
-        metrics_proto.set_video_codec(video_codec);
+    std::string video_codec;
+    if (item->getString("android.media.mediaplayer.video.codec", &video_codec)) {
+        metrics_proto.set_video_codec(std::move(video_codec));
     }
 
     int32_t width = -1;
@@ -97,13 +97,13 @@
         metrics_proto.set_framerate(fps);
     }
 
-    char *audio_mime = NULL;
-    if (item->getCString("android.media.mediaplayer.audio.mime", &audio_mime)) {
-        metrics_proto.set_audio_mime(audio_mime);
+    std::string audio_mime;
+    if (item->getString("android.media.mediaplayer.audio.mime", &audio_mime)) {
+        metrics_proto.set_audio_mime(std::move(audio_mime));
     }
-    char *audio_codec = NULL;
-    if (item->getCString("android.media.mediaplayer.audio.codec", &audio_codec)) {
-        metrics_proto.set_audio_codec(audio_codec);
+    std::string audio_codec;
+    if (item->getString("android.media.mediaplayer.audio.codec", &audio_codec)) {
+        metrics_proto.set_audio_codec(std::move(audio_codec));
     }
 
     int64_t duration_ms = -1;
@@ -123,14 +123,14 @@
     if (item->getInt32("android.media.mediaplayer.errcode", &error_code)) {
         metrics_proto.set_error_code(error_code);
     }
-    char *error_state = NULL;
-    if (item->getCString("android.media.mediaplayer.errstate", &error_state)) {
-        metrics_proto.set_error_state(error_state);
+    std::string error_state;
+    if (item->getString("android.media.mediaplayer.errstate", &error_state)) {
+        metrics_proto.set_error_state(std::move(error_state));
     }
 
-    char *data_source_type = NULL;
-    if (item->getCString("android.media.mediaplayer.dataSource", &data_source_type)) {
-        metrics_proto.set_data_source_type(data_source_type);
+    std::string data_source_type;
+    if (item->getString("android.media.mediaplayer.dataSource", &data_source_type)) {
+        metrics_proto.set_data_source_type(std::move(data_source_type));
     }
 
     int64_t rebufferingMs = -1;
@@ -164,14 +164,6 @@
         ALOGV("NOT sending: private data (len=%zu)", strlen(serialized.c_str()));
     }
 
-    // must free the strings that we were given
-    free(video_mime);
-    free(video_codec);
-    free(audio_mime);
-    free(audio_codec);
-    free(error_state);
-    free(data_source_type);
-
     return true;
 }
 
diff --git a/services/mediaanalytics/statsd_recorder.cpp b/services/mediaanalytics/statsd_recorder.cpp
index 4d981b4..d286f00 100644
--- a/services/mediaanalytics/statsd_recorder.cpp
+++ b/services/mediaanalytics/statsd_recorder.cpp
@@ -56,14 +56,14 @@
     //
 
     // string kRecorderAudioMime = "android.media.mediarecorder.audio.mime";
-    char *audio_mime = NULL;
-    if (item->getCString("android.media.mediarecorder.audio.mime", &audio_mime)) {
-        metrics_proto.set_audio_mime(audio_mime);
+    std::string audio_mime;
+    if (item->getString("android.media.mediarecorder.audio.mime", &audio_mime)) {
+        metrics_proto.set_audio_mime(std::move(audio_mime));
     }
     // string kRecorderVideoMime = "android.media.mediarecorder.video.mime";
-    char *video_mime = NULL;
-    if (item->getCString("android.media.mediarecorder.video.mime", &video_mime)) {
-        metrics_proto.set_video_mime(video_mime);
+    std::string video_mime;
+    if (item->getString("android.media.mediarecorder.video.mime", &video_mime)) {
+        metrics_proto.set_video_mime(std::move(video_mime));
     }
     // int32 kRecorderVideoProfile = "android.media.mediarecorder.video-encoder-profile";
     int32_t videoProfile = -1;
@@ -183,10 +183,6 @@
         ALOGV("NOT sending: private data (len=%zu)", strlen(serialized.c_str()));
     }
 
-    // must free the strings that we were given
-    free(audio_mime);
-    free(video_mime);
-
     return true;
 }
 
diff --git a/services/mediacodec/Android.bp b/services/mediacodec/Android.bp
index 99a6d6b..36042a4 100644
--- a/services/mediacodec/Android.bp
+++ b/services/mediacodec/Android.bp
@@ -10,8 +10,6 @@
         "libavservices_minijail",
         "libbase",
         "libhidlbase",
-        "libhidltransport",
-        "libhwbinder",
         "liblog",
         "libmedia_codecserviceregistrant",
     ],
diff --git a/services/mediacodec/Android.mk b/services/mediacodec/Android.mk
index ecc8408..d878d72 100644
--- a/services/mediacodec/Android.mk
+++ b/services/mediacodec/Android.mk
@@ -39,9 +39,7 @@
     libbase \
     libavservices_minijail_vendor \
     libcutils \
-    libhwbinder \
     libhidlbase \
-    libhidltransport \
     libstagefright_omx \
     libstagefright_xmlparser \
     android.hardware.media.omx@1.0 \
diff --git a/services/mediadrm/Android.mk b/services/mediadrm/Android.mk
index 227a29d..9f03964 100644
--- a/services/mediadrm/Android.mk
+++ b/services/mediadrm/Android.mk
@@ -20,6 +20,10 @@
     MediaDrmService.cpp \
     main_mediadrmserver.cpp
 
+LOCAL_HEADER_LIBRARIES:= \
+    libmedia_headers \
+    libmediadrm_headers
+
 LOCAL_SHARED_LIBRARIES:= \
     libbinder \
     liblog \
@@ -27,7 +31,6 @@
     libutils \
     libhidlbase \
     libhidlmemory \
-    libhidltransport \
     android.hardware.drm@1.0 \
     android.hardware.drm@1.1 \
     android.hardware.drm@1.2
diff --git a/services/mediaextractor/Android.bp b/services/mediaextractor/Android.bp
index b812244..e906500 100644
--- a/services/mediaextractor/Android.bp
+++ b/services/mediaextractor/Android.bp
@@ -8,6 +8,7 @@
     srcs: ["MediaExtractorService.cpp"],
 
     shared_libs: [
+        "libdatasource",
         "libmedia",
         "libstagefright",
         "libbinder",
diff --git a/services/mediaextractor/MediaExtractorService.cpp b/services/mediaextractor/MediaExtractorService.cpp
index 36e084b..6239fb2 100644
--- a/services/mediaextractor/MediaExtractorService.cpp
+++ b/services/mediaextractor/MediaExtractorService.cpp
@@ -20,8 +20,8 @@
 
 #include <utils/Vector.h>
 
+#include <datasource/DataSourceFactory.h>
 #include <media/DataSource.h>
-#include <media/stagefright/DataSourceFactory.h>
 #include <media/stagefright/InterfaceUtils.h>
 #include <media/stagefright/MediaExtractorFactory.h>
 #include <media/stagefright/RemoteDataSource.h>
@@ -55,7 +55,7 @@
 
 sp<IDataSource> MediaExtractorService::makeIDataSource(int fd, int64_t offset, int64_t length)
 {
-    sp<DataSource> source = DataSourceFactory::CreateFromFd(fd, offset, length);
+    sp<DataSource> source = DataSourceFactory::getInstance()->CreateFromFd(fd, offset, length);
     return CreateIDataSourceFromDataSource(source);
 }
 
diff --git a/services/medialog/Android.bp b/services/medialog/Android.bp
index bee5d25..74b63d5 100644
--- a/services/medialog/Android.bp
+++ b/services/medialog/Android.bp
@@ -6,6 +6,10 @@
         "MediaLogService.cpp",
     ],
 
+    header_libs: [
+        "libmedia_headers",
+    ],
+
     shared_libs: [
         "libaudioutils",
         "libbinder",
diff --git a/services/oboeservice/Android.mk b/services/oboeservice/Android.mk
index 3d5f140..5e4cd39 100644
--- a/services/oboeservice/Android.mk
+++ b/services/oboeservice/Android.mk
@@ -14,7 +14,6 @@
     $(call include-path-for, audio-utils) \
     frameworks/native/include \
     system/core/base/include \
-    $(TOP)/frameworks/native/media/libaaudio/include/include \
     $(TOP)/frameworks/av/media/libaaudio/include \
     $(TOP)/frameworks/av/media/utils/include \
     frameworks/native/include \
@@ -47,7 +46,7 @@
 LOCAL_CFLAGS += -Wall -Werror
 
 LOCAL_SHARED_LIBRARIES :=  \
-    libaaudio \
+    libaaudio_internal \
     libaudioflinger \
     libaudioclient \
     libbinder \
diff --git a/services/soundtrigger/Android.bp b/services/soundtrigger/Android.bp
index 3f02f48..1bbd591 100644
--- a/services/soundtrigger/Android.bp
+++ b/services/soundtrigger/Android.bp
@@ -31,10 +31,8 @@
         "libaudioutils",
         "libmediautils",
 
-        "libhwbinder",
         "libhidlbase",
         "libhidlmemory",
-        "libhidltransport",
         "libbase",
         "libaudiohal",
         "libaudiohal_deathhandler",
diff --git a/tools/resampler_tools/Android.bp b/tools/resampler_tools/Android.bp
new file mode 100644
index 0000000..7549359
--- /dev/null
+++ b/tools/resampler_tools/Android.bp
@@ -0,0 +1,15 @@
+// Copyright 2005 The Android Open Source Project
+//
+// Android.mk for resampler_tools
+//
+
+cc_binary_host {
+    name: "fir",
+
+    srcs: ["fir.cpp"],
+
+    cflags: [
+        "-Werror",
+        "-Wall",
+    ],
+}
diff --git a/tools/resampler_tools/Android.mk b/tools/resampler_tools/Android.mk
deleted file mode 100644
index bba5199..0000000
--- a/tools/resampler_tools/Android.mk
+++ /dev/null
@@ -1,17 +0,0 @@
-# Copyright 2005 The Android Open Source Project
-#
-# Android.mk for resampler_tools
-#
-
-
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := \
-	fir.cpp
-
-LOCAL_MODULE := fir
-
-LOCAL_CFLAGS := -Werror -Wall
-
-include $(BUILD_HOST_EXECUTABLE)