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

Commit 5708d191 authored by Mikhail Naganov's avatar Mikhail Naganov Committed by Gerrit Code Review
Browse files

Merge changes from topic "upstream-ag-25032627" into main

* changes:
  APM: update logic of populating profiles for dynamic mix port.
  Refresh mixer behavior when the IOProfile is constructed from parcelable.
  libaudiohal: implement supportsBluetoothVariableLatency for HIDL
parents a5083f6e 12537fc8
Loading
Loading
Loading
Loading
+28 −0
Original line number Diff line number Diff line
@@ -898,6 +898,22 @@ status_t AudioFlingerClientAdapter::getAudioPolicyConfig(media::AudioPolicyConfi
    return NO_ERROR;
}

status_t AudioFlingerClientAdapter::getAudioMixPort(const struct audio_port_v7 *devicePort,
                                                    struct audio_port_v7 *mixPort) const {
    if (devicePort == nullptr || mixPort == nullptr) {
        return BAD_VALUE;
    }
    media::AudioPortFw devicePortAidl = VALUE_OR_RETURN_STATUS(
            legacy2aidl_audio_port_v7_AudioPortFw(*devicePort));
    media::AudioPortFw mixPortAidl = VALUE_OR_RETURN_STATUS(
            legacy2aidl_audio_port_v7_AudioPortFw(*mixPort));
    media::AudioPortFw aidlRet;
    RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(
            mDelegate->getAudioMixPort(devicePortAidl, mixPortAidl, &aidlRet)));
    *mixPort = VALUE_OR_RETURN_STATUS(aidl2legacy_AudioPortFw_audio_port_v7(aidlRet));
    return OK;
}

////////////////////////////////////////////////////////////////////////////////////////////////////
// AudioFlingerServerAdapter
AudioFlingerServerAdapter::AudioFlingerServerAdapter(
@@ -1444,4 +1460,16 @@ Status AudioFlingerServerAdapter::getAudioPolicyConfig(media::AudioPolicyConfig*
    return Status::fromStatusT(mDelegate->getAudioPolicyConfig(_aidl_return));
}

Status AudioFlingerServerAdapter::getAudioMixPort(const media::AudioPortFw &devicePort,
                                                  const media::AudioPortFw &mixPort,
                                                  media::AudioPortFw *_aidl_return) {
    audio_port_v7 devicePortLegacy = VALUE_OR_RETURN_BINDER(
            aidl2legacy_AudioPortFw_audio_port_v7(devicePort));
    audio_port_v7 mixPortLegacy = VALUE_OR_RETURN_BINDER(
            aidl2legacy_AudioPortFw_audio_port_v7(mixPort));
    RETURN_BINDER_IF_ERROR(mDelegate->getAudioMixPort(&devicePortLegacy, &mixPortLegacy));
    *_aidl_return = VALUE_OR_RETURN_BINDER(legacy2aidl_audio_port_v7_AudioPortFw(mixPortLegacy));
    return Status::ok();
}

} // namespace android
+5 −0
Original line number Diff line number Diff line
@@ -288,6 +288,11 @@ interface IAudioFlingerService {
     */
    AudioPolicyConfig getAudioPolicyConfig();

    /**
     * Get the attributes of the mix port when connecting to the given device port.
     */
    AudioPortFw getAudioMixPort(in AudioPortFw devicePort, in AudioPortFw mixPort);

    // When adding a new method, please review and update
    // IAudioFlinger.h AudioFlingerServerAdapter::Delegate::TransactionCode
    // AudioFlinger.cpp AudioFlinger::onTransactWrapper()
+9 −0
Original line number Diff line number Diff line
@@ -384,6 +384,9 @@ public:
    virtual status_t supportsBluetoothVariableLatency(bool* support) const = 0;

    virtual status_t getAudioPolicyConfig(media::AudioPolicyConfig* output) = 0;

    virtual status_t getAudioMixPort(const struct audio_port_v7 *devicePort,
                                     struct audio_port_v7 *mixPort) const = 0;
};

