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

@ -28,8 +28,12 @@ LOCAL_SRC_FILES := \
android/service/host_connector.cpp \
android/service/local_socket_connection.cpp \
android/service/message_processor.cpp \
android/service/platform_api.cpp \
android/service/android_api_skeleton.cpp \
android/service/platform_service_interface.cpp \
android/service/platform_service.cpp \
android/service/platform_api_stub.cpp \
src/anbox/common/fd.cpp \
src/anbox/common/wait_handle.cpp \
src/anbox/bridge/message_processor.cpp \
src/anbox/bridge/pending_call_cache.cpp \
src/anbox/bridge/rpc_channel.cpp \
@ -46,12 +50,30 @@ LOCAL_STATIC_LIBRARIES := \
LOCAL_SHARED_LIBRARIES := \
liblog \
libprotobuf-cpp-lite \
libsysutils
libsysutils \
libbinder \
libcutils \
libutils
LOCAL_CFLAGS := \
-fexceptions \
-std=c++1y
include $(BUILD_EXECUTABLE)
include $(CLEAR_VARS)
LOCAL_MODULE_CLASS := EXECUTABLES
LOCAL_MODULE := anbox_test_platform_service
LOCAL_SRC_FILES := \
android/service/platform_service_interface.cpp \
android/service/test_platform_service.cpp
LOCAL_C_INCLUDES += \
$(LOCAL_PATH)/android/service
LOCAL_SHARED_LIBRARIES := \
liblog \
libbinder \
libcutils \
libutils
include $(BUILD_EXECUTABLE)
# Include the Android.mk files below will override LOCAL_PATH so we
# have to take a copy of it here.
TMP_PATH := $(LOCAL_PATH)
@ -61,3 +83,4 @@ TMP_PATH := $(LOCAL_PATH)
# include $(LOCAL_PATH)/android/shared_compositor/Android.mk
include $(TMP_PATH)/android/launcher/Android.mk
include $(TMP_PATH)/android/shared_compositor/Android.mk
include $(TMP_PATH)/android/bootanimation/Android.mk

View file

