Loading core/jni/android_media_AudioRecord.cpp +17 −9 Original line number Diff line number Diff line Loading @@ -584,14 +584,23 @@ static jboolean android_media_AudioRecord_setInputDevice( return lpRecorder->setInputDevice(device_id) == NO_ERROR; } static jint android_media_AudioRecord_getRoutedDeviceId( JNIEnv *env, jobject thiz) { static jintArray android_media_AudioRecord_getRoutedDeviceIds(JNIEnv *env, jobject thiz) { sp<AudioRecord> lpRecorder = getAudioRecord(env, thiz); if (lpRecorder == 0) { return 0; if (lpRecorder == NULL) { return NULL; } DeviceIdVector deviceIds = lpRecorder->getRoutedDeviceIds(); jintArray result; result = env->NewIntArray(deviceIds.size()); if (result == NULL) { return NULL; } jint *values = env->GetIntArrayElements(result, 0); for (unsigned int i = 0; i < deviceIds.size(); i++) { values[i++] = static_cast<jint>(deviceIds[i]); } return (jint)lpRecorder->getRoutedDeviceId(); env->ReleaseIntArrayElements(result, values, 0); return result; } // Enable and Disable Callback methods are synchronized on the Java side Loading Loading @@ -821,8 +830,7 @@ static const JNINativeMethod gMethods[] = { // name, signature, funcPtr {"native_start", "(II)I", (void *)android_media_AudioRecord_start}, {"native_stop", "()V", (void *)android_media_AudioRecord_stop}, {"native_setup", "(Ljava/lang/Object;Ljava/lang/Object;[IIIII[ILandroid/os/Parcel;JII)I", {"native_setup", "(Ljava/lang/Object;Ljava/lang/Object;[IIIII[ILandroid/os/Parcel;JII)I", (void *)android_media_AudioRecord_setup}, {"native_finalize", "()V", (void *)android_media_AudioRecord_finalize}, {"native_release", "()V", (void *)android_media_AudioRecord_release}, Loading @@ -846,7 +854,7 @@ static const JNINativeMethod gMethods[] = { {"native_getMetrics", "()Landroid/os/PersistableBundle;", (void *)android_media_AudioRecord_native_getMetrics}, {"native_setInputDevice", "(I)Z", (void *)android_media_AudioRecord_setInputDevice}, {"native_getRoutedDeviceId", "()I", (void *)android_media_AudioRecord_getRoutedDeviceId}, {"native_getRoutedDeviceIds", "()[I", (void *)android_media_AudioRecord_getRoutedDeviceIds}, {"native_enableDeviceCallback", "()V", (void *)android_media_AudioRecord_enableDeviceCallback}, {"native_disableDeviceCallback", "()V", Loading core/jni/android_media_AudioTrack.cpp +15 −7 Original line number Diff line number Diff line Loading @@ -1190,15 +1190,23 @@ static jboolean android_media_AudioTrack_setOutputDevice( } return lpTrack->setOutputDevice(device_id) == NO_ERROR; } static jint android_media_AudioTrack_getRoutedDeviceId( JNIEnv *env, jobject thiz) { static jintArray android_media_AudioTrack_getRoutedDeviceIds(JNIEnv *env, jobject thiz) { sp<AudioTrack> lpTrack = getAudioTrack(env, thiz); if (lpTrack == NULL) { return 0; return NULL; } DeviceIdVector deviceIds = lpTrack->getRoutedDeviceIds(); jintArray result; result = env->NewIntArray(deviceIds.size()); if (result == NULL) { return NULL; } jint *values = env->GetIntArrayElements(result, 0); for (unsigned int i = 0; i < deviceIds.size(); i++) { values[i++] = static_cast<jint>(deviceIds[i]); } return (jint)lpTrack->getRoutedDeviceId(); env->ReleaseIntArrayElements(result, values, 0); return result; } static void android_media_AudioTrack_enableDeviceCallback( Loading Loading @@ -1503,7 +1511,7 @@ static const JNINativeMethod gMethods[] = { (void *)android_media_AudioTrack_setAuxEffectSendLevel}, {"native_attachAuxEffect", "(I)I", (void *)android_media_AudioTrack_attachAuxEffect}, {"native_setOutputDevice", "(I)Z", (void *)android_media_AudioTrack_setOutputDevice}, {"native_getRoutedDeviceId", "()I", (void *)android_media_AudioTrack_getRoutedDeviceId}, {"native_getRoutedDeviceIds", "()[I", (void *)android_media_AudioTrack_getRoutedDeviceIds}, {"native_enableDeviceCallback", "()V", (void *)android_media_AudioTrack_enableDeviceCallback}, {"native_disableDeviceCallback", "()V", Loading core/jni/android_media_DeviceCallback.cpp +7 −8 Original line number Diff line number Diff line Loading @@ -61,21 +61,20 @@ JNIDeviceCallback::~JNIDeviceCallback() } void JNIDeviceCallback::onAudioDeviceUpdate(audio_io_handle_t audioIo, audio_port_handle_t deviceId) { const DeviceIdVector& deviceIds) { JNIEnv *env = AndroidRuntime::getJNIEnv(); if (env == NULL) { return; } ALOGV("%s audioIo %d deviceId %d", __FUNCTION__, audioIo, deviceId); env->CallStaticVoidMethod(mClass, mPostEventFromNative, mObject, AUDIO_NATIVE_EVENT_ROUTING_CHANGE, deviceId, 0, NULL); ALOGV("%s audioIo %d deviceIds %s", __FUNCTION__, audioIo, toString(deviceIds).c_str()); // Java should query the new device ids once it gets the event. // TODO(b/378505346): Pass the deviceIds to Java to avoid race conditions. env->CallStaticVoidMethod(mClass, mPostEventFromNative, mObject, AUDIO_NATIVE_EVENT_ROUTING_CHANGE, 0 /*arg1*/, 0 /*arg2*/, NULL /*obj*/); if (env->ExceptionCheck()) { ALOGW("An exception occurred while notifying an event."); env->ExceptionClear(); } } core/jni/android_media_DeviceCallback.h +1 −2 Original line number Diff line number Diff line Loading @@ -31,8 +31,7 @@ public: JNIDeviceCallback(JNIEnv* env, jobject thiz, jobject weak_thiz, jmethodID postEventFromNative); ~JNIDeviceCallback(); virtual void onAudioDeviceUpdate(audio_io_handle_t audioIo, audio_port_handle_t deviceId); virtual void onAudioDeviceUpdate(audio_io_handle_t audioIo, const DeviceIdVector& deviceIds); private: void sendEvent(int event); Loading media/java/android/media/AudioPlaybackConfiguration.java +41 −26 Original line number Diff line number Diff line Loading @@ -41,6 +41,7 @@ import java.io.PrintWriter; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Objects; Loading @@ -59,6 +60,8 @@ public final class AudioPlaybackConfiguration implements Parcelable { public static final int PLAYER_UPID_INVALID = -1; /** @hide */ public static final int PLAYER_DEVICEID_INVALID = 0; /** @hide */ public static final int[] PLAYER_DEVICEIDS_INVALID = new int[0]; // information about the implementation /** Loading Loading @@ -335,7 +338,7 @@ public final class AudioPlaybackConfiguration implements Parcelable { private final Object mUpdateablePropLock = new Object(); @GuardedBy("mUpdateablePropLock") private int mDeviceId; private @NonNull int[] mDeviceIds = AudioPlaybackConfiguration.PLAYER_DEVICEIDS_INVALID; @GuardedBy("mUpdateablePropLock") private int mSessionId; @GuardedBy("mUpdateablePropLock") Loading Loading @@ -364,7 +367,7 @@ public final class AudioPlaybackConfiguration implements Parcelable { mClientUid = uid; mClientPid = pid; mMutedState = 0; mDeviceId = PLAYER_DEVICEID_INVALID; mDeviceIds = AudioPlaybackConfiguration.PLAYER_DEVICEIDS_INVALID; mPlayerState = PLAYER_STATE_IDLE; mPlayerAttr = pic.mAttributes; if ((sPlayerDeathMonitor != null) && (pic.mIPlayer != null)) { Loading @@ -388,10 +391,11 @@ public final class AudioPlaybackConfiguration implements Parcelable { } // sets the fields that are updateable and require synchronization private void setUpdateableFields(int deviceId, int sessionId, int mutedState, FormatInfo format) private void setUpdateableFields(int[] deviceIds, int sessionId, int mutedState, FormatInfo format) { synchronized (mUpdateablePropLock) { mDeviceId = deviceId; mDeviceIds = deviceIds; mSessionId = sessionId; mMutedState = mutedState; mFormatInfo = format; Loading Loading @@ -427,7 +431,7 @@ public final class AudioPlaybackConfiguration implements Parcelable { anonymCopy.mClientPid = PLAYER_UPID_INVALID; anonymCopy.mIPlayerShell = null; anonymCopy.setUpdateableFields( /*deviceId*/ PLAYER_DEVICEID_INVALID, /*deviceIds*/ new int[0], /*sessionId*/ AudioSystem.AUDIO_SESSION_ALLOCATE, /*mutedState*/ 0, FormatInfo.DEFAULT); Loading Loading @@ -471,14 +475,14 @@ public final class AudioPlaybackConfiguration implements Parcelable { @Deprecated @FlaggedApi(FLAG_ROUTED_DEVICE_IDS) public @Nullable AudioDeviceInfo getAudioDeviceInfo() { final int deviceId; final int[] deviceIds; synchronized (mUpdateablePropLock) { deviceId = mDeviceId; deviceIds = mDeviceIds; } if (deviceId == PLAYER_DEVICEID_INVALID) { if (deviceIds.length == 0) { return null; } return AudioManager.getDeviceForPortId(deviceId, AudioManager.GET_DEVICES_OUTPUTS); return AudioManager.getDeviceForPortId(deviceIds[0], AudioManager.GET_DEVICES_OUTPUTS); } /** Loading @@ -491,10 +495,18 @@ public final class AudioPlaybackConfiguration implements Parcelable { @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public @NonNull List<AudioDeviceInfo> getAudioDeviceInfos() { List<AudioDeviceInfo> audioDeviceInfos = new ArrayList<AudioDeviceInfo>(); AudioDeviceInfo audioDeviceInfo = getAudioDeviceInfo(); final int[] deviceIds; synchronized (mUpdateablePropLock) { deviceIds = mDeviceIds; } for (int i = 0; i < deviceIds.length; i++) { AudioDeviceInfo audioDeviceInfo = AudioManager.getDeviceForPortId(deviceIds[i], AudioManager.GET_DEVICES_OUTPUTS); if (audioDeviceInfo != null) { audioDeviceInfos.add(audioDeviceInfo); } } return audioDeviceInfos; } Loading Loading @@ -701,15 +713,15 @@ public final class AudioPlaybackConfiguration implements Parcelable { * @hide * Handle a player state change * @param event * @param deviceId active device id or {@Code PLAYER_DEVICEID_INVALID} * <br>Note device id is valid for {@code PLAYER_UPDATE_DEVICE_ID} or * <br>{@code PLAYER_STATE_STARTED} events, as the device id will be reset to none when * <br>pausing or stopping playback. It will be set to active device when playback starts or * @param deviceIds an array of device ids. This can be empty. * <br>Note device ids are non-empty for {@code PLAYER_UPDATE_DEVICE_ID} or * <br>{@code PLAYER_STATE_STARTED} events, as the device ids will be emptied when pausing * <br>or stopping playback. It will be set to active devices when playback starts or * <br>it will be changed when PLAYER_UPDATE_DEVICE_ID is sent. The latter can happen if the * <br>device changes in the middle of playback. * <br>devices change in the middle of playback. * @return true if the state changed, false otherwise */ public boolean handleStateEvent(int event, int deviceId) { public boolean handleStateEvent(int event, int[] deviceIds) { boolean changed = false; synchronized (mUpdateablePropLock) { Loading @@ -720,8 +732,8 @@ public final class AudioPlaybackConfiguration implements Parcelable { } if (event == PLAYER_STATE_STARTED || event == PLAYER_UPDATE_DEVICE_ID) { changed = changed || (mDeviceId != deviceId); mDeviceId = deviceId; changed = changed || !Arrays.equals(mDeviceIds, deviceIds); mDeviceIds = deviceIds; } if (changed && (event == PLAYER_STATE_RELEASED) && (mIPlayerShell != null)) { Loading Loading @@ -801,8 +813,8 @@ public final class AudioPlaybackConfiguration implements Parcelable { @Override public int hashCode() { synchronized (mUpdateablePropLock) { return Objects.hash(mPlayerIId, mDeviceId, mMutedState, mPlayerType, mClientUid, mClientPid, mSessionId); return Objects.hash(mPlayerIId, Arrays.toString(mDeviceIds), mMutedState, mPlayerType, mClientUid, mClientPid, mSessionId); } } Loading @@ -815,7 +827,7 @@ public final class AudioPlaybackConfiguration implements Parcelable { public void writeToParcel(Parcel dest, int flags) { synchronized (mUpdateablePropLock) { dest.writeInt(mPlayerIId); dest.writeInt(mDeviceId); dest.writeIntArray(mDeviceIds); dest.writeInt(mMutedState); dest.writeInt(mPlayerType); dest.writeInt(mClientUid); Loading @@ -834,7 +846,10 @@ public final class AudioPlaybackConfiguration implements Parcelable { private AudioPlaybackConfiguration(Parcel in) { mPlayerIId = in.readInt(); mDeviceId = in.readInt(); mDeviceIds = new int[in.readInt()]; for (int i = 0; i < mDeviceIds.length; i++) { mDeviceIds[i] = in.readInt(); } mMutedState = in.readInt(); mPlayerType = in.readInt(); mClientUid = in.readInt(); Loading @@ -855,7 +870,7 @@ public final class AudioPlaybackConfiguration implements Parcelable { AudioPlaybackConfiguration that = (AudioPlaybackConfiguration) o; return ((mPlayerIId == that.mPlayerIId) && (mDeviceId == that.mDeviceId) && Arrays.equals(mDeviceIds, that.mDeviceIds) && (mMutedState == that.mMutedState) && (mPlayerType == that.mPlayerType) && (mClientUid == that.mClientUid) Loading @@ -868,7 +883,7 @@ public final class AudioPlaybackConfiguration implements Parcelable { StringBuilder apcToString = new StringBuilder(); synchronized (mUpdateablePropLock) { apcToString.append("AudioPlaybackConfiguration piid:").append(mPlayerIId).append( " deviceId:").append(mDeviceId).append(" type:").append( " deviceIds:").append(Arrays.toString(mDeviceIds)).append(" type:").append( toLogFriendlyPlayerType(mPlayerType)).append(" u/pid:").append( mClientUid).append( "/").append(mClientPid).append(" state:").append( Loading Loading
core/jni/android_media_AudioRecord.cpp +17 −9 Original line number Diff line number Diff line Loading @@ -584,14 +584,23 @@ static jboolean android_media_AudioRecord_setInputDevice( return lpRecorder->setInputDevice(device_id) == NO_ERROR; } static jint android_media_AudioRecord_getRoutedDeviceId( JNIEnv *env, jobject thiz) { static jintArray android_media_AudioRecord_getRoutedDeviceIds(JNIEnv *env, jobject thiz) { sp<AudioRecord> lpRecorder = getAudioRecord(env, thiz); if (lpRecorder == 0) { return 0; if (lpRecorder == NULL) { return NULL; } DeviceIdVector deviceIds = lpRecorder->getRoutedDeviceIds(); jintArray result; result = env->NewIntArray(deviceIds.size()); if (result == NULL) { return NULL; } jint *values = env->GetIntArrayElements(result, 0); for (unsigned int i = 0; i < deviceIds.size(); i++) { values[i++] = static_cast<jint>(deviceIds[i]); } return (jint)lpRecorder->getRoutedDeviceId(); env->ReleaseIntArrayElements(result, values, 0); return result; } // Enable and Disable Callback methods are synchronized on the Java side Loading Loading @@ -821,8 +830,7 @@ static const JNINativeMethod gMethods[] = { // name, signature, funcPtr {"native_start", "(II)I", (void *)android_media_AudioRecord_start}, {"native_stop", "()V", (void *)android_media_AudioRecord_stop}, {"native_setup", "(Ljava/lang/Object;Ljava/lang/Object;[IIIII[ILandroid/os/Parcel;JII)I", {"native_setup", "(Ljava/lang/Object;Ljava/lang/Object;[IIIII[ILandroid/os/Parcel;JII)I", (void *)android_media_AudioRecord_setup}, {"native_finalize", "()V", (void *)android_media_AudioRecord_finalize}, {"native_release", "()V", (void *)android_media_AudioRecord_release}, Loading @@ -846,7 +854,7 @@ static const JNINativeMethod gMethods[] = { {"native_getMetrics", "()Landroid/os/PersistableBundle;", (void *)android_media_AudioRecord_native_getMetrics}, {"native_setInputDevice", "(I)Z", (void *)android_media_AudioRecord_setInputDevice}, {"native_getRoutedDeviceId", "()I", (void *)android_media_AudioRecord_getRoutedDeviceId}, {"native_getRoutedDeviceIds", "()[I", (void *)android_media_AudioRecord_getRoutedDeviceIds}, {"native_enableDeviceCallback", "()V", (void *)android_media_AudioRecord_enableDeviceCallback}, {"native_disableDeviceCallback", "()V", Loading
core/jni/android_media_AudioTrack.cpp +15 −7 Original line number Diff line number Diff line Loading @@ -1190,15 +1190,23 @@ static jboolean android_media_AudioTrack_setOutputDevice( } return lpTrack->setOutputDevice(device_id) == NO_ERROR; } static jint android_media_AudioTrack_getRoutedDeviceId( JNIEnv *env, jobject thiz) { static jintArray android_media_AudioTrack_getRoutedDeviceIds(JNIEnv *env, jobject thiz) { sp<AudioTrack> lpTrack = getAudioTrack(env, thiz); if (lpTrack == NULL) { return 0; return NULL; } DeviceIdVector deviceIds = lpTrack->getRoutedDeviceIds(); jintArray result; result = env->NewIntArray(deviceIds.size()); if (result == NULL) { return NULL; } jint *values = env->GetIntArrayElements(result, 0); for (unsigned int i = 0; i < deviceIds.size(); i++) { values[i++] = static_cast<jint>(deviceIds[i]); } return (jint)lpTrack->getRoutedDeviceId(); env->ReleaseIntArrayElements(result, values, 0); return result; } static void android_media_AudioTrack_enableDeviceCallback( Loading Loading @@ -1503,7 +1511,7 @@ static const JNINativeMethod gMethods[] = { (void *)android_media_AudioTrack_setAuxEffectSendLevel}, {"native_attachAuxEffect", "(I)I", (void *)android_media_AudioTrack_attachAuxEffect}, {"native_setOutputDevice", "(I)Z", (void *)android_media_AudioTrack_setOutputDevice}, {"native_getRoutedDeviceId", "()I", (void *)android_media_AudioTrack_getRoutedDeviceId}, {"native_getRoutedDeviceIds", "()[I", (void *)android_media_AudioTrack_getRoutedDeviceIds}, {"native_enableDeviceCallback", "()V", (void *)android_media_AudioTrack_enableDeviceCallback}, {"native_disableDeviceCallback", "()V", Loading
core/jni/android_media_DeviceCallback.cpp +7 −8 Original line number Diff line number Diff line Loading @@ -61,21 +61,20 @@ JNIDeviceCallback::~JNIDeviceCallback() } void JNIDeviceCallback::onAudioDeviceUpdate(audio_io_handle_t audioIo, audio_port_handle_t deviceId) { const DeviceIdVector& deviceIds) { JNIEnv *env = AndroidRuntime::getJNIEnv(); if (env == NULL) { return; } ALOGV("%s audioIo %d deviceId %d", __FUNCTION__, audioIo, deviceId); env->CallStaticVoidMethod(mClass, mPostEventFromNative, mObject, AUDIO_NATIVE_EVENT_ROUTING_CHANGE, deviceId, 0, NULL); ALOGV("%s audioIo %d deviceIds %s", __FUNCTION__, audioIo, toString(deviceIds).c_str()); // Java should query the new device ids once it gets the event. // TODO(b/378505346): Pass the deviceIds to Java to avoid race conditions. env->CallStaticVoidMethod(mClass, mPostEventFromNative, mObject, AUDIO_NATIVE_EVENT_ROUTING_CHANGE, 0 /*arg1*/, 0 /*arg2*/, NULL /*obj*/); if (env->ExceptionCheck()) { ALOGW("An exception occurred while notifying an event."); env->ExceptionClear(); } }
core/jni/android_media_DeviceCallback.h +1 −2 Original line number Diff line number Diff line Loading @@ -31,8 +31,7 @@ public: JNIDeviceCallback(JNIEnv* env, jobject thiz, jobject weak_thiz, jmethodID postEventFromNative); ~JNIDeviceCallback(); virtual void onAudioDeviceUpdate(audio_io_handle_t audioIo, audio_port_handle_t deviceId); virtual void onAudioDeviceUpdate(audio_io_handle_t audioIo, const DeviceIdVector& deviceIds); private: void sendEvent(int event); Loading
media/java/android/media/AudioPlaybackConfiguration.java +41 −26 Original line number Diff line number Diff line Loading @@ -41,6 +41,7 @@ import java.io.PrintWriter; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Objects; Loading @@ -59,6 +60,8 @@ public final class AudioPlaybackConfiguration implements Parcelable { public static final int PLAYER_UPID_INVALID = -1; /** @hide */ public static final int PLAYER_DEVICEID_INVALID = 0; /** @hide */ public static final int[] PLAYER_DEVICEIDS_INVALID = new int[0]; // information about the implementation /** Loading Loading @@ -335,7 +338,7 @@ public final class AudioPlaybackConfiguration implements Parcelable { private final Object mUpdateablePropLock = new Object(); @GuardedBy("mUpdateablePropLock") private int mDeviceId; private @NonNull int[] mDeviceIds = AudioPlaybackConfiguration.PLAYER_DEVICEIDS_INVALID; @GuardedBy("mUpdateablePropLock") private int mSessionId; @GuardedBy("mUpdateablePropLock") Loading Loading @@ -364,7 +367,7 @@ public final class AudioPlaybackConfiguration implements Parcelable { mClientUid = uid; mClientPid = pid; mMutedState = 0; mDeviceId = PLAYER_DEVICEID_INVALID; mDeviceIds = AudioPlaybackConfiguration.PLAYER_DEVICEIDS_INVALID; mPlayerState = PLAYER_STATE_IDLE; mPlayerAttr = pic.mAttributes; if ((sPlayerDeathMonitor != null) && (pic.mIPlayer != null)) { Loading @@ -388,10 +391,11 @@ public final class AudioPlaybackConfiguration implements Parcelable { } // sets the fields that are updateable and require synchronization private void setUpdateableFields(int deviceId, int sessionId, int mutedState, FormatInfo format) private void setUpdateableFields(int[] deviceIds, int sessionId, int mutedState, FormatInfo format) { synchronized (mUpdateablePropLock) { mDeviceId = deviceId; mDeviceIds = deviceIds; mSessionId = sessionId; mMutedState = mutedState; mFormatInfo = format; Loading Loading @@ -427,7 +431,7 @@ public final class AudioPlaybackConfiguration implements Parcelable { anonymCopy.mClientPid = PLAYER_UPID_INVALID; anonymCopy.mIPlayerShell = null; anonymCopy.setUpdateableFields( /*deviceId*/ PLAYER_DEVICEID_INVALID, /*deviceIds*/ new int[0], /*sessionId*/ AudioSystem.AUDIO_SESSION_ALLOCATE, /*mutedState*/ 0, FormatInfo.DEFAULT); Loading Loading @@ -471,14 +475,14 @@ public final class AudioPlaybackConfiguration implements Parcelable { @Deprecated @FlaggedApi(FLAG_ROUTED_DEVICE_IDS) public @Nullable AudioDeviceInfo getAudioDeviceInfo() { final int deviceId; final int[] deviceIds; synchronized (mUpdateablePropLock) { deviceId = mDeviceId; deviceIds = mDeviceIds; } if (deviceId == PLAYER_DEVICEID_INVALID) { if (deviceIds.length == 0) { return null; } return AudioManager.getDeviceForPortId(deviceId, AudioManager.GET_DEVICES_OUTPUTS); return AudioManager.getDeviceForPortId(deviceIds[0], AudioManager.GET_DEVICES_OUTPUTS); } /** Loading @@ -491,10 +495,18 @@ public final class AudioPlaybackConfiguration implements Parcelable { @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public @NonNull List<AudioDeviceInfo> getAudioDeviceInfos() { List<AudioDeviceInfo> audioDeviceInfos = new ArrayList<AudioDeviceInfo>(); AudioDeviceInfo audioDeviceInfo = getAudioDeviceInfo(); final int[] deviceIds; synchronized (mUpdateablePropLock) { deviceIds = mDeviceIds; } for (int i = 0; i < deviceIds.length; i++) { AudioDeviceInfo audioDeviceInfo = AudioManager.getDeviceForPortId(deviceIds[i], AudioManager.GET_DEVICES_OUTPUTS); if (audioDeviceInfo != null) { audioDeviceInfos.add(audioDeviceInfo); } } return audioDeviceInfos; } Loading Loading @@ -701,15 +713,15 @@ public final class AudioPlaybackConfiguration implements Parcelable { * @hide * Handle a player state change * @param event * @param deviceId active device id or {@Code PLAYER_DEVICEID_INVALID} * <br>Note device id is valid for {@code PLAYER_UPDATE_DEVICE_ID} or * <br>{@code PLAYER_STATE_STARTED} events, as the device id will be reset to none when * <br>pausing or stopping playback. It will be set to active device when playback starts or * @param deviceIds an array of device ids. This can be empty. * <br>Note device ids are non-empty for {@code PLAYER_UPDATE_DEVICE_ID} or * <br>{@code PLAYER_STATE_STARTED} events, as the device ids will be emptied when pausing * <br>or stopping playback. It will be set to active devices when playback starts or * <br>it will be changed when PLAYER_UPDATE_DEVICE_ID is sent. The latter can happen if the * <br>device changes in the middle of playback. * <br>devices change in the middle of playback. * @return true if the state changed, false otherwise */ public boolean handleStateEvent(int event, int deviceId) { public boolean handleStateEvent(int event, int[] deviceIds) { boolean changed = false; synchronized (mUpdateablePropLock) { Loading @@ -720,8 +732,8 @@ public final class AudioPlaybackConfiguration implements Parcelable { } if (event == PLAYER_STATE_STARTED || event == PLAYER_UPDATE_DEVICE_ID) { changed = changed || (mDeviceId != deviceId); mDeviceId = deviceId; changed = changed || !Arrays.equals(mDeviceIds, deviceIds); mDeviceIds = deviceIds; } if (changed && (event == PLAYER_STATE_RELEASED) && (mIPlayerShell != null)) { Loading Loading @@ -801,8 +813,8 @@ public final class AudioPlaybackConfiguration implements Parcelable { @Override public int hashCode() { synchronized (mUpdateablePropLock) { return Objects.hash(mPlayerIId, mDeviceId, mMutedState, mPlayerType, mClientUid, mClientPid, mSessionId); return Objects.hash(mPlayerIId, Arrays.toString(mDeviceIds), mMutedState, mPlayerType, mClientUid, mClientPid, mSessionId); } } Loading @@ -815,7 +827,7 @@ public final class AudioPlaybackConfiguration implements Parcelable { public void writeToParcel(Parcel dest, int flags) { synchronized (mUpdateablePropLock) { dest.writeInt(mPlayerIId); dest.writeInt(mDeviceId); dest.writeIntArray(mDeviceIds); dest.writeInt(mMutedState); dest.writeInt(mPlayerType); dest.writeInt(mClientUid); Loading @@ -834,7 +846,10 @@ public final class AudioPlaybackConfiguration implements Parcelable { private AudioPlaybackConfiguration(Parcel in) { mPlayerIId = in.readInt(); mDeviceId = in.readInt(); mDeviceIds = new int[in.readInt()]; for (int i = 0; i < mDeviceIds.length; i++) { mDeviceIds[i] = in.readInt(); } mMutedState = in.readInt(); mPlayerType = in.readInt(); mClientUid = in.readInt(); Loading @@ -855,7 +870,7 @@ public final class AudioPlaybackConfiguration implements Parcelable { AudioPlaybackConfiguration that = (AudioPlaybackConfiguration) o; return ((mPlayerIId == that.mPlayerIId) && (mDeviceId == that.mDeviceId) && Arrays.equals(mDeviceIds, that.mDeviceIds) && (mMutedState == that.mMutedState) && (mPlayerType == that.mPlayerType) && (mClientUid == that.mClientUid) Loading @@ -868,7 +883,7 @@ public final class AudioPlaybackConfiguration implements Parcelable { StringBuilder apcToString = new StringBuilder(); synchronized (mUpdateablePropLock) { apcToString.append("AudioPlaybackConfiguration piid:").append(mPlayerIId).append( " deviceId:").append(mDeviceId).append(" type:").append( " deviceIds:").append(Arrays.toString(mDeviceIds)).append(" type:").append( toLogFriendlyPlayerType(mPlayerType)).append(" u/pid:").append( mClientUid).append( "/").append(mClientPid).append(" state:").append( Loading