Merge "Add getDirectProfilesForAttributes"
This commit is contained in:
committed by
Android (Google) Code Review
commit
8981d131ca
@@ -19859,6 +19859,7 @@ package android.media {
|
||||
method @Nullable public android.media.AudioDeviceInfo getCommunicationDevice();
|
||||
method public android.media.AudioDeviceInfo[] getDevices(int);
|
||||
method public static int getDirectPlaybackSupport(@NonNull android.media.AudioFormat, @NonNull android.media.AudioAttributes);
|
||||
method @NonNull public java.util.List<android.media.AudioProfile> getDirectProfilesForAttributes(@NonNull android.media.AudioAttributes);
|
||||
method public int getEncodedSurroundMode();
|
||||
method public java.util.List<android.media.MicrophoneInfo> getMicrophones() throws java.io.IOException;
|
||||
method public int getMode();
|
||||
|
||||
@@ -1236,6 +1236,65 @@ static bool isAudioPortArrayCountOutOfBounds(const struct audio_port_v7 *nAudioP
|
||||
return false;
|
||||
}
|
||||
|
||||
static jint convertAudioProfileFromNative(JNIEnv *env, jobject *jAudioProfile,
|
||||
const audio_profile *nAudioProfile, bool useInMask) {
|
||||
size_t numPositionMasks = 0;
|
||||
size_t numIndexMasks = 0;
|
||||
|
||||
// count up how many masks are positional and indexed
|
||||
for (size_t index = 0; index < nAudioProfile->num_channel_masks; index++) {
|
||||
const audio_channel_mask_t mask = nAudioProfile->channel_masks[index];
|
||||
if (audio_channel_mask_get_representation(mask) == AUDIO_CHANNEL_REPRESENTATION_INDEX) {
|
||||
numIndexMasks++;
|
||||
} else {
|
||||
numPositionMasks++;
|
||||
}
|
||||
}
|
||||
|
||||
ScopedLocalRef<jintArray> jSamplingRates(env,
|
||||
env->NewIntArray(nAudioProfile->num_sample_rates));
|
||||
ScopedLocalRef<jintArray> jChannelMasks(env, env->NewIntArray(numPositionMasks));
|
||||
ScopedLocalRef<jintArray> jChannelIndexMasks(env, env->NewIntArray(numIndexMasks));
|
||||
if (!jSamplingRates.get() || !jChannelMasks.get() || !jChannelIndexMasks.get()) {
|
||||
return AUDIO_JAVA_ERROR;
|
||||
}
|
||||
|
||||
if (nAudioProfile->num_sample_rates) {
|
||||
env->SetIntArrayRegion(jSamplingRates.get(), 0 /*start*/, nAudioProfile->num_sample_rates,
|
||||
(jint *)nAudioProfile->sample_rates);
|
||||
}
|
||||
|
||||
// put the masks in the output arrays
|
||||
for (size_t maskIndex = 0, posMaskIndex = 0, indexedMaskIndex = 0;
|
||||
maskIndex < nAudioProfile->num_channel_masks; maskIndex++) {
|
||||
const audio_channel_mask_t mask = nAudioProfile->channel_masks[maskIndex];
|
||||
if (audio_channel_mask_get_representation(mask) == AUDIO_CHANNEL_REPRESENTATION_INDEX) {
|
||||
jint jMask = audio_channel_mask_get_bits(mask);
|
||||
env->SetIntArrayRegion(jChannelIndexMasks.get(), indexedMaskIndex++, 1, &jMask);
|
||||
} else {
|
||||
jint jMask = useInMask ? inChannelMaskFromNative(mask) : outChannelMaskFromNative(mask);
|
||||
env->SetIntArrayRegion(jChannelMasks.get(), posMaskIndex++, 1, &jMask);
|
||||
}
|
||||
}
|
||||
|
||||
int encapsulationType;
|
||||
if (audioEncapsulationTypeFromNative(nAudioProfile->encapsulation_type, &encapsulationType) !=
|
||||
NO_ERROR) {
|
||||
ALOGW("Unknown encapsulation type for JAVA API: %u", nAudioProfile->encapsulation_type);
|
||||
}
|
||||
|
||||
*jAudioProfile =
|
||||
env->NewObject(gAudioProfileClass, gAudioProfileCstor,
|
||||
audioFormatFromNative(nAudioProfile->format), jSamplingRates.get(),
|
||||
jChannelMasks.get(), jChannelIndexMasks.get(), encapsulationType);
|
||||
|
||||
if (jAudioProfile == nullptr) {
|
||||
return AUDIO_JAVA_ERROR;
|
||||
}
|
||||
|
||||
return AUDIO_JAVA_SUCCESS;
|
||||
}
|
||||
|
||||
static jint convertAudioPortFromNative(JNIEnv *env, jobject *jAudioPort,
|
||||
const struct audio_port_v7 *nAudioPort) {
|
||||
jint jStatus = (jint)AUDIO_JAVA_SUCCESS;
|
||||
@@ -2814,6 +2873,50 @@ static jint android_media_AudioSystem_getDirectPlaybackSupport(JNIEnv *env, jobj
|
||||
return convertAudioDirectModeFromNative(directMode);
|
||||
}
|
||||
|
||||
static jint android_media_AudioSystem_getDirectProfilesForAttributes(JNIEnv *env, jobject thiz,
|
||||
jobject jAudioAttributes,
|
||||
jobject jAudioProfilesList) {
|
||||
ALOGV("getDirectProfilesForAttributes");
|
||||
|
||||
if (jAudioAttributes == nullptr) {
|
||||
ALOGE("jAudioAttributes is NULL");
|
||||
return (jint)AUDIO_JAVA_BAD_VALUE;
|
||||
}
|
||||
if (jAudioProfilesList == nullptr) {
|
||||
ALOGE("jAudioProfilesList is NULL");
|
||||
return (jint)AUDIO_JAVA_BAD_VALUE;
|
||||
}
|
||||
if (!env->IsInstanceOf(jAudioProfilesList, gArrayListClass)) {
|
||||
ALOGE("jAudioProfilesList not an ArrayList");
|
||||
return (jint)AUDIO_JAVA_BAD_VALUE;
|
||||
}
|
||||
|
||||
JNIAudioAttributeHelper::UniqueAaPtr paa = JNIAudioAttributeHelper::makeUnique();
|
||||
jint jStatus = JNIAudioAttributeHelper::nativeFromJava(env, jAudioAttributes, paa.get());
|
||||
if (jStatus != (jint)AUDIO_JAVA_SUCCESS) {
|
||||
return jStatus;
|
||||
}
|
||||
|
||||
std::vector<audio_profile> audioProfiles;
|
||||
status_t status = AudioSystem::getDirectProfilesForAttributes(paa.get(), &audioProfiles);
|
||||
if (status != NO_ERROR) {
|
||||
ALOGE("AudioSystem::getDirectProfilesForAttributes error %d", status);
|
||||
jStatus = nativeToJavaStatus(status);
|
||||
return jStatus;
|
||||
}
|
||||
|
||||
for (const auto &audioProfile : audioProfiles) {
|
||||
jobject jAudioProfile;
|
||||
jStatus = convertAudioProfileFromNative(env, &jAudioProfile, &audioProfile, false);
|
||||
if (jStatus != AUDIO_JAVA_SUCCESS) {
|
||||
return jStatus;
|
||||
}
|
||||
env->CallBooleanMethod(jAudioProfilesList, gArrayListMethods.add, jAudioProfile);
|
||||
env->DeleteLocalRef(jAudioProfile);
|
||||
}
|
||||
return jStatus;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
static const JNINativeMethod gMethods[] =
|
||||
@@ -2960,7 +3063,10 @@ static const JNINativeMethod gMethods[] =
|
||||
(void *)android_media_AudioSystem_canBeSpatialized},
|
||||
{"getDirectPlaybackSupport",
|
||||
"(Landroid/media/AudioFormat;Landroid/media/AudioAttributes;)I",
|
||||
(void *)android_media_AudioSystem_getDirectPlaybackSupport}};
|
||||
(void *)android_media_AudioSystem_getDirectPlaybackSupport},
|
||||
{"getDirectProfilesForAttributes",
|
||||
"(Landroid/media/AudioAttributes;Ljava/util/ArrayList;)I",
|
||||
(void *)android_media_AudioSystem_getDirectProfilesForAttributes}};
|
||||
|
||||
static const JNINativeMethod gEventHandlerMethods[] = {
|
||||
{"native_setup",
|
||||
|
||||
@@ -7674,6 +7674,33 @@ public class AudioManager {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of direct {@link AudioProfile} that are supported for the specified
|
||||
* {@link AudioAttributes}. This can be empty in case of an error or if no direct playback
|
||||
* is possible.
|
||||
*
|
||||
* <p>Direct playback means that the audio stream is not resampled or downmixed
|
||||
* by the framework. Checking for direct support can help the app select the representation
|
||||
* of audio content that most closely matches the capabilities of the device and peripherals
|
||||
* (e.g. A/V receiver) connected to it. Note that the provided stream can still be re-encoded
|
||||
* or mixed with other streams, if needed.
|
||||
* <p>When using this information to inform your application which audio format to play,
|
||||
* query again whenever audio output devices change (see {@link AudioDeviceCallback}).
|
||||
* @param attributes a non-null {@link AudioAttributes} instance.
|
||||
* @return a list of {@link AudioProfile}
|
||||
*/
|
||||
@NonNull
|
||||
public List<AudioProfile> getDirectProfilesForAttributes(@NonNull AudioAttributes attributes) {
|
||||
Objects.requireNonNull(attributes);
|
||||
ArrayList<AudioProfile> audioProfilesList = new ArrayList<>();
|
||||
int status = AudioSystem.getDirectProfilesForAttributes(attributes, audioProfilesList);
|
||||
if (status != SUCCESS) {
|
||||
Log.w(TAG, "getDirectProfilesForAttributes failed.");
|
||||
return new ArrayList<>();
|
||||
}
|
||||
return audioProfilesList;
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
* Returns an {@link AudioDeviceInfo} corresponding to a connected device of the type provided.
|
||||
|
||||
@@ -2115,6 +2115,15 @@ public class AudioSystem
|
||||
AudioFormat format,
|
||||
AudioDeviceAttributes[] devices);
|
||||
|
||||
/**
|
||||
* @hide
|
||||
* @param attributes audio attributes describing the playback use case
|
||||
* @param audioProfilesList the list of AudioProfiles that can be played as direct output
|
||||
* @return {@link #SUCCESS} if the list of AudioProfiles was successfully created (can be empty)
|
||||
*/
|
||||
public static native int getDirectProfilesForAttributes(@NonNull AudioAttributes attributes,
|
||||
@NonNull ArrayList<AudioProfile> audioProfilesList);
|
||||
|
||||
// Items shared with audio service
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user