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 #pragma once 18 19 #include <inttypes.h> 20 21 #include <sys/types.h> 22 23 #include <media/AudioContainers.h> 24 #include <utils/Errors.h> 25 #include <utils/Timers.h> 26 #include <utils/KeyedVector.h> 27 #include <system/audio.h> 28 #include "AudioIODescriptorInterface.h" 29 #include "ClientDescriptor.h" 30 #include "DeviceDescriptor.h" 31 #include "PolicyAudioPort.h" 32 #include "PreferredMixerAttributesInfo.h" 33 #include <vector> 34 35 namespace android { 36 37 class IOProfile; 38 class AudioPolicyMix; 39 class AudioPolicyClientInterface; 40 41 class ActivityTracking 42 { 43 public: 44 virtual ~ActivityTracking() = default; 45 bool isActive(uint32_t inPastMs = 0, nsecs_t sysTime = 0) const 46 { 47 if (mActivityCount > 0) { 48 return true; 49 } 50 if (inPastMs == 0) { 51 return false; 52 } 53 if (sysTime == 0) { 54 sysTime = systemTime(); 55 } 56 if (ns2ms(sysTime - mStopTime) < inPastMs) { 57 return true; 58 } 59 return false; 60 } changeActivityCount(int delta)61 void changeActivityCount(int delta) 62 { 63 if ((delta + (int)mActivityCount) < 0) { 64 LOG_ALWAYS_FATAL("%s: invalid delta %d, refCount %d", __func__, delta, mActivityCount); 65 } 66 mActivityCount += delta; 67 if (!mActivityCount) { 68 setStopTime(systemTime()); 69 } 70 } getActivityCount()71 uint32_t getActivityCount() const { return mActivityCount; } getStopTime()72 nsecs_t getStopTime() const { return mStopTime; } setStopTime(nsecs_t stopTime)73 void setStopTime(nsecs_t stopTime) { mStopTime = stopTime; } 74 dump(String8 * dst,int spaces)75 virtual void dump(String8 *dst, int spaces) const 76 { 77 dst->appendFormat("%*s- ActivityCount: %d, StopTime: %" PRId64 ", ", spaces, "", 78 getActivityCount(), getStopTime()); 79 } 80 private: 81 uint32_t mActivityCount = 0; 82 nsecs_t mStopTime = 0; 83 }; 84 85 /** 86 * @brief VolumeActivity: it tracks the activity for volume policy (volume index, mute, 87 * memorize previous stop, and store mute if incompatible device with another strategy. 88 */ 89 class VolumeActivity : public ActivityTracking 90 { 91 public: isMutedInternally()92 bool isMutedInternally() const { return mMuteCount > 0; } isMutedByGroup()93 bool isMutedByGroup() const { return mMutedByGroup > 0; } setMutedByGroup(bool mutedByGroup)94 void setMutedByGroup(bool mutedByGroup) { mMutedByGroup = mutedByGroup; } getMuteCount()95 int getMuteCount() const { return mMuteCount; } incMuteCount()96 int incMuteCount() { return ++mMuteCount; } decMuteCount()97 int decMuteCount() { return mMuteCount > 0 ? --mMuteCount : -1; } 98 dump(String8 * dst,int spaces)99 void dump(String8 *dst, int spaces) const override 100 { 101 ActivityTracking::dump(dst, spaces); 102 dst->appendFormat(", Volume: %.03f, MuteCount: %02d\n", mCurVolumeDb, mMuteCount); 103 } setVolume(float volumeDb)104 void setVolume(float volumeDb) { mCurVolumeDb = volumeDb; } getVolume()105 float getVolume() const { return mCurVolumeDb; } 106 setIsVoice(bool isVoice)107 void setIsVoice(bool isVoice) { mIsVoice = isVoice; } isVoice()108 bool isVoice() const { return mIsVoice; } 109 110 private: 111 int mMuteCount = 0; /**< mute request counter */ 112 bool mMutedByGroup = false; /**< mute from AudioService, does not add to counter */ 113 float mCurVolumeDb = NAN; /**< current volume in dB. */ 114 bool mIsVoice = false; /** true if this volume source is used for voice call volume */ 115 }; 116 /** 117 * Note: volume activities shall be indexed by CurvesId if we want to allow multiple 118 * curves per volume source, inferring a mute management or volume balancing between HW and SW is 119 * done 120 */ 121 using VolumeActivities = std::map<VolumeSource, VolumeActivity>; 122 123 /** 124 * @brief The Activity class: it tracks the activity for volume policy (volume index, mute, 125 * memorize previous stop, and store mute if incompatible device with another strategy. 126 * Having this class prevents from looping on all attributes (legacy streams) of the strategy 127 */ 128 class RoutingActivity : public ActivityTracking 129 { 130 public: setMutedByDevice(bool isMuted)131 void setMutedByDevice( bool isMuted) { mIsMutedByDevice = isMuted; } isMutedByDevice()132 bool isMutedByDevice() const { return mIsMutedByDevice; } 133 dump(String8 * dst,int spaces)134 void dump(String8 *dst, int spaces) const override { 135 ActivityTracking::dump(dst, spaces); 136 dst->appendFormat("\n"); 137 } 138 private: 139 /** 140 * strategies muted because of incompatible device selection. 141 * See AudioPolicyManager::checkDeviceMuteStrategies() 142 */ 143 bool mIsMutedByDevice = false; 144 }; 145 using RoutingActivities = std::map<product_strategy_t, RoutingActivity>; 146 147 // descriptor for audio outputs. Used to maintain current configuration of each opened audio output 148 // and keep track of the usage of this output by each audio stream type. 149 class AudioOutputDescriptor: public AudioPortConfig, 150 public PolicyAudioPortConfig, 151 public AudioIODescriptorInterface, 152 public ClientMapHandler<TrackClientDescriptor> 153 { 154 public: 155 AudioOutputDescriptor(const sp<PolicyAudioPort>& policyAudioPort, 156 AudioPolicyClientInterface *clientInterface); ~AudioOutputDescriptor()157 virtual ~AudioOutputDescriptor() {} 158 159 void dump(String8 *dst, int spaces, const char* extraInfo = nullptr) const override; 160 void log(const char* indent); 161 devices()162 virtual DeviceVector devices() const { return mDevices; } 163 bool sharesHwModuleWith(const sp<AudioOutputDescriptor>& outputDesc); supportedDevices()164 virtual DeviceVector supportedDevices() const { return mDevices; } isDuplicated()165 virtual bool isDuplicated() const { return false; } latency()166 virtual uint32_t latency() { return 0; } 167 virtual bool isFixedVolume(const DeviceTypeSet& deviceTypes); 168 virtual bool setVolume(float volumeDb, bool muted, 169 VolumeSource volumeSource, const StreamTypeVector &streams, 170 const DeviceTypeSet& deviceTypes, 171 uint32_t delayMs, 172 bool force, 173 bool isVoiceVolSrc = false); 174 175 /** 176 * @brief setStopTime set the stop time due to the client stoppage or a re routing of this 177 * client 178 * @param client to be considered 179 * @param sysTime when the client stopped/was rerouted 180 */ 181 void setStopTime(const sp<TrackClientDescriptor>& client, nsecs_t sysTime); 182 183 /** 184 * Changes the client->active() state and the output descriptor's global active count, 185 * along with the stream active count and mActiveClients. 186 * The client must be previously added by the base class addClient(). 187 * In case of duplicating thread, client shall be added on the duplicated thread, not on the 188 * involved outputs but setClientActive will be called on all output to track strategy and 189 * active client for a given output. 190 * Active ref count of the client will be incremented/decremented through setActive API 191 */ 192 virtual void setClientActive(const sp<TrackClientDescriptor>& client, bool active); 193 bool isClientActive(const sp<TrackClientDescriptor>& client); 194 195 bool isActive(uint32_t inPastMs) const; 196 bool isActive(VolumeSource volumeSource = VOLUME_SOURCE_NONE, 197 uint32_t inPastMs = 0, 198 nsecs_t sysTime = 0) const; 199 bool isAnyActive(VolumeSource volumeSourceToIgnore) const; 200 getActiveVolumeSources()201 std::vector<VolumeSource> getActiveVolumeSources() const { 202 std::vector<VolumeSource> activeList; 203 for (const auto &iter : mVolumeActivities) { 204 if (iter.second.isActive()) { 205 activeList.push_back(iter.first); 206 } 207 } 208 return activeList; 209 } getActivityCount(VolumeSource vs)210 uint32_t getActivityCount(VolumeSource vs) const 211 { 212 return mVolumeActivities.find(vs) != std::end(mVolumeActivities)? 213 mVolumeActivities.at(vs).getActivityCount() : 0; 214 } isMutedInternally(VolumeSource vs)215 bool isMutedInternally(VolumeSource vs) const 216 { 217 return mVolumeActivities.find(vs) != std::end(mVolumeActivities)? 218 mVolumeActivities.at(vs).isMutedInternally() : false; 219 } getMuteCount(VolumeSource vs)220 int getMuteCount(VolumeSource vs) const 221 { 222 return mVolumeActivities.find(vs) != std::end(mVolumeActivities)? 223 mVolumeActivities.at(vs).getMuteCount() : 0; 224 } isMutedByGroup(VolumeSource vs)225 bool isMutedByGroup(VolumeSource vs) 226 { 227 return mVolumeActivities.find(vs) != std::end(mVolumeActivities)? 228 mVolumeActivities.at(vs).isMutedByGroup() : false; 229 } hasVolumeSource(VolumeSource vs)230 bool hasVolumeSource(VolumeSource vs) 231 { 232 return mVolumeActivities.find(vs) != std::end(mVolumeActivities); 233 } incMuteCount(VolumeSource vs)234 int incMuteCount(VolumeSource vs) 235 { 236 return mVolumeActivities[vs].incMuteCount(); 237 } decMuteCount(VolumeSource vs)238 int decMuteCount(VolumeSource vs) 239 { 240 return mVolumeActivities[vs].decMuteCount(); 241 } setCurVolume(VolumeSource vs,float volumeDb,bool mutedByGroup,bool isVoiceVolSrc)242 void setCurVolume(VolumeSource vs, float volumeDb, bool mutedByGroup, bool isVoiceVolSrc) 243 { 244 // Even if not activity for this source registered, need to create anyway 245 mVolumeActivities[vs].setVolume(volumeDb); 246 mVolumeActivities[vs].setMutedByGroup(mutedByGroup); 247 mVolumeActivities[vs].setIsVoice(isVoiceVolSrc); 248 } getCurVolume(VolumeSource vs)249 float getCurVolume(VolumeSource vs) const 250 { 251 return mVolumeActivities.find(vs) != std::end(mVolumeActivities) ? 252 mVolumeActivities.at(vs).getVolume() : NAN; 253 } getVoiceSource()254 VolumeSource getVoiceSource() { 255 for (const auto &iter : mVolumeActivities) { 256 if (iter.second.isVoice()) { 257 return iter.first; 258 } 259 } 260 return VOLUME_SOURCE_NONE; 261 } 262 bool isStrategyActive(product_strategy_t ps, uint32_t inPastMs = 0, nsecs_t sysTime = 0) const 263 { 264 return mRoutingActivities.find(ps) != std::end(mRoutingActivities)? 265 mRoutingActivities.at(ps).isActive(inPastMs, sysTime) : false; 266 } isStrategyMutedByDevice(product_strategy_t ps)267 bool isStrategyMutedByDevice(product_strategy_t ps) const 268 { 269 return mRoutingActivities.find(ps) != std::end(mRoutingActivities)? 270 mRoutingActivities.at(ps).isMutedByDevice() : false; 271 } setStrategyMutedByDevice(product_strategy_t ps,bool isMuted)272 void setStrategyMutedByDevice(product_strategy_t ps, bool isMuted) 273 { 274 mRoutingActivities[ps].setMutedByDevice(isMuted); 275 } 276 277 // PolicyAudioPortConfig getPolicyAudioPort()278 virtual sp<PolicyAudioPort> getPolicyAudioPort() const 279 { 280 return mPolicyAudioPort; 281 } 282 283 // AudioPortConfig 284 virtual status_t applyAudioPortConfig(const struct audio_port_config *config, 285 struct audio_port_config *backupConfig = NULL); 286 virtual void toAudioPortConfig(struct audio_port_config *dstConfig, 287 const struct audio_port_config *srcConfig = NULL) const; getAudioPort()288 virtual sp<AudioPort> getAudioPort() const { return mPolicyAudioPort->asAudioPort(); } 289 290 virtual void toAudioPort(struct audio_port_v7 *port) const; 291 292 audio_module_handle_t getModuleHandle() const; 293 294 // implementation of AudioIODescriptorInterface 295 audio_config_base_t getConfig() const override; 296 audio_patch_handle_t getPatchHandle() const override; 297 void setPatchHandle(audio_patch_handle_t handle) override; isMmap()298 bool isMmap() override { 299 if (const auto policyPort = getPolicyAudioPort(); policyPort != nullptr) { 300 if (const auto port = policyPort->asAudioPort(); port != nullptr) { 301 return port->isMmap(); 302 } 303 } 304 return false; 305 } 306 307 TrackClientVector clientsList(bool activeOnly = false, 308 product_strategy_t strategy = PRODUCT_STRATEGY_NONE, 309 bool preferredDeviceOnly = false) const; 310 311 // override ClientMapHandler to abort when removing a client when active. removeClient(audio_port_handle_t portId)312 void removeClient(audio_port_handle_t portId) override { 313 auto client = getClient(portId); 314 LOG_ALWAYS_FATAL_IF(client.get() == nullptr, 315 "%s(%d): nonexistent client portId %d", __func__, mId, portId); 316 // it is possible that when a client is removed, we could remove its 317 // associated active count by calling changeStreamActiveCount(), 318 // but that would be hiding a problem, so we log fatal instead. 319 auto clientIter = std::find(begin(mActiveClients), end(mActiveClients), client); 320 LOG_ALWAYS_FATAL_IF(clientIter != mActiveClients.end(), 321 "%s(%d) removing client portId %d which is active (count %d)", 322 __func__, mId, portId, client->getActivityCount()); 323 ClientMapHandler<TrackClientDescriptor>::removeClient(portId); 324 } 325 getActiveClients()326 const TrackClientVector& getActiveClients() const { 327 return mActiveClients; 328 } 329 330 // Returns 0 if not all active clients have the same exclusive preferred device 331 // or the number of active clients with the same exclusive preferred device 332 size_t sameExclusivePreferredDevicesCount() const; 333 useHwGain()334 bool useHwGain() const 335 { 336 return !devices().isEmpty() ? devices().itemAt(0)->hasGainController() : false; 337 } isRouted()338 bool isRouted() const { return mPatchHandle != AUDIO_PATCH_HANDLE_NONE; } 339 340 DeviceVector mDevices; /**< current devices this output is routed to */ 341 wp<AudioPolicyMix> mPolicyMix; // non NULL when used by a dynamic policy 342 getRecommendedMuteDurationMs()343 virtual uint32_t getRecommendedMuteDurationMs() const { return 0; } info()344 virtual std::string info() const { 345 std::string result; 346 result.append("[portId:" ); 347 result.append(android::internal::ToString(getId())); 348 result.append("]"); 349 return result; 350 } 351 352 protected: 353 const sp<PolicyAudioPort> mPolicyAudioPort; 354 AudioPolicyClientInterface * const mClientInterface; 355 uint32_t mGlobalActiveCount = 0; // non-client-specific active count 356 audio_patch_handle_t mPatchHandle = AUDIO_PATCH_HANDLE_NONE; 357 audio_output_flags_t& mFlags = AudioPortConfig::mFlags.output; 358 359 // The ActiveClients shows the clients that contribute to the @VolumeSource counts 360 // and may include upstream clients from a duplicating thread. 361 // Compare with the ClientMap (mClients) which are external AudioTrack clients of the 362 // output descriptor (and do not count internal PatchTracks). 363 TrackClientVector mActiveClients; 364 365 RoutingActivities mRoutingActivities; /**< track routing activity on this ouput.*/ 366 367 VolumeActivities mVolumeActivities; /**< track volume activity on this ouput.*/ 368 }; 369 370 // Audio output driven by a software mixer in audio flinger. 371 class SwAudioOutputDescriptor: public AudioOutputDescriptor 372 { 373 public: 374 SwAudioOutputDescriptor(const sp<IOProfile>& profile, 375 AudioPolicyClientInterface *clientInterface); ~SwAudioOutputDescriptor()376 virtual ~SwAudioOutputDescriptor() {} 377 378 void dump(String8 *dst, int spaces, const char* extraInfo = nullptr) const override; 379 virtual DeviceVector devices() const; 380 void setDevices(const DeviceVector &devices); 381 bool sharesHwModuleWith(const sp<SwAudioOutputDescriptor>& outputDesc); 382 virtual DeviceVector supportedDevices() const; 383 virtual bool devicesSupportEncodedFormats(const DeviceTypeSet& deviceTypes); 384 virtual bool containsSingleDeviceSupportingEncodedFormats( 385 const sp<DeviceDescriptor>& device) const; 386 virtual uint32_t latency(); isDuplicated()387 virtual bool isDuplicated() const { return (mOutput1 != NULL && mOutput2 != NULL); } 388 virtual bool isFixedVolume(const DeviceTypeSet& deviceTypes); subOutput1()389 sp<SwAudioOutputDescriptor> subOutput1() { return mOutput1; } subOutput2()390 sp<SwAudioOutputDescriptor> subOutput2() { return mOutput2; } 391 void setClientActive(const sp<TrackClientDescriptor>& client, bool active) override; setAllClientsInactive()392 void setAllClientsInactive() 393 { 394 for (const auto &client : clientsList(true)) { 395 setClientActive(client, false); 396 } 397 } 398 399 /** 400 * @brief setSwMute for SwOutput routed on a device that supports Hw Gain, this function allows 401 * to mute the tracks associated to a given volume source only. 402 * As an output may host one or more source(s), and as AudioPolicyManager may dispatch or not 403 * the volume change request according to the priority of the volume source to control the 404 * unique hw gain controller, a separated API allows to force a mute/unmute of a volume source. 405 * @param muted true to mute, false otherwise 406 * @param vs volume source to be considered 407 * @param device scoped for the change 408 * @param delayMs potentially applyed to prevent cut sounds. 409 */ 410 void setSwMute(bool muted, VolumeSource vs, const StreamTypeVector &streams, 411 const DeviceTypeSet& device, uint32_t delayMs); 412 413 virtual bool setVolume(float volumeDb, bool muted, 414 VolumeSource volumeSource, const StreamTypeVector &streams, 415 const DeviceTypeSet& device, 416 uint32_t delayMs, 417 bool force, 418 bool isVoiceVolSrc = false); 419 420 virtual void toAudioPortConfig(struct audio_port_config *dstConfig, 421 const struct audio_port_config *srcConfig = NULL) const; 422 virtual void toAudioPort(struct audio_port_v7 *port) const; 423 424 status_t open(const audio_config_t *halConfig, 425 const audio_config_base_t *mixerConfig, 426 const DeviceVector &devices, 427 audio_stream_type_t stream, 428 audio_output_flags_t *flags, 429 audio_io_handle_t *output, 430 audio_attributes_t attributes); 431 432 // Called when a stream is about to be started 433 // Note: called before setClientActive(true); 434 status_t start(); 435 // Called after a stream is stopped. 436 // Note: called after setClientActive(false); 437 void stop(); 438 void close(); 439 status_t openDuplicating(const sp<SwAudioOutputDescriptor>& output1, 440 const sp<SwAudioOutputDescriptor>& output2, 441 audio_io_handle_t *ioHandle); 442 443 /** 444 * @brief supportsDevice 445 * @param device to be checked against 446 * @return true if the device is supported by type (for non bus / remote submix devices), 447 * true if the device is supported (both type and address) for bus / remote submix 448 * false otherwise 449 */ 450 bool supportsDevice(const sp<DeviceDescriptor> &device) const; 451 452 /** 453 * @brief supportsAllDevices 454 * @param devices to be checked against 455 * @return true if the device is weakly supported by type (e.g. for non bus / rsubmix devices), 456 * true if the device is supported (both type and address) for bus / remote submix 457 * false otherwise 458 */ 459 bool supportsAllDevices(const DeviceVector &devices) const; 460 461 /** 462 * @brief supportsAtLeastOne checks if any device in devices is currently supported 463 * @param devices to be checked against 464 * @return true if the device is weakly supported by type (e.g. for non bus / rsubmix devices), 465 * true if the device is supported (both type and address) for bus / remote submix 466 * false otherwise 467 */ 468 bool supportsAtLeastOne(const DeviceVector &devices) const; 469 470 /** 471 * @brief supportsDevicesForPlayback 472 * @param devices to be checked against 473 * @return true if the devices is a supported combo for playback 474 * false otherwise 475 */ 476 bool supportsDevicesForPlayback(const DeviceVector &devices) const; 477 478 /** 479 * @brief filterSupportedDevices takes a vector of devices and filters them according to the 480 * device supported by this output (the profile from which this output derives from) 481 * @param devices reference device vector to be filtered 482 * @return vector of devices filtered from the supported devices of this output (weakly or not 483 * depending on the device type) 484 */ 485 DeviceVector filterSupportedDevices(const DeviceVector &devices) const; 486 487 uint32_t getRecommendedMuteDurationMs() const override; 488 489 void setTracksInvalidatedStatusByStrategy(product_strategy_t strategy); 490 491 bool isConfigurationMatched(const audio_config_base_t& config, audio_output_flags_t flags); 492 493 PortHandleVector getClientsForStream(audio_stream_type_t streamType) const; 494 isBitPerfect()495 bool isBitPerfect() const { 496 return (getFlags().output & AUDIO_OUTPUT_FLAG_BIT_PERFECT) != AUDIO_OUTPUT_FLAG_NONE; 497 } 498 499 /** 500 * Return true if there is any client with the same usage active on the given device. 501 * When the given device is null, return true if there is any client active. 502 */ 503 bool isUsageActiveOnDevice(audio_usage_t usage, sp<DeviceDescriptor> device) const; 504 505 virtual std::string info() const override; 506 507 /** 508 * Finds all ports matching the given volume source. 509 * @param vs to be considered 510 * @return vector of ports following the given volume source. 511 */ 512 std::vector<audio_port_handle_t> getPortsForVolumeSource(const VolumeSource& vs); 513 514 const sp<IOProfile> mProfile; // I/O profile this output derives from 515 audio_io_handle_t mIoHandle; // output handle 516 uint32_t mLatency; // 517 using AudioOutputDescriptor::mFlags; 518 sp<SwAudioOutputDescriptor> mOutput1; // used by duplicated outputs: first output 519 sp<SwAudioOutputDescriptor> mOutput2; // used by duplicated outputs: second output 520 uint32_t mDirectOpenCount; // number of clients using this output (direct outputs only) 521 audio_session_t mDirectClientSession; // session id of the direct output client 522 bool mPendingReopenToQueryProfiles = false; 523 audio_channel_mask_t mMixerChannelMask = AUDIO_CHANNEL_NONE; 524 sp<PreferredMixerAttributesInfo> mPreferredAttrInfo = nullptr; 525 }; 526 527 // Audio output driven by an input device directly. 528 class HwAudioOutputDescriptor: public AudioOutputDescriptor 529 { 530 public: 531 HwAudioOutputDescriptor(const sp<SourceClientDescriptor>& source, 532 AudioPolicyClientInterface *clientInterface); ~HwAudioOutputDescriptor()533 virtual ~HwAudioOutputDescriptor() {} 534 535 void dump(String8 *dst, int spaces, const char* extraInfo) const override; 536 537 virtual bool setVolume(float volumeDb, bool muted, 538 VolumeSource volumeSource, const StreamTypeVector &streams, 539 const DeviceTypeSet& deviceTypes, 540 uint32_t delayMs, 541 bool force, 542 bool isVoiceVolSrc = false); 543 544 virtual void toAudioPortConfig(struct audio_port_config *dstConfig, 545 const struct audio_port_config *srcConfig = NULL) const; 546 virtual void toAudioPort(struct audio_port_v7 *port) const; 547 548 const sp<SourceClientDescriptor> mSource; 549 550 }; 551 552 class SwAudioOutputCollection : 553 public DefaultKeyedVector< audio_io_handle_t, sp<SwAudioOutputDescriptor> > 554 { 555 public: 556 bool isActive(VolumeSource volumeSource, uint32_t inPastMs = 0) const; 557 558 /** 559 * return whether any source contributing to VolumeSource is playing remotely, override 560 * to change the definition of 561 * local/remote playback, used for instance by notification manager to not make 562 * media players lose audio focus when not playing locally 563 * For the base implementation, "remotely" means playing during screen mirroring which 564 * uses an output for playback with a non-empty, non "0" address. 565 */ 566 bool isActiveRemotely(VolumeSource volumeSource, uint32_t inPastMs = 0) const; 567 568 /** 569 * return whether any source contributing to VolumeSource is playing, but not on a "remote" 570 * device. 571 * Override to change the definition of a local/remote playback. 572 * Used for instance by policy manager to alter the speaker playback ("speaker safe" behavior) 573 * when media plays or not locally. 574 * For the base implementation, "remotely" means playing during screen mirroring. 575 */ 576 bool isActiveLocally(VolumeSource volumeSource, uint32_t inPastMs = 0) const; 577 578 /** 579 * @brief isStrategyActiveOnSameModule checks if the given strategy is active (or was active 580 * in the past) on the given output and all the outputs belonging to the same HW Module 581 * the same module than the given output 582 * @param outputDesc to be considered 583 * @param ps product strategy to be checked upon activity status 584 * @param inPastMs if 0, check currently, otherwise, check in the past 585 * @param sysTime shall be set if request is done for the past activity. 586 * @return true if an output following the strategy is active on the same module than desc, 587 * false otherwise 588 */ 589 bool isStrategyActiveOnSameModule(product_strategy_t ps, 590 const sp<SwAudioOutputDescriptor>& desc, 591 uint32_t inPastMs = 0, nsecs_t sysTime = 0) const; 592 593 /** 594 * @brief isStrategyActive checks if the given strategy is active 595 * on the given output 596 * @param ps product strategy to be checked upon activity status 597 * @return true if an output following the strategy is active, false otherwise 598 */ 599 bool isStrategyActive(product_strategy_t ps) const; 600 601 /** 602 * @brief clearSessionRoutesForDevice: when a device is disconnected, and if this device has 603 * been chosen as the preferred device by any client, the policy manager shall 604 * prevent from using this device any more by clearing all the session routes involving this 605 * device. 606 * In other words, the preferred device port id of these clients will be resetted to NONE. 607 * @param disconnectedDevice device to be disconnected 608 */ 609 void clearSessionRoutesForDevice(const sp<DeviceDescriptor> &disconnectedDevice); 610 611 /** 612 * returns the A2DP output handle if it is open or 0 otherwise 613 */ 614 audio_io_handle_t getA2dpOutput() const; 615 616 /** 617 * returns true if primary HAL supports A2DP Offload 618 */ 619 bool isA2dpOffloadedOnPrimary() const; 620 621 sp<SwAudioOutputDescriptor> getOutputFromId(audio_port_handle_t id) const; 622 623 sp<SwAudioOutputDescriptor> getPrimaryOutput() const; 624 625 /** 626 * @brief isAnyOutputActive checks if any output is active (aka playing) except the one(s) that 627 * hold the volume source to be ignored 628 * @param volumeSourceToIgnore source not to be considered in the activity detection 629 * @return true if any output is active for any volume source except the one to be ignored 630 */ isAnyOutputActive(VolumeSource volumeSourceToIgnore)631 bool isAnyOutputActive(VolumeSource volumeSourceToIgnore) const 632 { 633 for (size_t i = 0; i < size(); i++) { 634 const sp<AudioOutputDescriptor> &outputDesc = valueAt(i); 635 if (outputDesc->isAnyActive(volumeSourceToIgnore)) { 636 return true; 637 } 638 } 639 return false; 640 } 641 642 audio_devices_t getSupportedDevices(audio_io_handle_t handle) const; 643 644 sp<SwAudioOutputDescriptor> getOutputForClient(audio_port_handle_t portId); 645 646 /** 647 * return whether any output is active and routed to any of the specified devices 648 */ 649 bool isAnyDeviceTypeActive(const DeviceTypeSet& deviceTypes) const; 650 651 bool isUsageActiveOnDevice(audio_usage_t usage, sp<DeviceDescriptor> device) const; 652 653 void dump(String8 *dst) const; 654 }; 655 656 class HwAudioOutputCollection : 657 public DefaultKeyedVector< audio_io_handle_t, sp<HwAudioOutputDescriptor> > 658 { 659 public: 660 bool isActive(VolumeSource volumeSource, uint32_t inPastMs = 0) const; 661 662 /** 663 * @brief isAnyOutputActive checks if any output is active (aka playing) except the one(s) that 664 * hold the volume source to be ignored 665 * @param volumeSourceToIgnore source not to be considered in the activity detection 666 * @return true if any output is active for any volume source except the one to be ignored 667 */ isAnyOutputActive(VolumeSource volumeSourceToIgnore)668 bool isAnyOutputActive(VolumeSource volumeSourceToIgnore) const 669 { 670 for (size_t i = 0; i < size(); i++) { 671 const sp<AudioOutputDescriptor> &outputDesc = valueAt(i); 672 if (outputDesc->isAnyActive(volumeSourceToIgnore)) { 673 return true; 674 } 675 } 676 return false; 677 } 678 679 void dump(String8 *dst) const; 680 }; 681 682 683 } // namespace android 684