1 // 2 // Copyright (C) 2020 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 #pragma once 16 17 #include <cinttypes> 18 19 #include <functional> 20 #include <memory> 21 22 #include "common/libs/fs/shared_fd.h" 23 #include "host/libs/audio_connector/buffers.h" 24 #include "host/libs/audio_connector/commands.h" 25 #include "host/libs/audio_connector/shm_layout.h" 26 27 namespace cuttlefish { 28 29 // Callbacks into objects implementing this interface will be made from the same 30 // thread that handles the connection fd. Implementations should make every 31 // effort to return immediately to avoid blocking the server's main loop. 32 class AudioServerExecutor { 33 public: 34 virtual ~AudioServerExecutor() = default; 35 36 // Implementations must ensure each command is replied to before returning 37 // from these functions. Failure to do so causes the program to abort. 38 virtual void StreamsInfo(StreamInfoCommand& cmd) = 0; 39 virtual void SetStreamParameters(StreamSetParamsCommand& cmd) = 0; 40 virtual void PrepareStream(StreamControlCommand& cmd) = 0; 41 virtual void ReleaseStream(StreamControlCommand& cmd) = 0; 42 virtual void StartStream(StreamControlCommand& cmd) = 0; 43 virtual void StopStream(StreamControlCommand& cmd) = 0; 44 virtual void ChmapsInfo(ChmapInfoCommand& cmd) = 0; 45 virtual void JacksInfo(JackInfoCommand& cmd) = 0; 46 47 // Implementations must call buffer.SendStatus() before destroying the buffer 48 // to notify the other side of the release of the buffer. Failure to do so 49 // will cause the program to abort. 50 virtual void OnPlaybackBuffer(TxBuffer buffer) = 0; 51 virtual void OnCaptureBuffer(RxBuffer buffer) = 0; 52 }; 53 54 class AudioClientConnection { 55 public: 56 static std::unique_ptr<AudioClientConnection> Create( 57 SharedFD client_socket, uint32_t num_streams, uint32_t num_jacks, 58 uint32_t num_chmaps, size_t tx_shm_len, size_t rx_shm_len); 59 60 AudioClientConnection() = delete; 61 AudioClientConnection(const AudioClientConnection&) = delete; 62 63 AudioClientConnection& operator=(const AudioClientConnection&) = delete; 64 65 // Allows the caller to react to commands sent by the client. 66 bool ReceiveCommands(AudioServerExecutor& executor); 67 // Allows the caller to react to IO buffers sent by the client. 68 bool ReceivePlayback(AudioServerExecutor& executor); 69 bool ReceiveCapture(AudioServerExecutor& executor); 70 71 bool SendEvent(/*TODO*/); 72 73 private: AudioClientConnection(ScopedMMap tx_shm,ScopedMMap rx_shm,SharedFD control_socket,SharedFD event_socket,SharedFD tx_socket,SharedFD rx_socket)74 AudioClientConnection(ScopedMMap tx_shm, ScopedMMap rx_shm, 75 SharedFD control_socket, SharedFD event_socket, 76 SharedFD tx_socket, SharedFD rx_socket) 77 : tx_shm_(std::move(tx_shm)), 78 rx_shm_(std::move(rx_shm)), 79 control_socket_(control_socket), 80 event_socket_(event_socket), 81 tx_socket_(tx_socket), 82 rx_socket_(rx_socket) {} 83 84 bool CmdReply(AudioStatus status, const void* data = nullptr, 85 size_t size = 0); 86 bool WithCommand(const virtio_snd_hdr* msg, size_t msg_len, 87 AudioServerExecutor& executor); 88 89 ssize_t ReceiveMsg(SharedFD socket, void* buffer, size_t size); 90 91 ScopedMMap tx_shm_; 92 ScopedMMap rx_shm_; 93 SharedFD control_socket_; 94 SharedFD event_socket_; 95 SharedFD tx_socket_; 96 SharedFD rx_socket_; 97 }; 98 99 class AudioServer { 100 public: AudioServer(SharedFD server_socket)101 AudioServer(SharedFD server_socket) : server_socket_(server_socket) {} 102 103 std::unique_ptr<AudioClientConnection> AcceptClient(uint32_t num_streams, 104 uint32_t num_jacks, 105 uint32_t num_chmaps, 106 size_t tx_shm_len, 107 size_t rx_shm_len); 108 109 private: 110 SharedFD server_socket_; 111 }; 112 113 } // namespace cuttlefish 114