Rework some of the RPC service bits and add boot support

This commit is contained in:
Simon Fels 2016-07-04 12:10:31 +02:00
commit 1879e634c5
39 changed files with 746 additions and 106 deletions

View file

@ -45,6 +45,7 @@ set(SOURCES
anbox/common/fd_sets.h
anbox/common/variable_length_array.h
anbox/common/wait_handle.cpp
anbox/common/dispatcher.cpp
anbox/network/message_sender.h
anbox/network/message_receiver.h
@ -75,6 +76,7 @@ set(SOURCES
anbox/support/fingerprint_message_processor.cpp
anbox/support/gsm_message_processor.cpp
anbox/support/at_parser.cpp
anbox/support/bootanimation_message_processor.cpp
anbox/bridge/constants.h
anbox/bridge/connection_creator.cpp
@ -83,11 +85,11 @@ set(SOURCES
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/platform_api_skeleton.cpp
anbox/bridge/rpc_channel.cpp
anbox/bridge/platform_api_proxy.cpp
anbox/bridge/android_api_stub.cpp
anbox/ubuntu/platform_server.cpp
anbox/ubuntu/platform_api_skeleton.cpp
anbox/ubuntu/mir_display_connection.cpp
anbox/ubuntu/window_creator.cpp
anbox/ubuntu/window.cpp

View file

@ -15,7 +15,7 @@
*
*/
#include "anbox/bridge/platform_api_proxy.h"
#include "anbox/bridge/android_api_stub.h"
#include "anbox/bridge/rpc_channel.h"
#include "anbox/utils.h"
#include "anbox/config.h"
@ -29,26 +29,26 @@ namespace fs = boost::filesystem;
namespace anbox {
namespace bridge {
PlatformApiProxy::PlatformApiProxy() {
AndroidApiStub::AndroidApiStub() {
}
PlatformApiProxy::~PlatformApiProxy() {
AndroidApiStub::~AndroidApiStub() {
}
void PlatformApiProxy::set_rpc_channel(const std::shared_ptr<RpcChannel> &channel) {
void AndroidApiStub::set_rpc_channel(const std::shared_ptr<RpcChannel> &channel) {
channel_ = channel;
}
void PlatformApiProxy::reset_rpc_channel() {
void AndroidApiStub::reset_rpc_channel() {
channel_.reset();
}
void PlatformApiProxy::ensure_rpc_channel() {
void AndroidApiStub::ensure_rpc_channel() {
if (!channel_)
throw std::runtime_error("No remote client connected");
}
void PlatformApiProxy::install(const std::string &path) {
void AndroidApiStub::install(const std::string &path) {
ensure_rpc_channel();
const auto target_path = utils::string_format("%s/%s",
@ -74,7 +74,7 @@ void PlatformApiProxy::install(const std::string &path) {
channel_->call_method("install_application",
&message,
c->response.get(),
google::protobuf::NewCallback(this, &PlatformApiProxy::application_installed, c.get()));
google::protobuf::NewCallback(this, &AndroidApiStub::application_installed, c.get()));
install_wait_handle_.wait_for_all();
@ -82,11 +82,11 @@ void PlatformApiProxy::install(const std::string &path) {
throw std::runtime_error(c->response->error());
}
void PlatformApiProxy::application_installed(Request<protobuf::bridge::Void> *request) {
void AndroidApiStub::application_installed(Request<protobuf::bridge::Void> *request) {
install_wait_handle_.result_received();
}
void PlatformApiProxy::launch(const std::string &package, const std::string &activity) {
void AndroidApiStub::launch(const std::string &package, const std::string &activity) {
ensure_rpc_channel();
auto c = std::make_shared<Request<protobuf::bridge::Void>>();
@ -102,7 +102,7 @@ void PlatformApiProxy::launch(const std::string &package, const std::string &act
channel_->call_method("launch_application",
&message,
c->response.get(),
google::protobuf::NewCallback(this, &PlatformApiProxy::application_launched, c.get()));
google::protobuf::NewCallback(this, &AndroidApiStub::application_launched, c.get()));
launch_wait_handle_.wait_for_all();
@ -110,11 +110,11 @@ void PlatformApiProxy::launch(const std::string &package, const std::string &act
throw std::runtime_error(c->response->error());
}
void PlatformApiProxy::application_launched(Request<protobuf::bridge::Void> *request) {
void AndroidApiStub::application_launched(Request<protobuf::bridge::Void> *request) {
launch_wait_handle_.result_received();
}
void PlatformApiProxy::set_dns_servers(const std::string &domain, const std::vector<std::string> &servers) {
void AndroidApiStub::set_dns_servers(const std::string &domain, const std::vector<std::string> &servers) {
ensure_rpc_channel();
auto c = std::make_shared<Request<protobuf::bridge::Void>>();
@ -135,7 +135,7 @@ void PlatformApiProxy::set_dns_servers(const std::string &domain, const std::vec
channel_->call_method("set_dns_servers",
&message,
c->response.get(),
google::protobuf::NewCallback(this, &PlatformApiProxy::dns_servers_set, c.get()));
google::protobuf::NewCallback(this, &AndroidApiStub::dns_servers_set, c.get()));
set_dns_servers_wait_handle_.wait_for_all();
@ -143,7 +143,7 @@ void PlatformApiProxy::set_dns_servers(const std::string &domain, const std::vec
throw std::runtime_error(c->response->error());
}
void PlatformApiProxy::dns_servers_set(Request<protobuf::bridge::Void> *request) {
void AndroidApiStub::dns_servers_set(Request<protobuf::bridge::Void> *request) {
set_dns_servers_wait_handle_.result_received();
}
} // namespace bridge

View file

@ -15,8 +15,8 @@
*
*/
#ifndef ANBOX_ANDROID_APPLICATION_MANAGER_H_
#define ANBOX_ANDROID_APPLICATION_MANAGER_H_
#ifndef ANBOX_BRIDGE_ANDROID_API_STUB_H_
#define ANBOX_BRIDGE_ANDROID_API_STUB_H_
#include "anbox/application_manager.h"
#include "anbox/common/wait_handle.h"
@ -32,10 +32,10 @@ class Void;
} // namespace protobuf
namespace bridge {
class RpcChannel;
class PlatformApiProxy : public anbox::ApplicationManager {
class AndroidApiStub : public anbox::ApplicationManager {
public:
PlatformApiProxy();
~PlatformApiProxy();
AndroidApiStub();
~AndroidApiStub();
void set_rpc_channel(const std::shared_ptr<RpcChannel> &channel);
void reset_rpc_channel();

View file

@ -15,18 +15,18 @@
*
*/
#include "anbox/bridge/platform_server.h"
#include "anbox/bridge/platform_api_skeleton.h"
#include "anbox/logger.h"
#include "anbox_bridge.pb.h"
namespace anbox {
namespace bridge {
PlatformServer::PlatformServer(const std::shared_ptr<PendingCallCache> &pending_calls) :
PlatformApiSkeleton::PlatformApiSkeleton(const std::shared_ptr<PendingCallCache> &pending_calls) :
pending_calls_(pending_calls) {
}
PlatformServer::~PlatformServer() {
PlatformApiSkeleton::~PlatformApiSkeleton() {
}
} // namespace bridge
} // namespace anbox

View file

@ -35,10 +35,14 @@ class Void;
} // namespace protobuf
namespace bridge {
class PendingCallCache;
class PlatformServer {
class PlatformApiSkeleton {
public:
PlatformServer(const std::shared_ptr<PendingCallCache> &pending_calls);
virtual ~PlatformServer();
PlatformApiSkeleton(const std::shared_ptr<PendingCallCache> &pending_calls);
virtual ~PlatformApiSkeleton();
virtual void boot_finished(anbox::protobuf::bridge::Void const *request,
anbox::protobuf::bridge::Void *response,
google::protobuf::Closure *done) = 0;
virtual void handle_notification(anbox::protobuf::bridge::Notification const *request,
anbox::protobuf::bridge::Void *response,

View file

@ -16,7 +16,7 @@
*/
#include "anbox/bridge/platform_message_processor.h"
#include "anbox/bridge/platform_server.h"
#include "anbox/bridge/platform_api_skeleton.h"
#include "anbox/bridge/template_message_processor.h"
#include "anbox_bridge.pb.h"
@ -24,7 +24,7 @@
namespace anbox {
namespace bridge {
PlatformMessageProcessor::PlatformMessageProcessor(const std::shared_ptr<network::MessageSender> &sender,
const std::shared_ptr<PlatformServer> &server,
const std::shared_ptr<PlatformApiSkeleton> &server,
const std::shared_ptr<PendingCallCache> &pending_calls) :
MessageProcessor(sender, pending_calls),
server_(server) {
@ -34,9 +34,10 @@ PlatformMessageProcessor::~PlatformMessageProcessor() {
}
void PlatformMessageProcessor::dispatch(Invocation const& invocation) {
if (invocation.method_name() == "handle_notification") {
invoke(this, server_.get(), &PlatformServer::handle_notification, invocation);
}
if (invocation.method_name() == "handle_notification")
invoke(this, server_.get(), &PlatformApiSkeleton::handle_notification, invocation);
else if (invocation.method_name() == "boot_finished")
invoke(this, server_.get(), &PlatformApiSkeleton::boot_finished, invocation);
}
void PlatformMessageProcessor::process_event_sequence(const std::string&) {

View file

@ -22,11 +22,11 @@
namespace anbox {
namespace bridge {
class PlatformServer;
class PlatformApiSkeleton;
class PlatformMessageProcessor : public MessageProcessor {
public:
PlatformMessageProcessor(const std::shared_ptr<network::MessageSender> &sender,
const std::shared_ptr<PlatformServer> &server,
const std::shared_ptr<PlatformApiSkeleton> &server,
const std::shared_ptr<PendingCallCache> &pending_calls);
~PlatformMessageProcessor();
@ -34,7 +34,7 @@ public:
void process_event_sequence(const std::string &event) override;
private:
std::shared_ptr<PlatformServer> server_;
std::shared_ptr<PlatformApiSkeleton> server_;
};
} // namespace anbox
} // namespace network

View file

@ -24,6 +24,7 @@
#include "anbox/container.h"
#include "anbox/config.h"
#include "anbox/pid_persister.h"
#include "anbox/common/dispatcher.h"
#include "anbox/cmds/run.h"
#include "anbox/network/published_socket_connector.h"
#include "anbox/network/qemu_pipe_connection_creator.h"
@ -32,8 +33,8 @@
#include "anbox/bridge/connection_creator.h"
#include "anbox/bridge/platform_message_processor.h"
#include "anbox/bridge/rpc_channel.h"
#include "anbox/bridge/platform_api_proxy.h"
#include "anbox/ubuntu/platform_server.h"
#include "anbox/bridge/android_api_stub.h"
#include "anbox/ubuntu/platform_api_skeleton.h"
#include "anbox/ubuntu/window_creator.h"
#include "anbox/dbus/skeleton/service.h"
@ -69,6 +70,11 @@ anbox::cmds::Run::Run(const BusFactory& bus_factory)
// Just for the purpose to allow QtMir (or unity8) to find this on our /proc/*/cmdline
// for proper confinement etc.
flag(cli::make_flag(cli::Name{"desktop_file_hint"}, cli::Description{"Desktop file hint for QtMir/Unity8"}, desktop_file_hint_));
flag(cli::make_flag(cli::Name{"apk"}, cli::Description{"Android application to install on startup"}, apk_));
flag(cli::make_flag(cli::Name{"package"}, cli::Description{"Specifies the package the activity should be launched from."}, package_));
flag(cli::make_flag(cli::Name{"activity"}, cli::Description{"Activity to start from specified package"}, activity_));
flag(cli::make_flag(cli::Name{"icon"}, cli::Description{"Icon of the application to run"}, icon_));
action([this](const cli::Command::Context &ctx) {
if (rootfs_.empty() || !fs::is_directory(fs::path(rootfs_))) {
ctx.cout << "Not valid rootfs path provided" << std::endl;
@ -83,6 +89,7 @@ anbox::cmds::Run::Run(const BusFactory& bus_factory)
});
auto rt = Runtime::create();
auto dispatcher = anbox::common::create_dispatcher_for_runtime(rt);
auto input_manager = std::make_shared<input::Manager>(rt);
@ -102,9 +109,11 @@ anbox::cmds::Run::Run(const BusFactory& bus_factory)
auto qemu_pipe_connector = std::make_shared<network::PublishedSocketConnector>(
utils::string_format("%s/qemu_pipe", config::data_path()),
rt,
std::make_shared<network::QemuPipeConnectionCreator>(rt, renderer->socket_path()));
std::make_shared<network::QemuPipeConnectionCreator>(rt,
renderer->socket_path(),
icon_));
auto platform_proxy = std::make_shared<bridge::PlatformApiProxy>();
auto android_api_stub = std::make_shared<bridge::AndroidApiStub>();
auto bridge_connector = std::make_shared<network::PublishedSocketConnector>(
utils::string_format("%s/anbox_bridge", config::data_path()),
@ -115,8 +124,28 @@ anbox::cmds::Run::Run(const BusFactory& bus_factory)
auto rpc_channel = std::make_shared<bridge::RpcChannel>(pending_calls, sender);
// This is safe as long as we only support a single client. If we support
// more than one one day we need proper dispatching to the right one.
platform_proxy->set_rpc_channel(rpc_channel);
auto server = std::make_shared<ubuntu::PlatformServer>(pending_calls);
android_api_stub->set_rpc_channel(rpc_channel);
dispatcher->dispatch([&]() {
// FIXME make this configurable or once we have a bridge let the host
// act as a DNS proxy.
android_api_stub->set_dns_servers("anbox", std::vector<std::string>{ "8.8.8.8" });
});
auto server = std::make_shared<ubuntu::PlatformApiSekeleton>(pending_calls);
// FIXME Implement a delegate or use signals from properties-cpp
server->on_boot_finished([&](){
DEBUG("Boot finished.");
dispatcher->dispatch([&]() {
if (!apk_.empty()) {
DEBUG("Installing %s ..", apk_);
android_api_stub->install(apk_);
}
if (!package_.empty() || !activity_.empty())
android_api_stub->launch(package_, activity_);
});
});
return std::make_shared<bridge::PlatformMessageProcessor>(sender, server, pending_calls);
}));
@ -156,7 +185,7 @@ anbox::cmds::Run::Run(const BusFactory& bus_factory)
auto bus = bus_factory_();
bus->install_executor(core::dbus::asio::make_executor(bus, rt->service()));
auto skeleton = anbox::dbus::skeleton::Service::create_for_bus(bus, platform_proxy);
auto skeleton = anbox::dbus::skeleton::Service::create_for_bus(bus, android_api_stub);
rt->start();
container->start();

View file

@ -40,6 +40,10 @@ private:
BusFactory bus_factory_;
std::string rootfs_;
std::string desktop_file_hint_;
std::string apk_;
std::string package_;
std::string activity_;
std::string icon_;
};
} // namespace cmds
} // namespace anbox

View file

@ -0,0 +1,43 @@
/*
* Copyright (C) 2016 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 as published by
* the Free Software Foundation; version 3.
*
* 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: Thomas Voß <thomas.voss@canonical.com>
*
*/
#include "anbox/common/dispatcher.h"
namespace {
struct AsioStrandDispatcher : public anbox::common::Dispatcher {
public:
AsioStrandDispatcher(const std::shared_ptr<anbox::Runtime>& rt)
: rt{rt},
strand{rt->service()} {
}
void dispatch(const Task &task) override {
strand.post(task);
}
private:
std::shared_ptr<anbox::Runtime> rt;
boost::asio::io_service::strand strand;
};
}
std::shared_ptr<anbox::common::Dispatcher> anbox::common::create_dispatcher_for_runtime(
const std::shared_ptr<anbox::Runtime>& rt) {
return std::make_shared<AsioStrandDispatcher>(rt);
}

View file

@ -0,0 +1,43 @@
/*
* Copyright (C) 2016 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 as published by
* the Free Software Foundation; version 3.
*
* 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: Thomas Voß <thomas.voss@canonical.com>
*
*/
#ifndef ANBOX_COMMON_DISPATCHER_H_
#define ANBOX_COMMON_DISPATCHER_H_
#include "anbox/do_not_copy_or_move.h"
#include "anbox/runtime.h"
#include <memory>
namespace anbox {
namespace common {
class Dispatcher : public DoNotCopyOrMove {
public:
typedef std::function<void()> Task;
virtual void dispatch(const Task& task) = 0;
protected:
Dispatcher() = default;
};
std::shared_ptr<Dispatcher> create_dispatcher_for_runtime(const std::shared_ptr<Runtime>&);
} // namespace common
} // namespace anbox
#endif

View file

@ -28,17 +28,20 @@
#include "anbox/support/camera_message_processor.h"
#include "anbox/support/fingerprint_message_processor.h"
#include "anbox/support/gsm_message_processor.h"
#include "anbox/support/bootanimation_message_processor.h"
namespace ba = boost::asio;
namespace anbox {
namespace network {
QemuPipeConnectionCreator::QemuPipeConnectionCreator(const std::shared_ptr<Runtime> &rt,
const std::string &renderer_socket_path) :
const std::string &renderer_socket_path,
const std::string &boot_animation_icon_path) :
runtime_(rt),
next_connection_id_(0),
connections_(std::make_shared<Connections<SocketConnection>>()),
renderer_socket_path_(renderer_socket_path) {
renderer_socket_path_(renderer_socket_path),
boot_animation_icon_path_(boot_animation_icon_path) {
}
QemuPipeConnectionCreator::~QemuPipeConnectionCreator() {
@ -95,6 +98,8 @@ QemuPipeConnectionCreator::client_type QemuPipeConnectionCreator::identify_clien
return client_type::qemud_fingerprint;
else if (utils::string_starts_with(identifier_and_args, "pipe:qemud:gsm"))
return client_type::qemud_gsm;
else if (utils::string_starts_with(identifier_and_args, "pipe:anbox:bootanimation"))
return client_type::bootanimation;
return client_type::invalid;
}
@ -114,6 +119,8 @@ std::shared_ptr<MessageProcessor> QemuPipeConnectionCreator::create_processor(co
return std::make_shared<support::FingerprintMessageProcessor>(messenger);
else if (type == client_type::qemud_gsm)
return std::make_shared<support::GsmMessageProcessor>(messenger);
else if (type == client_type::bootanimation)
return std::make_shared<support::BootAnimationMessageProcessor>(messenger, boot_animation_icon_path_);
return std::make_shared<support::NullMessageProcessor>();
}

View file

@ -36,7 +36,8 @@ class QemuPipeConnectionCreator : public ConnectionCreator {
public:
QemuPipeConnectionCreator(
const std::shared_ptr<Runtime> &rt,
const std::string &renderer_socket_path);
const std::string &renderer_socket_path,
const std::string &boot_animation_icon_path);
~QemuPipeConnectionCreator() noexcept;
void create_connection_for(
@ -51,6 +52,7 @@ public:
qemud_camera,
qemud_fingerprint,
qemud_gsm,
bootanimation,
};
private:
@ -65,6 +67,7 @@ private:
std::shared_ptr<Connections<SocketConnection>> const connections_;
std::string renderer_socket_path_;
std::string boot_animation_icon_path_;
};
} // namespace anbox
} // namespace network

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/>.
*
*/
#include "anbox/logger.h"
#include "anbox/support/bootanimation_message_processor.h"
#include <fstream>
namespace anbox {
namespace support {
BootAnimationMessageProcessor::BootAnimationMessageProcessor(const std::shared_ptr<network::SocketMessenger> &messenger,
const std::string &icon_path) :
QemudMessageProcessor(messenger),
icon_path_(icon_path) {
}
BootAnimationMessageProcessor::~BootAnimationMessageProcessor() {
}
void BootAnimationMessageProcessor::handle_command(const std::string &command) {
DEBUG("command %s", command);
if (command == "retrieve-icon")
retrieve_icon();
}
void BootAnimationMessageProcessor::retrieve_icon() {
std::ifstream icon_file(icon_path_, std::ifstream::binary);
std::array<char, 1024> buffer;
while (icon_file.read(buffer.data(), buffer.size())) {
const auto bytes_read = icon_file.gcount();
messenger_->send(buffer.data(), bytes_read);
DEBUG("Sending %d bytes", bytes_read);
}
}
} // namespace support
} // namespace anbox

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_SUPPORT_BOOT_ANIMATION_MESSAGE_PROCESSOR_H_
#define ANBOX_SUPPORT_BOOT_ANIMATION_MESSAGE_PROCESSOR_H_
#include "anbox/support/qemud_message_processor.h"
namespace anbox {
namespace support {
class BootAnimationMessageProcessor : public QemudMessageProcessor {
public:
BootAnimationMessageProcessor(const std::shared_ptr<network::SocketMessenger> &messenger,
const std::string &icon_path);
~BootAnimationMessageProcessor();
protected:
void handle_command(const std::string &command) override;
private:
void retrieve_icon();
std::string icon_path_;
};
} // namespace graphics
} // namespace anbox
#endif

View file

@ -15,21 +15,23 @@
*
*/
#include "anbox/ubuntu/platform_server.h"
#include "anbox/ubuntu/platform_api_skeleton.h"
#include "anbox/common/dispatcher.h"
#include "anbox/bridge/android_api_stub.h"
#include "anbox/logger.h"
#include "anbox_bridge.pb.h"
namespace anbox {
namespace ubuntu {
PlatformServer::PlatformServer(const std::shared_ptr<bridge::PendingCallCache> &pending_calls) :
bridge::PlatformServer(pending_calls) {
PlatformApiSekeleton::PlatformApiSekeleton(const std::shared_ptr<bridge::PendingCallCache> &pending_calls) :
bridge::PlatformApiSkeleton(pending_calls) {
}
PlatformServer::~PlatformServer() {
PlatformApiSekeleton::~PlatformApiSekeleton() {
}
void PlatformServer::handle_notification(anbox::protobuf::bridge::Notification const *request,
void PlatformApiSekeleton::handle_notification(anbox::protobuf::bridge::Notification const *request,
anbox::protobuf::bridge::Void *response,
google::protobuf::Closure *done) {
(void) request;
@ -38,5 +40,20 @@ void PlatformServer::handle_notification(anbox::protobuf::bridge::Notification c
done->Run();
}
void PlatformApiSekeleton::boot_finished(anbox::protobuf::bridge::Void const *request,
anbox::protobuf::bridge::Void *response,
google::protobuf::Closure *done) {
(void) request;
(void) response;
if (on_boot_finished_action_)
on_boot_finished_action_();
done->Run();
}
void PlatformApiSekeleton::on_boot_finished(const std::function<void()> &action) {
on_boot_finished_action_ = action;
}
} // namespace ubuntu
} // namespace anbox

View file

@ -18,18 +18,33 @@
#ifndef ANBOX_UBUNTU_PLATFORM_SERVER_H_
#define ANBOX_UBUNTU_PLATFORM_SERVER_H_
#include "anbox/bridge/platform_server.h"
#include "anbox/bridge/platform_api_skeleton.h"
namespace anbox {
namespace common {
class Dispatcher;
} // namespace common
namespace bridge {
class AndroidApiStub;
} // namespace bridge
namespace ubuntu {
class PlatformServer : public bridge::PlatformServer {
class PlatformApiSekeleton : public bridge::PlatformApiSkeleton {
public:
PlatformServer(const std::shared_ptr<bridge::PendingCallCache> &pending_calls);
virtual ~PlatformServer();
PlatformApiSekeleton(const std::shared_ptr<bridge::PendingCallCache> &pending_calls);
virtual ~PlatformApiSekeleton();
void handle_notification(anbox::protobuf::bridge::Notification const *request,
anbox::protobuf::bridge::Void *response,
google::protobuf::Closure *done) override;
void boot_finished(anbox::protobuf::bridge::Void const *request,
anbox::protobuf::bridge::Void *response,
google::protobuf::Closure *done) override;
void on_boot_finished(const std::function<void()> &action);
private:
std::function<void()> on_boot_finished_action_;
};
} // namespace bridge
} // namespace anbox