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

Commit f90cedc9 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Fix voice communication audio playback capture"

parents 6d62049c 287d330c
Loading
Loading
Loading
Loading
+2 −7
Original line number Original line Diff line number Diff line
@@ -86,6 +86,7 @@ status_t AudioMix::readFromParcel(Parcel *parcel)
    mDeviceAddress = parcel->readString8();
    mDeviceAddress = parcel->readString8();
    mCbFlags = (uint32_t)parcel->readInt32();
    mCbFlags = (uint32_t)parcel->readInt32();
    mAllowPrivilegedPlaybackCapture = parcel->readBool();
    mAllowPrivilegedPlaybackCapture = parcel->readBool();
    mVoiceCommunicationCaptureAllowed = parcel->readBool();
    size_t size = (size_t)parcel->readInt32();
    size_t size = (size_t)parcel->readInt32();
    if (size > MAX_CRITERIA_PER_MIX) {
    if (size > MAX_CRITERIA_PER_MIX) {
        size = MAX_CRITERIA_PER_MIX;
        size = MAX_CRITERIA_PER_MIX;
@@ -110,6 +111,7 @@ status_t AudioMix::writeToParcel(Parcel *parcel) const
    parcel->writeString8(mDeviceAddress);
    parcel->writeString8(mDeviceAddress);
    parcel->writeInt32(mCbFlags);
    parcel->writeInt32(mCbFlags);
    parcel->writeBool(mAllowPrivilegedPlaybackCapture);
    parcel->writeBool(mAllowPrivilegedPlaybackCapture);
    parcel->writeBool(mVoiceCommunicationCaptureAllowed);
    size_t size = mCriteria.size();
    size_t size = mCriteria.size();
    if (size > MAX_CRITERIA_PER_MIX) {
    if (size > MAX_CRITERIA_PER_MIX) {
        size = MAX_CRITERIA_PER_MIX;
        size = MAX_CRITERIA_PER_MIX;
@@ -206,11 +208,4 @@ bool AudioMix::isDeviceAffinityCompatible() const {
            && (mRouteFlags == MIX_ROUTE_FLAG_RENDER));
            && (mRouteFlags == MIX_ROUTE_FLAG_RENDER));
}
}


bool AudioMix::hasMatchingRuleForUsage(std::function<bool (audio_usage_t)>const& func) const {
    return std::any_of(mCriteria.begin(), mCriteria.end(), [func](auto& criterion) {
            return criterion.mRule == RULE_MATCH_ATTRIBUTE_USAGE
              && func(criterion.mValue.mUsage);
          });
}

} // namespace android
} // namespace android
+2 −8
Original line number Original line Diff line number Diff line
@@ -18,7 +18,6 @@
#ifndef ANDROID_AUDIO_POLICY_H
#ifndef ANDROID_AUDIO_POLICY_H
#define ANDROID_AUDIO_POLICY_H
#define ANDROID_AUDIO_POLICY_H


#include <functional>
#include <binder/Parcel.h>
#include <binder/Parcel.h>
#include <media/AudioDeviceTypeAddr.h>
#include <media/AudioDeviceTypeAddr.h>
#include <system/audio.h>
#include <system/audio.h>
@@ -113,13 +112,6 @@ public:
    /** returns true if this mix can be used for uid-device affinity routing */
    /** returns true if this mix can be used for uid-device affinity routing */
    bool isDeviceAffinityCompatible() const;
    bool isDeviceAffinityCompatible() const;


    /**
     * returns true if the mix has a capture rule for a usage that
     * matches the given predicate
     */
    bool hasMatchingRuleForUsage(
        std::function<bool (audio_usage_t)>const& func) const;

    mutable Vector<AudioMixMatchCriterion> mCriteria;
    mutable Vector<AudioMixMatchCriterion> mCriteria;
    uint32_t        mMixType;
    uint32_t        mMixType;
    audio_config_t  mFormat;
    audio_config_t  mFormat;
@@ -129,6 +121,8 @@ public:
    uint32_t        mCbFlags; // flags indicating which callbacks to use, see kCbFlag*
    uint32_t        mCbFlags; // flags indicating which callbacks to use, see kCbFlag*
    /** Ignore the AUDIO_FLAG_NO_MEDIA_PROJECTION */
    /** Ignore the AUDIO_FLAG_NO_MEDIA_PROJECTION */
    bool            mAllowPrivilegedPlaybackCapture = false;
    bool            mAllowPrivilegedPlaybackCapture = false;
    /** Indicates if the caller can capture voice communication output */
    bool            mVoiceCommunicationCaptureAllowed = false;
};
};




