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 34 AudioOutputDescriptor::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 57 audio_module_handle_t AudioOutputDescriptor::getModuleHandle() const 58 { 59 return mPort->getModuleHandle(); 60 } 61 62 audio_port_handle_t AudioOutputDescriptor::getId() const 63 { 64 return mId; 65 } 66 67 audio_devices_t AudioOutputDescriptor::device() const 68 { 69 return mDevice; 70 } 71 72 audio_devices_t AudioOutputDescriptor::supportedDevices() 73 { 74 return mDevice; 75 } 76 77 bool 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 hasSameHwModuleAs(outputDesc); 85 } 86 } 87 88 void 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 101 bool 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 118 bool 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 138 bool AudioOutputDescriptor::isFixedVolume(audio_devices_t device __unused) 139 { 140 return false; 141 } 142 143 bool 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 160 void 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 178 void 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 186 status_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 214 void 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 221 SwAudioOutputDescriptor::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), 227 mDirectClientSession(AUDIO_SESSION_NONE), mGlobalRefCount(0) 228 { 229 if (profile != NULL) { 230 mFlags = (audio_output_flags_t)profile->getFlags(); 231 } 232 } 233 234 void SwAudioOutputDescriptor::setIoHandle(audio_io_handle_t ioHandle) 235 { 236 mId = AudioPort::getNextUniqueId(); 237 mIoHandle = ioHandle; 238 } 239 240 241 status_t SwAudioOutputDescriptor::dump(int fd) 242 { 243 const size_t SIZE = 256; 244 char buffer[SIZE]; 245 String8 result; 246 247 snprintf(buffer, SIZE, " Latency: %d\n", mLatency); 248 result.append(buffer); 249 snprintf(buffer, SIZE, " Flags %08x\n", mFlags); 250 result.append(buffer); 251 write(fd, result.string(), result.size()); 252 253 AudioOutputDescriptor::dump(fd); 254 255 return NO_ERROR; 256 } 257 258 audio_devices_t SwAudioOutputDescriptor::device() const 259 { 260 if (isDuplicated()) { 261 return (audio_devices_t)(mOutput1->mDevice | mOutput2->mDevice); 262 } else { 263 return mDevice; 264 } 265 } 266 267 bool SwAudioOutputDescriptor::sharesHwModuleWith( 268 const sp<AudioOutputDescriptor>& outputDesc) 269 { 270 if (isDuplicated()) { 271 return mOutput1->sharesHwModuleWith(outputDesc) || mOutput2->sharesHwModuleWith(outputDesc); 272 } else if (outputDesc->isDuplicated()){ 273 return sharesHwModuleWith(outputDesc->subOutput1()) || 274 sharesHwModuleWith(outputDesc->subOutput2()); 275 } else { 276 return AudioOutputDescriptor::sharesHwModuleWith(outputDesc); 277 } 278 } 279 280 audio_devices_t SwAudioOutputDescriptor::supportedDevices() 281 { 282 if (isDuplicated()) { 283 return (audio_devices_t)(mOutput1->supportedDevices() | mOutput2->supportedDevices()); 284 } else { 285 return mProfile->getSupportedDevicesType(); 286 } 287 } 288 289 uint32_t SwAudioOutputDescriptor::latency() 290 { 291 if (isDuplicated()) { 292 return (mOutput1->mLatency > mOutput2->mLatency) ? mOutput1->mLatency : mOutput2->mLatency; 293 } else { 294 return mLatency; 295 } 296 } 297 298 void SwAudioOutputDescriptor::changeRefCount(audio_stream_type_t stream, 299 int delta) 300 { 301 // forward usage count change to attached outputs 302 if (isDuplicated()) { 303 mOutput1->changeRefCount(stream, delta); 304 mOutput2->changeRefCount(stream, delta); 305 } 306 AudioOutputDescriptor::changeRefCount(stream, delta); 307 308 // handle stream-independent ref count 309 uint32_t oldGlobalRefCount = mGlobalRefCount; 310 if ((delta + (int)mGlobalRefCount) < 0) { 311 ALOGW("changeRefCount() invalid delta %d globalRefCount %d", delta, mGlobalRefCount); 312 mGlobalRefCount = 0; 313 } else { 314 mGlobalRefCount += delta; 315 } 316 if ((oldGlobalRefCount == 0) && (mGlobalRefCount > 0)) { 317 if ((mPolicyMix != NULL) && ((mPolicyMix->mCbFlags & AudioMix::kCbFlagNotifyActivity) != 0)) 318 { 319 mClientInterface->onDynamicPolicyMixStateUpdate(mPolicyMix->mDeviceAddress, 320 MIX_STATE_MIXING); 321 } 322 323 } else if ((oldGlobalRefCount > 0) && (mGlobalRefCount == 0)) { 324 if ((mPolicyMix != NULL) && ((mPolicyMix->mCbFlags & AudioMix::kCbFlagNotifyActivity) != 0)) 325 { 326 mClientInterface->onDynamicPolicyMixStateUpdate(mPolicyMix->mDeviceAddress, 327 MIX_STATE_IDLE); 328 } 329 } 330 } 331 332 333 bool SwAudioOutputDescriptor::isFixedVolume(audio_devices_t device) 334 { 335 // unit gain if rerouting to external policy 336 if (device == AUDIO_DEVICE_OUT_REMOTE_SUBMIX) { 337 if (mPolicyMix != NULL) { 338 ALOGV("max gain when rerouting for output=%d", mIoHandle); 339 return true; 340 } 341 } 342 return false; 343 } 344 345 void SwAudioOutputDescriptor::toAudioPortConfig( 346 struct audio_port_config *dstConfig, 347 const struct audio_port_config *srcConfig) const 348 { 349 350 ALOG_ASSERT(!isDuplicated(), "toAudioPortConfig() called on duplicated output %d", mIoHandle); 351 AudioOutputDescriptor::toAudioPortConfig(dstConfig, srcConfig); 352 353 dstConfig->ext.mix.handle = mIoHandle; 354 } 355 356 void SwAudioOutputDescriptor::toAudioPort( 357 struct audio_port *port) const 358 { 359 ALOG_ASSERT(!isDuplicated(), "toAudioPort() called on duplicated output %d", mIoHandle); 360 361 AudioOutputDescriptor::toAudioPort(port); 362 363 toAudioPortConfig(&port->active_config); 364 port->ext.mix.handle = mIoHandle; 365 port->ext.mix.latency_class = 366 mFlags & AUDIO_OUTPUT_FLAG_FAST ? AUDIO_LATENCY_LOW : AUDIO_LATENCY_NORMAL; 367 } 368 369 bool SwAudioOutputDescriptor::setVolume(float volume, 370 audio_stream_type_t stream, 371 audio_devices_t device, 372 uint32_t delayMs, 373 bool force) 374 { 375 bool changed = AudioOutputDescriptor::setVolume(volume, stream, device, delayMs, force); 376 377 if (changed) { 378 // Force VOICE_CALL to track BLUETOOTH_SCO stream volume when bluetooth audio is 379 // enabled 380 float volume = Volume::DbToAmpl(mCurVolume[stream]); 381 if (stream == AUDIO_STREAM_BLUETOOTH_SCO) { 382 mClientInterface->setStreamVolume( 383 AUDIO_STREAM_VOICE_CALL, volume, mIoHandle, delayMs); 384 } 385 mClientInterface->setStreamVolume(stream, volume, mIoHandle, delayMs); 386 } 387 return changed; 388 } 389 390 // HwAudioOutputDescriptor implementation 391 HwAudioOutputDescriptor::HwAudioOutputDescriptor(const sp<AudioSourceDescriptor>& source, 392 AudioPolicyClientInterface *clientInterface) 393 : AudioOutputDescriptor(source->mDevice, clientInterface), 394 mSource(source) 395 { 396 } 397 398 status_t HwAudioOutputDescriptor::dump(int fd) 399 { 400 const size_t SIZE = 256; 401 char buffer[SIZE]; 402 String8 result; 403 404 AudioOutputDescriptor::dump(fd); 405 406 snprintf(buffer, SIZE, "Source:\n"); 407 result.append(buffer); 408 write(fd, result.string(), result.size()); 409 mSource->dump(fd); 410 411 return NO_ERROR; 412 } 413 414 audio_devices_t HwAudioOutputDescriptor::supportedDevices() 415 { 416 return mDevice; 417 } 418 419 void HwAudioOutputDescriptor::toAudioPortConfig( 420 struct audio_port_config *dstConfig, 421 const struct audio_port_config *srcConfig) const 422 { 423 mSource->mDevice->toAudioPortConfig(dstConfig, srcConfig); 424 } 425 426 void HwAudioOutputDescriptor::toAudioPort( 427 struct audio_port *port) const 428 { 429 mSource->mDevice->toAudioPort(port); 430 } 431 432 433 bool HwAudioOutputDescriptor::setVolume(float volume, 434 audio_stream_type_t stream, 435 audio_devices_t device, 436 uint32_t delayMs, 437 bool force) 438 { 439 bool changed = AudioOutputDescriptor::setVolume(volume, stream, device, delayMs, force); 440 441 if (changed) { 442 // TODO: use gain controller on source device if any to adjust volume 443 } 444 return changed; 445 } 446 447 // SwAudioOutputCollection implementation 448 bool SwAudioOutputCollection::isStreamActive(audio_stream_type_t stream, uint32_t inPastMs) const 449 { 450 nsecs_t sysTime = systemTime(); 451 for (size_t i = 0; i < this->size(); i++) { 452 const sp<SwAudioOutputDescriptor> outputDesc = this->valueAt(i); 453 if (outputDesc->isStreamActive(stream, inPastMs, sysTime)) { 454 return true; 455 } 456 } 457 return false; 458 } 459 460 bool SwAudioOutputCollection::isStreamActiveRemotely(audio_stream_type_t stream, 461 uint32_t inPastMs) const 462 { 463 nsecs_t sysTime = systemTime(); 464 for (size_t i = 0; i < size(); i++) { 465 const sp<SwAudioOutputDescriptor> outputDesc = valueAt(i); 466 if (((outputDesc->device() & APM_AUDIO_OUT_DEVICE_REMOTE_ALL) != 0) && 467 outputDesc->isStreamActive(stream, inPastMs, sysTime)) { 468 // do not consider re routing (when the output is going to a dynamic policy) 469 // as "remote playback" 470 if (outputDesc->mPolicyMix == NULL) { 471 return true; 472 } 473 } 474 } 475 return false; 476 } 477 478 audio_io_handle_t SwAudioOutputCollection::getA2dpOutput() const 479 { 480 for (size_t i = 0; i < size(); i++) { 481 sp<SwAudioOutputDescriptor> outputDesc = valueAt(i); 482 if (!outputDesc->isDuplicated() && outputDesc->device() & AUDIO_DEVICE_OUT_ALL_A2DP) { 483 return this->keyAt(i); 484 } 485 } 486 return 0; 487 } 488 489 sp<SwAudioOutputDescriptor> SwAudioOutputCollection::getPrimaryOutput() const 490 { 491 for (size_t i = 0; i < size(); i++) { 492 const sp<SwAudioOutputDescriptor> outputDesc = valueAt(i); 493 if (outputDesc->mFlags & AUDIO_OUTPUT_FLAG_PRIMARY) { 494 return outputDesc; 495 } 496 } 497 return NULL; 498 } 499 500 sp<SwAudioOutputDescriptor> SwAudioOutputCollection::getOutputFromId(audio_port_handle_t id) const 501 { 502 sp<SwAudioOutputDescriptor> outputDesc = NULL; 503 for (size_t i = 0; i < size(); i++) { 504 outputDesc = valueAt(i); 505 if (outputDesc->getId() == id) { 506 break; 507 } 508 } 509 return outputDesc; 510 } 511 512 bool SwAudioOutputCollection::isAnyOutputActive(audio_stream_type_t streamToIgnore) const 513 { 514 for (size_t s = 0 ; s < AUDIO_STREAM_CNT ; s++) { 515 if (s == (size_t) streamToIgnore) { 516 continue; 517 } 518 for (size_t i = 0; i < size(); i++) { 519 const sp<SwAudioOutputDescriptor> outputDesc = valueAt(i); 520 if (outputDesc->mRefCount[s] != 0) { 521 return true; 522 } 523 } 524 } 525 return false; 526 } 527 528 audio_devices_t SwAudioOutputCollection::getSupportedDevices(audio_io_handle_t handle) const 529 { 530 sp<SwAudioOutputDescriptor> outputDesc = valueFor(handle); 531 audio_devices_t devices = outputDesc->mProfile->getSupportedDevicesType(); 532 return devices; 533 } 534 535 536 status_t SwAudioOutputCollection::dump(int fd) const 537 { 538 const size_t SIZE = 256; 539 char buffer[SIZE]; 540 541 snprintf(buffer, SIZE, "\nOutputs dump:\n"); 542 write(fd, buffer, strlen(buffer)); 543 for (size_t i = 0; i < size(); i++) { 544 snprintf(buffer, SIZE, "- Output %d dump:\n", keyAt(i)); 545 write(fd, buffer, strlen(buffer)); 546 valueAt(i)->dump(fd); 547 } 548 549 return NO_ERROR; 550 } 551 552 // HwAudioOutputCollection implementation 553 bool HwAudioOutputCollection::isStreamActive(audio_stream_type_t stream, uint32_t inPastMs) const 554 { 555 nsecs_t sysTime = systemTime(); 556 for (size_t i = 0; i < this->size(); i++) { 557 const sp<HwAudioOutputDescriptor> outputDesc = this->valueAt(i); 558 if (outputDesc->isStreamActive(stream, inPastMs, sysTime)) { 559 return true; 560 } 561 } 562 return false; 563 } 564 565 bool HwAudioOutputCollection::isAnyOutputActive(audio_stream_type_t streamToIgnore) const 566 { 567 for (size_t s = 0 ; s < AUDIO_STREAM_CNT ; s++) { 568 if (s == (size_t) streamToIgnore) { 569 continue; 570 } 571 for (size_t i = 0; i < size(); i++) { 572 const sp<HwAudioOutputDescriptor> outputDesc = valueAt(i); 573 if (outputDesc->mRefCount[s] != 0) { 574 return true; 575 } 576 } 577 } 578 return false; 579 } 580 581 status_t HwAudioOutputCollection::dump(int fd) const 582 { 583 const size_t SIZE = 256; 584 char buffer[SIZE]; 585 586 snprintf(buffer, SIZE, "\nOutputs dump:\n"); 587 write(fd, buffer, strlen(buffer)); 588 for (size_t i = 0; i < size(); i++) { 589 snprintf(buffer, SIZE, "- Output %d dump:\n", keyAt(i)); 590 write(fd, buffer, strlen(buffer)); 591 valueAt(i)->dump(fd); 592 } 593 594 return NO_ERROR; 595 } 596 597 }; //namespace android 598