Fixed routing change bug

(1) Change logic of addAudioDeviceCallback() since mJAudioTrack is
likely to be null when this function is called.
(2) Replace add/removeGlobalRef() with JObjectHolder
(3) Replace std::vector with utils/Vector.h

Test: android.media.cts.RoutingTest#test_MediaPlayer2_RoutingChangedCallback with routing change log
Bug: 127314187

Change-Id: I62d9c7600c710b49f0435bd1fc2741d79c928b55
diff --git a/media/libmediaplayer2/JAudioTrack.cpp b/media/libmediaplayer2/JAudioTrack.cpp
index a01afa3..910edff 100644
--- a/media/libmediaplayer2/JAudioTrack.cpp
+++ b/media/libmediaplayer2/JAudioTrack.cpp
@@ -571,8 +571,8 @@
 }
 
 void JAudioTrack::registerRoutingDelegates(
-        std::vector<std::pair<jobject, jobject>>& routingDelegates) {
-    for (std::vector<std::pair<jobject, jobject>>::iterator it = routingDelegates.begin();
+        Vector<std::pair<jobject, jobject>>& routingDelegates) {
+    for (Vector<std::pair<jobject, jobject>>::iterator it = routingDelegates.begin();
             it != routingDelegates.end(); it++) {
         addAudioDeviceCallback(it->second, getHandler(it->second));
     }
@@ -597,23 +597,9 @@
     return env->CallObjectMethod(routingDelegateObj, jGetHandler);
 }
 
-jobject JAudioTrack::addGlobalRef(const jobject obj) {
+jobject JAudioTrack::findByKey(Vector<std::pair<jobject, jobject>>& mp, const jobject key) {
     JNIEnv *env = JavaVMHelper::getJNIEnv();
-    return reinterpret_cast<jobject>(env->NewGlobalRef(obj));
-}
-
-status_t JAudioTrack::removeGlobalRef(const jobject obj) {
-    if (obj == NULL) {
-        return BAD_VALUE;
-    }
-    JNIEnv *env = JavaVMHelper::getJNIEnv();
-    env->DeleteGlobalRef(obj);
-    return NO_ERROR;
-}
-
-jobject JAudioTrack::findByKey(std::vector<std::pair<jobject, jobject>>& mp, const jobject key) {
-    JNIEnv *env = JavaVMHelper::getJNIEnv();
-    for (std::vector<std::pair<jobject, jobject>>::iterator it = mp.begin(); it != mp.end(); it++) {
+    for (Vector<std::pair<jobject, jobject>>::iterator it = mp.begin(); it != mp.end(); it++) {
         if (env->IsSameObject(it->first, key)) {
             return it->second;
         }
@@ -621,9 +607,9 @@
     return nullptr;
 }
 
-void JAudioTrack::eraseByKey(std::vector<std::pair<jobject, jobject>>& mp, const jobject key) {
+void JAudioTrack::eraseByKey(Vector<std::pair<jobject, jobject>>& mp, const jobject key) {
     JNIEnv *env = JavaVMHelper::getJNIEnv();
-    for (std::vector<std::pair<jobject, jobject>>::iterator it = mp.begin(); it != mp.end(); it++) {
+    for (Vector<std::pair<jobject, jobject>>::iterator it = mp.begin(); it != mp.end(); it++) {
         if (env->IsSameObject(it->first, key)) {
             mp.erase(it);
             return;
diff --git a/media/libmediaplayer2/MediaPlayer2AudioOutput.cpp b/media/libmediaplayer2/MediaPlayer2AudioOutput.cpp
index 4de92ad..7c3063d 100644
--- a/media/libmediaplayer2/MediaPlayer2AudioOutput.cpp
+++ b/media/libmediaplayer2/MediaPlayer2AudioOutput.cpp
@@ -85,9 +85,6 @@
 }
 
 MediaPlayer2AudioOutput::~MediaPlayer2AudioOutput() {
-    for (auto routingDelegate : mRoutingDelegates) {
-        JAudioTrack::removeGlobalRef(routingDelegate.second);
-    }
     close();
     delete mCallbackData;
 }
@@ -524,13 +521,16 @@
 status_t MediaPlayer2AudioOutput::addAudioDeviceCallback(jobject jRoutingDelegate) {
     ALOGV("addAudioDeviceCallback");
     Mutex::Autolock lock(mLock);
-    jobject listener = JAudioTrack::getListener(jRoutingDelegate);
-    if (mJAudioTrack != nullptr &&
-        JAudioTrack::findByKey(mRoutingDelegates, listener) == nullptr) {
-        jobject handler = JAudioTrack::getHandler(jRoutingDelegate);
-        jobject routingDelegate = JAudioTrack::addGlobalRef(jRoutingDelegate);
+    jobject listener = (new JObjectHolder(
+            JAudioTrack::getListener(jRoutingDelegate)))->getJObject();
+    if (JAudioTrack::findByKey(mRoutingDelegates, listener) == nullptr) {
+        jobject handler = (new JObjectHolder(
+                JAudioTrack::getHandler(jRoutingDelegate)))->getJObject();
+        jobject routingDelegate = (new JObjectHolder(jRoutingDelegate))->getJObject();
         mRoutingDelegates.push_back(std::pair<jobject, jobject>(listener, routingDelegate));
-        return mJAudioTrack->addAudioDeviceCallback(routingDelegate, handler);
+        if (mJAudioTrack != nullptr) {
+            return mJAudioTrack->addAudioDeviceCallback(routingDelegate, handler);
+        }
     }
     return NO_ERROR;
 }
@@ -539,13 +539,11 @@
     ALOGV("removeAudioDeviceCallback");
     Mutex::Autolock lock(mLock);
     jobject routingDelegate = nullptr;
-    if (mJAudioTrack != nullptr &&
-        (routingDelegate = JAudioTrack::findByKey(mRoutingDelegates, listener)) != nullptr) {
-        mJAudioTrack->removeAudioDeviceCallback(routingDelegate);
-        JAudioTrack::eraseByKey(mRoutingDelegates, listener);
-        if (JAudioTrack::removeGlobalRef(routingDelegate) != NO_ERROR) {
-            return BAD_VALUE;
+    if ((routingDelegate = JAudioTrack::findByKey(mRoutingDelegates, listener)) != nullptr) {
+        if (mJAudioTrack != nullptr) {
+            mJAudioTrack->removeAudioDeviceCallback(routingDelegate);
         }
+        JAudioTrack::eraseByKey(mRoutingDelegates, listener);
     }
     return NO_ERROR;
 }
diff --git a/media/libmediaplayer2/include/mediaplayer2/JAudioTrack.h b/media/libmediaplayer2/include/mediaplayer2/JAudioTrack.h
index 87dc889..7381286 100644
--- a/media/libmediaplayer2/include/mediaplayer2/JAudioTrack.h
+++ b/media/libmediaplayer2/include/mediaplayer2/JAudioTrack.h
@@ -17,7 +17,6 @@
 #ifndef ANDROID_JAUDIOTRACK_H
 #define ANDROID_JAUDIOTRACK_H
 
-#include <vector>
 #include <utility>
 #include <jni.h>
 #include <media/AudioResamplerPublic.h>
@@ -25,6 +24,7 @@
 #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.
@@ -405,7 +405,7 @@
      * routingDelegates: backed-up routing delegates
      *
      */
-    void registerRoutingDelegates(std::vector<std::pair<jobject, jobject>>& routingDelegates);
+    void registerRoutingDelegates(Vector<std::pair<jobject, jobject>>& routingDelegates);
 
     /* get listener from RoutingDelegate object
      */
@@ -415,17 +415,6 @@
      */
     static jobject getHandler(const jobject routingDelegateObj);
 
-    /* convert local reference to global reference.
-     */
-    static jobject addGlobalRef(const jobject obj);
-
-    /* erase global reference.
-     *
-     * Returns NO_ERROR if succeeds
-     *         BAD_VALUE if obj is NULL
-     */
-    static status_t removeGlobalRef(const jobject obj);
-
     /*
      * Parameters:
      * map and key
@@ -433,13 +422,13 @@
      * Returns value if key is in the map
      *         nullptr if key is not in the map
      */
-    static jobject findByKey(std::vector<std::pair<jobject, jobject>>& mp, const jobject key);
+    static jobject findByKey(Vector<std::pair<jobject, jobject>>& mp, const jobject key);
 
     /*
      * Parameters:
      * map and key
      */
-    static void eraseByKey(std::vector<std::pair<jobject, jobject>>& mp, const jobject key);
+    static void eraseByKey(Vector<std::pair<jobject, jobject>>& mp, const jobject key);
 
 private:
     audio_output_flags_t mFlags;
diff --git a/media/libmediaplayer2/include/mediaplayer2/MediaPlayer2AudioOutput.h b/media/libmediaplayer2/include/mediaplayer2/MediaPlayer2AudioOutput.h
index bda4f61..1b3f2dc 100644
--- a/media/libmediaplayer2/include/mediaplayer2/MediaPlayer2AudioOutput.h
+++ b/media/libmediaplayer2/include/mediaplayer2/MediaPlayer2AudioOutput.h
@@ -22,7 +22,6 @@
 #include <mediaplayer2/JAudioTrack.h>
 #include <mediaplayer2/JObjectHolder.h>
 
-#include <vector>
 #include <utility>
 #include <utils/String16.h>
 #include <utils/Vector.h>
@@ -125,7 +124,7 @@
     audio_output_flags_t    mFlags;
     sp<JObjectHolder>       mPreferredDevice;
     mutable Mutex           mLock;
-    std::vector<std::pair<jobject, jobject>> mRoutingDelegates; // <listener, routingDelegate>
+    Vector<std::pair<jobject, jobject>> mRoutingDelegates; // <listener, routingDelegate>
 
     // static variables below not protected by mutex
     static bool             mIsOnEmulator;