MediaPlayer2: remove AudioManager private API usage

Private API AudioManager.getDevicesStatic() is being used in
MediaPlayer2 for conversion between id <=> AudioDeviceInfo.
This conversion was added to talk with internal native AudioTrack API,
but in MediaPlayer2 since we will use public java AudioTrack API,
the given AudioDeviceInfo can be directly passed to java AudioTrack
instance.

Test: CtsMediaTestCases:android.media.cts.RoutingTest
Bug: 112767549
Change-Id: I9aeae02202edb6b5f0eb72b4f4dd3c936103ced2
diff --git a/media/libmediaplayer2/JAudioTrack.cpp b/media/libmediaplayer2/JAudioTrack.cpp
index 5c0c6ea..543f700 100644
--- a/media/libmediaplayer2/JAudioTrack.cpp
+++ b/media/libmediaplayer2/JAudioTrack.cpp
@@ -486,19 +486,11 @@
     return NO_ERROR;
 }
 
-audio_port_handle_t JAudioTrack::getRoutedDeviceId() {
+jobject JAudioTrack::getRoutedDevice() {
     JNIEnv *env = JavaVMHelper::getJNIEnv();
     jmethodID jGetRoutedDevice = env->GetMethodID(mAudioTrackCls, "getRoutedDevice",
             "()Landroid/media/AudioDeviceInfo;");
-    jobject jAudioDeviceInfoObj = env->CallObjectMethod(mAudioTrackObj, jGetRoutedDevice);
-    if (env->IsSameObject(jAudioDeviceInfoObj, NULL)) {
-        return AUDIO_PORT_HANDLE_NONE;
-    }
-
-    jclass jAudioDeviceInfoCls = env->FindClass("android/media/AudioDeviceInfo");
-    jmethodID jGetId = env->GetMethodID(jAudioDeviceInfoCls, "getId", "()I");
-    jint routedDeviceId = env->CallIntMethod(jAudioDeviceInfoObj, jGetId);
-    return routedDeviceId;
+    return env->CallObjectMethod(mAudioTrackObj, jGetRoutedDevice);
 }
 
 audio_session_t JAudioTrack::getAudioSessionId() {
@@ -508,13 +500,11 @@
     return (audio_session_t) sessionId;
 }
 
-status_t JAudioTrack::setOutputDevice(audio_port_handle_t deviceId) {
+status_t JAudioTrack::setPreferredDevice(jobject device) {
     JNIEnv *env = JavaVMHelper::getJNIEnv();
-    jclass jMP2ImplCls = env->FindClass("android/media/MediaPlayer2Impl");
-    jmethodID jSetAudioOutputDeviceById = env->GetStaticMethodID(
-            jMP2ImplCls, "setAudioOutputDeviceById", "(Landroid/media/AudioTrack;I)Z");
-    jboolean result = env->CallStaticBooleanMethod(
-            jMP2ImplCls, jSetAudioOutputDeviceById, mAudioTrackObj, deviceId);
+    jmethodID jSetPreferredDeviceId = env->GetMethodID(mAudioTrackCls, "setPreferredDevice",
+            "(Landroid/media/AudioDeviceInfo;)Z");
+    jboolean result = env->CallBooleanMethod(mAudioTrackObj, jSetPreferredDeviceId, device);
     return result == true ? NO_ERROR : BAD_VALUE;
 }
 
@@ -522,7 +512,7 @@
     JNIEnv *env = JavaVMHelper::getJNIEnv();
     jclass jAudioAttributesCls = env->FindClass("android/media/AudioAttributes");
     jmethodID jGetVolumeControlStream = env->GetMethodID(jAudioAttributesCls,
-                                        "getVolumeControlStream", "()I");
+            "getVolumeControlStream", "()I");
     int javaAudioStreamType = env->CallIntMethod(mAudioAttributesObj, jGetVolumeControlStream);
     return (audio_stream_type_t)javaAudioStreamType;
 }
diff --git a/media/libmediaplayer2/MediaPlayer2AudioOutput.cpp b/media/libmediaplayer2/MediaPlayer2AudioOutput.cpp
index 9218fce..149f243 100644
--- a/media/libmediaplayer2/MediaPlayer2AudioOutput.cpp
+++ b/media/libmediaplayer2/MediaPlayer2AudioOutput.cpp
@@ -74,9 +74,7 @@
       mPid(pid),
       mSendLevel(0.0),
       mAuxEffectId(0),
-      mFlags(AUDIO_OUTPUT_FLAG_NONE),
-      mSelectedDeviceId(AUDIO_PORT_HANDLE_NONE),
-      mRoutedDeviceId(AUDIO_PORT_HANDLE_NONE) {
+      mFlags(AUDIO_OUTPUT_FLAG_NONE) {
     ALOGV("MediaPlayer2AudioOutput(%d)", sessionId);
     if (attr != nullptr) {
         mAttributes = (audio_attributes_t *) calloc(1, sizeof(audio_attributes_t));
@@ -388,7 +386,9 @@
             res = mJAudioTrack->attachAuxEffect(mAuxEffectId);
         }
     }
-    mJAudioTrack->setOutputDevice(mSelectedDeviceId);
+    if (mPreferredDevice != nullptr) {
+        mJAudioTrack->setPreferredDevice(mPreferredDevice->getJObject());
+    }
 
     mJAudioTrack->registerRoutingDelegates(mRoutingDelegates);
 
@@ -518,24 +518,26 @@
     return NO_ERROR;
 }
 
