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 <system/audio.h>
20 #include <utils/Errors.h>
21 #include <utils/SortedVector.h>
22 #include <utils/KeyedVector.h>
23 #include "AudioIODescriptorInterface.h"
24 #include "ClientDescriptor.h"
25 #include "DeviceDescriptor.h"
26 #include "EffectDescriptor.h"
27 #include "IOProfile.h"
28 #include "PolicyAudioPort.h"
29 
30 namespace android {
31 
32 class AudioPolicyMix;
33 class AudioPolicyClientInterface;
34 
35 // descriptor for audio inputs. Used to maintain current configuration of each opened audio input
36 // and keep track of the usage of this input.
37 class AudioInputDescriptor: public AudioPortConfig,
38         public PolicyAudioPortConfig,
39         public AudioIODescriptorInterface,
40         public ClientMapHandler<RecordClientDescriptor>
41 {
42 public:
43     AudioInputDescriptor(const sp<IOProfile>& profile,
44                          AudioPolicyClientInterface *clientInterface,
45                          bool isPreemptor);
46 
47     virtual ~AudioInputDescriptor() = default;
48 
49     audio_module_handle_t getModuleHandle() const;
50 
getDeviceType()51     audio_devices_t getDeviceType() const { return (mDevice != nullptr) ?
52                     mDevice->type() : AUDIO_DEVICE_NONE; }
getDevice()53     sp<DeviceDescriptor> getDevice() const { return mDevice; }
setDevice(const sp<DeviceDescriptor> & device)54     void setDevice(const sp<DeviceDescriptor> &device) { mDevice = device; }
supportedDevices()55     DeviceVector supportedDevices() const  {
56         return mProfile != nullptr ? mProfile->getSupportedDevices() :  DeviceVector(); }
57 
58     void dump(String8 *dst, int spaces, const char* extraInfo) const override;
59 
60     audio_io_handle_t   mIoHandle = AUDIO_IO_HANDLE_NONE; // input handle
61     wp<AudioPolicyMix>  mPolicyMix;                   // non NULL when used by a dynamic policy
62     const sp<IOProfile> mProfile;                     // I/O profile this output derives from
63 
64     // PolicyAudioPortConfig
getPolicyAudioPort()65     virtual sp<PolicyAudioPort> getPolicyAudioPort() const {
66         return mProfile;
67     }
68 
69     // AudioPortConfig
70     virtual status_t applyAudioPortConfig(const struct audio_port_config *config,
71                                           struct audio_port_config *backupConfig = NULL);
72     virtual void toAudioPortConfig(struct audio_port_config *dstConfig,
73             const struct audio_port_config *srcConfig = NULL) const;
getAudioPort()74     virtual sp<AudioPort> getAudioPort() const { return mProfile; }
75 
76     void toAudioPort(struct audio_port_v7 *port) const;
77     void setPreemptedSessions(const SortedVector<audio_session_t>& sessions);
78     SortedVector<audio_session_t> getPreemptedSessions() const;
79     bool hasPreemptedSession(audio_session_t session) const;
80     void clearPreemptedSessions();
isActive()81     bool isActive() const { return mGlobalActiveCount > 0; }
82     bool isSourceActive(audio_source_t source) const;
83     audio_source_t source() const;
84     bool isSoundTrigger() const;
85     sp<RecordClientDescriptor> getHighestPriorityClient() const;
86     audio_attributes_t getHighestPriorityAttributes() const;
87     void setClientActive(const sp<RecordClientDescriptor>& client, bool active);
activeCount()88     int32_t activeCount() { return mGlobalActiveCount; }
89     void trackEffectEnabled(const sp<EffectDescriptor> &effect, bool enabled);
90     EffectDescriptorCollection getEnabledEffects() const;
91     EffectDescriptorCollection getActiveEffects() const; // enabled and not suspended
92     // implementation of AudioIODescriptorInterface
93     audio_config_base_t getConfig() const override;
94     audio_patch_handle_t getPatchHandle() const override;
95     void setPatchHandle(audio_patch_handle_t handle) override;
isMmap()96     bool isMmap() override {
97         if (const auto policyPort = getPolicyAudioPort(); policyPort != nullptr) {
98             if (const auto port = policyPort->asAudioPort(); port != nullptr) {
99                 return port->isMmap();
100             }
101         }
102         return false;
103     }
104 
105     status_t open(const audio_config_t *config,
106                   const sp<DeviceDescriptor> &device,
107                   audio_source_t source,
108                   audio_input_flags_t flags,
109                   audio_io_handle_t *input);
110     // Called when a stream is about to be started.
111     // Note: called after setClientActive(client, true)
112     status_t start();
113     // Called after a stream is stopped
114     // Note: called after setClientActive(client, false)
115     void stop();
116     void close();
117 
118     RecordClientVector getClientsForSession(audio_session_t session);
119     RecordClientVector clientsList(bool activeOnly = false,
120         audio_source_t source = AUDIO_SOURCE_DEFAULT, bool preferredDeviceOnly = false) const;
121 
122     void setAppState(audio_port_handle_t portId, app_state_t state);
123 
124     // implementation of ClientMapHandler<RecordClientDescriptor>
125     void addClient(const sp<RecordClientDescriptor> &client) override;
126 
127     // Go over all active clients and suspend or restore effects according highest priority
128     // active use case
129     void checkSuspendEffects();
130 
isPreemptor()131     bool isPreemptor() const { return mIsPreemptor; }
132 
133  private:
134 
135     void updateClientRecordingConfiguration(int event, const sp<RecordClientDescriptor>& client);
136 
137     audio_patch_handle_t mPatchHandle = AUDIO_PATCH_HANDLE_NONE;
138     sp<DeviceDescriptor> mDevice = nullptr; /**< current device this input is routed to */
139 
140     // Because a preemptible capture session can preempt another one, we end up in an endless loop
141     // situation were each session is allowed to restart after being preempted,
142     // thus preempting the other one which restarts and so on.
143     // To avoid this situation, we store which audio session was preempted when
144     // a particular input started and prevent preemption of this active input by this session.
145     // We also inherit sessions from the preempted input to avoid a 3 way preemption loop etc...
146     SortedVector<audio_session_t> mPreemptedSessions;
147     AudioPolicyClientInterface * const mClientInterface;
148     int32_t mGlobalActiveCount = 0;  // non-client-specific activity ref count
149     EffectDescriptorCollection mEnabledEffects;
150     audio_input_flags_t& mFlags = AudioPortConfig::mFlags.input;
151     bool mIsPreemptor; // true if this input was opened after preemting another one
152 };
153 
154 class AudioInputCollection :
155         public DefaultKeyedVector< audio_io_handle_t, sp<AudioInputDescriptor> >
156 {
157 public:
158     bool isSourceActive(audio_source_t source) const;
159 
160     sp<AudioInputDescriptor> getInputFromId(audio_port_handle_t id) const;
161 
162     // count active capture sessions using one of the specified devices.
163     // ignore devices if empty vector is passed
164     uint32_t activeInputsCountOnDevices(const DeviceVector &devices) const;
165 
166     /**
167      * return io handle of active input or 0 if no input is active
168      * Only considers inputs from physical devices (e.g. main mic, headset mic) when
169      * ignoreVirtualInputs is true.
170      */
171     Vector<sp <AudioInputDescriptor> > getActiveInputs();
172 
173     sp<AudioInputDescriptor> getInputForClient(audio_port_handle_t portId);
174 
175     void trackEffectEnabled(const sp<EffectDescriptor> &effect, bool enabled);
176 
177     /**
178     * @brief clearSessionRoutesForDevice: when a device is disconnected, and if this device has
179     * been chosen as the preferred device by any client, the policy manager shall
180     * prevent from using this device any more by clearing all the session routes involving this
181     * device.
182     * In other words, the preferred device port id of these clients will be resetted to NONE.
183     * @param disconnectedDevice device to be disconnected
184     */
185     void clearSessionRoutesForDevice(const sp<DeviceDescriptor> &disconnectedDevice);
186 
187     void dump(String8 *dst) const;
188 };
189 
190 
191 } // namespace android
192