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

Commit 7bcde082 authored by jiabin's avatar jiabin Committed by Automerger Merge Worker
Browse files

APM: route all clients to bit-perfect output when it is active. am: d9a58d33

parents 6d9ccfc2 d9a58d33
Loading
Loading
Loading
Loading
+15 −6
Original line number Diff line number Diff line
@@ -1293,7 +1293,8 @@ status_t AudioPolicyManager::getOutputForAttrInt(
        if (outputDevices.size() == 1) {
            info = getPreferredMixerAttributesInfo(
                    outputDevices.itemAt(0)->getId(),
                    mEngine->getProductStrategyForAttributes(*resultAttr));
                    mEngine->getProductStrategyForAttributes(*resultAttr),
                    true /*activeBitPerfectPreferred*/);
            // Only use preferred mixer if the uid matches or the preferred mixer is bit-perfect
            // and it is currently active.
            if (info != nullptr && info->getUid() != uid &&
@@ -4485,16 +4486,24 @@ status_t AudioPolicyManager::setPreferredMixerAttributes(
}

sp<PreferredMixerAttributesInfo> AudioPolicyManager::getPreferredMixerAttributesInfo(
        audio_port_handle_t devicePortId, product_strategy_t strategy) {
        audio_port_handle_t devicePortId,
        product_strategy_t strategy,
        bool activeBitPerfectPreferred) {
    auto it = mPreferredMixerAttrInfos.find(devicePortId);
    if (it == mPreferredMixerAttrInfos.end()) {
        return nullptr;
    }
    auto mixerAttrInfoIt = it->second.find(strategy);
    if (mixerAttrInfoIt == it->second.end()) {
        return nullptr;
    if (activeBitPerfectPreferred) {
        for (auto [strategy, info] : it->second) {
            if ((info->getFlags() & AUDIO_OUTPUT_FLAG_BIT_PERFECT) != AUDIO_OUTPUT_FLAG_NONE
                && info->getActiveClientCount() != 0) {
                return info;
            }
        }
    }
    return mixerAttrInfoIt->second;
    auto strategyMatchedMixerAttrInfoIt = it->second.find(strategy);
    return strategyMatchedMixerAttrInfoIt == it->second.end()
            ? nullptr : strategyMatchedMixerAttrInfoIt->second;
}

status_t AudioPolicyManager::getPreferredMixerAttributes(
+8 −1
Original line number Diff line number Diff line
@@ -1298,8 +1298,15 @@ private:
                                       uint32_t flags,
                                       bool isInput);

        /**
         * Returns the preferred mixer attributes info for the given device port id and strategy.
         * Bit-perfect mixer attributes will be returned if it is active and
         * `activeBitPerfectPreferred` is true.
         */
        sp<PreferredMixerAttributesInfo> getPreferredMixerAttributesInfo(
                audio_port_handle_t devicePortId, product_strategy_t strategy);
                audio_port_handle_t devicePortId,
                product_strategy_t strategy,
                bool activeBitPerfectPreferred = false);

        sp<SwAudioOutputDescriptor> reopenOutput(
                sp<SwAudioOutputDescriptor> outputDesc,
+13 −0
Original line number Diff line number Diff line
@@ -1232,6 +1232,19 @@ TEST_F(AudioPolicyManagerTestWithConfigurationFile, BitPerfectPlayback) {
    EXPECT_FALSE(isBitPerfect);
    EXPECT_EQ(bitPerfectOutput, output);

    const audio_attributes_t dtmfAttr = {
            .content_type = AUDIO_CONTENT_TYPE_UNKNOWN,
            .usage = AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING,
    };
    audio_io_handle_t dtmfOutput = AUDIO_IO_HANDLE_NONE;
    selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
    portId = AUDIO_PORT_HANDLE_NONE;
    getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO,
            48000, AUDIO_OUTPUT_FLAG_NONE, &dtmfOutput, &portId, dtmfAttr,
            AUDIO_SESSION_NONE, anotherUid, &isBitPerfect);
    EXPECT_FALSE(isBitPerfect);
    EXPECT_EQ(bitPerfectOutput, dtmfOutput);

    // When configuration matches preferred mixer attributes, which is bit-perfect, but the client
    // is not the owner of preferred mixer attributes, the playback will not be bit-perfect.
    getOutputForAttr(&selectedDeviceId, bitPerfectFormat, bitPerfectChannelMask,