// Figure out which devices we should allow a user to write to. void PlatformUdisks::findDevices() { int i = 0; if (!udiskEnabled()) { QMessageBox msgBox; msgBox.setText(QObject::tr("You don't have UDisks support.")); msgBox.exec(); return; } // First get the list of disks QDBusConnection connection = QDBusConnection::systemBus(); QDBusMessage message; message = QDBusMessage::createMethodCall("org.freedesktop.UDisks", "/org/freedesktop/UDisks", "org.freedesktop.UDisks", "EnumerateDevices"); QDBusReply<QList<QDBusObjectPath> > reply = connection.call(message); if (!reply.isValid()) { qDebug() << "Failure: " << reply.error(); return; } QList<QDBusObjectPath> list = reply.value(); QStringList devList; QRegExp reg("[0-9]+$"); // Ignore partition slices for (i = 0; i < list.size(); ++i) if (!list.at(i).path().contains(reg)) devList << list.at(i).path(); QStringList diskList; // Safe mode (the default) only handles USB devices if (!mUnsafe) { for (i = 0; i < devList.size(); ++i) if (isUSB(devList.at(i))) diskList << devList.at(i); } else { diskList = devList; } for (i = 0; i < diskList.size(); ++i) { getNewDevice(diskList.at(i)); } return; }
void AudioPolicyManager::setPhoneState(int state) { ALOGV("setPhoneState() state %d", state); audio_devices_t newDevice = AUDIO_DEVICE_NONE; if (state < 0 || state >= AudioSystem::NUM_MODES) { ALOGW("setPhoneState() invalid state %d", state); return; } if (state == mPhoneState) { ALOGW("setPhoneState() setting same state %d", state); return; } // if leaving call state, handle special case of active streams // pertaining to sonification strategy see handleIncallSonification() if (isInCall()) { ALOGV("setPhoneState() in call state management: new state is %d", state); for (int stream = 0; stream < AudioSystem::NUM_STREAM_TYPES; stream++) { handleIncallSonification(stream, false, true); } } // store previous phone state for management of sonification strategy below int oldState = mPhoneState; mPhoneState = state; bool force = false; // are we entering or starting a call if (!isStateInCall(oldState) && isStateInCall(state)) { ALOGV(" Entering call in setPhoneState()"); // force routing command to audio hardware when starting a call // even if no device change is needed force = true; } else if (isStateInCall(oldState) && !isStateInCall(state)) { ALOGV(" Exiting call in setPhoneState()"); // force routing command to audio hardware when exiting a call // even if no device change is needed force = true; } else if (isStateInCall(state) && (state != oldState)) { ALOGV(" Switching between telephony and VoIP in setPhoneState()"); // force routing command to audio hardware when switching between telephony and VoIP // even if no device change is needed force = true; } // check for device and output changes triggered by new phone state newDevice = getNewDevice(mPrimaryOutput, false /*fromCache*/); checkA2dpSuspend(); checkOutputForAllStrategies(); updateDevicesAndOutputs(); AudioOutputDescriptor *hwOutputDesc = mOutputs.valueFor(mPrimaryOutput); // force routing command to audio hardware when ending call // even if no device change is needed if (isStateInCall(oldState) && newDevice == AUDIO_DEVICE_NONE) { newDevice = hwOutputDesc->device(); } // when changing from ring tone to in call mode, mute the ringing tone // immediately and delay the route change to avoid sending the ring tone // tail into the earpiece or headset. int delayMs = 0; if (isStateInCall(state) && oldState == AudioSystem::MODE_RINGTONE) { // delay the device change command by twice the output latency to have some margin // and be sure that audio buffers not yet affected by the mute are out when // we actually apply the route change delayMs = hwOutputDesc->mLatency*2; setStreamMute(AudioSystem::RING, true, mPrimaryOutput); } if (isStateInCall(state)) { for (size_t i = 0; i < mOutputs.size(); i++) { AudioOutputDescriptor *desc = mOutputs.valueAt(i); //take the biggest latency for all outputs if (delayMs < desc->mLatency*2) { delayMs = desc->mLatency*2; } //mute STRATEGY_MEDIA on all outputs if (desc->strategyRefCount(STRATEGY_MEDIA) != 0) { setStrategyMute(STRATEGY_MEDIA, true, mOutputs.keyAt(i)); setStrategyMute(STRATEGY_MEDIA, false, mOutputs.keyAt(i), MUTE_TIME_MS, getDeviceForStrategy(STRATEGY_MEDIA, true /*fromCache*/)); } } } // Ignore the delay to enable voice call on this target as the enabling the // voice call has enough delay to make sure the ringtone audio completely // played out if (state == AudioSystem::MODE_IN_CALL && oldState == AudioSystem::MODE_RINGTONE) { delayMs = 40; } // change routing is necessary setOutputDevice(mPrimaryOutput, newDevice, force, delayMs); // if entering in call state, handle special case of active streams // pertaining to sonification strategy see handleIncallSonification() if (isStateInCall(state)) { ALOGV("setPhoneState() in call state management: new state is %d", state); // unmute the ringing tone after a sufficient delay if it was muted before // setting output device above if (oldState == AudioSystem::MODE_RINGTONE) { setStreamMute(AudioSystem::RING, false, mPrimaryOutput, MUTE_TIME_MS); } for (int stream = 0; stream < AudioSystem::NUM_STREAM_TYPES; stream++) { handleIncallSonification(stream, true, true); } } // Flag that ringtone volume must be limited to music volume until we exit MODE_RINGTONE if (state == AudioSystem::MODE_RINGTONE && isStreamActive(AudioSystem::MUSIC, SONIFICATION_HEADSET_MUSIC_DELAY)) { mLimitRingtoneVolume = true; } else { mLimitRingtoneVolume = false; } }
status_t AudioPolicyManager::setDeviceConnectionState(AudioSystem::audio_devices device, AudioSystem::device_connection_state state, const char *device_address) { LOGV("setDeviceConnectionState() device: %x, state %d, address %s", device, state, device_address); // connect/disconnect only 1 device at a time if (AudioSystem::popCount(device) != 1) return BAD_VALUE; if (strlen(device_address) >= MAX_DEVICE_ADDRESS_LEN) { LOGE("setDeviceConnectionState() invalid address: %s", device_address); return BAD_VALUE; } // handle output devices if (AudioSystem::isOutputDevice(device)) { #ifndef WITH_A2DP if (AudioSystem::isA2dpDevice(device)) { LOGE("setDeviceConnectionState() invalid device: %x", device); return BAD_VALUE; } #endif switch (state) { // handle output device connection case AudioSystem::DEVICE_STATE_AVAILABLE: if (mAvailableOutputDevices & device) { LOGW("setDeviceConnectionState() device already connected: %x", device); return INVALID_OPERATION; } LOGV("setDeviceConnectionState() connecting device %x", device); // register new device as available mAvailableOutputDevices |= device; #ifdef WITH_A2DP // handle A2DP device connection if (AudioSystem::isA2dpDevice(device)) { status_t status = handleA2dpConnection(device, device_address); if (status != NO_ERROR) { mAvailableOutputDevices &= ~device; return status; } } else #endif { if (AudioSystem::isBluetoothScoDevice(device)) { LOGV("setDeviceConnectionState() BT SCO device, address %s", device_address); // keep track of SCO device address mScoDeviceAddress = String8(device_address, MAX_DEVICE_ADDRESS_LEN); } } break; // handle output device disconnection case AudioSystem::DEVICE_STATE_UNAVAILABLE: { if (!(mAvailableOutputDevices & device)) { LOGW("setDeviceConnectionState() device not connected: %x", device); return INVALID_OPERATION; } LOGV("setDeviceConnectionState() disconnecting device %x", device); // remove device from available output devices mAvailableOutputDevices &= ~device; #ifdef WITH_A2DP // handle A2DP device disconnection if (AudioSystem::isA2dpDevice(device)) { status_t status = handleA2dpDisconnection(device, device_address); if (status != NO_ERROR) { mAvailableOutputDevices |= device; return status; } } else #endif { if (AudioSystem::isBluetoothScoDevice(device)) { mScoDeviceAddress = ""; } } } break; default: LOGE("setDeviceConnectionState() invalid state: %x", state); return BAD_VALUE; } #ifdef HAVE_FM_RADIO if (device == AudioSystem::DEVICE_OUT_FM) { AudioOutputDescriptor *out = mOutputs.valueFor(mHardwareOutput); if (state == AudioSystem::DEVICE_STATE_AVAILABLE) { out->changeRefCount(AudioSystem::FM, 1); if (out->mRefCount[AudioSystem::FM] > 0) mpClientInterface->setParameters(0, String8("fm_on=1")); } else { out->changeRefCount(AudioSystem::FM, -1); if (out->mRefCount[AudioSystem::FM] <= 0) mpClientInterface->setParameters(0, String8("fm_off=1")); } } #endif // request routing change if necessary uint32_t newDevice = getNewDevice(mHardwareOutput, false); #ifdef WITH_A2DP checkA2dpSuspend(); checkOutputForAllStrategies(); // A2DP outputs must be closed after checkOutputForAllStrategies() is executed if (state == AudioSystem::DEVICE_STATE_UNAVAILABLE && AudioSystem::isA2dpDevice(device)) { closeA2dpOutputs(); } #endif updateDeviceForStrategy(); setOutputDevice(mHardwareOutput, newDevice); if (device == AudioSystem::DEVICE_OUT_WIRED_HEADSET) { device = AudioSystem::DEVICE_IN_WIRED_HEADSET; } else if (device == AudioSystem::DEVICE_OUT_BLUETOOTH_SCO || device == AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_HEADSET || device == AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_CARKIT) { device = AudioSystem::DEVICE_IN_BLUETOOTH_SCO_HEADSET; } else { return NO_ERROR; } } // handle input devices if (AudioSystem::isInputDevice(device)) { switch (state) { // handle input device connection case AudioSystem::DEVICE_STATE_AVAILABLE: { if (mAvailableInputDevices & device) { LOGW("setDeviceConnectionState() device already connected: %d", device); return INVALID_OPERATION; } mAvailableInputDevices |= device; } break; // handle input device disconnection case AudioSystem::DEVICE_STATE_UNAVAILABLE: { if (!(mAvailableInputDevices & device)) { LOGW("setDeviceConnectionState() device not connected: %d", device); return INVALID_OPERATION; } mAvailableInputDevices &= ~device; } break; default: LOGE("setDeviceConnectionState() invalid state: %x", state); return BAD_VALUE; } audio_io_handle_t activeInput = getActiveInput(); if (activeInput != 0) { AudioInputDescriptor *inputDesc = mInputs.valueFor(activeInput); uint32_t newDevice = getDeviceForInputSource(inputDesc->mInputSource); if (newDevice != inputDesc->mDevice) { LOGV("setDeviceConnectionState() changing device from %x to %x for input %d", inputDesc->mDevice, newDevice, activeInput); inputDesc->mDevice = newDevice; AudioParameter param = AudioParameter(); param.addInt(String8(AudioParameter::keyRouting), (int)newDevice); mpClientInterface->setParameters(activeInput, param.toString()); } } return NO_ERROR; } LOGW("setDeviceConnectionState() invalid device: %x", device); return BAD_VALUE; }
status_t AudioPolicyManagerALSA::setDeviceConnectionState(AudioSystem::audio_devices device, AudioSystem::device_connection_state state, const char *device_address) { LOGV("setDeviceConnectionState() device: %x, state %d, address %s", device, state, device_address); // connect/disconnect only 1 device at a time if (AudioSystem::popCount(device) != 1) return BAD_VALUE; if (strlen(device_address) >= MAX_DEVICE_ADDRESS_LEN) { LOGE("setDeviceConnectionState() invalid address: %s", device_address); return BAD_VALUE; } // handle output devices if (AudioSystem::isOutputDevice(device)) { #ifndef WITH_A2DP if (AudioSystem::isA2dpDevice(device)) { LOGE("setDeviceConnectionState() invalid device: %x", device); return BAD_VALUE; } #endif switch (state) { // handle output device connection case AudioSystem::DEVICE_STATE_AVAILABLE: if (mAvailableOutputDevices & device) { LOGW("setDeviceConnectionState() device already connected: %x", device); return INVALID_OPERATION; } LOGV("setDeviceConnectionState() connecting device %x", device); // register new device as available mAvailableOutputDevices |= device; #ifdef WITH_A2DP // handle A2DP device connection if (AudioSystem::isA2dpDevice(device)) { status_t status = handleA2dpConnection(device, device_address); if (status != NO_ERROR) { mAvailableOutputDevices &= ~device; return status; } } else #endif { if (AudioSystem::isBluetoothScoDevice(device)) { LOGV("setDeviceConnectionState() BT SCO device, address %s", device_address); // keep track of SCO device address mScoDeviceAddress = String8(device_address, MAX_DEVICE_ADDRESS_LEN); #ifdef WITH_A2DP if (mA2dpOutput != 0 && mPhoneState != AudioSystem::MODE_NORMAL) { mpClientInterface->suspendOutput(mA2dpOutput); } #endif } } break; // handle output device disconnection case AudioSystem::DEVICE_STATE_UNAVAILABLE: { if (!(mAvailableOutputDevices & device)) { LOGW("setDeviceConnectionState() device not connected: %x", device); return INVALID_OPERATION; } LOGV("setDeviceConnectionState() disconnecting device %x", device); // remove device from available output devices mAvailableOutputDevices &= ~device; #ifdef WITH_A2DP // handle A2DP device disconnection if (AudioSystem::isA2dpDevice(device)) { status_t status = handleA2dpDisconnection(device, device_address); if (status != NO_ERROR) { mAvailableOutputDevices |= device; return status; } } else #endif { if (AudioSystem::isBluetoothScoDevice(device)) { mScoDeviceAddress = ""; #ifdef WITH_A2DP if (mA2dpOutput != 0 && mPhoneState != AudioSystem::MODE_NORMAL) { mpClientInterface->restoreOutput(mA2dpOutput); } #endif } } } break; default: LOGE("setDeviceConnectionState() invalid state: %x", state); return BAD_VALUE; } // request routing change if necessary uint32_t newDevice = getNewDevice(mHardwareOutput, false); // force routing if device disconnection occurs when stream is stopped if ((newDevice == 0) && (state == AudioSystem::DEVICE_STATE_UNAVAILABLE)) newDevice = getDeviceForStrategy(STRATEGY_MEDIA, false); #ifdef WITH_A2DP //+++ KBNAM_PORTING /* org checkOutputForAllStrategies(newDevice); */ checkOutputForAllStrategies(); //--- // A2DP outputs must be closed after checkOutputForAllStrategies() is executed if (state == AudioSystem::DEVICE_STATE_UNAVAILABLE && AudioSystem::isA2dpDevice(device)) { closeA2dpOutputs(); } #endif updateDeviceForStrategy(); setOutputDevice(mHardwareOutput, newDevice); if (device == AudioSystem::DEVICE_OUT_WIRED_HEADSET) { device = AudioSystem::DEVICE_IN_WIRED_HEADSET; } else if (device == AudioSystem::DEVICE_OUT_BLUETOOTH_SCO || device == AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_HEADSET || device == AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_CARKIT) { device = AudioSystem::DEVICE_IN_BLUETOOTH_SCO_HEADSET; } else { return NO_ERROR; } } // handle input devices if (AudioSystem::isInputDevice(device)) { switch (state) { // handle input device connection case AudioSystem::DEVICE_STATE_AVAILABLE: { if (mAvailableInputDevices & device) { LOGW("setDeviceConnectionState() device already connected: %d", device); return INVALID_OPERATION; } mAvailableInputDevices |= device; } break; // handle input device disconnection case AudioSystem::DEVICE_STATE_UNAVAILABLE: { if (!(mAvailableInputDevices & device)) { LOGW("setDeviceConnectionState() device not connected: %d", device); return INVALID_OPERATION; } mAvailableInputDevices &= ~device; } break; default: LOGE("setDeviceConnectionState() invalid state: %x", state); return BAD_VALUE; } audio_io_handle_t activeInput = getActiveInput(); if (activeInput != 0) { AudioInputDescriptor *inputDesc = mInputs.valueFor(activeInput); uint32_t newDevice = getDeviceForInputSource(inputDesc->mInputSource); if (newDevice != inputDesc->mDevice) { LOGV("setDeviceConnectionState() changing device from %x to %x for input %d", inputDesc->mDevice, newDevice, activeInput); inputDesc->mDevice = newDevice; AudioParameter param = AudioParameter(); param.addInt(String8(AudioParameter::keyRouting), (int)newDevice); mpClientInterface->setParameters(activeInput, param.toString()); } } else { /* LGE_CHANGE_S [email protected] 2010.01.27 */ #ifdef SUPPORT_FM_ANALOG if (device == AudioSystem::DEVICE_IN_FM_ANALOG) { routing_strategy strategy = getStrategy((AudioSystem::stream_type)3); uint32_t curOutdevice = getDeviceForStrategy(strategy); /* If A2DP headset is connected then route FM to Headset */ if (curOutdevice == AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP || curOutdevice == AudioSystem::DEVICE_OUT_BLUETOOTH_SCO) { curOutdevice = AudioSystem::DEVICE_OUT_WIRED_HEADSET; } if (state) { // routing_strategy strategy = getStrategy((AudioSystem::stream_type)3); // uint32_t curOutdevice = getDeviceForStrategy(strategy); /* Get the new input descriptor for FM Rx In */ mfmInput = getFMInput(AUDIO_SOURCE_FM_ANALOG,8000,1, AudioSystem::CHANNEL_IN_MONO,(AudioSystem::audio_in_acoustics)7); /* Forcely open the current output device again for * FM Rx playback path to open */ LOGV("curOutdevice = %x",curOutdevice); setOutputDevice(mHardwareOutput, curOutdevice, true); /* Tell the audio flinger playback thread that * FM Rx is active */ mpClientInterface->setFMRxActive(true); } else { int newDevice=0; AudioParameter param = AudioParameter(); param.addInt(String8(AudioParameter::keyRouting), (int)newDevice); /* Change the input device from FM to default before releasing Input */ mpClientInterface->setParameters(mfmInput, param.toString()); param.addInt(String8("fm_off"), (int)newDevice); /* Close the capture handle */ mpClientInterface->setParameters(mfmInput, param.toString()); /* Release the input descriptor for FM Rx In */ releaseInput(mfmInput); /* Close the playback handle */ mpClientInterface->setParameters(mHardwareOutput, param.toString()); /* Tell the audio flinger playback thread that * FM Rx is not active now. */ mpClientInterface->setFMRxActive(false); } } #endif // SUPPORT_FM_ANALOG /* LGE_CHANGE_E [email protected] 2010.01.27 */ } return NO_ERROR; } LOGW("setDeviceConnectionState() invalid device: %x", device); return BAD_VALUE; }
status_t AudioPolicyManager::checkAndSetVolume(int stream, int index, audio_io_handle_t output, uint32_t device, int delayMs, bool force) { #ifdef WITH_QCOM_LPA // do not change actual stream volume if the stream is muted if ((mOutputs.valueFor(output)->mMuteCount[stream] != 0 && output != mLPADecodeOutput) || (output == mLPADecodeOutput && stream == mLPAStreamType && mLPAMuted == true)) { #else if (mOutputs.valueFor(output)->mMuteCount[stream] != 0) { #endif LOGV("checkAndSetVolume() stream %d muted count %d", stream, mOutputs.valueFor(output)->mMuteCount[stream]); return NO_ERROR; } // do not change in call volume if bluetooth is connected and vice versa if ((stream == AudioSystem::VOICE_CALL && mForceUse[AudioSystem::FOR_COMMUNICATION] == AudioSystem::FORCE_BT_SCO) || (stream == AudioSystem::BLUETOOTH_SCO && mForceUse[AudioSystem::FOR_COMMUNICATION] != AudioSystem::FORCE_BT_SCO)) { LOGV("checkAndSetVolume() cannot set stream %d volume with force use = %d for comm", stream, mForceUse[AudioSystem::FOR_COMMUNICATION]); return INVALID_OPERATION; } float volume = computeVolume(stream, index, output, device); // do not set volume if the float value did not change if ((volume != mOutputs.valueFor(output)->mCurVolume[stream]) || (stream == AudioSystem::VOICE_CALL) #ifdef FM_RADIO || (stream == AudioSystem::FM) #endif || force) { mOutputs.valueFor(output)->mCurVolume[stream] = volume; LOGD("setStreamVolume() for output %d stream %d, volume %f, delay %d", output, stream, volume, delayMs); if (stream == AudioSystem::VOICE_CALL || stream == AudioSystem::DTMF || stream == AudioSystem::BLUETOOTH_SCO) { float voiceVolume = -1.0; // offset value to reflect actual hardware volume that never reaches 0 // 1% corresponds roughly to first step in VOICE_CALL stream volume setting (see AudioService.java) volume = 0.01 + 0.99 * volume; if (stream == AudioSystem::VOICE_CALL) { voiceVolume = (float)index/(float)mStreams[stream].mIndexMax; } else if (stream == AudioSystem::BLUETOOTH_SCO) { voiceVolume = 1.0; } if (voiceVolume >= 0 && output == mHardwareOutput) { mpClientInterface->setVoiceVolume(voiceVolume, delayMs); } #ifdef FM_RADIO } else if (stream == AudioSystem::FM) { float fmVolume = -1.0; fmVolume = computeVolume(stream, index, output, device); if (fmVolume >= 0) { if(output == mHardwareOutput) mpClientInterface->setFmVolume(fmVolume, delayMs); else if(output == mA2dpOutput) mpClientInterface->setStreamVolume((AudioSystem::stream_type)stream, volume, output, delayMs); } return NO_ERROR; #endif } mpClientInterface->setStreamVolume((AudioSystem::stream_type)stream, volume, output, delayMs); } return NO_ERROR; } void AudioPolicyManager::setStreamMute(int stream, bool on, audio_io_handle_t output, int delayMs) { StreamDescriptor &streamDesc = mStreams[stream]; AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output); LOGV("setStreamMute() stream %d, mute %d, output %d, mMuteCount %d", stream, on, output, outputDesc->mMuteCount[stream]); if (on) { #ifdef WITH_QCOM_LPA if ((outputDesc->mMuteCount[stream] == 0 && output != mLPADecodeOutput) || (output == mLPADecodeOutput && stream == mLPAStreamType && false == mLPAMuted)) { #else if (outputDesc->mMuteCount[stream] == 0) { #endif if (streamDesc.mCanBeMuted) { checkAndSetVolume(stream, 0, output, outputDesc->device(), delayMs); } } #ifdef WITH_QCOM_LPA // increment mMuteCount after calling checkAndSetVolume() so that volume change is not ignored if(output == mLPADecodeOutput) { if(stream == mLPAStreamType && false == mLPAMuted) { mLPAMuted = true; } } else { #endif outputDesc->mMuteCount[stream]++; #ifdef WITH_QCOM_LPA } #endif } else { #ifdef WITH_QCOM_LPA if ((outputDesc->mMuteCount[stream] == 0 && output != mLPADecodeOutput) || (output == mLPADecodeOutput && stream == mLPAStreamType && false == mLPAMuted)) { #else if (outputDesc->mMuteCount[stream] == 0) { #endif LOGW("setStreamMute() unmuting non muted stream!"); return; } #ifdef WITH_QCOM_LPA if(output == mLPADecodeOutput) { if(stream == mLPAStreamType && true == mLPAMuted) { mLPAMuted = false; checkAndSetVolume(stream, streamDesc.mIndexCur, output, outputDesc->device(), delayMs); } } else { if(--outputDesc->mMuteCount[stream] == 0){ checkAndSetVolume(stream, streamDesc.mIndexCur, output, outputDesc->device(), delayMs); } } #else if(--outputDesc->mMuteCount[stream] == 0){ checkAndSetVolume(stream, streamDesc.mIndexCur, output, outputDesc->device(), delayMs); } #endif } } void AudioPolicyManager::setForceUse(AudioSystem::force_use usage, AudioSystem::forced_config config) { LOGD("setForceUse() usage %d, config %d, mPhoneState %d", usage, config, mPhoneState); bool forceVolumeReeval = false; switch(usage) { case AudioSystem::FOR_COMMUNICATION: if (config != AudioSystem::FORCE_SPEAKER && config != AudioSystem::FORCE_BT_SCO && config != AudioSystem::FORCE_NONE) { LOGW("setForceUse() invalid config %d for FOR_COMMUNICATION", config); return; } mForceUse[usage] = config; break; case AudioSystem::FOR_MEDIA: if (config != AudioSystem::FORCE_HEADPHONES && config != AudioSystem::FORCE_BT_A2DP && config != AudioSystem::FORCE_WIRED_ACCESSORY && config != AudioSystem::FORCE_NONE && config != AudioSystem::FORCE_SPEAKER) { LOGW("setForceUse() invalid config %d for FOR_MEDIA", config); return; } mForceUse[usage] = config; { uint32_t device = getDeviceForStrategy(STRATEGY_MEDIA); setOutputDevice(mHardwareOutput, device); } break; case AudioSystem::FOR_RECORD: if (config != AudioSystem::FORCE_BT_SCO && config != AudioSystem::FORCE_WIRED_ACCESSORY && config != AudioSystem::FORCE_NONE) { LOGW("setForceUse() invalid config %d for FOR_RECORD", config); return; } mForceUse[usage] = config; break; case AudioSystem::FOR_DOCK: if (config != AudioSystem::FORCE_NONE && config != AudioSystem::FORCE_BT_CAR_DOCK && config != AudioSystem::FORCE_BT_DESK_DOCK && config != AudioSystem::FORCE_WIRED_ACCESSORY) { LOGW("setForceUse() invalid config %d for FOR_DOCK", config); } forceVolumeReeval = true; mForceUse[usage] = config; break; default: LOGW("setForceUse() invalid usage %d", usage); break; } // check for device and output changes triggered by new phone state uint32_t newDevice = getNewDevice(mHardwareOutput, false); #ifdef WITH_A2DP checkOutputForAllStrategies(); #endif updateDeviceForStrategy(); setOutputDevice(mHardwareOutput, newDevice); if (forceVolumeReeval) { applyStreamVolumes(mHardwareOutput, newDevice); } } uint32_t AudioPolicyManager::getDeviceForInputSource(int inputSource) { uint32_t device; switch(inputSource) { case AUDIO_SOURCE_DEFAULT: case AUDIO_SOURCE_MIC: case AUDIO_SOURCE_VOICE_RECOGNITION: if (mForceUse[AudioSystem::FOR_RECORD] == AudioSystem::FORCE_BT_SCO && mAvailableInputDevices & AudioSystem::DEVICE_IN_BLUETOOTH_SCO_HEADSET) { device = AudioSystem::DEVICE_IN_BLUETOOTH_SCO_HEADSET; } else if (mAvailableInputDevices & AudioSystem::DEVICE_IN_WIRED_HEADSET) { device = AudioSystem::DEVICE_IN_WIRED_HEADSET; #ifdef QCOM_ANC } else if (mAvailableInputDevices & AudioSystem::DEVICE_IN_ANC_HEADSET) { device = AudioSystem::DEVICE_IN_ANC_HEADSET; #endif } else { device = AudioSystem::DEVICE_IN_BUILTIN_MIC; } break; case AUDIO_SOURCE_VOICE_COMMUNICATION: device = AudioSystem::DEVICE_IN_COMMUNICATION; break; case AUDIO_SOURCE_CAMCORDER: if (hasBackMicrophone()) { device = AudioSystem::DEVICE_IN_BACK_MIC; } else { device = AudioSystem::DEVICE_IN_BUILTIN_MIC; } break; case AUDIO_SOURCE_VOICE_UPLINK: case AUDIO_SOURCE_VOICE_DOWNLINK: case AUDIO_SOURCE_VOICE_CALL: device = AudioSystem::DEVICE_IN_VOICE_CALL; break; #ifdef FM_RADIO case AUDIO_SOURCE_FM_RX: device = AudioSystem::DEVICE_IN_FM_RX; break; case AUDIO_SOURCE_FM_RX_A2DP: device = AudioSystem::DEVICE_IN_FM_RX_A2DP; break; #endif default: LOGW("getInput() invalid input source %d", inputSource); device = 0; break; } LOGV("getDeviceForInputSource()input source %d, device %08x", inputSource, device); return device; }