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 32namespace android { 33 34AudioOutputDescriptor::AudioOutputDescriptor(const sp<AudioPort>& port, 35 AudioPolicyClientInterface *clientInterface) 36 : mPort(port), mDevice(AUDIO_DEVICE_NONE), 37 mClientInterface(clientInterface), mPatchHandle(AUDIO_PATCH_HANDLE_NONE), 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 port->pickAudioProfile(mSamplingRate, mChannelMask, mFormat); 51 if (port->mGains.size() > 0) { 52 port->mGains[0]->getDefaultConfig(&mGain); 53 } 54 } 55} 56 57audio_module_handle_t AudioOutputDescriptor::getModuleHandle() const 58{ 59 return mPort->getModuleHandle(); 60} 61 62audio_port_handle_t AudioOutputDescriptor::getId() const 63{ 64 return mId; 65} 66 67audio_devices_t AudioOutputDescriptor::device() const 68{ 69 return mDevice; 70} 71 72audio_devices_t AudioOutputDescriptor::supportedDevices() 73{ 74 return mDevice; 75} 76 77bool AudioOutputDescriptor::sharesHwModuleWith( 78 const sp<AudioOutputDescriptor> outputDesc) 79{ 80 if (outputDesc->isDuplicated()) { 81 return sharesHwModuleWith(outputDesc->subOutput1()) || 82 sharesHwModuleWith(outputDesc->subOutput2()); 83 } else { 84 return (getModuleHandle() == outputDesc->getModuleHandle()); 85 } 86} 87 88void AudioOutputDescriptor::changeRefCount(audio_stream_type_t stream, 89 int delta) 90{ 91 if ((delta + (int)mRefCount[stream]) < 0) { 92 ALOGW("changeRefCount() invalid delta %d for stream %d, refCount %d", 93 delta, stream, mRefCount[stream]); 94 mRefCount[stream] = 0; 95 return; 96 } 97 mRefCount[stream] += delta; 98 ALOGV("changeRefCount() stream %d, count %d", stream, mRefCount[stream]); 99} 100 101bool AudioOutputDescriptor::isActive(uint32_t inPastMs) const 102{ 103 nsecs_t sysTime = 0; 104 if (inPastMs != 0) { 105 sysTime = systemTime(); 106 } 107 for (int i = 0; i < (int)AUDIO_STREAM_CNT; i++) { 108 if (i == AUDIO_STREAM_PATCH) { 109 continue; 110 } 111 if (isStreamActive((audio_stream_type_t)i, inPastMs, sysTime)) { 112 return true; 113 } 114 } 115 return false; 116} 117 118bool AudioOutputDescriptor::isStreamActive(audio_stream_type_t stream, 119 uint32_t inPastMs, 120 nsecs_t sysTime) const 121{ 122 if (mRefCount[stream] != 0) { 123 return true; 124 } 125 if (inPastMs == 0) { 126 return false; 127 } 128 if (sysTime == 0) { 129 sysTime = systemTime(); 130 } 131 if (ns2ms(sysTime - mStopTime[stream]) < inPastMs) { 132 return true; 133 } 134 return false; 135} 136 137 138bool AudioOutputDescriptor::isFixedVolume(audio_devices_t device __unused) 139{ 140 return false; 141} 142 143bool AudioOutputDescriptor::setVolume(float volume, 144 audio_stream_type_t stream, 145 audio_devices_t device __unused, 146 uint32_t delayMs, 147 bool force) 148{ 149 // We actually change the volume if: 150 // - the float value returned by computeVolume() changed 151 // - the force flag is set 152 if (volume != mCurVolume[stream] || force) { 153 ALOGV("setVolume() for stream %d, volume %f, delay %d", stream, volume, delayMs); 154 mCurVolume[stream] = volume; 155 return true; 156 } 157 return false; 158} 159 160void AudioOutputDescriptor::toAudioPortConfig( 161 struct audio_port_config *dstConfig, 162 const struct audio_port_config *srcConfig) const 163{ 164 dstConfig->config_mask = AUDIO_PORT_CONFIG_SAMPLE_RATE|AUDIO_PORT_CONFIG_CHANNEL_MASK| 165 AUDIO_PORT_CONFIG_FORMAT|AUDIO_PORT_CONFIG_GAIN; 166 if (srcConfig != NULL) { 167 dstConfig->config_mask |= srcConfig->config_mask; 168 } 169 AudioPortConfig::toAudioPortConfig(dstConfig, srcConfig); 170 171 dstConfig->id = mId; 172 dstConfig->role = AUDIO_PORT_ROLE_SOURCE; 173 dstConfig->type = AUDIO_PORT_TYPE_MIX; 174 dstConfig->ext.mix.hw_module = getModuleHandle(); 175 dstConfig->ext.mix.usecase.stream = AUDIO_STREAM_DEFAULT; 176} 177 178void AudioOutputDescriptor::toAudioPort( 179 struct audio_port *port) const 180{ 181 mPort->toAudioPort(port); 182 port->id = mId; 183 port->ext.mix.hw_module = getModuleHandle(); 184} 185 186status_t AudioOutputDescriptor::dump(int fd) 187{ 188 const size_t SIZE = 256; 189 char buffer[SIZE]; 190 String8 result; 191 192 snprintf(buffer, SIZE, " ID: %d\n", mId); 193 result.append(buffer); 194 snprintf(buffer, SIZE, " Sampling rate: %d\n", mSamplingRate); 195 result.append(buffer); 196 snprintf(buffer, SIZE, " Format: %08x\n", mFormat); 197 result.append(buffer); 198 snprintf(buffer, SIZE, " Channels: %08x\n", mChannelMask); 199 result.append(buffer); 200 snprintf(buffer, SIZE, " Devices %08x\n", device()); 201 result.append(buffer); 202 snprintf(buffer, SIZE, " Stream volume refCount muteCount\n"); 203 result.append(buffer); 204 for (int i = 0; i < (int)AUDIO_STREAM_CNT; i++) { 205 snprintf(buffer, SIZE, " %02d %.03f %02d %02d\n", 206 i, mCurVolume[i], mRefCount[i], mMuteCount[i]); 207 result.append(buffer); 208 } 209 write(fd, result.string(), result.size()); 210 211 return NO_ERROR; 212} 213 214void AudioOutputDescriptor::log(const char* indent) 215{ 216 ALOGI("%sID: %d,0x%X, [rt:%d fmt:0x%X ch:0x%X]", 217 indent, mId, mId, mSamplingRate, mFormat, mChannelMask); 218} 219 220// SwAudioOutputDescriptor implementation 221SwAudioOutputDescriptor::SwAudioOutputDescriptor(const sp<IOProfile>& profile, 222 AudioPolicyClientInterface *clientInterface) 223 : AudioOutputDescriptor(profile, clientInterface), 224 mProfile(profile), mIoHandle(0), mLatency(0), 225 mFlags((audio_output_flags_t)0), mPolicyMix(NULL), 226 mOutput1(0), mOutput2(0), mDirectOpenCount(0), mGlobalRefCount(0) 227{ 228 if (profile != NULL) { 229 mFlags = (audio_output_flags_t)profile->getFlags(); 230 } 231} 232 233void SwAudioOutputDescriptor::setIoHandle(audio_io_handle_t ioHandle) 234{ 235 mId = AudioPort::getNextUniqueId(); 236 mIoHandle = ioHandle; 237} 238 239 240status_t SwAudioOutputDescriptor::dump(int fd) 241{ 242 const size_t SIZE = 256; 243 char buffer[SIZE]; 244 String8 result; 245 246 snprintf(buffer, SIZE, " Latency: %d\n", mLatency); 247 result.append(buffer); 248 snprintf(buffer, SIZE, " Flags %08x\n", mFlags); 249 result.append(buffer); 250 write(fd, result.string(), result.size()); 251 252 AudioOutputDescriptor::dump(fd); 253 254 return NO_ERROR; 255} 256 257audio_devices_t SwAudioOutputDescriptor::device() const 258{ 259 if (isDuplicated()) { 260 return (audio_devices_t)(mOutput1->mDevice | mOutput2->mDevice); 261 } else { 262 return mDevice; 263 } 264} 265 266bool SwAudioOutputDescriptor::sharesHwModuleWith( 267 const sp<AudioOutputDescriptor> outputDesc) 268{ 269 if (isDuplicated()) { 270 return mOutput1->sharesHwModuleWith(outputDesc) || mOutput2->sharesHwModuleWith(outputDesc); 271 } else if (outputDesc->isDuplicated()){ 272 return sharesHwModuleWith(outputDesc->subOutput1()) || 273 sharesHwModuleWith(outputDesc->subOutput2()); 274 } else { 275 return AudioOutputDescriptor::sharesHwModuleWith(outputDesc); 276 } 277} 278 279audio_devices_t SwAudioOutputDescriptor::supportedDevices() 280{ 281 if (isDuplicated()) { 282 return (audio_devices_t)(mOutput1->supportedDevices() | mOutput2->supportedDevices()); 283 } else { 284 return mProfile->getSupportedDevicesType(); 285 } 286} 287 288uint32_t SwAudioOutputDescriptor::latency() 289{ 290 if (isDuplicated()) { 291 return (mOutput1->mLatency > mOutput2->mLatency) ? mOutput1->mLatency : mOutput2->mLatency; 292 } else { 293 return mLatency; 294 } 295} 296 297void SwAudioOutputDescriptor::changeRefCount(audio_stream_type_t stream, 298 int delta) 299{ 300 // forward usage count change to attached outputs 301 if (isDuplicated()) { 302 mOutput1->changeRefCount(stream, delta); 303 mOutput2->changeRefCount(stream, delta); 304 } 305 AudioOutputDescriptor::changeRefCount(stream, delta); 306 307 // handle stream-independent ref count 308 uint32_t oldGlobalRefCount = mGlobalRefCount; 309 if ((delta + (int)mGlobalRefCount) < 0) { 310 ALOGW("changeRefCount() invalid delta %d globalRefCount %d", delta, mGlobalRefCount); 311 mGlobalRefCount = 0; 312 } else { 313 mGlobalRefCount += delta; 314 } 315 if ((oldGlobalRefCount == 0) && (mGlobalRefCount > 0)) { 316 if ((mPolicyMix != NULL) && ((mPolicyMix->mCbFlags & AudioMix::kCbFlagNotifyActivity) != 0)) 317 { 318 mClientInterface->onDynamicPolicyMixStateUpdate(mPolicyMix->mDeviceAddress, 319 MIX_STATE_MIXING); 320 } 321 322 } else if ((oldGlobalRefCount > 0) && (mGlobalRefCount == 0)) { 323 if ((mPolicyMix != NULL) && ((mPolicyMix->mCbFlags & AudioMix::kCbFlagNotifyActivity) != 0)) 324 { 325 mClientInterface->onDynamicPolicyMixStateUpdate(mPolicyMix->mDeviceAddress, 326 MIX_STATE_IDLE); 327 } 328 } 329} 330 331 332bool SwAudioOutputDescriptor::isFixedVolume(audio_devices_t device) 333{ 334 // unit gain if rerouting to external policy 335 if (device == AUDIO_DEVICE_OUT_REMOTE_SUBMIX) { 336 if (mPolicyMix != NULL) { 337 ALOGV("max gain when rerouting for output=%d", mIoHandle); 338 return true; 339 } 340 } 341 return false; 342} 343 344void SwAudioOutputDescriptor::toAudioPortConfig( 345 struct audio_port_config *dstConfig, 346 const struct audio_port_config *srcConfig) const 347{ 348 349 ALOG_ASSERT(!isDuplicated(), "toAudioPortConfig() called on duplicated output %d", mIoHandle); 350 AudioOutputDescriptor::toAudioPortConfig(dstConfig, srcConfig); 351 352 dstConfig->ext.mix.handle = mIoHandle; 353} 354 355void SwAudioOutputDescriptor::toAudioPort( 356 struct audio_port *port) const 357{ 358 ALOG_ASSERT(!isDuplicated(), "toAudioPort() called on duplicated output %d", mIoHandle); 359 360 AudioOutputDescriptor::toAudioPort(port); 361 362 toAudioPortConfig(&port->active_config); 363 port->ext.mix.handle = mIoHandle; 364 port->ext.mix.latency_class = 365 mFlags & AUDIO_OUTPUT_FLAG_FAST ? AUDIO_LATENCY_LOW : AUDIO_LATENCY_NORMAL; 366} 367 368bool SwAudioOutputDescriptor::setVolume(float volume, 369 audio_stream_type_t stream, 370 audio_devices_t device, 371 uint32_t delayMs, 372 bool force) 373{ 374 bool changed = AudioOutputDescriptor::setVolume(volume, stream, device, delayMs, force); 375 376 if (changed) { 377 // Force VOICE_CALL to track BLUETOOTH_SCO stream volume when bluetooth audio is 378 // enabled 379 float volume = Volume::DbToAmpl(mCurVolume[stream]); 380 if (stream == AUDIO_STREAM_BLUETOOTH_SCO) { 381 mClientInterface->setStreamVolume( 382 AUDIO_STREAM_VOICE_CALL, volume, mIoHandle, delayMs); 383 } 384 mClientInterface->setStreamVolume(stream, volume, mIoHandle, delayMs); 385 } 386 return changed; 387} 388 389// HwAudioOutputDescriptor implementation 390HwAudioOutputDescriptor::HwAudioOutputDescriptor(const sp<AudioSourceDescriptor>& source, 391 AudioPolicyClientInterface *clientInterface) 392 : AudioOutputDescriptor(source->mDevice, clientInterface), 393 mSource(source) 394{ 395} 396 397status_t HwAudioOutputDescriptor::dump(int fd) 398{ 399 const size_t SIZE = 256; 400 char buffer[SIZE]; 401 String8 result; 402 403 AudioOutputDescriptor::dump(fd); 404 405 snprintf(buffer, SIZE, "Source:\n"); 406 result.append(buffer); 407 write(fd, result.string(), result.size()); 408 mSource->dump(fd); 409 410 return NO_ERROR; 411} 412 413audio_devices_t HwAudioOutputDescriptor::supportedDevices() 414{ 415 return mDevice; 416} 417 418void HwAudioOutputDescriptor::toAudioPortConfig( 419 struct audio_port_config *dstConfig, 420 const struct audio_port_config *srcConfig) const 421{ 422 mSource->mDevice->toAudioPortConfig(dstConfig, srcConfig); 423} 424 425void HwAudioOutputDescriptor::toAudioPort( 426 struct audio_port *port) const 427{ 428 mSource->mDevice->toAudioPort(port); 429} 430 431 432bool HwAudioOutputDescriptor::setVolume(float volume, 433 audio_stream_type_t stream, 434 audio_devices_t device, 435 uint32_t delayMs, 436 bool force) 437{ 438 bool changed = AudioOutputDescriptor::setVolume(volume, stream, device, delayMs, force); 439 440 if (changed) { 441 // TODO: use gain controller on source device if any to adjust volume 442 } 443 return changed; 444} 445 446// SwAudioOutputCollection implementation 447bool SwAudioOutputCollection::isStreamActive(audio_stream_type_t stream, uint32_t inPastMs) const 448{ 449 nsecs_t sysTime = systemTime(); 450 for (size_t i = 0; i < this->size(); i++) { 451 const sp<SwAudioOutputDescriptor> outputDesc = this->valueAt(i); 452 if (outputDesc->isStreamActive(stream, inPastMs, sysTime)) { 453 return true; 454 } 455 } 456 return false; 457} 458 459bool SwAudioOutputCollection::isStreamActiveRemotely(audio_stream_type_t stream, 460 uint32_t inPastMs) const 461{ 462 nsecs_t sysTime = systemTime(); 463 for (size_t i = 0; i < size(); i++) { 464 const sp<SwAudioOutputDescriptor> outputDesc = valueAt(i); 465 if (((outputDesc->device() & APM_AUDIO_OUT_DEVICE_REMOTE_ALL) != 0) && 466 outputDesc->isStreamActive(stream, inPastMs, sysTime)) { 467 // do not consider re routing (when the output is going to a dynamic policy) 468 // as "remote playback" 469 if (outputDesc->mPolicyMix == NULL) { 470 return true; 471 } 472 } 473 } 474 return false; 475} 476 477audio_io_handle_t SwAudioOutputCollection::getA2dpOutput() const 478{ 479 for (size_t i = 0; i < size(); i++) { 480 sp<SwAudioOutputDescriptor> outputDesc = valueAt(i); 481 if (!outputDesc->isDuplicated() && outputDesc->device() & AUDIO_DEVICE_OUT_ALL_A2DP) { 482 return this->keyAt(i); 483 } 484 } 485 return 0; 486} 487 488sp<SwAudioOutputDescriptor> SwAudioOutputCollection::getPrimaryOutput() const 489{ 490 for (size_t i = 0; i < size(); i++) { 491 const sp<SwAudioOutputDescriptor> outputDesc = valueAt(i); 492 if (outputDesc->mFlags & AUDIO_OUTPUT_FLAG_PRIMARY) { 493 return outputDesc; 494 } 495 } 496 return NULL; 497} 498 499sp<SwAudioOutputDescriptor> SwAudioOutputCollection::getOutputFromId(audio_port_handle_t id) const 500{ 501 sp<SwAudioOutputDescriptor> outputDesc = NULL; 502 for (size_t i = 0; i < size(); i++) { 503 outputDesc = valueAt(i); 504 if (outputDesc->getId() == id) { 505 break; 506 } 507 } 508 return outputDesc; 509} 510 511bool SwAudioOutputCollection::isAnyOutputActive(audio_stream_type_t streamToIgnore) const 512{ 513 for (size_t s = 0 ; s < AUDIO_STREAM_CNT ; s++) { 514 if (s == (size_t) streamToIgnore) { 515 continue; 516 } 517 for (size_t i = 0; i < size(); i++) { 518 const sp<SwAudioOutputDescriptor> outputDesc = valueAt(i); 519 if (outputDesc->mRefCount[s] != 0) { 520 return true; 521 } 522 } 523 } 524 return false; 525} 526 527audio_devices_t SwAudioOutputCollection::getSupportedDevices(audio_io_handle_t handle) const 528{ 529 sp<SwAudioOutputDescriptor> outputDesc = valueFor(handle); 530 audio_devices_t devices = outputDesc->mProfile->getSupportedDevicesType(); 531 return devices; 532} 533 534 535status_t SwAudioOutputCollection::dump(int fd) const 536{ 537 const size_t SIZE = 256; 538 char buffer[SIZE]; 539 540 snprintf(buffer, SIZE, "\nOutputs dump:\n"); 541 write(fd, buffer, strlen(buffer)); 542 for (size_t i = 0; i < size(); i++) { 543 snprintf(buffer, SIZE, "- Output %d dump:\n", keyAt(i)); 544 write(fd, buffer, strlen(buffer)); 545 valueAt(i)->dump(fd); 546 } 547 548 return NO_ERROR; 549} 550 551// HwAudioOutputCollection implementation 552bool HwAudioOutputCollection::isStreamActive(audio_stream_type_t stream, uint32_t inPastMs) const 553{ 554 nsecs_t sysTime = systemTime(); 555 for (size_t i = 0; i < this->size(); i++) { 556 const sp<HwAudioOutputDescriptor> outputDesc = this->valueAt(i); 557 if (outputDesc->isStreamActive(stream, inPastMs, sysTime)) { 558 return true; 559 } 560 } 561 return false; 562} 563 564bool HwAudioOutputCollection::isAnyOutputActive(audio_stream_type_t streamToIgnore) const 565{ 566 for (size_t s = 0 ; s < AUDIO_STREAM_CNT ; s++) { 567 if (s == (size_t) streamToIgnore) { 568 continue; 569 } 570 for (size_t i = 0; i < size(); i++) { 571 const sp<HwAudioOutputDescriptor> outputDesc = valueAt(i); 572 if (outputDesc->mRefCount[s] != 0) { 573 return true; 574 } 575 } 576 } 577 return false; 578} 579 580status_t HwAudioOutputCollection::dump(int fd) const 581{ 582 const size_t SIZE = 256; 583 char buffer[SIZE]; 584 585 snprintf(buffer, SIZE, "\nOutputs dump:\n"); 586 write(fd, buffer, strlen(buffer)); 587 for (size_t i = 0; i < size(); i++) { 588 snprintf(buffer, SIZE, "- Output %d dump:\n", keyAt(i)); 589 write(fd, buffer, strlen(buffer)); 590 valueAt(i)->dump(fd); 591 } 592 593 return NO_ERROR; 594} 595 596}; //namespace android 597