分析Android O的AudioPolicyService服务(二)

音频的路由策略:routing_strategy:
frameworks/av/services/audiopolicy/common/include/RoutingStrategy.h
是一个枚举类型,有11种音频路由策略,相对于android5.0系统增加了6种:

#pragma once

namespace android {

// Time in milliseconds after media stopped playing during which we consider that the
// sonification should be as unobtrusive as during the time media was playing.
#define SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY 5000

enum routing_strategy {
    STRATEGY_MEDIA,
    STRATEGY_PHONE,
    STRATEGY_SONIFICATION,
    STRATEGY_SONIFICATION_RESPECTFUL,
    STRATEGY_DTMF,
    STRATEGY_FM,
    STRATEGY_ENFORCED_AUDIBLE,
    STRATEGY_TRANSMITTED_THROUGH_SPEAKER,
    STRATEGY_ACCESSIBILITY,
    STRATEGY_REROUTING,
    NUM_STRATEGIES
};

}; //namespace android

四个文件引用到这个枚举:
frameworks/av/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h
frameworks/av/services/audiopolicy/common/managerdefinitions/include/EffectDescriptor.h
frameworks/av/services/audiopolicy/common/managerdefinitions/include/AudioSourceDescriptor.h
frameworks/av/services/audiopolicy/engine/interface/AudioPolicyManagerInterface.h

重点分析AudioPolicyManagerInterface.h文件,因为Engine.cpp应用到了这个路由策略类型,音频的路由策略类型主要是在Engine.cpp中实现切换,看如下代码:
frameworks/av/services/audiopolicy/enginedefault/src/Engine.h

    /* Copy facilities are put private to disable copy. */
    Engine(const Engine &object);
    Engine &operator=(const Engine &object);

    void setObserver(AudioPolicyManagerObserver *observer);

    status_t initCheck();

    inline bool isInCall() const
    {
        return is_state_in_call(mPhoneState);
    }
   //设置电话状态
    status_t setPhoneState(audio_mode_t mode);
    audio_mode_t getPhoneState() const
    {
        return mPhoneState;
    }
   //强制设置音频策略
    status_t setForceUse(audio_policy_force_use_t usage, audio_policy_forced_cfg_t config);
    audio_policy_forced_cfg_t getForceUse(audio_policy_force_use_t usage) const
    {
        return mForceUse[usage];
    }
   //设置默认的音频设备
    status_t setDefaultDevice(audio_devices_t device);
    //从音频流类型中获取该音频流的路由策略
    routing_strategy getStrategyForStream(audio_stream_type_t stream);
    //根据音频的用途获取该使用的路由策略
    routing_strategy getStrategyForUsage(audio_usage_t usage);
    //根据音频路由策略获取相应的输出输入设备
    audio_devices_t getDeviceForStrategy(routing_strategy strategy) const;
   //根据音频策略获取设备
    audio_devices_t getDeviceForStrategyInt(routing_strategy strategy,
            DeviceVector availableOutputDevices,
            DeviceVector availableInputDevices,
            const SwAudioOutputCollection &outputs,
            uint32_t outputDeviceTypesToIgnore) const;
    //根据输入音频获取设备
    audio_devices_t getDeviceForInputSource(audio_source_t inputSource) const;
    audio_mode_t mPhoneState;  /**< current phone state. */

    /** current forced use configuration. */
    audio_policy_forced_cfg_t mForceUse[AUDIO_POLICY_FORCE_USE_CNT];

    AudioPolicyManagerObserver *mApmObserver;
    //这里有一个mApmObserver是从AudioPolicyManager中通过setObserver传递过来的引用地址

实现在Engine.cpp文件中,
这里有枚举类型:第一个:audio_stream_type_t,是一个枚举类型的结构体,代表的是音频流:
system/media/audio/include/system/audio-base.h

