Tomasz Wiszkowski | b34828c | 2017-09-28 14:03:41 -0700 | [diff] [blame] | 1 | /* |
Tomasz Wiszkowski | bbf8c0b | 2017-09-28 14:23:06 -0700 | [diff] [blame] | 2 | * Copyright (C) 2017 The Android Open Source Project |
Tomasz Wiszkowski | b34828c | 2017-09-28 14:03:41 -0700 | [diff] [blame] | 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 | */ |
Tomasz Wiszkowski | bbf8c0b | 2017-09-28 14:23:06 -0700 | [diff] [blame] | 16 | #pragma once |
Tomasz Wiszkowski | b34828c | 2017-09-28 14:03:41 -0700 | [diff] [blame] | 17 | |
Tomasz Wiszkowski | b34828c | 2017-09-28 14:03:41 -0700 | [diff] [blame] | 18 | #include <list> |
| 19 | #include <map> |
Tomasz Wiszkowski | b34828c | 2017-09-28 14:03:41 -0700 | [diff] [blame] | 20 | |
Tomasz Wiszkowski | bbf8c0b | 2017-09-28 14:23:06 -0700 | [diff] [blame] | 21 | #include "common/libs/fs/shared_fd.h" |
Greg Hartman | a4ff248 | 2017-10-03 16:35:00 -0700 | [diff] [blame^] | 22 | #include "common/libs/threads/cuttlefish_thread.h" |
Tomasz Wiszkowski | bbf8c0b | 2017-09-28 14:23:06 -0700 | [diff] [blame] | 23 | #include "guest/commands/audio/audio_hal.h" |
| 24 | #include "guest/commands/audio/vsoc_audio_input_stream.h" |
| 25 | #include "guest/commands/audio/vsoc_audio_message.h" |
| 26 | #include "guest/libs/platform_support/api_level_fixes.h" |
Tomasz Wiszkowski | b34828c | 2017-09-28 14:03:41 -0700 | [diff] [blame] | 27 | |
| 28 | namespace avd { |
| 29 | |
| 30 | class GceAudioInputStream; |
| 31 | class GceAudioOutputStream; |
| 32 | |
| 33 | class GceAudio : public audio_hw_device { |
| 34 | public: |
| 35 | // This common code manipulates the parameters of input and output streams. |
| 36 | static int SetStreamParameters(struct audio_stream *, const char *); |
| 37 | |
| 38 | ~GceAudio(); |
| 39 | |
| 40 | // Non-HAL methods that are part of the GCE implementation. |
| 41 | // Most of these are used by the input and output streams. |
| 42 | |
| 43 | // Returns true if the microphone is muted. Used by input streams. |
| 44 | bool IsMicrophoneMuted() { |
| 45 | avd::LockGuard<avd::Mutex> guard(lock_); |
| 46 | return mic_muted_; |
| 47 | } |
| 48 | |
| 49 | // Retrieves the SharedFD of the process accepting audio data. |
| 50 | // Returns a non-open fd if no process is listening (the normal case). |
| 51 | avd::SharedFD GetAudioFd(); |
| 52 | |
| 53 | // Send a message to the connected streamer. |
| 54 | // Returns: |
| 55 | // 0 if there is no streamer. |
| 56 | // >0 if the message was sent. |
| 57 | // -1 if there was an error. |
| 58 | ssize_t SendMsg(const msghdr&, int flags); |
| 59 | |
| 60 | // Sends a stream update to the connected streamer. |
| 61 | // Stream updates have no frames. Use SendMsg if the message has frames. |
| 62 | // 0 if there is no streamer. |
| 63 | // >0 if the message was sent. |
| 64 | // -1 if there was an error. |
| 65 | ssize_t SendStreamUpdate( |
| 66 | const gce_audio_message& stream_info, int flags); |
| 67 | |
| 68 | // Callbacks for the Android audio_module HAL interface. |
| 69 | // Most of the comments below are copied from |
| 70 | // libhardware/include/hardware/audio.h |
| 71 | // |
| 72 | // Where the is a conflict the comments there apply. |
| 73 | // By default these methods return 0 on success -<errno> for failure. |
| 74 | |
| 75 | // Opens the device. |
| 76 | static int Open(const hw_module_t* module, const char* name, |
| 77 | hw_device_t** device); |
| 78 | |
| 79 | // Closes the device, closing any open input streams and output streams. |
| 80 | int Close(); |
| 81 | |
| 82 | // Closes the input stream, throwing away any data in the buffer. |
| 83 | void CloseInputStream(audio_stream_in* stream); |
| 84 | |
| 85 | // Closes the output stream without waiting for the buffer to clear. |
| 86 | void CloseOutputStream(audio_stream_out* stream); |
| 87 | |
| 88 | // Creates an audio patch between several source and sink ports. |
| 89 | // The handle is allocated by the HAL and should be unique for this |
| 90 | // audio HAL module. |
| 91 | // TODO(ghartman): Implement this as part of HAL 3.0 |
| 92 | //int CreateAudioPatch(unsigned int num_sources, |
| 93 | // const struct audio_port_config *sources, |
| 94 | // unsigned int num_sinks, |
| 95 | // const struct audio_port_config *sinks, |
| 96 | // audio_patch_handle_t *handle); |
| 97 | |
| 98 | // dumps the state of the audio hardware to the given fd. |
| 99 | // This information can be retrieved using the dumpsys utility. |
| 100 | int Dump(int fd) const; |
| 101 | |
| 102 | // Fills the list of supported attributes for a given audio port. |
| 103 | // As input, "port" contains the information (type, role, address etc...) |
| 104 | // needed by the HAL to identify the port. |
| 105 | // As output, "port" contains possible attributes (sampling rates, formats, |
| 106 | // channel masks, gain controllers...) for this port. |
| 107 | // TODO(ghartman): Implement this as part of HAL 3.0 |
| 108 | // int GetAudioPort(struct audio_port *port); |
| 109 | |
| 110 | // Sets audio port configuration |
| 111 | // TODO(ghartman): Implement this as part of HAL 3.0 |
| 112 | // int SetAudioPortConfig(const struct audio_port_config *config); |
| 113 | |
| 114 | size_t GetInputBufferSize(const audio_config*) const; |
| 115 | |
| 116 | // Gets the current master volume value for the HAL, if the HAL supports |
| 117 | // master volume control. AudioFlinger will query this value from the |
| 118 | // primary audio HAL when the service starts and use the value for setting |
| 119 | // the initial master volume across all HALs. HALs which do not support |
| 120 | // this method may leave it set to NULL. |
| 121 | int GetMasterVolume(float* /*volume*/); |
| 122 | |
| 123 | // Get the current master mute status for the HAL, if the HAL supports |
| 124 | // master mute control. AudioFlinger will query this value from the primary |
| 125 | // audio HAL when the service starts and use the value for setting the |
| 126 | // initial master mute across all HALs. HALs which do not support this |
| 127 | // method may leave it set to NULL. |
| 128 | int GetMasterMute(bool* muted); |
| 129 | |
| 130 | // Gets the audio mute status for the microphone. |
| 131 | int GetMicMute(bool* state) const; |
| 132 | |
| 133 | // Retrieves the global audio parameters. |
| 134 | // TODO(ghartman): Implement this. |
| 135 | char* GetParameters(const char* keys) const; |
| 136 | |
| 137 | // Enumerates what devices are supported by each audio_hw_device |
| 138 | // implementation. |
| 139 | // Return value is a bitmask of 1 or more values of audio_devices_t |
| 140 | // used by audio flinger. |
| 141 | // NOTE: audio HAL implementations starting with |
| 142 | // AUDIO_DEVICE_API_VERSION_2_0 do not implement this function. |
| 143 | // AUDIO_DEVICE_API_VERSION_2_0 was the current version as of JB-MR1 |
| 144 | // All supported devices should be listed in audio_policy.conf |
| 145 | // file and the audio policy manager must choose the appropriate |
| 146 | // audio module based on information in this file. |
| 147 | uint32_t GetSupportedDevices() const; |
| 148 | |
| 149 | // Checks to see if the audio hardware interface has been initialized. |
| 150 | // Always returns 0 to indicate success, but -ENODEV is also allowed to |
| 151 | // indicate failure. |
| 152 | int InitCheck() const; |
| 153 | |
| 154 | // Creates an additional hardware input stream. |
| 155 | // Additional parameters were added in the 3.0 version of the HAL. |
| 156 | // These defaults make it easier to implement a cross-branch device. |
| 157 | int OpenInputStream( |
| 158 | audio_io_handle_t handle, |
| 159 | audio_devices_t devices, audio_config *config, |
| 160 | audio_stream_in **stream_in, |
| 161 | audio_input_flags_t flags = AUDIO_INPUT_FLAG_NONE, |
| 162 | const char* address = 0, |
| 163 | audio_source_t source = AUDIO_SOURCE_DEFAULT); |
| 164 | |
| 165 | // Creates an additional output stream. |
| 166 | // The "address" parameter qualifies the "devices" audio device type if |
| 167 | // needed. On GCE we ignore it for now because we simulate a single SoC |
| 168 | // hw devices. |
| 169 | // |
| 170 | // The format format depends on the device type: |
| 171 | // Bluetooth devices use the MAC address of the device in the form |
| 172 | // "00:11:22:AA:BB:CC" |
| 173 | // USB devices use the ALSA card and device numbers in the form |
| 174 | // "card=X;device=Y" |
| 175 | // Other devices may use a number or any other string. |
| 176 | int OpenOutputStream( |
| 177 | audio_io_handle_t handle, |
| 178 | audio_devices_t devices, audio_output_flags_t flags, |
| 179 | audio_config* config, audio_stream_out** stream_out, |
| 180 | const char* address = 0); |
| 181 | |
| 182 | // Releases an audio patch. |
| 183 | // TODO(ghartman): Implement this as part of HAL 3.0 |
| 184 | //int ReleaseAudioPatch(audio_patch_handle_t handle); |
| 185 | |
| 186 | // Sets the audio mute status for all audio activities. If any value other |
| 187 | // than 0 is returned, the software mixer will emulate this capability. |
| 188 | // The GCE implementation always returns 0. |
| 189 | int SetMasterMute(bool muted); |
| 190 | |
| 191 | // Sets the audio volume for all audio activities other than voice call. |
| 192 | // Range between 0.0 and 1.0. If any value other than 0 is returned, |
| 193 | // the software mixer will emulate this capability. |
| 194 | // The GCE implementation always returns 0. |
| 195 | int SetMasterVolume(float volume); |
| 196 | |
| 197 | // Sets the audio mute status for the microphone. |
| 198 | int SetMicMute(bool state); |
| 199 | |
| 200 | // set_mode is called when the audio mode changes. AUDIO_MODE_NORMAL mode |
| 201 | // is for standard audio playback, AUDIO_MODE_RINGTONE when a ringtone is |
| 202 | // playing, and AUDIO_MODE_IN_CALL when a call is in progress. |
| 203 | int SetMode(audio_mode_t mode); |
| 204 | |
| 205 | // Sets the global audio parameters. |
| 206 | // TODO(ghartman): Create a sensible implementation. |
| 207 | int SetParameters(const char* kvpairs); |
| 208 | |
| 209 | // Sets the audio volume of a voice call. Range is between 0.0 and 1.0 |
| 210 | int SetVoiceVolume(float volume); |
| 211 | |
| 212 | |
| 213 | private: |
| 214 | // Main routine for a thread that listens for incoming streamer connections. |
| 215 | void* Listener(); |
| 216 | // HAL 3.0 modifies the signatures of OpenInputStream and OpenOutputStream. |
| 217 | // We don't want to fork the implementation, and we don't want #ifdefs all |
| 218 | // over the code. The current implementation defines OpenInputStream and |
| 219 | // OpenOutputStream with default values for the paramteres that were added, |
| 220 | // and then generates a HAL-specific wrapper to be used in the function |
| 221 | // table. |
| 222 | #if defined(AUDIO_DEVICE_API_VERSION_3_0) |
| 223 | typedef int OpenInputStreamHAL_t( |
| 224 | audio_io_handle_t, audio_devices_t, audio_config*, audio_stream_in**, |
| 225 | audio_input_flags_t, const char*, audio_source_t); |
| 226 | |
| 227 | int OpenInputStreamCurrentHAL( |
| 228 | audio_io_handle_t a, audio_devices_t b, audio_config* c, |
| 229 | audio_stream_in** d, audio_input_flags_t e, const char* f, |
| 230 | audio_source_t g) { |
| 231 | return OpenInputStream(a, b, c, d, e, f, g); |
| 232 | } |
| 233 | |
| 234 | typedef int OpenOutputStreamHAL_t( |
| 235 | audio_io_handle_t, audio_devices_t, audio_output_flags_t, |
| 236 | audio_config*, audio_stream_out**, |
| 237 | const char*); |
| 238 | |
| 239 | int OpenOutputStreamCurrentHAL( |
| 240 | audio_io_handle_t a, audio_devices_t b, audio_output_flags_t c, |
| 241 | audio_config* d, audio_stream_out** e, |
| 242 | const char* f) { |
| 243 | return OpenOutputStream(a, b, c, d, e, f); |
| 244 | } |
| 245 | #else |
| 246 | typedef int OpenInputStreamHAL_t( |
| 247 | audio_io_handle_t, audio_devices_t, audio_config*, audio_stream_in**); |
| 248 | |
| 249 | int OpenInputStreamCurrentHAL( |
| 250 | audio_io_handle_t a, audio_devices_t b, audio_config* c, |
| 251 | audio_stream_in** d) { |
| 252 | return OpenInputStream(a, b, c, d); |
| 253 | } |
| 254 | |
| 255 | typedef int OpenOutputStreamHAL_t( |
| 256 | audio_io_handle_t, audio_devices_t, audio_output_flags_t, |
| 257 | audio_config*, audio_stream_out**); |
| 258 | |
| 259 | int OpenOutputStreamCurrentHAL( |
| 260 | audio_io_handle_t a, audio_devices_t b, audio_output_flags_t c, |
| 261 | audio_config* d, audio_stream_out** e) { |
| 262 | return OpenOutputStream(a, b, c, d, e); |
| 263 | } |
| 264 | #endif |
| 265 | |
| 266 | //TODO(ghartman): Update this when we support 3.0. |
| 267 | #if defined(AUDIO_DEVICE_API_VERSION_2_0) |
| 268 | static const unsigned int version_ = AUDIO_DEVICE_API_VERSION_2_0; |
| 269 | #else |
| 270 | static const unsigned int version_ = AUDIO_DEVICE_API_VERSION_1_0; |
| 271 | #endif |
| 272 | |
| 273 | // Thread to handle new connections. |
| 274 | pthread_t listener_thread_; |
| 275 | // Event to indicate that the listener thread should terminate. |
| 276 | avd::SharedFD terminate_listener_thread_event_; |
| 277 | // The listener socket, which is polled for new connections. |
| 278 | // TODO(ghartman): Consider using a thread. |
| 279 | avd::SharedFD audio_listener_socket_; |
| 280 | // Lock to protect the data below. |
| 281 | mutable avd::Mutex lock_; |
| 282 | // The data socket for the current streamer. Typically -1. |
| 283 | // The behavior of the HAL should not be affected by the presence or absence |
| 284 | // of the streamer. |
| 285 | avd::SharedFD audio_data_socket_; |
| 286 | // State that is managed at the device level. |
| 287 | float voice_volume_; |
| 288 | float master_volume_; |
| 289 | bool master_muted_; |
| 290 | bool mic_muted_; |
| 291 | audio_mode_t mode_; |
| 292 | // There can be multiple input and output streams. This field is used |
| 293 | // to assign each one a unique identifier. |
| 294 | // TODO(ghartman): This can wrap after 2^32 streams. Ideally we should check |
| 295 | // the output_list_ to ensure that the stream number hasn't been assigned. |
| 296 | // However, streams don't really appear and disapper that often. |
| 297 | // We use the same counter for both input and output streams to make things |
| 298 | // a little easier on the client. |
| 299 | uint32_t next_stream_number_; |
| 300 | // List of the currently active output streams. |
| 301 | // Used to clean things up Close() |
| 302 | std::list<GceAudioOutputStream *> output_list_; |
| 303 | // List of the currently active input streams. |
| 304 | // Used to clean things up Close() |
| 305 | typedef std::map<uint32_t, GceAudioInputStream *> input_map_t; |
| 306 | input_map_t input_map_; |
| 307 | |
| 308 | GceAudio() : |
| 309 | audio_hw_device(), |
| 310 | terminate_listener_thread_event_(avd::SharedFD::Event()), |
| 311 | voice_volume_(0.0), |
| 312 | master_volume_(0.0), |
| 313 | master_muted_(false), |
| 314 | mic_muted_(false), |
| 315 | mode_(AUDIO_MODE_NORMAL), |
| 316 | next_stream_number_(1) { } |
| 317 | }; |
| 318 | |
| 319 | } |
| 320 | |