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