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

Commit c2cdda35 authored by Oscar Azucena's avatar Oscar Azucena
Browse files

Added audio service API to set active assistants.

Added API to manage the currently active assistants UIDs. When an
assistant can become active the API can be called to set voice
interaction service and corresponging trusted hotword service as active.

If there are no assistant UIDs in the active list the audio policy
service uses the default policy, which is to find the latest active
assistant and allow that to continue listening. This is to continue
support for legacy devices where the management of the active assistant
should be preserve.

Bug: 189312611
Test: m -j, and run assistant
Change-Id: I18984f3dcb8bf63dd16b3ae86d96dfbce39ced03
parent 829d90db
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -1920,6 +1920,15 @@ status_t AudioSystem::setAssistantServicesUids(const std::vector<uid_t>& uids) {
    return statusTFromBinderStatus(aps->setAssistantServicesUids(uidsAidl));
}

status_t AudioSystem::setActiveAssistantServicesUids(const std::vector<uid_t>& activeUids) {
    const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
    if (aps == 0) return PERMISSION_DENIED;

    std::vector<int32_t> activeUidsAidl = VALUE_OR_RETURN_STATUS(
                convertContainer<std::vector<int32_t>>(activeUids, legacy2aidl_uid_t_int32_t));
    return statusTFromBinderStatus(aps->setActiveAssistantServicesUids(activeUidsAidl));
}

