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

Commit 5bbfdbfb authored by Jiabin Huang's avatar Jiabin Huang Committed by Gerrit Code Review
Browse files

Merge "Add AudioTransport to replace AudioProfile in AudioPort."

parents 38b3bcee 574a86fa
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -155,6 +155,12 @@ package android.audio.policy.configuration.V7_0 {
    enum_constant public static final android.audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_WIRED_HEADSET;
  }

  public enum AudioEncapsulationType {
    method @NonNull public String getRawName();
    enum_constant public static final android.audio.policy.configuration.V7_0.AudioEncapsulationType AUDIO_ENCAPSULATION_TYPE_IEC61937;
    enum_constant public static final android.audio.policy.configuration.V7_0.AudioEncapsulationType AUDIO_ENCAPSULATION_TYPE_NONE;
  }

  public enum AudioFormat {
    method @NonNull public String getRawName();
    enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_AAC;
@@ -487,10 +493,12 @@ package android.audio.policy.configuration.V7_0 {
  public class Profile {
    ctor public Profile();
    method @Nullable public java.util.List<android.audio.policy.configuration.V7_0.AudioChannelMask> getChannelMasks();
    method @Nullable public android.audio.policy.configuration.V7_0.AudioEncapsulationType getEncapsulationType();
    method @Nullable public String getFormat();
    method @Nullable public String getName();
    method @Nullable public java.util.List<java.math.BigInteger> getSamplingRates();
    method public void setChannelMasks(@Nullable java.util.List<android.audio.policy.configuration.V7_0.AudioChannelMask>);
    method public void setEncapsulationType(@Nullable android.audio.policy.configuration.V7_0.AudioEncapsulationType);
    method public void setFormat(@Nullable String);
    method public void setName(@Nullable String);
    method public void setSamplingRates(@Nullable java.util.List<java.math.BigInteger>);
+7 −0
Original line number Diff line number Diff line
@@ -550,11 +550,18 @@
    <xs:simpleType name="channelMasks">
        <xs:list itemType="audioChannelMask" />
    </xs:simpleType>
    <xs:simpleType name="audioEncapsulationType">
        <xs:restriction base="xs:string">
            <xs:enumeration value="AUDIO_ENCAPSULATION_TYPE_NONE"/>
            <xs:enumeration value="AUDIO_ENCAPSULATION_TYPE_IEC61937"/>
        </xs:restriction>
    </xs:simpleType>
    <xs:complexType name="profile">
        <xs:attribute name="name" type="xs:token" use="optional"/>
        <xs:attribute name="format" type="extendableAudioFormat" use="optional"/>
        <xs:attribute name="samplingRates" type="samplingRates" use="optional"/>
        <xs:attribute name="channelMasks" type="channelMasks" use="optional"/>
        <xs:attribute name="encapsulationType" type="audioEncapsulationType" use="optional"/>
    </xs:complexType>
    <xs:simpleType name="audioGainMode">
        <xs:restriction base="xs:string">
+4 −0
Original line number Diff line number Diff line
@@ -287,6 +287,10 @@ static inline bool isLinearPcm(const std::string& format) {
    return isLinearPcm(stringToAudioFormat(format));
}

static inline bool isUnknownAudioEncapsulationType(const std::string& encapsulationType) {
    return stringToAudioEncapsulationType(encapsulationType) == AudioEncapsulationType::UNKNOWN;
}

}  // namespace android::audio::policy::configuration::V7_0

#endif  // ANDROID_AUDIO_POLICY_CONFIGURATION_V7_0__ENUMS_H
+43 −2
Original line number Diff line number Diff line
@@ -144,6 +144,14 @@ struct AudioConfigBaseOptional {
    } channelMask;
};

/**
 * Audio encapsulation type indicates the encapsulation type that is required
 * for playback/capture.
 * See 'audioEncapsulationType' in audio_policy_configuration.xsd for the list
 * of allowed values.
 */
typedef string AudioEncapsulationType;

/**
 * Configurations supported for a certain audio format.
 */
@@ -155,6 +163,35 @@ struct AudioProfile {
    vec<AudioChannelMask> channelMasks;
};

/**
 * AudioTransport struct describes the capability of an audio port. The
 * capability is described via AudioProfile or raw hardware descriptors for
 * for formats that are not supported by the platform.
 */
struct AudioTransport {
    safe_union AudioCapability {
        /**
         * A certain audio format that is known by the platform and its
         * corresponding configuration.
         */
        AudioProfile profile;
        /**
         * The audio descriptor that is reported from EDID. See HDMI
         * specification 1.4b section 7 and CEA-861-G section 7.5.2 for more
         * information. When this value is set, it indicates the standard is
         * AUDIO_STANDARD_EDID.
         */
        vec<uint8_t> edid;
    } audioCapability;

    /**
     * The encapsulation type that is required when the framework is using this
     * format when playing or capturing to/from a stream or device exposing this
     * audio transport.
     */
    AudioEncapsulationType encapsulationType;
};

/**
 * Major modes for a mobile device. The current mode setting affects audio
 * routing.
@@ -488,8 +525,12 @@ struct AudioPort {
     * E.g. "telephony_tx" or "fm_tuner".
     */
    string name;
    /** List of audio profiles supported by the port. */
    vec<AudioProfile> profiles;
    /**
     * List of audio transports supported by the audio port. This includes
     * supported formats and raw hardware descriptors for formats not supported
     * by the platform.
     */
    vec<AudioTransport> transports;
    /** List of gain controls attached to the port. */
    vec<AudioGain> gains;
    /** Parameters that depend on the actual port role. */
+127 −14
Original line number Diff line number Diff line
@@ -715,6 +715,27 @@ status_t HidlUtils::audioPortExtendedInfoToHal(const AudioPortExtendedInfo& ext,
    return result;
}

status_t HidlUtils::encapsulationTypeFromHal(audio_encapsulation_type_t halEncapsulationType,
                                             AudioEncapsulationType* encapsulationType) {
    *encapsulationType = audio_encapsulation_type_to_string(halEncapsulationType);
    if (!encapsulationType->empty() && !xsd::isUnknownAudioEncapsulationType(*encapsulationType)) {
        return NO_ERROR;
    }
    ALOGE("Unknown audio encapsulation type value 0x%X", halEncapsulationType);
    return BAD_VALUE;
}

status_t HidlUtils::encapsulationTypeToHal(const AudioEncapsulationType& encapsulationType,
                                           audio_encapsulation_type_t* halEncapsulationType) {
    if (!xsd::isUnknownAudioEncapsulationType(encapsulationType) &&
        audio_encapsulation_type_from_string(encapsulationType.c_str(), halEncapsulationType)) {
        return NO_ERROR;
    }
    ALOGE("Unknown audio encapsulation type \"%s\"", encapsulationType.c_str());
    *halEncapsulationType = AUDIO_ENCAPSULATION_TYPE_NONE;
    return BAD_VALUE;
}

status_t HidlUtils::audioPortFromHal(const struct audio_port& halPort, AudioPort* port) {
    struct audio_port_v7 halPortV7 = {};
    audio_populate_audio_port_v7(&halPort, &halPortV7);
@@ -758,11 +779,7 @@ status_t HidlUtils::audioPortFromHal(const struct audio_port_v7& halPort, AudioP
    CONVERT_CHECKED(audioPortExtendedInfoFromHal(halPort.role, halPort.type, halDevice, halMix,
                                                 halSession, &port->ext, &isInput),
                    result);
    port->profiles.resize(halPort.num_audio_profiles);
    for (size_t i = 0; i < halPort.num_audio_profiles; ++i) {
        CONVERT_CHECKED(audioProfileFromHal(halPort.audio_profiles[i], isInput, &port->profiles[i]),
                        result);
    }
    CONVERT_CHECKED(audioTransportsFromHal(halPort, isInput, &port->transports), result);
    port->gains.resize(halPort.num_gains);
    for (size_t i = 0; i < halPort.num_gains; ++i) {
        CONVERT_CHECKED(audioGainFromHal(halPort.gains[i], isInput, &port->gains[i]), result);
@@ -780,15 +797,7 @@ status_t HidlUtils::audioPortToHal(const AudioPort& port, struct audio_port_v7*
        ALOGE("HIDL Audio Port name is too long: %zu", port.name.size());
        result = BAD_VALUE;
    }
    halPort->num_audio_profiles = port.profiles.size();
    if (halPort->num_audio_profiles > AUDIO_PORT_MAX_AUDIO_PROFILES) {
        ALOGE("HIDL Audio Port has too many profiles: %u", halPort->num_audio_profiles);
        halPort->num_audio_profiles = AUDIO_PORT_MAX_AUDIO_PROFILES;
        result = BAD_VALUE;
    }
    for (size_t i = 0; i < halPort->num_audio_profiles; ++i) {
        CONVERT_CHECKED(audioProfileToHal(port.profiles[i], &halPort->audio_profiles[i]), result);
    }
    CONVERT_CHECKED(audioTransportsToHal(port.transports, halPort), result);
    halPort->num_gains = port.gains.size();
    if (halPort->num_gains > AUDIO_PORT_MAX_GAINS) {
        ALOGE("HIDL Audio Port has too many gains: %u", halPort->num_gains);
@@ -824,6 +833,110 @@ status_t HidlUtils::audioPortToHal(const AudioPort& port, struct audio_port_v7*
    return result;
}

status_t HidlUtils::audioTransportsFromHal(const struct audio_port_v7& halPort, bool isInput,
                                           hidl_vec<AudioTransport>* transports) {
    if (halPort.num_audio_profiles > AUDIO_PORT_MAX_AUDIO_PROFILES ||
        halPort.num_extra_audio_descriptors > AUDIO_PORT_MAX_EXTRA_AUDIO_DESCRIPTORS) {
        ALOGE("%s, too many audio profiles(%u) or extra audio descriptors(%u)", __func__,
              halPort.num_audio_profiles, halPort.num_extra_audio_descriptors);
        return BAD_VALUE;
    }
    status_t result = NO_ERROR;
    transports->resize(halPort.num_audio_profiles + halPort.num_extra_audio_descriptors);
    size_t idx = 0;
    for (size_t i = 0; i < halPort.num_audio_profiles; ++i) {
        auto& transport = (*transports)[idx++];
        transport.audioCapability.profile({});
        CONVERT_CHECKED(audioProfileFromHal(halPort.audio_profiles[i], isInput,
                                            &transport.audioCapability.profile()),
                        result);
        CONVERT_CHECKED(encapsulationTypeFromHal(halPort.audio_profiles[i].encapsulation_type,
                                                 &transport.encapsulationType),
                        result);
    }
    for (size_t i = 0; i < halPort.num_extra_audio_descriptors; ++i) {
        switch (halPort.extra_audio_descriptors[i].standard) {
            case AUDIO_STANDARD_EDID: {
                const struct audio_extra_audio_descriptor* extraAudioDescriptor =
                        &halPort.extra_audio_descriptors[i];
                if (extraAudioDescriptor->descriptor_length <= EXTRA_AUDIO_DESCRIPTOR_SIZE) {
                    auto& transport = (*transports)[idx++];
                    transport.audioCapability.edid(
                            hidl_vec<uint8_t>(extraAudioDescriptor->descriptor,
                                              extraAudioDescriptor->descriptor +
                                                      extraAudioDescriptor->descriptor_length));
                    CONVERT_CHECKED(
                            encapsulationTypeFromHal(extraAudioDescriptor->encapsulation_type,
                                                     &transport.encapsulationType),
                            result);
                } else {
                    ALOGE("%s, invalid descriptor length %u", __func__,
                          extraAudioDescriptor->descriptor_length);
                    result = BAD_VALUE;
                }
            } break;
            case AUDIO_STANDARD_NONE:
            default:
                ALOGE("%s, invalid standard %u", __func__,
                      halPort.extra_audio_descriptors[i].standard);
                result = BAD_VALUE;
                break;
        }
    }
    return result;
}

status_t HidlUtils::audioTransportsToHal(const hidl_vec<AudioTransport>& transports,
                                         struct audio_port_v7* halPort) {
    status_t result = NO_ERROR;
    halPort->num_audio_profiles = 0;
    halPort->num_extra_audio_descriptors = 0;
    for (const auto& transport : transports) {
        switch (transport.audioCapability.getDiscriminator()) {
            case AudioTransport::AudioCapability::hidl_discriminator::profile:
                if (halPort->num_audio_profiles > AUDIO_PORT_MAX_AUDIO_PROFILES) {
                    ALOGE("%s, too many audio profiles", __func__);
                    result = BAD_VALUE;
                    break;
                }
                CONVERT_CHECKED(
                        audioProfileToHal(transport.audioCapability.profile(),
                                          &halPort->audio_profiles[halPort->num_audio_profiles]),
                        result);
                CONVERT_CHECKED(encapsulationTypeToHal(
                                        transport.encapsulationType,
                                        &halPort->audio_profiles[halPort->num_audio_profiles++]
                                                 .encapsulation_type),
                                result);
                break;
            case AudioTransport::AudioCapability::hidl_discriminator::edid:
                if (halPort->num_extra_audio_descriptors > AUDIO_PORT_MAX_EXTRA_AUDIO_DESCRIPTORS) {
                    ALOGE("%s, too many extra audio descriptors", __func__);
                    result = BAD_VALUE;
                    break;
                }
                if (transport.audioCapability.edid().size() > EXTRA_AUDIO_DESCRIPTOR_SIZE) {
                    ALOGE("%s, wrong edid size %zu", __func__,
                          transport.audioCapability.edid().size());
                    result = BAD_VALUE;
                    break;
                }
                struct audio_extra_audio_descriptor* extraAudioDescriptor =
                        &halPort->extra_audio_descriptors[halPort->num_extra_audio_descriptors++];
                extraAudioDescriptor->standard = AUDIO_STANDARD_EDID;
                extraAudioDescriptor->descriptor_length = transport.audioCapability.edid().size();
                memcpy(extraAudioDescriptor->descriptor, transport.audioCapability.edid().data(),
                       transport.audioCapability.edid().size() * sizeof(uint8_t));

                CONVERT_CHECKED(encapsulationTypeToHal(transport.encapsulationType,
                                                       &extraAudioDescriptor->encapsulation_type),
                                result);
                break;
        }
    }
    return result;
}

status_t HidlUtils::audioProfileFromHal(const struct audio_profile& halProfile, bool isInput,
                                        AudioProfile* profile) {
    status_t result = NO_ERROR;
Loading