First part of an RPC mechanism for container <-> host communication
Mostly based on the protobuf based implementation from Mir.
This commit is contained in:
parent
fb4f424325
commit
da971a88c3
38 changed files with 1750 additions and 52 deletions
|
|
@ -10,6 +10,20 @@ include_directories(
|
|||
${CMAKE_SOURCE_DIR}/external/android-emugl/host/include
|
||||
)
|
||||
|
||||
set(PROTOBUF_SOURCES
|
||||
anbox/protobuf/anbox_bridge.proto)
|
||||
|
||||
protobuf_generate_cpp(
|
||||
GENERATED_PROTOBUF_SRCS GENERATED_PROTOBUF_HDRS
|
||||
${PROTOBUF_SOURCES})
|
||||
|
||||
add_library(anbox-protobuf
|
||||
${GENERATED_PROTOBUF_SRCS}
|
||||
${GENERATED_PROTOBUF_HDRS}
|
||||
anbox/protobuf/google_protobuf_guard.cpp)
|
||||
target_link_libraries(anbox-protobuf
|
||||
${PROTOBUF_LITE_LIBRARIES})
|
||||
|
||||
set(SOURCES
|
||||
anbox/logger.cpp
|
||||
anbox/utils.cpp
|
||||
|
|
@ -56,6 +70,18 @@ set(SOURCES
|
|||
anbox/support/sensors_message_processor.cpp
|
||||
anbox/support/camera_message_processor.cpp
|
||||
anbox/support/fingerprint_message_processor.cpp
|
||||
anbox/support/gsm_message_processor.cpp
|
||||
anbox/support/at_parser.cpp
|
||||
|
||||
anbox/bridge/constants.h
|
||||
anbox/bridge/connection_creator.cpp
|
||||
anbox/bridge/message_processor.cpp
|
||||
anbox/bridge/template_message_processor.h
|
||||
anbox/bridge/pending_call_cache.cpp
|
||||
anbox/bridge/make_protobuf_object.h
|
||||
anbox/bridge/platform_message_processor.cpp
|
||||
anbox/bridge/platform_server.cpp
|
||||
anbox/bridge/rpc_channel.cpp
|
||||
|
||||
anbox/ubuntu/platform_server.cpp
|
||||
anbox/ubuntu/mir_display_connection.cpp
|
||||
|
|
@ -82,7 +108,8 @@ target_link_libraries(anbox-core
|
|||
|
||||
add_executable(anbox main.cpp)
|
||||
target_link_libraries(anbox
|
||||
anbox-core)
|
||||
anbox-core
|
||||
anbox-protobuf)
|
||||
|
||||
add_executable(anbox-container container_main.cpp)
|
||||
target_link_libraries(anbox-container
|
||||
|
|
|
|||
67
src/anbox/bridge/connection_creator.cpp
Normal file
67
src/anbox/bridge/connection_creator.cpp
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* Copyright (C) 2016 Simon Fels <morphis@gravedo.de>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 3, as published
|
||||
* by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranties of
|
||||
* MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "anbox/bridge/connection_creator.h"
|
||||
#include "anbox/bridge/message_processor.h"
|
||||
#include "anbox/network/socket_messenger.h"
|
||||
#include "anbox/logger.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace ba = boost::asio;
|
||||
|
||||
namespace anbox {
|
||||
namespace bridge {
|
||||
ConnectionCreator::ConnectionCreator(const std::shared_ptr<Runtime> &rt, const MessageProcessorFactory &factory) :
|
||||
runtime_(rt),
|
||||
next_connection_id_(0),
|
||||
connections_(std::make_shared<network::Connections<network::SocketConnection>>()),
|
||||
message_processor_factory_(factory) {
|
||||
}
|
||||
|
||||
ConnectionCreator::~ConnectionCreator() {
|
||||
}
|
||||
|
||||
void ConnectionCreator::create_connection_for(
|
||||
std::shared_ptr<boost::asio::local::stream_protocol::socket> const& socket) {
|
||||
|
||||
if (connections_->size() >= 1) {
|
||||
socket->close();
|
||||
WARNING("A second client tried to connect. Denied request as we already have one"
|
||||
"and only allow a single client");
|
||||
return;
|
||||
}
|
||||
|
||||
DEBUG("");
|
||||
|
||||
auto const messenger = std::make_shared<network::SocketMessenger>(socket);
|
||||
auto const processor = message_processor_factory_(messenger);
|
||||
|
||||
auto const& connection = std::make_shared<network::SocketConnection>(
|
||||
messenger, messenger, next_id(), connections_, processor);
|
||||
connections_->add(connection);
|
||||
connection->read_next_message();
|
||||
}
|
||||
|
||||
int ConnectionCreator::next_id()
|
||||
{
|
||||
return next_connection_id_.fetch_add(1);
|
||||
}
|
||||
|
||||
} // namespace anbox
|
||||
} // namespace network
|
||||
56
src/anbox/bridge/connection_creator.h
Normal file
56
src/anbox/bridge/connection_creator.h
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Copyright (C) 2016 Simon Fels <morphis@gravedo.de>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 3, as published
|
||||
* by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranties of
|
||||
* MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef ANBOX_BRIDGE_CONNECTION_CREATOR_H_
|
||||
#define ANBOX_BRIDGE_CONNECTION_CREATOR_H_
|
||||
|
||||
#include <boost/asio.hpp>
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "anbox/do_not_copy_or_move.h"
|
||||
#include "anbox/runtime.h"
|
||||
#include "anbox/network/connections.h"
|
||||
#include "anbox/network/socket_connection.h"
|
||||
#include "anbox/network/connection_creator.h"
|
||||
#include "anbox/network/socket_messenger.h"
|
||||
|
||||
namespace anbox {
|
||||
namespace bridge {
|
||||
class ConnectionCreator : public network::ConnectionCreator {
|
||||
public:
|
||||
typedef std::function<std::shared_ptr<network::MessageProcessor>(const std::shared_ptr<network::MessageSender>&)> MessageProcessorFactory;
|
||||
|
||||
ConnectionCreator(
|
||||
const std::shared_ptr<Runtime> &rt, const MessageProcessorFactory &factory);
|
||||
~ConnectionCreator() noexcept;
|
||||
|
||||
void create_connection_for(
|
||||
std::shared_ptr<boost::asio::local::stream_protocol::socket> const& socket) override;
|
||||
|
||||
private:
|
||||
int next_id();
|
||||
|
||||
std::shared_ptr<Runtime> runtime_;
|
||||
std::atomic<int> next_connection_id_;
|
||||
std::shared_ptr<network::Connections<network::SocketConnection>> const connections_;
|
||||
MessageProcessorFactory message_processor_factory_;
|
||||
};
|
||||
} // namespace anbox
|
||||
} // namespace network
|
||||
|
||||
#endif
|
||||
33
src/anbox/bridge/constants.h
Normal file
33
src/anbox/bridge/constants.h
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* Copyright (C) 2016 Simon Fels <morphis@gravedo.de>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 3, as published
|
||||
* by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranties of
|
||||
* MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef ANBOX_BRIDGE_CONSTANTS_H_
|
||||
#define ANBOX_BRIDGE_CONSTANTS_H_
|
||||
|
||||
namespace anbox {
|
||||
namespace bridge {
|
||||
static constexpr const long header_size{3};
|
||||
static constexpr unsigned int const serialization_buffer_size{2048};
|
||||
|
||||
enum MessageType {
|
||||
invocation = 0,
|
||||
response = 1,
|
||||
};
|
||||
} // namespace anbox
|
||||
} // namespace network
|
||||
|
||||
#endif
|
||||
40
src/anbox/bridge/make_protobuf_object.h
Normal file
40
src/anbox/bridge/make_protobuf_object.h
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Copyright © 2015 Canonical Ltd.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License version 3,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authored by: Alberto Aguirre <alberto.aguirre@canonical.com>
|
||||
*/
|
||||
|
||||
#ifndef ANBOX_BRIDGE_MAKE_PROTOBUF_OBJECT_H_
|
||||
#define ANBOX_BRIDGE_MAKE_PROTOBUF_OBJECT_H_
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace anbox {
|
||||
namespace bridge {
|
||||
template <typename ProtobufType>
|
||||
auto make_protobuf_object() {
|
||||
return std::unique_ptr<ProtobufType>{ProtobufType::default_instance().New()};
|
||||
}
|
||||
|
||||
template <typename ProtobufType>
|
||||
auto make_protobuf_object(ProtobufType const& from) {
|
||||
auto object = make_protobuf_object<ProtobufType>();
|
||||
object->CopyFrom(from);
|
||||
return object;
|
||||
}
|
||||
} // namespace bridge
|
||||
} // namespace anbox
|
||||
|
||||
#endif
|
||||
119
src/anbox/bridge/message_processor.cpp
Normal file
119
src/anbox/bridge/message_processor.cpp
Normal file
|
|
@ -0,0 +1,119 @@
|
|||
/*
|
||||
* Copyright (C) 2016 Simon Fels <morphis@gravedo.de>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 3, as published
|
||||
* by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranties of
|
||||
* MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "anbox/bridge/message_processor.h"
|
||||
#include "anbox/bridge/template_message_processor.h"
|
||||
#include "anbox/bridge/make_protobuf_object.h"
|
||||
#include "anbox/bridge/constants.h"
|
||||
#include "anbox/common/variable_length_array.h"
|
||||
|
||||
#include "anbox_bridge.pb.h"
|
||||
|
||||
namespace anbox {
|
||||
namespace bridge {
|
||||
const ::std::string& Invocation::method_name() const {
|
||||
return invocation_.method_name();
|
||||
}
|
||||
|
||||
const ::std::string& Invocation::parameters() const {
|
||||
return invocation_.parameters();
|
||||
}
|
||||
|
||||
google::protobuf::uint32 Invocation::id() const {
|
||||
return invocation_.id();
|
||||
}
|
||||
|
||||
MessageProcessor::MessageProcessor(const std::shared_ptr<network::MessageSender> &sender,
|
||||
const std::shared_ptr<PendingCallCache> &pending_calls) :
|
||||
sender_(sender),
|
||||
pending_calls_(pending_calls) {
|
||||
}
|
||||
|
||||
MessageProcessor::~MessageProcessor() {
|
||||
}
|
||||
|
||||
bool MessageProcessor::process_data(const std::vector<std::uint8_t> &data) {
|
||||
for (const auto &byte : data)
|
||||
buffer_.push_back(byte);
|
||||
|
||||
unsigned char const high = buffer_[0];
|
||||
unsigned char const low = buffer_[1];
|
||||
size_t const message_size = (high << 8) + low;
|
||||
unsigned char const message_type = buffer_[2];
|
||||
|
||||
// If we don't have yet all bytes for a new message return and wait
|
||||
// until we have all.
|
||||
if (buffer_.size() - header_size < message_size)
|
||||
return true;
|
||||
|
||||
buffer_.erase(buffer_.begin(), buffer_.begin() + header_size);
|
||||
|
||||
if (message_type == MessageType::invocation) {
|
||||
anbox::protobuf::bridge::Invocation raw_invocation;
|
||||
raw_invocation.ParseFromArray(buffer_.data(), message_size);
|
||||
|
||||
buffer_.erase(buffer_.begin(), buffer_.begin() + message_size);
|
||||
|
||||
dispatch(Invocation(raw_invocation));
|
||||
}
|
||||
else if (message_type == MessageType::response) {
|
||||
auto result = make_protobuf_object<protobuf::bridge::Result>();
|
||||
result->ParseFromArray(buffer_.data(), message_size);
|
||||
|
||||
buffer_.erase(buffer_.begin(), buffer_.end() + message_size);
|
||||
|
||||
for (int i = 0; i != result->events_size(); ++i)
|
||||
process_event_sequence(result->events(i));
|
||||
|
||||
pending_calls_->complete_response(*result);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void MessageProcessor::send_response(::google::protobuf::uint32 id, google::protobuf::MessageLite *response) {
|
||||
VariableLengthArray<serialization_buffer_size> send_response_buffer(
|
||||
static_cast<size_t>(response->ByteSize()));
|
||||
|
||||
response->SerializeWithCachedSizesToArray(send_response_buffer.data());
|
||||
|
||||
anbox::protobuf::bridge::Result send_response_result;
|
||||
send_response_result.set_id(id);
|
||||
send_response_result.set_response(send_response_buffer.data(), send_response_buffer.size());
|
||||
|
||||
send_response_buffer.resize(send_response_result.ByteSize());
|
||||
send_response_result.SerializeWithCachedSizesToArray(send_response_buffer.data());
|
||||
|
||||
const size_t size = send_response_buffer.size();
|
||||
const unsigned char header_bytes[header_size] = {
|
||||
static_cast<unsigned char>((size >> 8) & 0xff),
|
||||
static_cast<unsigned char>((size >> 0) & 0xff),
|
||||
MessageType::response,
|
||||
};
|
||||
|
||||
std::vector<std::uint8_t> send_buffer(sizeof(header_bytes) + size);
|
||||
std::copy(header_bytes,
|
||||
header_bytes + sizeof(header_bytes),
|
||||
send_buffer.begin());
|
||||
std::copy(send_response_buffer.data(),
|
||||
send_response_buffer.data() + send_response_buffer.size(),
|
||||
send_buffer.begin() + sizeof(header_bytes));
|
||||
|
||||
sender_->send(reinterpret_cast<const char*>(send_buffer.data()), send_buffer.size());
|
||||
}
|
||||
} // namespace anbox
|
||||
} // namespace network
|
||||
71
src/anbox/bridge/message_processor.h
Normal file
71
src/anbox/bridge/message_processor.h
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* Copyright (C) 2016 Simon Fels <morphis@gravedo.de>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 3, as published
|
||||
* by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranties of
|
||||
* MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef ANBOX_BRIDGE_MESSAGE_PROCESSOR_H_
|
||||
#define ANBOX_BRIDGE_MESSAGE_PROCESSOR_H_
|
||||
|
||||
#include "anbox/network/message_processor.h"
|
||||
#include "anbox/network/message_sender.h"
|
||||
#include "anbox/bridge/pending_call_cache.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <google/protobuf/stubs/common.h>
|
||||
#include <google/protobuf/message_lite.h>
|
||||
|
||||
namespace anbox {
|
||||
namespace protobuf {
|
||||
namespace bridge {
|
||||
class Invocation;
|
||||
} // namespace bridge
|
||||
} // namespace protobuf
|
||||
namespace bridge {
|
||||
class Invocation
|
||||
{
|
||||
public:
|
||||
Invocation(anbox::protobuf::bridge::Invocation const& invocation) :
|
||||
invocation_(invocation) {}
|
||||
|
||||
const ::std::string& method_name() const;
|
||||
const ::std::string& parameters() const;
|
||||
google::protobuf::uint32 id() const;
|
||||
private:
|
||||
anbox::protobuf::bridge::Invocation const& invocation_;
|
||||
};
|
||||
|
||||
class MessageProcessor : public network::MessageProcessor {
|
||||
public:
|
||||
MessageProcessor(const std::shared_ptr<network::MessageSender> &sender,
|
||||
const std::shared_ptr<PendingCallCache> &pending_calls);
|
||||
~MessageProcessor();
|
||||
|
||||
bool process_data(const std::vector<std::uint8_t> &data) override;
|
||||
|
||||
void send_response(::google::protobuf::uint32 id, google::protobuf::MessageLite *response);
|
||||
|
||||
virtual void dispatch(Invocation const& invocation) = 0;
|
||||
virtual void process_event_sequence(const std::string &event) = 0;
|
||||
|
||||
private:
|
||||
std::shared_ptr<network::MessageSender> sender_;
|
||||
std::vector<std::uint8_t> buffer_;
|
||||
std::shared_ptr<PendingCallCache> pending_calls_;
|
||||
};
|
||||
} // namespace bridge
|
||||
} // namespace anbox
|
||||
|
||||
#endif
|
||||
72
src/anbox/bridge/pending_call_cache.cpp
Normal file
72
src/anbox/bridge/pending_call_cache.cpp
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* Copyright © 2012 Canonical Ltd.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License version 3,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authored by: Alan Griffiths <alan@octopull.co.uk>
|
||||
*/
|
||||
|
||||
#include "anbox/bridge/pending_call_cache.h"
|
||||
|
||||
#include "anbox_bridge.pb.h"
|
||||
|
||||
namespace anbox {
|
||||
namespace bridge {
|
||||
PendingCallCache::PendingCallCache() {
|
||||
}
|
||||
|
||||
void PendingCallCache::save_completion_details(anbox::protobuf::bridge::Invocation const &invocation,
|
||||
google::protobuf::MessageLite *response,
|
||||
google::protobuf::Closure *complete) {
|
||||
std::unique_lock<std::mutex> lock(mutex_);
|
||||
pending_calls_[invocation.id()] = PendingCall(response, complete);
|
||||
}
|
||||
|
||||
void PendingCallCache::populate_message_for_result(anbox::protobuf::bridge::Result &result,
|
||||
std::function<void(google::protobuf::MessageLite*)> const& populator) {
|
||||
std::unique_lock<std::mutex> lock(mutex_);
|
||||
populator(pending_calls_.at(result.id()).response);
|
||||
}
|
||||
|
||||
void PendingCallCache::complete_response(anbox::protobuf::bridge::Result& result) {
|
||||
PendingCall completion;
|
||||
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(mutex_);
|
||||
auto call = pending_calls_.find(result.id());
|
||||
if (call != pending_calls_.end()) {
|
||||
completion = call->second;
|
||||
pending_calls_.erase(call);
|
||||
}
|
||||
}
|
||||
|
||||
if (completion.complete)
|
||||
completion.complete->Run();
|
||||
}
|
||||
|
||||
void PendingCallCache::force_completion() {
|
||||
std::unique_lock<std::mutex> lock(mutex_);
|
||||
for (auto& call : pending_calls_) {
|
||||
auto& completion = call.second;
|
||||
completion.complete->Run();
|
||||
}
|
||||
|
||||
pending_calls_.erase(pending_calls_.begin(), pending_calls_.end());
|
||||
}
|
||||
|
||||
bool PendingCallCache::empty() const {
|
||||
std::unique_lock<std::mutex> lock(mutex_);
|
||||
return pending_calls_.empty();
|
||||
}
|
||||
} // namespace bridge
|
||||
} // namespace anbox
|
||||
77
src/anbox/bridge/pending_call_cache.h
Normal file
77
src/anbox/bridge/pending_call_cache.h
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
* Copyright © 2012 Canonical Ltd.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License version 3,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authored by: Alan Griffiths <alan@octopull.co.uk>
|
||||
*/
|
||||
|
||||
#ifndef ANBOX_BRIDGE_PENDING_CALL_CACHE_
|
||||
#define ANBOX_BRIDGE_PENDING_CALL_CACHE_
|
||||
|
||||
#include <functional>
|
||||
#include <mutex>
|
||||
#include <map>
|
||||
|
||||
namespace google {
|
||||
namespace protobuf {
|
||||
class Closure;
|
||||
class MessageLite;
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
||||
|
||||
namespace anbox {
|
||||
namespace protobuf {
|
||||
namespace bridge {
|
||||
class Invocation;
|
||||
class Result;
|
||||
} // namespace bridge
|
||||
} // namespace protobuf
|
||||
namespace bridge {
|
||||
class PendingCallCache {
|
||||
public:
|
||||
PendingCallCache();
|
||||
|
||||
void save_completion_details(anbox::protobuf::bridge::Invocation const &invocation,
|
||||
google::protobuf::MessageLite *response,
|
||||
google::protobuf::Closure *complete);
|
||||
void populate_message_for_result(anbox::protobuf::bridge::Result &result,
|
||||
std::function<void(google::protobuf::MessageLite*)> const& populator);
|
||||
void complete_response(anbox::protobuf::bridge::Result& result);
|
||||
void force_completion();
|
||||
bool empty() const;
|
||||
|
||||
private:
|
||||
struct PendingCall {
|
||||
PendingCall(google::protobuf::MessageLite *response,
|
||||
google::protobuf::Closure *target) :
|
||||
response(response),
|
||||
complete(target) {
|
||||
}
|
||||
|
||||
PendingCall() :
|
||||
response(0),
|
||||
complete() {
|
||||
}
|
||||
|
||||
google::protobuf::MessageLite *response;
|
||||
google::protobuf::Closure *complete;
|
||||
};
|
||||
|
||||
std::mutex mutable mutex_;
|
||||
std::map<int, PendingCall> pending_calls_;
|
||||
};
|
||||
} // namespace bridge
|
||||
} // namespace anbox
|
||||
|
||||
#endif
|
||||
45
src/anbox/bridge/platform_message_processor.cpp
Normal file
45
src/anbox/bridge/platform_message_processor.cpp
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* Copyright (C) 2016 Simon Fels <morphis@gravedo.de>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 3, as published
|
||||
* by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranties of
|
||||
* MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "anbox/bridge/platform_message_processor.h"
|
||||
#include "anbox/bridge/platform_server.h"
|
||||
#include "anbox/bridge/template_message_processor.h"
|
||||
|
||||
#include "anbox_bridge.pb.h"
|
||||
|
||||
namespace anbox {
|
||||
namespace bridge {
|
||||
PlatformMessageProcessor::PlatformMessageProcessor(const std::shared_ptr<network::MessageSender> &sender,
|
||||
const std::shared_ptr<PlatformServer> &server,
|
||||
const std::shared_ptr<PendingCallCache> &pending_calls) :
|
||||
MessageProcessor(sender, pending_calls),
|
||||
server_(server) {
|
||||
}
|
||||
|
||||
PlatformMessageProcessor::~PlatformMessageProcessor() {
|
||||
}
|
||||
|
||||
void PlatformMessageProcessor::dispatch(Invocation const& invocation) {
|
||||
if (invocation.method_name() == "handle_notification") {
|
||||
invoke(this, server_.get(), &PlatformServer::handle_notification, invocation);
|
||||
}
|
||||
}
|
||||
|
||||
void PlatformMessageProcessor::process_event_sequence(const std::string&) {
|
||||
}
|
||||
} // namespace anbox
|
||||
} // namespace network
|
||||
42
src/anbox/bridge/platform_message_processor.h
Normal file
42
src/anbox/bridge/platform_message_processor.h
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* Copyright (C) 2016 Simon Fels <morphis@gravedo.de>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 3, as published
|
||||
* by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranties of
|
||||
* MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef ANBOX_BRIDGE_PLATFORM_MESSAGE_PROCESSOR_H_
|
||||
#define ANBOX_BRIDGE_PLATFORM_MESSAGE_PROCESSOR_H_
|
||||
|
||||
#include "anbox/bridge/message_processor.h"
|
||||
|
||||
namespace anbox {
|
||||
namespace bridge {
|
||||
class PlatformServer;
|
||||
class PlatformMessageProcessor : public MessageProcessor {
|
||||
public:
|
||||
PlatformMessageProcessor(const std::shared_ptr<network::MessageSender> &sender,
|
||||
const std::shared_ptr<PlatformServer> &server,
|
||||
const std::shared_ptr<PendingCallCache> &pending_calls);
|
||||
~PlatformMessageProcessor();
|
||||
|
||||
void dispatch(Invocation const& invocation) override;
|
||||
void process_event_sequence(const std::string &event) override;
|
||||
|
||||
private:
|
||||
std::shared_ptr<PlatformServer> server_;
|
||||
};
|
||||
} // namespace anbox
|
||||
} // namespace network
|
||||
|
||||
#endif
|
||||
32
src/anbox/bridge/platform_server.cpp
Normal file
32
src/anbox/bridge/platform_server.cpp
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* Copyright (C) 2016 Simon Fels <morphis@gravedo.de>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 3, as published
|
||||
* by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranties of
|
||||
* MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "anbox/bridge/platform_server.h"
|
||||
#include "anbox/logger.h"
|
||||
|
||||
#include "anbox_bridge.pb.h"
|
||||
|
||||
namespace anbox {
|
||||
namespace bridge {
|
||||
PlatformServer::PlatformServer(const std::shared_ptr<PendingCallCache> &pending_calls) :
|
||||
pending_calls_(pending_calls) {
|
||||
}
|
||||
|
||||
PlatformServer::~PlatformServer() {
|
||||
}
|
||||
} // namespace bridge
|
||||
} // namespace anbox
|
||||
53
src/anbox/bridge/platform_server.h
Normal file
53
src/anbox/bridge/platform_server.h
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* Copyright (C) 2016 Simon Fels <morphis@gravedo.de>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 3, as published
|
||||
* by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranties of
|
||||
* MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef ANBOX_BRIDGE_PLATFORM_SERVER_H_
|
||||
#define ANBOX_BRIDGE_PLATFORM_SERVER_H_
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace google {
|
||||
namespace protobuf {
|
||||
class Closure;
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
||||
|
||||
namespace anbox {
|
||||
namespace protobuf {
|
||||
namespace bridge {
|
||||
class Notification;
|
||||
class Void;
|
||||
} // namespace bridge
|
||||
} // namespace protobuf
|
||||
namespace bridge {
|
||||
class PendingCallCache;
|
||||
class PlatformServer {
|
||||
public:
|
||||
PlatformServer(const std::shared_ptr<PendingCallCache> &pending_calls);
|
||||
virtual ~PlatformServer();
|
||||
|
||||
virtual void handle_notification(anbox::protobuf::bridge::Notification const *request,
|
||||
anbox::protobuf::bridge::Void *response,
|
||||
google::protobuf::Closure *done) = 0;
|
||||
|
||||
private:
|
||||
std::shared_ptr<PendingCallCache> pending_calls_;
|
||||
};
|
||||
} // namespace bridge
|
||||
} // namespace anbox
|
||||
|
||||
#endif
|
||||
94
src/anbox/bridge/rpc_channel.cpp
Normal file
94
src/anbox/bridge/rpc_channel.cpp
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
/*
|
||||
* Copyright © 2012 Canonical Ltd.
|
||||
* © 2016 Simon Fels <morphis@gravedo.de>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License version 3,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authored by: Alan Griffiths <alan@octopull.co.uk>
|
||||
*/
|
||||
|
||||
#include "anbox/bridge/rpc_channel.h"
|
||||
#include "anbox/bridge/pending_call_cache.h"
|
||||
#include "anbox/bridge/constants.h"
|
||||
#include "anbox/common/variable_length_array.h"
|
||||
#include "anbox/network/message_sender.h"
|
||||
|
||||
#include "anbox_bridge.pb.h"
|
||||
|
||||
namespace anbox {
|
||||
namespace bridge {
|
||||
RpcChannel::RpcChannel(const std::shared_ptr<PendingCallCache> &pending_calls,
|
||||
const std::shared_ptr<network::MessageSender> &sender) :
|
||||
pending_calls_(pending_calls),
|
||||
sender_(sender) {
|
||||
}
|
||||
|
||||
RpcChannel::~RpcChannel() {
|
||||
}
|
||||
|
||||
void RpcChannel::call_method(std::string const& method_name,
|
||||
google::protobuf::MessageLite const *parameters,
|
||||
google::protobuf::MessageLite *response,
|
||||
google::protobuf::Closure *complete) {
|
||||
auto const &invocation = invocation_for(method_name, parameters);
|
||||
pending_calls_->save_completion_details(invocation, response, complete);
|
||||
send_message(invocation);
|
||||
}
|
||||
|
||||
protobuf::bridge::Invocation RpcChannel::invocation_for(std::string const& method_name,
|
||||
google::protobuf::MessageLite const* request) {
|
||||
|
||||
anbox::VariableLengthArray<2048> buffer{static_cast<size_t>(request->ByteSize())};
|
||||
|
||||
request->SerializeWithCachedSizesToArray(buffer.data());
|
||||
|
||||
anbox::protobuf::bridge::Invocation invoke;
|
||||
|
||||
invoke.set_id(next_id());
|
||||
invoke.set_method_name(method_name);
|
||||
invoke.set_parameters(buffer.data(), buffer.size());
|
||||
|
||||
return invoke;
|
||||
}
|
||||
|
||||
void RpcChannel::send_message(anbox::protobuf::bridge::Invocation const& invocation) {
|
||||
const size_t size = invocation.ByteSize();
|
||||
const unsigned char header_bytes[header_size] = {
|
||||
static_cast<unsigned char>((size >> 8) & 0xff),
|
||||
static_cast<unsigned char>((size >> 0) & 0xff),
|
||||
MessageType::invocation,
|
||||
};
|
||||
|
||||
std::vector<std::uint8_t> send_buffer(sizeof(header_bytes) + size);
|
||||
std::copy(header_bytes, header_bytes + sizeof(header_bytes), send_buffer.begin());
|
||||
invocation.SerializeToArray(send_buffer.data() + sizeof(header_bytes), size);
|
||||
|
||||
try {
|
||||
std::lock_guard<std::mutex> lock(write_mutex_);
|
||||
sender_->send(reinterpret_cast<const char*>(send_buffer.data()), send_buffer.size());
|
||||
}
|
||||
catch (std::runtime_error const&) {
|
||||
notify_disconnected();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
void RpcChannel::notify_disconnected() {
|
||||
pending_calls_->force_completion();
|
||||
}
|
||||
|
||||
int RpcChannel::next_id() {
|
||||
return next_message_id_.fetch_add(1);
|
||||
}
|
||||
} // namespace bridge
|
||||
} // namespace anbox
|
||||
71
src/anbox/bridge/rpc_channel.h
Normal file
71
src/anbox/bridge/rpc_channel.h
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* Copyright (C) 2016 Simon Fels <morphis@gravedo.de>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 3, as published
|
||||
* by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranties of
|
||||
* MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef ANBOX_BRIDGE_RPC_CHANNEL_H_
|
||||
#define ANBOX_BRIDGE_RPC_CHANNEL_H_
|
||||
|
||||
#include <memory>
|
||||
#include <atomic>
|
||||
#include <mutex>
|
||||
|
||||
namespace google {
|
||||
namespace protobuf {
|
||||
class Closure;
|
||||
class MessageLite;
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
||||
|
||||
|
||||
namespace anbox {
|
||||
namespace protobuf {
|
||||
namespace bridge {
|
||||
class Invocation;
|
||||
} // namespace bridge
|
||||
} // namespace protobuf
|
||||
namespace network {
|
||||
class MessageSender;
|
||||
} // namespace network
|
||||
namespace bridge {
|
||||
class PendingCallCache;
|
||||
class RpcChannel {
|
||||
public:
|
||||
RpcChannel(const std::shared_ptr<PendingCallCache> &pending_calls,
|
||||
const std::shared_ptr<network::MessageSender> &sender);
|
||||
~RpcChannel();
|
||||
|
||||
void call_method(std::string const& method_name,
|
||||
google::protobuf::MessageLite const *parameters,
|
||||
google::protobuf::MessageLite *response,
|
||||
google::protobuf::Closure *complete);
|
||||
|
||||
private:
|
||||
protobuf::bridge::Invocation invocation_for(
|
||||
std::string const& method_name,
|
||||
google::protobuf::MessageLite const* request);
|
||||
void send_message(anbox::protobuf::bridge::Invocation const& invocation);
|
||||
int next_id();
|
||||
void notify_disconnected();
|
||||
|
||||
std::atomic<int> next_message_id_;
|
||||
std::shared_ptr<PendingCallCache> pending_calls_;
|
||||
std::shared_ptr<network::MessageSender> sender_;
|
||||
std::mutex write_mutex_;
|
||||
};
|
||||
} // namespace bridge
|
||||
} // namespace anbox
|
||||
|
||||
#endif
|
||||
80
src/anbox/bridge/template_message_processor.h
Normal file
80
src/anbox/bridge/template_message_processor.h
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
* Copyright © 2014 Canonical Ltd.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 3,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authored by: Alan Griffiths <alan@octopull.co.uk>
|
||||
*/
|
||||
|
||||
#ifndef ANBOX_BRIDGE_TEMPLATE_MESSAGE_PROCESSOR_H_
|
||||
#define ANBOX_BRIDGE_TEMPLATE_MESSAGE_PROCESSOR_H_
|
||||
|
||||
#include <google/protobuf/stubs/common.h>
|
||||
|
||||
#include "anbox/bridge/message_processor.h"
|
||||
|
||||
#include "anbox_bridge.pb.h"
|
||||
|
||||
namespace anbox {
|
||||
namespace bridge {
|
||||
// Utility metafunction result_ptr_t<> allows invoke() to pick the right
|
||||
// send_response() overload. The base template resolves to the prototype
|
||||
// "send_response(::google::protobuf::uint32 id, ::google::protobuf::Message* response)"
|
||||
// Client code may specialize result_ptr_t to resolve to another overload.
|
||||
template<typename ResultType> struct result_ptr_t
|
||||
{ typedef ::google::protobuf::MessageLite* type; };
|
||||
|
||||
// Boiler plate for unpacking a parameter message, invoking a server function, and
|
||||
// sending the result message. Assumes the existence of Self::send_response().
|
||||
template<class Self, class Bridge, class BridgeX, class ParameterMessage, class ResultMessage>
|
||||
void invoke(
|
||||
Self* self,
|
||||
Bridge* bridge,
|
||||
void (BridgeX::*function)(
|
||||
ParameterMessage const* request,
|
||||
ResultMessage* response,
|
||||
::google::protobuf::Closure* done),
|
||||
Invocation const& invocation)
|
||||
{
|
||||
ParameterMessage parameter_message;
|
||||
if (!parameter_message.ParseFromString(invocation.parameters()))
|
||||
throw std::runtime_error("Failed to parse message parameters!");
|
||||
ResultMessage result_message;
|
||||
|
||||
try
|
||||
{
|
||||
std::unique_ptr<google::protobuf::Closure> callback(
|
||||
google::protobuf::NewPermanentCallback<
|
||||
Self,
|
||||
::google::protobuf::uint32,
|
||||
typename result_ptr_t<ResultMessage>::type>(
|
||||
self,
|
||||
&Self::send_response,
|
||||
invocation.id(),
|
||||
&result_message));
|
||||
|
||||
(bridge->*function)(
|
||||
¶meter_message,
|
||||
&result_message,
|
||||
callback.get());
|
||||
}
|
||||
catch (std::exception const& x)
|
||||
{
|
||||
result_message.set_error(std::string("Error processing request: ") + x.what());
|
||||
self->send_response(invocation.id(), &result_message);
|
||||
}
|
||||
}
|
||||
} // namespace bridge
|
||||
} // namespace anbox
|
||||
|
||||
#endif
|
||||
|
|
@ -29,6 +29,9 @@
|
|||
#include "anbox/network/qemu_pipe_connection_creator.h"
|
||||
#include "anbox/graphics/gl_renderer_server.h"
|
||||
#include "anbox/input/manager.h"
|
||||
#include "anbox/bridge/connection_creator.h"
|
||||
#include "anbox/bridge/platform_message_processor.h"
|
||||
#include "anbox/bridge/rpc_channel.h"
|
||||
#include "anbox/ubuntu/platform_server.h"
|
||||
#include "anbox/ubuntu/window_creator.h"
|
||||
|
||||
|
|
@ -89,10 +92,22 @@ anbox::cmds::Run::Run()
|
|||
rt,
|
||||
std::make_shared<network::QemuPipeConnectionCreator>(rt, renderer->socket_path()));
|
||||
|
||||
auto bridge_connector = std::make_shared<network::PublishedSocketConnector>(
|
||||
utils::string_format("%s/anbox_bridge", config::data_path()),
|
||||
rt,
|
||||
std::make_shared<bridge::ConnectionCreator>(rt,
|
||||
[](const std::shared_ptr<network::MessageSender> &sender) {
|
||||
auto pending_calls = std::make_shared<bridge::PendingCallCache>();
|
||||
auto rpc_channel = std::make_shared<bridge::RpcChannel>(pending_calls, sender);
|
||||
auto server = std::make_shared<ubuntu::PlatformServer>(pending_calls);
|
||||
return std::make_shared<bridge::PlatformMessageProcessor>(sender, server, pending_calls);
|
||||
}));
|
||||
|
||||
auto spec = Container::Spec::Default();
|
||||
spec.rootfs_path = rootfs_;
|
||||
spec.bind_paths.insert({qemud_connector->socket_file(), "/dev/qemud"});
|
||||
spec.bind_paths.insert({qemu_pipe_connector->socket_file(), "/dev/qemu_pipe"});
|
||||
spec.bind_paths.insert({bridge_connector->socket_file(), "/dev/anbox_bridge"});
|
||||
|
||||
input_manager->generate_mappings(spec.bind_paths);
|
||||
|
||||
|
|
|
|||
|
|
@ -15,8 +15,8 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#ifndef ANBOX_CMDS_RUN_QEMU_H_
|
||||
#define ANBOX_CMDS_RUN_QEMU_H_
|
||||
#ifndef ANBOX_CMDS_SHELL_H_
|
||||
#define ANBOX_CMDS_SHELL_H_
|
||||
|
||||
#include <functional>
|
||||
#include <iostream>
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ void SocketMessenger::send(char const* data, size_t length)
|
|||
VariableLengthArray<serialization_buffer_size> whole_message{length};
|
||||
std::copy(data, data + length, whole_message.data());
|
||||
|
||||
while (true) {
|
||||
for (;;) {
|
||||
try {
|
||||
std::unique_lock<std::mutex> lg(message_lock);
|
||||
ba::write(*socket,
|
||||
|
|
@ -62,10 +62,6 @@ void SocketMessenger::send(char const* data, size_t length)
|
|||
if (err.code() == boost::asio::error::try_again)
|
||||
continue;
|
||||
}
|
||||
catch (const std::exception &err) {
|
||||
ERROR("Could not write message: %s", err.what());
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
43
src/anbox/protobuf/anbox_bridge.proto
Normal file
43
src/anbox/protobuf/anbox_bridge.proto
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
option optimize_for = LITE_RUNTIME;
|
||||
|
||||
package anbox.protobuf.bridge;
|
||||
|
||||
message Invocation {
|
||||
required uint32 id = 1;
|
||||
required string method_name = 2;
|
||||
required bytes parameters = 3;
|
||||
required uint32 protocol_version = 4;
|
||||
}
|
||||
|
||||
message Result {
|
||||
optional uint32 id = 1;
|
||||
optional bytes response = 2;
|
||||
repeated bytes events = 3;
|
||||
}
|
||||
|
||||
message StructuredError {
|
||||
optional uint32 domain = 1;
|
||||
optional uint32 code = 2;
|
||||
}
|
||||
|
||||
message Void {
|
||||
optional string error = 127;
|
||||
optional StructuredError structured_error = 128;
|
||||
}
|
||||
|
||||
message Notification {
|
||||
required string package_name = 1;
|
||||
required string category = 2;
|
||||
required string title = 3;
|
||||
optional string ticker_text = 4;
|
||||
optional string text = 5;
|
||||
}
|
||||
|
||||
message InstallApplication {
|
||||
required string path = 1;
|
||||
}
|
||||
|
||||
message LaunchApplication {
|
||||
required string package_name = 1;
|
||||
optional string activity = 2;
|
||||
}
|
||||
40
src/anbox/protobuf/google_protobuf_guard.cpp
Normal file
40
src/anbox/protobuf/google_protobuf_guard.cpp
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Copyright © 2012 Canonical Ltd.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License version 3,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authored by: Alan Griffiths <alan@octopull.co.uk>
|
||||
*/
|
||||
|
||||
#include <google/protobuf/stubs/common.h>
|
||||
|
||||
extern "C" int __attribute__((constructor))
|
||||
init_google_protobuf()
|
||||
{
|
||||
GOOGLE_PROTOBUF_VERIFY_VERSION;
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern "C" int __attribute__((destructor))
|
||||
shutdown_google_protobuf()
|
||||
{
|
||||
google::protobuf::ShutdownProtobufLibrary();
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Preserve ABI
|
||||
namespace anbox { namespace protobuf { void google_protobuf_guard(); }}
|
||||
|
||||
void anbox::protobuf::google_protobuf_guard()
|
||||
{
|
||||
}
|
||||
42
src/anbox/ubuntu/platform_server.cpp
Normal file
42
src/anbox/ubuntu/platform_server.cpp
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* Copyright (C) 2016 Simon Fels <morphis@gravedo.de>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 3, as published
|
||||
* by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranties of
|
||||
* MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "anbox/ubuntu/platform_server.h"
|
||||
#include "anbox/logger.h"
|
||||
|
||||
#include "bridge.pb.h"
|
||||
|
||||
namespace anbox {
|
||||
namespace ubuntu {
|
||||
PlatformServer::PlatformServer(const std::shared_ptr<bridge::PendingCallCache> &pending_calls) :
|
||||
bridge::PlatformServer(pending_calls) {
|
||||
}
|
||||
|
||||
PlatformServer::~PlatformServer() {
|
||||
}
|
||||
|
||||
void PlatformServer::handle_notification(anbox::protobuf::bridge::Notification const *request,
|
||||
anbox::protobuf::bridge::Void *response,
|
||||
google::protobuf::Closure *done) {
|
||||
(void) request;
|
||||
(void) response;
|
||||
DEBUG("");
|
||||
done->Run();
|
||||
}
|
||||
|
||||
} // namespace ubuntu
|
||||
} // namespace anbox
|
||||
37
src/anbox/ubuntu/platform_server.h
Normal file
37
src/anbox/ubuntu/platform_server.h
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Copyright (C) 2016 Simon Fels <morphis@gravedo.de>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 3, as published
|
||||
* by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranties of
|
||||
* MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef ANBOX_UBUNTU_PLATFORM_SERVER_H_
|
||||
#define ANBOX_UBUNTU_PLATFORM_SERVER_H_
|
||||
|
||||
#include "anbox/bridge/platform_server.h"
|
||||
|
||||
namespace anbox {
|
||||
namespace ubuntu {
|
||||
class PlatformServer : public bridge::PlatformServer {
|
||||
public:
|
||||
PlatformServer(const std::shared_ptr<bridge::PendingCallCache> &pending_calls);
|
||||
virtual ~PlatformServer();
|
||||
|
||||
void handle_notification(anbox::protobuf::bridge::Notification const *request,
|
||||
anbox::protobuf::bridge::Void *response,
|
||||
google::protobuf::Closure *done) override;
|
||||
};
|
||||
} // namespace bridge
|
||||
} // namespace anbox
|
||||
|
||||
#endif
|
||||
Loading…
Add table
Add a link
Reference in a new issue