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