typedef enum {
    AUDIO_STREAM_DEFAULT = -1, // (-1)
    AUDIO_STREAM_MIN = 0,
    AUDIO_STREAM_VOICE_CALL = 0,
    AUDIO_STREAM_SYSTEM = 1,
    AUDIO_STREAM_RING = 2,
    AUDIO_STREAM_MUSIC = 3,
    AUDIO_STREAM_ALARM = 4,
    AUDIO_STREAM_NOTIFICATION = 5,
    AUDIO_STREAM_BLUETOOTH_SCO = 6,
    AUDIO_STREAM_ENFORCED_AUDIBLE = 7,
    AUDIO_STREAM_DTMF = 8,
    AUDIO_STREAM_TTS = 9,
    AUDIO_STREAM_ACCESSIBILITY = 10,
#ifndef AUDIO_NO_SYSTEM_DECLARATIONS
    /** For dynamic policy output mixes. Only used by the audio policy */
    AUDIO_STREAM_REROUTING = 11,
    /** For audio flinger tracks volume. Only used by the audioflinger */
    AUDIO_STREAM_PATCH = 12,
#endif // AUDIO_NO_SYSTEM_DECLARATIONS
#ifdef SPRD_CUSTOM_AUDIO_POLICY
    AUDIO_STREAM_FM = 13, /* For fm stream */
#endif
} audio_stream_type_t;

还定义了好几个类型:
audio_source_t,audio_session_t,audio_format_t,audio_mode_t,audio_output_flags_t,audio_input_flags_t,audio_usage_t,audio_content_type_t,audio_port_role_t,audio_port_type_t,audio_mix_latency_class_t

引用结构
frameworks/av/services/audiopolicy/common/include/policy.h
>system/media/audio/include/system/audio.h
>system/media/audio/include/system/audio-base.h
 

根据音频流获取音频策略,这个不多说,都是没有什么逻辑可言,是一一对应的关系:
frameworks/av/services/audiopolicy/enginedefault/src/Engine.cpp

routing_strategy Engine::getStrategyForStream(audio_stream_type_t stream)
{
    // stream to strategy mapping
    switch (stream) {
    case AUDIO_STREAM_VOICE_CALL:
    case AUDIO_STREAM_BLUETOOTH_SCO:
        return STRATEGY_PHONE;
    case AUDIO_STREAM_RING:
    case AUDIO_STREAM_ALARM:
        return STRATEGY_SONIFICATION;
    case AUDIO_STREAM_NOTIFICATION:
        return STRATEGY_SONIFICATION_RESPECTFUL;
    case AUDIO_STREAM_DTMF:
        return STRATEGY_DTMF;
    default:
        ALOGE("unknown stream type %d", stream);
    case AUDIO_STREAM_SYSTEM:
        // NOTE: SYSTEM stream uses MEDIA strategy because muting music and switching outputs
        // while key clicks are played produces a poor result
    case AUDIO_STREAM_MUSIC:
        return STRATEGY_MEDIA;
    case AUDIO_STREAM_ENFORCED_AUDIBLE:
        return STRATEGY_ENFORCED_AUDIBLE;
    case AUDIO_STREAM_TTS:
        return STRATEGY_TRANSMITTED_THROUGH_SPEAKER;
    case AUDIO_STREAM_ACCESSIBILITY:
        return STRATEGY_ACCESSIBILITY;
    case AUDIO_STREAM_REROUTING:
        return STRATEGY_REROUTING;
#ifdef SPRD_CUSTOM_AUDIO_POLICY
        //modify for FM
    case AUDIO_STREAM_FM:
        return STRATEGY_FM;
#endif
    }
}

根据音频用途获取音频策略也是一一对应的关系,就不多说了,

主要讲解为根据音频路由策略获取音频的输入输出设备getDeviceForStrategy():

audio_devices_t Engine::getDeviceForStrategy(routing_strategy strategy) const
{
		// 获取在AudioPolicyManager中对应于的可用输出输入设备集合
    DeviceVector availableOutputDevices = mApmObserver->getAvailableOutputDevices();
    DeviceVector availableInputDevices = mApmObserver->getAvailableInputDevices();
		//获取输出的设备集合
    const SwAudioOutputCollection &outputs = mApmObserver->getOutputs();
		//根据音频路由策略,输入输出设备,输出的设备集合获取相应的设备
    return getDeviceForStrategyInt(strategy, availableOutputDevices,
                                   availableInputDevices, outputs, (uint32_t)AUDIO_DEVICE_NONE);
}

这里的SwAudioOutputCollection集合的定义在AudioOutputDescriptor.h文件中:
frameworks/av/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h

