MediaPlayer2: create MP2AudioOutput in constructor

Move MP2AudioOutput creator from setDataSource() to constructor.
Test: MediaPlayer2Test, RoutingTest

Change-Id: Ibe19c8a259c735ea2b5822f769babaf4d7f2bed0
diff --git a/media/libmediaplayer2/JAudioTrack.cpp b/media/libmediaplayer2/JAudioTrack.cpp
index 543f700..cb139c9 100644
--- a/media/libmediaplayer2/JAudioTrack.cpp
+++ b/media/libmediaplayer2/JAudioTrack.cpp
@@ -35,7 +35,7 @@
         void* user,                                   // Offload
         size_t frameCount,                            // bufferSizeInBytes
         audio_session_t sessionId,                    // AudioTrack
-        const audio_attributes_t* pAttributes,        // AudioAttributes
+        const jobject attributes,                     // AudioAttributes
         float maxRequiredSpeed) {                     // bufferSizeInBytes
 
     JNIEnv *env = JavaVMHelper::getJNIEnv();
@@ -65,13 +65,17 @@
     jmethodID jBuilderCtor = env->GetMethodID(jBuilderCls, "<init>", "()V");
     jobject jBuilderObj = env->NewObject(jBuilderCls, jBuilderCtor);
 
-    jobject jAudioAttributesObj = JAudioAttributes::createAudioAttributesObj(env, pAttributes);
-    mAudioAttributesObj = reinterpret_cast<jobject>(env->NewGlobalRef(jAudioAttributesObj));
-    env->DeleteLocalRef(jAudioAttributesObj);
+    if (attributes != NULL) {
+        mAudioAttributesObj = new JObjectHolder(attributes);
+    } else {
+        mAudioAttributesObj = new JObjectHolder(
+                JAudioAttributes::createAudioAttributesObj(env, NULL));
+    }
 
     jmethodID jSetAudioAttributes = env->GetMethodID(jBuilderCls, "setAudioAttributes",
             "(Landroid/media/AudioAttributes;)Landroid/media/AudioTrack$Builder;");
-    jBuilderObj = env->CallObjectMethod(jBuilderObj, jSetAudioAttributes, mAudioAttributesObj);
+    jBuilderObj = env->CallObjectMethod(jBuilderObj,
+            jSetAudioAttributes, mAudioAttributesObj->getJObject());
 
     jmethodID jSetAudioFormat = env->GetMethodID(jBuilderCls, "setAudioFormat",
             "(Landroid/media/AudioFormat;)Landroid/media/AudioTrack$Builder;");
@@ -125,7 +129,6 @@
     JNIEnv *env = JavaVMHelper::getJNIEnv();
     env->DeleteGlobalRef(mAudioTrackCls);
     env->DeleteGlobalRef(mAudioTrackObj);
-    env->DeleteGlobalRef(mAudioAttributesObj);
 }
 
 size_t JAudioTrack::frameCount() {
@@ -509,11 +512,15 @@
 }
 
 audio_stream_type_t JAudioTrack::getAudioStreamType() {
+    if (mAudioAttributesObj == NULL) {
+        return AUDIO_STREAM_DEFAULT;
+    }
     JNIEnv *env = JavaVMHelper::getJNIEnv();
     jclass jAudioAttributesCls = env->FindClass("android/media/AudioAttributes");
     jmethodID jGetVolumeControlStream = env->GetMethodID(jAudioAttributesCls,
             "getVolumeControlStream", "()I");
-    int javaAudioStreamType = env->CallIntMethod(mAudioAttributesObj, jGetVolumeControlStream);
+    int javaAudioStreamType = env->CallIntMethod(
+            mAudioAttributesObj->getJObject(), jGetVolumeControlStream);
     return (audio_stream_type_t)javaAudioStreamType;
 }
 
