diff --git a/media/libmediaplayer2/mediaplayer2.cpp b/media/libmediaplayer2/mediaplayer2.cpp
index 75d06b8..b401ee8 100644
--- a/media/libmediaplayer2/mediaplayer2.cpp
+++ b/media/libmediaplayer2/mediaplayer2.cpp
@@ -18,44 +18,391 @@
 //#define LOG_NDEBUG 0
 #define LOG_TAG "MediaPlayer2Native"
 
-#include <fcntl.h>
-#include <inttypes.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-#include <utils/Log.h>
-
 #include <binder/IServiceManager.h>
 #include <binder/IPCThreadState.h>
 
-#include <media/AudioResamplerPublic.h>
 #include <media/AudioSystem.h>
-#include <media/AVSyncSettings.h>
-#include <media/DataSource.h>
 #include <media/DataSourceDesc.h>
 #include <media/MediaAnalyticsItem.h>
+#include <media/MemoryLeakTrackUtil.h>
+#include <media/Metadata.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 <binder/MemoryBase.h>
-
-#include <utils/KeyedVector.h>
+#include <utils/Log.h>
+#include <utils/SortedVector.h>
 #include <utils/String8.h>
 
 #include <system/audio.h>
 #include <system/window.h>
 
-#include "MediaPlayer2Manager.h"
+#include <nuplayer2/NuPlayer2Driver.h>
+
+#include <dirent.h>
+#include <sys/stat.h>
 
 namespace android {
 
-MediaPlayer2::MediaPlayer2()
-{
+extern ALooperRoster gLooperRoster;
+
+namespace {
+
+const int kDumpLockRetries = 50;
+const int kDumpLockSleepUs = 20000;
+
+// Max number of entries in the filter.
+const int kMaxFilterSize = 64;  // I pulled that out of thin air.
+
+// FIXME: Move all the metadata related function in the Metadata.cpp
+
+// Unmarshall a filter from a Parcel.
+// Filter format in a parcel:
+//
+//  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+// |                       number of entries (n)                   |
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+// |                       metadata type 1                         |
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+// |                       metadata type 2                         |
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+//  ....
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+// |                       metadata type n                         |
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+//
+// @param p Parcel that should start with a filter.
+// @param[out] filter On exit contains the list of metadata type to be
+//                    filtered.
+// @param[out] status On exit contains the status code to be returned.
+// @return true if the parcel starts with a valid filter.
+bool unmarshallFilter(const Parcel& p,
+                      media::Metadata::Filter *filter,
+                      status_t *status) {
+    int32_t val;
+    if (p.readInt32(&val) != OK) {
+        ALOGE("Failed to read filter's length");
+        *status = NOT_ENOUGH_DATA;
+        return false;
+    }
+
+    if (val > kMaxFilterSize || val < 0) {
+        ALOGE("Invalid filter len %d", val);
+        *status = BAD_VALUE;
+        return false;
+    }
+
+    const size_t num = val;
+
+    filter->clear();
+    filter->setCapacity(num);
+
+    size_t size = num * sizeof(media::Metadata::Type);
+
+
+    if (p.dataAvail() < size) {
+        ALOGE("Filter too short expected %zu but got %zu", size, p.dataAvail());
+        *status = NOT_ENOUGH_DATA;
+        return false;
+    }
+
+    const media::Metadata::Type *data =
+        static_cast<const media::Metadata::Type*>(p.readInplace(size));
+
+    if (NULL == data) {
+        ALOGE("Filter had no data");
+        *status = BAD_VALUE;
+        return false;
+    }
+
+    // TODO: The stl impl of vector would be more efficient here
+    // because it degenerates into a memcpy on pod types. Try to
+    // replace later or use stl::set.
+    for (size_t i = 0; i < num; ++i) {
+        filter->add(*data);
+        ++data;
+    }
+    *status = OK;
+    return true;
+}
+
+// @param filter Of metadata type.
+// @param val To be searched.
+// @return true if a match was found.
+bool findMetadata(const media::Metadata::Filter& filter, const int32_t val) {
+    // Deal with empty and ANY right away
+    if (filter.isEmpty()) {
+        return false;
+    }
+    if (filter[0] == media::Metadata::kAny) {
+        return true;
+    }
+
+    return filter.indexOf(val) >= 0;
+}
+
+// marshalling tag indicating flattened utf16 tags
+// keep in sync with frameworks/base/media/java/android/media/AudioAttributes.java
+const int32_t kAudioAttributesMarshallTagFlattenTags = 1;
+
+// Audio attributes format in a parcel:
+//
+//  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+// |                       usage                                   |
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+// |                       content_type                            |
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+// |                       source                                  |
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+// |                       flags                                   |
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+// |                       kAudioAttributesMarshallTagFlattenTags  | // ignore tags if not found
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+// |                       flattened tags in UTF16                 |
+// |                         ...                                   |
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+//
+// @param p Parcel that contains audio attributes.
+// @param[out] attributes On exit points to an initialized audio_attributes_t structure
+// @param[out] status On exit contains the status code to be returned.
+void unmarshallAudioAttributes(const Parcel& parcel, audio_attributes_t *attributes) {
+    attributes->usage = (audio_usage_t) parcel.readInt32();
+    attributes->content_type = (audio_content_type_t) parcel.readInt32();
+    attributes->source = (audio_source_t) parcel.readInt32();
+    attributes->flags = (audio_flags_mask_t) parcel.readInt32();
+    const bool hasFlattenedTag = (parcel.readInt32() == kAudioAttributesMarshallTagFlattenTags);
+    if (hasFlattenedTag) {
+        // the tags are UTF16, convert to UTF8
+        String16 tags = parcel.readString16();
+        ssize_t realTagSize = utf16_to_utf8_length(tags.string(), tags.size());
+        if (realTagSize <= 0) {
+            strcpy(attributes->tags, "");
+        } else {
+            // copy the flattened string into the attributes as the destination for the conversion:
+            // copying array size -1, array for tags was calloc'd, no need to NULL-terminate it
+            size_t tagSize = realTagSize > AUDIO_ATTRIBUTES_TAGS_MAX_SIZE - 1 ?
+                    AUDIO_ATTRIBUTES_TAGS_MAX_SIZE - 1 : realTagSize;
+            utf16_to_utf8(tags.string(), tagSize, attributes->tags,
+                    sizeof(attributes->tags) / sizeof(attributes->tags[0]));
+        }
+    } else {
+        ALOGE("unmarshallAudioAttributes() received unflattened tags, ignoring tag values");
+        strcpy(attributes->tags, "");
+    }
+}
+
+class AudioDeviceUpdatedNotifier: public AudioSystem::AudioDeviceCallback {
+public:
+    AudioDeviceUpdatedNotifier(const sp<MediaPlayer2Interface>& listener)
+        : mListener(listener) { }
+
+    ~AudioDeviceUpdatedNotifier() { }
+
+    virtual void onAudioDeviceUpdate(audio_io_handle_t audioIo,
+                                     audio_port_handle_t deviceId) override {
+        sp<MediaPlayer2Interface> listener = mListener.promote();
+        if (listener != NULL) {
+            listener->sendEvent(0, MEDIA2_AUDIO_ROUTING_CHANGED, audioIo, deviceId);
+        } else {
+            ALOGW("listener for process %d death is gone", MEDIA2_AUDIO_ROUTING_CHANGED);
+        }
+    }
+
+private:
+    wp<MediaPlayer2Interface> mListener;
+};
+
+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 Parcel *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.
+
+    if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
+        snprintf(buffer, SIZE, "Permission Denial: can't dump MediaPlayer2\n");
+        result.append(buffer);
+    } else {
+        {
+            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() {
+    sp<MediaPlayer2> player = new MediaPlayer2();
+
+    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() {
     ALOGV("constructor");
     mSrcId = 0;
+    mLockThreadId = 0;
     mListener = NULL;
-    mCookie = NULL;
     mStreamType = AUDIO_STREAM_MUSIC;
     mAudioAttributesParcel = NULL;
     mCurrentPosition = -1;
@@ -66,14 +413,18 @@
     mLoop = false;
     mLeftVolume = mRightVolume = 1.0;
     mVideoWidth = mVideoHeight = 0;
-    mLockThreadId = 0;
     mAudioSessionId = (audio_session_t) AudioSystem::newAudioUniqueId(AUDIO_UNIQUE_ID_USE_SESSION);
     AudioSystem::acquireAudioSessionId(mAudioSessionId, -1);
     mSendLevel = 0;
+
+    // TODO: get pid and uid from JAVA
+    mPid = IPCThreadState::self()->getCallingPid();
+    mUid = IPCThreadState::self()->getCallingUid();
+
+    mAudioAttributes = NULL;
 }
 
-MediaPlayer2::~MediaPlayer2()
-{
+MediaPlayer2::~MediaPlayer2() {
     ALOGV("destructor");
     if (mAudioAttributesParcel != NULL) {
         delete mAudioAttributesParcel;
@@ -81,13 +432,21 @@
     }
     AudioSystem::releaseAudioSessionId(mAudioSessionId, -1);
     disconnect();
-    IPCThreadState::self()->flushCommands();
+    removePlayer(this);
+    if (mAudioAttributes != NULL) {
+        free(mAudioAttributes);
+    }
 }
 
-void MediaPlayer2::disconnect()
-{
+bool MediaPlayer2::init() {
+    // TODO: after merge with NuPlayer2Driver, MediaPlayer2 will have its own
+    // looper for notification.
+    return true;
+}
+
+void MediaPlayer2::disconnect() {
     ALOGV("disconnect");
-    sp<MediaPlayer2Engine> p;
+    sp<MediaPlayer2Interface> p;
     {
         Mutex::Autolock _l(mLock);
         p = mPlayer;
@@ -95,13 +454,17 @@
     }
 
     if (p != 0) {
-        p->disconnect();
+        p->setListener(NULL);
+        p->reset();
+    }
+
+    {
+        Mutex::Autolock _l(mLock);
+        disconnectNativeWindow_l();
     }
 }
 
-// always call with lock held
-void MediaPlayer2::clear_l()
-{
+void MediaPlayer2::clear_l() {
     mCurrentPosition = -1;
     mCurrentSeekMode = MediaPlayer2SeekMode::SEEK_PREVIOUS_SYNC;
     mSeekPosition = -1;
@@ -109,8 +472,7 @@
     mVideoWidth = mVideoHeight = 0;
 }
 
-status_t MediaPlayer2::setListener(const sp<MediaPlayer2Listener>& listener)
-{
+status_t MediaPlayer2::setListener(const sp<MediaPlayer2Listener>& listener) {
     ALOGV("setListener");
     Mutex::Autolock _l(mLock);
     mListener = listener;
@@ -127,51 +489,54 @@
     return OK;
 }
 
-status_t MediaPlayer2::attachNewPlayer(const sp<MediaPlayer2Engine>& player, long srcId)
-{
-    status_t err = UNKNOWN_ERROR;
-    sp<MediaPlayer2Engine> p;
-    { // scope for the lock
-        Mutex::Autolock _l(mLock);
-
-        if ( !( (mCurrentState & MEDIA_PLAYER2_IDLE) ||
-                (mCurrentState == MEDIA_PLAYER2_STATE_ERROR ) ) ) {
-            ALOGE("attachNewPlayer called in state %d", mCurrentState);
-            return INVALID_OPERATION;
-        }
-
-        clear_l();
-        p = mPlayer;
-        mPlayer = player;
-        mSrcId = srcId;
-        if (player != 0) {
-            mCurrentState = MEDIA_PLAYER2_INITIALIZED;
-            err = NO_ERROR;
-        } else {
-            ALOGE("Unable to create media player");
-        }
-    }
-
-    if (p != 0) {
-        p->disconnect();
-    }
-
-    return err;
-}
-
-status_t MediaPlayer2::setDataSource(const sp<DataSourceDesc> &dsd)
-{
+status_t MediaPlayer2::setDataSource(const sp<DataSourceDesc> &dsd) {
     if (dsd == NULL) {
         return BAD_VALUE;
     }
-    ALOGV("setDataSource type(%d)", dsd->mType);
-    status_t err = UNKNOWN_ERROR;
-    sp<MediaPlayer2Engine> player(MediaPlayer2Manager::get().create(this, mAudioSessionId));
-    if (NO_ERROR != player->setDataSource(dsd)) {
-        player.clear();
+    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);
+        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));
+        mAudioOutput = new MediaPlayer2AudioOutput(mAudioSessionId, mUid,
+                mPid, mAudioAttributes, new AudioDeviceUpdatedNotifier(player));
+        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;
     }
-    err = attachNewPlayer(player, dsd->mId);
-    return err;
+
+    if (oldPlayer != NULL) {
+        oldPlayer->setListener(NULL);
+        oldPlayer->reset();
+    }
+
+    return OK;
 }
 
 status_t MediaPlayer2::prepareNextDataSource(const sp<DataSourceDesc> &dsd) {
@@ -181,81 +546,179 @@
     ALOGV("prepareNextDataSource type(%d), srcId(%lld)", dsd->mType, (long long)dsd->mId);
 
     Mutex::Autolock _l(mLock);
-    if (mPlayer != NULL) {
-        return mPlayer->prepareNextDataSource(dsd);
+    if (mPlayer == NULL) {
+        ALOGE("prepareNextDataSource failed: state %X, mPlayer(%p)", mCurrentState, mPlayer.get());
+        return INVALID_OPERATION;
     }
-    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) {
-        mSrcId = srcId;
-        return mPlayer->playNextDataSource(srcId);
+    if (mPlayer == NULL) {
+        ALOGE("playNextDataSource failed: state %X, mPlayer(%p)", mCurrentState, mPlayer.get());
+        return INVALID_OPERATION;
     }
-    ALOGE("playNextDataSource failed: state %X, mPlayer(%p)", mCurrentState, mPlayer.get());
-    return INVALID_OPERATION;
+    mSrcId = srcId;
+    return mPlayer->playNextDataSource(srcId);
 }
 
-status_t MediaPlayer2::invoke(const Parcel& request, Parcel *reply)
-{
+status_t MediaPlayer2::invoke(const Parcel& request, Parcel *reply) {
     Mutex::Autolock _l(mLock);
     const bool hasBeenInitialized =
             (mCurrentState != MEDIA_PLAYER2_STATE_ERROR) &&
             ((mCurrentState & MEDIA_PLAYER2_IDLE) != MEDIA_PLAYER2_IDLE);
-    if ((mPlayer != NULL) && hasBeenInitialized) {
-        ALOGV("invoke %zu", request.dataSize());
-        return  mPlayer->invoke(request, reply);
+    if ((mPlayer == NULL) || !hasBeenInitialized) {
+        ALOGE("invoke failed: wrong state %X, mPlayer(%p)", mCurrentState, mPlayer.get());
+        return INVALID_OPERATION;
     }
-    ALOGE("invoke failed: wrong state %X, mPlayer(%p)", mCurrentState, mPlayer.get());
-    return INVALID_OPERATION;
+    ALOGV("invoke %zu", request.dataSize());
+    return mPlayer->invoke(request, reply);
 }
 
-status_t MediaPlayer2::setMetadataFilter(const Parcel& filter)
-{
+// This call doesn't need to access the native player.
+status_t MediaPlayer2::setMetadataFilter(const Parcel& filter) {
     ALOGD("setMetadataFilter");
-    Mutex::Autolock lock(mLock);
-    if (mPlayer == NULL) {
-        return NO_INIT;
+
+    status_t status;
+    media::Metadata::Filter allow, drop;
+
+    if (unmarshallFilter(filter, &allow, &status) &&
+        unmarshallFilter(filter, &drop, &status)) {
+        Mutex::Autolock lock(mLock);
+
+        mMetadataAllow = allow;
+        mMetadataDrop = drop;
     }
-    return mPlayer->setMetadataFilter(filter);
+    return status;
 }
 
-status_t MediaPlayer2::getMetadata(bool update_only, bool apply_filter, Parcel *metadata)
-{
+status_t MediaPlayer2::getMetadata(bool update_only, bool /* apply_filter */, Parcel *reply) {
     ALOGD("getMetadata");
+    sp<MediaPlayer2Interface> player;
+    media::Metadata::Filter ids;
     Mutex::Autolock lock(mLock);
-    if (mPlayer == NULL) {
+    {
+        if (mPlayer == NULL) {
+            return NO_INIT;
+        }
+
+        player = mPlayer;
+        // Placeholder for the return code, updated by the caller.
+        reply->writeInt32(-1);
+
+        // We don't block notifications while we fetch the data. We clear
+        // mMetadataUpdated first so we don't lose notifications happening
+        // during the rest of this call.
+        if (update_only) {
+            ids = mMetadataUpdated;
+        }
+        mMetadataUpdated.clear();
+    }
+
+    media::Metadata metadata(reply);
+
+    metadata.appendHeader();
+    status_t status = player->getMetadata(ids, reply);
+
+    if (status != OK) {
+        metadata.resetParcel();
+        ALOGE("getMetadata failed %d", status);
+        return status;
+    }
+
+    // FIXME: ement filtering on the result. Not critical since
+    // filtering takes place on the update notifications already. This
+    // would be when all the metadata are fetch and a filter is set.
+
+    // Everything is fine, update the metadata length.
+    metadata.updateLength();
+    return OK;
+}
+
+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;
     }
-    return mPlayer->getMetadata(update_only, apply_filter, metadata);
+
+    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::setVideoSurfaceTexture(const sp<ANativeWindowWrapper>& nww)
-{
-    ALOGV("setVideoSurfaceTexture");
-    Mutex::Autolock _l(mLock);
-    if (mPlayer == 0) return NO_INIT;
-    return mPlayer->setVideoSurfaceTexture(nww);
-}
-
-status_t MediaPlayer2::getBufferingSettings(BufferingSettings* buffering /* nonnull */)
-{
+status_t MediaPlayer2::getBufferingSettings(BufferingSettings* buffering /* nonnull */) {
     ALOGV("getBufferingSettings");
 
     Mutex::Autolock _l(mLock);
     if (mPlayer == 0) {
         return NO_INIT;
     }
-    return mPlayer->getBufferingSettings(buffering);
+
+    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");
+status_t MediaPlayer2::setBufferingSettings(const BufferingSettings& buffering) {
+    ALOGV("setBufferingSettings{%s}", buffering.toString().string());
 
     Mutex::Autolock _l(mLock);
     if (mPlayer == 0) {
@@ -264,14 +727,37 @@
     return mPlayer->setBufferingSettings(buffering);
 }
 
-// must call with lock held
-status_t MediaPlayer2::prepareAsync_l()
-{
-    if ( (mPlayer != 0) && ( mCurrentState & (MEDIA_PLAYER2_INITIALIZED | MEDIA_PLAYER2_STOPPED) ) ) {
+status_t MediaPlayer2::setAudioAttributes_l(const Parcel &parcel) {
+    if (mAudioAttributes != NULL) {
+        free(mAudioAttributes);
+    }
+    mAudioAttributes = (audio_attributes_t *) calloc(1, sizeof(audio_attributes_t));
+    if (mAudioAttributes == NULL) {
+        return NO_MEMORY;
+    }
+    unmarshallAudioAttributes(parcel, mAudioAttributes);
+
+    ALOGV("setAudioAttributes_l() usage=%d content=%d flags=0x%x tags=%s",
+            mAudioAttributes->usage, mAudioAttributes->content_type, mAudioAttributes->flags,
+            mAudioAttributes->tags);
+
+    if (mAudioOutput != 0) {
+        mAudioOutput->setAudioAttributes(mAudioAttributes);
+    }
+    return NO_ERROR;
+}
+
+status_t MediaPlayer2::prepareAsync() {
+    ALOGV("prepareAsync");
+    Mutex::Autolock _l(mLock);
+    if ((mPlayer != 0) && (mCurrentState & (MEDIA_PLAYER2_INITIALIZED | MEDIA_PLAYER2_STOPPED))) {
         if (mAudioAttributesParcel != NULL) {
-            mPlayer->setParameter(MEDIA2_KEY_PARAMETER_AUDIO_ATTRIBUTES, *mAudioAttributesParcel);
-        } else {
-            mPlayer->setAudioStreamType(mStreamType);
+            status_t err = setAudioAttributes_l(*mAudioAttributesParcel);
+            if (err != OK) {
+                return err;
+            }
+        } else if (mAudioOutput != 0) {
+            mAudioOutput->setAudioStreamType(mStreamType);
         }
         mCurrentState = MEDIA_PLAYER2_PREPARING;
         return mPlayer->prepareAsync();
@@ -280,15 +766,7 @@
     return INVALID_OPERATION;
 }
 
-status_t MediaPlayer2::prepareAsync()
-{
-    ALOGV("prepareAsync");
-    Mutex::Autolock _l(mLock);
-    return prepareAsync_l();
-}
-
-status_t MediaPlayer2::start()
-{
+status_t MediaPlayer2::start() {
     ALOGV("start");
 
     status_t ret = NO_ERROR;
@@ -301,8 +779,14 @@
     } else if ( (mPlayer != 0) && ( mCurrentState & ( MEDIA_PLAYER2_PREPARED |
                     MEDIA_PLAYER2_PLAYBACK_COMPLETE | MEDIA_PLAYER2_PAUSED ) ) ) {
         mPlayer->setLooping(mLoop);
-        mPlayer->setVolume(mLeftVolume, mRightVolume);
-        mPlayer->setAuxEffectSendLevel(mSendLevel);
+
+        if (mAudioOutput != 0) {
+            mAudioOutput->setVolume(mLeftVolume, mRightVolume);
+        }
+
+        if (mAudioOutput != 0) {
+            mAudioOutput->setAuxEffectSendLevel(mSendLevel);
+        }
         mCurrentState = MEDIA_PLAYER2_STARTED;
         ret = mPlayer->start();
         if (ret != NO_ERROR) {
@@ -322,8 +806,7 @@
     return ret;
 }
 
-status_t MediaPlayer2::stop()
-{
+status_t MediaPlayer2::stop() {
     ALOGV("stop");
     Mutex::Autolock _l(mLock);
     if (mCurrentState & MEDIA_PLAYER2_STOPPED) return NO_ERROR;
@@ -341,8 +824,7 @@
     return INVALID_OPERATION;
 }
 
-status_t MediaPlayer2::pause()
-{
+status_t MediaPlayer2::pause() {
     ALOGV("pause");
     Mutex::Autolock _l(mLock);
     if (mCurrentState & (MEDIA_PLAYER2_PAUSED|MEDIA_PLAYER2_PLAYBACK_COMPLETE))
@@ -360,12 +842,10 @@
     return INVALID_OPERATION;
 }
 
-bool MediaPlayer2::isPlaying()
-{
+bool MediaPlayer2::isPlaying() {
     Mutex::Autolock _l(mLock);
     if (mPlayer != 0) {
-        bool temp = false;
-        mPlayer->isPlaying(&temp);
+        bool temp = mPlayer->isPlaying();
         ALOGV("isPlaying: %d", temp);
         if ((mCurrentState & MEDIA_PLAYER2_STARTED) && ! temp) {
             ALOGE("internal/external state mismatch corrected");
@@ -380,13 +860,12 @@
     return false;
 }
 
-status_t MediaPlayer2::setPlaybackSettings(const AudioPlaybackRate& rate)
-{
+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) {
+    if (rate.mSpeed <= 0.f || rate.mPitch < 0.f) {
         return BAD_VALUE;
     }
     Mutex::Autolock _l(mLock);
@@ -394,36 +873,27 @@
         return INVALID_OPERATION;
     }
 
-    if (rate.mSpeed != 0.f && !(mCurrentState & MEDIA_PLAYER2_STARTED)
-            && (mCurrentState & (MEDIA_PLAYER2_PREPARED | MEDIA_PLAYER2_PAUSED
-                    | MEDIA_PLAYER2_PLAYBACK_COMPLETE))) {
-        mPlayer->setLooping(mLoop);
-        mPlayer->setVolume(mLeftVolume, mRightVolume);
-        mPlayer->setAuxEffectSendLevel(mSendLevel);
-    }
-
     status_t err = mPlayer->setPlaybackSettings(rate);
-    if (err == OK) {
-        if (rate.mSpeed == 0.f && mCurrentState == MEDIA_PLAYER2_STARTED) {
-            mCurrentState = MEDIA_PLAYER2_PAUSED;
-        } else if (rate.mSpeed != 0.f
-                && (mCurrentState & (MEDIA_PLAYER2_PREPARED | MEDIA_PLAYER2_PAUSED
-                    | MEDIA_PLAYER2_PLAYBACK_COMPLETE))) {
-            mCurrentState = MEDIA_PLAYER2_STARTED;
-        }
-    }
     return err;
 }
 
-status_t MediaPlayer2::getPlaybackSettings(AudioPlaybackRate* rate /* nonnull */)
-{
+status_t MediaPlayer2::getPlaybackSettings(AudioPlaybackRate* rate /* nonnull */) {
     Mutex::Autolock _l(mLock);
-    if (mPlayer == 0) return INVALID_OPERATION;
+    if (mPlayer == 0) {
+        return INVALID_OPERATION;
+    }
     return mPlayer->getPlaybackSettings(rate);
+    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)
-{
+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);
@@ -432,83 +902,92 @@
 }
 
 status_t MediaPlayer2::getSyncSettings(
-        AVSyncSettings* sync /* nonnull */, float* videoFps /* nonnull */)
-{
+        AVSyncSettings* sync /* nonnull */, float* videoFps /* nonnull */) {
     Mutex::Autolock _l(mLock);
     if (mPlayer == 0) return INVALID_OPERATION;
-    return mPlayer->getSyncSettings(sync, videoFps);
+    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)
-{
+status_t MediaPlayer2::getVideoWidth(int *w) {
     ALOGV("getVideoWidth");
     Mutex::Autolock _l(mLock);
-    if (mPlayer == 0) return INVALID_OPERATION;
+    if (mPlayer == 0) {
+        return INVALID_OPERATION;
+    }
     *w = mVideoWidth;
     return NO_ERROR;
 }
 
-status_t MediaPlayer2::getVideoHeight(int *h)
-{
+status_t MediaPlayer2::getVideoHeight(int *h) {
     ALOGV("getVideoHeight");
     Mutex::Autolock _l(mLock);
-    if (mPlayer == 0) return INVALID_OPERATION;
+    if (mPlayer == 0) {
+        return INVALID_OPERATION;
+    }
     *h = mVideoHeight;
     return NO_ERROR;
 }
 
-status_t MediaPlayer2::getCurrentPosition(int *msec)
-{
+status_t MediaPlayer2::getCurrentPosition(int *msec) {
     ALOGV("getCurrentPosition");
     Mutex::Autolock _l(mLock);
-    if (mPlayer != 0) {
-        if (mCurrentPosition >= 0) {
-            ALOGV("Using cached seek position: %d", mCurrentPosition);
-            *msec = mCurrentPosition;
-            return NO_ERROR;
-        }
-        return mPlayer->getCurrentPosition(msec);
+    if (mPlayer == 0) {
+        return INVALID_OPERATION;
     }
-    return INVALID_OPERATION;
+    if (mCurrentPosition >= 0) {
+        ALOGV("Using cached seek position: %d", mCurrentPosition);
+        *msec = mCurrentPosition;
+        return NO_ERROR;
+    }
+    status_t ret = mPlayer->getCurrentPosition(msec);
+    if (ret == NO_ERROR) {
+        ALOGV("getCurrentPosition = %d", *msec);
+    } else {
+        ALOGE("getCurrentPosition returned %d", ret);
+    }
+    return ret;
 }
 
-status_t MediaPlayer2::getDuration_l(int *msec)
-{
+status_t MediaPlayer2::getDuration(int *msec) {
+    Mutex::Autolock _l(mLock);
     ALOGV("getDuration_l");
     bool isValidState = (mCurrentState & (MEDIA_PLAYER2_PREPARED | MEDIA_PLAYER2_STARTED |
             MEDIA_PLAYER2_PAUSED | MEDIA_PLAYER2_STOPPED | MEDIA_PLAYER2_PLAYBACK_COMPLETE));
-    if (mPlayer != 0 && isValidState) {
-        int durationMs;
-        status_t ret = mPlayer->getDuration(&durationMs);
-
-        if (ret != OK) {
-            // Do not enter error state just because no duration was available.
-            durationMs = -1;
-            ret = OK;
-        }
-
-        if (msec) {
-            *msec = durationMs;
-        }
-        return ret;
+    if (mPlayer == 0 || !isValidState) {
+        ALOGE("Attempt to call getDuration in wrong state: mPlayer=%p, mCurrentState=%u",
+                mPlayer.get(), mCurrentState);
+        return INVALID_OPERATION;
     }
-    ALOGE("Attempt to call getDuration in wrong state: mPlayer=%p, mCurrentState=%u",
-            mPlayer.get(), mCurrentState);
-    return INVALID_OPERATION;
+    int durationMs;
+    status_t ret = mPlayer->getDuration(&durationMs);
+
+    if (ret == NO_ERROR) {
+        ALOGV("getDuration = %d", 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::getDuration(int *msec)
-{
-    Mutex::Autolock _l(mLock);
-    return getDuration_l(msec);
-}
-
-status_t MediaPlayer2::seekTo_l(int msec, MediaPlayer2SeekMode mode)
-{
+status_t MediaPlayer2::seekTo_l(int msec, MediaPlayer2SeekMode mode) {
     ALOGV("seekTo (%d, %d)", msec, mode);
     if ((mPlayer != 0) && ( mCurrentState & ( MEDIA_PLAYER2_STARTED | MEDIA_PLAYER2_PREPARED |
             MEDIA_PLAYER2_PAUSED |  MEDIA_PLAYER2_PLAYBACK_COMPLETE) ) ) {
-        if ( msec < 0 ) {
+        if (msec < 0) {
             ALOGW("Attempt to seek to invalid position: %d", msec);
             msec = 0;
         }
@@ -537,8 +1016,7 @@
             mSeekPosition = msec;
             mSeekMode = mode;
             return mPlayer->seekTo(msec, mode);
-        }
-        else {
+        } else {
             ALOGV("Seek in progress - queue up seekTo[%d, %d]", msec, mode);
             return NO_ERROR;
         }
@@ -548,8 +1026,7 @@
     return INVALID_OPERATION;
 }
 
-status_t MediaPlayer2::seekTo(int msec, MediaPlayer2SeekMode mode)
-{
+status_t MediaPlayer2::seekTo(int msec, MediaPlayer2SeekMode mode) {
     mLockThreadId = getThreadId();
     Mutex::Autolock _l(mLock);
     status_t result = seekTo_l(msec, mode);
@@ -558,26 +1035,27 @@
     return result;
 }
 
-status_t MediaPlayer2::notifyAt(int64_t mediaTimeUs)
-{
+status_t MediaPlayer2::notifyAt(int64_t mediaTimeUs) {
     Mutex::Autolock _l(mLock);
     if (mPlayer != 0) {
-        return mPlayer->notifyAt(mediaTimeUs);
+        return INVALID_OPERATION;
     }
-    return INVALID_OPERATION;
+
+    return mPlayer->notifyAt(mediaTimeUs);
 }
 
-status_t MediaPlayer2::reset_l()
-{
+status_t MediaPlayer2::reset_l() {
     mLoop = false;
-    if (mCurrentState == MEDIA_PLAYER2_IDLE) return NO_ERROR;
+    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->disconnect();
+            mPlayer->setListener(NULL);
             mCurrentState = MEDIA_PLAYER2_IDLE;
         }
         // setDataSource has to be called again to create a
@@ -589,8 +1067,7 @@
     return NO_ERROR;
 }
 
-status_t MediaPlayer2::reset()
-{
+status_t MediaPlayer2::reset() {
     ALOGV("reset");
     mLockThreadId = getThreadId();
     Mutex::Autolock _l(mLock);
@@ -600,8 +1077,7 @@
     return result;
 }
 
-status_t MediaPlayer2::setAudioStreamType(audio_stream_type_t type)
-{
+status_t MediaPlayer2::setAudioStreamType(audio_stream_type_t type) {
     ALOGV("MediaPlayer2::setAudioStreamType");
     Mutex::Autolock _l(mLock);
     if (mStreamType == type) return NO_ERROR;
@@ -616,16 +1092,14 @@
     return OK;
 }
 
-status_t MediaPlayer2::getAudioStreamType(audio_stream_type_t *type)
-{
+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)
-{
+status_t MediaPlayer2::setLooping(int loop) {
     ALOGV("MediaPlayer2::setLooping");
     Mutex::Autolock _l(mLock);
     mLoop = (loop != 0);
@@ -645,20 +1119,18 @@
     return false;
 }
 
-status_t MediaPlayer2::setVolume(float leftVolume, float rightVolume)
-{
+status_t MediaPlayer2::setVolume(float leftVolume, float rightVolume) {
     ALOGV("MediaPlayer2::setVolume(%f, %f)", leftVolume, rightVolume);
     Mutex::Autolock _l(mLock);
     mLeftVolume = leftVolume;
     mRightVolume = rightVolume;
-    if (mPlayer != 0) {
-        return mPlayer->setVolume(leftVolume, rightVolume);
+    if (mAudioOutput != 0) {
+        mAudioOutput->setVolume(leftVolume, rightVolume);
     }
     return OK;
 }
 
-status_t MediaPlayer2::setAudioSessionId(audio_session_t sessionId)
-{
+status_t MediaPlayer2::setAudioSessionId(audio_session_t sessionId) {
     ALOGV("MediaPlayer2::setAudioSessionId(%d)", sessionId);
     Mutex::Autolock _l(mLock);
     if (!(mCurrentState & MEDIA_PLAYER2_IDLE)) {
@@ -676,40 +1148,36 @@
     return NO_ERROR;
 }
 
-audio_session_t MediaPlayer2::getAudioSessionId()
-{
+audio_session_t MediaPlayer2::getAudioSessionId() {
     Mutex::Autolock _l(mLock);
     return mAudioSessionId;
 }
 
-status_t MediaPlayer2::setAuxEffectSendLevel(float level)
-{
+status_t MediaPlayer2::setAuxEffectSendLevel(float level) {
     ALOGV("MediaPlayer2::setAuxEffectSendLevel(%f)", level);
     Mutex::Autolock _l(mLock);
     mSendLevel = level;
-    if (mPlayer != 0) {
-        return mPlayer->setAuxEffectSendLevel(level);
+    if (mAudioOutput != 0) {
+        return mAudioOutput->setAuxEffectSendLevel(level);
     }
     return OK;
 }
 
-status_t MediaPlayer2::attachAuxEffect(int effectId)
-{
+status_t MediaPlayer2::attachAuxEffect(int effectId) {
     ALOGV("MediaPlayer2::attachAuxEffect(%d)", effectId);
     Mutex::Autolock _l(mLock);
-    if (mPlayer == 0 ||
+    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 mPlayer->attachAuxEffect(effectId);
+    return mAudioOutput->attachAuxEffect(effectId);
 }
 
 // always call with lock held
-status_t MediaPlayer2::checkStateForKeySet_l(int key)
-{
+status_t MediaPlayer2::checkStateForKeySet_l(int key) {
     switch(key) {
     case MEDIA2_KEY_PARAMETER_AUDIO_ATTRIBUTES:
         if (mCurrentState & ( MEDIA_PLAYER2_PREPARED | MEDIA_PLAYER2_STARTED |
@@ -726,8 +1194,7 @@
     return OK;
 }
 
-status_t MediaPlayer2::setParameter(int key, const Parcel& request)
-{
+status_t MediaPlayer2::setParameter(int key, const Parcel& request) {
     ALOGV("MediaPlayer2::setParameter(%d)", key);
     status_t status = INVALID_OPERATION;
     Mutex::Autolock _l(mLock);
@@ -737,10 +1204,15 @@
     switch (key) {
     case MEDIA2_KEY_PARAMETER_AUDIO_ATTRIBUTES:
         // save the marshalled audio attributes
-        if (mAudioAttributesParcel != NULL) { delete mAudioAttributesParcel; };
+        if (mAudioAttributesParcel != NULL) {
+            delete mAudioAttributesParcel;
+        }
         mAudioAttributesParcel = new Parcel();
         mAudioAttributesParcel->appendFrom(&request, 0, request.dataSize());
-        status = OK;
+        status = setAudioAttributes_l(request);
+        if (status != OK) {
+            return status;
+        }
         break;
     default:
         ALOGV_IF(mPlayer == NULL, "setParameter: no active player");
@@ -753,25 +1225,59 @@
     return status;
 }
 
-status_t MediaPlayer2::getParameter(int key, Parcel *reply)
-{
+status_t MediaPlayer2::getParameter(int key, Parcel *reply) {
     ALOGV("MediaPlayer2::getParameter(%d)", key);
     Mutex::Autolock _l(mLock);
-    if (mPlayer != NULL) {
-        status_t status =  mPlayer->getParameter(key, reply);
-        if (status != OK) {
-            ALOGD("getParameter returns %d", status);
-        }
-        return status;
+    if (mPlayer == NULL) {
+        ALOGV("getParameter: no active player");
+        return INVALID_OPERATION;
     }
-    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;
 }
 
-void MediaPlayer2::notify(int64_t srcId, int msg, int ext1, int ext2, const Parcel *obj)
-{
+bool MediaPlayer2::shouldDropMetadata(media::Metadata::Type code) const {
+    Mutex::Autolock lock(mLock);
+
+    if (findMetadata(mMetadataDrop, code)) {
+        return true;
+    }
+
+    if (mMetadataAllow.isEmpty() || findMetadata(mMetadataAllow, code)) {
+        return false;
+    } else {
+        return true;
+    }
+}
+
+
+void MediaPlayer2::addNewMetadataUpdate(media::Metadata::Type metadata_type) {
+    Mutex::Autolock lock(mLock);
+    if (mMetadataUpdated.indexOf(metadata_type) < 0) {
+        mMetadataUpdated.add(metadata_type);
+    }
+}
+
+void MediaPlayer2::notify(int64_t srcId, int msg, int ext1, int ext2, const Parcel *obj) {
     ALOGV("message received srcId=%lld, msg=%d, ext1=%d, ext2=%d",
           (long long)srcId, msg, ext1, ext2);
+
+    if (MEDIA2_INFO == msg && MEDIA2_INFO_METADATA_UPDATE == ext1) {
+        const media::Metadata::Type metadata_type = ext2;
+
+        if(shouldDropMetadata(metadata_type)) {
+            return;
+        }
+
+        // Update the list of metadata that have changed. getMetadata
+        // also access mMetadataUpdated and clears it.
+        addNewMetadataUpdate(metadata_type);
+    }
+
     bool send = true;
     bool locked = false;
 
@@ -881,24 +1387,12 @@
     }
 }
 
-status_t MediaPlayer2::setNextMediaPlayer(const sp<MediaPlayer2>& next) {
-    Mutex::Autolock _l(mLock);
-    if (mPlayer == NULL) {
-        return NO_INIT;
-    }
-
-    if (next != NULL && !(next->mCurrentState &
-            (MEDIA_PLAYER2_PREPARED | MEDIA_PLAYER2_PAUSED | MEDIA_PLAYER2_PLAYBACK_COMPLETE))) {
-        ALOGE("next player is not prepared");
-        return INVALID_OPERATION;
-    }
-
-    return mPlayer->setNextPlayer(next == NULL ? NULL : next->mPlayer);
+status_t MediaPlayer2::setNextMediaPlayer(const sp<MediaPlayer2>& /* next */) {
+    return INVALID_OPERATION;
 }
 
 // Modular DRM
-status_t MediaPlayer2::prepareDrm(const uint8_t uuid[16], const Vector<uint8_t>& drmSessionId)
-{
+status_t MediaPlayer2::prepareDrm(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());
@@ -931,8 +1425,7 @@
     return status;
 }
 
-status_t MediaPlayer2::releaseDrm()
-{
+status_t MediaPlayer2::releaseDrm() {
     Mutex::Autolock _l(mLock);
     if (mPlayer == NULL) {
         return NO_INIT;
@@ -960,39 +1453,74 @@
     return status;
 }
 
-status_t MediaPlayer2::setOutputDevice(audio_port_handle_t deviceId)
-{
+status_t MediaPlayer2::setOutputDevice(audio_port_handle_t deviceId) {
     Mutex::Autolock _l(mLock);
-    if (mPlayer == NULL) {
-        ALOGV("setOutputDevice: player not init");
+    if (mAudioOutput == NULL) {
+        ALOGV("setOutputDevice: audio sink not init");
         return NO_INIT;
     }
-    return mPlayer->setOutputDevice(deviceId);
+    return mAudioOutput->setOutputDevice(deviceId);
 }
 
-audio_port_handle_t MediaPlayer2::getRoutedDeviceId()
-{
+audio_port_handle_t MediaPlayer2::getRoutedDeviceId() {
     Mutex::Autolock _l(mLock);
-    if (mPlayer == NULL) {
-        ALOGV("getRoutedDeviceId: player not init");
+    if (mAudioOutput == NULL) {
+        ALOGV("getRoutedDeviceId: audio sink not init");
         return AUDIO_PORT_HANDLE_NONE;
     }
     audio_port_handle_t deviceId;
-    status_t status = mPlayer->getRoutedDeviceId(&deviceId);
+    status_t status = mAudioOutput->getRoutedDeviceId(&deviceId);
     if (status != NO_ERROR) {
         return AUDIO_PORT_HANDLE_NONE;
     }
     return deviceId;
 }
 
-status_t MediaPlayer2::enableAudioDeviceCallback(bool enabled)
-{
+status_t MediaPlayer2::enableAudioDeviceCallback(bool enabled) {
     Mutex::Autolock _l(mLock);
-    if (mPlayer == NULL) {
+    if (mAudioOutput == NULL) {
         ALOGV("addAudioDeviceCallback: player not init");
         return NO_INIT;
     }
-    return mPlayer->enableAudioDeviceCallback(enabled);
+    return mAudioOutput->enableAudioDeviceCallback(enabled);
+}
+
+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
