blob: 223b43e680d17e6f0713d106353c4bf99accd18e [file] [log] [blame]
Ravi Kumar Alamanda89a81422013-10-08 23:47:55 -07001/*
2 * Copyright (c) 2013, The Linux Foundation. All rights reserved.
3 * Not a contribution.
4 *
5 * Copyright (C) 2009 The Android Open Source Project
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 */
19
20#define LOG_TAG "AudioPolicyManager"
21//#define LOG_NDEBUG 0
22
23//#define VERY_VERBOSE_LOGGING
24#ifdef VERY_VERBOSE_LOGGING
25#define ALOGVV ALOGV
26#else
27#define ALOGVV(a...) do { } while(0)
28#endif
29
30// A device mask for all audio input devices that are considered "virtual" when evaluating
31// active inputs in getActiveInput()
32#define APM_AUDIO_IN_DEVICE_VIRTUAL_ALL AUDIO_DEVICE_IN_REMOTE_SUBMIX
33// A device mask for all audio output devices that are considered "remote" when evaluating
34// active output devices in isStreamActiveRemotely()
35#define APM_AUDIO_OUT_DEVICE_REMOTE_ALL AUDIO_DEVICE_OUT_REMOTE_SUBMIX
36
37#include <utils/Log.h>
38#include "AudioPolicyManager.h"
39#include <hardware/audio_effect.h>
40#include <hardware/audio.h>
41#include <math.h>
42#include <hardware_legacy/audio_policy_conf.h>
43#include <cutils/properties.h>
44
45namespace android_audio_legacy {
46
47// ----------------------------------------------------------------------------
48// AudioPolicyInterface implementation
49// ----------------------------------------------------------------------------
50
51audio_devices_t AudioPolicyManager::getDeviceForStrategy(routing_strategy strategy,
52 bool fromCache)
53{
54 uint32_t device = AUDIO_DEVICE_NONE;
55
56 if (fromCache) {
57 ALOGVV("getDeviceForStrategy() from cache strategy %d, device %x",
58 strategy, mDeviceForStrategy[strategy]);
59 return mDeviceForStrategy[strategy];
60 }
61
62 switch (strategy) {
63
64 case STRATEGY_SONIFICATION_RESPECTFUL:
65 if (isInCall()) {
66 device = getDeviceForStrategy(STRATEGY_SONIFICATION, false /*fromCache*/);
67 } else if (isStreamActiveRemotely(AudioSystem::MUSIC,
68 SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY)) {
69 // while media is playing on a remote device, use the the sonification behavior.
70 // Note that we test this usecase before testing if media is playing because
71 // the isStreamActive() method only informs about the activity of a stream, not
72 // if it's for local playback. Note also that we use the same delay between both tests
73 device = getDeviceForStrategy(STRATEGY_SONIFICATION, false /*fromCache*/);
74 } else if (isStreamActive(AudioSystem::MUSIC, SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY)) {
75 // while media is playing (or has recently played), use the same device
76 device = getDeviceForStrategy(STRATEGY_MEDIA, false /*fromCache*/);
77 } else {
78 // when media is not playing anymore, fall back on the sonification behavior
79 device = getDeviceForStrategy(STRATEGY_SONIFICATION, false /*fromCache*/);
80 }
81
82 break;
83
84 case STRATEGY_DTMF:
85 if (!isInCall()) {
86 // when off call, DTMF strategy follows the same rules as MEDIA strategy
87 device = getDeviceForStrategy(STRATEGY_MEDIA, false /*fromCache*/);
88 break;
89 }
90 // when in call, DTMF and PHONE strategies follow the same rules
91 // FALL THROUGH
92
93 case STRATEGY_PHONE:
94 // for phone strategy, we first consider the forced use and then the available devices by order
95 // of priority
96 switch (mForceUse[AudioSystem::FOR_COMMUNICATION]) {
97 case AudioSystem::FORCE_BT_SCO:
98 if (!isInCall() || strategy != STRATEGY_DTMF) {
99 device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT;
100 if (device) break;
101 }
102 device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET;
103 if (device) break;
104 device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_BLUETOOTH_SCO;
105 if (device) break;
106 // if SCO device is requested but no SCO device is available, fall back to default case
107 // FALL THROUGH
108
109 default: // FORCE_NONE
110 // when not in a phone call, phone strategy should route STREAM_VOICE_CALL to A2DP
111 if (mHasA2dp && !isInCall() &&
112 (mForceUse[AudioSystem::FOR_MEDIA] != AudioSystem::FORCE_NO_BT_A2DP) &&
113 (getA2dpOutput() != 0) && !mA2dpSuspended) {
114 device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP;
115 if (device) break;
116 device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES;
117 if (device) break;
118 }
119 device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_WIRED_HEADPHONE;
120 if (device) break;
121 device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_WIRED_HEADSET;
122 if (device) break;
123 if (mPhoneState != AudioSystem::MODE_IN_CALL) {
124 device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_USB_ACCESSORY;
125 if (device) break;
126 device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_USB_DEVICE;
127 if (device) break;
128 device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_AUX_DIGITAL;
129 if (device) break;
130 }
131
132 // Allow voice call on USB ANLG DOCK headset
133 device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET;
134 if (device) break;
135
136 device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET;
137 if (device) break;
138
139 device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_EARPIECE;
140 if (device) break;
141 device = mDefaultOutputDevice;
142 if (device == AUDIO_DEVICE_NONE) {
143 ALOGE("getDeviceForStrategy() no device found for STRATEGY_PHONE");
144 }
145 break;
146
147 case AudioSystem::FORCE_SPEAKER:
148 // when not in a phone call, phone strategy should route STREAM_VOICE_CALL to
149 // A2DP speaker when forcing to speaker output
150 if (mHasA2dp && !isInCall() &&
151 (mForceUse[AudioSystem::FOR_MEDIA] != AudioSystem::FORCE_NO_BT_A2DP) &&
152 (getA2dpOutput() != 0) && !mA2dpSuspended) {
153 device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER;
154 if (device) break;
155 }
156 if (mPhoneState != AudioSystem::MODE_IN_CALL) {
157 device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_USB_ACCESSORY;
158 if (device) break;
159 device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_USB_DEVICE;
160 if (device) break;
161 device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET;
162 if (device) break;
163 device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_AUX_DIGITAL;
164 if (device) break;
165 device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET;
166 if (device) break;
167 }
168 device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_SPEAKER;
169 if (device) break;
170 device = mDefaultOutputDevice;
171 if (device == AUDIO_DEVICE_NONE) {
172 ALOGE("getDeviceForStrategy() no device found for STRATEGY_PHONE, FORCE_SPEAKER");
173 }
174 break;
175 }
176 break;
177
178 case STRATEGY_SONIFICATION:
179
180 // If incall, just select the STRATEGY_PHONE device: The rest of the behavior is handled by
181 // handleIncallSonification().
182 if (isInCall()) {
183 device = getDeviceForStrategy(STRATEGY_PHONE, false /*fromCache*/);
184 break;
185 }
186 // FALL THROUGH
187
188 case STRATEGY_ENFORCED_AUDIBLE:
189 // strategy STRATEGY_ENFORCED_AUDIBLE uses same routing policy as STRATEGY_SONIFICATION
190 // except:
191 // - when in call where it doesn't default to STRATEGY_PHONE behavior
192 // - in countries where not enforced in which case it follows STRATEGY_MEDIA
193
194 if ((strategy == STRATEGY_SONIFICATION) ||
195 (mForceUse[AudioSystem::FOR_SYSTEM] == AudioSystem::FORCE_SYSTEM_ENFORCED)) {
196 device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_SPEAKER;
197 if (device == AUDIO_DEVICE_NONE) {
198 ALOGE("getDeviceForStrategy() speaker device not found for STRATEGY_SONIFICATION");
199 }
200 }
201 // The second device used for sonification is the same as the device used by media strategy
202 // FALL THROUGH
203
204 case STRATEGY_MEDIA: {
205 uint32_t device2 = AUDIO_DEVICE_NONE;
206 if (strategy != STRATEGY_SONIFICATION) {
207 // no sonification on remote submix (e.g. WFD)
208 device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_REMOTE_SUBMIX;
209 }
210 if ((device2 == AUDIO_DEVICE_NONE) &&
211 mHasA2dp && (mForceUse[AudioSystem::FOR_MEDIA] != AudioSystem::FORCE_NO_BT_A2DP) &&
212 (getA2dpOutput() != 0) && !mA2dpSuspended) {
213 device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP;
214 if (device2 == AUDIO_DEVICE_NONE) {
215 device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES;
216 }
217 if (device2 == AUDIO_DEVICE_NONE) {
218 device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER;
219 }
220 }
221 if (device2 == AUDIO_DEVICE_NONE) {
222 device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_WIRED_HEADPHONE;
223 }
224 if (device2 == AUDIO_DEVICE_NONE) {
225 device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_WIRED_HEADSET;
226 }
227 if (device2 == AUDIO_DEVICE_NONE) {
228 device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_USB_ACCESSORY;
229 }
230 if (device2 == AUDIO_DEVICE_NONE) {
231 device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_USB_DEVICE;
232 }
233 if (device2 == AUDIO_DEVICE_NONE) {
234 device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET;
235 }
236 if ((device2 == AUDIO_DEVICE_NONE) && (strategy != STRATEGY_SONIFICATION)) {
237 // no sonification on aux digital (e.g. HDMI)
238 device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_AUX_DIGITAL;
239 }
240 if ((device2 == AUDIO_DEVICE_NONE) &&
241 (mForceUse[AudioSystem::FOR_DOCK] == AudioSystem::FORCE_ANALOG_DOCK)) {
242 device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET;
243 }
244 if (device2 == AUDIO_DEVICE_NONE) {
245 device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_SPEAKER;
246 }
247
248 // device is DEVICE_OUT_SPEAKER if we come from case STRATEGY_SONIFICATION or
249 // STRATEGY_ENFORCED_AUDIBLE, AUDIO_DEVICE_NONE otherwise
250 device |= device2;
251 if (device) break;
252 device = mDefaultOutputDevice;
253 if (device == AUDIO_DEVICE_NONE) {
254 ALOGE("getDeviceForStrategy() no device found for STRATEGY_MEDIA");
255 }
256 } break;
257
258 default:
259 ALOGW("getDeviceForStrategy() unknown strategy: %d", strategy);
260 break;
261 }
262
263 ALOGVV("getDeviceForStrategy() strategy %d, device %x", strategy, device);
264 return device;
265}
266
267AudioPolicyInterface* createAudioPolicyManager(AudioPolicyClientInterface *clientInterface)
268{
269 return new AudioPolicyManager(clientInterface);
270}
271
272void destroyAudioPolicyManager(AudioPolicyInterface *interface)
273{
274 delete interface;
275}
276
277}; // namespace android