diff --git a/media/libmediaplayer2/MediaPlayer2AudioOutput.cpp b/media/libmediaplayer2/MediaPlayer2AudioOutput.cpp
index 149f243..3040c2d 100644
--- a/media/libmediaplayer2/MediaPlayer2AudioOutput.cpp
+++ b/media/libmediaplayer2/MediaPlayer2AudioOutput.cpp
@@ -60,7 +60,7 @@
 }
 
 MediaPlayer2AudioOutput::MediaPlayer2AudioOutput(audio_session_t sessionId, uid_t uid, int pid,
-        const audio_attributes_t* attr, std::vector<jobject>& routingDelegatesBackup)
+        const jobject attributes)
     : mCallback(nullptr),
       mCallbackCookie(nullptr),
       mCallbackData(nullptr),
@@ -76,22 +76,13 @@
       mAuxEffectId(0),
       mFlags(AUDIO_OUTPUT_FLAG_NONE) {
     ALOGV("MediaPlayer2AudioOutput(%d)", sessionId);
-    if (attr != nullptr) {
-        mAttributes = (audio_attributes_t *) calloc(1, sizeof(audio_attributes_t));
-        if (mAttributes != nullptr) {
-            memcpy(mAttributes, attr, sizeof(audio_attributes_t));
-        }
-    } else {
-        mAttributes = nullptr;
+
+    if (attributes != nullptr) {
+        mAttributes = new JObjectHolder(attributes);
     }
 
     setMinBufferCount();
     mRoutingDelegates.clear();
-    for (auto routingDelegate : routingDelegatesBackup) {
-        mRoutingDelegates.push_back(std::pair<jobject, jobject>(
-                JAudioTrack::getListener(routingDelegate), routingDelegate));
-    }
-    routingDelegatesBackup.clear();
 }
 
 MediaPlayer2AudioOutput::~MediaPlayer2AudioOutput() {
@@ -99,7 +90,6 @@
         JAudioTrack::removeGlobalRef(routingDelegate.second);
     }
     close();
-    free(mAttributes);
     delete mCallbackData;
 }
 
@@ -251,16 +241,10 @@
     return status;
 }
 
-void MediaPlayer2AudioOutput::setAudioAttributes(const audio_attributes_t * attributes) {
+void MediaPlayer2AudioOutput::setAudioAttributes(const jobject attributes) {
     Mutex::Autolock lock(mLock);
-    if (attributes == nullptr) {
-        free(mAttributes);
-        mAttributes = nullptr;
-    } else {
-        if (mAttributes == nullptr) {
-            mAttributes = (audio_attributes_t *) calloc(1, sizeof(audio_attributes_t));
-        }
-        memcpy(mAttributes, attributes, sizeof(audio_attributes_t));
+    if (attributes != nullptr) {
+        sp<JObjectHolder> x = new JObjectHolder(attributes);
     }
 }
 
@@ -325,7 +309,7 @@
                  newcbd,
                  frameCount,
                  mSessionId,
-                 mAttributes,
+                 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
@@ -344,7 +328,7 @@
                  nullptr,
                  frameCount,
                  mSessionId,
-                 mAttributes,
+                 mAttributes != nullptr ? mAttributes->getJObject() : nullptr,
                  targetSpeed);
     }
 
@@ -569,15 +553,6 @@
     return NO_ERROR;
 }
 
-void MediaPlayer2AudioOutput::copyAudioDeviceCallback(
-        std::vector<jobject>& routingDelegateTarget) {
-    ALOGV("copyAudioDeviceCallback");
-    for (std::vector<std::pair<jobject, jobject>>::iterator it = mRoutingDelegates.begin();
-            it != mRoutingDelegates.end(); it++) {
-        routingDelegateTarget.push_back(it->second);
-    }
-}
-
 // static
 void MediaPlayer2AudioOutput::CallbackWrapper(
         int event, void *cookie, void *info) {
@@ -655,6 +630,11 @@
     return mSessionId;
 }
 
