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

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

Merge "audio: Fix connection between alsa_device_profile and _proxy" into main

parents 7761d90a 5d2bfbac
Loading
Loading
Loading
Loading
+5 −4
Original line number Diff line number Diff line
@@ -39,13 +39,14 @@ ndk::ScopedAStatus ModuleAlsa::populateConnectedDevicePort(AudioPort* audioPort)
    if (!deviceProfile.has_value()) {
        return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
    }
    auto profile = alsa::readAlsaDeviceInfo(*deviceProfile);
    if (!profile.has_value()) {
    auto proxy = alsa::readAlsaDeviceInfo(*deviceProfile);
    if (proxy.get() == nullptr) {
        return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
    }

    std::vector<AudioChannelLayout> channels = alsa::getChannelMasksFromProfile(&profile.value());
    std::vector<int> sampleRates = alsa::getSampleRatesFromProfile(&profile.value());
    alsa_device_profile* profile = proxy.getProfile();
    std::vector<AudioChannelLayout> channels = alsa::getChannelMasksFromProfile(profile);
    std::vector<int> sampleRates = alsa::getSampleRatesFromProfile(profile);

    for (size_t i = 0; i < std::min(MAX_PROFILE_FORMATS, AUDIO_PORT_MAX_AUDIO_PROFILES) &&
                       profile->formats[i] != PCM_FORMAT_INVALID;
+1 −1
Original line number Diff line number Diff line
@@ -83,7 +83,7 @@ StreamAlsa::StreamAlsa(StreamContext* context, const Metadata& metadata, int rea
            proxy = alsa::openProxyForAttachedDevice(
                    device, const_cast<struct pcm_config*>(&mConfig.value()), mBufferSizeFrames);
        }
        if (!proxy) {
        if (proxy.get() == nullptr) {
            return ::android::NO_INIT;
        }
        alsaDeviceProxies.push_back(std::move(proxy));
+36 −40
Original line number Diff line number Diff line
@@ -37,6 +37,23 @@ using aidl::android::media::audio::common::PcmType;

namespace aidl::android::hardware::audio::core::alsa {

DeviceProxy::DeviceProxy() : mProfile(nullptr), mProxy(nullptr, alsaProxyDeleter) {}

DeviceProxy::DeviceProxy(const DeviceProfile& deviceProfile)
    : mProfile(new alsa_device_profile), mProxy(new alsa_device_proxy, alsaProxyDeleter) {
    profile_init(mProfile.get(), deviceProfile.direction);
    mProfile->card = deviceProfile.card;
    mProfile->device = deviceProfile.device;
    memset(mProxy.get(), 0, sizeof(alsa_device_proxy));
}

void DeviceProxy::alsaProxyDeleter(alsa_device_proxy* proxy) {
    if (proxy != nullptr) {
        proxy_close(proxy);
        delete proxy;
    }
}

namespace {

using AudioChannelCountToMaskMap = std::map<unsigned int, AudioChannelLayout>;
@@ -261,39 +278,24 @@ std::vector<int> getSampleRatesFromProfile(const alsa_device_profile* profile) {
    return sampleRates;
}

DeviceProxy makeDeviceProxy() {
    DeviceProxy proxy(new alsa_device_proxy, [](alsa_device_proxy* proxy) {
        if (proxy != nullptr) {
            proxy_close(proxy);
            delete proxy;
        }
    });
    memset(proxy.get(), 0, sizeof(alsa_device_proxy));
    return proxy;
}

DeviceProxy openProxyForAttachedDevice(const DeviceProfile& deviceProfile,
                                       struct pcm_config* pcmConfig, size_t bufferFrameCount) {
    if (deviceProfile.isExternal) {
        LOG(FATAL) << __func__ << ": called for an external device, address=" << deviceProfile;
    }
    alsa_device_profile profile;
    profile_init(&profile, deviceProfile.direction);
    profile.card = deviceProfile.card;
    profile.device = deviceProfile.device;
    if (!profile_fill_builtin_device_info(&profile, pcmConfig, bufferFrameCount)) {
    DeviceProxy proxy(deviceProfile);
    if (!profile_fill_builtin_device_info(proxy.getProfile(), pcmConfig, bufferFrameCount)) {
        LOG(FATAL) << __func__ << ": failed to init for built-in device, address=" << deviceProfile;
    }
    auto proxy = makeDeviceProxy();
    if (int err = proxy_prepare_from_default_config(proxy.get(), &profile); err != 0) {
    if (int err = proxy_prepare_from_default_config(proxy.get(), proxy.getProfile()); err != 0) {
        LOG(FATAL) << __func__ << ": fail to prepare for device address=" << deviceProfile
                   << " error=" << err;
        return nullptr;
        return DeviceProxy();
    }
    if (int err = proxy_open(proxy.get()); err != 0) {
        LOG(ERROR) << __func__ << ": failed to open device, address=" << deviceProfile
                   << " error=" << err;
        return nullptr;
        return DeviceProxy();
    }
    return proxy;
}
@@ -303,42 +305,36 @@ DeviceProxy openProxyForExternalDevice(const DeviceProfile& deviceProfile,
    if (!deviceProfile.isExternal) {
        LOG(FATAL) << __func__ << ": called for an attached device, address=" << deviceProfile;
    }
    auto profile = readAlsaDeviceInfo(deviceProfile);
    if (!profile.has_value()) {
        LOG(ERROR) << __func__ << ": unable to read device info, device address=" << deviceProfile;
        return nullptr;
    auto proxy = readAlsaDeviceInfo(deviceProfile);
    if (proxy.get() == nullptr) {
        return proxy;
    }
    auto proxy = makeDeviceProxy();
    if (int err = proxy_prepare(proxy.get(), &profile.value(), pcmConfig, requireExactMatch);
    if (int err = proxy_prepare(proxy.get(), proxy.getProfile(), pcmConfig, requireExactMatch);
        err != 0) {
        LOG(ERROR) << __func__ << ": fail to prepare for device address=" << deviceProfile
                   << " error=" << err;
        return nullptr;
        return DeviceProxy();
    }
    if (int err = proxy_open(proxy.get()); err != 0) {
        LOG(ERROR) << __func__ << ": failed to open device, address=" << deviceProfile
                   << " error=" << err;
        return nullptr;
        return DeviceProxy();
    }
    return proxy;
}

std::optional<alsa_device_profile> readAlsaDeviceInfo(const DeviceProfile& deviceProfile) {
    alsa_device_profile profile;
    profile_init(&profile, deviceProfile.direction);
    profile.card = deviceProfile.card;
    profile.device = deviceProfile.device;
    if (!profile_read_device_info(&profile)) {
        LOG(ERROR) << __func__ << ": failed to read device info, card=" << profile.card
                   << ", device=" << profile.device;
        return std::nullopt;
DeviceProxy readAlsaDeviceInfo(const DeviceProfile& deviceProfile) {
    DeviceProxy proxy(deviceProfile);
    if (!profile_read_device_info(proxy.getProfile())) {
        LOG(ERROR) << __func__ << ": unable to read device info, device address=" << deviceProfile;
        return DeviceProxy();
    }
    return profile;
    return proxy;
}

void resetTransferredFrames(DeviceProxy& proxy, uint64_t frames) {
    if (proxy != nullptr) {
        proxy->transferred = frames;
    if (proxy.get() != nullptr) {
        proxy.get()->transferred = frames;
    }
}

+16 −4
Original line number Diff line number Diff line
@@ -43,8 +43,21 @@ struct DeviceProfile {
    bool isExternal;
};
std::ostream& operator<<(std::ostream& os, const DeviceProfile& device);
using DeviceProxyDeleter = std::function<void(alsa_device_proxy*)>;
using DeviceProxy = std::unique_ptr<alsa_device_proxy, DeviceProxyDeleter>;

class DeviceProxy {
  public:
    DeviceProxy();  // Constructs a "null" proxy.
    explicit DeviceProxy(const DeviceProfile& deviceProfile);
    alsa_device_profile* getProfile() { return mProfile.get(); }
    alsa_device_proxy* get() { return mProxy.get(); }

  private:
    static void alsaProxyDeleter(alsa_device_proxy* proxy);
    using AlsaProxy = std::unique_ptr<alsa_device_proxy, decltype(alsaProxyDeleter)*>;

    std::unique_ptr<alsa_device_profile> mProfile;
    AlsaProxy mProxy;
};

::aidl::android::media::audio::common::AudioChannelLayout getChannelLayoutMaskFromChannelCount(
        unsigned int channelCount, int isInput);
@@ -60,12 +73,11 @@ std::optional<DeviceProfile> getDeviceProfile(
        const ::aidl::android::media::audio::common::AudioPort& audioPort);
std::optional<struct pcm_config> getPcmConfig(const StreamContext& context, bool isInput);
std::vector<int> getSampleRatesFromProfile(const alsa_device_profile* profile);
DeviceProxy makeDeviceProxy();
DeviceProxy openProxyForAttachedDevice(const DeviceProfile& deviceProfile,
                                       struct pcm_config* pcmConfig, size_t bufferFrameCount);
DeviceProxy openProxyForExternalDevice(const DeviceProfile& deviceProfile,
                                       struct pcm_config* pcmConfig, bool requireExactMatch);
std::optional<alsa_device_profile> readAlsaDeviceInfo(const DeviceProfile& deviceProfile);
DeviceProxy readAlsaDeviceInfo(const DeviceProfile& deviceProfile);
void resetTransferredFrames(DeviceProxy& proxy, uint64_t frames);

::aidl::android::media::audio::common::AudioFormatDescription