class SwAudioOutputCollection :
        public DefaultKeyedVector< audio_io_handle_t, sp<SwAudioOutputDescriptor> >
{
public:
    bool isStreamActive(audio_stream_type_t stream, uint32_t inPastMs = 0) const;
    bool isStreamActiveRemotely(audio_stream_type_t stream, uint32_t inPastMs = 0) const;
    bool isStreamActiveLocally(audio_stream_type_t stream, uint32_t inPastMs = 0) const;
    audio_io_handle_t getA2dpOutput() const;
    bool isA2dpOffloadedOnPrimary() const;
    bool isA2dpSupported() const;
    sp<SwAudioOutputDescriptor> getOutputFromId(audio_port_handle_t id) const;
    sp<SwAudioOutputDescriptor> getPrimaryOutput() const;
    bool isAnyOutputActive(audio_stream_type_t streamToIgnore) const;
    audio_devices_t getSupportedDevices(audio_io_handle_t handle) const;
    status_t dump(int fd) const;
};

继续查看:getDeviceForStrategyInt

audio_devices_t Engine::getDeviceForStrategyInt(routing_strategy strategy,
        DeviceVector availableOutputDevices,
        DeviceVector availableInputDevices,
        const SwAudioOutputCollection &outputs,
        uint32_t outputDeviceTypesToIgnore) const
{
    uint32_t device = AUDIO_DEVICE_NONE;
    uint32_t availableOutputDevicesType =
            availableOutputDevices.types() & ~outputDeviceTypesToIgnore;

    switch (strategy) {
    	......
    default:
        ALOGW("getDeviceForStrategy() unknown strategy: %d", strategy);
        break;
    }

    if (device == AUDIO_DEVICE_NONE) {
        ALOGV("getDeviceForStrategy() no device found for strategy %d", strategy);
        device = mApmObserver->getDefaultOutputDevice()->type();
        ALOGE_IF(device == AUDIO_DEVICE_NONE,
                 "getDeviceForStrategy() no default device defined");
    }
    ALOGVV("getDeviceForStrategy() strategy %d, device %x", strategy, device);
    return device;
}

这个函数对应着所有根据音频路由策略获取相应的设备信息:
下面一条条来进行分析:
获取的音频输出设备是喇叭:

case STRATEGY_TRANSMITTED_THROUGH_SPEAKER:
    device = availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER;
    break;

根据通知的音频路由策略获取音频设备:
首先判断是否在通话中,如果是在通话中,则递归执行到 case STRATEGY_SONIFICATION:break;语句:同样也是先判断是否处于通话中这个特殊状态,是的话输出策略设定为STRATEGY_PHONE,然后直接break出来,

case STRATEGY_SONIFICATION_RESPECTFUL:
    if (isInCall() || outputs.isStreamActiveLocally(AUDIO_STREAM_VOICE_CALL)) {
        device = getDeviceForStrategyInt(
                STRATEGY_SONIFICATION, availableOutputDevices, availableInputDevices, outputs,
                outputDeviceTypesToIgnore);
    } else {
        bool media_active_locally =
                outputs.isStreamActiveLocally(
                        AUDIO_STREAM_MUSIC, SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY)
                || outputs.isStreamActiveLocally(
                        AUDIO_STREAM_ACCESSIBILITY, SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY);
        // routing is same as media without the "remote" device
        device = getDeviceForStrategyInt(STRATEGY_MEDIA,
                availableOutputDevices,
                availableInputDevices, outputs,
                AUDIO_DEVICE_OUT_REMOTE_SUBMIX | outputDeviceTypesToIgnore);
        // if no media is playing on the device, check for mandatory use of "safe" speaker
        // when media would have played on speaker, and the safe speaker path is available
        if (!media_active_locally
                && (device & AUDIO_DEVICE_OUT_SPEAKER)
                && (availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER_SAFE)) {
            device |= AUDIO_DEVICE_OUT_SPEAKER_SAFE;
            device &= ~AUDIO_DEVICE_OUT_SPEAKER;
        }
    }
    break;
case STRATEGY_SONIFICATION:

    // If incall, just select the STRATEGY_PHONE device: The rest of the behavior is handled by
    // handleIncallSonification().
    if (isInCall() || outputs.isStreamActiveLocally(AUDIO_STREAM_VOICE_CALL)) {
        device = getDeviceForStrategyInt(
                STRATEGY_PHONE, availableOutputDevices, availableInputDevices, outputs,
                outputDeviceTypesToIgnore);
        break;
    }
    // FALL THROUGH

