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

Commit a20c4e9c authored by Eric Laurent's avatar Eric Laurent
Browse files

AudioFlinger: add audio session for device effects

Add specific audio session ID for effects applied to a
particular audio device.
Device specific effects will be attached to a particular audio sink or
source device identified by its unique audio port ID and will all use
this same session ID.
Only one session of this type exists on a given playback or record
thread.
All effects in this session apply to the same device ID and are created/released
when the routing (audio patch) of this thread output or input stream is updated.

Bug: 136294538
Test: make

Change-Id: I4e3a55ed1244b918429dd9e217b6efecc1ec6449
Merged-In: I4e3a55ed1244b918429dd9e217b6efecc1ec6449
parent e5f01a7d
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -167,7 +167,7 @@ status_t AudioEffect::set(const effect_uuid_t *type,
    ALOGV("set() %p OK effect: %s id: %d status %d enabled %d pid %d", this, mDescriptor.name, mId,
            mStatus, mEnabled, mClientPid);

    if (mSessionId > AUDIO_SESSION_OUTPUT_MIX) {
    if (!audio_is_global_session(mSessionId)) {
        AudioSystem::acquireAudioSessionId(mSessionId, mClientPid);
    }

@@ -180,7 +180,7 @@ AudioEffect::~AudioEffect()
    ALOGV("Destructor %p", this);

    if (mStatus == NO_ERROR || mStatus == ALREADY_EXISTS) {
        if (mSessionId > AUDIO_SESSION_OUTPUT_MIX) {
        if (!audio_is_global_session(mSessionId)) {
            AudioSystem::releaseAudioSessionId(mSessionId, mClientPid);
        }
        if (mIEffect != NULL) {
+10 −3
Original line number Diff line number Diff line
@@ -174,12 +174,19 @@ bool modifyAudioRoutingAllowed() {
}

bool modifyDefaultAudioEffectsAllowed() {
    return modifyDefaultAudioEffectsAllowed(
        IPCThreadState::self()->getCallingPid(), IPCThreadState::self()->getCallingUid());
}

bool modifyDefaultAudioEffectsAllowed(pid_t pid, uid_t uid) {
    if (isAudioServerUid(IPCThreadState::self()->getCallingUid())) return true;

    static const String16 sModifyDefaultAudioEffectsAllowed(
            "android.permission.MODIFY_DEFAULT_AUDIO_EFFECTS");
    // IMPORTANT: Use PermissionCache - not a runtime permission and may not change.
    bool ok = PermissionCache::checkCallingPermission(sModifyDefaultAudioEffectsAllowed);

    if (!ok) ALOGE("android.permission.MODIFY_DEFAULT_AUDIO_EFFECTS");
    bool ok = PermissionCache::checkPermission(sModifyDefaultAudioEffectsAllowed, pid, uid);
    ALOGE_IF(!ok, "%s(): android.permission.MODIFY_DEFAULT_AUDIO_EFFECTS denied for uid %d",
            __func__, uid);
    return ok;
}

+1 −0
Original line number Diff line number Diff line
@@ -85,6 +85,7 @@ bool captureHotwordAllowed(const String16& opPackageName, pid_t pid, uid_t uid);
bool settingsAllowed();
bool modifyAudioRoutingAllowed();
bool modifyDefaultAudioEffectsAllowed();
bool modifyDefaultAudioEffectsAllowed(pid_t pid, uid_t uid);
bool dumpAllowed();
bool modifyPhoneStateAllowed(pid_t pid, uid_t uid);
bool bypassInterruptionPolicyAllowed(pid_t pid, uid_t uid);
+10 −3
Original line number Diff line number Diff line
@@ -2944,7 +2944,7 @@ std::vector<sp<AudioFlinger::EffectModule>> AudioFlinger::purgeStaleEffects_l()
        Mutex::Autolock _l(t->mLock);
        for (size_t j = 0; j < t->mEffectChains.size(); j++) {
            sp<EffectChain> ec = t->mEffectChains[j];
            if (ec->sessionId() > AUDIO_SESSION_OUTPUT_MIX) {
            if (!audio_is_global_session(ec->sessionId())) {
                chains.push(ec);
            }
        }
@@ -3346,6 +3346,13 @@ sp<IEffect> AudioFlinger::createEffect(
            lStatus = BAD_VALUE;
            goto Exit;
        }
    } else if (sessionId == AUDIO_SESSION_DEVICE) {
        if (!modifyDefaultAudioEffectsAllowed(pid, callingUid)) {
            ALOGE("%s: device effect permission denied for uid %d", __func__, callingUid);
            lStatus = PERMISSION_DENIED;
            goto Exit;
        }
        //TODO: add check on device ID when added to arguments
    } else {
        // general sessionId.

@@ -3381,7 +3388,7 @@ sp<IEffect> AudioFlinger::createEffect(
        // check recording permission for visualizer
        if ((memcmp(&desc.type, SL_IID_VISUALIZATION, sizeof(effect_uuid_t)) == 0) &&
            // TODO: Do we need to start/stop op - i.e. is there recording being performed?
            !recordingAllowed(opPackageName, pid, IPCThreadState::self()->getCallingUid())) {
            !recordingAllowed(opPackageName, pid, callingUid)) {
            lStatus = PERMISSION_DENIED;
            goto Exit;
        }
@@ -3479,7 +3486,7 @@ sp<IEffect> AudioFlinger::createEffect(
        sp<Client> client = registerPid(pid);

        // create effect on selected output thread
        bool pinned = (sessionId > AUDIO_SESSION_OUTPUT_MIX) && isSessionAcquired_l(sessionId);
        bool pinned = !audio_is_global_session(sessionId) && isSessionAcquired_l(sessionId);
        handle = thread->createEffect_l(client, effectClient, priority, sessionId,
                &desc, enabled, &lStatus, pinned);
        if (lStatus != NO_ERROR && lStatus != ALREADY_EXISTS) {
+2 −4
Original line number Diff line number Diff line
@@ -637,7 +637,7 @@ status_t AudioFlinger::EffectModule::configure()
    mConfig.outputCfg.bufferProvider.releaseBuffer = NULL;
    mConfig.inputCfg.accessMode = EFFECT_BUFFER_ACCESS_READ;
    // Insert effect:
    // - in session AUDIO_SESSION_OUTPUT_MIX or AUDIO_SESSION_OUTPUT_STAGE,
    // - in global sessions (e.g AUDIO_SESSION_OUTPUT_MIX),
    // always overwrites output buffer: input buffer == output buffer
    // - in other sessions:
    //      last effect in the chain accumulates in output buffer: input buffer != output buffer
@@ -2063,14 +2063,12 @@ void AudioFlinger::EffectChain::process_l()
        ALOGW("process_l(): cannot promote mixer thread");
        return;
    }
    bool isGlobalSession = (mSessionId == AUDIO_SESSION_OUTPUT_MIX) ||
            (mSessionId == AUDIO_SESSION_OUTPUT_STAGE);
    // never process effects when:
    // - on an OFFLOAD thread
    // - no more tracks are on the session and the effect tail has been rendered
    bool doProcess = (thread->type() != ThreadBase::OFFLOAD)
                  && (thread->type() != ThreadBase::MMAP);
    if (!isGlobalSession) {
    if (!audio_is_global_session(mSessionId)) {
        bool tracksOnSession = (trackCnt() != 0);

        if (!tracksOnSession && mTailBufferCount == 0) {
Loading