/**
@@ -498,6 +501,8 @@ public:
                                   sp<media::ISoundDose>* soundDose) const override;
    status_t invalidateTracks(const std::vector<audio_port_handle_t>& portIds) override;
    status_t getAudioPolicyConfig(media::AudioPolicyConfig* output) override;
    status_t getAudioMixPort(const struct audio_port_v7 *devicePort,
                             struct audio_port_v7 *mixPort) const override;

private:
    const sp<media::IAudioFlingerService> mDelegate;
@@ -599,6 +604,7 @@ public:
            INVALIDATE_TRACKS = media::BnAudioFlingerService::TRANSACTION_invalidateTracks,
            GET_AUDIO_POLICY_CONFIG =
                    media::BnAudioFlingerService::TRANSACTION_getAudioPolicyConfig,
            GET_AUDIO_MIX_PORT = media::BnAudioFlingerService::TRANSACTION_getAudioMixPort,
        };

    protected:
@@ -732,6 +738,9 @@ public:
                                 sp<media::ISoundDose>* _aidl_return) override;
    Status invalidateTracks(const std::vector<int32_t>& portIds) override;
    Status getAudioPolicyConfig(media::AudioPolicyConfig* _aidl_return) override;
    Status getAudioMixPort(const media::AudioPortFw& devicePort,
                           const media::AudioPortFw& mixPort,
                           media::AudioPortFw* _aidl_return) override;
private:
    const sp<AudioFlingerServerAdapter::Delegate> mDelegate;
};
+111 −0
Original line number Diff line number Diff line
@@ -119,4 +119,115 @@ std::string dumpDeviceTypes(const DeviceTypeSet &deviceTypes) {
    return ss.str();
}

std::string dumpMixerBehaviors(const MixerBehaviorSet& mixerBehaviors) {
    std::stringstream ss;
    for (auto it = mixerBehaviors.begin(); it != mixerBehaviors.end(); ++it) {
        if (it != mixerBehaviors.begin()) {
            ss << ", ";
        }
        ss << (*it);
    }
    return ss.str();
}

AudioProfileAttributesMultimap createAudioProfilesAttrMap(audio_profile profiles[],
                                                          uint32_t first,
                                                          uint32_t last) {
    AudioProfileAttributesMultimap result;
    for (uint32_t i = first; i < last; ++i) {
        SampleRateSet sampleRates(profiles[i].sample_rates,
                                  profiles[i].sample_rates + profiles[i].num_sample_rates);
        ChannelMaskSet channelMasks(profiles[i].channel_masks,
                                    profiles[i].channel_masks + profiles[i].num_channel_masks);
        result.emplace(profiles[i].format, std::make_pair(sampleRates, channelMasks));
    }
    return result;
}

namespace {

void populateAudioProfile(audio_format_t format,
                          const ChannelMaskSet& channelMasks,
                          const SampleRateSet& samplingRates,
                          audio_profile* profile) {
    profile->format = format;
    profile->num_channel_masks = 0;
    for (auto it = channelMasks.begin();
         it != channelMasks.end() && profile->num_channel_masks < AUDIO_PORT_MAX_CHANNEL_MASKS;
         ++it) {
        profile->channel_masks[profile->num_channel_masks++] = *it;
    }
    profile->num_sample_rates = 0;
    for (auto it = samplingRates.begin();
         it != samplingRates.end() && profile->num_sample_rates < AUDIO_PORT_MAX_SAMPLING_RATES;
         ++it) {
        profile->sample_rates[profile->num_sample_rates++] = *it;
    }
}

} // namespace

void populateAudioProfiles(const AudioProfileAttributesMultimap& profileAttrs,
                           audio_format_t format,
                           ChannelMaskSet allChannelMasks,
                           SampleRateSet allSampleRates,
                           audio_profile audioProfiles[],
                           uint32_t* numAudioProfiles,
                           uint32_t maxAudioProfiles) {
    if (*numAudioProfiles >= maxAudioProfiles) {
        return;
    }

    const auto lower= profileAttrs.lower_bound(format);
    const auto upper = profileAttrs.upper_bound(format);
    SampleRateSet sampleRatesPresent;
    ChannelMaskSet channelMasksPresent;
    for (auto it = lower; it != upper && *numAudioProfiles < maxAudioProfiles; ++it) {
        SampleRateSet srs;
        std::set_intersection(it->second.first.begin(), it->second.first.end(),
                              allSampleRates.begin(), allSampleRates.end(),
                              std::inserter(srs, srs.begin()));
        if (srs.empty()) {
            continue;
        }
        ChannelMaskSet cms;
        std::set_intersection(it->second.second.begin(), it->second.second.end(),
                              allChannelMasks.begin(), allChannelMasks.end(),
                              std::inserter(cms, cms.begin()));
        if (cms.empty()) {
            continue;
        }
        sampleRatesPresent.insert(srs.begin(), srs.end());
        channelMasksPresent.insert(cms.begin(), cms.end());
        populateAudioProfile(it->first, cms, srs,
                             &audioProfiles[(*numAudioProfiles)++]);
    }
    if (*numAudioProfiles >= maxAudioProfiles) {
        ALOGW("%s, too many audio profiles", __func__);
        return;
    }

    SampleRateSet srs;
    std::set_difference(allSampleRates.begin(), allSampleRates.end(),
                        sampleRatesPresent.begin(), sampleRatesPresent.end(),
                        std::inserter(srs, srs.begin()));
    if (!srs.empty()) {
        populateAudioProfile(format, allChannelMasks, srs,
                             &audioProfiles[(*numAudioProfiles)++]);
    }
    if (*numAudioProfiles >= maxAudioProfiles) {
        ALOGW("%s, too many audio profiles", __func__);
        return;
    }
    ChannelMaskSet cms;
    std::set_difference(allChannelMasks.begin(), allChannelMasks.end(),
                        channelMasksPresent.begin(), channelMasksPresent.end(),
                        std::inserter(cms, cms.begin()));
    if (!cms.empty()) {
        populateAudioProfile(format, cms, allSampleRates,
                             &audioProfiles[(*numAudioProfiles)++]);
    }

}

} // namespace android
+10 −0
Original line number Diff line number Diff line
@@ -383,6 +383,16 @@ void AudioProfileVector::addAllValidProfiles(const AudioProfileVector& audioProf
    }
}

ChannelMaskSet AudioProfileVector::getSupportedChannelMasks() const {
    ChannelMaskSet channelMasks;
    for (const auto& profile : *this) {
        if (profile->isValid()) {
            channelMasks.insert(profile->getChannels().begin(), profile->getChannels().end());
        }
    }
    return channelMasks;
}

ConversionResult<AudioProfileVector>
aidl2legacy_AudioProfileVector(const AudioProfileVector::Aidl& aidl, bool isInput) {
    return convertContainers<AudioProfileVector>(aidl.first, aidl.second,
Loading