当不再通话状态则,返回媒体音频策略的设备;在通话状态,走通话状态的策略设备;

    case STRATEGY_DTMF:
        if (!isInCall()) {
            // when off call, DTMF strategy follows the same rules as MEDIA strategy
            device = getDeviceForStrategyInt(
                    STRATEGY_MEDIA, availableOutputDevices, availableInputDevices, outputs,
                    outputDeviceTypesToIgnore);
            break;
        }
        // when in call, DTMF and PHONE strategies follow the same rules
        // FALL THROUGH

音频路由策略为通话状态:

case STRATEGY_PHONE:
    // Force use of only devices on primary output if:
    // - in call AND
    //   - cannot route from voice call RX OR
    //   - audio HAL version is < 3.0 and TX device is on the primary HW module
    if (getPhoneState() == AUDIO_MODE_IN_CALL) {
        audio_devices_t txDevice = getDeviceForInputSource(AUDIO_SOURCE_VOICE_COMMUNICATION);
        sp<AudioOutputDescriptor> primaryOutput = outputs.getPrimaryOutput();
        audio_devices_t availPrimaryInputDevices =
             availableInputDevices.getDevicesFromHwModule(primaryOutput->getModuleHandle());

        // TODO: getPrimaryOutput return only devices from first module in
        // audio_policy_configuration.xml, hearing aid is not there, but it's
        // a primary device
        // FIXME: this is not the right way of solving this problem
        audio_devices_t availPrimaryOutputDevices =
            (primaryOutput->supportedDevices() | AUDIO_DEVICE_OUT_HEARING_AID) &
            availableOutputDevices.types();

        if (((availableInputDevices.types() &
                AUDIO_DEVICE_IN_TELEPHONY_RX & ~AUDIO_DEVICE_BIT_IN) == 0) ||
                (((txDevice & availPrimaryInputDevices & ~AUDIO_DEVICE_BIT_IN) != 0) &&
                     (primaryOutput->getAudioPort()->getModuleVersionMajor() < 3))) {
            availableOutputDevicesType = availPrimaryOutputDevices;
        }
    }
    // for phone strategy, we first consider the forced use and then the available devices by
    // order of priority
    switch (mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION]) {
    case AUDIO_POLICY_FORCE_BT_SCO://强制指定蓝牙设备
        if (!isInCall() || strategy != STRATEGY_DTMF) {
            //如果没有在通话状态,则查询车载蓝牙是否存在???
            device = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT;
            if (device) break;
        }
        //在检测其他的蓝牙设备,如检测蓝牙耳机是否存在
        device = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET;
        if (device) break;
     //检测蓝牙设备是否存在
        device = availableOutputDevicesType & AUDIO_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 = availableOutputDevicesType & AUDIO_DEVICE_OUT_HEARING_AID;
        if (device) break;
        // when not in a phone call, phone strategy should route STREAM_VOICE_CALL to A2DP
        if (!isInCall() &&
                (mForceUse[AUDIO_POLICY_FORCE_FOR_MEDIA] != AUDIO_POLICY_FORCE_NO_BT_A2DP) &&
                 outputs.isA2dpSupported()) {
            device = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP;
            if (device) break;
            device = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES;
            if (device) break;
        }
        device = availableOutputDevicesType & AUDIO_DEVICE_OUT_WIRED_HEADPHONE;
        if (device) break;
        device = availableOutputDevicesType & AUDIO_DEVICE_OUT_WIRED_HEADSET;
        if (device) break;
        device = availableOutputDevicesType & AUDIO_DEVICE_OUT_LINE;
        if (device) break;
        device = availableOutputDevicesType & AUDIO_DEVICE_OUT_USB_HEADSET;
        if (device) break;
        device = availableOutputDevicesType & AUDIO_DEVICE_OUT_USB_DEVICE;
        if (device) break;
        if (!isInCall()) {
            device = availableOutputDevicesType & AUDIO_DEVICE_OUT_USB_ACCESSORY;
            if (device) break;
            device = availableOutputDevicesType & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET;
            if (device) break;
            device = availableOutputDevicesType & AUDIO_DEVICE_OUT_AUX_DIGITAL;
            if (device) break;
            device = availableOutputDevicesType & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET;
            if (device) break;
        }
        device = availableOutputDevicesType & AUDIO_DEVICE_OUT_EARPIECE;
        break;

    case AUDIO_POLICY_FORCE_SPEAKER://强制指定喇叭设备
        // when not in a phone call, phone strategy should route STREAM_VOICE_CALL to
        // A2DP speaker when forcing to speaker output
        if (!isInCall() &&
                (mForceUse[AUDIO_POLICY_FORCE_FOR_MEDIA] != AUDIO_POLICY_FORCE_NO_BT_A2DP) &&
                 outputs.isA2dpSupported()) {
            device = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER;
            if (device) break;
        }
        if (!isInCall()) {
            device = availableOutputDevicesType & AUDIO_DEVICE_OUT_USB_ACCESSORY;
            if (device) break;
            device = availableOutputDevicesType & AUDIO_DEVICE_OUT_USB_DEVICE;
            if (device) break;
            device = availableOutputDevicesType & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET;
            if (device) break;
            device = availableOutputDevicesType & AUDIO_DEVICE_OUT_AUX_DIGITAL;
            if (device) break;
            device = availableOutputDevicesType & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET;
            if (device) break;
        }
        device = availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER;
        break;
    }
