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