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 "AudioPolicyMix.h" 23 #include "IOProfile.h" 24 #include "AudioGain.h" 25 #include "Volume.h" 26 #include "HwModule.h" 27 #include "TypeConverter.h" 28 #include <media/AudioParameter.h> 29 #include <media/AudioPolicy.h> 30 31 // A device mask for all audio output devices that are considered "remote" when evaluating 32 // active output devices in isStreamActiveRemotely() 33 #define APM_AUDIO_OUT_DEVICE_REMOTE_ALL AUDIO_DEVICE_OUT_REMOTE_SUBMIX 34 35 namespace android { 36 37 AudioOutputDescriptor::AudioOutputDescriptor(const sp<AudioPort>& port, 38 AudioPolicyClientInterface *clientInterface) 39 : mPort(port), mClientInterface(clientInterface) 40 { 41 if (mPort.get() != nullptr) { 42 mPort->pickAudioProfile(mSamplingRate, mChannelMask, mFormat); 43 if (mPort->mGains.size() > 0) { 44 mPort->mGains[0]->getDefaultConfig(&mGain); 45 } 46 } 47 } 48 49 audio_config_base_t AudioOutputDescriptor::getConfig() const 50 { 51 const audio_config_base_t config = { .sample_rate = mSamplingRate, .channel_mask = mChannelMask, 52 .format = mFormat }; 53 return config; 54 } 55 56 audio_module_handle_t AudioOutputDescriptor::getModuleHandle() const 57 { 58 return mPort.get() != nullptr ? mPort->getModuleHandle() : AUDIO_MODULE_HANDLE_NONE; 59 } 60 61 audio_patch_handle_t AudioOutputDescriptor::getPatchHandle() const 62 { 63 return mPatchHandle; 64 } 65 66 void AudioOutputDescriptor::setPatchHandle(audio_patch_handle_t handle) 67 { 68 mPatchHandle = handle; 69 } 70 71 audio_port_handle_t AudioOutputDescriptor::getId() const 72 { 73 return mId; 74 } 75 76 bool AudioOutputDescriptor::sharesHwModuleWith( 77 const sp<AudioOutputDescriptor>& outputDesc) 78 { 79 return hasSameHwModuleAs(outputDesc); 80 } 81 82 void AudioOutputDescriptor::setStopTime(const sp<TrackClientDescriptor>& client, nsecs_t sysTime) 83 { 84 mVolumeActivities[client->volumeSource()].setStopTime(sysTime); 85 mRoutingActivities[client->strategy()].setStopTime(sysTime); 86 } 87 88 void AudioOutputDescriptor::setClientActive(const sp<TrackClientDescriptor>& client, bool active) 89 { 90 auto clientIter = std::find(begin(mActiveClients), end(mActiveClients), client); 91 if (active == (clientIter != end(mActiveClients))) { 92 ALOGW("%s(%s): ignored active: %d, current stream count %d", __func__, 93 client->toShortString().c_str(), active, 94 mRoutingActivities.at(client->strategy()).getActivityCount()); 95 return; 96 } 97 if (active) { 98 mActiveClients.push_back(client); 99 } else { 100 mActiveClients.erase(clientIter); 101 } 102 const int delta = active ? 1 : -1; 103 // If ps is unknown, it is time to track it! 104 mRoutingActivities[client->strategy()].changeActivityCount(delta); 105 mVolumeActivities[client->volumeSource()].changeActivityCount(delta); 106 107 // Handle non-client-specific activity ref count 108 int32_t oldGlobalActiveCount = mGlobalActiveCount; 109 if (!active && mGlobalActiveCount < 1) { 110 ALOGW("%s(%s): invalid deactivation with globalRefCount %d", 111 __func__, client->toShortString().c_str(), mGlobalActiveCount); 112 mGlobalActiveCount = 1; 113 } 114 mGlobalActiveCount += delta; 115 116 sp<AudioPolicyMix> policyMix = mPolicyMix.promote(); 117 if ((policyMix != NULL) && ((policyMix->mCbFlags & AudioMix::kCbFlagNotifyActivity) != 0)) { 118 if ((oldGlobalActiveCount == 0) || (mGlobalActiveCount == 0)) { 119 mClientInterface->onDynamicPolicyMixStateUpdate(policyMix->mDeviceAddress, 120 mGlobalActiveCount > 0 ? MIX_STATE_MIXING : MIX_STATE_IDLE); 121 } 122 } 123 client->setActive(active); 124 } 125 126 bool AudioOutputDescriptor::isActive(VolumeSource vs, uint32_t inPastMs, nsecs_t sysTime) const 127 { 128 return (vs == VOLUME_SOURCE_NONE) ? 129 isActive(inPastMs) : (mVolumeActivities.find(vs) != std::end(mVolumeActivities)? 130 mVolumeActivities.at(vs).isActive(inPastMs, sysTime) : false); 131 } 132 133 bool AudioOutputDescriptor::isActive(uint32_t inPastMs) const 134 { 135 nsecs_t sysTime = 0; 136 if (inPastMs != 0) { 137 sysTime = systemTime(); 138 } 139 for (const auto &iter : mVolumeActivities) { 140 if (iter.second.isActive(inPastMs, sysTime)) { 141 return true; 142 } 143 } 144 return false; 145 } 146 147 bool AudioOutputDescriptor::isFixedVolume(audio_devices_t device __unused) 148 { 149 return false; 150 } 151 152 bool AudioOutputDescriptor::setVolume(float volumeDb, 153 VolumeSource volumeSource, 154 const StreamTypeVector &/*streams*/, 155 audio_devices_t /*device*/, 156 uint32_t delayMs, 157 bool force) 158 { 159 // We actually change the volume if: 160 // - the float value returned by computeVolume() changed 161 // - the force flag is set 162 if (volumeDb != getCurVolume(volumeSource) || force) { 163 ALOGV("%s for volumeSrc %d, volume %f, delay %d", __func__, volumeSource, volumeDb, delayMs); 164 setCurVolume(volumeSource, volumeDb); 165 return true; 166 } 167 return false; 168 } 169 170 void AudioOutputDescriptor::toAudioPortConfig( 171 struct audio_port_config *dstConfig, 172 const struct audio_port_config *srcConfig) const 173 { 174 dstConfig->config_mask = AUDIO_PORT_CONFIG_SAMPLE_RATE|AUDIO_PORT_CONFIG_CHANNEL_MASK| 175 AUDIO_PORT_CONFIG_FORMAT|AUDIO_PORT_CONFIG_GAIN; 176 if (srcConfig != NULL) { 177 dstConfig->config_mask |= srcConfig->config_mask; 178 } 179 AudioPortConfig::toAudioPortConfig(dstConfig, srcConfig); 180 181 dstConfig->id = mId; 182 dstConfig->role = AUDIO_PORT_ROLE_SOURCE; 183 dstConfig->type = AUDIO_PORT_TYPE_MIX; 184 dstConfig->ext.mix.hw_module = getModuleHandle(); 185 dstConfig->ext.mix.usecase.stream = AUDIO_STREAM_DEFAULT; 186 } 187 188 void AudioOutputDescriptor::toAudioPort(struct audio_port *port) const 189 { 190 // Should not be called for duplicated ports, see SwAudioOutputDescriptor::toAudioPortConfig. 191 mPort->toAudioPort(port); 192 port->id = mId; 193 port->ext.mix.hw_module = getModuleHandle(); 194 } 195 196 TrackClientVector AudioOutputDescriptor::clientsList(bool activeOnly, product_strategy_t strategy, 197 bool preferredDeviceOnly) const 198 { 199 TrackClientVector clients; 200 for (const auto &client : getClientIterable()) { 201 if ((!activeOnly || client->active()) 202 && (strategy == PRODUCT_STRATEGY_NONE || strategy == client->strategy()) 203 && (!preferredDeviceOnly || 204 (client->hasPreferredDevice() && !client->isPreferredDeviceForExclusiveUse()))) { 205 clients.push_back(client); 206 } 207 } 208 return clients; 209 } 210 211 bool AudioOutputDescriptor::isAnyActive(VolumeSource volumeSourceToIgnore) const 212 { 213 return std::find_if(begin(mActiveClients), end(mActiveClients), 214 [&volumeSourceToIgnore](const auto &client) { 215 return client->volumeSource() != volumeSourceToIgnore; }) != end(mActiveClients); 216 } 217 218 void AudioOutputDescriptor::dump(String8 *dst) const 219 { 220 dst->appendFormat(" ID: %d\n", mId); 221 dst->appendFormat(" Sampling rate: %d\n", mSamplingRate); 222 dst->appendFormat(" Format: %08x\n", mFormat); 223 dst->appendFormat(" Channels: %08x\n", mChannelMask); 224 dst->appendFormat(" Devices: %s\n", devices().toString().c_str()); 225 dst->appendFormat(" Global active count: %u\n", mGlobalActiveCount); 226 for (const auto &iter : mRoutingActivities) { 227 dst->appendFormat(" Product Strategy id: %d", iter.first); 228 iter.second.dump(dst, 4); 229 } 230 for (const auto &iter : mVolumeActivities) { 231 dst->appendFormat(" Volume Activities id: %d", iter.first); 232 iter.second.dump(dst, 4); 233 } 234 dst->append(" AudioTrack Clients:\n"); 235 ClientMapHandler<TrackClientDescriptor>::dump(dst); 236 dst->append("\n"); 237 if (!mActiveClients.empty()) { 238 dst->append(" AudioTrack active (stream) clients:\n"); 239 size_t index = 0; 240 for (const auto& client : mActiveClients) { 241 client->dump(dst, 2, index++); 242 } 243 dst->append(" \n"); 244 } 245 } 246 247 void AudioOutputDescriptor::log(const char* indent) 248 { 249 ALOGI("%sID: %d,0x%X, [rt:%d fmt:0x%X ch:0x%X]", 250 indent, mId, mId, mSamplingRate, mFormat, mChannelMask); 251 } 252 253 // SwAudioOutputDescriptor implementation 254 SwAudioOutputDescriptor::SwAudioOutputDescriptor(const sp<IOProfile>& profile, 255 AudioPolicyClientInterface *clientInterface) 256 : AudioOutputDescriptor(profile, clientInterface), 257 mProfile(profile), mIoHandle(AUDIO_IO_HANDLE_NONE), mLatency(0), 258 mFlags((audio_output_flags_t)0), 259 mOutput1(0), mOutput2(0), mDirectOpenCount(0), 260 mDirectClientSession(AUDIO_SESSION_NONE) 261 { 262 if (profile != NULL) { 263 mFlags = (audio_output_flags_t)profile->getFlags(); 264 } 265 } 266 267 void SwAudioOutputDescriptor::dump(String8 *dst) const 268 { 269 dst->appendFormat(" Latency: %d\n", mLatency); 270 dst->appendFormat(" Flags %08x\n", mFlags); 271 AudioOutputDescriptor::dump(dst); 272 } 273 274 DeviceVector SwAudioOutputDescriptor::devices() const 275 { 276 if (isDuplicated()) { 277 DeviceVector devices = mOutput1->devices(); 278 devices.merge(mOutput2->devices()); 279 return devices; 280 } 281 return mDevices; 282 } 283 284 bool SwAudioOutputDescriptor::sharesHwModuleWith( 285 const sp<SwAudioOutputDescriptor>& outputDesc) 286 { 287 if (isDuplicated()) { 288 return mOutput1->sharesHwModuleWith(outputDesc) || mOutput2->sharesHwModuleWith(outputDesc); 289 } else if (outputDesc->isDuplicated()){ 290 return sharesHwModuleWith(outputDesc->subOutput1()) || 291 sharesHwModuleWith(outputDesc->subOutput2()); 292 } else { 293 return AudioOutputDescriptor::sharesHwModuleWith(outputDesc); 294 } 295 } 296 297 DeviceVector SwAudioOutputDescriptor::supportedDevices() const 298 { 299 if (isDuplicated()) { 300 DeviceVector supportedDevices = mOutput1->supportedDevices(); 301 supportedDevices.merge(mOutput2->supportedDevices()); 302 return supportedDevices; 303 } 304 return mProfile->getSupportedDevices(); 305 } 306 307 bool SwAudioOutputDescriptor::supportsDevice(const sp<DeviceDescriptor> &device) const 308 { 309 return supportedDevices().contains(device); 310 } 311 312 bool SwAudioOutputDescriptor::supportsAllDevices(const DeviceVector &devices) const 313 { 314 return supportedDevices().containsAllDevices(devices); 315 } 316 317 DeviceVector SwAudioOutputDescriptor::filterSupportedDevices(const DeviceVector &devices) const 318 { 319 DeviceVector filteredDevices = supportedDevices(); 320 return filteredDevices.filter(devices); 321 } 322 323 bool SwAudioOutputDescriptor::deviceSupportsEncodedFormats(audio_devices_t device) 324 { 325 if (isDuplicated()) { 326 return (mOutput1->deviceSupportsEncodedFormats(device) 327 || mOutput2->deviceSupportsEncodedFormats(device)); 328 } else { 329 return mProfile->deviceSupportsEncodedFormats(device); 330 } 331 } 332 333 uint32_t SwAudioOutputDescriptor::latency() 334 { 335 if (isDuplicated()) { 336 return (mOutput1->mLatency > mOutput2->mLatency) ? mOutput1->mLatency : mOutput2->mLatency; 337 } else { 338 return mLatency; 339 } 340 } 341 342 void SwAudioOutputDescriptor::setClientActive(const sp<TrackClientDescriptor>& client, bool active) 343 { 344 // forward usage count change to attached outputs 345 if (isDuplicated()) { 346 mOutput1->setClientActive(client, active); 347 mOutput2->setClientActive(client, active); 348 } 349 AudioOutputDescriptor::setClientActive(client, active); 350 } 351 352 bool SwAudioOutputDescriptor::isFixedVolume(audio_devices_t device) 353 { 354 // unit gain if rerouting to external policy 355 if (device == AUDIO_DEVICE_OUT_REMOTE_SUBMIX) { 356 if (mPolicyMix != NULL) { 357 ALOGV("max gain when rerouting for output=%d", mIoHandle); 358 return true; 359 } 360 } 361 if (device == AUDIO_DEVICE_OUT_TELEPHONY_TX) { 362 ALOGV("max gain when output device is telephony tx"); 363 return true; 364 } 365 return false; 366 } 367 368 void SwAudioOutputDescriptor::toAudioPortConfig( 369 struct audio_port_config *dstConfig, 370 const struct audio_port_config *srcConfig) const 371 { 372 373 ALOG_ASSERT(!isDuplicated(), "toAudioPortConfig() called on duplicated output %d", mIoHandle); 374 AudioOutputDescriptor::toAudioPortConfig(dstConfig, srcConfig); 375 376 dstConfig->ext.mix.handle = mIoHandle; 377 } 378 379 void SwAudioOutputDescriptor::toAudioPort( 380 struct audio_port *port) const 381 { 382 ALOG_ASSERT(!isDuplicated(), "toAudioPort() called on duplicated output %d", mIoHandle); 383 384 AudioOutputDescriptor::toAudioPort(port); 385 386 toAudioPortConfig(&port->active_config); 387 port->ext.mix.handle = mIoHandle; 388 port->ext.mix.latency_class = 389 mFlags & AUDIO_OUTPUT_FLAG_FAST ? AUDIO_LATENCY_LOW : AUDIO_LATENCY_NORMAL; 390 } 391 392 bool SwAudioOutputDescriptor::setVolume(float volumeDb, 393 VolumeSource vs, const StreamTypeVector &streamTypes, 394 audio_devices_t device, 395 uint32_t delayMs, 396 bool force) 397 { 398 StreamTypeVector streams = streamTypes; 399 if (!AudioOutputDescriptor::setVolume(volumeDb, vs, streamTypes, device, delayMs, force)) { 400 return false; 401 } 402 if (streams.empty()) { 403 streams.push_back(AUDIO_STREAM_MUSIC); 404 } 405 for (const auto& devicePort : devices()) { 406 // APM loops on all group, so filter on active group to set the port gain, 407 // let the other groups set the stream volume as per legacy 408 // TODO: Pass in the device address and check against it. 409 if (device == devicePort->type() && 410 devicePort->hasGainController(true) && isActive(vs)) { 411 ALOGV("%s: device %s has gain controller", __func__, devicePort->toString().c_str()); 412 // @todo: here we might be in trouble if the SwOutput has several active clients with 413 // different Volume Source (or if we allow several curves within same volume group) 414 // 415 // @todo: default stream volume to max (0) when using HW Port gain? 416 float volumeAmpl = Volume::DbToAmpl(0); 417 for (const auto &stream : streams) { 418 mClientInterface->setStreamVolume(stream, volumeAmpl, mIoHandle, delayMs); 419 } 420 421 AudioGains gains = devicePort->getGains(); 422 int gainMinValueInMb = gains[0]->getMinValueInMb(); 423 int gainMaxValueInMb = gains[0]->getMaxValueInMb(); 424 int gainStepValueInMb = gains[0]->getStepValueInMb(); 425 int gainValueMb = ((volumeDb * 100)/ gainStepValueInMb) * gainStepValueInMb; 426 gainValueMb = std::max(gainMinValueInMb, std::min(gainValueMb, gainMaxValueInMb)); 427 428 audio_port_config config = {}; 429 devicePort->toAudioPortConfig(&config); 430 config.config_mask = AUDIO_PORT_CONFIG_GAIN; 431 config.gain.values[0] = gainValueMb; 432 return mClientInterface->setAudioPortConfig(&config, 0) == NO_ERROR; 433 } 434 } 435 // Force VOICE_CALL to track BLUETOOTH_SCO stream volume when bluetooth audio is enabled 436 float volumeAmpl = Volume::DbToAmpl(getCurVolume(vs)); 437 if (hasStream(streams, AUDIO_STREAM_BLUETOOTH_SCO)) { 438 mClientInterface->setStreamVolume(AUDIO_STREAM_VOICE_CALL, volumeAmpl, mIoHandle, delayMs); 439 } 440 for (const auto &stream : streams) { 441 ALOGV("%s output %d for volumeSource %d, volume %f, delay %d stream=%s", __func__, 442 mIoHandle, vs, volumeDb, delayMs, toString(stream).c_str()); 443 mClientInterface->setStreamVolume(stream, volumeAmpl, mIoHandle, delayMs); 444 } 445 return true; 446 } 447 448 status_t SwAudioOutputDescriptor::open(const audio_config_t *config, 449 const DeviceVector &devices, 450 audio_stream_type_t stream, 451 audio_output_flags_t flags, 452 audio_io_handle_t *output) 453 { 454 mDevices = devices; 455 const String8& address = devices.getFirstValidAddress(); 456 audio_devices_t device = devices.types(); 457 458 audio_config_t lConfig; 459 if (config == nullptr) { 460 lConfig = AUDIO_CONFIG_INITIALIZER; 461 lConfig.sample_rate = mSamplingRate; 462 lConfig.channel_mask = mChannelMask; 463 lConfig.format = mFormat; 464 } else { 465 lConfig = *config; 466 } 467 468 // if the selected profile is offloaded and no offload info was specified, 469 // create a default one 470 if ((mProfile->getFlags() & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) && 471 lConfig.offload_info.format == AUDIO_FORMAT_DEFAULT) { 472 flags = (audio_output_flags_t)(flags | AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD); 473 lConfig.offload_info = AUDIO_INFO_INITIALIZER; 474 lConfig.offload_info.sample_rate = lConfig.sample_rate; 475 lConfig.offload_info.channel_mask = lConfig.channel_mask; 476 lConfig.offload_info.format = lConfig.format; 477 lConfig.offload_info.stream_type = stream; 478 lConfig.offload_info.duration_us = -1; 479 lConfig.offload_info.has_video = true; // conservative 480 lConfig.offload_info.is_streaming = true; // likely 481 } 482 483 mFlags = (audio_output_flags_t)(mFlags | flags); 484 485 ALOGV("opening output for device %s profile %p name %s", 486 mDevices.toString().c_str(), mProfile.get(), mProfile->getName().string()); 487 488 status_t status = mClientInterface->openOutput(mProfile->getModuleHandle(), 489 output, 490 &lConfig, 491 &device, 492 address, 493 &mLatency, 494 mFlags); 495 LOG_ALWAYS_FATAL_IF(mDevices.types() != device, 496 "%s openOutput returned device %08x when given device %08x", 497 __FUNCTION__, mDevices.types(), device); 498 499 if (status == NO_ERROR) { 500 LOG_ALWAYS_FATAL_IF(*output == AUDIO_IO_HANDLE_NONE, 501 "%s openOutput returned output handle %d for device %08x", 502 __FUNCTION__, *output, device); 503 mSamplingRate = lConfig.sample_rate; 504 mChannelMask = lConfig.channel_mask; 505 mFormat = lConfig.format; 506 mId = AudioPort::getNextUniqueId(); 507 mIoHandle = *output; 508 mProfile->curOpenCount++; 509 } 510 511 return status; 512 } 513 514 status_t SwAudioOutputDescriptor::start() 515 { 516 if (isDuplicated()) { 517 status_t status = mOutput1->start(); 518 if (status != NO_ERROR) { 519 return status; 520 } 521 status = mOutput2->start(); 522 if (status != NO_ERROR) { 523 mOutput1->stop(); 524 return status; 525 } 526 return NO_ERROR; 527 } 528 if (!isActive()) { 529 if (!mProfile->canStartNewIo()) { 530 return INVALID_OPERATION; 531 } 532 mProfile->curActiveCount++; 533 } 534 return NO_ERROR; 535 } 536 537 void SwAudioOutputDescriptor::stop() 538 { 539 if (isDuplicated()) { 540 mOutput1->stop(); 541 mOutput2->stop(); 542 return; 543 } 544 545 if (!isActive()) { 546 LOG_ALWAYS_FATAL_IF(mProfile->curActiveCount < 1, 547 "%s invalid profile active count %u", 548 __func__, mProfile->curActiveCount); 549 mProfile->curActiveCount--; 550 } 551 } 552 553 void SwAudioOutputDescriptor::close() 554 { 555 if (mIoHandle != AUDIO_IO_HANDLE_NONE) { 556 // clean up active clients if any (can happen if close() is called to force 557 // clients to reconnect 558 for (const auto &client : getClientIterable()) { 559 if (client->active()) { 560 ALOGW("%s client with port ID %d still active on output %d", 561 __func__, client->portId(), mId); 562 setClientActive(client, false); 563 stop(); 564 } 565 } 566 567 AudioParameter param; 568 param.add(String8("closing"), String8("true")); 569 mClientInterface->setParameters(mIoHandle, param.toString()); 570 571 mClientInterface->closeOutput(mIoHandle); 572 573 LOG_ALWAYS_FATAL_IF(mProfile->curOpenCount < 1, "%s profile open count %u", 574 __FUNCTION__, mProfile->curOpenCount); 575 mProfile->curOpenCount--; 576 mIoHandle = AUDIO_IO_HANDLE_NONE; 577 } 578 } 579 580 status_t SwAudioOutputDescriptor::openDuplicating(const sp<SwAudioOutputDescriptor>& output1, 581 const sp<SwAudioOutputDescriptor>& output2, 582 audio_io_handle_t *ioHandle) 583 { 584 // open a duplicating output thread for the new output and the primary output 585 // Note: openDuplicateOutput() API expects the output handles in the reverse order from the 586 // numbering in SwAudioOutputDescriptor mOutput1 and mOutput2 587 *ioHandle = mClientInterface->openDuplicateOutput(output2->mIoHandle, output1->mIoHandle); 588 if (*ioHandle == AUDIO_IO_HANDLE_NONE) { 589 return INVALID_OPERATION; 590 } 591 592 mId = AudioPort::getNextUniqueId(); 593 mIoHandle = *ioHandle; 594 mOutput1 = output1; 595 mOutput2 = output2; 596 mSamplingRate = output2->mSamplingRate; 597 mFormat = output2->mFormat; 598 mChannelMask = output2->mChannelMask; 599 mLatency = output2->mLatency; 600 601 return NO_ERROR; 602 } 603 604 // HwAudioOutputDescriptor implementation 605 HwAudioOutputDescriptor::HwAudioOutputDescriptor(const sp<SourceClientDescriptor>& source, 606 AudioPolicyClientInterface *clientInterface) 607 : AudioOutputDescriptor(source->srcDevice(), clientInterface), 608 mSource(source) 609 { 610 } 611 612 void HwAudioOutputDescriptor::dump(String8 *dst) const 613 { 614 AudioOutputDescriptor::dump(dst); 615 dst->append("Source:\n"); 616 mSource->dump(dst, 0, 0); 617 } 618 619 void HwAudioOutputDescriptor::toAudioPortConfig( 620 struct audio_port_config *dstConfig, 621 const struct audio_port_config *srcConfig) const 622 { 623 mSource->srcDevice()->toAudioPortConfig(dstConfig, srcConfig); 624 } 625 626 void HwAudioOutputDescriptor::toAudioPort( 627 struct audio_port *port) const 628 { 629 mSource->srcDevice()->toAudioPort(port); 630 } 631 632 633 bool HwAudioOutputDescriptor::setVolume(float volumeDb, 634 VolumeSource volumeSource, const StreamTypeVector &streams, 635 audio_devices_t device, 636 uint32_t delayMs, 637 bool force) 638 { 639 bool changed = 640 AudioOutputDescriptor::setVolume(volumeDb, volumeSource, streams, device, delayMs, force); 641 642 if (changed) { 643 // TODO: use gain controller on source device if any to adjust volume 644 } 645 return changed; 646 } 647 648 // SwAudioOutputCollection implementation 649 bool SwAudioOutputCollection::isActive(VolumeSource volumeSource, uint32_t inPastMs) const 650 { 651 nsecs_t sysTime = systemTime(); 652 for (size_t i = 0; i < this->size(); i++) { 653 const sp<SwAudioOutputDescriptor> outputDesc = this->valueAt(i); 654 if (outputDesc->isActive(volumeSource, inPastMs, sysTime)) { 655 return true; 656 } 657 } 658 return false; 659 } 660 661 bool SwAudioOutputCollection::isActiveLocally(VolumeSource volumeSource, uint32_t inPastMs) const 662 { 663 nsecs_t sysTime = systemTime(); 664 for (size_t i = 0; i < this->size(); i++) { 665 const sp<SwAudioOutputDescriptor> outputDesc = this->valueAt(i); 666 if (outputDesc->isActive(volumeSource, inPastMs, sysTime) 667 && ((outputDesc->devices().types() & APM_AUDIO_OUT_DEVICE_REMOTE_ALL) == 0)) { 668 return true; 669 } 670 } 671 return false; 672 } 673 674 bool SwAudioOutputCollection::isActiveRemotely(VolumeSource volumeSource, uint32_t inPastMs) const 675 { 676 nsecs_t sysTime = systemTime(); 677 for (size_t i = 0; i < size(); i++) { 678 const sp<SwAudioOutputDescriptor> outputDesc = valueAt(i); 679 if (((outputDesc->devices().types() & APM_AUDIO_OUT_DEVICE_REMOTE_ALL) != 0) && 680 outputDesc->isActive(volumeSource, inPastMs, sysTime)) { 681 // do not consider re routing (when the output is going to a dynamic policy) 682 // as "remote playback" 683 if (outputDesc->mPolicyMix == NULL) { 684 return true; 685 } 686 } 687 } 688 return false; 689 } 690 691 bool SwAudioOutputCollection::isStrategyActiveOnSameModule(product_strategy_t ps, 692 const sp<SwAudioOutputDescriptor>& desc, 693 uint32_t inPastMs, nsecs_t sysTime) const 694 { 695 for (size_t i = 0; i < size(); i++) { 696 const sp<SwAudioOutputDescriptor> otherDesc = valueAt(i); 697 if (desc->sharesHwModuleWith(otherDesc) && 698 otherDesc->isStrategyActive(ps, inPastMs, sysTime)) { 699 return true; 700 } 701 } 702 return false; 703 } 704 705 audio_io_handle_t SwAudioOutputCollection::getA2dpOutput() const 706 { 707 for (size_t i = 0; i < size(); i++) { 708 sp<SwAudioOutputDescriptor> outputDesc = valueAt(i); 709 if (!outputDesc->isDuplicated() && 710 outputDesc->devices().types() & AUDIO_DEVICE_OUT_ALL_A2DP && 711 outputDesc->deviceSupportsEncodedFormats( 712 AUDIO_DEVICE_OUT_BLUETOOTH_A2DP)) { 713 return this->keyAt(i); 714 } 715 } 716 return 0; 717 } 718 719 bool SwAudioOutputCollection::isA2dpOffloadedOnPrimary() const 720 { 721 sp<SwAudioOutputDescriptor> primaryOutput = getPrimaryOutput(); 722 723 if ((primaryOutput != NULL) && (primaryOutput->mProfile != NULL) 724 && (primaryOutput->mProfile->getModule() != NULL)) { 725 sp<HwModule> primaryHwModule = primaryOutput->mProfile->getModule(); 726 727 for (const auto &outputProfile : primaryHwModule->getOutputProfiles()) { 728 if (outputProfile->supportsDeviceTypes(AUDIO_DEVICE_OUT_ALL_A2DP)) { 729 return true; 730 } 731 } 732 } 733 return false; 734 } 735 736 bool SwAudioOutputCollection::isA2dpSupported() const 737 { 738 return (isA2dpOffloadedOnPrimary() || (getA2dpOutput() != 0)); 739 } 740 741 sp<SwAudioOutputDescriptor> SwAudioOutputCollection::getPrimaryOutput() const 742 { 743 for (size_t i = 0; i < size(); i++) { 744 const sp<SwAudioOutputDescriptor> outputDesc = valueAt(i); 745 if (outputDesc->mFlags & AUDIO_OUTPUT_FLAG_PRIMARY) { 746 return outputDesc; 747 } 748 } 749 return NULL; 750 } 751 752 sp<SwAudioOutputDescriptor> SwAudioOutputCollection::getOutputFromId(audio_port_handle_t id) const 753 { 754 for (size_t i = 0; i < size(); i++) { 755 const sp<SwAudioOutputDescriptor> outputDesc = valueAt(i); 756 if (outputDesc->getId() == id) { 757 return outputDesc; 758 } 759 } 760 return NULL; 761 } 762 763 sp<SwAudioOutputDescriptor> SwAudioOutputCollection::getOutputForClient(audio_port_handle_t portId) 764 { 765 for (size_t i = 0; i < size(); i++) { 766 sp<SwAudioOutputDescriptor> outputDesc = valueAt(i); 767 if (outputDesc->getClient(portId) != nullptr) { 768 return outputDesc; 769 } 770 } 771 return 0; 772 } 773 774 void SwAudioOutputCollection::clearSessionRoutesForDevice( 775 const sp<DeviceDescriptor> &disconnectedDevice) 776 { 777 for (size_t i = 0; i < size(); i++) { 778 sp<AudioOutputDescriptor> outputDesc = valueAt(i); 779 for (const auto& client : outputDesc->getClientIterable()) { 780 if (client->preferredDeviceId() == disconnectedDevice->getId()) { 781 client->setPreferredDeviceId(AUDIO_PORT_HANDLE_NONE); 782 } 783 } 784 } 785 } 786 787 void SwAudioOutputCollection::dump(String8 *dst) const 788 { 789 dst->append("\nOutputs dump:\n"); 790 for (size_t i = 0; i < size(); i++) { 791 dst->appendFormat("- Output %d dump:\n", keyAt(i)); 792 valueAt(i)->dump(dst); 793 } 794 } 795 796 // HwAudioOutputCollection implementation 797 bool HwAudioOutputCollection::isActive(VolumeSource volumeSource, uint32_t inPastMs) const 798 { 799 nsecs_t sysTime = systemTime(); 800 for (size_t i = 0; i < this->size(); i++) { 801 const sp<HwAudioOutputDescriptor> outputDesc = this->valueAt(i); 802 if (outputDesc->isActive(volumeSource, inPastMs, sysTime)) { 803 return true; 804 } 805 } 806 return false; 807 } 808 809 void HwAudioOutputCollection::dump(String8 *dst) const 810 { 811 dst->append("\nOutputs dump:\n"); 812 for (size_t i = 0; i < size(); i++) { 813 dst->appendFormat("- Output %d dump:\n", keyAt(i)); 814 valueAt(i)->dump(dst); 815 } 816 } 817 818 }; //namespace android 819