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

Commit 14b50ccd authored by jiabin's avatar jiabin
Browse files

APM: use preferred config for device when it is available.

When a device is connected, the device configuration, which includes
sample rate, channel mask and format is selected, is picked at the
highest values to ensure the best experience. This configuration will be
used as the device configuration when creating audio patch. When
bit-perfect playback is active, the configuration should not be the
highest one. Instead, it should be the same as the bit-perfect
configuration. In that case, adding the concept of preferred
configuration, which will be set when bit-perfect playback is active.
The device will use preferred configuration when it is available.

Bug: 251215866
Test: manually
Change-Id: I58f8fd14c3b0f7cf10daba51d3c7c74713f19991
parent 8d7480e6
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -364,7 +364,7 @@ public:

    void dump(String8 *dst, int spaces, const char* extraInfo = nullptr) const override;
    virtual DeviceVector devices() const;
    void setDevices(const DeviceVector &devices) { mDevices = devices; }
    void setDevices(const DeviceVector &devices);
    bool sharesHwModuleWith(const sp<SwAudioOutputDescriptor>& outputDesc);
    virtual DeviceVector supportedDevices() const;
    virtual bool devicesSupportEncodedFormats(const DeviceTypeSet& deviceTypes);
+3 −0
Original line number Diff line number Diff line
@@ -93,6 +93,8 @@ public:

    void setEncapsulationInfoFromHal(AudioPolicyClientInterface *clientInterface);

    void setPreferredConfig(const audio_config_base_t * preferredConfig);

    void dump(String8 *dst, int spaces, bool verbose = true) const;

private:
@@ -107,6 +109,7 @@ private:
    audio_format_t      mCurrentEncodedFormat;
    bool                mIsDynamic = false;
    std::string         mDeclaredAddress; // Original device address
    std::optional<audio_config_base_t> mPreferredConfig;
};

class DeviceVector : public SortedVector<sp<DeviceDescriptor> >
+13 −0
Original line number Diff line number Diff line
@@ -778,6 +778,19 @@ void SwAudioOutputDescriptor::setTracksInvalidatedStatusByStrategy(product_strat
    }
}

void SwAudioOutputDescriptor::setDevices(const android::DeviceVector &devices) {
    if ((mFlags & AUDIO_OUTPUT_FLAG_BIT_PERFECT) == AUDIO_OUTPUT_FLAG_BIT_PERFECT) {
        for (auto device : mDevices) {
            device->setPreferredConfig(nullptr);
        }
        auto config = getConfig();
        for (auto device : devices) {
            device->setPreferredConfig(&config);
        }
    }
    mDevices = devices;
}

// HwAudioOutputDescriptor implementation
HwAudioOutputDescriptor::HwAudioOutputDescriptor(const sp<SourceClientDescriptor>& source,
                                                 AudioPolicyClientInterface *clientInterface)
+29 −0
Original line number Diff line number Diff line
@@ -132,6 +132,20 @@ void DeviceDescriptor::toAudioPortConfig(struct audio_port_config *dstConfig,
{
    DeviceDescriptorBase::toAudioPortConfig(dstConfig, srcConfig);
    dstConfig->ext.device.hw_module = getModuleHandle();
    if (mPreferredConfig.has_value()) {
        if (mPreferredConfig->format != AUDIO_FORMAT_DEFAULT) {
            dstConfig->config_mask |= AUDIO_PORT_CONFIG_FORMAT;
            dstConfig->format = mPreferredConfig->format;
        }
        if (mPreferredConfig->sample_rate != 0) {
            dstConfig->config_mask |= AUDIO_PORT_CONFIG_SAMPLE_RATE;
            dstConfig->sample_rate = mPreferredConfig->sample_rate;
        }
        if (mPreferredConfig->channel_mask != AUDIO_CHANNEL_NONE) {
            dstConfig->config_mask |= AUDIO_PORT_CONFIG_CHANNEL_MASK;
            dstConfig->channel_mask = mPreferredConfig->channel_mask;
        }
    }
}

void DeviceDescriptor::toAudioPort(struct audio_port *port) const
@@ -183,6 +197,14 @@ void DeviceDescriptor::setEncapsulationInfoFromHal(
    }
}

void DeviceDescriptor::setPreferredConfig(const audio_config_base_t* preferredConfig) {
    if (preferredConfig == nullptr) {
        mPreferredConfig.reset();
    } else {
        mPreferredConfig = *preferredConfig;
    }
}

void DeviceDescriptor::dump(String8 *dst, int spaces, bool verbose) const
{
    String8 extraInfo;
@@ -193,6 +215,13 @@ void DeviceDescriptor::dump(String8 *dst, int spaces, bool verbose) const
    std::string descBaseDumpStr;
    DeviceDescriptorBase::dump(&descBaseDumpStr, spaces, extraInfo.c_str(), verbose);
    dst->append(descBaseDumpStr.c_str());

    if (mPreferredConfig.has_value()) {
        dst->append(base::StringPrintf(
                "%*sPreferred Config: format=%#x, channelMask=%#x, sampleRate=%u\n",
                spaces, "", mPreferredConfig.value().format, mPreferredConfig.value().channel_mask,
                mPreferredConfig.value().sample_rate).c_str());
    }
}


+12 −0
Original line number Diff line number Diff line
@@ -6747,6 +6747,12 @@ void AudioPolicyManager::closeOutput(audio_io_handle_t output)
        closingOutput->stop();
    }
    closingOutput->close();
    if ((closingOutput->getFlags().output & AUDIO_OUTPUT_FLAG_BIT_PERFECT)
            == AUDIO_OUTPUT_FLAG_BIT_PERFECT) {
        for (const auto device : closingOutput->devices()) {
            device->setPreferredConfig(nullptr);
        }
    }

    removeOutput(output);
    mPreviousOutputs = mOutputs;
@@ -8361,6 +8367,12 @@ sp<SwAudioOutputDescriptor> AudioPolicyManager::openOutputWithProfileAndDevice(
        ALOGE("%s failed to open output %d", __func__, status);
        return nullptr;
    }
    if ((flags & AUDIO_OUTPUT_FLAG_BIT_PERFECT) == AUDIO_OUTPUT_FLAG_BIT_PERFECT) {
        auto portConfig = desc->getConfig();
        for (const auto& device : devices) {
            device->setPreferredConfig(&portConfig);
        }
    }

    // Here is where the out_set_parameters() for card & device gets called
    sp<DeviceDescriptor> device = devices.getDeviceForOpening();