diff options
| -rw-r--r-- | core/api/current.txt | 1 | ||||
| -rw-r--r-- | core/jni/android_media_AudioSystem.cpp | 54 | ||||
| -rw-r--r-- | media/java/android/media/AudioManager.java | 48 | ||||
| -rw-r--r-- | media/java/android/media/AudioSystem.java | 3 |
4 files changed, 106 insertions, 0 deletions
diff --git a/core/api/current.txt b/core/api/current.txt index 0ab93b82b441..cf5a261f583d 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -21194,6 +21194,7 @@ package android.media { method public int getStreamMinVolume(int); method public int getStreamVolume(int); method public float getStreamVolumeDb(int, int, int); + method @FlaggedApi("android.media.audio.supported_device_types_api") @NonNull public java.util.Set<java.lang.Integer> getSupportedDeviceTypes(int); method @NonNull public java.util.List<android.media.AudioMixerAttributes> getSupportedMixerAttributes(@NonNull android.media.AudioDeviceInfo); method @Deprecated public int getVibrateSetting(int); method public int getVolumeGroupIdForAttributes(@NonNull android.media.AudioAttributes); diff --git a/core/jni/android_media_AudioSystem.cpp b/core/jni/android_media_AudioSystem.cpp index 3413ededb889..969e47b6a803 100644 --- a/core/jni/android_media_AudioSystem.cpp +++ b/core/jni/android_media_AudioSystem.cpp @@ -25,6 +25,7 @@ #include <android_os_Parcel.h> #include <audiomanager/AudioManager.h> #include <jni.h> +#include <media/AidlConversion.h> #include <media/AudioContainers.h> #include <media/AudioPolicy.h> #include <media/AudioSystem.h> @@ -66,6 +67,11 @@ static struct { jmethodID toArray; } gArrayListMethods; +static jclass gIntArrayClass; +static struct { + jmethodID add; +} gIntArrayMethods; + static jclass gBooleanClass; static jmethodID gBooleanCstor; @@ -1607,6 +1613,48 @@ android_media_AudioSystem_listAudioPorts(JNIEnv *env, jobject clazz, return jStatus; } +// From AudioDeviceInfo +static const int GET_DEVICES_INPUTS = 0x0001; +static const int GET_DEVICES_OUTPUTS = 0x0002; + +static int android_media_AudioSystem_getSupportedDeviceTypes(JNIEnv *env, jobject clazz, + jint direction, jobject jDeviceTypes) { + if (jDeviceTypes == NULL) { + ALOGE("%s NULL Device Types IntArray", __func__); + return AUDIO_JAVA_BAD_VALUE; + } + if (!env->IsInstanceOf(jDeviceTypes, gIntArrayClass)) { + ALOGE("%s not an IntArray", __func__); + return AUDIO_JAVA_BAD_VALUE; + } + + // Convert AudioManager.GET_DEVICES_ flags to AUDIO_PORT_ROLE_ constants + audio_port_role_t role; + if (direction == GET_DEVICES_INPUTS) { + role = AUDIO_PORT_ROLE_SOURCE; + } else if (direction == GET_DEVICES_OUTPUTS) { + role = AUDIO_PORT_ROLE_SINK; + } else { + ALOGE("%s invalid direction : 0x%X", __func__, direction); + return AUDIO_JAVA_BAD_VALUE; + } + + std::vector<media::AudioPortFw> deviceList; + AudioSystem::listDeclaredDevicePorts(static_cast<media::AudioPortRole>(role), &deviceList); + + // Walk the device list + for (const auto &device : deviceList) { + ConversionResult<audio_port_v7> result = aidl2legacy_AudioPortFw_audio_port_v7(device); + + struct audio_port_v7 port = VALUE_OR_RETURN_STATUS(result); + assert(port.type == AUDIO_PORT_TYPE_DEVICE); + + env->CallVoidMethod(jDeviceTypes, gIntArrayMethods.add, port.ext.device.type); + } + + return AUDIO_JAVA_SUCCESS; +} + static int android_media_AudioSystem_createAudioPatch(JNIEnv *env, jobject clazz, jobjectArray jPatches, jobjectArray jSources, jobjectArray jSinks) @@ -3184,6 +3232,8 @@ static const JNINativeMethod gMethods[] = android_media_AudioSystem_setAudioFlingerBinder), MAKE_JNI_NATIVE_METHOD("listAudioPorts", "(Ljava/util/ArrayList;[I)I", android_media_AudioSystem_listAudioPorts), + MAKE_JNI_NATIVE_METHOD("getSupportedDeviceTypes", "(ILandroid/util/IntArray;)I", + android_media_AudioSystem_getSupportedDeviceTypes), MAKE_JNI_NATIVE_METHOD("createAudioPatch", "([Landroid/media/AudioPatch;[Landroid/media/" "AudioPortConfig;[Landroid/media/AudioPortConfig;)I", @@ -3325,6 +3375,10 @@ int register_android_media_AudioSystem(JNIEnv *env) gArrayListMethods.add = GetMethodIDOrDie(env, arrayListClass, "add", "(Ljava/lang/Object;)Z"); gArrayListMethods.toArray = GetMethodIDOrDie(env, arrayListClass, "toArray", "()[Ljava/lang/Object;"); + jclass intArrayClass = FindClassOrDie(env, "android/util/IntArray"); + gIntArrayClass = MakeGlobalRefOrDie(env, intArrayClass); + gIntArrayMethods.add = GetMethodIDOrDie(env, gIntArrayClass, "add", "(I)V"); + jclass booleanClass = FindClassOrDie(env, "java/lang/Boolean"); gBooleanClass = MakeGlobalRefOrDie(env, booleanClass); gBooleanCstor = GetMethodIDOrDie(env, booleanClass, "<init>", "(Z)V"); diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java index 4918289e8b5c..69708ecde281 100644 --- a/media/java/android/media/AudioManager.java +++ b/media/java/android/media/AudioManager.java @@ -23,6 +23,7 @@ import static android.media.audio.Flags.autoPublicVolumeApiHardening; import static android.media.audio.Flags.automaticBtDeviceType; import static android.media.audio.Flags.FLAG_FOCUS_EXCLUSIVE_WITH_RECORDING; import static android.media.audio.Flags.FLAG_FOCUS_FREEZE_TEST_API; +import static android.media.audio.Flags.FLAG_SUPPORTED_DEVICE_TYPES_API; import static android.media.audiopolicy.Flags.FLAG_ENABLE_FADE_MANAGER_CONFIGURATION; import android.Manifest; @@ -80,6 +81,7 @@ import android.os.UserHandle; import android.provider.Settings; import android.text.TextUtils; import android.util.ArrayMap; +import android.util.IntArray; import android.util.Log; import android.util.Pair; import android.view.KeyEvent; @@ -100,6 +102,7 @@ import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Objects; +import java.util.Set; import java.util.TreeMap; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.Executor; @@ -7838,6 +7841,51 @@ public class AudioManager { } /** + * Returns a Set of unique Integers corresponding to audio device type identifiers that can + * <i>potentially</i> be connected to the system and meeting the criteria specified in the + * <code>direction</code> parameter. + * Note that this set contains {@link AudioDeviceInfo} device type identifiers for both devices + * currently available <i>and</i> those that can be available if the user connects an audio + * peripheral. Examples include TYPE_WIRED_HEADSET if the Android device supports an analog + * headset jack or TYPE_USB_DEVICE if the Android device supports a USB host-mode port. + * These are generally a superset of device type identifiers associated with the + * AudioDeviceInfo objects returned from AudioManager.getDevices(). + * @param direction The constant specifying whether input or output devices are queried. + * @see #GET_DEVICES_OUTPUTS + * @see #GET_DEVICES_INPUTS + * @return A (possibly zero-length) Set of Integer objects corresponding to the audio + * device types of devices supported by the implementation. + * @throws IllegalArgumentException If an invalid direction constant is specified. + */ + @FlaggedApi(FLAG_SUPPORTED_DEVICE_TYPES_API) + public @NonNull Set<Integer> + getSupportedDeviceTypes(int direction) { + if (direction != GET_DEVICES_OUTPUTS && direction != GET_DEVICES_INPUTS) { + throw new IllegalArgumentException("AudioManager.getSupportedDeviceTypes(" + + Integer.toHexString(direction) + ") - Invalid."); + } + + IntArray internalDeviceTypes = new IntArray(); + int status = AudioSystem.getSupportedDeviceTypes(direction, internalDeviceTypes); + if (status != AudioManager.SUCCESS) { + Log.e(TAG, "AudioManager.getSupportedDeviceTypes(" + direction + ") failed. status:" + + status); + } + + // convert to external (AudioDeviceInfo.getType()) device IDs + HashSet<Integer> externalDeviceTypes = new HashSet<Integer>(); + for (int index = 0; index < internalDeviceTypes.size(); index++) { + // Set will eliminate any duplicates which AudioSystem.getSupportedDeviceTypes() + // returns + externalDeviceTypes.add( + AudioDeviceInfo.convertInternalDeviceToDeviceType( + internalDeviceTypes.get(index))); + } + + return externalDeviceTypes; + } + + /** * Returns an array of {@link AudioDeviceInfo} objects corresponding to the audio devices * currently connected to the system and meeting the criteria specified in the * <code>flags</code> parameter. diff --git a/media/java/android/media/AudioSystem.java b/media/java/android/media/AudioSystem.java index 0f6cbffef300..f73be35fa130 100644 --- a/media/java/android/media/AudioSystem.java +++ b/media/java/android/media/AudioSystem.java @@ -36,6 +36,7 @@ import android.os.IBinder; import android.os.Parcel; import android.os.Vibrator; import android.telephony.TelephonyManager; +import android.util.IntArray; import android.util.Log; import android.util.Pair; @@ -1947,6 +1948,8 @@ public class AudioSystem /** @hide */ public static native int listAudioPorts(ArrayList<AudioPort> ports, int[] generation); /** @hide */ + public static native int getSupportedDeviceTypes(int flags, IntArray internalDeviceTypes); + /** @hide */ public static native int createAudioPatch(AudioPatch[] patch, AudioPortConfig[] sources, AudioPortConfig[] sinks); /** @hide */ |