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

Commit 7b1fd230 authored by Scott Randolph's avatar Scott Randolph
Browse files

setPreferedDevice considered ahead of Dynamic Rules

Audio policy is updated to allow an applications expressed preference
for a specific audio device to override dynamic policy rules, just as it
already overrides the rest of the policy engine's logic.
This is important in allowing 1st party automotive applications to
explicitly targets specific audio buses.

Test: build and run on Mojave
Change-Id: I482b74cba40f6d6150f69856769a998158a54a94
parent a0d38208
Loading
Loading
Loading
Loading
+32 −18
Original line number Diff line number Diff line
@@ -813,11 +813,22 @@ status_t AudioPolicyManager::getOutputForAttr(const audio_attributes_t *attr,
        stream_type_to_audio_attributes(*stream, &attributes);
    }

    ALOGV("getOutputForAttr() usage=%d, content=%d, tag=%s flags=%08x"
            " session %d selectedDeviceId %d",
            attributes.usage, attributes.content_type, attributes.tags, attributes.flags,
            session, *selectedDeviceId);

    // TODO: check for existing client for this port ID
    if (*portId == AUDIO_PORT_HANDLE_NONE) {
        *portId = AudioPort::getNextUniqueId();
    }

    // First check for explicit routing (eg. setPreferredDevice)
    sp<DeviceDescriptor> deviceDesc;
    if (*selectedDeviceId != AUDIO_PORT_HANDLE_NONE) {
        deviceDesc = mAvailableOutputDevices.getDeviceFromId(*selectedDeviceId);
    } else {
        // If no explict route, is there a matching dynamic policy that applies?
        sp<SwAudioOutputDescriptor> desc;
        if (mPolicyMixes.getOutputForAttr(attributes, uid, desc) == NO_ERROR) {
            ALOG_ASSERT(desc != 0, "Invalid desc returned by getOutputForAttr");
@@ -829,23 +840,26 @@ status_t AudioPolicyManager::getOutputForAttr(const audio_attributes_t *attr,
            ALOGV("getOutputForAttr() returns output %d", *output);
            return NO_ERROR;
        }

        // Virtual sources must always be dynamicaly or explicitly routed
        if (attributes.usage == AUDIO_USAGE_VIRTUAL_SOURCE) {
            ALOGW("getOutputForAttr() no policy mix found for usage AUDIO_USAGE_VIRTUAL_SOURCE");
            return BAD_VALUE;
        }
    }

    ALOGV("getOutputForAttr() usage=%d, content=%d, tag=%s flags=%08x"
            " session %d selectedDeviceId %d",
            attributes.usage, attributes.content_type, attributes.tags, attributes.flags,
            session, *selectedDeviceId);
    // Virtual sources must always be dynamicaly or explicitly routed
    if (attributes.usage == AUDIO_USAGE_VIRTUAL_SOURCE) {
        ALOGW("getOutputForAttr() no policy mix found for usage AUDIO_USAGE_VIRTUAL_SOURCE");
        return BAD_VALUE;
    }

    *stream = streamTypefromAttributesInt(&attributes);

    // Explicit routing?
    sp<DeviceDescriptor> deviceDesc;
    if (*selectedDeviceId != AUDIO_PORT_HANDLE_NONE) {
        deviceDesc = mAvailableOutputDevices.getDeviceFromId(*selectedDeviceId);
    }
    // TODO:  Should this happen only if an explicit route is active?
    // the previous code structure meant that this would always happen which
    // would appear to result in adding a null deviceDesc when not using an
    // explicit route.  Is that the intended and necessary behavior?
    mOutputRoutes.addRoute(session, *stream, SessionRoute::SOURCE_TYPE_NA, deviceDesc, uid);

    routing_strategy strategy = (routing_strategy) getStrategyForAttr(&attributes);