+void MediaPlayer2AudioOutput::setSessionId(const audio_session_t id) {
+    Mutex::Autolock lock(mLock);
+    mSessionId = id;
+}
+
 uint32_t MediaPlayer2AudioOutput::getSampleRate() const {
     Mutex::Autolock lock(mLock);
     if (mJAudioTrack == 0) {
diff --git a/media/libmediaplayer2/include/mediaplayer2/JAudioTrack.h b/media/libmediaplayer2/include/mediaplayer2/JAudioTrack.h
index 6122687..13cf85a 100644
--- a/media/libmediaplayer2/include/mediaplayer2/JAudioTrack.h
+++ b/media/libmediaplayer2/include/mediaplayer2/JAudioTrack.h
@@ -25,7 +25,7 @@
 #include <media/VolumeShaper.h>
 #include <system/audio.h>
 #include <utils/Errors.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.
 
@@ -115,7 +115,7 @@
                 void* user,
                 size_t frameCount = 0,
                 audio_session_t sessionId  = AUDIO_SESSION_ALLOCATE,
-                const audio_attributes_t* pAttributes = NULL,
+                const jobject pAttributes = NULL,
                 float maxRequiredSpeed = 1.0f);
 
     /*
@@ -446,7 +446,7 @@
 
     jclass mAudioTrackCls;
     jobject mAudioTrackObj;
-    jobject mAudioAttributesObj;
+    sp<JObjectHolder> mAudioAttributesObj;
 
     /* Creates a Java VolumeShaper.Configuration object from VolumeShaper::Configuration */
     jobject createVolumeShaperConfigurationObj(
diff --git a/media/libmediaplayer2/include/mediaplayer2/MediaPlayer2AudioOutput.h b/media/libmediaplayer2/include/mediaplayer2/MediaPlayer2AudioOutput.h
index d13c54c..fc020ca 100644
--- a/media/libmediaplayer2/include/mediaplayer2/MediaPlayer2AudioOutput.h
+++ b/media/libmediaplayer2/include/mediaplayer2/MediaPlayer2AudioOutput.h
@@ -41,8 +41,7 @@
     MediaPlayer2AudioOutput(audio_session_t sessionId,
                             uid_t uid,
                             int pid,
-                            const audio_attributes_t * attr,
-                            std::vector<jobject>& routingDelegatesBackup);
+                            const jobject attributes);
     virtual ~MediaPlayer2AudioOutput();
 
     virtual bool ready() const {
@@ -59,6 +58,7 @@
     virtual int64_t getPlayedOutDurationUs(int64_t nowUs) const;
     virtual status_t getFramesWritten(uint32_t *frameswritten) const;
     virtual audio_session_t getSessionId() const;
+    virtual void setSessionId(const audio_session_t id);
     virtual uint32_t getSampleRate() const;
     virtual int64_t getBufferDurationInUs() const;
 
@@ -76,7 +76,7 @@
     virtual void flush();
     virtual void pause();
     virtual void close();
-    void setAudioAttributes(const audio_attributes_t * attributes);
+    void setAudioAttributes(const jobject attributes);
     virtual audio_stream_type_t getAudioStreamType() const;
 
     void setVolume(float volume);
@@ -99,7 +99,6 @@
     virtual jobject getRoutedDevice();
     virtual status_t addAudioDeviceCallback(jobject routingDelegate);
     virtual status_t removeAudioDeviceCallback(jobject listener);
-    virtual void copyAudioDeviceCallback(std::vector<jobject>& routingDelegateTarget);
 
 private:
     static void setMinBufferCount();
@@ -112,7 +111,7 @@
     AudioCallback           mCallback;
     void *                  mCallbackCookie;
     CallbackData *          mCallbackData;
-    audio_attributes_t *    mAttributes;
+    sp<JObjectHolder>       mAttributes;
     float                   mVolume;
     AudioPlaybackRate       mPlaybackRate;
     uint32_t                mSampleRateHz; // sample rate of the content, as set in open()
diff --git a/media/libmediaplayer2/include/mediaplayer2/mediaplayer2.h b/media/libmediaplayer2/include/mediaplayer2/mediaplayer2.h
index a646399..d881813 100644
--- a/media/libmediaplayer2/include/mediaplayer2/mediaplayer2.h
+++ b/media/libmediaplayer2/include/mediaplayer2/mediaplayer2.h
@@ -24,8 +24,8 @@
 #include <media/mediaplayer_common.h>
 #include <mediaplayer2/MediaPlayer2Interface.h>
 #include <mediaplayer2/MediaPlayer2Types.h>
+#include <mediaplayer2/JObjectHolder.h>
 
-#include <vector>
 #include <jni.h>
 #include <utils/Errors.h>
 #include <utils/Mutex.h>
@@ -100,7 +100,8 @@
             audio_session_t getAudioSessionId();
             status_t        setAuxEffectSendLevel(float level);
             status_t        attachAuxEffect(int effectId);
-            status_t        setParameter(int key, const Parcel& request);
+            status_t        setAudioAttributes(const jobject attributes);
+            jobject         getAudioAttributes();
             status_t        getParameter(int key, Parcel* reply);
 
             // Modular DRM
@@ -121,14 +122,14 @@
     // Disconnect from the currently connected ANativeWindow.
     void disconnectNativeWindow_l();
 
-    status_t setAudioAttributes_l(const Parcel &request);
+    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 checkStateForKeySet_l(int key);
+    status_t checkState_l();
 
     pid_t                       mPid;
     uid_t                       mUid;
@@ -145,15 +146,13 @@
     int64_t                     mSeekPosition;
     MediaPlayer2SeekMode        mSeekMode;
     audio_stream_type_t         mStreamType;
-    Parcel*                     mAudioAttributesParcel;
     bool                        mLoop;
     float                       mVolume;
     int                         mVideoWidth;
     int                         mVideoHeight;
     audio_session_t             mAudioSessionId;
-    audio_attributes_t *        mAudioAttributes;
+    sp<JObjectHolder>           mAudioAttributes;
     float                       mSendLevel;
-    std::vector<jobject>        mRoutingDelegates;
     sp<ANativeWindowWrapper>    mConnectedWindow;
 };
 
diff --git a/media/libmediaplayer2/mediaplayer2.cpp b/media/libmediaplayer2/mediaplayer2.cpp
index 617da47..04a6f68 100644
--- a/media/libmediaplayer2/mediaplayer2.cpp
+++ b/media/libmediaplayer2/mediaplayer2.cpp
@@ -53,57 +53,6 @@
 const int kDumpLockRetries = 50;
 const int kDumpLockSleepUs = 20000;
 
-// 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 proxyListener : public MediaPlayer2InterfaceListener {
 public:
     proxyListener(const wp<MediaPlayer2> &player)
@@ -293,7 +242,7 @@
     mLockThreadId = 0;
     mListener = NULL;
     mStreamType = AUDIO_STREAM_MUSIC;
-    mAudioAttributesParcel = NULL;
+    mAudioAttributes = NULL;
     mCurrentPosition = -1;
     mCurrentSeekMode = MediaPlayer2SeekMode::SEEK_PREVIOUS_SYNC;
     mSeekPosition = -1;
@@ -310,21 +259,14 @@
     mPid = IPCThreadState::self()->getCallingPid();
     mUid = IPCThreadState::self()->getCallingUid();
 
-    mAudioAttributes = NULL;
+    mAudioOutput = new MediaPlayer2AudioOutput(mAudioSessionId, mUid, mPid, NULL /*attributes*/);
 }
 
 MediaPlayer2::~MediaPlayer2() {
     ALOGV("destructor");
-    if (mAudioAttributesParcel != NULL) {
-        delete mAudioAttributesParcel;
-        mAudioAttributesParcel = NULL;
-    }
     AudioSystem::releaseAudioSessionId(mAudioSessionId, -1);
     disconnect();
     removePlayer(this);
-    if (mAudioAttributes != NULL) {
-        free(mAudioAttributes);
-    }
 }
 
 bool MediaPlayer2::init() {
@@ -412,13 +354,7 @@
 
         clear_l();
 
-        if (mAudioOutput != NULL) {
-            mAudioOutput->copyAudioDeviceCallback(mRoutingDelegates);
-        }
-
         player->setListener(new proxyListener(this));
-        mAudioOutput = new MediaPlayer2AudioOutput(mAudioSessionId, mUid,
-                mPid, mAudioAttributes, mRoutingDelegates);
         player->setAudioSink(mAudioOutput);
 
         err = player->setDataSource(dsd);
@@ -568,22 +504,9 @@
     return mPlayer->setBufferingSettings(buffering);
 }
 
