TYPE3
[iec.git] / src / type3_AndroidCloud / anbox-master / src / anbox / audio / server.cpp
1 /*
2  * Copyright (C) 2017 Simon Fels <morphis@gravedo.de>
3  *
4  * This program is free software: you can redistribute it and/or modify it
5  * under the terms of the GNU General Public License version 3, as published
6  * by the Free Software Foundation.
7  *
8  * This program is distributed in the hope that it will be useful, but
9  * WITHOUT ANY WARRANTY; without even the implied warranties of
10  * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
11  * PURPOSE.  See the GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License along
14  * with this program.  If not, see <http://www.gnu.org/licenses/>.
15  *
16  */
17
18 #include "anbox/audio/server.h"
19 #include "anbox/audio/sink.h"
20 #include "anbox/network/published_socket_connector.h"
21 #include "anbox/network/delegate_connection_creator.h"
22 #include "anbox/network/local_socket_messenger.h"
23 #include "anbox/network/message_processor.h"
24 #include "anbox/common/type_traits.h"
25 #include "anbox/system_configuration.h"
26 #include "anbox/utils.h"
27 #include "anbox/logger.h"
28
29 using namespace std::placeholders;
30
31 namespace {
32 class AudioForwarder : public anbox::network::MessageProcessor {
33  public:
34   AudioForwarder(const std::shared_ptr<anbox::audio::Sink> &sink) :
35     sink_(sink) {
36   }
37
38   bool process_data(const std::vector<std::uint8_t> &data) override {
39     sink_->write_data(data);
40     return true;
41   }
42
43  private:
44   std::shared_ptr<anbox::audio::Sink> sink_;
45 };
46 }
47
48 namespace anbox {
49 namespace audio {
50 Server::Server(const std::shared_ptr<Runtime>& rt, const std::shared_ptr<platform::BasePlatform> &platform) :
51   platform_(platform),
52   socket_file_(utils::string_format("%s/anbox_audio", SystemConfiguration::instance().socket_dir())),
53   connector_(std::make_shared<network::PublishedSocketConnector>(
54              socket_file_, rt,
55              std::make_shared<network::DelegateConnectionCreator<boost::asio::local::stream_protocol>>(std::bind(&Server::create_connection_for, this, _1)))),
56   connections_(std::make_shared<network::Connections<network::SocketConnection>>()),
57   next_id_(0) {
58
59   // FIXME: currently creating the socket creates it with the rights of
60   // the user we're running as. As this one is mapped into the container
61   ::chmod(socket_file_.c_str(), 0777);
62 }
63
64 Server::~Server() {}
65
66 void Server::create_connection_for(std::shared_ptr<boost::asio::basic_stream_socket<boost::asio::local::stream_protocol>> const& socket) {
67   auto const messenger =
68       std::make_shared<network::LocalSocketMessenger>(socket);
69
70   // We have to read the client flags first before we can continue
71   // processing the actual commands
72   ClientInfo client_info;
73   auto err = messenger->receive_msg(
74       boost::asio::buffer(&client_info, sizeof(ClientInfo)));
75   if (err) {
76     ERROR("Failed to read client info: %s", err.message());
77     return;
78   }
79
80   std::shared_ptr<network::MessageProcessor> processor;
81
82   switch (client_info.type) {
83   case ClientInfo::Type::Playback:
84     processor = std::make_shared<AudioForwarder>(platform_->create_audio_sink());
85     break;
86   case ClientInfo::Type::Recording:
87     break;
88   default:
89     ERROR("Invalid client type %d", static_cast<int>(client_info.type));
90     return;
91   }
92
93   // Everything ok, so approve the client by sending the requesting client
94   // info back. Once we have more things to negotiate we will send a modified
95   // client info struct back.
96   messenger->send(reinterpret_cast<char*>(&client_info), sizeof(client_info));
97
98   auto connection = std::make_shared<network::SocketConnection>(
99         messenger, messenger, next_id(), connections_, processor);
100   connections_->add(connection);
101
102   connection->read_next_message();
103 }
104
105 int Server::next_id() {
106   return next_id_.fetch_add(1);
107 }
108 } // namespace audio
109 } // namespace anbox