165e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland/*
265e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland * Copyright (C) 2009 The Android Open Source Project
365e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland *
465e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland * Licensed under the Apache License, Version 2.0 (the "License");
565e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland * you may not use this file except in compliance with the License.
665e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland * You may obtain a copy of the License at
765e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland *
865e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland *      http://www.apache.org/licenses/LICENSE-2.0
965e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland *
1065e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland * Unless required by applicable law or agreed to in writing, software
1165e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland * distributed under the License is distributed on an "AS IS" BASIS,
1265e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1365e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland * See the License for the specific language governing permissions and
1465e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland * limitations under the License.
1565e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland */
1665e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland
1765e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland#define LOG_TAG "AudioPolicyManager"
1865e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland//#define LOG_NDEBUG 0
1965e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland#include <utils/Log.h>
2065e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland#include "AudioPolicyManager.h"
2165e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland#include <media/mediarecorder.h>
2265e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland
2365e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetlandnamespace android {
2465e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland
2565e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland
2665e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland// Max volume for streams when playing over bluetooth SCO device while in call: -18dB
2765e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland#define IN_CALL_SCO_VOLUME_MAX  0.126
2865e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland// Min music volume for 3.5mm jack in car dock: -10dB
2965e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland#define CAR_DOCK_MUSIC_MINI_JACK_VOLUME_MIN 0.316
3065e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland
3165e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland// ----------------------------------------------------------------------------
3265e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland// AudioPolicyManager implementation for qsd8k platform
3365e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland// Common audio policy manager code is implemented in AudioPolicyManagerBase class
3465e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland// ----------------------------------------------------------------------------
3565e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland
3665e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland// ---  class factory
3765e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland
3865e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland
3965e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetlandextern "C" AudioPolicyInterface* createAudioPolicyManager(AudioPolicyClientInterface *clientInterface)
4065e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland{
4165e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland    return new AudioPolicyManager(clientInterface);
4265e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland}
4365e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland
4465e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetlandextern "C" void destroyAudioPolicyManager(AudioPolicyInterface *interface)
4565e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland{
4665e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland    delete interface;
4765e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland}
4865e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland
4965e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland// ---
5065e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland
5165e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland
5265e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetlanduint32_t AudioPolicyManager::getDeviceForStrategy(routing_strategy strategy, bool fromCache)
5365e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland{
5465e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland    uint32_t device = 0;
5565e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland
5665e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland    if (fromCache) {
5765e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland        device = mDeviceForStrategy[strategy];
5822f2554680715d1ea993409217a4a21f652ef130Steve Block        ALOGV("getDeviceForStrategy() from cache strategy %d, device %x", strategy, device);
5965e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland        return device;
6065e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland    }
6165e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland
6265e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland    switch (strategy) {
6365e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland    case STRATEGY_DTMF:
6465e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland        if (mPhoneState != AudioSystem::MODE_IN_CALL) {
6565e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland            // when off call, DTMF strategy follows the same rules as MEDIA strategy
6665e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland            device = getDeviceForStrategy(STRATEGY_MEDIA, false);
6765e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland            break;
6865e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland        }
6965e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland        // when in call, DTMF and PHONE strategies follow the same rules
7065e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland        // FALL THROUGH
7165e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland
7265e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland    case STRATEGY_PHONE:
7365e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland        // for phone strategy, we first consider the forced use and then the available devices by order
7465e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland        // of priority
7565e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland        switch (mForceUse[AudioSystem::FOR_COMMUNICATION]) {
7665e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland        case AudioSystem::FORCE_BT_SCO:
7765e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland            if (mPhoneState != AudioSystem::MODE_IN_CALL || strategy != STRATEGY_DTMF) {
7865e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland                device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_CARKIT;
7965e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland                if (device) break;
8065e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland            }
8165e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland            // otherwise (not docked) continue with selection
8265e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland            device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_HEADSET;
8365e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland            if (device) break;
8465e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland            device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO;
8565e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland            if (device) break;
8665e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland            // if SCO device is requested but no SCO device is available, fall back to default case
8765e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland            // FALL THROUGH
8865e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland
8965e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland        default:    // FORCE_NONE
9065e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland            device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADPHONE;
9165e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland            if (device) break;
9265e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland            device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADSET;
9365e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland            if (device) break;
9465e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland            // when not in call:
9565e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland            if (mPhoneState != AudioSystem::MODE_IN_CALL) {
9665e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland                // - if we are docked to a BT CAR dock, give A2DP preference over earpiece
9765e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland                // - if we are docked to a BT DESK dock, give speaker preference over earpiece
9865e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland                if (mForceUse[AudioSystem::FOR_DOCK] == AudioSystem::FORCE_BT_CAR_DOCK) {
9965e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland                    device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP;
10065e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland                } else if (mForceUse[AudioSystem::FOR_DOCK] == AudioSystem::FORCE_BT_DESK_DOCK) {
10165e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland                    device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_SPEAKER;
10265e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland                }
10365e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland                if (device) break;
10465e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland                // - phone strategy should route STREAM_VOICE_CALL to A2DP
10565e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland                device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP;
10665e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland                if (device) break;
10765e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland                device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES;
10865e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland                if (device) break;
10965e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland            }
11065e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland            device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_EARPIECE;
11165e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland            if (device == 0) {
112c3dee7890047bad1136078f0f6e2b6d1a9a24947Steve Block                ALOGE("getDeviceForStrategy() earpiece device not found");
11365e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland            }
11465e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland            break;
11565e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland
11665e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland        case AudioSystem::FORCE_SPEAKER:
11765e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland            if (mPhoneState != AudioSystem::MODE_IN_CALL || strategy != STRATEGY_DTMF) {
11865e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland                device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_CARKIT;
11965e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland                if (device) break;
12065e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland            }
12165e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland            // when not in call:
12265e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland            if (mPhoneState != AudioSystem::MODE_IN_CALL) {
12365e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland                // - if we are docked to a BT CAR dock, give A2DP preference over phone spkr
12465e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland                if (mForceUse[AudioSystem::FOR_DOCK] == AudioSystem::FORCE_BT_CAR_DOCK) {
12565e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland                    device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP;
12665e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland                    if (device) break;
12765e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland                }
12865e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland                // - phone strategy should route STREAM_VOICE_CALL to A2DP speaker
12965e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland                //   when forcing to speaker output
13065e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland                device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER;
13165e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland                if (device) break;
13265e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland            }
13365e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland            device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_SPEAKER;
13465e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland            if (device == 0) {
135c3dee7890047bad1136078f0f6e2b6d1a9a24947Steve Block                ALOGE("getDeviceForStrategy() speaker device not found");
13665e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland            }
13765e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland            break;
13865e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland        }
13965e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland    break;
14065e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland
14165e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland    case STRATEGY_SONIFICATION:
14265e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland
14365e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland        // If incall, just select the STRATEGY_PHONE device: The rest of the behavior is handled by
14465e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland        // handleIncallSonification().
14565e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland        if (mPhoneState == AudioSystem::MODE_IN_CALL) {
14665e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland            device = getDeviceForStrategy(STRATEGY_PHONE, false);
14765e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland            break;
14865e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland        }
14965e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland        // If not incall:
15065e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland        // - if we are docked to a BT CAR dock, don't duplicate for the sonification strategy
15165e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland        // - if we are docked to a BT DESK dock, use only speaker for the sonification strategy
15265e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland        if (mForceUse[AudioSystem::FOR_DOCK] != AudioSystem::FORCE_BT_CAR_DOCK) {
15365e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland            device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_SPEAKER;
15465e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland            if (device == 0) {
155c3dee7890047bad1136078f0f6e2b6d1a9a24947Steve Block                ALOGE("getDeviceForStrategy() speaker device not found");
15665e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland            }
15765e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland            if (mForceUse[AudioSystem::FOR_DOCK] == AudioSystem::FORCE_BT_DESK_DOCK) {
15865e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland                if (mAvailableOutputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADPHONE) {
15965e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland                    device |= AudioSystem::DEVICE_OUT_WIRED_HEADPHONE;
16065e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland                } else if (mAvailableOutputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADSET) {
16165e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland                    device |= AudioSystem::DEVICE_OUT_WIRED_HEADSET;
16265e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland                }
16365e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland                break;
16465e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland            }
16565e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland        } else {
16665e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland            device = 0;
16765e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland        }
16865e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland        // The second device used for sonification is the same as the device used by media strategy
16965e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland        // Note that when docked, we pick the device below (no duplication)
17065e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland        // FALL THROUGH
17165e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland
17265e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland    case STRATEGY_MEDIA: {
17365e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland        uint32_t device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_AUX_DIGITAL;
17465e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland#ifdef WITH_A2DP
17565e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland        if (mA2dpOutput != 0) {
17665e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland            if (device2 == 0) {
17765e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland                // play ringtone over speaker (or speaker + headset) if in car dock
17865e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland                // because A2DP is suspended in this case
17965e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland                if (mForceUse[AudioSystem::FOR_DOCK] == AudioSystem::FORCE_BT_CAR_DOCK &&
18065e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland                    strategy == STRATEGY_SONIFICATION &&
18165e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland                    mPhoneState == AudioSystem::MODE_RINGTONE) {
18265e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland                    device2 = mAvailableOutputDevices &
18365e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland                              (AudioSystem::DEVICE_OUT_SPEAKER |
18465e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland                               AudioSystem::DEVICE_OUT_WIRED_HEADPHONE |
18565e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland                               AudioSystem::DEVICE_OUT_WIRED_HEADSET);
18665e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland                }
18765e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland            }
18865e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland        }
18965e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland#endif
19065e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland        if (device2 == 0) {
19165e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland            device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADPHONE;
19265e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland        }
19365e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland        if (device2 == 0) {
19465e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland            device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADSET;
19565e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland        }
19665e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland#ifdef WITH_A2DP
19765e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland        if (mA2dpOutput != 0) {
19865e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland            if (device2 == 0) {
19965e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland                device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP;
20065e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland            }
20165e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland            if (device2 == 0) {
20265e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland                device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES;
20365e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland            }
20465e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland            if (device2 == 0) {
20565e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland                device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER;
20665e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland            }
20765e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland        }
20865e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland#endif
20965e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland        if (device2 == 0) {
21065e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland            device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_SPEAKER;
21165e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland        }
21265e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland        // device is DEVICE_OUT_SPEAKER if we come from case STRATEGY_SONIFICATION, 0 otherwise
21365e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland        device |= device2;
21465e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland        if (device == 0) {
215c3dee7890047bad1136078f0f6e2b6d1a9a24947Steve Block            ALOGE("getDeviceForStrategy() speaker device not found");
21665e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland        }
21765e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland        // Do not play media stream if in call and the requested device would change the hardware
21865e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland        // output routing
21965e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland        if (mPhoneState == AudioSystem::MODE_IN_CALL &&
22065e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland            !AudioSystem::isA2dpDevice((AudioSystem::audio_devices)device) &&
22165e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland            device != getDeviceForStrategy(STRATEGY_PHONE, false)) {
22265e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland            device = 0;
22322f2554680715d1ea993409217a4a21f652ef130Steve Block            ALOGV("getDeviceForStrategy() incompatible media and phone devices");
22465e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland        }
22565e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland        } break;
22665e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland
22765e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland    default:
2283fb19cd0b6534ef9d36f8ac0c5ddbdc73ed92a26Steve Block        ALOGW("getDeviceForStrategy() unknown strategy: %d", strategy);
22965e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland        break;
23065e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland    }
23165e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland
23222f2554680715d1ea993409217a4a21f652ef130Steve Block    ALOGV("getDeviceForStrategy() strategy %d, device %x", strategy, device);
23365e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland    return device;
23465e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland}
23565e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland
23665e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetlandfloat AudioPolicyManager::computeVolume(int stream, int index, audio_io_handle_t output, uint32_t device)
23765e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland{
23865e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland    // force volume on A2DP output to maximum if playing through car dock speakers
23965e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland    // as volume is applied on the car dock and controlled via car dock keys.
24065e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland#ifdef WITH_A2DP
24165e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland    if (output == mA2dpOutput &&
24265e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland        mForceUse[AudioSystem::FOR_DOCK] == AudioSystem::FORCE_BT_CAR_DOCK) {
24365e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland        return 1.0;
24465e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland    }
24565e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland#endif
24665e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland
24765e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland    float volume = AudioPolicyManagerBase::computeVolume(stream, index, output, device);
24865e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland
24965e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland    // limit stream volume when in call and playing over bluetooth SCO device to
25065e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland    // avoid saturation
25165e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland    if (mPhoneState == AudioSystem::MODE_IN_CALL && AudioSystem::isBluetoothScoDevice((AudioSystem::audio_devices)device)) {
25265e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland        if (volume > IN_CALL_SCO_VOLUME_MAX) {
25322f2554680715d1ea993409217a4a21f652ef130Steve Block            ALOGV("computeVolume limiting SYSTEM volume %f to %f",volume, IN_CALL_SCO_VOLUME_MAX);
25465e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland            volume = IN_CALL_SCO_VOLUME_MAX;
25565e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland        }
25665e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland    }
25765e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland
25865e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland    // in car dock: when using the 3.5mm jack to play media, set a fixed volume as access to the
25965e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland    // physical volume keys is blocked by the car dock frame.
26065e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland    if ((mForceUse[AudioSystem::FOR_DOCK] == AudioSystem::FORCE_BT_CAR_DOCK) &&
26165e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland            (stream == AudioSystem::MUSIC) &&
26265e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland            (device & (AudioSystem::DEVICE_OUT_WIRED_HEADPHONE |
26365e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland                AudioSystem::DEVICE_OUT_WIRED_HEADSET))) {
26465e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland        volume = CAR_DOCK_MUSIC_MINI_JACK_VOLUME_MIN;
26565e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland    }
26665e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland
26765e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland    return volume;
26865e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland}
26965e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland
27065e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland
27165e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland
27265e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland
27365e6c49fb6a8872a5e36fa479c4ed9f9fceba43cBrian Swetland}; // namespace android
274