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