示例#1
0
status_t AudioPolicyManager::stopOutput(audio_io_handle_t output, AudioSystem::stream_type stream, int session)
{
    LOGV("stopOutput() output %d, stream %d", output, stream);
    ssize_t index = mOutputs.indexOfKey(output);
    if (index < 0) {
        LOGW("stopOutput() unknow output %d", output);
        return BAD_VALUE;
    }

    AudioOutputDescriptor *outputDesc = mOutputs.valueAt(index);
    routing_strategy strategy = AudioPolicyManagerBase::getStrategy((AudioSystem::stream_type)stream);

    // handle special case for sonification while in call
    if (isInCall()) {
        AudioPolicyManagerBase::handleIncallSonification(stream, false, false);
    }

    if (outputDesc->mRefCount[stream] > 0) {
        // decrement usage count of this stream on the output
        outputDesc->changeRefCount(stream, -1);
        // store time at which the last music track was stopped - see computeVolume()
        if (stream == AudioSystem::MUSIC) {
            outputDesc->mStopTime[stream] = systemTime();
           // mMusicStopTime = systemTime();
        }

#ifdef WITH_QCOM_LPA
        uint32_t newDevice = AudioPolicyManagerBase::getNewDevice(mHardwareOutput, false);

        if(newDevice == 0 && mLPADecodeOutput != -1) {
            newDevice = AudioPolicyManagerBase::getNewDevice(mLPADecodeOutput, false);
        }

        setOutputDevice(output, newDevice);
#else
        setOutputDevice(output, AudioPolicyManagerBase::getNewDevice(output));
#endif

#ifdef WITH_A2DP
        if (mA2dpOutput != 0 && !a2dpUsedForSonification() &&
                (strategy == STRATEGY_SONIFICATION || strategy == STRATEGY_ENFORCED_AUDIBLE)) {
            setStrategyMute(STRATEGY_MEDIA,
                            false,
                            mA2dpOutput,
                            mOutputs.valueFor(mHardwareOutput)->mLatency*2);
        }
#endif
        if (output != mHardwareOutput) {
            setOutputDevice(mHardwareOutput, AudioPolicyManagerBase::getNewDevice(mHardwareOutput), true);
        }
        return NO_ERROR;
    } else {
        LOGW("stopOutput() refcount is already 0 for output %d", output);
        return INVALID_OPERATION;
    }
}
示例#2
0
status_t AudioPolicyManager::startOutput(audio_io_handle_t output, AudioSystem::stream_type stream, int session)
{
    LOGV("startOutput() output %d, stream %d", output, stream);
    ssize_t index = mOutputs.indexOfKey(output);
    if (index < 0) {
        LOGW("startOutput() unknow output %d", output);
        return BAD_VALUE;
    }

    AudioOutputDescriptor *outputDesc = mOutputs.valueAt(index);
    routing_strategy strategy = getStrategy((AudioSystem::stream_type)stream);

#ifdef WITH_A2DP
    if (mA2dpOutput != 0  && !a2dpUsedForSonification() &&
            (strategy == STRATEGY_SONIFICATION || strategy == STRATEGY_ENFORCED_AUDIBLE)) {
        setStrategyMute(STRATEGY_MEDIA, true, mA2dpOutput);
    }
#endif

    // incremenent usage count for this stream on the requested output:
    // NOTE that the usage count is the same for duplicated output and hardware output which is
    // necassary for a correct control of hardware output routing by startOutput() and stopOutput()
    outputDesc->changeRefCount(stream, 1);
#ifdef FM_RADIO
#ifdef WITH_QCOM_LPA
    if ((stream == AudioSystem::FM && output == mA2dpOutput) || output == mLPADecodeOutput)
        setOutputDevice(output, AudioPolicyManagerBase::getNewDevice(output), true);
    else
        setOutputDevice(output, AudioPolicyManagerBase::getNewDevice(output));
#else
    if (stream == AudioSystem::FM && output == mA2dpOutput)
        setOutputDevice(output, AudioPolicyManagerBase::getNewDevice(output), true);
    else
        setOutputDevice(output, AudioPolicyManagerBase::getNewDevice(output));
#endif
#else
#ifdef WITH_QCOM_LPA
    if (output == mLPADecodeOutput)
        setOutputDevice(output, AudioPolicyManagerBase::getNewDevice(output), true);
    else
        setOutputDevice(output, AudioPolicyManagerBase::getNewDevice(output));
#else
    setOutputDevice(output, AudioPolicyManagerBase::getNewDevice(output));
#endif
#endif

    // handle special case for sonification while in call
    if (isInCall()) {
        AudioPolicyManagerBase::handleIncallSonification(stream, true, false);
    }

    // apply volume rules for current stream and device if necessary
    checkAndSetVolume(stream, mStreams[stream].mIndexCur, output, outputDesc->device());

    return NO_ERROR;
}
uint32_t AudioPolicyManager::getDeviceForStrategy(routing_strategy strategy, bool fromCache)
{
    uint32_t device = 0;

    if (fromCache) {
        LOGV("getDeviceForStrategy() from cache strategy %d, device %x", strategy, mDeviceForStrategy[strategy]);
        return mDeviceForStrategy[strategy];
    }

    switch (strategy) {
    case STRATEGY_DTMF:
        if (mPhoneState != AudioSystem::MODE_IN_CALL) {
            // when off call, DTMF strategy follows the same rules as MEDIA strategy
            device = getDeviceForStrategy(STRATEGY_MEDIA, false);
            break;
        }
        // when in call, DTMF and PHONE strategies follow the same rules
        // FALL THROUGH

    case STRATEGY_PHONE:
        // for phone strategy, we first consider the forced use and then the available devices by order
        // of priority
        switch (mForceUse[AudioSystem::FOR_COMMUNICATION]) {
        case AudioSystem::FORCE_BT_SCO:
            if (mPhoneState != AudioSystem::MODE_IN_CALL || strategy != STRATEGY_DTMF) {
                device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_CARKIT;
                if (device) break;
            }
            device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_HEADSET;
            if (device) break;
            device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO;
            if (device) break;
            // if SCO device is requested but no SCO device is available, fall back to default case
            // FALL THROUGH

        default:    // FORCE_NONE
            device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADPHONE;
            if (device) break;
            device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADSET;
            if (device) break;
#ifdef WITH_A2DP
            // when not in a phone call, phone strategy should route STREAM_VOICE_CALL to A2DP
            if (mPhoneState != AudioSystem::MODE_IN_CALL) {
                device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP;
                if (device) break;
                device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES;
                if (device) break;
            }
#endif
            if (mPhoneState == AudioSystem::MODE_RINGTONE)
                device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_SPEAKER;
            if (device) break;

            device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_EARPIECE;
            if (device == 0) {
                LOGE("getDeviceForStrategy() earpiece device not found");
            }
            break;

        case AudioSystem::FORCE_SPEAKER:
            if (mPhoneState != AudioSystem::MODE_IN_CALL || strategy != STRATEGY_DTMF) {
                device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_CARKIT;
                if (device) break;
            }
#ifdef WITH_A2DP
            // when not in a phone call, phone strategy should route STREAM_VOICE_CALL to
            // A2DP speaker when forcing to speaker output
            if (mPhoneState != AudioSystem::MODE_IN_CALL) {
                device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER;
                if (device) break;
            }
#endif
            if (mPhoneState == AudioSystem::MODE_IN_CALL) {
                device = DEVICE_OUT_SPEAKER_IN_CALL;
                if (device) break;
            }

            device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_SPEAKER;
            if (device == 0) {
                LOGE("getDeviceForStrategy() speaker device not found");
            }
            break;
        }
    break;

    case STRATEGY_SONIFICATION:
        device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_SPEAKER;
        if (device == 0) {
            LOGE("getDeviceForStrategy() speaker device not found");
        }
        // The second device used for sonification is the same as the device used by media strategy
        // FALL THROUGH

    case STRATEGY_MEDIA_SONIFICATION:
        // If incall, just select the STRATEGY_PHONE device: The rest of the behavior is handled by
        // handleIncallSonification().
        if (mPhoneState == AudioSystem::MODE_IN_CALL) {
            device = getDeviceForStrategy(STRATEGY_PHONE, false);
            break;
        }

    case STRATEGY_MEDIA: {
#ifdef HAVE_FM_RADIO
        uint32_t device2 = 0;
        if (mForceUse[AudioSystem::FOR_MEDIA] == AudioSystem::FORCE_SPEAKER) {
            device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_SPEAKER;
        }
        if (device2 == 0) {
            device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_AUX_DIGITAL;
        }
#else
        uint32_t device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_AUX_DIGITAL;
#endif
#ifdef WITH_A2DP
        if (mA2dpOutput != 0) {
            if (strategy == STRATEGY_SONIFICATION && !a2dpUsedForSonification()) {
                break;
            }
            if (device2 == 0) {
                device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP;
            }
            if (device2 == 0) {
                device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES;
            }
            if (device2 == 0) {
                device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER;
            }
        }
#endif
        if (device2 == 0) {
            device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADPHONE;
        }
        if (device2 == 0) {
            device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADSET;
        }
        if (device2 == 0) {
            device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_SPEAKER;
        }
        if (device2 == 0) {
            device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_EARPIECE;
        }

        // device is DEVICE_OUT_SPEAKER if we come from case STRATEGY_SONIFICATION, 0 otherwise
        device = device ? device : device2;
        if (device == 0) {
            LOGE("getDeviceForStrategy() speaker device not found");
        }

#ifdef HAVE_FM_RADIO
        if (mAvailableOutputDevices & AudioSystem::DEVICE_OUT_FM_ALL) {
                device |= AudioSystem::DEVICE_OUT_FM_ALL;
        }
#endif

        // Do not play media stream if in call and the requested device would change the hardware
        // output routing
        if (mPhoneState == AudioSystem::MODE_IN_CALL &&
            !AudioSystem::isA2dpDevice((AudioSystem::audio_devices)device) &&
            device != getDeviceForStrategy(STRATEGY_PHONE)) {
            device = 0;
            LOGV("getDeviceForStrategy() incompatible media and phone devices");
        }
        } break;

    default:
        LOGW("getDeviceForStrategy() unknown strategy: %d", strategy);
        break;
    }

    LOGV("getDeviceForStrategy() strategy %d, device %x", strategy, device);
    return device;
}
uint32_t AudioPolicyManagerALSA::getDeviceForStrategy(routing_strategy strategy, bool fromCache)
{
    uint32_t device = 0;

    if (fromCache) {
      LOGV("getDeviceForStrategy() from cache strategy %d, device %x", strategy, mDeviceForStrategy[strategy]);
      return mDeviceForStrategy[strategy];
    }

    switch (strategy) {
      case STRATEGY_DTMF:
           if (mPhoneState != AudioSystem::MODE_IN_CALL) {
           // when off call, DTMF strategy follows the same rules as MEDIA strategy
              device = getDeviceForStrategy(STRATEGY_MEDIA, false);
              break;
           }
           // when in call, DTMF and PHONE strategies follow the same rules
           // FALL THROUGH
      case STRATEGY_PHONE:
           // for phone strategy, we first consider the forced use and then the available devices by order
           // of priority
           switch (mForceUse[AudioSystem::FOR_COMMUNICATION]) {
           case AudioSystem::FORCE_BT_SCO:
              if (mPhoneState != AudioSystem::MODE_IN_CALL || strategy != STRATEGY_DTMF) {
                  device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_CARKIT;
                  if (device) break;
              }
              device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_HEADSET;
              if (device) break;
              device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO;
              if (device) break;
              // if SCO device is requested but no SCO device is available, fall back to default case
              // FALL THROUGH

           default:	// FORCE_NONE
              device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADPHONE;
              if (device) break;
              device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADSET;
              if (device) break;
#ifdef WITH_A2DP
              // when not in a phone call, phone strategy should route STREAM_VOICE_CALL to A2DP
              if (mPhoneState != AudioSystem::MODE_IN_CALL) {
                  device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP;
                  if (device) break;
                  device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES;
                  if (device) break;
              }
#endif
              device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_EARPIECE;
              if (device == 0) {
                  LOGE("getDeviceForStrategy() earpiece device not found");
              }
              break;

        case AudioSystem::FORCE_SPEAKER:
              if (mPhoneState != AudioSystem::MODE_IN_CALL || strategy != STRATEGY_DTMF) {
                    device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_CARKIT;
                    if (device) break;
              }
#ifdef WITH_A2DP
              // when not in a phone call, phone strategy should route STREAM_VOICE_CALL to
              // A2DP speaker when forcing to speaker output
              if (mPhoneState != AudioSystem::MODE_IN_CALL) {
                   device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER;
                   if (device) break;
              }
#endif
              device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_SPEAKER;
              if (device == 0) {
                   LOGE("getDeviceForStrategy() speaker device not found");
              }
              break;
//[email protected]  myoung_loopback
		 case AudioSystem::FORCE_RCV:
			device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_EARPIECE;
            if (device == 0) {
                LOGE("getDeviceForStrategy() earpiece device not found");
            }			
			break;
//myoung_loopback			
           }
         break;

         case STRATEGY_SONIFICATION:

              // If incall, just select the STRATEGY_PHONE device: The rest of the behavior is handled by
              // handleIncallSonification().
              if (mPhoneState == AudioSystem::MODE_IN_CALL) {
                  device = getDeviceForStrategy(STRATEGY_PHONE, false);
                  break;
              }
              device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_SPEAKER;
              if (device == 0) {
                  LOGE("getDeviceForStrategy() speaker device not found");
              }
             // The second device used for sonification is the same as the device used by media strategy
             // FALL THROUGH

        case STRATEGY_MEDIA: {
             uint32_t device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_AUX_DIGITAL;

//jungsoo1221.lee - Folder Test -------------------
	     if(mForceUse[AudioSystem::FOR_MEDIA] == AudioSystem::FORCE_RCV){
            device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_EARPIECE;
		}
//------------------------------------------
#ifdef WITH_A2DP
             if (mA2dpOutput != 0) {
                if (strategy == STRATEGY_SONIFICATION && !a2dpUsedForSonification()) {
                    break;
                }
                if (device2 == 0) {
                    device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP;
                }
                if (device2 == 0) {
                    device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES;
                }
                if (device2 == 0) {
                    device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER;
                }
            }
#endif
            // Once SCO connection is connected, map strategy_media to
            // SCO headset for music streaming. BT SCO MM_UL use case
            if (mForceUse[AudioSystem::FOR_COMMUNICATION] == AudioSystem::FORCE_BT_SCO) {
                 if (device2 == 0) {
                    device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_CARKIT;
                 }
                 if (device2 == 0) {
                    device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_HEADSET;
                 }
                 if (device2 == 0) {
                    device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO;
                 }
           }
             if (device2 == 0) {
                 device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADPHONE;
             }
             if (device2 == 0) {
                 device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADSET;
             }
/* LGE_CHANGE_S [email protected] 2010.01.27 */   
#ifdef SUPPORT_FM_ANALOG
            if (device2 == 0) {
                device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_FM_TRANSMIT;
            }
#endif // SUPPORT_FM_ANALOG
/* LGE_CHANGE_E [email protected] 2010.01.27 */   
            if (device2 == 0) {
                device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_SPEAKER;
            }

            // device is DEVICE_OUT_SPEAKER if we come from case STRATEGY_SONIFICATION, 0 otherwise
            device |= device2;
            if (device == 0) {
                 LOGE("getDeviceForStrategy() speaker device not found");
            }
            } break;

         default:
            LOGW("getDeviceForStrategy() unknown strategy: %d", strategy);
              break;
         }

         LOGV("getDeviceForStrategy() strategy %d, device %x", strategy, device);
         return device;
}