/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. #define LOG_TAG "AudioPolicyManager"
  17. //#define LOG_NDEBUG 0
  18. #include <utils/Log.h>
  19. #include "AudioPolicyManager.h"
  20. #include <media/mediarecorder.h>
  21. #include <fcntl.h>
  22. namespace android {
  23. // ----------------------------------------------------------------------------
  24. // AudioPolicyManager for msm7k platform
  25. // Common audio policy manager code is implemented in AudioPolicyManagerBase class
  26. // ----------------------------------------------------------------------------
  27. // --- class factory
  28. extern "C" AudioPolicyInterface* createAudioPolicyManager(AudioPolicyClientInterface *clientInterface)
  29. {
  30. return new AudioPolicyManager(clientInterface);
  31. }
  32. extern "C" void destroyAudioPolicyManager(AudioPolicyInterface *interface)
  33. {
  34. delete interface;
  35. }
  36. uint32_t AudioPolicyManager::getDeviceForStrategy(routing_strategy strategy, bool fromCache)
  37. {
  38. uint32_t device = 0;
  39. if (fromCache) {
  40. LOGV("getDeviceForStrategy() from cache strategy %d, device %x", strategy, mDeviceForStrategy[strategy]);
  41. return mDeviceForStrategy[strategy];
  42. }
  43. switch (strategy) {
  44. case STRATEGY_DTMF:
  45. if (mPhoneState != AudioSystem::MODE_IN_CALL) {
  46. // when off call, DTMF strategy follows the same rules as MEDIA strategy
  47. device = getDeviceForStrategy(STRATEGY_MEDIA, false);
  48. break;
  49. }
  50. // when in call, DTMF and PHONE strategies follow the same rules
  51. // FALL THROUGH
  52. case STRATEGY_PHONE:
  53. // for phone strategy, we first consider the forced use and then the available devices by order
  54. // of priority
  55. switch (mForceUse[AudioSystem::FOR_COMMUNICATION]) {
  56. case AudioSystem::FORCE_BT_SCO:
  57. if (mPhoneState != AudioSystem::MODE_IN_CALL || strategy != STRATEGY_DTMF) {
  58. device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_CARKIT;
  59. if (device) break;
  60. }
  61. device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_HEADSET;
  62. if (device) break;
  63. device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO;
  64. if (device) break;
  65. // if SCO device is requested but no SCO device is available, fall back to default case
  66. // FALL THROUGH
  67. default: // FORCE_NONE
  68. device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADPHONE;
  69. if (device) break;
  70. device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADSET;
  71. if (device) break;
  72. #ifdef WITH_A2DP
  73. // when not in a phone call, phone strategy should route STREAM_VOICE_CALL to A2DP
  74. if (mPhoneState != AudioSystem::MODE_IN_CALL) {
  75. device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP;
  76. if (device) break;
  77. device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES;
  78. if (device) break;
  79. }
  80. #endif
  81. if (mPhoneState == AudioSystem::MODE_RINGTONE)
  82. device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_SPEAKER;
  83. if (device) break;
  84. device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_EARPIECE;
  85. if (device == 0) {
  86. LOGE("getDeviceForStrategy() earpiece device not found");
  87. }
  88. break;
  89. case AudioSystem::FORCE_SPEAKER:
  90. if (mPhoneState != AudioSystem::MODE_IN_CALL || strategy != STRATEGY_DTMF) {
  91. device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_CARKIT;
  92. if (device) break;
  93. }
  94. #ifdef WITH_A2DP
  95. // when not in a phone call, phone strategy should route STREAM_VOICE_CALL to
  96. // A2DP speaker when forcing to speaker output
  97. if (mPhoneState != AudioSystem::MODE_IN_CALL) {
  98. device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER;
  99. if (device) break;
  100. }
  101. #endif
  102. device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_SPEAKER;
  103. if (device == 0) {
  104. LOGE("getDeviceForStrategy() speaker device not found");
  105. }
  106. break;
  107. }
  108. break;
  109. case STRATEGY_SONIFICATION:
  110. device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_SPEAKER;
  111. if (device == 0) {
  112. LOGE("getDeviceForStrategy() speaker device not found");
  113. }
  114. // The second device used for sonification is the same as the device used by media strategy
  115. // FALL THROUGH
  116. case STRATEGY_MEDIA_SONIFICATION:
  117. // If incall, just select the STRATEGY_PHONE device: The rest of the behavior is handled by
  118. // handleIncallSonification().
  119. if (mPhoneState == AudioSystem::MODE_IN_CALL) {
  120. device = getDeviceForStrategy(STRATEGY_PHONE, false);
  121. break;
  122. }
  123. case STRATEGY_MEDIA: {
  124. uint32_t device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_AUX_DIGITAL;
  125. #ifdef WITH_A2DP
  126. if (mA2dpOutput != 0) {
  127. if (strategy == STRATEGY_SONIFICATION && !a2dpUsedForSonification()) {
  128. break;
  129. }
  130. if (device2 == 0) {
  131. device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP;
  132. }
  133. if (device2 == 0) {
  134. device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES;
  135. }
  136. if (device2 == 0) {
  137. device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER;
  138. }
  139. }
  140. #endif
  141. if (device2 == 0) {
  142. device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADPHONE;
  143. }
  144. if (device2 == 0) {
  145. device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADSET;
  146. }
  147. if (device2 == 0) {
  148. device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_SPEAKER;
  149. }
  150. if (device2 == 0) {
  151. device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_EARPIECE;
  152. }
  153. // device is DEVICE_OUT_SPEAKER if we come from case STRATEGY_SONIFICATION, 0 otherwise
  154. device |= device2;
  155. // Do not play media stream if in call and the requested device would change the hardware
  156. // output routing
  157. if (mPhoneState == AudioSystem::MODE_IN_CALL &&
  158. !AudioSystem::isA2dpDevice((AudioSystem::audio_devices)device) &&
  159. device != getDeviceForStrategy(STRATEGY_PHONE)) {
  160. device = 0;
  161. LOGV("getDeviceForStrategy() incompatible media and phone devices");
  162. }
  163. } break;
  164. default:
  165. LOGW("getDeviceForStrategy() unknown strategy: %d", strategy);
  166. break;
  167. }
  168. LOGV("getDeviceForStrategy() strategy %d, device %x", strategy, device);
  169. return device;
  170. }
  171. }; // namespace android