audio_io_handle_t AudioPolicyService::getInput(audio_source_t inputSource, uint32_t samplingRate, audio_format_t format, audio_channel_mask_t channelMask, int audioSession, audio_input_flags_t flags) { if (mAudioPolicyManager == NULL) { return 0; } // already checked by client, but double-check in case the client wrapper is bypassed if (inputSource >= AUDIO_SOURCE_CNT && inputSource != AUDIO_SOURCE_HOTWORD) { return 0; } if ((inputSource == AUDIO_SOURCE_HOTWORD) && !captureHotwordAllowed()) { return 0; } audio_io_handle_t input; sp<AudioPolicyEffects>audioPolicyEffects; { Mutex::Autolock _l(mLock); // the audio_in_acoustics_t parameter is ignored by get_input() input = mAudioPolicyManager->getInput(inputSource, samplingRate, format, channelMask, (audio_session_t)audioSession, flags); audioPolicyEffects = mAudioPolicyEffects; } if (input == 0) { return input; } if (audioPolicyEffects != 0) { // create audio pre processors according to input source status_t status = audioPolicyEffects->addInputEffects(input, inputSource, audioSession); if (status != NO_ERROR && status != ALREADY_EXISTS) { ALOGW("Failed to add effects on input %d", input); } } return input; }
status_t AudioPolicyService::getInputForAttr(const audio_attributes_t *attr, audio_io_handle_t *input, audio_session_t session, uid_t uid, uint32_t samplingRate, audio_format_t format, audio_channel_mask_t channelMask, audio_input_flags_t flags, audio_port_handle_t selectedDeviceId) { if (mAudioPolicyManager == NULL) { return NO_INIT; } // already checked by client, but double-check in case the client wrapper is bypassed if (attr->source >= AUDIO_SOURCE_CNT && attr->source != AUDIO_SOURCE_HOTWORD && attr->source != AUDIO_SOURCE_FM_TUNER) { return BAD_VALUE; } if ((attr->source == AUDIO_SOURCE_HOTWORD) && !captureHotwordAllowed()) { return BAD_VALUE; } sp<AudioPolicyEffects>audioPolicyEffects; status_t status; AudioPolicyInterface::input_type_t inputType; // if the caller is us, trust the specified uid if (IPCThreadState::self()->getCallingPid() != getpid_cached || uid == (uid_t)-1) { uid_t newclientUid = IPCThreadState::self()->getCallingUid(); if (uid != (uid_t)-1 && uid != newclientUid) { ALOGW("%s uid %d tried to pass itself off as %d", __FUNCTION__, newclientUid, uid); } uid = newclientUid; } { Mutex::Autolock _l(mLock); // the audio_in_acoustics_t parameter is ignored by get_input() status = mAudioPolicyManager->getInputForAttr(attr, input, session, uid, samplingRate, format, channelMask, flags, selectedDeviceId, &inputType); audioPolicyEffects = mAudioPolicyEffects; if (status == NO_ERROR) { // enforce permission (if any) required for each type of input switch (inputType) { case AudioPolicyInterface::API_INPUT_LEGACY: break; case AudioPolicyInterface::API_INPUT_TELEPHONY_RX: // FIXME: use the same permission as for remote submix for now. case AudioPolicyInterface::API_INPUT_MIX_CAPTURE: if (!captureAudioOutputAllowed()) { ALOGE("getInputForAttr() permission denied: capture not allowed"); status = PERMISSION_DENIED; } break; case AudioPolicyInterface::API_INPUT_MIX_EXT_POLICY_REROUTE: if (!modifyAudioRoutingAllowed()) { ALOGE("getInputForAttr() permission denied: modify audio routing not allowed"); status = PERMISSION_DENIED; } break; case AudioPolicyInterface::API_INPUT_INVALID: default: LOG_ALWAYS_FATAL("getInputForAttr() encountered an invalid input type %d", (int)inputType); } } if (status != NO_ERROR) { if (status == PERMISSION_DENIED) { mAudioPolicyManager->releaseInput(*input, session); } return status; } } if (audioPolicyEffects != 0) { // create audio pre processors according to input source status_t status = audioPolicyEffects->addInputEffects(*input, attr->source, session); if (status != NO_ERROR && status != ALREADY_EXISTS) { ALOGW("Failed to add effects on input %d", *input); } } return NO_ERROR; }