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

Commit 850206ed authored by Eric Laurent's avatar Eric Laurent Committed by Android (Google) Code Review
Browse files

Merge "PatchPanel: do not use setParameters() internally." into mnc-dev

parents 94ce2185 054d9d3d
Loading
Loading
Loading
Loading
+9 −3
Original line number Diff line number Diff line
@@ -1013,6 +1013,14 @@ bool AudioFlinger::streamMute(audio_stream_type_t stream) const
    return streamMute_l(stream);
}


void AudioFlinger::broacastParametersToRecordThreads_l(const String8& keyValuePairs)
{
    for (size_t i = 0; i < mRecordThreads.size(); i++) {
        mRecordThreads.valueAt(i)->setParameters(keyValuePairs);
    }
}

status_t AudioFlinger::setParameters(audio_io_handle_t ioHandle, const String8& keyValuePairs)
{
    ALOGV("setParameters(): io %d, keyvalue %s, calling pid %d",
@@ -1087,9 +1095,7 @@ status_t AudioFlinger::setParameters(audio_io_handle_t ioHandle, const String8&
            int value;
            if ((param.getInt(String8(AudioParameter::keyRouting), value) == NO_ERROR) &&
                    (value != 0)) {
                for (size_t i = 0; i < mRecordThreads.size(); i++) {
                    mRecordThreads.valueAt(i)->setParameters(keyValuePairs);
                }
                broacastParametersToRecordThreads_l(keyValuePairs);
            }
        }
    }
+1 −0
Original line number Diff line number Diff line
@@ -590,6 +590,7 @@ private:
                // Return true if the effect was found in mOrphanEffectChains, false otherwise.
                bool            updateOrphanEffectChains(const sp<EffectModule>& effect);

                void broacastParametersToRecordThreads_l(const String8& keyValuePairs);

    // AudioStreamIn is immutable, so their fields are const.
    // For emphasis, we could also make all pointers to them be "const *",
+36 −96
Original line number Diff line number Diff line
@@ -274,7 +274,6 @@ status_t AudioFlinger::PatchPanel::createAudioPatch(const struct audio_patch *pa
                    goto exit;
                }
            } else {
                if (audioHwDevice->version() >= AUDIO_DEVICE_API_VERSION_3_0) {
                if (patch->sinks[0].type == AUDIO_PORT_TYPE_MIX) {
                    sp<ThreadBase> thread = audioflinger->checkRecordThread_l(
                                                              patch->sinks[0].ext.mix.handle);
@@ -286,6 +285,11 @@ status_t AudioFlinger::PatchPanel::createAudioPatch(const struct audio_patch *pa
                    }
                    status = thread->sendCreateAudioPatchConfigEvent(patch, &halHandle);
                } else {
                    if (audioHwDevice->version() < AUDIO_DEVICE_API_VERSION_3_0) {
                        status = INVALID_OPERATION;
                        goto exit;
                    }

                    audio_hw_device_t *hwDevice = audioHwDevice->hwDevice();
                    status = hwDevice->create_audio_patch(hwDevice,
                                                           patch->num_sources,
@@ -294,38 +298,6 @@ status_t AudioFlinger::PatchPanel::createAudioPatch(const struct audio_patch *pa
                                                           patch->sinks,
                                                           &halHandle);
                }
                } else {
                    if (patch->sinks[0].type != AUDIO_PORT_TYPE_MIX) {
                        status = INVALID_OPERATION;
                        goto exit;
                    }

                    sp<ThreadBase> thread = audioflinger->checkRecordThread_l(
                                                                    patch->sinks[0].ext.mix.handle);
                    if (thread == 0) {
                        ALOGW("createAudioPatch() bad capture I/O handle %d",
                                                                    patch->sinks[0].ext.mix.handle);
                        status = BAD_VALUE;
                        goto exit;
                    }
                    char *address;
                    if (strcmp(patch->sources[0].ext.device.address, "") != 0) {
                        address = audio_device_address_to_parameter(
                                                            patch->sources[0].ext.device.type,
                                                            patch->sources[0].ext.device.address);
                    } else {
                        address = (char *)calloc(1, 1);
                    }
                    AudioParameter param = AudioParameter(String8(address));
                    free(address);
                    param.addInt(String8(AUDIO_PARAMETER_STREAM_ROUTING),
                                 (int)patch->sources[0].ext.device.type);
                    param.addInt(String8(AUDIO_PARAMETER_STREAM_INPUT_SOURCE),
                                                     (int)patch->sinks[0].ext.mix.usecase.source);
                    ALOGV("createAudioPatch() AUDIO_PORT_TYPE_DEVICE setParameters %s",
                                                                      param.toString().string());
                    status = thread->setParameters(param.toString());
                }
            }
        } break;
        case AUDIO_PORT_TYPE_MIX: {
@@ -337,6 +309,7 @@ status_t AudioFlinger::PatchPanel::createAudioPatch(const struct audio_patch *pa
                goto exit;
            }
            // limit to connections between devices and output streams
            audio_devices_t type = AUDIO_DEVICE_NONE;
            for (unsigned int i = 0; i < patch->num_sinks; i++) {
                if (patch->sinks[i].type != AUDIO_PORT_TYPE_DEVICE) {
                    ALOGW("createAudioPatch() invalid sink type %d for mix source",
@@ -349,8 +322,8 @@ status_t AudioFlinger::PatchPanel::createAudioPatch(const struct audio_patch *pa
                    status = BAD_VALUE;
                    goto exit;
                }
                type |= patch->sinks[i].ext.device.type;
            }
            AudioHwDevice *audioHwDevice = audioflinger->mAudioHwDevs.valueAt(index);
            sp<ThreadBase> thread =
                            audioflinger->checkPlaybackThread_l(patch->sources[0].ext.mix.handle);
            if (thread == 0) {
@@ -359,28 +332,14 @@ status_t AudioFlinger::PatchPanel::createAudioPatch(const struct audio_patch *pa
                status = BAD_VALUE;
                goto exit;
            }
            if (audioHwDevice->version() >= AUDIO_DEVICE_API_VERSION_3_0) {
                status = thread->sendCreateAudioPatchConfigEvent(patch, &halHandle);
            } else {
                audio_devices_t type = AUDIO_DEVICE_NONE;
                for (unsigned int i = 0; i < patch->num_sinks; i++) {
                    type |= patch->sinks[i].ext.device.type;
                }
                char *address;
                if (strcmp(patch->sinks[0].ext.device.address, "") != 0) {
                    //FIXME: we only support address on first sink with HAL version < 3.0
                    address = audio_device_address_to_parameter(
                                                                patch->sinks[0].ext.device.type,
                                                                patch->sinks[0].ext.device.address);
                } else {
                    address = (char *)calloc(1, 1);
                }
                AudioParameter param = AudioParameter(String8(address));
                free(address);
            if (thread == audioflinger->primaryPlaybackThread_l()) {
                AudioParameter param = AudioParameter();
                param.addInt(String8(AUDIO_PARAMETER_STREAM_ROUTING), (int)type);
                status = thread->setParameters(param.toString());

                audioflinger->broacastParametersToRecordThreads_l(param.toString());
            }

            status = thread->sendCreateAudioPatchConfigEvent(patch, &halHandle);
        } break;
        default:
            status = BAD_VALUE;
@@ -581,8 +540,6 @@ status_t AudioFlinger::PatchPanel::releaseAudioPatch(audio_patch_handle_t handle
                break;
            }

            AudioHwDevice *audioHwDevice = audioflinger->mAudioHwDevs.valueAt(index);
            if (audioHwDevice->version() >= AUDIO_DEVICE_API_VERSION_3_0) {
            if (patch->sinks[0].type == AUDIO_PORT_TYPE_MIX) {
                sp<ThreadBase> thread = audioflinger->checkRecordThread_l(
                                                                patch->sinks[0].ext.mix.handle);
@@ -594,23 +551,13 @@ status_t AudioFlinger::PatchPanel::releaseAudioPatch(audio_patch_handle_t handle
                }
                status = thread->sendReleaseAudioPatchConfigEvent(removedPatch->mHalHandle);
            } else {
                    audio_hw_device_t *hwDevice = audioHwDevice->hwDevice();
                    status = hwDevice->release_audio_patch(hwDevice, removedPatch->mHalHandle);
                }
            } else {
                sp<ThreadBase> thread = audioflinger->checkRecordThread_l(
                                                                    patch->sinks[0].ext.mix.handle);
                if (thread == 0) {
                    ALOGW("releaseAudioPatch() bad capture I/O handle %d",
                                                                  patch->sinks[0].ext.mix.handle);
                    status = BAD_VALUE;
                AudioHwDevice *audioHwDevice = audioflinger->mAudioHwDevs.valueAt(index);
                if (audioHwDevice->version() < AUDIO_DEVICE_API_VERSION_3_0) {
                    status = INVALID_OPERATION;
                    break;
                }
                AudioParameter param;
                param.addInt(String8(AUDIO_PARAMETER_STREAM_ROUTING), 0);
                ALOGV("releaseAudioPatch() AUDIO_PORT_TYPE_DEVICE setParameters %s",
                                                                      param.toString().string());
                status = thread->setParameters(param.toString());
                audio_hw_device_t *hwDevice = audioHwDevice->hwDevice();
                status = hwDevice->release_audio_patch(hwDevice, removedPatch->mHalHandle);
            }
        } break;
        case AUDIO_PORT_TYPE_MIX: {
@@ -629,14 +576,7 @@ status_t AudioFlinger::PatchPanel::releaseAudioPatch(audio_patch_handle_t handle
                status = BAD_VALUE;
                break;
            }
            AudioHwDevice *audioHwDevice = audioflinger->mAudioHwDevs.valueAt(index);
            if (audioHwDevice->version() >= AUDIO_DEVICE_API_VERSION_3_0) {
            status = thread->sendReleaseAudioPatchConfigEvent(removedPatch->mHalHandle);
            } else {
                AudioParameter param;
                param.addInt(String8(AUDIO_PARAMETER_STREAM_ROUTING), 0);
                status = thread->setParameters(param.toString());
            }
        } break;
        default:
            status = BAD_VALUE;
+169 −36
Original line number Diff line number Diff line
@@ -2933,21 +2933,78 @@ status_t AudioFlinger::PlaybackThread::getTimestamp_l(AudioTimestamp& timestamp)
    return INVALID_OPERATION;
}

status_t AudioFlinger::MixerThread::createAudioPatch_l(const struct audio_patch *patch,
                                                          audio_patch_handle_t *handle)
{
    // if !&IDLE, holds the FastMixer state to restore after new parameters processed
    FastMixerState::Command previousCommand = FastMixerState::HOT_IDLE;
    if (mFastMixer != 0) {
        FastMixerStateQueue *sq = mFastMixer->sq();
        FastMixerState *state = sq->begin();
        if (!(state->mCommand & FastMixerState::IDLE)) {
            previousCommand = state->mCommand;
            state->mCommand = FastMixerState::HOT_IDLE;
            sq->end();
            sq->push(FastMixerStateQueue::BLOCK_UNTIL_ACKED);
        } else {
            sq->end(false /*didModify*/);
        }
    }
    status_t status = PlaybackThread::createAudioPatch_l(patch, handle);

    if (!(previousCommand & FastMixerState::IDLE)) {
        ALOG_ASSERT(mFastMixer != 0);
        FastMixerStateQueue *sq = mFastMixer->sq();
        FastMixerState *state = sq->begin();
        ALOG_ASSERT(state->mCommand == FastMixerState::HOT_IDLE);
        state->mCommand = previousCommand;
        sq->end();
        sq->push(FastMixerStateQueue::BLOCK_UNTIL_PUSHED);
    }

    return status;
}

status_t AudioFlinger::PlaybackThread::createAudioPatch_l(const struct audio_patch *patch,
                                                          audio_patch_handle_t *handle)
{
    status_t status = NO_ERROR;
    if (mOutput->audioHwDev->version() >= AUDIO_DEVICE_API_VERSION_3_0) {

    // store new device and send to effects
    audio_devices_t type = AUDIO_DEVICE_NONE;
    for (unsigned int i = 0; i < patch->num_sinks; i++) {
        type |= patch->sinks[i].ext.device.type;
    }
        mOutDevice = type;

#ifdef ADD_BATTERY_DATA
    // when changing the audio output device, call addBatteryData to notify
    // the change
    if (mOutDevice != type) {
        uint32_t params = 0;
        // check whether speaker is on
        if (type & AUDIO_DEVICE_OUT_SPEAKER) {
            params |= IMediaPlayerService::kBatteryDataSpeakerOn;
        }

        audio_devices_t deviceWithoutSpeaker
            = AUDIO_DEVICE_OUT_ALL & ~AUDIO_DEVICE_OUT_SPEAKER;
        // check if any other device (except speaker) is on
        if (type & deviceWithoutSpeaker) {
            params |= IMediaPlayerService::kBatteryDataOtherAudioDeviceOn;
        }

        if (params != 0) {
            addBatteryData(params);
        }
    }
#endif

    for (size_t i = 0; i < mEffectChains.size(); i++) {
            mEffectChains[i]->setDevice_l(mOutDevice);
        mEffectChains[i]->setDevice_l(type);
    }
    mOutDevice = type;

    if (mOutput->audioHwDev->version() >= AUDIO_DEVICE_API_VERSION_3_0) {
        audio_hw_device_t *hwDevice = mOutput->audioHwDev->hwDevice();
        status = hwDevice->create_audio_patch(hwDevice,
                                               patch->num_sources,
@@ -2956,19 +3013,71 @@ status_t AudioFlinger::PlaybackThread::createAudioPatch_l(const struct audio_pat
                                               patch->sinks,
                                               handle);
    } else {
        ALOG_ASSERT(false, "createAudioPatch_l() called on a pre 3.0 HAL");
        char *address;
        if (strcmp(patch->sinks[0].ext.device.address, "") != 0) {
            //FIXME: we only support address on first sink with HAL version < 3.0
            address = audio_device_address_to_parameter(
                                                        patch->sinks[0].ext.device.type,
                                                        patch->sinks[0].ext.device.address);
        } else {
            address = (char *)calloc(1, 1);
        }
        AudioParameter param = AudioParameter(String8(address));
        free(address);
        param.addInt(String8(AUDIO_PARAMETER_STREAM_ROUTING), (int)type);
        status = mOutput->stream->common.set_parameters(&mOutput->stream->common,
                param.toString().string());
        *handle = AUDIO_PATCH_HANDLE_NONE;
    }
    return status;
}

status_t AudioFlinger::MixerThread::releaseAudioPatch_l(const audio_patch_handle_t handle)
{
    // if !&IDLE, holds the FastMixer state to restore after new parameters processed
    FastMixerState::Command previousCommand = FastMixerState::HOT_IDLE;
    if (mFastMixer != 0) {
        FastMixerStateQueue *sq = mFastMixer->sq();
        FastMixerState *state = sq->begin();
        if (!(state->mCommand & FastMixerState::IDLE)) {
            previousCommand = state->mCommand;
            state->mCommand = FastMixerState::HOT_IDLE;
            sq->end();
            sq->push(FastMixerStateQueue::BLOCK_UNTIL_ACKED);
        } else {
            sq->end(false /*didModify*/);
        }
    }

    status_t status = PlaybackThread::releaseAudioPatch_l(handle);

    if (!(previousCommand & FastMixerState::IDLE)) {
        ALOG_ASSERT(mFastMixer != 0);
        FastMixerStateQueue *sq = mFastMixer->sq();
        FastMixerState *state = sq->begin();
        ALOG_ASSERT(state->mCommand == FastMixerState::HOT_IDLE);
        state->mCommand = previousCommand;
        sq->end();
        sq->push(FastMixerStateQueue::BLOCK_UNTIL_PUSHED);
    }

    return status;
}

status_t AudioFlinger::PlaybackThread::releaseAudioPatch_l(const audio_patch_handle_t handle)
{
    status_t status = NO_ERROR;

    mOutDevice = AUDIO_DEVICE_NONE;

    if (mOutput->audioHwDev->version() >= AUDIO_DEVICE_API_VERSION_3_0) {
        audio_hw_device_t *hwDevice = mOutput->audioHwDev->hwDevice();
        status = hwDevice->release_audio_patch(hwDevice, handle);
    } else {
        ALOG_ASSERT(false, "releaseAudioPatch_l() called on a pre 3.0 HAL");
        AudioParameter param;
        param.addInt(String8(AUDIO_PARAMETER_STREAM_ROUTING), 0);
        status = mOutput->stream->common.set_parameters(&mOutput->stream->common,
                param.toString().string());
    }
    return status;
}
@@ -6775,7 +6884,7 @@ status_t AudioFlinger::RecordThread::createAudioPatch_l(const struct audio_patch
                                                          audio_patch_handle_t *handle)
{
    status_t status = NO_ERROR;
    if (mInput->audioHwDev->version() >= AUDIO_DEVICE_API_VERSION_3_0) {

    // store new device and send to effects
    mInDevice = patch->sources[0].ext.device.type;
    for (size_t i = 0; i < mEffectChains.size(); i++) {
@@ -6802,6 +6911,7 @@ status_t AudioFlinger::RecordThread::createAudioPatch_l(const struct audio_patch
        }
    }

    if (mInput->audioHwDev->version() >= AUDIO_DEVICE_API_VERSION_3_0) {
        audio_hw_device_t *hwDevice = mInput->audioHwDev->hwDevice();
        status = hwDevice->create_audio_patch(hwDevice,
                                               patch->num_sources,
@@ -6810,19 +6920,42 @@ status_t AudioFlinger::RecordThread::createAudioPatch_l(const struct audio_patch
                                               patch->sinks,
                                               handle);
    } else {
        ALOG_ASSERT(false, "createAudioPatch_l() called on a pre 3.0 HAL");
        char *address;
        if (strcmp(patch->sources[0].ext.device.address, "") != 0) {
            address = audio_device_address_to_parameter(
                                                patch->sources[0].ext.device.type,
                                                patch->sources[0].ext.device.address);
        } else {
            address = (char *)calloc(1, 1);
        }
        AudioParameter param = AudioParameter(String8(address));
        free(address);
        param.addInt(String8(AUDIO_PARAMETER_STREAM_ROUTING),
                     (int)patch->sources[0].ext.device.type);
        param.addInt(String8(AUDIO_PARAMETER_STREAM_INPUT_SOURCE),
                                         (int)patch->sinks[0].ext.mix.usecase.source);
        status = mInput->stream->common.set_parameters(&mInput->stream->common,
                param.toString().string());
        *handle = AUDIO_PATCH_HANDLE_NONE;
    }

    return status;
}

status_t AudioFlinger::RecordThread::releaseAudioPatch_l(const audio_patch_handle_t handle)
{
    status_t status = NO_ERROR;

    mInDevice = AUDIO_DEVICE_NONE;

    if (mInput->audioHwDev->version() >= AUDIO_DEVICE_API_VERSION_3_0) {
        audio_hw_device_t *hwDevice = mInput->audioHwDev->hwDevice();
        status = hwDevice->release_audio_patch(hwDevice, handle);
    } else {
        ALOG_ASSERT(false, "releaseAudioPatch_l() called on a pre 3.0 HAL");
        AudioParameter param;
        param.addInt(String8(AUDIO_PARAMETER_STREAM_ROUTING), 0);
        status = mInput->stream->common.set_parameters(&mInput->stream->common,
                param.toString().string());
    }
    return status;
}
+4 −0
Original line number Diff line number Diff line
@@ -865,6 +865,10 @@ protected:
    virtual     void        threadLoop_removeTracks(const Vector< sp<Track> >& tracksToRemove);
    virtual     uint32_t    correctLatency_l(uint32_t latency) const;

    virtual     status_t    createAudioPatch_l(const struct audio_patch *patch,
                                   audio_patch_handle_t *handle);
    virtual     status_t    releaseAudioPatch_l(const audio_patch_handle_t handle);

                AudioMixer* mAudioMixer;    // normal mixer
private:
                // one-time initialization, no locks required