break;
case STRATEGY_ENFORCED_AUDIBLE://指定强制音频设备,上层用户空间设置
......
break;
case STRATEGY_ACCESSIBILITY://设置障碍设备
......
break;
case STRATEGY_REROUTING:
case STRATEGY_MEDIA: //指定媒体设备
.......
break;
case STRATEGY_FM: //指定FM输出设备
......
break;
  • 根据输入源指定获取设备:这个是一个固定的模式,比较好理解,记录一下:
    audio_devices_t Engine::getDeviceForInputSource(audio_source_t inputSource) const
    {
        const DeviceVector &availableOutputDevices = mApmObserver->getAvailableOutputDevices();
        const DeviceVector &availableInputDevices = mApmObserver->getAvailableInputDevices();
        const SwAudioOutputCollection &outputs = mApmObserver->getOutputs();
        audio_devices_t availableDeviceTypes = availableInputDevices.types() & ~AUDIO_DEVICE_BIT_IN;
    
        uint32_t device = AUDIO_DEVICE_NONE;
    
        // when a call is active, force device selection to match source VOICE_COMMUNICATION
        // for most other input sources to avoid rerouting call TX audio
        if (isInCall()) {
            switch (inputSource) {
            case AUDIO_SOURCE_DEFAULT:
            case AUDIO_SOURCE_MIC:
            case AUDIO_SOURCE_VOICE_RECOGNITION:
            case AUDIO_SOURCE_UNPROCESSED:
            case AUDIO_SOURCE_HOTWORD:
            case AUDIO_SOURCE_CAMCORDER:
                inputSource = AUDIO_SOURCE_VOICE_COMMUNICATION;
                break;
            default:
                break;
            }
        }
    
        switch (inputSource) {
        case AUDIO_SOURCE_VOICE_UPLINK:
          if (availableDeviceTypes & AUDIO_DEVICE_IN_VOICE_CALL) {
              device = AUDIO_DEVICE_IN_VOICE_CALL;
              break;
          }
          break;
    
        case AUDIO_SOURCE_DEFAULT:
        case AUDIO_SOURCE_MIC:
        if (availableDeviceTypes & AUDIO_DEVICE_IN_BLUETOOTH_A2DP) {
            device = AUDIO_DEVICE_IN_BLUETOOTH_A2DP;
        } else if ((mForceUse[AUDIO_POLICY_FORCE_FOR_RECORD] == AUDIO_POLICY_FORCE_BT_SCO) &&
            (availableDeviceTypes & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET)) {
            device = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET;
        } else if (availableDeviceTypes & AUDIO_DEVICE_IN_WIRED_HEADSET) {
            device = AUDIO_DEVICE_IN_WIRED_HEADSET;
        } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_HEADSET) {
            device = AUDIO_DEVICE_IN_USB_HEADSET;
        } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_DEVICE) {
            device = AUDIO_DEVICE_IN_USB_DEVICE;
        } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) {
            device = AUDIO_DEVICE_IN_BUILTIN_MIC;
        }
        break;
    
        case AUDIO_SOURCE_VOICE_COMMUNICATION:
            // Allow only use of devices on primary input if in call and HAL does not support routing
            // to voice call path.
            if ((getPhoneState() == AUDIO_MODE_IN_CALL) &&
                    (availableOutputDevices.types() & AUDIO_DEVICE_OUT_TELEPHONY_TX) == 0) {
                sp<AudioOutputDescriptor> primaryOutput = outputs.getPrimaryOutput();
                availableDeviceTypes =
                        availableInputDevices.getDevicesFromHwModule(primaryOutput->getModuleHandle())
                        & ~AUDIO_DEVICE_BIT_IN;
            }
    
            switch (mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION]) {
            case AUDIO_POLICY_FORCE_BT_SCO:
                // if SCO device is requested but no SCO device is available, fall back to default case
                if (availableDeviceTypes & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) {
                    device = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET;
                    break;
                }
                // FALL THROUGH
    
            default:    // FORCE_NONE
                if (availableDeviceTypes & AUDIO_DEVICE_IN_WIRED_HEADSET) {
                    device = AUDIO_DEVICE_IN_WIRED_HEADSET;
                } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_HEADSET) {
                    device = AUDIO_DEVICE_IN_USB_HEADSET;
                } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_DEVICE) {
                    device = AUDIO_DEVICE_IN_USB_DEVICE;
                } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) {
                    device = AUDIO_DEVICE_IN_BUILTIN_MIC;
                }
                break;
    
            case AUDIO_POLICY_FORCE_SPEAKER:
                if (availableDeviceTypes & AUDIO_DEVICE_IN_BACK_MIC) {
                    device = AUDIO_DEVICE_IN_BACK_MIC;
                } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) {
                    device = AUDIO_DEVICE_IN_BUILTIN_MIC;
                }
                break;
            }
            break;
    
        case AUDIO_SOURCE_VOICE_RECOGNITION:
        case AUDIO_SOURCE_UNPROCESSED:
        case AUDIO_SOURCE_HOTWORD:
            if (mForceUse[AUDIO_POLICY_FORCE_FOR_RECORD] == AUDIO_POLICY_FORCE_BT_SCO &&
                    availableDeviceTypes & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) {
                device = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET;
            } else if (availableDeviceTypes & AUDIO_DEVICE_IN_WIRED_HEADSET) {
                device = AUDIO_DEVICE_IN_WIRED_HEADSET;
            } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_HEADSET) {
                device = AUDIO_DEVICE_IN_USB_HEADSET;
            } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_DEVICE) {
                device = AUDIO_DEVICE_IN_USB_DEVICE;
            } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) {
                device = AUDIO_DEVICE_IN_BUILTIN_MIC;
            }
            break;
        case AUDIO_SOURCE_CAMCORDER:
            if (availableDeviceTypes & AUDIO_DEVICE_IN_BACK_MIC) {
                device = AUDIO_DEVICE_IN_BACK_MIC;
            } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) {
                device = AUDIO_DEVICE_IN_BUILTIN_MIC;
            }
            break;
        case AUDIO_SOURCE_VOICE_DOWNLINK:
        case AUDIO_SOURCE_VOICE_CALL:
            if (availableDeviceTypes & AUDIO_DEVICE_IN_VOICE_CALL) {
                device = AUDIO_DEVICE_IN_VOICE_CALL;
            }
            break;
        case AUDIO_SOURCE_REMOTE_SUBMIX:
            if (availableDeviceTypes & AUDIO_DEVICE_IN_REMOTE_SUBMIX) {
                device = AUDIO_DEVICE_IN_REMOTE_SUBMIX;
            }
            break;
         case AUDIO_SOURCE_FM_TUNER:
            if (availableDeviceTypes & AUDIO_DEVICE_IN_FM_TUNER) {
                device = AUDIO_DEVICE_IN_FM_TUNER;
            }
            break;
        default:
            ALOGW("getDeviceForInputSource() invalid input source %d", inputSource);
            break;
        }
        if (device == AUDIO_DEVICE_NONE) {
            ALOGV("getDeviceForInputSource() no device found for source %d", inputSource);
            if (availableDeviceTypes & AUDIO_DEVICE_IN_STUB) {
                device = AUDIO_DEVICE_IN_STUB;
            }
            ALOGE_IF(device == AUDIO_DEVICE_NONE,
                     "getDeviceForInputSource() no default device defined");
        }
        ALOGV("getDeviceForInputSource()input source %d, device %08x", inputSource, device);
        return device;
    }

 

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值