@ -7,7 +7,10 @@ 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/platform_api.cpp
service/platform_service.cpp
service/platform_service_interface.cpp
service/platform_api_stub.cpp
service/android_api_skeleton.cpp
service/message_processor.cpp
service/local_socket_connection.cpp
service/host_connector.cpp
@ -31,3 +34,13 @@ set(ANBOX_SHARED_COMPOSITOR
add_executable(anbox_shared_compositor ${ANBOX_SHARED_COMPOSITOR})
set_target_properties(anbox_shared_compositor
PROPERTIES EXCLUDE_FROM_ALL 1 EXCLUDE_FROM_DEFAULT_BUILD 1)
set(TEST_PLATFORM_SERVICE
service/test_platform_service.cpp)
add_executable(test_platform_service ${TEST_PLATFORM_SERVICE})
# As we're adding Android specific bits in this project we can't
# build this safely within default build anymore. We keep this
# for easy integration into used IDEs.
set_target_properties(test_platform_service
PROPERTIES EXCLUDE_FROM_ALL 1 EXCLUDE_FROM_DEFAULT_BUILD 1)

View file

@ -15,7 +15,7 @@
*
*/
#include "android/service/platform_api.h"
#include "android/service/android_api_skeleton.h"
#include "anbox_bridge.pb.h"
@ -30,14 +30,13 @@ std::map<std::string,std::string> common_env = {
}
namespace anbox {
namespace android {
PlatformApi::PlatformApi() {
AndroidApiSkeleton::AndroidApiSkeleton() {
}
PlatformApi::~PlatformApi() {
AndroidApiSkeleton::~AndroidApiSkeleton() {
}
void PlatformApi::wait_for_process(core::posix::ChildProcess &process,
void AndroidApiSkeleton::wait_for_process(core::posix::ChildProcess &process,
anbox::protobuf::bridge::Void *response) {
const auto result = process.wait_for(core::posix::wait::Flags::untraced);
if (result.status != core::posix::wait::Result::Status::exited ||
@ -48,7 +47,7 @@ void PlatformApi::wait_for_process(core::posix::ChildProcess &process,
}
}
void PlatformApi::install_application(anbox::protobuf::bridge::InstallApplication const *request,
void AndroidApiSkeleton::install_application(anbox::protobuf::bridge::InstallApplication const *request,
anbox::protobuf::bridge::Void *response,
google::protobuf::Closure *done) {
(void) response;
@ -65,7 +64,7 @@ void PlatformApi::install_application(anbox::protobuf::bridge::InstallApplicatio
done->Run();
}
void PlatformApi::launch_application(anbox::protobuf::bridge::LaunchApplication const *request,
void AndroidApiSkeleton::launch_application(anbox::protobuf::bridge::LaunchApplication const *request,
anbox::protobuf::bridge::Void *response,
google::protobuf::Closure *done) {
(void) response;
@ -86,7 +85,7 @@ void PlatformApi::launch_application(anbox::protobuf::bridge::LaunchApplication
done->Run();
}
void PlatformApi::set_dns_servers(anbox::protobuf::bridge::SetDnsServers const *request,
void AndroidApiSkeleton::set_dns_servers(anbox::protobuf::bridge::SetDnsServers const *request,
anbox::protobuf::bridge::Void *response,
google::protobuf::Closure *done) {
(void) response;
@ -107,4 +106,3 @@ void PlatformApi::set_dns_servers(anbox::protobuf::bridge::SetDnsServers const *
done->Run();
}
} // namespace anbox
} // namespace network

View file

@ -15,8 +15,8 @@
*
*/
#ifndef ANBOX_ANDROID_PLATFORM_API_H_
#define ANBOX_ANDROID_PLATFORM_API_H_
#ifndef ANBOX_PLATFORM_API_SKELETON_H_
#define ANBOX_PLATFORM_API_SKELETON_H_
namespace google {
namespace protobuf {
@ -39,11 +39,10 @@ class SetDnsServers;
class Void;
} // namespace bridge
} // namespace protobuf
namespace android {
class PlatformApi {
class AndroidApiSkeleton {
public:
PlatformApi();
~PlatformApi();
AndroidApiSkeleton();
~AndroidApiSkeleton();
void install_application(anbox::protobuf::bridge::InstallApplication const *request,
anbox::protobuf::bridge::Void *response,
@ -61,7 +60,6 @@ private:
void wait_for_process(core::posix::ChildProcess &process,
anbox::protobuf::bridge::Void *response);
};
} // namespace android
} // namespace anbox
#endif

View file

@ -17,6 +17,7 @@
#include "android/service/daemon.h"
#include "android/service/host_connector.h"
#include "android/service/platform_service.h"
#include "core/posix/signal.h"
@ -24,8 +25,11 @@
#include <cstdlib>
#include <binder/IPCThreadState.h>
#include <binder/ProcessState.h>
#include <binder/IServiceManager.h>
namespace anbox {
namespace android {
Daemon::Daemon() {
}
@ -42,9 +46,16 @@ int Daemon::run() {
auto host_connector = std::make_shared<HostConnector>();
host_connector->start();
android::defaultServiceManager()->addService(
android::String16(android::PlatformService::service_name()),
new android::PlatformService(host_connector->platform_api_stub()));
android::ProcessState::self()->startThreadPool();
trap->run();
android::IPCThreadState::self()->joinThreadPool();
return EXIT_SUCCESS;
}
} // namespace android
} // namespace anbox

View file

@ -19,7 +19,6 @@
#define ANBOX_ANDROID_DAEMON_H_
namespace anbox {
namespace android {
class Daemon {
public:
Daemon();
@ -27,7 +26,6 @@ public:
int run();
};
} // namespace android
} // namespace anbox
#endif

View file

@ -18,18 +18,22 @@
#include "android/service/host_connector.h"
#include "android/service/local_socket_connection.h"
#include "android/service/message_processor.h"
#include "android/service/platform_api.h"
#include "android/service/android_api_skeleton.h"
#include "android/service/platform_api_stub.h"
#include "anbox/bridge/rpc_channel.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>()),
platform_api_(std::make_shared<PlatformApi>()),
message_processor_(std::make_shared<MessageProcessor>(socket_, pending_calls_, platform_api_)),
android_api_skeleton_(std::make_shared<AndroidApiSkeleton>()),
message_processor_(std::make_shared<MessageProcessor>(socket_, pending_calls_, android_api_skeleton_)),
rpc_channel_(std::make_shared<bridge::RpcChannel>(pending_calls_, socket_)),
platform_api_stub_(std::make_shared<PlatformApiStub>(rpc_channel_)),
running_(false) {
}
@ -61,7 +65,7 @@ void HostConnector::main_loop() {
// 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++)
for (unsigned n = 0; n < bytes_read; n++)
data.push_back(buffer[n]);
if (!message_processor_->process_data(data))
@ -70,5 +74,8 @@ void HostConnector::main_loop() {
// FIXME notify our core that we've stopped
}
} // namespace android
std::shared_ptr<anbox::PlatformApiStub> HostConnector::platform_api_stub() const {
return platform_api_stub_;
}
} // namespace anbox

View file

@ -25,11 +25,12 @@
namespace anbox {
namespace bridge {
class PendingCallCache;
class RpcChannel;
} // namespace bridge
namespace android {
class LocalSocketConnection;
class MessageProcessor;
class PlatformApi;
class AndroidApiSkeleton;
class PlatformApiStub;
class HostConnector {
public:
HostConnector();
@ -38,17 +39,20 @@ public:
void start();
void stop();
std::shared_ptr<anbox::PlatformApiStub> platform_api_stub() const;
private:
void main_loop();
std::shared_ptr<LocalSocketConnection> socket_;
std::shared_ptr<bridge::PendingCallCache> pending_calls_;
std::shared_ptr<PlatformApi> platform_api_;
std::shared_ptr<AndroidApiSkeleton> android_api_skeleton_;
std::shared_ptr<MessageProcessor> message_processor_;
std::shared_ptr<bridge::RpcChannel> rpc_channel_;
std::shared_ptr<anbox::PlatformApiStub> platform_api_stub_;
std::thread thread_;
std::atomic<bool> running_;
};
} // namespace android
} // namespace anbox
#endif

View file

@ -23,6 +23,9 @@
#include <unistd.h>
#include <errno.h>
#define LOG_TAG "Anbox"
#include <cutils/log.h>
namespace {
bool socket_error_is_transient(int error_code) {
return (error_code == EINTR);
@ -30,7 +33,6 @@ bool socket_error_is_transient(int error_code) {
}
namespace anbox {
namespace android {
LocalSocketConnection::LocalSocketConnection(const std::string &path) :
fd_(Fd::invalid) {
@ -52,12 +54,15 @@ LocalSocketConnection::~LocalSocketConnection() {
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);
ALOGI("Read %d bytes", bytes_read);
return bytes_read;
}
void LocalSocketConnection::send(char const* data, size_t length) {
size_t bytes_written{0};
ALOGI("Writing %d bytes", length);
while(bytes_written < length) {
ssize_t const result = ::send(fd_,
data + bytes_written,
@ -73,5 +78,4 @@ void LocalSocketConnection::send(char const* data, size_t length) {
bytes_written += result;
}
}
} // namespace android
} // namespace anbox

View file

@ -25,7 +25,6 @@
#include "anbox/network/message_sender.h"
namespace anbox {
namespace android {
class LocalSocketConnection : public network::MessageSender {
public:
LocalSocketConnection(const std::string &path);
@ -37,7 +36,6 @@ public:
private:
Fd fd_;
};
} // namespace android
} // namespace anbox
#endif

View file

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

View file

@ -16,15 +16,14 @@
*/
#include "android/service/message_processor.h"
#include "android/service/platform_api.h"
#include "android/service/android_api_skeleton.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<PlatformApi> &platform_api) :
const std::shared_ptr<AndroidApiSkeleton> &platform_api) :
bridge::MessageProcessor(sender, pending_calls),
platform_api_(platform_api) {
}
@ -34,14 +33,13 @@ MessageProcessor::~MessageProcessor() {
void MessageProcessor::dispatch(bridge::Invocation const& invocation) {
if (invocation.method_name() == "install_application")
invoke(this, platform_api_.get(), &PlatformApi::install_application, invocation);
invoke(this, platform_api_.get(), &AndroidApiSkeleton::install_application, invocation);
else if (invocation.method_name() == "launch_application")
invoke(this, platform_api_.get(), &PlatformApi::launch_application, invocation);
invoke(this, platform_api_.get(), &AndroidApiSkeleton::launch_application, invocation);
else if (invocation.method_name() == "set_dns_servers")
invoke(this, platform_api_.get(), &PlatformApi::set_dns_servers, invocation);
invoke(this, platform_api_.get(), &AndroidApiSkeleton::set_dns_servers, invocation);
}
void MessageProcessor::process_event_sequence(const std::string&) {
}
} // namespace anbox
} // namespace network

View file

@ -21,22 +21,20 @@
#include "anbox/bridge/message_processor.h"
namespace anbox {
namespace android {
class PlatformApi;
class AndroidApiSkeleton;
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<PlatformApi> &platform_api);
const std::shared_ptr<AndroidApiSkeleton> &platform_api);
~MessageProcessor();
void dispatch(bridge::Invocation const& invocation) override;
void process_event_sequence(const std::string &event) override;
private:
std::shared_ptr<PlatformApi> platform_api_;
std::shared_ptr<AndroidApiSkeleton> platform_api_;
};
} // namespace anbox
} // namespace network
#endif

View file

@ -0,0 +1,57 @@
/*
* 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/platform_api_stub.h"
#include "anbox/bridge/rpc_channel.h"
#include "anbox_bridge.pb.h"
#define LOG_TAG "Anbox"
#include <cutils/log.h>
namespace anbox {
PlatformApiStub::PlatformApiStub(const std::shared_ptr<bridge::RpcChannel> &rpc_channel) :
rpc_channel_(rpc_channel) {
}
void PlatformApiStub::boot_finished() {
auto c = std::make_shared<Request<protobuf::bridge::Void>>();
ALOGI("Boot finished");
{
std::lock_guard<decltype(mutex_)> lock(mutex_);
boot_finished_wait_handle_.expect_result();
}
protobuf::bridge::Void message;
rpc_channel_->call_method(
"boot_finished",
&message, c->response.get(),
google::protobuf::NewCallback(this, &PlatformApiStub::handle_boot_finished_response, c.get()));
boot_finished_wait_handle_.wait_for_all();
ALOGI("Boot finished sent successfully!");
}
void PlatformApiStub::handle_boot_finished_response(Request<protobuf::bridge::Void>*) {
ALOGI("handle_boot_finished_response");
boot_finished_wait_handle_.result_received();
}
} // namespace anbox

View file

@ -0,0 +1,57 @@
/*
* 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_PLATFORM_API_STUB_H_
#define ANBOX_ANDROID_PLATFORM_API_STUB_H_
#include "anbox/common/wait_handle.h"
#include <memory>
namespace anbox {
namespace protobuf {
namespace bridge {
class Void;
} // namespace bridge
} // namespace protobuf
namespace bridge {
class RpcChannel;
} // namespace bridge
class PlatformApiStub {
public:
PlatformApiStub(const std::shared_ptr<bridge::RpcChannel> &rpc_channel);
void boot_finished();
private:
template<typename Response>
struct Request {
Request() : response(std::make_shared<Response>()), success(true) { }
std::shared_ptr<Response> response;
bool success;
};
void handle_boot_finished_response(Request<protobuf::bridge::Void> *request);
mutable std::mutex mutex_;
common::WaitHandle boot_finished_wait_handle_;
std::shared_ptr<bridge::RpcChannel> rpc_channel_;
};
} // namespace anbox
#endif

View file

View 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/>.
*
*/
#include "android/service/platform_service.h"
#include "android/service/platform_api_stub.h"
#include "anbox/bridge/rpc_channel.h"
#define LOG_TAG "Anboxd"
#include <cutils/log.h>
using namespace android;
namespace android {
PlatformService::PlatformService(const std::shared_ptr<anbox::PlatformApiStub> &platform_api_stub) :
platform_api_stub_(platform_api_stub) {
}
status_t PlatformService::boot_finished() {
ALOGI("!!!!!!!!!!!!!!!!!!!!!!! BOOOT FINISHED --- ANBOXD");
platform_api_stub_->boot_finished();
return OK;
}
} // namespace android

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_PLATFORM_SERVICE_H_
#define ANBOX_ANDROID_PLATFORM_SERVICE_H_
#include "android/service/platform_service_interface.h"
#include <memory>
namespace anbox {
class PlatformApiStub;
} // namespace anbox
namespace android {
class PlatformService : public BnPlatformService {
public:
static const char* service_name() { return "anbox.PlatformService"; }
PlatformService(const std::shared_ptr<anbox::PlatformApiStub> &platform_api_stub);
status_t boot_finished() override;
private:
std::shared_ptr<anbox::PlatformApiStub> platform_api_stub_;
};
} // namespace android
#endif

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/platform_service_interface.h"
namespace android {
BpPlatformService::BpPlatformService(const sp<IBinder> &binder) :
BpInterface<IPlatformService>(binder) {
}
status_t BpPlatformService::boot_finished() {
Parcel data, reply;
data.writeInterfaceToken(IPlatformService::getInterfaceDescriptor());
return remote()->transact(IPlatformService::BOOT_FINISHED, data, &reply);
}
IMPLEMENT_META_INTERFACE(PlatformService, "anbox.IPlatformService");
status_t BnPlatformService::onTransact(uint32_t code, const Parcel &data,
Parcel *reply, uint32_t flags) {
switch (code) {
case BOOT_FINISHED:
CHECK_INTERFACE(IPlatformService, data, reply);
return boot_finished();
default:
break;
}
return BBinder::onTransact(code, data, reply, flags);
}
} // namespace android

View file

@ -0,0 +1,55 @@
/*
* 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_PLATFORM_SERVICE_INTERFACE_H_
#define ANBOX_ANDROID_PLATFORM_SERVICE_INTERFACE_H_
#include <binder/IBinder.h>
#include <binder/IInterface.h>
#include <binder/Parcel.h>
#include <utils/String16.h>
#include <utils/StrongPointer.h>
#include <cstdint>
namespace android {
class IPlatformService : public IInterface {
public:
DECLARE_META_INTERFACE(PlatformService);
enum {
BOOT_FINISHED = IBinder::FIRST_CALL_TRANSACTION,
};
virtual status_t boot_finished() = 0;
};
class BpPlatformService : public BpInterface<IPlatformService> {
public:
BpPlatformService(const sp<IBinder> &binder);
status_t boot_finished() override;
};
class BnPlatformService : public BnInterface<IPlatformService> {
public:
virtual status_t onTransact(uint32_t code, const Parcel &data,
Parcel *reply, uint32_t flags);
};
} // namespace android
#endif

View file

@ -0,0 +1,34 @@
/*
* 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 <binder/IPCThreadState.h>
#include <binder/ProcessState.h>
#include <binder/IServiceManager.h>
#include "android/service/platform_service_interface.h"
int main(int, char**) {
auto binder = android::defaultServiceManager()->getService(android::String16("anbox.PlatformService"));
if (not binder.get())
return 0;
android::ProcessState::self()->startThreadPool();
android::sp<android::BpPlatformService> platform_service = new android::BpPlatformService(binder);
return platform_service->boot_finished();
}

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