+4 −0
Original line number Original line Diff line number Diff line
@@ -224,6 +224,10 @@ AudioPolicyMixCollection::MixMatchStatus AudioPolicyMixCollection::mixMatch(
                hasFlag(attributes.flags, AUDIO_FLAG_NO_MEDIA_PROJECTION)) {
                hasFlag(attributes.flags, AUDIO_FLAG_NO_MEDIA_PROJECTION)) {
                return MixMatchStatus::NO_MATCH;
                return MixMatchStatus::NO_MATCH;
            }
            }
            if (attributes.usage == AUDIO_USAGE_VOICE_COMMUNICATION &&
                !mix->mVoiceCommunicationCaptureAllowed) {
                return MixMatchStatus::NO_MATCH;
            }
            if (!(attributes.usage == AUDIO_USAGE_UNKNOWN ||
            if (!(attributes.usage == AUDIO_USAGE_UNKNOWN ||
                  attributes.usage == AUDIO_USAGE_MEDIA ||
                  attributes.usage == AUDIO_USAGE_MEDIA ||
                  attributes.usage == AUDIO_USAGE_GAME ||
                  attributes.usage == AUDIO_USAGE_GAME ||
+0 −1
Original line number Original line Diff line number Diff line
@@ -26,7 +26,6 @@ LOCAL_SHARED_LIBRARIES := \
    libaudioutils \
    libaudioutils \
    libaudiofoundation \
    libaudiofoundation \
    libhardware_legacy \
    libhardware_legacy \
    libaudiopolicy \
    libaudiopolicymanager \
    libaudiopolicymanager \
    libmedia_helper \
    libmedia_helper \
    libmediametrics \
    libmediametrics \
+5 −17
Original line number Original line Diff line number Diff line
@@ -1215,26 +1215,14 @@ status_t AudioPolicyService::registerPolicyMixes(const Vector<AudioMix>& mixes,
        return PERMISSION_DENIED;
        return PERMISSION_DENIED;
    }
    }


    // Require CAPTURE_VOICE_COMMUNICATION_OUTPUT if one of the
    // If one of the mixes has needCaptureVoiceCommunicationOutput set to true, then we
    // mixes is a render|loopback mix that aim to capture audio played with
    // need to verify that the caller still has CAPTURE_VOICE_COMMUNICATION_OUTPUT
    // USAGE_VOICE_COMMUNICATION.
    bool needCaptureVoiceCommunicationOutput =
    bool needCaptureVoiceCommunicationOutput =
        std::any_of(mixes.begin(), mixes.end(), [](auto& mix) {
        std::any_of(mixes.begin(), mixes.end(), [](auto& mix) {
            return is_mix_loopback_render(mix.mRouteFlags) &&
            return mix.mVoiceCommunicationCaptureAllowed; });
                mix.hasMatchingRuleForUsage([] (auto usage) {

                    return usage == AUDIO_USAGE_VOICE_COMMUNICATION;});
            });

    // Require CAPTURE_MEDIA_OUTPUT if there is a mix for priveliged capture
    // which is trying to capture any usage which is not USAGE_VOICE_COMMUNICATION.
    // (If USAGE_VOICE_COMMUNICATION should be captured, then CAPTURE_VOICE_COMMUNICATION_OUTPUT
    //  is required, even if it is not privileged capture).
    bool needCaptureMediaOutput = std::any_of(mixes.begin(), mixes.end(), [](auto& mix) {
    bool needCaptureMediaOutput = std::any_of(mixes.begin(), mixes.end(), [](auto& mix) {
            return mix.mAllowPrivilegedPlaybackCapture &&
            return mix.mAllowPrivilegedPlaybackCapture; });
                mix.hasMatchingRuleForUsage([] (auto usage) {
                    return usage != AUDIO_USAGE_VOICE_COMMUNICATION;
                });
            });


    const uid_t callingUid = IPCThreadState::self()->getCallingUid();
    const uid_t callingUid = IPCThreadState::self()->getCallingUid();
    const pid_t callingPid = IPCThreadState::self()->getCallingPid();
    const pid_t callingPid = IPCThreadState::self()->getCallingPid();