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