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 Original line 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);
        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
    // TODO: check for existing client for this port ID
    if (*portId == AUDIO_PORT_HANDLE_NONE) {
    if (*portId == AUDIO_PORT_HANDLE_NONE) {
        *portId = AudioPort::getNextUniqueId();
        *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;
        sp<SwAudioOutputDescriptor> desc;
        if (mPolicyMixes.getOutputForAttr(attributes, uid, desc) == NO_ERROR) {
        if (mPolicyMixes.getOutputForAttr(attributes, uid, desc) == NO_ERROR) {
            ALOG_ASSERT(desc != 0, "Invalid desc returned by getOutputForAttr");
            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);
            ALOGV("getOutputForAttr() returns output %d", *output);
            return NO_ERROR;
            return NO_ERROR;
        }
        }

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


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


    *stream = streamTypefromAttributesInt(&attributes);
    *stream = streamTypefromAttributesInt(&attributes);


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


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