Add PCM float profile if extended precision PCM shows but not pcm float.

This is required for backwards compatibility. This ensures pre-S apps
that look for pcm float continue to see that encoding if the device
supports extended precision integers.

Test: atest AudioManagerTest
Bug: 193747274
Change-Id: Ia244bdcd51520dd082a292baab54f1795ccccaea
This commit is contained in:
jiabin
2021-07-15 14:53:31 -07:00
parent f36c575bee
commit 3e575e58cc
2 changed files with 22 additions and 24 deletions

View File

@@ -1242,6 +1242,8 @@ static jint convertAudioPortFromNative(JNIEnv *env, jobject *jAudioPort,
jstring jDeviceName = NULL;
jobject jAudioProfiles = NULL;
jobject jAudioDescriptors = nullptr;
ScopedLocalRef<jobject> jPcmFloatProfileFromExtendedInteger(env, nullptr);
bool hasFloat = false;
bool useInMask;
ALOGV("convertAudioPortFromNative id %d role %d type %d name %s",
@@ -1338,6 +1340,25 @@ static jint convertAudioPortFromNative(JNIEnv *env, jobject *jAudioPort,
goto exit;
}
env->CallBooleanMethod(jAudioProfiles, gArrayListMethods.add, jAudioProfile.get());
if (nAudioPort->audio_profiles[i].format == AUDIO_FORMAT_PCM_FLOAT) {
hasFloat = true;
} else if (jPcmFloatProfileFromExtendedInteger.get() == nullptr &&
audio_is_linear_pcm(nAudioPort->audio_profiles[i].format) &&
audio_bytes_per_sample(nAudioPort->audio_profiles[i].format) > 2) {
jPcmFloatProfileFromExtendedInteger.reset(
env->NewObject(gAudioProfileClass, gAudioProfileCstor,
audioFormatFromNative(AUDIO_FORMAT_PCM_FLOAT),
jSamplingRates.get(), jChannelMasks.get(),
jChannelIndexMasks.get(), encapsulationType));
}
}
if (!hasFloat && jPcmFloatProfileFromExtendedInteger.get() != nullptr) {
// R and earlier compatibility - add ENCODING_PCM_FLOAT to the end
// (replacing the zero pad). This ensures pre-S apps that look
// for ENCODING_PCM_FLOAT continue to see that encoding if the device supports
// extended precision integers.
env->CallBooleanMethod(jAudioProfiles, gArrayListMethods.add,
jPcmFloatProfileFromExtendedInteger.get());
}
jAudioDescriptors = env->NewObject(gArrayListClass, gArrayListMethods.cstor);

View File

@@ -25,7 +25,6 @@ import android.util.SparseIntArray;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.TreeSet;
@@ -515,29 +514,7 @@ public final class AudioDeviceInfo {
* For forward compatibility, applications should ignore entries it does not recognize.
*/
public @NonNull int[] getEncodings() {
final int[] encodings = AudioFormat.filterPublicFormats(mPort.formats());
boolean hasFloat = false;
boolean hasExtendedIntegerPrecision = false;
for (int encoding : encodings) {
if (AudioFormat.isEncodingLinearPcm(encoding)) {
if (encoding == AudioFormat.ENCODING_PCM_FLOAT) {
hasFloat = true;
} else if (AudioFormat.getBytesPerSample(encoding) > 2) {
hasExtendedIntegerPrecision = true;
}
}
}
if (hasExtendedIntegerPrecision && !hasFloat) {
// R and earlier compatibility - add ENCODING_PCM_FLOAT to the end
// (replacing the zero pad). This ensures pre-S apps that look
// for ENCODING_PCM_FLOAT continue to see that encoding if the device supports
// extended precision integers.
int[] encodingsPlusFloat = Arrays.copyOf(encodings, encodings.length + 1);
encodingsPlusFloat[encodings.length] = AudioFormat.ENCODING_PCM_FLOAT;
return encodingsPlusFloat;
}
return encodings;
return AudioFormat.filterPublicFormats(mPort.formats());
}
/**