PageRenderTime 54ms CodeModel.GetById 9ms app.highlight 39ms RepoModel.GetById 1ms app.codeStats 1ms

/libaudio/AudioPolicyManager.cpp

http://github.com/CyanogenMod/android_device_zte_blade
C++ | 194 lines | 133 code | 23 blank | 38 comment | 59 complexity | 0775b0be300b975d24557856db49760a MD5 | raw file
  1/*
  2 * Copyright (C) 2009 The Android Open Source Project
  3 *
  4 * Licensed under the Apache License, Version 2.0 (the "License");
  5 * you may not use this file except in compliance with the License.
  6 * You may obtain a copy of the License at
  7 *
  8 *      http://www.apache.org/licenses/LICENSE-2.0
  9 *
 10 * Unless required by applicable law or agreed to in writing, software
 11 * distributed under the License is distributed on an "AS IS" BASIS,
 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 13 * See the License for the specific language governing permissions and
 14 * limitations under the License.
 15 */
 16
 17#define LOG_TAG "AudioPolicyManager"
 18//#define LOG_NDEBUG 0
 19#include <utils/Log.h>
 20#include "AudioPolicyManager.h"
 21#include <media/mediarecorder.h>
 22#include <fcntl.h>
 23
 24namespace android {
 25
 26
 27
 28// ----------------------------------------------------------------------------
 29// AudioPolicyManager for msm7k platform
 30// Common audio policy manager code is implemented in AudioPolicyManagerBase class
 31// ----------------------------------------------------------------------------
 32
 33// ---  class factory
 34
 35
 36extern "C" AudioPolicyInterface* createAudioPolicyManager(AudioPolicyClientInterface *clientInterface)
 37{
 38    return new AudioPolicyManager(clientInterface);
 39}
 40
 41extern "C" void destroyAudioPolicyManager(AudioPolicyInterface *interface)
 42{
 43    delete interface;
 44}
 45
 46uint32_t AudioPolicyManager::getDeviceForStrategy(routing_strategy strategy, bool fromCache)
 47{
 48    uint32_t device = 0;
 49
 50    if (fromCache) {
 51        LOGV("getDeviceForStrategy() from cache strategy %d, device %x", strategy, mDeviceForStrategy[strategy]);
 52        return mDeviceForStrategy[strategy];
 53    }
 54
 55    switch (strategy) {
 56    case STRATEGY_DTMF:
 57        if (mPhoneState != AudioSystem::MODE_IN_CALL) {
 58            // when off call, DTMF strategy follows the same rules as MEDIA strategy
 59            device = getDeviceForStrategy(STRATEGY_MEDIA, false);
 60            break;
 61        }
 62        // when in call, DTMF and PHONE strategies follow the same rules
 63        // FALL THROUGH
 64
 65    case STRATEGY_PHONE:
 66        // for phone strategy, we first consider the forced use and then the available devices by order
 67        // of priority
 68        switch (mForceUse[AudioSystem::FOR_COMMUNICATION]) {
 69        case AudioSystem::FORCE_BT_SCO:
 70            if (mPhoneState != AudioSystem::MODE_IN_CALL || strategy != STRATEGY_DTMF) {
 71                device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_CARKIT;
 72                if (device) break;
 73            }
 74            device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_HEADSET;
 75            if (device) break;
 76            device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO;
 77            if (device) break;
 78            // if SCO device is requested but no SCO device is available, fall back to default case
 79            // FALL THROUGH
 80
 81        default:    // FORCE_NONE
 82            device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADPHONE;
 83            if (device) break;
 84            device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADSET;
 85            if (device) break;
 86#ifdef WITH_A2DP
 87            // when not in a phone call, phone strategy should route STREAM_VOICE_CALL to A2DP
 88            if (mPhoneState != AudioSystem::MODE_IN_CALL) {
 89                device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP;
 90                if (device) break;
 91                device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES;
 92                if (device) break;
 93            }
 94#endif
 95            if (mPhoneState == AudioSystem::MODE_RINGTONE)
 96                device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_SPEAKER;
 97            if (device) break;
 98
 99            device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_EARPIECE;
100            if (device == 0) {
101                LOGE("getDeviceForStrategy() earpiece device not found");
102            }
103            break;
104
105        case AudioSystem::FORCE_SPEAKER:
106            if (mPhoneState != AudioSystem::MODE_IN_CALL || strategy != STRATEGY_DTMF) {
107                device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_CARKIT;
108                if (device) break;
109            }
110#ifdef WITH_A2DP
111            // when not in a phone call, phone strategy should route STREAM_VOICE_CALL to
112            // A2DP speaker when forcing to speaker output
113            if (mPhoneState != AudioSystem::MODE_IN_CALL) {
114                device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER;
115                if (device) break;
116            }
117#endif
118            device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_SPEAKER;
119            if (device == 0) {
120                LOGE("getDeviceForStrategy() speaker device not found");
121            }
122            break;
123        }
124    break;
125
126    case STRATEGY_SONIFICATION:
127        device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_SPEAKER;
128        if (device == 0) {
129            LOGE("getDeviceForStrategy() speaker device not found");
130        }
131        // The second device used for sonification is the same as the device used by media strategy
132        // FALL THROUGH
133
134    case STRATEGY_MEDIA_SONIFICATION:
135        // If incall, just select the STRATEGY_PHONE device: The rest of the behavior is handled by
136        // handleIncallSonification().
137        if (mPhoneState == AudioSystem::MODE_IN_CALL) {
138            device = getDeviceForStrategy(STRATEGY_PHONE, false);
139            break;
140        }
141
142    case STRATEGY_MEDIA: {
143        uint32_t device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_AUX_DIGITAL;
144#ifdef WITH_A2DP
145        if (mA2dpOutput != 0) {
146            if (strategy == STRATEGY_SONIFICATION && !a2dpUsedForSonification()) {
147                break;
148            }
149            if (device2 == 0) {
150                device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP;
151            }
152            if (device2 == 0) {
153                device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES;
154            }
155            if (device2 == 0) {
156                device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER;
157            }
158        }
159#endif
160        if (device2 == 0) {
161            device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADPHONE;
162        }
163        if (device2 == 0) {
164            device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADSET;
165        }
166        if (device2 == 0) {
167            device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_SPEAKER;
168        }
169        if (device2 == 0) {
170            device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_EARPIECE;
171        }
172
173        // device is DEVICE_OUT_SPEAKER if we come from case STRATEGY_SONIFICATION, 0 otherwise
174        device |= device2;
175        // Do not play media stream if in call and the requested device would change the hardware
176        // output routing
177        if (mPhoneState == AudioSystem::MODE_IN_CALL &&
178            !AudioSystem::isA2dpDevice((AudioSystem::audio_devices)device) &&
179            device != getDeviceForStrategy(STRATEGY_PHONE)) {
180            device = 0;
181            LOGV("getDeviceForStrategy() incompatible media and phone devices");
182        }
183        } break;
184
185    default:
186        LOGW("getDeviceForStrategy() unknown strategy: %d", strategy);
187        break;
188    }
189
190    LOGV("getDeviceForStrategy() strategy %d, device %x", strategy, device);
191    return device;
192}
193
194}; // namespace android