diff options
author | Misael Lopez Cruz | 2013-10-27 10:04:50 -0500 |
---|---|---|
committer | Gerrit Code Review | 2013-11-01 19:02:10 -0500 |
commit | 9c25fe1bb8ab3974b69bcc21930699faf05b365d (patch) | |
tree | feb2a1831fba539a5e1aa63b552816f78363ad4f | |
parent | 5aadbddedac5f56c83535c45c6c940ef67c96b5d (diff) | |
download | device-ti-common-open-9c25fe1bb8ab3974b69bcc21930699faf05b365d.tar.gz device-ti-common-open-9c25fe1bb8ab3974b69bcc21930699faf05b365d.tar.xz device-ti-common-open-9c25fe1bb8ab3974b69bcc21930699faf05b365d.zip |
audio: policy: Add initial implementation
Add initial implementation of the multizone audio policy and also
the regular audio policy.
Change-Id: Iacc468f5c6210417212b7b9dbe5de7b883a9ee9d
Signed-off-by: Misael Lopez Cruz <misael.lopez@ti.com>
-rw-r--r-- | audio/policy/Android.mk | 25 | ||||
-rw-r--r-- | audio/policy/legacy/Android.mk | 45 | ||||
-rw-r--r-- | audio/policy/legacy/AudioPolicyManager.cpp | 30 | ||||
-rw-r--r-- | audio/policy/legacy/AudioPolicyManager.h | 33 | ||||
-rw-r--r-- | audio/policy/legacy/TIAudioPolicyManager.cpp | 39 | ||||
-rw-r--r-- | audio/policy/multizone/Android.mk | 49 | ||||
-rw-r--r-- | audio/policy/multizone/AudioPolicyManager.cpp | 3421 | ||||
-rw-r--r-- | audio/policy/multizone/AudioPolicyManager.h | 778 | ||||
-rw-r--r-- | audio/policy/multizone/AudioPolicyParser.cpp | 728 | ||||
-rw-r--r-- | audio/policy/multizone/AudioPolicyParser.h | 136 | ||||
-rw-r--r-- | audio/policy/multizone/TIAudioPolicyManager.cpp | 39 |
11 files changed, 5323 insertions, 0 deletions
diff --git a/audio/policy/Android.mk b/audio/policy/Android.mk new file mode 100644 index 0000000..ee27817 --- /dev/null +++ b/audio/policy/Android.mk | |||
@@ -0,0 +1,25 @@ | |||
1 | # Copyright (C) 2013 Texas Instruments | ||
2 | # | ||
3 | # Licensed under the Apache License, Version 2.0 (the "License"); | ||
4 | # you may not use this file except in compliance with the License. | ||
5 | # You may obtain a copy of the License at | ||
6 | # | ||
7 | # http://www.apache.org/licenses/LICENSE-2.0 | ||
8 | # | ||
9 | # Unless required by applicable law or agreed to in writing, software | ||
10 | # distributed under the License is distributed on an "AS IS" BASIS, | ||
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
12 | # See the License for the specific language governing permissions and | ||
13 | # limitations under the License. | ||
14 | |||
15 | LOCAL_PATH := $(call my-dir) | ||
16 | |||
17 | include $(CLEAR_VARS) | ||
18 | |||
19 | ifeq ($(OMAP_MULTIZONE_AUDIO),true) | ||
20 | # Multizone Audio Policy | ||
21 | include $(LOCAL_PATH)/multizone/Android.mk | ||
22 | else | ||
23 | # Legacy Audio Policy (single output, stock policy) | ||
24 | include $(LOCAL_PATH)/legacy/Android.mk | ||
25 | endif | ||
diff --git a/audio/policy/legacy/Android.mk b/audio/policy/legacy/Android.mk new file mode 100644 index 0000000..ffea52e --- /dev/null +++ b/audio/policy/legacy/Android.mk | |||
@@ -0,0 +1,45 @@ | |||
1 | # Copyright (C) 2013 Texas Instruments | ||
2 | # | ||
3 | # Licensed under the Apache License, Version 2.0 (the "License"); | ||
4 | # you may not use this file except in compliance with the License. | ||
5 | # You may obtain a copy of the License at | ||
6 | # | ||
7 | # http://www.apache.org/licenses/LICENSE-2.0 | ||
8 | # | ||
9 | # Unless required by applicable law or agreed to in writing, software | ||
10 | # distributed under the License is distributed on an "AS IS" BASIS, | ||
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
12 | # See the License for the specific language governing permissions and | ||
13 | # limitations under the License. | ||
14 | |||
15 | LOCAL_PATH := $(call my-dir) | ||
16 | |||
17 | # -------------------------------- | ||
18 | # Multizone Audio Policy Manager | ||
19 | # -------------------------------- | ||
20 | |||
21 | include $(CLEAR_VARS) | ||
22 | |||
23 | LOCAL_MODULE := libaudiopolicy_ti_legacy | ||
24 | LOCAL_MODULE_TAGS := optional | ||
25 | LOCAL_SRC_FILES := AudioPolicyManager.cpp | ||
26 | LOCAL_WHOLE_STATIC_LIBRARIES := libaudiopolicy_legacy | ||
27 | |||
28 | include $(BUILD_STATIC_LIBRARY) | ||
29 | |||
30 | |||
31 | # ----------------- | ||
32 | # TI Audio Policy | ||
33 | # ----------------- | ||
34 | |||
35 | include $(CLEAR_VARS) | ||
36 | |||
37 | LOCAL_MODULE := audio_policy.$(TARGET_BOARD_PLATFORM) | ||
38 | LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw | ||
39 | LOCAL_MODULE_TAGS := optional | ||
40 | LOCAL_SRC_FILES := TIAudioPolicyManager.cpp | ||
41 | LOCAL_SHARED_LIBRARIES := libcutils libutils liblog | ||
42 | LOCAL_STATIC_LIBRARIES := libmedia_helper | ||
43 | LOCAL_WHOLE_STATIC_LIBRARIES := libaudiopolicy_ti_legacy | ||
44 | |||
45 | include $(BUILD_SHARED_LIBRARY) | ||
diff --git a/audio/policy/legacy/AudioPolicyManager.cpp b/audio/policy/legacy/AudioPolicyManager.cpp new file mode 100644 index 0000000..60c53a6 --- /dev/null +++ b/audio/policy/legacy/AudioPolicyManager.cpp | |||
@@ -0,0 +1,30 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2013 Texas Instruments | ||
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 | #include "AudioPolicyManager.h" | ||
18 | |||
19 | namespace android_audio_legacy { | ||
20 | |||
21 | AudioPolicyManager::AudioPolicyManager(AudioPolicyClientInterface *clientInterface) | ||
22 | : AudioPolicyManagerBase(clientInterface) | ||
23 | { | ||
24 | } | ||
25 | |||
26 | AudioPolicyManager::~AudioPolicyManager() | ||
27 | { | ||
28 | } | ||
29 | |||
30 | } // namespace android_audio_legacy | ||
diff --git a/audio/policy/legacy/AudioPolicyManager.h b/audio/policy/legacy/AudioPolicyManager.h new file mode 100644 index 0000000..65a31af --- /dev/null +++ b/audio/policy/legacy/AudioPolicyManager.h | |||
@@ -0,0 +1,33 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2013 Texas Instruments | ||
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 | #ifndef _POLICY_LEGACY_AUDIOPOLICYMANAGER_H_ | ||
18 | #define _POLICY_LEGACY_AUDIOPOLICYMANAGER_H_ | ||
19 | |||
20 | #include <hardware_legacy/AudioPolicyManagerBase.h> | ||
21 | |||
22 | namespace android_audio_legacy { | ||
23 | |||
24 | class AudioPolicyManager: public AudioPolicyManagerBase | ||
25 | { | ||
26 | public: | ||
27 | AudioPolicyManager(AudioPolicyClientInterface *clientInterface); | ||
28 | virtual ~AudioPolicyManager(); | ||
29 | }; | ||
30 | |||
31 | } // namespace android_audio_legacy | ||
32 | |||
33 | #endif // _POLICY_LEGACY_AUDIOPOLICYMANAGER_H_ | ||
diff --git a/audio/policy/legacy/TIAudioPolicyManager.cpp b/audio/policy/legacy/TIAudioPolicyManager.cpp new file mode 100644 index 0000000..43c0707 --- /dev/null +++ b/audio/policy/legacy/TIAudioPolicyManager.cpp | |||
@@ -0,0 +1,39 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2013 Texas Instruments | ||
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 | * This module is based on libhardware_legacy implementation. | ||
17 | * | ||
18 | */ | ||
19 | |||
20 | #define LOG_TAG "TIAudioPolicyManager" | ||
21 | //#define LOG_NDEBUG 0 | ||
22 | |||
23 | #include "AudioPolicyManager.h" | ||
24 | |||
25 | namespace android_audio_legacy { | ||
26 | |||
27 | extern "C" AudioPolicyInterface* createAudioPolicyManager(AudioPolicyClientInterface *clientInterface) | ||
28 | { | ||
29 | ALOGI("Creating TI AudioPolicyManager"); | ||
30 | return new AudioPolicyManager(clientInterface); | ||
31 | } | ||
32 | |||
33 | extern "C" void destroyAudioPolicyManager(AudioPolicyInterface *interface) | ||
34 | { | ||
35 | ALOGI("Destroying TI AudioPolicyManager"); | ||
36 | delete interface; | ||
37 | } | ||
38 | |||
39 | } // namespace android | ||
diff --git a/audio/policy/multizone/Android.mk b/audio/policy/multizone/Android.mk new file mode 100644 index 0000000..06abcb3 --- /dev/null +++ b/audio/policy/multizone/Android.mk | |||
@@ -0,0 +1,49 @@ | |||
1 | # Copyright (C) 2013 Texas Instruments | ||
2 | # | ||
3 | # Licensed under the Apache License, Version 2.0 (the "License"); | ||
4 | # you may not use this file except in compliance with the License. | ||
5 | # You may obtain a copy of the License at | ||
6 | # | ||
7 | # http://www.apache.org/licenses/LICENSE-2.0 | ||
8 | # | ||
9 | # Unless required by applicable law or agreed to in writing, software | ||
10 | # distributed under the License is distributed on an "AS IS" BASIS, | ||
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
12 | # See the License for the specific language governing permissions and | ||
13 | # limitations under the License. | ||
14 | |||
15 | LOCAL_PATH := $(call my-dir) | ||
16 | |||
17 | # -------------------------------- | ||
18 | # Multizone Audio Policy Manager | ||
19 | # -------------------------------- | ||
20 | |||
21 | include $(CLEAR_VARS) | ||
22 | |||
23 | LOCAL_MODULE := libaudiopolicy_ti_multizone | ||
24 | LOCAL_MODULE_TAGS := optional | ||
25 | LOCAL_SRC_FILES := \ | ||
26 | AudioPolicyManager.cpp \ | ||
27 | AudioPolicyParser.cpp | ||
28 | LOCAL_SHARED_LIBRARIES := libcutils libutils liblog | ||
29 | LOCAL_STATIC_LIBRARIES := libmedia_helper | ||
30 | LOCAL_WHOLE_STATIC_LIBRARIES := libaudiopolicy_legacy_base | ||
31 | |||
32 | include $(BUILD_STATIC_LIBRARY) | ||
33 | |||
34 | |||
35 | # ----------------- | ||
36 | # TI Audio Policy | ||
37 | # ----------------- | ||
38 | |||
39 | include $(CLEAR_VARS) | ||
40 | |||
41 | LOCAL_MODULE := audio_policy.$(TARGET_BOARD_PLATFORM) | ||
42 | LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw | ||
43 | LOCAL_MODULE_TAGS := optional | ||
44 | LOCAL_SRC_FILES := TIAudioPolicyManager.cpp | ||
45 | LOCAL_SHARED_LIBRARIES := libcutils libutils liblog | ||
46 | LOCAL_STATIC_LIBRARIES := libmedia_helper | ||
47 | LOCAL_WHOLE_STATIC_LIBRARIES := libaudiopolicy_ti_multizone | ||
48 | |||
49 | include $(BUILD_SHARED_LIBRARY) | ||
diff --git a/audio/policy/multizone/AudioPolicyManager.cpp b/audio/policy/multizone/AudioPolicyManager.cpp new file mode 100644 index 0000000..915cb72 --- /dev/null +++ b/audio/policy/multizone/AudioPolicyManager.cpp | |||
@@ -0,0 +1,3421 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2013 Texas Instruments | ||
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 | * This module is based on libhardware_legacy implementation. | ||
17 | * | ||
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 <cutils/properties.h> | ||
38 | #include <utils/Log.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 | |||
44 | #include "AudioPolicyManager.h" | ||
45 | |||
46 | namespace android_audio_legacy { | ||
47 | |||
48 | // ---------------------------------------------------------------------------- | ||
49 | // AudioPolicyInterface implementation | ||
50 | // ---------------------------------------------------------------------------- | ||
51 | |||
52 | status_t AudioPolicyManager::setDeviceConnectionState(audio_devices_t device, | ||
53 | AudioSystem::device_connection_state state, | ||
54 | const char *device_address) | ||
55 | { | ||
56 | ALOGI("setDeviceConnectionState() device 0x%08x state %d address %s", | ||
57 | device, state, device_address); | ||
58 | |||
59 | // connect/disconnect only 1 device at a time | ||
60 | if (!audio_is_output_device(device) && !audio_is_input_device(device)) { | ||
61 | return BAD_VALUE; | ||
62 | } | ||
63 | |||
64 | if (strlen(device_address) >= MAX_DEVICE_ADDRESS_LEN) { | ||
65 | ALOGE("setDeviceConnectionState() invalid address: %s", device_address); | ||
66 | return BAD_VALUE; | ||
67 | } | ||
68 | |||
69 | // handle output devices | ||
70 | if (audio_is_output_device(device)) { | ||
71 | |||
72 | if (!mHasA2dp && audio_is_a2dp_device(device)) { | ||
73 | ALOGE("setDeviceConnectionState() invalid A2DP device: 0x%08x", device); | ||
74 | return BAD_VALUE; | ||
75 | } | ||
76 | if (!mHasUsb && audio_is_usb_device(device)) { | ||
77 | ALOGE("setDeviceConnectionState() invalid USB audio device: 0x%08x", device); | ||
78 | return BAD_VALUE; | ||
79 | } | ||
80 | if (!mHasRemoteSubmix && audio_is_remote_submix_device((audio_devices_t)device)) { | ||
81 | ALOGE("setDeviceConnectionState() invalid remote submix audio device: 0x%08x", | ||
82 | device); | ||
83 | return BAD_VALUE; | ||
84 | } | ||
85 | |||
86 | // HEADPHONE is mapped to a listening zone, discard its input | ||
87 | if (device == AUDIO_DEVICE_OUT_WIRED_HEADSET) { | ||
88 | device = AUDIO_DEVICE_OUT_WIRED_HEADPHONE; | ||
89 | } | ||
90 | |||
91 | switch (state) { | ||
92 | |||
93 | // handle output device connection | ||
94 | case AudioSystem::DEVICE_STATE_AVAILABLE: { | ||
95 | if (mAvailableOutputDevices & device) { | ||
96 | ALOGW("setDeviceConnectionState() device already connected 0x%08x", device); | ||
97 | return INVALID_OPERATION; | ||
98 | } | ||
99 | |||
100 | // register new device as available | ||
101 | ALOGV("setDeviceConnectionState() connecting device 0x%08x", device); | ||
102 | mAvailableOutputDevices = (audio_devices_t)(mAvailableOutputDevices | device); | ||
103 | |||
104 | if (mHasA2dp && audio_is_a2dp_device(device)) { | ||
105 | mA2dpDeviceAddress = String8(device_address, MAX_DEVICE_ADDRESS_LEN); | ||
106 | mA2dpSuspended = false; | ||
107 | } else if (audio_is_bluetooth_sco_device(device)) { | ||
108 | mScoDeviceAddress = String8(device_address, MAX_DEVICE_ADDRESS_LEN); | ||
109 | } else if (mHasUsb && audio_is_usb_device(device)) { | ||
110 | mUsbCardAndDevice = String8(device_address, MAX_DEVICE_ADDRESS_LEN); | ||
111 | } | ||
112 | |||
113 | if ((device == AUDIO_DEVICE_OUT_WIRED_HEADPHONE) || | ||
114 | (device == AUDIO_DEVICE_OUT_WIRED_HEADPHONE2)) { | ||
115 | ALOGV("setDeviceConnectionState() headphone inserted (0x%08x), unmuting", | ||
116 | device); | ||
117 | audio_io_handle_t output = findOutput(device); | ||
118 | AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output); | ||
119 | // Mute/unmute is done only if the heaphone is the only device | ||
120 | // handled by the output | ||
121 | if (output && (outputDesc->device() == device)) | ||
122 | muteOutput(output, false); | ||
123 | } | ||
124 | } break; | ||
125 | |||
126 | // handle output device disconnection | ||
127 | case AudioSystem::DEVICE_STATE_UNAVAILABLE: { | ||
128 | if (!(mAvailableOutputDevices & device)) { | ||
129 | ALOGW("setDeviceConnectionState() device not connected: 0x08%x", device); | ||
130 | return INVALID_OPERATION; | ||
131 | } | ||
132 | |||
133 | // remove device from available output devices | ||
134 | ALOGV("setDeviceConnectionState() disconnecting device 0x%08x", device); | ||
135 | mAvailableOutputDevices = (audio_devices_t)(mAvailableOutputDevices & ~device); | ||
136 | |||
137 | if (mHasA2dp && audio_is_a2dp_device(device)) { | ||
138 | mA2dpDeviceAddress = ""; | ||
139 | mA2dpSuspended = false; | ||
140 | } else if (audio_is_bluetooth_sco_device(device)) { | ||
141 | mScoDeviceAddress = ""; | ||
142 | } else if (mHasUsb && audio_is_usb_device(device)) { | ||
143 | mUsbCardAndDevice = ""; | ||
144 | } | ||
145 | // not currently handling multiple simultaneous submixes: ignoring remote submix | ||
146 | // case and address | ||
147 | |||
148 | // HP1 and HP2 event don't cause the dynamic re-routing, just mute to | ||
149 | // prevent high-volume when the headphone is connected again | ||
150 | if ((device == AUDIO_DEVICE_OUT_WIRED_HEADPHONE) || | ||
151 | (device == AUDIO_DEVICE_OUT_WIRED_HEADPHONE2)) { | ||
152 | ALOGV("setDeviceConnectionState() headphone removed (0x%08x), muting", | ||
153 | device); | ||
154 | audio_io_handle_t output = findOutput(device); | ||
155 | AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output); | ||
156 | // Mute/unmute is done only if the heaphone is the only device | ||
157 | // handled by the output | ||
158 | if (output && (outputDesc->device() == device)) | ||
159 | muteOutput(output, true); | ||
160 | } else { | ||
161 | disconnectDevice(device); | ||
162 | } | ||
163 | |||
164 | } break; | ||
165 | |||
166 | default: | ||
167 | ALOGE("setDeviceConnectionState() invalid state: %x", state); | ||
168 | return BAD_VALUE; | ||
169 | } | ||
170 | |||
171 | checkA2dpSuspend(); | ||
172 | |||
173 | // We don't do dynamic routing based on new devices being attached | ||
174 | |||
175 | // Also add its input device | ||
176 | if ((device == AUDIO_DEVICE_OUT_BLUETOOTH_SCO) || | ||
177 | (device == AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET) || | ||
178 | (device == AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT)) { | ||
179 | device = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET; | ||
180 | } else { | ||
181 | return NO_ERROR; | ||
182 | } | ||
183 | } | ||
184 | |||
185 | // handle input devices | ||
186 | if (audio_is_input_device(device)) { | ||
187 | |||
188 | switch (state) { | ||
189 | |||
190 | // handle input device connection | ||
191 | case AudioSystem::DEVICE_STATE_AVAILABLE: { | ||
192 | if (mAvailableInputDevices & device) { | ||
193 | ALOGW("setDeviceConnectionState() device already connected: 0x%08x", device); | ||
194 | return INVALID_OPERATION; | ||
195 | } | ||
196 | ALOGV("setDeviceConnectionState() connecting device 0x%08x", device); | ||
197 | mAvailableInputDevices = mAvailableInputDevices | (device & ~AUDIO_DEVICE_BIT_IN); | ||
198 | } break; | ||
199 | |||
200 | // handle input device disconnection | ||
201 | case AudioSystem::DEVICE_STATE_UNAVAILABLE: { | ||
202 | if (!(mAvailableInputDevices & device)) { | ||
203 | ALOGW("setDeviceConnectionState() device not connected: 0x%08x", device); | ||
204 | return INVALID_OPERATION; | ||
205 | } | ||
206 | ALOGV("setDeviceConnectionState() disconnecting device 0x%08x", device); | ||
207 | mAvailableInputDevices = (audio_devices_t) (mAvailableInputDevices & ~device); | ||
208 | } break; | ||
209 | |||
210 | default: | ||
211 | ALOGE("setDeviceConnectionState() invalid state: %x", state); | ||
212 | return BAD_VALUE; | ||
213 | } | ||
214 | |||
215 | audio_io_handle_t activeInput = getActiveInput(); | ||
216 | if (activeInput != 0) { | ||
217 | AudioInputDescriptor *inputDesc = mInputs.valueFor(activeInput); | ||
218 | audio_devices_t newDevice = getDeviceForInputSource(inputDesc->mInputSource); | ||
219 | if ((newDevice != AUDIO_DEVICE_NONE) && (newDevice != inputDesc->mDevice)) { | ||
220 | ALOGV("setDeviceConnectionState() changing device from 0x%x to 0x%x for input %d", | ||
221 | inputDesc->mDevice, newDevice, activeInput); | ||
222 | inputDesc->mDevice = newDevice; | ||
223 | AudioParameter param = AudioParameter(); | ||
224 | param.addInt(String8(AudioParameter::keyRouting), (int)newDevice); | ||
225 | mpClientInterface->setParameters(activeInput, param.toString()); | ||
226 | } | ||
227 | } | ||
228 | |||
229 | return NO_ERROR; | ||
230 | } | ||
231 | |||
232 | ALOGW("setDeviceConnectionState() invalid device: %x", device); | ||
233 | return BAD_VALUE; | ||
234 | } | ||
235 | |||
236 | AudioSystem::device_connection_state | ||
237 | AudioPolicyManager::getDeviceConnectionState(audio_devices_t device, | ||
238 | const char *device_address) | ||
239 | { | ||
240 | AudioSystem::device_connection_state state = AudioSystem::DEVICE_STATE_UNAVAILABLE; | ||
241 | String8 address = String8(device_address); | ||
242 | |||
243 | if (audio_is_output_device(device)) { | ||
244 | if (device & mAvailableOutputDevices) { | ||
245 | if (audio_is_a2dp_device(device) && | ||
246 | (!mHasA2dp || (address != "" && mA2dpDeviceAddress != address))) { | ||
247 | return state; | ||
248 | } | ||
249 | if (audio_is_bluetooth_sco_device(device) && | ||
250 | address != "" && mScoDeviceAddress != address) { | ||
251 | return state; | ||
252 | } | ||
253 | if (audio_is_usb_device(device) && | ||
254 | (!mHasUsb || (address != "" && mUsbCardAndDevice != address))) { | ||
255 | ALOGE("getDeviceConnectionState() invalid device: 0x%08x", device); | ||
256 | return state; | ||
257 | } | ||
258 | if (audio_is_remote_submix_device((audio_devices_t)device) && !mHasRemoteSubmix) { | ||
259 | return state; | ||
260 | } | ||
261 | state = AudioSystem::DEVICE_STATE_AVAILABLE; | ||
262 | } | ||
263 | } else if (audio_is_input_device(device)) { | ||
264 | if (device & mAvailableInputDevices) { | ||
265 | state = AudioSystem::DEVICE_STATE_AVAILABLE; | ||
266 | } | ||
267 | } | ||
268 | |||
269 | return state; | ||
270 | } | ||
271 | |||
272 | void AudioPolicyManager::setPhoneState(int state) | ||
273 | { | ||
274 | ALOGV("setPhoneState() state %d", state); | ||
275 | |||
276 | if (state < 0 || state >= AudioSystem::NUM_MODES) { | ||
277 | ALOGW("setPhoneState() invalid state %d", state); | ||
278 | return; | ||
279 | } | ||
280 | |||
281 | if (state == mPhoneState ) { | ||
282 | ALOGW("setPhoneState() setting same state %d", state); | ||
283 | return; | ||
284 | } | ||
285 | |||
286 | // if leaving call state, handle special case of active streams | ||
287 | // pertaining to sonification strategy see handleIncallSonification() | ||
288 | if (isInCall()) { | ||
289 | ALOGV("setPhoneState() in call state management: new state is %d", state); | ||
290 | for (int stream = 0; stream < AudioSystem::NUM_STREAM_TYPES; stream++) { | ||
291 | handleIncallSonification(stream, false, true); | ||
292 | } | ||
293 | } | ||
294 | |||
295 | // store previous phone state for management of sonification strategy below | ||
296 | int oldState = mPhoneState; | ||
297 | mPhoneState = state; | ||
298 | bool force = false; | ||
299 | |||
300 | // are we entering or starting a call | ||
301 | if (!isStateInCall(oldState) && isStateInCall(state)) { | ||
302 | ALOGV(" Entering call in setPhoneState()"); | ||
303 | // force routing command to audio hardware when starting a call | ||
304 | // even if no device change is needed | ||
305 | force = true; | ||
306 | } else if (isStateInCall(oldState) && !isStateInCall(state)) { | ||
307 | ALOGV(" Exiting call in setPhoneState()"); | ||
308 | // force routing command to audio hardware when exiting a call | ||
309 | // even if no device change is needed | ||
310 | force = true; | ||
311 | } else if (isStateInCall(state) && (state != oldState)) { | ||
312 | ALOGV(" Switching between telephony and VoIP in setPhoneState()"); | ||
313 | // force routing command to audio hardware when switching between telephony and VoIP | ||
314 | // even if no device change is needed | ||
315 | force = true; | ||
316 | } | ||
317 | |||
318 | checkA2dpSuspend(); | ||
319 | |||
320 | // Restrict voice calls to cabin speakers | ||
321 | audio_devices_t device = getRefinedZoneDevices(AUDIO_ZONE_CABIN, | ||
322 | AudioSystem::VOICE_CALL); | ||
323 | |||
324 | // Set the voice call route in the audio hardware (primary output) | ||
325 | AudioParameter param = AudioParameter(); | ||
326 | param.addInt(String8(AUDIO_PARAMETER_CALL_ROUTING), (int)device); | ||
327 | mpClientInterface->setParameters(mPrimaryOutput, param.toString()); | ||
328 | |||
329 | // if entering in call state, handle special case of active streams | ||
330 | // pertaining to sonification strategy see handleIncallSonification() | ||
331 | if (isStateInCall(state)) { | ||
332 | ALOGV("setPhoneState() in call state management: new state is %d", state); | ||
333 | for (int stream = 0; stream < AudioSystem::NUM_STREAM_TYPES; stream++) { | ||
334 | handleIncallSonification(stream, true, true); | ||
335 | } | ||
336 | } | ||
337 | } | ||
338 | |||
339 | void AudioPolicyManager::setForceUse(AudioSystem::force_use usage, | ||
340 | AudioSystem::forced_config config) | ||
341 | { | ||
342 | ALOGV("setForceUse() usage %d, config %d, mPhoneState %d", | ||
343 | usage, config, mPhoneState); | ||
344 | |||
345 | bool forceVolumeReeval = false; | ||
346 | switch(usage) { | ||
347 | case AudioSystem::FOR_COMMUNICATION: | ||
348 | if (config != AudioSystem::FORCE_SPEAKER && | ||
349 | config != AudioSystem::FORCE_BT_SCO && | ||
350 | config != AudioSystem::FORCE_NONE) { | ||
351 | ALOGW("setForceUse() invalid config %d for FOR_COMMUNICATION", | ||
352 | config); | ||
353 | return; | ||
354 | } | ||
355 | forceVolumeReeval = true; | ||
356 | mForceUse[usage] = config; | ||
357 | break; | ||
358 | case AudioSystem::FOR_MEDIA: | ||
359 | if (config != AudioSystem::FORCE_HEADPHONES && | ||
360 | config != AudioSystem::FORCE_BT_A2DP && | ||
361 | config != AudioSystem::FORCE_WIRED_ACCESSORY && | ||
362 | config != AudioSystem::FORCE_ANALOG_DOCK && | ||
363 | config != AudioSystem::FORCE_DIGITAL_DOCK && | ||
364 | config != AudioSystem::FORCE_NONE && | ||
365 | config != AudioSystem::FORCE_NO_BT_A2DP) { | ||
366 | ALOGW("setForceUse() invalid config %d for FOR_MEDIA", config); | ||
367 | return; | ||
368 | } | ||
369 | mForceUse[usage] = config; | ||
370 | break; | ||
371 | case AudioSystem::FOR_RECORD: | ||
372 | if (config != AudioSystem::FORCE_BT_SCO && | ||
373 | config != AudioSystem::FORCE_WIRED_ACCESSORY && | ||
374 | config != AudioSystem::FORCE_NONE) { | ||
375 | ALOGW("setForceUse() invalid config %d for FOR_RECORD", config); | ||
376 | return; | ||
377 | } | ||
378 | mForceUse[usage] = config; | ||
379 | break; | ||
380 | case AudioSystem::FOR_DOCK: | ||
381 | if (config != AudioSystem::FORCE_NONE && | ||
382 | config != AudioSystem::FORCE_BT_CAR_DOCK && | ||
383 | config != AudioSystem::FORCE_BT_DESK_DOCK && | ||
384 | config != AudioSystem::FORCE_WIRED_ACCESSORY && | ||
385 | config != AudioSystem::FORCE_ANALOG_DOCK && | ||
386 | config != AudioSystem::FORCE_DIGITAL_DOCK) { | ||
387 | ALOGW("setForceUse() invalid config %d for FOR_DOCK", config); | ||
388 | } | ||
389 | forceVolumeReeval = true; | ||
390 | mForceUse[usage] = config; | ||
391 | break; | ||
392 | case AudioSystem::FOR_SYSTEM: | ||
393 | if (config != AudioSystem::FORCE_NONE && | ||
394 | config != AudioSystem::FORCE_SYSTEM_ENFORCED) { | ||
395 | ALOGW("setForceUse() invalid config %d for FOR_SYSTEM", config); | ||
396 | } | ||
397 | forceVolumeReeval = true; | ||
398 | mForceUse[usage] = config; | ||
399 | break; | ||
400 | default: | ||
401 | ALOGW("setForceUse() invalid usage %d", usage); | ||
402 | break; | ||
403 | } | ||
404 | |||
405 | // Force use and force configs are not scalable for multiple outputs in | ||
406 | // automotive environments: | ||
407 | // - FOR_COMMUNICATION: phone call is routed through BT SCO to cabin | ||
408 | // speakers. The existing force configs don't cause any route update | ||
409 | // - FOR_MEDIA: there may be multiple outputs playing media streams, so | ||
410 | // the force config cannot be fairly associated with one of them. | ||
411 | // It's currently used only for FORCE_NONE and FORCE_NO_BT_A2DP. | ||
412 | // The latter will be handled at setDeviceConnectionState() when | ||
413 | // BT A2DP is disconnected. | ||
414 | // - FOR_DOCK: It's not applicable either as it refers to the Android | ||
415 | // device being docked | ||
416 | // - FOR_SYSTEM: Used for camera sound (shutter). | ||
417 | // | ||
418 | // The logic is kept not to disturb AudioService, but there won't be | ||
419 | // any actions taken. | ||
420 | } | ||
421 | |||
422 | AudioSystem::forced_config AudioPolicyManager::getForceUse(AudioSystem::force_use usage) | ||
423 | { | ||
424 | return mForceUse[usage]; | ||
425 | } | ||
426 | |||
427 | void AudioPolicyManager::setSystemProperty(const char* property, const char* value) | ||
428 | { | ||
429 | ALOGV("setSystemProperty() property %s, value %s", property, value); | ||
430 | } | ||
431 | |||
432 | status_t AudioPolicyManager::setZoneDevices_l(audio_zones_t zone, | ||
433 | audio_devices_t devices) | ||
434 | { | ||
435 | if (AudioSystem::popCount(zone) > 1) { | ||
436 | ALOGE("setZoneDevices() cannot set multiple zones simultaneously"); | ||
437 | return BAD_VALUE; | ||
438 | } | ||
439 | |||
440 | if (devices == AUDIO_DEVICE_NONE) { | ||
441 | ALOGE("setZoneDevices() at least one device must be set per zone"); | ||
442 | return BAD_VALUE; | ||
443 | } | ||
444 | |||
445 | // Devices must be owned by only one zone | ||
446 | for (size_t i = 0; i < mZoneDevices.size(); i++) { | ||
447 | if (zone != mZoneDevices.keyAt(i)) { | ||
448 | audio_devices_t common = devices & mZoneDevices.valueAt(i); | ||
449 | if (common) { | ||
450 | ALOGE("setZoneDevices_l() devices 0x%08x are already set in zone 0x%x", | ||
451 | common, mZoneDevices.keyAt(i)); | ||
452 | return INVALID_OPERATION; | ||
453 | } | ||
454 | } | ||
455 | } | ||
456 | |||
457 | ALOGI("setZoneDevices_l() zone 0x%x set to devices 0x%08x", zone, devices); | ||
458 | mZoneDevices.replaceValueFor(zone, devices); | ||
459 | |||
460 | return NO_ERROR; | ||
461 | } | ||
462 | |||
463 | status_t AudioPolicyManager::setZoneDevices(audio_zones_t zone, | ||
464 | audio_devices_t devices) | ||
465 | { | ||
466 | ALOGI("setZoneDevices() zone 0x%x devices 0x%08x", zone, devices); | ||
467 | |||
468 | // Attached devices are assigned to a zone and cannot be moved | ||
469 | audio_devices_t tmpDevices = getZoneDevices(zone) & ~devices; | ||
470 | if (tmpDevices & mAttachedOutputDevices) { | ||
471 | ALOGE("setZoneDevices() attached devices 0x%08x cannot be removed", | ||
472 | tmpDevices & mAttachedOutputDevices); | ||
473 | return INVALID_OPERATION; | ||
474 | } | ||
475 | |||
476 | // Reject devices that are not supported by the zone, as defined | ||
477 | // in the zone_affinity section of the audio_policy.conf file | ||
478 | tmpDevices = devices & ~getZoneSupportedDevices(zone); | ||
479 | if (tmpDevices) { | ||
480 | ALOGE("setZoneDevices() devices 0x%08x not supported in zone 0x%x", | ||
481 | tmpDevices, zone); | ||
482 | return INVALID_OPERATION; | ||
483 | } | ||
484 | |||
485 | // Update the devices in the listening zone descriptor | ||
486 | status_t status; | ||
487 | status = setZoneDevices_l(zone, devices); | ||
488 | if (status != NO_ERROR) { | ||
489 | return status; | ||
490 | } | ||
491 | |||
492 | // Sessions using the zone being set must update their device too | ||
493 | for (size_t i = 0; i < mSessions.size(); i++) { | ||
494 | SessionDescriptor *sessionDesc = mSessions.valueAt(i); | ||
495 | if (sessionDesc->zones() & zone) { | ||
496 | ALOGI("setZoneDevices() update session %u with new zone devices 0x%08x", | ||
497 | sessionDesc->sessionId(), devices); | ||
498 | setSessionZones(sessionDesc->sessionId(), sessionDesc->zones()); | ||
499 | } | ||
500 | } | ||
501 | |||
502 | return NO_ERROR; | ||
503 | } | ||
504 | |||
505 | audio_devices_t AudioPolicyManager::getZoneDevices(audio_zones_t zones) | ||
506 | { | ||
507 | audio_devices_t devices = AUDIO_DEVICE_NONE; | ||
508 | |||
509 | for (size_t i = 0; i < mZoneDevices.size(); i++) { | ||
510 | if (zones & mZoneDevices.keyAt(i)) { | ||
511 | devices |= mZoneDevices.valueAt(i); | ||
512 | } | ||
513 | } | ||
514 | |||
515 | ALOGV("getZoneDevices() zones 0x%x devices 0x%08x", zones, devices); | ||
516 | |||
517 | return devices; | ||
518 | } | ||
519 | |||
520 | status_t AudioPolicyManager::setSessionZones(int session, audio_zones_t zones) | ||
521 | { | ||
522 | ALOGI("setSessionZones() session %d zones 0x%x", session, zones); | ||
523 | |||
524 | SessionDescriptor *sessionDesc; | ||
525 | ssize_t index = mSessions.indexOfKey(session); | ||
526 | if (index < 0) { | ||
527 | // Create an session desc entry with default output handle | ||
528 | ALOGV("setSessionZones() session %d hasn't been used yet", session); | ||
529 | sessionDesc = new SessionDescriptor(session, 0, zones, getZoneDevices(zones)); | ||
530 | mSessions.add(session, sessionDesc); | ||
531 | } else { | ||
532 | ALOGV("setSessionZones() session %d zones updated", session); | ||
533 | sessionDesc = mSessions.valueAt(index); | ||
534 | audio_devices_t prevDevices = sessionDesc->devices(); | ||
535 | sessionDesc->mZones = zones; | ||
536 | sessionDesc->mDevices = getZoneDevices(zones); | ||
537 | |||
538 | // Move tracks from previous to new devices if the output is already open | ||
539 | moveTracks(sessionDesc->mId, prevDevices, sessionDesc->devices()); | ||
540 | } | ||
541 | |||
542 | return NO_ERROR; | ||
543 | } | ||
544 | |||
545 | audio_zones_t AudioPolicyManager::getSessionZones(int session) | ||
546 | { | ||
547 | audio_zones_t zones; | ||
548 | |||
549 | ssize_t index = mSessions.indexOfKey(session); | ||
550 | if (index < 0) { | ||
551 | ALOGV("getSessionZones() session %d is not active", session); | ||
552 | zones = AUDIO_ZONE_NONE; | ||
553 | } else { | ||
554 | SessionDescriptor *sessionDesc = mSessions.valueAt(index); | ||
555 | zones = sessionDesc->zones(); | ||
556 | ALOGV("getSessionZones() session %d zones 0x%x", session, zones); | ||
557 | } | ||
558 | |||
559 | return zones; | ||
560 | } | ||
561 | |||
562 | status_t AudioPolicyManager::setZoneVolume(audio_zones_t zone, float volume) | ||
563 | { | ||
564 | ALOGI("setZoneVolume() zone 0x%x volume %f", zone, volume); | ||
565 | |||
566 | if (AudioSystem::popCount(zone) > 1) { | ||
567 | ALOGE("setZoneVolume() cannot set multiple zones simultaneously"); | ||
568 | return BAD_VALUE; | ||
569 | } | ||
570 | |||
571 | if (!audio_is_output_zone(zone)) { | ||
572 | ALOGE("setZoneVolume() zone 0x%x is invalid", zone); | ||
573 | return BAD_VALUE; | ||
574 | } | ||
575 | |||
576 | if (volume < 0.0f || volume > 1.0f) { | ||
577 | ALOGE("setZoneVolume() volume %f is out of limits", volume); | ||
578 | return BAD_VALUE; | ||
579 | } | ||
580 | |||
581 | ssize_t index = mZoneVolume.indexOfKey(zone); | ||
582 | if (index < 0) { | ||
583 | ALOGE("setZoneVolume() zone 0x%x is not supported", zone); | ||
584 | return BAD_VALUE; | ||
585 | } | ||
586 | |||
587 | mZoneVolume.replaceValueAt(index, volume); | ||
588 | |||
589 | // Update the volumes of all sessions playing on the listening zone | ||
590 | // whose volume just changed | ||
591 | for (size_t i = 0; i < mSessions.size(); i++) { | ||
592 | SessionDescriptor *sessionDesc = mSessions.valueAt(i); | ||
593 | int session = sessionDesc->sessionId(); | ||
594 | |||
595 | if (getSessionZones(session) & zone) { | ||
596 | float sessionVolume = sessionDesc->mVolume.valueFor(zone); | ||
597 | if (setSessionVolume_l(session, zone, sessionVolume) != NO_ERROR) { | ||
598 | ALOGE("setZoneVolume() couldn't to set volume for session %d on zone 0x%x", | ||
599 | session, zone); | ||
600 | } | ||
601 | } | ||
602 | } | ||
603 | |||
604 | return NO_ERROR; | ||
605 | } | ||
606 | |||
607 | float AudioPolicyManager::getZoneVolume(audio_zones_t zone) | ||
608 | { | ||
609 | float zoneVolume = -1.0f; | ||
610 | |||
611 | if (AudioSystem::popCount(zone) > 1) { | ||
612 | ALOGE("getZoneVolume() cannot get multiple zones simultaneously"); | ||
613 | return zoneVolume; | ||
614 | } | ||
615 | |||
616 | if (!audio_is_output_zone(zone)) { | ||
617 | ALOGE("getZoneVolume() zone 0x%x is invalid", zone); | ||
618 | return zoneVolume; | ||
619 | } | ||
620 | |||
621 | ssize_t index = mZoneVolume.indexOfKey(zone); | ||
622 | if (index < 0) { | ||
623 | ALOGE("getZoneVolume() zone 0x%x is not supported", zone); | ||
624 | return zoneVolume; | ||
625 | } | ||
626 | |||
627 | zoneVolume = mZoneVolume.valueAt(index); | ||
628 | |||
629 | ALOGV("getZoneVolume() zone 0x%x volume %f", zone, zoneVolume); | ||
630 | |||
631 | return zoneVolume; | ||
632 | } | ||
633 | |||
634 | status_t AudioPolicyManager::setSessionVolume_l(int session, | ||
635 | audio_zones_t zone, | ||
636 | float volume) | ||
637 | { | ||
638 | SessionDescriptor *sessionDesc = mSessions.valueFor(session); | ||
639 | audio_io_handle_t output = sessionDesc->mId; | ||
640 | audio_zones_t activeZones = getSessionZones(session); | ||
641 | |||
642 | if (zone & activeZones) { | ||
643 | float zoneVolume = volume * mZoneVolume.valueFor(zone); | ||
644 | |||
645 | // Duplicating output sets the volume to the output(s) that is actually | ||
646 | // handling that zone | ||
647 | SortedVector<audio_io_handle_t> zoneOutputs; | ||
648 | findOutputsInZone(output, zone, zoneOutputs); | ||
649 | for (size_t i = 0; i < zoneOutputs.size(); i++) { | ||
650 | mpClientInterface->setZoneVolume(zoneOutputs.itemAt(i), session, zoneVolume); | ||
651 | } | ||
652 | } | ||
653 | |||
654 | return NO_ERROR; | ||
655 | } | ||
656 | |||
657 | status_t AudioPolicyManager::setSessionVolume(int session, | ||
658 | audio_zones_t zones, | ||
659 | float volume) | ||
660 | { | ||
661 | ALOGI("setSessionVolume() session %d zones 0x%x volume %f", | ||
662 | session, zones, volume); | ||
663 | |||
664 | ssize_t index = mSessions.indexOfKey(session); | ||
665 | if (index < 0) { | ||
666 | ALOGE("setSessionVolume() session %d is not active", session); | ||
667 | return BAD_VALUE; | ||
668 | } | ||
669 | |||
670 | if (!audio_is_output_zones(zones)) { | ||
671 | ALOGE("setSessionVolume() zones 0x%x are not valid", zones); | ||
672 | return BAD_VALUE; | ||
673 | } | ||
674 | |||
675 | if (volume < 0.0f || volume > 1.0f) { | ||
676 | ALOGE("setSessionVolume() volume %f is out of limits", volume); | ||
677 | return BAD_VALUE; | ||
678 | } | ||
679 | |||
680 | SessionDescriptor *sessionDesc = mSessions.valueAt(index); | ||
681 | |||
682 | for (audio_zones_t zone = AUDIO_ZONE_LAST; zone & AUDIO_ZONE_ALL; zone >>= 1) { | ||
683 | audio_zones_t cur = zone & zones; | ||
684 | if (cur != AUDIO_ZONE_NONE) { | ||
685 | // The volume for the session takes into account the coarse per-zone | ||
686 | // volume as well | ||
687 | sessionDesc->mVolume.replaceValueFor(cur, volume); | ||
688 | float zoneVolume = mZoneVolume.valueFor(cur); | ||
689 | |||
690 | // Apply the calculated volume | ||
691 | ALOGV("setSessionVolume() session %d zone-vol %f session-vol %f final-vol %f", | ||
692 | session, zoneVolume, volume, zoneVolume * volume); | ||
693 | setSessionVolume_l(session, cur, volume); | ||
694 | } | ||
695 | } | ||
696 | |||
697 | return NO_ERROR; | ||
698 | } | ||
699 | |||
700 | float AudioPolicyManager::getSessionVolume(int session, audio_zones_t zone) | ||
701 | { | ||
702 | float sessionVolume = -1.0f; | ||
703 | |||
704 | ssize_t index = mSessions.indexOfKey(session); | ||
705 | if (index < 0) { | ||
706 | ALOGE("getSessionVolume() session %d is not active", session); | ||
707 | return sessionVolume; | ||
708 | } | ||
709 | |||
710 | if (AudioSystem::popCount(zone) > 1) { | ||
711 | ALOGE("getSessionVolume() cannot get multiple zones simultaneously"); | ||
712 | return sessionVolume; | ||
713 | } | ||
714 | |||
715 | if (!audio_is_output_zone(zone)) { | ||
716 | ALOGE("getSessionVolume() zone 0x%x is not valid", zone); | ||
717 | return sessionVolume; | ||
718 | } | ||
719 | |||
720 | SessionDescriptor *sessionDesc = mSessions.valueAt(index); | ||
721 | sessionVolume = sessionDesc->mVolume.valueFor(zone); | ||
722 | |||
723 | ALOGV("getSessionVolume() session %d volume %f", session, sessionVolume); | ||
724 | |||
725 | return sessionVolume; | ||
726 | } | ||
727 | |||
728 | audio_io_handle_t AudioPolicyManager::getOutput(AudioSystem::stream_type stream, | ||
729 | uint32_t samplingRate, | ||
730 | uint32_t format, | ||
731 | uint32_t channelMask, | ||
732 | AudioSystem::output_flags flags, | ||
733 | int session) | ||
734 | { | ||
735 | ALOGI("getOutput() stream %d rate %d format %d channelMask %x flags %x session %d", | ||
736 | stream, samplingRate, format, channelMask, flags, session); | ||
737 | |||
738 | // Find the best zone for this session, based on explicit requests or | ||
739 | // predefined policy rules | ||
740 | selectZones(session, stream); | ||
741 | |||
742 | // selectZones() must have returned valid zone(s) and device(s) since the | ||
743 | // last selection mechanism is a fixed listening zone | ||
744 | ssize_t index = mSessions.indexOfKey(session); | ||
745 | if (index < 0) { | ||
746 | ALOGE("getOutput() policy failed to find a zone for session %d", session); | ||
747 | return 0; | ||
748 | } | ||
749 | |||
750 | audio_devices_t devices = getSessionDevices(session); | ||
751 | if (!devices) { | ||
752 | ALOGE("getOutput() unexpected null device for session %d", session); | ||
753 | return 0; | ||
754 | } | ||
755 | |||
756 | SessionDescriptor *sessionDesc = mSessions.valueAt(index); | ||
757 | audio_io_handle_t output = sessionDesc->mId; | ||
758 | AudioOutputDescriptor *outputDesc; | ||
759 | |||
760 | // Multiple devices could be handled by different outputs, populate a vector | ||
761 | // with the needed outputs for all requested devices | ||
762 | SortedVector<audio_io_handle_t> outputs; | ||
763 | while (devices) { | ||
764 | ALOGV("getOutput() search output(s) for devices 0x%08x flags 0x%08x", devices, flags); | ||
765 | if (needsDirectOuput(stream, samplingRate, format, channelMask, flags, devices)) { | ||
766 | output = openOutput(devices, samplingRate, format, channelMask, | ||
767 | AUDIO_OUTPUT_FLAG_DIRECT); | ||
768 | } else { | ||
769 | output = openOutput(devices, samplingRate, format, channelMask, | ||
770 | (audio_output_flags_t)flags); | ||
771 | } | ||
772 | if (output) { | ||
773 | outputs.add(output); | ||
774 | outputDesc = mOutputs.valueFor(output); | ||
775 | devices &= ~outputDesc->device(); | ||
776 | |||
777 | // Try opening a direct output for multichannel tracks. One of the two | ||
778 | // outputs for their associated device(s) will be closed when refining | ||
779 | // outputs (see refineOutputs()) | ||
780 | if (!outputDesc->isDirectOutput() && | ||
781 | (AudioSystem::popCount(channelMask) > 2) && | ||
782 | (outputDesc->mChannelMask != channelMask)) { | ||
783 | ALOGV("getOutput() output %d requires downmix, try direct output", | ||
784 | output); | ||
785 | output = openOutput(outputDesc->device(), | ||
786 | samplingRate, format, channelMask, | ||
787 | AUDIO_OUTPUT_FLAG_DIRECT); | ||
788 | if (output) | ||
789 | outputs.add(output); | ||
790 | } | ||
791 | } else { | ||
792 | ALOGW("getOutput() no output found for devices 0x%08x", devices); | ||
793 | break; | ||
794 | } | ||
795 | } | ||
796 | |||
797 | if (outputs.isEmpty()) { | ||
798 | ALOGE("getOutput() session %d no output found", session); | ||
799 | clearSession(session); | ||
800 | return 0; | ||
801 | } | ||
802 | |||
803 | // Refine the list of outputs where audio data is going to be duplicated: | ||
804 | // either exclude all direct outputs (they're incompatible with duplicated | ||
805 | // output) or just take one direct output (no duplication will be possible) | ||
806 | if (outputs.size() > 1) | ||
807 | refineOutputs(outputs); | ||
808 | |||
809 | // There might be need of output duplication if the requested devices are not | ||
810 | // supported by a single output | ||
811 | if (outputs.size() > 1) { | ||
812 | // Create a duplicating output connected to all individual outputs that | ||
813 | // render to the requested devices | ||
814 | output = openDuplicateOutput(outputs, samplingRate, format, channelMask, session); | ||
815 | if (!output) { | ||
816 | ALOGE("getOutput() could not get duplicate output"); | ||
817 | for (size_t i = 0; i < outputs.size(); i++) { | ||
818 | closeOutput(outputs.itemAt(i)); | ||
819 | } | ||
820 | return 0; | ||
821 | } | ||
822 | ALOGV("getOutput() session %d got duplicate output %d", session, output); | ||
823 | } else { | ||
824 | // A single output is required to satisfy parameters and devices | ||
825 | output = outputs.itemAt(0); | ||
826 | outputDesc = mOutputs.valueFor(output); | ||
827 | ALOGV("getOutput() session %d got %s output %d", session, | ||
828 | outputDesc->isDirectOutput() ? "direct" : "mixer", output); | ||
829 | } | ||
830 | |||
831 | sessionDesc->mId = output; | ||
832 | |||
833 | // Session must be ref counted to maintain the current routes after re-routing | ||
834 | ALOGV("getOutput() session %d users %d->%d", | ||
835 | session, sessionDesc->mUsers, sessionDesc->mUsers+1); | ||
836 | sessionDesc->mUsers++; | ||
837 | |||
838 | initSessionVolume(session); | ||
839 | |||
840 | return output; | ||
841 | } | ||
842 | |||
843 | status_t AudioPolicyManager::startOutput(audio_io_handle_t output, | ||
844 | AudioSystem::stream_type stream, | ||
845 | int session) | ||
846 | { | ||
847 | ALOGI("startOutput() output %d session %d stream %d", output, session, stream); | ||
848 | |||
849 | ssize_t index = mOutputs.indexOfKey(output); | ||
850 | if (index < 0) { | ||
851 | ALOGW("startOutput() unknow output %d", output); | ||
852 | return BAD_VALUE; | ||
853 | } | ||
854 | |||
855 | AudioOutputDescriptor *outputDesc = mOutputs.valueAt(index); | ||
856 | |||
857 | // Increment usage count of this stream on the output | ||
858 | outputDesc->changeRefCount(stream, 1); | ||
859 | if (outputDesc->mRefCount[stream] == 1) { | ||
860 | audio_devices_t devices = getSessionDevices(session); | ||
861 | if (devices == AUDIO_DEVICE_NONE) { | ||
862 | ALOGW("startOutput() no device for session %d, using the cabin", | ||
863 | session); | ||
864 | setSessionZones(session, AUDIO_ZONE_CABIN); | ||
865 | } | ||
866 | |||
867 | setOutputDevice(output, devices, false); | ||
868 | |||
869 | // Apply volume rules for current stream and device if necessary | ||
870 | setVolume(stream, output); | ||
871 | } | ||
872 | |||
873 | return NO_ERROR; | ||
874 | } | ||
875 | |||
876 | status_t AudioPolicyManager::stopOutput(audio_io_handle_t output, | ||
877 | AudioSystem::stream_type stream, | ||
878 | int session) | ||
879 | { | ||
880 | ALOGI("stopOutput() output %d session %d stream %d", output, session, stream); | ||
881 | |||
882 | ssize_t index = mOutputs.indexOfKey(output); | ||
883 | if (index < 0) { | ||
884 | ALOGE("stopOutput() unknown output %d", output); | ||
885 | return BAD_VALUE; | ||
886 | } | ||
887 | |||
888 | AudioOutputDescriptor *outputDesc = mOutputs.valueAt(index); | ||
889 | |||
890 | if (outputDesc->mRefCount[stream] == 0) { | ||
891 | ALOGE("stopOutput() refcount is already 0 for output %d", output); | ||
892 | return INVALID_OPERATION; | ||
893 | } | ||
894 | |||
895 | // Decrement usage count of this stream on the output | ||
896 | outputDesc->changeRefCount(stream, -1); | ||
897 | |||
898 | // Store time at which the stream was stopped - see isStreamActive() | ||
899 | if (outputDesc->mRefCount[stream] == 0) { | ||
900 | outputDesc->mStopTime[stream] = systemTime(); | ||
901 | audio_devices_t devices = getSessionDevices(session); | ||
902 | |||
903 | // Delay the device switch by twice the latency because stopOutput() is | ||
904 | // executed when the track stop() command is received and at that time | ||
905 | // the audio track buffer can still contain data that needs to be drained. | ||
906 | // The latency only covers the audio HAL and kernel buffers. Also the | ||
907 | // latency does not always include additional delay in the audio path | ||
908 | // (audio DSP, CODEC ...) | ||
909 | setOutputDevice(output, devices, false, outputDesc->mLatency*2); | ||
910 | } | ||
911 | |||
912 | return NO_ERROR; | ||
913 | } | ||
914 | |||
915 | void AudioPolicyManager::releaseOutput(audio_io_handle_t output, int session) | ||
916 | { | ||
917 | ALOGI("releaseOutput() output %d session %d", output, session); | ||
918 | |||
919 | ssize_t index = mOutputs.indexOfKey(output); | ||
920 | if (index < 0) { | ||
921 | ALOGE("releaseOutput() unknown output %d", output); | ||
922 | return; | ||
923 | } | ||
924 | |||
925 | index = mSessions.indexOfKey(session); | ||
926 | if (index < 0) { | ||
927 | ALOGW("releaseOutput() unknown session %d", session); | ||
928 | } else { | ||
929 | SessionDescriptor *sessionDesc = mSessions.valueAt(index); | ||
930 | ALOGV("releaseOutput() session %d users %d->%d", | ||
931 | session, sessionDesc->mUsers, sessionDesc->mUsers-1); | ||
932 | if (!--sessionDesc->mUsers) | ||
933 | clearSession(session); | ||
934 | } | ||
935 | |||
936 | closeOutput(output); | ||
937 | } | ||
938 | |||
939 | audio_io_handle_t AudioPolicyManager::getInput(int inputSource, | ||
940 | uint32_t samplingRate, | ||
941 | uint32_t format, | ||
942 | uint32_t channelMask, | ||
943 | AudioSystem::audio_in_acoustics acoustics, | ||
944 | int session) | ||
945 | { | ||
946 | audio_io_handle_t input = 0; | ||
947 | audio_devices_t device = getDeviceForInputSource(inputSource); | ||
948 | |||
949 | ALOGI("getInput() inputSource %d rate %d format %d channelMask %04x acoustics %x", | ||
950 | inputSource, samplingRate, format, channelMask, acoustics); | ||
951 | |||
952 | if (device == AUDIO_DEVICE_NONE) { | ||
953 | ALOGW("getInput() could not find device for inputSource %d", inputSource); | ||
954 | return 0; | ||
955 | } | ||
956 | |||
957 | // adapt channel selection to input source | ||
958 | switch(inputSource) { | ||
959 | case AUDIO_SOURCE_VOICE_UPLINK: | ||
960 | channelMask = AudioSystem::CHANNEL_IN_VOICE_UPLINK; | ||
961 | break; | ||
962 | case AUDIO_SOURCE_VOICE_DOWNLINK: | ||
963 | channelMask = AudioSystem::CHANNEL_IN_VOICE_DNLINK; | ||
964 | break; | ||
965 | case AUDIO_SOURCE_VOICE_CALL: | ||
966 | channelMask = (AudioSystem::CHANNEL_IN_VOICE_UPLINK | | ||
967 | AudioSystem::CHANNEL_IN_VOICE_DNLINK); | ||
968 | break; | ||
969 | default: | ||
970 | break; | ||
971 | } | ||
972 | |||
973 | IOProfile *profile = getInputProfile(device, | ||
974 | samplingRate, | ||
975 | format, | ||
976 | channelMask); | ||
977 | if (profile == NULL) { | ||
978 | ALOGE("getInput() could not find profile"); | ||
979 | return 0; | ||
980 | } | ||
981 | |||
982 | if (profile->mModule->mHandle == 0) { | ||
983 | ALOGE("getInput(): HW module %s not opened", profile->mModule->mName); | ||
984 | return 0; | ||
985 | } | ||
986 | |||
987 | AudioInputDescriptor *inputDesc = new AudioInputDescriptor(profile); | ||
988 | |||
989 | inputDesc->mInputSource = inputSource; | ||
990 | inputDesc->mDevice = device; | ||
991 | inputDesc->mSamplingRate = samplingRate; | ||
992 | inputDesc->mFormat = (audio_format_t)format; | ||
993 | inputDesc->mChannelMask = (audio_channel_mask_t)channelMask; | ||
994 | inputDesc->mUsers = 0; | ||
995 | input = mpClientInterface->openInput(profile->mModule->mHandle, | ||
996 | &inputDesc->mDevice, | ||
997 | &inputDesc->mSamplingRate, | ||
998 | &inputDesc->mFormat, | ||
999 | &inputDesc->mChannelMask); | ||
1000 | |||
1001 | // only accept input with the exact requested set of parameters | ||
1002 | if (input == 0 || | ||
1003 | (samplingRate != inputDesc->mSamplingRate) || | ||
1004 | (format != inputDesc->mFormat) || | ||
1005 | (channelMask != inputDesc->mChannelMask)) { | ||
1006 | ALOGV("getInput() failed opening input: rate %d format %d channelMask %d", | ||
1007 | samplingRate, format, channelMask); | ||
1008 | if (input != 0) { | ||
1009 | mpClientInterface->closeInput(input); | ||
1010 | } | ||
1011 | delete inputDesc; | ||
1012 | return 0; | ||
1013 | } | ||
1014 | mInputs.add(input, inputDesc); | ||
1015 | return input; | ||
1016 | } | ||
1017 | |||
1018 | status_t AudioPolicyManager::startInput(audio_io_handle_t input) | ||
1019 | { | ||
1020 | ALOGI("startInput() input %d", input); | ||
1021 | |||
1022 | ssize_t index = mInputs.indexOfKey(input); | ||
1023 | if (index < 0) { | ||
1024 | ALOGW("startInput() unknow input %d", input); | ||
1025 | return BAD_VALUE; | ||
1026 | } | ||
1027 | |||
1028 | AudioInputDescriptor *inputDesc = mInputs.valueAt(index); | ||
1029 | |||
1030 | // Refuse 2 active AudioRecord clients at the same time | ||
1031 | if (getActiveInput() != 0) { | ||
1032 | ALOGE("startInput() input %d failed: other input already started", input); | ||
1033 | return INVALID_OPERATION; | ||
1034 | } | ||
1035 | |||
1036 | audio_devices_t newDevice = getDeviceForInputSource(inputDesc->mInputSource); | ||
1037 | if ((newDevice != AUDIO_DEVICE_NONE) && (newDevice != inputDesc->mDevice)) { | ||
1038 | inputDesc->mDevice = newDevice; | ||
1039 | } | ||
1040 | |||
1041 | AudioParameter param = AudioParameter(); | ||
1042 | param.addInt(String8(AudioParameter::keyRouting), (int)inputDesc->mDevice); | ||
1043 | param.addInt(String8(AudioParameter::keyInputSource), (int)inputDesc->mInputSource); | ||
1044 | ALOGV("startInput() input source %d", inputDesc->mInputSource); | ||
1045 | mpClientInterface->setParameters(input, param.toString()); | ||
1046 | |||
1047 | inputDesc->mUsers = 1; | ||
1048 | |||
1049 | return NO_ERROR; | ||
1050 | } | ||
1051 | |||
1052 | status_t AudioPolicyManager::stopInput(audio_io_handle_t input) | ||
1053 | { | ||
1054 | ALOGI("stopInput() input %d", input); | ||
1055 | |||
1056 | ssize_t index = mInputs.indexOfKey(input); | ||
1057 | if (index < 0) { | ||
1058 | ALOGW("stopInput() unknow input %d", input); | ||
1059 | return BAD_VALUE; | ||
1060 | } | ||
1061 | AudioInputDescriptor *inputDesc = mInputs.valueAt(index); | ||
1062 | |||
1063 | if (inputDesc->mUsers == 0) { | ||
1064 | ALOGW("stopInput() input %d already stopped", input); | ||
1065 | return INVALID_OPERATION; | ||
1066 | } else { | ||
1067 | AudioParameter param = AudioParameter(); | ||
1068 | param.addInt(String8(AudioParameter::keyRouting), 0); | ||
1069 | mpClientInterface->setParameters(input, param.toString()); | ||
1070 | inputDesc->mUsers = 0; | ||
1071 | return NO_ERROR; | ||
1072 | } | ||
1073 | } | ||
1074 | |||
1075 | void AudioPolicyManager::releaseInput(audio_io_handle_t input, int session) | ||
1076 | { | ||
1077 | ALOGI("releaseInput() %d", input); | ||
1078 | |||
1079 | ssize_t index = mInputs.indexOfKey(input); | ||
1080 | if (index < 0) { | ||
1081 | ALOGW("releaseInput() unknown input %d", input); | ||
1082 | return; | ||
1083 | } | ||
1084 | mpClientInterface->closeInput(input); | ||
1085 | delete mInputs.valueAt(index); | ||
1086 | mInputs.removeItem(input); | ||
1087 | } | ||
1088 | |||
1089 | void AudioPolicyManager::initStreamVolume(AudioSystem::stream_type stream, | ||
1090 | int indexMin, | ||
1091 | int indexMax) | ||
1092 | { | ||
1093 | ALOGV("initStreamVolume() stream %d min %d max %d", stream, indexMin, indexMax); | ||
1094 | |||
1095 | if (indexMin < 0 || indexMin >= indexMax) { | ||
1096 | ALOGW("initStreamVolume() invalid index limits for stream %d min %d max %d", | ||
1097 | stream, indexMin, indexMax); | ||
1098 | return; | ||
1099 | } | ||
1100 | |||
1101 | mStreams[stream].mIndexMin = indexMin; | ||
1102 | mStreams[stream].mIndexMax = indexMax; | ||
1103 | } | ||
1104 | |||
1105 | status_t AudioPolicyManager::setStreamVolumeIndex(AudioSystem::stream_type stream, | ||
1106 | int index, | ||
1107 | audio_devices_t device) | ||
1108 | { | ||
1109 | if ((index < mStreams[stream].mIndexMin) || (index > mStreams[stream].mIndexMax)) { | ||
1110 | ALOGE("setStreamVolumeIndex() invalid index %d, should be within %d,%d", | ||
1111 | index, mStreams[stream].mIndexMin, mStreams[stream].mIndexMax); | ||
1112 | return BAD_VALUE; | ||
1113 | } | ||
1114 | |||
1115 | if (!audio_is_output_device(device)) { | ||
1116 | ALOGE("setStreamVolumeIndex() devices 0x%08x is invalid", device); | ||
1117 | return BAD_VALUE; | ||
1118 | } | ||
1119 | |||
1120 | // Force max volume if stream cannot be muted | ||
1121 | if (!mStreams[stream].mCanBeMuted) | ||
1122 | index = mStreams[stream].mIndexMax; | ||
1123 | |||
1124 | ALOGV("setStreamVolumeIndex() stream %d device 0x%08x index %d", | ||
1125 | stream, device, index); | ||
1126 | |||
1127 | mStreams[stream].mIndexCur = index; | ||
1128 | |||
1129 | // Compute and apply stream volume on all outputs | ||
1130 | status_t status = NO_ERROR; | ||
1131 | for (size_t i = 0; i < mOutputs.size(); i++) { | ||
1132 | status_t volStatus = setVolume(stream, mOutputs.keyAt(i)); | ||
1133 | if (volStatus != NO_ERROR) | ||
1134 | status = volStatus; | ||
1135 | } | ||
1136 | |||
1137 | return status; | ||
1138 | } | ||
1139 | |||
1140 | status_t AudioPolicyManager::getStreamVolumeIndex(AudioSystem::stream_type stream, | ||
1141 | int *index, | ||
1142 | audio_devices_t device) | ||
1143 | { | ||
1144 | if (index == NULL) | ||
1145 | return BAD_VALUE; | ||
1146 | |||
1147 | if (!audio_is_output_device(device)) { | ||
1148 | ALOGE("getStreamVolumeIndex() devices 0x%08x is invalid", device); | ||
1149 | return BAD_VALUE; | ||
1150 | } | ||
1151 | |||
1152 | *index = mStreams[stream].mIndexCur; | ||
1153 | |||
1154 | ALOGV("getStreamVolumeIndex() stream %d device 0x%08x index %d", | ||
1155 | stream, device, *index); | ||
1156 | |||
1157 | return NO_ERROR; | ||
1158 | } | ||
1159 | |||
1160 | uint32_t AudioPolicyManager::getStrategyForStream(AudioSystem::stream_type stream) | ||
1161 | { | ||
1162 | return (uint32_t)getStrategy(stream); | ||
1163 | } | ||
1164 | |||
1165 | audio_devices_t AudioPolicyManager::getDevicesForStream(AudioSystem::stream_type stream) | ||
1166 | { | ||
1167 | if (stream < (AudioSystem::stream_type) 0 || | ||
1168 | stream >= AudioSystem::NUM_STREAM_TYPES) { | ||
1169 | return AUDIO_DEVICE_NONE; | ||
1170 | } | ||
1171 | |||
1172 | // Same stream type on different listening zones may produce devices | ||
1173 | // that are anyways discarded by AudioService, since it gives priority | ||
1174 | // to speaker. Use main cabin device refined for the stream type as | ||
1175 | // reference for stream type volume in the system. | ||
1176 | return getRefinedZoneDevices(AUDIO_ZONE_CABIN, stream); | ||
1177 | } | ||
1178 | |||
1179 | audio_io_handle_t AudioPolicyManager::getOutputForEffect(const effect_descriptor_t *desc) | ||
1180 | { | ||
1181 | audio_devices_t device = getRefinedZoneDevices(AUDIO_ZONE_CABIN, | ||
1182 | AudioSystem::MUSIC); | ||
1183 | audio_io_handle_t output = mPrimaryOutput; | ||
1184 | for (size_t i = 0; i < mOutputs.size(); i++) { | ||
1185 | AudioOutputDescriptor *outputDesc = mOutputs.valueAt(i); | ||
1186 | if ((device & outputDesc->supportedDevices()) == device) { | ||
1187 | output = mOutputs.keyAt(i); | ||
1188 | if (outputDesc->mFlags & AUDIO_OUTPUT_FLAG_DEEP_BUFFER) | ||
1189 | break; | ||
1190 | } | ||
1191 | } | ||
1192 | |||
1193 | ALOGV("getOutputForEffect() output %d", output); | ||
1194 | |||
1195 | return output; | ||
1196 | } | ||
1197 | |||
1198 | status_t AudioPolicyManager::registerEffect(const effect_descriptor_t *desc, | ||
1199 | audio_io_handle_t io, | ||
1200 | uint32_t strategy, | ||
1201 | int session, | ||
1202 | int id) | ||
1203 | { | ||
1204 | ssize_t index = mOutputs.indexOfKey(io); | ||
1205 | if (index < 0) { | ||
1206 | index = mInputs.indexOfKey(io); | ||
1207 | if (index < 0) { | ||
1208 | ALOGW("registerEffect() unknown io %d", io); | ||
1209 | return INVALID_OPERATION; | ||
1210 | } | ||
1211 | } | ||
1212 | |||
1213 | if (mTotalEffectsMemory + desc->memoryUsage > getMaxEffectsMemory()) { | ||
1214 | ALOGW("registerEffect() memory limit exceeded for Fx %s, Memory %d KB", | ||
1215 | desc->name, desc->memoryUsage); | ||
1216 | return INVALID_OPERATION; | ||
1217 | } | ||
1218 | mTotalEffectsMemory += desc->memoryUsage; | ||
1219 | ALOGV("registerEffect() effect %s, io %d, strategy %d session %d id %d", | ||
1220 | desc->name, io, strategy, session, id); | ||
1221 | ALOGV("registerEffect() memory %d, total memory %d", | ||
1222 | desc->memoryUsage, mTotalEffectsMemory); | ||
1223 | |||
1224 | EffectDescriptor *pDesc = new EffectDescriptor(); | ||
1225 | memcpy (&pDesc->mDesc, desc, sizeof(effect_descriptor_t)); | ||
1226 | pDesc->mIo = io; | ||
1227 | pDesc->mStrategy = (routing_strategy)strategy; | ||
1228 | pDesc->mSession = session; | ||
1229 | pDesc->mEnabled = false; | ||
1230 | |||
1231 | mEffects.add(id, pDesc); | ||
1232 | |||
1233 | return NO_ERROR; | ||
1234 | } | ||
1235 | |||
1236 | status_t AudioPolicyManager::unregisterEffect(int id) | ||
1237 | { | ||
1238 | ssize_t index = mEffects.indexOfKey(id); | ||
1239 | if (index < 0) { | ||
1240 | ALOGW("unregisterEffect() unknown effect ID %d", id); | ||
1241 | return INVALID_OPERATION; | ||
1242 | } | ||
1243 | |||
1244 | EffectDescriptor *pDesc = mEffects.valueAt(index); | ||
1245 | |||
1246 | setEffectEnabled(pDesc, false); | ||
1247 | |||
1248 | if (mTotalEffectsMemory < pDesc->mDesc.memoryUsage) { | ||
1249 | ALOGW("unregisterEffect() memory %d too big for total %d", | ||
1250 | pDesc->mDesc.memoryUsage, mTotalEffectsMemory); | ||
1251 | pDesc->mDesc.memoryUsage = mTotalEffectsMemory; | ||
1252 | } | ||
1253 | mTotalEffectsMemory -= pDesc->mDesc.memoryUsage; | ||
1254 | ALOGV("unregisterEffect() effect %s, ID %d, memory %d total memory %d", | ||
1255 | pDesc->mDesc.name, id, pDesc->mDesc.memoryUsage, mTotalEffectsMemory); | ||
1256 | |||
1257 | mEffects.removeItem(id); | ||
1258 | delete pDesc; | ||
1259 | |||
1260 | return NO_ERROR; | ||
1261 | } | ||
1262 | |||
1263 | status_t AudioPolicyManager::setEffectEnabled(int id, bool enabled) | ||
1264 | { | ||
1265 | ssize_t index = mEffects.indexOfKey(id); | ||
1266 | if (index < 0) { | ||
1267 | ALOGW("unregisterEffect() unknown effect ID %d", id); | ||
1268 | return INVALID_OPERATION; | ||
1269 | } | ||
1270 | |||
1271 | return setEffectEnabled(mEffects.valueAt(index), enabled); | ||
1272 | } | ||
1273 | |||
1274 | status_t AudioPolicyManager::setEffectEnabled(EffectDescriptor *pDesc, bool enabled) | ||
1275 | { | ||
1276 | if (enabled == pDesc->mEnabled) { | ||
1277 | ALOGV("setEffectEnabled(%s) effect already %s", | ||
1278 | enabled?"true":"false", enabled?"enabled":"disabled"); | ||
1279 | return INVALID_OPERATION; | ||
1280 | } | ||
1281 | |||
1282 | if (enabled) { | ||
1283 | if (mTotalEffectsCpuLoad + pDesc->mDesc.cpuLoad > getMaxEffectsCpuLoad()) { | ||
1284 | ALOGW("setEffectEnabled(true) CPU Load limit exceeded for Fx %s, CPU %f MIPS", | ||
1285 | pDesc->mDesc.name, (float)pDesc->mDesc.cpuLoad/10); | ||
1286 | return INVALID_OPERATION; | ||
1287 | } | ||
1288 | mTotalEffectsCpuLoad += pDesc->mDesc.cpuLoad; | ||
1289 | ALOGV("setEffectEnabled(true) total CPU %d", mTotalEffectsCpuLoad); | ||
1290 | } else { | ||
1291 | if (mTotalEffectsCpuLoad < pDesc->mDesc.cpuLoad) { | ||
1292 | ALOGW("setEffectEnabled(false) CPU load %d too high for total %d", | ||
1293 | pDesc->mDesc.cpuLoad, mTotalEffectsCpuLoad); | ||
1294 | pDesc->mDesc.cpuLoad = mTotalEffectsCpuLoad; | ||
1295 | } | ||
1296 | mTotalEffectsCpuLoad -= pDesc->mDesc.cpuLoad; | ||
1297 | ALOGV("setEffectEnabled(false) total CPU %d", mTotalEffectsCpuLoad); | ||
1298 | } | ||
1299 | pDesc->mEnabled = enabled; | ||
1300 | return NO_ERROR; | ||
1301 | } | ||
1302 | |||
1303 | bool AudioPolicyManager::isStreamActive(int stream, uint32_t inPastMs) const | ||
1304 | { | ||
1305 | nsecs_t sysTime = systemTime(); | ||
1306 | for (size_t i = 0; i < mOutputs.size(); i++) { | ||
1307 | const AudioOutputDescriptor *outputDesc = mOutputs.valueAt(i); | ||
1308 | if (outputDesc->isStreamActive((AudioSystem::stream_type)stream, | ||
1309 | inPastMs, sysTime)) { | ||
1310 | return true; | ||
1311 | } | ||
1312 | } | ||
1313 | return false; | ||
1314 | } | ||
1315 | |||
1316 | bool AudioPolicyManager::isStreamActiveRemotely(int stream, uint32_t inPastMs) const | ||
1317 | { | ||
1318 | nsecs_t sysTime = systemTime(); | ||
1319 | for (size_t i = 0; i < mOutputs.size(); i++) { | ||
1320 | const AudioOutputDescriptor *outputDesc = mOutputs.valueAt(i); | ||
1321 | if (((outputDesc->device() & APM_AUDIO_OUT_DEVICE_REMOTE_ALL) != 0) && | ||
1322 | outputDesc->isStreamActive((AudioSystem::stream_type)stream, | ||
1323 | inPastMs, sysTime)) { | ||
1324 | return true; | ||
1325 | } | ||
1326 | } | ||
1327 | return false; | ||
1328 | } | ||
1329 | |||
1330 | bool AudioPolicyManager::isSourceActive(audio_source_t source) const | ||
1331 | { | ||
1332 | for (size_t i = 0; i < mInputs.size(); i++) { | ||
1333 | const AudioInputDescriptor * inputDescriptor = mInputs.valueAt(i); | ||
1334 | if ((inputDescriptor->mInputSource == (int) source) | ||
1335 | && (inputDescriptor->mUsers > 0)) { | ||
1336 | return true; | ||
1337 | } | ||
1338 | } | ||
1339 | return false; | ||
1340 | } | ||
1341 | |||
1342 | status_t AudioPolicyManager::dump(int fd) | ||
1343 | { | ||
1344 | const size_t SIZE = 256; | ||
1345 | char buffer[SIZE]; | ||
1346 | String8 result; | ||
1347 | |||
1348 | snprintf(buffer, SIZE, "\nAudioPolicyManager Dump: %p\n", this); | ||
1349 | result.append(buffer); | ||
1350 | |||
1351 | snprintf(buffer, SIZE, " Primary Output: %d\n", mPrimaryOutput); | ||
1352 | result.append(buffer); | ||
1353 | snprintf(buffer, SIZE, " A2DP device address: %s\n", mA2dpDeviceAddress.string()); | ||
1354 | result.append(buffer); | ||
1355 | snprintf(buffer, SIZE, " SCO device address: %s\n", mScoDeviceAddress.string()); | ||
1356 | result.append(buffer); | ||
1357 | snprintf(buffer, SIZE, " USB audio ALSA %s\n", mUsbCardAndDevice.string()); | ||
1358 | result.append(buffer); | ||
1359 | snprintf(buffer, SIZE, " Output devices: %08x\n", mAvailableOutputDevices); | ||
1360 | result.append(buffer); | ||
1361 | snprintf(buffer, SIZE, " Input devices: %08x\n", mAvailableInputDevices); | ||
1362 | result.append(buffer); | ||
1363 | snprintf(buffer, SIZE, " Phone state: %d\n", mPhoneState); | ||
1364 | result.append(buffer); | ||
1365 | snprintf(buffer, SIZE, " Force use for communications %d\n", mForceUse[AudioSystem::FOR_COMMUNICATION]); | ||
1366 | result.append(buffer); | ||
1367 | snprintf(buffer, SIZE, " Force use for media %d\n", mForceUse[AudioSystem::FOR_MEDIA]); | ||
1368 | result.append(buffer); | ||
1369 | snprintf(buffer, SIZE, " Force use for record %d\n", mForceUse[AudioSystem::FOR_RECORD]); | ||
1370 | result.append(buffer); | ||
1371 | snprintf(buffer, SIZE, " Force use for dock %d\n", mForceUse[AudioSystem::FOR_DOCK]); | ||
1372 | result.append(buffer); | ||
1373 | snprintf(buffer, SIZE, " Force use for system %d\n", mForceUse[AudioSystem::FOR_SYSTEM]); | ||
1374 | result.append(buffer); | ||
1375 | write(fd, result.string(), result.size()); | ||
1376 | |||
1377 | |||
1378 | snprintf(buffer, SIZE, "\nHW Modules dump:\n"); | ||
1379 | write(fd, buffer, strlen(buffer)); | ||
1380 | for (size_t i = 0; i < mHwModules.size(); i++) { | ||
1381 | snprintf(buffer, SIZE, "- HW Module %d:\n", i + 1); | ||
1382 | write(fd, buffer, strlen(buffer)); | ||
1383 | mHwModules[i]->dump(fd); | ||
1384 | } | ||
1385 | |||
1386 | snprintf(buffer, SIZE, "\nOutputs dump:\n"); | ||
1387 | write(fd, buffer, strlen(buffer)); | ||
1388 | for (size_t i = 0; i < mOutputs.size(); i++) { | ||
1389 | snprintf(buffer, SIZE, "- Output %d dump:\n", mOutputs.keyAt(i)); | ||
1390 | write(fd, buffer, strlen(buffer)); | ||
1391 | mOutputs.valueAt(i)->dump(fd); | ||
1392 | } | ||
1393 | |||
1394 | snprintf(buffer, SIZE, "\nInputs dump:\n"); | ||
1395 | write(fd, buffer, strlen(buffer)); | ||
1396 | for (size_t i = 0; i < mInputs.size(); i++) { | ||
1397 | snprintf(buffer, SIZE, "- Input %d dump:\n", mInputs.keyAt(i)); | ||
1398 | write(fd, buffer, strlen(buffer)); | ||
1399 | mInputs.valueAt(i)->dump(fd); | ||
1400 | } | ||
1401 | |||
1402 | snprintf(buffer, SIZE, "\nStreams dump:\n"); | ||
1403 | write(fd, buffer, strlen(buffer)); | ||
1404 | snprintf(buffer, SIZE, | ||
1405 | " Stream Can be muted Index Min Index Max Index Cur\n"); | ||
1406 | write(fd, buffer, strlen(buffer)); | ||
1407 | for (size_t i = 0; i < AudioSystem::NUM_STREAM_TYPES; i++) { | ||
1408 | snprintf(buffer, SIZE, " %02d ", i); | ||
1409 | write(fd, buffer, strlen(buffer)); | ||
1410 | mStreams[i].dump(fd); | ||
1411 | } | ||
1412 | |||
1413 | snprintf(buffer, SIZE, "\nTotal Effects CPU: %f MIPS, Total Effects memory: %d KB\n", | ||
1414 | (float)mTotalEffectsCpuLoad/10, mTotalEffectsMemory); | ||
1415 | write(fd, buffer, strlen(buffer)); | ||
1416 | |||
1417 | snprintf(buffer, SIZE, "Registered effects:\n"); | ||
1418 | write(fd, buffer, strlen(buffer)); | ||
1419 | for (size_t i = 0; i < mEffects.size(); i++) { | ||
1420 | snprintf(buffer, SIZE, "- Effect %d dump:\n", mEffects.keyAt(i)); | ||
1421 | write(fd, buffer, strlen(buffer)); | ||
1422 | mEffects.valueAt(i)->dump(fd); | ||
1423 | } | ||
1424 | |||
1425 | snprintf(buffer, SIZE, "\nSessions:\n"); | ||
1426 | write(fd, buffer, strlen(buffer)); | ||
1427 | for (size_t i = 0; i < mSessions.size(); i++) { | ||
1428 | snprintf(buffer, SIZE, "- Session %d dump:\n", mSessions.keyAt(i)); | ||
1429 | write(fd, buffer, strlen(buffer)); | ||
1430 | mSessions.valueAt(i)->dump(fd); | ||
1431 | } | ||
1432 | |||
1433 | snprintf(buffer, SIZE, "\nZone Affinity:\n"); | ||
1434 | write(fd, buffer, strlen(buffer)); | ||
1435 | snprintf(buffer, SIZE, " Zone Devices\n"); | ||
1436 | write(fd, buffer, strlen(buffer)); | ||
1437 | for (size_t i = 0; i < mZoneAffinity.size(); i++) { | ||
1438 | snprintf(buffer, SIZE, " 0x%x 0x%08x\n", | ||
1439 | mZoneAffinity.keyAt(i), mZoneAffinity.valueAt(i)); | ||
1440 | write(fd, buffer, strlen(buffer)); | ||
1441 | } | ||
1442 | |||
1443 | return NO_ERROR; | ||
1444 | } | ||
1445 | |||
1446 | // ---------------------------------------------------------------------------- | ||
1447 | // AudioPolicyManager | ||
1448 | // ---------------------------------------------------------------------------- | ||
1449 | |||
1450 | AudioPolicyManager::AudioPolicyManager(AudioPolicyClientInterface *clientInterface) | ||
1451 | : mPrimaryOutput((audio_io_handle_t)0), | ||
1452 | mAvailableOutputDevices(AUDIO_DEVICE_NONE), | ||
1453 | mA2dpSuspended(false), | ||
1454 | mHasA2dp(false), | ||
1455 | mHasUsb(false), | ||
1456 | mHasRemoteSubmix(false), | ||
1457 | mPhoneState(AudioSystem::MODE_NORMAL), | ||
1458 | mLastVoiceVolume(-1.0f), | ||
1459 | mTotalEffectsCpuLoad(0), | ||
1460 | mTotalEffectsMemory(0), | ||
1461 | mParser(mHwModules, mZoneAffinity) | ||
1462 | { | ||
1463 | mpClientInterface = clientInterface; | ||
1464 | |||
1465 | for (int i = 0; i < AudioSystem::NUM_FORCE_USE; i++) { | ||
1466 | mForceUse[i] = AudioSystem::FORCE_NONE; | ||
1467 | } | ||
1468 | |||
1469 | initializeVolumeCurves(); | ||
1470 | |||
1471 | mA2dpDeviceAddress = String8(""); | ||
1472 | mScoDeviceAddress = String8(""); | ||
1473 | mUsbCardAndDevice = String8(""); | ||
1474 | |||
1475 | if (mParser.loadAudioPolicyConfig(AUDIO_POLICY_VENDOR_CONFIG_FILE) != NO_ERROR) { | ||
1476 | if (mParser.loadAudioPolicyConfig(AUDIO_POLICY_CONFIG_FILE) != NO_ERROR) { | ||
1477 | ALOGE("could not load audio policy configuration file, setting defaults"); | ||
1478 | mParser.defaultAudioPolicyConfig(); | ||
1479 | } | ||
1480 | } | ||
1481 | |||
1482 | mAvailableInputDevices = mParser.getAttachedInputDevices(); | ||
1483 | mAttachedOutputDevices = mParser.getAttachedOutputDevices(); | ||
1484 | mDefaultOutputDevice = mParser.getDefaultOutputDevice(); | ||
1485 | mHasA2dp = mParser.supportsA2DP(); | ||
1486 | mHasUsb = mParser.supportsUSB(); | ||
1487 | mHasRemoteSubmix = mParser.supportsRemoteSubmix(); | ||
1488 | |||
1489 | if (mZoneAffinity.indexOfKey(AUDIO_ZONE_CABIN) < 0) { | ||
1490 | ALOGW("No affinity set for cabin, using default"); | ||
1491 | mZoneAffinity.add(AUDIO_ZONE_CABIN, AUDIO_DEVICE_OUT_SPEAKER); | ||
1492 | } | ||
1493 | |||
1494 | if (mZoneAffinity.indexOfKey(AUDIO_ZONE_BACKSEAT1) < 0) { | ||
1495 | ALOGW("No affinity set for back-seat 1, using default"); | ||
1496 | mZoneAffinity.add(AUDIO_ZONE_BACKSEAT1, AUDIO_DEVICE_OUT_WIRED_HEADPHONE); | ||
1497 | } | ||
1498 | |||
1499 | if (mZoneAffinity.indexOfKey(AUDIO_ZONE_BACKSEAT2) < 0) { | ||
1500 | ALOGW("No affinity set for back-seat 2, using default"); | ||
1501 | mZoneAffinity.add(AUDIO_ZONE_BACKSEAT2, AUDIO_DEVICE_OUT_WIRED_HEADPHONE2); | ||
1502 | } | ||
1503 | |||
1504 | ALOGI("Initialize per-listening zone volumes"); | ||
1505 | for (audio_zones_t zone = AUDIO_ZONE_LAST; zone & AUDIO_ZONE_ALL; zone >>= 1) { | ||
1506 | mZoneVolume.add(zone, 1.0f); | ||
1507 | } | ||
1508 | |||
1509 | ALOGI("Initialize listening zones routes"); | ||
1510 | setZoneDevices(AUDIO_ZONE_CABIN, mDefaultOutputDevice | | ||
1511 | (mZoneAffinity.valueFor(AUDIO_ZONE_CABIN) & mAttachedOutputDevices)); | ||
1512 | setZoneDevices(AUDIO_ZONE_BACKSEAT1, | ||
1513 | mZoneAffinity.valueFor(AUDIO_ZONE_BACKSEAT1) & mAttachedOutputDevices); | ||
1514 | setZoneDevices(AUDIO_ZONE_BACKSEAT2, | ||
1515 | mZoneAffinity.valueFor(AUDIO_ZONE_BACKSEAT2) & mAttachedOutputDevices); | ||
1516 | |||
1517 | // Open all output streams needed to access attached devices | ||
1518 | for (size_t i = 0; i < mHwModules.size(); i++) { | ||
1519 | mHwModules[i]->mHandle = mpClientInterface->loadHwModule(mHwModules[i]->mName); | ||
1520 | if (mHwModules[i]->mHandle == 0) { | ||
1521 | ALOGW("could not open HW module %s", mHwModules[i]->mName); | ||
1522 | continue; | ||
1523 | } | ||
1524 | // Open all output streams needed to access attached devices | ||
1525 | for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++) { | ||
1526 | IOProfile *profile = mHwModules[i]->mOutputProfiles[j]; | ||
1527 | audio_devices_t devices = profile->mSupportedDevices & mAttachedOutputDevices; | ||
1528 | |||
1529 | // Skip profiles that don't support attached output devices | ||
1530 | if (devices == AUDIO_DEVICE_NONE) | ||
1531 | continue; | ||
1532 | |||
1533 | // Open the output with flags defined in the config file | ||
1534 | audio_io_handle_t output = openOutput_l(profile, devices, profile->mFlags); | ||
1535 | if (output) { | ||
1536 | AudioOutputDescriptor *desc = mOutputs.valueFor(output); | ||
1537 | |||
1538 | ALOGV("output %d users %u->%u", | ||
1539 | output, desc->mUsers, desc->mUsers+1); | ||
1540 | desc->mUsers++; | ||
1541 | |||
1542 | mAvailableOutputDevices |= devices; | ||
1543 | if (!mPrimaryOutput && | ||
1544 | (profile->mFlags & AUDIO_OUTPUT_FLAG_PRIMARY)) { | ||
1545 | mPrimaryOutput = output; | ||
1546 | } | ||
1547 | setOutputDevice(output, devices, true); | ||
1548 | } | ||
1549 | } | ||
1550 | } | ||
1551 | |||
1552 | ALOGE_IF((mAttachedOutputDevices & ~mAvailableOutputDevices), | ||
1553 | "No output found for attached devices 0x%08x", | ||
1554 | (mAttachedOutputDevices & ~mAvailableOutputDevices)); | ||
1555 | |||
1556 | ALOGE_IF((mPrimaryOutput == 0), "Failed to open primary output"); | ||
1557 | } | ||
1558 | |||
1559 | AudioPolicyManager::~AudioPolicyManager() | ||
1560 | { | ||
1561 | for (size_t i = 0; i < mOutputs.size(); i++) { | ||
1562 | mpClientInterface->closeOutput(mOutputs.keyAt(i)); | ||
1563 | delete mOutputs.valueAt(i); | ||
1564 | } | ||
1565 | for (size_t i = 0; i < mSessions.size(); i++) { | ||
1566 | delete mSessions.valueAt(i); | ||
1567 | } | ||
1568 | for (size_t i = 0; i < mInputs.size(); i++) { | ||
1569 | mpClientInterface->closeInput(mInputs.keyAt(i)); | ||
1570 | delete mInputs.valueAt(i); | ||
1571 | } | ||
1572 | } | ||
1573 | |||
1574 | status_t AudioPolicyManager::initCheck() | ||
1575 | { | ||
1576 | return (mPrimaryOutput == 0) ? NO_INIT : NO_ERROR; | ||
1577 | } | ||
1578 | |||
1579 | // --- | ||
1580 | |||
1581 | AudioPolicyManager::routing_strategy | ||
1582 | AudioPolicyManager::getStrategy(AudioSystem::stream_type stream) | ||
1583 | { | ||
1584 | // stream to strategy mapping | ||
1585 | switch (stream) { | ||
1586 | case AudioSystem::VOICE_CALL: | ||
1587 | case AudioSystem::BLUETOOTH_SCO: | ||
1588 | return STRATEGY_PHONE; | ||
1589 | case AudioSystem::RING: | ||
1590 | case AudioSystem::ALARM: | ||
1591 | return STRATEGY_SONIFICATION; | ||
1592 | case AudioSystem::NOTIFICATION: | ||
1593 | return STRATEGY_SONIFICATION_RESPECTFUL; | ||
1594 | case AudioSystem::DTMF: | ||
1595 | return STRATEGY_DTMF; | ||
1596 | default: | ||
1597 | ALOGE("unknown stream type"); | ||
1598 | case AudioSystem::SYSTEM: | ||
1599 | // NOTE: SYSTEM stream uses MEDIA strategy because muting music and switching outputs | ||
1600 | // while key clicks are played produces a poor result | ||
1601 | case AudioSystem::TTS: | ||
1602 | case AudioSystem::MUSIC: | ||
1603 | return STRATEGY_MEDIA; | ||
1604 | case AudioSystem::ENFORCED_AUDIBLE: | ||
1605 | return STRATEGY_ENFORCED_AUDIBLE; | ||
1606 | } | ||
1607 | } | ||
1608 | |||
1609 | AudioPolicyManager::device_category | ||
1610 | AudioPolicyManager::getDeviceCategory(audio_devices_t device) | ||
1611 | { | ||
1612 | switch(getDeviceForVolume(device)) { | ||
1613 | case AUDIO_DEVICE_OUT_EARPIECE: | ||
1614 | return DEVICE_CATEGORY_EARPIECE; | ||
1615 | case AUDIO_DEVICE_OUT_WIRED_HEADSET: | ||
1616 | case AUDIO_DEVICE_OUT_WIRED_HEADPHONE: | ||
1617 | case AUDIO_DEVICE_OUT_WIRED_HEADPHONE2: | ||
1618 | case AUDIO_DEVICE_OUT_BLUETOOTH_SCO: | ||
1619 | case AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET: | ||
1620 | case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP: | ||
1621 | case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES: | ||
1622 | return DEVICE_CATEGORY_HEADSET; | ||
1623 | case AUDIO_DEVICE_OUT_SPEAKER: | ||
1624 | case AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT: | ||
1625 | case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER: | ||
1626 | case AUDIO_DEVICE_OUT_AUX_DIGITAL: | ||
1627 | case AUDIO_DEVICE_OUT_USB_ACCESSORY: | ||
1628 | case AUDIO_DEVICE_OUT_USB_DEVICE: | ||
1629 | case AUDIO_DEVICE_OUT_REMOTE_SUBMIX: | ||
1630 | default: | ||
1631 | return DEVICE_CATEGORY_SPEAKER; | ||
1632 | } | ||
1633 | } | ||
1634 | |||
1635 | audio_devices_t AudioPolicyManager::getDeviceForVolume(audio_devices_t device) | ||
1636 | { | ||
1637 | if (device == AUDIO_DEVICE_NONE) { | ||
1638 | // this happens when forcing a route update and no track is active on an output. | ||
1639 | // In this case the returned category is not important. | ||
1640 | device = AUDIO_DEVICE_OUT_SPEAKER; | ||
1641 | } else if (AudioSystem::popCount(device) > 1) { | ||
1642 | // Multiple device selection is either: | ||
1643 | // - speaker + one other device: give priority to speaker in this case. | ||
1644 | // - headphone(s) + other devices: give priority to headphones (back-seat) | ||
1645 | // - one A2DP device + another device: happens with duplicated output. | ||
1646 | // In this case retain the device on the A2DP output as the other must not | ||
1647 | // correspond to an active selection if not the speaker. | ||
1648 | if (device & AUDIO_DEVICE_OUT_SPEAKER) { | ||
1649 | device = AUDIO_DEVICE_OUT_SPEAKER; | ||
1650 | } else if (device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE) { | ||
1651 | device = AUDIO_DEVICE_OUT_WIRED_HEADPHONE; | ||
1652 | } else if (device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE2) { | ||
1653 | device = AUDIO_DEVICE_OUT_WIRED_HEADPHONE2; | ||
1654 | } else { | ||
1655 | device = (audio_devices_t)(device & AUDIO_DEVICE_OUT_ALL_A2DP); | ||
1656 | } | ||
1657 | } | ||
1658 | |||
1659 | ALOGW_IF(AudioSystem::popCount(device) != 1, | ||
1660 | "getDeviceForVolume() invalid device combination: 0x%08x", device); | ||
1661 | |||
1662 | return device; | ||
1663 | } | ||
1664 | |||
1665 | bool AudioPolicyManager::needsDirectOuput(AudioSystem::stream_type stream, | ||
1666 | uint32_t samplingRate, | ||
1667 | uint32_t format, | ||
1668 | uint32_t channelMask, | ||
1669 | AudioSystem::output_flags flags, | ||
1670 | audio_devices_t device) | ||
1671 | { | ||
1672 | return ((flags & AudioSystem::OUTPUT_FLAG_DIRECT) || | ||
1673 | (format != 0 && !AudioSystem::isLinearPCM(format))); | ||
1674 | } | ||
1675 | |||
1676 | void AudioPolicyManager::queryOutputParameters(audio_io_handle_t output, | ||
1677 | IOProfile *profile) | ||
1678 | { | ||
1679 | String8 reply; | ||
1680 | char *rates = NULL; | ||
1681 | char *formats = NULL; | ||
1682 | char *channels = NULL; | ||
1683 | |||
1684 | if (profile->mSamplingRates[0] == 0) { | ||
1685 | reply = mpClientInterface->getParameters(output, | ||
1686 | String8(AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES)); | ||
1687 | ALOGV("queryOutputParameters() direct output sup sampling rates %s", | ||
1688 | reply.string()); | ||
1689 | rates = (char *)reply.string(); | ||
1690 | } | ||
1691 | |||
1692 | if (profile->mFormats[0] == 0) { | ||
1693 | reply = mpClientInterface->getParameters(output, | ||
1694 | String8(AUDIO_PARAMETER_STREAM_SUP_FORMATS)); | ||
1695 | ALOGV("queryOutputParameters() direct output sup formats %s", | ||
1696 | reply.string()); | ||
1697 | formats = (char *)reply.string(); | ||
1698 | } | ||
1699 | |||
1700 | if (profile->mChannelMasks[0] == 0) { | ||
1701 | reply = mpClientInterface->getParameters(output, | ||
1702 | String8(AUDIO_PARAMETER_STREAM_SUP_CHANNELS)); | ||
1703 | ALOGV("queryOutputParameters() direct output sup channel masks %s", | ||
1704 | reply.string()); | ||
1705 | channels = (char *)reply.string(); | ||
1706 | } | ||
1707 | |||
1708 | mParser.fillProfile(profile, rates, formats, channels); | ||
1709 | } | ||
1710 | |||
1711 | void AudioPolicyManager::getProfilesForDevices(audio_devices_t devices, | ||
1712 | SortedVector<IOProfile*> &profiles) | ||
1713 | { | ||
1714 | for (size_t i = 0; i < mHwModules.size(); i++) { | ||
1715 | if (mHwModules[i]->mHandle == 0) | ||
1716 | continue; | ||
1717 | |||
1718 | for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++) { | ||
1719 | IOProfile *profile = mHwModules[i]->mOutputProfiles[j]; | ||
1720 | if (profile->mSupportedDevices & devices) | ||
1721 | profiles.add(profile); | ||
1722 | } | ||
1723 | } | ||
1724 | } | ||
1725 | |||
1726 | void AudioPolicyManager::setDeviceAddress(audio_io_handle_t output, | ||
1727 | audio_devices_t device) | ||
1728 | { | ||
1729 | String8 paramStr; | ||
1730 | |||
1731 | if (mHasA2dp && audio_is_a2dp_device(device)) { | ||
1732 | AudioParameter param; | ||
1733 | param.add(String8(AUDIO_PARAMETER_A2DP_SINK_ADDRESS), mA2dpDeviceAddress); | ||
1734 | paramStr = param.toString(); | ||
1735 | } else if (mHasUsb && audio_is_usb_device(device)) { | ||
1736 | paramStr = mUsbCardAndDevice; | ||
1737 | } | ||
1738 | |||
1739 | // not currently handling multiple simultaneous submixes: ignoring remote submix | ||
1740 | // case and address | ||
1741 | if (!paramStr.isEmpty()) { | ||
1742 | ALOGV("setDeviceAddress() set device address '%s'", paramStr.string()); | ||
1743 | mpClientInterface->setParameters(output, paramStr); | ||
1744 | } | ||
1745 | } | ||
1746 | |||
1747 | void AudioPolicyManager::refineOutputs(SortedVector<audio_io_handle_t> &outputs) | ||
1748 | { | ||
1749 | SortedVector<audio_io_handle_t> direct; | ||
1750 | SortedVector<audio_io_handle_t> discarded; | ||
1751 | bool useDirectOutput; | ||
1752 | char value[PROPERTY_VALUE_MAX]; | ||
1753 | |||
1754 | // AudioFlinger's duplicating output doesn't support direct outputs, so there | ||
1755 | // are two possible choices: | ||
1756 | // - Keep mixer outputs, discard all direct outputs (useDirectOutput = false) | ||
1757 | // - Use a single direct output, discard the rest (useDirectOutput = true) | ||
1758 | if ((property_get("multizone_audio.use_direct", value, NULL) == 0) || | ||
1759 | !strcmp(value, "0") || !strcasecmp(value, "false")) { | ||
1760 | ALOGV("refineOutputs() keep mixer outputs, discard all direct outputs"); | ||
1761 | useDirectOutput = false; | ||
1762 | } else { | ||
1763 | ALOGV("refineOutputs() keep a single direct output"); | ||
1764 | useDirectOutput = true; | ||
1765 | } | ||
1766 | |||
1767 | // Find all direct outputs in the candidates for duplication | ||
1768 | for (size_t i = 0; i < outputs.size(); i++) { | ||
1769 | AudioOutputDescriptor *desc = mOutputs.valueFor(outputs.itemAt(i)); | ||
1770 | if (desc->isDirectOutput()) | ||
1771 | direct.add(outputs.itemAt(i)); | ||
1772 | } | ||
1773 | |||
1774 | // If all outputs are direct, the only option is using one of them to | ||
1775 | // prevent duplication of direct outputs | ||
1776 | useDirectOutput |= (direct.size() == outputs.size()); | ||
1777 | |||
1778 | if (direct.isEmpty()) { | ||
1779 | // Nothing to refine when no direct outputs were found | ||
1780 | ALOGVV("refineOutputs() no direct outputs found"); | ||
1781 | } else if (useDirectOutput) { | ||
1782 | // Use the first direct output and discard the rest | ||
1783 | audio_io_handle_t out = direct.itemAt(0); | ||
1784 | discarded = outputs; | ||
1785 | discarded.remove(out); | ||
1786 | outputs.clear(); | ||
1787 | outputs.add(out); | ||
1788 | } else { | ||
1789 | // Discard direct outputs, keep mixer outputs | ||
1790 | for (size_t i = 0; i < direct.size(); i++) | ||
1791 | outputs.remove(direct.itemAt(i)); | ||
1792 | discarded = direct; | ||
1793 | } | ||
1794 | |||
1795 | ALOGI_IF(!discarded.isEmpty(), "refineOutputs() discard %d %s outputs", | ||
1796 | discarded.size(), useDirectOutput ? "mixer" : "direct"); | ||
1797 | |||
1798 | for (size_t i = 0; i < discarded.size(); i++) | ||
1799 | closeOutput(discarded.itemAt(i)); | ||
1800 | } | ||
1801 | |||
1802 | audio_io_handle_t AudioPolicyManager::openOutput_l(IOProfile *profile, | ||
1803 | audio_devices_t devices, | ||
1804 | audio_output_flags_t flags, | ||
1805 | uint32_t samplingRate, | ||
1806 | uint32_t format, | ||
1807 | uint32_t channelMask) | ||
1808 | { | ||
1809 | ALOGV("openOutput_l() opening output for devices 0x%08x", | ||
1810 | devices & profile->mSupportedDevices); | ||
1811 | |||
1812 | AudioOutputDescriptor *desc = new AudioOutputDescriptor(profile); | ||
1813 | audio_io_handle_t output = 0; | ||
1814 | |||
1815 | // Direct outputs must be opened with the exact requested parameters | ||
1816 | if (flags & AUDIO_OUTPUT_FLAG_DIRECT) { | ||
1817 | if (samplingRate) | ||
1818 | desc->mSamplingRate = samplingRate; | ||
1819 | if (format) | ||
1820 | desc->mFormat = (audio_format_t)format; | ||
1821 | if (channelMask) | ||
1822 | desc->mChannelMask = channelMask; | ||
1823 | } | ||
1824 | |||
1825 | // AudioTrack queries the sampling rate to check if default resampler | ||
1826 | // implementation supports it. Resampler limits the input sampling rate | ||
1827 | // to 2x the output rate, so the best output sampling rate in the profile | ||
1828 | // is the highest | ||
1829 | if (!desc->mSamplingRate) { | ||
1830 | uint32_t maxRate = 0; | ||
1831 | for (size_t i = 0; i < profile->mSamplingRates.size(); i++) { | ||
1832 | if (profile->mSamplingRates[i] > maxRate) | ||
1833 | maxRate = profile->mSamplingRates[i]; | ||
1834 | } | ||
1835 | desc->mSamplingRate = maxRate; | ||
1836 | } | ||
1837 | |||
1838 | // Skip profiles that don't support the requested flags (direct or none) | ||
1839 | if ((flags & AUDIO_OUTPUT_FLAG_DIRECT) != | ||
1840 | (desc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT)) { | ||
1841 | ALOGV("openOutput_l() flags mismatch req 0x%08x desc 0x%08x", | ||
1842 | flags, desc->mFlags); | ||
1843 | delete desc; | ||
1844 | return 0; | ||
1845 | } | ||
1846 | |||
1847 | desc->mDevice = devices & profile->mSupportedDevices; | ||
1848 | |||
1849 | // It's hardware module task to restrict the number of outputs that | ||
1850 | // can be opened | ||
1851 | output = mpClientInterface->openOutput(profile->mModule->mHandle, | ||
1852 | &desc->mDevice, | ||
1853 | &desc->mSamplingRate, | ||
1854 | &desc->mFormat, | ||
1855 | &desc->mChannelMask, | ||
1856 | &desc->mLatency, | ||
1857 | desc->mFlags); | ||
1858 | if (!output) { | ||
1859 | ALOGW("openOutput_l() could not open output for device 0x%08x", | ||
1860 | devices); | ||
1861 | delete desc; | ||
1862 | return 0; | ||
1863 | } | ||
1864 | |||
1865 | if (desc->isDirectOutput()) { | ||
1866 | if (profile->hasDynamicParams()) { | ||
1867 | // It's important to keep the original profile intact because it has | ||
1868 | // information about what parameters are dynamic | ||
1869 | IOProfile dynamicProfile = *profile; | ||
1870 | queryOutputParameters(output, &dynamicProfile); | ||
1871 | devices &= profile->mSupportedDevices; | ||
1872 | // Close and re-open the port with new parameters if its profile | ||
1873 | // supports the requested parameters | ||
1874 | if (dynamicProfile.isCompatibleProfile(devices, samplingRate, format, | ||
1875 | channelMask, flags)) { | ||
1876 | mpClientInterface->closeOutput(output); | ||
1877 | desc->mDevice = devices; | ||
1878 | desc->mSamplingRate = samplingRate; | ||
1879 | desc->mFormat = (audio_format_t)format; | ||
1880 | desc->mChannelMask = channelMask; | ||
1881 | desc->mLatency = 0; | ||
1882 | output = mpClientInterface->openOutput(dynamicProfile.mModule->mHandle, | ||
1883 | &desc->mDevice, | ||
1884 | &desc->mSamplingRate, | ||
1885 | &desc->mFormat, | ||
1886 | &desc->mChannelMask, | ||
1887 | &desc->mLatency, | ||
1888 | desc->mFlags); | ||
1889 | if (!output) { | ||
1890 | ALOGE("openOutput_l() could not re-open direct output"); | ||
1891 | delete desc; | ||
1892 | return 0; | ||
1893 | } | ||
1894 | } | ||
1895 | } | ||
1896 | if ((samplingRate && (samplingRate != desc->mSamplingRate)) || | ||
1897 | (format && (format != desc->mFormat)) || | ||
1898 | (channelMask && (channelMask != desc->mChannelMask))) { | ||
1899 | ALOGV("openOutput_l() params mismatch"); | ||
1900 | mpClientInterface->closeOutput(output); | ||
1901 | output = 0; | ||
1902 | delete desc; | ||
1903 | } | ||
1904 | } | ||
1905 | |||
1906 | if (output) { | ||
1907 | ALOGV("openOutput_l() adding output %d", output); | ||
1908 | addOutput(output, desc); | ||
1909 | setDeviceAddress(output, desc->device()); | ||
1910 | } | ||
1911 | |||
1912 | return output; | ||
1913 | } | ||
1914 | |||
1915 | audio_io_handle_t AudioPolicyManager::openOutput(audio_devices_t devices, | ||
1916 | uint32_t samplingRate, | ||
1917 | uint32_t format, | ||
1918 | uint32_t channelMask, | ||
1919 | audio_output_flags_t flags) | ||
1920 | { | ||
1921 | ALOGVV("openOutput() devices 0x%08x", devices); | ||
1922 | |||
1923 | if (devices == AUDIO_DEVICE_NONE) { | ||
1924 | ALOGE("openOutput() invalid device 0x%08x", devices); | ||
1925 | return BAD_VALUE; | ||
1926 | } | ||
1927 | |||
1928 | audio_io_handle_t output = 0; | ||
1929 | AudioOutputDescriptor *desc; | ||
1930 | |||
1931 | // First look in the active outputs | ||
1932 | for (size_t i = 0; i < mOutputs.size(); i++) { | ||
1933 | desc = mOutputs.valueAt(i); | ||
1934 | |||
1935 | // Skip duplicating outputs | ||
1936 | if (desc->isDuplicated()) | ||
1937 | continue; | ||
1938 | |||
1939 | // Skip outputs that don't match the requested flags | ||
1940 | if ((flags & AUDIO_OUTPUT_FLAG_DIRECT) != | ||
1941 | (desc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT)) | ||
1942 | continue; | ||
1943 | |||
1944 | // Direct outputs cannot mix the new stream, but can be moved to | ||
1945 | // a different track | ||
1946 | if (desc->isDirectOutput() && (desc->mUsers > 1)) | ||
1947 | continue; | ||
1948 | |||
1949 | if (devices & desc->supportedDevices()) { | ||
1950 | output = mOutputs.keyAt(i); | ||
1951 | // Direct outputs can be reassigned only if requested parameters | ||
1952 | // are the same than those of the open output | ||
1953 | if (desc->isDirectOutput() && | ||
1954 | (samplingRate == desc->mSamplingRate) && | ||
1955 | (channelMask == desc->mChannelMask) && | ||
1956 | (format == desc->mFormat)) { | ||
1957 | ALOGV("openOutput() direct output %d will be reused", output); | ||
1958 | break; | ||
1959 | } | ||
1960 | } | ||
1961 | } | ||
1962 | |||
1963 | // Look in other profiles that can route to the requested devices | ||
1964 | if (!output) { | ||
1965 | SortedVector<IOProfile*> profiles; | ||
1966 | getProfilesForDevices(devices, profiles); | ||
1967 | if (profiles.isEmpty()) { | ||
1968 | ALOGE("openOutput() no profile available for devices 0x%08x", devices); | ||
1969 | return 0; | ||
1970 | } | ||
1971 | |||
1972 | for (size_t i = 0; i < profiles.size(); i++) { | ||
1973 | IOProfile *profile = profiles.itemAt(i); | ||
1974 | output = openOutput_l(profile, devices, flags, | ||
1975 | samplingRate, format, channelMask); | ||
1976 | if (output) | ||
1977 | break; | ||
1978 | } | ||
1979 | } | ||
1980 | |||
1981 | // Increase use count if a valid output was found | ||
1982 | if (output) { | ||
1983 | desc = mOutputs.valueFor(output); | ||
1984 | ALOGV("openOutput() output %d users %u->%u", | ||
1985 | output, desc->mUsers, desc->mUsers+1); | ||
1986 | desc->mUsers++; | ||
1987 | } | ||
1988 | |||
1989 | ALOGV("openOutput() got output %d", output); | ||
1990 | |||
1991 | return output; | ||
1992 | } | ||
1993 | |||
1994 | audio_io_handle_t AudioPolicyManager::openDuplicateOutput(SortedVector<audio_io_handle_t> &outputs, | ||
1995 | uint32_t samplingRate, | ||
1996 | uint32_t format, | ||
1997 | uint32_t channelMask, | ||
1998 | int session) | ||
1999 | { | ||
2000 | audio_io_handle_t dupOutput; | ||
2001 | audio_io_handle_t outs[outputs.size()]; | ||
2002 | uint32_t idx = 0; | ||
2003 | |||
2004 | ALOGV("openDuplicateOutput() open output to duplicate to %d more outputs", | ||
2005 | outputs.size()); | ||
2006 | |||
2007 | for (size_t i = 0; i < outputs.size(); i++) { | ||
2008 | outs[idx++] = outputs.itemAt(i); | ||
2009 | ALOGV("openDuplicateOutput() duplicate to output %d", outputs.itemAt(i)); | ||
2010 | } | ||
2011 | |||
2012 | dupOutput = mpClientInterface->openDuplicateOutput(outs, outputs.size()); | ||
2013 | if (!dupOutput) { | ||
2014 | ALOGE("openDuplicateOutput() could not open duplicated output"); | ||
2015 | return 0; | ||
2016 | } | ||
2017 | |||
2018 | // Add duplicated output descriptor | ||
2019 | AudioOutputDescriptor *dupDesc = new AudioOutputDescriptor(NULL); | ||
2020 | for (size_t i = 0; i < outputs.size(); i++) { | ||
2021 | dupDesc->mDupOutputs.add(mOutputs.valueFor(outputs.itemAt(i))); | ||
2022 | } | ||
2023 | dupDesc->mSamplingRate = samplingRate; | ||
2024 | dupDesc->mFormat = (audio_format_t)format; | ||
2025 | dupDesc->mChannelMask = channelMask; | ||
2026 | |||
2027 | addOutput(dupOutput, dupDesc); | ||
2028 | |||
2029 | ALOGV("openDuplicateOutput() output %d users %u->%u", | ||
2030 | dupOutput, dupDesc->mUsers, dupDesc->mUsers+1); | ||
2031 | dupDesc->mUsers++; | ||
2032 | |||
2033 | ALOGV("openDuplicateOutput() got output %d", dupOutput); | ||
2034 | |||
2035 | return dupOutput; | ||
2036 | } | ||
2037 | |||
2038 | void AudioPolicyManager::addOutput(audio_io_handle_t id, | ||
2039 | AudioOutputDescriptor *outputDesc) | ||
2040 | { | ||
2041 | outputDesc->mId = id; | ||
2042 | mOutputs.add(id, outputDesc); | ||
2043 | } | ||
2044 | |||
2045 | void AudioPolicyManager::closeOutput(audio_io_handle_t output) | ||
2046 | { | ||
2047 | ALOGV("closeOutput() output %d", output); | ||
2048 | |||
2049 | AudioOutputDescriptor *desc = mOutputs.valueFor(output); | ||
2050 | if (!desc) { | ||
2051 | ALOGE("closeOutput() unknown output %d", output); | ||
2052 | return; | ||
2053 | } | ||
2054 | |||
2055 | // Output appears to be already closed | ||
2056 | if (!desc->mUsers) { | ||
2057 | ALOGW("closeOutput() invalid count %d for output %d", | ||
2058 | desc->mUsers, output); | ||
2059 | return; | ||
2060 | } | ||
2061 | |||
2062 | // Look for duplicated outputs connected to the output being removed | ||
2063 | if (desc->isDuplicated() && (desc->mUsers == 1)) { | ||
2064 | for (size_t i = 0; i < desc->mDupOutputs.size(); i++) { | ||
2065 | audio_io_handle_t dupOutput = desc->mDupOutputs.itemAt(i)->mId; | ||
2066 | if (dupOutput) | ||
2067 | closeOutput(dupOutput); | ||
2068 | else | ||
2069 | ALOGW("closeOutput() unexpected duplicated output %d", dupOutput); | ||
2070 | } | ||
2071 | } | ||
2072 | |||
2073 | ALOGV("closeOutput() output %d users %u->%u", | ||
2074 | output, desc->mUsers, desc->mUsers-1); | ||
2075 | desc->mUsers--; | ||
2076 | |||
2077 | if (!desc->mUsers) { | ||
2078 | AudioParameter param; | ||
2079 | param.add(String8("closing"), String8("true")); | ||
2080 | mpClientInterface->setParameters(output, param.toString()); | ||
2081 | mpClientInterface->closeOutput(output); | ||
2082 | delete desc; | ||
2083 | mOutputs.removeItem(output); | ||
2084 | } | ||
2085 | } | ||
2086 | |||
2087 | void AudioPolicyManager::setOutputDevice(audio_io_handle_t output, | ||
2088 | audio_devices_t device, | ||
2089 | bool force, | ||
2090 | int delayMs) | ||
2091 | { | ||
2092 | AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output); | ||
2093 | AudioParameter param; | ||
2094 | |||
2095 | ALOGV("setOutputDevice() output %d device 0x%08x delayMs %d", | ||
2096 | output, device, delayMs); | ||
2097 | |||
2098 | // The duplicating output passes the new device selection to the | ||
2099 | // connected outputs since they are the ones actually connected | ||
2100 | // to the audio hardware | ||
2101 | if (outputDesc->isDuplicated()) { | ||
2102 | for (size_t i = 0; i < outputDesc->mDupOutputs.size(); i++) { | ||
2103 | AudioOutputDescriptor *dupDesc = outputDesc->mDupOutputs.itemAt(i); | ||
2104 | if (dupDesc) | ||
2105 | setOutputDevice(dupDesc->mId, dupDesc->mDevice, force, delayMs); | ||
2106 | } | ||
2107 | return; | ||
2108 | } | ||
2109 | |||
2110 | // No need to proceed if new device is valid but not supported by the | ||
2111 | // current output profile | ||
2112 | if (device && !(device & outputDesc->mProfile->mSupportedDevices)) | ||
2113 | return; | ||
2114 | |||
2115 | // filter devices according to output selected | ||
2116 | device = (audio_devices_t)(device & outputDesc->mProfile->mSupportedDevices); | ||
2117 | |||
2118 | audio_devices_t prevDevice = outputDesc->device(); | ||
2119 | |||
2120 | // Do not change the routing if: | ||
2121 | // - the requested device is AUDIO_DEVICE_NONE | ||
2122 | // - the requested device is the same as current device and force is not specified. | ||
2123 | // Doing this check here allows the caller to call setOutputDevice() without conditions | ||
2124 | if (((device == AUDIO_DEVICE_NONE) || (device == prevDevice)) && !force) { | ||
2125 | ALOGV("setOutputDevice() setting same device 0x%08x for output %d", | ||
2126 | device, output); | ||
2127 | return; | ||
2128 | } | ||
2129 | |||
2130 | outputDesc->mDevice = device; | ||
2131 | |||
2132 | // Mute while transitioning to the new selected devices prevents volume bursts | ||
2133 | // when volume for the old device(s) and new device(s) are different. | ||
2134 | // The volume that is restored may have changed due if the new devices have | ||
2135 | // different volume curve. | ||
2136 | if (getDeviceForVolume(prevDevice) != getDeviceForVolume(device)) { | ||
2137 | // Mute takes place immediately | ||
2138 | muteOutput(output, true, 0); | ||
2139 | // Unmute after device has been changed | ||
2140 | muteOutput(output, false, delayMs * 2); | ||
2141 | } | ||
2142 | |||
2143 | // Do the routing | ||
2144 | ALOGI("setOutputDevice() changing device to 0x%08x", device); | ||
2145 | param.addInt(String8(AudioParameter::keyRouting), (int)device); | ||
2146 | mpClientInterface->setParameters(output, param.toString(), delayMs); | ||
2147 | } | ||
2148 | |||
2149 | void AudioPolicyManager::muteOutput(audio_io_handle_t output, | ||
2150 | bool mute, | ||
2151 | int delayMs) | ||
2152 | { | ||
2153 | AudioOutputDescriptor *desc = mOutputs.valueFor(output); | ||
2154 | audio_devices_t devices = desc->device(); | ||
2155 | |||
2156 | ALOGV("muteOutput() %s output %d devices 0x%08x", | ||
2157 | mute ? "mute" : "unmute", output, devices); | ||
2158 | |||
2159 | // Nothing to do | ||
2160 | if (devices == AUDIO_DEVICE_NONE) | ||
2161 | return; | ||
2162 | |||
2163 | // Caller must ensure muteOutput() is called on each connected output | ||
2164 | // in order to have more granular volume per output | ||
2165 | if (desc->isDuplicated()) { | ||
2166 | ALOGW("muteOutput() cannot mute duplicating outputs"); | ||
2167 | return; | ||
2168 | } | ||
2169 | |||
2170 | // Volume after unmuting is selected based on the most relevant device | ||
2171 | // for volume settings | ||
2172 | devices = getDeviceForVolume(devices); | ||
2173 | |||
2174 | for (int stream = 0; stream < AudioSystem::NUM_STREAM_TYPES; stream++) { | ||
2175 | setStreamMute(stream, mute, output, mute ? 0 : delayMs, devices); | ||
2176 | } | ||
2177 | } | ||
2178 | |||
2179 | status_t AudioPolicyManager::moveTracks(audio_io_handle_t output, | ||
2180 | audio_devices_t oldDevices, | ||
2181 | audio_devices_t newDevices) | ||
2182 | { | ||
2183 | // Move tracks if the output is open and devices have changed | ||
2184 | if (output && (oldDevices != newDevices)) { | ||
2185 | ALOGV("moveTracks() invalidate tracks on output %d", output); | ||
2186 | // Invalidate all tracks associated with this output | ||
2187 | for (int i = 0; i < (int)AudioSystem::NUM_STREAM_TYPES; i++) { | ||
2188 | mpClientInterface->setStreamOutput((AudioSystem::stream_type)i, | ||
2189 | output); | ||
2190 | } | ||
2191 | } | ||
2192 | |||
2193 | return NO_ERROR; | ||
2194 | } | ||
2195 | |||
2196 | audio_devices_t AudioPolicyManager::getZoneSupportedDevices(audio_zones_t zone) | ||
2197 | { | ||
2198 | if (!audio_is_output_zone(zone)) { | ||
2199 | ALOGE("getZoneSupportedDevices() zone 0x%x is invalid", zone); | ||
2200 | return AUDIO_DEVICE_NONE; | ||
2201 | } | ||
2202 | |||
2203 | ssize_t index = mZoneAffinity.indexOfKey(zone); | ||
2204 | if (index < 0) { | ||
2205 | ALOGE("getZoneSupportedDevices() zone 0x%x has affinity information", zone); | ||
2206 | return AUDIO_DEVICE_NONE; | ||
2207 | } | ||
2208 | |||
2209 | audio_devices_t devices = mZoneAffinity.valueAt(index); | ||
2210 | |||
2211 | ALOGV("getZoneSupportedDevices() zone 0x%x supports devices 0x%08x", zone, devices); | ||
2212 | |||
2213 | return devices; | ||
2214 | } | ||
2215 | |||
2216 | audio_devices_t AudioPolicyManager::getPrimaryDevices() | ||
2217 | { | ||
2218 | return mAttachedOutputDevices; | ||
2219 | } | ||
2220 | |||
2221 | audio_devices_t AudioPolicyManager::getRefinedZoneDevices(audio_zones_t zones, | ||
2222 | AudioSystem::stream_type stream) | ||
2223 | { | ||
2224 | audio_devices_t devices = getZoneDevices(zones); | ||
2225 | |||
2226 | // Refine zone devices based on the stream type, in case it's not required | ||
2227 | // to be routed to all its devices (e.g. voice call is restricted to cabin | ||
2228 | // speakers). | ||
2229 | switch (stream) { | ||
2230 | case AudioSystem::DTMF: | ||
2231 | case AudioSystem::BLUETOOTH_SCO: | ||
2232 | case AudioSystem::VOICE_CALL: | ||
2233 | if (devices & AUDIO_DEVICE_OUT_SPEAKER) | ||
2234 | devices = AUDIO_DEVICE_OUT_SPEAKER; | ||
2235 | break; | ||
2236 | default: | ||
2237 | break; | ||
2238 | } | ||
2239 | |||
2240 | return devices; | ||
2241 | } | ||
2242 | |||
2243 | audio_devices_t AudioPolicyManager::getSessionDevices(int session) | ||
2244 | { | ||
2245 | audio_devices_t devices; | ||
2246 | |||
2247 | ssize_t index = mSessions.indexOfKey(session); | ||
2248 | if (index < 0) { | ||
2249 | ALOGV("getSessionDevices() session %d is not active", session); | ||
2250 | devices = AUDIO_DEVICE_NONE; | ||
2251 | } else { | ||
2252 | SessionDescriptor *sessionDesc = mSessions.valueAt(index); | ||
2253 | devices = sessionDesc->devices(); | ||
2254 | ALOGV("getSessionDevices() session %d devices 0x%08x", session, devices); | ||
2255 | } | ||
2256 | |||
2257 | return devices; | ||
2258 | } | ||
2259 | |||
2260 | audio_io_handle_t AudioPolicyManager::findOutput(audio_devices_t device) | ||
2261 | { | ||
2262 | audio_io_handle_t output = 0; | ||
2263 | |||
2264 | for (size_t i = 0; i < mOutputs.size(); i++) { | ||
2265 | AudioOutputDescriptor *outputDesc = mOutputs.valueAt(i); | ||
2266 | if (!outputDesc->isDuplicated() && | ||
2267 | (outputDesc->device() & device)) { | ||
2268 | output = outputDesc->mId; | ||
2269 | break; | ||
2270 | } | ||
2271 | } | ||
2272 | |||
2273 | return output; | ||
2274 | } | ||
2275 | |||
2276 | audio_zones_t AudioPolicyManager::findZone(audio_devices_t device) | ||
2277 | { | ||
2278 | audio_zones_t zone = AUDIO_ZONE_NONE; | ||
2279 | |||
2280 | if (popcount(device) > 1) { | ||
2281 | ALOGE("findZone() expected only one device, got 0x%08x", device); | ||
2282 | return AUDIO_ZONE_NONE; | ||
2283 | } | ||
2284 | |||
2285 | for (size_t i = 0; i < mZoneDevices.size(); i++) { | ||
2286 | if (mZoneDevices.valueAt(i) & device) { | ||
2287 | zone = mZoneDevices.keyAt(i); | ||
2288 | break; | ||
2289 | } | ||
2290 | } | ||
2291 | |||
2292 | return zone; | ||
2293 | } | ||
2294 | |||
2295 | void AudioPolicyManager::findOutputsInZone(audio_io_handle_t output, | ||
2296 | audio_zones_t zone, | ||
2297 | SortedVector<audio_io_handle_t> &outputs) | ||
2298 | { | ||
2299 | AudioOutputDescriptor *desc = mOutputs.valueFor(output); | ||
2300 | |||
2301 | if (AudioSystem::popCount(zone) > 1) { | ||
2302 | ALOGE("findOutputsInZone() cannot find multiple zones simultaneously"); | ||
2303 | return; | ||
2304 | } | ||
2305 | |||
2306 | if (desc->isDuplicated()) { | ||
2307 | audio_devices_t devices = getZoneDevices(zone); | ||
2308 | |||
2309 | for (size_t i = 0; i < desc->mDupOutputs.size(); i++) { | ||
2310 | AudioOutputDescriptor *dupDesc = desc->mDupOutputs.itemAt(i); | ||
2311 | if (devices & dupDesc->device()) { | ||
2312 | outputs.add(dupDesc->mId); | ||
2313 | } | ||
2314 | } | ||
2315 | } else { | ||
2316 | outputs.add(output); | ||
2317 | } | ||
2318 | |||
2319 | ALOGV("findOutputsInZone() found %u outputs in zone 0x%x", outputs.size(), zone); | ||
2320 | } | ||
2321 | |||
2322 | void AudioPolicyManager::clearSession(int session) | ||
2323 | { | ||
2324 | ALOGV("clearSession() session %d", session); | ||
2325 | |||
2326 | ssize_t index = mSessions.indexOfKey(session); | ||
2327 | if (index < 0) { | ||
2328 | ALOGW("clearSession() session %d is not registered", session); | ||
2329 | } else { | ||
2330 | // Remove session routes and volumes | ||
2331 | SessionDescriptor *sessionDesc = mSessions.valueAt(index); | ||
2332 | delete sessionDesc; | ||
2333 | mSessions.removeItem(session); | ||
2334 | } | ||
2335 | } | ||
2336 | |||
2337 | status_t AudioPolicyManager::disconnectDevice(audio_devices_t device) | ||
2338 | { | ||
2339 | // Find the listening zone affected by the device disconnection | ||
2340 | audio_zones_t zone = findZone(device); | ||
2341 | |||
2342 | ALOGI("disconnectDevice() zone 0x%x device 0x%08x", zone, device); | ||
2343 | |||
2344 | // The disconnected device was not assigned to a listening zone | ||
2345 | if (zone == AUDIO_ZONE_NONE) { | ||
2346 | ALOGW("disconnectDevice() device 0x%08x is not assigned to a zone, " | ||
2347 | "cannot disconnect", device); | ||
2348 | return INVALID_OPERATION; | ||
2349 | } | ||
2350 | |||
2351 | if (device & mAttachedOutputDevices) { | ||
2352 | ALOGE("disconnectDevice() attached devices 0x%08x cannot be disconnected", | ||
2353 | device & mAttachedOutputDevices); | ||
2354 | return INVALID_OPERATION; | ||
2355 | } | ||
2356 | |||
2357 | // Update the devices of the listening zone | ||
2358 | setZoneDevices_l(zone, getZoneDevices(zone) & ~device); | ||
2359 | |||
2360 | // Find the audio sessions affected by the device disconnection | ||
2361 | for (size_t i = 0; i < mSessions.size(); i++) { | ||
2362 | SessionDescriptor *sessionDesc = mSessions.valueAt(i); | ||
2363 | |||
2364 | // Skip sessions not rendering to the disconnected device | ||
2365 | if (!(sessionDesc->devices() & device)) | ||
2366 | continue; | ||
2367 | |||
2368 | ALOGV("disconnectDevice() session %d device 0x%08x", | ||
2369 | sessionDesc->sessionId(), device); | ||
2370 | |||
2371 | sessionDesc->mDevices &= getZoneDevices(zone); | ||
2372 | |||
2373 | // Move all tracks in the output | ||
2374 | moveTracks(sessionDesc->mId, 0, sessionDesc->devices()); | ||
2375 | } | ||
2376 | |||
2377 | return NO_ERROR; | ||
2378 | } | ||
2379 | |||
2380 | void AudioPolicyManager::selectZoneForStrategy(routing_strategy strategy, | ||
2381 | audio_zones_t &zones, | ||
2382 | audio_devices_t &devices) | ||
2383 | { | ||
2384 | zones = AUDIO_ZONE_NONE; | ||
2385 | devices = AUDIO_DEVICE_NONE; | ||
2386 | |||
2387 | switch (strategy) { | ||
2388 | case STRATEGY_MEDIA: | ||
2389 | break; | ||
2390 | |||
2391 | case STRATEGY_DTMF: | ||
2392 | case STRATEGY_SONIFICATION: | ||
2393 | case STRATEGY_SONIFICATION_RESPECTFUL: | ||
2394 | zones = AUDIO_ZONE_CABIN; | ||
2395 | devices = getZoneDevices(zones); | ||
2396 | break; | ||
2397 | |||
2398 | case STRATEGY_PHONE: | ||
2399 | // Calls go strictly to speaker, not all cabin zone devices | ||
2400 | if (mAttachedOutputDevices & AUDIO_DEVICE_OUT_SPEAKER) { | ||
2401 | devices = AUDIO_DEVICE_OUT_SPEAKER; | ||
2402 | zones = findZone(devices); | ||
2403 | } | ||
2404 | break; | ||
2405 | |||
2406 | case STRATEGY_ENFORCED_AUDIBLE: | ||
2407 | zones = AUDIO_ZONE_ALL; | ||
2408 | devices = getZoneDevices(zones); | ||
2409 | break; | ||
2410 | |||
2411 | default: | ||
2412 | break; | ||
2413 | } | ||
2414 | |||
2415 | ALOGV("selectZoneForStrategy() zones 0x%x devices 0x%08x", zones, devices); | ||
2416 | } | ||
2417 | |||
2418 | void AudioPolicyManager::selectZoneForStream(AudioSystem::stream_type stream, | ||
2419 | audio_zones_t &zones, | ||
2420 | audio_devices_t &devices) | ||
2421 | { | ||
2422 | zones = AUDIO_ZONE_NONE; | ||
2423 | devices = AUDIO_DEVICE_NONE; | ||
2424 | |||
2425 | switch (stream) { | ||
2426 | case AudioSystem::ENFORCED_AUDIBLE: | ||
2427 | zones = AUDIO_ZONE_ALL; | ||
2428 | devices = getZoneDevices(zones); | ||
2429 | break; | ||
2430 | |||
2431 | case AudioSystem::DTMF: | ||
2432 | case AudioSystem::TTS: | ||
2433 | case AudioSystem::SYSTEM: | ||
2434 | case AudioSystem::RING: | ||
2435 | case AudioSystem::ALARM: | ||
2436 | case AudioSystem::NOTIFICATION: | ||
2437 | zones = AUDIO_ZONE_CABIN; | ||
2438 | devices = getZoneDevices(zones); | ||
2439 | break; | ||
2440 | |||
2441 | case AudioSystem::BLUETOOTH_SCO: | ||
2442 | case AudioSystem::VOICE_CALL: | ||
2443 | // Calls go strictly to speaker, not all cabin zone devices | ||
2444 | zones = AUDIO_ZONE_CABIN; | ||
2445 | devices = getZoneDevices(zones); | ||
2446 | if (devices & AUDIO_DEVICE_OUT_SPEAKER) | ||
2447 | devices = AUDIO_DEVICE_OUT_SPEAKER; | ||
2448 | break; | ||
2449 | |||
2450 | case AudioSystem::MUSIC: | ||
2451 | default: | ||
2452 | // Any listening zone is equally valid for music streams, | ||
2453 | // none is chosen to let the next selection mechanism execute | ||
2454 | break; | ||
2455 | } | ||
2456 | |||
2457 | ALOGV("selectZoneForStream() zones 0x%x devices 0x%08x", zones, devices); | ||
2458 | } | ||
2459 | |||
2460 | void AudioPolicyManager::selectZones(int session, | ||
2461 | AudioSystem::stream_type stream) | ||
2462 | { | ||
2463 | audio_zones_t zones = AUDIO_ZONE_NONE; | ||
2464 | audio_devices_t devices = AUDIO_DEVICE_NONE; | ||
2465 | |||
2466 | // First option: zones explicitly requested | ||
2467 | ssize_t index = mSessions.indexOfKey(session); | ||
2468 | if (index >= 0) { | ||
2469 | // Zones and devices are already populated | ||
2470 | zones = getSessionZones(session); | ||
2471 | ALOGV_IF(zones != AUDIO_ZONE_NONE, | ||
2472 | "selectZones() session %d got zone from descriptor", session); | ||
2473 | return; | ||
2474 | } | ||
2475 | |||
2476 | // Second option: best zones for strategy | ||
2477 | if (zones == AUDIO_ZONE_NONE) { | ||
2478 | selectZoneForStrategy(getStrategy(stream), zones, devices); | ||
2479 | ALOGV_IF(zones != AUDIO_ZONE_NONE, | ||
2480 | "selectZones() session %d got zone from strategy", session); | ||
2481 | } | ||
2482 | |||
2483 | // Third option: best zones for stream type | ||
2484 | if (zones == AUDIO_ZONE_NONE) { | ||
2485 | selectZoneForStream(stream, zones, devices); | ||
2486 | ALOGV_IF(zones != AUDIO_ZONE_NONE, | ||
2487 | "selectZones() session %d got zone from stream type", session); | ||
2488 | } | ||
2489 | |||
2490 | // Fourth option: cabin | ||
2491 | if (zones == AUDIO_ZONE_NONE) { | ||
2492 | zones = AUDIO_ZONE_CABIN; | ||
2493 | devices = getZoneDevices(zones); | ||
2494 | ALOGV("selectZones() session %d got default zone", session); | ||
2495 | } | ||
2496 | |||
2497 | ALOGV("selectZones() session %d got zones 0x%x devices 0x%08x", | ||
2498 | session, zones, devices); | ||
2499 | |||
2500 | // Create an session descriptor with the selected zone(s) and device(s) | ||
2501 | mSessions.add(session, new SessionDescriptor(session, 0, zones, devices)); | ||
2502 | } | ||
2503 | |||
2504 | const AudioPolicyManager::VolumeCurvePoint | ||
2505 | AudioPolicyManager::sDefaultVolumeCurve[AudioPolicyManager::VOLCNT] = { | ||
2506 | {1, -49.5f}, {33, -33.5f}, {66, -17.0f}, {100, 0.0f} | ||
2507 | }; | ||
2508 | |||
2509 | const AudioPolicyManager::VolumeCurvePoint | ||
2510 | AudioPolicyManager::sDefaultMediaVolumeCurve[AudioPolicyManager::VOLCNT] = { | ||
2511 | {1, -58.0f}, {20, -40.0f}, {60, -17.0f}, {100, 0.0f} | ||
2512 | }; | ||
2513 | |||
2514 | const AudioPolicyManager::VolumeCurvePoint | ||
2515 | AudioPolicyManager::sSpeakerMediaVolumeCurve[AudioPolicyManager::VOLCNT] = { | ||
2516 | {1, -56.0f}, {20, -34.0f}, {60, -11.0f}, {100, 0.0f} | ||
2517 | }; | ||
2518 | |||
2519 | const AudioPolicyManager::VolumeCurvePoint | ||
2520 | AudioPolicyManager::sSpeakerSonificationVolumeCurve[AudioPolicyManager::VOLCNT] = { | ||
2521 | {1, -29.7f}, {33, -20.1f}, {66, -10.2f}, {100, 0.0f} | ||
2522 | }; | ||
2523 | |||
2524 | // AUDIO_STREAM_SYSTEM, AUDIO_STREAM_ENFORCED_AUDIBLE and AUDIO_STREAM_DTMF volume tracks | ||
2525 | // AUDIO_STREAM_RING on phones and AUDIO_STREAM_MUSIC on tablets (See AudioService.java). | ||
2526 | // The range is constrained between -24dB and -6dB over speaker and -30dB and -18dB over headset. | ||
2527 | const AudioPolicyManager::VolumeCurvePoint | ||
2528 | AudioPolicyManager::sDefaultSystemVolumeCurve[AudioPolicyManager::VOLCNT] = { | ||
2529 | {1, -24.0f}, {33, -18.0f}, {66, -12.0f}, {100, -6.0f} | ||
2530 | }; | ||
2531 | |||
2532 | const AudioPolicyManager::VolumeCurvePoint | ||
2533 | AudioPolicyManager::sHeadsetSystemVolumeCurve[AudioPolicyManager::VOLCNT] = { | ||
2534 | {1, -30.0f}, {33, -26.0f}, {66, -22.0f}, {100, -18.0f} | ||
2535 | }; | ||
2536 | |||
2537 | const AudioPolicyManager::VolumeCurvePoint | ||
2538 | AudioPolicyManager::sDefaultVoiceVolumeCurve[AudioPolicyManager::VOLCNT] = { | ||
2539 | {0, -42.0f}, {33, -28.0f}, {66, -14.0f}, {100, 0.0f} | ||
2540 | }; | ||
2541 | |||
2542 | const AudioPolicyManager::VolumeCurvePoint | ||
2543 | AudioPolicyManager::sSpeakerVoiceVolumeCurve[AudioPolicyManager::VOLCNT] = { | ||
2544 | {0, -24.0f}, {33, -16.0f}, {66, -8.0f}, {100, 0.0f} | ||
2545 | }; | ||
2546 | |||
2547 | const AudioPolicyManager::VolumeCurvePoint | ||
2548 | *AudioPolicyManager::sVolumeProfiles[AUDIO_STREAM_CNT] | ||
2549 | [AudioPolicyManager::DEVICE_CATEGORY_CNT] = { | ||
2550 | { // AUDIO_STREAM_VOICE_CALL | ||
2551 | sDefaultVoiceVolumeCurve, // DEVICE_CATEGORY_HEADSET | ||
2552 | sSpeakerVoiceVolumeCurve, // DEVICE_CATEGORY_SPEAKER | ||
2553 | sDefaultVoiceVolumeCurve // DEVICE_CATEGORY_EARPIECE | ||
2554 | }, | ||
2555 | { // AUDIO_STREAM_SYSTEM | ||
2556 | sHeadsetSystemVolumeCurve, // DEVICE_CATEGORY_HEADSET | ||
2557 | sDefaultSystemVolumeCurve, // DEVICE_CATEGORY_SPEAKER | ||
2558 | sDefaultSystemVolumeCurve // DEVICE_CATEGORY_EARPIECE | ||
2559 | }, | ||
2560 | { // AUDIO_STREAM_RING | ||
2561 | sDefaultVolumeCurve, // DEVICE_CATEGORY_HEADSET | ||
2562 | sSpeakerSonificationVolumeCurve, // DEVICE_CATEGORY_SPEAKER | ||
2563 | sDefaultVolumeCurve // DEVICE_CATEGORY_EARPIECE | ||
2564 | }, | ||
2565 | { // AUDIO_STREAM_MUSIC | ||
2566 | sDefaultMediaVolumeCurve, // DEVICE_CATEGORY_HEADSET | ||
2567 | sSpeakerMediaVolumeCurve, // DEVICE_CATEGORY_SPEAKER | ||
2568 | sDefaultMediaVolumeCurve // DEVICE_CATEGORY_EARPIECE | ||
2569 | }, | ||
2570 | { // AUDIO_STREAM_ALARM | ||
2571 | sDefaultVolumeCurve, // DEVICE_CATEGORY_HEADSET | ||
2572 | sSpeakerSonificationVolumeCurve, // DEVICE_CATEGORY_SPEAKER | ||
2573 | sDefaultVolumeCurve // DEVICE_CATEGORY_EARPIECE | ||
2574 | }, | ||
2575 | { // AUDIO_STREAM_NOTIFICATION | ||
2576 | sDefaultVolumeCurve, // DEVICE_CATEGORY_HEADSET | ||
2577 | sSpeakerSonificationVolumeCurve, // DEVICE_CATEGORY_SPEAKER | ||
2578 | sDefaultVolumeCurve // DEVICE_CATEGORY_EARPIECE | ||
2579 | }, | ||
2580 | { // AUDIO_STREAM_BLUETOOTH_SCO | ||
2581 | sDefaultVoiceVolumeCurve, // DEVICE_CATEGORY_HEADSET | ||
2582 | sSpeakerVoiceVolumeCurve, // DEVICE_CATEGORY_SPEAKER | ||
2583 | sDefaultVoiceVolumeCurve // DEVICE_CATEGORY_EARPIECE | ||
2584 | }, | ||
2585 | { // AUDIO_STREAM_ENFORCED_AUDIBLE | ||
2586 | sHeadsetSystemVolumeCurve, // DEVICE_CATEGORY_HEADSET | ||
2587 | sDefaultSystemVolumeCurve, // DEVICE_CATEGORY_SPEAKER | ||
2588 | sDefaultSystemVolumeCurve // DEVICE_CATEGORY_EARPIECE | ||
2589 | }, | ||
2590 | { // AUDIO_STREAM_DTMF | ||
2591 | sHeadsetSystemVolumeCurve, // DEVICE_CATEGORY_HEADSET | ||
2592 | sDefaultSystemVolumeCurve, // DEVICE_CATEGORY_SPEAKER | ||
2593 | sDefaultSystemVolumeCurve // DEVICE_CATEGORY_EARPIECE | ||
2594 | }, | ||
2595 | { // AUDIO_STREAM_TTS | ||
2596 | sDefaultMediaVolumeCurve, // DEVICE_CATEGORY_HEADSET | ||
2597 | sSpeakerMediaVolumeCurve, // DEVICE_CATEGORY_SPEAKER | ||
2598 | sDefaultMediaVolumeCurve // DEVICE_CATEGORY_EARPIECE | ||
2599 | }, | ||
2600 | }; | ||
2601 | |||
2602 | void AudioPolicyManager::initializeVolumeCurves() | ||
2603 | { | ||
2604 | for (int i = 0; i < AUDIO_STREAM_CNT; i++) { | ||
2605 | for (int j = 0; j < DEVICE_CATEGORY_CNT; j++) { | ||
2606 | mStreams[i].mVolumeCurve[j] = sVolumeProfiles[i][j]; | ||
2607 | } | ||
2608 | } | ||
2609 | } | ||
2610 | |||
2611 | float AudioPolicyManager::computeVolume(int stream, | ||
2612 | int index, | ||
2613 | audio_io_handle_t output, | ||
2614 | audio_devices_t device) | ||
2615 | { | ||
2616 | float volume = 1.0; | ||
2617 | AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output); | ||
2618 | StreamDescriptor &streamDesc = mStreams[stream]; | ||
2619 | |||
2620 | if (device == AUDIO_DEVICE_NONE) | ||
2621 | device = outputDesc->device(); | ||
2622 | |||
2623 | // if volume is not 0 (not muted), force media volume to max on digital output | ||
2624 | if (stream == AudioSystem::MUSIC && | ||
2625 | index != mStreams[stream].mIndexMin && | ||
2626 | (device == AUDIO_DEVICE_OUT_AUX_DIGITAL || | ||
2627 | device == AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET || | ||
2628 | device == AUDIO_DEVICE_OUT_USB_ACCESSORY || | ||
2629 | device == AUDIO_DEVICE_OUT_USB_DEVICE)) { | ||
2630 | return 1.0; | ||
2631 | } | ||
2632 | |||
2633 | volume = volIndexToAmpl(device, streamDesc, index); | ||
2634 | |||
2635 | // Always attenuate ringtones and notifications volume by 6dB with a minimum threshold | ||
2636 | // at -36d so that notification is always perceived | ||
2637 | const routing_strategy stream_strategy = getStrategy((AudioSystem::stream_type)stream); | ||
2638 | if ((device & (AUDIO_DEVICE_OUT_BLUETOOTH_A2DP | | ||
2639 | AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES | | ||
2640 | AUDIO_DEVICE_OUT_WIRED_HEADSET | | ||
2641 | AUDIO_DEVICE_OUT_WIRED_HEADPHONE | | ||
2642 | AUDIO_DEVICE_OUT_WIRED_HEADPHONE2)) && | ||
2643 | ((stream_strategy == STRATEGY_SONIFICATION) || | ||
2644 | (stream_strategy == STRATEGY_SONIFICATION_RESPECTFUL) || | ||
2645 | (stream == AudioSystem::SYSTEM) || | ||
2646 | ((stream_strategy == STRATEGY_ENFORCED_AUDIBLE) && | ||
2647 | (mForceUse[AudioSystem::FOR_SYSTEM] == AudioSystem::FORCE_NONE))) && | ||
2648 | streamDesc.mCanBeMuted) { | ||
2649 | volume *= SONIFICATION_HEADSET_VOLUME_FACTOR; | ||
2650 | float minVol = (volume > SONIFICATION_HEADSET_VOLUME_MIN) ? | ||
2651 | volume : SONIFICATION_HEADSET_VOLUME_MIN; | ||
2652 | if (volume > minVol) { | ||
2653 | volume = minVol; | ||
2654 | ALOGV("computeVolume() limiting volume to %f (was %f)", minVol, volume); | ||
2655 | } | ||
2656 | } | ||
2657 | |||
2658 | ALOGV("computeVolume() output %d stream %d index %d devices 0x%08x volume %f", | ||
2659 | output, stream, index, device, volume); | ||
2660 | |||
2661 | return volume; | ||
2662 | } | ||
2663 | |||
2664 | float AudioPolicyManager::volIndexToAmpl(audio_devices_t device, | ||
2665 | const StreamDescriptor& streamDesc, | ||
2666 | int indexInUi) | ||
2667 | { | ||
2668 | device_category deviceCategory = getDeviceCategory(device); | ||
2669 | const VolumeCurvePoint *curve = streamDesc.mVolumeCurve[deviceCategory]; | ||
2670 | |||
2671 | // The volume index in the UI is relative to the min and max volume | ||
2672 | // indices for this stream type | ||
2673 | int nbSteps = 1 + curve[VOLMAX].mIndex - curve[VOLMIN].mIndex; | ||
2674 | int volIdx = (nbSteps * (indexInUi - streamDesc.mIndexMin)) / | ||
2675 | (streamDesc.mIndexMax - streamDesc.mIndexMin); | ||
2676 | |||
2677 | // Find what part of the curve this index volume belongs to or if | ||
2678 | // it's out of bounds | ||
2679 | int segment = 0; | ||
2680 | if (volIdx < curve[VOLMIN].mIndex) { // out of bounds | ||
2681 | return 0.0f; | ||
2682 | } else if (volIdx < curve[VOLKNEE1].mIndex) { | ||
2683 | segment = 0; | ||
2684 | } else if (volIdx < curve[VOLKNEE2].mIndex) { | ||
2685 | segment = 1; | ||
2686 | } else if (volIdx <= curve[VOLMAX].mIndex) { | ||
2687 | segment = 2; | ||
2688 | } else { // out of bounds | ||
2689 | return 1.0f; | ||
2690 | } | ||
2691 | |||
2692 | // Linear interpolation in the attenuation table in dB | ||
2693 | float decibels = curve[segment].mDBAttenuation + | ||
2694 | ((float)(volIdx - curve[segment].mIndex)) * | ||
2695 | ( (curve[segment+1].mDBAttenuation - | ||
2696 | curve[segment].mDBAttenuation) / | ||
2697 | ((float)(curve[segment+1].mIndex - | ||
2698 | curve[segment].mIndex)) ); | ||
2699 | |||
2700 | float amplification = exp( decibels * 0.115129f); // exp( dB * ln(10) / 20 ) | ||
2701 | |||
2702 | ALOGVV("VOLUME vol index=[%d %d %d], dB=[%.1f %.1f %.1f] ampl=%.5f", | ||
2703 | curve[segment].mIndex, volIdx, | ||
2704 | curve[segment+1].mIndex, | ||
2705 | curve[segment].mDBAttenuation, | ||
2706 | decibels, | ||
2707 | curve[segment+1].mDBAttenuation, | ||
2708 | amplification); | ||
2709 | |||
2710 | return amplification; | ||
2711 | } | ||
2712 | |||
2713 | status_t AudioPolicyManager::setVolume(int stream, | ||
2714 | audio_io_handle_t output, | ||
2715 | int delayMs) | ||
2716 | { | ||
2717 | return setVolume_l(stream, output, false, delayMs); | ||
2718 | } | ||
2719 | |||
2720 | status_t AudioPolicyManager::muteVolume(int stream, | ||
2721 | audio_io_handle_t output, | ||
2722 | int delayMs) | ||
2723 | { | ||
2724 | return setVolume_l(stream, output, true, delayMs); | ||
2725 | } | ||
2726 | |||
2727 | status_t AudioPolicyManager::setVolume_l(int stream, | ||
2728 | audio_io_handle_t output, | ||
2729 | bool mute, | ||
2730 | int delayMs) | ||
2731 | { | ||
2732 | AudioOutputDescriptor *desc = mOutputs.valueFor(output); | ||
2733 | status_t status; | ||
2734 | |||
2735 | ALOGV("setVolume_l() output %d stream %d mute %d delayMs %d", | ||
2736 | output, stream, mute, delayMs); | ||
2737 | |||
2738 | if (desc->isDuplicated()) | ||
2739 | status = setDuplicatingVolume(stream, output, mute, delayMs); | ||
2740 | else | ||
2741 | status = setStreamVolume(stream, output, mute, delayMs); | ||
2742 | |||
2743 | return status; | ||
2744 | } | ||
2745 | |||
2746 | status_t AudioPolicyManager::setStreamVolume(int stream, | ||
2747 | audio_io_handle_t output, | ||
2748 | bool mute, | ||
2749 | int delayMs) | ||
2750 | { | ||
2751 | AudioOutputDescriptor *desc = mOutputs.valueFor(output); | ||
2752 | |||
2753 | // Select the most relevant device for volume computation | ||
2754 | audio_devices_t device = getDeviceForVolume(desc->device()); | ||
2755 | |||
2756 | int index = mute ? 0 : mStreams[stream].mIndexCur; | ||
2757 | |||
2758 | ALOGV("setStreamVolume() output %d stream %d index %d delayMs %d", | ||
2759 | output, stream, index, delayMs); | ||
2760 | |||
2761 | // Do not change actual stream volume if the stream is muted | ||
2762 | if (desc->mMuteCount[stream] != 0) { | ||
2763 | ALOGV("setStreamVolume() stream %d muted count %d", | ||
2764 | stream, desc->mMuteCount[stream]); | ||
2765 | return NO_ERROR; | ||
2766 | } | ||
2767 | |||
2768 | float volume = computeVolume(stream, index, output, device); | ||
2769 | if (volume != desc->mCurVolume[stream]) { | ||
2770 | desc->mCurVolume[stream] = volume; | ||
2771 | |||
2772 | ALOGV("setStreamVolume() for output %d stream %d, volume %f, delay %d", | ||
2773 | output, stream, volume, delayMs); | ||
2774 | |||
2775 | // Force VOICE_CALL to track BLUETOOTH_SCO stream volume when | ||
2776 | // bluetooth audio is enabled | ||
2777 | if (stream == AudioSystem::BLUETOOTH_SCO) { | ||
2778 | mpClientInterface->setStreamVolume(AudioSystem::VOICE_CALL, | ||
2779 | volume, output, delayMs); | ||
2780 | } | ||
2781 | mpClientInterface->setStreamVolume((AudioSystem::stream_type)stream, | ||
2782 | volume, output, delayMs); | ||
2783 | } | ||
2784 | |||
2785 | if (stream == AudioSystem::VOICE_CALL || | ||
2786 | stream == AudioSystem::BLUETOOTH_SCO) { | ||
2787 | // Force voice volume to max for bluetooth SCO as volume is managed by | ||
2788 | // the headset | ||
2789 | float voiceVolume; | ||
2790 | if (stream == AudioSystem::VOICE_CALL) { | ||
2791 | voiceVolume = (float)index/(float)mStreams[stream].mIndexMax; | ||
2792 | } else { | ||
2793 | voiceVolume = 1.0; | ||
2794 | } | ||
2795 | |||
2796 | if (voiceVolume != mLastVoiceVolume && output == mPrimaryOutput) { | ||
2797 | mpClientInterface->setVoiceVolume(voiceVolume, delayMs); | ||
2798 | mLastVoiceVolume = voiceVolume; | ||
2799 | } | ||
2800 | } | ||
2801 | |||
2802 | return NO_ERROR; | ||
2803 | } | ||
2804 | |||
2805 | status_t AudioPolicyManager::setDuplicatingVolume(int stream, | ||
2806 | audio_io_handle_t output, | ||
2807 | bool mute, | ||
2808 | int delayMs) | ||
2809 | { | ||
2810 | AudioOutputDescriptor *desc = mOutputs.valueFor(output); | ||
2811 | |||
2812 | ALOGV("setDuplicatingVolume() output %d stream %d delayMs %d", | ||
2813 | output, stream, delayMs); | ||
2814 | |||
2815 | if (!desc->isDuplicated()) { | ||
2816 | ALOGE("setDuplicatingVolume() output %d is not duplicate", output); | ||
2817 | return INVALID_OPERATION; | ||
2818 | } | ||
2819 | |||
2820 | // Set the volume for all outputs that are receiving the duplicated data. | ||
2821 | // The volume to be set is in the OutputTrack, which only exists for | ||
2822 | // duplicating threads | ||
2823 | for (size_t i = 0; i < desc->mDupOutputs.size(); i++) { | ||
2824 | AudioOutputDescriptor *dupDesc = desc->mDupOutputs.itemAt(i); | ||
2825 | if (dupDesc) { | ||
2826 | // Select the most relevant device for volume computation | ||
2827 | ALOGE("setDuplicatingVolume() output %d device 0x%08x forvol 0x%08x", | ||
2828 | dupDesc->mId, dupDesc->device(), getDeviceForVolume(dupDesc->device())); | ||
2829 | audio_devices_t device = getDeviceForVolume(dupDesc->device()); | ||
2830 | int index = mute ? 0 : mStreams[stream].mIndexCur; | ||
2831 | float volume; | ||
2832 | if (!dupDesc->mMuteCount[stream]) | ||
2833 | volume = computeVolume(stream, index, output, device); | ||
2834 | else | ||
2835 | volume = 0; | ||
2836 | |||
2837 | ALOGV("setDuplicatingVolume() dup output %d devices 0x%08x " | ||
2838 | "index %d volume %f", dupDesc->mId, device, index, volume); | ||
2839 | mpClientInterface->setDuplicatingVolume(output, dupDesc->mId, volume); | ||
2840 | } | ||
2841 | } | ||
2842 | |||
2843 | // The volume for the duplicating output is set to 0dB as its OutputTrack's | ||
2844 | // already took care of per-device category volume | ||
2845 | for (int i = 0; i < AudioSystem::NUM_STREAM_TYPES; i++) { | ||
2846 | mpClientInterface->setStreamVolume((AudioSystem::stream_type)i, | ||
2847 | 1.0f, output, delayMs); | ||
2848 | } | ||
2849 | |||
2850 | return NO_ERROR; | ||
2851 | } | ||
2852 | |||
2853 | void AudioPolicyManager::setStreamMute(int stream, | ||
2854 | bool on, | ||
2855 | audio_io_handle_t output, | ||
2856 | int delayMs, | ||
2857 | audio_devices_t device) | ||
2858 | { | ||
2859 | StreamDescriptor &streamDesc = mStreams[stream]; | ||
2860 | AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output); | ||
2861 | |||
2862 | if (device == AUDIO_DEVICE_NONE) | ||
2863 | device = outputDesc->device(); | ||
2864 | |||
2865 | ALOGV("setStreamMute() stream %d mute %d output %d mMuteCount %d device 0x%08x", | ||
2866 | stream, on, output, outputDesc->mMuteCount[stream], device); | ||
2867 | |||
2868 | if (on) { | ||
2869 | if (outputDesc->mMuteCount[stream] == 0) { | ||
2870 | if (streamDesc.mCanBeMuted && | ||
2871 | ((stream != AudioSystem::ENFORCED_AUDIBLE) || | ||
2872 | (mForceUse[AudioSystem::FOR_SYSTEM] == AudioSystem::FORCE_NONE))) { | ||
2873 | muteVolume(stream, output, delayMs); | ||
2874 | } | ||
2875 | } | ||
2876 | // Increment mMuteCount after calling muteVolume() so that volume change | ||
2877 | // is not ignored | ||
2878 | ALOGV("setStreamMute() output %d stream %d mute %d->%d", output, stream, | ||
2879 | outputDesc->mMuteCount[stream], outputDesc->mMuteCount[stream]+1); | ||
2880 | outputDesc->mMuteCount[stream]++; | ||
2881 | } else { | ||
2882 | if (outputDesc->mMuteCount[stream] == 0) { | ||
2883 | ALOGW("setStreamMute() unmuting non muted stream!"); | ||
2884 | return; | ||
2885 | } | ||
2886 | ALOGV("setStreamMute() output %d stream %d mute %d->%d", output, stream, | ||
2887 | outputDesc->mMuteCount[stream], outputDesc->mMuteCount[stream]-1); | ||
2888 | if (--outputDesc->mMuteCount[stream] == 0) | ||
2889 | setVolume(stream, output, delayMs); | ||
2890 | } | ||
2891 | } | ||
2892 | |||
2893 | void AudioPolicyManager::initSessionVolume(int session) | ||
2894 | { | ||
2895 | // Session 0 is a special case where the output is used only to query | ||
2896 | // hardware parameters, no need for volume updates | ||
2897 | if (!session) | ||
2898 | return; | ||
2899 | |||
2900 | SessionDescriptor *sessionDesc = mSessions.valueFor(session); | ||
2901 | audio_zones_t zones = getSessionZones(session); | ||
2902 | |||
2903 | for (audio_zones_t zone = AUDIO_ZONE_LAST; zone & AUDIO_ZONE_ALL; zone >>= 1) { | ||
2904 | audio_zones_t cur = zone & zones; | ||
2905 | if (cur != AUDIO_ZONE_NONE) { | ||
2906 | float zoneVolume = mZoneVolume.valueFor(cur); | ||
2907 | float sessionVolume = sessionDesc->mVolume.valueFor(cur); | ||
2908 | float volume = zoneVolume * sessionVolume; | ||
2909 | |||
2910 | ALOGI("initSessionVolume() session %d zone 0x%0x " | ||
2911 | "zone-vol %f session-vol %f final-vol %f", | ||
2912 | session, cur, zoneVolume, sessionVolume, volume); | ||
2913 | |||
2914 | setSessionVolume_l(session, cur, volume); | ||
2915 | } | ||
2916 | } | ||
2917 | } | ||
2918 | |||
2919 | bool AudioPolicyManager::isInCall() | ||
2920 | { | ||
2921 | return isStateInCall(mPhoneState); | ||
2922 | } | ||
2923 | |||
2924 | bool AudioPolicyManager::isStateInCall(int state) { | ||
2925 | return ((state == AudioSystem::MODE_IN_CALL) || | ||
2926 | (state == AudioSystem::MODE_IN_COMMUNICATION)); | ||
2927 | } | ||
2928 | |||
2929 | |||
2930 | |||
2931 | void AudioPolicyManager::handleIncallSonification(int stream, bool starting, bool stateChange) | ||
2932 | { | ||
2933 | // if the stream pertains to sonification strategy and we are in call we must | ||
2934 | // mute the stream if it is low visibility. If it is high visibility, we must play a tone | ||
2935 | // in the device used for phone strategy and play the tone if the selected device does not | ||
2936 | // interfere with the device used for phone strategy | ||
2937 | // if stateChange is true, we are called from setPhoneState() and we must mute or unmute as | ||
2938 | // many times as there are active tracks on the output | ||
2939 | |||
2940 | const routing_strategy stream_strategy = getStrategy((AudioSystem::stream_type)stream); | ||
2941 | |||
2942 | if ((stream_strategy != STRATEGY_SONIFICATION) && | ||
2943 | (stream_strategy != STRATEGY_SONIFICATION_RESPECTFUL)) { | ||
2944 | return; | ||
2945 | } | ||
2946 | |||
2947 | AudioOutputDescriptor *outputDesc = mOutputs.valueFor(mPrimaryOutput); | ||
2948 | |||
2949 | ALOGV("handleIncallSonification() stream %d starting %d device %x stateChange %d", | ||
2950 | stream, starting, outputDesc->mDevice, stateChange); | ||
2951 | |||
2952 | // nothing to do if output is inactive | ||
2953 | if (!outputDesc->mRefCount[stream]) { | ||
2954 | return; | ||
2955 | } | ||
2956 | |||
2957 | int muteCount = 1; | ||
2958 | if (stateChange) { | ||
2959 | muteCount = outputDesc->mRefCount[stream]; | ||
2960 | } | ||
2961 | if (AudioSystem::isLowVisibility((AudioSystem::stream_type)stream)) { | ||
2962 | ALOGV("handleIncallSonification() low visibility, muteCount %d", muteCount); | ||
2963 | for (int i = 0; i < muteCount; i++) { | ||
2964 | setStreamMute(stream, starting, mPrimaryOutput); | ||
2965 | } | ||
2966 | } else { | ||
2967 | ALOGV("handleIncallSonification() high visibility"); | ||
2968 | if (outputDesc->device() & | ||
2969 | getRefinedZoneDevices(AUDIO_ZONE_CABIN, AudioSystem::VOICE_CALL)) { | ||
2970 | ALOGV("handleIncallSonification() high visibility muted, muteCount %d", | ||
2971 | muteCount); | ||
2972 | for (int i = 0; i < muteCount; i++) { | ||
2973 | setStreamMute(stream, starting, mPrimaryOutput); | ||
2974 | } | ||
2975 | } | ||
2976 | if (starting) { | ||
2977 | mpClientInterface->startTone(ToneGenerator::TONE_SUP_CALL_WAITING, | ||
2978 | AudioSystem::VOICE_CALL); | ||
2979 | } else { | ||
2980 | mpClientInterface->stopTone(); | ||
2981 | } | ||
2982 | } | ||
2983 | } | ||
2984 | |||
2985 | void AudioPolicyManager::checkA2dpSuspend() | ||
2986 | { | ||
2987 | if (!mHasA2dp) { | ||
2988 | return; | ||
2989 | } | ||
2990 | audio_io_handle_t a2dpOutput = getA2dpOutput(); | ||
2991 | if (a2dpOutput == 0) { | ||
2992 | return; | ||
2993 | } | ||
2994 | |||
2995 | // suspend A2DP output if: | ||
2996 | // (NOT already suspended) && | ||
2997 | // ((SCO device is connected && | ||
2998 | // (forced usage for communication || for record is SCO))) || | ||
2999 | // (phone state is ringing || in call) | ||
3000 | // | ||
3001 | // restore A2DP output if: | ||
3002 | // (Already suspended) && | ||
3003 | // ((SCO device is NOT connected || | ||
3004 | // (forced usage NOT for communication && NOT for record is SCO))) && | ||
3005 | // (phone state is NOT ringing && NOT in call) | ||
3006 | // | ||
3007 | if (mA2dpSuspended) { | ||
3008 | if (((mScoDeviceAddress == "") || | ||
3009 | ((mForceUse[AudioSystem::FOR_COMMUNICATION] != AudioSystem::FORCE_BT_SCO) && | ||
3010 | (mForceUse[AudioSystem::FOR_RECORD] != AudioSystem::FORCE_BT_SCO))) && | ||
3011 | ((mPhoneState != AudioSystem::MODE_IN_CALL) && | ||
3012 | (mPhoneState != AudioSystem::MODE_RINGTONE))) { | ||
3013 | mpClientInterface->restoreOutput(a2dpOutput); | ||
3014 | mA2dpSuspended = false; | ||
3015 | } | ||
3016 | } else { | ||
3017 | if (((mScoDeviceAddress != "") && | ||
3018 | ((mForceUse[AudioSystem::FOR_COMMUNICATION] == AudioSystem::FORCE_BT_SCO) || | ||
3019 | (mForceUse[AudioSystem::FOR_RECORD] == AudioSystem::FORCE_BT_SCO))) || | ||
3020 | ((mPhoneState == AudioSystem::MODE_IN_CALL) || | ||
3021 | (mPhoneState == AudioSystem::MODE_RINGTONE))) { | ||
3022 | |||
3023 | mpClientInterface->suspendOutput(a2dpOutput); | ||
3024 | mA2dpSuspended = true; | ||
3025 | } | ||
3026 | } | ||
3027 | } | ||
3028 | |||
3029 | audio_io_handle_t AudioPolicyManager::getA2dpOutput() | ||
3030 | { | ||
3031 | if (!mHasA2dp) | ||
3032 | return 0; | ||
3033 | |||
3034 | for (size_t i = 0; i < mOutputs.size(); i++) { | ||
3035 | AudioOutputDescriptor *outputDesc = mOutputs.valueAt(i); | ||
3036 | if (!outputDesc->isDuplicated() && outputDesc->device() & AUDIO_DEVICE_OUT_ALL_A2DP) { | ||
3037 | return mOutputs.keyAt(i); | ||
3038 | } | ||
3039 | } | ||
3040 | |||
3041 | return 0; | ||
3042 | } | ||
3043 | |||
3044 | uint32_t AudioPolicyManager::getMaxEffectsCpuLoad() | ||
3045 | { | ||
3046 | return MAX_EFFECTS_CPU_LOAD; | ||
3047 | } | ||
3048 | |||
3049 | uint32_t AudioPolicyManager::getMaxEffectsMemory() | ||
3050 | { | ||
3051 | return MAX_EFFECTS_MEMORY; | ||
3052 | } | ||
3053 | |||
3054 | IOProfile *AudioPolicyManager::getInputProfile(audio_devices_t device, | ||
3055 | uint32_t samplingRate, | ||
3056 | uint32_t format, | ||
3057 | uint32_t channelMask) | ||
3058 | { | ||
3059 | // Choose an input profile based on the requested capture parameters: | ||
3060 | // select the first available profile supporting all requested parameters | ||
3061 | for (size_t i = 0; i < mHwModules.size(); i++) { | ||
3062 | if (mHwModules[i]->mHandle == 0) { | ||
3063 | continue; | ||
3064 | } | ||
3065 | for (size_t j = 0; j < mHwModules[i]->mInputProfiles.size(); j++) { | ||
3066 | IOProfile *profile = mHwModules[i]->mInputProfiles[j]; | ||
3067 | if (profile->isCompatibleProfile(device, samplingRate, | ||
3068 | format, channelMask, | ||
3069 | (audio_output_flags_t)0)) { | ||
3070 | return profile; | ||
3071 | } | ||
3072 | } | ||
3073 | } | ||
3074 | return NULL; | ||
3075 | } | ||
3076 | |||
3077 | audio_devices_t AudioPolicyManager::getDeviceForInputSource(int inputSource) | ||
3078 | { | ||
3079 | uint32_t device = AUDIO_DEVICE_NONE; | ||
3080 | |||
3081 | switch (inputSource) { | ||
3082 | case AUDIO_SOURCE_VOICE_UPLINK: | ||
3083 | if (mAvailableInputDevices & AUDIO_DEVICE_IN_VOICE_CALL) { | ||
3084 | device = AUDIO_DEVICE_IN_VOICE_CALL; | ||
3085 | break; | ||
3086 | } | ||
3087 | // FALL THROUGH | ||
3088 | |||
3089 | case AUDIO_SOURCE_DEFAULT: | ||
3090 | case AUDIO_SOURCE_MIC: | ||
3091 | case AUDIO_SOURCE_VOICE_RECOGNITION: | ||
3092 | case AUDIO_SOURCE_VOICE_COMMUNICATION: | ||
3093 | if (mForceUse[AudioSystem::FOR_RECORD] == AudioSystem::FORCE_BT_SCO && | ||
3094 | mAvailableInputDevices & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) { | ||
3095 | device = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET; | ||
3096 | } else if (mAvailableInputDevices & AUDIO_DEVICE_IN_WIRED_HEADSET) { | ||
3097 | device = AUDIO_DEVICE_IN_WIRED_HEADSET; | ||
3098 | } else if (mAvailableInputDevices & AUDIO_DEVICE_IN_BUILTIN_MIC) { | ||
3099 | device = AUDIO_DEVICE_IN_BUILTIN_MIC; | ||
3100 | } | ||
3101 | break; | ||
3102 | case AUDIO_SOURCE_CAMCORDER: | ||
3103 | if (mAvailableInputDevices & AUDIO_DEVICE_IN_BACK_MIC) { | ||
3104 | device = AUDIO_DEVICE_IN_BACK_MIC; | ||
3105 | } else if (mAvailableInputDevices & AUDIO_DEVICE_IN_BUILTIN_MIC) { | ||
3106 | device = AUDIO_DEVICE_IN_BUILTIN_MIC; | ||
3107 | } | ||
3108 | break; | ||
3109 | case AUDIO_SOURCE_VOICE_DOWNLINK: | ||
3110 | case AUDIO_SOURCE_VOICE_CALL: | ||
3111 | if (mAvailableInputDevices & AUDIO_DEVICE_IN_VOICE_CALL) { | ||
3112 | device = AUDIO_DEVICE_IN_VOICE_CALL; | ||
3113 | } | ||
3114 | break; | ||
3115 | case AUDIO_SOURCE_REMOTE_SUBMIX: | ||
3116 | if (mAvailableInputDevices & AUDIO_DEVICE_IN_REMOTE_SUBMIX) { | ||
3117 | device = AUDIO_DEVICE_IN_REMOTE_SUBMIX; | ||
3118 | } | ||
3119 | break; | ||
3120 | default: | ||
3121 | ALOGW("getDeviceForInputSource() invalid input source %d", inputSource); | ||
3122 | break; | ||
3123 | } | ||
3124 | |||
3125 | ALOGV("getDeviceForInputSource()input source %d, device %08x", inputSource, device); | ||
3126 | return device; | ||
3127 | } | ||
3128 | |||
3129 | bool AudioPolicyManager::isVirtualInputDevice(audio_devices_t device) | ||
3130 | { | ||
3131 | if ((device & AUDIO_DEVICE_BIT_IN) != 0) { | ||
3132 | device &= ~AUDIO_DEVICE_BIT_IN; | ||
3133 | if ((popcount(device) == 1) && ((device & ~APM_AUDIO_IN_DEVICE_VIRTUAL_ALL) == 0)) | ||
3134 | return true; | ||
3135 | } | ||
3136 | return false; | ||
3137 | } | ||
3138 | |||
3139 | audio_io_handle_t AudioPolicyManager::getActiveInput(bool ignoreVirtualInputs) | ||
3140 | { | ||
3141 | for (size_t i = 0; i < mInputs.size(); i++) { | ||
3142 | const AudioInputDescriptor *inputDesc = mInputs.valueAt(i); | ||
3143 | if ((inputDesc->mUsers > 0) && | ||
3144 | (!ignoreVirtualInputs || !isVirtualInputDevice(inputDesc->mDevice))) { | ||
3145 | return mInputs.keyAt(i); | ||
3146 | } | ||
3147 | } | ||
3148 | return 0; | ||
3149 | } | ||
3150 | |||
3151 | // --- AudioOutputDescriptor class implementation | ||
3152 | |||
3153 | AudioPolicyManager::AudioOutputDescriptor::AudioOutputDescriptor(const IOProfile *profile) | ||
3154 | : mId(0), mSamplingRate(0), mFormat((audio_format_t)0), | ||
3155 | mChannelMask((audio_channel_mask_t)0), mLatency(0), | ||
3156 | mFlags((audio_output_flags_t)0), mDevice(AUDIO_DEVICE_NONE), | ||
3157 | mUsers(0), mProfile(profile) | ||
3158 | { | ||
3159 | // clear usage count for all stream types | ||
3160 | for (int i = 0; i < AudioSystem::NUM_STREAM_TYPES; i++) { | ||
3161 | mRefCount[i] = 0; | ||
3162 | mCurVolume[i] = -1.0; | ||
3163 | mMuteCount[i] = 0; | ||
3164 | mStopTime[i] = 0; | ||
3165 | } | ||
3166 | mDupOutputs.clear(); | ||
3167 | if (profile != NULL) { | ||
3168 | mSamplingRate = profile->mSamplingRates[0]; | ||
3169 | mFormat = profile->mFormats[0]; | ||
3170 | mChannelMask = profile->mChannelMasks[0]; | ||
3171 | mFlags = profile->mFlags; | ||
3172 | } | ||
3173 | } | ||
3174 | |||
3175 | audio_devices_t AudioPolicyManager::AudioOutputDescriptor::device() const | ||
3176 | { | ||
3177 | audio_devices_t devices = AUDIO_DEVICE_NONE; | ||
3178 | |||
3179 | if (isDuplicated()) { | ||
3180 | // All devices supported for each individual duplicated output | ||
3181 | for (size_t i = 0; i < mDupOutputs.size(); i++) { | ||
3182 | AudioOutputDescriptor *dupDesc = mDupOutputs.itemAt(i); | ||
3183 | if (dupDesc) | ||
3184 | devices |= dupDesc->device(); | ||
3185 | } | ||
3186 | } else { | ||
3187 | devices = mDevice; | ||
3188 | } | ||
3189 | |||
3190 | return devices; | ||
3191 | } | ||
3192 | |||
3193 | uint32_t AudioPolicyManager::AudioOutputDescriptor::latency() | ||
3194 | { | ||
3195 | uint32_t latency = 0; | ||
3196 | |||
3197 | if (isDuplicated()) { | ||
3198 | // Highest latency in all duplicated outputs | ||
3199 | for (size_t i = 0; i < mDupOutputs.size(); i++) { | ||
3200 | AudioOutputDescriptor *dupDesc = mDupOutputs.itemAt(i); | ||
3201 | if (dupDesc) { | ||
3202 | latency = (latency > dupDesc->mLatency) ? | ||
3203 | latency : dupDesc->mLatency; | ||
3204 | } | ||
3205 | } | ||
3206 | } else { | ||
3207 | latency = mLatency; | ||
3208 | } | ||
3209 | |||
3210 | return latency; | ||
3211 | } | ||
3212 | |||
3213 | void AudioPolicyManager::AudioOutputDescriptor::changeRefCount(AudioSystem::stream_type stream, | ||
3214 | int delta) | ||
3215 | { | ||
3216 | // Forward usage count change to attached outputs | ||
3217 | if (isDuplicated()) { | ||