Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3e575e58 authored by jiabin's avatar jiabin
Browse files

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
parent f36c575b
Loading
Loading
Loading
Loading
+21 −0
Original line number Diff line number Diff line
@@ -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);
+1 −24
Original line number Diff line number Diff line
@@ -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());
    }

    /**