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
50
Android.mk
Normal file
50
Android.mk
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
LOCAL_PATH:= $(call my-dir)
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_MODULE_TAGS := optional
|
||||
LOCAL_MODULE := libprocess-cpp-minimal
|
||||
LOCAL_SRC_FILES := \
|
||||
external/process-cpp-minimal/src/core/posix/process.cpp \
|
||||
external/process-cpp-minimal/src/core/posix/process_group.cpp \
|
||||
external/process-cpp-minimal/src/core/posix/signal.cpp \
|
||||
external/process-cpp-minimal/src/core/posix/signalable.cpp \
|
||||
external/process-cpp-minimal/src/core/posix/standard_stream.cpp \
|
||||
external/process-cpp-minimal/src/core/posix/wait.cpp
|
||||
LOCAL_CFLAGS := \
|
||||
-fexceptions
|
||||
LOCAL_C_INCLUDES += \
|
||||
$(LOCAL_PATH)/external/process-cpp-minimal/include
|
||||
include $(BUILD_STATIC_LIBRARY)
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_MODULE_TAGS := optional
|
||||
LOCAL_MODULE_CLASS := EXECUTABLES
|
||||
LOCAL_MODULE := anboxd
|
||||
LOCAL_SRC_FILES := \
|
||||
android/service/main.cpp \
|
||||
android/service/daemon.cpp \
|
||||
android/service/host_connector.cpp \
|
||||
android/service/local_socket_connection.cpp \
|
||||
android/service/message_processor.cpp \
|
||||
src/anbox/common/fd.cpp \
|
||||
src/anbox/bridge/message_processor.cpp \
|
||||
src/anbox/bridge/pending_call_cache.cpp \
|
||||
src/anbox/bridge/rpc_channel.cpp \
|
||||
src/anbox/protobuf/bridge.proto
|
||||
proto_header_dir := $(call local-generated-sources-dir)/proto/$(LOCAL_PATH)/src/anbox/protobuf
|
||||
LOCAL_C_INCLUDES += \
|
||||
$(proto_header_dir) \
|
||||
$(LOCAL_PATH)/external/process-cpp-minimal/include \
|
||||
$(LOCAL_PATH)/src \
|
||||
$(LOCAL_PATH)/android/service
|
||||
LOCAL_EXPORT_C_INCLUDE_DIRS += $(proto_header_dir)
|
||||
LOCAL_STATIC_LIBRARIES := \
|
||||
libprocess-cpp-minimal
|
||||
LOCAL_SHARED_LIBRARIES := \
|
||||
liblog \
|
||||
libprotobuf-cpp-lite \
|
||||
libsysutils
|
||||
LOCAL_CFLAGS := \
|
||||
-fexceptions \
|
||||
-std=c++1y
|
||||
include $(BUILD_EXECUTABLE)
|
||||
|
|
@ -60,6 +60,7 @@ find_package(PkgConfig)
|
|||
find_package(Threads)
|
||||
find_package(EGL REQUIRED)
|
||||
find_package(GLESv2 REQUIRED)
|
||||
find_package(Protobuf REQUIRED)
|
||||
|
||||
# TODO(morphis): make mir an optional requirement so we can also add support
|
||||
# for X11, wayland, ... at a later point if needed.
|
||||
|
|
|
|||
|
|
@ -1,43 +0,0 @@
|
|||
LOCAL_PATH:= $(call my-dir)
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_MODULE_TAGS := optional
|
||||
LOCAL_SRC_FILES = \
|
||||
jni/anbox_support.cpp \
|
||||
jni/application_manager.cpp \
|
||||
jni/jni_helper.cpp
|
||||
LOCAL_C_INCLUDES := \
|
||||
$(JNI_H_INCLUDE) \
|
||||
libcore/include
|
||||
LOCAL_SHARED_LIBRARIES := \
|
||||
liblog \
|
||||
libnativehelper
|
||||
LOCAL_MODULE := libanbox_support
|
||||
|
||||
include $(BUILD_SHARED_LIBRARY)
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_MODULE_TAGS := optional
|
||||
LOCAL_AIDL_INCLUDES := $(LOCAL_PATH)/java
|
||||
LOCAL_SRC_FILES := $(call all-java-files-under, java)
|
||||
LOCAL_JAVA_LIBRARIES := telephony-common
|
||||
LOCAL_JNI_SHARED_LIBRARIES := \
|
||||
libanbox_support
|
||||
# Block certain packages from being installed
|
||||
# LOCAL_OVERRIDES_PACKAGES := \
|
||||
# SystemUI \
|
||||
# Home \
|
||||
# Launcher2 \
|
||||
# Calculator \
|
||||
# BasicDreams \
|
||||
# Calendar \
|
||||
# PrintSpooler \
|
||||
# WallpaperCropper
|
||||
LOCAL_PACKAGE_NAME := anboxd
|
||||
LOCAL_CERTIFICATE := platform
|
||||
LOCAL_PRIVILEGED_MODULE := true
|
||||
|
||||
include $(BUILD_PACKAGE)
|
||||
|
||||
include $(call all-makefiles-under,$(LOCAL_PATH))
|
||||
|
|
@ -1,4 +1,21 @@
|
|||
include_directories(
|
||||
${CMAKE_SOURCE_DIR}
|
||||
${CMAKE_SOURCE_DIR}/src
|
||||
${CMAKE_BINARY_DIR}/src)
|
||||
|
||||
set(ANBOXD_SOURCES
|
||||
${CMAKE_SOURCE_DIR}/src/anbox/bridge/message_processor.cpp
|
||||
${CMAKE_SOURCE_DIR}/src/anbox/bridge/pending_call_cache.cpp
|
||||
${CMAKE_SOURCE_DIR}/src/anbox/common/fd.cpp
|
||||
service/server.cpp
|
||||
service/message_processor.cpp
|
||||
service/local_socket_connection.cpp
|
||||
service/host_connector.cpp
|
||||
service/daemon.cpp
|
||||
service/main.cpp)
|
||||
|
||||
add_executable(anboxd ${ANBOXD_SOURCES})
|
||||
target_link_libraries(anboxd
|
||||
pthread
|
||||
process-cpp
|
||||
anbox-protobuf)
|
||||
|
|
|
|||
49
android/service/daemon.cpp
Normal file
49
android/service/daemon.cpp
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* 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 "android/service/daemon.h"
|
||||
#include "android/service/host_connector.h"
|
||||
|
||||
#include "core/posix/signal.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <cstdlib>
|
||||
|
||||
namespace anbox {
|
||||
namespace android {
|
||||
Daemon::Daemon() {
|
||||
}
|
||||
|
||||
Daemon::~Daemon() {
|
||||
}
|
||||
|
||||
int Daemon::run() {
|
||||
auto trap = core::posix::trap_signals_for_process({core::posix::Signal::sig_term,
|
||||
core::posix::Signal::sig_int});
|
||||
trap->signal_raised().connect([trap](const core::posix::Signal&) {
|
||||
trap->stop();
|
||||
});
|
||||
|
||||
auto host_connector = std::make_shared<HostConnector>();
|
||||
|
||||
trap->run();
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
} // namespace android
|
||||
} // namespace anbox
|
||||
33
android/service/daemon.h
Normal file
33
android/service/daemon.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_ANDROID_DAEMON_H_
|
||||
#define ANBOX_ANDROID_DAEMON_H_
|
||||
|
||||
namespace anbox {
|
||||
namespace android {
|
||||
class Daemon {
|
||||
public:
|
||||
Daemon();
|
||||
~Daemon();
|
||||
|
||||
int run();
|
||||
};
|
||||
} // namespace android
|
||||
} // namespace anbox
|
||||
|
||||
#endif
|
||||
74
android/service/host_connector.cpp
Normal file
74
android/service/host_connector.cpp
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* 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 "android/service/host_connector.h"
|
||||
#include "android/service/local_socket_connection.h"
|
||||
#include "android/service/message_processor.h"
|
||||
#include "android/service/server.h"
|
||||
|
||||
#include <functional>
|
||||
#include <array>
|
||||
|
||||
namespace anbox {
|
||||
namespace android {
|
||||
HostConnector::HostConnector() :
|
||||
socket_(std::make_shared<LocalSocketConnection>("/dev/anbox_bridge")),
|
||||
pending_calls_(std::make_shared<bridge::PendingCallCache>()),
|
||||
server_(std::make_shared<Server>()),
|
||||
message_processor_(std::make_shared<MessageProcessor>(socket_, pending_calls_, server_)),
|
||||
running_(false) {
|
||||
}
|
||||
|
||||
HostConnector::~HostConnector() {
|
||||
}
|
||||
|
||||
void HostConnector::start() {
|
||||
if (running_)
|
||||
return;
|
||||
|
||||
running_.exchange(true);
|
||||
thread_ = std::thread(std::bind(&HostConnector::main_loop, this));
|
||||
}
|
||||
|
||||
void HostConnector::stop() {
|
||||
if (!running_.exchange(false))
|
||||
return;
|
||||
|
||||
thread_.join();
|
||||
}
|
||||
|
||||
void HostConnector::main_loop() {
|
||||
while (running_) {
|
||||
std::array<std::uint8_t, 8192> buffer;
|
||||
const auto bytes_read = socket_->read_all(buffer.data(), buffer.size());
|
||||
if (bytes_read == 0)
|
||||
break;
|
||||
|
||||
// MessageProcessor wants an vector so give it what it wants until
|
||||
// we refactor this.
|
||||
std::vector<std::uint8_t> data;
|
||||
for (auto n = 0; n < bytes_read; n++)
|
||||
data.push_back(buffer[n]);
|
||||
|
||||
if (!message_processor_->process_data(data))
|
||||
break;
|
||||
}
|
||||
|
||||
// FIXME notify our core that we've stopped
|
||||
}
|
||||
} // namespace android
|
||||
} // namespace anbox
|
||||
54
android/service/host_connector.h
Normal file
54
android/service/host_connector.h
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* 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_ANDROID_HOST_CONNECTOR_H_
|
||||
#define ANBOX_ANDROID_HOST_CONNECTOR_H_
|
||||
|
||||
#include <memory>
|
||||
#include <thread>
|
||||
#include <atomic>
|
||||
|
||||
namespace anbox {
|
||||
namespace bridge {
|
||||
class PendingCallCache;
|
||||
} // namespace bridge
|
||||
namespace android {
|
||||
class LocalSocketConnection;
|
||||
class MessageProcessor;
|
||||
class Server;
|
||||
class HostConnector {
|
||||
public:
|
||||
HostConnector();
|
||||
~HostConnector();
|
||||
|
||||
void start();
|
||||
void stop();
|
||||
|
||||
private:
|
||||
void main_loop();
|
||||
|
||||
std::shared_ptr<LocalSocketConnection> socket_;
|
||||
std::shared_ptr<bridge::PendingCallCache> pending_calls_;
|
||||
std::shared_ptr<Server> server_;
|
||||
std::shared_ptr<MessageProcessor> message_processor_;
|
||||
std::thread thread_;
|
||||
std::atomic<bool> running_;
|
||||
};
|
||||
} // namespace android
|
||||
} // namespace anbox
|
||||
|
||||
#endif
|
||||
77
android/service/local_socket_connection.cpp
Normal file
77
android/service/local_socket_connection.cpp
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
* 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 "android/service/local_socket_connection.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
|
||||
namespace {
|
||||
bool socket_error_is_transient(int error_code) {
|
||||
return (error_code == EINTR);
|
||||
}
|
||||
}
|
||||
|
||||
namespace anbox {
|
||||
namespace android {
|
||||
LocalSocketConnection::LocalSocketConnection(const std::string &path) :
|
||||
fd_(Fd::invalid) {
|
||||
|
||||
struct sockaddr_un socket_address;
|
||||
memset(&socket_address, 0, sizeof(socket_address));
|
||||
|
||||
socket_address.sun_family = AF_UNIX;
|
||||
memcpy(socket_address.sun_path, path.data(), path.size());
|
||||
|
||||
fd_ = Fd{socket(AF_UNIX, SOCK_STREAM, 0)};
|
||||
if (connect(fd_, reinterpret_cast<sockaddr*>(&socket_address), sizeof(socket_address)) < 0)
|
||||
throw std::runtime_error("Failed to connect to server socket");
|
||||
}
|
||||
|
||||
LocalSocketConnection::~LocalSocketConnection() {
|
||||
if (fd_ > 0)
|
||||
::close(fd_);
|
||||
}
|
||||
|
||||
ssize_t LocalSocketConnection::read_all(std::uint8_t *buffer, const size_t &size) {
|
||||
ssize_t bytes_read = ::recv(fd_, reinterpret_cast<void*>(buffer), size, 0);
|
||||
return bytes_read;
|
||||
}
|
||||
|
||||
void LocalSocketConnection::send(char const* data, size_t length) {
|
||||
size_t bytes_written{0};
|
||||
|
||||
while(bytes_written < length) {
|
||||
ssize_t const result = ::send(fd_,
|
||||
data + bytes_written,
|
||||
length - bytes_written,
|
||||
MSG_NOSIGNAL);
|
||||
if (result < 0) {
|
||||
if (socket_error_is_transient(errno))
|
||||
continue;
|
||||
else
|
||||
throw std::runtime_error("Failed to send message to server");
|
||||
}
|
||||
|
||||
bytes_written += result;
|
||||
}
|
||||
}
|
||||
} // namespace android
|
||||
} // namespace anbox
|
||||
43
android/service/local_socket_connection.h
Normal file
43
android/service/local_socket_connection.h
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* 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_ANDROID_LOCAL_SOCKET_CONNECTION_H_
|
||||
#define ANBOX_ANDROID_LOCAL_SOCKET_CONNECTION_H_
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "anbox/common/fd.h"
|
||||
#include "anbox/network/message_sender.h"
|
||||
|
||||
namespace anbox {
|
||||
namespace android {
|
||||
class LocalSocketConnection : public network::MessageSender {
|
||||
public:
|
||||
LocalSocketConnection(const std::string &path);
|
||||
~LocalSocketConnection();
|
||||
|
||||
ssize_t read_all(std::uint8_t *buffer, const size_t &size);
|
||||
void send(char const* data, size_t length) override;
|
||||
|
||||
private:
|
||||
Fd fd_;
|
||||
};
|
||||
} // namespace android
|
||||
} // namespace anbox
|
||||
|
||||
#endif
|
||||
|
|
@ -15,6 +15,9 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#include "android/service/daemon.h"
|
||||
|
||||
int main(int, char**) {
|
||||
return 0;
|
||||
anbox::android::Daemon daemon;
|
||||
return daemon.run();
|
||||
}
|
||||
|
|
|
|||
45
android/service/message_processor.cpp
Normal file
45
android/service/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 "android/service/message_processor.h"
|
||||
#include "android/service/server.h"
|
||||
|
||||
#include "anbox/bridge/template_message_processor.h"
|
||||
|
||||
namespace anbox {
|
||||
namespace android {
|
||||
MessageProcessor::MessageProcessor(const std::shared_ptr<network::MessageSender> &sender,
|
||||
const std::shared_ptr<bridge::PendingCallCache> &pending_calls,
|
||||
const std::shared_ptr<Server> &server) :
|
||||
bridge::MessageProcessor(sender, pending_calls),
|
||||
server_(server) {
|
||||
}
|
||||
|
||||
MessageProcessor::~MessageProcessor() {
|
||||
}
|
||||
|
||||
void MessageProcessor::dispatch(bridge::Invocation const& invocation) {
|
||||
if (invocation.method_name() == "install_application")
|
||||
invoke(this, server_.get(), &Server::install_application, invocation);
|
||||
else if (invocation.method_name() == "launch_application")
|
||||
invoke(this, server_.get(), &Server::launch_application, invocation);
|
||||
}
|
||||
|
||||
void MessageProcessor::process_event_sequence(const std::string&) {
|
||||
}
|
||||
} // namespace anbox
|
||||
} // namespace network
|
||||
42
android/service/message_processor.h
Normal file
42
android/service/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_ANDROID_MESSAGE_PROCESSOR_H_
|
||||
#define ANBOX_ANDROID_MESSAGE_PROCESSOR_H_
|
||||
|
||||
#include "anbox/bridge/message_processor.h"
|
||||
|
||||
namespace anbox {
|
||||
namespace android {
|
||||
class Server;
|
||||
class MessageProcessor : public bridge::MessageProcessor {
|
||||
public:
|
||||
MessageProcessor(const std::shared_ptr<network::MessageSender> &sender,
|
||||
const std::shared_ptr<bridge::PendingCallCache> &pending_calls,
|
||||
const std::shared_ptr<Server> &server);
|
||||
~MessageProcessor();
|
||||
|
||||
void dispatch(bridge::Invocation const& invocation) override;
|
||||
void process_event_sequence(const std::string &event) override;
|
||||
|
||||
private:
|
||||
std::shared_ptr<Server> server_;
|
||||
};
|
||||
} // namespace anbox
|
||||
} // namespace network
|
||||
|
||||
#endif
|
||||
49
android/service/server.cpp
Normal file
49
android/service/server.cpp
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* 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 "android/service/server.h"
|
||||
|
||||
#include "anbox_bridge.pb.h"
|
||||
|
||||
namespace anbox {
|
||||
namespace android {
|
||||
Server::Server() {
|
||||
}
|
||||
|
||||
Server::~Server() {
|
||||
}
|
||||
|
||||
void Server::install_application(anbox::protobuf::bridge::InstallApplication const *request,
|
||||
anbox::protobuf::bridge::Void *response,
|
||||
google::protobuf::Closure *done) {
|
||||
(void) request;
|
||||
(void) response;
|
||||
|
||||
done->Run();
|
||||
}
|
||||
|
||||
void Server::launch_application(anbox::protobuf::bridge::LaunchApplication const *request,
|
||||
anbox::protobuf::bridge::Void *response,
|
||||
google::protobuf::Closure *done) {
|
||||
(void) request;
|
||||
(void) response;
|
||||
|
||||
done->Run();
|
||||
}
|
||||
|
||||
} // namespace anbox
|
||||
} // namespace network
|
||||
52
android/service/server.h
Normal file
52
android/service/server.h
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* 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_ANDROID_SERVER_H_
|
||||
#define ANBOX_ANDROID_SERVER_H_
|
||||
|
||||
namespace google {
|
||||
namespace protobuf {
|
||||
class Closure;
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
||||
|
||||
namespace anbox {
|
||||
namespace protobuf {
|
||||
namespace bridge {
|
||||
class InstallApplication;
|
||||
class LaunchApplication;
|
||||
class Void;
|
||||
} // namespace bridge
|
||||
} // namespace protobuf
|
||||
namespace android {
|
||||
class Server {
|
||||
public:
|
||||
Server();
|
||||
~Server();
|
||||
|
||||
void install_application(anbox::protobuf::bridge::InstallApplication const *request,
|
||||
anbox::protobuf::bridge::Void *response,
|
||||
google::protobuf::Closure *done);
|
||||
|
||||
void launch_application(anbox::protobuf::bridge::LaunchApplication const *request,
|
||||
anbox::protobuf::bridge::Void *response,
|
||||
google::protobuf::Closure *done);
|
||||
};
|
||||
} // namespace android
|
||||
} // namespace anbox
|
||||
|
||||
#endif
|
||||
|
|
@ -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