Rework some of the RPC service bits and add boot support
This commit is contained in:
parent
e664839b14
commit
1879e634c5
39 changed files with 746 additions and 106 deletions
27
Android.mk
27
Android.mk
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -18,6 +18,6 @@
|
|||
#include "android/service/daemon.h"
|
||||
|
||||
int main(int, char**) {
|
||||
anbox::android::Daemon daemon;
|
||||
anbox::Daemon daemon;
|
||||
return daemon.run();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
57
android/service/platform_api_stub.cpp
Normal file
57
android/service/platform_api_stub.cpp
Normal 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
|
||||
57
android/service/platform_api_stub.h
Normal file
57
android/service/platform_api_stub.h
Normal 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
|
||||
0
android/service/platform_server_proxy.cpp
Normal file
0
android/service/platform_server_proxy.cpp
Normal file
0
android/service/platform_server_proxy.h
Normal file
0
android/service/platform_server_proxy.h
Normal file
37
android/service/platform_service.cpp
Normal file
37
android/service/platform_service.cpp
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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#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
|
||||
43
android/service/platform_service.h
Normal file
43
android/service/platform_service.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_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
|
||||
45
android/service/platform_service_interface.cpp
Normal file
45
android/service/platform_service_interface.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/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
|
||||
55
android/service/platform_service_interface.h
Normal file
55
android/service/platform_service_interface.h
Normal 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
|
||||
34
android/service/test_platform_service.cpp
Normal file
34
android/service/test_platform_service.cpp
Normal 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();
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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();
|
||||
|
|
@ -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
|
||||
|
|
@ -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,
|
||||
|
|
@ -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&) {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
43
src/anbox/common/dispatcher.cpp
Normal file
43
src/anbox/common/dispatcher.cpp
Normal 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);
|
||||
}
|
||||
43
src/anbox/common/dispatcher.h
Normal file
43
src/anbox/common/dispatcher.h
Normal 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
|
||||
|
|
@ -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>();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
52
src/anbox/support/bootanimation_message_processor.cpp
Normal file
52
src/anbox/support/bootanimation_message_processor.cpp
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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#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
|
||||
42
src/anbox/support/bootanimation_message_processor.h
Normal file
42
src/anbox/support/bootanimation_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_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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
Loading…
Add table
Add a link
Reference in a new issue