-status_t MediaPlayer2AudioOutput::setOutputDevice(audio_port_handle_t deviceId) {
-    ALOGV("setOutputDevice(%d)", deviceId);
+status_t MediaPlayer2AudioOutput::setPreferredDevice(jobject device) {
+    ALOGV("setPreferredDevice");
     Mutex::Autolock lock(mLock);
-    mSelectedDeviceId = deviceId;
+    status_t ret = NO_ERROR;
     if (mJAudioTrack != nullptr) {
-        return mJAudioTrack->setOutputDevice(deviceId);
+        ret = mJAudioTrack->setPreferredDevice(device);
     }
-    return NO_ERROR;
+    if (ret == NO_ERROR) {
+        mPreferredDevice = new JObjectHolder(device);
+    }
+    return ret;
 }
 
-status_t MediaPlayer2AudioOutput::getRoutedDeviceId(audio_port_handle_t* deviceId) {
-    ALOGV("getRoutedDeviceId");
+jobject MediaPlayer2AudioOutput::getRoutedDevice() {
+    ALOGV("getRoutedDevice");
     Mutex::Autolock lock(mLock);
     if (mJAudioTrack != nullptr) {
-        mRoutedDeviceId = mJAudioTrack->getRoutedDeviceId();
+        return mJAudioTrack->getRoutedDevice();
     }
-    *deviceId = mRoutedDeviceId;
-    return NO_ERROR;
+    return nullptr;
 }
 
 status_t MediaPlayer2AudioOutput::addAudioDeviceCallback(jobject jRoutingDelegate) {
diff --git a/media/libmediaplayer2/include/mediaplayer2/JAudioTrack.h b/media/libmediaplayer2/include/mediaplayer2/JAudioTrack.h
index 629968f..6122687 100644
--- a/media/libmediaplayer2/include/mediaplayer2/JAudioTrack.h
+++ b/media/libmediaplayer2/include/mediaplayer2/JAudioTrack.h
@@ -335,25 +335,24 @@
      */
     status_t dump(int fd, const Vector<String16>& args) const;
 
-    /* Returns the ID of the audio device actually used by the output to which this AudioTrack is
-     * attached. When the AudioTrack is inactive, it will return AUDIO_PORT_HANDLE_NONE.
+    /* Returns the AudioDeviceInfo used by the output to which this AudioTrack is
+     * attached.
      */
-    audio_port_handle_t getRoutedDeviceId();
+    jobject getRoutedDevice();
 
     /* Returns the ID of the audio session this AudioTrack belongs to. */
     audio_session_t getAudioSessionId();
 
-    /* Selects the audio device to use for output of this AudioTrack. A value of
-     * AUDIO_PORT_HANDLE_NONE indicates default routing.
+    /* Sets the preferred audio device to use for output of this AudioTrack.
      *
      * Parameters:
-     *  The device ID of the selected device (as returned by the AudioDevicesManager API).
+     * Device: an AudioDeviceInfo object.
      *
      * Returned value:
      *  - NO_ERROR: successful operation
-     *  - BAD_VALUE: failed to find the valid output device with given device Id.
+     *  - BAD_VALUE: failed to set the device
      */
-    status_t setOutputDevice(audio_port_handle_t deviceId);
+    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.
diff --git a/media/libmediaplayer2/include/mediaplayer2/JObjectHolder.h b/media/libmediaplayer2/include/mediaplayer2/JObjectHolder.h
new file mode 100644
index 0000000..93d8b40
--- /dev/null
+++ b/media/libmediaplayer2/include/mediaplayer2/JObjectHolder.h
@@ -0,0 +1,47 @@
+/*
+ * 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/MediaPlayer2AudioOutput.h b/media/libmediaplayer2/include/mediaplayer2/MediaPlayer2AudioOutput.h
index 9fca641..d13c54c 100644
--- a/media/libmediaplayer2/include/mediaplayer2/MediaPlayer2AudioOutput.h
+++ b/media/libmediaplayer2/include/mediaplayer2/MediaPlayer2AudioOutput.h
@@ -20,12 +20,15 @@
 
 #include <mediaplayer2/MediaPlayer2Interface.h>
 #include <mediaplayer2/JAudioTrack.h>
+#include <mediaplayer2/JObjectHolder.h>
 
 #include <vector>
 #include <utility>
 #include <utils/String16.h>
 #include <utils/Vector.h>
 
+#include "jni.h"
+
 namespace android {
 
 class AudioTrack;
@@ -92,8 +95,8 @@
         //return mNextOutput == NULL;
     }
     // AudioRouting
-    virtual status_t setOutputDevice(audio_port_handle_t deviceId);
-    virtual status_t getRoutedDeviceId(audio_port_handle_t* deviceId);
+    virtual status_t setPreferredDevice(jobject device);
+    virtual jobject getRoutedDevice();
     virtual status_t addAudioDeviceCallback(jobject routingDelegate);
     virtual status_t removeAudioDeviceCallback(jobject listener);
     virtual void copyAudioDeviceCallback(std::vector<jobject>& routingDelegateTarget);
@@ -121,8 +124,7 @@
     float                   mSendLevel;
     int                     mAuxEffectId;
     audio_output_flags_t    mFlags;
-    audio_port_handle_t     mSelectedDeviceId;
-    audio_port_handle_t     mRoutedDeviceId;
+    sp<JObjectHolder>       mPreferredDevice;
     mutable Mutex           mLock;
     std::vector<std::pair<jobject, jobject>> mRoutingDelegates; // <listener, routingDelegate>
 
diff --git a/media/libmediaplayer2/include/mediaplayer2/MediaPlayer2Interface.h b/media/libmediaplayer2/include/mediaplayer2/MediaPlayer2Interface.h
index 9a35ed9..07a7946 100644
--- a/media/libmediaplayer2/include/mediaplayer2/MediaPlayer2Interface.h
+++ b/media/libmediaplayer2/include/mediaplayer2/MediaPlayer2Interface.h
@@ -34,6 +34,7 @@
 #include <media/stagefright/foundation/AHandler.h>
 #include <mediaplayer2/MediaPlayer2Types.h>
 
+#include "jni.h"
 #include "mediaplayer2.pb.h"
 
 using android::media::MediaPlayer2Proto::PlayerMessage;
@@ -142,8 +143,8 @@
         }
 
         // AudioRouting
-        virtual status_t    setOutputDevice(audio_port_handle_t deviceId);
-        virtual status_t    getRoutedDeviceId(audio_port_handle_t* deviceId);
+        virtual status_t    setPreferredDevice(jobject device);
+        virtual jobject     getRoutedDevice();
         virtual status_t    addAudioDeviceCallback(jobject routingDelegate);
         virtual status_t    removeAudioDeviceCallback(jobject listener);
     };
diff --git a/media/libmediaplayer2/include/mediaplayer2/mediaplayer2.h b/media/libmediaplayer2/include/mediaplayer2/mediaplayer2.h
index a1908e6..a646399 100644
--- a/media/libmediaplayer2/include/mediaplayer2/mediaplayer2.h
+++ b/media/libmediaplayer2/include/mediaplayer2/mediaplayer2.h
@@ -34,6 +34,8 @@
 #include <utils/Vector.h>
 #include <system/audio-base.h>
 
+#include "jni.h"
+
 namespace android {
 
 struct ANativeWindowWrapper;
@@ -105,8 +107,8 @@
             status_t        prepareDrm(const uint8_t uuid[16], const Vector<uint8_t>& drmSessionId);
             status_t        releaseDrm();
             // AudioRouting
-            status_t        setOutputDevice(audio_port_handle_t deviceId);
-            audio_port_handle_t getRoutedDeviceId();
+            status_t        setPreferredDevice(jobject device);
+            jobject         getRoutedDevice();
             status_t        addAudioDeviceCallback(jobject routingDelegate);
             status_t        removeAudioDeviceCallback(jobject listener);
 
diff --git a/media/libmediaplayer2/mediaplayer2.cpp b/media/libmediaplayer2/mediaplayer2.cpp
index 4960694..617da47 100644
--- a/media/libmediaplayer2/mediaplayer2.cpp
+++ b/media/libmediaplayer2/mediaplayer2.cpp
@@ -1264,27 +1264,22 @@
     return status;
 }
 
-status_t MediaPlayer2::setOutputDevice(audio_port_handle_t deviceId) {
+status_t MediaPlayer2::setPreferredDevice(jobject device) {
     Mutex::Autolock _l(mLock);
     if (mAudioOutput == NULL) {
-        ALOGV("setOutputDevice: audio sink not init");
+        ALOGV("setPreferredDevice: audio sink not init");
         return NO_INIT;
     }
-    return mAudioOutput->setOutputDevice(deviceId);
+    return mAudioOutput->setPreferredDevice(device);
 }
 
-audio_port_handle_t MediaPlayer2::getRoutedDeviceId() {
+jobject MediaPlayer2::getRoutedDevice() {
     Mutex::Autolock _l(mLock);
     if (mAudioOutput == NULL) {
-        ALOGV("getRoutedDeviceId: audio sink not init");
-        return AUDIO_PORT_HANDLE_NONE;
+        ALOGV("getRoutedDevice: audio sink not init");
+        return nullptr;
     }
-    audio_port_handle_t deviceId;
-    status_t status = mAudioOutput->getRoutedDeviceId(&deviceId);
-    if (status != NO_ERROR) {
-        return AUDIO_PORT_HANDLE_NONE;
-    }
-    return deviceId;
+    return mAudioOutput->getRoutedDevice();
 }
 
 status_t MediaPlayer2::addAudioDeviceCallback(jobject routingDelegate) {