-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);
+status_t MediaPlayer2::setAudioAttributes_l(const jobject attributes) {
+    if (mAudioOutput != NULL) {
+        mAudioOutput->setAudioAttributes(attributes);
     }
     return NO_ERROR;
 }
@@ -592,8 +515,8 @@
     ALOGV("prepareAsync");
     Mutex::Autolock _l(mLock);
     if ((mPlayer != 0) && (mCurrentState & MEDIA_PLAYER2_INITIALIZED)) {
-        if (mAudioAttributesParcel != NULL) {
-            status_t err = setAudioAttributes_l(*mAudioAttributesParcel);
+        if (mAudioAttributes != NULL) {
+            status_t err = setAudioAttributes_l(mAudioAttributes->getJObject());
             if (err != OK) {
                 return err;
             }
@@ -983,6 +906,9 @@
         AudioSystem::releaseAudioSessionId(mAudioSessionId, -1);
         mAudioSessionId = sessionId;
     }
+    if (mAudioOutput != NULL && mAudioSessionId != mAudioOutput->getSessionId()) {
+        mAudioOutput->setSessionId(sessionId);
+    }
     return NO_ERROR;
 }
 
@@ -1015,67 +941,37 @@
 }
 
 // always call with lock held
-status_t MediaPlayer2::checkStateForKeySet_l(int key) {
-    switch(key) {
-    case MEDIA2_KEY_PARAMETER_AUDIO_ATTRIBUTES:
-        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;
-        }
-        break;
-    default:
-        // parameter doesn't require player state check
-        break;
+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::setParameter(int key, const Parcel& request) {
-    ALOGV("MediaPlayer2::setParameter(%d)", key);
+status_t MediaPlayer2::setAudioAttributes(const jobject attributes) {
+    ALOGV("MediaPlayer2::setAudioAttributes");
     status_t status = INVALID_OPERATION;
     Mutex::Autolock _l(mLock);
-    if (checkStateForKeySet_l(key) != OK) {
+    if (checkState_l() != OK) {
         return status;
     }
-    switch (key) {
-    case MEDIA2_KEY_PARAMETER_AUDIO_ATTRIBUTES:
-        // save the marshalled audio attributes
-        if (mAudioAttributesParcel != NULL) {
-            delete mAudioAttributesParcel;
-        }
-        mAudioAttributesParcel = new Parcel();
-        mAudioAttributesParcel->appendFrom(&request, 0, request.dataSize());
-        status = setAudioAttributes_l(request);
-        if (status != OK) {
-            return status;
-        }
-        break;
-    default:
-        ALOGV_IF(mPlayer == NULL, "setParameter: no active player");
-        break;
-    }
-
-    if (mPlayer != NULL) {
-        status = mPlayer->setParameter(key, request);
-    }
+    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 (key == MEDIA2_KEY_PARAMETER_AUDIO_ATTRIBUTES) {
-        if (reply == NULL) {
-            return BAD_VALUE;
-        }
-        if (mAudioAttributesParcel != NULL) {
-            reply->appendFrom(mAudioAttributesParcel, 0, mAudioAttributesParcel->dataSize());
-        }
-        return OK;
-    }
-
     if (mPlayer == NULL) {
         ALOGV("getParameter: no active player");
         return INVALID_OPERATION;
@@ -1286,7 +1182,6 @@
     Mutex::Autolock _l(mLock);
     if (mAudioOutput == NULL) {
         ALOGV("addAudioDeviceCallback: player not init");
-        mRoutingDelegates.push_back(routingDelegate);
         return NO_INIT;
     }
     return mAudioOutput->addAudioDeviceCallback(routingDelegate);