Home | History | Annotate | Download | only in include
      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     }
     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     }
     70     uint32_t getActivityCount() const { return mActivityCount; }
     71     nsecs_t getStopTime() const { return mStopTime; }
     72     void setStopTime(nsecs_t stopTime) { mStopTime = stopTime; }
     73 
     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:
     91     bool isMuted() const { return mMuteCount > 0; }
     92     int getMuteCount() const { return mMuteCount; }
     93     int incMuteCount() { return ++mMuteCount; }
     94     int decMuteCount() { return mMuteCount > 0 ? --mMuteCount : -1; }
     95 
     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     }
    101     void setVolume(float volumeDb) { mCurVolumeDb = volumeDb; }
    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:
    123     void setMutedByDevice( bool isMuted) { mIsMutedByDevice = isMuted; }
    124     bool isMutedByDevice() const { return mIsMutedByDevice; }
    125 
    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);
    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;
    153     virtual DeviceVector devices() const { return mDevices; }
    154     bool sharesHwModuleWith(const sp<AudioOutputDescriptor>& outputDesc);
    155     virtual DeviceVector supportedDevices() const  { return mDevices; }
    156     virtual bool isDuplicated() const { return false; }
    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 
    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     }
    199     uint32_t getActivityCount(VolumeSource vs) const
    200     {
    201         return mVolumeActivities.find(vs) != std::end(mVolumeActivities)?
    202                     mVolumeActivities.at(vs).getActivityCount() : 0;
    203     }
    204     bool isMuted(VolumeSource vs) const
    205     {
    206         return mVolumeActivities.find(vs) != std::end(mVolumeActivities)?
    207                     mVolumeActivities.at(vs).isMuted() : false;
    208     }
    209     int getMuteCount(VolumeSource vs) const
    210     {
    211         return mVolumeActivities.find(vs) != std::end(mVolumeActivities)?
    212                     mVolumeActivities.at(vs).getMuteCount() : 0;
    213     }
    214     int incMuteCount(VolumeSource vs)
    215     {
    216         return mVolumeActivities[vs].incMuteCount();
    217     }
    218     int decMuteCount(VolumeSource vs)
    219     {
    220         return mVolumeActivities[vs].decMuteCount();
    221     }
    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     }
    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     }
    238     bool isStrategyMutedByDevice(product_strategy_t ps) const
    239     {
    240         return mRoutingActivities.find(ps) != std::end(mRoutingActivities)?
    241                     mRoutingActivities.at(ps).isMutedByDevice() : false;
    242     }
    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;
    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.
    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 
    279     const TrackClientVector& getActiveClients() const {
    280         return mActiveClients;
    281     }
    282 
    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);
    315     virtual ~SwAudioOutputDescriptor() {}
    316 
    317             void dump(String8 *dst) const override;
    318     virtual DeviceVector devices() const;
    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();
    324     virtual bool isDuplicated() const { return (mOutput1 != NULL && mOutput2 != NULL); }
    325     virtual bool isFixedVolume(audio_devices_t device);
    326     sp<SwAudioOutputDescriptor> subOutput1() { return mOutput1; }
    327     sp<SwAudioOutputDescriptor> subOutput2() { return mOutput2; }
    328     void setClientActive(const sp<TrackClientDescriptor>& client, bool active) override;
    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);
    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      */
    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      */
    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