status_t AudioSystem::setA11yServicesUids(const std::vector<uid_t>& uids) {
    const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
    if (aps == 0) return PERMISSION_DENIED;
+2 −0
Original line number Diff line number Diff line
@@ -304,6 +304,8 @@ interface IAudioPolicyService {

    void setAssistantServicesUids(in int[] /* uid_t[] */ uids);

    void setActiveAssistantServicesUids(in int[] /* uid_t[] */ activeUids);

    void setA11yServicesUids(in int[] /* uid_t[] */ uids);

    void setCurrentImeUid(int /* uid_t */ uid);
+2 −0
Original line number Diff line number Diff line
@@ -439,6 +439,8 @@ public:
    static status_t setSurroundFormatEnabled(audio_format_t audioFormat, bool enabled);

    static status_t setAssistantServicesUids(const std::vector<uid_t>& uids);
    static status_t setActiveAssistantServicesUids(const std::vector<uid_t>& activeUids);

    static status_t setA11yServicesUids(const std::vector<uid_t>& uids);
    static status_t setCurrentImeUid(uid_t uid);

+10 −0
Original line number Diff line number Diff line
@@ -2024,6 +2024,16 @@ Status AudioPolicyService::setAssistantServicesUids(const std::vector<int32_t>&
    return Status::ok();
}

Status AudioPolicyService::setActiveAssistantServicesUids(
        const std::vector<int32_t>& activeUidsAidl) {
    std::vector<uid_t> activeUids;
    RETURN_IF_BINDER_ERROR(convertInt32VectorToUidVectorWithLimit(activeUidsAidl, activeUids));

    Mutex::Autolock _l(mLock);
    mUidPolicy->setActiveAssistantUids(activeUids);
    return Status::ok();
}

Status AudioPolicyService::setA11yServicesUids(const std::vector<int32_t>& uidsAidl)
{
    std::vector<uid_t> uids;
+70 −14
Original line number Diff line number Diff line
@@ -609,13 +609,20 @@ void AudioPolicyService::updateUidStates_l()
{
//    Go over all active clients and allow capture (does not force silence) in the
//    following cases:
//    The client is the assistant
//    The client is in the active assistant list
//         AND is TOP
//               AND an accessibility service is TOP
//                  AND source is either VOICE_RECOGNITION OR HOTWORD
//               OR there is no active privacy sensitive capture or call
//                          OR client has CAPTURE_AUDIO_OUTPUT privileged permission
//                  AND source is VOICE_RECOGNITION OR HOTWORD
//    The client is an assistant AND active assistant is not being used
//        AND an accessibility service is on TOP or a RTT call is active
//                AND the source is VOICE_RECOGNITION or HOTWORD
//            OR uses VOICE_RECOGNITION AND is on TOP
//                OR uses HOTWORD
//            AND there is no active privacy sensitive capture or call
//        OR there is no active privacy sensitive capture or call
//                OR client has CAPTURE_AUDIO_OUTPUT privileged permission
//            AND is TOP most recent assistant and uses VOICE_RECOGNITION or HOTWORD
//                OR there is no top recent assistant and source is HOTWORD
//    OR The client is an accessibility service
//        AND Is on TOP
//                AND the source is VOICE_RECOGNITION or HOTWORD
@@ -643,13 +650,16 @@ void AudioPolicyService::updateUidStates_l()
    sp<AudioRecordClient> latestActive;
    sp<AudioRecordClient> topSensitiveActive;
    sp<AudioRecordClient> latestSensitiveActiveOrComm;
    sp<AudioRecordClient> latestActiveAssistant;

    nsecs_t topStartNs = 0;
    nsecs_t latestStartNs = 0;
    nsecs_t topSensitiveStartNs = 0;
    nsecs_t latestSensitiveStartNs = 0;
    nsecs_t latestAssistantStartNs = 0;
    bool isA11yOnTop = mUidPolicy->isA11yOnTop();
    bool isAssistantOnTop = false;
    bool useActiveAssistantList = false;
    bool isSensitiveActive = false;
    bool isInCall = mPhoneState == AUDIO_MODE_IN_CALL;
    bool isInCommunication = mPhoneState == AUDIO_MODE_IN_COMMUNICATION;
@@ -684,6 +694,7 @@ void AudioPolicyService::updateUidStates_l()
        // for top or latest active to avoid masking regular clients started before
        if (!isAccessibility && !isVirtualSource(current->attributes.source)) {
            bool isAssistant = mUidPolicy->isAssistantUid(currentUid);
            bool isActiveAssistant = mUidPolicy->isActiveAssistantUid(currentUid);
            bool isPrivacySensitive =
                    (current->attributes.flags & AUDIO_FLAG_CAPTURE_PRIVATE) != 0;

@@ -701,6 +712,14 @@ void AudioPolicyService::updateUidStates_l()
                }
                if (isAssistant) {
                    isAssistantOnTop = true;
                    if (isActiveAssistant) {
                        useActiveAssistantList = true;
                    } else if (!useActiveAssistantList) {
                        if (current->startTimeNs > latestAssistantStartNs) {
                            latestActiveAssistant = current;
                            latestAssistantStartNs = current->startTimeNs;
                        }
                    }
                }
            }
            // Clients capturing for HOTWORD are not considered
@@ -780,6 +799,8 @@ void AudioPolicyService::updateUidStates_l()
            current->attributionSource.uid == topActive->attributionSource.uid;
        bool isTopOrLatestSensitive = topSensitiveActive == nullptr ? false :
            current->attributionSource.uid == topSensitiveActive->attributionSource.uid;
        bool isTopOrLatestAssistant = latestActiveAssistant == nullptr ? false :
            current->attributionSource.uid == latestActiveAssistant->attributionSource.uid;

        auto canCaptureIfInCallOrCommunication = [&](const auto &recordClient) REQUIRES(mLock) {
            uid_t recordUid = VALUE_OR_FATAL(aidl2legacy_int32_t_uid_t(
@@ -809,23 +830,45 @@ void AudioPolicyService::updateUidStates_l()
        } else if (isVirtualSource(source)) {
            // Allow capture for virtual (remote submix, call audio TX or RX...) sources
            allowCapture = true;
        } else if (mUidPolicy->isAssistantUid(currentUid)) {
        } else if (!useActiveAssistantList && mUidPolicy->isAssistantUid(currentUid)) {
            // For assistant allow capture if:
            //     An accessibility service is on TOP or a RTT call is active
            //     Active assistant list is not being used
            //     AND accessibility service is on TOP or a RTT call is active
            //            AND the source is VOICE_RECOGNITION or HOTWORD
            //     OR is on TOP AND uses VOICE_RECOGNITION
            //            OR uses HOTWORD
            //         AND there is no active privacy sensitive capture or call
            //     OR there is no active privacy sensitive capture or call
            //          OR client has CAPTURE_AUDIO_OUTPUT privileged permission
            //            AND is latest TOP assistant AND
            //               uses VOICE_RECOGNITION OR uses HOTWORD
            //            OR there is no TOP assistant and uses HOTWORD
            if (isA11yOnTop || rttCallActive) {
                if (source == AUDIO_SOURCE_HOTWORD || source == AUDIO_SOURCE_VOICE_RECOGNITION) {
                    allowCapture = true;
                }
            } else {
                if (((isAssistantOnTop && source == AUDIO_SOURCE_VOICE_RECOGNITION) ||
                        source == AUDIO_SOURCE_HOTWORD)
                        && !(isSensitiveActive && !current->canCaptureOutput)
            } else if (!(isSensitiveActive && !current->canCaptureOutput)
                    && canCaptureIfInCallOrCommunication(current)) {
                if (isTopOrLatestAssistant
                    && (source == AUDIO_SOURCE_VOICE_RECOGNITION
                        || source == AUDIO_SOURCE_HOTWORD)) {
                        allowCapture = true;
                } else if (!isAssistantOnTop && (source == AUDIO_SOURCE_HOTWORD)) {
                    allowCapture = true;
                }
            }
        } else if (useActiveAssistantList && mUidPolicy->isActiveAssistantUid(currentUid)) {
            // For assistant on active list and on top allow capture if:
            //     An accessibility service is on TOP
            //         AND the source is VOICE_RECOGNITION or HOTWORD
            //     OR there is no active privacy sensitive capture or call
            //             OR client has CAPTURE_AUDIO_OUTPUT privileged permission
            //         AND uses VOICE_RECOGNITION OR uses HOTWORD
            if (isA11yOnTop) {
                if (source == AUDIO_SOURCE_HOTWORD || source == AUDIO_SOURCE_VOICE_RECOGNITION) {
                    allowCapture = true;
                }
            } else if (!(isSensitiveActive && !current->canCaptureOutput)
                        && canCaptureIfInCallOrCommunication(current)) {
                if ((source == AUDIO_SOURCE_VOICE_RECOGNITION) || (source == AUDIO_SOURCE_HOTWORD))
                {
                    allowCapture = true;
                }
            }
@@ -1039,6 +1082,7 @@ status_t AudioPolicyService::onTransact(
        case TRANSACTION_getReportedSurroundFormats:
        case TRANSACTION_setSurroundFormatEnabled:
        case TRANSACTION_setAssistantServicesUids:
        case TRANSACTION_setActiveAssistantServicesUids:
        case TRANSACTION_setA11yServicesUids:
        case TRANSACTION_setUidDeviceAffinities:
        case TRANSACTION_removeUidDeviceAffinities:
@@ -1487,6 +1531,17 @@ bool AudioPolicyService::UidPolicy::isAssistantUid(uid_t uid)
    return it != mAssistantUids.end();
}

void AudioPolicyService::UidPolicy::setActiveAssistantUids(const std::vector<uid_t>& activeUids) {
    mActiveAssistantUids = activeUids;
}

bool AudioPolicyService::UidPolicy::isActiveAssistantUid(uid_t uid)
{
    std::vector<uid_t>::iterator it = find(mActiveAssistantUids.begin(),
            mActiveAssistantUids.end(), uid);
    return it != mActiveAssistantUids.end();
}

void AudioPolicyService::UidPolicy::dumpInternals(int fd) {
    const size_t SIZE = 256;
    char buffer[SIZE];
@@ -1512,6 +1567,7 @@ void AudioPolicyService::UidPolicy::dumpInternals(int fd) {
    result.append(buffer);

    appendUidsToResult("Assistants UIDs", mAssistantUids);
    appendUidsToResult("Active Assistants UIDs", mActiveAssistantUids);

    appendUidsToResult("Accessibility UIDs", mA11yUids);

Loading