1 /*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #define LOG_TAG "APM::AudioOutputDescriptor"
18 //#define LOG_NDEBUG 0
19
20 #include <AudioPolicyInterface.h>
21 #include "AudioOutputDescriptor.h"
22 #include "IOProfile.h"
23 #include "AudioGain.h"
24 #include "Volume.h"
25 #include "HwModule.h"
26 #include <media/AudioPolicy.h>
27
28 // A device mask for all audio output devices that are considered "remote" when evaluating
29 // active output devices in isStreamActiveRemotely()
30 #define APM_AUDIO_OUT_DEVICE_REMOTE_ALL AUDIO_DEVICE_OUT_REMOTE_SUBMIX
31
32 namespace android {
33
AudioOutputDescriptor(const sp<AudioPort> & port,AudioPolicyClientInterface * clientInterface)34 AudioOutputDescriptor::AudioOutputDescriptor(const sp<AudioPort>& port,
35 AudioPolicyClientInterface *clientInterface)
36 : mPort(port), mDevice(AUDIO_DEVICE_NONE),
37 mPatchHandle(0), mClientInterface(clientInterface), mId(0)
38 {
39 // clear usage count for all stream types
40 for (int i = 0; i < AUDIO_STREAM_CNT; i++) {
41 mRefCount[i] = 0;
42 mCurVolume[i] = -1.0;
43 mMuteCount[i] = 0;
44 mStopTime[i] = 0;
45 }
46 for (int i = 0; i < NUM_STRATEGIES; i++) {
47 mStrategyMutedByDevice[i] = false;
48 }
49 if (port != NULL) {
50 mSamplingRate = port->pickSamplingRate();
51 mFormat = port->pickFormat();
52 mChannelMask = port->pickChannelMask();
53 if (port->mGains.size() > 0) {
54 port->mGains[0]->getDefaultConfig(&mGain);
55 }
56 }
57 }
58
getModuleHandle() const59 audio_module_handle_t AudioOutputDescriptor::getModuleHandle() const
60 {
61 return mPort->getModuleHandle();
62 }
63
getId() const64 audio_port_handle_t AudioOutputDescriptor::getId() const
65 {
66 return mId;
67 }
68
device() const69 audio_devices_t AudioOutputDescriptor::device() const
70 {
71 return mDevice;
72 }
73
supportedDevices()74 audio_devices_t AudioOutputDescriptor::supportedDevices()
75 {
76 return mDevice;
77 }
78
sharesHwModuleWith(const sp<AudioOutputDescriptor> outputDesc)79 bool AudioOutputDescriptor::sharesHwModuleWith(
80 const sp<AudioOutputDescriptor> outputDesc)
81 {
82 if (outputDesc->isDuplicated()) {
83 return sharesHwModuleWith(outputDesc->subOutput1()) ||
84 sharesHwModuleWith(outputDesc->subOutput2());
85 } else {
86 return (getModuleHandle() == outputDesc->getModuleHandle());
87 }
88 }
89
changeRefCount(audio_stream_type_t stream,int delta)90 void AudioOutputDescriptor::changeRefCount(audio_stream_type_t stream,
91 int delta)
92 {
93 if ((delta + (int)mRefCount[stream]) < 0) {
94 ALOGW("changeRefCount() invalid delta %d for stream %d, refCount %d",
95 delta, stream, mRefCount[stream]);
96 mRefCount[stream] = 0;
97 return;
98 }
99 mRefCount[stream] += delta;
100 ALOGV("changeRefCount() stream %d, count %d", stream, mRefCount[stream]);
101 }
102
isActive(uint32_t inPastMs) const103 bool AudioOutputDescriptor::isActive(uint32_t inPastMs) const
104 {
105 nsecs_t sysTime = 0;
106 if (inPastMs != 0) {
107 sysTime = systemTime();
108 }
109 for (int i = 0; i < (int)AUDIO_STREAM_CNT; i++) {
110 if (i == AUDIO_STREAM_PATCH) {
111 continue;
112 }
113 if (isStreamActive((audio_stream_type_t)i, inPastMs, sysTime)) {
114 return true;
115 }
116 }
117 return false;
118 }
119
isStreamActive(audio_stream_type_t stream,uint32_t inPastMs,nsecs_t sysTime) const120 bool AudioOutputDescriptor::isStreamActive(audio_stream_type_t stream,
121 uint32_t inPastMs,
122 nsecs_t sysTime) const
123 {
124 if (mRefCount[stream] != 0) {
125 return true;
126 }
127 if (inPastMs == 0) {
128 return false;
129 }
130 if (sysTime == 0) {
131 sysTime = systemTime();
132 }
133 if (ns2ms(sysTime - mStopTime[stream]) < inPastMs) {
134 return true;
135 }
136 return false;
137 }
138
139
isFixedVolume(audio_devices_t device __unused)140 bool AudioOutputDescriptor::isFixedVolume(audio_devices_t device __unused)
141 {
142 return false;
143 }
144
setVolume(float volume,audio_stream_type_t stream,audio_devices_t device __unused,uint32_t delayMs,bool force)145 bool AudioOutputDescriptor::setVolume(float volume,
146 audio_stream_type_t stream,
147 audio_devices_t device __unused,
148 uint32_t delayMs,
149 bool force)
150 {
151 // We actually change the volume if:
152 // - the float value returned by computeVolume() changed
153 // - the force flag is set
154 if (volume != mCurVolume[stream] || force) {
155 ALOGV("setVolume() for stream %d, volume %f, delay %d", stream, volume, delayMs);
156 mCurVolume[stream] = volume;
157 return true;
158 }
159 return false;
160 }
161
toAudioPortConfig(struct audio_port_config * dstConfig,const struct audio_port_config * srcConfig) const162 void AudioOutputDescriptor::toAudioPortConfig(
163 struct audio_port_config *dstConfig,
164 const struct audio_port_config *srcConfig) const
165 {
166 dstConfig->config_mask = AUDIO_PORT_CONFIG_SAMPLE_RATE|AUDIO_PORT_CONFIG_CHANNEL_MASK|
167 AUDIO_PORT_CONFIG_FORMAT|AUDIO_PORT_CONFIG_GAIN;
168 if (srcConfig != NULL) {
169 dstConfig->config_mask |= srcConfig->config_mask;
170 }
171 AudioPortConfig::toAudioPortConfig(dstConfig, srcConfig);
172
173 dstConfig->id = mId;
174 dstConfig->role = AUDIO_PORT_ROLE_SOURCE;
175 dstConfig->type = AUDIO_PORT_TYPE_MIX;
176 dstConfig->ext.mix.hw_module = getModuleHandle();
177 dstConfig->ext.mix.usecase.stream = AUDIO_STREAM_DEFAULT;
178 }
179
toAudioPort(struct audio_port * port) const180 void AudioOutputDescriptor::toAudioPort(
181 struct audio_port *port) const
182 {
183 mPort->toAudioPort(port);
184 port->id = mId;
185 port->ext.mix.hw_module = getModuleHandle();
186 }
187
dump(int fd)188 status_t AudioOutputDescriptor::dump(int fd)
189 {
190 const size_t SIZE = 256;
191 char buffer[SIZE];
192 String8 result;
193
194 snprintf(buffer, SIZE, " ID: %d\n", mId);
195 result.append(buffer);
196 snprintf(buffer, SIZE, " Sampling rate: %d\n", mSamplingRate);
197 result.append(buffer);
198 snprintf(buffer, SIZE, " Format: %08x\n", mFormat);
199 result.append(buffer);
200 snprintf(buffer, SIZE, " Channels: %08x\n", mChannelMask);
201 result.append(buffer);
202 snprintf(buffer, SIZE, " Devices %08x\n", device());
203 result.append(buffer);
204 snprintf(buffer, SIZE, " Stream volume refCount muteCount\n");
205 result.append(buffer);
206 for (int i = 0; i < (int)AUDIO_STREAM_CNT; i++) {
207 snprintf(buffer, SIZE, " %02d %.03f %02d %02d\n",
208 i, mCurVolume[i], mRefCount[i], mMuteCount[i]);
209 result.append(buffer);
210 }
211 write(fd, result.string(), result.size());
212
213 return NO_ERROR;
214 }
215
log(const char * indent)216 void AudioOutputDescriptor::log(const char* indent)
217 {
218 ALOGI("%sID: %d,0x%X, [rt:%d fmt:0x%X ch:0x%X]",
219 indent, mId, mId, mSamplingRate, mFormat, mChannelMask);
220 }
221
222 // SwAudioOutputDescriptor implementation
SwAudioOutputDescriptor(const sp<IOProfile> & profile,AudioPolicyClientInterface * clientInterface)223 SwAudioOutputDescriptor::SwAudioOutputDescriptor(
224 const sp<IOProfile>& profile, AudioPolicyClientInterface *clientInterface)
225 : AudioOutputDescriptor(profile, clientInterface),
226 mProfile(profile), mIoHandle(0), mLatency(0),
227 mFlags((audio_output_flags_t)0), mPolicyMix(NULL),
228 mOutput1(0), mOutput2(0), mDirectOpenCount(0), mGlobalRefCount(0)
229 {
230 if (profile != NULL) {
231 mFlags = (audio_output_flags_t)profile->mFlags;
232 }
233 }
234
setIoHandle(audio_io_handle_t ioHandle)235 void SwAudioOutputDescriptor::setIoHandle(audio_io_handle_t ioHandle)
236 {
237 mId = AudioPort::getNextUniqueId();
238 mIoHandle = ioHandle;
239 }
240
241
dump(int fd)242 status_t SwAudioOutputDescriptor::dump(int fd)
243 {
244 const size_t SIZE = 256;
245 char buffer[SIZE];
246 String8 result;
247
248 snprintf(buffer, SIZE, " Latency: %d\n", mLatency);
249 result.append(buffer);
250 snprintf(buffer, SIZE, " Flags %08x\n", mFlags);
251 result.append(buffer);
252 write(fd, result.string(), result.size());
253
254 AudioOutputDescriptor::dump(fd);
255
256 return NO_ERROR;
257 }
258
device() const259 audio_devices_t SwAudioOutputDescriptor::device() const
260 {
261 if (isDuplicated()) {
262 return (audio_devices_t)(mOutput1->mDevice | mOutput2->mDevice);
263 } else {
264 return mDevice;
265 }
266 }
267
sharesHwModuleWith(const sp<AudioOutputDescriptor> outputDesc)268 bool SwAudioOutputDescriptor::sharesHwModuleWith(
269 const sp<AudioOutputDescriptor> outputDesc)
270 {
271 if (isDuplicated()) {
272 return mOutput1->sharesHwModuleWith(outputDesc) || mOutput2->sharesHwModuleWith(outputDesc);
273 } else if (outputDesc->isDuplicated()){
274 return sharesHwModuleWith(outputDesc->subOutput1()) ||
275 sharesHwModuleWith(outputDesc->subOutput2());
276 } else {
277 return AudioOutputDescriptor::sharesHwModuleWith(outputDesc);
278 }
279 }
280
supportedDevices()281 audio_devices_t SwAudioOutputDescriptor::supportedDevices()
282 {
283 if (isDuplicated()) {
284 return (audio_devices_t)(mOutput1->supportedDevices() | mOutput2->supportedDevices());
285 } else {
286 return mProfile->mSupportedDevices.types() ;
287 }
288 }
289
latency()290 uint32_t SwAudioOutputDescriptor::latency()
291 {
292 if (isDuplicated()) {
293 return (mOutput1->mLatency > mOutput2->mLatency) ? mOutput1->mLatency : mOutput2->mLatency;
294 } else {
295 return mLatency;
296 }
297 }
298
changeRefCount(audio_stream_type_t stream,int delta)299 void SwAudioOutputDescriptor::changeRefCount(audio_stream_type_t stream,
300 int delta)
301 {
302 // forward usage count change to attached outputs
303 if (isDuplicated()) {
304 mOutput1->changeRefCount(stream, delta);
305 mOutput2->changeRefCount(stream, delta);
306 }
307 AudioOutputDescriptor::changeRefCount(stream, delta);
308
309 // handle stream-independent ref count
310 uint32_t oldGlobalRefCount = mGlobalRefCount;
311 if ((delta + (int)mGlobalRefCount) < 0) {
312 ALOGW("changeRefCount() invalid delta %d globalRefCount %d", delta, mGlobalRefCount);
313 mGlobalRefCount = 0;
314 } else {
315 mGlobalRefCount += delta;
316 }
317 if ((oldGlobalRefCount == 0) && (mGlobalRefCount > 0)) {
318 if ((mPolicyMix != NULL) && ((mPolicyMix->mCbFlags & AudioMix::kCbFlagNotifyActivity) != 0))
319 {
320 mClientInterface->onDynamicPolicyMixStateUpdate(mPolicyMix->mRegistrationId,
321 MIX_STATE_MIXING);
322 }
323
324 } else if ((oldGlobalRefCount > 0) && (mGlobalRefCount == 0)) {
325 if ((mPolicyMix != NULL) && ((mPolicyMix->mCbFlags & AudioMix::kCbFlagNotifyActivity) != 0))
326 {
327 mClientInterface->onDynamicPolicyMixStateUpdate(mPolicyMix->mRegistrationId,
328 MIX_STATE_IDLE);
329 }
330 }
331 }
332
333
isFixedVolume(audio_devices_t device)334 bool SwAudioOutputDescriptor::isFixedVolume(audio_devices_t device)
335 {
336 // unit gain if rerouting to external policy
337 if (device == AUDIO_DEVICE_OUT_REMOTE_SUBMIX) {
338 if (mPolicyMix != NULL) {
339 ALOGV("max gain when rerouting for output=%d", mIoHandle);
340 return true;
341 }
342 }
343 return false;
344 }
345
toAudioPortConfig(struct audio_port_config * dstConfig,const struct audio_port_config * srcConfig) const346 void SwAudioOutputDescriptor::toAudioPortConfig(
347 struct audio_port_config *dstConfig,
348 const struct audio_port_config *srcConfig) const
349 {
350
351 ALOG_ASSERT(!isDuplicated(), "toAudioPortConfig() called on duplicated output %d", mIoHandle);
352 AudioOutputDescriptor::toAudioPortConfig(dstConfig, srcConfig);
353
354 dstConfig->ext.mix.handle = mIoHandle;
355 }
356
toAudioPort(struct audio_port * port) const357 void SwAudioOutputDescriptor::toAudioPort(
358 struct audio_port *port) const
359 {
360 ALOG_ASSERT(!isDuplicated(), "toAudioPort() called on duplicated output %d", mIoHandle);
361
362 AudioOutputDescriptor::toAudioPort(port);
363
364 toAudioPortConfig(&port->active_config);
365 port->ext.mix.handle = mIoHandle;
366 port->ext.mix.latency_class =
367 mFlags & AUDIO_OUTPUT_FLAG_FAST ? AUDIO_LATENCY_LOW : AUDIO_LATENCY_NORMAL;
368 }
369
setVolume(float volume,audio_stream_type_t stream,audio_devices_t device,uint32_t delayMs,bool force)370 bool SwAudioOutputDescriptor::setVolume(float volume,
371 audio_stream_type_t stream,
372 audio_devices_t device,
373 uint32_t delayMs,
374 bool force)
375 {
376 bool changed = AudioOutputDescriptor::setVolume(volume, stream, device, delayMs, force);
377
378 if (changed) {
379 // Force VOICE_CALL to track BLUETOOTH_SCO stream volume when bluetooth audio is
380 // enabled
381 float volume = Volume::DbToAmpl(mCurVolume[stream]);
382 if (stream == AUDIO_STREAM_BLUETOOTH_SCO) {
383 mClientInterface->setStreamVolume(
384 AUDIO_STREAM_VOICE_CALL, volume, mIoHandle, delayMs);
385 }
386 mClientInterface->setStreamVolume(stream, volume, mIoHandle, delayMs);
387 }
388 return changed;
389 }
390
391 // SwAudioOutputCollection implementation
392
isStreamActive(audio_stream_type_t stream,uint32_t inPastMs) const393 bool SwAudioOutputCollection::isStreamActive(audio_stream_type_t stream, uint32_t inPastMs) const
394 {
395 nsecs_t sysTime = systemTime();
396 for (size_t i = 0; i < this->size(); i++) {
397 const sp<SwAudioOutputDescriptor> outputDesc = this->valueAt(i);
398 if (outputDesc->isStreamActive(stream, inPastMs, sysTime)) {
399 return true;
400 }
401 }
402 return false;
403 }
404
isStreamActiveRemotely(audio_stream_type_t stream,uint32_t inPastMs) const405 bool SwAudioOutputCollection::isStreamActiveRemotely(audio_stream_type_t stream,
406 uint32_t inPastMs) const
407 {
408 nsecs_t sysTime = systemTime();
409 for (size_t i = 0; i < size(); i++) {
410 const sp<SwAudioOutputDescriptor> outputDesc = valueAt(i);
411 if (((outputDesc->device() & APM_AUDIO_OUT_DEVICE_REMOTE_ALL) != 0) &&
412 outputDesc->isStreamActive(stream, inPastMs, sysTime)) {
413 // do not consider re routing (when the output is going to a dynamic policy)
414 // as "remote playback"
415 if (outputDesc->mPolicyMix == NULL) {
416 return true;
417 }
418 }
419 }
420 return false;
421 }
422
getA2dpOutput() const423 audio_io_handle_t SwAudioOutputCollection::getA2dpOutput() const
424 {
425 for (size_t i = 0; i < size(); i++) {
426 sp<SwAudioOutputDescriptor> outputDesc = valueAt(i);
427 if (!outputDesc->isDuplicated() && outputDesc->device() & AUDIO_DEVICE_OUT_ALL_A2DP) {
428 return this->keyAt(i);
429 }
430 }
431 return 0;
432 }
433
getPrimaryOutput() const434 sp<SwAudioOutputDescriptor> SwAudioOutputCollection::getPrimaryOutput() const
435 {
436 for (size_t i = 0; i < size(); i++) {
437 const sp<SwAudioOutputDescriptor> outputDesc = valueAt(i);
438 if (outputDesc->mFlags & AUDIO_OUTPUT_FLAG_PRIMARY) {
439 return outputDesc;
440 }
441 }
442 return NULL;
443 }
444
getOutputFromId(audio_port_handle_t id) const445 sp<SwAudioOutputDescriptor> SwAudioOutputCollection::getOutputFromId(audio_port_handle_t id) const
446 {
447 sp<SwAudioOutputDescriptor> outputDesc = NULL;
448 for (size_t i = 0; i < size(); i++) {
449 outputDesc = valueAt(i);
450 if (outputDesc->getId() == id) {
451 break;
452 }
453 }
454 return outputDesc;
455 }
456
isAnyOutputActive(audio_stream_type_t streamToIgnore) const457 bool SwAudioOutputCollection::isAnyOutputActive(audio_stream_type_t streamToIgnore) const
458 {
459 for (size_t s = 0 ; s < AUDIO_STREAM_CNT ; s++) {
460 if (s == (size_t) streamToIgnore) {
461 continue;
462 }
463 for (size_t i = 0; i < size(); i++) {
464 const sp<SwAudioOutputDescriptor> outputDesc = valueAt(i);
465 if (outputDesc->mRefCount[s] != 0) {
466 return true;
467 }
468 }
469 }
470 return false;
471 }
472
getSupportedDevices(audio_io_handle_t handle) const473 audio_devices_t SwAudioOutputCollection::getSupportedDevices(audio_io_handle_t handle) const
474 {
475 sp<SwAudioOutputDescriptor> outputDesc = valueFor(handle);
476 audio_devices_t devices = outputDesc->mProfile->mSupportedDevices.types();
477 return devices;
478 }
479
480
dump(int fd) const481 status_t SwAudioOutputCollection::dump(int fd) const
482 {
483 const size_t SIZE = 256;
484 char buffer[SIZE];
485
486 snprintf(buffer, SIZE, "\nOutputs dump:\n");
487 write(fd, buffer, strlen(buffer));
488 for (size_t i = 0; i < size(); i++) {
489 snprintf(buffer, SIZE, "- Output %d dump:\n", keyAt(i));
490 write(fd, buffer, strlen(buffer));
491 valueAt(i)->dump(fd);
492 }
493
494 return NO_ERROR;
495 }
496
497 }; //namespace android
498