First part of an RPC mechanism for container <-> host communication

Mostly based on the protobuf based implementation from Mir.
This commit is contained in:
Simon Fels 2016-06-28 00:21:30 +02:00
commit da971a88c3
38 changed files with 1750 additions and 52 deletions

View file

@ -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))

View file

@ -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)

View 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
View 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

View 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

View 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

View 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

View 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

View file

@ -15,6 +15,9 @@
*
*/
#include "android/service/daemon.h"
int main(int, char**) {
return 0;
anbox::android::Daemon daemon;
return daemon.run();
}

View 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

View 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

View 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
View 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