2 * Copyright (C) 2016 Simon Fels <morphis@gravedo.de>
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.
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.
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/>.
20 #include "anbox/graphics/opengles_message_processor.h"
21 #include "anbox/logger.h"
22 #include "anbox/network/local_socket_messenger.h"
23 #include "anbox/qemu/adb_message_processor.h"
24 #include "anbox/qemu/boot_properties_message_processor.h"
25 #include "anbox/qemu/bootanimation_message_processor.h"
26 #include "anbox/qemu/camera_message_processor.h"
27 #include "anbox/qemu/fingerprint_message_processor.h"
28 #include "anbox/qemu/gsm_message_processor.h"
29 #include "anbox/qemu/hwcontrol_message_processor.h"
30 #include "anbox/qemu/null_message_processor.h"
31 #include "anbox/qemu/pipe_connection_creator.h"
32 #include "anbox/qemu/sensors_message_processor.h"
34 namespace ba = boost::asio;
37 std::string client_type_to_string(
38 const anbox::qemu::PipeConnectionCreator::client_type &type) {
40 case anbox::qemu::PipeConnectionCreator::client_type::opengles:
42 case anbox::qemu::PipeConnectionCreator::client_type::qemud_boot_properties:
43 return "boot-properties";
44 case anbox::qemu::PipeConnectionCreator::client_type::qemud_hw_control:
46 case anbox::qemu::PipeConnectionCreator::client_type::qemud_sensors:
48 case anbox::qemu::PipeConnectionCreator::client_type::qemud_camera:
50 case anbox::qemu::PipeConnectionCreator::client_type::qemud_fingerprint:
52 case anbox::qemu::PipeConnectionCreator::client_type::qemud_gsm:
54 case anbox::qemu::PipeConnectionCreator::client_type::qemud_adb:
56 case anbox::qemu::PipeConnectionCreator::client_type::bootanimation:
57 return "boot-animation";
58 case anbox::qemu::PipeConnectionCreator::client_type::invalid:
68 PipeConnectionCreator::PipeConnectionCreator(const std::shared_ptr<Renderer> &renderer, const std::shared_ptr<Runtime> &rt)
69 : renderer_(renderer),
71 next_connection_id_(0),
73 std::make_shared<network::Connections<network::SocketConnection>>()) {
76 PipeConnectionCreator::~PipeConnectionCreator() noexcept {
77 connections_->clear();
80 void PipeConnectionCreator::create_connection_for(
81 std::shared_ptr<boost::asio::local::stream_protocol::socket> const
83 auto const messenger = std::make_shared<network::LocalSocketMessenger>(socket);
84 const auto type = identify_client(messenger);
85 auto const processor = create_processor(type, messenger);
87 BOOST_THROW_EXCEPTION(std::runtime_error("Unhandled client type"));
89 auto const &connection = std::make_shared<network::SocketConnection>(
90 messenger, messenger, next_id(), connections_, processor);
91 connection->set_name(client_type_to_string(type));
92 connections_->add(connection);
93 connection->read_next_message();
96 PipeConnectionCreator::client_type PipeConnectionCreator::identify_client(
97 std::shared_ptr<network::SocketMessenger> const &messenger) {
98 // The client will identify itself as first thing by writing a string
99 // in the format 'pipe:<name>[:<arguments>]\0' to the channel.
100 std::vector<char> buffer;
102 unsigned char byte[1] = {0};
103 const auto err = messenger->receive_msg(ba::buffer(byte, 1));
105 buffer.push_back(byte[0]);
106 if (byte[0] == 0x0) break;
109 std::string identifier_and_args = buffer.data();
111 if (utils::string_starts_with(identifier_and_args, "pipe:opengles"))
112 return client_type::opengles;
113 // Even if 'boot-properties' is an argument to the service 'qemud' here we
114 // take this as a own service instance as that is what it is.
115 else if (utils::string_starts_with(identifier_and_args,
116 "pipe:qemud:boot-properties"))
117 return client_type::qemud_boot_properties;
118 else if (utils::string_starts_with(identifier_and_args,
119 "pipe:qemud:hw-control"))
120 return client_type::qemud_hw_control;
121 else if (utils::string_starts_with(identifier_and_args, "pipe:qemud:sensors"))
122 return client_type::qemud_sensors;
123 else if (utils::string_starts_with(identifier_and_args, "pipe:qemud:camera"))
124 return client_type::qemud_camera;
125 else if (utils::string_starts_with(identifier_and_args,
126 "pipe:qemud:fingerprintlisten"))
127 return client_type::qemud_fingerprint;
128 else if (utils::string_starts_with(identifier_and_args, "pipe:qemud:gsm"))
129 return client_type::qemud_gsm;
130 else if (utils::string_starts_with(identifier_and_args,
131 "pipe:anbox:bootanimation"))
132 return client_type::bootanimation;
133 else if (utils::string_starts_with(identifier_and_args, "pipe:qemud:adb"))
134 return client_type::qemud_adb;
136 return client_type::invalid;
139 std::shared_ptr<network::MessageProcessor>
140 PipeConnectionCreator::create_processor(
141 const client_type &type,
142 const std::shared_ptr<network::SocketMessenger> &messenger) {
143 if (type == client_type::opengles)
144 return std::make_shared<graphics::OpenGlesMessageProcessor>(renderer_, messenger);
145 else if (type == client_type::qemud_boot_properties)
146 return std::make_shared<qemu::BootPropertiesMessageProcessor>(messenger);
147 else if (type == client_type::qemud_hw_control)
148 return std::make_shared<qemu::HwControlMessageProcessor>(messenger);
149 else if (type == client_type::qemud_sensors)
150 return std::make_shared<qemu::SensorsMessageProcessor>(messenger);
151 else if (type == client_type::qemud_camera)
152 return std::make_shared<qemu::CameraMessageProcessor>(messenger);
153 else if (type == client_type::qemud_fingerprint)
154 return std::make_shared<qemu::FingerprintMessageProcessor>(messenger);
155 else if (type == client_type::qemud_gsm)
156 return std::make_shared<qemu::GsmMessageProcessor>(messenger);
157 else if (type == client_type::qemud_adb)
158 return std::make_shared<qemu::AdbMessageProcessor>(runtime_, messenger);
160 return std::make_shared<qemu::NullMessageProcessor>();
163 int PipeConnectionCreator::next_id() {
164 return next_connection_id_.fetch_add(1);