From b10382d2d82b7af18de9c0fb526a52e3796d5236 Mon Sep 17 00:00:00 2001 From: Simon Fels Date: Fri, 2 Dec 2016 17:36:54 +0100 Subject: [PATCH] Reformat all code and use the Google cpp code style --- .clang-format | 8 + scripts/clean-format.sh | 3 + src/anbox/android/intent.cpp | 31 +- src/anbox/android/intent.h | 21 +- src/anbox/application/launcher_storage.cpp | 62 +- src/anbox/application/launcher_storage.h | 26 +- src/anbox/application_manager.h | 8 +- src/anbox/bridge/android_api_stub.cpp | 123 +- src/anbox/bridge/android_api_stub.h | 52 +- src/anbox/bridge/platform_api_skeleton.cpp | 133 +- src/anbox/bridge/platform_api_skeleton.h | 52 +- .../bridge/platform_message_processor.cpp | 61 +- src/anbox/bridge/platform_message_processor.h | 23 +- src/anbox/cli.cpp | 366 ++-- src/anbox/cli.h | 455 ++-- src/anbox/cmds/container_manager.cpp | 39 +- src/anbox/cmds/container_manager.h | 8 +- src/anbox/cmds/install.cpp | 33 +- src/anbox/cmds/install.h | 12 +- src/anbox/cmds/launch.cpp | 41 +- src/anbox/cmds/launch.h | 14 +- src/anbox/cmds/run.cpp | 221 +- src/anbox/cmds/run.h | 20 +- src/anbox/cmds/version.cpp | 18 +- src/anbox/cmds/version.h | 8 +- src/anbox/common/dispatcher.cpp | 25 +- src/anbox/common/dispatcher.h | 17 +- src/anbox/common/fd.cpp | 56 +- src/anbox/common/fd.h | 40 +- src/anbox/common/fd_sets.h | 4 +- src/anbox/common/variable_length_array.h | 49 +- src/anbox/common/wait_handle.cpp | 77 +- src/anbox/common/wait_handle.h | 37 +- src/anbox/config.cpp | 77 +- src/anbox/config.h | 4 +- src/anbox/container/client.cpp | 55 +- src/anbox/container/client.h | 37 +- src/anbox/container/configuration.h | 8 +- src/anbox/container/container.cpp | 7 +- src/anbox/container/container.h | 30 +- src/anbox/container/lxc_container.cpp | 196 +- src/anbox/container/lxc_container.h | 24 +- .../management_api_message_processor.cpp | 34 +- .../management_api_message_processor.h | 23 +- .../container/management_api_skeleton.cpp | 76 +- src/anbox/container/management_api_skeleton.h | 37 +- src/anbox/container/management_api_stub.cpp | 65 +- src/anbox/container/management_api_stub.h | 44 +- src/anbox/container/service.cpp | 109 +- src/anbox/container/service.h | 39 +- src/anbox/daemon.cpp | 40 +- src/anbox/daemon.h | 16 +- src/anbox/dbus/interface.h | 47 +- .../dbus/skeleton/application_manager.cpp | 43 +- src/anbox/dbus/skeleton/application_manager.h | 28 +- src/anbox/dbus/skeleton/service.cpp | 42 +- src/anbox/dbus/skeleton/service.h | 35 +- src/anbox/dbus/stub/application_manager.cpp | 46 +- src/anbox/dbus/stub/application_manager.h | 29 +- src/anbox/defer_action.h | 19 +- src/anbox/do_not_copy_or_move.h | 20 +- src/anbox/graphics/density.h | 22 +- src/anbox/graphics/emugl/ColorBuffer.cpp | 521 +++-- src/anbox/graphics/emugl/ColorBuffer.h | 144 +- src/anbox/graphics/emugl/DisplayManager.cpp | 16 +- src/anbox/graphics/emugl/DisplayManager.h | 16 +- src/anbox/graphics/emugl/ReadBuffer.cpp | 83 +- src/anbox/graphics/emugl/ReadBuffer.h | 26 +- src/anbox/graphics/emugl/RenderApi.cpp | 356 ++-- src/anbox/graphics/emugl/RenderContext.cpp | 39 +- src/anbox/graphics/emugl/RenderContext.h | 58 +- src/anbox/graphics/emugl/RenderControl.cpp | 683 +++--- src/anbox/graphics/emugl/RenderControl.h | 7 +- src/anbox/graphics/emugl/RenderServer.cpp | 186 +- src/anbox/graphics/emugl/RenderServer.h | 25 +- src/anbox/graphics/emugl/RenderThread.cpp | 155 +- src/anbox/graphics/emugl/RenderThread.h | 44 +- src/anbox/graphics/emugl/RenderThreadInfo.cpp | 14 +- src/anbox/graphics/emugl/RenderThreadInfo.h | 44 +- src/anbox/graphics/emugl/RenderWindow.cpp | 447 ++-- src/anbox/graphics/emugl/RenderWindow.h | 128 +- src/anbox/graphics/emugl/Renderable.cpp | 68 +- src/anbox/graphics/emugl/Renderable.h | 45 +- src/anbox/graphics/emugl/Renderer.cpp | 1851 ++++++++--------- src/anbox/graphics/emugl/Renderer.h | 432 ++-- src/anbox/graphics/emugl/RendererConfig.cpp | 386 ++-- src/anbox/graphics/emugl/RendererConfig.h | 163 +- src/anbox/graphics/emugl/SocketStream.cpp | 238 +-- src/anbox/graphics/emugl/SocketStream.h | 42 +- src/anbox/graphics/emugl/TcpStream.cpp | 54 +- src/anbox/graphics/emugl/TcpStream.h | 17 +- src/anbox/graphics/emugl/TextureDraw.cpp | 285 ++- src/anbox/graphics/emugl/TextureDraw.h | 40 +- src/anbox/graphics/emugl/TextureResize.cpp | 354 ++-- src/anbox/graphics/emugl/TextureResize.h | 46 +- src/anbox/graphics/emugl/TimeUtils.cpp | 17 +- src/anbox/graphics/emugl/UnixStream.cpp | 202 +- src/anbox/graphics/emugl/UnixStream.h | 19 +- src/anbox/graphics/emugl/WindowSurface.cpp | 263 ++- src/anbox/graphics/emugl/WindowSurface.h | 112 +- src/anbox/graphics/gl_renderer_server.cpp | 100 +- src/anbox/graphics/gl_renderer_server.h | 28 +- src/anbox/graphics/layer_composer.cpp | 128 +- src/anbox/graphics/layer_composer.h | 18 +- .../graphics/opengles_message_processor.cpp | 63 +- .../graphics/opengles_message_processor.h | 33 +- src/anbox/graphics/primitives.h | 33 +- src/anbox/graphics/program_family.cpp | 124 +- src/anbox/graphics/program_family.h | 51 +- src/anbox/graphics/rect.cpp | 25 +- src/anbox/graphics/rect.h | 92 +- src/anbox/input/device.cpp | 155 +- src/anbox/input/device.h | 110 +- src/anbox/input/manager.cpp | 31 +- src/anbox/input/manager.h | 24 +- src/anbox/logger.cpp | 188 +- src/anbox/logger.h | 143 +- src/anbox/network/base_socket_messenger.cpp | 155 +- src/anbox/network/base_socket_messenger.h | 51 +- src/anbox/network/connection_context.cpp | 11 +- src/anbox/network/connection_context.h | 28 +- src/anbox/network/connection_creator.h | 13 +- src/anbox/network/connections.h | 77 +- src/anbox/network/connector.h | 6 +- src/anbox/network/credentials.cpp | 23 +- src/anbox/network/credentials.h | 24 +- .../network/delegate_connection_creator.h | 40 +- .../network/delegate_message_processor.cpp | 21 +- .../network/delegate_message_processor.h | 17 +- src/anbox/network/fd_socket_transmission.cpp | 297 ++- src/anbox/network/fd_socket_transmission.h | 25 +- src/anbox/network/local_socket_messenger.cpp | 41 +- src/anbox/network/local_socket_messenger.h | 22 +- src/anbox/network/message_processor.h | 12 +- src/anbox/network/message_receiver.h | 38 +- src/anbox/network/message_sender.h | 21 +- .../network/published_socket_connector.cpp | 46 +- .../network/published_socket_connector.h | 43 +- src/anbox/network/socket_connection.cpp | 80 +- src/anbox/network/socket_connection.h | 55 +- src/anbox/network/socket_helper.cpp | 88 +- src/anbox/network/socket_helper.h | 4 +- src/anbox/network/socket_messenger.h | 21 +- src/anbox/network/stream_socket_transport.cpp | 50 +- src/anbox/network/stream_socket_transport.h | 55 +- src/anbox/network/tcp_socket_connector.cpp | 65 +- src/anbox/network/tcp_socket_connector.h | 45 +- src/anbox/network/tcp_socket_messenger.cpp | 30 +- src/anbox/network/tcp_socket_messenger.h | 21 +- src/anbox/not_reachable.cpp | 17 +- src/anbox/not_reachable.h | 16 +- src/anbox/optional.h | 5 +- src/anbox/protobuf/google_protobuf_guard.cpp | 26 +- src/anbox/qemu/adb_message_processor.cpp | 232 ++- src/anbox/qemu/adb_message_processor.h | 67 +- src/anbox/qemu/at_parser.cpp | 80 +- src/anbox/qemu/at_parser.h | 24 +- .../boot_properties_message_processor.cpp | 41 +- .../qemu/boot_properties_message_processor.h | 19 +- .../qemu/bootanimation_message_processor.cpp | 35 +- .../qemu/bootanimation_message_processor.h | 23 +- src/anbox/qemu/camera_message_processor.cpp | 59 +- src/anbox/qemu/camera_message_processor.h | 25 +- .../qemu/fingerprint_message_processor.cpp | 28 +- .../qemu/fingerprint_message_processor.h | 19 +- src/anbox/qemu/gsm_message_processor.cpp | 118 +- src/anbox/qemu/gsm_message_processor.h | 49 +- .../qemu/hwcontrol_message_processor.cpp | 15 +- src/anbox/qemu/hwcontrol_message_processor.h | 15 +- src/anbox/qemu/null_message_processor.cpp | 16 +- src/anbox/qemu/null_message_processor.h | 12 +- src/anbox/qemu/pipe_connection_creator.cpp | 216 +- src/anbox/qemu/pipe_connection_creator.h | 74 +- src/anbox/qemu/qemud_message_processor.cpp | 72 +- src/anbox/qemu/qemud_message_processor.h | 29 +- src/anbox/qemu/sensors_message_processor.cpp | 32 +- src/anbox/qemu/sensors_message_processor.h | 19 +- src/anbox/qemu/telephony_manager.cpp | 24 +- src/anbox/qemu/telephony_manager.h | 20 +- src/anbox/rpc/channel.cpp | 105 +- src/anbox/rpc/channel.h | 56 +- src/anbox/rpc/connection_creator.cpp | 63 +- src/anbox/rpc/connection_creator.h | 42 +- src/anbox/rpc/constants.h | 8 +- src/anbox/rpc/make_protobuf_object.h | 12 +- src/anbox/rpc/message_processor.cpp | 133 +- src/anbox/rpc/message_processor.h | 55 +- src/anbox/rpc/pending_call_cache.cpp | 64 +- src/anbox/rpc/pending_call_cache.h | 63 +- src/anbox/rpc/template_message_processor.h | 74 +- src/anbox/runtime.cpp | 90 +- src/anbox/runtime.h | 61 +- src/anbox/ubuntu/keycode_converter.cpp | 425 ++-- src/anbox/ubuntu/keycode_converter.h | 13 +- src/anbox/ubuntu/mir_display_connection.cpp | 125 +- src/anbox/ubuntu/mir_display_connection.h | 32 +- src/anbox/ubuntu/platform_policy.cpp | 282 +-- src/anbox/ubuntu/platform_policy.h | 60 +- src/anbox/ubuntu/window.cpp | 119 +- src/anbox/ubuntu/window.h | 57 +- src/anbox/utils.cpp | 182 +- src/anbox/utils.h | 39 +- src/anbox/version.cpp | 10 +- src/anbox/version.h | 18 +- src/anbox/wm/default_platform_policy.cpp | 35 +- src/anbox/wm/default_platform_policy.h | 12 +- src/anbox/wm/display.cpp | 4 +- src/anbox/wm/display.h | 16 +- src/anbox/wm/manager.cpp | 138 +- src/anbox/wm/manager.h | 28 +- src/anbox/wm/platform_policy.cpp | 7 +- src/anbox/wm/platform_policy.h | 11 +- src/anbox/wm/stack.cpp | 4 +- src/anbox/wm/stack.h | 20 +- src/anbox/wm/task.cpp | 4 +- src/anbox/wm/task.h | 14 +- src/anbox/wm/window.cpp | 62 +- src/anbox/wm/window.h | 51 +- src/anbox/wm/window_state.cpp | 43 +- src/anbox/wm/window_state.h | 52 +- src/container_main.cpp | 8 +- src/main.cpp | 4 +- 222 files changed, 8739 insertions(+), 9281 deletions(-) create mode 100644 .clang-format create mode 100755 scripts/clean-format.sh diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..23e384e --- /dev/null +++ b/.clang-format @@ -0,0 +1,8 @@ +# Defines the Chromium style for automatic reformatting. +# http://clang.llvm.org/docs/ClangFormatStyleOptions.html +BasedOnStyle: Google +# This defaults to 'Auto'. Explicitly set it for a while, so that +# 'vector >' in existing files gets formatted to +# 'vector>'. ('Auto' means that clang-format will only use +# 'int>>' if the file already contains at least one such instance.) +Standard: Cpp11 diff --git a/scripts/clean-format.sh b/scripts/clean-format.sh new file mode 100755 index 0000000..0f8c4ce --- /dev/null +++ b/scripts/clean-format.sh @@ -0,0 +1,3 @@ +#!/bin/sh +find src -name "*.h" | xargs clang-format -style=file -i +find src -name "*.cpp" | xargs clang-format -style=file -i diff --git a/src/anbox/android/intent.cpp b/src/anbox/android/intent.cpp index 61c927b..aa40f2c 100644 --- a/src/anbox/android/intent.cpp +++ b/src/anbox/android/intent.cpp @@ -21,21 +21,18 @@ namespace anbox { namespace android { -std::ostream& operator<<(std::ostream &out, const Intent &intent) -{ - out << "[" - << "action=" << intent.action << " " - << "uri=" << intent.uri << " " - << "type=" << intent.type << " " - << "flags=" << intent.flags << " " - << "package=" << intent.package << " " - << "component=" << intent.component << " " - << "categories=[ "; - for (const auto &category : intent.categories) - out << category << " "; - out << "]]"; - return out; +std::ostream &operator<<(std::ostream &out, const Intent &intent) { + out << "[" + << "action=" << intent.action << " " + << "uri=" << intent.uri << " " + << "type=" << intent.type << " " + << "flags=" << intent.flags << " " + << "package=" << intent.package << " " + << "component=" << intent.component << " " + << "categories=[ "; + for (const auto &category : intent.categories) out << category << " "; + out << "]]"; + return out; } -} // namespace android -} // namespace anbox - +} // namespace android +} // namespace anbox diff --git a/src/anbox/android/intent.h b/src/anbox/android/intent.h index 107dd05..a628f8f 100644 --- a/src/anbox/android/intent.h +++ b/src/anbox/android/intent.h @@ -24,18 +24,17 @@ namespace anbox { namespace android { struct Intent { - std::string action; - std::string uri; - std::string type; - int flags = 0; - std::string package; - std::string component; - std::vector categories; + std::string action; + std::string uri; + std::string type; + int flags = 0; + std::string package; + std::string component; + std::vector categories; }; -std::ostream& operator<<(std::ostream &out, const Intent &intent); -} // namespace android -} // namespace anbox - +std::ostream &operator<<(std::ostream &out, const Intent &intent); +} // namespace android +} // namespace anbox #endif diff --git a/src/anbox/application/launcher_storage.cpp b/src/anbox/application/launcher_storage.cpp index 871f709..4003289 100644 --- a/src/anbox/application/launcher_storage.cpp +++ b/src/anbox/application/launcher_storage.cpp @@ -19,53 +19,51 @@ #include "anbox/utils.h" #include -#include #include +#include namespace fs = boost::filesystem; namespace anbox { namespace application { -LauncherStorage::LauncherStorage(const fs::path &path) : - path_(path) { -} +LauncherStorage::LauncherStorage(const fs::path &path) : path_(path) {} -LauncherStorage::~LauncherStorage() { -} +LauncherStorage::~LauncherStorage() {} void LauncherStorage::add(const Item &item) { - if (!fs::exists(path_)) - fs::create_directories(path_); + if (!fs::exists(path_)) fs::create_directories(path_); - auto package_name = item.package; - std::replace(package_name.begin(), package_name.end(), '.', '-'); + auto package_name = item.package; + std::replace(package_name.begin(), package_name.end(), '.', '-'); - const auto item_path = path_ / utils::string_format("anbox-%s.desktop", package_name); - std::string exec = "anbox launch "; + const auto item_path = + path_ / utils::string_format("anbox-%s.desktop", package_name); + std::string exec = "anbox launch "; - if (!item.launch_intent.action.empty()) - exec += utils::string_format("--action=%s ", item.launch_intent.action); + if (!item.launch_intent.action.empty()) + exec += utils::string_format("--action=%s ", item.launch_intent.action); - if (!item.launch_intent.type.empty()) - exec += utils::string_format("--type=%s ", item.launch_intent.type); + if (!item.launch_intent.type.empty()) + exec += utils::string_format("--type=%s ", item.launch_intent.type); - if (!item.launch_intent.uri.empty()) - exec += utils::string_format("--uri=%s ", item.launch_intent.uri); + if (!item.launch_intent.uri.empty()) + exec += utils::string_format("--uri=%s ", item.launch_intent.uri); - if (!item.launch_intent.package.empty()) - exec += utils::string_format("--package=%s ", item.launch_intent.package); + if (!item.launch_intent.package.empty()) + exec += utils::string_format("--package=%s ", item.launch_intent.package); - if (!item.launch_intent.component.empty()) - exec += utils::string_format("--component=%s ", item.launch_intent.component); + if (!item.launch_intent.component.empty()) + exec += + utils::string_format("--component=%s ", item.launch_intent.component); - std::ofstream f(item_path.string()); - f << "[Desktop Entry]" << std::endl - << "Name=" << item.package << std::endl - << "Exec=" << exec << std::endl - << "Terminal=false" << std::endl - << "Type=Application" << std::endl - << "Encoding=UTF-8" << std::endl; - f.close(); + std::ofstream f(item_path.string()); + f << "[Desktop Entry]" << std::endl + << "Name=" << item.package << std::endl + << "Exec=" << exec << std::endl + << "Terminal=false" << std::endl + << "Type=Application" << std::endl + << "Encoding=UTF-8" << std::endl; + f.close(); } -} // namespace application -} // namespace anbox +} // namespace application +} // namespace anbox diff --git a/src/anbox/application/launcher_storage.h b/src/anbox/application/launcher_storage.h index c6c21eb..db2c882 100644 --- a/src/anbox/application/launcher_storage.h +++ b/src/anbox/application/launcher_storage.h @@ -28,22 +28,22 @@ namespace anbox { namespace application { class LauncherStorage { -public: - LauncherStorage(const boost::filesystem::path &path); - ~LauncherStorage(); + public: + LauncherStorage(const boost::filesystem::path &path); + ~LauncherStorage(); - struct Item { - std::string name; - std::string package; - android::Intent launch_intent; - }; + struct Item { + std::string name; + std::string package; + android::Intent launch_intent; + }; - void add(const Item &item); + void add(const Item &item); -private: - boost::filesystem::path path_; + private: + boost::filesystem::path path_; }; -} // namespace application -} // namespace anbox +} // namespace application +} // namespace anbox #endif diff --git a/src/anbox/application_manager.h b/src/anbox/application_manager.h index 52dea49..577ff09 100644 --- a/src/anbox/application_manager.h +++ b/src/anbox/application_manager.h @@ -18,16 +18,16 @@ #ifndef ANBOX_APPLICATION_MANAGER_H_ #define ANBOX_APPLICATION_MANAGER_H_ -#include "anbox/do_not_copy_or_move.h" #include "anbox/android/intent.h" +#include "anbox/do_not_copy_or_move.h" #include namespace anbox { class ApplicationManager : public DoNotCopyOrMove { -public: - virtual void launch(const android::Intent &intent) = 0; + public: + virtual void launch(const android::Intent &intent) = 0; }; -} // namespace anbox +} // namespace anbox #endif diff --git a/src/anbox/bridge/android_api_stub.cpp b/src/anbox/bridge/android_api_stub.cpp index a6f5b6f..05e6de1 100644 --- a/src/anbox/bridge/android_api_stub.cpp +++ b/src/anbox/bridge/android_api_stub.cpp @@ -16,13 +16,13 @@ */ #include "anbox/bridge/android_api_stub.h" -#include "anbox/rpc/channel.h" -#include "anbox/utils.h" #include "anbox/config.h" #include "anbox/logger.h" +#include "anbox/rpc/channel.h" +#include "anbox/utils.h" -#include "anbox_rpc.pb.h" #include "anbox_bridge.pb.h" +#include "anbox_rpc.pb.h" #include @@ -30,101 +30,90 @@ namespace fs = boost::filesystem; namespace anbox { namespace bridge { -AndroidApiStub::AndroidApiStub() { +AndroidApiStub::AndroidApiStub() {} + +AndroidApiStub::~AndroidApiStub() {} + +void AndroidApiStub::set_rpc_channel( + const std::shared_ptr &channel) { + channel_ = channel; } -AndroidApiStub::~AndroidApiStub() { -} - -void AndroidApiStub::set_rpc_channel(const std::shared_ptr &channel) { - channel_ = channel; -} - -void AndroidApiStub::reset_rpc_channel() { - channel_.reset(); -} +void AndroidApiStub::reset_rpc_channel() { channel_.reset(); } void AndroidApiStub::ensure_rpc_channel() { - if (!channel_) - throw std::runtime_error("No remote client connected"); + if (!channel_) throw std::runtime_error("No remote client connected"); } void AndroidApiStub::launch(const android::Intent &intent) { - ensure_rpc_channel(); + ensure_rpc_channel(); - auto c = std::make_shared>(); - protobuf::bridge::LaunchApplication message; + auto c = std::make_shared>(); + protobuf::bridge::LaunchApplication message; - { - std::lock_guard lock(mutex_); - launch_wait_handle_.expect_result(); - } + { + std::lock_guard lock(mutex_); + launch_wait_handle_.expect_result(); + } - auto launch_intent = message.mutable_intent(); + auto launch_intent = message.mutable_intent(); - if (!intent.action.empty()) - launch_intent->set_action(intent.action); + if (!intent.action.empty()) launch_intent->set_action(intent.action); - if (!intent.uri.empty()) - launch_intent->set_uri(intent.uri); + if (!intent.uri.empty()) launch_intent->set_uri(intent.uri); - if (!intent.type.empty()) - launch_intent->set_type(intent.type); + if (!intent.type.empty()) launch_intent->set_type(intent.type); - if (!intent.package.empty()) - launch_intent->set_package(intent.package); + if (!intent.package.empty()) launch_intent->set_package(intent.package); - if (!intent.component.empty()) - launch_intent->set_component(intent.component); + if (!intent.component.empty()) launch_intent->set_component(intent.component); - for (const auto &category : intent.categories) { - auto c = launch_intent->add_categories(); - *c = category; - } + for (const auto &category : intent.categories) { + auto c = launch_intent->add_categories(); + *c = category; + } - channel_->call_method("launch_application", - &message, - c->response.get(), - google::protobuf::NewCallback(this, &AndroidApiStub::application_launched, c.get())); + channel_->call_method( + "launch_application", &message, c->response.get(), + google::protobuf::NewCallback(this, &AndroidApiStub::application_launched, + c.get())); - launch_wait_handle_.wait_for_all(); + launch_wait_handle_.wait_for_all(); - if (c->response->has_error()) - throw std::runtime_error(c->response->error()); + if (c->response->has_error()) throw std::runtime_error(c->response->error()); } -void AndroidApiStub::application_launched(Request *request) { - (void) request; - launch_wait_handle_.result_received(); +void AndroidApiStub::application_launched( + Request *request) { + (void)request; + launch_wait_handle_.result_received(); } void AndroidApiStub::set_focused_task(const std::int32_t &id) { - ensure_rpc_channel(); + ensure_rpc_channel(); - auto c = std::make_shared>(); + auto c = std::make_shared>(); - protobuf::bridge::SetFocusedTask message; - message.set_id(id); + protobuf::bridge::SetFocusedTask message; + message.set_id(id); - { - std::lock_guard lock(mutex_); - set_focused_task_handle_.expect_result(); - } + { + std::lock_guard lock(mutex_); + set_focused_task_handle_.expect_result(); + } - channel_->call_method("set_focused_task", - &message, - c->response.get(), - google::protobuf::NewCallback(this, &AndroidApiStub::focused_task_set, c.get())); + channel_->call_method("set_focused_task", &message, c->response.get(), + google::protobuf::NewCallback( + this, &AndroidApiStub::focused_task_set, c.get())); - set_focused_task_handle_.wait_for_all(); + set_focused_task_handle_.wait_for_all(); - if (c->response->has_error()) - throw std::runtime_error(c->response->error()); + if (c->response->has_error()) throw std::runtime_error(c->response->error()); } void AndroidApiStub::focused_task_set(Request *request) { - (void) request; - set_focused_task_handle_.result_received(); + (void)request; + set_focused_task_handle_.result_received(); } -} // namespace bridge -} // namespace anbox +} // namespace bridge +} // namespace anbox diff --git a/src/anbox/bridge/android_api_stub.h b/src/anbox/bridge/android_api_stub.h index 9f8d1ac..aa77f12 100644 --- a/src/anbox/bridge/android_api_stub.h +++ b/src/anbox/bridge/android_api_stub.h @@ -28,43 +28,43 @@ namespace anbox { namespace protobuf { namespace rpc { class Void; -} // namespace bridge -} // namespace protobuf +} // namespace bridge +} // namespace protobuf namespace rpc { class Channel; -} // namespace rpc +} // namespace rpc namespace bridge { class AndroidApiStub : public anbox::ApplicationManager { -public: - AndroidApiStub(); - ~AndroidApiStub(); + public: + AndroidApiStub(); + ~AndroidApiStub(); - void set_rpc_channel(const std::shared_ptr &channel); - void reset_rpc_channel(); + void set_rpc_channel(const std::shared_ptr &channel); + void reset_rpc_channel(); - void launch(const android::Intent &intent) override; + void launch(const android::Intent &intent) override; - void set_focused_task(const std::int32_t &id); + void set_focused_task(const std::int32_t &id); -private: - void ensure_rpc_channel(); + private: + void ensure_rpc_channel(); - template - struct Request { - Request() : response(std::make_shared()), success(true) { } - std::shared_ptr response; - bool success; - }; + template + struct Request { + Request() : response(std::make_shared()), success(true) {} + std::shared_ptr response; + bool success; + }; - void application_launched(Request *request); - void focused_task_set(Request *request); + void application_launched(Request *request); + void focused_task_set(Request *request); - mutable std::mutex mutex_; - std::shared_ptr channel_; - common::WaitHandle launch_wait_handle_; - common::WaitHandle set_focused_task_handle_; + mutable std::mutex mutex_; + std::shared_ptr channel_; + common::WaitHandle launch_wait_handle_; + common::WaitHandle set_focused_task_handle_; }; -} // namespace bridge -} // namespace anbox +} // namespace bridge +} // namespace anbox #endif diff --git a/src/anbox/bridge/platform_api_skeleton.cpp b/src/anbox/bridge/platform_api_skeleton.cpp index 02966f8..7861d31 100644 --- a/src/anbox/bridge/platform_api_skeleton.cpp +++ b/src/anbox/bridge/platform_api_skeleton.cpp @@ -17,83 +17,86 @@ #include "anbox/bridge/platform_api_skeleton.h" #include "anbox/application/launcher_storage.h" +#include "anbox/logger.h" #include "anbox/wm/manager.h" #include "anbox/wm/window_state.h" -#include "anbox/logger.h" #include "anbox_bridge.pb.h" namespace anbox { namespace bridge { -PlatformApiSkeleton::PlatformApiSkeleton(const std::shared_ptr &pending_calls, - const std::shared_ptr &window_manager, - const std::shared_ptr &launcher_storage) : - pending_calls_(pending_calls), - window_manager_(window_manager), - launcher_storage_(launcher_storage) { +PlatformApiSkeleton::PlatformApiSkeleton( + const std::shared_ptr &pending_calls, + const std::shared_ptr &window_manager, + const std::shared_ptr &launcher_storage) + : pending_calls_(pending_calls), + window_manager_(window_manager), + launcher_storage_(launcher_storage) {} + +PlatformApiSkeleton::~PlatformApiSkeleton() {} + +void PlatformApiSkeleton::handle_boot_finished_event( + const anbox::protobuf::bridge::BootFinishedEvent &event) { + (void)event; + + if (boot_finished_handler_) boot_finished_handler_(); } -PlatformApiSkeleton::~PlatformApiSkeleton() { +void PlatformApiSkeleton::handle_window_state_update_event( + const anbox::protobuf::bridge::WindowStateUpdateEvent &event) { + auto convert_window_state = []( + const ::anbox::protobuf::bridge::WindowStateUpdateEvent_WindowState + &window) { + return wm::WindowState( + wm::Display::Id(window.display_id()), window.has_surface(), + graphics::Rect(window.frame_left(), window.frame_top(), + window.frame_right(), window.frame_bottom()), + window.package_name(), wm::Task::Id(window.task_id()), + wm::Stack::Id(window.stack_id())); + }; + + wm::WindowState::List updated; + for (int n = 0; n < event.windows_size(); n++) { + const auto window = event.windows(n); + updated.push_back(convert_window_state(window)); + } + + wm::WindowState::List removed; + for (int n = 0; n < event.removed_windows_size(); n++) { + const auto window = event.removed_windows(n); + removed.push_back(convert_window_state(window)); + } + + window_manager_->apply_window_state_update(updated, removed); } -void PlatformApiSkeleton::handle_boot_finished_event(const anbox::protobuf::bridge::BootFinishedEvent &event) { - (void) event; +void PlatformApiSkeleton::handle_application_list_update_event( + const anbox::protobuf::bridge::ApplicationListUpdateEvent &event) { + for (int n = 0; n < event.applications_size(); n++) { + application::LauncherStorage::Item item; - if (boot_finished_handler_) - boot_finished_handler_(); + const auto app = event.applications(n); + item.name = app.name(); + item.package = app.package(); + + const auto li = app.launch_intent(); + item.launch_intent.action = li.action(); + item.launch_intent.uri = li.uri(); + item.launch_intent.type = li.uri(); + item.launch_intent.package = li.package(); + item.launch_intent.component = li.component(); + + for (int m = 0; m < li.categories_size(); m++) + item.launch_intent.categories.push_back(li.categories(m)); + + // If the item is already stored it will be updated + launcher_storage_->add(item); + } } -void PlatformApiSkeleton::handle_window_state_update_event(const anbox::protobuf::bridge::WindowStateUpdateEvent &event) { - auto convert_window_state = [](const ::anbox::protobuf::bridge::WindowStateUpdateEvent_WindowState &window) { - return wm::WindowState( - wm::Display::Id(window.display_id()), - window.has_surface(), - graphics::Rect(window.frame_left(), window.frame_top(), window.frame_right(), window.frame_bottom()), - window.package_name(), - wm::Task::Id(window.task_id()), - wm::Stack::Id(window.stack_id())); - }; - - wm::WindowState::List updated; - for (int n = 0; n < event.windows_size(); n++) { - const auto window = event.windows(n); - updated.push_back(convert_window_state(window)); - } - - wm::WindowState::List removed; - for (int n = 0; n < event.removed_windows_size(); n++) { - const auto window = event.removed_windows(n); - removed.push_back(convert_window_state(window)); - } - - window_manager_->apply_window_state_update(updated, removed); +void PlatformApiSkeleton::register_boot_finished_handler( + const std::function &action) { + boot_finished_handler_ = action; } - -void PlatformApiSkeleton::handle_application_list_update_event(const anbox::protobuf::bridge::ApplicationListUpdateEvent &event) { - for (int n = 0; n < event.applications_size(); n++) { - application::LauncherStorage::Item item; - - const auto app = event.applications(n); - item.name = app.name(); - item.package = app.package(); - - const auto li = app.launch_intent(); - item.launch_intent.action = li.action(); - item.launch_intent.uri = li.uri(); - item.launch_intent.type = li.uri(); - item.launch_intent.package = li.package(); - item.launch_intent.component = li.component(); - - for (int m = 0; m < li.categories_size(); m++) - item.launch_intent.categories.push_back(li.categories(m)); - - // If the item is already stored it will be updated - launcher_storage_->add(item); - } -} - -void PlatformApiSkeleton::register_boot_finished_handler(const std::function &action) { - boot_finished_handler_ = action; -} -} // namespace bridge -} // namespace anbox +} // namespace bridge +} // namespace anbox diff --git a/src/anbox/bridge/platform_api_skeleton.h b/src/anbox/bridge/platform_api_skeleton.h index 0cf0c3b..02531c3 100644 --- a/src/anbox/bridge/platform_api_skeleton.h +++ b/src/anbox/bridge/platform_api_skeleton.h @@ -23,50 +23,54 @@ namespace google { namespace protobuf { class Closure; -} // namespace protobuf -} // namespace google +} // namespace protobuf +} // namespace google namespace anbox { namespace protobuf { namespace rpc { class Void; -} // namespace rpc +} // namespace rpc namespace bridge { class BootFinishedEvent; class WindowStateUpdateEvent; class ApplicationListUpdateEvent; -} // namespace bridge -} // namespace protobuf +} // namespace bridge +} // namespace protobuf namespace rpc { class PendingCallCache; -} // namespace rpc +} // namespace rpc namespace wm { class Manager; -} // namespace wm +} // namespace wm namespace application { class LauncherStorage; -} // namespace application +} // namespace application namespace bridge { class PlatformApiSkeleton { -public: - PlatformApiSkeleton(const std::shared_ptr &pending_calls, - const std::shared_ptr &window_manager, - const std::shared_ptr &launcher_storage); - virtual ~PlatformApiSkeleton(); + public: + PlatformApiSkeleton( + const std::shared_ptr &pending_calls, + const std::shared_ptr &window_manager, + const std::shared_ptr &launcher_storage); + virtual ~PlatformApiSkeleton(); - void handle_boot_finished_event(const anbox::protobuf::bridge::BootFinishedEvent &event); - void handle_window_state_update_event(const anbox::protobuf::bridge::WindowStateUpdateEvent &event); - void handle_application_list_update_event(const anbox::protobuf::bridge::ApplicationListUpdateEvent &event); + void handle_boot_finished_event( + const anbox::protobuf::bridge::BootFinishedEvent &event); + void handle_window_state_update_event( + const anbox::protobuf::bridge::WindowStateUpdateEvent &event); + void handle_application_list_update_event( + const anbox::protobuf::bridge::ApplicationListUpdateEvent &event); - void register_boot_finished_handler(const std::function &action); + void register_boot_finished_handler(const std::function &action); -private: - std::shared_ptr pending_calls_; - std::shared_ptr window_manager_; - std::shared_ptr launcher_storage_; - std::function boot_finished_handler_; + private: + std::shared_ptr pending_calls_; + std::shared_ptr window_manager_; + std::shared_ptr launcher_storage_; + std::function boot_finished_handler_; }; -} // namespace bridge -} // namespace anbox +} // namespace bridge +} // namespace anbox #endif diff --git a/src/anbox/bridge/platform_message_processor.cpp b/src/anbox/bridge/platform_message_processor.cpp index 4bffa79..ebeab86 100644 --- a/src/anbox/bridge/platform_message_processor.cpp +++ b/src/anbox/bridge/platform_message_processor.cpp @@ -17,41 +17,40 @@ #include "anbox/bridge/platform_message_processor.h" #include "anbox/bridge/platform_api_skeleton.h" -#include "anbox/rpc/template_message_processor.h" #include "anbox/logger.h" +#include "anbox/rpc/template_message_processor.h" #include "anbox_bridge.pb.h" namespace anbox { namespace bridge { -PlatformMessageProcessor::PlatformMessageProcessor(const std::shared_ptr &sender, - const std::shared_ptr &server, - const std::shared_ptr &pending_calls) : - rpc::MessageProcessor(sender, pending_calls), - server_(server) { +PlatformMessageProcessor::PlatformMessageProcessor( + const std::shared_ptr &sender, + const std::shared_ptr &server, + const std::shared_ptr &pending_calls) + : rpc::MessageProcessor(sender, pending_calls), server_(server) {} + +PlatformMessageProcessor::~PlatformMessageProcessor() {} + +void PlatformMessageProcessor::dispatch(rpc::Invocation const &invocation) {} + +void PlatformMessageProcessor::process_event_sequence( + const std::string &raw_events) { + anbox::protobuf::bridge::EventSequence seq; + if (!seq.ParseFromString(raw_events)) { + WARNING("Failed to parse events from raw string"); + return; + } + + if (seq.has_boot_finished()) + server_->handle_boot_finished_event(seq.boot_finished()); + + if (seq.has_window_state_update()) + server_->handle_window_state_update_event(seq.window_state_update()); + + if (seq.has_application_list_update()) + server_->handle_application_list_update_event( + seq.application_list_update()); } - -PlatformMessageProcessor::~PlatformMessageProcessor() { -} - -void PlatformMessageProcessor::dispatch(rpc::Invocation const& invocation) { -} - -void PlatformMessageProcessor::process_event_sequence(const std::string &raw_events) { - anbox::protobuf::bridge::EventSequence seq; - if (!seq.ParseFromString(raw_events)) { - WARNING("Failed to parse events from raw string"); - return; - } - - if (seq.has_boot_finished()) - server_->handle_boot_finished_event(seq.boot_finished()); - - if (seq.has_window_state_update()) - server_->handle_window_state_update_event(seq.window_state_update()); - - if (seq.has_application_list_update()) - server_->handle_application_list_update_event(seq.application_list_update()); -} -} // namespace anbox -} // namespace network +} // namespace anbox +} // namespace network diff --git a/src/anbox/bridge/platform_message_processor.h b/src/anbox/bridge/platform_message_processor.h index a956ea0..307b051 100644 --- a/src/anbox/bridge/platform_message_processor.h +++ b/src/anbox/bridge/platform_message_processor.h @@ -24,19 +24,20 @@ namespace anbox { namespace bridge { class PlatformApiSkeleton; class PlatformMessageProcessor : public rpc::MessageProcessor { -public: - PlatformMessageProcessor(const std::shared_ptr &sender, - const std::shared_ptr &server, - const std::shared_ptr &pending_calls); - ~PlatformMessageProcessor(); + public: + PlatformMessageProcessor( + const std::shared_ptr &sender, + const std::shared_ptr &server, + const std::shared_ptr &pending_calls); + ~PlatformMessageProcessor(); - void dispatch(rpc::Invocation const& invocation) override; - void process_event_sequence(const std::string &event) override; + void dispatch(rpc::Invocation const &invocation) override; + void process_event_sequence(const std::string &event) override; -private: - std::shared_ptr server_; + private: + std::shared_ptr server_; }; -} // namespace anbox -} // namespace network +} // namespace anbox +} // namespace network #endif diff --git a/src/anbox/cli.cpp b/src/anbox/cli.cpp index fc33db4..748c921 100644 --- a/src/anbox/cli.cpp +++ b/src/anbox/cli.cpp @@ -28,258 +28,216 @@ namespace po = boost::program_options; namespace { namespace pattern { static constexpr const char* help_for_command_with_subcommands = -"NAME:\n" -" %1% - %2%\n" -"\n" -"USAGE:\n" -" %3% [command options] [arguments...]"; + "NAME:\n" + " %1% - %2%\n" + "\n" + "USAGE:\n" + " %3% [command options] [arguments...]"; -static constexpr const char* commands = "COMMANDS:"; -static constexpr const char* command = " %1% %2%"; +static constexpr const char* commands = "COMMANDS:"; +static constexpr const char* command = " %1% %2%"; -static constexpr const char* options = "OPTIONS:"; -static constexpr const char* option = " --%1% %2%"; +static constexpr const char* options = "OPTIONS:"; +static constexpr const char* option = " --%1% %2%"; } -void add_to_desc_for_flags(po::options_description& desc, const std::set& flags) -{ - for (auto flag : flags) - { - auto v = po::value()->notifier([flag](const std::string& s) - { - flag->notify(s); - }); - desc.add_options()(flag->name().as_string().c_str(), v, flag->description().as_string().c_str()); - } +void add_to_desc_for_flags(po::options_description& desc, + const std::set& flags) { + for (auto flag : flags) { + auto v = po::value()->notifier( + [flag](const std::string& s) { flag->notify(s); }); + desc.add_options()(flag->name().as_string().c_str(), v, + flag->description().as_string().c_str()); + } } } -std::vector cli::args(int argc, char **argv) -{ - std::vector result; - for (int i = 1; i < argc; i++) result.push_back(argv[i]); - return result; +std::vector cli::args(int argc, char** argv) { + std::vector result; + for (int i = 1; i < argc; i++) result.push_back(argv[i]); + return result; } -const cli::Name& cli::Flag::name() const -{ - return name_; -} +const cli::Name& cli::Flag::name() const { return name_; } -const cli::Description& cli::Flag::description() const -{ - return description_; -} +const cli::Description& cli::Flag::description() const { return description_; } cli::Flag::Flag(const Name& name, const Description& description) - : name_{name}, - description_{description} -{ + : name_{name}, description_{description} {} + +cli::Command::FlagsWithInvalidValue::FlagsWithInvalidValue() + : std::runtime_error{"Flags with invalid value"} {} + +cli::Command::FlagsMissing::FlagsMissing() + : std::runtime_error{"Flags are missing in command invocation"} {} + +cli::Name cli::Command::name() const { return name_; } + +cli::Usage cli::Command::usage() const { return usage_; } + +cli::Description cli::Command::description() const { return description_; } + +cli::Command::Command(const cli::Name& name, const cli::Usage& usage, + const cli::Description& description) + : name_(name), usage_(usage), description_(description) {} + +cli::CommandWithSubcommands::CommandWithSubcommands( + const Name& name, const Usage& usage, const Description& description) + : Command{name, usage, description} { + command(std::make_shared(*this)); } -cli::Command::FlagsWithInvalidValue::FlagsWithInvalidValue() : std::runtime_error{"Flags with invalid value"} -{ +cli::CommandWithSubcommands& cli::CommandWithSubcommands::command( + const Command::Ptr& command) { + commands_[command->name().as_string()] = command; + return *this; } -cli::Command::FlagsMissing::FlagsMissing() : std::runtime_error{"Flags are missing in command invocation"} -{ +cli::CommandWithSubcommands& cli::CommandWithSubcommands::flag( + const Flag::Ptr& flag) { + flags_.insert(flag); + return *this; } -cli::Name cli::Command::name() const -{ - return name_; +void cli::CommandWithSubcommands::help(std::ostream& out) { + out << boost::format(pattern::help_for_command_with_subcommands) % + name().as_string() % usage().as_string() % name().as_string() + << std::endl; + + if (flags_.size() > 0) { + out << std::endl << pattern::options << std::endl; + for (const auto& flag : flags_) + out << boost::format(pattern::option) % flag->name() % flag->description() + << std::endl; + } + + if (commands_.size() > 0) { + out << std::endl << pattern::commands << std::endl; + for (const auto& cmd : commands_) { + if (cmd.second) + out << boost::format(pattern::command) % cmd.second->name() % + cmd.second->description() + << std::endl; + } + } } -cli::Usage cli::Command::usage() const -{ - return usage_; -} +int cli::CommandWithSubcommands::run(const cli::Command::Context& ctxt) { + po::positional_options_description pdesc; + pdesc.add("command", 1); -cli::Description cli::Command::description() const -{ - return description_; -} + po::options_description desc("Options"); + desc.add_options()("command", po::value()->required(), + "the command to be executed"); -cli::Command::Command(const cli::Name& name, const cli::Usage& usage, const cli::Description& description) - : name_(name), - usage_(usage), - description_(description) -{ -} + add_to_desc_for_flags(desc, flags_); -cli::CommandWithSubcommands::CommandWithSubcommands(const Name& name, const Usage& usage, const Description& description) - : Command{name, usage, description} -{ - command(std::make_shared(*this)); -} + try { + po::variables_map vm; + auto parsed = po::command_line_parser(ctxt.args) + .options(desc) + .positional(pdesc) + .style(po::command_line_style::unix_style) + .allow_unregistered() + .run(); -cli::CommandWithSubcommands& cli::CommandWithSubcommands::command(const Command::Ptr& command) -{ - commands_[command->name().as_string()] = command; - return *this; -} + po::store(parsed, vm); + po::notify(vm); -cli::CommandWithSubcommands& cli::CommandWithSubcommands::flag(const Flag::Ptr& flag) -{ - flags_.insert(flag); - return *this; -} - -void cli::CommandWithSubcommands::help(std::ostream& out) -{ - out << boost::format(pattern::help_for_command_with_subcommands) - % name().as_string() % usage().as_string() - % name().as_string() << std::endl; - - if (flags_.size() > 0) - { - out << std::endl << pattern::options << std::endl; - for (const auto& flag : flags_) - out << boost::format(pattern::option) % flag->name() % flag->description() << std::endl; - } - - if (commands_.size() > 0) - { - out << std::endl << pattern::commands << std::endl; - for (const auto& cmd : commands_) { - if (cmd.second) - out << boost::format(pattern::command) % cmd.second->name() % cmd.second->description() << std::endl; - } - } -} - -int cli::CommandWithSubcommands::run(const cli::Command::Context& ctxt) -{ - po::positional_options_description pdesc; - pdesc.add("command", 1); - - po::options_description desc("Options"); - desc.add_options()("command", po::value()->required(), "the command to be executed"); - - add_to_desc_for_flags(desc, flags_); - - try - { - po::variables_map vm; - auto parsed = po::command_line_parser(ctxt.args) - .options(desc) - .positional(pdesc) - .style(po::command_line_style::unix_style) - .allow_unregistered() - .run(); - - po::store(parsed, vm); - po::notify(vm); - - auto cmd = commands_[vm["command"].as()]; - if (!cmd) - { - ctxt.cout << "Unknown command '" << vm["command"].as() << "'" << std::endl; - help(ctxt.cout); - return EXIT_FAILURE; - } - - return cmd->run(cli::Command::Context - { - ctxt.cin, - ctxt.cout, - po::collect_unrecognized(parsed.options, po::include_positional) - }); - } - catch (const po::error& e) - { - ctxt.cout << e.what() << std::endl; - help(ctxt.cout); - return EXIT_FAILURE; + auto cmd = commands_[vm["command"].as()]; + if (!cmd) { + ctxt.cout << "Unknown command '" << vm["command"].as() << "'" + << std::endl; + help(ctxt.cout); + return EXIT_FAILURE; } + return cmd->run(cli::Command::Context{ + ctxt.cin, ctxt.cout, + po::collect_unrecognized(parsed.options, po::include_positional)}); + } catch (const po::error& e) { + ctxt.cout << e.what() << std::endl; + help(ctxt.cout); return EXIT_FAILURE; + } + + return EXIT_FAILURE; } -cli::CommandWithFlagsAndAction::CommandWithFlagsAndAction(const Name& name, const Usage& usage, const Description& description) - : Command{name, usage, description} -{ +cli::CommandWithFlagsAndAction::CommandWithFlagsAndAction( + const Name& name, const Usage& usage, const Description& description) + : Command{name, usage, description} {} + +cli::CommandWithFlagsAndAction& cli::CommandWithFlagsAndAction::flag( + const Flag::Ptr& flag) { + flags_.insert(flag); + return *this; } -cli::CommandWithFlagsAndAction& cli::CommandWithFlagsAndAction::flag(const Flag::Ptr& flag) -{ - flags_.insert(flag); - return *this; +cli::CommandWithFlagsAndAction& cli::CommandWithFlagsAndAction::action( + const Action& action) { + action_ = action; + return *this; } -cli::CommandWithFlagsAndAction& cli::CommandWithFlagsAndAction::action(const Action& action) -{ - action_ = action; - return *this; -} +int cli::CommandWithFlagsAndAction::run(const Context& ctxt) { + po::options_description cd(name().as_string()); -int cli::CommandWithFlagsAndAction::run(const Context& ctxt) -{ - po::options_description cd(name().as_string()); + bool help_requested{false}; + cd.add_options()("help", po::bool_switch(&help_requested), + "produces a help message"); - bool help_requested{false}; - cd.add_options()("help", po::bool_switch(&help_requested), "produces a help message"); + add_to_desc_for_flags(cd, flags_); - add_to_desc_for_flags(cd, flags_); + try { + po::variables_map vm; + auto parsed = po::command_line_parser(ctxt.args) + .options(cd) + .style(po::command_line_style::unix_style) + .allow_unregistered() + .run(); + po::store(parsed, vm); + po::notify(vm); - try - { - po::variables_map vm; - auto parsed = po::command_line_parser(ctxt.args).options(cd).style(po::command_line_style::unix_style).allow_unregistered().run(); - po::store(parsed, vm); - po::notify(vm); - - if (help_requested) - { - help(ctxt.cout); - return EXIT_SUCCESS; - } - - return action_(cli::Command::Context - { - ctxt.cin, - ctxt.cout, - po::collect_unrecognized(parsed.options, po::exclude_positional) - }); - } - catch (const po::error& e) - { - ctxt.cout << e.what() << std::endl; - help(ctxt.cout); - return EXIT_FAILURE; + if (help_requested) { + help(ctxt.cout); + return EXIT_SUCCESS; } + return action_(cli::Command::Context{ + ctxt.cin, ctxt.cout, + po::collect_unrecognized(parsed.options, po::exclude_positional)}); + } catch (const po::error& e) { + ctxt.cout << e.what() << std::endl; + help(ctxt.cout); return EXIT_FAILURE; + } + + return EXIT_FAILURE; } -void cli::CommandWithFlagsAndAction::help(std::ostream& out) -{ - out << boost::format(pattern::help_for_command_with_subcommands) - % name().as_string() % description().as_string() - % name().as_string() << std::endl; +void cli::CommandWithFlagsAndAction::help(std::ostream& out) { + out << boost::format(pattern::help_for_command_with_subcommands) % + name().as_string() % description().as_string() % name().as_string() + << std::endl; - if (flags_.size() > 0) - { - out << std::endl << boost::format(pattern::options) << std::endl; - for (const auto& flag : flags_) - out << boost::format(pattern::option) % flag->name() % flag->description() << std::endl; - } + if (flags_.size() > 0) { + out << std::endl << boost::format(pattern::options) << std::endl; + for (const auto& flag : flags_) + out << boost::format(pattern::option) % flag->name() % flag->description() + << std::endl; + } } cli::cmd::Help::Help(Command& cmd) - : Command{cli::Name{"help"}, cli::Usage{"prints a short help message"}, cli::Description{"prints a short help message"}}, - command{cmd} -{ -} + : Command{cli::Name{"help"}, cli::Usage{"prints a short help message"}, + cli::Description{"prints a short help message"}}, + command{cmd} {} // From Command -int cli::cmd::Help::run(const Context &context) -{ - command.help(context.cout); - return EXIT_FAILURE; +int cli::cmd::Help::run(const Context& context) { + command.help(context.cout); + return EXIT_FAILURE; } -void cli::cmd::Help::help(std::ostream &out) -{ - command.help(out); -} +void cli::cmd::Help::help(std::ostream& out) { command.help(out); } diff --git a/src/anbox/cli.h b/src/anbox/cli.h index c22ab28..6b64ed2 100644 --- a/src/anbox/cli.h +++ b/src/anbox/cli.h @@ -34,46 +34,38 @@ namespace anbox { namespace cli { -template -class SizeConstrainedString -{ -public: - SizeConstrainedString(const std::string& s) : s{s} - { - if(s.size() > max) - throw std::logic_error{"Max size exceeded " + std::to_string(max)}; - } +template +class SizeConstrainedString { + public: + SizeConstrainedString(const std::string& s) : s{s} { + if (s.size() > max) + throw std::logic_error{"Max size exceeded " + std::to_string(max)}; + } - const std::string& as_string() const - { - return s; - } + const std::string& as_string() const { return s; } - operator std::string() const - { - return s; - } + operator std::string() const { return s; } -private: - std::string s; + private: + std::string s; }; -template -bool operator<(const SizeConstrainedString& lhs, const SizeConstrainedString& rhs) -{ - return lhs.as_string() < rhs.as_string(); +template +bool operator<(const SizeConstrainedString& lhs, + const SizeConstrainedString& rhs) { + return lhs.as_string() < rhs.as_string(); } -template -bool operator==(const SizeConstrainedString& lhs, const SizeConstrainedString& rhs) -{ - return lhs.as_string() == rhs.as_string(); +template +bool operator==(const SizeConstrainedString& lhs, + const SizeConstrainedString& rhs) { + return lhs.as_string() == rhs.as_string(); } -template -std::ostream& operator<<(std::ostream& out, const SizeConstrainedString& scs) -{ - return out << std::setw(max) << std::left << scs.as_string(); +template +std::ostream& operator<<(std::ostream& out, + const SizeConstrainedString& scs) { + return out << std::setw(max) << std::left << scs.as_string(); } // We are imposing size constraints to ensure a consistent CLI layout. @@ -82,246 +74,238 @@ typedef SizeConstrainedString<60> Usage; typedef SizeConstrainedString<60> Description; /// @brief Flag models an input parameter to a command. -class Flag : public DoNotCopyOrMove -{ -public: - // Safe us some typing. - typedef std::shared_ptr Ptr; +class Flag : public DoNotCopyOrMove { + public: + // Safe us some typing. + typedef std::shared_ptr Ptr; - /// @brief notify announces a new value to the flag. - virtual void notify(const std::string& value) = 0; - /// @brief name returns the name of the Flag. - const Name& name() const; - /// @brief description returns a human-readable description of the flag. - const Description& description() const; + /// @brief notify announces a new value to the flag. + virtual void notify(const std::string& value) = 0; + /// @brief name returns the name of the Flag. + const Name& name() const; + /// @brief description returns a human-readable description of the flag. + const Description& description() const; -protected: - /// @brief Flag creates a new instance, initializing name and description - /// from the given values. - Flag(const Name& name, const Description& description); + protected: + /// @brief Flag creates a new instance, initializing name and description + /// from the given values. + Flag(const Name& name, const Description& description); -private: - Name name_; - Description description_; + private: + Name name_; + Description description_; }; -/// @brief TypedFlag implements Flag relying on operator<< and operator>> to read/write values to/from strings. -template -class TypedFlag : public Flag -{ -public: - typedef std::shared_ptr> Ptr; +/// @brief TypedFlag implements Flag relying on operator<< and operator>> to +/// read/write values to/from strings. +template +class TypedFlag : public Flag { + public: + typedef std::shared_ptr> Ptr; - TypedFlag(const Name& name, const Description& description) : Flag{name, description} - { - } + TypedFlag(const Name& name, const Description& description) + : Flag{name, description} {} - /// @brief value installs the given value in the flag. - TypedFlag& value(const T& value) - { - value_ = value; - return *this; - } + /// @brief value installs the given value in the flag. + TypedFlag& value(const T& value) { + value_ = value; + return *this; + } - /// @brief value returns the optional value associated with the flag. - const Optional& value() const - { - return value_; - } + /// @brief value returns the optional value associated with the flag. + const Optional& value() const { return value_; } - /// @brief notify tries to unwrap a value of type T from value. - void notify(const std::string& s) override - { - std::stringstream ss{s}; - T value; ss >> value; - value_ = value; - } + /// @brief notify tries to unwrap a value of type T from value. + void notify(const std::string& s) override { + std::stringstream ss{s}; + T value; + ss >> value; + value_ = value; + } -private: - Optional value_; + private: + Optional value_; }; -/// @brief TypedReferenceFlag implements Flag, relying on operator<> to convert to/from string representations, +/// @brief TypedReferenceFlag implements Flag, relying on operator<> to +/// convert to/from string representations, /// updating the given mutable reference to a value of type T. -template -class TypedReferenceFlag : public Flag -{ -public: - // Safe us some typing. - typedef std::shared_ptr> Ptr; +template +class TypedReferenceFlag : public Flag { + public: + // Safe us some typing. + typedef std::shared_ptr> Ptr; - /// @brief TypedReferenceFlag initializes a new instance with name, description and value. - TypedReferenceFlag(const Name& name, const Description& description, T& value) - : Flag{name, description}, - value_{value} - { - } + /// @brief TypedReferenceFlag initializes a new instance with name, + /// description and value. + TypedReferenceFlag(const Name& name, const Description& description, T& value) + : Flag{name, description}, value_{value} {} - /// @brief notify tries to unwrap a value of type T from value, - /// relying on operator>> to read from given string s. - void notify(const std::string& s) override - { - std::stringstream ss{s}; - ss >> value_.get(); - } + /// @brief notify tries to unwrap a value of type T from value, + /// relying on operator>> to read from given string s. + void notify(const std::string& s) override { + std::stringstream ss{s}; + ss >> value_.get(); + } -private: - std::reference_wrapper value_; + private: + std::reference_wrapper value_; }; -/// @brief OptionalTypedReferenceFlag handles Optional references, making sure that -/// a value is always read on notify, even if the Optional wasn't initialized previously. -template -class OptionalTypedReferenceFlag : public Flag -{ -public: - typedef std::shared_ptr> Ptr; +/// @brief OptionalTypedReferenceFlag handles Optional references, making +/// sure that +/// a value is always read on notify, even if the Optional wasn't initialized +/// previously. +template +class OptionalTypedReferenceFlag : public Flag { + public: + typedef std::shared_ptr> Ptr; - OptionalTypedReferenceFlag(const Name& name, const Description& description, Optional& value) - : Flag{name, description}, - value_{value} - { - } + OptionalTypedReferenceFlag(const Name& name, const Description& description, + Optional& value) + : Flag{name, description}, value_{value} {} - /// @brief notify tries to unwrap a value of type T from value. - void notify(const std::string& s) override - { - std::stringstream ss{s}; T value; ss >> value; - value_.get() = value; - } + /// @brief notify tries to unwrap a value of type T from value. + void notify(const std::string& s) override { + std::stringstream ss{s}; + T value; + ss >> value; + value_.get() = value; + } -private: - std::reference_wrapper> value_; + private: + std::reference_wrapper> value_; }; /// @brief Command abstracts an individual command available from the daemon. -class Command : public DoNotCopyOrMove -{ -public: - // Safe us some typing - typedef std::shared_ptr Ptr; +class Command : public DoNotCopyOrMove { + public: + // Safe us some typing + typedef std::shared_ptr Ptr; - /// @brief FlagsMissing is thrown if at least one required flag is missing. - struct FlagsMissing : public std::runtime_error - { - /// @brief FlagsMissing initializes a new instance. - FlagsMissing(); - }; + /// @brief FlagsMissing is thrown if at least one required flag is missing. + struct FlagsMissing : public std::runtime_error { + /// @brief FlagsMissing initializes a new instance. + FlagsMissing(); + }; - /// @brief FlagsWithWrongValue is thrown if a value passed on the command line is invalid. - struct FlagsWithInvalidValue : public std::runtime_error - { - /// @brief FlagsWithInvalidValue initializes a new instance. - FlagsWithInvalidValue(); - }; + /// @brief FlagsWithWrongValue is thrown if a value passed on the command line + /// is invalid. + struct FlagsWithInvalidValue : public std::runtime_error { + /// @brief FlagsWithInvalidValue initializes a new instance. + FlagsWithInvalidValue(); + }; - /// @brief Context bundles information passed to Command::run invocations. - struct Context - { - std::istream& cin; ///< The std::istream that should be used for reading. - std::ostream& cout; ///< The std::ostream that should be used for writing. - std::vector args; ///< The command line args. - }; + /// @brief Context bundles information passed to Command::run invocations. + struct Context { + std::istream& cin; ///< The std::istream that should be used for reading. + std::ostream& cout; ///< The std::ostream that should be used for writing. + std::vector args; ///< The command line args. + }; - /// @brief name returns the Name of the command. - virtual Name name() const; + /// @brief name returns the Name of the command. + virtual Name name() const; - /// @brief usage returns a short usage string for the command. - virtual Usage usage() const; + /// @brief usage returns a short usage string for the command. + virtual Usage usage() const; - /// @brief description returns a longer string explaining the command. - virtual Description description() const; + /// @brief description returns a longer string explaining the command. + virtual Description description() const; - /// @brief run puts the command to execution. - virtual int run(const Context& context) = 0; + /// @brief run puts the command to execution. + virtual int run(const Context& context) = 0; - /// @brief help prints information about a command to out. - virtual void help(std::ostream& out) = 0; + /// @brief help prints information about a command to out. + virtual void help(std::ostream& out) = 0; -protected: - /// @brief Command initializes a new instance with the given name, usage and description. - Command(const Name& name, const Usage& usage, const Description& description); + protected: + /// @brief Command initializes a new instance with the given name, usage and + /// description. + Command(const Name& name, const Usage& usage, const Description& description); - /// @brief name adjusts the name of the command to n. - // virtual void name(const Name& n); - /// @brief usage adjusts the usage string of the comand to u. - // virtual void usage(const Usage& u); - /// @brief description adjusts the description string of the command to d. - // virtual void description(const Description& d); + /// @brief name adjusts the name of the command to n. + // virtual void name(const Name& n); + /// @brief usage adjusts the usage string of the comand to u. + // virtual void usage(const Usage& u); + /// @brief description adjusts the description string of the command to d. + // virtual void description(const Description& d); -private: - Name name_; - Usage usage_; - Description description_; + private: + Name name_; + Usage usage_; + Description description_; }; -/// @brief CommandWithSubcommands implements Command, selecting one of a set of actions. -class CommandWithSubcommands : public Command -{ -public: - typedef std::shared_ptr Ptr; - typedef std::function Action; +/// @brief CommandWithSubcommands implements Command, selecting one of a set of +/// actions. +class CommandWithSubcommands : public Command { + public: + typedef std::shared_ptr Ptr; + typedef std::function Action; - /// @brief CommandWithSubcommands initializes a new instance with the given name, usage and description - CommandWithSubcommands(const Name& name, const Usage& usage, const Description& description); + /// @brief CommandWithSubcommands initializes a new instance with the given + /// name, usage and description + CommandWithSubcommands(const Name& name, const Usage& usage, + const Description& description); - /// @brief command adds the given command to the set of known commands. - CommandWithSubcommands& command(const Command::Ptr& command); + /// @brief command adds the given command to the set of known commands. + CommandWithSubcommands& command(const Command::Ptr& command); - /// @brief flag adds the given flag to the set of known flags. - CommandWithSubcommands& flag(const Flag::Ptr& flag); + /// @brief flag adds the given flag to the set of known flags. + CommandWithSubcommands& flag(const Flag::Ptr& flag); - // From Command - int run(const Context& context) override; - void help(std::ostream &out) override; + // From Command + int run(const Context& context) override; + void help(std::ostream& out) override; -private: - std::unordered_map commands_; - std::set flags_; + private: + std::unordered_map commands_; + std::set flags_; }; -/// @brief CommandWithFlagsAction implements Command, executing an Action after handling -class CommandWithFlagsAndAction : public Command -{ -public: - typedef std::shared_ptr Ptr; - typedef std::function Action; +/// @brief CommandWithFlagsAction implements Command, executing an Action after +/// handling +class CommandWithFlagsAndAction : public Command { + public: + typedef std::shared_ptr Ptr; + typedef std::function Action; - /// @brief CommandWithFlagsAndAction initializes a new instance with the given name, usage and description - CommandWithFlagsAndAction(const Name& name, const Usage& usage, const Description& description); + /// @brief CommandWithFlagsAndAction initializes a new instance with the given + /// name, usage and description + CommandWithFlagsAndAction(const Name& name, const Usage& usage, + const Description& description); - /// @brief flag adds the given flag to the set of known flags. - CommandWithFlagsAndAction& flag(const Flag::Ptr& flag); + /// @brief flag adds the given flag to the set of known flags. + CommandWithFlagsAndAction& flag(const Flag::Ptr& flag); - /// @brief action installs the given action. - CommandWithFlagsAndAction& action(const Action& action); + /// @brief action installs the given action. + CommandWithFlagsAndAction& action(const Action& action); - // From Command - int run(const Context& context) override; - void help(std::ostream &out) override; + // From Command + int run(const Context& context) override; + void help(std::ostream& out) override; -private: - std::set flags_; - Action action_; + private: + std::set flags_; + Action action_; }; -namespace cmd -{ +namespace cmd { /// @brief HelpFor prints a help message for the given command on execution. -class Help : public Command -{ -public: - /// @brief HelpFor initializes a new instance with the given reference to a cmd. - explicit Help(Command& cmd); +class Help : public Command { + public: + /// @brief HelpFor initializes a new instance with the given reference to a + /// cmd. + explicit Help(Command& cmd); - // From Command - int run(const Context &context) override; - void help(std::ostream &out) override; + // From Command + int run(const Context& context) override; + void help(std::ostream& out) override; -private: - /// @cond - Command& command; - /// @endcond + private: + /// @cond + Command& command; + /// @endcond }; } @@ -329,28 +313,31 @@ private: std::vector args(int argc, char** argv); /// @brief make_flag returns a flag with the given name and description. -template -typename TypedFlag::Ptr make_flag(const Name& name, const Description& description) -{ - return std::make_shared>(name, description); +template +typename TypedFlag::Ptr make_flag(const Name& name, + const Description& description) { + return std::make_shared>(name, description); } -/// @brief make_flag returns a flag with the given name and description, notifying updates to value. -template -typename TypedReferenceFlag::Ptr make_flag(const Name& name, const Description& desc, T& value) -{ - return std::make_shared>(name, desc, value); +/// @brief make_flag returns a flag with the given name and description, +/// notifying updates to value. +template +typename TypedReferenceFlag::Ptr make_flag(const Name& name, + const Description& desc, + T& value) { + return std::make_shared>(name, desc, value); } -/// @brief make_flag returns a flag with the given name and description, updating the given optional value. -template -typename OptionalTypedReferenceFlag::Ptr make_flag(const Name& name, const Description& desc, Optional& value) -{ - return std::make_shared>(name, desc, value); +/// @brief make_flag returns a flag with the given name and description, +/// updating the given optional value. +template +typename OptionalTypedReferenceFlag::Ptr make_flag(const Name& name, + const Description& desc, + Optional& value) { + return std::make_shared>(name, desc, value); } -} // namespace cli -} // namespace anbox - +} // namespace cli +} // namespace anbox #endif diff --git a/src/anbox/cmds/container_manager.cpp b/src/anbox/cmds/container_manager.cpp index f30c08d..fba7492 100644 --- a/src/anbox/cmds/container_manager.cpp +++ b/src/anbox/cmds/container_manager.cpp @@ -17,29 +17,30 @@ #include "anbox/cmds/container_manager.h" #include "anbox/container/service.h" -#include "anbox/runtime.h" #include "anbox/logger.h" +#include "anbox/runtime.h" #include "core/posix/signal.h" anbox::cmds::ContainerManager::ContainerManager() - : CommandWithFlagsAndAction{cli::Name{"container-manager"}, cli::Usage{"container-manager"}, cli::Description{"Start the container manager service"}} -{ - action([](const cli::Command::Context& ctxt) { - auto trap = core::posix::trap_signals_for_process({core::posix::Signal::sig_term, - core::posix::Signal::sig_int}); - trap->signal_raised().connect([trap](const core::posix::Signal &signal) { - INFO("Signal %i received. Good night.", static_cast(signal)); - trap->stop(); - }); - - auto rt = Runtime::create(); - auto service = container::Service::create(rt); - - rt->start(); - trap->run(); - rt->stop(); - - return 0; + : CommandWithFlagsAndAction{ + cli::Name{"container-manager"}, cli::Usage{"container-manager"}, + cli::Description{"Start the container manager service"}} { + action([](const cli::Command::Context& ctxt) { + auto trap = core::posix::trap_signals_for_process( + {core::posix::Signal::sig_term, core::posix::Signal::sig_int}); + trap->signal_raised().connect([trap](const core::posix::Signal& signal) { + INFO("Signal %i received. Good night.", static_cast(signal)); + trap->stop(); }); + + auto rt = Runtime::create(); + auto service = container::Service::create(rt); + + rt->start(); + trap->run(); + rt->stop(); + + return 0; + }); } diff --git a/src/anbox/cmds/container_manager.h b/src/anbox/cmds/container_manager.h index 8f92ef7..866e85f 100644 --- a/src/anbox/cmds/container_manager.h +++ b/src/anbox/cmds/container_manager.h @@ -27,10 +27,10 @@ namespace anbox { namespace cmds { class ContainerManager : public cli::CommandWithFlagsAndAction { -public: - ContainerManager(); + public: + ContainerManager(); }; -} // namespace cmds -} // namespace anbox +} // namespace cmds +} // namespace anbox #endif diff --git a/src/anbox/cmds/install.cpp b/src/anbox/cmds/install.cpp index 82d4eba..ff3c4af 100644 --- a/src/anbox/cmds/install.cpp +++ b/src/anbox/cmds/install.cpp @@ -25,22 +25,27 @@ namespace fs = boost::filesystem; anbox::cmds::Install::Install() - : CommandWithFlagsAndAction{cli::Name{"install"}, cli::Usage{"install"}, cli::Description{"Install specified application in the Android container"}} -{ - flag(cli::make_flag(cli::Name{"apk"}, cli::Description{"Path to APK to install"}, apk_)); - action([this](const cli::Command::Context&) { - if (apk_.length() == 0) - BOOST_THROW_EXCEPTION(std::runtime_error("No APK to install specified")); + : CommandWithFlagsAndAction{ + cli::Name{"install"}, cli::Usage{"install"}, + cli::Description{ + "Install specified application in the Android container"}} { + flag(cli::make_flag(cli::Name{"apk"}, + cli::Description{"Path to APK to install"}, apk_)); + action([this](const cli::Command::Context&) { + if (apk_.length() == 0) + BOOST_THROW_EXCEPTION(std::runtime_error("No APK to install specified")); - if (!fs::is_regular_file(apk_)) - BOOST_THROW_EXCEPTION(std::runtime_error("Specified APK file does not exist")); + if (!fs::is_regular_file(apk_)) + BOOST_THROW_EXCEPTION( + std::runtime_error("Specified APK file does not exist")); - auto bus = std::make_shared(core::dbus::WellKnownBus::session); - bus->install_executor(core::dbus::asio::make_executor(bus)); - auto stub = dbus::stub::ApplicationManager::create_for_bus(bus); + auto bus = + std::make_shared(core::dbus::WellKnownBus::session); + bus->install_executor(core::dbus::asio::make_executor(bus)); + auto stub = dbus::stub::ApplicationManager::create_for_bus(bus); - stub->install(apk_); + stub->install(apk_); - return EXIT_SUCCESS; - }); + return EXIT_SUCCESS; + }); } diff --git a/src/anbox/cmds/install.h b/src/anbox/cmds/install.h index d7833dd..63f2102 100644 --- a/src/anbox/cmds/install.h +++ b/src/anbox/cmds/install.h @@ -27,13 +27,13 @@ namespace anbox { namespace cmds { class Install : public cli::CommandWithFlagsAndAction { -public: - Install(); + public: + Install(); -private: - std::string apk_; + private: + std::string apk_; }; -} // namespace cmds -} // namespace anbox +} // namespace cmds +} // namespace anbox #endif diff --git a/src/anbox/cmds/launch.cpp b/src/anbox/cmds/launch.cpp index b86da8a..6e611d3 100644 --- a/src/anbox/cmds/launch.cpp +++ b/src/anbox/cmds/launch.cpp @@ -25,21 +25,34 @@ namespace fs = boost::filesystem; anbox::cmds::Launch::Launch() - : CommandWithFlagsAndAction{cli::Name{"launch"}, cli::Usage{"launch"}, cli::Description{"Launch an Activity by sending an intent"}} -{ - flag(cli::make_flag(cli::Name{"action"}, cli::Description{"Action of the intent"}, intent_.action)); - flag(cli::make_flag(cli::Name{"type"}, cli::Description{"MIME type for the intent"}, intent_.type)); - flag(cli::make_flag(cli::Name{"uri"}, cli::Description{"URI used as data within the intent"}, intent_.uri)); - flag(cli::make_flag(cli::Name{"package"}, cli::Description{"Package the intent should go to"}, intent_.package)); - flag(cli::make_flag(cli::Name{"component"}, cli::Description{"Component of a package the intent should go"}, intent_.component)); + : CommandWithFlagsAndAction{ + cli::Name{"launch"}, cli::Usage{"launch"}, + cli::Description{"Launch an Activity by sending an intent"}} { + flag(cli::make_flag(cli::Name{"action"}, + cli::Description{"Action of the intent"}, + intent_.action)); + flag(cli::make_flag(cli::Name{"type"}, + cli::Description{"MIME type for the intent"}, + intent_.type)); + flag(cli::make_flag(cli::Name{"uri"}, + cli::Description{"URI used as data within the intent"}, + intent_.uri)); + flag(cli::make_flag(cli::Name{"package"}, + cli::Description{"Package the intent should go to"}, + intent_.package)); + flag(cli::make_flag( + cli::Name{"component"}, + cli::Description{"Component of a package the intent should go"}, + intent_.component)); - action([this](const cli::Command::Context&) { - auto bus = std::make_shared(core::dbus::WellKnownBus::session); - bus->install_executor(core::dbus::asio::make_executor(bus)); - auto stub = dbus::stub::ApplicationManager::create_for_bus(bus); + action([this](const cli::Command::Context&) { + auto bus = + std::make_shared(core::dbus::WellKnownBus::session); + bus->install_executor(core::dbus::asio::make_executor(bus)); + auto stub = dbus::stub::ApplicationManager::create_for_bus(bus); - stub->launch(intent_); + stub->launch(intent_); - return EXIT_SUCCESS; - }); + return EXIT_SUCCESS; + }); } diff --git a/src/anbox/cmds/launch.h b/src/anbox/cmds/launch.h index 98075a0..8ee4537 100644 --- a/src/anbox/cmds/launch.h +++ b/src/anbox/cmds/launch.h @@ -22,19 +22,19 @@ #include #include -#include "anbox/cli.h" #include "anbox/android/intent.h" +#include "anbox/cli.h" namespace anbox { namespace cmds { class Launch : public cli::CommandWithFlagsAndAction { -public: - Launch(); + public: + Launch(); -private: - android::Intent intent_; + private: + android::Intent intent_; }; -} // namespace cmds -} // namespace anbox +} // namespace cmds +} // namespace anbox #endif diff --git a/src/anbox/cmds/run.cpp b/src/anbox/cmds/run.cpp index 84a4b66..6547672 100644 --- a/src/anbox/cmds/run.cpp +++ b/src/anbox/cmds/run.cpp @@ -19,95 +19,103 @@ #include "core/posix/signal.h" -#include "anbox/logger.h" -#include "anbox/runtime.h" -#include "anbox/config.h" -#include "anbox/common/dispatcher.h" -#include "anbox/cmds/run.h" -#include "anbox/network/published_socket_connector.h" -#include "anbox/qemu/pipe_connection_creator.h" -#include "anbox/graphics/gl_renderer_server.h" -#include "anbox/input/manager.h" -#include "anbox/rpc/connection_creator.h" -#include "anbox/rpc/channel.h" -#include "anbox/bridge/platform_message_processor.h" +#include "anbox/application/launcher_storage.h" #include "anbox/bridge/android_api_stub.h" #include "anbox/bridge/platform_api_skeleton.h" -#include "anbox/dbus/skeleton/service.h" +#include "anbox/bridge/platform_message_processor.h" +#include "anbox/cmds/run.h" +#include "anbox/common/dispatcher.h" +#include "anbox/config.h" #include "anbox/container/client.h" -#include "anbox/wm/manager.h" +#include "anbox/dbus/skeleton/service.h" +#include "anbox/graphics/gl_renderer_server.h" +#include "anbox/input/manager.h" +#include "anbox/logger.h" +#include "anbox/network/published_socket_connector.h" +#include "anbox/qemu/pipe_connection_creator.h" +#include "anbox/rpc/channel.h" +#include "anbox/rpc/connection_creator.h" +#include "anbox/runtime.h" #include "anbox/ubuntu/platform_policy.h" -#include "anbox/application/launcher_storage.h" +#include "anbox/wm/manager.h" #include "external/xdg/xdg.h" #include -#include #include +#include namespace fs = boost::filesystem; namespace { -class NullConnectionCreator : public anbox::network::ConnectionCreator { -public: - void create_connection_for( - std::shared_ptr const& socket) override { - WARNING("Not implemented"); - socket->close(); - } +class NullConnectionCreator : public anbox::network::ConnectionCreator< + boost::asio::local::stream_protocol> { + public: + void create_connection_for( + std::shared_ptr const + &socket) override { + WARNING("Not implemented"); + socket->close(); + } }; } anbox::cmds::Run::BusFactory anbox::cmds::Run::session_bus_factory() { - return []() { - return std::make_shared(core::dbus::WellKnownBus::session); - }; + return []() { + return std::make_shared(core::dbus::WellKnownBus::session); + }; } -anbox::cmds::Run::Run(const BusFactory& bus_factory) - : CommandWithFlagsAndAction{cli::Name{"run"}, cli::Usage{"run"}, cli::Description{"Run the the anbox system"}}, - bus_factory_(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{"icon"}, cli::Description{"Icon of the application to run"}, icon_)); +anbox::cmds::Run::Run(const BusFactory &bus_factory) + : CommandWithFlagsAndAction{cli::Name{"run"}, cli::Usage{"run"}, + cli::Description{"Run the the anbox system"}}, + bus_factory_(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{"icon"}, + cli::Description{"Icon of the application to run"}, + icon_)); - action([this](const cli::Command::Context &ctx) { - auto trap = core::posix::trap_signals_for_process({core::posix::Signal::sig_term, - core::posix::Signal::sig_int}); - trap->signal_raised().connect([trap](const core::posix::Signal &signal) { - INFO("Signal %i received. Good night.", static_cast(signal)); - trap->stop(); - }); + action([this](const cli::Command::Context &ctx) { + auto trap = core::posix::trap_signals_for_process( + {core::posix::Signal::sig_term, core::posix::Signal::sig_int}); + trap->signal_raised().connect([trap](const core::posix::Signal &signal) { + INFO("Signal %i received. Good night.", static_cast(signal)); + trap->stop(); + }); - utils::ensure_paths({ - config::socket_path(), - config::host_input_device_path(), - }); + utils::ensure_paths({ + config::socket_path(), config::host_input_device_path(), + }); - auto rt = Runtime::create(); - auto dispatcher = anbox::common::create_dispatcher_for_runtime(rt); + auto rt = Runtime::create(); + auto dispatcher = anbox::common::create_dispatcher_for_runtime(rt); - auto input_manager = std::make_shared(rt); + auto input_manager = std::make_shared(rt); - auto android_api_stub = std::make_shared(); + auto android_api_stub = std::make_shared(); - auto policy = std::make_shared(input_manager, android_api_stub); - // FIXME this needs to be removed and solved differently behind the scenes - registerDisplayManager(policy); + auto policy = std::make_shared(input_manager, + android_api_stub); + // FIXME this needs to be removed and solved differently behind the scenes + registerDisplayManager(policy); - auto window_manager = std::make_shared(policy); + auto window_manager = std::make_shared(policy); - auto launcher_storage = std::make_shared( - xdg::data().home() / "applications"); + auto launcher_storage = std::make_shared( + xdg::data().home() / "applications"); - auto renderer = std::make_shared(window_manager); - renderer->start(); + auto renderer = + std::make_shared(window_manager); + renderer->start(); - // Socket which will be used by the qemud service inside the Android - // container for things like sensors, vibrtator etc. +// Socket which will be used by the qemud service inside the Android +// container for things like sensors, vibrtator etc. #if 0 auto qemud_connector = std::make_shared( utils::string_format("%s/qemud", config::socket_path()), @@ -115,60 +123,59 @@ anbox::cmds::Run::Run(const BusFactory& bus_factory) std::make_shared()); #endif - // The qemu pipe is used as a very fast communication channel between guest - // and host for things like the GLES emulation/translation, the RIL or ADB. - auto qemu_pipe_connector = std::make_shared( - utils::string_format("%s/qemu_pipe", config::socket_path()), - rt, - std::make_shared(rt, - renderer->socket_path(), - icon_)); + // The qemu pipe is used as a very fast communication channel between guest + // and host for things like the GLES emulation/translation, the RIL or ADB. + auto qemu_pipe_connector = + std::make_shared( + utils::string_format("%s/qemu_pipe", config::socket_path()), rt, + std::make_shared( + rt, renderer->socket_path(), icon_)); + auto bridge_connector = std::make_shared( + utils::string_format("%s/anbox_bridge", config::socket_path()), rt, + std::make_shared( + rt, [&](const std::shared_ptr &sender) { + auto pending_calls = std::make_shared(); + auto rpc_channel = + std::make_shared(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. + android_api_stub->set_rpc_channel(rpc_channel); - auto bridge_connector = std::make_shared( - utils::string_format("%s/anbox_bridge", config::socket_path()), - rt, - std::make_shared(rt, - [&](const std::shared_ptr &sender) { - auto pending_calls = std::make_shared(); - auto rpc_channel = std::make_shared(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. - android_api_stub->set_rpc_channel(rpc_channel); + auto server = std::make_shared( + pending_calls, window_manager, launcher_storage); + server->register_boot_finished_handler( + [&]() { DEBUG("Android successfully booted"); }); + return std::make_shared( + sender, server, pending_calls); + })); - auto server = std::make_shared(pending_calls, - window_manager, - launcher_storage); - server->register_boot_finished_handler([&]() { - DEBUG("Android successfully booted"); - }); - return std::make_shared(sender, server, pending_calls); - })); + container::Client container(rt); + container::Configuration container_configuration; + container_configuration.bind_mounts = { + // { qemud_connector->socket_file(), "/dev/qemud" }, + {qemu_pipe_connector->socket_file(), "/dev/qemu_pipe"}, + {bridge_connector->socket_file(), "/dev/anbox_bridge"}, + {config::host_input_device_path(), "/dev/input"}, + {"/dev/binder", "/dev/binder"}, + {"/dev/ashmem", "/dev/ashmem"}, + }; - container::Client container(rt); - container::Configuration container_configuration; - container_configuration.bind_mounts = { - // { qemud_connector->socket_file(), "/dev/qemud" }, - { qemu_pipe_connector->socket_file(), "/dev/qemu_pipe" }, - { bridge_connector->socket_file(), "/dev/anbox_bridge" }, - { config::host_input_device_path(), "/dev/input" }, - { "/dev/binder", "/dev/binder" }, - { "/dev/ashmem", "/dev/ashmem" }, - }; + dispatcher->dispatch( + [&]() { container.start_container(container_configuration); }); - dispatcher->dispatch([&]() { - container.start_container(container_configuration); - }); + auto bus = bus_factory_(); + bus->install_executor(core::dbus::asio::make_executor(bus, rt->service())); - 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, android_api_stub); - auto skeleton = anbox::dbus::skeleton::Service::create_for_bus(bus, android_api_stub); + rt->start(); + trap->run(); + rt->stop(); - rt->start(); - trap->run(); - rt->stop(); - - return EXIT_SUCCESS; - }); + return EXIT_SUCCESS; + }); } diff --git a/src/anbox/cmds/run.h b/src/anbox/cmds/run.h index 0b887e7..7e14a18 100644 --- a/src/anbox/cmds/run.h +++ b/src/anbox/cmds/run.h @@ -29,19 +29,19 @@ namespace anbox { namespace cmds { class Run : public cli::CommandWithFlagsAndAction { -public: - typedef std::function BusFactory; + public: + typedef std::function BusFactory; - static BusFactory session_bus_factory(); + static BusFactory session_bus_factory(); - Run(const BusFactory& bus_factory = session_bus_factory()); + Run(const BusFactory& bus_factory = session_bus_factory()); -private: - BusFactory bus_factory_; - std::string desktop_file_hint_; - std::string icon_; + private: + BusFactory bus_factory_; + std::string desktop_file_hint_; + std::string icon_; }; -} // namespace cmds -} // namespace anbox +} // namespace cmds +} // namespace anbox #endif diff --git a/src/anbox/cmds/version.cpp b/src/anbox/cmds/version.cpp index 538b42f..c405e48 100644 --- a/src/anbox/cmds/version.cpp +++ b/src/anbox/cmds/version.cpp @@ -21,13 +21,13 @@ #include "anbox/version.h" anbox::cmds::Version::Version() - : CommandWithFlagsAndAction{cli::Name{"version"}, cli::Usage{"version"}, cli::Description{"print the version of the daemon"}} -{ - action([](const cli::Command::Context& ctxt) - { - std::uint32_t major, minor, patch; - anbox::version(major, minor, patch); - ctxt.cout << "anbox " << major << "." << minor << "." << patch << std::endl; - return 0; - }); + : CommandWithFlagsAndAction{ + cli::Name{"version"}, cli::Usage{"version"}, + cli::Description{"print the version of the daemon"}} { + action([](const cli::Command::Context& ctxt) { + std::uint32_t major, minor, patch; + anbox::version(major, minor, patch); + ctxt.cout << "anbox " << major << "." << minor << "." << patch << std::endl; + return 0; + }); } diff --git a/src/anbox/cmds/version.h b/src/anbox/cmds/version.h index 37b38d4..43dab98 100644 --- a/src/anbox/cmds/version.h +++ b/src/anbox/cmds/version.h @@ -29,10 +29,10 @@ namespace anbox { namespace cmds { class Version : public cli::CommandWithFlagsAndAction { -public: - Version(); + public: + Version(); }; -} // namespace cmds -} // namespace anbox +} // namespace cmds +} // namespace anbox #endif diff --git a/src/anbox/common/dispatcher.cpp b/src/anbox/common/dispatcher.cpp index 4a32c68..aaec441 100644 --- a/src/anbox/common/dispatcher.cpp +++ b/src/anbox/common/dispatcher.cpp @@ -21,23 +21,20 @@ namespace { struct AsioStrandDispatcher : public anbox::common::Dispatcher { -public: - AsioStrandDispatcher(const std::shared_ptr& rt) - : rt{rt}, - strand{rt->service()} { - } + public: + AsioStrandDispatcher(const std::shared_ptr& rt) + : rt{rt}, strand{rt->service()} {} - void dispatch(const Task &task) override { - strand.post(task); - } + void dispatch(const Task& task) override { strand.post(task); } -private: - std::shared_ptr rt; - boost::asio::io_service::strand strand; + private: + std::shared_ptr rt; + boost::asio::io_service::strand strand; }; } -std::shared_ptr anbox::common::create_dispatcher_for_runtime( - const std::shared_ptr& rt) { - return std::make_shared(rt); +std::shared_ptr +anbox::common::create_dispatcher_for_runtime( + const std::shared_ptr& rt) { + return std::make_shared(rt); } diff --git a/src/anbox/common/dispatcher.h b/src/anbox/common/dispatcher.h index 8bd1eef..53d4b43 100644 --- a/src/anbox/common/dispatcher.h +++ b/src/anbox/common/dispatcher.h @@ -28,16 +28,17 @@ namespace anbox { namespace common { class Dispatcher : public DoNotCopyOrMove { -public: - typedef std::function Task; - virtual void dispatch(const Task& task) = 0; + public: + typedef std::function Task; + virtual void dispatch(const Task& task) = 0; -protected: - Dispatcher() = default; + protected: + Dispatcher() = default; }; -std::shared_ptr create_dispatcher_for_runtime(const std::shared_ptr&); -} // namespace common -} // namespace anbox +std::shared_ptr create_dispatcher_for_runtime( + const std::shared_ptr&); +} // namespace common +} // namespace anbox #endif diff --git a/src/anbox/common/fd.cpp b/src/anbox/common/fd.cpp index 9e9a4ef..d7f1748 100644 --- a/src/anbox/common/fd.cpp +++ b/src/anbox/common/fd.cpp @@ -21,41 +21,27 @@ #include namespace anbox { -Fd::Fd() : - Fd{invalid} -{ +Fd::Fd() : Fd{invalid} {} + +Fd::Fd(IntOwnedFd fd) : fd{std::make_shared(fd.int_owned_fd)} {} + +Fd::Fd(int raw_fd) + : fd{new int{raw_fd}, + [](int* fd) { + if (!fd) return; + if (*fd > Fd::invalid) ::close(*fd); + delete fd; + }} {} + +Fd::Fd(Fd&& other) : fd{std::move(other.fd)} {} + +Fd& Fd::operator=(Fd other) { + std::swap(fd, other.fd); + return *this; } -Fd::Fd(IntOwnedFd fd) : - fd{std::make_shared(fd.int_owned_fd)} -{ +Fd::operator int() const { + if (fd) return *fd; + return invalid; } - -Fd::Fd(int raw_fd) : - fd{new int{raw_fd}, - [](int* fd) - { - if (!fd) return; - if (*fd > Fd::invalid) ::close(*fd); - delete fd; - }} -{ -} - -Fd::Fd(Fd&& other) : - fd{std::move(other.fd)} -{ -} - -Fd& Fd::operator=(Fd other) -{ - std::swap(fd, other.fd); - return *this; -} - -Fd::operator int() const -{ - if (fd) return *fd; - return invalid; -} -} // namespace anbox +} // namespace anbox diff --git a/src/anbox/common/fd.h b/src/anbox/common/fd.h index 37ca9c1..6b2d922 100644 --- a/src/anbox/common/fd.h +++ b/src/anbox/common/fd.h @@ -22,29 +22,29 @@ #include namespace anbox { -struct IntOwnedFd -{ - int int_owned_fd; +struct IntOwnedFd { + int int_owned_fd; }; -class Fd -{ -public: - //transfer ownership of the POD-int to the object. The int no longer needs close()ing, - //and has the lifetime of the Fd object. - explicit Fd(int fd); - explicit Fd(IntOwnedFd); - static int const invalid{-1}; - Fd(); //Initializes fd to the anbox::Fd::invalid; - Fd(Fd&&); - Fd(Fd const&) = default; - Fd& operator=(Fd); +class Fd { + public: + // transfer ownership of the POD-int to the object. The int no longer needs + // close()ing, + // and has the lifetime of the Fd object. + explicit Fd(int fd); + explicit Fd(IntOwnedFd); + static int const invalid{-1}; + Fd(); // Initializes fd to the anbox::Fd::invalid; + Fd(Fd&&); + Fd(Fd const&) = default; + Fd& operator=(Fd); - //bit of a convenient kludge. take care not to close or otherwise destroy the FD. - operator int() const; + // bit of a convenient kludge. take care not to close or otherwise destroy the + // FD. + operator int() const; -private: - std::shared_ptr fd; + private: + std::shared_ptr fd; }; -} // namespace anbox +} // namespace anbox #endif diff --git a/src/anbox/common/fd_sets.h b/src/anbox/common/fd_sets.h index fba4013..7e578f9 100644 --- a/src/anbox/common/fd_sets.h +++ b/src/anbox/common/fd_sets.h @@ -19,13 +19,13 @@ #ifndef ANBOX_COMMON_FD_SETS_H_ #define ANBOX_COMMON_FD_SETS_H_ -#include #include +#include #include "anbox/common/fd.h" namespace anbox { typedef std::vector> FdSets; -} // namespace anbox +} // namespace anbox #endif diff --git a/src/anbox/common/variable_length_array.h b/src/anbox/common/variable_length_array.h index b4f3526..52fedbf 100644 --- a/src/anbox/common/variable_length_array.h +++ b/src/anbox/common/variable_length_array.h @@ -24,38 +24,35 @@ namespace anbox { template -class VariableLengthArray -{ -public: - explicit VariableLengthArray(size_t size) : size_{size} - { - /* Don't call resize if the initial values of member variables are valid */ - if (size > BuiltInBufferSize) resize(size); - } +class VariableLengthArray { + public: + explicit VariableLengthArray(size_t size) : size_{size} { + /* Don't call resize if the initial values of member variables are valid */ + if (size > BuiltInBufferSize) resize(size); + } - void resize(size_t size) - { - if (size > BuiltInBufferSize) - effective_buffer = BufferUPtr{new unsigned char[size], heap_deleter}; - else - effective_buffer = BufferUPtr{builtin_buffer, null_deleter}; + void resize(size_t size) { + if (size > BuiltInBufferSize) + effective_buffer = BufferUPtr{new unsigned char[size], heap_deleter}; + else + effective_buffer = BufferUPtr{builtin_buffer, null_deleter}; - size_ = size; - } + size_ = size; + } - unsigned char* data() const { return effective_buffer.get(); } - size_t size() const { return size_; } + unsigned char* data() const { return effective_buffer.get(); } + size_t size() const { return size_; } -private: - typedef std::unique_ptr BufferUPtr; + private: + typedef std::unique_ptr BufferUPtr; - static void null_deleter(unsigned char*) {} - static void heap_deleter(unsigned char* b) { delete[] b; } + static void null_deleter(unsigned char*) {} + static void heap_deleter(unsigned char* b) { delete[] b; } - unsigned char builtin_buffer[BuiltInBufferSize]; - BufferUPtr effective_buffer{builtin_buffer, null_deleter}; - size_t size_; + unsigned char builtin_buffer[BuiltInBufferSize]; + BufferUPtr effective_buffer{builtin_buffer, null_deleter}; + size_t size_; }; -} // namespace anbox +} // namespace anbox #endif diff --git a/src/anbox/common/wait_handle.cpp b/src/anbox/common/wait_handle.cpp index d3bb509..0159816 100644 --- a/src/anbox/common/wait_handle.cpp +++ b/src/anbox/common/wait_handle.cpp @@ -21,72 +21,59 @@ namespace anbox { namespace common { -WaitHandle::WaitHandle() : - guard(), - wait_condition(), - expecting(0), - received(0) -{ +WaitHandle::WaitHandle() + : guard(), wait_condition(), expecting(0), received(0) {} + +WaitHandle::~WaitHandle() {} + +void WaitHandle::expect_result() { + std::lock_guard lock(guard); + + expecting++; } -WaitHandle::~WaitHandle() -{ -} +void WaitHandle::result_received() { + std::lock_guard lock(guard); -void WaitHandle::expect_result() -{ - std::lock_guard lock(guard); - - expecting++; -} - -void WaitHandle::result_received() -{ - std::lock_guard lock(guard); - - received++; - wait_condition.notify_all(); + received++; + wait_condition.notify_all(); } void WaitHandle::wait_for_all() // wait for all results you expect { - std::unique_lock lock(guard); + std::unique_lock lock(guard); - wait_condition.wait(lock, [&]{ return received == expecting; }); + wait_condition.wait(lock, [&] { return received == expecting; }); - received = 0; - expecting = 0; + received = 0; + expecting = 0; } -void WaitHandle::wait_for_pending(std::chrono::milliseconds limit) -{ - std::unique_lock lock(guard); +void WaitHandle::wait_for_pending(std::chrono::milliseconds limit) { + std::unique_lock lock(guard); - wait_condition.wait_for(lock, limit, [&]{ return received == expecting; }); + wait_condition.wait_for(lock, limit, [&] { return received == expecting; }); } - void WaitHandle::wait_for_one() // wait for any single result { - std::unique_lock lock(guard); + std::unique_lock lock(guard); - wait_condition.wait(lock, [&]{ return received != 0; }); + wait_condition.wait(lock, [&] { return received != 0; }); - --received; - --expecting; + --received; + --expecting; } -bool WaitHandle::has_result() -{ - std::lock_guard lock(guard); +bool WaitHandle::has_result() { + std::lock_guard lock(guard); - return received > 0; + return received > 0; } -bool WaitHandle::is_pending() -{ - std::unique_lock lock(guard); - return expecting > 0 && received != expecting; +bool WaitHandle::is_pending() { + std::unique_lock lock(guard); + return expecting > 0 && received != expecting; } -} // namespace common -} // namespace anbox +} // namespace common +} // namespace anbox diff --git a/src/anbox/common/wait_handle.h b/src/anbox/common/wait_handle.h index 13e3cd8..37c12c6 100644 --- a/src/anbox/common/wait_handle.h +++ b/src/anbox/common/wait_handle.h @@ -26,29 +26,28 @@ namespace anbox { namespace common { -struct WaitHandle -{ -public: - WaitHandle(); - ~WaitHandle(); +struct WaitHandle { + public: + WaitHandle(); + ~WaitHandle(); - void expect_result(); - void result_received(); - void wait_for_all(); - void wait_for_one(); - void wait_for_pending(std::chrono::milliseconds limit); + void expect_result(); + void result_received(); + void wait_for_all(); + void wait_for_one(); + void wait_for_pending(std::chrono::milliseconds limit); - bool has_result(); - bool is_pending(); + bool has_result(); + bool is_pending(); -private: - std::mutex guard; - std::condition_variable wait_condition; + private: + std::mutex guard; + std::condition_variable wait_condition; - int expecting; - int received; + int expecting; + int received; }; -} // namespace common -} // namespace anbox +} // namespace common +} // namespace anbox #endif diff --git a/src/anbox/config.cpp b/src/anbox/config.cpp index 730ac95..c9db3c2 100644 --- a/src/anbox/config.cpp +++ b/src/anbox/config.cpp @@ -27,76 +27,81 @@ namespace fs = boost::filesystem; namespace anbox { namespace config { std::string in_snap_dir(const std::string &path) { - return utils::prefix_dir_from_env(path, "SNAP"); + return utils::prefix_dir_from_env(path, "SNAP"); } std::string in_snap_data_dir(const std::string &path) { - return utils::prefix_dir_from_env(path, "SNAP_COMMON"); + return utils::prefix_dir_from_env(path, "SNAP_COMMON"); } std::string in_snap_user_data_dir(const std::string &path) { - return utils::prefix_dir_from_env(path, "SNAP_USER_COMMON"); + return utils::prefix_dir_from_env(path, "SNAP_USER_COMMON"); } std::string home_dir() { - static std::string path; - if (path.empty()) { - path = utils::get_env_value("HOME", ""); - if (path.empty()) - BOOST_THROW_EXCEPTION(std::runtime_error("No home directory specified")); - } - return path; + static std::string path; + if (path.empty()) { + path = utils::get_env_value("HOME", ""); + if (path.empty()) + BOOST_THROW_EXCEPTION(std::runtime_error("No home directory specified")); + } + return path; } std::string runtime_dir() { - static std::string path; - if (path.empty()) { - path = utils::get_env_value("XDG_RUNTIME_DIR", ""); - if (path.empty()) - BOOST_THROW_EXCEPTION(std::runtime_error("No runtime directory specified")); - } - return path; + static std::string path; + if (path.empty()) { + path = utils::get_env_value("XDG_RUNTIME_DIR", ""); + if (path.empty()) + BOOST_THROW_EXCEPTION( + std::runtime_error("No runtime directory specified")); + } + return path; } std::string state_dir() { - static std::string path = "/var/lib"; - return path; + static std::string path = "/var/lib"; + return path; } std::string log_path() { - static std::string path = in_snap_data_dir(utils::string_format("%s/anbox/", state_dir())); - return path; + static std::string path = + in_snap_data_dir(utils::string_format("%s/anbox/", state_dir())); + return path; } std::string socket_path() { - - static std::string path = utils::string_format("%s/anbox/sockets", runtime_dir()); - return path; + static std::string path = + utils::string_format("%s/anbox/sockets", runtime_dir()); + return path; } std::string data_path() { - static std::string path = utils::string_format("%s/.anbox/data", home_dir()); - return path; + static std::string path = utils::string_format("%s/.anbox/data", home_dir()); + return path; } std::string rootfs_path() { - static std::string path = in_snap_data_dir(utils::string_format("%s/anbox/rootfs", state_dir())); - return path; + static std::string path = + in_snap_data_dir(utils::string_format("%s/anbox/rootfs", state_dir())); + return path; } std::string container_config_path() { - static std::string path = in_snap_data_dir(utils::string_format("%s/anbox/containers", state_dir())); - return path; + static std::string path = in_snap_data_dir( + utils::string_format("%s/anbox/containers", state_dir())); + return path; } std::string container_socket_path() { - std::string path = "/run/anbox-container.socket"; - return path; + std::string path = "/run/anbox-container.socket"; + return path; } std::string host_input_device_path() { - static std::string path = utils::string_format("%s/anbox/input-devices", runtime_dir()); - return path; + static std::string path = + utils::string_format("%s/anbox/input-devices", runtime_dir()); + return path; } -} // namespace config -} // namespace anbox +} // namespace config +} // namespace anbox diff --git a/src/anbox/config.h b/src/anbox/config.h index 1808f76..21514d1 100644 --- a/src/anbox/config.h +++ b/src/anbox/config.h @@ -32,7 +32,7 @@ std::string socket_path(); std::string container_config_path(); std::string container_socket_path(); std::string host_input_device_path(); -} // namespace config -} // namespace anbox +} // namespace config +} // namespace anbox #endif diff --git a/src/anbox/container/client.cpp b/src/anbox/container/client.cpp index f7bc599..fe0e9d5 100644 --- a/src/anbox/container/client.cpp +++ b/src/anbox/container/client.cpp @@ -16,53 +16,50 @@ */ #include "anbox/container/client.h" +#include "anbox/config.h" #include "anbox/container/management_api_stub.h" +#include "anbox/logger.h" #include "anbox/network/local_socket_messenger.h" -#include "anbox/rpc/pending_call_cache.h" #include "anbox/rpc/channel.h" #include "anbox/rpc/message_processor.h" -#include "anbox/config.h" -#include "anbox/logger.h" +#include "anbox/rpc/pending_call_cache.h" namespace ba = boost::asio; namespace bs = boost::system; namespace anbox { namespace container { -Client::Client(const std::shared_ptr &rt) : - messenger_(std::make_shared(config::container_socket_path(), rt)), - pending_calls_(std::make_shared()), - rpc_channel_(std::make_shared(pending_calls_, messenger_)), - management_api_(std::make_shared(rpc_channel_)), - processor_(std::make_shared(messenger_, pending_calls_)) { - - read_next_message(); +Client::Client(const std::shared_ptr &rt) + : messenger_(std::make_shared( + config::container_socket_path(), rt)), + pending_calls_(std::make_shared()), + rpc_channel_(std::make_shared(pending_calls_, messenger_)), + management_api_(std::make_shared(rpc_channel_)), + processor_( + std::make_shared(messenger_, pending_calls_)) { + read_next_message(); } -Client::~Client() { -} +Client::~Client() {} void Client::start_container(const Configuration &configuration) { - management_api_->start_container(configuration); + management_api_->start_container(configuration); } -void Client::read_next_message() -{ - auto callback = std::bind(&Client::on_read_size, - this, std::placeholders::_1, std::placeholders::_2); - messenger_->async_receive_msg(callback, ba::buffer(buffer_)); +void Client::read_next_message() { + auto callback = std::bind(&Client::on_read_size, this, std::placeholders::_1, + std::placeholders::_2); + messenger_->async_receive_msg(callback, ba::buffer(buffer_)); } -void Client::on_read_size(const boost::system::error_code& error, std::size_t bytes_read) -{ - if (error) - BOOST_THROW_EXCEPTION(std::runtime_error(error.message())); +void Client::on_read_size(const boost::system::error_code &error, + std::size_t bytes_read) { + if (error) BOOST_THROW_EXCEPTION(std::runtime_error(error.message())); - std::vector data(bytes_read); - std::copy(buffer_.data(), buffer_.data() + bytes_read, data.data()); + std::vector data(bytes_read); + std::copy(buffer_.data(), buffer_.data() + bytes_read, data.data()); - if (processor_->process_data(data)) - read_next_message(); + if (processor_->process_data(data)) read_next_message(); } -} // namespace container -} // namespace anbox +} // namespace container +} // namespace anbox diff --git a/src/anbox/container/client.h b/src/anbox/container/client.h index e0236b4..63aabdf 100644 --- a/src/anbox/container/client.h +++ b/src/anbox/container/client.h @@ -18,39 +18,40 @@ #ifndef ANBOX_CONTAINER_CLIENT_H_ #define ANBOX_CONTAINER_CLIENT_H_ -#include "anbox/runtime.h" #include "anbox/container/configuration.h" +#include "anbox/runtime.h" namespace anbox { namespace rpc { class PendingCallCache; class Channel; class MessageProcessor; -} // namespace rpc +} // namespace rpc namespace network { class LocalSocketMessenger; -} // namespace network +} // namespace network namespace container { class ManagementApiStub; class Client { -public: - Client(const std::shared_ptr &rt); - ~Client(); + public: + Client(const std::shared_ptr &rt); + ~Client(); - void start_container(const Configuration &configuration); + void start_container(const Configuration &configuration); -private: - void read_next_message(); - void on_read_size(const boost::system::error_code& ec, std::size_t bytes_read); + private: + void read_next_message(); + void on_read_size(const boost::system::error_code &ec, + std::size_t bytes_read); - std::shared_ptr messenger_; - std::shared_ptr pending_calls_; - std::shared_ptr rpc_channel_; - std::shared_ptr management_api_; - std::shared_ptr processor_; - std::array buffer_; + std::shared_ptr messenger_; + std::shared_ptr pending_calls_; + std::shared_ptr rpc_channel_; + std::shared_ptr management_api_; + std::shared_ptr processor_; + std::array buffer_; }; -} // namespace container -} // namespace anbox +} // namespace container +} // namespace anbox #endif diff --git a/src/anbox/container/configuration.h b/src/anbox/container/configuration.h index 2bb8768..7e62ad4 100644 --- a/src/anbox/container/configuration.h +++ b/src/anbox/container/configuration.h @@ -18,15 +18,15 @@ #ifndef ANBOX_CONTAINER_CONFIGURATION_H_ #define ANBOX_CONTAINER_CONFIGURATION_H_ -#include #include +#include namespace anbox { namespace container { struct Configuration { - std::map bind_mounts; + std::map bind_mounts; }; -} // namespace container -} // namespace anbox +} // namespace container +} // namespace anbox #endif diff --git a/src/anbox/container/container.cpp b/src/anbox/container/container.cpp index b25f23f..fa62829 100644 --- a/src/anbox/container/container.cpp +++ b/src/anbox/container/container.cpp @@ -19,7 +19,6 @@ namespace anbox { namespace container { -Container::~Container() { -} -} // namespace container -} // namespace anbox +Container::~Container() {} +} // namespace container +} // namespace anbox diff --git a/src/anbox/container/container.h b/src/anbox/container/container.h index 2e1776d..c88c40a 100644 --- a/src/anbox/container/container.h +++ b/src/anbox/container/container.h @@ -20,30 +20,30 @@ #include "anbox/container/configuration.h" -#include #include +#include namespace anbox { namespace container { class Container { -public: - virtual ~Container(); + public: + virtual ~Container(); - enum class State { - inactive, - running, - }; + enum class State { + inactive, + running, + }; - // Start the container in background - virtual void start(const Configuration &configuration) = 0; + // Start the container in background + virtual void start(const Configuration &configuration) = 0; - // Stop a running container - virtual void stop() = 0; + // Stop a running container + virtual void stop() = 0; - // Get the current container state - virtual State state() = 0; + // Get the current container state + virtual State state() = 0; }; -} // namespace container -} // namespace anbox +} // namespace container +} // namespace anbox #endif diff --git a/src/anbox/container/lxc_container.cpp b/src/anbox/container/lxc_container.cpp index bde4889..ab721bd 100644 --- a/src/anbox/container/lxc_container.cpp +++ b/src/anbox/container/lxc_container.cpp @@ -16,158 +16,168 @@ */ #include "anbox/container/lxc_container.h" -#include "anbox/utils.h" #include "anbox/config.h" #include "anbox/logger.h" +#include "anbox/utils.h" -#include #include +#include -#include #include +#include -#include #include -#include #include +#include +#include namespace fs = boost::filesystem; namespace anbox { namespace container { -LxcContainer::LxcContainer() : - state_(State::inactive), - container_(nullptr) { - utils::ensure_paths({ - config::container_config_path(), - config::log_path(), - }); +LxcContainer::LxcContainer() : state_(State::inactive), container_(nullptr) { + utils::ensure_paths({ + config::container_config_path(), config::log_path(), + }); } LxcContainer::~LxcContainer() { - DEBUG(""); + DEBUG(""); - stop(); + stop(); - if (container_) - lxc_container_put(container_); + if (container_) lxc_container_put(container_); } void LxcContainer::start(const Configuration &configuration) { - if (getuid() != 0) - BOOST_THROW_EXCEPTION(std::runtime_error("You have to start the container as root")); + if (getuid() != 0) + BOOST_THROW_EXCEPTION( + std::runtime_error("You have to start the container as root")); - if (container_ && container_->is_running(container_)) { - BOOST_THROW_EXCEPTION(std::runtime_error("Container already started, stopping it now")); - container_->stop(container_); - } + if (container_ && container_->is_running(container_)) { + BOOST_THROW_EXCEPTION( + std::runtime_error("Container already started, stopping it now")); + container_->stop(container_); + } - if (!container_) { - DEBUG("Containers are stored in %s", config::container_config_path()); + if (!container_) { + DEBUG("Containers are stored in %s", config::container_config_path()); - // Remove container config to be be able to rewrite it - ::unlink(utils::string_format("%s/default/config", config::container_config_path()).c_str()); + // Remove container config to be be able to rewrite it + ::unlink(utils::string_format("%s/default/config", + config::container_config_path()) + .c_str()); - container_ = lxc_container_new("default", config::container_config_path().c_str()); - if (!container_) - BOOST_THROW_EXCEPTION(std::runtime_error("Failed to create LXC container instance")); + container_ = + lxc_container_new("default", config::container_config_path().c_str()); + if (!container_) + BOOST_THROW_EXCEPTION( + std::runtime_error("Failed to create LXC container instance")); - // If container is still running (for example after a crash) we stop it here to ensure - // its configuration is synchronized. - if (container_->is_running(container_)) - container_->stop(container_); - } + // If container is still running (for example after a crash) we stop it here + // to ensure + // its configuration is synchronized. + if (container_->is_running(container_)) container_->stop(container_); + } - // We drop all not needed capabilities - set_config_item("lxc.cap.drop", "mac_admin mac_override sys_time sys_module sys_rawio"); + // We drop all not needed capabilities + set_config_item("lxc.cap.drop", + "mac_admin mac_override sys_time sys_module sys_rawio"); - // We can mount proc/sys as rw here as we will run the container unprivileged in the end - set_config_item("lxc.mount.auto", "proc:mixed sys:mixed cgroup:mixed"); + // We can mount proc/sys as rw here as we will run the container unprivileged + // in the end + set_config_item("lxc.mount.auto", "proc:mixed sys:mixed cgroup:mixed"); - set_config_item("lxc.autodev", "1"); - set_config_item("lxc.pts", "1024"); - set_config_item("lxc.tty", "0"); - set_config_item("lxc.utsname", "anbox"); + set_config_item("lxc.autodev", "1"); + set_config_item("lxc.pts", "1024"); + set_config_item("lxc.tty", "0"); + set_config_item("lxc.utsname", "anbox"); - set_config_item("lxc.group.devices.deny",""); - set_config_item("lxc.group.devices.allow",""); + set_config_item("lxc.group.devices.deny", ""); + set_config_item("lxc.group.devices.allow", ""); - // We can't move bind-mounts, so don't use /dev/lxc/ - set_config_item("lxc.devttydir", ""); + // We can't move bind-mounts, so don't use /dev/lxc/ + set_config_item("lxc.devttydir", ""); - set_config_item("lxc.environment", "PATH=/system/bin:/system/sbin:/system/xbin"); + set_config_item("lxc.environment", + "PATH=/system/bin:/system/sbin:/system/xbin"); - set_config_item("lxc.init_cmd", "/anbox-init.sh"); - set_config_item("lxc.rootfs.backend", "dir"); + set_config_item("lxc.init_cmd", "/anbox-init.sh"); + set_config_item("lxc.rootfs.backend", "dir"); - DEBUG("Using rootfs path %s", config::rootfs_path()); - set_config_item("lxc.rootfs", config::rootfs_path()); + DEBUG("Using rootfs path %s", config::rootfs_path()); + set_config_item("lxc.rootfs", config::rootfs_path()); - set_config_item("lxc.loglevel", "0"); - set_config_item("lxc.logfile", utils::string_format("%s/container.log", config::log_path()).c_str()); + set_config_item("lxc.loglevel", "0"); + set_config_item( + "lxc.logfile", + utils::string_format("%s/container.log", config::log_path()).c_str()); - set_config_item("lxc.network.type", "veth"); - set_config_item("lxc.network.flags", "up"); - set_config_item("lxc.network.link", "anboxbr0"); + set_config_item("lxc.network.type", "veth"); + set_config_item("lxc.network.flags", "up"); + set_config_item("lxc.network.link", "anboxbr0"); #if 0 // Android uses namespaces as well so we have to allow nested namespaces for LXC // which are otherwise forbidden by AppArmor. set_config_item("lxc.aa_profile", "lxc-container-default-with-nesting"); #else - // FIXME: when using the nested profile we still get various denials from things - // Android tries to do but isn't allowed to. We need to look into those and see - // how we can switch back to a confined way of running the container. - set_config_item("lxc.aa_profile", "unconfined"); + // FIXME: when using the nested profile we still get various denials from + // things + // Android tries to do but isn't allowed to. We need to look into those and + // see + // how we can switch back to a confined way of running the container. + set_config_item("lxc.aa_profile", "unconfined"); #endif - for (const auto &bind_mount : configuration.bind_mounts) { - std::string create_type = "file"; + for (const auto &bind_mount : configuration.bind_mounts) { + std::string create_type = "file"; - if (fs::is_directory(bind_mount.first)) - create_type = "dir"; + if (fs::is_directory(bind_mount.first)) create_type = "dir"; - auto target_path = bind_mount.second; - // LXC wants target paths relative to the container rootfs so - // prividing an absolute path doesn't work. - if (utils::string_starts_with(target_path, "/")) - target_path.erase(0, 1); + auto target_path = bind_mount.second; + // LXC wants target paths relative to the container rootfs so + // prividing an absolute path doesn't work. + if (utils::string_starts_with(target_path, "/")) target_path.erase(0, 1); - set_config_item("lxc.mount.entry", - utils::string_format("%s %s none bind,create=%s,optional 0 0", - bind_mount.first, target_path, create_type)); - } + set_config_item( + "lxc.mount.entry", + utils::string_format("%s %s none bind,create=%s,optional 0 0", + bind_mount.first, target_path, create_type)); + } - if (!container_->save_config(container_, nullptr)) - BOOST_THROW_EXCEPTION(std::runtime_error("Failed to save container configuration")); + if (!container_->save_config(container_, nullptr)) + BOOST_THROW_EXCEPTION( + std::runtime_error("Failed to save container configuration")); - if (not container_->start(container_, 0, nullptr)) - BOOST_THROW_EXCEPTION(std::runtime_error("Failed to start container")); + if (not container_->start(container_, 0, nullptr)) + BOOST_THROW_EXCEPTION(std::runtime_error("Failed to start container")); - state_ = Container::State::running; + state_ = Container::State::running; - DEBUG("Container successfully started"); + DEBUG("Container successfully started"); } void LxcContainer::stop() { - if (not container_ || not container_->is_running(container_)) - BOOST_THROW_EXCEPTION(std::runtime_error("Cannot stop container as it is not running")); + if (not container_ || not container_->is_running(container_)) + BOOST_THROW_EXCEPTION( + std::runtime_error("Cannot stop container as it is not running")); - if (not container_->stop(container_)) - BOOST_THROW_EXCEPTION(std::runtime_error("Failed to stop container")); + if (not container_->stop(container_)) + BOOST_THROW_EXCEPTION(std::runtime_error("Failed to stop container")); - state_ = Container::State::inactive; + state_ = Container::State::inactive; - DEBUG("Container successfully stopped"); + DEBUG("Container successfully stopped"); } -void LxcContainer::set_config_item(const std::string &key, const std::string &value) { - if (!container_->set_config_item(container_, key.c_str(), value.c_str())) - BOOST_THROW_EXCEPTION(std::runtime_error("Failed to configure LXC container")); +void LxcContainer::set_config_item(const std::string &key, + const std::string &value) { + if (!container_->set_config_item(container_, key.c_str(), value.c_str())) + BOOST_THROW_EXCEPTION( + std::runtime_error("Failed to configure LXC container")); } -Container::State LxcContainer::state() { - return state_; -} -} // namespace container -} // namespace anbox +Container::State LxcContainer::state() { return state_; } +} // namespace container +} // namespace anbox diff --git a/src/anbox/container/lxc_container.h b/src/anbox/container/lxc_container.h index c412b55..4efdd3c 100644 --- a/src/anbox/container/lxc_container.h +++ b/src/anbox/container/lxc_container.h @@ -27,21 +27,21 @@ namespace anbox { namespace container { class LxcContainer : public Container { -public: - LxcContainer(); - ~LxcContainer(); + public: + LxcContainer(); + ~LxcContainer(); - void start(const Configuration &configuration) override; - void stop() override; - State state() override; + void start(const Configuration &configuration) override; + void stop() override; + State state() override; -private: - void set_config_item(const std::string &key, const std::string &value); + private: + void set_config_item(const std::string &key, const std::string &value); - State state_; - lxc_container *container_; + State state_; + lxc_container *container_; }; -} // namespace container -} // namespace anbox +} // namespace container +} // namespace anbox #endif diff --git a/src/anbox/container/management_api_message_processor.cpp b/src/anbox/container/management_api_message_processor.cpp index 1573fcf..51254cb 100644 --- a/src/anbox/container/management_api_message_processor.cpp +++ b/src/anbox/container/management_api_message_processor.cpp @@ -24,22 +24,22 @@ namespace anbox { namespace container { -ManagementApiMessageProcessor::ManagementApiMessageProcessor(const std::shared_ptr &sender, - const std::shared_ptr &pending_calls, - const std::shared_ptr &server) : - rpc::MessageProcessor(sender, pending_calls), - server_(server) { +ManagementApiMessageProcessor::ManagementApiMessageProcessor( + const std::shared_ptr &sender, + const std::shared_ptr &pending_calls, + const std::shared_ptr &server) + : rpc::MessageProcessor(sender, pending_calls), server_(server) {} + +ManagementApiMessageProcessor::~ManagementApiMessageProcessor() {} + +void ManagementApiMessageProcessor::dispatch( + rpc::Invocation const &invocation) { + if (invocation.method_name() == "start_container") + invoke(this, server_.get(), &ManagementApiSkeleton::start_container, + invocation); } -ManagementApiMessageProcessor::~ManagementApiMessageProcessor() { -} - -void ManagementApiMessageProcessor::dispatch(rpc::Invocation const& invocation) { - if (invocation.method_name() == "start_container") - invoke(this, server_.get(), &ManagementApiSkeleton::start_container, invocation); -} - -void ManagementApiMessageProcessor::process_event_sequence(const std::string&) { -} -} // namespace container -} // namespace anbox +void ManagementApiMessageProcessor::process_event_sequence( + const std::string &) {} +} // namespace container +} // namespace anbox diff --git a/src/anbox/container/management_api_message_processor.h b/src/anbox/container/management_api_message_processor.h index 9b5e851..9fe1810 100644 --- a/src/anbox/container/management_api_message_processor.h +++ b/src/anbox/container/management_api_message_processor.h @@ -24,19 +24,20 @@ namespace anbox { namespace container { class ManagementApiSkeleton; class ManagementApiMessageProcessor : public rpc::MessageProcessor { -public: - ManagementApiMessageProcessor(const std::shared_ptr &sender, - const std::shared_ptr &pending_calls, - const std::shared_ptr &server); - ~ManagementApiMessageProcessor(); + public: + ManagementApiMessageProcessor( + const std::shared_ptr &sender, + const std::shared_ptr &pending_calls, + const std::shared_ptr &server); + ~ManagementApiMessageProcessor(); - void dispatch(rpc::Invocation const& invocation) override; - void process_event_sequence(const std::string &event) override; + void dispatch(rpc::Invocation const &invocation) override; + void process_event_sequence(const std::string &event) override; -private: - std::shared_ptr server_; + private: + std::shared_ptr server_; }; -} // namespace anbox -} // namespace network +} // namespace anbox +} // namespace network #endif diff --git a/src/anbox/container/management_api_skeleton.cpp b/src/anbox/container/management_api_skeleton.cpp index a11067e..f231a44 100644 --- a/src/anbox/container/management_api_skeleton.cpp +++ b/src/anbox/container/management_api_skeleton.cpp @@ -16,54 +16,52 @@ */ #include "anbox/container/management_api_skeleton.h" -#include "anbox/container/container.h" #include "anbox/container/configuration.h" +#include "anbox/container/container.h" #include "anbox/defer_action.h" -#include "anbox/utils.h" #include "anbox/logger.h" +#include "anbox/utils.h" -#include "anbox_rpc.pb.h" #include "anbox_container.pb.h" +#include "anbox_rpc.pb.h" namespace anbox { namespace container { -ManagementApiSkeleton::ManagementApiSkeleton(const std::shared_ptr &pending_calls, - const std::shared_ptr &container) : - pending_calls_(pending_calls), - container_(container) { -} +ManagementApiSkeleton::ManagementApiSkeleton( + const std::shared_ptr &pending_calls, + const std::shared_ptr &container) + : pending_calls_(pending_calls), container_(container) {} -ManagementApiSkeleton::~ManagementApiSkeleton() { -} - -void ManagementApiSkeleton::start_container(anbox::protobuf::container::StartContainer const *request, - anbox::protobuf::rpc::Void *response, - google::protobuf::Closure *done) { - - if (container_->state() == Container::State::running) { - response->set_error("Container is already running"); - done->Run(); - return; - } - - Configuration container_configuration; - - const auto configuration = request->configuration(); - for (int n = 0; n < configuration.bind_mounts_size(); n++) { - const auto bind_mount = configuration.bind_mounts(n); - container_configuration.bind_mounts.insert({ bind_mount.source(), bind_mount.target() }); - } - - try { - container_->start(container_configuration); - } - catch (std::exception &err) { - response->set_error(utils::string_format("Failed to start container: %s", err.what())); - } - - DEBUG(""); +ManagementApiSkeleton::~ManagementApiSkeleton() {} +void ManagementApiSkeleton::start_container( + anbox::protobuf::container::StartContainer const *request, + anbox::protobuf::rpc::Void *response, google::protobuf::Closure *done) { + if (container_->state() == Container::State::running) { + response->set_error("Container is already running"); done->Run(); + return; + } + + Configuration container_configuration; + + const auto configuration = request->configuration(); + for (int n = 0; n < configuration.bind_mounts_size(); n++) { + const auto bind_mount = configuration.bind_mounts(n); + container_configuration.bind_mounts.insert( + {bind_mount.source(), bind_mount.target()}); + } + + try { + container_->start(container_configuration); + } catch (std::exception &err) { + response->set_error( + utils::string_format("Failed to start container: %s", err.what())); + } + + DEBUG(""); + + done->Run(); } -} // namespace container -} // namespace anbox +} // namespace container +} // namespace anbox diff --git a/src/anbox/container/management_api_skeleton.h b/src/anbox/container/management_api_skeleton.h index 3007ee7..6296151 100644 --- a/src/anbox/container/management_api_skeleton.h +++ b/src/anbox/container/management_api_skeleton.h @@ -23,38 +23,39 @@ namespace google { namespace protobuf { class Closure; -} // namespace protobuf -} // namespace google +} // namespace protobuf +} // namespace google namespace anbox { namespace protobuf { namespace rpc { class Void; -} // namespace rpc +} // namespace rpc namespace container { class StartContainer; -} // namespace container -} // namespace protobuf +} // namespace container +} // namespace protobuf namespace rpc { class PendingCallCache; -} // namespace rpc +} // namespace rpc namespace container { class Container; class ManagementApiSkeleton { -public: - ManagementApiSkeleton(const std::shared_ptr &pending_calls, - const std::shared_ptr &container); - ~ManagementApiSkeleton(); + public: + ManagementApiSkeleton( + const std::shared_ptr &pending_calls, + const std::shared_ptr &container); + ~ManagementApiSkeleton(); - void start_container(anbox::protobuf::container::StartContainer const *request, - anbox::protobuf::rpc::Void *response, - google::protobuf::Closure *done); + void start_container( + anbox::protobuf::container::StartContainer const *request, + anbox::protobuf::rpc::Void *response, google::protobuf::Closure *done); -private: - std::shared_ptr pending_calls_; - std::shared_ptr container_; + private: + std::shared_ptr pending_calls_; + std::shared_ptr container_; }; -} // namespace container -} // namespace anbox +} // namespace container +} // namespace anbox #endif diff --git a/src/anbox/container/management_api_stub.cpp b/src/anbox/container/management_api_stub.cpp index 9a8254b..87ffd50 100644 --- a/src/anbox/container/management_api_stub.cpp +++ b/src/anbox/container/management_api_stub.cpp @@ -16,55 +16,54 @@ */ #include "anbox/container/management_api_stub.h" -#include "anbox/rpc/channel.h" #include "anbox/logger.h" +#include "anbox/rpc/channel.h" -#include "anbox_rpc.pb.h" #include "anbox_container.pb.h" +#include "anbox_rpc.pb.h" namespace anbox { namespace container { -ManagementApiStub::ManagementApiStub(const std::shared_ptr &channel) : - channel_(channel) { -} +ManagementApiStub::ManagementApiStub( + const std::shared_ptr &channel) + : channel_(channel) {} -ManagementApiStub::~ManagementApiStub() { -} +ManagementApiStub::~ManagementApiStub() {} void ManagementApiStub::start_container(const Configuration &configuration) { - auto c = std::make_shared>(); + auto c = std::make_shared>(); - protobuf::container::StartContainer message; - auto message_configuration = new protobuf::container::Configuration; + protobuf::container::StartContainer message; + auto message_configuration = new protobuf::container::Configuration; - for (const auto item : configuration.bind_mounts) { - auto bind_mount_message = message_configuration->add_bind_mounts(); - bind_mount_message->set_source(item.first); - bind_mount_message->set_target(item.second); - } + for (const auto item : configuration.bind_mounts) { + auto bind_mount_message = message_configuration->add_bind_mounts(); + bind_mount_message->set_source(item.first); + bind_mount_message->set_target(item.second); + } - message.set_allocated_configuration(message_configuration); + message.set_allocated_configuration(message_configuration); - { - std::lock_guard lock(mutex_); - start_wait_handle_.expect_result(); - } + { + std::lock_guard lock(mutex_); + start_wait_handle_.expect_result(); + } - channel_->call_method("start_container", - &message, - c->response.get(), - google::protobuf::NewCallback(this, &ManagementApiStub::container_started, c.get())); + channel_->call_method( + "start_container", &message, c->response.get(), + google::protobuf::NewCallback(this, &ManagementApiStub::container_started, + c.get())); - start_wait_handle_.wait_for_all(); + start_wait_handle_.wait_for_all(); - if (c->response->has_error()) - throw std::runtime_error(c->response->error()); + if (c->response->has_error()) throw std::runtime_error(c->response->error()); } -void ManagementApiStub::container_started(Request *request) { - (void) request; - DEBUG(""); - start_wait_handle_.result_received(); +void ManagementApiStub::container_started( + Request *request) { + (void)request; + DEBUG(""); + start_wait_handle_.result_received(); } -} // namespace container -} // namespace anbox +} // namespace container +} // namespace anbox diff --git a/src/anbox/container/management_api_stub.h b/src/anbox/container/management_api_stub.h index 3577b73..ac7fd6c 100644 --- a/src/anbox/container/management_api_stub.h +++ b/src/anbox/container/management_api_stub.h @@ -18,9 +18,9 @@ #ifndef ANBOX_CONTAINER_MANAGEMENT_API_STUB_H_ #define ANBOX_CONTAINER_MANAGEMENT_API_STUB_H_ -#include "anbox/do_not_copy_or_move.h" -#include "anbox/container/configuration.h" #include "anbox/common/wait_handle.h" +#include "anbox/container/configuration.h" +#include "anbox/do_not_copy_or_move.h" #include @@ -28,34 +28,34 @@ namespace anbox { namespace protobuf { namespace rpc { class Void; -} // namespace rpc -} // namespace protobuf +} // namespace rpc +} // namespace protobuf namespace rpc { class Channel; -} // namespace rpc +} // namespace rpc namespace container { class ManagementApiStub : public DoNotCopyOrMove { -public: - ManagementApiStub(const std::shared_ptr &channel); - ~ManagementApiStub(); + public: + ManagementApiStub(const std::shared_ptr &channel); + ~ManagementApiStub(); - void start_container(const Configuration &configuration); + void start_container(const Configuration &configuration); -private: - template - struct Request { - Request() : response(std::make_shared()), success(true) { } - std::shared_ptr response; - bool success; - }; + private: + template + struct Request { + Request() : response(std::make_shared()), success(true) {} + std::shared_ptr response; + bool success; + }; - void container_started(Request *request); + void container_started(Request *request); - mutable std::mutex mutex_; - std::shared_ptr channel_; - common::WaitHandle start_wait_handle_; + mutable std::mutex mutex_; + std::shared_ptr channel_; + common::WaitHandle start_wait_handle_; }; -} // namespace container -} // namespace anbox +} // namespace container +} // namespace anbox #endif diff --git a/src/anbox/container/service.cpp b/src/anbox/container/service.cpp index f606e09..8df6b52 100644 --- a/src/anbox/container/service.cpp +++ b/src/anbox/container/service.cpp @@ -16,76 +16,77 @@ */ #include "anbox/container/service.h" +#include "anbox/config.h" +#include "anbox/container/lxc_container.h" +#include "anbox/container/management_api_message_processor.h" +#include "anbox/container/management_api_skeleton.h" +#include "anbox/logger.h" #include "anbox/network/delegate_connection_creator.h" #include "anbox/network/delegate_message_processor.h" #include "anbox/network/local_socket_messenger.h" #include "anbox/qemu/null_message_processor.h" -#include "anbox/rpc/pending_call_cache.h" #include "anbox/rpc/channel.h" -#include "anbox/container/lxc_container.h" -#include "anbox/container/management_api_message_processor.h" -#include "anbox/container/management_api_skeleton.h" -#include "anbox/config.h" -#include "anbox/logger.h" +#include "anbox/rpc/pending_call_cache.h" namespace anbox { namespace container { std::shared_ptr Service::create(const std::shared_ptr &rt) { - auto sp = std::make_shared(rt); + auto sp = std::make_shared(rt); - auto delegate_connector = std::make_shared>( - [sp](std::shared_ptr const &socket) { - sp->new_client(socket); - }); + auto delegate_connector = std::make_shared< + network::DelegateConnectionCreator>( + [sp](std::shared_ptr const + &socket) { sp->new_client(socket); }); - sp->connector_ = std::make_shared( - config::container_socket_path(), rt, delegate_connector); + sp->connector_ = std::make_shared( + config::container_socket_path(), rt, delegate_connector); - // Make sure others can connect to our socket - ::chmod(config::container_socket_path().c_str(), S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); + // Make sure others can connect to our socket + ::chmod(config::container_socket_path().c_str(), + S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); - DEBUG("Everything setup. Waiting for incoming connections."); + DEBUG("Everything setup. Waiting for incoming connections."); - return sp; + return sp; } -Service::Service(const std::shared_ptr &rt) : - dispatcher_(anbox::common::create_dispatcher_for_runtime(rt)), - next_connection_id_(0), - connections_(std::make_shared>()) { +Service::Service(const std::shared_ptr &rt) + : dispatcher_(anbox::common::create_dispatcher_for_runtime(rt)), + next_connection_id_(0), + connections_( + std::make_shared>()) { } -Service::~Service() { - DEBUG(""); +Service::~Service() { DEBUG(""); } + +int Service::next_id() { return next_connection_id_++; } + +void Service::new_client( + std::shared_ptr const + &socket) { + if (connections_->size() >= 1) { + socket->close(); + return; + } + + auto const messenger = + std::make_shared(socket); + + DEBUG("Got connection from pid %d", messenger->creds().pid()); + + auto pending_calls = std::make_shared(); + auto rpc_channel = std::make_shared(pending_calls, messenger); + auto server = std::make_shared( + pending_calls, std::make_shared()); + auto processor = std::make_shared( + messenger, pending_calls, server); + + auto const &connection = std::make_shared( + messenger, messenger, next_id(), connections_, processor); + connection->set_name("container-service"); + + connections_->add(connection); + connection->read_next_message(); } - -int Service::next_id() { - return next_connection_id_++; -} - -void Service::new_client(std::shared_ptr const &socket) { - if (connections_->size() >= 1) { - socket->close(); - return; - } - - auto const messenger = std::make_shared(socket); - - DEBUG("Got connection from pid %d", messenger->creds().pid()); - - auto pending_calls = std::make_shared(); - auto rpc_channel = std::make_shared(pending_calls, messenger); - auto server = std::make_shared( - pending_calls, std::make_shared()); - auto processor = std::make_shared( - messenger, pending_calls, server); - - auto const& connection = std::make_shared( - messenger, messenger, next_id(), connections_, processor); - connection->set_name("container-service"); - - connections_->add(connection); - connection->read_next_message(); -} -} // namespace container -} // namespace anbox +} // namespace container +} // namespace anbox diff --git a/src/anbox/container/service.h b/src/anbox/container/service.h index f76b517..7aaf006 100644 --- a/src/anbox/container/service.h +++ b/src/anbox/container/service.h @@ -18,34 +18,35 @@ #ifndef ANBOX_CONTAINER_SERVICE_H_ #define ANBOX_CONTAINER_SERVICE_H_ -#include "anbox/network/published_socket_connector.h" -#include "anbox/network/connections.h" -#include "anbox/network/socket_connection.h" -#include "anbox/network/credentials.h" -#include "anbox/container/container.h" #include "anbox/common/dispatcher.h" +#include "anbox/container/container.h" +#include "anbox/network/connections.h" +#include "anbox/network/credentials.h" +#include "anbox/network/published_socket_connector.h" +#include "anbox/network/socket_connection.h" #include "anbox/runtime.h" namespace anbox { namespace container { class Service : public std::enable_shared_from_this { -public: - static std::shared_ptr create(const std::shared_ptr &rt); + public: + static std::shared_ptr create(const std::shared_ptr &rt); - Service(const std::shared_ptr &rt); - ~Service(); + Service(const std::shared_ptr &rt); + ~Service(); -private: - int next_id(); - void new_client(std::shared_ptr const &socket); + private: + int next_id(); + void new_client(std::shared_ptr< + boost::asio::local::stream_protocol::socket> const &socket); - std::shared_ptr dispatcher_; - std::shared_ptr connector_; - std::atomic next_connection_id_; - std::shared_ptr> connections_; - std::shared_ptr backend_; + std::shared_ptr dispatcher_; + std::shared_ptr connector_; + std::atomic next_connection_id_; + std::shared_ptr> connections_; + std::shared_ptr backend_; }; -} // namespace container -} // namespace anbox +} // namespace container +} // namespace anbox #endif diff --git a/src/anbox/daemon.cpp b/src/anbox/daemon.cpp index 5953ab3..69fb079 100644 --- a/src/anbox/daemon.cpp +++ b/src/anbox/daemon.cpp @@ -15,38 +15,36 @@ * */ -#include #include +#include -#include "anbox/logger.h" -#include "anbox/daemon.h" #include "anbox/config.h" +#include "anbox/daemon.h" +#include "anbox/logger.h" -#include "anbox/cmds/version.h" -#include "anbox/cmds/run.h" -#include "anbox/cmds/launch.h" #include "anbox/cmds/container_manager.h" +#include "anbox/cmds/launch.h" +#include "anbox/cmds/run.h" +#include "anbox/cmds/version.h" #include namespace fs = boost::filesystem; namespace anbox { -Daemon::Daemon() : - cmd{cli::Name{"anbox"}, cli::Usage{"anbox"}, cli::Description{"The Android in a Box runtime"}} { - - cmd.command(std::make_shared()) - .command(std::make_shared()) - .command(std::make_shared()) - .command(std::make_shared()); +Daemon::Daemon() + : cmd{cli::Name{"anbox"}, cli::Usage{"anbox"}, + cli::Description{"The Android in a Box runtime"}} { + cmd.command(std::make_shared()) + .command(std::make_shared()) + .command(std::make_shared()) + .command(std::make_shared()); } -int Daemon::Run(const std::vector &arguments) -try { - return cmd.run({std::cin, std::cout, arguments}); +int Daemon::Run(const std::vector &arguments) try { + return cmd.run({std::cin, std::cout, arguments}); +} catch (std::exception &err) { + ERROR("%s", err.what()); + return EXIT_FAILURE; } -catch(std::exception &err) { - ERROR("%s", err.what()); - return EXIT_FAILURE; -} -} // namespace anbox +} // namespace anbox diff --git a/src/anbox/daemon.h b/src/anbox/daemon.h index cba8ca2..8c2e74a 100644 --- a/src/anbox/daemon.h +++ b/src/anbox/daemon.h @@ -18,22 +18,22 @@ #ifndef ANBOX_DAEMON_H_ #define ANBOX_DAEMON_H_ -#include #include +#include -#include "anbox/do_not_copy_or_move.h" #include "anbox/cli.h" +#include "anbox/do_not_copy_or_move.h" namespace anbox { class Daemon : public DoNotCopyOrMove { -public: - Daemon(); + public: + Daemon(); - int Run(const std::vector &arguments); + int Run(const std::vector &arguments); -private: - cli::CommandWithSubcommands cmd; + private: + cli::CommandWithSubcommands cmd; }; -} // namespace anbox +} // namespace anbox #endif diff --git a/src/anbox/dbus/interface.h b/src/anbox/dbus/interface.h index bc9a202..cbd9566 100644 --- a/src/anbox/dbus/interface.h +++ b/src/anbox/dbus/interface.h @@ -20,42 +20,45 @@ #include -#include #include +#include namespace anbox { namespace dbus { namespace interface { struct Service { - static inline std::string name() { return "org.anbox"; } - static inline std::string path() { return "/"; } + static inline std::string name() { return "org.anbox"; } + static inline std::string path() { return "/"; } }; struct ApplicationManager { - static inline std::string name() { return "org.anbox.ApplicationManager"; } - struct Methods { - struct Launch { - static inline std::string name() { return "Launch"; } - typedef anbox::dbus::interface::ApplicationManager Interface; - typedef void ResultType; - static inline std::chrono::milliseconds default_timeout() { return std::chrono::seconds{1}; } - }; + static inline std::string name() { return "org.anbox.ApplicationManager"; } + struct Methods { + struct Launch { + static inline std::string name() { return "Launch"; } + typedef anbox::dbus::interface::ApplicationManager Interface; + typedef void ResultType; + static inline std::chrono::milliseconds default_timeout() { + return std::chrono::seconds{1}; + } }; + }; }; -} // namespace interface -} // namespace dbus -} // namespace anbox +} // namespace interface +} // namespace dbus +} // namespace anbox namespace core { namespace dbus { namespace traits { -template<> struct Service { - static inline const std::string& interface_name() { - static const std::string s{"org.anbox.ApplicationManager"}; - return s; - } +template <> +struct Service { + static inline const std::string& interface_name() { + static const std::string s{"org.anbox.ApplicationManager"}; + return s; + } }; -} // namespace traits -} // namespace dbus -} // namespace core +} // namespace traits +} // namespace dbus +} // namespace core #endif diff --git a/src/anbox/dbus/skeleton/application_manager.cpp b/src/anbox/dbus/skeleton/application_manager.cpp index 6db626b..2b5e3bc 100644 --- a/src/anbox/dbus/skeleton/application_manager.cpp +++ b/src/anbox/dbus/skeleton/application_manager.cpp @@ -16,22 +16,20 @@ */ #include "anbox/dbus/skeleton/application_manager.h" -#include "anbox/dbus/interface.h" #include "anbox/android/intent.h" +#include "anbox/dbus/interface.h" #include "anbox/logger.h" namespace anbox { namespace dbus { namespace skeleton { -ApplicationManager::ApplicationManager(const core::dbus::Bus::Ptr &bus, - const core::dbus::Object::Ptr& object, - const std::shared_ptr &impl) : - bus_(bus), - object_(object), - impl_(impl) { - - object_->install_method_handler( - [this](const core::dbus::Message::Ptr &msg) { +ApplicationManager::ApplicationManager( + const core::dbus::Bus::Ptr &bus, const core::dbus::Object::Ptr &object, + const std::shared_ptr &impl) + : bus_(bus), object_(object), impl_(impl) { + object_->install_method_handler< + anbox::dbus::interface::ApplicationManager::Methods::Launch>( + [this](const core::dbus::Message::Ptr &msg) { auto reader = msg->reader(); android::Intent intent; @@ -45,25 +43,22 @@ ApplicationManager::ApplicationManager(const core::dbus::Bus::Ptr &bus, core::dbus::Message::Ptr reply; try { - launch(intent); - reply = core::dbus::Message::make_method_return(msg); - } - catch (std::exception const &err) { - reply = core::dbus::Message::make_error(msg, - "org.anbox.Error.Failed", - err.what()); + launch(intent); + reply = core::dbus::Message::make_method_return(msg); + } catch (std::exception const &err) { + reply = core::dbus::Message::make_error(msg, "org.anbox.Error.Failed", + err.what()); } bus_->send(reply); - }); + }); } -ApplicationManager::~ApplicationManager() { -} +ApplicationManager::~ApplicationManager() {} void ApplicationManager::launch(const android::Intent &intent) { - impl_->launch(intent); + impl_->launch(intent); } -} // namespace skeleton -} // namespace dbus -} // namespace anbox +} // namespace skeleton +} // namespace dbus +} // namespace anbox diff --git a/src/anbox/dbus/skeleton/application_manager.h b/src/anbox/dbus/skeleton/application_manager.h index d894e1f..af45ddd 100644 --- a/src/anbox/dbus/skeleton/application_manager.h +++ b/src/anbox/dbus/skeleton/application_manager.h @@ -28,22 +28,22 @@ namespace anbox { namespace dbus { namespace skeleton { class ApplicationManager : public anbox::ApplicationManager { -public: - ApplicationManager(const core::dbus::Bus::Ptr &bus, - const core::dbus::Object::Ptr& object, - const std::shared_ptr &impl); - ~ApplicationManager(); + public: + ApplicationManager(const core::dbus::Bus::Ptr &bus, + const core::dbus::Object::Ptr &object, + const std::shared_ptr &impl); + ~ApplicationManager(); - void launch(const android::Intent &intent) override; + void launch(const android::Intent &intent) override; -private: - core::dbus::Bus::Ptr bus_; - core::dbus::Service::Ptr service_; - core::dbus::Object::Ptr object_; - std::shared_ptr impl_; + private: + core::dbus::Bus::Ptr bus_; + core::dbus::Service::Ptr service_; + core::dbus::Object::Ptr object_; + std::shared_ptr impl_; }; -} // namespace skeleton -} // namespace dbus -} // namespace anbox +} // namespace skeleton +} // namespace dbus +} // namespace anbox #endif diff --git a/src/anbox/dbus/skeleton/service.cpp b/src/anbox/dbus/skeleton/service.cpp index 6abca53..c205896 100644 --- a/src/anbox/dbus/skeleton/service.cpp +++ b/src/anbox/dbus/skeleton/service.cpp @@ -16,31 +16,33 @@ */ #include "anbox/dbus/skeleton/service.h" -#include "anbox/dbus/skeleton/application_manager.h" #include "anbox/dbus/interface.h" +#include "anbox/dbus/skeleton/application_manager.h" namespace anbox { namespace dbus { namespace skeleton { -std::shared_ptr Service::create_for_bus(const core::dbus::Bus::Ptr &bus, - const std::shared_ptr &application_manager) { - auto service = core::dbus::Service::add_service(bus, anbox::dbus::interface::Service::name()); - auto object = service->add_object_for_path(anbox::dbus::interface::Service::path()); - return std::make_shared(bus, service, object, application_manager); +std::shared_ptr Service::create_for_bus( + const core::dbus::Bus::Ptr &bus, + const std::shared_ptr &application_manager) { + auto service = core::dbus::Service::add_service( + bus, anbox::dbus::interface::Service::name()); + auto object = + service->add_object_for_path(anbox::dbus::interface::Service::path()); + return std::make_shared(bus, service, object, application_manager); } -Service::Service(const core::dbus::Bus::Ptr &bus, - const core::dbus::Service::Ptr& service, - const core::dbus::Object::Ptr& object, - const std::shared_ptr &application_manager) : - bus_(bus), - service_(service), - object_(object), - application_manager_(std::make_shared(bus_, object_, application_manager)) { -} +Service::Service( + const core::dbus::Bus::Ptr &bus, const core::dbus::Service::Ptr &service, + const core::dbus::Object::Ptr &object, + const std::shared_ptr &application_manager) + : bus_(bus), + service_(service), + object_(object), + application_manager_(std::make_shared( + bus_, object_, application_manager)) {} -Service::~Service() { -} -} // namespace skeleton -} // namespace dbus -} // namespace anbox +Service::~Service() {} +} // namespace skeleton +} // namespace dbus +} // namespace anbox diff --git a/src/anbox/dbus/skeleton/service.h b/src/anbox/dbus/skeleton/service.h index 99e8be6..c169861 100644 --- a/src/anbox/dbus/skeleton/service.h +++ b/src/anbox/dbus/skeleton/service.h @@ -18,8 +18,8 @@ #ifndef ANBOX_DBUS_SKELETON_SERVICE_H_ #define ANBOX_DBUS_SKELETON_SERVICE_H_ -#include "anbox/do_not_copy_or_move.h" #include "anbox/application_manager.h" +#include "anbox/do_not_copy_or_move.h" #include #include @@ -30,24 +30,25 @@ namespace dbus { namespace skeleton { class ApplicationManager; class Service : public DoNotCopyOrMove { -public: - static std::shared_ptr create_for_bus(const core::dbus::Bus::Ptr &bus, - const std::shared_ptr &application_manager); + public: + static std::shared_ptr create_for_bus( + const core::dbus::Bus::Ptr &bus, + const std::shared_ptr &application_manager); - Service(const core::dbus::Bus::Ptr &bus, - const core::dbus::Service::Ptr& service, - const core::dbus::Object::Ptr& object, - const std::shared_ptr &application_manager); - ~Service(); + Service( + const core::dbus::Bus::Ptr &bus, const core::dbus::Service::Ptr &service, + const core::dbus::Object::Ptr &object, + const std::shared_ptr &application_manager); + ~Service(); -private: - core::dbus::Bus::Ptr bus_; - core::dbus::Service::Ptr service_; - core::dbus::Object::Ptr object_; - std::shared_ptr application_manager_; + private: + core::dbus::Bus::Ptr bus_; + core::dbus::Service::Ptr service_; + core::dbus::Object::Ptr object_; + std::shared_ptr application_manager_; }; -} // namespace skeleton -} // namespace dbus -} // namespace anbox +} // namespace skeleton +} // namespace dbus +} // namespace anbox #endif diff --git a/src/anbox/dbus/stub/application_manager.cpp b/src/anbox/dbus/stub/application_manager.cpp index 3388a9d..06c548a 100644 --- a/src/anbox/dbus/stub/application_manager.cpp +++ b/src/anbox/dbus/stub/application_manager.cpp @@ -22,37 +22,31 @@ namespace anbox { namespace dbus { namespace stub { -std::shared_ptr ApplicationManager::create_for_bus(const core::dbus::Bus::Ptr &bus) { - auto service = core::dbus::Service::use_service(bus, anbox::dbus::interface::Service::name()); - auto object = service->add_object_for_path(anbox::dbus::interface::Service::path()); - return std::make_shared(bus, service, object); +std::shared_ptr ApplicationManager::create_for_bus( + const core::dbus::Bus::Ptr &bus) { + auto service = core::dbus::Service::use_service( + bus, anbox::dbus::interface::Service::name()); + auto object = + service->add_object_for_path(anbox::dbus::interface::Service::path()); + return std::make_shared(bus, service, object); } ApplicationManager::ApplicationManager(const core::dbus::Bus::Ptr &bus, - const core::dbus::Service::Ptr& service, - const core::dbus::Object::Ptr& object) : - bus_(bus), - service_(service), - object_(object) { -} + const core::dbus::Service::Ptr &service, + const core::dbus::Object::Ptr &object) + : bus_(bus), service_(service), object_(object) {} -ApplicationManager::~ApplicationManager() { -} +ApplicationManager::~ApplicationManager() {} void ApplicationManager::launch(const android::Intent &intent) { - auto result = object_->invoke_method_synchronously< - anbox::dbus::interface::ApplicationManager::Methods::Launch, - anbox::dbus::interface::ApplicationManager::Methods::Launch::ResultType>( - intent.action, - intent.uri, - intent.type, - intent.flags, - intent.package, - intent.component); + auto result = object_->invoke_method_synchronously< + anbox::dbus::interface::ApplicationManager::Methods::Launch, + anbox::dbus::interface::ApplicationManager::Methods::Launch::ResultType>( + intent.action, intent.uri, intent.type, intent.flags, intent.package, + intent.component); - if (result.is_error()) - throw std::runtime_error(result.error().print()); + if (result.is_error()) throw std::runtime_error(result.error().print()); } -} // namespace skeleton -} // namespace dbus -} // namespace anbox +} // namespace skeleton +} // namespace dbus +} // namespace anbox diff --git a/src/anbox/dbus/stub/application_manager.h b/src/anbox/dbus/stub/application_manager.h index b7ceca8..6042409 100644 --- a/src/anbox/dbus/stub/application_manager.h +++ b/src/anbox/dbus/stub/application_manager.h @@ -28,23 +28,24 @@ namespace anbox { namespace dbus { namespace stub { class ApplicationManager : public anbox::ApplicationManager { -public: - static std::shared_ptr create_for_bus(const core::dbus::Bus::Ptr &bus); + public: + static std::shared_ptr create_for_bus( + const core::dbus::Bus::Ptr &bus); - ApplicationManager(const core::dbus::Bus::Ptr &bus, - const core::dbus::Service::Ptr& service, - const core::dbus::Object::Ptr& object); - ~ApplicationManager(); + ApplicationManager(const core::dbus::Bus::Ptr &bus, + const core::dbus::Service::Ptr &service, + const core::dbus::Object::Ptr &object); + ~ApplicationManager(); - void launch(const android::Intent &intent) override; + void launch(const android::Intent &intent) override; -private: - core::dbus::Bus::Ptr bus_; - core::dbus::Service::Ptr service_; - core::dbus::Object::Ptr object_; + private: + core::dbus::Bus::Ptr bus_; + core::dbus::Service::Ptr service_; + core::dbus::Object::Ptr object_; }; -} // namespace stub -} // namespace dbus -} // namespace anbox +} // namespace stub +} // namespace dbus +} // namespace anbox #endif diff --git a/src/anbox/defer_action.h b/src/anbox/defer_action.h index 905a8ec..b649bb2 100644 --- a/src/anbox/defer_action.h +++ b/src/anbox/defer_action.h @@ -25,20 +25,17 @@ namespace anbox { class DeferAction : public DoNotCopyOrMove { -public: - DeferAction(const std::function action) : - action_(action) { - } + public: + DeferAction(const std::function action) : action_(action) {} - ~DeferAction() { - if (action_) - action_(); - } + ~DeferAction() { + if (action_) action_(); + } -private: - std::function action_; + private: + std::function action_; }; -} // namespace anbox +} // namespace anbox #endif diff --git a/src/anbox/do_not_copy_or_move.h b/src/anbox/do_not_copy_or_move.h index e7a9508..6bb63b5 100644 --- a/src/anbox/do_not_copy_or_move.h +++ b/src/anbox/do_not_copy_or_move.h @@ -20,19 +20,17 @@ namespace anbox { -class DoNotCopyOrMove -{ -public: - DoNotCopyOrMove(const DoNotCopyOrMove&) = delete; - DoNotCopyOrMove(DoNotCopyOrMove&&) = delete; - virtual ~DoNotCopyOrMove() = default; - DoNotCopyOrMove& operator=(const DoNotCopyOrMove&) = delete; - DoNotCopyOrMove& operator=(DoNotCopyOrMove&&) = delete; +class DoNotCopyOrMove { + public: + DoNotCopyOrMove(const DoNotCopyOrMove&) = delete; + DoNotCopyOrMove(DoNotCopyOrMove&&) = delete; + virtual ~DoNotCopyOrMove() = default; + DoNotCopyOrMove& operator=(const DoNotCopyOrMove&) = delete; + DoNotCopyOrMove& operator=(DoNotCopyOrMove&&) = delete; -protected: - DoNotCopyOrMove() = default; + protected: + DoNotCopyOrMove() = default; }; - } #endif diff --git a/src/anbox/graphics/density.h b/src/anbox/graphics/density.h index 5965321..4338dc4 100644 --- a/src/anbox/graphics/density.h +++ b/src/anbox/graphics/density.h @@ -21,19 +21,21 @@ namespace anbox { namespace graphics { /** - * @brief Defines different types of density being used in an Android system. See the - * documentation in frameworks/base/core/java/android/util/DisplayMetrics.java + * @brief Defines different types of density being used in an Android system. + * See the + * documentation in + * frameworks/base/core/java/android/util/DisplayMetrics.java * of the Android source tree which defines the different types. */ enum class DensityType { - low = 120, - medium = 160, - tv = 213, - high = 240, - xhigh = 360, - xxhigh = 480, + low = 120, + medium = 160, + tv = 213, + high = 240, + xhigh = 360, + xxhigh = 480, }; -} // namespace graphics -} // namespace anbox +} // namespace graphics +} // namespace anbox #endif diff --git a/src/anbox/graphics/emugl/ColorBuffer.cpp b/src/anbox/graphics/emugl/ColorBuffer.cpp index 2537503..9231558 100644 --- a/src/anbox/graphics/emugl/ColorBuffer.cpp +++ b/src/anbox/graphics/emugl/ColorBuffer.cpp @@ -30,23 +30,23 @@ namespace { // implemented as unsigned integers. These convenience template functions // help casting between them safely without generating compiler warnings. inline void* SafePointerFromUInt(unsigned int handle) { - return (void*)(uintptr_t)(handle); + return (void*)(uintptr_t)(handle); } inline unsigned int SafeUIntFromPointer(const void* ptr) { #if 1 - // Ignore the assert below to avoid crashing when running older - // system images, which might have buggy encoder libraries. Print - // an error message though. - if ((uintptr_t)(ptr) != (unsigned int)(uintptr_t)(ptr)) { - fprintf(stderr, "EmuGL:WARNING: bad generic pointer %p\n", ptr); - } + // Ignore the assert below to avoid crashing when running older + // system images, which might have buggy encoder libraries. Print + // an error message though. + if ((uintptr_t)(ptr) != (unsigned int)(uintptr_t)(ptr)) { + fprintf(stderr, "EmuGL:WARNING: bad generic pointer %p\n", ptr); + } #else - // Assertion error if the pointer contains a value that does not fit - // in an unsigned integer! - assert((uintptr_t)(ptr) == (unsigned int)(uintptr_t)(ptr)); + // Assertion error if the pointer contains a value that does not fit + // in an unsigned integer! + assert((uintptr_t)(ptr) == (unsigned int)(uintptr_t)(ptr)); #endif - return (unsigned int)(uintptr_t)(ptr); + return (unsigned int)(uintptr_t)(ptr); } // Lazily create and bind a framebuffer object to the current host context. @@ -55,31 +55,28 @@ inline unsigned int SafeUIntFromPointer(const void* ptr) { // on creation only. I.e. all rendering operations will target it. // returns true in case of success, false on failure. bool bindFbo(GLuint* fbo, GLuint tex) { - if (*fbo) { - // fbo already exist - just bind - s_gles2.glBindFramebuffer(GL_FRAMEBUFFER, *fbo); - return true; - } - - s_gles2.glGenFramebuffers(1, fbo); + if (*fbo) { + // fbo already exist - just bind s_gles2.glBindFramebuffer(GL_FRAMEBUFFER, *fbo); - s_gles2.glFramebufferTexture2D(GL_FRAMEBUFFER, - GL_COLOR_ATTACHMENT0_OES, - GL_TEXTURE_2D, tex, 0); - GLenum status = s_gles2.glCheckFramebufferStatus(GL_FRAMEBUFFER); - if (status != GL_FRAMEBUFFER_COMPLETE_OES) { - ERR("ColorBuffer::bindFbo: FBO not complete: %#x\n", status); - s_gles2.glBindFramebuffer(GL_FRAMEBUFFER, 0); - s_gles2.glDeleteFramebuffers(1, fbo); - *fbo = 0; - return false; - } return true; + } + + s_gles2.glGenFramebuffers(1, fbo); + s_gles2.glBindFramebuffer(GL_FRAMEBUFFER, *fbo); + s_gles2.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0_OES, + GL_TEXTURE_2D, tex, 0); + GLenum status = s_gles2.glCheckFramebufferStatus(GL_FRAMEBUFFER); + if (status != GL_FRAMEBUFFER_COMPLETE_OES) { + ERR("ColorBuffer::bindFbo: FBO not complete: %#x\n", status); + s_gles2.glBindFramebuffer(GL_FRAMEBUFFER, 0); + s_gles2.glDeleteFramebuffers(1, fbo); + *fbo = 0; + return false; + } + return true; } -void unbindFbo() { - s_gles2.glBindFramebuffer(GL_FRAMEBUFFER, 0); -} +void unbindFbo() { s_gles2.glBindFramebuffer(GL_FRAMEBUFFER, 0); } // Helper class to use a ColorBuffer::Helper context. // Usage is pretty simple: @@ -93,302 +90,268 @@ void unbindFbo() { // } // automatically calls m_helper->teardownContext(); // class ScopedHelperContext { -public: - ScopedHelperContext(ColorBuffer::Helper* helper) : mHelper(helper) { - if (!helper->setupContext()) { - mHelper = NULL; - } + public: + ScopedHelperContext(ColorBuffer::Helper* helper) : mHelper(helper) { + if (!helper->setupContext()) { + mHelper = NULL; } + } - bool isOk() const { return mHelper != NULL; } + bool isOk() const { return mHelper != NULL; } - ~ScopedHelperContext() { - release(); + ~ScopedHelperContext() { release(); } + + void release() { + if (mHelper) { + mHelper->teardownContext(); + mHelper = NULL; } + } - void release() { - if (mHelper) { - mHelper->teardownContext(); - mHelper = NULL; - } - } -private: - ColorBuffer::Helper* mHelper; + private: + ColorBuffer::Helper* mHelper; }; } // namespace // static -ColorBuffer* ColorBuffer::create(EGLDisplay p_display, - int p_width, - int p_height, - GLenum p_internalFormat, - bool has_eglimage_texture_2d, - Helper* helper) { - GLenum texInternalFormat = 0; +ColorBuffer* ColorBuffer::create(EGLDisplay p_display, int p_width, + int p_height, GLenum p_internalFormat, + bool has_eglimage_texture_2d, Helper* helper) { + GLenum texInternalFormat = 0; - switch (p_internalFormat) { - case GL_RGB: - case GL_RGB565_OES: - texInternalFormat = GL_RGB; - break; + switch (p_internalFormat) { + case GL_RGB: + case GL_RGB565_OES: + texInternalFormat = GL_RGB; + break; - case GL_RGBA: - case GL_RGB5_A1_OES: - case GL_RGBA4_OES: - texInternalFormat = GL_RGBA; - break; + case GL_RGBA: + case GL_RGB5_A1_OES: + case GL_RGBA4_OES: + texInternalFormat = GL_RGBA; + break; - default: - return NULL; - break; - } + default: + return NULL; + break; + } - ScopedHelperContext context(helper); - if (!context.isOk()) { - return NULL; - } + ScopedHelperContext context(helper); + if (!context.isOk()) { + return NULL; + } - ColorBuffer *cb = new ColorBuffer(p_display, helper); + ColorBuffer* cb = new ColorBuffer(p_display, helper); - s_gles2.glGenTextures(1, &cb->m_tex); - s_gles2.glBindTexture(GL_TEXTURE_2D, cb->m_tex); + s_gles2.glGenTextures(1, &cb->m_tex); + s_gles2.glBindTexture(GL_TEXTURE_2D, cb->m_tex); - int nComp = (texInternalFormat == GL_RGB ? 3 : 4); + int nComp = (texInternalFormat == GL_RGB ? 3 : 4); - char* zBuff = static_cast(::calloc(nComp * p_width * p_height, 1)); - s_gles2.glTexImage2D(GL_TEXTURE_2D, - 0, - texInternalFormat, - p_width, - p_height, - 0, - texInternalFormat, - GL_UNSIGNED_BYTE, - zBuff); - ::free(zBuff); + char* zBuff = static_cast(::calloc(nComp * p_width * p_height, 1)); + s_gles2.glTexImage2D(GL_TEXTURE_2D, 0, texInternalFormat, p_width, p_height, + 0, texInternalFormat, GL_UNSIGNED_BYTE, zBuff); + ::free(zBuff); - s_gles2.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - s_gles2.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - s_gles2.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - s_gles2.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + s_gles2.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + s_gles2.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + s_gles2.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + s_gles2.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - // - // create another texture for that colorbuffer for blit - // - s_gles2.glGenTextures(1, &cb->m_blitTex); - s_gles2.glBindTexture(GL_TEXTURE_2D, cb->m_blitTex); - s_gles2.glTexImage2D(GL_TEXTURE_2D, - 0, - texInternalFormat, - p_width, - p_height, - 0, - texInternalFormat, - GL_UNSIGNED_BYTE, - NULL); + // + // create another texture for that colorbuffer for blit + // + s_gles2.glGenTextures(1, &cb->m_blitTex); + s_gles2.glBindTexture(GL_TEXTURE_2D, cb->m_blitTex); + s_gles2.glTexImage2D(GL_TEXTURE_2D, 0, texInternalFormat, p_width, p_height, + 0, texInternalFormat, GL_UNSIGNED_BYTE, NULL); - s_gles2.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - s_gles2.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - s_gles2.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - s_gles2.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + s_gles2.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + s_gles2.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + s_gles2.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + s_gles2.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - cb->m_width = p_width; - cb->m_height = p_height; - cb->m_internalFormat = texInternalFormat; + cb->m_width = p_width; + cb->m_height = p_height; + cb->m_internalFormat = texInternalFormat; - if (has_eglimage_texture_2d) { - cb->m_eglImage = s_egl.eglCreateImageKHR( - p_display, - s_egl.eglGetCurrentContext(), - EGL_GL_TEXTURE_2D_KHR, - (EGLClientBuffer)SafePointerFromUInt(cb->m_tex), - NULL); + if (has_eglimage_texture_2d) { + cb->m_eglImage = s_egl.eglCreateImageKHR( + p_display, s_egl.eglGetCurrentContext(), EGL_GL_TEXTURE_2D_KHR, + (EGLClientBuffer)SafePointerFromUInt(cb->m_tex), NULL); - cb->m_blitEGLImage = s_egl.eglCreateImageKHR( - p_display, - s_egl.eglGetCurrentContext(), - EGL_GL_TEXTURE_2D_KHR, - (EGLClientBuffer)SafePointerFromUInt(cb->m_blitTex), - NULL); - } + cb->m_blitEGLImage = s_egl.eglCreateImageKHR( + p_display, s_egl.eglGetCurrentContext(), EGL_GL_TEXTURE_2D_KHR, + (EGLClientBuffer)SafePointerFromUInt(cb->m_blitTex), NULL); + } - cb->m_resizer = new TextureResize(p_width, p_height); + cb->m_resizer = new TextureResize(p_width, p_height); - return cb; + return cb; } -ColorBuffer::ColorBuffer(EGLDisplay display, Helper* helper) : - m_tex(0), - m_blitTex(0), - m_eglImage(NULL), - m_blitEGLImage(NULL), - m_fbo(0), - m_internalFormat(0), - m_display(display), - m_helper(helper) {} +ColorBuffer::ColorBuffer(EGLDisplay display, Helper* helper) + : m_tex(0), + m_blitTex(0), + m_eglImage(NULL), + m_blitEGLImage(NULL), + m_fbo(0), + m_internalFormat(0), + m_display(display), + m_helper(helper) {} ColorBuffer::~ColorBuffer() { - ScopedHelperContext context(m_helper); + ScopedHelperContext context(m_helper); - if (m_blitEGLImage) { - s_egl.eglDestroyImageKHR(m_display, m_blitEGLImage); - } - if (m_eglImage) { - s_egl.eglDestroyImageKHR(m_display, m_eglImage); - } + if (m_blitEGLImage) { + s_egl.eglDestroyImageKHR(m_display, m_blitEGLImage); + } + if (m_eglImage) { + s_egl.eglDestroyImageKHR(m_display, m_eglImage); + } - if (m_fbo) { - s_gles2.glDeleteFramebuffers(1, &m_fbo); - } + if (m_fbo) { + s_gles2.glDeleteFramebuffers(1, &m_fbo); + } - GLuint tex[2] = {m_tex, m_blitTex}; - s_gles2.glDeleteTextures(2, tex); + GLuint tex[2] = {m_tex, m_blitTex}; + s_gles2.glDeleteTextures(2, tex); - delete m_resizer; + delete m_resizer; } -void ColorBuffer::readPixels(int x, - int y, - int width, - int height, - GLenum p_format, - GLenum p_type, - void* pixels) { - ScopedHelperContext context(m_helper); - if (!context.isOk()) { - return; - } +void ColorBuffer::readPixels(int x, int y, int width, int height, + GLenum p_format, GLenum p_type, void* pixels) { + ScopedHelperContext context(m_helper); + if (!context.isOk()) { + return; + } - if (bindFbo(&m_fbo, m_tex)) { - s_gles2.glReadPixels(x, y, width, height, p_format, p_type, pixels); - unbindFbo(); - } -} - -void ColorBuffer::subUpdate(int x, - int y, - int width, - int height, - GLenum p_format, - GLenum p_type, - void* pixels) { - ScopedHelperContext context(m_helper); - if (!context.isOk()) { - return; - } - - s_gles2.glBindTexture(GL_TEXTURE_2D, m_tex); - s_gles2.glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - s_gles2.glTexSubImage2D( - GL_TEXTURE_2D, 0, x, y, width, height, p_format, p_type, pixels); -} - -bool ColorBuffer::blitFromCurrentReadBuffer() -{ - RenderThreadInfo *tInfo = RenderThreadInfo::get(); - if (!tInfo->currContext.Ptr()) { - // no Current context - return false; - } - - // Copy the content of the current read surface into m_blitEGLImage. - // This is done by creating a temporary texture, bind it to the EGLImage - // then call glCopyTexSubImage2D(). - GLuint tmpTex; - GLint currTexBind; - if (tInfo->currContext->isGL2()) { - s_gles2.glGetIntegerv(GL_TEXTURE_BINDING_2D, &currTexBind); - s_gles2.glGenTextures(1,&tmpTex); - s_gles2.glBindTexture(GL_TEXTURE_2D, tmpTex); - s_gles2.glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, m_blitEGLImage); - s_gles2.glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, - m_width, m_height); - s_gles2.glDeleteTextures(1, &tmpTex); - s_gles2.glBindTexture(GL_TEXTURE_2D, currTexBind); - } - else { - s_gles1.glGetIntegerv(GL_TEXTURE_BINDING_2D, &currTexBind); - s_gles1.glGenTextures(1,&tmpTex); - s_gles1.glBindTexture(GL_TEXTURE_2D, tmpTex); - s_gles1.glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, m_blitEGLImage); - s_gles1.glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, - m_width, m_height); - s_gles1.glDeleteTextures(1, &tmpTex); - s_gles1.glBindTexture(GL_TEXTURE_2D, currTexBind); - } - - ScopedHelperContext context(m_helper); - if (!context.isOk()) { - return false; - } - - if (!bindFbo(&m_fbo, m_tex)) { - return false; - } - - // Save current viewport and match it to the current colorbuffer size. - GLint vport[4] = { 0, }; - s_gles2.glGetIntegerv(GL_VIEWPORT, vport); - s_gles2.glViewport(0, 0, m_width, m_height); - - // render m_blitTex - m_helper->getTextureDraw()->draw(m_blitTex); - - // Restore previous viewport. - s_gles2.glViewport(vport[0], vport[1], vport[2], vport[3]); + if (bindFbo(&m_fbo, m_tex)) { + s_gles2.glReadPixels(x, y, width, height, p_format, p_type, pixels); unbindFbo(); + } +} - return true; +void ColorBuffer::subUpdate(int x, int y, int width, int height, + GLenum p_format, GLenum p_type, void* pixels) { + ScopedHelperContext context(m_helper); + if (!context.isOk()) { + return; + } + + s_gles2.glBindTexture(GL_TEXTURE_2D, m_tex); + s_gles2.glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + s_gles2.glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, width, height, p_format, + p_type, pixels); +} + +bool ColorBuffer::blitFromCurrentReadBuffer() { + RenderThreadInfo* tInfo = RenderThreadInfo::get(); + if (!tInfo->currContext.Ptr()) { + // no Current context + return false; + } + + // Copy the content of the current read surface into m_blitEGLImage. + // This is done by creating a temporary texture, bind it to the EGLImage + // then call glCopyTexSubImage2D(). + GLuint tmpTex; + GLint currTexBind; + if (tInfo->currContext->isGL2()) { + s_gles2.glGetIntegerv(GL_TEXTURE_BINDING_2D, &currTexBind); + s_gles2.glGenTextures(1, &tmpTex); + s_gles2.glBindTexture(GL_TEXTURE_2D, tmpTex); + s_gles2.glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, m_blitEGLImage); + s_gles2.glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, m_width, + m_height); + s_gles2.glDeleteTextures(1, &tmpTex); + s_gles2.glBindTexture(GL_TEXTURE_2D, currTexBind); + } else { + s_gles1.glGetIntegerv(GL_TEXTURE_BINDING_2D, &currTexBind); + s_gles1.glGenTextures(1, &tmpTex); + s_gles1.glBindTexture(GL_TEXTURE_2D, tmpTex); + s_gles1.glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, m_blitEGLImage); + s_gles1.glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, m_width, + m_height); + s_gles1.glDeleteTextures(1, &tmpTex); + s_gles1.glBindTexture(GL_TEXTURE_2D, currTexBind); + } + + ScopedHelperContext context(m_helper); + if (!context.isOk()) { + return false; + } + + if (!bindFbo(&m_fbo, m_tex)) { + return false; + } + + // Save current viewport and match it to the current colorbuffer size. + GLint vport[4] = { + 0, + }; + s_gles2.glGetIntegerv(GL_VIEWPORT, vport); + s_gles2.glViewport(0, 0, m_width, m_height); + + // render m_blitTex + m_helper->getTextureDraw()->draw(m_blitTex); + + // Restore previous viewport. + s_gles2.glViewport(vport[0], vport[1], vport[2], vport[3]); + unbindFbo(); + + return true; } bool ColorBuffer::bindToTexture() { - if (!m_eglImage) { - return false; - } - RenderThreadInfo *tInfo = RenderThreadInfo::get(); - if (!tInfo->currContext.Ptr()) { - return false; - } - if (tInfo->currContext->isGL2()) { - s_gles2.glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, m_eglImage); - } - else { - s_gles1.glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, m_eglImage); - } - return true; + if (!m_eglImage) { + return false; + } + RenderThreadInfo* tInfo = RenderThreadInfo::get(); + if (!tInfo->currContext.Ptr()) { + return false; + } + if (tInfo->currContext->isGL2()) { + s_gles2.glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, m_eglImage); + } else { + s_gles1.glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, m_eglImage); + } + return true; } bool ColorBuffer::bindToRenderbuffer() { - if (!m_eglImage) { - return false; - } - RenderThreadInfo *tInfo = RenderThreadInfo::get(); - if (!tInfo->currContext.Ptr()) { - return false; - } - if (tInfo->currContext->isGL2()) { - s_gles2.glEGLImageTargetRenderbufferStorageOES(GL_RENDERBUFFER_OES, m_eglImage); - } - else { - s_gles1.glEGLImageTargetRenderbufferStorageOES(GL_RENDERBUFFER_OES, m_eglImage); - } - return true; + if (!m_eglImage) { + return false; + } + RenderThreadInfo* tInfo = RenderThreadInfo::get(); + if (!tInfo->currContext.Ptr()) { + return false; + } + if (tInfo->currContext->isGL2()) { + s_gles2.glEGLImageTargetRenderbufferStorageOES(GL_RENDERBUFFER_OES, + m_eglImage); + } else { + s_gles1.glEGLImageTargetRenderbufferStorageOES(GL_RENDERBUFFER_OES, + m_eglImage); + } + return true; } void ColorBuffer::readback(unsigned char* img) { - ScopedHelperContext context(m_helper); - if (!context.isOk()) { - return; - } - if (bindFbo(&m_fbo, m_tex)) { - s_gles2.glReadPixels( - 0, 0, m_width, m_height, GL_RGBA, GL_UNSIGNED_BYTE, img); - unbindFbo(); - } + ScopedHelperContext context(m_helper); + if (!context.isOk()) { + return; + } + if (bindFbo(&m_fbo, m_tex)) { + s_gles2.glReadPixels(0, 0, m_width, m_height, GL_RGBA, GL_UNSIGNED_BYTE, + img); + unbindFbo(); + } } void ColorBuffer::bind() { - const auto id = m_resizer->update(m_tex); - s_gles2.glBindTexture(GL_TEXTURE_2D, id); + const auto id = m_resizer->update(m_tex); + s_gles2.glBindTexture(GL_TEXTURE_2D, id); } diff --git a/src/anbox/graphics/emugl/ColorBuffer.h b/src/anbox/graphics/emugl/ColorBuffer.h index 6eb48a3..793a671 100644 --- a/src/anbox/graphics/emugl/ColorBuffer.h +++ b/src/anbox/graphics/emugl/ColorBuffer.h @@ -55,96 +55,84 @@ class TextureResize; // As an additional twist. class ColorBuffer { -public: - // Helper interface class used during ColorBuffer operations. This is - // introduced to remove coupling from the FrameBuffer class implementation. - class Helper { - public: - Helper() {} - virtual ~Helper() {} - virtual bool setupContext() = 0; - virtual void teardownContext() = 0; - virtual TextureDraw* getTextureDraw() const = 0; - }; + public: + // Helper interface class used during ColorBuffer operations. This is + // introduced to remove coupling from the FrameBuffer class implementation. + class Helper { + public: + Helper() {} + virtual ~Helper() {} + virtual bool setupContext() = 0; + virtual void teardownContext() = 0; + virtual TextureDraw* getTextureDraw() const = 0; + }; - // Create a new ColorBuffer instance. - // |p_display| is the host EGLDisplay handle. - // |p_width| and |p_height| are the buffer's dimensions in pixels. - // |p_internalFormat| is the internal pixel format to use, valid values - // are: GL_RGB, GL_RGB565, GL_RGBA, GL_RGB5_A1_OES and GL_RGBA4_OES. - // Implementation is free to use something else though. - // |has_eglimage_texture_2d| should be true iff the display supports - // the EGL_KHR_gl_texture_2D_image extension. - // Returns NULL on failure. - static ColorBuffer* create(EGLDisplay p_display, - int p_width, - int p_height, - GLenum p_internalFormat, - bool has_eglimage_texture_2d, - Helper* helper); + // Create a new ColorBuffer instance. + // |p_display| is the host EGLDisplay handle. + // |p_width| and |p_height| are the buffer's dimensions in pixels. + // |p_internalFormat| is the internal pixel format to use, valid values + // are: GL_RGB, GL_RGB565, GL_RGBA, GL_RGB5_A1_OES and GL_RGBA4_OES. + // Implementation is free to use something else though. + // |has_eglimage_texture_2d| should be true iff the display supports + // the EGL_KHR_gl_texture_2D_image extension. + // Returns NULL on failure. + static ColorBuffer* create(EGLDisplay p_display, int p_width, int p_height, + GLenum p_internalFormat, + bool has_eglimage_texture_2d, Helper* helper); - // Destructor. - ~ColorBuffer(); + // Destructor. + ~ColorBuffer(); - // Return ColorBuffer width and height in pixels - GLuint getWidth() const { return m_width; } - GLuint getHeight() const { return m_height; } + // Return ColorBuffer width and height in pixels + GLuint getWidth() const { return m_width; } + GLuint getHeight() const { return m_height; } - // Read the ColorBuffer instance's pixel values into host memory. - void readPixels(int x, - int y, - int width, - int height, - GLenum p_format, - GLenum p_type, - void *pixels); + // Read the ColorBuffer instance's pixel values into host memory. + void readPixels(int x, int y, int width, int height, GLenum p_format, + GLenum p_type, void* pixels); - // Update the ColorBuffer instance's pixel values from host memory. - void subUpdate(int x, - int y, - int width, - int height, - GLenum p_format, - GLenum p_type, - void *pixels); + // Update the ColorBuffer instance's pixel values from host memory. + void subUpdate(int x, int y, int width, int height, GLenum p_format, + GLenum p_type, void* pixels); - // Bind the current context's EGL_TEXTURE_2D texture to this ColorBuffer's - // EGLImage. This is intended to implement glEGLImageTargetTexture2DOES() - // for all GLES versions. - bool bindToTexture(); + // Bind the current context's EGL_TEXTURE_2D texture to this ColorBuffer's + // EGLImage. This is intended to implement glEGLImageTargetTexture2DOES() + // for all GLES versions. + bool bindToTexture(); - // Bind the current context's EGL_RENDERBUFFER_OES render buffer to this - // ColorBuffer's EGLImage. This is intended to implement - // glEGLImageTargetRenderbufferStorageOES() for all GLES versions. - bool bindToRenderbuffer(); + // Bind the current context's EGL_RENDERBUFFER_OES render buffer to this + // ColorBuffer's EGLImage. This is intended to implement + // glEGLImageTargetRenderbufferStorageOES() for all GLES versions. + bool bindToRenderbuffer(); - // Copy the content of the current context's read surface to this - // ColorBuffer. This is used from WindowSurface::flushColorBuffer(). - // Return true on success, false on failure (e.g. no current context). - bool blitFromCurrentReadBuffer(); + // Copy the content of the current context's read surface to this + // ColorBuffer. This is used from WindowSurface::flushColorBuffer(). + // Return true on success, false on failure (e.g. no current context). + bool blitFromCurrentReadBuffer(); - // Read the content of the whole ColorBuffer as 32-bit RGBA pixels. - // |img| must be a buffer large enough (i.e. width * height * 4). - void readback(unsigned char* img); + // Read the content of the whole ColorBuffer as 32-bit RGBA pixels. + // |img| must be a buffer large enough (i.e. width * height * 4). + void readback(unsigned char* img); - void bind(); -private: - ColorBuffer(); // no default constructor. + void bind(); - explicit ColorBuffer(EGLDisplay display, Helper* helper); + private: + ColorBuffer(); // no default constructor. -private: - GLuint m_tex; - GLuint m_blitTex; - EGLImageKHR m_eglImage; - EGLImageKHR m_blitEGLImage; - GLuint m_width; - GLuint m_height; - GLuint m_fbo; - GLenum m_internalFormat; - EGLDisplay m_display; - Helper* m_helper; - TextureResize * m_resizer; + explicit ColorBuffer(EGLDisplay display, Helper* helper); + + private: + GLuint m_tex; + GLuint m_blitTex; + EGLImageKHR m_eglImage; + EGLImageKHR m_blitEGLImage; + GLuint m_width; + GLuint m_height; + GLuint m_fbo; + GLenum m_internalFormat; + EGLDisplay m_display; + Helper* m_helper; + TextureResize* m_resizer; }; typedef emugl::SmartPtr ColorBufferPtr; diff --git a/src/anbox/graphics/emugl/DisplayManager.cpp b/src/anbox/graphics/emugl/DisplayManager.cpp index 2e26a81..0a624cd 100644 --- a/src/anbox/graphics/emugl/DisplayManager.cpp +++ b/src/anbox/graphics/emugl/DisplayManager.cpp @@ -21,22 +21,18 @@ namespace { std::shared_ptr display_mgr; class NullDisplayManager : public DisplayManager { -public: - DisplayInfo display_info() const override { - return {1280, 720}; - } + public: + DisplayInfo display_info() const override { return {1280, 720}; } }; } -DisplayManager::~DisplayManager() { -} +DisplayManager::~DisplayManager() {} std::shared_ptr DisplayManager::get() { - if (!display_mgr) - display_mgr = std::make_shared(); - return display_mgr; + if (!display_mgr) display_mgr = std::make_shared(); + return display_mgr; } void registerDisplayManager(const std::shared_ptr &mgr) { - display_mgr = mgr; + display_mgr = mgr; } diff --git a/src/anbox/graphics/emugl/DisplayManager.h b/src/anbox/graphics/emugl/DisplayManager.h index beb678a..857742f 100644 --- a/src/anbox/graphics/emugl/DisplayManager.h +++ b/src/anbox/graphics/emugl/DisplayManager.h @@ -21,17 +21,17 @@ #include class DisplayManager { -public: - virtual ~DisplayManager(); + public: + virtual ~DisplayManager(); - struct DisplayInfo { - int horizontal_resolution; - int vertical_resolution; - }; + struct DisplayInfo { + int horizontal_resolution; + int vertical_resolution; + }; - virtual DisplayInfo display_info() const = 0; + virtual DisplayInfo display_info() const = 0; - static std::shared_ptr get(); + static std::shared_ptr get(); }; void registerDisplayManager(const std::shared_ptr &mgr); diff --git a/src/anbox/graphics/emugl/ReadBuffer.cpp b/src/anbox/graphics/emugl/ReadBuffer.cpp index 5db9948..b5a0fdb 100644 --- a/src/anbox/graphics/emugl/ReadBuffer.cpp +++ b/src/anbox/graphics/emugl/ReadBuffer.cpp @@ -14,61 +14,54 @@ * limitations under the License. */ #include "ReadBuffer.h" -#include #include #include +#include #include "ErrorLog.h" -ReadBuffer::ReadBuffer(size_t bufsize) -{ - m_size = bufsize; - m_buf = (unsigned char*)malloc(m_size*sizeof(unsigned char)); - m_validData = 0; - m_readPtr = m_buf; +ReadBuffer::ReadBuffer(size_t bufsize) { + m_size = bufsize; + m_buf = (unsigned char*)malloc(m_size * sizeof(unsigned char)); + m_validData = 0; + m_readPtr = m_buf; } -ReadBuffer::~ReadBuffer() -{ - free(m_buf); -} +ReadBuffer::~ReadBuffer() { free(m_buf); } -int ReadBuffer::getData(IOStream *stream) -{ - if(stream == NULL) - return -1; - if ((m_validData > 0) && (m_readPtr > m_buf)) { - memmove(m_buf, m_readPtr, m_validData); +int ReadBuffer::getData(IOStream* stream) { + if (stream == NULL) return -1; + if ((m_validData > 0) && (m_readPtr > m_buf)) { + memmove(m_buf, m_readPtr, m_validData); + } + // get fresh data into the buffer; + size_t len = m_size - m_validData; + if (len == 0) { + // we need to inc our buffer + size_t new_size = m_size * 2; + unsigned char* new_buf; + if (new_size < m_size) { // overflow check + new_size = INT_MAX; } - // get fresh data into the buffer; - size_t len = m_size - m_validData; - if (len==0) { - //we need to inc our buffer - size_t new_size = m_size*2; - unsigned char* new_buf; - if (new_size < m_size) { // overflow check - new_size = INT_MAX; - } - new_buf = (unsigned char*)realloc(m_buf, new_size); - if (!new_buf) { - ERR("Failed to alloc %zu bytes for ReadBuffer\n", new_size); - return -1; - } - m_size = new_size; - m_buf = new_buf; - len = m_size - m_validData; + new_buf = (unsigned char*)realloc(m_buf, new_size); + if (!new_buf) { + ERR("Failed to alloc %zu bytes for ReadBuffer\n", new_size); + return -1; } - m_readPtr = m_buf; - if (NULL != stream->read(m_buf + m_validData, &len)) { - m_validData += len; - return len; - } - return -1; + m_size = new_size; + m_buf = new_buf; + len = m_size - m_validData; + } + m_readPtr = m_buf; + if (NULL != stream->read(m_buf + m_validData, &len)) { + m_validData += len; + return len; + } + return -1; } -void ReadBuffer::consume(size_t amount) -{ - assert(amount <= m_validData); - m_validData -= amount; - m_readPtr += amount; +void ReadBuffer::consume(size_t amount) { + assert(amount <= m_validData); + m_validData -= amount; + m_readPtr += amount; } diff --git a/src/anbox/graphics/emugl/ReadBuffer.h b/src/anbox/graphics/emugl/ReadBuffer.h index 484b6c1..86a486f 100644 --- a/src/anbox/graphics/emugl/ReadBuffer.h +++ b/src/anbox/graphics/emugl/ReadBuffer.h @@ -19,17 +19,19 @@ #include "IOStream.h" class ReadBuffer { -public: - ReadBuffer(size_t bufSize); - ~ReadBuffer(); - int getData(IOStream *stream); // get fresh data from the stream - unsigned char *buf() { return m_readPtr; } // return the next read location - size_t validData() { return m_validData; } // return the amount of valid data in readptr - void consume(size_t amount); // notify that 'amount' data has been consumed; -private: - unsigned char *m_buf; - unsigned char *m_readPtr; - size_t m_size; - size_t m_validData; + public: + ReadBuffer(size_t bufSize); + ~ReadBuffer(); + int getData(IOStream *stream); // get fresh data from the stream + unsigned char *buf() { return m_readPtr; } // return the next read location + size_t validData() { + return m_validData; + } // return the amount of valid data in readptr + void consume(size_t amount); // notify that 'amount' data has been consumed; + private: + unsigned char *m_buf; + unsigned char *m_readPtr; + size_t m_size; + size_t m_validData; }; #endif diff --git a/src/anbox/graphics/emugl/RenderApi.cpp b/src/anbox/graphics/emugl/RenderApi.cpp index d0b40e9..2633b7e 100644 --- a/src/anbox/graphics/emugl/RenderApi.cpp +++ b/src/anbox/graphics/emugl/RenderApi.cpp @@ -41,210 +41,200 @@ static char s_renderAddr[256]; static RenderWindow* s_renderWindow = NULL; -static IOStream *createRenderThread(int p_stream_buffer_size, +static IOStream* createRenderThread(int p_stream_buffer_size, unsigned int clientFlags); -RENDER_APICALL int RENDER_APIENTRY initLibrary(void) -{ - // - // Load EGL Plugin - // - if (!init_egl_dispatch()) { - // Failed to load EGL - printf("Failed to init_egl_dispatch\n"); - return false; - } +RENDER_APICALL int RENDER_APIENTRY initLibrary(void) { + // + // Load EGL Plugin + // + if (!init_egl_dispatch()) { + // Failed to load EGL + printf("Failed to init_egl_dispatch\n"); + return false; + } - // - // Load GLES Plugin - // - if (!gles1_dispatch_init(&s_gles1)) { - // Failed to load GLES - ERR("Failed to gles1_dispatch_init\n"); - return false; - } + // + // Load GLES Plugin + // + if (!gles1_dispatch_init(&s_gles1)) { + // Failed to load GLES + ERR("Failed to gles1_dispatch_init\n"); + return false; + } - /* failure to init the GLES2 dispatch table is not fatal */ - if (!gles2_dispatch_init(&s_gles2)) { - ERR("Failed to gles2_dispatch_init\n"); - return false; - } + /* failure to init the GLES2 dispatch table is not fatal */ + if (!gles2_dispatch_init(&s_gles2)) { + ERR("Failed to gles2_dispatch_init\n"); + return false; + } - return true; + return true; } RENDER_APICALL int RENDER_APIENTRY initOpenGLRenderer( - EGLNativeDisplayType native_display, char* addr, size_t addrLen, - emugl_logger_struct logfuncs, emugl_crash_func_t crashfunc) { - set_emugl_crash_reporter(crashfunc); - set_emugl_logger(logfuncs.coarse); - set_emugl_cxt_logger(logfuncs.fine); - // - // Fail if renderer is already initialized - // - if (s_renderThread) { - return false; - } - - // kUseThread is used to determine whether the RenderWindow should use - // a separate thread to manage its subwindow GL/GLES context. - // For now, this feature is disabled entirely for the following - // reasons: - // - // - It must be disabled on Windows at all times, otherwise the main window becomes - // unresponsive after a few seconds of user interaction (e.g. trying to - // move it over the desktop). Probably due to the subtle issues around - // input on this platform (input-queue is global, message-queue is - // per-thread). Also, this messes considerably the display of the - // main window when running the executable under Wine. - // - // - On Linux/XGL and OSX/Cocoa, this used to be necessary to avoid corruption - // issues with the GL state of the main window when using the SDL UI. - // After the switch to Qt, this is no longer necessary and may actually cause - // undesired interactions between the UI thread and the RenderWindow thread: - // for example, in a multi-monitor setup the context might be recreated when - // dragging the window between monitors, triggering a Qt-specific callback - // in the context of RenderWindow thread, which will become blocked on the UI - // thread, which may in turn be blocked on something else. - bool kUseThread = false; - - // - // initialize the renderer and listen to connections - // on a thread in the current process. - // - s_renderWindow = new RenderWindow(native_display, kUseThread); - if (!s_renderWindow) { - ERR("Could not create rendering window class"); - GL_LOG("Could not create rendering window class"); - return false; - } - if (!s_renderWindow->isValid()) { - ERR("Could not initialize emulated framebuffer\n"); - delete s_renderWindow; - s_renderWindow = NULL; - return false; - } - - s_renderThread = RenderServer::create(addr, addrLen); - if (!s_renderThread) { - return false; - } - strncpy(s_renderAddr, addr, sizeof(s_renderAddr)); - - s_renderThread->start(); - - GL_LOG("OpenGL renderer initialized successfully"); - return true; -} - -RENDER_APICALL void RENDER_APIENTRY getHardwareStrings( - const char** vendor, - const char** renderer, - const char** version) { - if (s_renderWindow && - s_renderWindow->getHardwareStrings(vendor, renderer, version)) { - return; - } - *vendor = *renderer = *version = NULL; -} - -RENDER_APICALL int RENDER_APIENTRY stopOpenGLRenderer(void) -{ - bool ret = false; - - // open a dummy connection to the renderer to make it - // realize the exit request. - // (send the exit request in clientFlags) - IOStream *dummy = createRenderThread(8, IOSTREAM_CLIENT_EXIT_SERVER); - if (!dummy) return false; - - if (s_renderThread) { - // wait for the thread to exit - ret = s_renderThread->wait(NULL); - - delete s_renderThread; - s_renderThread = NULL; - } - - if (s_renderWindow != NULL) { - delete s_renderWindow; - s_renderWindow = NULL; - } - - delete dummy; - - return ret; -} - -RENDER_APICALL bool RENDER_APIENTRY showOpenGLSubwindow( - FBNativeWindowType window_id, - int wx, - int wy, - int ww, - int wh, - int fbw, - int fbh, - float dpr, - float zRot) -{ - RenderWindow* window = s_renderWindow; - - if (window) { - return window->setupSubWindow(window_id,wx,wy,ww,wh,fbw,fbh,dpr,zRot); - } - // XXX: should be implemented by sending the renderer process - // a request - ERR("%s not implemented for separate renderer process !!!\n", - __FUNCTION__); + EGLNativeDisplayType native_display, char* addr, size_t addrLen, + emugl_logger_struct logfuncs, emugl_crash_func_t crashfunc) { + set_emugl_crash_reporter(crashfunc); + set_emugl_logger(logfuncs.coarse); + set_emugl_cxt_logger(logfuncs.fine); + // + // Fail if renderer is already initialized + // + if (s_renderThread) { return false; + } + + // kUseThread is used to determine whether the RenderWindow should use + // a separate thread to manage its subwindow GL/GLES context. + // For now, this feature is disabled entirely for the following + // reasons: + // + // - It must be disabled on Windows at all times, otherwise the main window + // becomes + // unresponsive after a few seconds of user interaction (e.g. trying to + // move it over the desktop). Probably due to the subtle issues around + // input on this platform (input-queue is global, message-queue is + // per-thread). Also, this messes considerably the display of the + // main window when running the executable under Wine. + // + // - On Linux/XGL and OSX/Cocoa, this used to be necessary to avoid corruption + // issues with the GL state of the main window when using the SDL UI. + // After the switch to Qt, this is no longer necessary and may actually + // cause + // undesired interactions between the UI thread and the RenderWindow thread: + // for example, in a multi-monitor setup the context might be recreated when + // dragging the window between monitors, triggering a Qt-specific callback + // in the context of RenderWindow thread, which will become blocked on the + // UI + // thread, which may in turn be blocked on something else. + bool kUseThread = false; + + // + // initialize the renderer and listen to connections + // on a thread in the current process. + // + s_renderWindow = new RenderWindow(native_display, kUseThread); + if (!s_renderWindow) { + ERR("Could not create rendering window class"); + GL_LOG("Could not create rendering window class"); + return false; + } + if (!s_renderWindow->isValid()) { + ERR("Could not initialize emulated framebuffer\n"); + delete s_renderWindow; + s_renderWindow = NULL; + return false; + } + + s_renderThread = RenderServer::create(addr, addrLen); + if (!s_renderThread) { + return false; + } + strncpy(s_renderAddr, addr, sizeof(s_renderAddr)); + + s_renderThread->start(); + + GL_LOG("OpenGL renderer initialized successfully"); + return true; } -RENDER_APICALL bool RENDER_APIENTRY destroyOpenGLSubwindow(void) -{ - RenderWindow* window = s_renderWindow; +RENDER_APICALL void RENDER_APIENTRY getHardwareStrings(const char** vendor, + const char** renderer, + const char** version) { + if (s_renderWindow && + s_renderWindow->getHardwareStrings(vendor, renderer, version)) { + return; + } + *vendor = *renderer = *version = NULL; +} - if (window) { - return window->removeSubWindow(); - } +RENDER_APICALL int RENDER_APIENTRY stopOpenGLRenderer(void) { + bool ret = false; - // XXX: should be implemented by sending the renderer process - // a request - ERR("%s not implemented for separate renderer process !!!\n", - __FUNCTION__); - return false; + // open a dummy connection to the renderer to make it + // realize the exit request. + // (send the exit request in clientFlags) + IOStream* dummy = createRenderThread(8, IOSTREAM_CLIENT_EXIT_SERVER); + if (!dummy) return false; + + if (s_renderThread) { + // wait for the thread to exit + ret = s_renderThread->wait(NULL); + + delete s_renderThread; + s_renderThread = NULL; + } + + if (s_renderWindow != NULL) { + delete s_renderWindow; + s_renderWindow = NULL; + } + + delete dummy; + + return ret; +} + +RENDER_APICALL bool RENDER_APIENTRY +showOpenGLSubwindow(FBNativeWindowType window_id, int wx, int wy, int ww, + int wh, int fbw, int fbh, float dpr, float zRot) { + RenderWindow* window = s_renderWindow; + + if (window) { + return window->setupSubWindow(window_id, wx, wy, ww, wh, fbw, fbh, dpr, + zRot); + } + // XXX: should be implemented by sending the renderer process + // a request + ERR("%s not implemented for separate renderer process !!!\n", __FUNCTION__); + return false; +} + +RENDER_APICALL bool RENDER_APIENTRY destroyOpenGLSubwindow(void) { + RenderWindow* window = s_renderWindow; + + if (window) { + return window->removeSubWindow(); + } + + // XXX: should be implemented by sending the renderer process + // a request + ERR("%s not implemented for separate renderer process !!!\n", __FUNCTION__); + return false; } #define DEFAULT_STREAM_MODE RENDER_API_STREAM_MODE_UNIX int gRendererStreamMode = DEFAULT_STREAM_MODE; -IOStream *createRenderThread(int p_stream_buffer_size, unsigned int clientFlags) -{ - SocketStream* stream = NULL; +IOStream* createRenderThread(int p_stream_buffer_size, + unsigned int clientFlags) { + SocketStream* stream = NULL; - if (gRendererStreamMode == RENDER_API_STREAM_MODE_TCP) { - stream = new TcpStream(p_stream_buffer_size); - } else { - stream = new UnixStream(p_stream_buffer_size); - } + if (gRendererStreamMode == RENDER_API_STREAM_MODE_TCP) { + stream = new TcpStream(p_stream_buffer_size); + } else { + stream = new UnixStream(p_stream_buffer_size); + } - if (!stream) { - ERR("createRenderThread failed to create stream\n"); - return NULL; - } - if (stream->connect(s_renderAddr) < 0) { - ERR("createRenderThread failed to connect\n"); - delete stream; - return NULL; - } + if (!stream) { + ERR("createRenderThread failed to create stream\n"); + return NULL; + } + if (stream->connect(s_renderAddr) < 0) { + ERR("createRenderThread failed to connect\n"); + delete stream; + return NULL; + } - // - // send clientFlags to the renderer - // - unsigned int *pClientFlags = - (unsigned int *)stream->allocBuffer(sizeof(unsigned int)); - *pClientFlags = clientFlags; - stream->commitBuffer(sizeof(unsigned int)); + // + // send clientFlags to the renderer + // + unsigned int* pClientFlags = + (unsigned int*)stream->allocBuffer(sizeof(unsigned int)); + *pClientFlags = clientFlags; + stream->commitBuffer(sizeof(unsigned int)); - return stream; + return stream; } diff --git a/src/anbox/graphics/emugl/RenderContext.cpp b/src/anbox/graphics/emugl/RenderContext.cpp index 59faa4b..ef47143 100644 --- a/src/anbox/graphics/emugl/RenderContext.cpp +++ b/src/anbox/graphics/emugl/RenderContext.cpp @@ -17,33 +17,24 @@ #include "OpenGLESDispatch/EGLDispatch.h" -RenderContext* RenderContext::create(EGLDisplay display, - EGLConfig config, - EGLContext sharedContext, - bool isGl2) { - const EGLint contextAttribs[] = { - EGL_CONTEXT_CLIENT_VERSION, isGl2 ? 2 : 1, - EGL_NONE - }; - EGLContext context = s_egl.eglCreateContext( - display, config, sharedContext, contextAttribs); - if (context == EGL_NO_CONTEXT) { - return NULL; - } +RenderContext* RenderContext::create(EGLDisplay display, EGLConfig config, + EGLContext sharedContext, bool isGl2) { + const EGLint contextAttribs[] = {EGL_CONTEXT_CLIENT_VERSION, isGl2 ? 2 : 1, + EGL_NONE}; + EGLContext context = + s_egl.eglCreateContext(display, config, sharedContext, contextAttribs); + if (context == EGL_NO_CONTEXT) { + return NULL; + } - return new RenderContext(display, context, isGl2); + return new RenderContext(display, context, isGl2); } -RenderContext::RenderContext(EGLDisplay display, - EGLContext context, - bool isGl2) : - mDisplay(display), - mContext(context), - mIsGl2(isGl2), - mContextData() {} +RenderContext::RenderContext(EGLDisplay display, EGLContext context, bool isGl2) + : mDisplay(display), mContext(context), mIsGl2(isGl2), mContextData() {} RenderContext::~RenderContext() { - if (mContext != EGL_NO_CONTEXT) { - s_egl.eglDestroyContext(mDisplay, mContext); - } + if (mContext != EGL_NO_CONTEXT) { + s_egl.eglDestroyContext(mDisplay, mContext); + } } diff --git a/src/anbox/graphics/emugl/RenderContext.h b/src/anbox/graphics/emugl/RenderContext.h index 4182996..fd2dccf 100644 --- a/src/anbox/graphics/emugl/RenderContext.h +++ b/src/anbox/graphics/emugl/RenderContext.h @@ -16,8 +16,8 @@ #ifndef _LIBRENDER_RENDER_CONTEXT_H #define _LIBRENDER_RENDER_CONTEXT_H -#include "emugl/common/smart_ptr.h" #include "GLDecoderContextData.h" +#include "emugl/common/smart_ptr.h" #include @@ -25,43 +25,39 @@ // EGLContext, associated with an GLDecoderContextData instance that is // used to store copies of guest-side arrays. class RenderContext { -public: - // Create a new RenderContext instance. - // |display| is the host EGLDisplay handle. - // |config| is the host EGLConfig to use. - // |sharedContext| is either EGL_NO_CONTEXT of a host EGLContext handle. - // |isGl2| is true iff the new context will be used with GLESv2, or - // GLESv1 otherwise. - static RenderContext *create(EGLDisplay display, - EGLConfig config, - EGLContext sharedContext, - bool isGL2 = false); + public: + // Create a new RenderContext instance. + // |display| is the host EGLDisplay handle. + // |config| is the host EGLConfig to use. + // |sharedContext| is either EGL_NO_CONTEXT of a host EGLContext handle. + // |isGl2| is true iff the new context will be used with GLESv2, or + // GLESv1 otherwise. + static RenderContext* create(EGLDisplay display, EGLConfig config, + EGLContext sharedContext, bool isGL2 = false); - // Destructor. - ~RenderContext(); + // Destructor. + ~RenderContext(); - // Retrieve host EGLContext value. - EGLContext getEGLContext() const { return mContext; } + // Retrieve host EGLContext value. + EGLContext getEGLContext() const { return mContext; } - // Return true iff this is a GLESv2 context. - bool isGL2() const { return mIsGl2; } + // Return true iff this is a GLESv2 context. + bool isGL2() const { return mIsGl2; } - // Retrieve GLDecoderContextData instance reference for this - // RenderContext instance. - GLDecoderContextData& decoderContextData() { return mContextData; } + // Retrieve GLDecoderContextData instance reference for this + // RenderContext instance. + GLDecoderContextData& decoderContextData() { return mContextData; } -private: - RenderContext(); + private: + RenderContext(); - RenderContext(EGLDisplay display, - EGLContext context, - bool isGl2); + RenderContext(EGLDisplay display, EGLContext context, bool isGl2); -private: - EGLDisplay mDisplay; - EGLContext mContext; - bool mIsGl2; - GLDecoderContextData mContextData; + private: + EGLDisplay mDisplay; + EGLContext mContext; + bool mIsGl2; + GLDecoderContextData mContextData; }; typedef emugl::SmartPtr RenderContextPtr; diff --git a/src/anbox/graphics/emugl/RenderControl.cpp b/src/anbox/graphics/emugl/RenderControl.cpp index 5ea6d96..eba7e43 100644 --- a/src/anbox/graphics/emugl/RenderControl.cpp +++ b/src/anbox/graphics/emugl/RenderControl.cpp @@ -15,12 +15,12 @@ */ #include "RenderControl.h" -#include "DispatchTables.h" -#include "RendererConfig.h" -#include "Renderer.h" -#include "RenderThreadInfo.h" #include "ChecksumCalculatorThreadInfo.h" +#include "DispatchTables.h" #include "DisplayManager.h" +#include "RenderThreadInfo.h" +#include "Renderer.h" +#include "RendererConfig.h" #include "OpenGLESDispatch/EGLDispatch.h" @@ -33,471 +33,428 @@ static const GLint rendererVersion = 1; static std::shared_ptr composer; -void registerLayerComposer(const std::shared_ptr &c) -{ - composer = c; +void registerLayerComposer( + const std::shared_ptr &c) { + composer = c; } -static GLint rcGetRendererVersion() -{ - return rendererVersion; +static GLint rcGetRendererVersion() { return rendererVersion; } + +static EGLint rcGetEGLVersion(EGLint *major, EGLint *minor) { + Renderer *fb = Renderer::get(); + if (!fb) { + return EGL_FALSE; + } + *major = (EGLint)fb->getCaps().eglMajor; + *minor = (EGLint)fb->getCaps().eglMinor; + + return EGL_TRUE; } -static EGLint rcGetEGLVersion(EGLint* major, EGLint* minor) -{ - Renderer *fb = Renderer::get(); - if (!fb) { - return EGL_FALSE; - } - *major = (EGLint)fb->getCaps().eglMajor; - *minor = (EGLint)fb->getCaps().eglMinor; +static EGLint rcQueryEGLString(EGLenum name, void *buffer, EGLint bufferSize) { + Renderer *fb = Renderer::get(); + if (!fb) { + return 0; + } - return EGL_TRUE; + const char *str = s_egl.eglQueryString(fb->getDisplay(), name); + if (!str) { + return 0; + } + + int len = strlen(str) + 1; + if (!buffer || len > bufferSize) { + return -len; + } + + strcpy((char *)buffer, str); + return len; } -static EGLint rcQueryEGLString(EGLenum name, void* buffer, EGLint bufferSize) -{ - Renderer *fb = Renderer::get(); - if (!fb) { - return 0; +static EGLint rcGetGLString(EGLenum name, void *buffer, EGLint bufferSize) { + RenderThreadInfo *tInfo = RenderThreadInfo::get(); + std::string result; + + if (tInfo && tInfo->currContext) { + const char *str = nullptr; + if (tInfo->currContext->isGL2()) + str = reinterpret_cast(s_gles2.glGetString(name)); + else + str = reinterpret_cast(s_gles1.glGetString(name)); + + if (str) result += str; + } + + // We're forcing version 2.0 no matter what the host provides as + // our emulation layer isn't prepared for anything newer (yet). + // This goes in parallel with filtering the extension set for + // any unwanted extensions. If we don't force the right version + // here certain parts of the system will assume API conditions + // which aren't met. + if (name == GL_VERSION) + result = "OpenGL ES 2.0"; + else if (name == GL_EXTENSIONS) { + std::string approved_extensions = result; + std::vector unsupported_extensions = { + // Leaving this enabled gives crippeled text rendering when + // using the host mesa GLES drivers. + "GL_EXT_unpack_subimage", + }; + + for (const auto &extension : unsupported_extensions) { + size_t start_pos = approved_extensions.find(extension); + if (start_pos == std::string::npos) continue; + approved_extensions.replace(start_pos, extension.length(), ""); } - const char *str = s_egl.eglQueryString(fb->getDisplay(), name); - if (!str) { - return 0; - } + result = approved_extensions; + } - int len = strlen(str) + 1; - if (!buffer || len > bufferSize) { - return -len; - } + int nextBufferSize = result.size() + 1; - strcpy((char *)buffer, str); - return len; + if (!buffer || nextBufferSize > bufferSize) return -nextBufferSize; + + snprintf(static_cast(buffer), nextBufferSize, "%s", result.c_str()); + return nextBufferSize; } -static EGLint rcGetGLString(EGLenum name, void* buffer, EGLint bufferSize) -{ - RenderThreadInfo *tInfo = RenderThreadInfo::get(); - std::string result; +static EGLint rcGetNumConfigs(uint32_t *p_numAttribs) { + int numConfigs = 0, numAttribs = 0; - if (tInfo && tInfo->currContext) { - const char *str = nullptr; - if (tInfo->currContext->isGL2()) - str = reinterpret_cast(s_gles2.glGetString(name)); - else - str = reinterpret_cast(s_gles1.glGetString(name)); - - if (str) - result += str; - } - - // We're forcing version 2.0 no matter what the host provides as - // our emulation layer isn't prepared for anything newer (yet). - // This goes in parallel with filtering the extension set for - // any unwanted extensions. If we don't force the right version - // here certain parts of the system will assume API conditions - // which aren't met. - if (name == GL_VERSION) - result = "OpenGL ES 2.0"; - else if (name == GL_EXTENSIONS) { - std::string approved_extensions = result; - std::vector unsupported_extensions = { - // Leaving this enabled gives crippeled text rendering when - // using the host mesa GLES drivers. - "GL_EXT_unpack_subimage", - }; - - for (const auto &extension : unsupported_extensions) { - size_t start_pos = approved_extensions.find(extension); - if(start_pos == std::string::npos) - continue; - approved_extensions.replace(start_pos, extension.length(), ""); - } - - result = approved_extensions; - } - - int nextBufferSize = result.size() + 1; - - if (!buffer || nextBufferSize > bufferSize) - return -nextBufferSize; - - snprintf(static_cast(buffer), nextBufferSize, "%s", result.c_str()); - return nextBufferSize; + Renderer::get()->getConfigs()->getPackInfo(&numConfigs, &numAttribs); + if (p_numAttribs) { + *p_numAttribs = static_cast(numAttribs); + } + return numConfigs; } -static EGLint rcGetNumConfigs(uint32_t* p_numAttribs) -{ - int numConfigs = 0, numAttribs = 0; - - Renderer::get()->getConfigs()->getPackInfo(&numConfigs, &numAttribs); - if (p_numAttribs) { - *p_numAttribs = static_cast(numAttribs); - } - return numConfigs; +static EGLint rcGetConfigs(uint32_t bufSize, GLuint *buffer) { + GLuint bufferSize = (GLuint)bufSize; + return Renderer::get()->getConfigs()->packConfigs(bufferSize, buffer); } -static EGLint rcGetConfigs(uint32_t bufSize, GLuint* buffer) -{ - GLuint bufferSize = (GLuint)bufSize; - return Renderer::get()->getConfigs()->packConfigs(bufferSize, buffer); +static EGLint rcChooseConfig(EGLint *attribs, uint32_t attribs_size, + uint32_t *configs, uint32_t configs_size) { + Renderer *fb = Renderer::get(); + if (!fb || attribs_size == 0) { + return 0; + } + + return fb->getConfigs()->chooseConfig(attribs, (EGLint *)configs, + (EGLint)configs_size); } -static EGLint rcChooseConfig(EGLint *attribs, - uint32_t attribs_size, - uint32_t *configs, - uint32_t configs_size) -{ - Renderer *fb = Renderer::get(); - if (!fb || attribs_size==0) { - return 0; - } +static EGLint rcGetFBParam(EGLint param) { + Renderer *fb = Renderer::get(); + if (!fb) { + return 0; + } - return fb->getConfigs()->chooseConfig( - attribs, (EGLint*)configs, (EGLint)configs_size); + EGLint ret = 0; + + switch (param) { + case FB_WIDTH: + ret = DisplayManager::get()->display_info().horizontal_resolution; + break; + case FB_HEIGHT: + ret = DisplayManager::get()->display_info().vertical_resolution; + break; + case FB_XDPI: + ret = 72; // XXX: should be implemented + break; + case FB_YDPI: + ret = 72; // XXX: should be implemented + break; + case FB_FPS: + ret = 60; + break; + case FB_MIN_SWAP_INTERVAL: + ret = 1; // XXX: should be implemented + break; + case FB_MAX_SWAP_INTERVAL: + ret = 1; // XXX: should be implemented + break; + default: + break; + } + + return ret; } -static EGLint rcGetFBParam(EGLint param) -{ - Renderer *fb = Renderer::get(); - if (!fb) { - return 0; - } +static uint32_t rcCreateContext(uint32_t config, uint32_t share, + uint32_t glVersion) { + Renderer *fb = Renderer::get(); + if (!fb) { + return 0; + } - EGLint ret = 0; - - switch(param) { - case FB_WIDTH: - ret = DisplayManager::get()->display_info().horizontal_resolution; - break; - case FB_HEIGHT: - ret = DisplayManager::get()->display_info().vertical_resolution; - break; - case FB_XDPI: - ret = 72; // XXX: should be implemented - break; - case FB_YDPI: - ret = 72; // XXX: should be implemented - break; - case FB_FPS: - ret = 60; - break; - case FB_MIN_SWAP_INTERVAL: - ret = 1; // XXX: should be implemented - break; - case FB_MAX_SWAP_INTERVAL: - ret = 1; // XXX: should be implemented - break; - default: - break; - } - - return ret; + // To make it consistent with the guest, create GLES2 context when GL + // version==2 or 3 + HandleType ret = + fb->createRenderContext(config, share, glVersion == 2 || glVersion == 3); + return ret; } -static uint32_t rcCreateContext(uint32_t config, - uint32_t share, uint32_t glVersion) -{ - Renderer *fb = Renderer::get(); - if (!fb) { - return 0; - } +static void rcDestroyContext(uint32_t context) { + Renderer *fb = Renderer::get(); + if (!fb) { + return; + } - // To make it consistent with the guest, create GLES2 context when GL - // version==2 or 3 - HandleType ret = fb->createRenderContext(config, share, glVersion == 2 || glVersion == 3); - return ret; + fb->DestroyRenderContext(context); } -static void rcDestroyContext(uint32_t context) -{ - Renderer *fb = Renderer::get(); - if (!fb) { - return; - } +static uint32_t rcCreateWindowSurface(uint32_t config, uint32_t width, + uint32_t height) { + Renderer *fb = Renderer::get(); + if (!fb) { + return 0; + } - fb->DestroyRenderContext(context); + return fb->createWindowSurface(config, width, height); } -static uint32_t rcCreateWindowSurface(uint32_t config, - uint32_t width, uint32_t height) -{ - Renderer *fb = Renderer::get(); - if (!fb) { - return 0; - } +static void rcDestroyWindowSurface(uint32_t windowSurface) { + Renderer *fb = Renderer::get(); + if (!fb) { + return; + } - return fb->createWindowSurface(config, width, height); + fb->DestroyWindowSurface(windowSurface); } -static void rcDestroyWindowSurface(uint32_t windowSurface) -{ - Renderer *fb = Renderer::get(); - if (!fb) { - return; - } +static uint32_t rcCreateColorBuffer(uint32_t width, uint32_t height, + GLenum internalFormat) { + Renderer *fb = Renderer::get(); + if (!fb) { + return 0; + } - fb->DestroyWindowSurface( windowSurface ); + return fb->createColorBuffer(width, height, internalFormat); } -static uint32_t rcCreateColorBuffer(uint32_t width, - uint32_t height, GLenum internalFormat) -{ - Renderer *fb = Renderer::get(); - if (!fb) { - return 0; - } - - return fb->createColorBuffer(width, height, internalFormat); -} - -static int rcOpenColorBuffer2(uint32_t colorbuffer) -{ - Renderer *fb = Renderer::get(); - if (!fb) { - return -1; - } - return fb->openColorBuffer( colorbuffer ); +static int rcOpenColorBuffer2(uint32_t colorbuffer) { + Renderer *fb = Renderer::get(); + if (!fb) { + return -1; + } + return fb->openColorBuffer(colorbuffer); } // Deprecated, kept for compatibility with old system images only. // Use rcOpenColorBuffer2 instead. -static void rcOpenColorBuffer(uint32_t colorbuffer) -{ - (void) rcOpenColorBuffer2(colorbuffer); +static void rcOpenColorBuffer(uint32_t colorbuffer) { + (void)rcOpenColorBuffer2(colorbuffer); } -static void rcCloseColorBuffer(uint32_t colorbuffer) -{ - Renderer *fb = Renderer::get(); - if (!fb) { - return; - } - fb->closeColorBuffer( colorbuffer ); +static void rcCloseColorBuffer(uint32_t colorbuffer) { + Renderer *fb = Renderer::get(); + if (!fb) { + return; + } + fb->closeColorBuffer(colorbuffer); } -static int rcFlushWindowColorBuffer(uint32_t windowSurface) -{ - Renderer *fb = Renderer::get(); - if (!fb) { - return -1; - } - if (!fb->flushWindowSurfaceColorBuffer(windowSurface)) { - return -1; - } - return 0; +static int rcFlushWindowColorBuffer(uint32_t windowSurface) { + Renderer *fb = Renderer::get(); + if (!fb) { + return -1; + } + if (!fb->flushWindowSurfaceColorBuffer(windowSurface)) { + return -1; + } + return 0; } static void rcSetWindowColorBuffer(uint32_t windowSurface, - uint32_t colorBuffer) -{ - Renderer *fb = Renderer::get(); - if (!fb) { - return; - } - fb->setWindowSurfaceColorBuffer(windowSurface, colorBuffer); + uint32_t colorBuffer) { + Renderer *fb = Renderer::get(); + if (!fb) { + return; + } + fb->setWindowSurfaceColorBuffer(windowSurface, colorBuffer); } -static EGLint rcMakeCurrent(uint32_t context, - uint32_t drawSurf, uint32_t readSurf) -{ - Renderer *fb = Renderer::get(); - if (!fb) { - return EGL_FALSE; - } +static EGLint rcMakeCurrent(uint32_t context, uint32_t drawSurf, + uint32_t readSurf) { + Renderer *fb = Renderer::get(); + if (!fb) { + return EGL_FALSE; + } - bool ret = fb->bindContext(context, drawSurf, readSurf); + bool ret = fb->bindContext(context, drawSurf, readSurf); - return (ret ? EGL_TRUE : EGL_FALSE); + return (ret ? EGL_TRUE : EGL_FALSE); } -static void rcFBPost(uint32_t colorBuffer) -{ - WARNING("Not implemented"); +static void rcFBPost(uint32_t colorBuffer) { WARNING("Not implemented"); } + +static void rcFBSetSwapInterval(EGLint interval) { + // XXX: TBD - should be implemented } -static void rcFBSetSwapInterval(EGLint interval) -{ - // XXX: TBD - should be implemented +static void rcBindTexture(uint32_t colorBuffer) { + Renderer *fb = Renderer::get(); + if (!fb) { + return; + } + + fb->bindColorBufferToTexture(colorBuffer); } -static void rcBindTexture(uint32_t colorBuffer) -{ - Renderer *fb = Renderer::get(); - if (!fb) { - return; - } +static void rcBindRenderbuffer(uint32_t colorBuffer) { + Renderer *fb = Renderer::get(); + if (!fb) { + return; + } - fb->bindColorBufferToTexture(colorBuffer); + fb->bindColorBufferToRenderbuffer(colorBuffer); } -static void rcBindRenderbuffer(uint32_t colorBuffer) -{ - Renderer *fb = Renderer::get(); - if (!fb) { - return; - } - - fb->bindColorBufferToRenderbuffer(colorBuffer); +static EGLint rcColorBufferCacheFlush(uint32_t colorBuffer, EGLint postCount, + int forRead) { + // XXX: TBD - should be implemented + return 0; } -static EGLint rcColorBufferCacheFlush(uint32_t colorBuffer, - EGLint postCount, int forRead) -{ - // XXX: TBD - should be implemented - return 0; +static void rcReadColorBuffer(uint32_t colorBuffer, GLint x, GLint y, + GLint width, GLint height, GLenum format, + GLenum type, void *pixels) { + Renderer *fb = Renderer::get(); + if (!fb) { + return; + } + + fb->readColorBuffer(colorBuffer, x, y, width, height, format, type, pixels); } -static void rcReadColorBuffer(uint32_t colorBuffer, - GLint x, GLint y, - GLint width, GLint height, - GLenum format, GLenum type, void* pixels) -{ - Renderer *fb = Renderer::get(); - if (!fb) { - return; - } +static int rcUpdateColorBuffer(uint32_t colorBuffer, GLint x, GLint y, + GLint width, GLint height, GLenum format, + GLenum type, void *pixels) { + Renderer *fb = Renderer::get(); + if (!fb) { + return -1; + } - fb->readColorBuffer(colorBuffer, x, y, width, height, format, type, pixels); + fb->updateColorBuffer(colorBuffer, x, y, width, height, format, type, pixels); + return 0; } -static int rcUpdateColorBuffer(uint32_t colorBuffer, - GLint x, GLint y, - GLint width, GLint height, - GLenum format, GLenum type, void* pixels) -{ - Renderer *fb = Renderer::get(); - if (!fb) { - return -1; - } - - fb->updateColorBuffer(colorBuffer, x, y, width, height, format, type, pixels); +static uint32_t rcCreateClientImage(uint32_t context, EGLenum target, + GLuint buffer) { + Renderer *fb = Renderer::get(); + if (!fb) { return 0; + } + + return fb->createClientImage(context, target, buffer); } -static uint32_t rcCreateClientImage(uint32_t context, EGLenum target, GLuint buffer) -{ - Renderer *fb = Renderer::get(); - if (!fb) { - return 0; - } +static int rcDestroyClientImage(uint32_t image) { + Renderer *fb = Renderer::get(); + if (!fb) { + return 0; + } - return fb->createClientImage(context, target, buffer); -} - -static int rcDestroyClientImage(uint32_t image) -{ - Renderer *fb = Renderer::get(); - if (!fb) { - return 0; - } - - return fb->destroyClientImage(image); + return fb->destroyClientImage(image); } static void rcSelectChecksumCalculator(uint32_t protocol, uint32_t reserved) { - ChecksumCalculatorThreadInfo::setVersion(protocol); + ChecksumCalculatorThreadInfo::setVersion(protocol); } -int rcGetNumDisplays() { - return 1; -} +int rcGetNumDisplays() { return 1; } int rcGetDisplayWidth(uint32_t display_id) { - printf("%s: display_id=%d\n", __func__, display_id); - return DisplayManager::get()->display_info().horizontal_resolution; + printf("%s: display_id=%d\n", __func__, display_id); + return DisplayManager::get()->display_info().horizontal_resolution; } int rcGetDisplayHeight(uint32_t display_id) { - printf("%s: display_id=%d\n", __func__, display_id); - return DisplayManager::get()->display_info().vertical_resolution; + printf("%s: display_id=%d\n", __func__, display_id); + return DisplayManager::get()->display_info().vertical_resolution; } int rcGetDisplayDpiX(uint32_t display_id) { - printf("%s: display_id=%d\n", __func__, display_id); - return 120; + printf("%s: display_id=%d\n", __func__, display_id); + return 120; } int rcGetDisplayDpiY(uint32_t display_id) { - printf("%s: display_id=%d\n", __func__, display_id); - return 120; + printf("%s: display_id=%d\n", __func__, display_id); + return 120; } int rcGetDisplayVsyncPeriod(uint32_t display_id) { - printf("%s: display_id=%d\n", __func__, display_id); - return 1; + printf("%s: display_id=%d\n", __func__, display_id); + return 1; } static std::vector frame_layers; bool is_layer_blacklisted(const std::string &name) { - static std::vector blacklist = { - "Sprite", - }; - return std::find(blacklist.begin(), blacklist.end(), name) != blacklist.end(); + static std::vector blacklist = { + "Sprite", + }; + return std::find(blacklist.begin(), blacklist.end(), name) != blacklist.end(); } void rcPostLayer(const char *name, uint32_t color_buffer, int32_t sourceCropLeft, int32_t sourceCropTop, int32_t sourceCropRight, int32_t sourceCropBottom, int32_t displayFrameLeft, int32_t displayFrameTop, - int32_t displayFrameRight, int32_t displayFrameBottom) -{ - Renderable r{ - name, - color_buffer, - {displayFrameLeft, displayFrameTop, displayFrameRight, displayFrameBottom}, - {sourceCropLeft, sourceCropTop, sourceCropRight, sourceCropBottom} - }; - frame_layers.push_back(r); + int32_t displayFrameRight, int32_t displayFrameBottom) { + Renderable r{ + name, + color_buffer, + {displayFrameLeft, displayFrameTop, displayFrameRight, + displayFrameBottom}, + {sourceCropLeft, sourceCropTop, sourceCropRight, sourceCropBottom}}; + frame_layers.push_back(r); } -void rcPostAllLayersDone() -{ - if (composer) - composer->submit_layers(frame_layers); +void rcPostAllLayersDone() { + if (composer) composer->submit_layers(frame_layers); - frame_layers.clear(); + frame_layers.clear(); } -void initRenderControlContext(renderControl_decoder_context_t *dec) -{ - dec->rcGetRendererVersion = rcGetRendererVersion; - dec->rcGetEGLVersion = rcGetEGLVersion; - dec->rcQueryEGLString = rcQueryEGLString; - dec->rcGetGLString = rcGetGLString; - dec->rcGetNumConfigs = rcGetNumConfigs; - dec->rcGetConfigs = rcGetConfigs; - dec->rcChooseConfig = rcChooseConfig; - dec->rcGetFBParam = rcGetFBParam; - dec->rcCreateContext = rcCreateContext; - dec->rcDestroyContext = rcDestroyContext; - dec->rcCreateWindowSurface = rcCreateWindowSurface; - dec->rcDestroyWindowSurface = rcDestroyWindowSurface; - dec->rcCreateColorBuffer = rcCreateColorBuffer; - dec->rcOpenColorBuffer = rcOpenColorBuffer; - dec->rcCloseColorBuffer = rcCloseColorBuffer; - dec->rcSetWindowColorBuffer = rcSetWindowColorBuffer; - dec->rcFlushWindowColorBuffer = rcFlushWindowColorBuffer; - dec->rcMakeCurrent = rcMakeCurrent; - dec->rcFBPost = rcFBPost; - dec->rcFBSetSwapInterval = rcFBSetSwapInterval; - dec->rcBindTexture = rcBindTexture; - dec->rcBindRenderbuffer = rcBindRenderbuffer; - dec->rcColorBufferCacheFlush = rcColorBufferCacheFlush; - dec->rcReadColorBuffer = rcReadColorBuffer; - dec->rcUpdateColorBuffer = rcUpdateColorBuffer; - dec->rcOpenColorBuffer2 = rcOpenColorBuffer2; - dec->rcCreateClientImage = rcCreateClientImage; - dec->rcDestroyClientImage = rcDestroyClientImage; - dec->rcSelectChecksumCalculator = rcSelectChecksumCalculator; - dec->rcGetNumDisplays = rcGetNumDisplays; - dec->rcGetDisplayWidth = rcGetDisplayWidth; - dec->rcGetDisplayHeight = rcGetDisplayHeight; - dec->rcGetDisplayDpiX = rcGetDisplayDpiX; - dec->rcGetDisplayDpiY = rcGetDisplayDpiY; - dec->rcGetDisplayVsyncPeriod = rcGetDisplayVsyncPeriod; - dec->rcPostLayer = rcPostLayer; - dec->rcPostAllLayersDone = rcPostAllLayersDone; +void initRenderControlContext(renderControl_decoder_context_t *dec) { + dec->rcGetRendererVersion = rcGetRendererVersion; + dec->rcGetEGLVersion = rcGetEGLVersion; + dec->rcQueryEGLString = rcQueryEGLString; + dec->rcGetGLString = rcGetGLString; + dec->rcGetNumConfigs = rcGetNumConfigs; + dec->rcGetConfigs = rcGetConfigs; + dec->rcChooseConfig = rcChooseConfig; + dec->rcGetFBParam = rcGetFBParam; + dec->rcCreateContext = rcCreateContext; + dec->rcDestroyContext = rcDestroyContext; + dec->rcCreateWindowSurface = rcCreateWindowSurface; + dec->rcDestroyWindowSurface = rcDestroyWindowSurface; + dec->rcCreateColorBuffer = rcCreateColorBuffer; + dec->rcOpenColorBuffer = rcOpenColorBuffer; + dec->rcCloseColorBuffer = rcCloseColorBuffer; + dec->rcSetWindowColorBuffer = rcSetWindowColorBuffer; + dec->rcFlushWindowColorBuffer = rcFlushWindowColorBuffer; + dec->rcMakeCurrent = rcMakeCurrent; + dec->rcFBPost = rcFBPost; + dec->rcFBSetSwapInterval = rcFBSetSwapInterval; + dec->rcBindTexture = rcBindTexture; + dec->rcBindRenderbuffer = rcBindRenderbuffer; + dec->rcColorBufferCacheFlush = rcColorBufferCacheFlush; + dec->rcReadColorBuffer = rcReadColorBuffer; + dec->rcUpdateColorBuffer = rcUpdateColorBuffer; + dec->rcOpenColorBuffer2 = rcOpenColorBuffer2; + dec->rcCreateClientImage = rcCreateClientImage; + dec->rcDestroyClientImage = rcDestroyClientImage; + dec->rcSelectChecksumCalculator = rcSelectChecksumCalculator; + dec->rcGetNumDisplays = rcGetNumDisplays; + dec->rcGetDisplayWidth = rcGetDisplayWidth; + dec->rcGetDisplayHeight = rcGetDisplayHeight; + dec->rcGetDisplayDpiX = rcGetDisplayDpiX; + dec->rcGetDisplayDpiY = rcGetDisplayDpiY; + dec->rcGetDisplayVsyncPeriod = rcGetDisplayVsyncPeriod; + dec->rcPostLayer = rcPostLayer; + dec->rcPostAllLayersDone = rcPostAllLayersDone; } diff --git a/src/anbox/graphics/emugl/RenderControl.h b/src/anbox/graphics/emugl/RenderControl.h index 2867acc..ba707bc 100644 --- a/src/anbox/graphics/emugl/RenderControl.h +++ b/src/anbox/graphics/emugl/RenderControl.h @@ -23,10 +23,11 @@ namespace anbox { namespace graphics { class LayerComposer; -} // namespace graphics -} // namespace anbox +} // namespace graphics +} // namespace anbox void initRenderControlContext(renderControl_decoder_context_t *dec); -void registerLayerComposer(const std::shared_ptr &c); +void registerLayerComposer( + const std::shared_ptr &c); #endif diff --git a/src/anbox/graphics/emugl/RenderServer.cpp b/src/anbox/graphics/emugl/RenderServer.cpp index 5f23093..303e38c 100644 --- a/src/anbox/graphics/emugl/RenderServer.cpp +++ b/src/anbox/graphics/emugl/RenderServer.cpp @@ -15,11 +15,11 @@ */ #include "RenderServer.h" +#include +#include #include "RenderThread.h" #include "TcpStream.h" #include "UnixStream.h" -#include -#include #include "OpenglRender/render_api.h" @@ -29,123 +29,109 @@ typedef std::set RenderThreadsSet; -RenderServer::RenderServer() : - m_lock(), - m_listenSock(NULL), - m_exiting(false) -{ -} - -RenderServer::~RenderServer() -{ - delete m_listenSock; -} +RenderServer::RenderServer() : m_lock(), m_listenSock(NULL), m_exiting(false) {} +RenderServer::~RenderServer() { delete m_listenSock; } extern "C" int gRendererStreamMode; -RenderServer *RenderServer::create(char* addr, size_t addrLen) -{ - RenderServer *server = new RenderServer(); - if (!server) { - return NULL; - } +RenderServer *RenderServer::create(char *addr, size_t addrLen) { + RenderServer *server = new RenderServer(); + if (!server) { + return NULL; + } - if (gRendererStreamMode == RENDER_API_STREAM_MODE_TCP) { - server->m_listenSock = new TcpStream(); - } else { - server->m_listenSock = new UnixStream(); - } + if (gRendererStreamMode == RENDER_API_STREAM_MODE_TCP) { + server->m_listenSock = new TcpStream(); + } else { + server->m_listenSock = new UnixStream(); + } - char addrstr[SocketStream::MAX_ADDRSTR_LEN]; - if (server->m_listenSock->listen(addrstr) < 0) { - ERR("RenderServer::create failed to listen\n"); - delete server; - return NULL; - } + char addrstr[SocketStream::MAX_ADDRSTR_LEN]; + if (server->m_listenSock->listen(addrstr) < 0) { + ERR("RenderServer::create failed to listen\n"); + delete server; + return NULL; + } - size_t len = strlen(addrstr) + 1; - if (len > addrLen) { - ERR("RenderServer address name too big for provided buffer: %zu > %zu\n", - len, addrLen); - delete server; - return NULL; - } - memcpy(addr, addrstr, len); + size_t len = strlen(addrstr) + 1; + if (len > addrLen) { + ERR("RenderServer address name too big for provided buffer: %zu > %zu\n", + len, addrLen); + delete server; + return NULL; + } + memcpy(addr, addrstr, len); - return server; + return server; } -intptr_t RenderServer::main() -{ - RenderThreadsSet threads; +intptr_t RenderServer::main() { + RenderThreadsSet threads; - while(1) { - SocketStream *stream = m_listenSock->accept(); - if (!stream) { - fprintf(stderr,"Error accepting gles connection, ignoring.\n"); - continue; - } + while (1) { + SocketStream *stream = m_listenSock->accept(); + if (!stream) { + fprintf(stderr, "Error accepting gles connection, ignoring.\n"); + continue; + } - unsigned int clientFlags; - if (!stream->readFully(&clientFlags, sizeof(unsigned int))) { - fprintf(stderr,"Error reading clientFlags\n"); - delete stream; - continue; - } + unsigned int clientFlags; + if (!stream->readFully(&clientFlags, sizeof(unsigned int))) { + fprintf(stderr, "Error reading clientFlags\n"); + delete stream; + continue; + } - // check if we have been requested to exit while waiting on accept - if ((clientFlags & IOSTREAM_CLIENT_EXIT_SERVER) != 0) { - m_exiting = true; - delete stream; - break; - } + // check if we have been requested to exit while waiting on accept + if ((clientFlags & IOSTREAM_CLIENT_EXIT_SERVER) != 0) { + m_exiting = true; + delete stream; + break; + } - RenderThread *rt = RenderThread::create(stream, &m_lock); - if (!rt) { - fprintf(stderr,"Failed to create RenderThread\n"); - delete stream; - } else if (!rt->start()) { - fprintf(stderr,"Failed to start RenderThread\n"); - delete rt; - delete stream; - } - - // - // remove from the threads list threads which are - // no longer running - // - for (RenderThreadsSet::iterator n,t = threads.begin(); - t != threads.end(); - t = n) { - // first find next iterator - n = t; - n++; - - // delete and erase the current iterator - // if thread is no longer running - if ((*t)->isFinished()) { - delete (*t); - threads.erase(t); - } - } - - // if the thread has been created and started, insert it to the list - if (rt) - threads.insert(rt); + RenderThread *rt = RenderThread::create(stream, &m_lock); + if (!rt) { + fprintf(stderr, "Failed to create RenderThread\n"); + delete stream; + } else if (!rt->start()) { + fprintf(stderr, "Failed to start RenderThread\n"); + delete rt; + delete stream; } // - // Wait for all threads to finish + // remove from the threads list threads which are + // no longer running // - for (RenderThreadsSet::iterator t = threads.begin(); - t != threads.end(); - t++) { - (*t)->forceStop(); - (*t)->wait(NULL); + for (RenderThreadsSet::iterator n, t = threads.begin(); t != threads.end(); + t = n) { + // first find next iterator + n = t; + n++; + + // delete and erase the current iterator + // if thread is no longer running + if ((*t)->isFinished()) { delete (*t); + threads.erase(t); + } } - threads.clear(); - return 0; + // if the thread has been created and started, insert it to the list + if (rt) threads.insert(rt); + } + + // + // Wait for all threads to finish + // + for (RenderThreadsSet::iterator t = threads.begin(); t != threads.end(); + t++) { + (*t)->forceStop(); + (*t)->wait(NULL); + delete (*t); + } + threads.clear(); + + return 0; } diff --git a/src/anbox/graphics/emugl/RenderServer.h b/src/anbox/graphics/emugl/RenderServer.h index 8be8a17..6d8e564 100644 --- a/src/anbox/graphics/emugl/RenderServer.h +++ b/src/anbox/graphics/emugl/RenderServer.h @@ -20,23 +20,22 @@ #include "emugl/common/mutex.h" #include "emugl/common/thread.h" -class RenderServer : public emugl::Thread -{ -public: - static RenderServer *create(char* addr, size_t addrLen); - virtual ~RenderServer(); +class RenderServer : public emugl::Thread { + public: + static RenderServer *create(char *addr, size_t addrLen); + virtual ~RenderServer(); - virtual intptr_t main(); + virtual intptr_t main(); - bool isExiting() const { return m_exiting; } + bool isExiting() const { return m_exiting; } -private: - RenderServer(); + private: + RenderServer(); -private: - emugl::Mutex m_lock; - SocketStream *m_listenSock; - bool m_exiting; + private: + emugl::Mutex m_lock; + SocketStream *m_listenSock; + bool m_exiting; }; #endif diff --git a/src/anbox/graphics/emugl/RenderThread.cpp b/src/anbox/graphics/emugl/RenderThread.cpp index 2185e8c..c4252be 100644 --- a/src/anbox/graphics/emugl/RenderThread.cpp +++ b/src/anbox/graphics/emugl/RenderThread.cpp @@ -15,107 +15,102 @@ */ #include "RenderThread.h" -#include "Renderer.h" #include "ReadBuffer.h" #include "RenderControl.h" #include "RenderThreadInfo.h" +#include "Renderer.h" #include "TimeUtils.h" -#include "OpenGLESDispatch/EGLDispatch.h" -#include "OpenGLESDispatch/GLESv2Dispatch.h" -#include "OpenGLESDispatch/GLESv1Dispatch.h" #include "../../../shared/OpenglCodecCommon/ChecksumCalculatorThreadInfo.h" +#include "OpenGLESDispatch/EGLDispatch.h" +#include "OpenGLESDispatch/GLESv1Dispatch.h" +#include "OpenGLESDispatch/GLESv2Dispatch.h" -#define STREAM_BUFFER_SIZE 4*1024*1024 +#define STREAM_BUFFER_SIZE 4 * 1024 * 1024 -RenderThread::RenderThread(IOStream *stream, emugl::Mutex *lock) : - emugl::Thread(), - m_lock(lock), - m_stream(stream) {} +RenderThread::RenderThread(IOStream *stream, emugl::Mutex *lock) + : emugl::Thread(), m_lock(lock), m_stream(stream) {} -RenderThread::~RenderThread() { - delete m_stream; -} +RenderThread::~RenderThread() { delete m_stream; } // static -RenderThread* RenderThread::create(IOStream *stream, emugl::Mutex *lock) { - return new RenderThread(stream, lock); +RenderThread *RenderThread::create(IOStream *stream, emugl::Mutex *lock) { + return new RenderThread(stream, lock); } -void RenderThread::forceStop() { - m_stream->forceStop(); -} +void RenderThread::forceStop() { m_stream->forceStop(); } intptr_t RenderThread::main() { - RenderThreadInfo tInfo; - ChecksumCalculatorThreadInfo tChecksumInfo; + RenderThreadInfo tInfo; + ChecksumCalculatorThreadInfo tChecksumInfo; - // - // initialize decoders - // - tInfo.m_glDec.initGL(gles1_dispatch_get_proc_func, NULL); - tInfo.m_gl2Dec.initGL(gles2_dispatch_get_proc_func, NULL); - initRenderControlContext(&tInfo.m_rcDec); + // + // initialize decoders + // + tInfo.m_glDec.initGL(gles1_dispatch_get_proc_func, NULL); + tInfo.m_gl2Dec.initGL(gles2_dispatch_get_proc_func, NULL); + initRenderControlContext(&tInfo.m_rcDec); - ReadBuffer readBuf(STREAM_BUFFER_SIZE); - - while (1) { - - int stat = readBuf.getData(m_stream); - if (stat <= 0) { - break; - } - - bool progress; - do { - progress = false; - - m_lock->lock(); - // - // try to process some of the command buffer using the GLESv1 decoder - // - size_t last = tInfo.m_glDec.decode(readBuf.buf(), readBuf.validData(), m_stream); - if (last > 0) { - progress = true; - readBuf.consume(last); - } - - // - // try to process some of the command buffer using the GLESv2 decoder - // - last = tInfo.m_gl2Dec.decode(readBuf.buf(), readBuf.validData(), m_stream); - if (last > 0) { - progress = true; - readBuf.consume(last); - } - - // - // try to process some of the command buffer using the - // renderControl decoder - // - last = tInfo.m_rcDec.decode(readBuf.buf(), readBuf.validData(), m_stream); - if (last > 0) { - readBuf.consume(last); - progress = true; - } - - m_lock->unlock(); - - } while( progress ); + ReadBuffer readBuf(STREAM_BUFFER_SIZE); + while (1) { + int stat = readBuf.getData(m_stream); + if (stat <= 0) { + break; } - // - // Release references to the current thread's context/surfaces if any - // - Renderer::get()->bindContext(0, 0, 0); - if (tInfo.currContext || tInfo.currDrawSurf || tInfo.currReadSurf) { - fprintf(stderr, "ERROR: RenderThread exiting with current context/surfaces\n"); - } + bool progress; + do { + progress = false; - Renderer::get()->drainWindowSurface(); + m_lock->lock(); + // + // try to process some of the command buffer using the GLESv1 decoder + // + size_t last = + tInfo.m_glDec.decode(readBuf.buf(), readBuf.validData(), m_stream); + if (last > 0) { + progress = true; + readBuf.consume(last); + } - Renderer::get()->drainRenderContext(); + // + // try to process some of the command buffer using the GLESv2 decoder + // + last = + tInfo.m_gl2Dec.decode(readBuf.buf(), readBuf.validData(), m_stream); + if (last > 0) { + progress = true; + readBuf.consume(last); + } - return 0; + // + // try to process some of the command buffer using the + // renderControl decoder + // + last = tInfo.m_rcDec.decode(readBuf.buf(), readBuf.validData(), m_stream); + if (last > 0) { + readBuf.consume(last); + progress = true; + } + + m_lock->unlock(); + + } while (progress); + } + + // + // Release references to the current thread's context/surfaces if any + // + Renderer::get()->bindContext(0, 0, 0); + if (tInfo.currContext || tInfo.currDrawSurf || tInfo.currReadSurf) { + fprintf(stderr, + "ERROR: RenderThread exiting with current context/surfaces\n"); + } + + Renderer::get()->drainWindowSurface(); + + Renderer::get()->drainRenderContext(); + + return 0; } diff --git a/src/anbox/graphics/emugl/RenderThread.h b/src/anbox/graphics/emugl/RenderThread.h index 7487764..b2bbc71 100644 --- a/src/anbox/graphics/emugl/RenderThread.h +++ b/src/anbox/graphics/emugl/RenderThread.h @@ -24,35 +24,35 @@ // A class used to model a thread of the RenderServer. Each one of them // handles a single guest client / protocol byte stream. class RenderThread : public emugl::Thread { -public: - // Create a new RenderThread instance. - // |stream| is an input stream that will be read from the thread, - // and deleted by it when it exits. - // |mutex| is a pointer to a shared mutex used to serialize - // decoding operations between all threads. - // TODO(digit): Why is this needed here? Shouldn't this be handled - // by the decoders themselves or at a lower-level? - static RenderThread* create(IOStream* stream, emugl::Mutex* mutex); + public: + // Create a new RenderThread instance. + // |stream| is an input stream that will be read from the thread, + // and deleted by it when it exits. + // |mutex| is a pointer to a shared mutex used to serialize + // decoding operations between all threads. + // TODO(digit): Why is this needed here? Shouldn't this be handled + // by the decoders themselves or at a lower-level? + static RenderThread* create(IOStream* stream, emugl::Mutex* mutex); - // Destructor. - virtual ~RenderThread(); + // Destructor. + virtual ~RenderThread(); - // Returns true iff the thread has finished. - // Note that this also means that the thread's stack has been - bool isFinished() { return tryWait(NULL); } + // Returns true iff the thread has finished. + // Note that this also means that the thread's stack has been + bool isFinished() { return tryWait(NULL); } - // Force a thread to stop. - void forceStop(); + // Force a thread to stop. + void forceStop(); -private: - RenderThread(); // No default constructor + private: + RenderThread(); // No default constructor - RenderThread(IOStream* stream, emugl::Mutex* mutex); + RenderThread(IOStream* stream, emugl::Mutex* mutex); - virtual intptr_t main(); + virtual intptr_t main(); - emugl::Mutex* m_lock; - IOStream* m_stream; + emugl::Mutex* m_lock; + IOStream* m_stream; }; #endif diff --git a/src/anbox/graphics/emugl/RenderThreadInfo.cpp b/src/anbox/graphics/emugl/RenderThreadInfo.cpp index e88069d..69c9f99 100644 --- a/src/anbox/graphics/emugl/RenderThreadInfo.cpp +++ b/src/anbox/graphics/emugl/RenderThreadInfo.cpp @@ -22,22 +22,18 @@ namespace { class ThreadInfoStore : public ::emugl::ThreadStore { -public: - ThreadInfoStore() : ::emugl::ThreadStore(NULL) {} + public: + ThreadInfoStore() : ::emugl::ThreadStore(NULL) {} }; } // namespace static ::emugl::LazyInstance s_tls = LAZY_INSTANCE_INIT; -RenderThreadInfo::RenderThreadInfo() { - s_tls->set(this); -} +RenderThreadInfo::RenderThreadInfo() { s_tls->set(this); } -RenderThreadInfo::~RenderThreadInfo() { - s_tls->set(NULL); -} +RenderThreadInfo::~RenderThreadInfo() { s_tls->set(NULL); } RenderThreadInfo* RenderThreadInfo::get() { - return static_cast(s_tls->get()); + return static_cast(s_tls->get()); } diff --git a/src/anbox/graphics/emugl/RenderThreadInfo.h b/src/anbox/graphics/emugl/RenderThreadInfo.h index fd15433..f246ae5 100644 --- a/src/anbox/graphics/emugl/RenderThreadInfo.h +++ b/src/anbox/graphics/emugl/RenderThreadInfo.h @@ -16,10 +16,10 @@ #ifndef _LIB_OPENGL_RENDER_THREAD_INFO_H #define _LIB_OPENGL_RENDER_THREAD_INFO_H -#include "RenderContext.h" -#include "WindowSurface.h" #include "GLESv1Decoder.h" #include "GLESv2Decoder.h" +#include "RenderContext.h" +#include "WindowSurface.h" #include "renderControl_dec.h" #include @@ -30,31 +30,31 @@ typedef std::set WindowSurfaceSet; // A class used to model the state of each RenderThread related struct RenderThreadInfo { - // Create new instance. Only call this once per thread. - // Future callls to get() will return this instance until - // it is destroyed. - RenderThreadInfo(); + // Create new instance. Only call this once per thread. + // Future callls to get() will return this instance until + // it is destroyed. + RenderThreadInfo(); - // Destructor. - ~RenderThreadInfo(); + // Destructor. + ~RenderThreadInfo(); - // Return the current thread's instance, if any, or NULL. - static RenderThreadInfo* get(); + // Return the current thread's instance, if any, or NULL. + static RenderThreadInfo* get(); - // Current EGL context, draw surface and read surface. - RenderContextPtr currContext; - WindowSurfacePtr currDrawSurf; - WindowSurfacePtr currReadSurf; + // Current EGL context, draw surface and read surface. + RenderContextPtr currContext; + WindowSurfacePtr currDrawSurf; + WindowSurfacePtr currReadSurf; - // Decoder states. - GLESv1Decoder m_glDec; - GLESv2Decoder m_gl2Dec; - renderControl_decoder_context_t m_rcDec; + // Decoder states. + GLESv1Decoder m_glDec; + GLESv2Decoder m_gl2Dec; + renderControl_decoder_context_t m_rcDec; - // all the contexts that are created by this render thread - ThreadContextSet m_contextSet; - // all the window surfaces that are created by this render thread - WindowSurfaceSet m_windowSet; + // all the contexts that are created by this render thread + ThreadContextSet m_contextSet; + // all the window surfaces that are created by this render thread + WindowSurfaceSet m_windowSet; }; #endif diff --git a/src/anbox/graphics/emugl/RenderWindow.cpp b/src/anbox/graphics/emugl/RenderWindow.cpp index a734045..a1bfe51 100644 --- a/src/anbox/graphics/emugl/RenderWindow.cpp +++ b/src/anbox/graphics/emugl/RenderWindow.cpp @@ -14,51 +14,51 @@ #include "RenderWindow.h" +#include "Renderer.h" #include "emugl/common/logging.h" #include "emugl/common/message_channel.h" #include "emugl/common/mutex.h" #include "emugl/common/thread.h" -#include "Renderer.h" +#include +#include #include #include -#include -#include #define DEBUG 0 #if DEBUG -# define D(...) my_debug(__PRETTY_FUNCTION__, __LINE__, __VA_ARGS__) +#define D(...) my_debug(__PRETTY_FUNCTION__, __LINE__, __VA_ARGS__) #else -# define D(...) ((void)0) +#define D(...) ((void)0) #endif namespace { #if DEBUG void my_debug(const char* function, int line, const char* format, ...) { - static ::emugl::Mutex mutex; - va_list args; - va_start(args, format); - mutex.lock(); - fprintf(stderr, "%s:%d:", function, line); - vfprintf(stderr, format, args); - mutex.unlock(); - va_end(args); + static ::emugl::Mutex mutex; + va_list args; + va_start(args, format); + mutex.lock(); + fprintf(stderr, "%s:%d:", function, line); + vfprintf(stderr, format, args); + mutex.unlock(); + va_end(args); } #endif // List of possible commands to send to the render window thread from // the main one. enum Command { - CMD_INITIALIZE, - CMD_SET_POST_CALLBACK, - CMD_SETUP_SUBWINDOW, - CMD_REMOVE_SUBWINDOW, - CMD_SET_ROTATION, - CMD_SET_TRANSLATION, - CMD_REPAINT, - CMD_FINALIZE, + CMD_INITIALIZE, + CMD_SET_POST_CALLBACK, + CMD_SETUP_SUBWINDOW, + CMD_REMOVE_SUBWINDOW, + CMD_SET_ROTATION, + CMD_SET_TRANSLATION, + CMD_REPAINT, + CMD_FINALIZE, }; } // namespace @@ -66,74 +66,73 @@ enum Command { // A single message sent from the main thread to the render window thread. // |cmd| determines which fields are valid to read. struct RenderWindowMessage { - Command cmd; - union { - // CMD_INITIALIZE - struct { - EGLNativeDisplayType nativeDisplay; - } init; + Command cmd; + union { + // CMD_INITIALIZE + struct { + EGLNativeDisplayType nativeDisplay; + } init; - // CMD_SET_POST_CALLBACK - struct { - OnPostFn on_post; - void* on_post_context; - } set_post_callback; + // CMD_SET_POST_CALLBACK + struct { + OnPostFn on_post; + void* on_post_context; + } set_post_callback; - // CMD_SETUP_SUBWINDOW - struct { - FBNativeWindowType parent; - int wx; - int wy; - int ww; - int wh; - int fbw; - int fbh; - float dpr; - float rotation; - } subwindow; + // CMD_SETUP_SUBWINDOW + struct { + FBNativeWindowType parent; + int wx; + int wy; + int ww; + int wh; + int fbw; + int fbh; + float dpr; + float rotation; + } subwindow; - // CMD_SET_TRANSLATION; - struct { - float px; - float py; - } trans; + // CMD_SET_TRANSLATION; + struct { + float px; + float py; + } trans; - // CMD_SET_ROTATION - float rotation; + // CMD_SET_ROTATION + float rotation; - // result of operations. - bool result; - }; + // result of operations. + bool result; + }; - // Process the current message, and updates its |result| field. - // Returns true on success, or false on failure. - bool process() const { - const RenderWindowMessage& msg = *this; - Renderer* fb; - bool result = false; - switch (msg.cmd) { - case CMD_INITIALIZE: - D("CMD_INITIALIZE\n"); - GL_LOG("RenderWindow: CMD_INITIALIZE"); - result = Renderer::initialize(msg.init.nativeDisplay); - break; + // Process the current message, and updates its |result| field. + // Returns true on success, or false on failure. + bool process() const { + const RenderWindowMessage& msg = *this; + Renderer* fb; + bool result = false; + switch (msg.cmd) { + case CMD_INITIALIZE: + D("CMD_INITIALIZE\n"); + GL_LOG("RenderWindow: CMD_INITIALIZE"); + result = Renderer::initialize(msg.init.nativeDisplay); + break; - case CMD_FINALIZE: - D("CMD_FINALIZE\n"); - // this command may be issued even when frame buffer is not - // yet created (e.g. if CMD_INITIALIZE failed), - // so make sure we check if it is there before finalizing - if (const auto fb = Renderer::get()) { - fb->finalize(); - } - result = true; - break; - - default: - ; + case CMD_FINALIZE: + D("CMD_FINALIZE\n"); + // this command may be issued even when frame buffer is not + // yet created (e.g. if CMD_INITIALIZE failed), + // so make sure we check if it is there before finalizing + if (const auto fb = Renderer::get()) { + fb->finalize(); } - return result; + result = true; + break; + + default:; } + return result; + } }; // Simple synchronization structure used to exchange data between the @@ -159,43 +158,43 @@ struct RenderWindowMessage { // canWriteCmd.signal() // class RenderWindowChannel { -public: - RenderWindowChannel() : mIn(), mOut() {} - ~RenderWindowChannel() {} + public: + RenderWindowChannel() : mIn(), mOut() {} + ~RenderWindowChannel() {} - // Send a message from the main thread. - // Note that the content of |msg| is copied into the channel. - // Returns with the command's result (true or false). - bool sendMessageAndGetResult(const RenderWindowMessage& msg) { - D("msg.cmd=%d\n", msg.cmd); - mIn.send(msg); - D("waiting for result\n"); - bool result = false; - mOut.receive(&result); - D("result=%s\n", result ? "success" : "failure"); - return result; - } + // Send a message from the main thread. + // Note that the content of |msg| is copied into the channel. + // Returns with the command's result (true or false). + bool sendMessageAndGetResult(const RenderWindowMessage& msg) { + D("msg.cmd=%d\n", msg.cmd); + mIn.send(msg); + D("waiting for result\n"); + bool result = false; + mOut.receive(&result); + D("result=%s\n", result ? "success" : "failure"); + return result; + } - // Receive a message from the render window thread. - // On exit, |*msg| gets a copy of the message. The caller - // must always call sendResult() after processing the message. - void receiveMessage(RenderWindowMessage* msg) { - D("entering\n"); - mIn.receive(msg); - D("message cmd=%d\n", msg->cmd); - } + // Receive a message from the render window thread. + // On exit, |*msg| gets a copy of the message. The caller + // must always call sendResult() after processing the message. + void receiveMessage(RenderWindowMessage* msg) { + D("entering\n"); + mIn.receive(msg); + D("message cmd=%d\n", msg->cmd); + } - // Send result from the render window thread to the main one. - // Must always be called after receiveMessage(). - void sendResult(bool result) { - D("waiting to send result (%s)\n", result ? "success" : "failure"); - mOut.send(result); - D("result sent\n"); - } + // Send result from the render window thread to the main one. + // Must always be called after receiveMessage(). + void sendResult(bool result) { + D("waiting to send result (%s)\n", result ? "success" : "failure"); + mOut.send(result); + D("result sent\n"); + } -private: - emugl::MessageChannel mIn; - emugl::MessageChannel mOut; + private: + emugl::MessageChannel mIn; + emugl::MessageChannel mOut; }; namespace { @@ -207,162 +206,152 @@ namespace { // The thread ends with a CMD_FINALIZE. // class RenderWindowThread : public emugl::Thread { -public: - RenderWindowThread(RenderWindowChannel* channel) : mChannel(channel) {} + public: + RenderWindowThread(RenderWindowChannel* channel) : mChannel(channel) {} - virtual intptr_t main() { - D("Entering render window thread thread\n"); - sigset_t set; - sigfillset(&set); - pthread_sigmask(SIG_SETMASK, &set, NULL); - bool running = true; - while (running) { - RenderWindowMessage msg; + virtual intptr_t main() { + D("Entering render window thread thread\n"); + sigset_t set; + sigfillset(&set); + pthread_sigmask(SIG_SETMASK, &set, NULL); + bool running = true; + while (running) { + RenderWindowMessage msg; - D("Waiting for message from main thread\n"); - mChannel->receiveMessage(&msg); + D("Waiting for message from main thread\n"); + mChannel->receiveMessage(&msg); - bool result = msg.process(); - if (msg.cmd == CMD_FINALIZE) { - running = false; - } + bool result = msg.process(); + if (msg.cmd == CMD_FINALIZE) { + running = false; + } - D("Sending result (%s) to main thread\n", result ? "success" : "failure"); - mChannel->sendResult(result); - } - D("Exiting thread\n"); - return 0; + D("Sending result (%s) to main thread\n", result ? "success" : "failure"); + mChannel->sendResult(result); } + D("Exiting thread\n"); + return 0; + } -private: - RenderWindowChannel* mChannel; + private: + RenderWindowChannel* mChannel; }; } // namespace -RenderWindow::RenderWindow(EGLNativeDisplayType native_display, - bool use_thread) : - mValid(false), - mHasSubWindow(false), - mThread(NULL), - mChannel(NULL) { - if (use_thread) { - mChannel = new RenderWindowChannel(); - mThread = new RenderWindowThread(mChannel); - mThread->start(); - } +RenderWindow::RenderWindow(EGLNativeDisplayType native_display, bool use_thread) + : mValid(false), mHasSubWindow(false), mThread(NULL), mChannel(NULL) { + if (use_thread) { + mChannel = new RenderWindowChannel(); + mThread = new RenderWindowThread(mChannel); + mThread->start(); + } - RenderWindowMessage msg; - msg.cmd = CMD_INITIALIZE; - msg.init.nativeDisplay = native_display; - mValid = processMessage(msg); + RenderWindowMessage msg; + msg.cmd = CMD_INITIALIZE; + msg.init.nativeDisplay = native_display; + mValid = processMessage(msg); } RenderWindow::~RenderWindow() { - D("Entering\n"); - removeSubWindow(); - D("Sending CMD_FINALIZE\n"); - RenderWindowMessage msg; - msg.cmd = CMD_FINALIZE; - (void) processMessage(msg); + D("Entering\n"); + removeSubWindow(); + D("Sending CMD_FINALIZE\n"); + RenderWindowMessage msg; + msg.cmd = CMD_FINALIZE; + (void)processMessage(msg); - if (mThread) { - mThread->wait(NULL); - delete mThread; - delete mChannel; - } + if (mThread) { + mThread->wait(NULL); + delete mThread; + delete mChannel; + } } bool RenderWindow::getHardwareStrings(const char** vendor, const char** renderer, const char** version) { - D("Entering\n"); - // TODO(digit): Move this to render window thread. - Renderer* fb = Renderer::get(); - if (!fb) { - D("No framebuffer!\n"); - return false; - } - fb->getGLStrings(vendor, renderer, version); - D("Exiting vendor=[%s] renderer=[%s] version=[%s]\n", - *vendor, *renderer, *version); + D("Entering\n"); + // TODO(digit): Move this to render window thread. + Renderer* fb = Renderer::get(); + if (!fb) { + D("No framebuffer!\n"); + return false; + } + fb->getGLStrings(vendor, renderer, version); + D("Exiting vendor=[%s] renderer=[%s] version=[%s]\n", *vendor, *renderer, + *version); - return true; + return true; } -bool RenderWindow::setupSubWindow(FBNativeWindowType window, - int wx, - int wy, - int ww, - int wh, - int fbw, - int fbh, - float dpr, +bool RenderWindow::setupSubWindow(FBNativeWindowType window, int wx, int wy, + int ww, int wh, int fbw, int fbh, float dpr, float zRot) { - D("Entering mHasSubWindow=%s\n", mHasSubWindow ? "true" : "false"); + D("Entering mHasSubWindow=%s\n", mHasSubWindow ? "true" : "false"); - RenderWindowMessage msg; - msg.cmd = CMD_SETUP_SUBWINDOW; - msg.subwindow.parent = window; - msg.subwindow.wx = wx; - msg.subwindow.wy = wy; - msg.subwindow.ww = ww; - msg.subwindow.wh = wh; - msg.subwindow.fbw = fbw; - msg.subwindow.fbh = fbh; - msg.subwindow.dpr = dpr; - msg.subwindow.rotation = zRot; + RenderWindowMessage msg; + msg.cmd = CMD_SETUP_SUBWINDOW; + msg.subwindow.parent = window; + msg.subwindow.wx = wx; + msg.subwindow.wy = wy; + msg.subwindow.ww = ww; + msg.subwindow.wh = wh; + msg.subwindow.fbw = fbw; + msg.subwindow.fbh = fbh; + msg.subwindow.dpr = dpr; + msg.subwindow.rotation = zRot; - mHasSubWindow = processMessage(msg); - D("Exiting mHasSubWindow=%s\n", mHasSubWindow ? "true" : "false"); - return mHasSubWindow; + mHasSubWindow = processMessage(msg); + D("Exiting mHasSubWindow=%s\n", mHasSubWindow ? "true" : "false"); + return mHasSubWindow; } bool RenderWindow::removeSubWindow() { - D("Entering mHasSubWindow=%s\n", mHasSubWindow ? "true" : "false"); - if (!mHasSubWindow) { - return false; - } - mHasSubWindow = false; + D("Entering mHasSubWindow=%s\n", mHasSubWindow ? "true" : "false"); + if (!mHasSubWindow) { + return false; + } + mHasSubWindow = false; - RenderWindowMessage msg; - msg.cmd = CMD_REMOVE_SUBWINDOW; - bool result = processMessage(msg); - D("Exiting result=%s\n", result ? "success" : "failure"); - return result; + RenderWindowMessage msg; + msg.cmd = CMD_REMOVE_SUBWINDOW; + bool result = processMessage(msg); + D("Exiting result=%s\n", result ? "success" : "failure"); + return result; } void RenderWindow::setRotation(float zRot) { - D("Entering rotation=%f\n", zRot); - RenderWindowMessage msg; - msg.cmd = CMD_SET_ROTATION; - msg.rotation = zRot; - (void) processMessage(msg); - D("Exiting\n"); + D("Entering rotation=%f\n", zRot); + RenderWindowMessage msg; + msg.cmd = CMD_SET_ROTATION; + msg.rotation = zRot; + (void)processMessage(msg); + D("Exiting\n"); } void RenderWindow::setTranslation(float px, float py) { - D("Entering translation=%f,%f\n", px, py); - RenderWindowMessage msg; - msg.cmd = CMD_SET_TRANSLATION; - msg.trans.px = px; - msg.trans.py = py; - (void) processMessage(msg); - D("Exiting\n"); + D("Entering translation=%f,%f\n", px, py); + RenderWindowMessage msg; + msg.cmd = CMD_SET_TRANSLATION; + msg.trans.px = px; + msg.trans.py = py; + (void)processMessage(msg); + D("Exiting\n"); } void RenderWindow::repaint() { - D("Entering\n"); - RenderWindowMessage msg; - msg.cmd = CMD_REPAINT; - (void) processMessage(msg); - D("Exiting\n"); + D("Entering\n"); + RenderWindowMessage msg; + msg.cmd = CMD_REPAINT; + (void)processMessage(msg); + D("Exiting\n"); } bool RenderWindow::processMessage(const RenderWindowMessage& msg) { - if (mChannel) { - return mChannel->sendMessageAndGetResult(msg); - } else { - return msg.process(); - } + if (mChannel) { + return mChannel->sendMessageAndGetResult(msg); + } else { + return msg.process(); + } } diff --git a/src/anbox/graphics/emugl/RenderWindow.h b/src/anbox/graphics/emugl/RenderWindow.h index dd2eb2f..a5f6c57 100644 --- a/src/anbox/graphics/emugl/RenderWindow.h +++ b/src/anbox/graphics/emugl/RenderWindow.h @@ -47,84 +47,76 @@ struct RenderWindowMessage; // 6) Call repaint() to force a repaint(). // class RenderWindow { -public: - // Create new instance. |width| and |height| are the dimensions of the - // emulated accelerated framebuffer. |use_thread| can be true to force - // the use of a separate thread, which might be required on some platforms - // to avoid GL-realted corruption issues in the main window. Call - // isValid() after construction to verify that it worked properly. - // - // |use_sub_window| is true if the client will call setupSubWindow(), - // and false if it will call setPostCallback(). - // - // Note that this call doesn't display anything, it just initializes - // the library, use setupSubWindow() to display something. - RenderWindow(EGLNativeDisplayType native_display, bool use_thread); + public: + // Create new instance. |width| and |height| are the dimensions of the + // emulated accelerated framebuffer. |use_thread| can be true to force + // the use of a separate thread, which might be required on some platforms + // to avoid GL-realted corruption issues in the main window. Call + // isValid() after construction to verify that it worked properly. + // + // |use_sub_window| is true if the client will call setupSubWindow(), + // and false if it will call setPostCallback(). + // + // Note that this call doesn't display anything, it just initializes + // the library, use setupSubWindow() to display something. + RenderWindow(EGLNativeDisplayType native_display, bool use_thread); - // Destructor. This will automatically call removeSubWindow() is needed. - ~RenderWindow(); + // Destructor. This will automatically call removeSubWindow() is needed. + ~RenderWindow(); - // Returns true if the RenderWindow instance is valid, which really - // means that the constructor succeeded. - bool isValid() const { return mValid; } + // Returns true if the RenderWindow instance is valid, which really + // means that the constructor succeeded. + bool isValid() const { return mValid; } - // Return misc. GL strings to the caller. On success, return true and sets - // |*vendor| to the GL vendor string, |*renderer| to the GL renderer one, - // and |*version| to the GL version one. On failure, return false. - bool getHardwareStrings(const char** vendor, - const char** renderer, - const char** version); + // Return misc. GL strings to the caller. On success, return true and sets + // |*vendor| to the GL vendor string, |*renderer| to the GL renderer one, + // and |*version| to the GL version one. On failure, return false. + bool getHardwareStrings(const char** vendor, const char** renderer, + const char** version); - // Start displaying the emulated framebuffer using a sub-window of a - // parent |window| id. |wx|, |wy|, |ww| and |wh| are the position - // and dimension of the sub-window, relative to its parent. - // |fbw| and |fbh| are the dimensions of the underlying guest framebuffer. - // |dpr| is the device pixel ratio for the monitor, which is required for - // higher-density displays (such as retina). - // |rotation| is a clockwise-rotation for the content. Only multiples of - // 90. are accepted. Returns true on success, false otherwise. - // - // If the subwindow already exists, this function will update - // the dimensions of the subwindow, backing framebuffer, and rendering - // pipeline to reflect the new values. - // - // One can call removeSubWindow() to remove the sub-window. - bool setupSubWindow(FBNativeWindowType window, - int wx, - int wy, - int ww, - int wh, - int fbw, - int fbh, - float dpr, - float rotation); + // Start displaying the emulated framebuffer using a sub-window of a + // parent |window| id. |wx|, |wy|, |ww| and |wh| are the position + // and dimension of the sub-window, relative to its parent. + // |fbw| and |fbh| are the dimensions of the underlying guest framebuffer. + // |dpr| is the device pixel ratio for the monitor, which is required for + // higher-density displays (such as retina). + // |rotation| is a clockwise-rotation for the content. Only multiples of + // 90. are accepted. Returns true on success, false otherwise. + // + // If the subwindow already exists, this function will update + // the dimensions of the subwindow, backing framebuffer, and rendering + // pipeline to reflect the new values. + // + // One can call removeSubWindow() to remove the sub-window. + bool setupSubWindow(FBNativeWindowType window, int wx, int wy, int ww, int wh, + int fbw, int fbh, float dpr, float rotation); - // Remove the sub-window created by calling setupSubWindow(). - // Note that this doesn't discard the content of the emulated framebuffer, - // it just hides it from the main window. Returns true on success, false - // otherwise. - bool removeSubWindow(); + // Remove the sub-window created by calling setupSubWindow(). + // Note that this doesn't discard the content of the emulated framebuffer, + // it just hides it from the main window. Returns true on success, false + // otherwise. + bool removeSubWindow(); - // Change the display rotation on the fly. |zRot| is a clockwise rotation - // angle in degrees. Only multiples of 90. are accepted. - void setRotation(float zRot); + // Change the display rotation on the fly. |zRot| is a clockwise rotation + // angle in degrees. Only multiples of 90. are accepted. + void setRotation(float zRot); - // Change the display translation. |px|,|py| are numbers between 0 and 1, - // with (0,0) indicating "align the bottom left of the framebuffer with the - // bottom left of the subwindow", and (1,1) indicating "align the top right of - // the framebuffer with the top right of the subwindow." - void setTranslation(float px, float py); + // Change the display translation. |px|,|py| are numbers between 0 and 1, + // with (0,0) indicating "align the bottom left of the framebuffer with the + // bottom left of the subwindow", and (1,1) indicating "align the top right of + // the framebuffer with the top right of the subwindow." + void setTranslation(float px, float py); - // Force a repaint of the whole content into the sub-window. - void repaint(); + // Force a repaint of the whole content into the sub-window. + void repaint(); -private: - bool processMessage(const RenderWindowMessage& msg); + private: + bool processMessage(const RenderWindowMessage& msg); - bool mValid; - bool mHasSubWindow; - emugl::Thread* mThread; - RenderWindowChannel* mChannel; + bool mValid; + bool mHasSubWindow; + emugl::Thread* mThread; + RenderWindowChannel* mChannel; }; #endif // ANDROID_EMUGL_LIBRENDER_RENDER_WINDOW_H diff --git a/src/anbox/graphics/emugl/Renderable.cpp b/src/anbox/graphics/emugl/Renderable.cpp index 6d8a997..da32471 100644 --- a/src/anbox/graphics/emugl/Renderable.cpp +++ b/src/anbox/graphics/emugl/Renderable.cpp @@ -16,56 +16,34 @@ #include "Renderable.h" -Renderable::Renderable(const std::string &name, - const std::uint32_t &buffer, +Renderable::Renderable(const std::string &name, const std::uint32_t &buffer, const anbox::graphics::Rect &screen_position, const anbox::graphics::Rect &crop, - const glm::mat4 &transformation, - const float &alpha) : - name_(name), - buffer_(buffer), - screen_position_(screen_position), - crop_(crop), - transformation_(transformation), - alpha_(alpha) -{ + const glm::mat4 &transformation, const float &alpha) + : name_(name), + buffer_(buffer), + screen_position_(screen_position), + crop_(crop), + transformation_(transformation), + alpha_(alpha) {} + +Renderable::~Renderable() {} + +std::string Renderable::name() const { return name_; } + +std::uint32_t Renderable::buffer() const { return buffer_; } + +anbox::graphics::Rect Renderable::screen_position() const { + return screen_position_; } -Renderable::~Renderable() -{ -} +anbox::graphics::Rect Renderable::crop() const { return crop_; } -std::string Renderable::name() const -{ - return name_; -} +glm::mat4 Renderable::transformation() const { return transformation_; } -std::uint32_t Renderable::buffer() const -{ - return buffer_; -} +float Renderable::alpha() const { return alpha_; } -anbox::graphics::Rect Renderable::screen_position() const -{ - return screen_position_; -} - -anbox::graphics::Rect Renderable::crop() const -{ - return crop_; -} - -glm::mat4 Renderable::transformation() const -{ - return transformation_; -} - -float Renderable::alpha() const -{ - return alpha_; -} - -void Renderable::set_screen_position(const anbox::graphics::Rect &screen_position) -{ - screen_position_ = screen_position; +void Renderable::set_screen_position( + const anbox::graphics::Rect &screen_position) { + screen_position_ = screen_position; } diff --git a/src/anbox/graphics/emugl/Renderable.h b/src/anbox/graphics/emugl/Renderable.h index 0cd5205..bdf8a12 100644 --- a/src/anbox/graphics/emugl/Renderable.h +++ b/src/anbox/graphics/emugl/Renderable.h @@ -26,33 +26,30 @@ #include -class Renderable -{ -public: - Renderable(const std::string &name, - const std::uint32_t &buffer, - const anbox::graphics::Rect &screen_position, - const anbox::graphics::Rect &crop = {}, - const glm::mat4 &transformation = {}, - const float &alpha = 1.0f); - ~Renderable(); +class Renderable { + public: + Renderable(const std::string &name, const std::uint32_t &buffer, + const anbox::graphics::Rect &screen_position, + const anbox::graphics::Rect &crop = {}, + const glm::mat4 &transformation = {}, const float &alpha = 1.0f); + ~Renderable(); - std::string name() const; - std::uint32_t buffer() const; - anbox::graphics::Rect screen_position() const; - anbox::graphics::Rect crop() const; - glm::mat4 transformation() const; - float alpha() const; + std::string name() const; + std::uint32_t buffer() const; + anbox::graphics::Rect screen_position() const; + anbox::graphics::Rect crop() const; + glm::mat4 transformation() const; + float alpha() const; - void set_screen_position(const anbox::graphics::Rect &screen_position); + void set_screen_position(const anbox::graphics::Rect &screen_position); -private: - std::string name_; - std::uint32_t buffer_; - anbox::graphics::Rect screen_position_; - anbox::graphics::Rect crop_; - glm::mat4 transformation_; - float alpha_; + private: + std::string name_; + std::uint32_t buffer_; + anbox::graphics::Rect screen_position_; + anbox::graphics::Rect crop_; + glm::mat4 transformation_; + float alpha_; }; typedef std::vector RenderableList; diff --git a/src/anbox/graphics/emugl/Renderer.cpp b/src/anbox/graphics/emugl/Renderer.cpp index 3e26991..93a7737 100644 --- a/src/anbox/graphics/emugl/Renderer.cpp +++ b/src/anbox/graphics/emugl/Renderer.cpp @@ -30,62 +30,55 @@ #include #include -#include #include +#include namespace { // Helper class to call the bind_locked() / unbind_locked() properly. class ScopedBind { -public: - // Constructor will call bind_locked() on |fb|. - // Use isValid() to check for errors. - ScopedBind(Renderer* fb) : mFb(fb) { - if (!mFb->bind_locked()) { - mFb = NULL; - } + public: + // Constructor will call bind_locked() on |fb|. + // Use isValid() to check for errors. + ScopedBind(Renderer *fb) : mFb(fb) { + if (!mFb->bind_locked()) { + mFb = NULL; } + } - // Returns true if contruction bound the framebuffer context properly. - bool isValid() const { return mFb != NULL; } + // Returns true if contruction bound the framebuffer context properly. + bool isValid() const { return mFb != NULL; } - // Unbound the framebuffer explictly. This is also called by the - // destructor. - void release() { - if (mFb) { - mFb->unbind_locked(); - mFb = NULL; - } + // Unbound the framebuffer explictly. This is also called by the + // destructor. + void release() { + if (mFb) { + mFb->unbind_locked(); + mFb = NULL; } + } - // Destructor will call release(). - ~ScopedBind() { - release(); - } + // Destructor will call release(). + ~ScopedBind() { release(); } -private: - Renderer* mFb; + private: + Renderer *mFb; }; // Implementation of a ColorBuffer::Helper instance that redirects calls // to a FrameBuffer instance. class ColorBufferHelper : public ColorBuffer::Helper { -public: - ColorBufferHelper(Renderer* fb) : mFb(fb) {} + public: + ColorBufferHelper(Renderer *fb) : mFb(fb) {} - virtual bool setupContext() { - return mFb->bind_locked(); - } + virtual bool setupContext() { return mFb->bind_locked(); } - virtual void teardownContext() { - mFb->unbind_locked(); - } + virtual void teardownContext() { mFb->unbind_locked(); } - virtual TextureDraw* getTextureDraw() const { - return mFb->getTextureDraw(); - } -private: - Renderer* mFb; + virtual TextureDraw *getTextureDraw() const { return mFb->getTextureDraw(); } + + private: + Renderer *mFb; }; } // namespace @@ -93,893 +86,843 @@ private: Renderer *Renderer::s_renderer = NULL; HandleType Renderer::s_nextHandle = 0; -static char* getGLES1ExtensionString(EGLDisplay p_dpy) -{ - EGLConfig config; - EGLSurface surface; +static char *getGLES1ExtensionString(EGLDisplay p_dpy) { + EGLConfig config; + EGLSurface surface; - static const GLint configAttribs[] = { - EGL_SURFACE_TYPE, EGL_PBUFFER_BIT, - EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT, - EGL_NONE - }; + static const GLint configAttribs[] = {EGL_SURFACE_TYPE, EGL_PBUFFER_BIT, + EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT, + EGL_NONE}; - int n; - if (!s_egl.eglChooseConfig(p_dpy, configAttribs, - &config, 1, &n) || n == 0) { - ERR("%s: Could not find GLES 1.x config!\n", __FUNCTION__); - return NULL; - } + int n; + if (!s_egl.eglChooseConfig(p_dpy, configAttribs, &config, 1, &n) || n == 0) { + ERR("%s: Could not find GLES 1.x config!\n", __FUNCTION__); + return NULL; + } - DBG("%s: Found config %p\n", __FUNCTION__, (void*)config); + DBG("%s: Found config %p\n", __FUNCTION__, (void *)config); - static const EGLint pbufAttribs[] = { - EGL_WIDTH, 1, - EGL_HEIGHT, 1, - EGL_NONE - }; + static const EGLint pbufAttribs[] = {EGL_WIDTH, 1, EGL_HEIGHT, 1, EGL_NONE}; - surface = s_egl.eglCreatePbufferSurface(p_dpy, config, pbufAttribs); - if (surface == EGL_NO_SURFACE) { - ERR("%s: Could not create GLES 1.x Pbuffer!\n", __FUNCTION__); - return NULL; - } + surface = s_egl.eglCreatePbufferSurface(p_dpy, config, pbufAttribs); + if (surface == EGL_NO_SURFACE) { + ERR("%s: Could not create GLES 1.x Pbuffer!\n", __FUNCTION__); + return NULL; + } - static const GLint gles1ContextAttribs[] = { - EGL_CONTEXT_CLIENT_VERSION, 1, - EGL_NONE - }; + static const GLint gles1ContextAttribs[] = {EGL_CONTEXT_CLIENT_VERSION, 1, + EGL_NONE}; - EGLContext ctx = s_egl.eglCreateContext(p_dpy, config, - EGL_NO_CONTEXT, - gles1ContextAttribs); - if (ctx == EGL_NO_CONTEXT) { - ERR("%s: Could not create GLES 1.x Context!\n", __FUNCTION__); - s_egl.eglDestroySurface(p_dpy, surface); - return NULL; - } - - if (!s_egl.eglMakeCurrent(p_dpy, surface, surface, ctx)) { - ERR("%s: Could not make GLES 1.x context current!\n", __FUNCTION__); - s_egl.eglDestroySurface(p_dpy, surface); - s_egl.eglDestroyContext(p_dpy, ctx); - return NULL; - } - - // the string pointer may become invalid when the context is destroyed - const char* s = (const char*)s_gles1.glGetString(GL_EXTENSIONS); - char* extString = strdup(s ? s : ""); - - s_egl.eglMakeCurrent(p_dpy, NULL, NULL, NULL); - s_egl.eglDestroyContext(p_dpy, ctx); + EGLContext ctx = s_egl.eglCreateContext(p_dpy, config, EGL_NO_CONTEXT, + gles1ContextAttribs); + if (ctx == EGL_NO_CONTEXT) { + ERR("%s: Could not create GLES 1.x Context!\n", __FUNCTION__); s_egl.eglDestroySurface(p_dpy, surface); + return NULL; + } - return extString; + if (!s_egl.eglMakeCurrent(p_dpy, surface, surface, ctx)) { + ERR("%s: Could not make GLES 1.x context current!\n", __FUNCTION__); + s_egl.eglDestroySurface(p_dpy, surface); + s_egl.eglDestroyContext(p_dpy, ctx); + return NULL; + } + + // the string pointer may become invalid when the context is destroyed + const char *s = (const char *)s_gles1.glGetString(GL_EXTENSIONS); + char *extString = strdup(s ? s : ""); + + s_egl.eglMakeCurrent(p_dpy, NULL, NULL, NULL); + s_egl.eglDestroyContext(p_dpy, ctx); + s_egl.eglDestroySurface(p_dpy, surface); + + return extString; } -void Renderer::finalize(){ - m_colorbuffers.clear(); - m_windows.clear(); - m_contexts.clear(); - s_egl.eglMakeCurrent(m_eglDisplay, NULL, NULL, NULL); - s_egl.eglDestroyContext(m_eglDisplay, m_eglContext); - s_egl.eglDestroyContext(m_eglDisplay, m_pbufContext); - s_egl.eglDestroySurface(m_eglDisplay, m_pbufSurface); +void Renderer::finalize() { + m_colorbuffers.clear(); + m_windows.clear(); + m_contexts.clear(); + s_egl.eglMakeCurrent(m_eglDisplay, NULL, NULL, NULL); + s_egl.eglDestroyContext(m_eglDisplay, m_eglContext); + s_egl.eglDestroyContext(m_eglDisplay, m_pbufContext); + s_egl.eglDestroySurface(m_eglDisplay, m_pbufSurface); } -bool Renderer::initialize(EGLNativeDisplayType nativeDisplay) -{ - GL_LOG("FrameBuffer::initialize"); - if (s_renderer != NULL) { - return true; - } - - // - // allocate space for the FrameBuffer object - // - Renderer *fb = new Renderer(); - if (!fb) { - ERR("Failed to create fb\n"); - return false; - } - - // - // Initialize backend EGL display - // - fb->m_eglDisplay = s_egl.eglGetDisplay(nativeDisplay); - if (fb->m_eglDisplay == EGL_NO_DISPLAY) { - ERR("Failed to Initialize backend EGL display\n"); - delete fb; - return false; - } - - GL_LOG("call eglInitialize"); - if (!s_egl.eglInitialize(fb->m_eglDisplay, - &fb->m_caps.eglMajor, - &fb->m_caps.eglMinor)) { - ERR("Failed to eglInitialize\n"); - GL_LOG("Failed to eglInitialize"); - delete fb; - return false; - } - - DBG("egl: %d %d\n", fb->m_caps.eglMajor, fb->m_caps.eglMinor); - GL_LOG("egl: %d %d", fb->m_caps.eglMajor, fb->m_caps.eglMinor); - s_egl.eglBindAPI(EGL_OPENGL_ES_API); - - // - // if GLES2 plugin has loaded - try to make GLES2 context and - // get GLES2 extension string - // - char* gles1Extensions = NULL; - gles1Extensions = getGLES1ExtensionString(fb->m_eglDisplay); - if (!gles1Extensions) { - // Could not create GLES2 context - drop GL2 capability - ERR("Failed to obtain GLES 2.x extensions string!\n"); - delete fb; - return false; - } - - // - // Create EGL context for framebuffer post rendering. - // - GLint surfaceType = EGL_WINDOW_BIT| EGL_PBUFFER_BIT; - const GLint configAttribs[] = { - EGL_RED_SIZE, 1, - EGL_GREEN_SIZE, 1, - EGL_BLUE_SIZE, 1, - EGL_SURFACE_TYPE, surfaceType, - EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, - EGL_NONE - }; - - int n; - if (!s_egl.eglChooseConfig(fb->m_eglDisplay, configAttribs, - &fb->m_eglConfig, 1, &n)) { - ERR("Failed on eglChooseConfig\n"); - free(gles1Extensions); - delete fb; - return false; - } - - static const GLint glContextAttribs[] = { - EGL_CONTEXT_CLIENT_VERSION, 2, - EGL_NONE - }; - - GL_LOG("attempting to create egl context"); - fb->m_eglContext = s_egl.eglCreateContext(fb->m_eglDisplay, - fb->m_eglConfig, - EGL_NO_CONTEXT, - glContextAttribs); - if (fb->m_eglContext == EGL_NO_CONTEXT) { - ERR("Failed to create context 0x%x\n", s_egl.eglGetError()); - free(gles1Extensions); - delete fb; - return false; - } - - GL_LOG("attempting to create egl pbuffer context"); - // - // Create another context which shares with the eglContext to be used - // when we bind the pbuffer. That prevent switching drawable binding - // back and forth on framebuffer context. - // The main purpose of it is to solve a "blanking" behaviour we see on - // on Mac platform when switching binded drawable for a context however - // it is more efficient on other platforms as well. - // - fb->m_pbufContext = s_egl.eglCreateContext(fb->m_eglDisplay, - fb->m_eglConfig, - fb->m_eglContext, - glContextAttribs); - if (fb->m_pbufContext == EGL_NO_CONTEXT) { - ERR("Failed to create Pbuffer Context 0x%x\n", s_egl.eglGetError()); - free(gles1Extensions); - delete fb; - return false; - } - - GL_LOG("context creation successful"); - // - // create a 1x1 pbuffer surface which will be used for binding - // the FB context. - // The FB output will go to a subwindow, if one exist. - // - static const EGLint pbufAttribs[] = { - EGL_WIDTH, 1, - EGL_HEIGHT, 1, - EGL_NONE - }; - - fb->m_pbufSurface = s_egl.eglCreatePbufferSurface(fb->m_eglDisplay, - fb->m_eglConfig, - pbufAttribs); - if (fb->m_pbufSurface == EGL_NO_SURFACE) { - ERR("Failed to create pbuf surface for FB 0x%x\n", s_egl.eglGetError()); - free(gles1Extensions); - delete fb; - return false; - } - - GL_LOG("attempting to make context current"); - // Make the context current - ScopedBind bind(fb); - if (!bind.isValid()) { - ERR("Failed to make current\n"); - free(gles1Extensions); - delete fb; - return false; - } - GL_LOG("context-current successful"); - - // - // Initilize framebuffer capabilities - // - //const char* gles2Extensions = (const char *)s_gles2.glGetString(GL_EXTENSIONS); - bool has_gl_oes_image = false; - -// printf("GLES1 [%s]\n", gles1Extensions); -// printf("GLES2 [%s]\n", gles2Extensions); - - has_gl_oes_image = true; - - if (has_gl_oes_image) { - has_gl_oes_image &= strstr(gles1Extensions, "GL_OES_EGL_image") != NULL; - } - free((void*)gles1Extensions); - gles1Extensions = NULL; - - const char *eglExtensions = s_egl.eglQueryString(fb->m_eglDisplay, - EGL_EXTENSIONS); - - if (eglExtensions && has_gl_oes_image) { - fb->m_caps.has_eglimage_texture_2d = - strstr(eglExtensions, "EGL_KHR_gl_texture_2D_image") != NULL; - fb->m_caps.has_eglimage_renderbuffer = - strstr(eglExtensions, "EGL_KHR_gl_renderbuffer_image") != NULL; - } - else { - fb->m_caps.has_eglimage_texture_2d = false; - fb->m_caps.has_eglimage_renderbuffer = false; - } - - // - // Fail initialization if not all of the following extensions - // exist: - // EGL_KHR_gl_texture_2d_image - // GL_OES_EGL_IMAGE (by both GLES implementations [1 and 2]) - // - if (!fb->m_caps.has_eglimage_texture_2d) { - ERR("Failed: Missing egl_image related extension(s)\n"); - bind.release(); - delete fb; - return false; - } - - GL_LOG("host system has enough extensions"); - // - // Initialize set of configs - // - fb->m_configs = new RendererConfigList(fb->m_eglDisplay); - if (fb->m_configs->empty()) { - ERR("Failed: Initialize set of configs\n"); - bind.release(); - delete fb; - return false; - } - - // - // Check that we have config for each GLES and GLES2 - // - size_t nConfigs = fb->m_configs->size(); - int nGLConfigs = 0; - int nGL2Configs = 0; - for (size_t i = 0; i < nConfigs; ++i) { - GLint rtype = fb->m_configs->get(i)->getRenderableType(); - if (0 != (rtype & EGL_OPENGL_ES_BIT)) { - nGLConfigs++; - } - if (0 != (rtype & EGL_OPENGL_ES2_BIT)) { - nGL2Configs++; - } - } - - // - // Fail initialization if no GLES configs exist - // - if (nGLConfigs == 0) { - bind.release(); - delete fb; - return false; - } - - // - // If no GLES2 configs exist - not GLES2 capability - // - if (nGL2Configs == 0) { - ERR("Failed: No GLES 2.x configs found!\n"); - bind.release(); - delete fb; - return false; - } - - GL_LOG("There are sufficient EGLconfigs available"); - - // - // Cache the GL strings so we don't have to think about threading or - // current-context when asked for them. - // - fb->m_glVendor = (const char*)s_gles2.glGetString(GL_VENDOR); - fb->m_glRenderer = (const char*)s_gles2.glGetString(GL_RENDERER); - fb->m_glVersion = (const char*)s_gles2.glGetString(GL_VERSION); - - fb->m_textureDraw = new TextureDraw(fb->m_eglDisplay); - if (!fb->m_textureDraw) { - ERR("Failed: creation of TextureDraw instance\n"); - bind.release(); - delete fb; - return false; - } - - fb->m_defaultProgram = fb->m_family.add_program(vshader, defaultFShader); - fb->m_alphaProgram = fb->m_family.add_program(vshader, alphaFShader); - - // release the FB context - bind.release(); - - // - // Keep the singleton framebuffer pointer - // - s_renderer = fb; - GL_LOG("basic EGL initialization successful"); +bool Renderer::initialize(EGLNativeDisplayType nativeDisplay) { + GL_LOG("FrameBuffer::initialize"); + if (s_renderer != NULL) { return true; + } + + // + // allocate space for the FrameBuffer object + // + Renderer *fb = new Renderer(); + if (!fb) { + ERR("Failed to create fb\n"); + return false; + } + + // + // Initialize backend EGL display + // + fb->m_eglDisplay = s_egl.eglGetDisplay(nativeDisplay); + if (fb->m_eglDisplay == EGL_NO_DISPLAY) { + ERR("Failed to Initialize backend EGL display\n"); + delete fb; + return false; + } + + GL_LOG("call eglInitialize"); + if (!s_egl.eglInitialize(fb->m_eglDisplay, &fb->m_caps.eglMajor, + &fb->m_caps.eglMinor)) { + ERR("Failed to eglInitialize\n"); + GL_LOG("Failed to eglInitialize"); + delete fb; + return false; + } + + DBG("egl: %d %d\n", fb->m_caps.eglMajor, fb->m_caps.eglMinor); + GL_LOG("egl: %d %d", fb->m_caps.eglMajor, fb->m_caps.eglMinor); + s_egl.eglBindAPI(EGL_OPENGL_ES_API); + + // + // if GLES2 plugin has loaded - try to make GLES2 context and + // get GLES2 extension string + // + char *gles1Extensions = NULL; + gles1Extensions = getGLES1ExtensionString(fb->m_eglDisplay); + if (!gles1Extensions) { + // Could not create GLES2 context - drop GL2 capability + ERR("Failed to obtain GLES 2.x extensions string!\n"); + delete fb; + return false; + } + + // + // Create EGL context for framebuffer post rendering. + // + GLint surfaceType = EGL_WINDOW_BIT | EGL_PBUFFER_BIT; + const GLint configAttribs[] = {EGL_RED_SIZE, + 1, + EGL_GREEN_SIZE, + 1, + EGL_BLUE_SIZE, + 1, + EGL_SURFACE_TYPE, + surfaceType, + EGL_RENDERABLE_TYPE, + EGL_OPENGL_ES2_BIT, + EGL_NONE}; + + int n; + if (!s_egl.eglChooseConfig(fb->m_eglDisplay, configAttribs, &fb->m_eglConfig, + 1, &n)) { + ERR("Failed on eglChooseConfig\n"); + free(gles1Extensions); + delete fb; + return false; + } + + static const GLint glContextAttribs[] = {EGL_CONTEXT_CLIENT_VERSION, 2, + EGL_NONE}; + + GL_LOG("attempting to create egl context"); + fb->m_eglContext = s_egl.eglCreateContext(fb->m_eglDisplay, fb->m_eglConfig, + EGL_NO_CONTEXT, glContextAttribs); + if (fb->m_eglContext == EGL_NO_CONTEXT) { + ERR("Failed to create context 0x%x\n", s_egl.eglGetError()); + free(gles1Extensions); + delete fb; + return false; + } + + GL_LOG("attempting to create egl pbuffer context"); + // + // Create another context which shares with the eglContext to be used + // when we bind the pbuffer. That prevent switching drawable binding + // back and forth on framebuffer context. + // The main purpose of it is to solve a "blanking" behaviour we see on + // on Mac platform when switching binded drawable for a context however + // it is more efficient on other platforms as well. + // + fb->m_pbufContext = s_egl.eglCreateContext( + fb->m_eglDisplay, fb->m_eglConfig, fb->m_eglContext, glContextAttribs); + if (fb->m_pbufContext == EGL_NO_CONTEXT) { + ERR("Failed to create Pbuffer Context 0x%x\n", s_egl.eglGetError()); + free(gles1Extensions); + delete fb; + return false; + } + + GL_LOG("context creation successful"); + // + // create a 1x1 pbuffer surface which will be used for binding + // the FB context. + // The FB output will go to a subwindow, if one exist. + // + static const EGLint pbufAttribs[] = {EGL_WIDTH, 1, EGL_HEIGHT, 1, EGL_NONE}; + + fb->m_pbufSurface = s_egl.eglCreatePbufferSurface( + fb->m_eglDisplay, fb->m_eglConfig, pbufAttribs); + if (fb->m_pbufSurface == EGL_NO_SURFACE) { + ERR("Failed to create pbuf surface for FB 0x%x\n", s_egl.eglGetError()); + free(gles1Extensions); + delete fb; + return false; + } + + GL_LOG("attempting to make context current"); + // Make the context current + ScopedBind bind(fb); + if (!bind.isValid()) { + ERR("Failed to make current\n"); + free(gles1Extensions); + delete fb; + return false; + } + GL_LOG("context-current successful"); + + // + // Initilize framebuffer capabilities + // + // const char* gles2Extensions = (const char + // *)s_gles2.glGetString(GL_EXTENSIONS); + bool has_gl_oes_image = false; + + // printf("GLES1 [%s]\n", gles1Extensions); + // printf("GLES2 [%s]\n", gles2Extensions); + + has_gl_oes_image = true; + + if (has_gl_oes_image) { + has_gl_oes_image &= strstr(gles1Extensions, "GL_OES_EGL_image") != NULL; + } + free((void *)gles1Extensions); + gles1Extensions = NULL; + + const char *eglExtensions = + s_egl.eglQueryString(fb->m_eglDisplay, EGL_EXTENSIONS); + + if (eglExtensions && has_gl_oes_image) { + fb->m_caps.has_eglimage_texture_2d = + strstr(eglExtensions, "EGL_KHR_gl_texture_2D_image") != NULL; + fb->m_caps.has_eglimage_renderbuffer = + strstr(eglExtensions, "EGL_KHR_gl_renderbuffer_image") != NULL; + } else { + fb->m_caps.has_eglimage_texture_2d = false; + fb->m_caps.has_eglimage_renderbuffer = false; + } + + // + // Fail initialization if not all of the following extensions + // exist: + // EGL_KHR_gl_texture_2d_image + // GL_OES_EGL_IMAGE (by both GLES implementations [1 and 2]) + // + if (!fb->m_caps.has_eglimage_texture_2d) { + ERR("Failed: Missing egl_image related extension(s)\n"); + bind.release(); + delete fb; + return false; + } + + GL_LOG("host system has enough extensions"); + // + // Initialize set of configs + // + fb->m_configs = new RendererConfigList(fb->m_eglDisplay); + if (fb->m_configs->empty()) { + ERR("Failed: Initialize set of configs\n"); + bind.release(); + delete fb; + return false; + } + + // + // Check that we have config for each GLES and GLES2 + // + size_t nConfigs = fb->m_configs->size(); + int nGLConfigs = 0; + int nGL2Configs = 0; + for (size_t i = 0; i < nConfigs; ++i) { + GLint rtype = fb->m_configs->get(i)->getRenderableType(); + if (0 != (rtype & EGL_OPENGL_ES_BIT)) { + nGLConfigs++; + } + if (0 != (rtype & EGL_OPENGL_ES2_BIT)) { + nGL2Configs++; + } + } + + // + // Fail initialization if no GLES configs exist + // + if (nGLConfigs == 0) { + bind.release(); + delete fb; + return false; + } + + // + // If no GLES2 configs exist - not GLES2 capability + // + if (nGL2Configs == 0) { + ERR("Failed: No GLES 2.x configs found!\n"); + bind.release(); + delete fb; + return false; + } + + GL_LOG("There are sufficient EGLconfigs available"); + + // + // Cache the GL strings so we don't have to think about threading or + // current-context when asked for them. + // + fb->m_glVendor = (const char *)s_gles2.glGetString(GL_VENDOR); + fb->m_glRenderer = (const char *)s_gles2.glGetString(GL_RENDERER); + fb->m_glVersion = (const char *)s_gles2.glGetString(GL_VERSION); + + fb->m_textureDraw = new TextureDraw(fb->m_eglDisplay); + if (!fb->m_textureDraw) { + ERR("Failed: creation of TextureDraw instance\n"); + bind.release(); + delete fb; + return false; + } + + fb->m_defaultProgram = fb->m_family.add_program(vshader, defaultFShader); + fb->m_alphaProgram = fb->m_family.add_program(vshader, alphaFShader); + + // release the FB context + bind.release(); + + // + // Keep the singleton framebuffer pointer + // + s_renderer = fb; + GL_LOG("basic EGL initialization successful"); + return true; } -Renderer::Program::Program(GLuint program_id) -{ - id = program_id; - position_attr = s_gles2.glGetAttribLocation(id, "position"); - texcoord_attr = s_gles2.glGetAttribLocation(id, "texcoord"); - tex_uniform = s_gles2.glGetUniformLocation(id, "tex"); - center_uniform = s_gles2.glGetUniformLocation(id, "centre"); - display_transform_uniform = s_gles2.glGetUniformLocation(id, "display_transform"); - transform_uniform = s_gles2.glGetUniformLocation(id, "transform"); - screen_to_gl_coords_uniform = s_gles2.glGetUniformLocation(id, "screen_to_gl_coords"); - alpha_uniform = s_gles2.glGetUniformLocation(id, "alpha"); +Renderer::Program::Program(GLuint program_id) { + id = program_id; + position_attr = s_gles2.glGetAttribLocation(id, "position"); + texcoord_attr = s_gles2.glGetAttribLocation(id, "texcoord"); + tex_uniform = s_gles2.glGetUniformLocation(id, "tex"); + center_uniform = s_gles2.glGetUniformLocation(id, "centre"); + display_transform_uniform = + s_gles2.glGetUniformLocation(id, "display_transform"); + transform_uniform = s_gles2.glGetUniformLocation(id, "transform"); + screen_to_gl_coords_uniform = + s_gles2.glGetUniformLocation(id, "screen_to_gl_coords"); + alpha_uniform = s_gles2.glGetUniformLocation(id, "alpha"); } -Renderer::Renderer() : - m_configs(NULL), - m_eglDisplay(EGL_NO_DISPLAY), - m_colorBufferHelper(new ColorBufferHelper(this)), - m_eglContext(EGL_NO_CONTEXT), - m_pbufContext(EGL_NO_CONTEXT), - m_prevContext(EGL_NO_CONTEXT), - m_prevReadSurf(EGL_NO_SURFACE), - m_prevDrawSurf(EGL_NO_SURFACE), - m_textureDraw(NULL), - m_lastPostedColorBuffer(0), - m_statsNumFrames(0), - m_statsStartTime(0LL), - m_glVendor(NULL), - m_glRenderer(NULL), - m_glVersion(NULL) -{ - m_fpsStats = getenv("SHOW_FPS_STATS") != NULL; +Renderer::Renderer() + : m_configs(NULL), + m_eglDisplay(EGL_NO_DISPLAY), + m_colorBufferHelper(new ColorBufferHelper(this)), + m_eglContext(EGL_NO_CONTEXT), + m_pbufContext(EGL_NO_CONTEXT), + m_prevContext(EGL_NO_CONTEXT), + m_prevReadSurf(EGL_NO_SURFACE), + m_prevDrawSurf(EGL_NO_SURFACE), + m_textureDraw(NULL), + m_lastPostedColorBuffer(0), + m_statsNumFrames(0), + m_statsStartTime(0LL), + m_glVendor(NULL), + m_glRenderer(NULL), + m_glVersion(NULL) { + m_fpsStats = getenv("SHOW_FPS_STATS") != NULL; } Renderer::~Renderer() { - delete m_textureDraw; - delete m_configs; - delete m_colorBufferHelper; + delete m_textureDraw; + delete m_configs; + delete m_colorBufferHelper; } struct RendererWindow { - EGLNativeWindowType native_window = 0; - EGLSurface surface = EGL_NO_SURFACE; - anbox::graphics::Rect viewport; - glm::mat4 screen_to_gl_coords; - glm::mat4 display_transform; + EGLNativeWindowType native_window = 0; + EGLSurface surface = EGL_NO_SURFACE; + anbox::graphics::Rect viewport; + glm::mat4 screen_to_gl_coords; + glm::mat4 display_transform; }; -RendererWindow* Renderer::createNativeWindow(EGLNativeWindowType native_window) -{ - m_lock.lock(); - - auto window = new RendererWindow; - window->native_window = native_window; - window->surface = s_egl.eglCreateWindowSurface( - m_eglDisplay, m_eglConfig, window->native_window, nullptr); - if (window->surface == EGL_NO_SURFACE) - { - delete window; - m_lock.unlock(); - return nullptr; - } - - if (!bindWindow_locked(window)) - { - s_egl.eglDestroySurface(m_eglDisplay, window->surface); - delete window; - m_lock.unlock(); - return nullptr; - } - - s_gles2.glClear(GL_COLOR_BUFFER_BIT | - GL_DEPTH_BUFFER_BIT | - GL_STENCIL_BUFFER_BIT); - s_egl.eglSwapBuffers(m_eglDisplay, window->surface); - - unbind_locked(); - - m_nativeWindows.insert({native_window, window}); +RendererWindow *Renderer::createNativeWindow( + EGLNativeWindowType native_window) { + m_lock.lock(); + auto window = new RendererWindow; + window->native_window = native_window; + window->surface = s_egl.eglCreateWindowSurface( + m_eglDisplay, m_eglConfig, window->native_window, nullptr); + if (window->surface == EGL_NO_SURFACE) { + delete window; m_lock.unlock(); + return nullptr; + } - return window; + if (!bindWindow_locked(window)) { + s_egl.eglDestroySurface(m_eglDisplay, window->surface); + delete window; + m_lock.unlock(); + return nullptr; + } + + s_gles2.glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | + GL_STENCIL_BUFFER_BIT); + s_egl.eglSwapBuffers(m_eglDisplay, window->surface); + + unbind_locked(); + + m_nativeWindows.insert({native_window, window}); + + m_lock.unlock(); + + return window; } void Renderer::destroyNativeWindow(EGLNativeWindowType native_window) { - auto w = m_nativeWindows.find(native_window); - if (w == m_nativeWindows.end()) - return; + auto w = m_nativeWindows.find(native_window); + if (w == m_nativeWindows.end()) return; - m_lock.lock(); + m_lock.lock(); - s_egl.eglMakeCurrent(m_eglDisplay, nullptr, nullptr, nullptr); + s_egl.eglMakeCurrent(m_eglDisplay, nullptr, nullptr, nullptr); - if (w->second->surface != EGL_NO_SURFACE) - s_egl.eglDestroySurface(m_eglDisplay, w->second->surface); + if (w->second->surface != EGL_NO_SURFACE) + s_egl.eglDestroySurface(m_eglDisplay, w->second->surface); - delete w->second; - m_nativeWindows.erase(w); + delete w->second; + m_nativeWindows.erase(w); - m_lock.unlock(); + m_lock.unlock(); } -HandleType Renderer::genHandle() -{ - HandleType id; - do { - id = ++s_nextHandle; - } while( id == 0 || - m_contexts.find(id) != m_contexts.end() || - m_windows.find(id) != m_windows.end() ); +HandleType Renderer::genHandle() { + HandleType id; + do { + id = ++s_nextHandle; + } while (id == 0 || m_contexts.find(id) != m_contexts.end() || + m_windows.find(id) != m_windows.end()); - return id; + return id; } HandleType Renderer::createColorBuffer(int p_width, int p_height, - GLenum p_internalFormat) -{ - emugl::Mutex::AutoLock mutex(m_lock); - HandleType ret = 0; + GLenum p_internalFormat) { + emugl::Mutex::AutoLock mutex(m_lock); + HandleType ret = 0; - ColorBufferPtr cb(ColorBuffer::create( - getDisplay(), - p_width, - p_height, - p_internalFormat, - getCaps().has_eglimage_texture_2d, - m_colorBufferHelper)); - if (cb.Ptr() != NULL) { - ret = genHandle(); - m_colorbuffers[ret].cb = cb; - m_colorbuffers[ret].refcount = 1; - } - return ret; + ColorBufferPtr cb(ColorBuffer::create( + getDisplay(), p_width, p_height, p_internalFormat, + getCaps().has_eglimage_texture_2d, m_colorBufferHelper)); + if (cb.Ptr() != NULL) { + ret = genHandle(); + m_colorbuffers[ret].cb = cb; + m_colorbuffers[ret].refcount = 1; + } + return ret; } HandleType Renderer::createRenderContext(int p_config, HandleType p_share, - bool p_isGL2) -{ - emugl::Mutex::AutoLock mutex(m_lock); - HandleType ret = 0; + bool p_isGL2) { + emugl::Mutex::AutoLock mutex(m_lock); + HandleType ret = 0; - const RendererConfig* config = getConfigs()->get(p_config); - if (!config) { - return ret; - } - - RenderContextPtr share(NULL); - if (p_share != 0) { - RenderContextMap::iterator s(m_contexts.find(p_share)); - if (s == m_contexts.end()) { - return ret; - } - share = (*s).second; - } - EGLContext sharedContext = - share.Ptr() ? share->getEGLContext() : EGL_NO_CONTEXT; - - RenderContextPtr rctx(RenderContext::create( - m_eglDisplay, config->getEglConfig(), sharedContext, p_isGL2)); - if (rctx.Ptr() != NULL) { - ret = genHandle(); - m_contexts[ret] = rctx; - RenderThreadInfo *tinfo = RenderThreadInfo::get(); - tinfo->m_contextSet.insert(ret); - } + const RendererConfig *config = getConfigs()->get(p_config); + if (!config) { return ret; -} + } -HandleType Renderer::createWindowSurface(int p_config, int p_width, int p_height) -{ - emugl::Mutex::AutoLock mutex(m_lock); - - HandleType ret = 0; - - const RendererConfig* config = getConfigs()->get(p_config); - if (!config) { - return ret; + RenderContextPtr share(NULL); + if (p_share != 0) { + RenderContextMap::iterator s(m_contexts.find(p_share)); + if (s == m_contexts.end()) { + return ret; } + share = (*s).second; + } + EGLContext sharedContext = + share.Ptr() ? share->getEGLContext() : EGL_NO_CONTEXT; - WindowSurfacePtr win(WindowSurface::create( - getDisplay(), config->getEglConfig(), p_width, p_height)); - if (win.Ptr() != NULL) { - ret = genHandle(); - m_windows[ret] = std::pair(win,0); - RenderThreadInfo *tinfo = RenderThreadInfo::get(); - tinfo->m_windowSet.insert(ret); - } - - return ret; -} - -void Renderer::drainRenderContext() -{ - emugl::Mutex::AutoLock mutex(m_lock); + RenderContextPtr rctx(RenderContext::create( + m_eglDisplay, config->getEglConfig(), sharedContext, p_isGL2)); + if (rctx.Ptr() != NULL) { + ret = genHandle(); + m_contexts[ret] = rctx; RenderThreadInfo *tinfo = RenderThreadInfo::get(); - if (tinfo->m_contextSet.empty()) return; - for (std::set::iterator it = tinfo->m_contextSet.begin(); - it != tinfo->m_contextSet.end(); ++it) { - HandleType contextHandle = *it; - m_contexts.erase(contextHandle); - } - tinfo->m_contextSet.clear(); + tinfo->m_contextSet.insert(ret); + } + return ret; } -void Renderer::drainWindowSurface() -{ - emugl::Mutex::AutoLock mutex(m_lock); +HandleType Renderer::createWindowSurface(int p_config, int p_width, + int p_height) { + emugl::Mutex::AutoLock mutex(m_lock); + + HandleType ret = 0; + + const RendererConfig *config = getConfigs()->get(p_config); + if (!config) { + return ret; + } + + WindowSurfacePtr win(WindowSurface::create( + getDisplay(), config->getEglConfig(), p_width, p_height)); + if (win.Ptr() != NULL) { + ret = genHandle(); + m_windows[ret] = std::pair(win, 0); + RenderThreadInfo *tinfo = RenderThreadInfo::get(); + tinfo->m_windowSet.insert(ret); + } + + return ret; +} + +void Renderer::drainRenderContext() { + emugl::Mutex::AutoLock mutex(m_lock); + RenderThreadInfo *tinfo = RenderThreadInfo::get(); + if (tinfo->m_contextSet.empty()) return; + for (std::set::iterator it = tinfo->m_contextSet.begin(); + it != tinfo->m_contextSet.end(); ++it) { + HandleType contextHandle = *it; + m_contexts.erase(contextHandle); + } + tinfo->m_contextSet.clear(); +} + +void Renderer::drainWindowSurface() { + emugl::Mutex::AutoLock mutex(m_lock); + RenderThreadInfo *tinfo = RenderThreadInfo::get(); + if (tinfo->m_windowSet.empty()) return; + for (std::set::iterator it = tinfo->m_windowSet.begin(); + it != tinfo->m_windowSet.end(); ++it) { + HandleType windowHandle = *it; + if (m_windows.find(windowHandle) != m_windows.end()) { + HandleType oldColorBufferHandle = m_windows[windowHandle].second; + if (oldColorBufferHandle) { + ColorBufferMap::iterator cit(m_colorbuffers.find(oldColorBufferHandle)); + if (cit != m_colorbuffers.end()) { + if (--(*cit).second.refcount == 0) { + m_colorbuffers.erase(cit); + } + } + } + m_windows.erase(windowHandle); + } + } + tinfo->m_windowSet.clear(); +} + +void Renderer::DestroyRenderContext(HandleType p_context) { + emugl::Mutex::AutoLock mutex(m_lock); + m_contexts.erase(p_context); + RenderThreadInfo *tinfo = RenderThreadInfo::get(); + if (tinfo->m_contextSet.empty()) return; + tinfo->m_contextSet.erase(p_context); +} + +void Renderer::DestroyWindowSurface(HandleType p_surface) { + emugl::Mutex::AutoLock mutex(m_lock); + if (m_windows.find(p_surface) != m_windows.end()) { + m_windows.erase(p_surface); RenderThreadInfo *tinfo = RenderThreadInfo::get(); if (tinfo->m_windowSet.empty()) return; - for (std::set::iterator it = tinfo->m_windowSet.begin(); - it != tinfo->m_windowSet.end(); ++it) { - HandleType windowHandle = *it; - if (m_windows.find(windowHandle) != m_windows.end()) { - HandleType oldColorBufferHandle = m_windows[windowHandle].second; - if (oldColorBufferHandle) { - ColorBufferMap::iterator cit(m_colorbuffers.find(oldColorBufferHandle)); - if (cit != m_colorbuffers.end()) { - if (--(*cit).second.refcount == 0) { m_colorbuffers.erase(cit); } - } - } - m_windows.erase(windowHandle); - } - } - tinfo->m_windowSet.clear(); + tinfo->m_windowSet.erase(p_surface); + } } -void Renderer::DestroyRenderContext(HandleType p_context) -{ - emugl::Mutex::AutoLock mutex(m_lock); - m_contexts.erase(p_context); - RenderThreadInfo *tinfo = RenderThreadInfo::get(); - if (tinfo->m_contextSet.empty()) return; - tinfo->m_contextSet.erase(p_context); +int Renderer::openColorBuffer(HandleType p_colorbuffer) { + emugl::Mutex::AutoLock mutex(m_lock); + ColorBufferMap::iterator c(m_colorbuffers.find(p_colorbuffer)); + if (c == m_colorbuffers.end()) { + // bad colorbuffer handle + ERR("FB: openColorBuffer cb handle %#x not found\n", p_colorbuffer); + return -1; + } + (*c).second.refcount++; + return 0; } -void Renderer::DestroyWindowSurface(HandleType p_surface) -{ - emugl::Mutex::AutoLock mutex(m_lock); - if (m_windows.find(p_surface) != m_windows.end()) { - m_windows.erase(p_surface); - RenderThreadInfo *tinfo = RenderThreadInfo::get(); - if (tinfo->m_windowSet.empty()) return; - tinfo->m_windowSet.erase(p_surface); - } +void Renderer::closeColorBuffer(HandleType p_colorbuffer) { + emugl::Mutex::AutoLock mutex(m_lock); + ColorBufferMap::iterator c(m_colorbuffers.find(p_colorbuffer)); + if (c == m_colorbuffers.end()) { + // This is harmless: it is normal for guest system to issue + // closeColorBuffer command when the color buffer is already + // garbage collected on the host. (we dont have a mechanism + // to give guest a notice yet) + return; + } + if (--(*c).second.refcount == 0) { + m_colorbuffers.erase(c); + } } -int Renderer::openColorBuffer(HandleType p_colorbuffer) -{ - emugl::Mutex::AutoLock mutex(m_lock); - ColorBufferMap::iterator c(m_colorbuffers.find(p_colorbuffer)); - if (c == m_colorbuffers.end()) { - // bad colorbuffer handle - ERR("FB: openColorBuffer cb handle %#x not found\n", p_colorbuffer); - return -1; - } - (*c).second.refcount++; - return 0; -} +bool Renderer::flushWindowSurfaceColorBuffer(HandleType p_surface) { + emugl::Mutex::AutoLock mutex(m_lock); -void Renderer::closeColorBuffer(HandleType p_colorbuffer) -{ - emugl::Mutex::AutoLock mutex(m_lock); - ColorBufferMap::iterator c(m_colorbuffers.find(p_colorbuffer)); - if (c == m_colorbuffers.end()) { - // This is harmless: it is normal for guest system to issue - // closeColorBuffer command when the color buffer is already - // garbage collected on the host. (we dont have a mechanism - // to give guest a notice yet) - return; - } - if (--(*c).second.refcount == 0) { - m_colorbuffers.erase(c); - } -} + WindowSurfaceMap::iterator w(m_windows.find(p_surface)); + if (w == m_windows.end()) { + ERR("FB::flushWindowSurfaceColorBuffer: window handle %#x not found\n", + p_surface); + // bad surface handle + return false; + } -bool Renderer::flushWindowSurfaceColorBuffer(HandleType p_surface) -{ - emugl::Mutex::AutoLock mutex(m_lock); + WindowSurface *surface = (*w).second.first.Ptr(); + surface->flushColorBuffer(); - WindowSurfaceMap::iterator w( m_windows.find(p_surface) ); - if (w == m_windows.end()) { - ERR("FB::flushWindowSurfaceColorBuffer: window handle %#x not found\n", p_surface); - // bad surface handle - return false; - } - - WindowSurface* surface = (*w).second.first.Ptr(); - surface->flushColorBuffer(); - - return true; + return true; } bool Renderer::setWindowSurfaceColorBuffer(HandleType p_surface, - HandleType p_colorbuffer) -{ - emugl::Mutex::AutoLock mutex(m_lock); + HandleType p_colorbuffer) { + emugl::Mutex::AutoLock mutex(m_lock); - WindowSurfaceMap::iterator w( m_windows.find(p_surface) ); + WindowSurfaceMap::iterator w(m_windows.find(p_surface)); + if (w == m_windows.end()) { + // bad surface handle + ERR("%s: bad window surface handle %#x\n", __FUNCTION__, p_surface); + return false; + } + + ColorBufferMap::iterator c(m_colorbuffers.find(p_colorbuffer)); + if (c == m_colorbuffers.end()) { + DBG("%s: bad color buffer handle %#x\n", __FUNCTION__, p_colorbuffer); + // bad colorbuffer handle + return false; + } + + (*w).second.first->setColorBuffer((*c).second.cb); + (*w).second.second = p_colorbuffer; + return true; +} + +void Renderer::readColorBuffer(HandleType p_colorbuffer, int x, int y, + int width, int height, GLenum format, + GLenum type, void *pixels) { + emugl::Mutex::AutoLock mutex(m_lock); + + ColorBufferMap::iterator c(m_colorbuffers.find(p_colorbuffer)); + if (c == m_colorbuffers.end()) { + // bad colorbuffer handle + return; + } + + (*c).second.cb->readPixels(x, y, width, height, format, type, pixels); +} + +bool Renderer::updateColorBuffer(HandleType p_colorbuffer, int x, int y, + int width, int height, GLenum format, + GLenum type, void *pixels) { + emugl::Mutex::AutoLock mutex(m_lock); + + ColorBufferMap::iterator c(m_colorbuffers.find(p_colorbuffer)); + if (c == m_colorbuffers.end()) { + // bad colorbuffer handle + return false; + } + + (*c).second.cb->subUpdate(x, y, width, height, format, type, pixels); + + return true; +} + +bool Renderer::bindColorBufferToTexture(HandleType p_colorbuffer) { + emugl::Mutex::AutoLock mutex(m_lock); + + ColorBufferMap::iterator c(m_colorbuffers.find(p_colorbuffer)); + if (c == m_colorbuffers.end()) { + // bad colorbuffer handle + return false; + } + + return (*c).second.cb->bindToTexture(); +} + +bool Renderer::bindColorBufferToRenderbuffer(HandleType p_colorbuffer) { + emugl::Mutex::AutoLock mutex(m_lock); + + ColorBufferMap::iterator c(m_colorbuffers.find(p_colorbuffer)); + if (c == m_colorbuffers.end()) { + // bad colorbuffer handle + return false; + } + + return (*c).second.cb->bindToRenderbuffer(); +} + +bool Renderer::bindContext(HandleType p_context, HandleType p_drawSurface, + HandleType p_readSurface) { + emugl::Mutex::AutoLock mutex(m_lock); + + WindowSurfacePtr draw(NULL), read(NULL); + RenderContextPtr ctx(NULL); + + // + // if this is not an unbind operation - make sure all handles are good + // + if (p_context || p_drawSurface || p_readSurface) { + RenderContextMap::iterator r(m_contexts.find(p_context)); + if (r == m_contexts.end()) { + // bad context handle + return false; + } + + ctx = (*r).second; + WindowSurfaceMap::iterator w(m_windows.find(p_drawSurface)); if (w == m_windows.end()) { + // bad surface handle + return false; + } + draw = (*w).second.first; + + if (p_readSurface != p_drawSurface) { + WindowSurfaceMap::iterator w(m_windows.find(p_readSurface)); + if (w == m_windows.end()) { // bad surface handle - ERR("%s: bad window surface handle %#x\n", __FUNCTION__, p_surface); return false; - } - - ColorBufferMap::iterator c( m_colorbuffers.find(p_colorbuffer) ); - if (c == m_colorbuffers.end()) { - DBG("%s: bad color buffer handle %#x\n", __FUNCTION__, p_colorbuffer); - // bad colorbuffer handle - return false; - } - - (*w).second.first->setColorBuffer((*c).second.cb); - (*w).second.second = p_colorbuffer; - return true; -} - -void Renderer::readColorBuffer(HandleType p_colorbuffer, - int x, int y, int width, int height, - GLenum format, GLenum type, void *pixels) -{ - emugl::Mutex::AutoLock mutex(m_lock); - - ColorBufferMap::iterator c( m_colorbuffers.find(p_colorbuffer) ); - if (c == m_colorbuffers.end()) { - // bad colorbuffer handle - return; - } - - (*c).second.cb->readPixels(x, y, width, height, format, type, pixels); -} - -bool Renderer::updateColorBuffer(HandleType p_colorbuffer, - int x, int y, int width, int height, - GLenum format, GLenum type, void *pixels) -{ - emugl::Mutex::AutoLock mutex(m_lock); - - ColorBufferMap::iterator c( m_colorbuffers.find(p_colorbuffer) ); - if (c == m_colorbuffers.end()) { - // bad colorbuffer handle - return false; - } - - (*c).second.cb->subUpdate(x, y, width, height, format, type, pixels); - - return true; -} - -bool Renderer::bindColorBufferToTexture(HandleType p_colorbuffer) -{ - emugl::Mutex::AutoLock mutex(m_lock); - - ColorBufferMap::iterator c( m_colorbuffers.find(p_colorbuffer) ); - if (c == m_colorbuffers.end()) { - // bad colorbuffer handle - return false; - } - - return (*c).second.cb->bindToTexture(); -} - -bool Renderer::bindColorBufferToRenderbuffer(HandleType p_colorbuffer) -{ - emugl::Mutex::AutoLock mutex(m_lock); - - ColorBufferMap::iterator c( m_colorbuffers.find(p_colorbuffer) ); - if (c == m_colorbuffers.end()) { - // bad colorbuffer handle - return false; - } - - return (*c).second.cb->bindToRenderbuffer(); -} - -bool Renderer::bindContext(HandleType p_context, - HandleType p_drawSurface, - HandleType p_readSurface) -{ - emugl::Mutex::AutoLock mutex(m_lock); - - WindowSurfacePtr draw(NULL), read(NULL); - RenderContextPtr ctx(NULL); - - // - // if this is not an unbind operation - make sure all handles are good - // - if (p_context || p_drawSurface || p_readSurface) { - RenderContextMap::iterator r( m_contexts.find(p_context) ); - if (r == m_contexts.end()) { - // bad context handle - return false; - } - - ctx = (*r).second; - WindowSurfaceMap::iterator w( m_windows.find(p_drawSurface) ); - if (w == m_windows.end()) { - // bad surface handle - return false; - } - draw = (*w).second.first; - - if (p_readSurface != p_drawSurface) { - WindowSurfaceMap::iterator w( m_windows.find(p_readSurface) ); - if (w == m_windows.end()) { - // bad surface handle - return false; - } - read = (*w).second.first; - } - else { - read = draw; - } - } - - if (!s_egl.eglMakeCurrent(m_eglDisplay, - draw ? draw->getEGLSurface() : EGL_NO_SURFACE, - read ? read->getEGLSurface() : EGL_NO_SURFACE, - ctx ? ctx->getEGLContext() : EGL_NO_CONTEXT)) { - ERR("eglMakeCurrent failed\n"); - return false; - } - - // - // Bind the surface(s) to the context - // - RenderThreadInfo *tinfo = RenderThreadInfo::get(); - WindowSurfacePtr bindDraw, bindRead; - if (draw.Ptr() == NULL && read.Ptr() == NULL) { - // Unbind the current read and draw surfaces from the context - bindDraw = tinfo->currDrawSurf; - bindRead = tinfo->currReadSurf; + } + read = (*w).second.first; } else { - bindDraw = draw; - bindRead = read; + read = draw; } + } - if (bindDraw.Ptr() != NULL && bindRead.Ptr() != NULL) { - if (bindDraw.Ptr() != bindRead.Ptr()) { - bindDraw->bind(ctx, WindowSurface::BIND_DRAW); - bindRead->bind(ctx, WindowSurface::BIND_READ); - } - else { - bindDraw->bind(ctx, WindowSurface::BIND_READDRAW); - } - } + if (!s_egl.eglMakeCurrent(m_eglDisplay, + draw ? draw->getEGLSurface() : EGL_NO_SURFACE, + read ? read->getEGLSurface() : EGL_NO_SURFACE, + ctx ? ctx->getEGLContext() : EGL_NO_CONTEXT)) { + ERR("eglMakeCurrent failed\n"); + return false; + } - // - // update thread info with current bound context - // - tinfo->currContext = ctx; - tinfo->currDrawSurf = draw; - tinfo->currReadSurf = read; - if (ctx) { - if (ctx->isGL2()) tinfo->m_gl2Dec.setContextData(&ctx->decoderContextData()); - else tinfo->m_glDec.setContextData(&ctx->decoderContextData()); + // + // Bind the surface(s) to the context + // + RenderThreadInfo *tinfo = RenderThreadInfo::get(); + WindowSurfacePtr bindDraw, bindRead; + if (draw.Ptr() == NULL && read.Ptr() == NULL) { + // Unbind the current read and draw surfaces from the context + bindDraw = tinfo->currDrawSurf; + bindRead = tinfo->currReadSurf; + } else { + bindDraw = draw; + bindRead = read; + } + + if (bindDraw.Ptr() != NULL && bindRead.Ptr() != NULL) { + if (bindDraw.Ptr() != bindRead.Ptr()) { + bindDraw->bind(ctx, WindowSurface::BIND_DRAW); + bindRead->bind(ctx, WindowSurface::BIND_READ); + } else { + bindDraw->bind(ctx, WindowSurface::BIND_READDRAW); } - else { - tinfo->m_glDec.setContextData(NULL); - tinfo->m_gl2Dec.setContextData(NULL); - } - return true; + } + + // + // update thread info with current bound context + // + tinfo->currContext = ctx; + tinfo->currDrawSurf = draw; + tinfo->currReadSurf = read; + if (ctx) { + if (ctx->isGL2()) + tinfo->m_gl2Dec.setContextData(&ctx->decoderContextData()); + else + tinfo->m_glDec.setContextData(&ctx->decoderContextData()); + } else { + tinfo->m_glDec.setContextData(NULL); + tinfo->m_gl2Dec.setContextData(NULL); + } + return true; } -HandleType Renderer::createClientImage(HandleType context, EGLenum target, GLuint buffer) -{ - RenderContextPtr ctx(NULL); +HandleType Renderer::createClientImage(HandleType context, EGLenum target, + GLuint buffer) { + RenderContextPtr ctx(NULL); - if (context) { - RenderContextMap::iterator r( m_contexts.find(context) ); - if (r == m_contexts.end()) { - // bad context handle - return false; - } - - ctx = (*r).second; + if (context) { + RenderContextMap::iterator r(m_contexts.find(context)); + if (r == m_contexts.end()) { + // bad context handle + return false; } - EGLContext eglContext = ctx ? ctx->getEGLContext() : EGL_NO_CONTEXT; - EGLImageKHR image = s_egl.eglCreateImageKHR( - m_eglDisplay, eglContext, target, - reinterpret_cast(buffer), NULL); + ctx = (*r).second; + } - return (HandleType)reinterpret_cast(image); + EGLContext eglContext = ctx ? ctx->getEGLContext() : EGL_NO_CONTEXT; + EGLImageKHR image = + s_egl.eglCreateImageKHR(m_eglDisplay, eglContext, target, + reinterpret_cast(buffer), NULL); + + return (HandleType) reinterpret_cast(image); } -EGLBoolean Renderer::destroyClientImage(HandleType image) -{ - return s_egl.eglDestroyImageKHR(m_eglDisplay, - reinterpret_cast(image)); +EGLBoolean Renderer::destroyClientImage(HandleType image) { + return s_egl.eglDestroyImageKHR(m_eglDisplay, + reinterpret_cast(image)); } // // The framebuffer lock should be held when calling this function ! // -bool Renderer::bind_locked() -{ - EGLContext prevContext = s_egl.eglGetCurrentContext(); - EGLSurface prevReadSurf = s_egl.eglGetCurrentSurface(EGL_READ); - EGLSurface prevDrawSurf = s_egl.eglGetCurrentSurface(EGL_DRAW); +bool Renderer::bind_locked() { + EGLContext prevContext = s_egl.eglGetCurrentContext(); + EGLSurface prevReadSurf = s_egl.eglGetCurrentSurface(EGL_READ); + EGLSurface prevDrawSurf = s_egl.eglGetCurrentSurface(EGL_DRAW); - if (!s_egl.eglMakeCurrent(m_eglDisplay, m_pbufSurface, - m_pbufSurface, m_pbufContext)) { - ERR("eglMakeCurrent failed\n"); - return false; - } + if (!s_egl.eglMakeCurrent(m_eglDisplay, m_pbufSurface, m_pbufSurface, + m_pbufContext)) { + ERR("eglMakeCurrent failed\n"); + return false; + } - m_prevContext = prevContext; - m_prevReadSurf = prevReadSurf; - m_prevDrawSurf = prevDrawSurf; - return true; + m_prevContext = prevContext; + m_prevReadSurf = prevReadSurf; + m_prevDrawSurf = prevDrawSurf; + return true; } -bool Renderer::bindWindow_locked(RendererWindow *window) -{ - EGLContext prevContext = s_egl.eglGetCurrentContext(); - EGLSurface prevReadSurf = s_egl.eglGetCurrentSurface(EGL_READ); - EGLSurface prevDrawSurf = s_egl.eglGetCurrentSurface(EGL_DRAW); +bool Renderer::bindWindow_locked(RendererWindow *window) { + EGLContext prevContext = s_egl.eglGetCurrentContext(); + EGLSurface prevReadSurf = s_egl.eglGetCurrentSurface(EGL_READ); + EGLSurface prevDrawSurf = s_egl.eglGetCurrentSurface(EGL_DRAW); - if (!s_egl.eglMakeCurrent(m_eglDisplay, window->surface, - window->surface, m_eglContext)) { - ERR("eglMakeCurrent failed\n"); - return false; - } + if (!s_egl.eglMakeCurrent(m_eglDisplay, window->surface, window->surface, + m_eglContext)) { + ERR("eglMakeCurrent failed\n"); + return false; + } - m_prevContext = prevContext; - m_prevReadSurf = prevReadSurf; - m_prevDrawSurf = prevDrawSurf; - return true; + m_prevContext = prevContext; + m_prevReadSurf = prevReadSurf; + m_prevDrawSurf = prevDrawSurf; + return true; } -bool Renderer::unbind_locked() -{ - if (!s_egl.eglMakeCurrent(m_eglDisplay, m_prevDrawSurf, - m_prevReadSurf, m_prevContext)) { - return false; - } +bool Renderer::unbind_locked() { + if (!s_egl.eglMakeCurrent(m_eglDisplay, m_prevDrawSurf, m_prevReadSurf, + m_prevContext)) { + return false; + } - m_prevContext = EGL_NO_CONTEXT; - m_prevReadSurf = EGL_NO_SURFACE; - m_prevDrawSurf = EGL_NO_SURFACE; - return true; + m_prevContext = EGL_NO_CONTEXT; + m_prevReadSurf = EGL_NO_SURFACE; + m_prevDrawSurf = EGL_NO_SURFACE; + return true; } -const GLchar* const Renderer::vshader = -{ +const GLchar *const Renderer::vshader = { "attribute vec3 position;\n" "attribute vec2 texcoord;\n" "uniform mat4 screen_to_gl_coords;\n" @@ -992,11 +935,9 @@ const GLchar* const Renderer::vshader = " vec4 transformed = (transform * (vec4(position, 1.0) - mid)) + mid;\n" " gl_Position = display_transform * screen_to_gl_coords * transformed;\n" " v_texcoord = texcoord;\n" - "}\n" -}; + "}\n"}; -const GLchar* const Renderer::alphaFShader = -{ +const GLchar *const Renderer::alphaFShader = { "precision mediump float;\n" "uniform sampler2D tex;\n" "uniform float alpha;\n" @@ -1004,173 +945,161 @@ const GLchar* const Renderer::alphaFShader = "void main() {\n" " vec4 frag = texture2D(tex, v_texcoord);\n" " gl_FragColor = alpha*frag;\n" - "}\n" -}; + "}\n"}; -const GLchar* const Renderer::defaultFShader = -{ // This is the fastest fragment shader. Use it when you can. - "precision mediump float;\n" - "uniform sampler2D tex;\n" - "varying vec2 v_texcoord;\n" - "void main() {\n" - " gl_FragColor = texture2D(tex, v_texcoord);\n" - "}\n" -}; +const GLchar *const Renderer::defaultFShader = + { // This is the fastest fragment shader. Use it when you can. + "precision mediump float;\n" + "uniform sampler2D tex;\n" + "varying vec2 v_texcoord;\n" + "void main() {\n" + " gl_FragColor = texture2D(tex, v_texcoord);\n" + "}\n"}; -void Renderer::setupViewport(RendererWindow *window, const anbox::graphics::Rect &rect) -{ - /* - * Here we provide a 3D perspective projection with a default 30 degrees - * vertical field of view. This projection matrix is carefully designed - * such that any vertices at depth z=0 will fit the screen coordinates. So - * client texels will fit screen pixels perfectly as long as the surface is - * at depth zero. But if you want to do anything fancy, you can also choose - * a different depth and it will appear to come out of or go into the - * screen. - */ - window->screen_to_gl_coords = glm::translate(glm::mat4(1.0f), glm::vec3{-1.0f, 1.0f, 0.0f}); +void Renderer::setupViewport(RendererWindow *window, + const anbox::graphics::Rect &rect) { + /* + * Here we provide a 3D perspective projection with a default 30 degrees + * vertical field of view. This projection matrix is carefully designed + * such that any vertices at depth z=0 will fit the screen coordinates. So + * client texels will fit screen pixels perfectly as long as the surface is + * at depth zero. But if you want to do anything fancy, you can also choose + * a different depth and it will appear to come out of or go into the + * screen. + */ + window->screen_to_gl_coords = + glm::translate(glm::mat4(1.0f), glm::vec3{-1.0f, 1.0f, 0.0f}); - /* - * Perspective division is one thing that can't be done in a matrix - * multiplication. It happens after the matrix multiplications. GL just - * scales {x,y} by 1/w. So modify the final part of the projection matrix - * to set w ([3]) to be the incoming z coordinate ([2]). - */ - window->screen_to_gl_coords[2][3] = -1.0f; + /* + * Perspective division is one thing that can't be done in a matrix + * multiplication. It happens after the matrix multiplications. GL just + * scales {x,y} by 1/w. So modify the final part of the projection matrix + * to set w ([3]) to be the incoming z coordinate ([2]). + */ + window->screen_to_gl_coords[2][3] = -1.0f; - float const vertical_fov_degrees = 30.0f; - float const near = - (rect.height() / 2.0f) / - std::tan((vertical_fov_degrees * M_PI / 180.0f) / 2.0f); - float const far = -near; + float const vertical_fov_degrees = 30.0f; + float const near = (rect.height() / 2.0f) / + std::tan((vertical_fov_degrees * M_PI / 180.0f) / 2.0f); + float const far = -near; - window->screen_to_gl_coords = glm::scale(window->screen_to_gl_coords, - glm::vec3{2.0f / rect.width(), - -2.0f / rect.height(), - 2.0f / (near - far)}); - window->screen_to_gl_coords = glm::translate(window->screen_to_gl_coords, - glm::vec3{-rect.left(), - -rect.top(), - 0.0f}); + window->screen_to_gl_coords = + glm::scale(window->screen_to_gl_coords, + glm::vec3{2.0f / rect.width(), -2.0f / rect.height(), + 2.0f / (near - far)}); + window->screen_to_gl_coords = glm::translate( + window->screen_to_gl_coords, glm::vec3{-rect.left(), -rect.top(), 0.0f}); - window->viewport = rect; + window->viewport = rect; } -void Renderer::tessellate(std::vector& primitives, +void Renderer::tessellate(std::vector &primitives, const anbox::graphics::Rect &buf_size, - const Renderable &renderable) -{ - auto rect = renderable.screen_position(); - GLfloat left = rect.left(); - GLfloat right = rect.right(); - GLfloat top = rect.top(); - GLfloat bottom = rect.bottom(); + const Renderable &renderable) { + auto rect = renderable.screen_position(); + GLfloat left = rect.left(); + GLfloat right = rect.right(); + GLfloat top = rect.top(); + GLfloat bottom = rect.bottom(); - anbox::graphics::Primitive rectangle; - rectangle.tex_id = 0; - rectangle.type = GL_TRIANGLE_STRIP; + anbox::graphics::Primitive rectangle; + rectangle.tex_id = 0; + rectangle.type = GL_TRIANGLE_STRIP; - GLfloat tex_right = static_cast(rect.width()) / - buf_size.width(); - GLfloat tex_bottom = static_cast(rect.height()) / - buf_size.height(); + GLfloat tex_right = static_cast(rect.width()) / buf_size.width(); + GLfloat tex_bottom = static_cast(rect.height()) / buf_size.height(); - auto& vertices = rectangle.vertices; - vertices[0] = {{left, top, 0.0f}, {0.0f, 0.0f}}; - vertices[1] = {{left, bottom, 0.0f}, {0.0f, tex_bottom}}; - vertices[2] = {{right, top, 0.0f}, {tex_right, 0.0f}}; - vertices[3] = {{right, bottom, 0.0f}, {tex_right, tex_bottom}}; + auto &vertices = rectangle.vertices; + vertices[0] = {{left, top, 0.0f}, {0.0f, 0.0f}}; + vertices[1] = {{left, bottom, 0.0f}, {0.0f, tex_bottom}}; + vertices[2] = {{right, top, 0.0f}, {tex_right, 0.0f}}; + vertices[3] = {{right, bottom, 0.0f}, {tex_right, tex_bottom}}; - primitives.resize(1); - primitives[0] = rectangle; + primitives.resize(1); + primitives[0] = rectangle; } -void Renderer::draw(RendererWindow *window, const Renderable &renderable, const Program &prog) -{ - const auto &color_buffer = m_colorbuffers.find(renderable.buffer()); - if (color_buffer == m_colorbuffers.end()) - return; +void Renderer::draw(RendererWindow *window, const Renderable &renderable, + const Program &prog) { + const auto &color_buffer = m_colorbuffers.find(renderable.buffer()); + if (color_buffer == m_colorbuffers.end()) return; - const auto &cb = color_buffer->second.cb; + const auto &cb = color_buffer->second.cb; - s_gles2.glUseProgram(prog.id); - s_gles2.glUniform1i(prog.tex_uniform, 0); - s_gles2.glUniformMatrix4fv(prog.display_transform_uniform, 1, GL_FALSE, - glm::value_ptr(window->display_transform)); - s_gles2.glUniformMatrix4fv(prog.screen_to_gl_coords_uniform, 1, GL_FALSE, - glm::value_ptr(window->screen_to_gl_coords)); + s_gles2.glUseProgram(prog.id); + s_gles2.glUniform1i(prog.tex_uniform, 0); + s_gles2.glUniformMatrix4fv(prog.display_transform_uniform, 1, GL_FALSE, + glm::value_ptr(window->display_transform)); + s_gles2.glUniformMatrix4fv(prog.screen_to_gl_coords_uniform, 1, GL_FALSE, + glm::value_ptr(window->screen_to_gl_coords)); - s_gles2.glActiveTexture(GL_TEXTURE0); + s_gles2.glActiveTexture(GL_TEXTURE0); - auto const& rect = renderable.screen_position(); - GLfloat centerx = rect.left() + - rect.width() / 2.0f; - GLfloat centery = rect.top() + - rect.height() / 2.0f; - s_gles2.glUniform2f(prog.center_uniform, centerx, centery); + auto const &rect = renderable.screen_position(); + GLfloat centerx = rect.left() + rect.width() / 2.0f; + GLfloat centery = rect.top() + rect.height() / 2.0f; + s_gles2.glUniform2f(prog.center_uniform, centerx, centery); - s_gles2.glUniformMatrix4fv(prog.transform_uniform, 1, GL_FALSE, - glm::value_ptr(renderable.transformation())); + s_gles2.glUniformMatrix4fv(prog.transform_uniform, 1, GL_FALSE, + glm::value_ptr(renderable.transformation())); - if (prog.alpha_uniform >= 0) - s_gles2.glUniform1f(prog.alpha_uniform, renderable.alpha()); + if (prog.alpha_uniform >= 0) + s_gles2.glUniform1f(prog.alpha_uniform, renderable.alpha()); - s_gles2.glEnableVertexAttribArray(prog.position_attr); - s_gles2.glEnableVertexAttribArray(prog.texcoord_attr); + s_gles2.glEnableVertexAttribArray(prog.position_attr); + s_gles2.glEnableVertexAttribArray(prog.texcoord_attr); - m_primitives.clear(); - tessellate(m_primitives, {cb->getWidth(), cb->getHeight()}, renderable); + m_primitives.clear(); + tessellate(m_primitives, {cb->getWidth(), cb->getHeight()}, renderable); - for (auto const& p : m_primitives) - { - cb->bind(); + for (auto const &p : m_primitives) { + cb->bind(); - s_gles2.glVertexAttribPointer(prog.position_attr, 3, GL_FLOAT, - GL_FALSE, sizeof(anbox::graphics::Vertex), - &p.vertices[0].position); - s_gles2.glVertexAttribPointer(prog.texcoord_attr, 2, GL_FLOAT, - GL_FALSE, sizeof(anbox::graphics::Vertex), - &p.vertices[0].texcoord); + s_gles2.glVertexAttribPointer(prog.position_attr, 3, GL_FLOAT, GL_FALSE, + sizeof(anbox::graphics::Vertex), + &p.vertices[0].position); + s_gles2.glVertexAttribPointer(prog.texcoord_attr, 2, GL_FLOAT, GL_FALSE, + sizeof(anbox::graphics::Vertex), + &p.vertices[0].texcoord); - s_gles2.glEnable(GL_BLEND); - s_gles2.glBlendFuncSeparate(GL_ONE, GL_ONE_MINUS_SRC_ALPHA, - GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + s_gles2.glEnable(GL_BLEND); + s_gles2.glBlendFuncSeparate(GL_ONE, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, + GL_ONE_MINUS_SRC_ALPHA); - s_gles2.glDrawArrays(p.type, 0, p.nvertices); - } + s_gles2.glDrawArrays(p.type, 0, p.nvertices); + } - s_gles2.glDisableVertexAttribArray(prog.texcoord_attr); - s_gles2.glDisableVertexAttribArray(prog.position_attr); + s_gles2.glDisableVertexAttribArray(prog.texcoord_attr); + s_gles2.glDisableVertexAttribArray(prog.position_attr); } -bool Renderer::draw(EGLNativeWindowType native_window, const anbox::graphics::Rect &window_frame, const RenderableList &renderables) -{ - auto w = m_nativeWindows.find(native_window); - if (w == m_nativeWindows.end()) - return false; - - if (!bindWindow_locked(w->second)) - { - m_lock.unlock(); - return false; - } - - setupViewport(w->second, window_frame); - s_gles2.glViewport(0, 0, window_frame.width(), window_frame.height()); - s_gles2.glClearColor(0.0, 0.0, 0.0, 1.0); - s_gles2.glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); - s_gles2.glClear(GL_COLOR_BUFFER_BIT); - - for (const auto &r : renderables) - draw(w->second, r, r.alpha() < 1.0f ? m_alphaProgram : m_defaultProgram); - - s_egl.eglSwapBuffers(m_eglDisplay, w->second->surface); - - unbind_locked(); - - m_lock.lock(); +bool Renderer::draw(EGLNativeWindowType native_window, + const anbox::graphics::Rect &window_frame, + const RenderableList &renderables) { + auto w = m_nativeWindows.find(native_window); + if (w == m_nativeWindows.end()) return false; + if (!bindWindow_locked(w->second)) { m_lock.unlock(); - return false; + } + + setupViewport(w->second, window_frame); + s_gles2.glViewport(0, 0, window_frame.width(), window_frame.height()); + s_gles2.glClearColor(0.0, 0.0, 0.0, 1.0); + s_gles2.glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + s_gles2.glClear(GL_COLOR_BUFFER_BIT); + + for (const auto &r : renderables) + draw(w->second, r, r.alpha() < 1.0f ? m_alphaProgram : m_defaultProgram); + + s_egl.eglSwapBuffers(m_eglDisplay, w->second->surface); + + unbind_locked(); + + m_lock.lock(); + + m_lock.unlock(); + + return false; } diff --git a/src/anbox/graphics/emugl/Renderer.h b/src/anbox/graphics/emugl/Renderer.h index b0bc2c2..c33da81 100644 --- a/src/anbox/graphics/emugl/Renderer.h +++ b/src/anbox/graphics/emugl/Renderer.h @@ -17,18 +17,18 @@ #define _LIBRENDER_FRAMEBUFFER_H #include "ColorBuffer.h" -#include "emugl/common/mutex.h" -#include "RendererConfig.h" #include "RenderContext.h" +#include "RendererConfig.h" #include "TextureDraw.h" #include "WindowSurface.h" +#include "emugl/common/mutex.h" #include "OpenglRender/render_api.h" #include "Renderable.h" -#include "anbox/graphics/program_family.h" #include "anbox/graphics/primitives.h" +#include "anbox/graphics/program_family.h" #include @@ -41,11 +41,12 @@ typedef uint32_t HandleType; struct ColorBufferRef { - ColorBufferPtr cb; - uint32_t refcount; // number of client-side references + ColorBufferPtr cb; + uint32_t refcount; // number of client-side references }; typedef std::map RenderContextMap; -typedef std::map > WindowSurfaceMap; +typedef std::map> + WindowSurfaceMap; typedef std::map ColorBufferMap; // A structure used to list the capabilities of the underlying EGL @@ -57,10 +58,10 @@ typedef std::map ColorBufferMap; // |eglMajor| and |eglMinor| are the major and minor version numbers of // the underlying EGL implementation. struct RendererCaps { - bool has_eglimage_texture_2d; - bool has_eglimage_renderbuffer; - EGLint eglMajor; - EGLint eglMinor; + bool has_eglimage_texture_2d; + bool has_eglimage_renderbuffer; + EGLint eglMajor; + EGLint eglMinor; }; struct RendererWindow; @@ -73,252 +74,251 @@ struct RendererWindow; // and which must be previously setup by calling initialize(). // class Renderer { -public: - // Initialize the global instance. - // |width| and |height| are the dimensions of the emulator GPU display - // in pixels. |useSubWindow| is true to indicate that the caller - // will use setupSubWindow() to let EmuGL display the GPU content in its - // own sub-windows. If false, this means the caller will use - // setPostCallback() instead to retrieve the content. - // Returns true on success, false otherwise. - static bool initialize(EGLNativeDisplayType nativeDisplay); + public: + // Initialize the global instance. + // |width| and |height| are the dimensions of the emulator GPU display + // in pixels. |useSubWindow| is true to indicate that the caller + // will use setupSubWindow() to let EmuGL display the GPU content in its + // own sub-windows. If false, this means the caller will use + // setPostCallback() instead to retrieve the content. + // Returns true on success, false otherwise. + static bool initialize(EGLNativeDisplayType nativeDisplay); - // Finalize the instance. - void finalize(); + // Finalize the instance. + void finalize(); - // Return a pointer to the global instance. initialize() must be called - // previously, or this will return NULL. - static Renderer *get() { return s_renderer; } + // Return a pointer to the global instance. initialize() must be called + // previously, or this will return NULL. + static Renderer* get() { return s_renderer; } - // Return the capabilities of the underlying display. - const RendererCaps &getCaps() const { return m_caps; } + // Return the capabilities of the underlying display. + const RendererCaps& getCaps() const { return m_caps; } - // Return the list of configs available from this display. - const RendererConfigList* getConfigs() const { return m_configs; } + // Return the list of configs available from this display. + const RendererConfigList* getConfigs() const { return m_configs; } - // Set a callback that will be called each time the emulated GPU content - // is updated. This can be relatively slow with host-based GPU emulation, - // so only do this when you need to. - void setPostCallback(OnPostFn onPost, void* onPostContext); + // Set a callback that will be called each time the emulated GPU content + // is updated. This can be relatively slow with host-based GPU emulation, + // so only do this when you need to. + void setPostCallback(OnPostFn onPost, void* onPostContext); - // Retrieve the GL strings of the underlying EGL/GLES implementation. - // On return, |*vendor|, |*renderer| and |*version| will point to strings - // that are owned by the instance (and must not be freed by the caller). - void getGLStrings(const char** vendor, - const char** renderer, - const char** version) const { - *vendor = m_glVendor; - *renderer = m_glRenderer; - *version = m_glVersion; - } + // Retrieve the GL strings of the underlying EGL/GLES implementation. + // On return, |*vendor|, |*renderer| and |*version| will point to strings + // that are owned by the instance (and must not be freed by the caller). + void getGLStrings(const char** vendor, const char** renderer, + const char** version) const { + *vendor = m_glVendor; + *renderer = m_glRenderer; + *version = m_glVersion; + } - RendererWindow* createNativeWindow(EGLNativeWindowType native_window); - void destroyNativeWindow(RendererWindow *window); - void destroyNativeWindow(EGLNativeWindowType native_window); + RendererWindow* createNativeWindow(EGLNativeWindowType native_window); + void destroyNativeWindow(RendererWindow* window); + void destroyNativeWindow(EGLNativeWindowType native_window); - // Create a new RenderContext instance for this display instance. - // |p_config| is the index of one of the configs returned by getConfigs(). - // |p_share| is either EGL_NO_CONTEXT or the handle of a shared context. - // |p_isGL2| is true to create a GLES 2.x context, or false for a GLES 1.x - // one. - // Return a new handle value, which will be 0 in case of error. - HandleType createRenderContext( - int p_config, HandleType p_share, bool p_isGL2 = false); + // Create a new RenderContext instance for this display instance. + // |p_config| is the index of one of the configs returned by getConfigs(). + // |p_share| is either EGL_NO_CONTEXT or the handle of a shared context. + // |p_isGL2| is true to create a GLES 2.x context, or false for a GLES 1.x + // one. + // Return a new handle value, which will be 0 in case of error. + HandleType createRenderContext(int p_config, HandleType p_share, + bool p_isGL2 = false); - // Create a new WindowSurface instance from this display instance. - // |p_config| is the index of one of the configs returned by getConfigs(). - // |p_width| and |p_height| are the window dimensions in pixels. - // Return a new handle value, or 0 in case of error. - HandleType createWindowSurface(int p_config, int p_width, int p_height); + // Create a new WindowSurface instance from this display instance. + // |p_config| is the index of one of the configs returned by getConfigs(). + // |p_width| and |p_height| are the window dimensions in pixels. + // Return a new handle value, or 0 in case of error. + HandleType createWindowSurface(int p_config, int p_width, int p_height); - // Create a new ColorBuffer instance from this display instance. - // |p_width| and |p_height| are its dimensions in pixels. - // |p_internalFormat| is the pixel format. See ColorBuffer::create() for - // list of valid values. Note that ColorBuffer instances are reference- - // counted. Use openColorBuffer / closeColorBuffer to operate on the - // internal count. - HandleType createColorBuffer( - int p_width, int p_height, GLenum p_internalFormat); + // Create a new ColorBuffer instance from this display instance. + // |p_width| and |p_height| are its dimensions in pixels. + // |p_internalFormat| is the pixel format. See ColorBuffer::create() for + // list of valid values. Note that ColorBuffer instances are reference- + // counted. Use openColorBuffer / closeColorBuffer to operate on the + // internal count. + HandleType createColorBuffer(int p_width, int p_height, + GLenum p_internalFormat); - // Call this function when a render thread terminates to destroy all - // the remaining contexts it created. Necessary to avoid leaking host - // contexts when a guest application crashes, for example. - void drainRenderContext(); + // Call this function when a render thread terminates to destroy all + // the remaining contexts it created. Necessary to avoid leaking host + // contexts when a guest application crashes, for example. + void drainRenderContext(); - // Call this function when a render thread terminates to destroy all - // remaining window surfqce it created. Necessary to avoid leaking - // host buffers when a guest application crashes, for example. - void drainWindowSurface(); + // Call this function when a render thread terminates to destroy all + // remaining window surfqce it created. Necessary to avoid leaking + // host buffers when a guest application crashes, for example. + void drainWindowSurface(); - // Destroy a given RenderContext instance. |p_context| is its handle - // value as returned by createRenderContext(). - void DestroyRenderContext(HandleType p_context); + // Destroy a given RenderContext instance. |p_context| is its handle + // value as returned by createRenderContext(). + void DestroyRenderContext(HandleType p_context); - // Destroy a given WindowSurface instance. |p_surcace| is its handle - // value as returned by createWindowSurface(). - void DestroyWindowSurface(HandleType p_surface); + // Destroy a given WindowSurface instance. |p_surcace| is its handle + // value as returned by createWindowSurface(). + void DestroyWindowSurface(HandleType p_surface); - // Increment the reference count associated with a given ColorBuffer - // instance. |p_colorbuffer| is its handle value as returned by - // createColorBuffer(). - int openColorBuffer(HandleType p_colorbuffer); + // Increment the reference count associated with a given ColorBuffer + // instance. |p_colorbuffer| is its handle value as returned by + // createColorBuffer(). + int openColorBuffer(HandleType p_colorbuffer); - // Decrement the reference count associated with a given ColorBuffer - // instance. |p_colorbuffer| is its handle value as returned by - // createColorBuffer(). Note that if the reference count reaches 0, - // the instance is destroyed automatically. - void closeColorBuffer(HandleType p_colorbuffer); + // Decrement the reference count associated with a given ColorBuffer + // instance. |p_colorbuffer| is its handle value as returned by + // createColorBuffer(). Note that if the reference count reaches 0, + // the instance is destroyed automatically. + void closeColorBuffer(HandleType p_colorbuffer); - // Equivalent for eglMakeCurrent() for the current display. - // |p_context|, |p_drawSurface| and |p_readSurface| are the handle values - // of the context, the draw surface and the read surface, respectively. - // Returns true on success, false on failure. - // Note: if all handle values are 0, this is an unbind operation. - bool bindContext(HandleType p_context, - HandleType p_drawSurface, - HandleType p_readSurface); + // Equivalent for eglMakeCurrent() for the current display. + // |p_context|, |p_drawSurface| and |p_readSurface| are the handle values + // of the context, the draw surface and the read surface, respectively. + // Returns true on success, false on failure. + // Note: if all handle values are 0, this is an unbind operation. + bool bindContext(HandleType p_context, HandleType p_drawSurface, + HandleType p_readSurface); - // Attach a ColorBuffer to a WindowSurface instance. - // See the documentation for WindowSurface::setColorBuffer(). - // |p_surface| is the target WindowSurface's handle value. - // |p_colorbuffer| is the ColorBuffer handle value. - // Returns true on success, false otherwise. - bool setWindowSurfaceColorBuffer( - HandleType p_surface, HandleType p_colorbuffer); + // Attach a ColorBuffer to a WindowSurface instance. + // See the documentation for WindowSurface::setColorBuffer(). + // |p_surface| is the target WindowSurface's handle value. + // |p_colorbuffer| is the ColorBuffer handle value. + // Returns true on success, false otherwise. + bool setWindowSurfaceColorBuffer(HandleType p_surface, + HandleType p_colorbuffer); - // Copy the content of a WindowSurface's Pbuffer to its attached - // ColorBuffer. See the documentation for WindowSurface::flushColorBuffer() - // |p_surface| is the target WindowSurface's handle value. - // Returns true on success, false on failure. - bool flushWindowSurfaceColorBuffer(HandleType p_surface); + // Copy the content of a WindowSurface's Pbuffer to its attached + // ColorBuffer. See the documentation for WindowSurface::flushColorBuffer() + // |p_surface| is the target WindowSurface's handle value. + // Returns true on success, false on failure. + bool flushWindowSurfaceColorBuffer(HandleType p_surface); - // Bind the current context's EGL_TEXTURE_2D texture to a ColorBuffer - // instance's EGLImage. This is intended to implement - // glEGLImageTargetTexture2DOES() for all GLES versions. - // |p_colorbuffer| is the ColorBuffer's handle value. - // Returns true on success, false on failure. - bool bindColorBufferToTexture(HandleType p_colorbuffer); + // Bind the current context's EGL_TEXTURE_2D texture to a ColorBuffer + // instance's EGLImage. This is intended to implement + // glEGLImageTargetTexture2DOES() for all GLES versions. + // |p_colorbuffer| is the ColorBuffer's handle value. + // Returns true on success, false on failure. + bool bindColorBufferToTexture(HandleType p_colorbuffer); - // Bind the current context's EGL_RENDERBUFFER_OES render buffer to this - // ColorBuffer's EGLImage. This is intended to implement - // glEGLImageTargetRenderbufferStorageOES() for all GLES versions. - // |p_colorbuffer| is the ColorBuffer's handle value. - // Returns true on success, false on failure. - bool bindColorBufferToRenderbuffer(HandleType p_colorbuffer); + // Bind the current context's EGL_RENDERBUFFER_OES render buffer to this + // ColorBuffer's EGLImage. This is intended to implement + // glEGLImageTargetRenderbufferStorageOES() for all GLES versions. + // |p_colorbuffer| is the ColorBuffer's handle value. + // Returns true on success, false on failure. + bool bindColorBufferToRenderbuffer(HandleType p_colorbuffer); - // Read the content of a given ColorBuffer into client memory. - // |p_colorbuffer| is the ColorBuffer's handle value. Similar - // to glReadPixels(), this can be a slow operation. - // |x|, |y|, |width| and |height| are the position and dimensions of - // a rectangle whose pixel values will be transfered to the host. - // |format| indicates the format of the pixel data, e.g. GL_RGB or GL_RGBA. - // |type| is the type of pixel data, e.g. GL_UNSIGNED_BYTE. - // |pixels| is the address of a caller-provided buffer that will be filled - // with the pixel data. - void readColorBuffer(HandleType p_colorbuffer, - int x, int y, int width, int height, - GLenum format, GLenum type, void *pixels); + // Read the content of a given ColorBuffer into client memory. + // |p_colorbuffer| is the ColorBuffer's handle value. Similar + // to glReadPixels(), this can be a slow operation. + // |x|, |y|, |width| and |height| are the position and dimensions of + // a rectangle whose pixel values will be transfered to the host. + // |format| indicates the format of the pixel data, e.g. GL_RGB or GL_RGBA. + // |type| is the type of pixel data, e.g. GL_UNSIGNED_BYTE. + // |pixels| is the address of a caller-provided buffer that will be filled + // with the pixel data. + void readColorBuffer(HandleType p_colorbuffer, int x, int y, int width, + int height, GLenum format, GLenum type, void* pixels); - // Update the content of a given ColorBuffer from client data. - // |p_colorbuffer| is the ColorBuffer's handle value. Similar - // to glReadPixels(), this can be a slow operation. - // |x|, |y|, |width| and |height| are the position and dimensions of - // a rectangle whose pixel values will be transfered to the GPU - // |format| indicates the format of the pixel data, e.g. GL_RGB or GL_RGBA. - // |type| is the type of pixel data, e.g. GL_UNSIGNED_BYTE. - // |pixels| is the address of a buffer containing the new pixel data. - // Returns true on success, false otherwise. - bool updateColorBuffer(HandleType p_colorbuffer, - int x, int y, int width, int height, - GLenum format, GLenum type, void *pixels); + // Update the content of a given ColorBuffer from client data. + // |p_colorbuffer| is the ColorBuffer's handle value. Similar + // to glReadPixels(), this can be a slow operation. + // |x|, |y|, |width| and |height| are the position and dimensions of + // a rectangle whose pixel values will be transfered to the GPU + // |format| indicates the format of the pixel data, e.g. GL_RGB or GL_RGBA. + // |type| is the type of pixel data, e.g. GL_UNSIGNED_BYTE. + // |pixels| is the address of a buffer containing the new pixel data. + // Returns true on success, false otherwise. + bool updateColorBuffer(HandleType p_colorbuffer, int x, int y, int width, + int height, GLenum format, GLenum type, void* pixels); - bool draw(EGLNativeWindowType native_window, const anbox::graphics::Rect &window_frame, const RenderableList &renderables); + bool draw(EGLNativeWindowType native_window, + const anbox::graphics::Rect& window_frame, + const RenderableList& renderables); - // Return the host EGLDisplay used by this instance. - EGLDisplay getDisplay() const { return m_eglDisplay; } + // Return the host EGLDisplay used by this instance. + EGLDisplay getDisplay() const { return m_eglDisplay; } - // Return a TextureDraw instance that can be used with this surfaces - // and windows created by this instance. - TextureDraw* getTextureDraw() const { return m_textureDraw; } + // Return a TextureDraw instance that can be used with this surfaces + // and windows created by this instance. + TextureDraw* getTextureDraw() const { return m_textureDraw; } - HandleType createClientImage(HandleType context, EGLenum target, GLuint buffer); - EGLBoolean destroyClientImage(HandleType image); + HandleType createClientImage(HandleType context, EGLenum target, + GLuint buffer); + EGLBoolean destroyClientImage(HandleType image); - // Used internally. - bool bind_locked(); - bool unbind_locked(); + // Used internally. + bool bind_locked(); + bool unbind_locked(); -private: - Renderer(); - ~Renderer(); - HandleType genHandle(); + private: + Renderer(); + ~Renderer(); + HandleType genHandle(); - bool bindWindow_locked(RendererWindow *window); + bool bindWindow_locked(RendererWindow* window); - void setupViewport(RendererWindow *window, const anbox::graphics::Rect &rect); - struct Program; - void draw(RendererWindow *window, const Renderable &renderable, const Program &prog); - void tessellate(std::vector& primitives, - const anbox::graphics::Rect &buf_size, - const Renderable &renderable); + void setupViewport(RendererWindow* window, const anbox::graphics::Rect& rect); + struct Program; + void draw(RendererWindow* window, const Renderable& renderable, + const Program& prog); + void tessellate(std::vector& primitives, + const anbox::graphics::Rect& buf_size, + const Renderable& renderable); -private: - static Renderer *s_renderer; - static HandleType s_nextHandle; - emugl::Mutex m_lock; - RendererConfigList* m_configs; - FBNativeWindowType m_nativeWindow; - RendererCaps m_caps; - EGLDisplay m_eglDisplay; - RenderContextMap m_contexts; - WindowSurfaceMap m_windows; - ColorBufferMap m_colorbuffers; - ColorBuffer::Helper* m_colorBufferHelper; + private: + static Renderer* s_renderer; + static HandleType s_nextHandle; + emugl::Mutex m_lock; + RendererConfigList* m_configs; + FBNativeWindowType m_nativeWindow; + RendererCaps m_caps; + EGLDisplay m_eglDisplay; + RenderContextMap m_contexts; + WindowSurfaceMap m_windows; + ColorBufferMap m_colorbuffers; + ColorBuffer::Helper* m_colorBufferHelper; - EGLContext m_eglContext; - EGLSurface m_pbufSurface; - EGLContext m_pbufContext; + EGLContext m_eglContext; + EGLSurface m_pbufSurface; + EGLContext m_pbufContext; - EGLContext m_prevContext; - EGLSurface m_prevReadSurf; - EGLSurface m_prevDrawSurf; - TextureDraw* m_textureDraw; - EGLConfig m_eglConfig; - HandleType m_lastPostedColorBuffer; + EGLContext m_prevContext; + EGLSurface m_prevReadSurf; + EGLSurface m_prevDrawSurf; + TextureDraw* m_textureDraw; + EGLConfig m_eglConfig; + HandleType m_lastPostedColorBuffer; - int m_statsNumFrames; - long long m_statsStartTime; - bool m_fpsStats; + int m_statsNumFrames; + long long m_statsStartTime; + bool m_fpsStats; - const char* m_glVendor; - const char* m_glRenderer; - const char* m_glVersion; + const char* m_glVendor; + const char* m_glRenderer; + const char* m_glVersion; - std::map m_nativeWindows; + std::map m_nativeWindows; - anbox::graphics::ProgramFamily m_family; - struct Program - { - GLuint id = 0; - GLint tex_uniform = -1; - GLint position_attr = -1; - GLint texcoord_attr = -1; - GLint center_uniform = -1; - GLint display_transform_uniform = -1; - GLint transform_uniform = -1; - GLint screen_to_gl_coords_uniform = -1; - GLint alpha_uniform = -1; - mutable long long last_used_frameno = 0; + anbox::graphics::ProgramFamily m_family; + struct Program { + GLuint id = 0; + GLint tex_uniform = -1; + GLint position_attr = -1; + GLint texcoord_attr = -1; + GLint center_uniform = -1; + GLint display_transform_uniform = -1; + GLint transform_uniform = -1; + GLint screen_to_gl_coords_uniform = -1; + GLint alpha_uniform = -1; + mutable long long last_used_frameno = 0; - Program(GLuint program_id); - Program() {} - }; - Program m_defaultProgram, m_alphaProgram; + Program(GLuint program_id); + Program() {} + }; + Program m_defaultProgram, m_alphaProgram; - std::vector m_primitives; + std::vector m_primitives; - static const GLchar* const vshader; - static const GLchar* const defaultFShader; - static const GLchar* const alphaFShader; + static const GLchar* const vshader; + static const GLchar* const defaultFShader; + static const GLchar* const alphaFShader; }; #endif diff --git a/src/anbox/graphics/emugl/RendererConfig.cpp b/src/anbox/graphics/emugl/RendererConfig.cpp index 09f227a..dd76f46 100644 --- a/src/anbox/graphics/emugl/RendererConfig.cpp +++ b/src/anbox/graphics/emugl/RendererConfig.cpp @@ -21,255 +21,223 @@ namespace { -#define E(...) fprintf(stderr, __VA_ARGS__) +#define E(...) fprintf(stderr, __VA_ARGS__) const GLuint kConfigAttributes[] = { - EGL_DEPTH_SIZE, // must be first - see getDepthSize() - EGL_STENCIL_SIZE, // must be second - see getStencilSize() - EGL_RENDERABLE_TYPE,// must be third - see getRenderableType() - EGL_SURFACE_TYPE, // must be fourth - see getSurfaceType() - EGL_CONFIG_ID, // must be fifth - see chooseConfig() - EGL_BUFFER_SIZE, - EGL_ALPHA_SIZE, - EGL_BLUE_SIZE, - EGL_GREEN_SIZE, - EGL_RED_SIZE, - EGL_CONFIG_CAVEAT, - EGL_LEVEL, - EGL_MAX_PBUFFER_HEIGHT, - EGL_MAX_PBUFFER_PIXELS, - EGL_MAX_PBUFFER_WIDTH, - EGL_NATIVE_RENDERABLE, - EGL_NATIVE_VISUAL_ID, - EGL_NATIVE_VISUAL_TYPE, - EGL_SAMPLES, - EGL_SAMPLE_BUFFERS, - EGL_TRANSPARENT_TYPE, - EGL_TRANSPARENT_BLUE_VALUE, - EGL_TRANSPARENT_GREEN_VALUE, - EGL_TRANSPARENT_RED_VALUE, - EGL_BIND_TO_TEXTURE_RGB, - EGL_BIND_TO_TEXTURE_RGBA, - EGL_MIN_SWAP_INTERVAL, - EGL_MAX_SWAP_INTERVAL, - EGL_LUMINANCE_SIZE, - EGL_ALPHA_MASK_SIZE, + EGL_DEPTH_SIZE, // must be first - see getDepthSize() + EGL_STENCIL_SIZE, // must be second - see getStencilSize() + EGL_RENDERABLE_TYPE, // must be third - see getRenderableType() + EGL_SURFACE_TYPE, // must be fourth - see getSurfaceType() + EGL_CONFIG_ID, // must be fifth - see chooseConfig() + EGL_BUFFER_SIZE, EGL_ALPHA_SIZE, EGL_BLUE_SIZE, EGL_GREEN_SIZE, + EGL_RED_SIZE, EGL_CONFIG_CAVEAT, EGL_LEVEL, EGL_MAX_PBUFFER_HEIGHT, + EGL_MAX_PBUFFER_PIXELS, EGL_MAX_PBUFFER_WIDTH, EGL_NATIVE_RENDERABLE, + EGL_NATIVE_VISUAL_ID, EGL_NATIVE_VISUAL_TYPE, EGL_SAMPLES, + EGL_SAMPLE_BUFFERS, EGL_TRANSPARENT_TYPE, EGL_TRANSPARENT_BLUE_VALUE, + EGL_TRANSPARENT_GREEN_VALUE, EGL_TRANSPARENT_RED_VALUE, + EGL_BIND_TO_TEXTURE_RGB, EGL_BIND_TO_TEXTURE_RGBA, EGL_MIN_SWAP_INTERVAL, + EGL_MAX_SWAP_INTERVAL, EGL_LUMINANCE_SIZE, EGL_ALPHA_MASK_SIZE, EGL_COLOR_BUFFER_TYPE, - //EGL_MATCH_NATIVE_PIXMAP, - EGL_CONFORMANT -}; + // EGL_MATCH_NATIVE_PIXMAP, + EGL_CONFORMANT}; const size_t kConfigAttributesLen = - sizeof(kConfigAttributes) / sizeof(kConfigAttributes[0]); + sizeof(kConfigAttributes) / sizeof(kConfigAttributes[0]); bool isCompatibleHostConfig(EGLConfig config, EGLDisplay display) { - // Filter out configs which do not support pbuffers, since they - // are used to implement window surfaces. - EGLint surfaceType; - s_egl.eglGetConfigAttrib( - display, config, EGL_SURFACE_TYPE, &surfaceType); - if (!(surfaceType & EGL_PBUFFER_BIT)) { - return false; - } + // Filter out configs which do not support pbuffers, since they + // are used to implement window surfaces. + EGLint surfaceType; + s_egl.eglGetConfigAttrib(display, config, EGL_SURFACE_TYPE, &surfaceType); + if (!(surfaceType & EGL_PBUFFER_BIT)) { + return false; + } - // Filter out configs that do not support RGB pixel values. - EGLint redSize = 0, greenSize = 0, blueSize = 0, alphaSize = 0; - s_egl.eglGetConfigAttrib( - display, config,EGL_RED_SIZE, &redSize); - s_egl.eglGetConfigAttrib( - display, config, EGL_GREEN_SIZE, &greenSize); - s_egl.eglGetConfigAttrib( - display, config, EGL_BLUE_SIZE, &blueSize); - s_egl.eglGetConfigAttrib( - display, config, EGL_ALPHA_SIZE, &alphaSize); + // Filter out configs that do not support RGB pixel values. + EGLint redSize = 0, greenSize = 0, blueSize = 0, alphaSize = 0; + s_egl.eglGetConfigAttrib(display, config, EGL_RED_SIZE, &redSize); + s_egl.eglGetConfigAttrib(display, config, EGL_GREEN_SIZE, &greenSize); + s_egl.eglGetConfigAttrib(display, config, EGL_BLUE_SIZE, &blueSize); + s_egl.eglGetConfigAttrib(display, config, EGL_ALPHA_SIZE, &alphaSize); - if (!redSize || !greenSize || !blueSize || !alphaSize) { - return false; - } + if (!redSize || !greenSize || !blueSize || !alphaSize) { + return false; + } - return true; + return true; } } // namespace -RendererConfig::~RendererConfig() { - delete [] mAttribValues; +RendererConfig::~RendererConfig() { delete[] mAttribValues; } + +RendererConfig::RendererConfig(EGLConfig hostConfig, EGLDisplay hostDisplay) + : mEglConfig(hostConfig), mAttribValues(NULL) { + mAttribValues = new GLint[kConfigAttributesLen]; + for (size_t i = 0; i < kConfigAttributesLen; ++i) { + mAttribValues[i] = 0; + s_egl.eglGetConfigAttrib(hostDisplay, hostConfig, kConfigAttributes[i], + &mAttribValues[i]); + + // This implementation supports guest window surfaces by wrapping + // them around host Pbuffers, so always report it to the guest. + if (kConfigAttributes[i] == EGL_SURFACE_TYPE) { + mAttribValues[i] |= EGL_WINDOW_BIT; + } + } } -RendererConfig::RendererConfig(EGLConfig hostConfig, EGLDisplay hostDisplay) : - mEglConfig(hostConfig), mAttribValues(NULL) { - mAttribValues = new GLint[kConfigAttributesLen]; - for (size_t i = 0; i < kConfigAttributesLen; ++i) { - mAttribValues[i] = 0; - s_egl.eglGetConfigAttrib(hostDisplay, - hostConfig, - kConfigAttributes[i], - &mAttribValues[i]); +RendererConfigList::RendererConfigList(EGLDisplay display) + : mCount(0), mConfigs(NULL), mDisplay(display) { + if (display == EGL_NO_DISPLAY) { + E("%s: Invalid display value %p (EGL_NO_DISPLAY)\n", __FUNCTION__, + (void*)display); + return; + } - // This implementation supports guest window surfaces by wrapping - // them around host Pbuffers, so always report it to the guest. - if (kConfigAttributes[i] == EGL_SURFACE_TYPE) { - mAttribValues[i] |= EGL_WINDOW_BIT; - } + EGLint numHostConfigs = 0; + if (!s_egl.eglGetConfigs(display, NULL, 0, &numHostConfigs)) { + E("%s: Could not get number of host EGL configs\n", __FUNCTION__); + return; + } + EGLConfig* hostConfigs = new EGLConfig[numHostConfigs]; + s_egl.eglGetConfigs(display, hostConfigs, numHostConfigs, &numHostConfigs); + + mConfigs = new RendererConfig*[numHostConfigs]; + for (EGLint i = 0; i < numHostConfigs; ++i) { + // Filter out configs that are not compatible with our implementation. + if (!isCompatibleHostConfig(hostConfigs[i], display)) { + continue; } -} + mConfigs[mCount] = new RendererConfig(hostConfigs[i], display); + mCount++; + } -RendererConfigList::RendererConfigList(EGLDisplay display) : - mCount(0), mConfigs(NULL), mDisplay(display) { - if (display == EGL_NO_DISPLAY) { - E("%s: Invalid display value %p (EGL_NO_DISPLAY)\n", - __FUNCTION__, (void*)display); - return; - } - - EGLint numHostConfigs = 0; - if (!s_egl.eglGetConfigs(display, NULL, 0, &numHostConfigs)) { - E("%s: Could not get number of host EGL configs\n", __FUNCTION__); - return; - } - EGLConfig* hostConfigs = new EGLConfig[numHostConfigs]; - s_egl.eglGetConfigs(display, hostConfigs, numHostConfigs, &numHostConfigs); - - mConfigs = new RendererConfig*[numHostConfigs]; - for (EGLint i = 0; i < numHostConfigs; ++i) { - // Filter out configs that are not compatible with our implementation. - if (!isCompatibleHostConfig(hostConfigs[i], display)) { - continue; - } - mConfigs[mCount] = new RendererConfig(hostConfigs[i], display); - mCount++; - } - - delete [] hostConfigs; + delete[] hostConfigs; } RendererConfigList::~RendererConfigList() { - for (int n = 0; n < mCount; ++n) { - delete mConfigs[n]; - } - delete [] mConfigs; + for (int n = 0; n < mCount; ++n) { + delete mConfigs[n]; + } + delete[] mConfigs; } -int RendererConfigList::chooseConfig(const EGLint* attribs, - EGLint* configs, - EGLint configsSize) const { - EGLint numHostConfigs = 0; - if (!s_egl.eglGetConfigs(mDisplay, NULL, 0, &numHostConfigs)) { - E("%s: Could not get number of host EGL configs\n", __FUNCTION__); - return 0; +int RendererConfigList::chooseConfig(const EGLint* attribs, EGLint* configs, + EGLint configsSize) const { + EGLint numHostConfigs = 0; + if (!s_egl.eglGetConfigs(mDisplay, NULL, 0, &numHostConfigs)) { + E("%s: Could not get number of host EGL configs\n", __FUNCTION__); + return 0; + } + + EGLConfig* matchedConfigs = new EGLConfig[numHostConfigs]; + + // If EGL_SURFACE_TYPE appears in |attribs|, the value passed to + // eglChooseConfig should be forced to EGL_PBUFFER_BIT because that's + // what it used by the current implementation, exclusively. This forces + // the rewrite of |attribs| into a new array. + bool hasSurfaceType = false; + bool mustReplaceSurfaceType = false; + int numAttribs = 0; + while (attribs[numAttribs] != EGL_NONE) { + if (attribs[numAttribs] == EGL_SURFACE_TYPE) { + hasSurfaceType = true; + if (attribs[numAttribs + 1] != EGL_PBUFFER_BIT) { + mustReplaceSurfaceType = true; + } } + numAttribs += 2; + } - EGLConfig* matchedConfigs = new EGLConfig[numHostConfigs]; + EGLint* newAttribs = NULL; - // If EGL_SURFACE_TYPE appears in |attribs|, the value passed to - // eglChooseConfig should be forced to EGL_PBUFFER_BIT because that's - // what it used by the current implementation, exclusively. This forces - // the rewrite of |attribs| into a new array. - bool hasSurfaceType = false; - bool mustReplaceSurfaceType = false; - int numAttribs = 0; - while (attribs[numAttribs] != EGL_NONE) { - if (attribs[numAttribs] == EGL_SURFACE_TYPE) { - hasSurfaceType = true; - if (attribs[numAttribs + 1] != EGL_PBUFFER_BIT) { - mustReplaceSurfaceType = true; - } - } - numAttribs += 2; + if (mustReplaceSurfaceType) { + // There is at least on EGL_SURFACE_TYPE in |attribs|. Copy the + // array and replace all values with EGL_PBUFFER_BIT + newAttribs = new GLint[numAttribs + 1]; + memcpy(newAttribs, attribs, numAttribs * sizeof(GLint)); + newAttribs[numAttribs] = EGL_NONE; + for (int n = 0; n < numAttribs; n += 2) { + if (newAttribs[n] == EGL_SURFACE_TYPE) { + newAttribs[n + 1] = EGL_PBUFFER_BIT; + } } + } else if (!hasSurfaceType) { + // There is no EGL_SURFACE_TYPE in |attribs|, then add one entry + // with the value EGL_PBUFFER_BIT. + newAttribs = new GLint[numAttribs + 3]; + memcpy(newAttribs, attribs, numAttribs * sizeof(GLint)); + newAttribs[numAttribs] = EGL_SURFACE_TYPE; + newAttribs[numAttribs + 1] = EGL_PBUFFER_BIT; + newAttribs[numAttribs + 2] = EGL_NONE; + } - EGLint* newAttribs = NULL; + if (!s_egl.eglChooseConfig(mDisplay, newAttribs ? newAttribs : attribs, + matchedConfigs, numHostConfigs, &numHostConfigs)) { + numHostConfigs = 0; + } - if (mustReplaceSurfaceType) { - // There is at least on EGL_SURFACE_TYPE in |attribs|. Copy the - // array and replace all values with EGL_PBUFFER_BIT - newAttribs = new GLint[numAttribs + 1]; - memcpy(newAttribs, attribs, numAttribs * sizeof(GLint)); - newAttribs[numAttribs] = EGL_NONE; - for (int n = 0; n < numAttribs; n += 2) { - if (newAttribs[n] == EGL_SURFACE_TYPE) { - newAttribs[n + 1] = EGL_PBUFFER_BIT; - } - } - } else if (!hasSurfaceType) { - // There is no EGL_SURFACE_TYPE in |attribs|, then add one entry - // with the value EGL_PBUFFER_BIT. - newAttribs = new GLint[numAttribs + 3]; - memcpy(newAttribs, attribs, numAttribs * sizeof(GLint)); - newAttribs[numAttribs] = EGL_SURFACE_TYPE; - newAttribs[numAttribs + 1] = EGL_PBUFFER_BIT; - newAttribs[numAttribs + 2] = EGL_NONE; + delete[] newAttribs; + + int result = 0; + for (int n = 0; n < numHostConfigs; ++n) { + // Don't count or write more than |configsSize| items if |configs| + // is not NULL. + if (configs && configsSize > 0 && result >= configsSize) { + break; } - - if (!s_egl.eglChooseConfig(mDisplay, - newAttribs ? newAttribs : attribs, - matchedConfigs, - numHostConfigs, - &numHostConfigs)) { - numHostConfigs = 0; + // Skip incompatible host configs. + if (!isCompatibleHostConfig(matchedConfigs[n], mDisplay)) { + continue; } - - delete [] newAttribs; - - int result = 0; - for (int n = 0; n < numHostConfigs; ++n) { - // Don't count or write more than |configsSize| items if |configs| - // is not NULL. - if (configs && configsSize > 0 && result >= configsSize) { - break; - } - // Skip incompatible host configs. - if (!isCompatibleHostConfig(matchedConfigs[n], mDisplay)) { - continue; - } - // Find the FbConfig with the same EGL_CONFIG_ID - EGLint hostConfigId; - s_egl.eglGetConfigAttrib( - mDisplay, matchedConfigs[n], EGL_CONFIG_ID, &hostConfigId); - for (int k = 0; k < mCount; ++k) { - int guestConfigId = mConfigs[k]->getConfigId(); - if (guestConfigId == hostConfigId) { - // There is a match. Write it to |configs| if it is not NULL. - if (configs && result < configsSize) { - configs[result] = (uint32_t)k; - } - result ++; - break; - } + // Find the FbConfig with the same EGL_CONFIG_ID + EGLint hostConfigId; + s_egl.eglGetConfigAttrib(mDisplay, matchedConfigs[n], EGL_CONFIG_ID, + &hostConfigId); + for (int k = 0; k < mCount; ++k) { + int guestConfigId = mConfigs[k]->getConfigId(); + if (guestConfigId == hostConfigId) { + // There is a match. Write it to |configs| if it is not NULL. + if (configs && result < configsSize) { + configs[result] = (uint32_t)k; } + result++; + break; + } } + } - delete [] matchedConfigs; + delete[] matchedConfigs; - return result; + return result; } - void RendererConfigList::getPackInfo(EGLint* numConfigs, - EGLint* numAttributes) const { - if (numConfigs) { - *numConfigs = mCount; - } - if (numAttributes) { - *numAttributes = static_cast(kConfigAttributesLen); - } + EGLint* numAttributes) const { + if (numConfigs) { + *numConfigs = mCount; + } + if (numAttributes) { + *numAttributes = static_cast(kConfigAttributesLen); + } } -EGLint RendererConfigList::packConfigs(GLuint bufferByteSize, GLuint* buffer) const { - GLuint numAttribs = static_cast(kConfigAttributesLen); - GLuint kGLuintSize = static_cast(sizeof(GLuint)); - GLuint neededByteSize = (mCount + 1) * numAttribs * kGLuintSize; - if (!buffer || bufferByteSize < neededByteSize) { - return -neededByteSize; - } - // Write to the buffer the config attribute ids, followed for each one - // of the configs, their values. - memcpy(buffer, kConfigAttributes, kConfigAttributesLen * kGLuintSize); +EGLint RendererConfigList::packConfigs(GLuint bufferByteSize, + GLuint* buffer) const { + GLuint numAttribs = static_cast(kConfigAttributesLen); + GLuint kGLuintSize = static_cast(sizeof(GLuint)); + GLuint neededByteSize = (mCount + 1) * numAttribs * kGLuintSize; + if (!buffer || bufferByteSize < neededByteSize) { + return -neededByteSize; + } + // Write to the buffer the config attribute ids, followed for each one + // of the configs, their values. + memcpy(buffer, kConfigAttributes, kConfigAttributesLen * kGLuintSize); - for (int i = 0; i < mCount; ++i) { - memcpy(buffer + (i + 1) * kConfigAttributesLen, - mConfigs[i]->mAttribValues, - kConfigAttributesLen * kGLuintSize); - } - return mCount; + for (int i = 0; i < mCount; ++i) { + memcpy(buffer + (i + 1) * kConfigAttributesLen, mConfigs[i]->mAttribValues, + kConfigAttributesLen * kGLuintSize); + } + return mCount; } diff --git a/src/anbox/graphics/emugl/RendererConfig.h b/src/anbox/graphics/emugl/RendererConfig.h index c49ee1a..5dfcb89 100644 --- a/src/anbox/graphics/emugl/RendererConfig.h +++ b/src/anbox/graphics/emugl/RendererConfig.h @@ -33,43 +33,43 @@ // an FbConfigList from the host EGLDisplay, and use its size() and get() // methods to access it. class RendererConfig { -public: - // Destructor - ~RendererConfig(); + public: + // Destructor + ~RendererConfig(); - // Retrieve host EGLConfig. - EGLConfig getEglConfig() const { return mEglConfig; } + // Retrieve host EGLConfig. + EGLConfig getEglConfig() const { return mEglConfig; } - // Get depth size in bits. - GLuint getDepthSize() const { return getAttribValue(0); } + // Get depth size in bits. + GLuint getDepthSize() const { return getAttribValue(0); } - // Get stencil size in bits. - GLuint getStencilSize() const { return getAttribValue(1); } + // Get stencil size in bits. + GLuint getStencilSize() const { return getAttribValue(1); } - // Get renderable type mask. - GLuint getRenderableType() const { return getAttribValue(2); } + // Get renderable type mask. + GLuint getRenderableType() const { return getAttribValue(2); } - // Get surface type mask. - GLuint getSurfaceType() const { return getAttribValue(3); } + // Get surface type mask. + GLuint getSurfaceType() const { return getAttribValue(3); } - // Get the EGL_CONFIG_ID value. This is the same as the one of the - // underlying host EGLConfig handle. - GLint getConfigId() const { return (GLint)getAttribValue(4); } + // Get the EGL_CONFIG_ID value. This is the same as the one of the + // underlying host EGLConfig handle. + GLint getConfigId() const { return (GLint)getAttribValue(4); } -private: - RendererConfig(); - RendererConfig(RendererConfig& other); + private: + RendererConfig(); + RendererConfig(RendererConfig& other); - explicit RendererConfig(EGLConfig hostConfig, EGLDisplay hostDisplay); + explicit RendererConfig(EGLConfig hostConfig, EGLDisplay hostDisplay); - friend class RendererConfigList; + friend class RendererConfigList; - GLuint getAttribValue(int n) const { - return mAttribValues ? mAttribValues[n] : 0U; - } + GLuint getAttribValue(int n) const { + return mAttribValues ? mAttribValues[n] : 0U; + } - EGLConfig mEglConfig; - GLint* mAttribValues; + EGLConfig mEglConfig; + GLint* mAttribValues; }; // A class to model the list of FbConfig for a given EGLDisplay, this is @@ -92,72 +92,71 @@ private: // 5) Use getPackInfo() and packConfigs() to retrieve information about // available configs to the guest. class RendererConfigList { -public: - // Create a new list of FbConfig instance, by querying all compatible - // host configs from |display|. A compatible config is one that supports - // Pbuffers and RGB pixel values. - // - // After construction, call empty() to check if there are items. - // An empty list means there was an error during construction. - explicit RendererConfigList(EGLDisplay display); + public: + // Create a new list of FbConfig instance, by querying all compatible + // host configs from |display|. A compatible config is one that supports + // Pbuffers and RGB pixel values. + // + // After construction, call empty() to check if there are items. + // An empty list means there was an error during construction. + explicit RendererConfigList(EGLDisplay display); - // Destructor. - ~RendererConfigList(); + // Destructor. + ~RendererConfigList(); - // Return true iff the list is empty. true means there was an error - // during construction. - bool empty() const { return mCount == 0; } + // Return true iff the list is empty. true means there was an error + // during construction. + bool empty() const { return mCount == 0; } - // Return the number of FbConfig instances in the list. - // Each instance is identified by a number from 0 to N-1, - // where N is the result of this function. - size_t size() const { return static_cast(mCount); } + // Return the number of FbConfig instances in the list. + // Each instance is identified by a number from 0 to N-1, + // where N is the result of this function. + size_t size() const { return static_cast(mCount); } - // Retrieve the FbConfig instance associated with |guestId|, - // which must be an integer between 0 and |size() - 1|. Returns - // NULL in case of failure. - const RendererConfig* get(int guestId) const { - if (guestId >= 0 && guestId < mCount) { - return mConfigs[guestId]; - } else { - return NULL; - } + // Retrieve the FbConfig instance associated with |guestId|, + // which must be an integer between 0 and |size() - 1|. Returns + // NULL in case of failure. + const RendererConfig* get(int guestId) const { + if (guestId >= 0 && guestId < mCount) { + return mConfigs[guestId]; + } else { + return NULL; } + } - // Use |attribs| a list of EGL attribute name/values terminated by - // EGL_NONE, to select a set of matching FbConfig instances. - // - // On success, returns the number of matching instances. - // If |configs| is not NULL, it will be populated with the guest IDs - // of the matched FbConfig instances. - // - // |configsSize| is the number of entries in the |configs| array. The - // function will never write more than |configsSize| entries into - // |configsSize|. - EGLint chooseConfig(const EGLint* attribs, - EGLint* configs, - EGLint configsSize) const; + // Use |attribs| a list of EGL attribute name/values terminated by + // EGL_NONE, to select a set of matching FbConfig instances. + // + // On success, returns the number of matching instances. + // If |configs| is not NULL, it will be populated with the guest IDs + // of the matched FbConfig instances. + // + // |configsSize| is the number of entries in the |configs| array. The + // function will never write more than |configsSize| entries into + // |configsSize|. + EGLint chooseConfig(const EGLint* attribs, EGLint* configs, + EGLint configsSize) const; - // Retrieve information that can be sent to the guest before packed - // config list information. If |numConfigs| is NULL, then |*numConfigs| - // will be set on return to the number of config instances. - // If |numAttribs| is not NULL, then |*numAttribs| will be set on return - // to the number of attribute values cached by each FbConfig instance. - void getPackInfo(EGLint* mumConfigs, EGLint* numAttribs) const; + // Retrieve information that can be sent to the guest before packed + // config list information. If |numConfigs| is NULL, then |*numConfigs| + // will be set on return to the number of config instances. + // If |numAttribs| is not NULL, then |*numAttribs| will be set on return + // to the number of attribute values cached by each FbConfig instance. + void getPackInfo(EGLint* mumConfigs, EGLint* numAttribs) const; - // Write the full list information into an array of EGLuint items. - // |buffer| is the output buffer that will receive the data. - // |bufferByteSize| is teh buffer size in bytes. - // On success, this returns - EGLint packConfigs(GLuint bufferByteSize, GLuint* buffer) const; + // Write the full list information into an array of EGLuint items. + // |buffer| is the output buffer that will receive the data. + // |bufferByteSize| is teh buffer size in bytes. + // On success, this returns + EGLint packConfigs(GLuint bufferByteSize, GLuint* buffer) const; -private: - RendererConfigList(); - RendererConfigList(const RendererConfigList& other); + private: + RendererConfigList(); + RendererConfigList(const RendererConfigList& other); - int mCount; - RendererConfig** mConfigs; - EGLDisplay mDisplay; + int mCount; + RendererConfig** mConfigs; + EGLDisplay mDisplay; }; #endif // _LIBRENDER_FB_CONFIG_H diff --git a/src/anbox/graphics/emugl/SocketStream.cpp b/src/anbox/graphics/emugl/SocketStream.cpp index 24f5436..6c08dfc 100644 --- a/src/anbox/graphics/emugl/SocketStream.cpp +++ b/src/anbox/graphics/emugl/SocketStream.cpp @@ -15,152 +15,130 @@ */ #include "SocketStream.h" #include -#include -#include -#include -#include #include #include +#include +#include +#include #include +#include -SocketStream::SocketStream(size_t bufSize) : - IOStream(bufSize), - m_sock(-1), - m_bufsize(bufSize), - m_buf(NULL) -{ +SocketStream::SocketStream(size_t bufSize) + : IOStream(bufSize), m_sock(-1), m_bufsize(bufSize), m_buf(NULL) {} + +SocketStream::SocketStream(int sock, size_t bufSize) + : IOStream(bufSize), m_sock(sock), m_bufsize(bufSize), m_buf(NULL) {} + +SocketStream::~SocketStream() { + if (m_sock >= 0) { + forceStop(); + if (close(m_sock) < 0) perror("Closing SocketStream failed"); + // DBG("SocketStream::~close @ %d \n", m_sock); + m_sock = -1; + } + if (m_buf != NULL) { + free(m_buf); + m_buf = NULL; + } } -SocketStream::SocketStream(int sock, size_t bufSize) : - IOStream(bufSize), - m_sock(sock), - m_bufsize(bufSize), - m_buf(NULL) -{ -} - -SocketStream::~SocketStream() -{ - if (m_sock >= 0) { - forceStop(); - if(close(m_sock) < 0) - perror("Closing SocketStream failed"); - // DBG("SocketStream::~close @ %d \n", m_sock); - m_sock = -1; +void *SocketStream::allocBuffer(size_t minSize) { + size_t allocSize = (m_bufsize < minSize ? minSize : m_bufsize); + if (!m_buf) { + m_buf = (unsigned char *)malloc(allocSize); + } else if (m_bufsize < allocSize) { + unsigned char *p = (unsigned char *)realloc(m_buf, allocSize); + if (p != NULL) { + m_buf = p; + m_bufsize = allocSize; + } else { + ERR("%s: realloc (%zu) failed\n", __FUNCTION__, allocSize); + free(m_buf); + m_buf = NULL; + m_bufsize = 0; } - if (m_buf != NULL) { - free(m_buf); - m_buf = NULL; - } -} + } - -void *SocketStream::allocBuffer(size_t minSize) -{ - size_t allocSize = (m_bufsize < minSize ? minSize : m_bufsize); - if (!m_buf) { - m_buf = (unsigned char *)malloc(allocSize); - } - else if (m_bufsize < allocSize) { - unsigned char *p = (unsigned char *)realloc(m_buf, allocSize); - if (p != NULL) { - m_buf = p; - m_bufsize = allocSize; - } else { - ERR("%s: realloc (%zu) failed\n", __FUNCTION__, allocSize); - free(m_buf); - m_buf = NULL; - m_bufsize = 0; - } - } - - return m_buf; + return m_buf; }; -int SocketStream::commitBuffer(size_t size) -{ - return writeFully(m_buf, size); -} +int SocketStream::commitBuffer(size_t size) { return writeFully(m_buf, size); } -int SocketStream::writeFully(const void* buffer, size_t size) -{ - if (!valid()) return -1; +int SocketStream::writeFully(const void *buffer, size_t size) { + if (!valid()) return -1; - size_t res = size; - int retval = 0; + size_t res = size; + int retval = 0; - while (res > 0) { - ssize_t stat = ::send(m_sock, (const char *)buffer + (size - res), res, 0); - if (stat < 0) { - if (errno != EINTR) { - retval = stat; - ERR("%s: failed: %s\n", __FUNCTION__, strerror(errno)); - break; - } - } else { - res -= stat; - } - } - return retval; -} - -const unsigned char *SocketStream::readFully(void *buf, size_t len) -{ - if (!valid()) return NULL; - if (!buf) { - return NULL; // do not allow NULL buf in that implementation - } - size_t res = len; - while (res > 0) { - ssize_t stat = ::recv(m_sock, (char *)(buf) + len - res, res, 0); - if (stat > 0) { - res -= stat; - continue; - } - if (stat == 0 || errno != EINTR) { // client shutdown or error - return NULL; - } - } - return (const unsigned char *)buf; -} - -const unsigned char *SocketStream::read( void *buf, size_t *inout_len) -{ - if (!valid()) return NULL; - if (!buf) { - return NULL; // do not allow NULL buf in that implementation - } - - int n; - do { - n = this->recv(buf, *inout_len); - } while( n < 0 && errno == EINTR ); - - if (n > 0) { - *inout_len = n; - return (const unsigned char *)buf; - } - - return NULL; -} - -int SocketStream::recv(void *buf, size_t len) -{ - if (!valid()) return int(ERR_INVALID_SOCKET); - int res = 0; - while(true) { - res = ::recv(m_sock, (char *)buf, len, 0); - if (res < 0) { - if (errno == EINTR) { - continue; - } - } + while (res > 0) { + ssize_t stat = ::send(m_sock, (const char *)buffer + (size - res), res, 0); + if (stat < 0) { + if (errno != EINTR) { + retval = stat; + ERR("%s: failed: %s\n", __FUNCTION__, strerror(errno)); break; + } + } else { + res -= stat; } - return res; + } + return retval; +} + +const unsigned char *SocketStream::readFully(void *buf, size_t len) { + if (!valid()) return NULL; + if (!buf) { + return NULL; // do not allow NULL buf in that implementation + } + size_t res = len; + while (res > 0) { + ssize_t stat = ::recv(m_sock, (char *)(buf) + len - res, res, 0); + if (stat > 0) { + res -= stat; + continue; + } + if (stat == 0 || errno != EINTR) { // client shutdown or error + return NULL; + } + } + return (const unsigned char *)buf; +} + +const unsigned char *SocketStream::read(void *buf, size_t *inout_len) { + if (!valid()) return NULL; + if (!buf) { + return NULL; // do not allow NULL buf in that implementation + } + + int n; + do { + n = this->recv(buf, *inout_len); + } while (n < 0 && errno == EINTR); + + if (n > 0) { + *inout_len = n; + return (const unsigned char *)buf; + } + + return NULL; +} + +int SocketStream::recv(void *buf, size_t len) { + if (!valid()) return int(ERR_INVALID_SOCKET); + int res = 0; + while (true) { + res = ::recv(m_sock, (char *)buf, len, 0); + if (res < 0) { + if (errno == EINTR) { + continue; + } + } + break; + } + return res; } void SocketStream::forceStop() { - // Shutdown socket to force read/write errors. - ::shutdown(m_sock, SHUT_RDWR); + // Shutdown socket to force read/write errors. + ::shutdown(m_sock, SHUT_RDWR); } diff --git a/src/anbox/graphics/emugl/SocketStream.h b/src/anbox/graphics/emugl/SocketStream.h index 2a9cf13..df88659 100644 --- a/src/anbox/graphics/emugl/SocketStream.h +++ b/src/anbox/graphics/emugl/SocketStream.h @@ -20,34 +20,34 @@ #include "IOStream.h" class SocketStream : public IOStream { -public: - typedef enum { ERR_INVALID_SOCKET = -1000 } SocketStreamError; - static const size_t MAX_ADDRSTR_LEN = 256; + public: + typedef enum { ERR_INVALID_SOCKET = -1000 } SocketStreamError; + static const size_t MAX_ADDRSTR_LEN = 256; - explicit SocketStream(size_t bufsize = 10000); - virtual ~SocketStream(); + explicit SocketStream(size_t bufsize = 10000); + virtual ~SocketStream(); - virtual int listen(char addrstr[MAX_ADDRSTR_LEN]) = 0; - virtual SocketStream *accept() = 0; - virtual int connect(const char* addr) = 0; + virtual int listen(char addrstr[MAX_ADDRSTR_LEN]) = 0; + virtual SocketStream *accept() = 0; + virtual int connect(const char *addr) = 0; - virtual void *allocBuffer(size_t minSize); - virtual int commitBuffer(size_t size); - virtual const unsigned char *readFully(void *buf, size_t len); - virtual const unsigned char *read(void *buf, size_t *inout_len); + virtual void *allocBuffer(size_t minSize); + virtual int commitBuffer(size_t size); + virtual const unsigned char *readFully(void *buf, size_t len); + virtual const unsigned char *read(void *buf, size_t *inout_len); - bool valid() { return m_sock >= 0; } - virtual int recv(void *buf, size_t len); - virtual int writeFully(const void *buf, size_t len); + bool valid() { return m_sock >= 0; } + virtual int recv(void *buf, size_t len); + virtual int writeFully(const void *buf, size_t len); - virtual void forceStop(); + virtual void forceStop(); -protected: - int m_sock; - size_t m_bufsize; - unsigned char *m_buf; + protected: + int m_sock; + size_t m_bufsize; + unsigned char *m_buf; - SocketStream(int sock, size_t bufSize); + SocketStream(int sock, size_t bufSize); }; #endif /* __SOCKET_STREAM_H */ diff --git a/src/anbox/graphics/emugl/TcpStream.cpp b/src/anbox/graphics/emugl/TcpStream.cpp index de97c02..a5df199 100644 --- a/src/anbox/graphics/emugl/TcpStream.cpp +++ b/src/anbox/graphics/emugl/TcpStream.cpp @@ -19,8 +19,8 @@ #include #include #include -#include #include +#include #include #include @@ -29,46 +29,42 @@ TcpStream::TcpStream(size_t bufSize) : SocketStream(bufSize) {} -TcpStream::TcpStream(int sock, size_t bufSize) : - SocketStream(sock, bufSize) { - // disable Nagle algorithm to improve bandwidth of small - // packets which are quite common in our implementation. - emugl::socketTcpDisableNagle(sock); +TcpStream::TcpStream(int sock, size_t bufSize) : SocketStream(sock, bufSize) { + // disable Nagle algorithm to improve bandwidth of small + // packets which are quite common in our implementation. + emugl::socketTcpDisableNagle(sock); } int TcpStream::listen(char addrstr[MAX_ADDRSTR_LEN]) { - m_sock = emugl::socketTcpLoopbackServer(0, SOCK_STREAM); - if (!valid()) - return int(ERR_INVALID_SOCKET); + m_sock = emugl::socketTcpLoopbackServer(0, SOCK_STREAM); + if (!valid()) return int(ERR_INVALID_SOCKET); - int port = emugl::socketGetPort(m_sock); - if (port < 0) { - ::close(m_sock); - return int(ERR_INVALID_SOCKET); - } + int port = emugl::socketGetPort(m_sock); + if (port < 0) { + ::close(m_sock); + return int(ERR_INVALID_SOCKET); + } - snprintf(addrstr, MAX_ADDRSTR_LEN - 1, "%hu", port); - addrstr[MAX_ADDRSTR_LEN-1] = '\0'; + snprintf(addrstr, MAX_ADDRSTR_LEN - 1, "%hu", port); + addrstr[MAX_ADDRSTR_LEN - 1] = '\0'; - return 0; + return 0; } -SocketStream * TcpStream::accept() { - int clientSock = emugl::socketAccept(m_sock); - if (clientSock < 0) - return NULL; +SocketStream* TcpStream::accept() { + int clientSock = emugl::socketAccept(m_sock); + if (clientSock < 0) return NULL; - return new TcpStream(clientSock, m_bufsize); + return new TcpStream(clientSock, m_bufsize); } int TcpStream::connect(const char* addr) { - int port = atoi(addr); - m_sock = emugl::socketTcpLoopbackClient(port, SOCK_STREAM); - return valid() ? 0 : -1; + int port = atoi(addr); + m_sock = emugl::socketTcpLoopbackClient(port, SOCK_STREAM); + return valid() ? 0 : -1; } -int TcpStream::connect(const char* hostname, unsigned short port) -{ - m_sock = emugl::socketTcpClient(hostname, port, SOCK_STREAM); - return valid() ? 0 : -1; +int TcpStream::connect(const char* hostname, unsigned short port) { + m_sock = emugl::socketTcpClient(hostname, port, SOCK_STREAM); + return valid() ? 0 : -1; } diff --git a/src/anbox/graphics/emugl/TcpStream.h b/src/anbox/graphics/emugl/TcpStream.h index f5b462b..40c42d2 100644 --- a/src/anbox/graphics/emugl/TcpStream.h +++ b/src/anbox/graphics/emugl/TcpStream.h @@ -19,14 +19,15 @@ #include "SocketStream.h" class TcpStream : public SocketStream { -public: - explicit TcpStream(size_t bufsize = 10000); - virtual int listen(char addrstr[MAX_ADDRSTR_LEN]); - virtual SocketStream *accept(); - virtual int connect(const char* addr); - int connect(const char* hostname, unsigned short port); -private: - TcpStream(int sock, size_t bufSize); + public: + explicit TcpStream(size_t bufsize = 10000); + virtual int listen(char addrstr[MAX_ADDRSTR_LEN]); + virtual SocketStream* accept(); + virtual int connect(const char* addr); + int connect(const char* hostname, unsigned short port); + + private: + TcpStream(int sock, size_t bufSize); }; #endif diff --git a/src/anbox/graphics/emugl/TextureDraw.cpp b/src/anbox/graphics/emugl/TextureDraw.cpp index d0f8dd7..2befd71 100644 --- a/src/anbox/graphics/emugl/TextureDraw.cpp +++ b/src/anbox/graphics/emugl/TextureDraw.cpp @@ -21,7 +21,7 @@ #include #include -#define ERR(...) fprintf(stderr, __VA_ARGS__) +#define ERR(...) fprintf(stderr, __VA_ARGS__) // M_PI isn't defined in C++ (when strict ISO compliance is enabled) #ifndef M_PI @@ -35,25 +35,25 @@ namespace { // |shaderText| is a 0-terminated C string for the shader source to use. // On success, return the handle of the new compiled shader, or 0 on failure. GLuint createShader(GLint shaderType, const char* shaderText) { - // Create new shader handle and attach source. - GLuint shader = s_gles2.glCreateShader(shaderType); - if (!shader) { - return 0; - } - const GLchar* text = static_cast(shaderText); - const GLint textLen = ::strlen(shaderText); - s_gles2.glShaderSource(shader, 1, &text, &textLen); + // Create new shader handle and attach source. + GLuint shader = s_gles2.glCreateShader(shaderType); + if (!shader) { + return 0; + } + const GLchar* text = static_cast(shaderText); + const GLint textLen = ::strlen(shaderText); + s_gles2.glShaderSource(shader, 1, &text, &textLen); - // Compiler the shader. - GLint success; - s_gles2.glCompileShader(shader); - s_gles2.glGetShaderiv(shader, GL_COMPILE_STATUS, &success); - if (success == GL_FALSE) { - s_gles2.glDeleteShader(shader); - return 0; - } + // Compiler the shader. + GLint success; + s_gles2.glCompileShader(shader); + s_gles2.glGetShaderiv(shader, GL_COMPILE_STATUS, &success); + if (success == GL_FALSE) { + s_gles2.glDeleteShader(shader); + return 0; + } - return shader; + return shader; } // No scaling / projection since we want to fill the whole viewport with @@ -80,173 +80,156 @@ const char kFragmentShaderSource[] = // Hard-coded arrays of vertex information. struct Vertex { - float pos[3]; - float coord[2]; + float pos[3]; + float coord[2]; }; const Vertex kVertices[] = { - {{ +1, -1, +0 }, { +1, +1 }}, - {{ +1, +1, +0 }, { +1, +0 }}, - {{ -1, +1, +0 }, { +0, +0 }}, - {{ -1, -1, +0 }, { +0, +1 }}, + {{+1, -1, +0}, {+1, +1}}, + {{+1, +1, +0}, {+1, +0}}, + {{-1, +1, +0}, {+0, +0}}, + {{-1, -1, +0}, {+0, +1}}, }; -const GLubyte kIndices[] = { 0, 1, 2, 2, 3, 0 }; +const GLubyte kIndices[] = {0, 1, 2, 2, 3, 0}; const GLint kIndicesLen = sizeof(kIndices) / sizeof(kIndices[0]); } // namespace -TextureDraw::TextureDraw(EGLDisplay display) : - mDisplay(display), - mVertexShader(0), - mFragmentShader(0), - mProgram(0), - mPositionSlot(-1), - mInCoordSlot(-1), - mTextureSlot(-1), - mRotationSlot(-1), - mTranslationSlot(-1) { - // Create shaders and program. - mVertexShader = createShader(GL_VERTEX_SHADER, kVertexShaderSource); - mFragmentShader = createShader(GL_FRAGMENT_SHADER, kFragmentShaderSource); +TextureDraw::TextureDraw(EGLDisplay display) + : mDisplay(display), + mVertexShader(0), + mFragmentShader(0), + mProgram(0), + mPositionSlot(-1), + mInCoordSlot(-1), + mTextureSlot(-1), + mRotationSlot(-1), + mTranslationSlot(-1) { + // Create shaders and program. + mVertexShader = createShader(GL_VERTEX_SHADER, kVertexShaderSource); + mFragmentShader = createShader(GL_FRAGMENT_SHADER, kFragmentShaderSource); - mProgram = s_gles2.glCreateProgram(); - s_gles2.glAttachShader(mProgram, mVertexShader); - s_gles2.glAttachShader(mProgram, mFragmentShader); + mProgram = s_gles2.glCreateProgram(); + s_gles2.glAttachShader(mProgram, mVertexShader); + s_gles2.glAttachShader(mProgram, mFragmentShader); - GLint success; - s_gles2.glLinkProgram(mProgram); - s_gles2.glGetProgramiv(mProgram, GL_LINK_STATUS, &success); - if (success == GL_FALSE) { - GLchar messages[256]; - s_gles2.glGetProgramInfoLog( - mProgram, sizeof(messages), 0, &messages[0]); - ERR("%s: Could not create/link program: %s\n", __FUNCTION__, messages); - s_gles2.glDeleteProgram(mProgram); - mProgram = 0; - return; - } + GLint success; + s_gles2.glLinkProgram(mProgram); + s_gles2.glGetProgramiv(mProgram, GL_LINK_STATUS, &success); + if (success == GL_FALSE) { + GLchar messages[256]; + s_gles2.glGetProgramInfoLog(mProgram, sizeof(messages), 0, &messages[0]); + ERR("%s: Could not create/link program: %s\n", __FUNCTION__, messages); + s_gles2.glDeleteProgram(mProgram); + mProgram = 0; + return; + } - s_gles2.glUseProgram(mProgram); + s_gles2.glUseProgram(mProgram); - // Retrieve attribute/uniform locations. - mPositionSlot = s_gles2.glGetAttribLocation(mProgram, "position"); - s_gles2.glEnableVertexAttribArray(mPositionSlot); + // Retrieve attribute/uniform locations. + mPositionSlot = s_gles2.glGetAttribLocation(mProgram, "position"); + s_gles2.glEnableVertexAttribArray(mPositionSlot); - mInCoordSlot = s_gles2.glGetAttribLocation(mProgram, "inCoord"); - s_gles2.glEnableVertexAttribArray(mInCoordSlot); + mInCoordSlot = s_gles2.glGetAttribLocation(mProgram, "inCoord"); + s_gles2.glEnableVertexAttribArray(mInCoordSlot); - mTextureSlot = s_gles2.glGetUniformLocation(mProgram, "texture"); + mTextureSlot = s_gles2.glGetUniformLocation(mProgram, "texture"); - // Create vertex and index buffers. - s_gles2.glGenBuffers(1, &mVertexBuffer); - s_gles2.glBindBuffer(GL_ARRAY_BUFFER, mVertexBuffer); - s_gles2.glBufferData( - GL_ARRAY_BUFFER, sizeof(kVertices), kVertices, GL_STATIC_DRAW); + // Create vertex and index buffers. + s_gles2.glGenBuffers(1, &mVertexBuffer); + s_gles2.glBindBuffer(GL_ARRAY_BUFFER, mVertexBuffer); + s_gles2.glBufferData(GL_ARRAY_BUFFER, sizeof(kVertices), kVertices, + GL_STATIC_DRAW); - s_gles2.glGenBuffers(1, &mIndexBuffer); - s_gles2.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffer); - s_gles2.glBufferData(GL_ELEMENT_ARRAY_BUFFER, - sizeof(kIndices), - kIndices, - GL_STATIC_DRAW); + s_gles2.glGenBuffers(1, &mIndexBuffer); + s_gles2.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffer); + s_gles2.glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(kIndices), kIndices, + GL_STATIC_DRAW); } bool TextureDraw::draw(GLuint texture) { - if (!mProgram) { - ERR("%s: no program\n", __FUNCTION__); - return false; - } + if (!mProgram) { + ERR("%s: no program\n", __FUNCTION__); + return false; + } - // TODO(digit): Save previous program state. + // TODO(digit): Save previous program state. - GLenum err; + GLenum err; - s_gles2.glUseProgram(mProgram); - err = s_gles2.glGetError(); - if (err != GL_NO_ERROR) { - ERR("%s: Could not use program error=0x%x\n", - __FUNCTION__, err); - } + s_gles2.glUseProgram(mProgram); + err = s_gles2.glGetError(); + if (err != GL_NO_ERROR) { + ERR("%s: Could not use program error=0x%x\n", __FUNCTION__, err); + } + // Setup the |position| attribute values. + s_gles2.glBindBuffer(GL_ARRAY_BUFFER, mVertexBuffer); + err = s_gles2.glGetError(); + if (err != GL_NO_ERROR) { + ERR("%s: Could not bind GL_ARRAY_BUFFER error=0x%x\n", __FUNCTION__, err); + } - // Setup the |position| attribute values. - s_gles2.glBindBuffer(GL_ARRAY_BUFFER, mVertexBuffer); - err = s_gles2.glGetError(); - if (err != GL_NO_ERROR) { - ERR("%s: Could not bind GL_ARRAY_BUFFER error=0x%x\n", - __FUNCTION__, err); - } + s_gles2.glEnableVertexAttribArray(mPositionSlot); + s_gles2.glVertexAttribPointer(mPositionSlot, 3, GL_FLOAT, GL_FALSE, + sizeof(Vertex), 0); + err = s_gles2.glGetError(); + if (err != GL_NO_ERROR) { + ERR("%s: Could glVertexAttribPointer with mPositionSlot error=0x%x\n", + __FUNCTION__, err); + } - s_gles2.glEnableVertexAttribArray(mPositionSlot); - s_gles2.glVertexAttribPointer(mPositionSlot, - 3, - GL_FLOAT, - GL_FALSE, - sizeof(Vertex), - 0); - err = s_gles2.glGetError(); - if (err != GL_NO_ERROR) { - ERR("%s: Could glVertexAttribPointer with mPositionSlot error=0x%x\n", - __FUNCTION__, err); - } + // Setup the |inCoord| attribute values. + s_gles2.glEnableVertexAttribArray(mInCoordSlot); + s_gles2.glVertexAttribPointer( + mInCoordSlot, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), + reinterpret_cast(static_cast(sizeof(float) * 3))); - // Setup the |inCoord| attribute values. - s_gles2.glEnableVertexAttribArray(mInCoordSlot); - s_gles2.glVertexAttribPointer(mInCoordSlot, - 2, - GL_FLOAT, - GL_FALSE, - sizeof(Vertex), - reinterpret_cast( - static_cast( - sizeof(float) * 3))); + // setup the |texture| uniform value. + s_gles2.glActiveTexture(GL_TEXTURE0); + s_gles2.glBindTexture(GL_TEXTURE_2D, texture); + s_gles2.glUniform1i(mTextureSlot, 0); - // setup the |texture| uniform value. - s_gles2.glActiveTexture(GL_TEXTURE0); - s_gles2.glBindTexture(GL_TEXTURE_2D, texture); - s_gles2.glUniform1i(mTextureSlot, 0); + // Validate program, just to be sure. + s_gles2.glValidateProgram(mProgram); + GLint validState = 0; + s_gles2.glGetProgramiv(mProgram, GL_VALIDATE_STATUS, &validState); + if (validState == GL_FALSE) { + GLchar messages[256]; + s_gles2.glGetProgramInfoLog(mProgram, sizeof(messages), 0, &messages[0]); + ERR("%s: Could not run program: %s\n", __FUNCTION__, messages); + return false; + } - // Validate program, just to be sure. - s_gles2.glValidateProgram(mProgram); - GLint validState = 0; - s_gles2.glGetProgramiv(mProgram, GL_VALIDATE_STATUS, &validState); - if (validState == GL_FALSE) { - GLchar messages[256]; - s_gles2.glGetProgramInfoLog( - mProgram, sizeof(messages), 0, &messages[0]); - ERR("%s: Could not run program: %s\n", __FUNCTION__, messages); - return false; - } + // Do the rendering. + s_gles2.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffer); + err = s_gles2.glGetError(); + if (err != GL_NO_ERROR) { + ERR("%s: Could not glBindBuffer(GL_ELEMENT_ARRAY_BUFFER) error=0x%x\n", + __FUNCTION__, err); + } - // Do the rendering. - s_gles2.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffer); - err = s_gles2.glGetError(); - if (err != GL_NO_ERROR) { - ERR("%s: Could not glBindBuffer(GL_ELEMENT_ARRAY_BUFFER) error=0x%x\n", - __FUNCTION__, err); - } + s_gles2.glDrawElements(GL_TRIANGLES, kIndicesLen, GL_UNSIGNED_BYTE, 0); + err = s_gles2.glGetError(); + if (err != GL_NO_ERROR) { + ERR("%s: Could not glDrawElements() error=0x%x\n", __FUNCTION__, err); + } - s_gles2.glDrawElements(GL_TRIANGLES, kIndicesLen, GL_UNSIGNED_BYTE, 0); - err = s_gles2.glGetError(); - if (err != GL_NO_ERROR) { - ERR("%s: Could not glDrawElements() error=0x%x\n", - __FUNCTION__, err); - } + // TODO(digit): Restore previous program state. - // TODO(digit): Restore previous program state. - - return true; + return true; } TextureDraw::~TextureDraw() { - s_gles2.glDeleteBuffers(1, &mIndexBuffer); - s_gles2.glDeleteBuffers(1, &mVertexBuffer); + s_gles2.glDeleteBuffers(1, &mIndexBuffer); + s_gles2.glDeleteBuffers(1, &mVertexBuffer); - if (mFragmentShader) { - s_gles2.glDeleteShader(mFragmentShader); - } - if (mVertexShader) { - s_gles2.glDeleteShader(mVertexShader); - } + if (mFragmentShader) { + s_gles2.glDeleteShader(mFragmentShader); + } + if (mVertexShader) { + s_gles2.glDeleteShader(mVertexShader); + } } diff --git a/src/anbox/graphics/emugl/TextureDraw.h b/src/anbox/graphics/emugl/TextureDraw.h index b8cc7c3..5f6ef96 100644 --- a/src/anbox/graphics/emugl/TextureDraw.h +++ b/src/anbox/graphics/emugl/TextureDraw.h @@ -30,29 +30,29 @@ // framebuffer with texture content. // class TextureDraw { -public: - // Create a new instance. - TextureDraw(EGLDisplay display); + public: + // Create a new instance. + TextureDraw(EGLDisplay display); - // Destructor - ~TextureDraw(); + // Destructor + ~TextureDraw(); - // Fill the current framebuffer with the content of |texture|, which must - // be the name of a GLES 2.x texture object. - bool draw(GLuint texture); + // Fill the current framebuffer with the content of |texture|, which must + // be the name of a GLES 2.x texture object. + bool draw(GLuint texture); -private: - EGLDisplay mDisplay; - GLuint mVertexShader; - GLuint mFragmentShader; - GLuint mProgram; - GLint mPositionSlot; - GLint mInCoordSlot; - GLint mTextureSlot; - GLint mRotationSlot; - GLint mTranslationSlot; - GLuint mVertexBuffer; - GLuint mIndexBuffer; + private: + EGLDisplay mDisplay; + GLuint mVertexShader; + GLuint mFragmentShader; + GLuint mProgram; + GLint mPositionSlot; + GLint mInCoordSlot; + GLint mTextureSlot; + GLint mRotationSlot; + GLint mTranslationSlot; + GLuint mVertexBuffer; + GLuint mIndexBuffer; }; #endif // TEXTURE_DRAW_H diff --git a/src/anbox/graphics/emugl/TextureResize.cpp b/src/anbox/graphics/emugl/TextureResize.cpp index e09b939..5aeab99 100644 --- a/src/anbox/graphics/emugl/TextureResize.cpp +++ b/src/anbox/graphics/emugl/TextureResize.cpp @@ -22,7 +22,7 @@ #include #include -#define ERR(...) fprintf(stderr, __VA_ARGS__) +#define ERR(...) fprintf(stderr, __VA_ARGS__) #define MAX_FACTOR_POWER 4 static const char kCommonShaderSource[] = @@ -126,219 +126,237 @@ const char kFragmentShaderSource[] = static const float kVertexData[] = {-1, -1, 3, -1, -1, 3}; static void detachShaders(GLuint program) { - GLuint shaders[2] = {}; - GLsizei count = 0; - s_gles2.glGetAttachedShaders(program, 2, &count, shaders); - if (s_gles2.glGetError() == GL_NO_ERROR) { - for (GLsizei i = 0; i < count; i++) { - s_gles2.glDetachShader(program, shaders[i]); - s_gles2.glDeleteShader(shaders[i]); - } + GLuint shaders[2] = {}; + GLsizei count = 0; + s_gles2.glGetAttachedShaders(program, 2, &count, shaders); + if (s_gles2.glGetError() == GL_NO_ERROR) { + for (GLsizei i = 0; i < count; i++) { + s_gles2.glDetachShader(program, shaders[i]); + s_gles2.glDeleteShader(shaders[i]); } + } } -static GLuint createShader(GLenum type, const std::initializer_list& source) { - GLint success, infoLength; +static GLuint createShader(GLenum type, + const std::initializer_list& source) { + GLint success, infoLength; - GLuint shader = s_gles2.glCreateShader(type); - if (shader) { - s_gles2.glShaderSource(shader, source.size(), source.begin(), nullptr); - s_gles2.glCompileShader(shader); - s_gles2.glGetShaderiv(shader, GL_COMPILE_STATUS, &success); - if (success == GL_FALSE) { - s_gles2.glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLength); - std::string infoLog(infoLength + 1, '\0'); - s_gles2.glGetShaderInfoLog(shader, infoLength, nullptr, &infoLog[0]); - ERR("%s shader compile failed:\n%s\n", - (type == GL_VERTEX_SHADER) ? "Vertex" : "Fragment", - infoLog.c_str()); - s_gles2.glDeleteShader(shader); - shader = 0; - } + GLuint shader = s_gles2.glCreateShader(type); + if (shader) { + s_gles2.glShaderSource(shader, source.size(), source.begin(), nullptr); + s_gles2.glCompileShader(shader); + s_gles2.glGetShaderiv(shader, GL_COMPILE_STATUS, &success); + if (success == GL_FALSE) { + s_gles2.glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLength); + std::string infoLog(infoLength + 1, '\0'); + s_gles2.glGetShaderInfoLog(shader, infoLength, nullptr, &infoLog[0]); + ERR("%s shader compile failed:\n%s\n", + (type == GL_VERTEX_SHADER) ? "Vertex" : "Fragment", infoLog.c_str()); + s_gles2.glDeleteShader(shader); + shader = 0; } - return shader; + } + return shader; } -static void attachShaders(TextureResize::Framebuffer* fb, const char* factorDefine, - const char* dimensionDefine, GLuint width, GLuint height) { +static void attachShaders(TextureResize::Framebuffer* fb, + const char* factorDefine, const char* dimensionDefine, + GLuint width, GLuint height) { + std::ostringstream dimensionConst; + dimensionConst << "const vec2 kDimension = vec2(" << width << ", " << height + << ");\n"; - std::ostringstream dimensionConst; - dimensionConst << "const vec2 kDimension = vec2(" << width << ", " << height << ");\n"; + GLuint vShader = createShader( + GL_VERTEX_SHADER, {factorDefine, dimensionDefine, kCommonShaderSource, + dimensionConst.str().c_str(), kVertexShaderSource}); + GLuint fShader = createShader( + GL_FRAGMENT_SHADER, {factorDefine, dimensionDefine, kCommonShaderSource, + kFragmentShaderSource}); - GLuint vShader = createShader(GL_VERTEX_SHADER, { - factorDefine, dimensionDefine, - kCommonShaderSource, dimensionConst.str().c_str(), kVertexShaderSource - }); - GLuint fShader = createShader(GL_FRAGMENT_SHADER, { - factorDefine, dimensionDefine, kCommonShaderSource, kFragmentShaderSource - }); + if (!vShader || !fShader) { + return; + } - if (!vShader || !fShader) { - return; - } + s_gles2.glAttachShader(fb->program, vShader); + s_gles2.glAttachShader(fb->program, fShader); + s_gles2.glLinkProgram(fb->program); - s_gles2.glAttachShader(fb->program, vShader); - s_gles2.glAttachShader(fb->program, fShader); - s_gles2.glLinkProgram(fb->program); - - s_gles2.glUseProgram(fb->program); - fb->aPosition = s_gles2.glGetAttribLocation(fb->program, "aPosition"); - fb->uTexture = s_gles2.glGetUniformLocation(fb->program, "uTexture"); + s_gles2.glUseProgram(fb->program); + fb->aPosition = s_gles2.glGetAttribLocation(fb->program, "aPosition"); + fb->uTexture = s_gles2.glGetUniformLocation(fb->program, "uTexture"); } -TextureResize::TextureResize(GLuint width, GLuint height) : - mWidth(width), - mHeight(height), - mFactor(1), - mFBWidth({0,}), - mFBHeight({0,}) { - s_gles2.glGenTextures(1, &mFBWidth.texture); - s_gles2.glBindTexture(GL_TEXTURE_2D, mFBWidth.texture); - s_gles2.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - s_gles2.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - s_gles2.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - s_gles2.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); +TextureResize::TextureResize(GLuint width, GLuint height) + : mWidth(width), + mHeight(height), + mFactor(1), + mFBWidth({ + 0, + }), + mFBHeight({ + 0, + }) { + s_gles2.glGenTextures(1, &mFBWidth.texture); + s_gles2.glBindTexture(GL_TEXTURE_2D, mFBWidth.texture); + s_gles2.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + s_gles2.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + s_gles2.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + s_gles2.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - s_gles2.glGenTextures(1, &mFBHeight.texture); - s_gles2.glBindTexture(GL_TEXTURE_2D, mFBHeight.texture); - s_gles2.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - s_gles2.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - s_gles2.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - s_gles2.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + s_gles2.glGenTextures(1, &mFBHeight.texture); + s_gles2.glBindTexture(GL_TEXTURE_2D, mFBHeight.texture); + s_gles2.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + s_gles2.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + s_gles2.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + s_gles2.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - s_gles2.glGenFramebuffers(1, &mFBWidth.framebuffer); - s_gles2.glGenFramebuffers(1, &mFBHeight.framebuffer); + s_gles2.glGenFramebuffers(1, &mFBWidth.framebuffer); + s_gles2.glGenFramebuffers(1, &mFBHeight.framebuffer); - mFBWidth.program = s_gles2.glCreateProgram(); - mFBHeight.program = s_gles2.glCreateProgram(); + mFBWidth.program = s_gles2.glCreateProgram(); + mFBHeight.program = s_gles2.glCreateProgram(); - s_gles2.glGenBuffers(1, &mVertexBuffer); - s_gles2.glBindBuffer(GL_ARRAY_BUFFER, mVertexBuffer); - s_gles2.glBufferData(GL_ARRAY_BUFFER, sizeof(kVertexData), kVertexData, GL_STATIC_DRAW); + s_gles2.glGenBuffers(1, &mVertexBuffer); + s_gles2.glBindBuffer(GL_ARRAY_BUFFER, mVertexBuffer); + s_gles2.glBufferData(GL_ARRAY_BUFFER, sizeof(kVertexData), kVertexData, + GL_STATIC_DRAW); } TextureResize::~TextureResize() { - GLuint fb[2] = {mFBWidth.framebuffer, mFBHeight.framebuffer}; - s_gles2.glDeleteFramebuffers(2, fb); + GLuint fb[2] = {mFBWidth.framebuffer, mFBHeight.framebuffer}; + s_gles2.glDeleteFramebuffers(2, fb); - GLuint tex[2] = {mFBWidth.texture, mFBHeight.texture}; - s_gles2.glDeleteTextures(2, tex); + GLuint tex[2] = {mFBWidth.texture, mFBHeight.texture}; + s_gles2.glDeleteTextures(2, tex); - s_gles2.glDeleteProgram(mFBWidth.program); - s_gles2.glDeleteProgram(mFBHeight.program); + s_gles2.glDeleteProgram(mFBWidth.program); + s_gles2.glDeleteProgram(mFBHeight.program); - s_gles2.glDeleteBuffers(1, &mVertexBuffer); + s_gles2.glDeleteBuffers(1, &mVertexBuffer); } GLuint TextureResize::update(GLuint texture) { - // Store the viewport. The viewport is clobbered due to the framebuffers. - GLint vport[4] = { 0, }; - s_gles2.glGetIntegerv(GL_VIEWPORT, vport); + // Store the viewport. The viewport is clobbered due to the framebuffers. + GLint vport[4] = { + 0, + }; + s_gles2.glGetIntegerv(GL_VIEWPORT, vport); - // Correctly deal with rotated screens. - GLint tWidth = vport[2], tHeight = vport[3]; - if ((mWidth < mHeight) != (tWidth < tHeight)) { - std::swap(tWidth, tHeight); - } + // Correctly deal with rotated screens. + GLint tWidth = vport[2], tHeight = vport[3]; + if ((mWidth < mHeight) != (tWidth < tHeight)) { + std::swap(tWidth, tHeight); + } - // Compute the scaling factor needed to get an image just larger than the target viewport. - unsigned int factor = 1; - for (int i = 0, w = mWidth / 2, h = mHeight / 2; - i < MAX_FACTOR_POWER && w >= tWidth && h >= tHeight; - i++, w /= 2, h /= 2, factor *= 2) { - } + // Compute the scaling factor needed to get an image just larger than the + // target viewport. + unsigned int factor = 1; + for (int i = 0, w = mWidth / 2, h = mHeight / 2; + i < MAX_FACTOR_POWER && w >= tWidth && h >= tHeight; + i++, w /= 2, h /= 2, factor *= 2) { + } - // No resizing needed. - if (factor == 1) { - return texture; - } + // No resizing needed. + if (factor == 1) { + return texture; + } - s_gles2.glGetError(); // Clear any GL errors. - setupFramebuffers(factor); - resize(texture); - s_gles2.glViewport(vport[0], vport[1], vport[2], vport[3]); // Restore the viewport. + s_gles2.glGetError(); // Clear any GL errors. + setupFramebuffers(factor); + resize(texture); + s_gles2.glViewport(vport[0], vport[1], vport[2], + vport[3]); // Restore the viewport. - // If there was an error while resizing, just use the unscaled texture. - GLenum error = s_gles2.glGetError(); - if (error != GL_NO_ERROR) { - ERR("GL error while resizing: 0x%x (ignored)\n", error); - return texture; - } + // If there was an error while resizing, just use the unscaled texture. + GLenum error = s_gles2.glGetError(); + if (error != GL_NO_ERROR) { + ERR("GL error while resizing: 0x%x (ignored)\n", error); + return texture; + } - return mFBHeight.texture; + return mFBHeight.texture; } void TextureResize::setupFramebuffers(unsigned int factor) { - if (factor == mFactor) { - // The factor hasn't changed, no need to update the framebuffers. - return; - } + if (factor == mFactor) { + // The factor hasn't changed, no need to update the framebuffers. + return; + } - // Update the framebuffer sizes to match the new factor. - s_gles2.glBindTexture(GL_TEXTURE_2D, mFBWidth.texture); - s_gles2.glTexImage2D( - GL_TEXTURE_2D, 0, GL_RGBA, mWidth / factor, mHeight, 0, GL_RGBA, GL_FLOAT, nullptr); - s_gles2.glBindFramebuffer(GL_FRAMEBUFFER, mFBWidth.framebuffer); - s_gles2.glFramebufferTexture2D( - GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mFBWidth.texture, 0); + // Update the framebuffer sizes to match the new factor. + s_gles2.glBindTexture(GL_TEXTURE_2D, mFBWidth.texture); + s_gles2.glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, mWidth / factor, mHeight, 0, + GL_RGBA, GL_FLOAT, nullptr); + s_gles2.glBindFramebuffer(GL_FRAMEBUFFER, mFBWidth.framebuffer); + s_gles2.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, + GL_TEXTURE_2D, mFBWidth.texture, 0); - s_gles2.glBindTexture(GL_TEXTURE_2D, mFBHeight.texture); - s_gles2.glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, mWidth / factor, mHeight / factor, 0, GL_RGBA, - GL_UNSIGNED_BYTE, nullptr); - s_gles2.glBindFramebuffer(GL_FRAMEBUFFER, mFBHeight.framebuffer); - s_gles2.glFramebufferTexture2D( - GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mFBHeight.texture, 0); + s_gles2.glBindTexture(GL_TEXTURE_2D, mFBHeight.texture); + s_gles2.glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, mWidth / factor, + mHeight / factor, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); + s_gles2.glBindFramebuffer(GL_FRAMEBUFFER, mFBHeight.framebuffer); + s_gles2.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, + GL_TEXTURE_2D, mFBHeight.texture, 0); - // Update the shaders to the new factor. First detach the old shaders... - detachShaders(mFBWidth.program); - detachShaders(mFBHeight.program); + // Update the shaders to the new factor. First detach the old shaders... + detachShaders(mFBWidth.program); + detachShaders(mFBHeight.program); - // ... then attach the new ones. - std::ostringstream factorDefine; - factorDefine << "#define FACTOR " << factor << "\n"; - attachShaders(&mFBWidth, factorDefine.str().c_str(), "#define HORIZONTAL\n", mWidth, mHeight); - attachShaders(&mFBHeight, factorDefine.str().c_str(), "#define VERTICAL\n", mWidth, mHeight); + // ... then attach the new ones. + std::ostringstream factorDefine; + factorDefine << "#define FACTOR " << factor << "\n"; + attachShaders(&mFBWidth, factorDefine.str().c_str(), "#define HORIZONTAL\n", + mWidth, mHeight); + attachShaders(&mFBHeight, factorDefine.str().c_str(), "#define VERTICAL\n", + mWidth, mHeight); - mFactor = factor; + mFactor = factor; } void TextureResize::resize(GLuint texture) { - s_gles2.glBindBuffer(GL_ARRAY_BUFFER, mVertexBuffer); - s_gles2.glActiveTexture(GL_TEXTURE0); + s_gles2.glBindBuffer(GL_ARRAY_BUFFER, mVertexBuffer); + s_gles2.glActiveTexture(GL_TEXTURE0); - // First scale the horizontal dimension by rendering the input texture to a scaled framebuffer. - s_gles2.glBindFramebuffer(GL_FRAMEBUFFER, mFBWidth.framebuffer); - s_gles2.glViewport(0, 0, mWidth / mFactor, mHeight); - s_gles2.glUseProgram(mFBWidth.program); - s_gles2.glEnableVertexAttribArray(mFBWidth.aPosition); - s_gles2.glVertexAttribPointer(mFBWidth.aPosition, 2, GL_FLOAT, GL_FALSE, 0, 0); - s_gles2.glBindTexture(GL_TEXTURE_2D, texture); + // First scale the horizontal dimension by rendering the input texture to a + // scaled framebuffer. + s_gles2.glBindFramebuffer(GL_FRAMEBUFFER, mFBWidth.framebuffer); + s_gles2.glViewport(0, 0, mWidth / mFactor, mHeight); + s_gles2.glUseProgram(mFBWidth.program); + s_gles2.glEnableVertexAttribArray(mFBWidth.aPosition); + s_gles2.glVertexAttribPointer(mFBWidth.aPosition, 2, GL_FLOAT, GL_FALSE, 0, + 0); + s_gles2.glBindTexture(GL_TEXTURE_2D, texture); - // Store the current texture filters and set to nearest for scaling. - GLint mag_filter, min_filter; - s_gles2.glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, &mag_filter); - s_gles2.glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, &min_filter); - s_gles2.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - s_gles2.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - s_gles2.glUniform1i(mFBWidth.uTexture, 0); - s_gles2.glDrawArrays(GL_TRIANGLES, 0, sizeof(kVertexData) / (2 * sizeof(float))); + // Store the current texture filters and set to nearest for scaling. + GLint mag_filter, min_filter; + s_gles2.glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, + &mag_filter); + s_gles2.glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, + &min_filter); + s_gles2.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + s_gles2.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + s_gles2.glUniform1i(mFBWidth.uTexture, 0); + s_gles2.glDrawArrays(GL_TRIANGLES, 0, + sizeof(kVertexData) / (2 * sizeof(float))); - // Restore the previous texture filters. - s_gles2.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter); - s_gles2.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter); + // Restore the previous texture filters. + s_gles2.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter); + s_gles2.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter); - // Secondly, scale the vertical dimension using the second framebuffer. - s_gles2.glBindFramebuffer(GL_FRAMEBUFFER, mFBHeight.framebuffer); - s_gles2.glViewport(0, 0, mWidth / mFactor, mHeight / mFactor); - s_gles2.glUseProgram(mFBHeight.program); - s_gles2.glEnableVertexAttribArray(mFBHeight.aPosition); - s_gles2.glVertexAttribPointer(mFBHeight.aPosition, 2, GL_FLOAT, GL_FALSE, 0, 0); - s_gles2.glBindTexture(GL_TEXTURE_2D, mFBWidth.texture); - s_gles2.glUniform1i(mFBHeight.uTexture, 0); - s_gles2.glDrawArrays(GL_TRIANGLES, 0, sizeof(kVertexData) / (2 * sizeof(float))); + // Secondly, scale the vertical dimension using the second framebuffer. + s_gles2.glBindFramebuffer(GL_FRAMEBUFFER, mFBHeight.framebuffer); + s_gles2.glViewport(0, 0, mWidth / mFactor, mHeight / mFactor); + s_gles2.glUseProgram(mFBHeight.program); + s_gles2.glEnableVertexAttribArray(mFBHeight.aPosition); + s_gles2.glVertexAttribPointer(mFBHeight.aPosition, 2, GL_FLOAT, GL_FALSE, 0, + 0); + s_gles2.glBindTexture(GL_TEXTURE_2D, mFBWidth.texture); + s_gles2.glUniform1i(mFBHeight.uTexture, 0); + s_gles2.glDrawArrays(GL_TRIANGLES, 0, + sizeof(kVertexData) / (2 * sizeof(float))); - // Clear the bindings. - s_gles2.glBindBuffer(GL_ARRAY_BUFFER, 0); - s_gles2.glBindFramebuffer(GL_FRAMEBUFFER, 0); - s_gles2.glBindTexture(GL_TEXTURE_2D, 0); + // Clear the bindings. + s_gles2.glBindBuffer(GL_ARRAY_BUFFER, 0); + s_gles2.glBindFramebuffer(GL_FRAMEBUFFER, 0); + s_gles2.glBindTexture(GL_TEXTURE_2D, 0); } diff --git a/src/anbox/graphics/emugl/TextureResize.h b/src/anbox/graphics/emugl/TextureResize.h index 3dd9d31..1b81a63 100644 --- a/src/anbox/graphics/emugl/TextureResize.h +++ b/src/anbox/graphics/emugl/TextureResize.h @@ -19,33 +19,33 @@ #include class TextureResize { -public: - TextureResize(GLuint width, GLuint height); - ~TextureResize(); + public: + TextureResize(GLuint width, GLuint height); + ~TextureResize(); - // Scales the given texture for the current viewport and returns the scaled - // texture. May return the input if no scaling is required. - GLuint update(GLuint texture); + // Scales the given texture for the current viewport and returns the scaled + // texture. May return the input if no scaling is required. + GLuint update(GLuint texture); - struct Framebuffer { - GLuint texture; - GLuint framebuffer; - GLuint program; - GLuint aPosition; - GLuint uTexture; - }; + struct Framebuffer { + GLuint texture; + GLuint framebuffer; + GLuint program; + GLuint aPosition; + GLuint uTexture; + }; -private: - void setupFramebuffers(unsigned int factor); - void resize(GLuint texture); + private: + void setupFramebuffers(unsigned int factor); + void resize(GLuint texture); -private: - GLuint mWidth; - GLuint mHeight; - unsigned int mFactor; - Framebuffer mFBWidth; - Framebuffer mFBHeight; - GLuint mVertexBuffer; + private: + GLuint mWidth; + GLuint mHeight; + unsigned int mFactor; + Framebuffer mFBWidth; + Framebuffer mFBHeight; + GLuint mVertexBuffer; }; #endif diff --git a/src/anbox/graphics/emugl/TimeUtils.cpp b/src/anbox/graphics/emugl/TimeUtils.cpp index 1a7fbf9..854bb79 100644 --- a/src/anbox/graphics/emugl/TimeUtils.cpp +++ b/src/anbox/graphics/emugl/TimeUtils.cpp @@ -15,21 +15,16 @@ */ #include "TimeUtils.h" - #include #include #include #include -long long GetCurrentTimeMS() -{ - struct timespec now; - clock_gettime(CLOCK_MONOTONIC, &now); - long long iDiff = (now.tv_sec * 1000LL) + now.tv_nsec/1000000LL; - return iDiff; +long long GetCurrentTimeMS() { + struct timespec now; + clock_gettime(CLOCK_MONOTONIC, &now); + long long iDiff = (now.tv_sec * 1000LL) + now.tv_nsec / 1000000LL; + return iDiff; } -void TimeSleepMS(int p_mili) -{ - usleep(p_mili * 1000); -} +void TimeSleepMS(int p_mili) { usleep(p_mili * 1000); } diff --git a/src/anbox/graphics/emugl/UnixStream.cpp b/src/anbox/graphics/emugl/UnixStream.cpp index 49b02fe..f66bbf6 100644 --- a/src/anbox/graphics/emugl/UnixStream.cpp +++ b/src/anbox/graphics/emugl/UnixStream.cpp @@ -20,155 +20,141 @@ #include #include #include -#include #include +#include #include #include -#include #include +#include /* Not all systems define PATH_MAX, those who don't generally don't * have a limit on the maximum path size, so use a value that is * large enough for our very limited needs. */ #ifndef PATH_MAX -#define PATH_MAX 128 +#define PATH_MAX 128 #endif -UnixStream::UnixStream(size_t bufSize) : - SocketStream(bufSize), - bound_socket_path(NULL) -{ -} +UnixStream::UnixStream(size_t bufSize) + : SocketStream(bufSize), bound_socket_path(NULL) {} -UnixStream::UnixStream(int sock, size_t bufSize) : - SocketStream(sock, bufSize), - bound_socket_path(NULL) -{ -} +UnixStream::UnixStream(int sock, size_t bufSize) + : SocketStream(sock, bufSize), bound_socket_path(NULL) {} -UnixStream::~UnixStream() -{ - if (bound_socket_path != NULL) { - int ret = 0; - do { - ret = unlink(bound_socket_path); - } while (ret < 0 && errno == EINTR); - if(ret != 0) { - ERR("Failed to unlink UNIX socket at \"%s\"\n", bound_socket_path); - perror("UNIX socket could not be unlinked"); - } - free(bound_socket_path); +UnixStream::~UnixStream() { + if (bound_socket_path != NULL) { + int ret = 0; + do { + ret = unlink(bound_socket_path); + } while (ret < 0 && errno == EINTR); + if (ret != 0) { + ERR("Failed to unlink UNIX socket at \"%s\"\n", bound_socket_path); + perror("UNIX socket could not be unlinked"); } + free(bound_socket_path); + } } /* Initialize a sockaddr_un with the appropriate values corresponding * to a given 'virtual port'. Returns 0 on success, -1 on error. */ -static int -make_unix_path(char *path, size_t pathlen, int port_number) -{ - char tmp[PATH_MAX]; // temp directory - int ret = 0; +static int make_unix_path(char *path, size_t pathlen, int port_number) { + char tmp[PATH_MAX]; // temp directory + int ret = 0; - // First, create user-specific temp directory if needed - const char* user = getenv("XDG_RUNTIME_DIR"); - if (user != NULL) { - struct stat st; - snprintf(tmp, sizeof(tmp), "%s/anbox", user); - do { - ret = ::lstat(tmp, &st); - } while (ret < 0 && errno == EINTR); + // First, create user-specific temp directory if needed + const char *user = getenv("XDG_RUNTIME_DIR"); + if (user != NULL) { + struct stat st; + snprintf(tmp, sizeof(tmp), "%s/anbox", user); + do { + ret = ::lstat(tmp, &st); + } while (ret < 0 && errno == EINTR); - if (ret < 0 && errno == ENOENT) { - do { - ret = ::mkdir(tmp, 0766); - } while (ret < 0 && errno == EINTR); - if (ret < 0) { - ERR("Could not create temp directory: %s", tmp); - user = NULL; // will fall-back to /tmp - } - } - else if (ret < 0) { - user = NULL; // will fallback to /tmp - } + if (ret < 0 && errno == ENOENT) { + do { + ret = ::mkdir(tmp, 0766); + } while (ret < 0 && errno == EINTR); + if (ret < 0) { + ERR("Could not create temp directory: %s", tmp); + user = NULL; // will fall-back to /tmp + } + } else if (ret < 0) { + user = NULL; // will fallback to /tmp } + } - if (user == NULL) { // fallback to /tmp in case of error - snprintf(tmp, sizeof(tmp), "/tmp"); + if (user == NULL) { // fallback to /tmp in case of error + snprintf(tmp, sizeof(tmp), "/tmp"); + } + + // Now, initialize it properly + snprintf(path, pathlen, "%s/qemu-gles-%d", tmp, port_number); + + // If the emulator is killed, it can leave the socket file behind. + // Since the filename has PID in it, we can be sure that this socket + // is not supposed to be here and delete it, to prevent EADDRINUSE + // later in bind() + if (::access(path, F_OK) == 0) { + ret = ::remove(path); + if (ret < 0) { + ERR("Failed to remove stale socket file at %s: %s\n", path, + strerror(errno)); + } else { + DBG("Stale socket file at %s was removed.\n", path); } + } - // Now, initialize it properly - snprintf(path, pathlen, "%s/qemu-gles-%d", tmp, port_number); - - // If the emulator is killed, it can leave the socket file behind. - // Since the filename has PID in it, we can be sure that this socket - // is not supposed to be here and delete it, to prevent EADDRINUSE - // later in bind() - if (::access(path, F_OK) == 0) { - ret = ::remove(path); - if (ret < 0) { - ERR("Failed to remove stale socket file at %s: %s\n", path, strerror(errno)); - } else { - DBG("Stale socket file at %s was removed.\n", path); - } - } - - return 0; + return 0; } +int UnixStream::listen(char addrstr[MAX_ADDRSTR_LEN]) { + if (make_unix_path(addrstr, MAX_ADDRSTR_LEN, getpid()) < 0) { + return -1; + } -int UnixStream::listen(char addrstr[MAX_ADDRSTR_LEN]) -{ - if (make_unix_path(addrstr, MAX_ADDRSTR_LEN, getpid()) < 0) { - return -1; - } + m_sock = emugl::socketLocalServer(addrstr, SOCK_STREAM); - m_sock = emugl::socketLocalServer(addrstr, SOCK_STREAM); + if (!valid()) return int(ERR_INVALID_SOCKET); - if (!valid()) - return int(ERR_INVALID_SOCKET); + bound_socket_path = strdup(addrstr); + if (bound_socket_path == NULL) { + ERR("WARNING: UNIX socket at \"%s\" should be manually removed \n", + addrstr); + return -1; + } - bound_socket_path = strdup(addrstr); - if(bound_socket_path == NULL) { - ERR("WARNING: UNIX socket at \"%s\" should be manually removed \n", - addrstr); - return -1; - } - - return 0; + return 0; } -SocketStream * UnixStream::accept() -{ - int clientSock = -1; +SocketStream *UnixStream::accept() { + int clientSock = -1; - while (true) { - struct sockaddr_un addr; - socklen_t len = sizeof(addr); - clientSock = ::accept(m_sock, (sockaddr *)&addr, &len); - // DBG("UnixStream::accept @ %d \n", clientSock); + while (true) { + struct sockaddr_un addr; + socklen_t len = sizeof(addr); + clientSock = ::accept(m_sock, (sockaddr *)&addr, &len); + // DBG("UnixStream::accept @ %d \n", clientSock); - if (clientSock < 0 && errno == EINTR) { - continue; - } - break; + if (clientSock < 0 && errno == EINTR) { + continue; } + break; + } - UnixStream *clientStream = NULL; + UnixStream *clientStream = NULL; - if (clientSock >= 0) { - clientStream = new UnixStream(clientSock, m_bufsize); - } - return clientStream; + if (clientSock >= 0) { + clientStream = new UnixStream(clientSock, m_bufsize); + } + return clientStream; } -int UnixStream::connect(const char* addr) -{ - m_sock = emugl::socketLocalClient(addr, SOCK_STREAM); - // DBG("UnixStream::connect @ %d \n", m_sock); - if (!valid()) return -1; +int UnixStream::connect(const char *addr) { + m_sock = emugl::socketLocalClient(addr, SOCK_STREAM); + // DBG("UnixStream::connect @ %d \n", m_sock); + if (!valid()) return -1; - return 0; + return 0; } diff --git a/src/anbox/graphics/emugl/UnixStream.h b/src/anbox/graphics/emugl/UnixStream.h index 5e2025d..99e1162 100644 --- a/src/anbox/graphics/emugl/UnixStream.h +++ b/src/anbox/graphics/emugl/UnixStream.h @@ -19,15 +19,16 @@ #include "SocketStream.h" class UnixStream : public SocketStream { -public: - explicit UnixStream(size_t bufsize = 10000); - ~UnixStream(); - virtual int listen(char addrstr[MAX_ADDRSTR_LEN]); - virtual SocketStream *accept(); - virtual int connect(const char* addr); -private: - char *bound_socket_path; - UnixStream(int sock, size_t bufSize); + public: + explicit UnixStream(size_t bufsize = 10000); + ~UnixStream(); + virtual int listen(char addrstr[MAX_ADDRSTR_LEN]); + virtual SocketStream *accept(); + virtual int connect(const char *addr); + + private: + char *bound_socket_path; + UnixStream(int sock, size_t bufSize); }; #endif diff --git a/src/anbox/graphics/emugl/WindowSurface.cpp b/src/anbox/graphics/emugl/WindowSurface.cpp index caf7609..583d3e3 100644 --- a/src/anbox/graphics/emugl/WindowSurface.cpp +++ b/src/anbox/graphics/emugl/WindowSurface.cpp @@ -25,163 +25,150 @@ #include #include - -WindowSurface::WindowSurface(EGLDisplay display, - EGLConfig config) : - mSurface(NULL), - mAttachedColorBuffer(NULL), - mReadContext(NULL), - mDrawContext(NULL), - mWidth(0), - mHeight(0), - mConfig(config), - mDisplay(display) {} +WindowSurface::WindowSurface(EGLDisplay display, EGLConfig config) + : mSurface(NULL), + mAttachedColorBuffer(NULL), + mReadContext(NULL), + mDrawContext(NULL), + mWidth(0), + mHeight(0), + mConfig(config), + mDisplay(display) {} WindowSurface::~WindowSurface() { - if (mSurface) { - s_egl.eglDestroySurface(mDisplay, mSurface); - } + if (mSurface) { + s_egl.eglDestroySurface(mDisplay, mSurface); + } } -WindowSurface *WindowSurface::create(EGLDisplay display, - EGLConfig config, - int p_width, - int p_height) { - // allocate space for the WindowSurface object - WindowSurface *win = new WindowSurface(display, config); - if (!win) { - return NULL; - } +WindowSurface *WindowSurface::create(EGLDisplay display, EGLConfig config, + int p_width, int p_height) { + // allocate space for the WindowSurface object + WindowSurface *win = new WindowSurface(display, config); + if (!win) { + return NULL; + } - // Create a pbuffer to be used as the egl surface - // for that window. - if (!win->resize(p_width, p_height)) { - delete win; - return NULL; - } + // Create a pbuffer to be used as the egl surface + // for that window. + if (!win->resize(p_width, p_height)) { + delete win; + return NULL; + } - return win; + return win; } - void WindowSurface::setColorBuffer(ColorBufferPtr p_colorBuffer) { - mAttachedColorBuffer = p_colorBuffer; + mAttachedColorBuffer = p_colorBuffer; - // resize the window if the attached color buffer is of different - // size. - unsigned int cbWidth = mAttachedColorBuffer->getWidth(); - unsigned int cbHeight = mAttachedColorBuffer->getHeight(); + // resize the window if the attached color buffer is of different + // size. + unsigned int cbWidth = mAttachedColorBuffer->getWidth(); + unsigned int cbHeight = mAttachedColorBuffer->getHeight(); - if (cbWidth != mWidth || cbHeight != mHeight) { - resize(cbWidth, cbHeight); - } + if (cbWidth != mWidth || cbHeight != mHeight) { + resize(cbWidth, cbHeight); + } } void WindowSurface::bind(RenderContextPtr p_ctx, BindType p_bindType) { - if (p_bindType == BIND_READ) { - mReadContext = p_ctx; - } else if (p_bindType == BIND_DRAW) { - mDrawContext = p_ctx; - } else if (p_bindType == BIND_READDRAW) { - mReadContext = p_ctx; - mDrawContext = p_ctx; - } + if (p_bindType == BIND_READ) { + mReadContext = p_ctx; + } else if (p_bindType == BIND_DRAW) { + mDrawContext = p_ctx; + } else if (p_bindType == BIND_READDRAW) { + mReadContext = p_ctx; + mDrawContext = p_ctx; + } } bool WindowSurface::flushColorBuffer() { - if (!mAttachedColorBuffer.Ptr()) { - return true; - } - if (!mWidth || !mHeight) { - return false; - } - - if (mAttachedColorBuffer->getWidth() != mWidth || - mAttachedColorBuffer->getHeight() != mHeight) { - // XXX: should never happen - how this needs to be handled? - fprintf(stderr, "Dimensions do not match\n"); - return false; - } - - if (!mDrawContext.Ptr()) { - fprintf(stderr, "Draw context is NULL\n"); - return false; - } - - // Make the surface current - EGLContext prevContext = s_egl.eglGetCurrentContext(); - EGLSurface prevReadSurf = s_egl.eglGetCurrentSurface(EGL_READ); - EGLSurface prevDrawSurf = s_egl.eglGetCurrentSurface(EGL_DRAW); - - if (!s_egl.eglMakeCurrent(mDisplay, - mSurface, - mSurface, - mDrawContext->getEGLContext())) { - fprintf(stderr, "Error making draw context current\n"); - return false; - } - - mAttachedColorBuffer->blitFromCurrentReadBuffer(); - - // restore current context/surface - s_egl.eglMakeCurrent(mDisplay, prevDrawSurf, prevReadSurf, prevContext); - + if (!mAttachedColorBuffer.Ptr()) { return true; + } + if (!mWidth || !mHeight) { + return false; + } + + if (mAttachedColorBuffer->getWidth() != mWidth || + mAttachedColorBuffer->getHeight() != mHeight) { + // XXX: should never happen - how this needs to be handled? + fprintf(stderr, "Dimensions do not match\n"); + return false; + } + + if (!mDrawContext.Ptr()) { + fprintf(stderr, "Draw context is NULL\n"); + return false; + } + + // Make the surface current + EGLContext prevContext = s_egl.eglGetCurrentContext(); + EGLSurface prevReadSurf = s_egl.eglGetCurrentSurface(EGL_READ); + EGLSurface prevDrawSurf = s_egl.eglGetCurrentSurface(EGL_DRAW); + + if (!s_egl.eglMakeCurrent(mDisplay, mSurface, mSurface, + mDrawContext->getEGLContext())) { + fprintf(stderr, "Error making draw context current\n"); + return false; + } + + mAttachedColorBuffer->blitFromCurrentReadBuffer(); + + // restore current context/surface + s_egl.eglMakeCurrent(mDisplay, prevDrawSurf, prevReadSurf, prevContext); + + return true; } -bool WindowSurface::resize(unsigned int p_width, unsigned int p_height) -{ - if (mSurface && mWidth == p_width && mHeight == p_height) { - // no need to resize - return true; - } - - EGLContext prevContext = s_egl.eglGetCurrentContext(); - EGLSurface prevReadSurf = s_egl.eglGetCurrentSurface(EGL_READ); - EGLSurface prevDrawSurf = s_egl.eglGetCurrentSurface(EGL_DRAW); - EGLSurface prevPbuf = mSurface; - bool needRebindContext = mSurface && - (prevReadSurf == mSurface || - prevDrawSurf == mSurface); - - if (needRebindContext) { - s_egl.eglMakeCurrent( - mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); - } - - // - // Destroy previous surface - // - if (mSurface) { - s_egl.eglDestroySurface(mDisplay, mSurface); - mSurface = NULL; - } - - // - // Create pbuffer surface. - // - const EGLint pbufAttribs[5] = { - EGL_WIDTH, (EGLint) p_width, EGL_HEIGHT, (EGLint) p_height, EGL_NONE, - }; - - mSurface = s_egl.eglCreatePbufferSurface(mDisplay, - mConfig, - pbufAttribs); - if (mSurface == EGL_NO_SURFACE) { - fprintf(stderr, "Renderer error: failed to create/resize pbuffer!!\n"); - return false; - } - - mWidth = p_width; - mHeight = p_height; - - if (needRebindContext) { - s_egl.eglMakeCurrent( - mDisplay, - (prevDrawSurf == prevPbuf) ? mSurface : prevDrawSurf, - (prevReadSurf == prevPbuf) ? mSurface : prevReadSurf, - prevContext); - } - +bool WindowSurface::resize(unsigned int p_width, unsigned int p_height) { + if (mSurface && mWidth == p_width && mHeight == p_height) { + // no need to resize return true; + } + + EGLContext prevContext = s_egl.eglGetCurrentContext(); + EGLSurface prevReadSurf = s_egl.eglGetCurrentSurface(EGL_READ); + EGLSurface prevDrawSurf = s_egl.eglGetCurrentSurface(EGL_DRAW); + EGLSurface prevPbuf = mSurface; + bool needRebindContext = + mSurface && (prevReadSurf == mSurface || prevDrawSurf == mSurface); + + if (needRebindContext) { + s_egl.eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, + EGL_NO_CONTEXT); + } + + // + // Destroy previous surface + // + if (mSurface) { + s_egl.eglDestroySurface(mDisplay, mSurface); + mSurface = NULL; + } + + // + // Create pbuffer surface. + // + const EGLint pbufAttribs[5] = { + EGL_WIDTH, (EGLint)p_width, EGL_HEIGHT, (EGLint)p_height, EGL_NONE, + }; + + mSurface = s_egl.eglCreatePbufferSurface(mDisplay, mConfig, pbufAttribs); + if (mSurface == EGL_NO_SURFACE) { + fprintf(stderr, "Renderer error: failed to create/resize pbuffer!!\n"); + return false; + } + + mWidth = p_width; + mHeight = p_height; + + if (needRebindContext) { + s_egl.eglMakeCurrent( + mDisplay, (prevDrawSurf == prevPbuf) ? mSurface : prevDrawSurf, + (prevReadSurf == prevPbuf) ? mSurface : prevReadSurf, prevContext); + } + + return true; } diff --git a/src/anbox/graphics/emugl/WindowSurface.h b/src/anbox/graphics/emugl/WindowSurface.h index 5e302be..85f73e6 100644 --- a/src/anbox/graphics/emugl/WindowSurface.h +++ b/src/anbox/graphics/emugl/WindowSurface.h @@ -27,75 +27,69 @@ // A class used to model a guest-side window surface. The implementation // uses a host Pbuffer to act as the EGL rendering surface instead. class WindowSurface { -public: - // Create a new WindowSurface instance. - // |display| is the host EGLDisplay value. - // |config| is the host EGLConfig value. - // |width| and |height| are the initial size of the Pbuffer. - // Return a new WindowSurface instance on success, or NULL on failure. - static WindowSurface* create(EGLDisplay display, - EGLConfig config, - int width, - int height); + public: + // Create a new WindowSurface instance. + // |display| is the host EGLDisplay value. + // |config| is the host EGLConfig value. + // |width| and |height| are the initial size of the Pbuffer. + // Return a new WindowSurface instance on success, or NULL on failure. + static WindowSurface* create(EGLDisplay display, EGLConfig config, int width, + int height); - // Destructor. - ~WindowSurface(); + // Destructor. + ~WindowSurface(); - // Retrieve the host EGLSurface of the WindowSurface's Pbuffer. - EGLSurface getEGLSurface() const { return mSurface; } + // Retrieve the host EGLSurface of the WindowSurface's Pbuffer. + EGLSurface getEGLSurface() const { return mSurface; } - // Attach a ColorBuffer to this WindowSurface. - // Once attached, calling flushColorBuffer() will copy the Pbuffer's - // pixels to the color buffer. - // - // IMPORTANT: This automatically resizes the Pbuffer's to the ColorBuffer's - // dimensions. Potentially losing pixel values in the process. - void setColorBuffer(ColorBufferPtr p_colorBuffer); + // Attach a ColorBuffer to this WindowSurface. + // Once attached, calling flushColorBuffer() will copy the Pbuffer's + // pixels to the color buffer. + // + // IMPORTANT: This automatically resizes the Pbuffer's to the ColorBuffer's + // dimensions. Potentially losing pixel values in the process. + void setColorBuffer(ColorBufferPtr p_colorBuffer); - // Copy the Pbuffer's pixels to the attached color buffer. - // Returns true on success, or false on error (e.g. if there is no - // attached color buffer). - bool flushColorBuffer(); + // Copy the Pbuffer's pixels to the attached color buffer. + // Returns true on success, or false on error (e.g. if there is no + // attached color buffer). + bool flushColorBuffer(); - // Used by bind() below. - enum BindType { - BIND_READ, - BIND_DRAW, - BIND_READDRAW - }; + // Used by bind() below. + enum BindType { BIND_READ, BIND_DRAW, BIND_READDRAW }; - // TODO(digit): What is this used for exactly? For example, the - // mReadContext is never used by this class. The mDrawContext is only - // used temporarily during flushColorBuffer() operation, and could be - // passed as a parameter to the function instead. Maybe this is only used - // to increment reference counts on the smart pointers. - // - // Bind a context to the WindowSurface (huh? Normally you would bind a - // surface to the context, not the other way around) - // - // |p_ctx| is a RenderContext pointer. - // |p_bindType| is the type of bind. For BIND_READ, this assigns |p_ctx| - // to mReadContext, for BIND_DRAW, it assigns it to mDrawContext, and for - // for BIND_READDRAW, it assigns it to both. - void bind(RenderContextPtr p_ctx, BindType p_bindType); + // TODO(digit): What is this used for exactly? For example, the + // mReadContext is never used by this class. The mDrawContext is only + // used temporarily during flushColorBuffer() operation, and could be + // passed as a parameter to the function instead. Maybe this is only used + // to increment reference counts on the smart pointers. + // + // Bind a context to the WindowSurface (huh? Normally you would bind a + // surface to the context, not the other way around) + // + // |p_ctx| is a RenderContext pointer. + // |p_bindType| is the type of bind. For BIND_READ, this assigns |p_ctx| + // to mReadContext, for BIND_DRAW, it assigns it to mDrawContext, and for + // for BIND_READDRAW, it assigns it to both. + void bind(RenderContextPtr p_ctx, BindType p_bindType); -private: - WindowSurface(); - WindowSurface(const WindowSurface& other); + private: + WindowSurface(); + WindowSurface(const WindowSurface& other); - explicit WindowSurface(EGLDisplay display, EGLConfig config); + explicit WindowSurface(EGLDisplay display, EGLConfig config); - bool resize(unsigned int p_width, unsigned int p_height); + bool resize(unsigned int p_width, unsigned int p_height); -private: - EGLSurface mSurface; - ColorBufferPtr mAttachedColorBuffer; - RenderContextPtr mReadContext; - RenderContextPtr mDrawContext; - GLuint mWidth; - GLuint mHeight; - EGLConfig mConfig; - EGLDisplay mDisplay; + private: + EGLSurface mSurface; + ColorBufferPtr mAttachedColorBuffer; + RenderContextPtr mReadContext; + RenderContextPtr mDrawContext; + GLuint mWidth; + GLuint mHeight; + EGLConfig mConfig; + EGLDisplay mDisplay; }; typedef emugl::SmartPtr WindowSurfacePtr; diff --git a/src/anbox/graphics/gl_renderer_server.cpp b/src/anbox/graphics/gl_renderer_server.cpp index e770c79..1769a47 100644 --- a/src/anbox/graphics/gl_renderer_server.cpp +++ b/src/anbox/graphics/gl_renderer_server.cpp @@ -15,75 +15,83 @@ * */ -#include "anbox/logger.h" #include "anbox/graphics/gl_renderer_server.h" -#include "anbox/graphics/layer_composer.h" #include "anbox/graphics/emugl/RenderControl.h" +#include "anbox/graphics/layer_composer.h" +#include "anbox/logger.h" #include "anbox/wm/manager.h" #include "OpenglRender/render_api.h" #include -#include #include +#include namespace anbox { namespace graphics { -GLRendererServer::GLRendererServer(const std::shared_ptr &wm) : - wm_(wm), - composer_(std::make_shared(wm)) -{ +GLRendererServer::GLRendererServer(const std::shared_ptr &wm) + : wm_(wm), composer_(std::make_shared(wm)) { + if (utils::is_env_set("USE_HOST_GLES")) { + // Force the host EGL/GLES libraries as translator implementation + ::setenv("ANDROID_EGL_LIB", "libEGL.so.1", 0); + ::setenv("ANDROID_GLESv1_LIB", "libGLESv2.so.2", 0); + ::setenv("ANDROID_GLESv2_LIB", "libGLESv2.so.2", 0); + } else { + auto translator_dir = + utils::prefix_dir_from_env(TRANSLATOR_INSTALL_DIR, "SNAP"); + ::setenv( + "ANDROID_EGL_LIB", + utils::string_format("%s/libEGL_translator.so", translator_dir).c_str(), + 0); + ::setenv("ANDROID_GLESv1_LIB", + utils::string_format("%s/libGLES_CM_translator.so", translator_dir) + .c_str(), + 0); + ::setenv("ANDROID_GLESv2_LIB", + utils::string_format("%s/libGLES_V2_translator.so", translator_dir) + .c_str(), + 0); + } - if (utils::is_env_set("USE_HOST_GLES")) { - // Force the host EGL/GLES libraries as translator implementation - ::setenv("ANDROID_EGL_LIB", "libEGL.so.1", 0); - ::setenv("ANDROID_GLESv1_LIB", "libGLESv2.so.2", 0); - ::setenv("ANDROID_GLESv2_LIB", "libGLESv2.so.2", 0); - } else { - auto translator_dir = utils::prefix_dir_from_env(TRANSLATOR_INSTALL_DIR, "SNAP"); - ::setenv("ANDROID_EGL_LIB", utils::string_format("%s/libEGL_translator.so", translator_dir).c_str(), 0); - ::setenv("ANDROID_GLESv1_LIB", utils::string_format("%s/libGLES_CM_translator.so", translator_dir).c_str(), 0); - ::setenv("ANDROID_GLESv2_LIB", utils::string_format("%s/libGLES_V2_translator.so", translator_dir).c_str(), 0); - } + if (!initLibrary()) + BOOST_THROW_EXCEPTION( + std::runtime_error("Failed to initialize OpenGL renderer")); - if (!initLibrary()) - BOOST_THROW_EXCEPTION(std::runtime_error("Failed to initialize OpenGL renderer")); - - registerLayerComposer(composer_); + registerLayerComposer(composer_); } -GLRendererServer::~GLRendererServer() { - stopOpenGLRenderer(); -} +GLRendererServer::~GLRendererServer() { stopOpenGLRenderer(); } void logger_write(const char *format, ...) { - char message[2048]; - va_list args; + char message[2048]; + va_list args; - va_start(args, format); - vsnprintf(message, sizeof(message) - 1, format, args); - va_end(args); + va_start(args, format); + vsnprintf(message, sizeof(message) - 1, format, args); + va_end(args); - DEBUG("%s", message); + DEBUG("%s", message); } void GLRendererServer::start() { - emugl_logger_struct log_funcs; - log_funcs.coarse = logger_write; - log_funcs.fine = logger_write; + emugl_logger_struct log_funcs; + log_funcs.coarse = logger_write; + log_funcs.fine = logger_write; - char server_addr[256] = { 0 }; - // The width & height we supply here are the dimensions the internal framebuffer - // will use. Making this static prevents us for now to resize the window we create - // later for the actual display. - if (!initOpenGLRenderer(0, server_addr, sizeof(server_addr), log_funcs, logger_write)) - BOOST_THROW_EXCEPTION(std::runtime_error("Failed to setup OpenGL renderer")); + char server_addr[256] = {0}; + // The width & height we supply here are the dimensions the internal + // framebuffer + // will use. Making this static prevents us for now to resize the window we + // create + // later for the actual display. + if (!initOpenGLRenderer(0, server_addr, sizeof(server_addr), log_funcs, + logger_write)) + BOOST_THROW_EXCEPTION( + std::runtime_error("Failed to setup OpenGL renderer")); - socket_path_ = server_addr; + socket_path_ = server_addr; } -std::string GLRendererServer::socket_path() const { - return socket_path_; -} -} // namespace graphics -} // namespace anbox +std::string GLRendererServer::socket_path() const { return socket_path_; } +} // namespace graphics +} // namespace anbox diff --git a/src/anbox/graphics/gl_renderer_server.h b/src/anbox/graphics/gl_renderer_server.h index 7bee80d..a8d059a 100644 --- a/src/anbox/graphics/gl_renderer_server.h +++ b/src/anbox/graphics/gl_renderer_server.h @@ -18,34 +18,34 @@ #ifndef ANBOX_GRAPHICS_GL_RENDERER_SERVER_H_ #define ANBOX_GRAPHICS_GL_RENDERER_SERVER_H_ -#include #include +#include namespace anbox { namespace input { class Manager; -} // namespace input +} // namespace input namespace wm { class Manager; -} // namespace wm +} // namespace wm namespace graphics { class LayerComposer; class GLRendererServer { -public: - GLRendererServer(const std::shared_ptr &wm); - ~GLRendererServer(); + public: + GLRendererServer(const std::shared_ptr &wm); + ~GLRendererServer(); - void start(); + void start(); - std::string socket_path() const; + std::string socket_path() const; -private: - std::string socket_path_; - std::shared_ptr wm_; - std::shared_ptr composer_; + private: + std::string socket_path_; + std::shared_ptr wm_; + std::shared_ptr composer_; }; -} // namespace graphics -} // namespace anbox +} // namespace graphics +} // namespace anbox #endif diff --git a/src/anbox/graphics/layer_composer.cpp b/src/anbox/graphics/layer_composer.cpp index b595afc..3f594f8 100644 --- a/src/anbox/graphics/layer_composer.cpp +++ b/src/anbox/graphics/layer_composer.cpp @@ -17,86 +17,78 @@ #include "anbox/graphics/layer_composer.h" #include "anbox/graphics/emugl/Renderer.h" -#include "anbox/wm/manager.h" #include "anbox/logger.h" +#include "anbox/wm/manager.h" namespace anbox { namespace graphics { -LayerComposer::LayerComposer(const std::shared_ptr &wm) : - wm_(wm) -{ -} +LayerComposer::LayerComposer(const std::shared_ptr &wm) + : wm_(wm) {} -LayerComposer::~LayerComposer() -{ -} +LayerComposer::~LayerComposer() {} -void LayerComposer::submit_layers(const RenderableList &renderables) -{ - std::map,RenderableList> win_layers; - for (const auto &renderable : renderables) - { - // Ignore all surfaces which are not meant for a task - if (!utils::string_starts_with(renderable.name(), "org.anbox.surface.")) - continue; +void LayerComposer::submit_layers(const RenderableList &renderables) { + std::map, RenderableList> win_layers; + for (const auto &renderable : renderables) { + // Ignore all surfaces which are not meant for a task + if (!utils::string_starts_with(renderable.name(), "org.anbox.surface.")) + continue; - wm::Task::Id task_id = 0; - if (sscanf(renderable.name().c_str(), "org.anbox.surface.%d", &task_id) != 1 || !task_id) - continue; + wm::Task::Id task_id = 0; + if (sscanf(renderable.name().c_str(), "org.anbox.surface.%d", &task_id) != + 1 || + !task_id) + continue; - auto w = wm_->find_window_for_task(task_id); - if (!w) - continue; + auto w = wm_->find_window_for_task(task_id); + if (!w) continue; - if (win_layers.find(w) == win_layers.end()) { - win_layers.insert({w, {renderable}}); - continue; - } - - win_layers[w].push_back(renderable); + if (win_layers.find(w) == win_layers.end()) { + win_layers.insert({w, {renderable}}); + continue; } - for (const auto &w : win_layers) - { - const auto &window = w.first; - const auto &renderables = w.second; - RenderableList final_renderables; - auto new_window_frame = Rect::Invalid; + win_layers[w].push_back(renderable); + } - for (auto &r : renderables) - { - if (new_window_frame == Rect::Invalid) - new_window_frame = r.screen_position(); - else - new_window_frame.merge(r.screen_position()); - } + for (const auto &w : win_layers) { + const auto &window = w.first; + const auto &renderables = w.second; + RenderableList final_renderables; + auto new_window_frame = Rect::Invalid; - for (auto &r : renderables) - { - // As we get absolute display coordinates from the Android hwcomposer we - // need to recalculate all layer coordinates into relatives ones to the - // window they are drawn into. - auto left = r.screen_position().left() - new_window_frame.left(); - auto top = r.screen_position().top() - new_window_frame.top(); - - auto rect = Rect{ - left - r.crop().left(), - top - r.crop().top(), - r.screen_position().width() + left, - r.screen_position().height() + top, - }; - - auto new_renderable = r; - new_renderable.set_screen_position(rect); - final_renderables.push_back(new_renderable); - } - - w.first->update_frame(new_window_frame); - - Renderer::get()->draw(window->native_handle(), - Rect{0, 0, window->frame().width(), window->frame().height()}, - final_renderables); + for (auto &r : renderables) { + if (new_window_frame == Rect::Invalid) + new_window_frame = r.screen_position(); + else + new_window_frame.merge(r.screen_position()); } + + for (auto &r : renderables) { + // As we get absolute display coordinates from the Android hwcomposer we + // need to recalculate all layer coordinates into relatives ones to the + // window they are drawn into. + auto left = r.screen_position().left() - new_window_frame.left(); + auto top = r.screen_position().top() - new_window_frame.top(); + + auto rect = Rect{ + left - r.crop().left(), top - r.crop().top(), + r.screen_position().width() + left, + r.screen_position().height() + top, + }; + + auto new_renderable = r; + new_renderable.set_screen_position(rect); + final_renderables.push_back(new_renderable); + } + + w.first->update_frame(new_window_frame); + + Renderer::get()->draw( + window->native_handle(), + Rect{0, 0, window->frame().width(), window->frame().height()}, + final_renderables); + } } -} // namespace graphics -} // namespace anbox +} // namespace graphics +} // namespace anbox diff --git a/src/anbox/graphics/layer_composer.h b/src/anbox/graphics/layer_composer.h index 9127b2d..ff6498a 100644 --- a/src/anbox/graphics/layer_composer.h +++ b/src/anbox/graphics/layer_composer.h @@ -25,19 +25,19 @@ namespace anbox { namespace wm { class Manager; -} // namespace wm +} // namespace wm namespace graphics { class LayerComposer { -public: - LayerComposer(const std::shared_ptr &wm); - ~LayerComposer(); + public: + LayerComposer(const std::shared_ptr &wm); + ~LayerComposer(); - void submit_layers(const RenderableList &renderables); + void submit_layers(const RenderableList &renderables); -private: - std::shared_ptr wm_; + private: + std::shared_ptr wm_; }; -} // namespace graphics -} // namespace anbox +} // namespace graphics +} // namespace anbox #endif diff --git a/src/anbox/graphics/opengles_message_processor.cpp b/src/anbox/graphics/opengles_message_processor.cpp index 6f5a26d..4f5aaba 100644 --- a/src/anbox/graphics/opengles_message_processor.cpp +++ b/src/anbox/graphics/opengles_message_processor.cpp @@ -15,45 +15,46 @@ * */ -#include "anbox/logger.h" #include "anbox/graphics/opengles_message_processor.h" -#include "anbox/network/local_socket_messenger.h" +#include "anbox/logger.h" #include "anbox/network/connections.h" #include "anbox/network/delegate_message_processor.h" +#include "anbox/network/local_socket_messenger.h" namespace anbox { namespace graphics { -OpenGlesMessageProcessor::OpenGlesMessageProcessor(const std::string &renderer_socket_path, - const std::shared_ptr &rt, - const std::shared_ptr &messenger) : - client_messenger_(messenger) { - - connect_and_attach(renderer_socket_path, rt); +OpenGlesMessageProcessor::OpenGlesMessageProcessor( + const std::string &renderer_socket_path, const std::shared_ptr &rt, + const std::shared_ptr &messenger) + : client_messenger_(messenger) { + connect_and_attach(renderer_socket_path, rt); } -OpenGlesMessageProcessor::~OpenGlesMessageProcessor() { +OpenGlesMessageProcessor::~OpenGlesMessageProcessor() {} + +void OpenGlesMessageProcessor::connect_and_attach( + const std::string &socket_path, const std::shared_ptr &rt) { + auto socket = std::make_shared( + rt->service()); + socket->connect(boost::asio::local::stream_protocol::endpoint(socket_path)); + + messenger_ = std::make_shared(socket); + renderer_ = std::make_shared( + messenger_, messenger_, 0, nullptr, + std::make_shared( + [&](const std::vector &data) { + client_messenger_->send(reinterpret_cast(data.data()), + data.size()); + return true; + })); + renderer_->set_name("opengles-renderer"); + renderer_->read_next_message(); } -void OpenGlesMessageProcessor::connect_and_attach(const std::string &socket_path, - const std::shared_ptr &rt) { - - auto socket = std::make_shared(rt->service()); - socket->connect(boost::asio::local::stream_protocol::endpoint(socket_path)); - - messenger_ = std::make_shared(socket); - renderer_ = std::make_shared( - messenger_, messenger_, 0, nullptr, - std::make_shared([&](const std::vector &data) { - client_messenger_->send(reinterpret_cast(data.data()), data.size()); - return true; - })); - renderer_->set_name("opengles-renderer"); - renderer_->read_next_message(); +bool OpenGlesMessageProcessor::process_data( + const std::vector &data) { + messenger_->send(reinterpret_cast(data.data()), data.size()); + return true; } - -bool OpenGlesMessageProcessor::process_data(const std::vector &data) { - messenger_->send(reinterpret_cast(data.data()), data.size()); - return true; -} -} // namespace graphics -} // namespace anbox +} // namespace graphics +} // namespace anbox diff --git a/src/anbox/graphics/opengles_message_processor.h b/src/anbox/graphics/opengles_message_processor.h index 05612cf..8166c66 100644 --- a/src/anbox/graphics/opengles_message_processor.h +++ b/src/anbox/graphics/opengles_message_processor.h @@ -22,31 +22,32 @@ #include -#include "anbox/runtime.h" #include "anbox/network/message_processor.h" -#include "anbox/network/socket_messenger.h" #include "anbox/network/socket_connection.h" +#include "anbox/network/socket_messenger.h" +#include "anbox/runtime.h" namespace anbox { namespace graphics { class OpenGlesMessageProcessor : public network::MessageProcessor { -public: - OpenGlesMessageProcessor(const std::string &renderer_socket_path, - const std::shared_ptr &rt, - const std::shared_ptr &messenger); - ~OpenGlesMessageProcessor(); + public: + OpenGlesMessageProcessor( + const std::string &renderer_socket_path, + const std::shared_ptr &rt, + const std::shared_ptr &messenger); + ~OpenGlesMessageProcessor(); - bool process_data(const std::vector &data) override; + bool process_data(const std::vector &data) override; -private: - void connect_and_attach(const std::string &socket_path, - const std::shared_ptr &rt); + private: + void connect_and_attach(const std::string &socket_path, + const std::shared_ptr &rt); - std::shared_ptr client_messenger_; - std::shared_ptr messenger_; - std::shared_ptr renderer_; + std::shared_ptr client_messenger_; + std::shared_ptr messenger_; + std::shared_ptr renderer_; }; -} // namespace graphics -} // namespace anbox +} // namespace graphics +} // namespace anbox #endif diff --git a/src/anbox/graphics/primitives.h b/src/anbox/graphics/primitives.h index 5529f95..de7191a 100644 --- a/src/anbox/graphics/primitives.h +++ b/src/anbox/graphics/primitives.h @@ -17,7 +17,6 @@ * Kevin DuBois */ - #ifndef ANBOX_GRAPHICS_PRIMITIVES_H_ #define ANBOX_GRAPHICS_PRIMITIVES_H_ @@ -25,28 +24,24 @@ namespace anbox { namespace graphics { -struct Vertex -{ - GLfloat position[3]; - GLfloat texcoord[2]; +struct Vertex { + GLfloat position[3]; + GLfloat texcoord[2]; }; -struct Primitive -{ - enum {max_vertices = 4}; +struct Primitive { + enum { max_vertices = 4 }; - Primitive() - : type(GL_TRIANGLE_FAN), nvertices(4) - { - // Default is a quad. Just need to assign vertices[] and tex_id. - } + Primitive() : type(GL_TRIANGLE_FAN), nvertices(4) { + // Default is a quad. Just need to assign vertices[] and tex_id. + } - GLenum type; // GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN, GL_TRIANGLES etc - GLuint tex_id; // GL texture ID (or 0 to represent the surface itself) - int nvertices; - Vertex vertices[max_vertices]; + GLenum type; // GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN, GL_TRIANGLES etc + GLuint tex_id; // GL texture ID (or 0 to represent the surface itself) + int nvertices; + Vertex vertices[max_vertices]; }; -} // namespace graphics -} // namespace anbox +} // namespace graphics +} // namespace anbox #endif diff --git a/src/anbox/graphics/program_family.cpp b/src/anbox/graphics/program_family.cpp index c47e49e..c0bf8a0 100644 --- a/src/anbox/graphics/program_family.cpp +++ b/src/anbox/graphics/program_family.cpp @@ -22,86 +22,72 @@ namespace anbox { namespace graphics { -void ProgramFamily::Shader::init(GLenum type, const GLchar* src) -{ - if (!id) - { - id = s_gles2.glCreateShader(type); - if (id) - { - s_gles2.glShaderSource(id, 1, &src, NULL); - s_gles2.glCompileShader(id); - GLint ok; - s_gles2.glGetShaderiv(id, GL_COMPILE_STATUS, &ok); - if (!ok) - { - GLchar log[1024]; - s_gles2.glGetShaderInfoLog(id, sizeof log - 1, NULL, log); - log[sizeof log - 1] = '\0'; - s_gles2.glDeleteShader(id); - id = 0; - throw std::runtime_error(std::string("Compile failed: ")+ - log + " for:\n" + src); - } - } +void ProgramFamily::Shader::init(GLenum type, const GLchar* src) { + if (!id) { + id = s_gles2.glCreateShader(type); + if (id) { + s_gles2.glShaderSource(id, 1, &src, NULL); + s_gles2.glCompileShader(id); + GLint ok; + s_gles2.glGetShaderiv(id, GL_COMPILE_STATUS, &ok); + if (!ok) { + GLchar log[1024]; + s_gles2.glGetShaderInfoLog(id, sizeof log - 1, NULL, log); + log[sizeof log - 1] = '\0'; + s_gles2.glDeleteShader(id); + id = 0; + throw std::runtime_error(std::string("Compile failed: ") + log + + " for:\n" + src); + } } + } } -ProgramFamily::~ProgramFamily() noexcept -{ - // shader and program lifetimes are managed manually, so that we don't - // need any reference counting or to worry about how many copy constructions - // might have been followed by destructor calls during container resizes. +ProgramFamily::~ProgramFamily() noexcept { + // shader and program lifetimes are managed manually, so that we don't + // need any reference counting or to worry about how many copy constructions + // might have been followed by destructor calls during container resizes. - for (auto& p : program) - { - if (p.second.id) - s_gles2.glDeleteProgram(p.second.id); - } + for (auto& p : program) { + if (p.second.id) s_gles2.glDeleteProgram(p.second.id); + } - for (auto& v : vshader) - { - if (v.second.id) - s_gles2.glDeleteShader(v.second.id); - } + for (auto& v : vshader) { + if (v.second.id) s_gles2.glDeleteShader(v.second.id); + } - for (auto& f : fshader) - { - if (f.second.id) - s_gles2.glDeleteShader(f.second.id); - } + for (auto& f : fshader) { + if (f.second.id) s_gles2.glDeleteShader(f.second.id); + } } GLuint ProgramFamily::add_program(const GLchar* const vshader_src, - const GLchar* const fshader_src) -{ - auto& v = vshader[vshader_src]; - if (!v.id) v.init(GL_VERTEX_SHADER, vshader_src); + const GLchar* const fshader_src) { + auto& v = vshader[vshader_src]; + if (!v.id) v.init(GL_VERTEX_SHADER, vshader_src); - auto& f = fshader[fshader_src]; - if (!f.id) f.init(GL_FRAGMENT_SHADER, fshader_src); + auto& f = fshader[fshader_src]; + if (!f.id) f.init(GL_FRAGMENT_SHADER, fshader_src); - auto& p = program[{v.id, f.id}]; - if (!p.id) - { - p.id = s_gles2.glCreateProgram(); - s_gles2.glAttachShader(p.id, v.id); - s_gles2.glAttachShader(p.id, f.id); - s_gles2.glLinkProgram(p.id); - GLint ok; - s_gles2.glGetProgramiv(p.id, GL_LINK_STATUS, &ok); - if (!ok) - { - GLchar log[1024]; - s_gles2.glGetProgramInfoLog(p.id, sizeof log - 1, NULL, log); - log[sizeof log - 1] = '\0'; - s_gles2.glDeleteShader(p.id); - p.id = 0; - throw std::runtime_error(std::string("Link failed: ")+log); - } + auto& p = program[{v.id, f.id}]; + if (!p.id) { + p.id = s_gles2.glCreateProgram(); + s_gles2.glAttachShader(p.id, v.id); + s_gles2.glAttachShader(p.id, f.id); + s_gles2.glLinkProgram(p.id); + GLint ok; + s_gles2.glGetProgramiv(p.id, GL_LINK_STATUS, &ok); + if (!ok) { + GLchar log[1024]; + s_gles2.glGetProgramInfoLog(p.id, sizeof log - 1, NULL, log); + log[sizeof log - 1] = '\0'; + s_gles2.glDeleteShader(p.id); + p.id = 0; + throw std::runtime_error(std::string("Link failed: ") + log); } + } - return p.id; + return p.id; } -} // namespace graphics -} // namespace anbox +} // namespace graphics +} // namespace anbox diff --git a/src/anbox/graphics/program_family.h b/src/anbox/graphics/program_family.h index 98e7f88..4de720e 100644 --- a/src/anbox/graphics/program_family.h +++ b/src/anbox/graphics/program_family.h @@ -19,9 +19,9 @@ #ifndef ANBOX_GRAPHICS_PROGRAM_FAMILY_H_ #define ANBOX_GRAPHICS_PROGRAM_FAMILY_H_ -#include #include #include +#include #include @@ -35,34 +35,31 @@ namespace graphics { * different programs within the family to share common patterns of uniform * usage too. */ -class ProgramFamily -{ -public: - ProgramFamily() = default; - ProgramFamily(ProgramFamily const&) = delete; - ProgramFamily& operator=(ProgramFamily const&) = delete; - ~ProgramFamily() noexcept; +class ProgramFamily { + public: + ProgramFamily() = default; + ProgramFamily(ProgramFamily const&) = delete; + ProgramFamily& operator=(ProgramFamily const&) = delete; + ~ProgramFamily() noexcept; - GLuint add_program(const GLchar* const static_vshader_src, - const GLchar* const static_fshader_src); + GLuint add_program(const GLchar* const static_vshader_src, + const GLchar* const static_fshader_src); -private: - struct Shader - { - GLuint id = 0; - void init(GLenum type, const GLchar* src); - }; - typedef std::unordered_map ShaderMap; - ShaderMap vshader, fshader; + private: + struct Shader { + GLuint id = 0; + void init(GLenum type, const GLchar* src); + }; + typedef std::unordered_map ShaderMap; + ShaderMap vshader, fshader; - typedef std::pair ShaderPair; - struct Program - { - GLuint id = 0; - }; - std::map program; + typedef std::pair ShaderPair; + struct Program { + GLuint id = 0; + }; + std::map program; }; -} // namespace graphics -} // namespace anbox +} // namespace graphics +} // namespace anbox -#endif // MIR_RENDERER_GL_PROGRAM_FAMILY_H_ +#endif // MIR_RENDERER_GL_PROGRAM_FAMILY_H_ diff --git a/src/anbox/graphics/rect.cpp b/src/anbox/graphics/rect.cpp index 707dfeb..5915766 100644 --- a/src/anbox/graphics/rect.cpp +++ b/src/anbox/graphics/rect.cpp @@ -22,20 +22,19 @@ namespace anbox { namespace graphics { -const Rect Rect::Invalid{-1,-1,-1,-1}; -const Rect Rect::Empty{0,0,0,0}; +const Rect Rect::Invalid{-1, -1, -1, -1}; +const Rect Rect::Empty{0, 0, 0, 0}; -void Rect::merge(const Rect &rhs) -{ - left_ = std::min(left_, rhs.left()); - top_ = std::min(top_, rhs.top()); - right_ = std::max(right_, rhs.right()); - bottom_ = std::max(bottom_, rhs.bottom()); +void Rect::merge(const Rect &rhs) { + left_ = std::min(left_, rhs.left()); + top_ = std::min(top_, rhs.top()); + right_ = std::max(right_, rhs.right()); + bottom_ = std::max(bottom_, rhs.bottom()); } -std::ostream& operator<<(std::ostream &out, const Rect &rect) -{ - return out << "{" << rect.left() << "," << rect.top() << ","<< rect.right() << "," << rect.bottom() << "}"; +std::ostream &operator<<(std::ostream &out, const Rect &rect) { + return out << "{" << rect.left() << "," << rect.top() << "," << rect.right() + << "," << rect.bottom() << "}"; } -} // namespace graphics -} // namespace anbox +} // namespace graphics +} // namespace anbox diff --git a/src/anbox/graphics/rect.h b/src/anbox/graphics/rect.h index 0ef812b..ec26683 100644 --- a/src/anbox/graphics/rect.h +++ b/src/anbox/graphics/rect.h @@ -25,83 +25,53 @@ namespace anbox { namespace graphics { class Rect { -public: - static const Rect Invalid; - static const Rect Empty; + public: + static const Rect Invalid; + static const Rect Empty; - inline Rect() : Rect(Empty) {} + inline Rect() : Rect(Empty) {} - inline Rect(const std::int32_t &left, - const std::int32_t &top, - const std::int32_t &right, - const std::int32_t &bottom) : - left_(left), - top_(top), - right_(right), - bottom_(bottom) { - } + inline Rect(const std::int32_t &left, const std::int32_t &top, + const std::int32_t &right, const std::int32_t &bottom) + : left_(left), top_(top), right_(right), bottom_(bottom) {} - inline Rect(const std::int32_t &width, const std::int32_t &height) : - left_(0), - top_(0), - right_(width), - bottom_(height) { - } + inline Rect(const std::int32_t &width, const std::int32_t &height) + : left_(0), top_(0), right_(width), bottom_(height) {} - inline void clear() { - left_ = top_ = right_ = bottom_ = 0; - } + inline void clear() { left_ = top_ = right_ = bottom_ = 0; } - inline bool valid() const { - return width() >= 0 && height() >= 0; - } + inline bool valid() const { return width() >= 0 && height() >= 0; } - inline std::int32_t width() const { - return right_ - left_; - } + inline std::int32_t width() const { return right_ - left_; } - inline std::int32_t height() const { - return bottom_ - top_; - } + inline std::int32_t height() const { return bottom_ - top_; } - inline std::int32_t left() const { - return left_; - } + inline std::int32_t left() const { return left_; } - inline std::int32_t top() const { - return top_; - } + inline std::int32_t top() const { return top_; } - inline std::int32_t right() const { - return right_; - } + inline std::int32_t right() const { return right_; } - inline std::int32_t bottom() const { - return bottom_; - } + inline std::int32_t bottom() const { return bottom_; } - inline bool operator == (const Rect &rhs) const { - return (left_ == rhs.left() && - top_ == rhs.top() && - right_ == rhs.right() && - bottom_ == rhs.bottom()); - } + inline bool operator==(const Rect &rhs) const { + return (left_ == rhs.left() && top_ == rhs.top() && right_ == rhs.right() && + bottom_ == rhs.bottom()); + } - inline bool operator != (const Rect &rhs) const { - return !operator == (rhs); - } + inline bool operator!=(const Rect &rhs) const { return !operator==(rhs); } - void merge(const Rect &rhs); + void merge(const Rect &rhs); -private: - std::int32_t left_; - std::int32_t top_; - std::int32_t right_; - std::int32_t bottom_; + private: + std::int32_t left_; + std::int32_t top_; + std::int32_t right_; + std::int32_t bottom_; }; -std::ostream& operator<<(std::ostream &out, const Rect &rect); -} // namespace graphics -} // namespace anbox +std::ostream &operator<<(std::ostream &out, const Rect &rect); +} // namespace graphics +} // namespace anbox #endif diff --git a/src/anbox/input/device.cpp b/src/anbox/input/device.cpp index 0a2d0ae..130ae1d 100644 --- a/src/anbox/input/device.cpp +++ b/src/anbox/input/device.cpp @@ -16,152 +16,153 @@ */ #include "anbox/input/device.h" +#include "anbox/logger.h" #include "anbox/network/delegate_connection_creator.h" #include "anbox/network/delegate_message_processor.h" #include "anbox/network/local_socket_messenger.h" #include "anbox/qemu/null_message_processor.h" -#include "anbox/logger.h" #include namespace anbox { namespace input { -std::shared_ptr Device::create(const std::string &path, const std::shared_ptr &runtime) { - auto sp = std::make_shared(); +std::shared_ptr Device::create( + const std::string &path, const std::shared_ptr &runtime) { + auto sp = std::make_shared(); - auto delegate_connector = std::make_shared>( - [sp](std::shared_ptr const &socket) { - sp->new_client(socket); - }); + auto delegate_connector = std::make_shared< + network::DelegateConnectionCreator>( + [sp](std::shared_ptr const + &socket) { sp->new_client(socket); }); - sp->connector_ = std::make_shared(path, runtime, delegate_connector); + sp->connector_ = std::make_shared( + path, runtime, delegate_connector); - return sp; + return sp; } -Device::Device() : - next_connection_id_(0), - connections_(std::make_shared>()) { - ::memset(&info_, 0, sizeof(info_)); +Device::Device() + : next_connection_id_(0), + connections_( + std::make_shared>()) { + ::memset(&info_, 0, sizeof(info_)); } -Device::~Device() { -} +Device::~Device() {} void Device::send_events(const std::vector &events) { - struct CompatEvent { - // NOTE: A bit dirty but as we're running currently a 64 bit container - // struct input_event has a different size. We rebuild the struct here - // to reach the correct size. - std::uint64_t sec; - std::uint64_t usec; - std::uint16_t type; - std::uint16_t code; - std::uint32_t value; - }; + struct CompatEvent { + // NOTE: A bit dirty but as we're running currently a 64 bit container + // struct input_event has a different size. We rebuild the struct here + // to reach the correct size. + std::uint64_t sec; + std::uint64_t usec; + std::uint16_t type; + std::uint16_t code; + std::uint32_t value; + }; - struct timespec spec; - clock_gettime(CLOCK_MONOTONIC, &spec); + struct timespec spec; + clock_gettime(CLOCK_MONOTONIC, &spec); - auto data = new CompatEvent[events.size()]; - int n = 0; - for (const auto &event : events) { - data[n].sec = spec.tv_sec; - data[n].usec = spec.tv_nsec / 1000; - data[n].type = event.type; - data[n].code = event.code; - data[n].value = event.value; - n++; - } + auto data = new CompatEvent[events.size()]; + int n = 0; + for (const auto &event : events) { + data[n].sec = spec.tv_sec; + data[n].usec = spec.tv_nsec / 1000; + data[n].type = event.type; + data[n].code = event.code; + data[n].value = event.value; + n++; + } - for (unsigned n = 0; n < connections_->size(); n++) { - connections_->at(n)->send(reinterpret_cast(data), - events.size() * sizeof(struct CompatEvent)); - } + for (unsigned n = 0; n < connections_->size(); n++) { + connections_->at(n)->send(reinterpret_cast(data), + events.size() * sizeof(struct CompatEvent)); + } } void Device::set_name(const std::string &name) { - snprintf(info_.name, 80, "%s", name.c_str()); + snprintf(info_.name, 80, "%s", name.c_str()); } void Device::set_driver_version(const int &version) { - info_.driver_version = version; + info_.driver_version = version; } void Device::set_input_id(const struct input_id &id) { - info_.id.bustype = id.bustype; - info_.id.product = id.product; - info_.id.vendor = id.vendor; - info_.id.version = id.version; + info_.id.bustype = id.bustype; + info_.id.product = id.product; + info_.id.vendor = id.vendor; + info_.id.version = id.version; } void Device::set_physical_location(const std::string &physical_location) { - snprintf(info_.physical_location, 80, "%s", physical_location.c_str()); + snprintf(info_.physical_location, 80, "%s", physical_location.c_str()); } void Device::set_key_bit(const std::uint64_t &bit) { - set_bit(info_.key_bitmask, bit); + set_bit(info_.key_bitmask, bit); } void Device::set_abs_bit(const std::uint64_t &bit) { - set_bit(info_.abs_bitmask, bit); + set_bit(info_.abs_bitmask, bit); } void Device::set_rel_bit(const std::uint64_t &bit) { - set_bit(info_.rel_bitmask, bit); + set_bit(info_.rel_bitmask, bit); } void Device::set_sw_bit(const std::uint64_t &bit) { - set_bit(info_.sw_bitmask, bit); + set_bit(info_.sw_bitmask, bit); } void Device::set_led_bit(const std::uint64_t &bit) { - set_bit(info_.led_bitmask, bit); + set_bit(info_.led_bitmask, bit); } void Device::set_ff_bit(const std::uint64_t &bit) { - set_bit(info_.ff_bitmask, bit); + set_bit(info_.ff_bitmask, bit); } void Device::set_prop_bit(const std::uint64_t &bit) { - set_bit(info_.prop_bitmask, bit); + set_bit(info_.prop_bitmask, bit); } void Device::set_abs_min(const std::uint64_t &bit, const std::uint32_t &value) { - info_.abs_min[bit] = value; + info_.abs_min[bit] = value; } void Device::set_abs_max(const std::uint64_t &bit, const std::uint32_t &value) { - info_.abs_max[bit] = value; + info_.abs_max[bit] = value; } void Device::set_bit(std::uint8_t *array, const std::uint64_t &bit) { - array[bit/8] |= (1 << (bit % 8)); + array[bit / 8] |= (1 << (bit % 8)); } void Device::set_unique_id(const std::string &unique_id) { - snprintf(info_.unique_id, 80, "%s", unique_id.c_str()); + snprintf(info_.unique_id, 80, "%s", unique_id.c_str()); } -std::string Device::socket_path() const { - return connector_->socket_file(); -} +std::string Device::socket_path() const { return connector_->socket_file(); } -int Device::next_id() { - return next_connection_id_++; -} +int Device::next_id() { return next_connection_id_++; } -void Device::new_client(std::shared_ptr const &socket) { - auto const messenger = std::make_shared(socket); - auto const& connection = std::make_shared( - messenger, messenger, next_id(), connections_, - std::make_shared()); - connection->set_name("input-device"); - connections_->add(connection); +void Device::new_client( + std::shared_ptr const + &socket) { + auto const messenger = + std::make_shared(socket); + auto const &connection = std::make_shared( + messenger, messenger, next_id(), connections_, + std::make_shared()); + connection->set_name("input-device"); + connections_->add(connection); - // Send all necessary information about our device so that the remote - // side can properly configure itself for this input device - connection->send(reinterpret_cast(&info_), sizeof(info_)); + // Send all necessary information about our device so that the remote + // side can properly configure itself for this input device + connection->send(reinterpret_cast(&info_), sizeof(info_)); } -} // namespace input -} // namespace anbox +} // namespace input +} // namespace anbox diff --git a/src/anbox/input/device.h b/src/anbox/input/device.h index 8c6cc16..865e9fe 100644 --- a/src/anbox/input/device.h +++ b/src/anbox/input/device.h @@ -18,8 +18,8 @@ #ifndef ANBOX_INPUT_DEVICE_H_ #define ANBOX_INPUT_DEVICE_H_ -#include "anbox/network/published_socket_connector.h" #include "anbox/network/connections.h" +#include "anbox/network/published_socket_connector.h" #include "anbox/network/socket_connection.h" #include "anbox/runtime.h" @@ -30,70 +30,74 @@ namespace anbox { namespace input { struct Event { - std::uint16_t type; - std::uint16_t code; - std::int32_t value; + std::uint16_t type; + std::uint16_t code; + std::int32_t value; }; class Device : public std::enable_shared_from_this { -public: - static std::shared_ptr create(const std::string &path, const std::shared_ptr &runtime); + public: + static std::shared_ptr create( + const std::string &path, const std::shared_ptr &runtime); - Device(); - ~Device(); + Device(); + ~Device(); - void send_events(const std::vector &events); - void send_event(const std::uint16_t &code, const std::uint16_t &event, const std::int32_t &value); + void send_events(const std::vector &events); + void send_event(const std::uint16_t &code, const std::uint16_t &event, + const std::int32_t &value); - void set_name(const std::string &name); - void set_driver_version(const int &version); - void set_input_id(const struct input_id &id); - void set_physical_location(const std::string &physical_location); - void set_unique_id(const std::string &unique_id); - void set_key_bit(const std::uint64_t &bit); - void set_abs_bit(const std::uint64_t &bit); - void set_rel_bit(const std::uint64_t &bit); - void set_sw_bit(const std::uint64_t &bit); - void set_led_bit(const std::uint64_t &bit); - void set_ff_bit(const std::uint64_t &bit); - void set_prop_bit(const std::uint64_t &bit); + void set_name(const std::string &name); + void set_driver_version(const int &version); + void set_input_id(const struct input_id &id); + void set_physical_location(const std::string &physical_location); + void set_unique_id(const std::string &unique_id); + void set_key_bit(const std::uint64_t &bit); + void set_abs_bit(const std::uint64_t &bit); + void set_rel_bit(const std::uint64_t &bit); + void set_sw_bit(const std::uint64_t &bit); + void set_led_bit(const std::uint64_t &bit); + void set_ff_bit(const std::uint64_t &bit); + void set_prop_bit(const std::uint64_t &bit); - void set_abs_min(const std::uint64_t &bit, const std::uint32_t &value); - void set_abs_max(const std::uint64_t &bit, const std::uint32_t &value); + void set_abs_min(const std::uint64_t &bit, const std::uint32_t &value); + void set_abs_max(const std::uint64_t &bit, const std::uint32_t &value); - std::string socket_path() const; + std::string socket_path() const; -private: - int next_id(); - void new_client(std::shared_ptr const &socket); + private: + int next_id(); + void new_client(std::shared_ptr< + boost::asio::local::stream_protocol::socket> const &socket); - // NOTE: If you modify this struct you have to modify the version on - // the Android side too. See frameworks/native/services/inputflinger/EventHub.cpp - struct Info { - char name[80]; - int driver_version; - struct input_id id; - char physical_location[80]; - char unique_id[80]; - std::uint8_t key_bitmask[(KEY_MAX + 1) / 8]; - std::uint8_t abs_bitmask[(ABS_MAX + 1) / 8]; - std::uint8_t rel_bitmask[(REL_MAX + 1) / 8]; - std::uint8_t sw_bitmask[(SW_MAX + 1) / 8]; - std::uint8_t led_bitmask[(LED_MAX + 1) / 8]; - std::uint8_t ff_bitmask[(FF_MAX + 1) / 8]; - std::uint8_t prop_bitmask[(INPUT_PROP_MAX + 1) / 8]; - std::uint32_t abs_max[ABS_CNT]; - std::uint32_t abs_min[ABS_CNT]; - }; + // NOTE: If you modify this struct you have to modify the version on + // the Android side too. See + // frameworks/native/services/inputflinger/EventHub.cpp + struct Info { + char name[80]; + int driver_version; + struct input_id id; + char physical_location[80]; + char unique_id[80]; + std::uint8_t key_bitmask[(KEY_MAX + 1) / 8]; + std::uint8_t abs_bitmask[(ABS_MAX + 1) / 8]; + std::uint8_t rel_bitmask[(REL_MAX + 1) / 8]; + std::uint8_t sw_bitmask[(SW_MAX + 1) / 8]; + std::uint8_t led_bitmask[(LED_MAX + 1) / 8]; + std::uint8_t ff_bitmask[(FF_MAX + 1) / 8]; + std::uint8_t prop_bitmask[(INPUT_PROP_MAX + 1) / 8]; + std::uint32_t abs_max[ABS_CNT]; + std::uint32_t abs_min[ABS_CNT]; + }; - void set_bit(std::uint8_t *array, const std::uint64_t &bit); + void set_bit(std::uint8_t *array, const std::uint64_t &bit); - std::shared_ptr connector_; - std::atomic next_connection_id_; - std::shared_ptr> connections_; - Info info_; + std::shared_ptr connector_; + std::atomic next_connection_id_; + std::shared_ptr> connections_; + Info info_; }; -} // namespace input -} // namespace anbox +} // namespace input +} // namespace anbox #endif diff --git a/src/anbox/input/manager.cpp b/src/anbox/input/manager.cpp index 7d244dc..8ce84f2 100644 --- a/src/anbox/input/manager.cpp +++ b/src/anbox/input/manager.cpp @@ -16,39 +16,38 @@ */ #include "anbox/input/manager.h" +#include "anbox/config.h" #include "anbox/input/device.h" #include "anbox/runtime.h" -#include "anbox/config.h" #include "anbox/utils.h" #include namespace anbox { namespace input { -Manager::Manager(const std::shared_ptr &runtime) : - runtime_(runtime) { - utils::ensure_paths({ config::host_input_device_path() }); +Manager::Manager(const std::shared_ptr &runtime) : runtime_(runtime) { + utils::ensure_paths({config::host_input_device_path()}); } -Manager::~Manager() { -} +Manager::~Manager() {} std::shared_ptr Manager::create_device() { - const auto id = next_id(); - const auto path = build_device_path(id); - auto device = Device::create(path, runtime_); - devices_.insert({id, device}); - return device; + const auto id = next_id(); + const auto path = build_device_path(id); + auto device = Device::create(path, runtime_); + devices_.insert({id, device}); + return device; } std::uint32_t Manager::next_id() { - static std::uint32_t next_id = 0; - return next_id++; + static std::uint32_t next_id = 0; + return next_id++; } std::string Manager::build_device_path(const std::uint32_t &id) { - return (boost::format("%1%/event%2%") % config::host_input_device_path() % id).str(); + return (boost::format("%1%/event%2%") % config::host_input_device_path() % id) + .str(); } -} // namespace input -} // namespace anbox +} // namespace input +} // namespace anbox diff --git a/src/anbox/input/manager.h b/src/anbox/input/manager.h index f3a5c38..774d23d 100644 --- a/src/anbox/input/manager.h +++ b/src/anbox/input/manager.h @@ -18,28 +18,28 @@ #ifndef ANBOX_INPUT_MANAGER_H_ #define ANBOX_INPUT_MANAGER_H_ -#include #include +#include namespace anbox { class Runtime; namespace input { class Device; class Manager { -public: - Manager(const std::shared_ptr &runtime); - ~Manager(); + public: + Manager(const std::shared_ptr &runtime); + ~Manager(); - std::shared_ptr create_device(); + std::shared_ptr create_device(); -private: - std::uint32_t next_id(); - std::string build_device_path(const std::uint32_t &id); + private: + std::uint32_t next_id(); + std::string build_device_path(const std::uint32_t &id); - std::shared_ptr runtime_; - std::map> devices_; + std::shared_ptr runtime_; + std::map> devices_; }; -} // namespace input -} // namespace anbox +} // namespace input +} // namespace anbox #endif diff --git a/src/anbox/logger.cpp b/src/anbox/logger.cpp index 4b83bfe..c2c2aed 100644 --- a/src/anbox/logger.cpp +++ b/src/anbox/logger.cpp @@ -20,9 +20,9 @@ #define BOOST_LOG_DYN_LINK #include #include -#include #include #include +#include #include #include @@ -30,125 +30,139 @@ namespace { namespace attrs { -BOOST_LOG_ATTRIBUTE_KEYWORD(Severity, "anbox::Severity", anbox::Logger::Severity) +BOOST_LOG_ATTRIBUTE_KEYWORD(Severity, "anbox::Severity", + anbox::Logger::Severity) BOOST_LOG_ATTRIBUTE_KEYWORD(Location, "Location", anbox::Logger::Location) BOOST_LOG_ATTRIBUTE_KEYWORD(Timestamp, "Timestamp", boost::posix_time::ptime) } struct BoostLogLogger : public anbox::Logger { - BoostLogLogger() : - initialized_(false) { + BoostLogLogger() : initialized_(false) {} + + void Init(const anbox::Logger::Severity& severity = + anbox::Logger::Severity::kWarning) override { + if (initialized_) return; + + boost::log::formatter formatter = + boost::log::expressions::stream + << "[" << attrs::Severity << " " + << boost::log::expressions::format_date_time( + "Timestamp", "%Y-%m-%d %H:%M:%S") + << "] " + << boost::log::expressions::if_(boost::log::expressions::has_attr( + attrs::Location))[boost::log::expressions::stream + << "[" << attrs::Location << "] "] + << boost::log::expressions::smessage; + + boost::log::core::get()->remove_all_sinks(); + auto logger = boost::log::add_console_log(std::cout); + logger->set_formatter(formatter); + + // FIXME need to enable this once we found how we wrap this + // properly into our service architecture. For now left as + // it is. + boost::ignore_unused_variable_warning(severity); + // logger->set_filter(attrs::Severity < severity); + + initialized_ = true; + } + + void Log(Severity severity, const std::string& message, + const boost::optional& loc) { + if (!initialized_) Init(); + + if (auto rec = boost::log::trivial::logger::get().open_record()) { + boost::log::record_ostream out{rec}; + out << boost::log::add_value(attrs::Severity, severity) + << boost::log::add_value( + attrs::Timestamp, + boost::posix_time::microsec_clock::universal_time()) + << message; + + if (loc) { + // We have to pass in a temporary as boost::log (<= 1.55) expects a + // mutable reference to be passed to boost::log::add_value(...). + auto tmp = *loc; + out << boost::log::add_value(attrs::Location, tmp); + } + + boost::log::trivial::logger::get().push_record(std::move(rec)); } + } - void Init(const anbox::Logger::Severity &severity = anbox::Logger::Severity::kWarning) override { - if (initialized_) - return; - - boost::log::formatter formatter = boost::log::expressions::stream - << "[" << attrs::Severity << " " - << boost::log::expressions::format_date_time< boost::posix_time::ptime >("Timestamp", "%Y-%m-%d %H:%M:%S") - << "] " - << boost::log::expressions::if_(boost::log::expressions::has_attr(attrs::Location)) - [ - boost::log::expressions::stream << "[" << attrs::Location << "] " - ] - << boost::log::expressions::smessage; - - boost::log::core::get()->remove_all_sinks(); - auto logger = boost::log::add_console_log(std::cout); - logger->set_formatter(formatter); - - // FIXME need to enable this once we found how we wrap this - // properly into our service architecture. For now left as - // it is. - boost::ignore_unused_variable_warning(severity); - // logger->set_filter(attrs::Severity < severity); - - initialized_ = true; - } - - void Log(Severity severity, const std::string& message, const boost::optional &loc) { - if (!initialized_) - Init(); - - if (auto rec = boost::log::trivial::logger::get().open_record()) { - boost::log::record_ostream out{rec}; - out << boost::log::add_value(attrs::Severity, severity) - << boost::log::add_value(attrs::Timestamp, boost::posix_time::microsec_clock::universal_time()) - << message; - - if (loc) { - // We have to pass in a temporary as boost::log (<= 1.55) expects a - // mutable reference to be passed to boost::log::add_value(...). - auto tmp = *loc; - out << boost::log::add_value(attrs::Location, tmp); - } - - boost::log::trivial::logger::get().push_record(std::move(rec)); - } - } - -private: - bool initialized_; + private: + bool initialized_; }; std::shared_ptr& MutableInstance() { - static std::shared_ptr instance{new BoostLogLogger()}; - return instance; + static std::shared_ptr instance{new BoostLogLogger()}; + return instance; } void SetInstance(const std::shared_ptr& logger) { - MutableInstance() = logger; + MutableInstance() = logger; } } namespace anbox { -void Logger::Trace(const std::string& message, const boost::optional& location) { - Log(Severity::kTrace, message, location); +void Logger::Trace(const std::string& message, + const boost::optional& location) { + Log(Severity::kTrace, message, location); } -void Logger::Debug(const std::string& message, const boost::optional& location) { - Log(Severity::kDebug, message, location); +void Logger::Debug(const std::string& message, + const boost::optional& location) { + Log(Severity::kDebug, message, location); } -void Logger::Info(const std::string& message, const boost::optional& location) { - Log(Severity::kInfo, message, location); +void Logger::Info(const std::string& message, + const boost::optional& location) { + Log(Severity::kInfo, message, location); } -void Logger::Warning(const std::string& message, const boost::optional& location) { - Log(Severity::kWarning, message, location); +void Logger::Warning(const std::string& message, + const boost::optional& location) { + Log(Severity::kWarning, message, location); } -void Logger::Error(const std::string& message, const boost::optional& location) { - Log(Severity::kError, message, location); +void Logger::Error(const std::string& message, + const boost::optional& location) { + Log(Severity::kError, message, location); } -void Logger::Fatal(const std::string& message, const boost::optional& location) { - Log(Severity::kFatal, message, location); +void Logger::Fatal(const std::string& message, + const boost::optional& location) { + Log(Severity::kFatal, message, location); } std::ostream& operator<<(std::ostream& strm, anbox::Logger::Severity severity) { - switch (severity) { - case anbox::Logger::Severity::kTrace: return strm << "TT"; - case anbox::Logger::Severity::kDebug: return strm << "DD"; - case anbox::Logger::Severity::kInfo: return strm << "II"; - case anbox::Logger::Severity::kWarning: return strm << "WW"; - case anbox::Logger::Severity::kError: return strm << "EE"; - case anbox::Logger::Severity::kFatal: return strm << "FF"; - default: return strm << static_cast(severity); - } + switch (severity) { + case anbox::Logger::Severity::kTrace: + return strm << "TT"; + case anbox::Logger::Severity::kDebug: + return strm << "DD"; + case anbox::Logger::Severity::kInfo: + return strm << "II"; + case anbox::Logger::Severity::kWarning: + return strm << "WW"; + case anbox::Logger::Severity::kError: + return strm << "EE"; + case anbox::Logger::Severity::kFatal: + return strm << "FF"; + default: + return strm << static_cast(severity); + } } -std::ostream& operator<<(std::ostream& out, const Logger::Location &location) { - return out << utils::string_format("%s:%d@%s", boost::filesystem::path(location.file).filename().string(), location.line, location.function); +std::ostream& operator<<(std::ostream& out, const Logger::Location& location) { + return out << utils::string_format( + "%s:%d@%s", + boost::filesystem::path(location.file).filename().string(), + location.line, location.function); } -Logger& Log() { - return *MutableInstance(); -} +Logger& Log() { return *MutableInstance(); } -void SetLogger(const std::shared_ptr& logger) { - SetInstance(logger); -} +void SetLogger(const std::shared_ptr& logger) { SetInstance(logger); } -} // namespace anbox +} // namespace anbox diff --git a/src/anbox/logger.h b/src/anbox/logger.h index 3604e8e..696a10c 100644 --- a/src/anbox/logger.h +++ b/src/anbox/logger.h @@ -20,8 +20,8 @@ #include -#include #include +#include #include "anbox/do_not_copy_or_move.h" #include "anbox/utils.h" @@ -30,76 +30,87 @@ namespace anbox { // A Logger enables persisting of messages describing & explaining the // state of the system. class Logger : public DoNotCopyOrMove { -public: - // Severity enumerates all known severity levels - // applicable to log messages. - enum class Severity { - kTrace, - kDebug, - kInfo, - kWarning, - kError, - kFatal - }; + public: + // Severity enumerates all known severity levels + // applicable to log messages. + enum class Severity { kTrace, kDebug, kInfo, kWarning, kError, kFatal }; - // A Location describes the origin of a log message. - struct Location { - std::string file; // The name of the file that contains the log message. - std::string function; // The function that contains the log message. - std::uint32_t line; // The line in file that resulted in the log message. - }; + // A Location describes the origin of a log message. + struct Location { + std::string file; // The name of the file that contains the log message. + std::string function; // The function that contains the log message. + std::uint32_t line; // The line in file that resulted in the log message. + }; - virtual void Init(const Severity &severity = Severity::kWarning) = 0; + virtual void Init(const Severity& severity = Severity::kWarning) = 0; - virtual void Log(Severity severity, const std::string &message, const boost::optional& location) = 0; + virtual void Log(Severity severity, const std::string& message, + const boost::optional& location) = 0; - virtual void Trace(const std::string& message, const boost::optional& location = boost::optional{}); - virtual void Debug(const std::string& message, const boost::optional& location = boost::optional{}); - virtual void Info(const std::string& message, const boost::optional& location = boost::optional{}); - virtual void Warning(const std::string& message, const boost::optional& location = boost::optional{}); - virtual void Error(const std::string& message, const boost::optional& location = boost::optional{}); - virtual void Fatal(const std::string& message, const boost::optional& location = boost::optional{}); + virtual void Trace( + const std::string& message, + const boost::optional& location = boost::optional{}); + virtual void Debug( + const std::string& message, + const boost::optional& location = boost::optional{}); + virtual void Info( + const std::string& message, + const boost::optional& location = boost::optional{}); + virtual void Warning( + const std::string& message, + const boost::optional& location = boost::optional{}); + virtual void Error( + const std::string& message, + const boost::optional& location = boost::optional{}); + virtual void Fatal( + const std::string& message, + const boost::optional& location = boost::optional{}); + template + void Tracef(const boost::optional& location, + const std::string& pattern, T&&... args) { + Trace(utils::string_format(pattern, std::forward(args)...), location); + } - template - void Tracef(const boost::optional& location, const std::string& pattern, T&&...args) { - Trace(utils::string_format(pattern, std::forward(args)...), location); - } + template + void Debugf(const boost::optional& location, + const std::string& pattern, T&&... args) { + Debug(utils::string_format(pattern, std::forward(args)...), location); + } - template - void Debugf(const boost::optional& location, const std::string& pattern, T&&...args) { - Debug(utils::string_format(pattern, std::forward(args)...), location); - } + template + void Infof(const boost::optional& location, + const std::string& pattern, T&&... args) { + Info(utils::string_format(pattern, std::forward(args)...), location); + } - template - void Infof(const boost::optional& location, const std::string& pattern, T&&...args) { - Info(utils::string_format(pattern, std::forward(args)...), location); - } + template + void Warningf(const boost::optional& location, + const std::string& pattern, T&&... args) { + Warning(utils::string_format(pattern, std::forward(args)...), location); + } - template - void Warningf(const boost::optional& location, const std::string& pattern, T&&...args) { - Warning(utils::string_format(pattern, std::forward(args)...), location); - } + template + void Errorf(const boost::optional& location, + const std::string& pattern, T&&... args) { + Error(utils::string_format(pattern, std::forward(args)...), location); + } - template - void Errorf(const boost::optional& location, const std::string& pattern, T&&...args) { - Error(utils::string_format(pattern, std::forward(args)...), location); - } + template + void Fatalf(const boost::optional& location, + const std::string& pattern, T&&... args) { + Fatal(utils::string_format(pattern, std::forward(args)...), location); + } - template - void Fatalf(const boost::optional& location, const std::string& pattern, T&&...args) { - Fatal(utils::string_format(pattern, std::forward(args)...), location); - } - -protected: - Logger() = default; + protected: + Logger() = default; }; // operator<< inserts severity into out. std::ostream& operator<<(std::ostream& out, Logger::Severity severity); // operator<< inserts location into out. -std::ostream& operator<<(std::ostream& out, const Logger::Location &location); +std::ostream& operator<<(std::ostream& out, const Logger::Location& location); // Log returns the mcs-wide configured logger instance. // Save to call before/after main. @@ -108,11 +119,23 @@ Logger& Log(); void SetLogger(const std::shared_ptr& logger); } -#define TRACE(...) anbox::Log().Tracef(anbox::Logger::Location{__FILE__, __FUNCTION__, __LINE__}, __VA_ARGS__) -#define DEBUG(...) anbox::Log().Debugf(anbox::Logger::Location{__FILE__, __FUNCTION__, __LINE__}, __VA_ARGS__) -#define INFO(...) anbox::Log().Infof(anbox::Logger::Location{__FILE__, __FUNCTION__, __LINE__}, __VA_ARGS__) -#define WARNING(...) anbox::Log().Warningf(anbox::Logger::Location{__FILE__, __FUNCTION__, __LINE__}, __VA_ARGS__) -#define ERROR(...) anbox::Log().Errorf(anbox::Logger::Location{__FILE__, __FUNCTION__, __LINE__}, __VA_ARGS__) -#define FATAL(...) anbox::Log().Fatalf(anbox::Logger::Location{__FILE__, __FUNCTION__, __LINE__}, __VA_ARGS__) +#define TRACE(...) \ + anbox::Log().Tracef( \ + anbox::Logger::Location{__FILE__, __FUNCTION__, __LINE__}, __VA_ARGS__) +#define DEBUG(...) \ + anbox::Log().Debugf( \ + anbox::Logger::Location{__FILE__, __FUNCTION__, __LINE__}, __VA_ARGS__) +#define INFO(...) \ + anbox::Log().Infof( \ + anbox::Logger::Location{__FILE__, __FUNCTION__, __LINE__}, __VA_ARGS__) +#define WARNING(...) \ + anbox::Log().Warningf( \ + anbox::Logger::Location{__FILE__, __FUNCTION__, __LINE__}, __VA_ARGS__) +#define ERROR(...) \ + anbox::Log().Errorf( \ + anbox::Logger::Location{__FILE__, __FUNCTION__, __LINE__}, __VA_ARGS__) +#define FATAL(...) \ + anbox::Log().Fatalf( \ + anbox::Logger::Location{__FILE__, __FUNCTION__, __LINE__}, __VA_ARGS__) #endif diff --git a/src/anbox/network/base_socket_messenger.cpp b/src/anbox/network/base_socket_messenger.cpp index 1cce830..2c5b06f 100644 --- a/src/anbox/network/base_socket_messenger.cpp +++ b/src/anbox/network/base_socket_messenger.cpp @@ -37,123 +37,110 @@ unsigned int const serialization_buffer_size = 2048; namespace anbox { namespace network { -template -BaseSocketMessenger::BaseSocketMessenger() { +template +BaseSocketMessenger::BaseSocketMessenger() {} + +template +BaseSocketMessenger::BaseSocketMessenger( + std::shared_ptr> const& socket) { + setup(socket); } -template -BaseSocketMessenger::BaseSocketMessenger(std::shared_ptr> const& socket) -{ - setup(socket); +template +BaseSocketMessenger::~BaseSocketMessenger() {} + +template +void BaseSocketMessenger::setup( + std::shared_ptr> const& s) { + socket = s; + socket_fd = anbox::Fd{IntOwnedFd{socket->native_handle()}}; + socket->non_blocking(true); + boost::asio::socket_base::send_buffer_size option(64 * 1024); + socket->set_option(option); } -template -BaseSocketMessenger::~BaseSocketMessenger() -{ -} - -template -void BaseSocketMessenger::setup(std::shared_ptr> const& s) { - socket = s; - socket_fd = anbox::Fd{IntOwnedFd{socket->native_handle()}}; - socket->non_blocking(true); - boost::asio::socket_base::send_buffer_size option(64*1024); - socket->set_option(option); -} - -template +template Credentials BaseSocketMessenger::creds() const { - struct ucred cr; - socklen_t cl = sizeof(cr); + struct ucred cr; + socklen_t cl = sizeof(cr); - auto status = getsockopt(socket_fd, SOL_SOCKET, SO_PEERCRED, &cr, &cl); + auto status = getsockopt(socket_fd, SOL_SOCKET, SO_PEERCRED, &cr, &cl); - if (status) - BOOST_THROW_EXCEPTION(std::runtime_error("Failed to query client socket credentials")); + if (status) + BOOST_THROW_EXCEPTION( + std::runtime_error("Failed to query client socket credentials")); - return {cr.pid, cr.uid, cr.gid}; + return {cr.pid, cr.uid, cr.gid}; } -template -void BaseSocketMessenger::send(char const* data, size_t length) -{ - VariableLengthArray whole_message{length}; - std::copy(data, data + length, whole_message.data()); +template +void BaseSocketMessenger::send(char const* data, + size_t length) { + VariableLengthArray whole_message{length}; + std::copy(data, data + length, whole_message.data()); - for (;;) { - try { - std::unique_lock lg(message_lock); - ba::write(*socket, - ba::buffer(whole_message.data(), whole_message.size()), - boost::asio::transfer_all()); - } - catch (const boost::system::system_error &err) { - if (err.code() == boost::asio::error::try_again) - continue; - } - break; + for (;;) { + try { + std::unique_lock lg(message_lock); + ba::write(*socket, ba::buffer(whole_message.data(), whole_message.size()), + boost::asio::transfer_all()); + } catch (const boost::system::system_error& err) { + if (err.code() == boost::asio::error::try_again) continue; } + break; + } } -template +template void BaseSocketMessenger::async_receive_msg( - AnboxReadHandler const& handler, - ba::mutable_buffers_1 const& buffer) -{ - socket->async_read_some(buffer, handler); + AnboxReadHandler const& handler, ba::mutable_buffers_1 const& buffer) { + socket->async_read_some(buffer, handler); } -template +template bs::error_code BaseSocketMessenger::receive_msg( - ba::mutable_buffers_1 const& buffer) -{ - bs::error_code e; - size_t nread = 0; + ba::mutable_buffers_1 const& buffer) { + bs::error_code e; + size_t nread = 0; - while (nread < ba::buffer_size(buffer)) - { - nread += boost::asio::read( - *socket, - ba::mutable_buffers_1{buffer + nread}, - e); + while (nread < ba::buffer_size(buffer)) { + nread += + boost::asio::read(*socket, ba::mutable_buffers_1{buffer + nread}, e); - if (e && e != ba::error::would_block) - break; - } + if (e && e != ba::error::would_block) break; + } - return e; + return e; } -template -size_t BaseSocketMessenger::available_bytes() -{ - boost::asio::socket_base::bytes_readable command{true}; - socket->io_control(command); - return command.get(); +template +size_t BaseSocketMessenger::available_bytes() { + boost::asio::socket_base::bytes_readable command{true}; + socket->io_control(command); + return command.get(); } -template +template unsigned short BaseSocketMessenger::local_port() const { - return 0; + return 0; } -template +template void BaseSocketMessenger::set_no_delay() { - const auto fd = socket->native(); - int flag = 1; - const auto ret = ::setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, - reinterpret_cast(&flag), - sizeof(flag)); - if (ret < 0) - WARNING("Failed to disable TCP delay for socket"); + const auto fd = socket->native(); + int flag = 1; + const auto ret = + ::setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, + reinterpret_cast(&flag), sizeof(flag)); + if (ret < 0) WARNING("Failed to disable TCP delay for socket"); } -template +template void BaseSocketMessenger::close() { - socket->close(); + socket->close(); } template class BaseSocketMessenger; template class BaseSocketMessenger; -} // namespace network -} // namespace anbox +} // namespace network +} // namespace anbox diff --git a/src/anbox/network/base_socket_messenger.h b/src/anbox/network/base_socket_messenger.h index c28f037..aa0dde4 100644 --- a/src/anbox/network/base_socket_messenger.h +++ b/src/anbox/network/base_socket_messenger.h @@ -19,41 +19,46 @@ #ifndef ANBOX_NETWORK_BASE_SOCKET_MESSENGER_H_ #define ANBOX_NETWORK_BASE_SOCKET_MESSENGER_H_ -#include "anbox/network/socket_messenger.h" #include "anbox/common/fd_sets.h" +#include "anbox/network/socket_messenger.h" -#include #include +#include namespace anbox { namespace network { -template +template class BaseSocketMessenger : public SocketMessenger { -public: - BaseSocketMessenger(std::shared_ptr> const& socket); - virtual ~BaseSocketMessenger(); + public: + BaseSocketMessenger( + std::shared_ptr> const& + socket); + virtual ~BaseSocketMessenger(); - Credentials creds() const override; - unsigned short local_port() const override; + Credentials creds() const override; + unsigned short local_port() const override; - void send(char const* data, size_t length) override; - void async_receive_msg(AnboxReadHandler const& handle, boost::asio::mutable_buffers_1 const &buffer) override; - boost::system::error_code receive_msg(boost::asio::mutable_buffers_1 const& buffer) override; - size_t available_bytes() override; + void send(char const* data, size_t length) override; + void async_receive_msg(AnboxReadHandler const& handle, + boost::asio::mutable_buffers_1 const& buffer) override; + boost::system::error_code receive_msg( + boost::asio::mutable_buffers_1 const& buffer) override; + size_t available_bytes() override; - void set_no_delay() override; - void close() override; + void set_no_delay() override; + void close() override; -protected: - BaseSocketMessenger(); - void setup(std::shared_ptr> const& s); + protected: + BaseSocketMessenger(); + void setup(std::shared_ptr< + boost::asio::basic_stream_socket> const& s); -private: - std::shared_ptr> socket; - anbox::Fd socket_fd; - std::mutex message_lock; + private: + std::shared_ptr> socket; + anbox::Fd socket_fd; + std::mutex message_lock; }; -} // namespace network -} // namespace anbox +} // namespace network +} // namespace anbox #endif diff --git a/src/anbox/network/connection_context.cpp b/src/anbox/network/connection_context.cpp index b9b74f8..3327e3a 100644 --- a/src/anbox/network/connection_context.cpp +++ b/src/anbox/network/connection_context.cpp @@ -21,11 +21,8 @@ namespace anbox { namespace network { ConnectionContext::ConnectionContext( - std::function const connect_handler, - Connector const* connector) : - connect_handler(connect_handler), - connector(connector) { -} + std::function const connect_handler, Connector const* connector) + : connect_handler(connect_handler), connector(connector) {} -} // namespace anbox -} // namespace network +} // namespace anbox +} // namespace network diff --git a/src/anbox/network/connection_context.h b/src/anbox/network/connection_context.h index 40413bf..92fa638 100644 --- a/src/anbox/network/connection_context.h +++ b/src/anbox/network/connection_context.h @@ -26,23 +26,21 @@ namespace anbox { namespace network { class Connector; -class ConnectionContext -{ -public: - ConnectionContext(Connector const* connector) : - ConnectionContext([](){}, connector) {} - ConnectionContext( - std::function const connect_handler, - Connector const* connector); +class ConnectionContext { + public: + ConnectionContext(Connector const* connector) + : ConnectionContext([]() {}, connector) {} + ConnectionContext(std::function const connect_handler, + Connector const* connector); - int fd_for_new_client(std::function const& connect_handler) const; - void handle_client_connect() const { connect_handler(); } + int fd_for_new_client(std::function const& connect_handler) const; + void handle_client_connect() const { connect_handler(); } -private: - std::function const connect_handler; - Connector const* const connector; + private: + std::function const connect_handler; + Connector const* const connector; }; -} // namespace anbox -} // namespace network +} // namespace anbox +} // namespace network #endif diff --git a/src/anbox/network/connection_creator.h b/src/anbox/network/connection_creator.h index dbe0446..7badfaf 100644 --- a/src/anbox/network/connection_creator.h +++ b/src/anbox/network/connection_creator.h @@ -25,12 +25,13 @@ #include "anbox/do_not_copy_or_move.h" namespace anbox { namespace network { -template +template class ConnectionCreator : public DoNotCopyOrMove { -public: - virtual void create_connection_for( - std::shared_ptr> const& socket) = 0; + public: + virtual void create_connection_for( + std::shared_ptr> const& + socket) = 0; }; -} // namespace anbox -} // namespace network +} // namespace anbox +} // namespace network #endif diff --git a/src/anbox/network/connections.h b/src/anbox/network/connections.h index 6780110..f206a91 100644 --- a/src/anbox/network/connections.h +++ b/src/anbox/network/connections.h @@ -19,65 +19,50 @@ #ifndef ANBOX_NETWORK_CONNECTIONS_H_ #define ANBOX_NETWORK_CONNECTIONS_H_ +#include #include #include -#include namespace anbox { namespace network { -template -class Connections -{ -public: - Connections() {} - ~Connections() { - clear(); - } +template +class Connections { + public: + Connections() {} + ~Connections() { clear(); } + void add(std::shared_ptr const& connection) { + std::unique_lock lock(mutex); + connections.insert({connection->id(), connection}); + } - void add(std::shared_ptr const& connection) - { - std::unique_lock lock(mutex); - connections.insert({connection->id(), connection}); - } + void remove(int id) { + std::unique_lock lock(mutex); + connections.erase(id); + } - void remove(int id) - { - std::unique_lock lock(mutex); - connections.erase(id); - } + bool includes(int id) const { + std::unique_lock lock(mutex); + return connections.find(id) != connections.end(); + } - bool includes(int id) const - { - std::unique_lock lock(mutex); - return connections.find(id) != connections.end(); - } + void clear() { + std::unique_lock lock(mutex); + connections.clear(); + } - void clear() - { - std::unique_lock lock(mutex); - connections.clear(); - } + size_t size() { return connections.size(); } - size_t size() - { - return connections.size(); - } + std::shared_ptr at(size_t n) { return connections.at(n); } - std::shared_ptr at(size_t n) - { - return connections.at(n); - } + private: + Connections(Connections const&) = delete; + Connections& operator=(Connections const&) = delete; -private: - Connections(Connections const&) = delete; - Connections& operator =(Connections const&) = delete; - - std::mutex mutex; - std::map> connections; + std::mutex mutex; + std::map> connections; }; -} // namespace anbox -} // namespace network - +} // namespace anbox +} // namespace network #endif diff --git a/src/anbox/network/connector.h b/src/anbox/network/connector.h index e624f49..77450ab 100644 --- a/src/anbox/network/connector.h +++ b/src/anbox/network/connector.h @@ -21,9 +21,9 @@ namespace anbox { namespace network { class Connector { -public: + public: }; -} // namespace network -} // namespace anbox +} // namespace network +} // namespace anbox #endif diff --git a/src/anbox/network/credentials.cpp b/src/anbox/network/credentials.cpp index 91a943b..f418fb9 100644 --- a/src/anbox/network/credentials.cpp +++ b/src/anbox/network/credentials.cpp @@ -19,22 +19,13 @@ namespace anbox { namespace network { -Credentials::Credentials(pid_t pid, uid_t uid, gid_t gid) : - pid_{pid}, - uid_{uid}, - gid_{gid} { -} +Credentials::Credentials(pid_t pid, uid_t uid, gid_t gid) + : pid_{pid}, uid_{uid}, gid_{gid} {} -pid_t Credentials::pid() const { - return pid_; -} +pid_t Credentials::pid() const { return pid_; } -uid_t Credentials::uid() const { - return uid_; -} +uid_t Credentials::uid() const { return uid_; } -gid_t Credentials::gid() const { - return gid_; -} -} // namespace network -} // namespace anbox +gid_t Credentials::gid() const { return gid_; } +} // namespace network +} // namespace anbox diff --git a/src/anbox/network/credentials.h b/src/anbox/network/credentials.h index f97abd7..40edbcf 100644 --- a/src/anbox/network/credentials.h +++ b/src/anbox/network/credentials.h @@ -23,21 +23,21 @@ namespace anbox { namespace network { class Credentials { -public: - Credentials(pid_t pid, uid_t uid, gid_t gid); + public: + Credentials(pid_t pid, uid_t uid, gid_t gid); - pid_t pid() const; - uid_t uid() const; - gid_t gid() const; + pid_t pid() const; + uid_t uid() const; + gid_t gid() const; -private: - Credentials() = delete; + private: + Credentials() = delete; - pid_t pid_; - uid_t uid_; - gid_t gid_; + pid_t pid_; + uid_t uid_; + gid_t gid_; }; -} // namespace network -} // namespace anbox +} // namespace network +} // namespace anbox #endif diff --git a/src/anbox/network/delegate_connection_creator.h b/src/anbox/network/delegate_connection_creator.h index 4e71367..3692c0d 100644 --- a/src/anbox/network/delegate_connection_creator.h +++ b/src/anbox/network/delegate_connection_creator.h @@ -18,31 +18,37 @@ #ifndef ANBOX_NETWORK_DELEGATE_CONNECTION_CREATOR_H_ #define ANBOX_NETWORK_DELEGATE_CONNECTION_CREATOR_H_ -#include "anbox/network/connection_creator.h" #include +#include "anbox/network/connection_creator.h" #include namespace anbox { namespace network { -template +template class DelegateConnectionCreator : public ConnectionCreator { -public: - DelegateConnectionCreator(std::function> const&)> delegate) : - delegate_(delegate) { - } + public: + DelegateConnectionCreator( + std::function> const&)> + delegate) + : delegate_(delegate) {} - void create_connection_for( - std::shared_ptr> const& socket) override { - if (delegate_) - delegate_(socket); - else - socket->close(); - } -private: - std::function> const&)> delegate_; + void create_connection_for( + std::shared_ptr> const& + socket) override { + if (delegate_) + delegate_(socket); + else + socket->close(); + } + + private: + std::function> const&)> + delegate_; }; -} // namespace network -} // namespace anbox +} // namespace network +} // namespace anbox #endif diff --git a/src/anbox/network/delegate_message_processor.cpp b/src/anbox/network/delegate_message_processor.cpp index 7c830cf..c6997ce 100644 --- a/src/anbox/network/delegate_message_processor.cpp +++ b/src/anbox/network/delegate_message_processor.cpp @@ -19,18 +19,17 @@ namespace anbox { namespace network { -DelegateMessageProcessor::DelegateMessageProcessor(std::function&)> process_data) : - process_data_(process_data) { -} +DelegateMessageProcessor::DelegateMessageProcessor( + std::function &)> process_data) + : process_data_(process_data) {} -DelegateMessageProcessor::~DelegateMessageProcessor() { -} +DelegateMessageProcessor::~DelegateMessageProcessor() {} -bool DelegateMessageProcessor::process_data(const std::vector &data) { - if (!process_data_) - return false; +bool DelegateMessageProcessor::process_data( + const std::vector &data) { + if (!process_data_) return false; - return process_data_(data); + return process_data_(data); } -} // namespace network -} // namespace anbox +} // namespace network +} // namespace anbox diff --git a/src/anbox/network/delegate_message_processor.h b/src/anbox/network/delegate_message_processor.h index bae9612..a009838 100644 --- a/src/anbox/network/delegate_message_processor.h +++ b/src/anbox/network/delegate_message_processor.h @@ -25,16 +25,17 @@ namespace anbox { namespace network { class DelegateMessageProcessor : public MessageProcessor { -public: - DelegateMessageProcessor(std::function&)> process_data); - ~DelegateMessageProcessor(); + public: + DelegateMessageProcessor( + std::function &)> process_data); + ~DelegateMessageProcessor(); - bool process_data(const std::vector &data) override; + bool process_data(const std::vector &data) override; -private: - std::function&)> process_data_; + private: + std::function &)> process_data_; }; -} // namespace network -} // namespace anbox +} // namespace network +} // namespace anbox #endif diff --git a/src/anbox/network/fd_socket_transmission.cpp b/src/anbox/network/fd_socket_transmission.cpp index 656ff76..ea74c83 100644 --- a/src/anbox/network/fd_socket_transmission.cpp +++ b/src/anbox/network/fd_socket_transmission.cpp @@ -19,174 +19,163 @@ #include "anbox/network/fd_socket_transmission.h" #include "anbox/common/variable_length_array.h" -#include -#include #include -#include +#include +#include #include +#include #include namespace anbox { -socket_error::socket_error(std::string const& message) : - std::system_error(errno, std::system_category(), message) -{ +socket_error::socket_error(std::string const& message) + : std::system_error(errno, std::system_category(), message) {} + +socket_disconnected_error::socket_disconnected_error(std::string const& message) + : std::system_error(errno, std::system_category(), message) {} + +fd_reception_error::fd_reception_error(std::string const& message) + : std::runtime_error(message) {} + +void send_fds(Fd const& socket, std::vector const& fds) { + if (fds.size() > 0) { + // We send dummy data + struct iovec iov; + char dummy_iov_data = 'M'; + iov.iov_base = &dummy_iov_data; + iov.iov_len = 1; + + // Allocate space for control message + static auto const builtin_n_fds = 5; + static auto const builtin_cmsg_space = + CMSG_SPACE(builtin_n_fds * sizeof(int)); + auto const fds_bytes = fds.size() * sizeof(int); + VariableLengthArray control{CMSG_SPACE(fds_bytes)}; + // Silence valgrind uninitialized memory complaint + memset(control.data(), 0, control.size()); + + // Message to send + struct msghdr header; + header.msg_name = NULL; + header.msg_namelen = 0; + header.msg_iov = &iov; + header.msg_iovlen = 1; + header.msg_controllen = control.size(); + header.msg_control = control.data(); + header.msg_flags = 0; + + // Control message contains file descriptors + struct cmsghdr* message = CMSG_FIRSTHDR(&header); + message->cmsg_len = CMSG_LEN(fds_bytes); + message->cmsg_level = SOL_SOCKET; + message->cmsg_type = SCM_RIGHTS; + + int* const data = reinterpret_cast(CMSG_DATA(message)); + int i = 0; + for (auto& fd : fds) data[i++] = fd; + + auto const sent = sendmsg(socket, &header, MSG_NOSIGNAL); + if (sent < 0) + BOOST_THROW_EXCEPTION(std::runtime_error("Failed to send fds: " + + std::string(strerror(errno)))); + } } -socket_disconnected_error::socket_disconnected_error(std::string const& message) : - std::system_error(errno, std::system_category(), message) -{ -} +bool socket_error_is_transient(int error_code) { return (error_code == EINTR); } -fd_reception_error::fd_reception_error(std::string const& message) : - std::runtime_error(message) -{ -} +void receive_data(Fd const& socket, void* buffer, size_t bytes_requested, + std::vector& fds) { + if (bytes_requested == 0) + BOOST_THROW_EXCEPTION(std::logic_error("Attempted to receive 0 bytes")); -void send_fds( - Fd const& socket, - std::vector const& fds) -{ - if (fds.size() > 0) - { - // We send dummy data - struct iovec iov; - char dummy_iov_data = 'M'; - iov.iov_base = &dummy_iov_data; - iov.iov_len = 1; + size_t bytes_read{0}; + unsigned fds_read{0}; + while (bytes_read < bytes_requested) { + // Store the data in the buffer requested + struct iovec iov; + iov.iov_base = static_cast(buffer) + bytes_read; + iov.iov_len = bytes_requested - bytes_read; - // Allocate space for control message - static auto const builtin_n_fds = 5; - static auto const builtin_cmsg_space = CMSG_SPACE(builtin_n_fds * sizeof(int)); - auto const fds_bytes = fds.size() * sizeof(int); - VariableLengthArray control{CMSG_SPACE(fds_bytes)}; - // Silence valgrind uninitialized memory complaint - memset(control.data(), 0, control.size()); + // Allocate space for control message + static auto const builtin_n_fds = 5; + static auto const builtin_cmsg_space = + CMSG_SPACE(builtin_n_fds * sizeof(int)); + auto const fds_bytes = (fds.size() - fds_read) * sizeof(int); + VariableLengthArray control{CMSG_SPACE(fds_bytes)}; - // Message to send - struct msghdr header; - header.msg_name = NULL; - header.msg_namelen = 0; - header.msg_iov = &iov; - header.msg_iovlen = 1; - header.msg_controllen = control.size(); - header.msg_control = control.data(); - header.msg_flags = 0; + // Message to read + struct msghdr header; + header.msg_name = NULL; + header.msg_namelen = 0; + header.msg_iov = &iov; + header.msg_iovlen = 1; + header.msg_controllen = control.size(); + header.msg_control = control.data(); + header.msg_flags = 0; - // Control message contains file descriptors - struct cmsghdr *message = CMSG_FIRSTHDR(&header); - message->cmsg_len = CMSG_LEN(fds_bytes); - message->cmsg_level = SOL_SOCKET; - message->cmsg_type = SCM_RIGHTS; + ssize_t const result = recvmsg(socket, &header, MSG_NOSIGNAL | MSG_WAITALL); + if (result == 0) + BOOST_THROW_EXCEPTION(socket_disconnected_error( + "Failed to read message from server: server has shutdown")); + if (result < 0) { + if (socket_error_is_transient(errno)) continue; + if (errno == EAGAIN) continue; + if (errno == EPIPE) + BOOST_THROW_EXCEPTION( + boost::enable_error_info( + socket_disconnected_error("Failed to read message from server")) + << boost::errinfo_errno(errno)); - int* const data = reinterpret_cast(CMSG_DATA(message)); - int i = 0; - for (auto& fd : fds) - data[i++] = fd; - - auto const sent = sendmsg(socket, &header, MSG_NOSIGNAL); - if (sent < 0) - BOOST_THROW_EXCEPTION(std::runtime_error("Failed to send fds: " + std::string(strerror(errno)))); - } -} - -bool socket_error_is_transient(int error_code) -{ - return (error_code == EINTR); -} - -void receive_data(Fd const& socket, void* buffer, size_t bytes_requested, std::vector& fds) -{ - if (bytes_requested == 0) - BOOST_THROW_EXCEPTION(std::logic_error("Attempted to receive 0 bytes")); - - size_t bytes_read{0}; - unsigned fds_read{0}; - while (bytes_read < bytes_requested) - { - // Store the data in the buffer requested - struct iovec iov; - iov.iov_base = static_cast(buffer) + bytes_read; - iov.iov_len = bytes_requested - bytes_read; - - // Allocate space for control message - static auto const builtin_n_fds = 5; - static auto const builtin_cmsg_space = CMSG_SPACE(builtin_n_fds * sizeof(int)); - auto const fds_bytes = (fds.size() - fds_read) * sizeof(int); - VariableLengthArray control{CMSG_SPACE(fds_bytes)}; - - // Message to read - struct msghdr header; - header.msg_name = NULL; - header.msg_namelen = 0; - header.msg_iov = &iov; - header.msg_iovlen = 1; - header.msg_controllen = control.size(); - header.msg_control = control.data(); - header.msg_flags = 0; - - ssize_t const result = recvmsg(socket, &header, MSG_NOSIGNAL | MSG_WAITALL); - if (result == 0) - BOOST_THROW_EXCEPTION(socket_disconnected_error("Failed to read message from server: server has shutdown")); - if (result < 0) - { - if (socket_error_is_transient(errno)) - continue; - if (errno == EAGAIN) - continue; - if (errno == EPIPE) - BOOST_THROW_EXCEPTION( - boost::enable_error_info(socket_disconnected_error("Failed to read message from server")) - << boost::errinfo_errno(errno)); - - BOOST_THROW_EXCEPTION( - boost::enable_error_info(socket_error("Failed to read message from server")) - << boost::errinfo_errno(errno)); - } - - bytes_read += result; - - // If we get a proper control message, copy the received - // file descriptors back to the caller - struct cmsghdr const* const cmsg = CMSG_FIRSTHDR(&header); - if (cmsg) - { - if ((cmsg->cmsg_level == SOL_SOCKET) && (cmsg->cmsg_type == SCM_CREDENTIALS)) - BOOST_THROW_EXCEPTION(fd_reception_error("received SCM_CREDENTIALS when expecting fd")); - if (cmsg->cmsg_level != SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) - BOOST_THROW_EXCEPTION(fd_reception_error("Invalid control message for receiving file descriptors")); - - int const* const data = reinterpret_castCMSG_DATA(cmsg); - ptrdiff_t const header_size = reinterpret_cast(data) - reinterpret_cast(cmsg); - int const nfds = (cmsg->cmsg_len - header_size) / sizeof(int); - - // NOTE: This relies on the file descriptor cmsg being read - // (and written) atomically. - if (cmsg->cmsg_len > CMSG_LEN(fds_bytes) || (header.msg_flags & MSG_CTRUNC)) - { - for (int i = 0; i < nfds; i++) - ::close(data[i]); - BOOST_THROW_EXCEPTION(std::runtime_error("Received more fds than expected")); - } - - // We can't properly pass Fds through google::protobuf::Message, - // which is where these get shoved. - // - // When we have our own RPC generator plugin and aren't using deprecated - // Protobuf features this can go away. - for (int i = 0; i < nfds; i++) - fds[fds_read + i] = Fd{IntOwnedFd{data[i]}}; - - fds_read += nfds; - } + BOOST_THROW_EXCEPTION(boost::enable_error_info(socket_error( + "Failed to read message from server")) + << boost::errinfo_errno(errno)); } - if (fds_read < fds.size()) - { - for (auto fd : fds) - if (fd >= 0) - ::close(fd); - fds.clear(); - BOOST_THROW_EXCEPTION(std::runtime_error("Received fewer fds than expected")); + bytes_read += result; + + // If we get a proper control message, copy the received + // file descriptors back to the caller + struct cmsghdr const* const cmsg = CMSG_FIRSTHDR(&header); + if (cmsg) { + if ((cmsg->cmsg_level == SOL_SOCKET) && + (cmsg->cmsg_type == SCM_CREDENTIALS)) + BOOST_THROW_EXCEPTION( + fd_reception_error("received SCM_CREDENTIALS when expecting fd")); + if (cmsg->cmsg_level != SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) + BOOST_THROW_EXCEPTION(fd_reception_error( + "Invalid control message for receiving file descriptors")); + + int const* const data = reinterpret_cast CMSG_DATA(cmsg); + ptrdiff_t const header_size = reinterpret_cast(data) - + reinterpret_cast(cmsg); + int const nfds = (cmsg->cmsg_len - header_size) / sizeof(int); + + // NOTE: This relies on the file descriptor cmsg being read + // (and written) atomically. + if (cmsg->cmsg_len > CMSG_LEN(fds_bytes) || + (header.msg_flags & MSG_CTRUNC)) { + for (int i = 0; i < nfds; i++) ::close(data[i]); + BOOST_THROW_EXCEPTION( + std::runtime_error("Received more fds than expected")); + } + + // We can't properly pass Fds through google::protobuf::Message, + // which is where these get shoved. + // + // When we have our own RPC generator plugin and aren't using deprecated + // Protobuf features this can go away. + for (int i = 0; i < nfds; i++) + fds[fds_read + i] = Fd{IntOwnedFd{data[i]}}; + + fds_read += nfds; } + } + + if (fds_read < fds.size()) { + for (auto fd : fds) + if (fd >= 0) ::close(fd); + fds.clear(); + BOOST_THROW_EXCEPTION( + std::runtime_error("Received fewer fds than expected")); + } } -} // namespace anbox +} // namespace anbox diff --git a/src/anbox/network/fd_socket_transmission.h b/src/anbox/network/fd_socket_transmission.h index 12454f3..7999abd 100644 --- a/src/anbox/network/fd_socket_transmission.h +++ b/src/anbox/network/fd_socket_transmission.h @@ -21,30 +21,27 @@ #include "anbox/common/fd.h" -#include -#include #include +#include +#include -namespace anbox -{ -struct socket_error : std::system_error -{ - socket_error(std::string const& message); +namespace anbox { +struct socket_error : std::system_error { + socket_error(std::string const& message); }; -struct socket_disconnected_error : std::system_error -{ - socket_disconnected_error(std::string const& message); +struct socket_disconnected_error : std::system_error { + socket_disconnected_error(std::string const& message); }; -struct fd_reception_error : std::runtime_error -{ - fd_reception_error(std::string const& message); +struct fd_reception_error : std::runtime_error { + fd_reception_error(std::string const& message); }; bool socket_error_is_transient(int error_code); void send_fds(Fd const& socket, std::vector const& fd); -void receive_data(Fd const& socket, void* buffer, size_t bytes_requested, std::vector& fds); +void receive_data(Fd const& socket, void* buffer, size_t bytes_requested, + std::vector& fds); } #endif diff --git a/src/anbox/network/local_socket_messenger.cpp b/src/anbox/network/local_socket_messenger.cpp index 3d37d42..de251bc 100644 --- a/src/anbox/network/local_socket_messenger.cpp +++ b/src/anbox/network/local_socket_messenger.cpp @@ -16,32 +16,33 @@ */ #include "anbox/network/local_socket_messenger.h" +#include "anbox/logger.h" #include "anbox/network/socket_helper.h" #include "anbox/utils.h" -#include "anbox/logger.h" #include namespace anbox { namespace network { -LocalSocketMessenger::LocalSocketMessenger(std::shared_ptr const &socket) : - BaseSocketMessenger(socket) { +LocalSocketMessenger::LocalSocketMessenger( + std::shared_ptr const &socket) + : BaseSocketMessenger(socket) {} + +LocalSocketMessenger::LocalSocketMessenger(const std::string &path, + const std::shared_ptr &rt) + : socket_(std::make_shared( + rt->service())) { + boost::system::error_code err; + socket_->connect(boost::asio::local::stream_protocol::endpoint(path), err); + if (err) { + const auto msg = utils::string_format("Failed to connect to socket %s: %s", + path, err.message()); + BOOST_THROW_EXCEPTION(std::runtime_error(msg)); + } + + setup(socket_); } -LocalSocketMessenger::LocalSocketMessenger(const std::string &path, const std::shared_ptr &rt) : - socket_(std::make_shared(rt->service())) { - - boost::system::error_code err; - socket_->connect(boost::asio::local::stream_protocol::endpoint(path), err); - if (err) { - const auto msg = utils::string_format("Failed to connect to socket %s: %s", path, err.message()); - BOOST_THROW_EXCEPTION(std::runtime_error(msg)); - } - - setup(socket_); -} - -LocalSocketMessenger::~LocalSocketMessenger() { -} -} // namespace network -} // namespace anbox +LocalSocketMessenger::~LocalSocketMessenger() {} +} // namespace network +} // namespace anbox diff --git a/src/anbox/network/local_socket_messenger.h b/src/anbox/network/local_socket_messenger.h index 960f541..1c6e6bc 100644 --- a/src/anbox/network/local_socket_messenger.h +++ b/src/anbox/network/local_socket_messenger.h @@ -25,16 +25,20 @@ namespace anbox { namespace network { -class LocalSocketMessenger : public BaseSocketMessenger { -public: - LocalSocketMessenger(std::shared_ptr const &socket); - LocalSocketMessenger(const std::string &path, const std::shared_ptr &rt); - ~LocalSocketMessenger(); +class LocalSocketMessenger + : public BaseSocketMessenger { + public: + LocalSocketMessenger( + std::shared_ptr const + &socket); + LocalSocketMessenger(const std::string &path, + const std::shared_ptr &rt); + ~LocalSocketMessenger(); -private: - std::shared_ptr socket_; + private: + std::shared_ptr socket_; }; -} // namespace network -} // namespace anbox +} // namespace network +} // namespace anbox #endif diff --git a/src/anbox/network/message_processor.h b/src/anbox/network/message_processor.h index 5f0d5d1..b133ba8 100644 --- a/src/anbox/network/message_processor.h +++ b/src/anbox/network/message_processor.h @@ -18,17 +18,17 @@ #ifndef ANBOX_NETWORK_MESSAGE_PROCESSOR_H #define ANBOX_NETWORK_MESSAGE_PROCESSOR_H -#include #include +#include namespace anbox { namespace network { class MessageProcessor { -public: - virtual ~MessageProcessor() { } - virtual bool process_data(const std::vector &data) = 0; + public: + virtual ~MessageProcessor() {} + virtual bool process_data(const std::vector &data) = 0; }; -} // namespace network -} // namespace anbox +} // namespace network +} // namespace anbox #endif diff --git a/src/anbox/network/message_receiver.h b/src/anbox/network/message_receiver.h index c7f7c3b..773da77 100644 --- a/src/anbox/network/message_receiver.h +++ b/src/anbox/network/message_receiver.h @@ -19,30 +19,34 @@ #ifndef ANBOX_NETWORK_MESSAGE_RECEIVER_H_ #define ANBOX_NETWORK_MESSAGE_RECEIVER_H_ -#include -#include #include +#include +#include #include "anbox/common/fd.h" namespace anbox { namespace network { -class MessageReceiver -{ -public: - //receive message from the socket. 'handler' will be called when 'buffer' has been filled with exactly 'size' - typedef std::function AnboxReadHandler; - virtual void async_receive_msg(AnboxReadHandler const& handler, boost::asio::mutable_buffers_1 const& buffer) = 0; - virtual boost::system::error_code receive_msg(boost::asio::mutable_buffers_1 const& buffer) = 0; - virtual size_t available_bytes() = 0; +class MessageReceiver { + public: + // receive message from the socket. 'handler' will be called when 'buffer' has + // been filled with exactly 'size' + typedef std::function + AnboxReadHandler; + virtual void async_receive_msg( + AnboxReadHandler const& handler, + boost::asio::mutable_buffers_1 const& buffer) = 0; + virtual boost::system::error_code receive_msg( + boost::asio::mutable_buffers_1 const& buffer) = 0; + virtual size_t available_bytes() = 0; -protected: - MessageReceiver() = default; - virtual ~MessageReceiver() = default; - MessageReceiver(MessageReceiver const&) = delete; - MessageReceiver& operator=(MessageReceiver const&) = delete; + protected: + MessageReceiver() = default; + virtual ~MessageReceiver() = default; + MessageReceiver(MessageReceiver const&) = delete; + MessageReceiver& operator=(MessageReceiver const&) = delete; }; -} // namespace network -} // namespace anbox +} // namespace network +} // namespace anbox #endif diff --git a/src/anbox/network/message_sender.h b/src/anbox/network/message_sender.h index 750715d..7c984ff 100644 --- a/src/anbox/network/message_sender.h +++ b/src/anbox/network/message_sender.h @@ -23,18 +23,17 @@ namespace anbox { namespace network { -class MessageSender -{ -public: - virtual void send(char const* data, size_t length) = 0; +class MessageSender { + public: + virtual void send(char const* data, size_t length) = 0; -protected: - MessageSender() = default; - virtual ~MessageSender() = default; - MessageSender(MessageSender const&) = delete; - MessageSender& operator=(MessageSender const&) = delete; + protected: + MessageSender() = default; + virtual ~MessageSender() = default; + MessageSender(MessageSender const&) = delete; + MessageSender& operator=(MessageSender const&) = delete; }; -} // namespace anbox -} // namespace network +} // namespace anbox +} // namespace network #endif diff --git a/src/anbox/network/published_socket_connector.cpp b/src/anbox/network/published_socket_connector.cpp index 75327c8..b1ae7f6 100644 --- a/src/anbox/network/published_socket_connector.cpp +++ b/src/anbox/network/published_socket_connector.cpp @@ -22,38 +22,34 @@ namespace anbox { namespace network { PublishedSocketConnector::PublishedSocketConnector( - const std::string& socket_file, - const std::shared_ptr &rt, - const std::shared_ptr> &connection_creator) : - socket_file_(remove_socket_if_stale(socket_file)), - runtime_(rt), - connection_creator_(connection_creator), - acceptor_(rt->service(), socket_file_) { - - start_accept(); + const std::string& socket_file, const std::shared_ptr& rt, + const std::shared_ptr>& connection_creator) + : socket_file_(remove_socket_if_stale(socket_file)), + runtime_(rt), + connection_creator_(connection_creator), + acceptor_(rt->service(), socket_file_) { + start_accept(); } -PublishedSocketConnector::~PublishedSocketConnector() { -} +PublishedSocketConnector::~PublishedSocketConnector() {} void PublishedSocketConnector::start_accept() { - auto socket = std::make_shared(runtime_->service()); + auto socket = std::make_shared( + runtime_->service()); - acceptor_.async_accept( - *socket, - [this, socket](boost::system::error_code const& err) { - on_new_connection(socket, err); - }); + acceptor_.async_accept(*socket, + [this, socket](boost::system::error_code const& err) { + on_new_connection(socket, err); + }); } void PublishedSocketConnector::on_new_connection( - std::shared_ptr const& socket, - boost::system::error_code const& err) { + std::shared_ptr const& socket, + boost::system::error_code const& err) { + if (!err) connection_creator_->create_connection_for(socket); - if (!err) - connection_creator_->create_connection_for(socket); - - start_accept(); + start_accept(); } -} // namespace network -} // namespace anbox +} // namespace network +} // namespace anbox diff --git a/src/anbox/network/published_socket_connector.h b/src/anbox/network/published_socket_connector.h index be48a27..068f070 100644 --- a/src/anbox/network/published_socket_connector.h +++ b/src/anbox/network/published_socket_connector.h @@ -23,34 +23,35 @@ #include "anbox/do_not_copy_or_move.h" #include "anbox/runtime.h" -#include "anbox/network/connector.h" #include "anbox/network/connection_creator.h" +#include "anbox/network/connector.h" namespace anbox { namespace network { -class PublishedSocketConnector : public DoNotCopyOrMove, - public Connector { -public: - explicit PublishedSocketConnector( - const std::string& socket_file, - const std::shared_ptr &rt, - const std::shared_ptr> &connection_creator); - ~PublishedSocketConnector() noexcept; +class PublishedSocketConnector : public DoNotCopyOrMove, public Connector { + public: + explicit PublishedSocketConnector( + const std::string& socket_file, const std::shared_ptr& rt, + const std::shared_ptr>& connection_creator); + ~PublishedSocketConnector() noexcept; - std::string socket_file() const { return socket_file_; } + std::string socket_file() const { return socket_file_; } -private: - void start_accept(); - void on_new_connection( - std::shared_ptr const& socket, - boost::system::error_code const& err); + private: + void start_accept(); + void on_new_connection( + std::shared_ptr const& + socket, + boost::system::error_code const& err); - const std::string socket_file_; - std::shared_ptr runtime_; - std::shared_ptr> connection_creator_; - boost::asio::local::stream_protocol::acceptor acceptor_; + const std::string socket_file_; + std::shared_ptr runtime_; + std::shared_ptr> + connection_creator_; + boost::asio::local::stream_protocol::acceptor acceptor_; }; -} // namespace network -} // namespace anbox +} // namespace network +} // namespace anbox #endif diff --git a/src/anbox/network/socket_connection.cpp b/src/anbox/network/socket_connection.cpp index e36f56b..d2c1014 100644 --- a/src/anbox/network/socket_connection.cpp +++ b/src/anbox/network/socket_connection.cpp @@ -18,17 +18,17 @@ #include "anbox/logger.h" -#include "anbox/network/socket_connection.h" -#include "anbox/network/message_sender.h" #include "anbox/network/message_receiver.h" +#include "anbox/network/message_sender.h" +#include "anbox/network/socket_connection.h" #include #include #include -#include #include +#include namespace ba = boost::asio; namespace bs = boost::system; @@ -37,52 +37,42 @@ namespace anbox { namespace network { SocketConnection::SocketConnection( std::shared_ptr const& message_receiver, - std::shared_ptr const& message_sender, - int id_, + std::shared_ptr const& message_sender, int id_, std::shared_ptr> const& connections, std::shared_ptr const& processor) - : message_receiver_(message_receiver), - message_sender_(message_sender), - id_(id_), - connections_(connections), - processor_(processor) -{ + : message_receiver_(message_receiver), + message_sender_(message_sender), + id_(id_), + connections_(connections), + processor_(processor) {} + +SocketConnection::~SocketConnection() noexcept {} + +void SocketConnection::send(char const* data, size_t length) { + message_sender_->send(data, length); } -SocketConnection::~SocketConnection() noexcept -{ +void SocketConnection::read_next_message() { + auto callback = std::bind(&SocketConnection::on_read_size, this, + std::placeholders::_1, std::placeholders::_2); + message_receiver_->async_receive_msg(callback, ba::buffer(buffer_)); } -void SocketConnection::send(char const* data, size_t length) -{ - message_sender_->send(data, length); +void SocketConnection::on_read_size(const boost::system::error_code& error, + std::size_t bytes_read) { + if (error) { + if (connections_) connections_->remove(id()); + + return; + } + + std::vector data(bytes_read); + std::copy(buffer_.data(), buffer_.data() + bytes_read, data.data()); + + if (processor_->process_data(data)) + read_next_message(); + else if (connections_) + connections_->remove(id()); } - -void SocketConnection::read_next_message() -{ - auto callback = std::bind(&SocketConnection::on_read_size, - this, std::placeholders::_1, std::placeholders::_2); - message_receiver_->async_receive_msg(callback, ba::buffer(buffer_)); -} - -void SocketConnection::on_read_size(const boost::system::error_code& error, std::size_t bytes_read) -{ - if (error) - { - if (connections_) - connections_->remove(id()); - - return; - } - - std::vector data(bytes_read); - std::copy(buffer_.data(), buffer_.data() + bytes_read, data.data()); - - if (processor_->process_data(data)) - read_next_message(); - else if (connections_) - connections_->remove(id()); -} -} // namespace anbox -} // namespace network - +} // namespace anbox +} // namespace network diff --git a/src/anbox/network/socket_connection.h b/src/anbox/network/socket_connection.h index ba500dc..a0618e0 100644 --- a/src/anbox/network/socket_connection.h +++ b/src/anbox/network/socket_connection.h @@ -20,9 +20,9 @@ #define ANBOX_NETWORK_SOCKET_CONNECTION_H_ #include "anbox/network/connections.h" +#include "anbox/network/message_processor.h" #include "anbox/network/message_receiver.h" #include "anbox/network/message_sender.h" -#include "anbox/network/message_processor.h" #include @@ -30,39 +30,40 @@ namespace anbox { namespace network { -class SocketConnection -{ -public: - SocketConnection( - std::shared_ptr const& message_receiver, - std::shared_ptr const& message_sender, - int id, - std::shared_ptr> const& connections, - std::shared_ptr const& processor); +class SocketConnection { + public: + SocketConnection( + std::shared_ptr const& message_receiver, + std::shared_ptr const& message_sender, int id, + std::shared_ptr> const& connections, + std::shared_ptr const& processor); - ~SocketConnection() noexcept; + ~SocketConnection() noexcept; - void set_name(const std::string &name) { name_ = name; } + void set_name(const std::string& name) { name_ = name; } - std::shared_ptr message_sender() const { return message_sender_; } + std::shared_ptr message_sender() const { + return message_sender_; + } - int id() const { return id_; } + int id() const { return id_; } - void send(char const* data, size_t length); - void read_next_message(); + void send(char const* data, size_t length); + void read_next_message(); -private: - void on_read_size(const boost::system::error_code& ec, std::size_t bytes_read); + private: + void on_read_size(const boost::system::error_code& ec, + std::size_t bytes_read); - std::shared_ptr message_receiver_; - std::shared_ptr message_sender_; - int id_; - std::shared_ptr> connections_; - std::shared_ptr processor_; - std::array buffer_; - std::string name_; + std::shared_ptr message_receiver_; + std::shared_ptr message_sender_; + int id_; + std::shared_ptr> connections_; + std::shared_ptr processor_; + std::array buffer_; + std::string name_; }; -} // namespace anbox -} // namespace network +} // namespace anbox +} // namespace network #endif diff --git a/src/anbox/network/socket_helper.cpp b/src/anbox/network/socket_helper.cpp index 8db0447..55261c0 100644 --- a/src/anbox/network/socket_helper.cpp +++ b/src/anbox/network/socket_helper.cpp @@ -19,68 +19,58 @@ #include -#include -#include #include +#include +#include #include namespace anbox { namespace network { -bool socket_file_exists(std::string const& filename) -{ - struct stat statbuf; - bool exists = (0 == stat(filename.c_str(), &statbuf)); - /* Avoid removing non-socket files */ - bool is_socket_type = (statbuf.st_mode & S_IFMT) == S_IFSOCK; - return exists && is_socket_type; +bool socket_file_exists(std::string const& filename) { + struct stat statbuf; + bool exists = (0 == stat(filename.c_str(), &statbuf)); + /* Avoid removing non-socket files */ + bool is_socket_type = (statbuf.st_mode & S_IFMT) == S_IFSOCK; + return exists && is_socket_type; } -bool socket_exists(std::string const& socket_name) -{ - try - { - std::string socket_path{socket_name}; +bool socket_exists(std::string const& socket_name) { + try { + std::string socket_path{socket_name}; - /* In case an abstract socket name exists with the same name*/ - socket_path.insert(std::begin(socket_path), ' '); + /* In case an abstract socket name exists with the same name*/ + socket_path.insert(std::begin(socket_path), ' '); - /* If the name is contained in this table, it signifies - * a process is truly using that socket connection - */ - std::ifstream socket_names_file("/proc/net/unix"); - std::string line; - while (std::getline(socket_names_file, line)) - { - auto index = line.find(socket_path); - /* check for complete match */ - if (index != std::string::npos && - (index + socket_path.length()) == line.length()) - { - return true; - } - } - } - catch (...) - { - /* Assume the socket exists */ + /* If the name is contained in this table, it signifies + * a process is truly using that socket connection + */ + std::ifstream socket_names_file("/proc/net/unix"); + std::string line; + while (std::getline(socket_names_file, line)) { + auto index = line.find(socket_path); + /* check for complete match */ + if (index != std::string::npos && + (index + socket_path.length()) == line.length()) { return true; + } } - return false; + } catch (...) { + /* Assume the socket exists */ + return true; + } + return false; } -std::string remove_socket_if_stale(std::string const& socket_name) -{ - if (socket_file_exists(socket_name) && !socket_exists(socket_name)) - { - if (std::remove(socket_name.c_str()) != 0) - { - BOOST_THROW_EXCEPTION( - boost::enable_error_info( - std::runtime_error("Failed removing stale socket file")) << boost::errinfo_errno(errno)); - } +std::string remove_socket_if_stale(std::string const& socket_name) { + if (socket_file_exists(socket_name) && !socket_exists(socket_name)) { + if (std::remove(socket_name.c_str()) != 0) { + BOOST_THROW_EXCEPTION(boost::enable_error_info(std::runtime_error( + "Failed removing stale socket file")) + << boost::errinfo_errno(errno)); } - return socket_name; + } + return socket_name; } -} // namespace network -} // namespace anbox +} // namespace network +} // namespace anbox diff --git a/src/anbox/network/socket_helper.h b/src/anbox/network/socket_helper.h index c3e9b11..52cf95d 100644 --- a/src/anbox/network/socket_helper.h +++ b/src/anbox/network/socket_helper.h @@ -25,7 +25,7 @@ namespace network { bool socket_file_exists(std::string const& filename); bool socket_exists(std::string const& socket_name); std::string remove_socket_if_stale(std::string const& socket_name); -} // namespace network -} // namespace anbox +} // namespace network +} // namespace anbox #endif diff --git a/src/anbox/network/socket_messenger.h b/src/anbox/network/socket_messenger.h index cacd5ed..d5c17b5 100644 --- a/src/anbox/network/socket_messenger.h +++ b/src/anbox/network/socket_messenger.h @@ -21,21 +21,20 @@ #include -#include "anbox/network/message_sender.h" -#include "anbox/network/message_receiver.h" #include "anbox/network/credentials.h" +#include "anbox/network/message_receiver.h" +#include "anbox/network/message_sender.h" namespace anbox { namespace network { -class SocketMessenger : public MessageSender, - public MessageReceiver { -public: - virtual Credentials creds() const = 0; - virtual unsigned short local_port() const = 0; - virtual void set_no_delay() = 0; - virtual void close() = 0; +class SocketMessenger : public MessageSender, public MessageReceiver { + public: + virtual Credentials creds() const = 0; + virtual unsigned short local_port() const = 0; + virtual void set_no_delay() = 0; + virtual void close() = 0; }; -} // namespace network -} // namespace anbox +} // namespace network +} // namespace anbox #endif diff --git a/src/anbox/network/stream_socket_transport.cpp b/src/anbox/network/stream_socket_transport.cpp index aa52574..df46d32 100644 --- a/src/anbox/network/stream_socket_transport.cpp +++ b/src/anbox/network/stream_socket_transport.cpp @@ -15,16 +15,16 @@ * */ -#include "anbox/common/variable_length_array.h" #include "anbox/network/stream_socket_transport.h" +#include "anbox/common/variable_length_array.h" #include "anbox/network/fd_socket_transmission.h" #include #include #include -#include #include +#include #include #include @@ -33,42 +33,36 @@ namespace anbox { namespace network { -StreamSocketTransport::StreamSocketTransport(const std::string &socket_path, - const std::shared_ptr &rt) : - socket_(std::make_shared(rt->service())), +StreamSocketTransport::StreamSocketTransport(const std::string& socket_path, + const std::shared_ptr& rt) + : socket_(std::make_shared( + rt->service())), { - socket_.connect(boost::asio::local::stream_protocol::endpoint(socket_path)); - read_next_message(); + socket_.connect(boost::asio::local::stream_protocol::endpoint(socket_path)); + read_next_message(); } -void StreamSocketTransport::register_observer(std::shared_ptr const& observer) -{ - this->observer_ = observer; +void StreamSocketTransport::register_observer( + std::shared_ptr const& observer) { + this->observer_ = observer; } -void StreamSocketTransport::unregister_observer(std::shared_ptr const& observer) -{ - if (this->observer_ != observer) - return; +void StreamSocketTransport::unregister_observer( + std::shared_ptr const& observer) { + if (this->observer_ != observer) return; - this->observer_.reset(); + this->observer_.reset(); } -void StreamSocketTransport::send_message(std::vector const& buffer) -{ -} +void StreamSocketTransport::send_message(std::vector const& buffer) {} void StreamSocketTransport::read_next_message() { - auto callback = std::bind(&StreamSocketTransport::on_read_size, - this, - std::placeholders::_1, - std::placeholders::_2); - + auto callback = std::bind(&StreamSocketTransport::on_read_size, this, + std::placeholders::_1, std::placeholders::_2); } -void StreamSocketTransport::on_read_size(const boost::system::error_code& ec, std::size_t bytes_read) { +void StreamSocketTransport::on_read_size(const boost::system::error_code& ec, + std::size_t bytes_read) {} -} - -} // namespace network -} // namespace anbox +} // namespace network +} // namespace anbox diff --git a/src/anbox/network/stream_socket_transport.h b/src/anbox/network/stream_socket_transport.h index b2a9d4a..587ffbb 100644 --- a/src/anbox/network/stream_socket_transport.h +++ b/src/anbox/network/stream_socket_transport.h @@ -19,8 +19,8 @@ #define ANBOX_STREAM_SOCKET_TRANSPORT_H_ #include "anbox/common/fd.h" -#include "anbox/runtime.h" #include "anbox/network/socket_messenger.h" +#include "anbox/runtime.h" #include @@ -28,39 +28,38 @@ namespace anbox { namespace network { -class StreamSocketTransport -{ -public: - class Observer { - public: - Observer() = default; - virtual ~Observer() = default; +class StreamSocketTransport { + public: + class Observer { + public: + Observer() = default; + virtual ~Observer() = default; - virtual void on_data_available() = 0; - virtual void on_disconnected() = 0; + virtual void on_data_available() = 0; + virtual void on_disconnected() = 0; - Observer(Observer const&) = delete; - Observer& operator=(Observer const&) = delete; - }; + Observer(Observer const&) = delete; + Observer& operator=(Observer const&) = delete; + }; - StreamSocketTransport(const std::string &socket_path, - const std::shared_ptr &rt); + StreamSocketTransport(const std::string& socket_path, + const std::shared_ptr& rt); - void register_observer(std::shared_ptr const& observer_); - void unregister_observer(std::shared_ptr const& observer_); + void register_observer(std::shared_ptr const& observer_); + void unregister_observer(std::shared_ptr const& observer_); - void send_message(std::vector const& buffer); - void read_next_message(); + void send_message(std::vector const& buffer); + void read_next_message(); -private: - void on_read_size(const boost::system::error_code& ec, std::size_t bytes_read); + private: + void on_read_size(const boost::system::error_code& ec, + std::size_t bytes_read); - std::shared_ptr observer_; - std::shared_ptr socket_; - SocketMessenger messenger_; + std::shared_ptr observer_; + std::shared_ptr socket_; + SocketMessenger messenger_; }; -} // namespace network -} // namespace anbox +} // namespace network +} // namespace anbox - -#endif // STREAM_SOCKET_TRANSPORT_H_ +#endif // STREAM_SOCKET_TRANSPORT_H_ diff --git a/src/anbox/network/tcp_socket_connector.cpp b/src/anbox/network/tcp_socket_connector.cpp index e01cb55..36ee840 100644 --- a/src/anbox/network/tcp_socket_connector.cpp +++ b/src/anbox/network/tcp_socket_connector.cpp @@ -22,51 +22,46 @@ namespace anbox { namespace network { TcpSocketConnector::TcpSocketConnector( - const boost::asio::ip::address_v4 &address, - unsigned short port, - const std::shared_ptr &rt, - const std::shared_ptr> &connection_creator) : - address_(address), - port_(port), - runtime_(rt), - connection_creator_(connection_creator), - acceptor_(rt->service(), boost::asio::ip::tcp::endpoint(address, port)) { - - start_accept(); + const boost::asio::ip::address_v4& address, unsigned short port, + const std::shared_ptr& rt, + const std::shared_ptr>& + connection_creator) + : address_(address), + port_(port), + runtime_(rt), + connection_creator_(connection_creator), + acceptor_(rt->service(), boost::asio::ip::tcp::endpoint(address, port)) { + start_accept(); } -TcpSocketConnector::~TcpSocketConnector() { - acceptor_.cancel(); -} +TcpSocketConnector::~TcpSocketConnector() { acceptor_.cancel(); } void TcpSocketConnector::start_accept() { - auto socket = std::make_shared(runtime_->service()); + auto socket = + std::make_shared(runtime_->service()); - acceptor_.async_accept( - *socket, - [this, socket](boost::system::error_code const& err) { - on_new_connection(socket, err); - }); + acceptor_.async_accept(*socket, + [this, socket](boost::system::error_code const& err) { + on_new_connection(socket, err); + }); } void TcpSocketConnector::on_new_connection( - std::shared_ptr const& socket, - boost::system::error_code const& err) { - - - switch (err.value()) { + std::shared_ptr const& socket, + boost::system::error_code const& err) { + switch (err.value()) { case boost::system::errc::success: - connection_creator_->create_connection_for(socket); - break; + connection_creator_->create_connection_for(socket); + break; case boost::system::errc::operation_canceled: - // Socket was closed so don't listen for any further incoming - // connection attempts. - return; + // Socket was closed so don't listen for any further incoming + // connection attempts. + return; default: - break; - } + break; + } - start_accept(); + start_accept(); } -} // namespace network -} // namespace anbox +} // namespace network +} // namespace anbox diff --git a/src/anbox/network/tcp_socket_connector.h b/src/anbox/network/tcp_socket_connector.h index d79c389..94fa0a3 100644 --- a/src/anbox/network/tcp_socket_connector.h +++ b/src/anbox/network/tcp_socket_connector.h @@ -23,36 +23,35 @@ #include "anbox/do_not_copy_or_move.h" #include "anbox/runtime.h" -#include "anbox/network/connector.h" #include "anbox/network/connection_creator.h" +#include "anbox/network/connector.h" namespace anbox { namespace network { -class TcpSocketConnector : public DoNotCopyOrMove, - public Connector { -public: - explicit TcpSocketConnector( - const boost::asio::ip::address_v4 &address, - unsigned short port, - const std::shared_ptr &rt, - const std::shared_ptr> &connection_creator); - ~TcpSocketConnector() noexcept; +class TcpSocketConnector : public DoNotCopyOrMove, public Connector { + public: + explicit TcpSocketConnector( + const boost::asio::ip::address_v4 &address, unsigned short port, + const std::shared_ptr &rt, + const std::shared_ptr> + &connection_creator); + ~TcpSocketConnector() noexcept; - unsigned short port() const { return port_; } + unsigned short port() const { return port_; } -private: - void start_accept(); - void on_new_connection( - std::shared_ptr const& socket, - boost::system::error_code const& err); + private: + void start_accept(); + void on_new_connection( + std::shared_ptr const &socket, + boost::system::error_code const &err); - boost::asio::ip::address_v4 address_; - unsigned short port_; - std::shared_ptr runtime_; - std::shared_ptr> connection_creator_; - boost::asio::ip::tcp::acceptor acceptor_; + boost::asio::ip::address_v4 address_; + unsigned short port_; + std::shared_ptr runtime_; + std::shared_ptr> connection_creator_; + boost::asio::ip::tcp::acceptor acceptor_; }; -} // namespace network -} // namespace anbox +} // namespace network +} // namespace anbox #endif diff --git a/src/anbox/network/tcp_socket_messenger.cpp b/src/anbox/network/tcp_socket_messenger.cpp index d52dbf4..7e83055 100644 --- a/src/anbox/network/tcp_socket_messenger.cpp +++ b/src/anbox/network/tcp_socket_messenger.cpp @@ -19,24 +19,22 @@ namespace anbox { namespace network { -TcpSocketMessenger::TcpSocketMessenger(const boost::asio::ip::address_v4 &addr, unsigned short port, +TcpSocketMessenger::TcpSocketMessenger(const boost::asio::ip::address_v4 &addr, + unsigned short port, const std::shared_ptr &rt) { - boost::asio::ip::tcp::endpoint endpoint(addr, port); - auto socket = std::make_shared(rt->service()); - socket->connect(endpoint); - setup(socket); - local_port_ = socket->local_endpoint().port(); + boost::asio::ip::tcp::endpoint endpoint(addr, port); + auto socket = std::make_shared(rt->service()); + socket->connect(endpoint); + setup(socket); + local_port_ = socket->local_endpoint().port(); } -TcpSocketMessenger::TcpSocketMessenger(std::shared_ptr const &socket) : - BaseSocketMessenger(socket) { -} +TcpSocketMessenger::TcpSocketMessenger( + std::shared_ptr const &socket) + : BaseSocketMessenger(socket) {} -TcpSocketMessenger::~TcpSocketMessenger() { -} +TcpSocketMessenger::~TcpSocketMessenger() {} -unsigned short TcpSocketMessenger::local_port() const { - return local_port_; -} -} // namespace network -} // namespace anbox +unsigned short TcpSocketMessenger::local_port() const { return local_port_; } +} // namespace network +} // namespace anbox diff --git a/src/anbox/network/tcp_socket_messenger.h b/src/anbox/network/tcp_socket_messenger.h index 5327b95..2712b52 100644 --- a/src/anbox/network/tcp_socket_messenger.h +++ b/src/anbox/network/tcp_socket_messenger.h @@ -26,18 +26,19 @@ namespace anbox { namespace network { class TcpSocketMessenger : public BaseSocketMessenger { -public: - TcpSocketMessenger(const boost::asio::ip::address_v4 &addr, unsigned short port, - const std::shared_ptr &rt); - TcpSocketMessenger(std::shared_ptr const &socket); - ~TcpSocketMessenger(); + public: + TcpSocketMessenger(const boost::asio::ip::address_v4 &addr, + unsigned short port, const std::shared_ptr &rt); + TcpSocketMessenger( + std::shared_ptr const &socket); + ~TcpSocketMessenger(); - unsigned short local_port() const; + unsigned short local_port() const; -private: - unsigned short local_port_; + private: + unsigned short local_port_; }; -} // namespace network -} // namespace anbox +} // namespace network +} // namespace anbox #endif diff --git a/src/anbox/not_reachable.cpp b/src/anbox/not_reachable.cpp index 6cc1cd2..4b30c93 100644 --- a/src/anbox/not_reachable.cpp +++ b/src/anbox/not_reachable.cpp @@ -21,12 +21,15 @@ #include -anbox::util::NotReachable::NotReachable(const std::string& function, const std::string& file, std::uint32_t line) - : std::logic_error{(boost::format{"Code should not be reachable: %1% in %2%:%3%"} % function % file % line).str()} -{ -} +anbox::util::NotReachable::NotReachable(const std::string& function, + const std::string& file, + std::uint32_t line) + : std::logic_error{ + (boost::format{"Code should not be reachable: %1% in %2%:%3%"} % + function % file % line) + .str()} {} -void anbox::util::not_reachable(const std::string& function, const std::string& file, std::uint32_t line) -{ - throw NotReachable{function, file, line}; +void anbox::util::not_reachable(const std::string& function, + const std::string& file, std::uint32_t line) { + throw NotReachable{function, file, line}; } diff --git a/src/anbox/not_reachable.h b/src/anbox/not_reachable.h index c234d0c..880f72f 100644 --- a/src/anbox/not_reachable.h +++ b/src/anbox/not_reachable.h @@ -26,15 +26,17 @@ namespace anbox { namespace util { /// @brief NotReachable is thrown from not_reachable. -struct NotReachable : public std::logic_error -{ - /// @brief NotImplemented initializes a new instance for the given function name. - NotReachable(const std::string& function, const std::string& file, std::uint32_t line); +struct NotReachable : public std::logic_error { + /// @brief NotImplemented initializes a new instance for the given function + /// name. + NotReachable(const std::string& function, const std::string& file, + std::uint32_t line); }; /// @brief not_reachable throws NotReachable. -[[noreturn]] void not_reachable(const std::string& function, const std::string& file, std::uint32_t line); -} // namespace util -} // namespace anbox +[[noreturn]] void not_reachable(const std::string& function, + const std::string& file, std::uint32_t line); +} // namespace util +} // namespace anbox #endif diff --git a/src/anbox/optional.h b/src/anbox/optional.h index c4a38c6..4c42353 100644 --- a/src/anbox/optional.h +++ b/src/anbox/optional.h @@ -23,9 +23,8 @@ #include #include -namespace anbox -{ -template +namespace anbox { +template using Optional = boost::optional; } diff --git a/src/anbox/protobuf/google_protobuf_guard.cpp b/src/anbox/protobuf/google_protobuf_guard.cpp index e450da9..afe278d 100644 --- a/src/anbox/protobuf/google_protobuf_guard.cpp +++ b/src/anbox/protobuf/google_protobuf_guard.cpp @@ -18,23 +18,21 @@ #include -extern "C" int __attribute__((constructor)) -init_google_protobuf() -{ - GOOGLE_PROTOBUF_VERIFY_VERSION; - return 0; +extern "C" int __attribute__((constructor)) init_google_protobuf() { + GOOGLE_PROTOBUF_VERIFY_VERSION; + return 0; } -extern "C" int __attribute__((destructor)) -shutdown_google_protobuf() -{ - google::protobuf::ShutdownProtobufLibrary(); - return 0; +extern "C" int __attribute__((destructor)) shutdown_google_protobuf() { + google::protobuf::ShutdownProtobufLibrary(); + return 0; } // Preserve ABI -namespace anbox { namespace protobuf { void google_protobuf_guard(); }} - -void anbox::protobuf::google_protobuf_guard() -{ +namespace anbox { +namespace protobuf { +void google_protobuf_guard(); } +} + +void anbox::protobuf::google_protobuf_guard() {} diff --git a/src/anbox/qemu/adb_message_processor.cpp b/src/anbox/qemu/adb_message_processor.cpp index 9635dbe..921b921 100644 --- a/src/anbox/qemu/adb_message_processor.cpp +++ b/src/anbox/qemu/adb_message_processor.cpp @@ -15,11 +15,11 @@ * */ -#include "anbox/logger.h" #include "anbox/qemu/adb_message_processor.h" +#include "anbox/logger.h" +#include "anbox/network/delegate_connection_creator.h" #include "anbox/network/delegate_message_processor.h" #include "anbox/network/tcp_socket_messenger.h" -#include "anbox/network/delegate_connection_creator.h" #include #include @@ -39,147 +39,155 @@ using namespace std::placeholders; namespace anbox { namespace qemu { -AdbMessageProcessor::AdbMessageProcessor(const std::shared_ptr &rt, - const std::shared_ptr &messenger) : - runtime_(rt), - state_(waiting_for_guest_accept_command), - expected_command_(accept_command), - messenger_(messenger), - host_notify_timer_(rt->service()) { -} +AdbMessageProcessor::AdbMessageProcessor( + const std::shared_ptr &rt, + const std::shared_ptr &messenger) + : runtime_(rt), + state_(waiting_for_guest_accept_command), + expected_command_(accept_command), + messenger_(messenger), + host_notify_timer_(rt->service()) {} AdbMessageProcessor::~AdbMessageProcessor() { - host_connector_.reset(); - active_instance.unlock(); + host_connector_.reset(); + active_instance.unlock(); } void AdbMessageProcessor::advance_state() { - switch (state_) { + switch (state_) { case waiting_for_guest_accept_command: - // Try to get a lock here as if we already have another processor - // running we don't have to do anything here until that one is done. - // The container directly starts a second connection once the first - // one is established but will not use it until the active one is closed. - active_instance.lock(); + // Try to get a lock here as if we already have another processor + // running we don't have to do anything here until that one is done. + // The container directly starts a second connection once the first + // one is established but will not use it until the active one is closed. + active_instance.lock(); - wait_for_host_connection(); - break; + wait_for_host_connection(); + break; case waiting_for_host_connection: - messenger_->send(reinterpret_cast(ok_command.data()), ok_command.size()); - state_ = waiting_for_guest_start_command; - expected_command_ = start_command; - break; + messenger_->send(reinterpret_cast(ok_command.data()), + ok_command.size()); + state_ = waiting_for_guest_start_command; + expected_command_ = start_command; + break; case waiting_for_guest_start_command: - state_ = proxying_data; - read_next_host_message(); - break; + state_ = proxying_data; + read_next_host_message(); + break; case proxying_data: - break; + break; case closed_by_host: - // Close the connection to the container as our adb host connection - // turned down. The container will try to establish a connection - // immediately again and we will handle that by waiting for the - // host adb to run up again. - messenger_->close(); - break; + // Close the connection to the container as our adb host connection + // turned down. The container will try to establish a connection + // immediately again and we will handle that by waiting for the + // host adb to run up again. + messenger_->close(); + break; case closed_by_container: - // In this case the container will close the pipe connection and this - // message processor will be deleted once the owning socket connection - // is closed. - break; + // In this case the container will close the pipe connection and this + // message processor will be deleted once the owning socket connection + // is closed. + break; default: - break; - } + break; + } } void AdbMessageProcessor::wait_for_host_connection() { - if (!host_connector_) { - host_connector_ = std::make_shared( - boost::asio::ip::address_v4::from_string("127.0.0.1"), - default_host_listen_port, - runtime_, - std::make_shared>( - std::bind(&AdbMessageProcessor::on_host_connection, this, _1))); - } + if (!host_connector_) { + host_connector_ = std::make_shared( + boost::asio::ip::address_v4::from_string("127.0.0.1"), + default_host_listen_port, runtime_, + std::make_shared< + network::DelegateConnectionCreator>( + std::bind(&AdbMessageProcessor::on_host_connection, this, _1))); + } - try { - // Notify the adb host instance so that it knows on which port our - // proxy is waiting for incoming connections. - auto messenger = std::make_shared(boost::asio::ip::address_v4::from_string("127.0.0.1"), - default_adb_client_port, - runtime_); - auto message = utils::string_format("host:emulator:%d", default_host_listen_port); - auto handshake = utils::string_format("%04x%s", message.size(), message.c_str()); - messenger->send(handshake.data(), handshake.size()); - } catch (std::exception&) { - // Try again later when the host adb service is maybe available - host_notify_timer_.expires_from_now(default_adb_wait_time); - host_notify_timer_.async_wait([&](const boost::system::error_code&) { - wait_for_host_connection(); - }); - } + try { + // Notify the adb host instance so that it knows on which port our + // proxy is waiting for incoming connections. + auto messenger = std::make_shared( + boost::asio::ip::address_v4::from_string("127.0.0.1"), + default_adb_client_port, runtime_); + auto message = + utils::string_format("host:emulator:%d", default_host_listen_port); + auto handshake = + utils::string_format("%04x%s", message.size(), message.c_str()); + messenger->send(handshake.data(), handshake.size()); + } catch (std::exception &) { + // Try again later when the host adb service is maybe available + host_notify_timer_.expires_from_now(default_adb_wait_time); + host_notify_timer_.async_wait( + [&](const boost::system::error_code &) { wait_for_host_connection(); }); + } } -void AdbMessageProcessor::on_host_connection(std::shared_ptr> const &socket) { - host_messenger_ = std::make_shared(socket); +void AdbMessageProcessor::on_host_connection( + std::shared_ptr< + boost::asio::basic_stream_socket> const &socket) { + host_messenger_ = std::make_shared(socket); - // set_no_delay() reduces the latency of sending data, at the cost - // of creating more TCP packets on the connection. It's useful when - // doing lots of small send() calls, like the ADB protocol requires. - // And since this is on localhost, the packet increase should not be - // noticeable. - host_messenger_->set_no_delay(); + // set_no_delay() reduces the latency of sending data, at the cost + // of creating more TCP packets on the connection. It's useful when + // doing lots of small send() calls, like the ADB protocol requires. + // And since this is on localhost, the packet increase should not be + // noticeable. + host_messenger_->set_no_delay(); - // Let adb inside the container know that we have a connection to - // the adb host instance - messenger_->send(reinterpret_cast(ok_command.data()), ok_command.size()); + // Let adb inside the container know that we have a connection to + // the adb host instance + messenger_->send(reinterpret_cast(ok_command.data()), + ok_command.size()); - state_ = waiting_for_guest_start_command; - expected_command_ = start_command; + state_ = waiting_for_guest_start_command; + expected_command_ = start_command; } void AdbMessageProcessor::read_next_host_message() { - auto callback = std::bind(&AdbMessageProcessor::on_host_read_size, - this, _1, _2); - host_messenger_->async_receive_msg(callback, boost::asio::buffer(host_buffer_)); + auto callback = + std::bind(&AdbMessageProcessor::on_host_read_size, this, _1, _2); + host_messenger_->async_receive_msg(callback, + boost::asio::buffer(host_buffer_)); } -void AdbMessageProcessor::on_host_read_size(const boost::system::error_code& error, std::size_t bytes_read) { - if (error) { - // If messenger is still alive then close the connection which will - // trigger the terminate of our processor instance too. - if (messenger_) - messenger_->close(); +void AdbMessageProcessor::on_host_read_size( + const boost::system::error_code &error, std::size_t bytes_read) { + if (error) { + // If messenger is still alive then close the connection which will + // trigger the terminate of our processor instance too. + if (messenger_) messenger_->close(); - return; - } + return; + } - messenger_->send(reinterpret_cast(host_buffer_.data()), bytes_read); - read_next_host_message(); + messenger_->send(reinterpret_cast(host_buffer_.data()), + bytes_read); + read_next_host_message(); } bool AdbMessageProcessor::process_data(const std::vector &data) { - if (state_ == proxying_data) { - host_messenger_->send(reinterpret_cast(data.data()), data.size()); - return true; - } - - for (const auto &byte : data) - buffer_.push_back(byte); - - if (expected_command_.size() > 0 && buffer_.size() >= expected_command_.size()) { - if (::memcmp(buffer_.data(), expected_command_.data(), data.size()) != 0) { - // We got not the command we expected and will terminate here - return false; - } - - buffer_.erase(buffer_.begin(), buffer_.begin() + expected_command_.size()); - expected_command_.clear(); - - advance_state(); - } - + if (state_ == proxying_data) { + host_messenger_->send(reinterpret_cast(data.data()), + data.size()); return true; + } + + for (const auto &byte : data) buffer_.push_back(byte); + + if (expected_command_.size() > 0 && + buffer_.size() >= expected_command_.size()) { + if (::memcmp(buffer_.data(), expected_command_.data(), data.size()) != 0) { + // We got not the command we expected and will terminate here + return false; + } + + buffer_.erase(buffer_.begin(), buffer_.begin() + expected_command_.size()); + expected_command_.clear(); + + advance_state(); + } + + return true; } -} // namespace qemu -} // namespace anbox +} // namespace qemu +} // namespace anbox diff --git a/src/anbox/qemu/adb_message_processor.h b/src/anbox/qemu/adb_message_processor.h index af6d3cd..88f0cd6 100644 --- a/src/anbox/qemu/adb_message_processor.h +++ b/src/anbox/qemu/adb_message_processor.h @@ -18,53 +18,56 @@ #ifndef ANBOX_QEMU_ADBD_MESSAGE_PROCESSOR_H_ #define ANBOX_QEMU_ADBD_MESSAGE_PROCESSOR_H_ -#include "anbox/runtime.h" #include "anbox/network/message_processor.h" -#include "anbox/network/socket_messenger.h" #include "anbox/network/socket_connection.h" +#include "anbox/network/socket_messenger.h" #include "anbox/network/tcp_socket_connector.h" #include "anbox/network/tcp_socket_messenger.h" +#include "anbox/runtime.h" #include namespace anbox { namespace qemu { class AdbMessageProcessor : public network::MessageProcessor { -public: - AdbMessageProcessor(const std::shared_ptr &rt, - const std::shared_ptr &messenger); - ~AdbMessageProcessor(); + public: + AdbMessageProcessor( + const std::shared_ptr &rt, + const std::shared_ptr &messenger); + ~AdbMessageProcessor(); - bool process_data(const std::vector &data) override; + bool process_data(const std::vector &data) override; -private: - enum State { - waiting_for_guest_accept_command, - waiting_for_host_connection, - waiting_for_guest_start_command, - proxying_data, - closed_by_container, - closed_by_host, - }; + private: + enum State { + waiting_for_guest_accept_command, + waiting_for_host_connection, + waiting_for_guest_start_command, + proxying_data, + closed_by_container, + closed_by_host, + }; - void advance_state(); + void advance_state(); - void wait_for_host_connection(); - void on_host_connection(std::shared_ptr> const &socket); - void read_next_host_message(); - void on_host_read_size(const boost::system::error_code& error, std::size_t bytes_read); + void wait_for_host_connection(); + void on_host_connection(std::shared_ptr> const &socket); + void read_next_host_message(); + void on_host_read_size(const boost::system::error_code &error, + std::size_t bytes_read); - std::shared_ptr runtime_; - State state_ = waiting_for_guest_accept_command; - std::string expected_command_; - std::shared_ptr messenger_; - std::vector buffer_; - std::shared_ptr host_connector_; - std::shared_ptr host_messenger_; - std::array host_buffer_; - boost::asio::deadline_timer host_notify_timer_; + std::shared_ptr runtime_; + State state_ = waiting_for_guest_accept_command; + std::string expected_command_; + std::shared_ptr messenger_; + std::vector buffer_; + std::shared_ptr host_connector_; + std::shared_ptr host_messenger_; + std::array host_buffer_; + boost::asio::deadline_timer host_notify_timer_; }; -} // namespace graphics -} // namespace anbox +} // namespace graphics +} // namespace anbox #endif diff --git a/src/anbox/qemu/at_parser.cpp b/src/anbox/qemu/at_parser.cpp index 7b052cd..e353b89 100644 --- a/src/anbox/qemu/at_parser.cpp +++ b/src/anbox/qemu/at_parser.cpp @@ -16,59 +16,61 @@ */ #include "anbox/qemu//at_parser.h" -#include "anbox/utils.h" #include "anbox/logger.h" +#include "anbox/utils.h" namespace anbox { namespace qemu { -AtParser::AtParser() { -} +AtParser::AtParser() {} -void AtParser::register_command(const std::string &command, CommandHandler handler) { - handlers_.insert({ command, handler }); +void AtParser::register_command(const std::string &command, + CommandHandler handler) { + handlers_.insert({command, handler}); } void AtParser::process_data(std::vector &data) { - size_t bytes_processed = 0; - for (size_t pos = 0; pos < data.size(); ) { - const auto byte = data.at(pos); - if (byte == '\n' || byte == '\r') { - std::string command; - command.insert(0, reinterpret_cast(data.data()) + bytes_processed, pos - bytes_processed); - bytes_processed += (pos - bytes_processed) + 1; - processs_command(command); - } - pos++; + size_t bytes_processed = 0; + for (size_t pos = 0; pos < data.size();) { + const auto byte = data.at(pos); + if (byte == '\n' || byte == '\r') { + std::string command; + command.insert( + 0, reinterpret_cast(data.data()) + bytes_processed, + pos - bytes_processed); + bytes_processed += (pos - bytes_processed) + 1; + processs_command(command); } + pos++; + } - data.erase(data.begin(), data.begin() + bytes_processed); + data.erase(data.begin(), data.begin() + bytes_processed); } void AtParser::processs_command(const std::string &command) { - if (!utils::string_starts_with(command, "AT")) { - WARNING("Invalid AT command: '%s'", command); - return; + if (!utils::string_starts_with(command, "AT")) { + WARNING("Invalid AT command: '%s'", command); + return; + } + + // Strip AT prefix from command + auto real_command = command.substr(2, command.length() - 2); + + DEBUG("command: %s", real_command); + + CommandHandler handler = nullptr; + for (const auto &iter : handlers_) { + if (utils::string_starts_with(real_command, iter.first)) { + handler = iter.second; + break; } + } - // Strip AT prefix from command - auto real_command = command.substr(2, command.length() - 2); + if (!handler) { + WARNING("No handler for command '%s' available", real_command); + return; + } - DEBUG("command: %s", real_command); - - CommandHandler handler = nullptr; - for (const auto &iter : handlers_) { - if (utils::string_starts_with(real_command, iter.first)) { - handler = iter.second; - break; - } - } - - if (!handler) { - WARNING("No handler for command '%s' available", real_command); - return; - } - - handler(real_command); + handler(real_command); } -} // namespace qemu -} // namespace anbox +} // namespace qemu +} // namespace anbox diff --git a/src/anbox/qemu/at_parser.h b/src/anbox/qemu/at_parser.h index 6ca57e1..3935376 100644 --- a/src/anbox/qemu/at_parser.h +++ b/src/anbox/qemu/at_parser.h @@ -18,31 +18,31 @@ #ifndef ANBOX_QEMU_AT_PARSER_H_ #define ANBOX_QEMU_AT_PARSER_H_ -#include #include -#include #include +#include +#include #include "anbox/do_not_copy_or_move.h" namespace anbox { namespace qemu { class AtParser { -public: - typedef std::function CommandHandler; + public: + typedef std::function CommandHandler; - AtParser(); + AtParser(); - void register_command(const std::string &command, CommandHandler handler); + void register_command(const std::string &command, CommandHandler handler); - void process_data(std::vector &data); + void process_data(std::vector &data); -private: - void processs_command(const std::string &command); + private: + void processs_command(const std::string &command); - std::map handlers_; + std::map handlers_; }; -} // namespace qemu -} // namespace anbox +} // namespace qemu +} // namespace anbox #endif diff --git a/src/anbox/qemu/boot_properties_message_processor.cpp b/src/anbox/qemu/boot_properties_message_processor.cpp index 0165942..783b568 100644 --- a/src/anbox/qemu/boot_properties_message_processor.cpp +++ b/src/anbox/qemu/boot_properties_message_processor.cpp @@ -21,31 +21,32 @@ namespace anbox { namespace qemu { -BootPropertiesMessageProcessor::BootPropertiesMessageProcessor(const std::shared_ptr &messenger) : - QemudMessageProcessor(messenger) { -} +BootPropertiesMessageProcessor::BootPropertiesMessageProcessor( + const std::shared_ptr &messenger) + : QemudMessageProcessor(messenger) {} -BootPropertiesMessageProcessor::~BootPropertiesMessageProcessor() { -} +BootPropertiesMessageProcessor::~BootPropertiesMessageProcessor() {} -void BootPropertiesMessageProcessor::handle_command(const std::string &command) { - if (command == "list") - list_properties(); +void BootPropertiesMessageProcessor::handle_command( + const std::string &command) { + if (command == "list") list_properties(); } void BootPropertiesMessageProcessor::list_properties() { - std::vector properties = { - // TODO(morphis): Using HDPI here for now but should be adjusted to the device - // we're running on. - utils::string_format("ro.sf.lcd_density=%d", static_cast(graphics::DensityType::medium)), - }; + std::vector properties = { + // TODO(morphis): Using HDPI here for now but should be adjusted to the + // device + // we're running on. + utils::string_format("ro.sf.lcd_density=%d", + static_cast(graphics::DensityType::medium)), + }; - for (const auto &prop : properties) { - send_header(prop.length()); - messenger_->send(prop.c_str(), prop.length()); - } + for (const auto &prop : properties) { + send_header(prop.length()); + messenger_->send(prop.c_str(), prop.length()); + } - finish_message(); + finish_message(); } -} // namespace qemu -} // namespace anbox +} // namespace qemu +} // namespace anbox diff --git a/src/anbox/qemu/boot_properties_message_processor.h b/src/anbox/qemu/boot_properties_message_processor.h index 3960826..ffd9ac1 100644 --- a/src/anbox/qemu/boot_properties_message_processor.h +++ b/src/anbox/qemu/boot_properties_message_processor.h @@ -23,17 +23,18 @@ namespace anbox { namespace qemu { class BootPropertiesMessageProcessor : public QemudMessageProcessor { -public: - BootPropertiesMessageProcessor(const std::shared_ptr &messenger); - ~BootPropertiesMessageProcessor(); + public: + BootPropertiesMessageProcessor( + const std::shared_ptr &messenger); + ~BootPropertiesMessageProcessor(); -protected: - void handle_command(const std::string &command) override; + protected: + void handle_command(const std::string &command) override; -private: - void list_properties(); + private: + void list_properties(); }; -} // namespace graphics -} // namespace anbox +} // namespace graphics +} // namespace anbox #endif diff --git a/src/anbox/qemu/bootanimation_message_processor.cpp b/src/anbox/qemu/bootanimation_message_processor.cpp index c166a21..05c097c 100644 --- a/src/anbox/qemu/bootanimation_message_processor.cpp +++ b/src/anbox/qemu/bootanimation_message_processor.cpp @@ -15,37 +15,34 @@ * */ -#include "anbox/logger.h" #include "anbox/qemu//bootanimation_message_processor.h" +#include "anbox/logger.h" #include namespace anbox { namespace qemu { -BootAnimationMessageProcessor::BootAnimationMessageProcessor(const std::shared_ptr &messenger, - const std::string &icon_path) : - QemudMessageProcessor(messenger), - icon_path_(icon_path) { -} +BootAnimationMessageProcessor::BootAnimationMessageProcessor( + const std::shared_ptr &messenger, + const std::string &icon_path) + : QemudMessageProcessor(messenger), icon_path_(icon_path) {} -BootAnimationMessageProcessor::~BootAnimationMessageProcessor() { -} +BootAnimationMessageProcessor::~BootAnimationMessageProcessor() {} void BootAnimationMessageProcessor::handle_command(const std::string &command) { - if (command == "retrieve-icon") - retrieve_icon(); + if (command == "retrieve-icon") retrieve_icon(); } void BootAnimationMessageProcessor::retrieve_icon() { - std::ifstream icon_file(icon_path_, std::ifstream::binary); - std::array buffer; + std::ifstream icon_file(icon_path_, std::ifstream::binary); + std::array 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); - } + 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 qemu -} // namespace anbox +} // namespace qemu +} // namespace anbox diff --git a/src/anbox/qemu/bootanimation_message_processor.h b/src/anbox/qemu/bootanimation_message_processor.h index 4158c1a..c4dea50 100644 --- a/src/anbox/qemu/bootanimation_message_processor.h +++ b/src/anbox/qemu/bootanimation_message_processor.h @@ -23,20 +23,21 @@ namespace anbox { namespace qemu { class BootAnimationMessageProcessor : public QemudMessageProcessor { -public: - BootAnimationMessageProcessor(const std::shared_ptr &messenger, - const std::string &icon_path); - ~BootAnimationMessageProcessor(); + public: + BootAnimationMessageProcessor( + const std::shared_ptr &messenger, + const std::string &icon_path); + ~BootAnimationMessageProcessor(); -protected: - void handle_command(const std::string &command) override; + protected: + void handle_command(const std::string &command) override; -private: - void retrieve_icon(); + private: + void retrieve_icon(); - std::string icon_path_; + std::string icon_path_; }; -} // namespace graphics -} // namespace anbox +} // namespace graphics +} // namespace anbox #endif diff --git a/src/anbox/qemu/camera_message_processor.cpp b/src/anbox/qemu/camera_message_processor.cpp index c936044..740fde0 100644 --- a/src/anbox/qemu/camera_message_processor.cpp +++ b/src/anbox/qemu/camera_message_processor.cpp @@ -15,53 +15,50 @@ * */ -#include "anbox/logger.h" #include "anbox/qemu/camera_message_processor.h" +#include "anbox/logger.h" namespace anbox { namespace qemu { -CameraMessageProcessor::CameraMessageProcessor(const std::shared_ptr &messenger) : - messenger_(messenger) { -} +CameraMessageProcessor::CameraMessageProcessor( + const std::shared_ptr &messenger) + : messenger_(messenger) {} -CameraMessageProcessor::~CameraMessageProcessor() { -} +CameraMessageProcessor::~CameraMessageProcessor() {} -bool CameraMessageProcessor::process_data(const std::vector &data) { - for (const auto &byte : data) - buffer_.push_back(byte); +bool CameraMessageProcessor::process_data( + const std::vector &data) { + for (const auto &byte : data) buffer_.push_back(byte); - process_commands(); + process_commands(); - return true; + return true; } void CameraMessageProcessor::process_commands() { - while (buffer_.size() > 0) { - size_t size = 0; - while (size < buffer_.size()) { - if (buffer_.at(size) == 0x0) - break; - size++; - } - - std::string command; - command.insert(0, reinterpret_cast(buffer_.data()), size); - buffer_.erase(buffer_.begin(), buffer_.begin() + size + 1); - - handle_command(command); + while (buffer_.size() > 0) { + size_t size = 0; + while (size < buffer_.size()) { + if (buffer_.at(size) == 0x0) break; + size++; } + + std::string command; + command.insert(0, reinterpret_cast(buffer_.data()), size); + buffer_.erase(buffer_.begin(), buffer_.begin() + size + 1); + + handle_command(command); + } } void CameraMessageProcessor::handle_command(const std::string &command) { - if (command == "list") - list(); + if (command == "list") list(); } void CameraMessageProcessor::list() { - char buf[5]; - snprintf(buf, 5, "\n"); - messenger_->send(buf, strlen(buf)); + char buf[5]; + snprintf(buf, 5, "\n"); + messenger_->send(buf, strlen(buf)); } -} // namespace qemu -} // namespace anbox +} // namespace qemu +} // namespace anbox diff --git a/src/anbox/qemu/camera_message_processor.h b/src/anbox/qemu/camera_message_processor.h index ec603ce..4639170 100644 --- a/src/anbox/qemu/camera_message_processor.h +++ b/src/anbox/qemu/camera_message_processor.h @@ -24,22 +24,23 @@ namespace anbox { namespace qemu { class CameraMessageProcessor : public network::MessageProcessor { -public: - CameraMessageProcessor(const std::shared_ptr &messenger); - ~CameraMessageProcessor(); + public: + CameraMessageProcessor( + const std::shared_ptr &messenger); + ~CameraMessageProcessor(); - bool process_data(const std::vector &data) override; + bool process_data(const std::vector &data) override; -private: - void process_commands(); + private: + void process_commands(); - void handle_command(const std::string &command); - void list(); + void handle_command(const std::string &command); + void list(); - std::shared_ptr messenger_; - std::vector buffer_; + std::shared_ptr messenger_; + std::vector buffer_; }; -} // namespace graphics -} // namespace anbox +} // namespace graphics +} // namespace anbox #endif diff --git a/src/anbox/qemu/fingerprint_message_processor.cpp b/src/anbox/qemu/fingerprint_message_processor.cpp index eb256a3..420e492 100644 --- a/src/anbox/qemu/fingerprint_message_processor.cpp +++ b/src/anbox/qemu/fingerprint_message_processor.cpp @@ -15,29 +15,27 @@ * */ -#include "anbox/logger.h" #include "anbox/qemu/fingerprint_message_processor.h" +#include "anbox/logger.h" namespace anbox { namespace qemu { -FingerprintMessageProcessor::FingerprintMessageProcessor(const std::shared_ptr &messenger) : - QemudMessageProcessor(messenger) { -} +FingerprintMessageProcessor::FingerprintMessageProcessor( + const std::shared_ptr &messenger) + : QemudMessageProcessor(messenger) {} -FingerprintMessageProcessor::~FingerprintMessageProcessor() { -} +FingerprintMessageProcessor::~FingerprintMessageProcessor() {} void FingerprintMessageProcessor::handle_command(const std::string &command) { - if (command == "listen") - listen(); + if (command == "listen") listen(); } void FingerprintMessageProcessor::listen() { - char buf[12]; - snprintf(buf, sizeof(buf), "off"); - send_header(strlen(buf)); - messenger_->send(buf, strlen(buf)); - finish_message(); + char buf[12]; + snprintf(buf, sizeof(buf), "off"); + send_header(strlen(buf)); + messenger_->send(buf, strlen(buf)); + finish_message(); } -} // namespace qemu -} // namespace anbox +} // namespace qemu +} // namespace anbox diff --git a/src/anbox/qemu/fingerprint_message_processor.h b/src/anbox/qemu/fingerprint_message_processor.h index 885f772..e9c1ceb 100644 --- a/src/anbox/qemu/fingerprint_message_processor.h +++ b/src/anbox/qemu/fingerprint_message_processor.h @@ -23,17 +23,18 @@ namespace anbox { namespace qemu { class FingerprintMessageProcessor : public QemudMessageProcessor { -public: - FingerprintMessageProcessor(const std::shared_ptr &messenger); - ~FingerprintMessageProcessor(); + public: + FingerprintMessageProcessor( + const std::shared_ptr &messenger); + ~FingerprintMessageProcessor(); -protected: - void handle_command(const std::string &command) override; + protected: + void handle_command(const std::string &command) override; -private: - void listen(); + private: + void listen(); }; -} // namespace graphics -} // namespace anbox +} // namespace graphics +} // namespace anbox #endif diff --git a/src/anbox/qemu/gsm_message_processor.cpp b/src/anbox/qemu/gsm_message_processor.cpp index dc3c945..27ea8cd 100644 --- a/src/anbox/qemu/gsm_message_processor.cpp +++ b/src/anbox/qemu/gsm_message_processor.cpp @@ -15,8 +15,8 @@ * */ -#include "anbox/logger.h" #include "anbox/qemu/gsm_message_processor.h" +#include "anbox/logger.h" #include "anbox/qemu/at_parser.h" #include @@ -26,85 +26,87 @@ using namespace std::placeholders; namespace anbox { namespace qemu { -GsmMessageProcessor::GsmMessageProcessor(const std::shared_ptr &messenger) : - messenger_(messenger), - parser_(std::make_shared()) { +GsmMessageProcessor::GsmMessageProcessor( + const std::shared_ptr &messenger) + : messenger_(messenger), parser_(std::make_shared()) { + auto ok_reply = [&](const std::string &) { send_reply("OK"); }; - auto ok_reply = [&](const std::string&) { send_reply("OK"); }; - - parser_->register_command("E0Q0V1", ok_reply); - parser_->register_command("S0=0", ok_reply); - parser_->register_command("+CTEC", std::bind(&GsmMessageProcessor::handle_ctec, this, _1)); - parser_->register_command("+CMEE=1", ok_reply); - parser_->register_command("+CCWA=1", ok_reply); - parser_->register_command("+CMOD=0", ok_reply); - parser_->register_command("+CMUT=0", ok_reply); - parser_->register_command("+CSSN=0,1", ok_reply); - parser_->register_command("+COLP=0", ok_reply); - parser_->register_command("+CSCS=\"HEX\"", ok_reply); - parser_->register_command("+CUSD=1", ok_reply); - parser_->register_command("+CGEREP=1,0", ok_reply); - parser_->register_command("+CMGF", std::bind(&GsmMessageProcessor::handle_cmgf, this, _1)); - parser_->register_command("%CPI=3", ok_reply); - parser_->register_command("%CSTAT=1", ok_reply); - parser_->register_command("+CREG", std::bind(&GsmMessageProcessor::handle_creg, this, _1)); - parser_->register_command("+CGREG", std::bind(&GsmMessageProcessor::handle_cgreg, this, _1)); - parser_->register_command("+CFUN", std::bind(&GsmMessageProcessor::handle_cfun, this, _1)); + parser_->register_command("E0Q0V1", ok_reply); + parser_->register_command("S0=0", ok_reply); + parser_->register_command( + "+CTEC", std::bind(&GsmMessageProcessor::handle_ctec, this, _1)); + parser_->register_command("+CMEE=1", ok_reply); + parser_->register_command("+CCWA=1", ok_reply); + parser_->register_command("+CMOD=0", ok_reply); + parser_->register_command("+CMUT=0", ok_reply); + parser_->register_command("+CSSN=0,1", ok_reply); + parser_->register_command("+COLP=0", ok_reply); + parser_->register_command("+CSCS=\"HEX\"", ok_reply); + parser_->register_command("+CUSD=1", ok_reply); + parser_->register_command("+CGEREP=1,0", ok_reply); + parser_->register_command( + "+CMGF", std::bind(&GsmMessageProcessor::handle_cmgf, this, _1)); + parser_->register_command("%CPI=3", ok_reply); + parser_->register_command("%CSTAT=1", ok_reply); + parser_->register_command( + "+CREG", std::bind(&GsmMessageProcessor::handle_creg, this, _1)); + parser_->register_command( + "+CGREG", std::bind(&GsmMessageProcessor::handle_cgreg, this, _1)); + parser_->register_command( + "+CFUN", std::bind(&GsmMessageProcessor::handle_cfun, this, _1)); } -GsmMessageProcessor::~GsmMessageProcessor() { -} +GsmMessageProcessor::~GsmMessageProcessor() {} bool GsmMessageProcessor::process_data(const std::vector &data) { - for (const auto &byte : data) - buffer_.push_back(byte); + for (const auto &byte : data) buffer_.push_back(byte); - parser_->process_data(buffer_); - return true; + parser_->process_data(buffer_); + return true; } void GsmMessageProcessor::send_reply(const std::string &message) { - auto reply = utils::string_format("%s\rOK\n", message); - std::vector data; - std::copy(reply.begin(), reply.end(), std::back_inserter(data)); - messenger_->send(reinterpret_cast(data.data()), data.size()); + auto reply = utils::string_format("%s\rOK\n", message); + std::vector data; + std::copy(reply.begin(), reply.end(), std::back_inserter(data)); + messenger_->send(reinterpret_cast(data.data()), data.size()); } void GsmMessageProcessor::handle_ctec(const std::string &command) { - if (command == "+CTEC=?") - send_reply("+CTEC: 0,1,2,3"); - else if (command == "+CTEC?") - send_reply(utils::string_format("+CTEC: %d,%x", static_cast(technology::gsm), 0x0f)); + if (command == "+CTEC=?") + send_reply("+CTEC: 0,1,2,3"); + else if (command == "+CTEC?") + send_reply(utils::string_format( + "+CTEC: %d,%x", static_cast(technology::gsm), 0x0f)); } void GsmMessageProcessor::handle_cmgf(const std::string &command) { - if (command == "+CMGF=0") - send_reply(""); + if (command == "+CMGF=0") send_reply(""); } void GsmMessageProcessor::handle_creg(const std::string &command) { - if (command == "+CREG=?") - send_reply("+CREG: (0-2)"); - else if (command == "+CREG?") - send_reply(utils::string_format("+CREF: %d,%d", 0, 0)); - else if (utils::string_starts_with(command, "+CREG=")) - send_reply(""); + if (command == "+CREG=?") + send_reply("+CREG: (0-2)"); + else if (command == "+CREG?") + send_reply(utils::string_format("+CREF: %d,%d", 0, 0)); + else if (utils::string_starts_with(command, "+CREG=")) + send_reply(""); } void GsmMessageProcessor::handle_cgreg(const std::string &command) { - if (command == "+CGREG=?") - send_reply("+CGREG: (0-2)"); - else if (command == "+CGREG?") - send_reply(utils::string_format("+CGREG: %d,%d", 0, 0)); - else if (utils::string_starts_with(command, "+CGREG=")) - send_reply(""); + if (command == "+CGREG=?") + send_reply("+CGREG: (0-2)"); + else if (command == "+CGREG?") + send_reply(utils::string_format("+CGREG: %d,%d", 0, 0)); + else if (utils::string_starts_with(command, "+CGREG=")) + send_reply(""); } void GsmMessageProcessor::handle_cfun(const std::string &command) { - if (command == "+CFUN?") - send_reply(utils::string_format("+CFUN: %d", 1)); - else if (utils::string_starts_with(command, "+CFUN=")) - send_reply(""); + if (command == "+CFUN?") + send_reply(utils::string_format("+CFUN: %d", 1)); + else if (utils::string_starts_with(command, "+CFUN=")) + send_reply(""); } -} // namespace qemu -} // namespace anbox +} // namespace qemu +} // namespace anbox diff --git a/src/anbox/qemu/gsm_message_processor.h b/src/anbox/qemu/gsm_message_processor.h index c644d81..7f9e2b0 100644 --- a/src/anbox/qemu/gsm_message_processor.h +++ b/src/anbox/qemu/gsm_message_processor.h @@ -25,35 +25,36 @@ namespace anbox { namespace qemu { class AtParser; class GsmMessageProcessor : public network::MessageProcessor { -public: - GsmMessageProcessor(const std::shared_ptr &messenger); - ~GsmMessageProcessor(); + public: + GsmMessageProcessor( + const std::shared_ptr &messenger); + ~GsmMessageProcessor(); - bool process_data(const std::vector &data) override; + bool process_data(const std::vector &data) override; -private: - enum class technology { - gsm = 0, - wcdm, - cdma, - evdo, - lte, - unknown, - }; + private: + enum class technology { + gsm = 0, + wcdm, + cdma, + evdo, + lte, + unknown, + }; - void send_reply(const std::string &message); + void send_reply(const std::string &message); - void handle_ctec(const std::string &command); - void handle_cmgf(const std::string &command); - void handle_creg(const std::string &command); - void handle_cgreg(const std::string &command); - void handle_cfun(const std::string &command); + void handle_ctec(const std::string &command); + void handle_cmgf(const std::string &command); + void handle_creg(const std::string &command); + void handle_cgreg(const std::string &command); + void handle_cfun(const std::string &command); - std::shared_ptr messenger_; - std::vector buffer_; - std::shared_ptr parser_; + std::shared_ptr messenger_; + std::vector buffer_; + std::shared_ptr parser_; }; -} // namespace graphics -} // namespace anbox +} // namespace graphics +} // namespace anbox #endif diff --git a/src/anbox/qemu/hwcontrol_message_processor.cpp b/src/anbox/qemu/hwcontrol_message_processor.cpp index ebe0369..2ccd57f 100644 --- a/src/anbox/qemu/hwcontrol_message_processor.cpp +++ b/src/anbox/qemu/hwcontrol_message_processor.cpp @@ -20,12 +20,11 @@ namespace anbox { namespace qemu { -HwControlMessageProcessor::HwControlMessageProcessor(const std::shared_ptr &messenger) : - QemudMessageProcessor(messenger) { -} +HwControlMessageProcessor::HwControlMessageProcessor( + const std::shared_ptr &messenger) + : QemudMessageProcessor(messenger) {} -HwControlMessageProcessor::~HwControlMessageProcessor() { -} +HwControlMessageProcessor::~HwControlMessageProcessor() {} void HwControlMessageProcessor::handle_command(const std::string &command) { #if 0 @@ -38,8 +37,8 @@ void HwControlMessageProcessor::handle_command(const std::string &command) { else DEBUG("Unknown command '%s'", command); #else - (void) command; + (void)command; #endif } -} // namespace qemu -} // namespace anbox +} // namespace qemu +} // namespace anbox diff --git a/src/anbox/qemu/hwcontrol_message_processor.h b/src/anbox/qemu/hwcontrol_message_processor.h index 5cf5ba4..ea05fc8 100644 --- a/src/anbox/qemu/hwcontrol_message_processor.h +++ b/src/anbox/qemu/hwcontrol_message_processor.h @@ -23,14 +23,15 @@ namespace anbox { namespace qemu { class HwControlMessageProcessor : public QemudMessageProcessor { -public: - HwControlMessageProcessor(const std::shared_ptr &messenger); - ~HwControlMessageProcessor(); + public: + HwControlMessageProcessor( + const std::shared_ptr &messenger); + ~HwControlMessageProcessor(); -protected: - void handle_command(const std::string &command) override; + protected: + void handle_command(const std::string &command) override; }; -} // namespace graphics -} // namespace anbox +} // namespace graphics +} // namespace anbox #endif diff --git a/src/anbox/qemu/null_message_processor.cpp b/src/anbox/qemu/null_message_processor.cpp index 90a211d..8ccbd79 100644 --- a/src/anbox/qemu/null_message_processor.cpp +++ b/src/anbox/qemu/null_message_processor.cpp @@ -16,22 +16,20 @@ */ #include "anbox/qemu/null_message_processor.h" -#include "anbox/utils.h" #include "anbox/logger.h" +#include "anbox/utils.h" #include namespace anbox { namespace qemu { -NullMessageProcessor::NullMessageProcessor() { -} +NullMessageProcessor::NullMessageProcessor() {} -NullMessageProcessor::~NullMessageProcessor() { -} +NullMessageProcessor::~NullMessageProcessor() {} bool NullMessageProcessor::process_data(const std::vector &data) { - (void) data; - return true; + (void)data; + return true; } -} // namespace qemu -} // namespace anbox +} // namespace qemu +} // namespace anbox diff --git a/src/anbox/qemu/null_message_processor.h b/src/anbox/qemu/null_message_processor.h index 5a7acb4..225e962 100644 --- a/src/anbox/qemu/null_message_processor.h +++ b/src/anbox/qemu/null_message_processor.h @@ -23,13 +23,13 @@ namespace anbox { namespace qemu { class NullMessageProcessor : public network::MessageProcessor { -public: - NullMessageProcessor(); - ~NullMessageProcessor(); + public: + NullMessageProcessor(); + ~NullMessageProcessor(); - bool process_data(const std::vector &data) override; + bool process_data(const std::vector &data) override; }; -} // namespace graphics -} // namespace anbox +} // namespace graphics +} // namespace anbox #endif diff --git a/src/anbox/qemu/pipe_connection_creator.cpp b/src/anbox/qemu/pipe_connection_creator.cpp index 0273d86..e9921e8 100644 --- a/src/anbox/qemu/pipe_connection_creator.cpp +++ b/src/anbox/qemu/pipe_connection_creator.cpp @@ -17,148 +17,154 @@ #include +#include "anbox/graphics/opengles_message_processor.h" #include "anbox/logger.h" #include "anbox/network/local_socket_messenger.h" -#include "anbox/graphics/opengles_message_processor.h" -#include "anbox/qemu/pipe_connection_creator.h" +#include "anbox/qemu/adb_message_processor.h" #include "anbox/qemu/boot_properties_message_processor.h" -#include "anbox/qemu/null_message_processor.h" -#include "anbox/qemu/hwcontrol_message_processor.h" -#include "anbox/qemu/sensors_message_processor.h" +#include "anbox/qemu/bootanimation_message_processor.h" #include "anbox/qemu/camera_message_processor.h" #include "anbox/qemu/fingerprint_message_processor.h" #include "anbox/qemu/gsm_message_processor.h" -#include "anbox/qemu/bootanimation_message_processor.h" -#include "anbox/qemu/adb_message_processor.h" +#include "anbox/qemu/hwcontrol_message_processor.h" +#include "anbox/qemu/null_message_processor.h" +#include "anbox/qemu/pipe_connection_creator.h" +#include "anbox/qemu/sensors_message_processor.h" namespace ba = boost::asio; namespace { -std::string client_type_to_string(const anbox::qemu::PipeConnectionCreator::client_type &type) { - switch (type) { +std::string client_type_to_string( + const anbox::qemu::PipeConnectionCreator::client_type &type) { + switch (type) { case anbox::qemu::PipeConnectionCreator::client_type::opengles: - return "opengles"; + return "opengles"; case anbox::qemu::PipeConnectionCreator::client_type::qemud_boot_properties: - return "boot-properties"; + return "boot-properties"; case anbox::qemu::PipeConnectionCreator::client_type::qemud_hw_control: - return "hw-control"; + return "hw-control"; case anbox::qemu::PipeConnectionCreator::client_type::qemud_sensors: - return "sensors"; + return "sensors"; case anbox::qemu::PipeConnectionCreator::client_type::qemud_camera: - return "camera"; + return "camera"; case anbox::qemu::PipeConnectionCreator::client_type::qemud_fingerprint: - return "fingerprint"; + return "fingerprint"; case anbox::qemu::PipeConnectionCreator::client_type::qemud_gsm: - return "gsm"; + return "gsm"; case anbox::qemu::PipeConnectionCreator::client_type::qemud_adb: - return "adb"; + return "adb"; case anbox::qemu::PipeConnectionCreator::client_type::bootanimation: - return "boot-animation"; + return "boot-animation"; case anbox::qemu::PipeConnectionCreator::client_type::invalid: - break; - } - return "unknown"; + break; + } + return "unknown"; } } namespace anbox { namespace qemu { -PipeConnectionCreator::PipeConnectionCreator(const std::shared_ptr &rt, - const std::string &renderer_socket_path, - const std::string &boot_animation_icon_path) : - runtime_(rt), - next_connection_id_(0), - connections_(std::make_shared>()), - renderer_socket_path_(renderer_socket_path), - boot_animation_icon_path_(boot_animation_icon_path) { -} +PipeConnectionCreator::PipeConnectionCreator( + const std::shared_ptr &rt, const std::string &renderer_socket_path, + const std::string &boot_animation_icon_path) + : runtime_(rt), + next_connection_id_(0), + connections_( + std::make_shared>()), + renderer_socket_path_(renderer_socket_path), + boot_animation_icon_path_(boot_animation_icon_path) {} -PipeConnectionCreator::~PipeConnectionCreator() { -} +PipeConnectionCreator::~PipeConnectionCreator() {} void PipeConnectionCreator::create_connection_for( - std::shared_ptr const& socket) { + std::shared_ptr const + &socket) { + auto const messenger = + std::make_shared(socket); + const auto type = identify_client(messenger); + auto const processor = create_processor(type, messenger); + if (!processor) + BOOST_THROW_EXCEPTION(std::runtime_error("Unhandled client type")); - auto const messenger = std::make_shared(socket); - const auto type = identify_client(messenger); - auto const processor = create_processor(type, messenger); - if (!processor) - BOOST_THROW_EXCEPTION(std::runtime_error("Unhandled client type")); - - auto const& connection = std::make_shared( - messenger, messenger, next_id(), connections_, processor); - connection->set_name(client_type_to_string(type)); - connections_->add(connection); - connection->read_next_message(); + auto const &connection = std::make_shared( + messenger, messenger, next_id(), connections_, processor); + connection->set_name(client_type_to_string(type)); + connections_->add(connection); + connection->read_next_message(); } PipeConnectionCreator::client_type PipeConnectionCreator::identify_client( - std::shared_ptr const& messenger) { + std::shared_ptr const &messenger) { + // The client will identify itself as first thing by writing a string + // in the format 'pipe:[:]\0' to the channel. + std::vector buffer; + for (;;) { + unsigned char byte[1] = {0}; + const auto err = messenger->receive_msg(ba::buffer(byte, 1)); + if (err) break; + buffer.push_back(byte[0]); + if (byte[0] == 0x0) break; + } - // The client will identify itself as first thing by writing a string - // in the format 'pipe:[:]\0' to the channel. - std::vector buffer; - for (;;) { - unsigned char byte[1] = { 0 }; - const auto err = messenger->receive_msg(ba::buffer(byte, 1)); - if (err) - break; - buffer.push_back(byte[0]); - if (byte[0] == 0x0) - break; - } + std::string identifier_and_args = buffer.data(); - std::string identifier_and_args = buffer.data(); + if (utils::string_starts_with(identifier_and_args, "pipe:opengles")) + return client_type::opengles; + // Even if 'boot-properties' is an argument to the service 'qemud' here we + // take this as a own service instance as that is what it is. + else if (utils::string_starts_with(identifier_and_args, + "pipe:qemud:boot-properties")) + return client_type::qemud_boot_properties; + else if (utils::string_starts_with(identifier_and_args, + "pipe:qemud:hw-control")) + return client_type::qemud_hw_control; + else if (utils::string_starts_with(identifier_and_args, "pipe:qemud:sensors")) + return client_type::qemud_sensors; + else if (utils::string_starts_with(identifier_and_args, "pipe:qemud:camera")) + return client_type::qemud_camera; + else if (utils::string_starts_with(identifier_and_args, + "pipe:qemud:fingerprintlisten")) + 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; + else if (utils::string_starts_with(identifier_and_args, "pipe:qemud:adb")) + return client_type::qemud_adb; - if (utils::string_starts_with(identifier_and_args, "pipe:opengles")) - return client_type::opengles; - // Even if 'boot-properties' is an argument to the service 'qemud' here we - // take this as a own service instance as that is what it is. - else if (utils::string_starts_with(identifier_and_args, "pipe:qemud:boot-properties")) - return client_type::qemud_boot_properties; - else if (utils::string_starts_with(identifier_and_args, "pipe:qemud:hw-control")) - return client_type::qemud_hw_control; - else if (utils::string_starts_with(identifier_and_args, "pipe:qemud:sensors")) - return client_type::qemud_sensors; - else if (utils::string_starts_with(identifier_and_args, "pipe:qemud:camera")) - return client_type::qemud_camera; - else if (utils::string_starts_with(identifier_and_args, "pipe:qemud:fingerprintlisten")) - 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; - else if (utils::string_starts_with(identifier_and_args, "pipe:qemud:adb")) - return client_type::qemud_adb; - - return client_type::invalid; + return client_type::invalid; } -std::shared_ptr PipeConnectionCreator::create_processor(const client_type &type, const std::shared_ptr &messenger) { - if (type == client_type::opengles) - return std::make_shared(renderer_socket_path_, runtime_, messenger); - else if (type == client_type::qemud_boot_properties) - return std::make_shared(messenger); - else if (type == client_type::qemud_hw_control) - return std::make_shared(messenger); - else if (type == client_type::qemud_sensors) - return std::make_shared(messenger); - else if (type == client_type::qemud_camera) - return std::make_shared(messenger); - else if (type == client_type::qemud_fingerprint) - return std::make_shared(messenger); - else if (type == client_type::qemud_gsm) - return std::make_shared(messenger); - else if (type == client_type::bootanimation) - return std::make_shared(messenger, boot_animation_icon_path_); - else if (type == client_type::qemud_adb) - return std::make_shared(runtime_, messenger); +std::shared_ptr +PipeConnectionCreator::create_processor( + const client_type &type, + const std::shared_ptr &messenger) { + if (type == client_type::opengles) + return std::make_shared( + renderer_socket_path_, runtime_, messenger); + else if (type == client_type::qemud_boot_properties) + return std::make_shared(messenger); + else if (type == client_type::qemud_hw_control) + return std::make_shared(messenger); + else if (type == client_type::qemud_sensors) + return std::make_shared(messenger); + else if (type == client_type::qemud_camera) + return std::make_shared(messenger); + else if (type == client_type::qemud_fingerprint) + return std::make_shared(messenger); + else if (type == client_type::qemud_gsm) + return std::make_shared(messenger); + else if (type == client_type::bootanimation) + return std::make_shared( + messenger, boot_animation_icon_path_); + else if (type == client_type::qemud_adb) + return std::make_shared(runtime_, messenger); - return std::make_shared(); + return std::make_shared(); } -int PipeConnectionCreator::next_id() -{ - return next_connection_id_.fetch_add(1); +int PipeConnectionCreator::next_id() { + return next_connection_id_.fetch_add(1); } -} // namespace qemu -} // namespace anbox +} // namespace qemu +} // namespace anbox diff --git a/src/anbox/qemu/pipe_connection_creator.h b/src/anbox/qemu/pipe_connection_creator.h index 391fedf..46c69ff 100644 --- a/src/anbox/qemu/pipe_connection_creator.h +++ b/src/anbox/qemu/pipe_connection_creator.h @@ -23,53 +23,57 @@ #include #include "anbox/do_not_copy_or_move.h" -#include "anbox/runtime.h" +#include "anbox/network/connection_creator.h" #include "anbox/network/connections.h" #include "anbox/network/socket_connection.h" -#include "anbox/network/connection_creator.h" #include "anbox/network/socket_messenger.h" +#include "anbox/runtime.h" namespace anbox { namespace qemu { -class PipeConnectionCreator : public network::ConnectionCreator { -public: - PipeConnectionCreator( - const std::shared_ptr &rt, - const std::string &renderer_socket_path, - const std::string &boot_animation_icon_path); - ~PipeConnectionCreator() noexcept; +class PipeConnectionCreator + : public network::ConnectionCreator { + public: + PipeConnectionCreator(const std::shared_ptr &rt, + const std::string &renderer_socket_path, + const std::string &boot_animation_icon_path); + ~PipeConnectionCreator() noexcept; - void create_connection_for( - std::shared_ptr> const& socket) override; + void create_connection_for( + std::shared_ptr> const &socket) override; - enum class client_type { - invalid, - opengles, - qemud_boot_properties, - qemud_hw_control, - qemud_sensors, - qemud_camera, - qemud_fingerprint, - qemud_gsm, - qemud_adb, - bootanimation, - }; + enum class client_type { + invalid, + opengles, + qemud_boot_properties, + qemud_hw_control, + qemud_sensors, + qemud_camera, + qemud_fingerprint, + qemud_gsm, + qemud_adb, + bootanimation, + }; -private: - int next_id(); + private: + int next_id(); - client_type identify_client(std::shared_ptr const& messenger); - std::shared_ptr create_processor( - const client_type &type, const std::shared_ptr &messenger); + client_type identify_client( + std::shared_ptr const &messenger); + std::shared_ptr create_processor( + const client_type &type, + const std::shared_ptr &messenger); - std::shared_ptr runtime_; - std::atomic next_connection_id_; - std::shared_ptr> const connections_; + std::shared_ptr runtime_; + std::atomic next_connection_id_; + std::shared_ptr> const + connections_; - std::string renderer_socket_path_; - std::string boot_animation_icon_path_; + std::string renderer_socket_path_; + std::string boot_animation_icon_path_; }; -} // namespace qemu -} // namespace anbox +} // namespace qemu +} // namespace anbox #endif diff --git a/src/anbox/qemu/qemud_message_processor.cpp b/src/anbox/qemu/qemud_message_processor.cpp index 7a39afa..ad7c544 100644 --- a/src/anbox/qemu/qemud_message_processor.cpp +++ b/src/anbox/qemu/qemud_message_processor.cpp @@ -16,8 +16,8 @@ */ #include "anbox/qemu/qemud_message_processor.h" -#include "anbox/utils.h" #include "anbox/logger.h" +#include "anbox/utils.h" #include @@ -27,59 +27,57 @@ static constexpr const long header_size{4}; namespace anbox { namespace qemu { -QemudMessageProcessor::QemudMessageProcessor(const std::shared_ptr &messenger) : - messenger_(messenger) { -} +QemudMessageProcessor::QemudMessageProcessor( + const std::shared_ptr &messenger) + : messenger_(messenger) {} -QemudMessageProcessor::~QemudMessageProcessor() { -} +QemudMessageProcessor::~QemudMessageProcessor() {} -bool QemudMessageProcessor::process_data(const std::vector &data) { - for (const auto &byte : data) - buffer_.push_back(byte); +bool QemudMessageProcessor::process_data( + const std::vector &data) { + for (const auto &byte : data) buffer_.push_back(byte); - process_commands(); + process_commands(); - return true; + return true; } void QemudMessageProcessor::process_commands() { - while (true) { - if (buffer_.size() < header_size) - break; + while (true) { + if (buffer_.size() < header_size) break; - char header[header_size] = { 0 }; - ::memcpy(header, buffer_.data(), header_size); + char header[header_size] = {0}; + ::memcpy(header, buffer_.data(), header_size); - unsigned int body_size = 0; - ::sscanf(header, "%04x", &body_size); - if (body_size != buffer_.size() - header_size) - break; + unsigned int body_size = 0; + ::sscanf(header, "%04x", &body_size); + if (body_size != buffer_.size() - header_size) break; - std::string command; - // Make sure we only copy as much bytes as we have to and not more - command.insert(0, reinterpret_cast(buffer_.data()) + header_size, body_size); + std::string command; + // Make sure we only copy as much bytes as we have to and not more + command.insert(0, + reinterpret_cast(buffer_.data()) + header_size, + body_size); - handle_command(command); + handle_command(command); - const auto consumed = header_size + body_size; - buffer_.erase(buffer_.begin(), buffer_.begin() + consumed); + const auto consumed = header_size + body_size; + buffer_.erase(buffer_.begin(), buffer_.begin() + consumed); - const auto remaining = buffer_.size() - consumed; - if (remaining <= 0) - break; - } + const auto remaining = buffer_.size() - consumed; + if (remaining <= 0) break; + } } void QemudMessageProcessor::send_header(const size_t &size) { - char header[header_size + 1]; - std::snprintf(header, header_size + 1, "%04x", size); - messenger_->send(header, header_size); + char header[header_size + 1]; + std::snprintf(header, header_size + 1, "%04x", size); + messenger_->send(header, header_size); } void QemudMessageProcessor::finish_message() { - // Send terminating NULL byte - messenger_->send(static_cast(""), 1); + // Send terminating NULL byte + messenger_->send(static_cast(""), 1); } -} // namespace qemu -} // namespace anbox +} // namespace qemu +} // namespace anbox diff --git a/src/anbox/qemu/qemud_message_processor.h b/src/anbox/qemu/qemud_message_processor.h index eee7fdf..e560881 100644 --- a/src/anbox/qemu/qemud_message_processor.h +++ b/src/anbox/qemu/qemud_message_processor.h @@ -24,26 +24,27 @@ namespace anbox { namespace qemu { class QemudMessageProcessor : public network::MessageProcessor { -public: - QemudMessageProcessor(const std::shared_ptr &messenger); - ~QemudMessageProcessor(); + public: + QemudMessageProcessor( + const std::shared_ptr &messenger); + ~QemudMessageProcessor(); - bool process_data(const std::vector &data) override; + bool process_data(const std::vector &data) override; -protected: - virtual void handle_command(const std::string &command) = 0; + protected: + virtual void handle_command(const std::string &command) = 0; - void send_header(const size_t &size); - void finish_message(); + void send_header(const size_t &size); + void finish_message(); - std::shared_ptr messenger_; + std::shared_ptr messenger_; -private: - void process_commands(); + private: + void process_commands(); - std::vector buffer_; + std::vector buffer_; }; -} // namespace graphics -} // namespace anbox +} // namespace graphics +} // namespace anbox #endif diff --git a/src/anbox/qemu/sensors_message_processor.cpp b/src/anbox/qemu/sensors_message_processor.cpp index 5843164..cb25b35 100644 --- a/src/anbox/qemu/sensors_message_processor.cpp +++ b/src/anbox/qemu/sensors_message_processor.cpp @@ -15,31 +15,29 @@ * */ -#include "anbox/logger.h" #include "anbox/qemu/sensors_message_processor.h" +#include "anbox/logger.h" namespace anbox { namespace qemu { -SensorsMessageProcessor::SensorsMessageProcessor(const std::shared_ptr &messenger) : - QemudMessageProcessor(messenger) { -} +SensorsMessageProcessor::SensorsMessageProcessor( + const std::shared_ptr &messenger) + : QemudMessageProcessor(messenger) {} -SensorsMessageProcessor::~SensorsMessageProcessor() { -} +SensorsMessageProcessor::~SensorsMessageProcessor() {} void SensorsMessageProcessor::handle_command(const std::string &command) { - if (command == "list-sensors") - list_sensors(); + if (command == "list-sensors") list_sensors(); } void SensorsMessageProcessor::list_sensors() { - // We don't support sensors yet so we mark all as disabled - int mask = 0; - char buf[12]; - snprintf(buf, sizeof(buf), "%d", mask); - send_header(strlen(buf)); - messenger_->send(buf, strlen(buf)); - finish_message(); + // We don't support sensors yet so we mark all as disabled + int mask = 0; + char buf[12]; + snprintf(buf, sizeof(buf), "%d", mask); + send_header(strlen(buf)); + messenger_->send(buf, strlen(buf)); + finish_message(); } -} // namespace qemu -} // namespace anbox +} // namespace qemu +} // namespace anbox diff --git a/src/anbox/qemu/sensors_message_processor.h b/src/anbox/qemu/sensors_message_processor.h index 95b4aeb..a58b63e 100644 --- a/src/anbox/qemu/sensors_message_processor.h +++ b/src/anbox/qemu/sensors_message_processor.h @@ -23,17 +23,18 @@ namespace anbox { namespace qemu { class SensorsMessageProcessor : public QemudMessageProcessor { -public: - SensorsMessageProcessor(const std::shared_ptr &messenger); - ~SensorsMessageProcessor(); + public: + SensorsMessageProcessor( + const std::shared_ptr &messenger); + ~SensorsMessageProcessor(); -protected: - void handle_command(const std::string &command) override; + protected: + void handle_command(const std::string &command) override; -private: - void list_sensors(); + private: + void list_sensors(); }; -} // namespace graphics -} // namespace anbox +} // namespace graphics +} // namespace anbox #endif diff --git a/src/anbox/qemu/telephony_manager.cpp b/src/anbox/qemu/telephony_manager.cpp index 25c44de..bf168df 100644 --- a/src/anbox/qemu/telephony_manager.cpp +++ b/src/anbox/qemu/telephony_manager.cpp @@ -21,18 +21,20 @@ namespace anbox { namespace qemu { -TelephonyManager::TelephonyManager(const core::dbus::Bus::Ptr &bus) : - bus_(bus) { - ofono_ = core::dbus::Service::use_service(bus_, "org.ofono"); - modem_ = ofono_->object_for_path({"/ril_0"}); +TelephonyManager::TelephonyManager(const core::dbus::Bus::Ptr &bus) + : bus_(bus) { + ofono_ = core::dbus::Service::use_service(bus_, "org.ofono"); + modem_ = ofono_->object_for_path({"/ril_0"}); - auto netreg_prop_changed = modem_->get_signal(); - netreg_prop_changed->connect([&](const org::ofono::NetworkRegistration::Signals::PropertyChanged::ArgumentType &arguments) { + auto netreg_prop_changed = modem_->get_signal< + org::ofono::NetworkRegistration::Signals::PropertyChanged>(); + netreg_prop_changed->connect( + [&](const org::ofono::NetworkRegistration::Signals::PropertyChanged:: + ArgumentType &arguments) { DEBUG("org::ofono::NetworkRegistration::PropertyChanged"); - }); + }); } -TelephonyManager::~TelephonyManager() { -} -} // namespace qemu -} // namespace anbox +TelephonyManager::~TelephonyManager() {} +} // namespace qemu +} // namespace anbox diff --git a/src/anbox/qemu/telephony_manager.h b/src/anbox/qemu/telephony_manager.h index 9742561..3254b62 100644 --- a/src/anbox/qemu/telephony_manager.h +++ b/src/anbox/qemu/telephony_manager.h @@ -19,22 +19,22 @@ #define ANBOX_QEMU_TELEPHONY_MANAGER_H_ #include -#include #include +#include namespace anbox { namespace qemu { class TelephonyManager { -public: - TelephonyManager(const core::dbus::Bus::Ptr &bus); - ~TelephonyManager(); + public: + TelephonyManager(const core::dbus::Bus::Ptr &bus); + ~TelephonyManager(); -private: - core::dbus::Bus::Ptr bus_; - core::dbus::Service::Ptr ofono_; - core::dbus::Object::Ptr modem_; + private: + core::dbus::Bus::Ptr bus_; + core::dbus::Service::Ptr ofono_; + core::dbus::Object::Ptr modem_; }; -} // namespace qemu -} // namespace anbox +} // namespace qemu +} // namespace anbox #endif diff --git a/src/anbox/rpc/channel.cpp b/src/anbox/rpc/channel.cpp index d613996..71ffa80 100644 --- a/src/anbox/rpc/channel.cpp +++ b/src/anbox/rpc/channel.cpp @@ -18,89 +18,86 @@ */ #include "anbox/rpc/channel.h" -#include "anbox/rpc/pending_call_cache.h" -#include "anbox/rpc/constants.h" #include "anbox/common/variable_length_array.h" #include "anbox/network/message_sender.h" +#include "anbox/rpc/constants.h" +#include "anbox/rpc/pending_call_cache.h" #include "anbox_rpc.pb.h" namespace anbox { namespace rpc { Channel::Channel(const std::shared_ptr &pending_calls, - const std::shared_ptr &sender) : - pending_calls_(pending_calls), - sender_(sender) { -} + const std::shared_ptr &sender) + : pending_calls_(pending_calls), sender_(sender) {} -Channel::~Channel() { -} +Channel::~Channel() {} -void Channel::call_method(std::string const& method_name, +void Channel::call_method(std::string const &method_name, google::protobuf::MessageLite const *parameters, google::protobuf::MessageLite *response, google::protobuf::Closure *complete) { - auto const &invocation = invocation_for(method_name, parameters); - pending_calls_->save_completion_details(invocation, response, complete); - send_message(MessageType::invocation, invocation); + auto const &invocation = invocation_for(method_name, parameters); + pending_calls_->save_completion_details(invocation, response, complete); + send_message(MessageType::invocation, invocation); } -void Channel::send_event(google::protobuf::MessageLite const& event) { - VariableLengthArray<2048> buffer{static_cast(event.ByteSize())}; - event.SerializeWithCachedSizesToArray(buffer.data()); +void Channel::send_event(google::protobuf::MessageLite const &event) { + VariableLengthArray<2048> buffer{static_cast(event.ByteSize())}; + event.SerializeWithCachedSizesToArray(buffer.data()); - anbox::protobuf::rpc::Result response; - response.add_events(buffer.data(), buffer.size()); + anbox::protobuf::rpc::Result response; + response.add_events(buffer.data(), buffer.size()); - send_message(MessageType::response, response); + send_message(MessageType::response, response); } -protobuf::rpc::Invocation Channel::invocation_for(std::string const& method_name, - google::protobuf::MessageLite const* request) { +protobuf::rpc::Invocation Channel::invocation_for( + std::string const &method_name, + google::protobuf::MessageLite const *request) { + anbox::VariableLengthArray<2048> buffer{ + static_cast(request->ByteSize())}; - anbox::VariableLengthArray<2048> buffer{static_cast(request->ByteSize())}; + request->SerializeWithCachedSizesToArray(buffer.data()); - request->SerializeWithCachedSizesToArray(buffer.data()); + anbox::protobuf::rpc::Invocation invoke; - anbox::protobuf::rpc::Invocation invoke; + invoke.set_id(next_id()); + invoke.set_method_name(method_name); + invoke.set_parameters(buffer.data(), buffer.size()); + invoke.set_protocol_version(1); - invoke.set_id(next_id()); - invoke.set_method_name(method_name); - invoke.set_parameters(buffer.data(), buffer.size()); - invoke.set_protocol_version(1); - - return invoke; + return invoke; } -void Channel::send_message(const std::uint8_t &type, google::protobuf::MessageLite const& message) { - const size_t size = message.ByteSize(); - const unsigned char header_bytes[header_size] = { - static_cast((size >> 8) & 0xff), - static_cast((size >> 0) & 0xff), - type, - }; +void Channel::send_message(const std::uint8_t &type, + google::protobuf::MessageLite const &message) { + const size_t size = message.ByteSize(); + const unsigned char header_bytes[header_size] = { + static_cast((size >> 8) & 0xff), + static_cast((size >> 0) & 0xff), type, + }; - std::vector send_buffer(sizeof(header_bytes) + size); - std::copy(header_bytes, header_bytes + sizeof(header_bytes), send_buffer.begin()); - message.SerializeToArray(send_buffer.data() + sizeof(header_bytes), size); + std::vector send_buffer(sizeof(header_bytes) + size); + std::copy(header_bytes, header_bytes + sizeof(header_bytes), + send_buffer.begin()); + message.SerializeToArray(send_buffer.data() + sizeof(header_bytes), size); - try { - std::lock_guard lock(write_mutex_); - sender_->send(reinterpret_cast(send_buffer.data()), send_buffer.size()); - } - catch (std::runtime_error const&) { - notify_disconnected(); - throw; - } + try { + std::lock_guard lock(write_mutex_); + sender_->send(reinterpret_cast(send_buffer.data()), + send_buffer.size()); + } catch (std::runtime_error const &) { + notify_disconnected(); + throw; + } } -void Channel::notify_disconnected() { - pending_calls_->force_completion(); -} +void Channel::notify_disconnected() { pending_calls_->force_completion(); } std::uint32_t Channel::next_id() { - static std::uint32_t next_message_id = 0; - return next_message_id++; + static std::uint32_t next_message_id = 0; + return next_message_id++; } -} // namespace rpc -} // namespace anbox +} // namespace rpc +} // namespace anbox diff --git a/src/anbox/rpc/channel.h b/src/anbox/rpc/channel.h index 3dc9e11..fb98a7b 100644 --- a/src/anbox/rpc/channel.h +++ b/src/anbox/rpc/channel.h @@ -18,55 +18,55 @@ #ifndef ANBOX_RPC_CHANNEL_H_ #define ANBOX_RPC_CHANNEL_H_ -#include #include +#include #include namespace google { namespace protobuf { class Closure; class MessageLite; -} // namespace protobuf -} // namespace google - +} // namespace protobuf +} // namespace google namespace anbox { namespace protobuf { namespace rpc { class Invocation; -} // namespace rpc -} // namespace protobuf +} // namespace rpc +} // namespace protobuf namespace network { class MessageSender; -} // namespace network +} // namespace network namespace rpc { class PendingCallCache; class Channel { -public: - Channel(const std::shared_ptr &pending_calls, - const std::shared_ptr &sender); - ~Channel(); + public: + Channel(const std::shared_ptr &pending_calls, + const std::shared_ptr &sender); + ~Channel(); - void call_method(std::string const& method_name, - google::protobuf::MessageLite const *parameters, - google::protobuf::MessageLite *response, - google::protobuf::Closure *complete); + void call_method(std::string const &method_name, + google::protobuf::MessageLite const *parameters, + google::protobuf::MessageLite *response, + google::protobuf::Closure *complete); - void send_event(google::protobuf::MessageLite const& event); + void send_event(google::protobuf::MessageLite const &event); -private: - protobuf::rpc::Invocation invocation_for( - std::string const& method_name, - google::protobuf::MessageLite const* request); - void send_message(const std::uint8_t &type, google::protobuf::MessageLite const& message); - std::uint32_t next_id(); - void notify_disconnected(); + private: + protobuf::rpc::Invocation invocation_for( + std::string const &method_name, + google::protobuf::MessageLite const *request); + void send_message(const std::uint8_t &type, + google::protobuf::MessageLite const &message); + std::uint32_t next_id(); + void notify_disconnected(); - std::shared_ptr pending_calls_; - std::shared_ptr sender_; - std::mutex write_mutex_; + std::shared_ptr pending_calls_; + std::shared_ptr sender_; + std::mutex write_mutex_; }; -} // namespace rpc -} // namespace anbox +} // namespace rpc +} // namespace anbox #endif diff --git a/src/anbox/rpc/connection_creator.cpp b/src/anbox/rpc/connection_creator.cpp index cd4d808..2989675 100644 --- a/src/anbox/rpc/connection_creator.cpp +++ b/src/anbox/rpc/connection_creator.cpp @@ -15,11 +15,10 @@ * */ - #include "anbox/rpc/connection_creator.h" -#include "anbox/rpc/message_processor.h" -#include "anbox/network/local_socket_messenger.h" #include "anbox/logger.h" +#include "anbox/network/local_socket_messenger.h" +#include "anbox/rpc/message_processor.h" #include @@ -27,40 +26,40 @@ namespace ba = boost::asio; namespace anbox { namespace rpc { -ConnectionCreator::ConnectionCreator(const std::shared_ptr &rt, const MessageProcessorFactory &factory) : - runtime_(rt), - next_connection_id_(0), - connections_(std::make_shared>()), - message_processor_factory_(factory) { -} +ConnectionCreator::ConnectionCreator(const std::shared_ptr& rt, + const MessageProcessorFactory& factory) + : runtime_(rt), + next_connection_id_(0), + connections_( + std::make_shared>()), + message_processor_factory_(factory) {} -ConnectionCreator::~ConnectionCreator() { -} +ConnectionCreator::~ConnectionCreator() {} void ConnectionCreator::create_connection_for( - std::shared_ptr const& socket) { + std::shared_ptr const& + socket) { + if (connections_->size() >= 1) { + socket->close(); + WARNING( + "A second client tried to connect. Denied request as we already have " + "one" + "and only allow a single client"); + return; + } - if (connections_->size() >= 1) { - socket->close(); - WARNING("A second client tried to connect. Denied request as we already have one" - "and only allow a single client"); - return; - } + auto const messenger = + std::make_shared(socket); + auto const processor = message_processor_factory_(messenger); - auto const messenger = std::make_shared(socket); - auto const processor = message_processor_factory_(messenger); - - auto const& connection = std::make_shared( - messenger, messenger, next_id(), connections_, processor); - connection->set_name("rpc"); - connections_->add(connection); - connection->read_next_message(); + auto const& connection = std::make_shared( + messenger, messenger, next_id(), connections_, processor); + connection->set_name("rpc"); + connections_->add(connection); + connection->read_next_message(); } -int ConnectionCreator::next_id() -{ - return next_connection_id_.fetch_add(1); -} +int ConnectionCreator::next_id() { return next_connection_id_.fetch_add(1); } -} // namespace rpc -} // namespace anbox +} // namespace rpc +} // namespace anbox diff --git a/src/anbox/rpc/connection_creator.h b/src/anbox/rpc/connection_creator.h index 12bcaf6..960e47f 100644 --- a/src/anbox/rpc/connection_creator.h +++ b/src/anbox/rpc/connection_creator.h @@ -23,35 +23,39 @@ #include #include "anbox/do_not_copy_or_move.h" -#include "anbox/runtime.h" +#include "anbox/network/connection_creator.h" #include "anbox/network/connections.h" #include "anbox/network/socket_connection.h" -#include "anbox/network/connection_creator.h" #include "anbox/network/socket_messenger.h" +#include "anbox/runtime.h" namespace anbox { namespace rpc { -class ConnectionCreator : public network::ConnectionCreator { -public: - typedef std::function( - const std::shared_ptr&)> MessageProcessorFactory; +class ConnectionCreator + : public network::ConnectionCreator { + public: + typedef std::function( + const std::shared_ptr &)> + MessageProcessorFactory; - ConnectionCreator( - const std::shared_ptr &rt, const MessageProcessorFactory &factory); - ~ConnectionCreator() noexcept; + ConnectionCreator(const std::shared_ptr &rt, + const MessageProcessorFactory &factory); + ~ConnectionCreator() noexcept; - void create_connection_for( - std::shared_ptr> const& socket) override; + void create_connection_for( + std::shared_ptr> const &socket) override; -private: - int next_id(); + private: + int next_id(); - std::shared_ptr runtime_; - std::atomic next_connection_id_; - std::shared_ptr> const connections_; - MessageProcessorFactory message_processor_factory_; + std::shared_ptr runtime_; + std::atomic next_connection_id_; + std::shared_ptr> const + connections_; + MessageProcessorFactory message_processor_factory_; }; -} // namespace rpc -} // namespace anbox +} // namespace rpc +} // namespace anbox #endif diff --git a/src/anbox/rpc/constants.h b/src/anbox/rpc/constants.h index 9c0621e..1d4265a 100644 --- a/src/anbox/rpc/constants.h +++ b/src/anbox/rpc/constants.h @@ -24,10 +24,10 @@ static constexpr const long header_size{3}; static constexpr unsigned int const serialization_buffer_size{2048}; enum MessageType { - invocation = 0, - response = 1, + invocation = 0, + response = 1, }; -} // namespace rpc -} // namespace network +} // namespace rpc +} // namespace network #endif diff --git a/src/anbox/rpc/make_protobuf_object.h b/src/anbox/rpc/make_protobuf_object.h index 9e42b66..a1ba08d 100644 --- a/src/anbox/rpc/make_protobuf_object.h +++ b/src/anbox/rpc/make_protobuf_object.h @@ -25,16 +25,16 @@ namespace anbox { namespace rpc { template auto make_protobuf_object() { - return std::unique_ptr{ProtobufType::default_instance().New()}; + return std::unique_ptr{ProtobufType::default_instance().New()}; } template auto make_protobuf_object(ProtobufType const& from) { - auto object = make_protobuf_object(); - object->CopyFrom(from); - return object; + auto object = make_protobuf_object(); + object->CopyFrom(from); + return object; } -} // namespace rpc -} // namespace anbox +} // namespace rpc +} // namespace anbox #endif diff --git a/src/anbox/rpc/message_processor.cpp b/src/anbox/rpc/message_processor.cpp index c9134c6..c1a9d95 100644 --- a/src/anbox/rpc/message_processor.cpp +++ b/src/anbox/rpc/message_processor.cpp @@ -16,103 +16,98 @@ */ #include "anbox/rpc/message_processor.h" -#include "anbox/rpc/template_message_processor.h" -#include "anbox/rpc/make_protobuf_object.h" -#include "anbox/rpc/constants.h" #include "anbox/common/variable_length_array.h" +#include "anbox/rpc/constants.h" +#include "anbox/rpc/make_protobuf_object.h" +#include "anbox/rpc/template_message_processor.h" #include "anbox_rpc.pb.h" namespace anbox { namespace rpc { -const ::std::string& Invocation::method_name() const { - return invocation_.method_name(); +const ::std::string &Invocation::method_name() const { + return invocation_.method_name(); } -const ::std::string& Invocation::parameters() const { - return invocation_.parameters(); +const ::std::string &Invocation::parameters() const { + return invocation_.parameters(); } -google::protobuf::uint32 Invocation::id() const { - return invocation_.id(); -} +google::protobuf::uint32 Invocation::id() const { return invocation_.id(); } -MessageProcessor::MessageProcessor(const std::shared_ptr &sender, - const std::shared_ptr &pending_calls) : - sender_(sender), - pending_calls_(pending_calls) { -} +MessageProcessor::MessageProcessor( + const std::shared_ptr &sender, + const std::shared_ptr &pending_calls) + : sender_(sender), pending_calls_(pending_calls) {} -MessageProcessor::~MessageProcessor() { -} +MessageProcessor::~MessageProcessor() {} bool MessageProcessor::process_data(const std::vector &data) { - for (const auto &byte : data) - buffer_.push_back(byte); + for (const auto &byte : data) buffer_.push_back(byte); - while (buffer_.size() > 0) { - const auto high = buffer_[0]; - const auto low = buffer_[1]; - size_t const message_size = (high << 8) + low; - const auto message_type = buffer_[2]; + while (buffer_.size() > 0) { + const auto high = buffer_[0]; + const auto low = buffer_[1]; + size_t const message_size = (high << 8) + low; + const auto message_type = buffer_[2]; - // If we don't have yet all bytes for a new message return and wait - // until we have all. - if (buffer_.size() - header_size < message_size) - break; + // If we don't have yet all bytes for a new message return and wait + // until we have all. + if (buffer_.size() - header_size < message_size) break; - if (message_type == MessageType::invocation) { - anbox::protobuf::rpc::Invocation raw_invocation; - raw_invocation.ParseFromArray(buffer_.data() + header_size, message_size); + if (message_type == MessageType::invocation) { + anbox::protobuf::rpc::Invocation raw_invocation; + raw_invocation.ParseFromArray(buffer_.data() + header_size, message_size); - dispatch(Invocation(raw_invocation)); - } - else if (message_type == MessageType::response) { - auto result = make_protobuf_object(); - result->ParseFromArray(buffer_.data() + header_size, message_size); + dispatch(Invocation(raw_invocation)); + } else if (message_type == MessageType::response) { + auto result = make_protobuf_object(); + result->ParseFromArray(buffer_.data() + header_size, message_size); - if (result->has_id()) - pending_calls_->complete_response(*result); + if (result->has_id()) pending_calls_->complete_response(*result); - for (int n = 0; n < result->events_size(); n++) - process_event_sequence(result->events(n)); - } - - buffer_.erase(buffer_.begin(), buffer_.begin() + header_size + message_size); + for (int n = 0; n < result->events_size(); n++) + process_event_sequence(result->events(n)); } - return true; + buffer_.erase(buffer_.begin(), + buffer_.begin() + header_size + message_size); + } + + return true; } -void MessageProcessor::send_response(::google::protobuf::uint32 id, google::protobuf::MessageLite *response) { - VariableLengthArray send_response_buffer( - static_cast(response->ByteSize())); +void MessageProcessor::send_response(::google::protobuf::uint32 id, + google::protobuf::MessageLite *response) { + VariableLengthArray send_response_buffer( + static_cast(response->ByteSize())); - response->SerializeWithCachedSizesToArray(send_response_buffer.data()); + response->SerializeWithCachedSizesToArray(send_response_buffer.data()); - anbox::protobuf::rpc::Result send_response_result; - send_response_result.set_id(id); - send_response_result.set_response(send_response_buffer.data(), send_response_buffer.size()); + anbox::protobuf::rpc::Result send_response_result; + send_response_result.set_id(id); + send_response_result.set_response(send_response_buffer.data(), + send_response_buffer.size()); - send_response_buffer.resize(send_response_result.ByteSize()); - send_response_result.SerializeWithCachedSizesToArray(send_response_buffer.data()); + send_response_buffer.resize(send_response_result.ByteSize()); + send_response_result.SerializeWithCachedSizesToArray( + send_response_buffer.data()); - const size_t size = send_response_buffer.size(); - const unsigned char header_bytes[header_size] = { - static_cast((size >> 8) & 0xff), - static_cast((size >> 0) & 0xff), - MessageType::response, - }; + const size_t size = send_response_buffer.size(); + const unsigned char header_bytes[header_size] = { + static_cast((size >> 8) & 0xff), + static_cast((size >> 0) & 0xff), MessageType::response, + }; - std::vector send_buffer(sizeof(header_bytes) + size); - std::copy(header_bytes, - header_bytes + sizeof(header_bytes), - send_buffer.begin()); - std::copy(send_response_buffer.data(), - send_response_buffer.data() + send_response_buffer.size(), - send_buffer.begin() + sizeof(header_bytes)); + std::vector send_buffer(sizeof(header_bytes) + size); + std::copy(header_bytes, header_bytes + sizeof(header_bytes), + send_buffer.begin()); + std::copy(send_response_buffer.data(), + send_response_buffer.data() + send_response_buffer.size(), + send_buffer.begin() + sizeof(header_bytes)); - sender_->send(reinterpret_cast(send_buffer.data()), send_buffer.size()); + sender_->send(reinterpret_cast(send_buffer.data()), + send_buffer.size()); } -} // namespace anbox -} // namespace network +} // namespace anbox +} // namespace network diff --git a/src/anbox/rpc/message_processor.h b/src/anbox/rpc/message_processor.h index dd6a44e..0bec3f3 100644 --- a/src/anbox/rpc/message_processor.h +++ b/src/anbox/rpc/message_processor.h @@ -24,48 +24,49 @@ #include -#include #include +#include namespace anbox { namespace protobuf { namespace rpc { class Invocation; -} // namespace rpc -} // namespace protobuf +} // namespace rpc +} // namespace protobuf namespace rpc { -class Invocation -{ -public: - Invocation(anbox::protobuf::rpc::Invocation const& invocation) : - invocation_(invocation) {} +class Invocation { + public: + Invocation(anbox::protobuf::rpc::Invocation const& invocation) + : invocation_(invocation) {} - const ::std::string& method_name() const; - const ::std::string& parameters() const; - google::protobuf::uint32 id() const; -private: - anbox::protobuf::rpc::Invocation const& invocation_; + const ::std::string& method_name() const; + const ::std::string& parameters() const; + google::protobuf::uint32 id() const; + + private: + anbox::protobuf::rpc::Invocation const& invocation_; }; class MessageProcessor : public network::MessageProcessor { -public: - MessageProcessor(const std::shared_ptr &sender, - const std::shared_ptr &pending_calls); - ~MessageProcessor(); + public: + MessageProcessor(const std::shared_ptr& sender, + const std::shared_ptr& pending_calls); + ~MessageProcessor(); - bool process_data(const std::vector &data) override; + bool process_data(const std::vector& data) override; - void send_response(::google::protobuf::uint32 id, google::protobuf::MessageLite *response); + void send_response(::google::protobuf::uint32 id, + google::protobuf::MessageLite* response); - virtual void dispatch(Invocation const& invocation) { } - virtual void process_event_sequence(const std::string &event) { } + virtual void dispatch(Invocation const& invocation) {} + virtual void process_event_sequence(const std::string& event) {} -private: - std::shared_ptr sender_; - std::vector buffer_; - std::shared_ptr pending_calls_; + private: + std::shared_ptr sender_; + std::vector buffer_; + std::shared_ptr pending_calls_; }; -} // namespace rpc -} // namespace anbox +} // namespace rpc +} // namespace anbox #endif diff --git a/src/anbox/rpc/pending_call_cache.cpp b/src/anbox/rpc/pending_call_cache.cpp index b1ddfdd..1e0ff78 100644 --- a/src/anbox/rpc/pending_call_cache.cpp +++ b/src/anbox/rpc/pending_call_cache.cpp @@ -22,51 +22,51 @@ namespace anbox { namespace rpc { -PendingCallCache::PendingCallCache() { +PendingCallCache::PendingCallCache() {} + +void PendingCallCache::save_completion_details( + anbox::protobuf::rpc::Invocation const& invocation, + google::protobuf::MessageLite* response, + google::protobuf::Closure* complete) { + std::unique_lock lock(mutex_); + pending_calls_[invocation.id()] = PendingCall(response, complete); } -void PendingCallCache::save_completion_details(anbox::protobuf::rpc::Invocation const &invocation, - google::protobuf::MessageLite *response, - google::protobuf::Closure *complete) { - std::unique_lock lock(mutex_); - pending_calls_[invocation.id()] = PendingCall(response, complete); -} - -void PendingCallCache::populate_message_for_result(anbox::protobuf::rpc::Result &result, - std::function const& populator) { - std::unique_lock lock(mutex_); - populator(pending_calls_.at(result.id()).response); +void PendingCallCache::populate_message_for_result( + anbox::protobuf::rpc::Result& result, + std::function const& populator) { + std::unique_lock lock(mutex_); + populator(pending_calls_.at(result.id()).response); } void PendingCallCache::complete_response(anbox::protobuf::rpc::Result& result) { - PendingCall completion; + PendingCall completion; - { - std::unique_lock lock(mutex_); - auto call = pending_calls_.find(result.id()); - if (call != pending_calls_.end()) { - completion = call->second; - pending_calls_.erase(call); - } + { + std::unique_lock lock(mutex_); + auto call = pending_calls_.find(result.id()); + if (call != pending_calls_.end()) { + completion = call->second; + pending_calls_.erase(call); } + } - if (completion.complete) - completion.complete->Run(); + if (completion.complete) completion.complete->Run(); } void PendingCallCache::force_completion() { - std::unique_lock lock(mutex_); - for (auto& call : pending_calls_) { - auto& completion = call.second; - completion.complete->Run(); - } + std::unique_lock lock(mutex_); + for (auto& call : pending_calls_) { + auto& completion = call.second; + completion.complete->Run(); + } - pending_calls_.erase(pending_calls_.begin(), pending_calls_.end()); + pending_calls_.erase(pending_calls_.begin(), pending_calls_.end()); } bool PendingCallCache::empty() const { - std::unique_lock lock(mutex_); - return pending_calls_.empty(); + std::unique_lock lock(mutex_); + return pending_calls_.empty(); } -} // namespace rpc -} // namespace anbox +} // namespace rpc +} // namespace anbox diff --git a/src/anbox/rpc/pending_call_cache.h b/src/anbox/rpc/pending_call_cache.h index 8ea9c78..f35ef9a 100644 --- a/src/anbox/rpc/pending_call_cache.h +++ b/src/anbox/rpc/pending_call_cache.h @@ -20,58 +20,55 @@ #define ANBOX_RPC_PENDING_CALL_CACHE_ #include -#include #include +#include namespace google { namespace protobuf { class Closure; class MessageLite; -} // namespace protobuf -} // namespace google +} // namespace protobuf +} // namespace google namespace anbox { namespace protobuf { namespace rpc { class Invocation; class Result; -} // namespace rpc -} // namespace protobuf +} // namespace rpc +} // namespace protobuf namespace rpc { class PendingCallCache { -public: - PendingCallCache(); + public: + PendingCallCache(); - void save_completion_details(anbox::protobuf::rpc::Invocation const &invocation, - google::protobuf::MessageLite *response, - google::protobuf::Closure *complete); - void populate_message_for_result(anbox::protobuf::rpc::Result &result, - std::function const& populator); - void complete_response(anbox::protobuf::rpc::Result& result); - void force_completion(); - bool empty() const; + void save_completion_details( + anbox::protobuf::rpc::Invocation const &invocation, + google::protobuf::MessageLite *response, + google::protobuf::Closure *complete); + void populate_message_for_result( + anbox::protobuf::rpc::Result &result, + std::function const &populator); + void complete_response(anbox::protobuf::rpc::Result &result); + void force_completion(); + bool empty() const; -private: - struct PendingCall { - PendingCall(google::protobuf::MessageLite *response, - google::protobuf::Closure *target) : - response(response), - complete(target) { - } + private: + struct PendingCall { + PendingCall(google::protobuf::MessageLite *response, + google::protobuf::Closure *target) + : response(response), complete(target) {} - PendingCall() : - response(0), - complete() { - } + PendingCall() : response(0), complete() {} - google::protobuf::MessageLite *response; - google::protobuf::Closure *complete; - }; + google::protobuf::MessageLite *response; + google::protobuf::Closure *complete; + }; - std::mutex mutable mutex_; - std::map pending_calls_; + std::mutex mutable mutex_; + std::map pending_calls_; }; -} // namespace rpc -} // namespace anbox +} // namespace rpc +} // namespace anbox #endif diff --git a/src/anbox/rpc/template_message_processor.h b/src/anbox/rpc/template_message_processor.h index b2fe7d0..3032840 100644 --- a/src/anbox/rpc/template_message_processor.h +++ b/src/anbox/rpc/template_message_processor.h @@ -29,52 +29,44 @@ namespace anbox { namespace rpc { // Utility metafunction result_ptr_t<> allows invoke() to pick the right // send_response() overload. The base template resolves to the prototype -// "send_response(::google::protobuf::uint32 id, ::google::protobuf::Message* response)" +// "send_response(::google::protobuf::uint32 id, ::google::protobuf::Message* +// response)" // Client code may specialize result_ptr_t to resolve to another overload. -template struct result_ptr_t -{ typedef ::google::protobuf::MessageLite* type; }; +template +struct result_ptr_t { + typedef ::google::protobuf::MessageLite* type; +}; -// Boiler plate for unpacking a parameter message, invoking a server function, and +// Boiler plate for unpacking a parameter message, invoking a server function, +// and // sending the result message. Assumes the existence of Self::send_response(). -template -void invoke( - Self* self, - Bridge* rpc, - void (BridgeX::*function)( - ParameterMessage const* request, - ResultMessage* response, - ::google::protobuf::Closure* done), - Invocation const& invocation) -{ - ParameterMessage parameter_message; - if (!parameter_message.ParseFromString(invocation.parameters())) - throw std::runtime_error("Failed to parse message parameters!"); - ResultMessage result_message; +template +void invoke(Self* self, Bridge* rpc, + void (BridgeX::*function)(ParameterMessage const* request, + ResultMessage* response, + ::google::protobuf::Closure* done), + Invocation const& invocation) { + ParameterMessage parameter_message; + if (!parameter_message.ParseFromString(invocation.parameters())) + throw std::runtime_error("Failed to parse message parameters!"); + ResultMessage result_message; - try - { - std::unique_ptr callback( - google::protobuf::NewPermanentCallback< - Self, - ::google::protobuf::uint32, - typename result_ptr_t::type>( - self, - &Self::send_response, - invocation.id(), - &result_message)); + try { + std::unique_ptr callback( + google::protobuf::NewPermanentCallback< + Self, ::google::protobuf::uint32, + typename result_ptr_t::type>( + self, &Self::send_response, invocation.id(), &result_message)); - (rpc->*function)( - ¶meter_message, - &result_message, - callback.get()); - } - catch (std::exception const& x) - { - result_message.set_error(std::string("Error processing request: ") + x.what()); - self->send_response(invocation.id(), &result_message); - } + (rpc->*function)(¶meter_message, &result_message, callback.get()); + } catch (std::exception const& x) { + result_message.set_error(std::string("Error processing request: ") + + x.what()); + self->send_response(invocation.id(), &result_message); + } } -} // namespace rpc -} // namespace anbox +} // namespace rpc +} // namespace anbox #endif diff --git a/src/anbox/runtime.cpp b/src/anbox/runtime.cpp index 58358b0..896a0c1 100644 --- a/src/anbox/runtime.cpp +++ b/src/anbox/runtime.cpp @@ -20,80 +20,70 @@ #include "anbox/logger.h" #include "anbox/runtime.h" -namespace -{ +namespace { // exception_safe_run runs service, catching all exceptions and // restarting operation until an explicit shutdown has been requested. // -// TODO(tvoss): Catching all exceptions is risky as they might signal unrecoverable -// errors. We should enable calling code to decide whether an exception should be considered +// TODO(tvoss): Catching all exceptions is risky as they might signal +// unrecoverable +// errors. We should enable calling code to decide whether an exception should +// be considered // fatal or not. void exception_safe_run(boost::asio::io_service& service) { - while (true) { - try { - service.run(); - // a clean return from run only happens in case of - // stop() being called (we are keeping the service alive with - // a service::work instance). - break; - } - catch (const std::exception& e) { - std::cerr << e.what() << std::endl; - } - catch (...) { - std::cerr << "Unknown exception caught while executing boost::asio::io_service"; - } + while (true) { + try { + service.run(); + // a clean return from run only happens in case of + // stop() being called (we are keeping the service alive with + // a service::work instance). + break; + } catch (const std::exception& e) { + std::cerr << e.what() << std::endl; + } catch (...) { + std::cerr + << "Unknown exception caught while executing boost::asio::io_service"; } + } } } namespace anbox { std::shared_ptr Runtime::create(std::uint32_t pool_size) { - return std::shared_ptr(new Runtime(pool_size)); + return std::shared_ptr(new Runtime(pool_size)); } -Runtime::Runtime(std::uint32_t pool_size) : - pool_size_{pool_size}, - service_{pool_size_}, - strand_{service_}, - keep_alive_{service_} { -} +Runtime::Runtime(std::uint32_t pool_size) + : pool_size_{pool_size}, + service_{pool_size_}, + strand_{service_}, + keep_alive_{service_} {} Runtime::~Runtime() { - try { - stop(); - } - catch(...) { - // Dropping all exceptions to satisfy the nothrow guarantee. - } + try { + stop(); + } catch (...) { + // Dropping all exceptions to satisfy the nothrow guarantee. + } } void Runtime::start() { - for (unsigned int i = 0; i < pool_size_; i++) - workers_.push_back(std::thread{exception_safe_run, std::ref(service_)}); + for (unsigned int i = 0; i < pool_size_; i++) + workers_.push_back(std::thread{exception_safe_run, std::ref(service_)}); } void Runtime::stop() { - service_.stop(); + service_.stop(); - for (auto& worker : workers_) - pthread_kill(worker.native_handle(), SIGTERM); + for (auto& worker : workers_) pthread_kill(worker.native_handle(), SIGTERM); } -std::function)> Runtime::to_dispatcher_functional() -{ - // We have to make sure that we stay alive for as long as - // calling code requires the dispatcher to work. - auto sp = shared_from_this(); - return [sp](std::function task) - { - sp->strand_.post(task); - }; +std::function)> Runtime::to_dispatcher_functional() { + // We have to make sure that we stay alive for as long as + // calling code requires the dispatcher to work. + auto sp = shared_from_this(); + return [sp](std::function task) { sp->strand_.post(task); }; } -boost::asio::io_service& Runtime::service() { - return service_; -} +boost::asio::io_service& Runtime::service() { return service_; } - -} // namespace anbox +} // namespace anbox diff --git a/src/anbox/runtime.h b/src/anbox/runtime.h index 5d3d75a..43065be 100644 --- a/src/anbox/runtime.h +++ b/src/anbox/runtime.h @@ -20,8 +20,8 @@ #include -#include #include +#include #include #include "anbox/do_not_copy_or_move.h" @@ -33,44 +33,45 @@ namespace anbox { // another , forcing execution to a well known set of threads. class Runtime : public DoNotCopyOrMove, public std::enable_shared_from_this { -public: - // Our default concurrency setup. - static constexpr const std::uint32_t worker_threads = 8; + public: + // Our default concurrency setup. + static constexpr const std::uint32_t worker_threads = 8; - // create returns a Runtime instance with pool_size worker threads - // executing the underlying service. - static std::shared_ptr create(std::uint32_t pool_size = worker_threads); + // create returns a Runtime instance with pool_size worker threads + // executing the underlying service. + static std::shared_ptr create( + std::uint32_t pool_size = worker_threads); - // Tears down the runtime, stopping all worker threads. - ~Runtime() noexcept(true); + // Tears down the runtime, stopping all worker threads. + ~Runtime() noexcept(true); - // start executes the underlying io_service on a thread pool with - // the size configured at creation time. - void start(); + // start executes the underlying io_service on a thread pool with + // the size configured at creation time. + void start(); - // stop cleanly shuts down a Runtime instance. - void stop(); + // stop cleanly shuts down a Runtime instance. + void stop(); - // to_dispatcher_functional returns a function for integration - // with components that expect a dispatcher for operation. - std::function)> to_dispatcher_functional(); + // to_dispatcher_functional returns a function for integration + // with components that expect a dispatcher for operation. + std::function)> to_dispatcher_functional(); - // service returns the underlying boost::asio::io_service that is executed - // by the Runtime. - boost::asio::io_service& service(); + // service returns the underlying boost::asio::io_service that is executed + // by the Runtime. + boost::asio::io_service& service(); -private: - // Runtime constructs a new instance, firing up pool_size - // worker threads. - Runtime(std::uint32_t pool_size); + private: + // Runtime constructs a new instance, firing up pool_size + // worker threads. + Runtime(std::uint32_t pool_size); - std::uint32_t pool_size_; - boost::asio::io_service service_; - boost::asio::io_service::strand strand_; - boost::asio::io_service::work keep_alive_; - std::vector workers_; + std::uint32_t pool_size_; + boost::asio::io_service service_; + boost::asio::io_service::strand strand_; + boost::asio::io_service::work keep_alive_; + std::vector workers_; }; -} // namespace anbox +} // namespace anbox #endif diff --git a/src/anbox/ubuntu/keycode_converter.cpp b/src/anbox/ubuntu/keycode_converter.cpp index ac2d46d..e3d4eaf 100644 --- a/src/anbox/ubuntu/keycode_converter.cpp +++ b/src/anbox/ubuntu/keycode_converter.cpp @@ -22,194 +22,195 @@ namespace anbox { namespace ubuntu { std::uint16_t KeycodeConverter::convert(const SDL_Scancode &scan_code) { - for (std::uint16_t n = 0; n < code_map.size(); n++) { - if (code_map[n] == scan_code) - return n; - } - return KEY_RESERVED; + for (std::uint16_t n = 0; n < code_map.size(); n++) { + if (code_map[n] == scan_code) return n; + } + return KEY_RESERVED; } const std::array KeycodeConverter::code_map = {{ - SDL_SCANCODE_UNKNOWN, /* KEY_RESERVED 0 */ - SDL_SCANCODE_ESCAPE, /* KEY_ESC 1 */ - SDL_SCANCODE_1, /* KEY_1 2 */ - SDL_SCANCODE_2, /* KEY_2 3 */ - SDL_SCANCODE_3, /* KEY_3 4 */ - SDL_SCANCODE_4, /* KEY_4 5 */ - SDL_SCANCODE_5, /* KEY_5 6 */ - SDL_SCANCODE_6, /* KEY_6 7 */ - SDL_SCANCODE_7, /* KEY_7 8 */ - SDL_SCANCODE_8, /* KEY_8 9 */ - SDL_SCANCODE_9, /* KEY_9 10 */ - SDL_SCANCODE_0, /* KEY_0 11 */ - SDL_SCANCODE_MINUS, /* KEY_MINUS 12 */ - SDL_SCANCODE_EQUALS, /* KEY_EQUAL 13 */ - SDL_SCANCODE_BACKSPACE, /* KEY_BACKSPACE 14 */ - SDL_SCANCODE_TAB, /* KEY_TAB 15 */ - SDL_SCANCODE_Q, /* KEY_Q 16 */ - SDL_SCANCODE_W, /* KEY_W 17 */ - SDL_SCANCODE_E, /* KEY_E 18 */ - SDL_SCANCODE_R, /* KEY_R 19 */ - SDL_SCANCODE_T, /* KEY_T 20 */ - SDL_SCANCODE_Y, /* KEY_Y 21 */ - SDL_SCANCODE_U, /* KEY_U 22 */ - SDL_SCANCODE_I, /* KEY_I 23 */ - SDL_SCANCODE_O, /* KEY_O 24 */ - SDL_SCANCODE_P, /* KEY_P 25 */ - SDL_SCANCODE_LEFTBRACKET, /* KEY_LEFTBRACE 26 */ - SDL_SCANCODE_RIGHTBRACKET, /* KEY_RIGHTBRACE 27 */ - SDL_SCANCODE_RETURN, /* KEY_ENTER 28 */ - SDL_SCANCODE_LCTRL, /* KEY_LEFTCTRL 29 */ - SDL_SCANCODE_A, /* KEY_A 30 */ - SDL_SCANCODE_S, /* KEY_S 31 */ - SDL_SCANCODE_D, /* KEY_D 32 */ - SDL_SCANCODE_F, /* KEY_F 33 */ - SDL_SCANCODE_G, /* KEY_G 34 */ - SDL_SCANCODE_H, /* KEY_H 35 */ - SDL_SCANCODE_J, /* KEY_J 36 */ - SDL_SCANCODE_K, /* KEY_K 37 */ - SDL_SCANCODE_L, /* KEY_L 38 */ - SDL_SCANCODE_SEMICOLON, /* KEY_SEMICOLON 39 */ - SDL_SCANCODE_APOSTROPHE, /* KEY_APOSTROPHE 40 */ - SDL_SCANCODE_GRAVE, /* KEY_GRAVE 41 */ - SDL_SCANCODE_LSHIFT, /* KEY_LEFTSHIFT 42 */ - SDL_SCANCODE_BACKSLASH, /* KEY_BACKSLASH 43 */ - SDL_SCANCODE_Z, /* KEY_Z 44 */ - SDL_SCANCODE_X, /* KEY_X 45 */ - SDL_SCANCODE_C, /* KEY_C 46 */ - SDL_SCANCODE_V, /* KEY_V 47 */ - SDL_SCANCODE_B, /* KEY_B 48 */ - SDL_SCANCODE_N, /* KEY_N 49 */ - SDL_SCANCODE_M, /* KEY_M 50 */ - SDL_SCANCODE_COMMA, /* KEY_COMMA 51 */ - SDL_SCANCODE_PERIOD, /* KEY_DOT 52 */ - SDL_SCANCODE_SLASH, /* KEY_SLASH 53 */ - SDL_SCANCODE_RSHIFT, /* KEY_RIGHTSHIFT 54 */ - SDL_SCANCODE_KP_MULTIPLY, /* KEY_KPASTERISK 55 */ - SDL_SCANCODE_LALT, /* KEY_LEFTALT 56 */ - SDL_SCANCODE_SPACE, /* KEY_SPACE 57 */ - SDL_SCANCODE_CAPSLOCK, /* KEY_CAPSLOCK 58 */ - SDL_SCANCODE_F1, /* KEY_F1 59 */ - SDL_SCANCODE_F2, /* KEY_F2 60 */ - SDL_SCANCODE_F3, /* KEY_F3 61 */ - SDL_SCANCODE_F4, /* KEY_F4 62 */ - SDL_SCANCODE_F5, /* KEY_F5 63 */ - SDL_SCANCODE_F6, /* KEY_F6 64 */ - SDL_SCANCODE_F7, /* KEY_F7 65 */ - SDL_SCANCODE_F8, /* KEY_F8 66 */ - SDL_SCANCODE_F9, /* KEY_F9 67 */ - SDL_SCANCODE_F10, /* KEY_F10 68 */ - SDL_SCANCODE_NUMLOCKCLEAR, /* KEY_NUMLOCK 69 */ - SDL_SCANCODE_SCROLLLOCK, /* KEY_SCROLLLOCK 70 */ - SDL_SCANCODE_KP_7, /* KEY_KP7 71 */ - SDL_SCANCODE_KP_8, /* KEY_KP8 72 */ - SDL_SCANCODE_KP_9, /* KEY_KP9 73 */ - SDL_SCANCODE_KP_MINUS, /* KEY_KPMINUS 74 */ - SDL_SCANCODE_KP_4, /* KEY_KP4 75 */ - SDL_SCANCODE_KP_5, /* KEY_KP5 76 */ - SDL_SCANCODE_KP_6, /* KEY_KP6 77 */ - SDL_SCANCODE_KP_PLUS, /* KEY_KPPLUS 78 */ - SDL_SCANCODE_KP_1, /* KEY_KP1 79 */ - SDL_SCANCODE_KP_2, /* KEY_KP2 80 */ - SDL_SCANCODE_KP_3, /* KEY_KP3 81 */ - SDL_SCANCODE_KP_0, /* KEY_KP0 82 */ - SDL_SCANCODE_KP_PERIOD, /* KEY_KPDOT 83 */ - SDL_SCANCODE_UNKNOWN, /* 84 */ - SDL_SCANCODE_LANG5, /* KEY_ZENKAKUHANKAKU 85 */ - SDL_SCANCODE_UNKNOWN, /* KEY_102ND 86 */ - SDL_SCANCODE_F11, /* KEY_F11 87 */ - SDL_SCANCODE_F12, /* KEY_F12 88 */ - SDL_SCANCODE_UNKNOWN, /* KEY_RO 89 */ - SDL_SCANCODE_LANG3, /* KEY_KATAKANA 90 */ - SDL_SCANCODE_LANG4, /* KEY_HIRAGANA 91 */ - SDL_SCANCODE_UNKNOWN, /* KEY_HENKAN 92 */ - SDL_SCANCODE_LANG3, /* KEY_KATAKANAHIRAGANA 93 */ - SDL_SCANCODE_UNKNOWN, /* KEY_MUHENKAN 94 */ - SDL_SCANCODE_KP_COMMA, /* KEY_KPJPCOMMA 95 */ - SDL_SCANCODE_KP_ENTER, /* KEY_KPENTER 96 */ - SDL_SCANCODE_RCTRL, /* KEY_RIGHTCTRL 97 */ - SDL_SCANCODE_KP_DIVIDE, /* KEY_KPSLASH 98 */ - SDL_SCANCODE_SYSREQ, /* KEY_SYSRQ 99 */ - SDL_SCANCODE_RALT, /* KEY_RIGHTALT 100 */ - SDL_SCANCODE_UNKNOWN, /* KEY_LINEFEED 101 */ - SDL_SCANCODE_HOME, /* KEY_HOME 102 */ - SDL_SCANCODE_UP, /* KEY_UP 103 */ - SDL_SCANCODE_PAGEUP, /* KEY_PAGEUP 104 */ - SDL_SCANCODE_LEFT, /* KEY_LEFT 105 */ - SDL_SCANCODE_RIGHT, /* KEY_RIGHT 106 */ - SDL_SCANCODE_END, /* KEY_END 107 */ - SDL_SCANCODE_DOWN, /* KEY_DOWN 108 */ - SDL_SCANCODE_PAGEDOWN, /* KEY_PAGEDOWN 109 */ - SDL_SCANCODE_INSERT, /* KEY_INSERT 110 */ - SDL_SCANCODE_DELETE, /* KEY_DELETE 111 */ - SDL_SCANCODE_UNKNOWN, /* KEY_MACRO 112 */ - SDL_SCANCODE_MUTE, /* KEY_MUTE 113 */ - SDL_SCANCODE_VOLUMEDOWN, /* KEY_VOLUMEDOWN 114 */ - SDL_SCANCODE_VOLUMEUP, /* KEY_VOLUMEUP 115 */ - SDL_SCANCODE_POWER, /* KEY_POWER 116 SC System Power Down */ - SDL_SCANCODE_KP_EQUALS, /* KEY_KPEQUAL 117 */ - SDL_SCANCODE_KP_MINUS, /* KEY_KPPLUSMINUS 118 */ - SDL_SCANCODE_PAUSE, /* KEY_PAUSE 119 */ - SDL_SCANCODE_UNKNOWN, /* KEY_SCALE 120 AL Compiz Scale (Expose) */ - SDL_SCANCODE_KP_COMMA, /* KEY_KPCOMMA 121 */ - SDL_SCANCODE_LANG1, /* KEY_HANGEUL,KEY_HANGUEL 122 */ - SDL_SCANCODE_LANG2, /* KEY_HANJA 123 */ - SDL_SCANCODE_INTERNATIONAL3,/* KEY_YEN 124 */ - SDL_SCANCODE_LGUI, /* KEY_LEFTMETA 125 */ - SDL_SCANCODE_RGUI, /* KEY_RIGHTMETA 126 */ - SDL_SCANCODE_APPLICATION, /* KEY_COMPOSE 127 */ - SDL_SCANCODE_STOP, /* KEY_STOP 128 AC Stop */ - SDL_SCANCODE_AGAIN, /* KEY_AGAIN 129 */ - SDL_SCANCODE_UNKNOWN, /* KEY_PROPS 130 AC Properties */ - SDL_SCANCODE_UNDO, /* KEY_UNDO 131 AC Undo */ - SDL_SCANCODE_UNKNOWN, /* KEY_FRONT 132 */ - SDL_SCANCODE_COPY, /* KEY_COPY 133 AC Copy */ - SDL_SCANCODE_UNKNOWN, /* KEY_OPEN 134 AC Open */ - SDL_SCANCODE_PASTE, /* KEY_PASTE 135 AC Paste */ - SDL_SCANCODE_FIND, /* KEY_FIND 136 AC Search */ - SDL_SCANCODE_CUT, /* KEY_CUT 137 AC Cut */ - SDL_SCANCODE_HELP, /* KEY_HELP 138 AL Integrated Help Center */ - SDL_SCANCODE_MENU, /* KEY_MENU 139 Menu (show menu) */ - SDL_SCANCODE_CALCULATOR, /* KEY_CALC 140 AL Calculator */ - SDL_SCANCODE_UNKNOWN, /* KEY_SETUP 141 */ - SDL_SCANCODE_SLEEP, /* KEY_SLEEP 142 SC System Sleep */ - SDL_SCANCODE_UNKNOWN, /* KEY_WAKEUP 143 System Wake Up */ - SDL_SCANCODE_UNKNOWN, /* KEY_FILE 144 AL Local Machine Browser */ - SDL_SCANCODE_UNKNOWN, /* KEY_SENDFILE 145 */ - SDL_SCANCODE_UNKNOWN, /* KEY_DELETEFILE 146 */ - SDL_SCANCODE_UNKNOWN, /* KEY_XFER 147 */ - SDL_SCANCODE_APP1, /* KEY_PROG1 148 */ - SDL_SCANCODE_APP1, /* KEY_PROG2 149 */ - SDL_SCANCODE_WWW, /* KEY_WWW 150 AL Internet Browser */ - SDL_SCANCODE_UNKNOWN, /* KEY_MSDOS 151 */ - SDL_SCANCODE_UNKNOWN, /* KEY_COFFEE,KEY_SCREENLOCK 152 AL Terminal Lock/Screensaver */ - SDL_SCANCODE_UNKNOWN, /* KEY_DIRECTION 153 */ - SDL_SCANCODE_UNKNOWN, /* KEY_CYCLEWINDOWS 154 */ - SDL_SCANCODE_MAIL, /* KEY_MAIL 155 */ - SDL_SCANCODE_AC_BOOKMARKS, /* KEY_BOOKMARKS 156 AC Bookmarks */ - SDL_SCANCODE_COMPUTER, /* KEY_COMPUTER 157 */ - SDL_SCANCODE_AC_BACK, /* KEY_BACK 158 AC Back */ - SDL_SCANCODE_AC_FORWARD, /* KEY_FORWARD 159 AC Forward */ - SDL_SCANCODE_UNKNOWN, /* KEY_CLOSECD 160 */ - SDL_SCANCODE_EJECT, /* KEY_EJECTCD 161 */ - SDL_SCANCODE_UNKNOWN, /* KEY_EJECTCLOSECD 162 */ - SDL_SCANCODE_AUDIONEXT, /* KEY_NEXTSONG 163 */ - SDL_SCANCODE_AUDIOPLAY, /* KEY_PLAYPAUSE 164 */ - SDL_SCANCODE_AUDIOPREV, /* KEY_PREVIOUSSONG 165 */ - SDL_SCANCODE_AUDIOSTOP, /* KEY_STOPCD 166 */ - SDL_SCANCODE_UNKNOWN, /* KEY_RECORD 167 */ - SDL_SCANCODE_UNKNOWN, /* KEY_REWIND 168 */ - SDL_SCANCODE_UNKNOWN, /* KEY_PHONE 169 Media Select Telephone */ - SDL_SCANCODE_UNKNOWN, /* KEY_ISO 170 */ - SDL_SCANCODE_UNKNOWN, /* KEY_CONFIG 171 AL Consumer Control Configuration */ - SDL_SCANCODE_AC_HOME, /* KEY_HOMEPAGE 172 AC Home */ - SDL_SCANCODE_AC_REFRESH, /* KEY_REFRESH 173 AC Refresh */ - SDL_SCANCODE_UNKNOWN, /* KEY_EXIT 174 AC Exit */ - SDL_SCANCODE_UNKNOWN, /* KEY_MOVE 175 */ - SDL_SCANCODE_UNKNOWN, /* KEY_EDIT 176 */ - SDL_SCANCODE_UNKNOWN, /* KEY_SCROLLUP 177 */ - SDL_SCANCODE_UNKNOWN, /* KEY_SCROLLDOWN 178 */ - SDL_SCANCODE_KP_LEFTPAREN, /* KEY_KPLEFTPAREN 179 */ + SDL_SCANCODE_UNKNOWN, /* KEY_RESERVED 0 */ + SDL_SCANCODE_ESCAPE, /* KEY_ESC 1 */ + SDL_SCANCODE_1, /* KEY_1 2 */ + SDL_SCANCODE_2, /* KEY_2 3 */ + SDL_SCANCODE_3, /* KEY_3 4 */ + SDL_SCANCODE_4, /* KEY_4 5 */ + SDL_SCANCODE_5, /* KEY_5 6 */ + SDL_SCANCODE_6, /* KEY_6 7 */ + SDL_SCANCODE_7, /* KEY_7 8 */ + SDL_SCANCODE_8, /* KEY_8 9 */ + SDL_SCANCODE_9, /* KEY_9 10 */ + SDL_SCANCODE_0, /* KEY_0 11 */ + SDL_SCANCODE_MINUS, /* KEY_MINUS 12 */ + SDL_SCANCODE_EQUALS, /* KEY_EQUAL 13 */ + SDL_SCANCODE_BACKSPACE, /* KEY_BACKSPACE 14 */ + SDL_SCANCODE_TAB, /* KEY_TAB 15 */ + SDL_SCANCODE_Q, /* KEY_Q 16 */ + SDL_SCANCODE_W, /* KEY_W 17 */ + SDL_SCANCODE_E, /* KEY_E 18 */ + SDL_SCANCODE_R, /* KEY_R 19 */ + SDL_SCANCODE_T, /* KEY_T 20 */ + SDL_SCANCODE_Y, /* KEY_Y 21 */ + SDL_SCANCODE_U, /* KEY_U 22 */ + SDL_SCANCODE_I, /* KEY_I 23 */ + SDL_SCANCODE_O, /* KEY_O 24 */ + SDL_SCANCODE_P, /* KEY_P 25 */ + SDL_SCANCODE_LEFTBRACKET, /* KEY_LEFTBRACE 26 */ + SDL_SCANCODE_RIGHTBRACKET, /* KEY_RIGHTBRACE 27 */ + SDL_SCANCODE_RETURN, /* KEY_ENTER 28 */ + SDL_SCANCODE_LCTRL, /* KEY_LEFTCTRL 29 */ + SDL_SCANCODE_A, /* KEY_A 30 */ + SDL_SCANCODE_S, /* KEY_S 31 */ + SDL_SCANCODE_D, /* KEY_D 32 */ + SDL_SCANCODE_F, /* KEY_F 33 */ + SDL_SCANCODE_G, /* KEY_G 34 */ + SDL_SCANCODE_H, /* KEY_H 35 */ + SDL_SCANCODE_J, /* KEY_J 36 */ + SDL_SCANCODE_K, /* KEY_K 37 */ + SDL_SCANCODE_L, /* KEY_L 38 */ + SDL_SCANCODE_SEMICOLON, /* KEY_SEMICOLON 39 */ + SDL_SCANCODE_APOSTROPHE, /* KEY_APOSTROPHE 40 */ + SDL_SCANCODE_GRAVE, /* KEY_GRAVE 41 */ + SDL_SCANCODE_LSHIFT, /* KEY_LEFTSHIFT 42 */ + SDL_SCANCODE_BACKSLASH, /* KEY_BACKSLASH 43 */ + SDL_SCANCODE_Z, /* KEY_Z 44 */ + SDL_SCANCODE_X, /* KEY_X 45 */ + SDL_SCANCODE_C, /* KEY_C 46 */ + SDL_SCANCODE_V, /* KEY_V 47 */ + SDL_SCANCODE_B, /* KEY_B 48 */ + SDL_SCANCODE_N, /* KEY_N 49 */ + SDL_SCANCODE_M, /* KEY_M 50 */ + SDL_SCANCODE_COMMA, /* KEY_COMMA 51 */ + SDL_SCANCODE_PERIOD, /* KEY_DOT 52 */ + SDL_SCANCODE_SLASH, /* KEY_SLASH 53 */ + SDL_SCANCODE_RSHIFT, /* KEY_RIGHTSHIFT 54 */ + SDL_SCANCODE_KP_MULTIPLY, /* KEY_KPASTERISK 55 */ + SDL_SCANCODE_LALT, /* KEY_LEFTALT 56 */ + SDL_SCANCODE_SPACE, /* KEY_SPACE 57 */ + SDL_SCANCODE_CAPSLOCK, /* KEY_CAPSLOCK 58 */ + SDL_SCANCODE_F1, /* KEY_F1 59 */ + SDL_SCANCODE_F2, /* KEY_F2 60 */ + SDL_SCANCODE_F3, /* KEY_F3 61 */ + SDL_SCANCODE_F4, /* KEY_F4 62 */ + SDL_SCANCODE_F5, /* KEY_F5 63 */ + SDL_SCANCODE_F6, /* KEY_F6 64 */ + SDL_SCANCODE_F7, /* KEY_F7 65 */ + SDL_SCANCODE_F8, /* KEY_F8 66 */ + SDL_SCANCODE_F9, /* KEY_F9 67 */ + SDL_SCANCODE_F10, /* KEY_F10 68 */ + SDL_SCANCODE_NUMLOCKCLEAR, /* KEY_NUMLOCK 69 */ + SDL_SCANCODE_SCROLLLOCK, /* KEY_SCROLLLOCK 70 */ + SDL_SCANCODE_KP_7, /* KEY_KP7 71 */ + SDL_SCANCODE_KP_8, /* KEY_KP8 72 */ + SDL_SCANCODE_KP_9, /* KEY_KP9 73 */ + SDL_SCANCODE_KP_MINUS, /* KEY_KPMINUS 74 */ + SDL_SCANCODE_KP_4, /* KEY_KP4 75 */ + SDL_SCANCODE_KP_5, /* KEY_KP5 76 */ + SDL_SCANCODE_KP_6, /* KEY_KP6 77 */ + SDL_SCANCODE_KP_PLUS, /* KEY_KPPLUS 78 */ + SDL_SCANCODE_KP_1, /* KEY_KP1 79 */ + SDL_SCANCODE_KP_2, /* KEY_KP2 80 */ + SDL_SCANCODE_KP_3, /* KEY_KP3 81 */ + SDL_SCANCODE_KP_0, /* KEY_KP0 82 */ + SDL_SCANCODE_KP_PERIOD, /* KEY_KPDOT 83 */ + SDL_SCANCODE_UNKNOWN, /* 84 */ + SDL_SCANCODE_LANG5, /* KEY_ZENKAKUHANKAKU 85 */ + SDL_SCANCODE_UNKNOWN, /* KEY_102ND 86 */ + SDL_SCANCODE_F11, /* KEY_F11 87 */ + SDL_SCANCODE_F12, /* KEY_F12 88 */ + SDL_SCANCODE_UNKNOWN, /* KEY_RO 89 */ + SDL_SCANCODE_LANG3, /* KEY_KATAKANA 90 */ + SDL_SCANCODE_LANG4, /* KEY_HIRAGANA 91 */ + SDL_SCANCODE_UNKNOWN, /* KEY_HENKAN 92 */ + SDL_SCANCODE_LANG3, /* KEY_KATAKANAHIRAGANA 93 */ + SDL_SCANCODE_UNKNOWN, /* KEY_MUHENKAN 94 */ + SDL_SCANCODE_KP_COMMA, /* KEY_KPJPCOMMA 95 */ + SDL_SCANCODE_KP_ENTER, /* KEY_KPENTER 96 */ + SDL_SCANCODE_RCTRL, /* KEY_RIGHTCTRL 97 */ + SDL_SCANCODE_KP_DIVIDE, /* KEY_KPSLASH 98 */ + SDL_SCANCODE_SYSREQ, /* KEY_SYSRQ 99 */ + SDL_SCANCODE_RALT, /* KEY_RIGHTALT 100 */ + SDL_SCANCODE_UNKNOWN, /* KEY_LINEFEED 101 */ + SDL_SCANCODE_HOME, /* KEY_HOME 102 */ + SDL_SCANCODE_UP, /* KEY_UP 103 */ + SDL_SCANCODE_PAGEUP, /* KEY_PAGEUP 104 */ + SDL_SCANCODE_LEFT, /* KEY_LEFT 105 */ + SDL_SCANCODE_RIGHT, /* KEY_RIGHT 106 */ + SDL_SCANCODE_END, /* KEY_END 107 */ + SDL_SCANCODE_DOWN, /* KEY_DOWN 108 */ + SDL_SCANCODE_PAGEDOWN, /* KEY_PAGEDOWN 109 */ + SDL_SCANCODE_INSERT, /* KEY_INSERT 110 */ + SDL_SCANCODE_DELETE, /* KEY_DELETE 111 */ + SDL_SCANCODE_UNKNOWN, /* KEY_MACRO 112 */ + SDL_SCANCODE_MUTE, /* KEY_MUTE 113 */ + SDL_SCANCODE_VOLUMEDOWN, /* KEY_VOLUMEDOWN 114 */ + SDL_SCANCODE_VOLUMEUP, /* KEY_VOLUMEUP 115 */ + SDL_SCANCODE_POWER, /* KEY_POWER 116 SC System Power Down */ + SDL_SCANCODE_KP_EQUALS, /* KEY_KPEQUAL 117 */ + SDL_SCANCODE_KP_MINUS, /* KEY_KPPLUSMINUS 118 */ + SDL_SCANCODE_PAUSE, /* KEY_PAUSE 119 */ + SDL_SCANCODE_UNKNOWN, /* KEY_SCALE 120 AL Compiz Scale (Expose) */ + SDL_SCANCODE_KP_COMMA, /* KEY_KPCOMMA 121 */ + SDL_SCANCODE_LANG1, /* KEY_HANGEUL,KEY_HANGUEL 122 */ + SDL_SCANCODE_LANG2, /* KEY_HANJA 123 */ + SDL_SCANCODE_INTERNATIONAL3, /* KEY_YEN 124 */ + SDL_SCANCODE_LGUI, /* KEY_LEFTMETA 125 */ + SDL_SCANCODE_RGUI, /* KEY_RIGHTMETA 126 */ + SDL_SCANCODE_APPLICATION, /* KEY_COMPOSE 127 */ + SDL_SCANCODE_STOP, /* KEY_STOP 128 AC Stop */ + SDL_SCANCODE_AGAIN, /* KEY_AGAIN 129 */ + SDL_SCANCODE_UNKNOWN, /* KEY_PROPS 130 AC Properties */ + SDL_SCANCODE_UNDO, /* KEY_UNDO 131 AC Undo */ + SDL_SCANCODE_UNKNOWN, /* KEY_FRONT 132 */ + SDL_SCANCODE_COPY, /* KEY_COPY 133 AC Copy */ + SDL_SCANCODE_UNKNOWN, /* KEY_OPEN 134 AC Open */ + SDL_SCANCODE_PASTE, /* KEY_PASTE 135 AC Paste */ + SDL_SCANCODE_FIND, /* KEY_FIND 136 AC Search */ + SDL_SCANCODE_CUT, /* KEY_CUT 137 AC Cut */ + SDL_SCANCODE_HELP, /* KEY_HELP 138 AL Integrated Help Center */ + SDL_SCANCODE_MENU, /* KEY_MENU 139 Menu (show menu) */ + SDL_SCANCODE_CALCULATOR, /* KEY_CALC 140 AL Calculator */ + SDL_SCANCODE_UNKNOWN, /* KEY_SETUP 141 */ + SDL_SCANCODE_SLEEP, /* KEY_SLEEP 142 SC System Sleep */ + SDL_SCANCODE_UNKNOWN, /* KEY_WAKEUP 143 System Wake Up */ + SDL_SCANCODE_UNKNOWN, /* KEY_FILE 144 AL Local Machine Browser */ + SDL_SCANCODE_UNKNOWN, /* KEY_SENDFILE 145 */ + SDL_SCANCODE_UNKNOWN, /* KEY_DELETEFILE 146 */ + SDL_SCANCODE_UNKNOWN, /* KEY_XFER 147 */ + SDL_SCANCODE_APP1, /* KEY_PROG1 148 */ + SDL_SCANCODE_APP1, /* KEY_PROG2 149 */ + SDL_SCANCODE_WWW, /* KEY_WWW 150 AL Internet Browser */ + SDL_SCANCODE_UNKNOWN, /* KEY_MSDOS 151 */ + SDL_SCANCODE_UNKNOWN, /* KEY_COFFEE,KEY_SCREENLOCK 152 AL Terminal + Lock/Screensaver */ + SDL_SCANCODE_UNKNOWN, /* KEY_DIRECTION 153 */ + SDL_SCANCODE_UNKNOWN, /* KEY_CYCLEWINDOWS 154 */ + SDL_SCANCODE_MAIL, /* KEY_MAIL 155 */ + SDL_SCANCODE_AC_BOOKMARKS, /* KEY_BOOKMARKS 156 AC Bookmarks */ + SDL_SCANCODE_COMPUTER, /* KEY_COMPUTER 157 */ + SDL_SCANCODE_AC_BACK, /* KEY_BACK 158 AC Back */ + SDL_SCANCODE_AC_FORWARD, /* KEY_FORWARD 159 AC Forward */ + SDL_SCANCODE_UNKNOWN, /* KEY_CLOSECD 160 */ + SDL_SCANCODE_EJECT, /* KEY_EJECTCD 161 */ + SDL_SCANCODE_UNKNOWN, /* KEY_EJECTCLOSECD 162 */ + SDL_SCANCODE_AUDIONEXT, /* KEY_NEXTSONG 163 */ + SDL_SCANCODE_AUDIOPLAY, /* KEY_PLAYPAUSE 164 */ + SDL_SCANCODE_AUDIOPREV, /* KEY_PREVIOUSSONG 165 */ + SDL_SCANCODE_AUDIOSTOP, /* KEY_STOPCD 166 */ + SDL_SCANCODE_UNKNOWN, /* KEY_RECORD 167 */ + SDL_SCANCODE_UNKNOWN, /* KEY_REWIND 168 */ + SDL_SCANCODE_UNKNOWN, /* KEY_PHONE 169 Media Select Telephone */ + SDL_SCANCODE_UNKNOWN, /* KEY_ISO 170 */ + SDL_SCANCODE_UNKNOWN, /* KEY_CONFIG 171 AL Consumer Control + Configuration */ + SDL_SCANCODE_AC_HOME, /* KEY_HOMEPAGE 172 AC Home */ + SDL_SCANCODE_AC_REFRESH, /* KEY_REFRESH 173 AC Refresh */ + SDL_SCANCODE_UNKNOWN, /* KEY_EXIT 174 AC Exit */ + SDL_SCANCODE_UNKNOWN, /* KEY_MOVE 175 */ + SDL_SCANCODE_UNKNOWN, /* KEY_EDIT 176 */ + SDL_SCANCODE_UNKNOWN, /* KEY_SCROLLUP 177 */ + SDL_SCANCODE_UNKNOWN, /* KEY_SCROLLDOWN 178 */ + SDL_SCANCODE_KP_LEFTPAREN, /* KEY_KPLEFTPAREN 179 */ SDL_SCANCODE_KP_RIGHTPAREN, /* KEY_KPRIGHTPAREN 180 */ SDL_SCANCODE_UNKNOWN, /* KEY_NEW 181 AC New */ SDL_SCANCODE_AGAIN, /* KEY_REDO 182 AC Redo/Repeat */ @@ -257,28 +258,34 @@ const std::array KeycodeConverter::code_map = {{ SDL_SCANCODE_UNKNOWN, /* KEY_BRIGHTNESSDOWN 224 */ SDL_SCANCODE_UNKNOWN, /* KEY_BRIGHTNESSUP 225 */ SDL_SCANCODE_UNKNOWN, /* KEY_MEDIA 226 */ - SDL_SCANCODE_UNKNOWN, /* KEY_SWITCHVIDEOMODE 227 Cycle between available video outputs (Monitor/LCD/TV-out/etc) */ - SDL_SCANCODE_UNKNOWN, /* KEY_KBDILLUMTOGGLE 228 */ - SDL_SCANCODE_UNKNOWN, /* KEY_KBDILLUMDOWN 229 */ - SDL_SCANCODE_UNKNOWN, /* KEY_KBDILLUMUP 230 */ - SDL_SCANCODE_UNKNOWN, /* KEY_SEND 231 AC Send */ - SDL_SCANCODE_UNKNOWN, /* KEY_REPLY 232 AC Reply */ - SDL_SCANCODE_UNKNOWN, /* KEY_FORWARDMAIL 233 AC Forward Msg */ - SDL_SCANCODE_UNKNOWN, /* KEY_SAVE 234 AC Save */ - SDL_SCANCODE_UNKNOWN, /* KEY_DOCUMENTS 235 */ - SDL_SCANCODE_UNKNOWN, /* KEY_BATTERY 236 */ - SDL_SCANCODE_UNKNOWN, /* KEY_BLUETOOTH 237 */ - SDL_SCANCODE_UNKNOWN, /* KEY_WLAN 238 */ - SDL_SCANCODE_UNKNOWN, /* KEY_UWB 239 */ - SDL_SCANCODE_UNKNOWN, /* KEY_UNKNOWN 240 */ - SDL_SCANCODE_UNKNOWN, /* KEY_VIDEO_NEXT 241 drive next video source */ - SDL_SCANCODE_UNKNOWN, /* KEY_VIDEO_PREV 242 drive previous video source */ - SDL_SCANCODE_UNKNOWN, /* KEY_BRIGHTNESS_CYCLE 243 brightness up, after max is min */ - SDL_SCANCODE_UNKNOWN, /* KEY_BRIGHTNESS_ZERO 244 brightness off, use ambient */ - SDL_SCANCODE_UNKNOWN, /* KEY_DISPLAY_OFF 245 display device to off state */ - SDL_SCANCODE_UNKNOWN, /* KEY_WIMAX 246 */ - SDL_SCANCODE_UNKNOWN, /* KEY_RFKILL 247 Key that controls all radios */ - SDL_SCANCODE_UNKNOWN /* KEY_MICMUTE 248 Mute / unmute the microphone */ + SDL_SCANCODE_UNKNOWN, /* KEY_SWITCHVIDEOMODE 227 Cycle between available + video outputs (Monitor/LCD/TV-out/etc) */ + SDL_SCANCODE_UNKNOWN, /* KEY_KBDILLUMTOGGLE 228 */ + SDL_SCANCODE_UNKNOWN, /* KEY_KBDILLUMDOWN 229 */ + SDL_SCANCODE_UNKNOWN, /* KEY_KBDILLUMUP 230 */ + SDL_SCANCODE_UNKNOWN, /* KEY_SEND 231 AC Send */ + SDL_SCANCODE_UNKNOWN, /* KEY_REPLY 232 AC Reply */ + SDL_SCANCODE_UNKNOWN, /* KEY_FORWARDMAIL 233 AC Forward Msg */ + SDL_SCANCODE_UNKNOWN, /* KEY_SAVE 234 AC Save */ + SDL_SCANCODE_UNKNOWN, /* KEY_DOCUMENTS 235 */ + SDL_SCANCODE_UNKNOWN, /* KEY_BATTERY 236 */ + SDL_SCANCODE_UNKNOWN, /* KEY_BLUETOOTH 237 */ + SDL_SCANCODE_UNKNOWN, /* KEY_WLAN 238 */ + SDL_SCANCODE_UNKNOWN, /* KEY_UWB 239 */ + SDL_SCANCODE_UNKNOWN, /* KEY_UNKNOWN 240 */ + SDL_SCANCODE_UNKNOWN, /* KEY_VIDEO_NEXT 241 drive next video source */ + SDL_SCANCODE_UNKNOWN, /* KEY_VIDEO_PREV 242 drive previous video + source */ + SDL_SCANCODE_UNKNOWN, /* KEY_BRIGHTNESS_CYCLE 243 brightness up, after + max is min */ + SDL_SCANCODE_UNKNOWN, /* KEY_BRIGHTNESS_ZERO 244 brightness off, use + ambient */ + SDL_SCANCODE_UNKNOWN, /* KEY_DISPLAY_OFF 245 display device to off + state */ + SDL_SCANCODE_UNKNOWN, /* KEY_WIMAX 246 */ + SDL_SCANCODE_UNKNOWN, /* KEY_RFKILL 247 Key that controls all radios + */ + SDL_SCANCODE_UNKNOWN /* KEY_MICMUTE 248 Mute / unmute the microphone */ }}; -} // namespace ubuntu -} // namespace anbox +} // namespace ubuntu +} // namespace anbox diff --git a/src/anbox/ubuntu/keycode_converter.h b/src/anbox/ubuntu/keycode_converter.h index ae7d2df..45f3d80 100644 --- a/src/anbox/ubuntu/keycode_converter.h +++ b/src/anbox/ubuntu/keycode_converter.h @@ -27,12 +27,13 @@ namespace anbox { namespace ubuntu { class KeycodeConverter { -public: - static std::uint16_t convert(const SDL_Scancode &scan_code); -private: - static const std::array code_map; + public: + static std::uint16_t convert(const SDL_Scancode &scan_code); + + private: + static const std::array code_map; }; -} // namespace ubuntu -} // namespace anbox +} // namespace ubuntu +} // namespace anbox #endif diff --git a/src/anbox/ubuntu/mir_display_connection.cpp b/src/anbox/ubuntu/mir_display_connection.cpp index da0aa83..5146d78 100644 --- a/src/anbox/ubuntu/mir_display_connection.cpp +++ b/src/anbox/ubuntu/mir_display_connection.cpp @@ -24,107 +24,100 @@ namespace { static const MirDisplayOutput *find_active_output( - const MirDisplayConfiguration *conf) -{ - const MirDisplayOutput *output = NULL; - int d; + const MirDisplayConfiguration *conf) { + const MirDisplayOutput *output = NULL; + int d; - for (d = 0; d < (int)conf->num_outputs; d++) - { - const MirDisplayOutput *out = conf->outputs + d; + for (d = 0; d < (int)conf->num_outputs; d++) { + const MirDisplayOutput *out = conf->outputs + d; - if (out->used && - out->connected && - out->num_modes && - out->current_mode < out->num_modes) - { - output = out; - break; - } + if (out->used && out->connected && out->num_modes && + out->current_mode < out->num_modes) { + output = out; + break; } + } - return output; + return output; } } namespace anbox { namespace ubuntu { -MirDisplayConnection::MirDisplayConnection() : - connection_(nullptr), - output_id_(-1), - vertical_resolution_(0), - horizontal_resolution_(0) { +MirDisplayConnection::MirDisplayConnection() + : connection_(nullptr), + output_id_(-1), + vertical_resolution_(0), + horizontal_resolution_(0) { + auto xdg_runtime_dir = ::getenv("XDG_RUNTIME_DIR"); + if (!xdg_runtime_dir) + BOOST_THROW_EXCEPTION(std::runtime_error("Failed to find XDG_RUNTIME_DIR")); - auto xdg_runtime_dir = ::getenv("XDG_RUNTIME_DIR"); - if (!xdg_runtime_dir) - BOOST_THROW_EXCEPTION(std::runtime_error("Failed to find XDG_RUNTIME_DIR")); + std::string socket_path = xdg_runtime_dir; + socket_path += "/mir_socket"; - std::string socket_path = xdg_runtime_dir; - socket_path += "/mir_socket"; + connection_ = mir_connect_sync(socket_path.c_str(), "anbox"); + if (!mir_connection_is_valid(connection_)) { + std::string msg; + msg += "Failed to connect with Mir server: "; + msg += mir_connection_get_error_message(connection_); + BOOST_THROW_EXCEPTION(std::runtime_error(msg.c_str())); + } - connection_ = mir_connect_sync(socket_path.c_str(), "anbox"); - if (!mir_connection_is_valid(connection_)) { - std::string msg; - msg += "Failed to connect with Mir server: "; - msg += mir_connection_get_error_message(connection_); - BOOST_THROW_EXCEPTION(std::runtime_error(msg.c_str())); - } - - mir_connection_set_display_config_change_callback( - connection_, - [](MirConnection* connection, void* context) { - auto thiz = reinterpret_cast(context); + mir_connection_set_display_config_change_callback( + connection_, + [](MirConnection *connection, void *context) { + auto thiz = reinterpret_cast(context); DEBUG(""); - }, this); + }, + this); - MirDisplayConfiguration* display_config = - mir_connection_create_display_config(connection_); + MirDisplayConfiguration *display_config = + mir_connection_create_display_config(connection_); - const MirDisplayOutput *output = find_active_output(display_config); - if (!output) - BOOST_THROW_EXCEPTION(std::runtime_error("Failed to find active output display")); + const MirDisplayOutput *output = find_active_output(display_config); + if (!output) + BOOST_THROW_EXCEPTION( + std::runtime_error("Failed to find active output display")); - DEBUG("Selecting output id %d", output->output_id); + DEBUG("Selecting output id %d", output->output_id); - output_id_ = output->output_id; + output_id_ = output->output_id; - const MirDisplayMode *mode = &output->modes[output->current_mode]; + const MirDisplayMode *mode = &output->modes[output->current_mode]; - vertical_resolution_ = mode->vertical_resolution; - horizontal_resolution_ = mode->horizontal_resolution; + vertical_resolution_ = mode->vertical_resolution; + horizontal_resolution_ = mode->horizontal_resolution; - mir_display_config_destroy(display_config); + mir_display_config_destroy(display_config); } MirDisplayConnection::~MirDisplayConnection() { - mir_connection_release(connection_); + mir_connection_release(connection_); } -MirConnection* MirDisplayConnection::connection() const { - return connection_; -} +MirConnection *MirDisplayConnection::connection() const { return connection_; } MirPixelFormat MirDisplayConnection::default_pixel_format() const { - MirPixelFormat format; - unsigned int nformats; - mir_connection_get_available_surface_formats(connection_, &format, 1, &nformats); - return format; + MirPixelFormat format; + unsigned int nformats; + mir_connection_get_available_surface_formats(connection_, &format, 1, + &nformats); + return format; } EGLNativeDisplayType MirDisplayConnection::native_display() const { - return mir_connection_get_egl_native_display(connection_); + return mir_connection_get_egl_native_display(connection_); } -int MirDisplayConnection::output_id() const { - return output_id_; -} +int MirDisplayConnection::output_id() const { return output_id_; } int MirDisplayConnection::vertical_resolution() const { - return vertical_resolution_; + return vertical_resolution_; } int MirDisplayConnection::horizontal_resolution() const { - return horizontal_resolution_; + return horizontal_resolution_; } -} // namespace ubuntu -} // namespace anbox +} // namespace ubuntu +} // namespace anbox diff --git a/src/anbox/ubuntu/mir_display_connection.h b/src/anbox/ubuntu/mir_display_connection.h index e3176ac..7904208 100644 --- a/src/anbox/ubuntu/mir_display_connection.h +++ b/src/anbox/ubuntu/mir_display_connection.h @@ -27,26 +27,26 @@ namespace anbox { namespace ubuntu { class MirDisplayConnection { -public: - MirDisplayConnection(); - ~MirDisplayConnection(); + public: + MirDisplayConnection(); + ~MirDisplayConnection(); - MirPixelFormat default_pixel_format() const; + MirPixelFormat default_pixel_format() const; - MirConnection* connection() const; - EGLNativeDisplayType native_display() const; + MirConnection* connection() const; + EGLNativeDisplayType native_display() const; - int output_id() const; - int vertical_resolution() const; - int horizontal_resolution() const; + int output_id() const; + int vertical_resolution() const; + int horizontal_resolution() const; -private: - MirConnection *connection_; - int output_id_; - int vertical_resolution_; - int horizontal_resolution_; + private: + MirConnection* connection_; + int output_id_; + int vertical_resolution_; + int horizontal_resolution_; }; -} // namespace ubuntu -} // namespace anbox +} // namespace ubuntu +} // namespace anbox #endif diff --git a/src/anbox/ubuntu/platform_policy.cpp b/src/anbox/ubuntu/platform_policy.cpp index 2eefe38..e813c72 100644 --- a/src/anbox/ubuntu/platform_policy.cpp +++ b/src/anbox/ubuntu/platform_policy.cpp @@ -16,201 +16,201 @@ */ #include "anbox/ubuntu/platform_policy.h" -#include "anbox/ubuntu/window.h" -#include "anbox/ubuntu/keycode_converter.h" -#include "anbox/input/manager.h" -#include "anbox/input/device.h" #include "anbox/bridge/android_api_stub.h" +#include "anbox/input/device.h" +#include "anbox/input/manager.h" #include "anbox/logger.h" +#include "anbox/ubuntu/keycode_converter.h" +#include "anbox/ubuntu/window.h" #include -#include #include +#include namespace anbox { namespace ubuntu { -PlatformPolicy::PlatformPolicy(const std::shared_ptr &input_manager, - const std::shared_ptr &android_api) : - input_manager_(input_manager), - android_api_(android_api), - event_thread_running_(false) { +PlatformPolicy::PlatformPolicy( + const std::shared_ptr &input_manager, + const std::shared_ptr &android_api) + : input_manager_(input_manager), + android_api_(android_api), + event_thread_running_(false) { + if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS) < 0) + BOOST_THROW_EXCEPTION(std::runtime_error("Failed to initialize SDL")); - if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS) < 0) - BOOST_THROW_EXCEPTION(std::runtime_error("Failed to initialize SDL")); + event_thread_ = std::thread(&PlatformPolicy::process_events, this); - event_thread_ = std::thread(&PlatformPolicy::process_events, this); + SDL_DisplayMode display_mode; + // FIXME statically just check the first (primary) display for its mode; + // once we get multi-monitor support we need to do this better. + if (SDL_GetCurrentDisplayMode(0, &display_mode) == 0) { + display_info_.horizontal_resolution = display_mode.w; + display_info_.vertical_resolution = display_mode.h; + } - SDL_DisplayMode display_mode; - // FIXME statically just check the first (primary) display for its mode; - // once we get multi-monitor support we need to do this better. - if (SDL_GetCurrentDisplayMode(0, &display_mode) == 0) { - display_info_.horizontal_resolution = display_mode.w; - display_info_.vertical_resolution = display_mode.h; - } + pointer_ = input_manager->create_device(); + pointer_->set_name("anbox-pointer"); + pointer_->set_driver_version(1); + pointer_->set_input_id({BUS_VIRTUAL, 2, 2, 2}); + pointer_->set_physical_location("none"); + pointer_->set_key_bit(BTN_MOUSE); + // NOTE: We don't use REL_X/REL_Y in reality but have to specify them here + // to allow InputFlinger to detect we're a cursor device. + pointer_->set_rel_bit(REL_X); + pointer_->set_rel_bit(REL_Y); + pointer_->set_rel_bit(REL_HWHEEL); + pointer_->set_rel_bit(REL_WHEEL); + pointer_->set_prop_bit(INPUT_PROP_POINTER); - pointer_ = input_manager->create_device(); - pointer_->set_name("anbox-pointer"); - pointer_->set_driver_version(1); - pointer_->set_input_id({ BUS_VIRTUAL, 2, 2, 2 }); - pointer_->set_physical_location("none"); - pointer_->set_key_bit(BTN_MOUSE); - // NOTE: We don't use REL_X/REL_Y in reality but have to specify them here - // to allow InputFlinger to detect we're a cursor device. - pointer_->set_rel_bit(REL_X); - pointer_->set_rel_bit(REL_Y); - pointer_->set_rel_bit(REL_HWHEEL); - pointer_->set_rel_bit(REL_WHEEL); - pointer_->set_prop_bit(INPUT_PROP_POINTER); - - keyboard_ = input_manager->create_device(); - keyboard_->set_name("anbox-keyboard"); - keyboard_->set_driver_version(1); - keyboard_->set_input_id({ BUS_VIRTUAL, 3, 3, 3 }); - keyboard_->set_physical_location("none"); - keyboard_->set_key_bit(BTN_MISC); - keyboard_->set_key_bit(KEY_OK); + keyboard_ = input_manager->create_device(); + keyboard_->set_name("anbox-keyboard"); + keyboard_->set_driver_version(1); + keyboard_->set_input_id({BUS_VIRTUAL, 3, 3, 3}); + keyboard_->set_physical_location("none"); + keyboard_->set_key_bit(BTN_MISC); + keyboard_->set_key_bit(KEY_OK); } PlatformPolicy::~PlatformPolicy() { - event_thread_running_ = false; - event_thread_.join(); + event_thread_running_ = false; + event_thread_.join(); } void PlatformPolicy::process_events() { - event_thread_running_ = true; + event_thread_running_ = true; - while(event_thread_running_) { - SDL_Event event; - while (SDL_WaitEventTimeout(&event, 100)) { - switch (event.type) { - case SDL_QUIT: - // This is the best way to reliable terminate the whole application for now. It will - // trigger a correct shutdown in the main part. - ::kill(getpid(), SIGTERM); - break; - case SDL_WINDOWEVENT: - for (auto &iter : windows_) { - if (auto w = iter.second.lock()) { - if (w->window_id() == event.window.windowID) { - w->process_event(event); - break; - } - } - } - break; - case SDL_MOUSEMOTION: - case SDL_MOUSEBUTTONDOWN: - case SDL_MOUSEBUTTONUP: - case SDL_MOUSEWHEEL: - case SDL_KEYDOWN: - case SDL_KEYUP: - process_input_event(event); + while (event_thread_running_) { + SDL_Event event; + while (SDL_WaitEventTimeout(&event, 100)) { + switch (event.type) { + case SDL_QUIT: + // This is the best way to reliable terminate the whole application + // for now. It will + // trigger a correct shutdown in the main part. + ::kill(getpid(), SIGTERM); + break; + case SDL_WINDOWEVENT: + for (auto &iter : windows_) { + if (auto w = iter.second.lock()) { + if (w->window_id() == event.window.windowID) { + w->process_event(event); break; + } } - } + } + break; + case SDL_MOUSEMOTION: + case SDL_MOUSEBUTTONDOWN: + case SDL_MOUSEBUTTONUP: + case SDL_MOUSEWHEEL: + case SDL_KEYDOWN: + case SDL_KEYUP: + process_input_event(event); + break; + } } + } } void PlatformPolicy::process_input_event(const SDL_Event &event) { - std::vector mouse_events; - std::vector keyboard_events; + std::vector mouse_events; + std::vector keyboard_events; - std::int32_t x = 0; - std::int32_t y = 0; - SDL_Window *window = nullptr; + std::int32_t x = 0; + std::int32_t y = 0; + SDL_Window *window = nullptr; - switch (event.type) { + switch (event.type) { case SDL_MOUSEBUTTONDOWN: - mouse_events.push_back({ EV_KEY, BTN_LEFT, 1 }); - mouse_events.push_back({ EV_SYN, SYN_REPORT, 0 }); - break; + mouse_events.push_back({EV_KEY, BTN_LEFT, 1}); + mouse_events.push_back({EV_SYN, SYN_REPORT, 0}); + break; case SDL_MOUSEBUTTONUP: - mouse_events.push_back({ EV_KEY, BTN_LEFT, 0 }); - mouse_events.push_back({ EV_SYN, SYN_REPORT, 0 }); - break; + mouse_events.push_back({EV_KEY, BTN_LEFT, 0}); + mouse_events.push_back({EV_SYN, SYN_REPORT, 0}); + break; case SDL_MOUSEMOTION: - // As we get only absolute coordindates relative to our window we have to - // calculate the correct position based on the current focused window - window = SDL_GetWindowFromID(event.window.windowID); - if (!window) - break; + // As we get only absolute coordindates relative to our window we have to + // calculate the correct position based on the current focused window + window = SDL_GetWindowFromID(event.window.windowID); + if (!window) break; - SDL_GetWindowPosition(window, &x, &y); - x += event.motion.x; - y += event.motion.y; + SDL_GetWindowPosition(window, &x, &y); + x += event.motion.x; + y += event.motion.y; - // NOTE: Sending relative move events doesn't really work and we have changes - // in libinputflinger to take ABS_X/ABS_Y instead for absolute position events. - mouse_events.push_back({ EV_ABS, ABS_X, x }); - mouse_events.push_back({ EV_ABS, ABS_Y, y }); - // We're sending relative position updates here too but they will be only used - // by the Android side EventHub/InputReader to determine if the cursor was - // moved. They are not used to find out the exact position. - mouse_events.push_back({ EV_REL, REL_X, event.motion.xrel }); - mouse_events.push_back({ EV_REL, REL_Y, event.motion.yrel }); - mouse_events.push_back({ EV_SYN, SYN_REPORT, 0 }); - break; + // NOTE: Sending relative move events doesn't really work and we have + // changes + // in libinputflinger to take ABS_X/ABS_Y instead for absolute position + // events. + mouse_events.push_back({EV_ABS, ABS_X, x}); + mouse_events.push_back({EV_ABS, ABS_Y, y}); + // We're sending relative position updates here too but they will be only + // used + // by the Android side EventHub/InputReader to determine if the cursor was + // moved. They are not used to find out the exact position. + mouse_events.push_back({EV_REL, REL_X, event.motion.xrel}); + mouse_events.push_back({EV_REL, REL_Y, event.motion.yrel}); + mouse_events.push_back({EV_SYN, SYN_REPORT, 0}); + break; case SDL_MOUSEWHEEL: - mouse_events.push_back({ EV_REL, REL_WHEEL, static_cast(event.wheel.y) }); - break; + mouse_events.push_back( + {EV_REL, REL_WHEEL, static_cast(event.wheel.y)}); + break; case SDL_KEYDOWN: { - const auto code = KeycodeConverter::convert(event.key.keysym.scancode); - if (code == KEY_RESERVED) - break; - keyboard_events.push_back({ EV_KEY, code, 1 }); - break; + const auto code = KeycodeConverter::convert(event.key.keysym.scancode); + if (code == KEY_RESERVED) break; + keyboard_events.push_back({EV_KEY, code, 1}); + break; } case SDL_KEYUP: { - const auto code = KeycodeConverter::convert(event.key.keysym.scancode); - if (code == KEY_RESERVED) - break; - keyboard_events.push_back({ EV_KEY, code, 0 }); - break; + const auto code = KeycodeConverter::convert(event.key.keysym.scancode); + if (code == KEY_RESERVED) break; + keyboard_events.push_back({EV_KEY, code, 0}); + break; } default: - break; - } + break; + } - if (mouse_events.size() > 0) - pointer_->send_events(mouse_events); + if (mouse_events.size() > 0) pointer_->send_events(mouse_events); - if (keyboard_events.size() > 0) - keyboard_->send_events(keyboard_events); + if (keyboard_events.size() > 0) keyboard_->send_events(keyboard_events); } Window::Id PlatformPolicy::next_window_id() { - static Window::Id next_id = 0; - return next_id++; + static Window::Id next_id = 0; + return next_id++; } -std::shared_ptr PlatformPolicy::create_window(const anbox::wm::Task::Id &task, const anbox::graphics::Rect &frame) { - auto id = next_window_id(); - auto w = std::make_shared(id, task, shared_from_this(), frame); - windows_.insert({id, w}); - return w; +std::shared_ptr PlatformPolicy::create_window( + const anbox::wm::Task::Id &task, const anbox::graphics::Rect &frame) { + auto id = next_window_id(); + auto w = std::make_shared(id, task, shared_from_this(), frame); + windows_.insert({id, w}); + return w; } void PlatformPolicy::window_deleted(const Window::Id &id) { - auto w = windows_.find(id); - if (w == windows_.end()) { - WARNING("Got window removed event for unknown window (id %d)", id); - return; - } - windows_.erase(w); + auto w = windows_.find(id); + if (w == windows_.end()) { + WARNING("Got window removed event for unknown window (id %d)", id); + return; + } + windows_.erase(w); } void PlatformPolicy::window_wants_focus(const Window::Id &id) { - auto w = windows_.find(id); - if (w == windows_.end()) - return; + auto w = windows_.find(id); + if (w == windows_.end()) return; - if (auto window = w->second.lock()) - android_api_->set_focused_task(window->task()); + if (auto window = w->second.lock()) + android_api_->set_focused_task(window->task()); } DisplayManager::DisplayInfo PlatformPolicy::display_info() const { - return display_info_; + return display_info_; } -} // namespace wm -} // namespace anbox +} // namespace wm +} // namespace anbox diff --git a/src/anbox/ubuntu/platform_policy.h b/src/anbox/ubuntu/platform_policy.h index 7bab173..57de532 100644 --- a/src/anbox/ubuntu/platform_policy.h +++ b/src/anbox/ubuntu/platform_policy.h @@ -18,13 +18,13 @@ #ifndef ANBOX_UBUNTU_PLATFORM_POLICY_H_ #define ANBOX_UBUNTU_PLATFORM_POLICY_H_ -#include "anbox/wm/platform_policy.h" #include "anbox/ubuntu/window.h" +#include "anbox/wm/platform_policy.h" #include "anbox/graphics/emugl/DisplayManager.h" -#include #include +#include #include @@ -32,46 +32,48 @@ namespace anbox { namespace input { class Device; class Manager; -} // namespace input +} // namespace input namespace bridge { class AndroidApiStub; -} // namespace bridge +} // namespace bridge namespace ubuntu { class PlatformPolicy : public std::enable_shared_from_this, public wm::PlatformPolicy, public Window::Observer, public DisplayManager { -public: - PlatformPolicy(const std::shared_ptr &input_manager, - const std::shared_ptr &android_api); - ~PlatformPolicy(); + public: + PlatformPolicy(const std::shared_ptr &input_manager, + const std::shared_ptr &android_api); + ~PlatformPolicy(); - std::shared_ptr create_window(const anbox::wm::Task::Id &task, const anbox::graphics::Rect &frame) override; + std::shared_ptr create_window( + const anbox::wm::Task::Id &task, + const anbox::graphics::Rect &frame) override; - void window_deleted(const Window::Id &id) override; - void window_wants_focus(const Window::Id &id) override; + void window_deleted(const Window::Id &id) override; + void window_wants_focus(const Window::Id &id) override; - DisplayInfo display_info() const override; + DisplayInfo display_info() const override; -private: - void process_events(); - void process_input_event(const SDL_Event &event); + private: + void process_events(); + void process_input_event(const SDL_Event &event); - static Window::Id next_window_id(); + static Window::Id next_window_id(); - std::shared_ptr input_manager_; - std::shared_ptr android_api_; - // We don't own the windows anymore after the got created by us so we - // need to be careful once we try to use them again. - std::map> windows_; - std::shared_ptr current_window_; - std::thread event_thread_; - bool event_thread_running_; - std::shared_ptr pointer_; - std::shared_ptr keyboard_; - DisplayManager::DisplayInfo display_info_; + std::shared_ptr input_manager_; + std::shared_ptr android_api_; + // We don't own the windows anymore after the got created by us so we + // need to be careful once we try to use them again. + std::map> windows_; + std::shared_ptr current_window_; + std::thread event_thread_; + bool event_thread_running_; + std::shared_ptr pointer_; + std::shared_ptr keyboard_; + DisplayManager::DisplayInfo display_info_; }; -} // namespace wm -} // namespace anbox +} // namespace wm +} // namespace anbox #endif diff --git a/src/anbox/ubuntu/window.cpp b/src/anbox/ubuntu/window.cpp index 1864dcd..692f910 100644 --- a/src/anbox/ubuntu/window.cpp +++ b/src/anbox/ubuntu/window.cpp @@ -16,113 +16,100 @@ */ #include "anbox/ubuntu/window.h" -#include "anbox/wm/window_state.h" #include "anbox/logger.h" +#include "anbox/wm/window_state.h" #include #include namespace { -constexpr const char* default_window_name{"anbox"}; +constexpr const char *default_window_name{"anbox"}; } namespace anbox { namespace ubuntu { Window::Id Window::Invalid{-1}; -Window::Observer::~Observer() { -} +Window::Observer::~Observer() {} -Window::Window(const Id &id, - const wm::Task::Id &task, +Window::Window(const Id &id, const wm::Task::Id &task, const std::shared_ptr &observer, - const graphics::Rect &frame) : - wm::Window(task, frame), - id_(id), - observer_(observer), - native_display_(0), - native_window_(0) { + const graphics::Rect &frame) + : wm::Window(task, frame), + id_(id), + observer_(observer), + native_display_(0), + native_window_(0) { + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 1); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 1); + window_ = SDL_CreateWindow(default_window_name, frame.left(), frame.top(), + frame.width(), frame.height(), + SDL_WINDOW_OPENGL | SDL_WINDOW_BORDERLESS); + if (!window_) { + const auto message = + utils::string_format("Failed to create window: %s", SDL_GetError()); + BOOST_THROW_EXCEPTION(std::runtime_error(message)); + } - window_ = SDL_CreateWindow(default_window_name, - frame.left(), - frame.top(), - frame.width(), - frame.height(), - SDL_WINDOW_OPENGL | SDL_WINDOW_BORDERLESS); - if (!window_) { - const auto message = utils::string_format("Failed to create window: %s", SDL_GetError()); - BOOST_THROW_EXCEPTION(std::runtime_error(message)); - } - - SDL_SysWMinfo info; - SDL_VERSION(&info.version); - SDL_GetWindowWMInfo(window_, &info); - switch (info.subsystem) { + SDL_SysWMinfo info; + SDL_VERSION(&info.version); + SDL_GetWindowWMInfo(window_, &info); + switch (info.subsystem) { case SDL_SYSWM_X11: - native_display_ = static_cast(info.info.x11.display); - native_window_ = static_cast(info.info.x11.window); - break; + native_display_ = + static_cast(info.info.x11.display); + native_window_ = static_cast(info.info.x11.window); + break; default: - ERROR("Unknown subsystem (%d)", info.subsystem); - BOOST_THROW_EXCEPTION(std::runtime_error("SDL subsystem not suported")); - } + ERROR("Unknown subsystem (%d)", info.subsystem); + BOOST_THROW_EXCEPTION(std::runtime_error("SDL subsystem not suported")); + } - int actual_width = 0, actual_height = 0; - int actual_x = 0, actual_y = 0; - SDL_GetWindowSize(window_, &actual_width, &actual_height); - SDL_GetWindowPosition(window_, &actual_x, &actual_y); + int actual_width = 0, actual_height = 0; + int actual_x = 0, actual_y = 0; + SDL_GetWindowSize(window_, &actual_width, &actual_height); + SDL_GetWindowPosition(window_, &actual_x, &actual_y); } Window::~Window() { - if (window_) - SDL_DestroyWindow(window_); + if (window_) SDL_DestroyWindow(window_); - if (observer_) - observer_->window_deleted(id_); + if (observer_) observer_->window_deleted(id_); } void Window::resize(int width, int height) { - SDL_SetWindowSize(window_, width, height); + SDL_SetWindowSize(window_, width, height); } void Window::update_position(int x, int y) { - SDL_SetWindowPosition(window_, x, y); + SDL_SetWindowPosition(window_, x, y); } void Window::process_event(const SDL_Event &event) { - switch (event.window.event) { + switch (event.window.event) { case SDL_WINDOWEVENT_FOCUS_GAINED: - if (observer_) - observer_->window_wants_focus(id_); - break; + if (observer_) observer_->window_wants_focus(id_); + break; case SDL_WINDOWEVENT_FOCUS_LOST: - break; + break; case SDL_WINDOWEVENT_RESIZED: - break; + break; case SDL_WINDOWEVENT_SIZE_CHANGED: - break; + break; case SDL_WINDOWEVENT_MOVED: - break; + break; case SDL_WINDOWEVENT_SHOWN: - break; + break; case SDL_WINDOWEVENT_HIDDEN: - break; - } + break; + } } -EGLNativeWindowType Window::native_handle() const { - return native_window_; -} +EGLNativeWindowType Window::native_handle() const { return native_window_; } -Window::Id Window::id() const { - return id_; -} +Window::Id Window::id() const { return id_; } -std::uint32_t Window::window_id() const { - return SDL_GetWindowID(window_); -} -} // namespace bridge -} // namespace anbox +std::uint32_t Window::window_id() const { return SDL_GetWindowID(window_); } +} // namespace bridge +} // namespace anbox diff --git a/src/anbox/ubuntu/window.h b/src/anbox/ubuntu/window.h index a2fb444..4e66cb4 100644 --- a/src/anbox/ubuntu/window.h +++ b/src/anbox/ubuntu/window.h @@ -29,40 +29,41 @@ namespace anbox { namespace ubuntu { -class Window : public std::enable_shared_from_this, - public wm::Window { -public: - typedef std::int32_t Id; - static Id Invalid; +class Window : public std::enable_shared_from_this, public wm::Window { + public: + typedef std::int32_t Id; + static Id Invalid; - class Observer { - public: - virtual ~Observer(); - virtual void window_deleted(const Id &id) = 0; - virtual void window_wants_focus(const Id &id) = 0; - }; + class Observer { + public: + virtual ~Observer(); + virtual void window_deleted(const Id &id) = 0; + virtual void window_wants_focus(const Id &id) = 0; + }; - Window(const Id &id, const wm::Task::Id &task, const std::shared_ptr &observer, const graphics::Rect &frame); - ~Window(); + Window(const Id &id, const wm::Task::Id &task, + const std::shared_ptr &observer, + const graphics::Rect &frame); + ~Window(); - void process_event(const SDL_Event &event); + void process_event(const SDL_Event &event); - EGLNativeWindowType native_handle() const override; - Id id() const; - std::uint32_t window_id() const; + EGLNativeWindowType native_handle() const override; + Id id() const; + std::uint32_t window_id() const; -protected: - void resize(int width, int height) override; - void update_position(int x, int y) override; + protected: + void resize(int width, int height) override; + void update_position(int x, int y) override; -private: - Id id_; - std::shared_ptr observer_; - EGLNativeDisplayType native_display_; - EGLNativeWindowType native_window_; - SDL_Window *window_; + private: + Id id_; + std::shared_ptr observer_; + EGLNativeDisplayType native_display_; + EGLNativeWindowType native_window_; + SDL_Window *window_; }; -} // namespace bridge -} // namespace anbox +} // namespace bridge +} // namespace anbox #endif diff --git a/src/anbox/utils.cpp b/src/anbox/utils.cpp index 5777bba..3b4af39 100644 --- a/src/anbox/utils.cpp +++ b/src/anbox/utils.cpp @@ -19,8 +19,8 @@ #include #include -#include #include +#include #include #include @@ -33,132 +33,130 @@ namespace anbox { namespace utils { std::vector collect_arguments(int argc, char **argv) { - std::vector result; - for (int i = 1; i < argc; i++) result.push_back(argv[i]); - return result; + std::vector result; + for (int i = 1; i < argc; i++) result.push_back(argv[i]); + return result; } std::string read_file_if_exists_or_throw(const std::string &file_path) { - if (!boost::filesystem::is_regular(boost::filesystem::path(file_path))) - BOOST_THROW_EXCEPTION(std::runtime_error("File does not exist")); + if (!boost::filesystem::is_regular(boost::filesystem::path(file_path))) + BOOST_THROW_EXCEPTION(std::runtime_error("File does not exist")); - std::ifstream file; - file.open(file_path, std::ifstream::in); - std::string content; - file >> content; - file.close(); - return content; + std::ifstream file; + file.open(file_path, std::ifstream::in); + std::string content; + file >> content; + file.close(); + return content; } bool write_to_file(const std::string &file_path, const std::string &content) { - std::ofstream of; - of.open(file_path, std::ofstream::out); - of << content; - of.close(); - return true; + std::ofstream of; + of.open(file_path, std::ofstream::out); + of << content; + of.close(); + return true; } int write_to_fd(int fd, const char *content, ssize_t len) { - while (len > 0) { - const auto res = write (fd, content, len); - if (res < 0 && errno == EINTR) - continue; + while (len > 0) { + const auto res = write(fd, content, len); + if (res < 0 && errno == EINTR) continue; - if (res <= 0) { - if (res == 0) /* Unexpected short write, should not happen when writing to a file */ - errno = ENOSPC; - return -1; - } - - len -= res; - content += res; + if (res <= 0) { + if (res == 0) /* Unexpected short write, should not happen when writing to + a file */ + errno = ENOSPC; + return -1; } - return 0; + + len -= res; + content += res; + } + return 0; } int write_file_at(int dirfd, const char *path, const char *content) { - const auto fd = openat (dirfd, path, O_RDWR | O_CLOEXEC, 0); - if (fd == -1) - return -1; + const auto fd = openat(dirfd, path, O_RDWR | O_CLOEXEC, 0); + if (fd == -1) return -1; - auto res = 0; - if (content) - res = write_to_fd (fd, content, strlen (content)); + auto res = 0; + if (content) res = write_to_fd(fd, content, strlen(content)); - const auto errsv = errno; - close (fd); - errno = errsv; + const auto errsv = errno; + close(fd); + errno = errsv; - return res; + return res; } bool string_starts_with(const std::string &text, const std::string &prefix) { - return text.compare(0, prefix.size(), prefix) == 0; + return text.compare(0, prefix.size(), prefix) == 0; } std::string hex_dump(const uint8_t *data, uint32_t size) { - unsigned char buff[17]; - const uint8_t *pc = data; - std::stringstream buffer; - - if (size == 0) { - buffer << "NULL" << std::endl; - return buffer.str(); - } - - uint32_t i; - for (i = 0; i < size; i++) { - if ((i % 16) == 0) { - if (i != 0) - buffer << string_format(" %s", buff) << std::endl; - - buffer << string_format("%02x ", i); - } - - buffer << string_format(" %02x", static_cast(pc[i])); - - if ((pc[i] < 0x20) || (pc[i] > 0x7e)) - buff[i % 16] = '.'; - else - buff[i % 16] = pc[i]; - buff[(i % 16) + 1] = '\0'; - } - - while ((i % 16) != 0) { - buffer << " "; - i++; - } - - buffer << string_format(" %s", buff) << std::endl; + unsigned char buff[17]; + const uint8_t *pc = data; + std::stringstream buffer; + if (size == 0) { + buffer << "NULL" << std::endl; return buffer.str(); + } + + uint32_t i; + for (i = 0; i < size; i++) { + if ((i % 16) == 0) { + if (i != 0) buffer << string_format(" %s", buff) << std::endl; + + buffer << string_format("%02x ", i); + } + + buffer << string_format(" %02x", static_cast(pc[i])); + + if ((pc[i] < 0x20) || (pc[i] > 0x7e)) + buff[i % 16] = '.'; + else + buff[i % 16] = pc[i]; + buff[(i % 16) + 1] = '\0'; + } + + while ((i % 16) != 0) { + buffer << " "; + i++; + } + + buffer << string_format(" %s", buff) << std::endl; + + return buffer.str(); } -std::string get_env_value(const std::string &name, const std::string &default_value) { - char *value = getenv(name.c_str()); - if (!value) - return default_value; - return std::string(value); +std::string get_env_value(const std::string &name, + const std::string &default_value) { + char *value = getenv(name.c_str()); + if (!value) return default_value; + return std::string(value); } bool is_env_set(const std::string &name) { - return getenv(name.c_str()) != nullptr; + return getenv(name.c_str()) != nullptr; } void ensure_paths(const std::vector &paths) { - for (const auto &path: paths) { - if (!fs::is_directory(fs::path(path))) - fs::create_directories(fs::path(path)); - } + for (const auto &path : paths) { + if (!fs::is_directory(fs::path(path))) + fs::create_directories(fs::path(path)); + } } -std::string prefix_dir_from_env(const std::string &path, const std::string &env_var) { - static auto snap_data_path = anbox::utils::get_env_value(env_var, ""); - auto result = path; - if (!snap_data_path.empty()) - result = anbox::utils::string_format("%s%s", snap_data_path, path); - return result; +std::string prefix_dir_from_env(const std::string &path, + const std::string &env_var) { + static auto snap_data_path = anbox::utils::get_env_value(env_var, ""); + auto result = path; + if (!snap_data_path.empty()) + result = anbox::utils::string_format("%s%s", snap_data_path, path); + return result; } -} // namespace utils -} // namespace anbox +} // namespace utils +} // namespace anbox diff --git a/src/anbox/utils.h b/src/anbox/utils.h index 2c1c394..93c3946 100644 --- a/src/anbox/utils.h +++ b/src/anbox/utils.h @@ -20,8 +20,8 @@ #include -#include #include +#include namespace anbox { namespace utils { @@ -30,7 +30,8 @@ std::vector collect_arguments(int argc, char **argv); std::string read_file_if_exists_or_throw(const std::string &file_path); -bool write_to_file(const std::string &file_path, const std::string &content = ""); +bool write_to_file(const std::string &file_path, + const std::string &content = ""); int write_to_fd(int fd, const char *content, ssize_t len); int write_file_at(int dirfd, const char *path, const char *content); @@ -38,36 +39,36 @@ bool string_starts_with(const std::string &text, const std::string &prefix); std::string hex_dump(const uint8_t *data, uint32_t size); -std::string get_env_value(const std::string &name, const std::string &default_value = ""); +std::string get_env_value(const std::string &name, + const std::string &default_value = ""); bool is_env_set(const std::string &name); void ensure_paths(const std::vector &paths); -std::string prefix_dir_from_env(const std::string &path, const std::string &env_var); +std::string prefix_dir_from_env(const std::string &path, + const std::string &env_var); -template -static std::string string_format(const std::string& fmt_str, Types&&... args); -} // namespace utils -} // namespace anbox +template +static std::string string_format(const std::string &fmt_str, Types &&... args); +} // namespace utils +} // namespace anbox namespace impl { // Base case, just return the passed in boost::format instance. -inline boost::format& string_format(boost::format& f) -{ - return f; -} +inline boost::format &string_format(boost::format &f) { return f; } // Sprintf recursively walks the parameter pack at compile time. template -inline boost::format& string_format(boost::format& f, Head const& head, Tail&&... tail) { - return string_format(f % head, std::forward(tail)...); +inline boost::format &string_format(boost::format &f, Head const &head, + Tail &&... tail) { + return string_format(f % head, std::forward(tail)...); } -} // namespace impl +} // namespace impl template -inline std::string anbox::utils::string_format(const std::string& format, Types&&... args) { - boost::format f(format); - return impl::string_format(f, std::forward(args)...).str(); +inline std::string anbox::utils::string_format(const std::string &format, + Types &&... args) { + boost::format f(format); + return impl::string_format(f, std::forward(args)...).str(); } - #endif diff --git a/src/anbox/version.cpp b/src/anbox/version.cpp index 8c0445f..8759db7 100644 --- a/src/anbox/version.cpp +++ b/src/anbox/version.cpp @@ -19,9 +19,9 @@ #include "anbox/version.h" -void anbox::version(std::uint32_t& major, std::uint32_t& minor, std::uint32_t& patch) -{ - major = anbox::build::version_major; - minor = anbox::build::version_minor; - patch = anbox::build::version_patch; +void anbox::version(std::uint32_t& major, std::uint32_t& minor, + std::uint32_t& patch) { + major = anbox::build::version_major; + minor = anbox::build::version_minor; + patch = anbox::build::version_patch; } diff --git a/src/anbox/version.h b/src/anbox/version.h index 7c1d11b..6b45a54 100644 --- a/src/anbox/version.h +++ b/src/anbox/version.h @@ -24,19 +24,23 @@ namespace anbox { namespace build { -/// @brief version_major marks the major version of the library. The constant is meant to be used +/// @brief version_major marks the major version of the library. The constant is +/// meant to be used /// by client code both at build and runtime, enabling version checks. static constexpr const std::uint32_t version_major{1}; -/// @brief version_major marks the minor version of the library. The constant is meant to be used +/// @brief version_major marks the minor version of the library. The constant is +/// meant to be used /// by client code both at build and runtime, enabling version checks. static constexpr const std::uint32_t version_minor{0}; -/// @brief version_patch marks the major version of the library. The constant is meant to be used +/// @brief version_patch marks the major version of the library. The constant is +/// meant to be used /// by client code both at build and runtime, enabling version checks. static constexpr const std::uint32_t version_patch{1}; -} // namespace build +} // namespace build -/// @brief version queries the version of the library, placing the result in major, minor and patch. +/// @brief version queries the version of the library, placing the result in +/// major, minor and patch. void version(std::uint32_t& major, std::uint32_t& minor, std::uint32_t& patch); -} // namespace build +} // namespace build -#endif // ANBOX_VERSION_H_ +#endif // ANBOX_VERSION_H_ diff --git a/src/anbox/wm/default_platform_policy.cpp b/src/anbox/wm/default_platform_policy.cpp index 0dce9e8..88aa831 100644 --- a/src/anbox/wm/default_platform_policy.cpp +++ b/src/anbox/wm/default_platform_policy.cpp @@ -16,36 +16,31 @@ */ #include "anbox/wm/default_platform_policy.h" -#include "anbox/wm/window.h" #include "anbox/logger.h" +#include "anbox/wm/window.h" namespace { class NullWindow : public anbox::wm::Window { -public: - NullWindow(const anbox::wm::Task::Id &task, const anbox::graphics::Rect &frame) : - anbox::wm::Window(0, frame) { - } + public: + NullWindow(const anbox::wm::Task::Id &task, + const anbox::graphics::Rect &frame) + : anbox::wm::Window(0, frame) {} -protected: - void resize(int width, int height) override { - WARNING("Not implemented"); - } + protected: + void resize(int width, int height) override { WARNING("Not implemented"); } - void update_position(int x, int y) override { - WARNING("Not implemented"); - } + void update_position(int x, int y) override { WARNING("Not implemented"); } }; } namespace anbox { namespace wm { -DefaultPlatformPolicy::DefaultPlatformPolicy() { -} +DefaultPlatformPolicy::DefaultPlatformPolicy() {} -std::shared_ptr DefaultPlatformPolicy::create_window(const anbox::wm::Task::Id &task, const anbox::graphics::Rect &frame) -{ - DEBUG(""); - return std::make_shared<::NullWindow>(task, frame); +std::shared_ptr DefaultPlatformPolicy::create_window( + const anbox::wm::Task::Id &task, const anbox::graphics::Rect &frame) { + DEBUG(""); + return std::make_shared<::NullWindow>(task, frame); } -} // namespace wm -} // namespace anbox +} // namespace wm +} // namespace anbox diff --git a/src/anbox/wm/default_platform_policy.h b/src/anbox/wm/default_platform_policy.h index 9476050..2209506 100644 --- a/src/anbox/wm/default_platform_policy.h +++ b/src/anbox/wm/default_platform_policy.h @@ -23,11 +23,13 @@ namespace anbox { namespace wm { class DefaultPlatformPolicy : public PlatformPolicy { -public: - DefaultPlatformPolicy(); - std::shared_ptr create_window(const anbox::wm::Task::Id &task, const anbox::graphics::Rect &frame) override; + public: + DefaultPlatformPolicy(); + std::shared_ptr create_window( + const anbox::wm::Task::Id &task, + const anbox::graphics::Rect &frame) override; }; -} // namespace wm -} // namespace anbox +} // namespace wm +} // namespace anbox #endif diff --git a/src/anbox/wm/display.cpp b/src/anbox/wm/display.cpp index 671a166..0391234 100644 --- a/src/anbox/wm/display.cpp +++ b/src/anbox/wm/display.cpp @@ -21,5 +21,5 @@ namespace anbox { namespace wm { Display::Id Display::Invalid = -1; Display::Id Display::Default = 0; -} // namespace wm -} // namespace anbox +} // namespace wm +} // namespace anbox diff --git a/src/anbox/wm/display.h b/src/anbox/wm/display.h index 6b53baf..8488ae3 100644 --- a/src/anbox/wm/display.h +++ b/src/anbox/wm/display.h @@ -23,16 +23,16 @@ namespace anbox { namespace wm { class Display { -public: - typedef std::int32_t Id; + public: + typedef std::int32_t Id; - static Id Invalid; - static Id Default; + static Id Invalid; + static Id Default; - Display() = delete; - Display(const Display&) = delete; + Display() = delete; + Display(const Display&) = delete; }; -} // namespace wm -} // namespace anbox +} // namespace wm +} // namespace anbox #endif diff --git a/src/anbox/wm/manager.cpp b/src/anbox/wm/manager.cpp index 67c7a24..fbd58b9 100644 --- a/src/anbox/wm/manager.cpp +++ b/src/anbox/wm/manager.cpp @@ -16,99 +16,87 @@ */ #include "anbox/wm/manager.h" -#include "anbox/wm/platform_policy.h" #include "anbox/logger.h" +#include "anbox/wm/platform_policy.h" #include namespace anbox { namespace wm { -Manager::Manager(const std::shared_ptr &platform) : - platform_(platform) { -} +Manager::Manager(const std::shared_ptr &platform) + : platform_(platform) {} -Manager::~Manager() { -} +Manager::~Manager() {} void Manager::apply_window_state_update(const WindowState::List &updated, - const WindowState::List &removed) -{ - std::lock_guard l(mutex_); + const WindowState::List &removed) { + std::lock_guard l(mutex_); - // Base on the update we get from the Android WindowManagerService we will create - // different window instances with the properties supplied. Incoming layer updates - // from SurfaceFlinger will be mapped later into those windows and eventually - // composited there via GLES (e.g. for popups, ..) + // Base on the update we get from the Android WindowManagerService we will + // create + // different window instances with the properties supplied. Incoming layer + // updates + // from SurfaceFlinger will be mapped later into those windows and eventually + // composited there via GLES (e.g. for popups, ..) - std::map task_updates; + std::map task_updates; - for (const auto &window : updated) - { - // Ignore all windows which are not part of the freeform task stack - if (window.stack() != Stack::Freeform) - continue; + for (const auto &window : updated) { + // Ignore all windows which are not part of the freeform task stack + if (window.stack() != Stack::Freeform) continue; - // And also those which don't have a surface mapped at the moment - if (!window.has_surface()) - continue; + // And also those which don't have a surface mapped at the moment + if (!window.has_surface()) continue; - // If we know that task already we first collect all window updates - // for it so we can apply all of them together. - auto w = windows_.find(window.task()); - if (w != windows_.end()) - { - auto t = task_updates.find(window.task()); - if (t == task_updates.end()) - task_updates.insert({window.task(), {window}}); - else - task_updates[window.task()].push_back(window); - continue; - } - - auto platform_window = platform_->create_window(window.task(), window.frame()); - platform_window->attach(); - windows_.insert({window.task(), platform_window}); + // If we know that task already we first collect all window updates + // for it so we can apply all of them together. + auto w = windows_.find(window.task()); + if (w != windows_.end()) { + auto t = task_updates.find(window.task()); + if (t == task_updates.end()) + task_updates.insert({window.task(), {window}}); + else + task_updates[window.task()].push_back(window); + continue; } - // Send updates we collected per task down to the corresponding window - // so that they can update themself. - for (const auto &u : task_updates) - { - auto w = windows_.find(u.first); - if (w == windows_.end()) - continue; + auto platform_window = + platform_->create_window(window.task(), window.frame()); + platform_window->attach(); + windows_.insert({window.task(), platform_window}); + } - w->second->update_state(u.second); - } - - // As final step we process all windows we need to remove as they - // got killed on the other side. We need to respect here that we - // also get removals for windows which are part of a task which is - // still in use by other windows. - for (const auto &window : removed) - { - auto w = windows_.find(window.task()); - if (w == windows_.end()) - continue; - - if (task_updates.find(window.task()) == task_updates.end()) - { - auto platform_window = w->second; - platform_window->release(); - windows_.erase(w); - } + // Send updates we collected per task down to the corresponding window + // so that they can update themself. + for (const auto &u : task_updates) { + auto w = windows_.find(u.first); + if (w == windows_.end()) continue; + + w->second->update_state(u.second); + } + + // As final step we process all windows we need to remove as they + // got killed on the other side. We need to respect here that we + // also get removals for windows which are part of a task which is + // still in use by other windows. + for (const auto &window : removed) { + auto w = windows_.find(window.task()); + if (w == windows_.end()) continue; + + if (task_updates.find(window.task()) == task_updates.end()) { + auto platform_window = w->second; + platform_window->release(); + windows_.erase(w); } + } } -std::shared_ptr Manager::find_window_for_task(const Task::Id &task) -{ - std::lock_guard l(mutex_); - for (const auto &w : windows_) - { - if (w.second->task() == task) - return w.second; - } - return nullptr; +std::shared_ptr Manager::find_window_for_task(const Task::Id &task) { + std::lock_guard l(mutex_); + for (const auto &w : windows_) { + if (w.second->task() == task) return w.second; + } + return nullptr; } -} // namespace wm -} // namespace anbox +} // namespace wm +} // namespace anbox diff --git a/src/anbox/wm/manager.h b/src/anbox/wm/manager.h index aa4eede..823547f 100644 --- a/src/anbox/wm/manager.h +++ b/src/anbox/wm/manager.h @@ -18,32 +18,32 @@ #ifndef ANBOX_WM_MANAGER_H_ #define ANBOX_WM_MANAGER_H_ -#include "anbox/wm/window_state.h" #include "anbox/wm/window.h" +#include "anbox/wm/window_state.h" -#include #include +#include #include namespace anbox { namespace wm { class PlatformPolicy; class Manager { -public: - Manager(const std::shared_ptr &platform); - ~Manager(); + public: + Manager(const std::shared_ptr &platform); + ~Manager(); - void apply_window_state_update(const WindowState::List &updated, - const WindowState::List &removed); + void apply_window_state_update(const WindowState::List &updated, + const WindowState::List &removed); - std::shared_ptr find_window_for_task(const Task::Id &task); + std::shared_ptr find_window_for_task(const Task::Id &task); -private: - std::mutex mutex_; - std::shared_ptr platform_; - std::map> windows_; + private: + std::mutex mutex_; + std::shared_ptr platform_; + std::map> windows_; }; -} // namespace wm -} // namespace anbox +} // namespace wm +} // namespace anbox #endif diff --git a/src/anbox/wm/platform_policy.cpp b/src/anbox/wm/platform_policy.cpp index 922acf5..daf55b9 100644 --- a/src/anbox/wm/platform_policy.cpp +++ b/src/anbox/wm/platform_policy.cpp @@ -19,7 +19,6 @@ namespace anbox { namespace wm { -PlatformPolicy::~PlatformPolicy() { -} -} // namespace wm -} // namespace anbox +PlatformPolicy::~PlatformPolicy() {} +} // namespace wm +} // namespace anbox diff --git a/src/anbox/wm/platform_policy.h b/src/anbox/wm/platform_policy.h index f9261e3..4fb286f 100644 --- a/src/anbox/wm/platform_policy.h +++ b/src/anbox/wm/platform_policy.h @@ -27,12 +27,13 @@ namespace anbox { namespace wm { class Window; class PlatformPolicy { -public: - virtual ~PlatformPolicy(); + public: + virtual ~PlatformPolicy(); - virtual std::shared_ptr create_window(const anbox::wm::Task::Id &task, const anbox::graphics::Rect &frame) = 0; + virtual std::shared_ptr create_window( + const anbox::wm::Task::Id &task, const anbox::graphics::Rect &frame) = 0; }; -} // namespace wm -} // namespace anbox +} // namespace wm +} // namespace anbox #endif diff --git a/src/anbox/wm/stack.cpp b/src/anbox/wm/stack.cpp index 99af33f..009a860 100644 --- a/src/anbox/wm/stack.cpp +++ b/src/anbox/wm/stack.cpp @@ -23,5 +23,5 @@ Stack::Id Stack::Invalid = -1; Stack::Id Stack::Default = 0; Stack::Id Stack::Fullscreen = 1; Stack::Id Stack::Freeform = 2; -} // namespace wm -} // namespace anbox +} // namespace wm +} // namespace anbox diff --git a/src/anbox/wm/stack.h b/src/anbox/wm/stack.h index ea15985..092b29d 100644 --- a/src/anbox/wm/stack.h +++ b/src/anbox/wm/stack.h @@ -23,18 +23,18 @@ namespace anbox { namespace wm { class Stack { -public: - typedef std::int32_t Id; + public: + typedef std::int32_t Id; - static Id Invalid; - static Id Default; - static Id Fullscreen; - static Id Freeform; + static Id Invalid; + static Id Default; + static Id Fullscreen; + static Id Freeform; - Stack() = delete; - Stack(const Stack&) = delete; + Stack() = delete; + Stack(const Stack&) = delete; }; -} // namespace wm -} // namespace anbox +} // namespace wm +} // namespace anbox #endif diff --git a/src/anbox/wm/task.cpp b/src/anbox/wm/task.cpp index 46cecee..92be801 100644 --- a/src/anbox/wm/task.cpp +++ b/src/anbox/wm/task.cpp @@ -20,5 +20,5 @@ namespace anbox { namespace wm { Task::Id Task::Invalid = -1; -} // namespace wm -} // namespace anbox +} // namespace wm +} // namespace anbox diff --git a/src/anbox/wm/task.h b/src/anbox/wm/task.h index fa7e8f7..b137ecf 100644 --- a/src/anbox/wm/task.h +++ b/src/anbox/wm/task.h @@ -23,15 +23,15 @@ namespace anbox { namespace wm { class Task { -public: - typedef std::int32_t Id; + public: + typedef std::int32_t Id; - static Id Invalid; + static Id Invalid; - Task() = delete; - Task(const Task&) = delete; + Task() = delete; + Task(const Task&) = delete; }; -} // namespace wm -} // namespace anbox +} // namespace wm +} // namespace anbox #endif diff --git a/src/anbox/wm/window.cpp b/src/anbox/wm/window.cpp index 03968fb..49d681e 100644 --- a/src/anbox/wm/window.cpp +++ b/src/anbox/wm/window.cpp @@ -21,51 +21,37 @@ namespace anbox { namespace wm { -Window::Window(const Task::Id &task, const graphics::Rect &frame) : - task_(task), - frame_(frame) { +Window::Window(const Task::Id &task, const graphics::Rect &frame) + : task_(task), frame_(frame) {} + +Window::~Window() {} + +void Window::update_state(const WindowState::List &states) {} + +void Window::update_frame(const graphics::Rect &frame) { + if (frame == frame_) return; + + if (frame.width() != frame_.width() || frame.height() != frame_.height()) + resize(frame.width(), frame.height()); + + if (frame.top() != frame_.top() || frame.left() != frame_.left()) + update_position(frame.left(), frame.top()); + + frame_ = frame; } -Window::~Window() { -} +Task::Id Window::task() const { return task_; } -void Window::update_state(const WindowState::List &states) -{ -} +graphics::Rect Window::frame() const { return frame_; } -void Window::update_frame(const graphics::Rect &frame) -{ - if (frame == frame_) - return; - - if (frame.width() != frame_.width() || frame.height() != frame_.height()) - resize(frame.width(), frame.height()); - - if (frame.top() != frame_.top() || frame.left() != frame_.left()) - update_position(frame.left(), frame.top()); - - frame_ = frame; -} - -Task::Id Window::task() const { - return task_; -} - -graphics::Rect Window::frame() const { - return frame_; -} - -EGLNativeWindowType Window::native_handle() const { - return 0; -} +EGLNativeWindowType Window::native_handle() const { return 0; } bool Window::attach() { - return Renderer::get()->createNativeWindow(native_handle()); + return Renderer::get()->createNativeWindow(native_handle()); } void Window::release() { - Renderer::get()->destroyNativeWindow(native_handle()); + Renderer::get()->destroyNativeWindow(native_handle()); } -} // namespace wm -} // namespace anbox - +} // namespace wm +} // namespace anbox diff --git a/src/anbox/wm/window.h b/src/anbox/wm/window.h index 687e90d..0e44e58 100644 --- a/src/anbox/wm/window.h +++ b/src/anbox/wm/window.h @@ -20,8 +20,8 @@ #include "anbox/wm/window_state.h" -#include #include +#include #include @@ -30,40 +30,39 @@ namespace wm { // FIXME(morphis): move this somewhere else once we have the integration // with the emugl layer. class Layer { -public: - graphics::Rect frame() const { return frame_; } + public: + graphics::Rect frame() const { return frame_; } -private: - graphics::Rect frame_; + private: + graphics::Rect frame_; }; -class Window -{ -public: - typedef std::vector List; +class Window { + public: + typedef std::vector List; - Window(const Task::Id &task, const graphics::Rect &frame); - virtual ~Window(); + Window(const Task::Id &task, const graphics::Rect &frame); + virtual ~Window(); - bool attach(); - void release(); + bool attach(); + void release(); - void update_state(const WindowState::List &states); - void update_frame(const graphics::Rect &frame); + void update_state(const WindowState::List &states); + void update_frame(const graphics::Rect &frame); - virtual EGLNativeWindowType native_handle() const; - graphics::Rect frame() const; - Task::Id task() const; + virtual EGLNativeWindowType native_handle() const; + graphics::Rect frame() const; + Task::Id task() const; -protected: - virtual void resize(int width, int height) = 0; - virtual void update_position(int x, int y) = 0; + protected: + virtual void resize(int width, int height) = 0; + virtual void update_position(int x, int y) = 0; -private: - Task::Id task_; - graphics::Rect frame_; + private: + Task::Id task_; + graphics::Rect frame_; }; -} // namespace wm -} // namespace anbox +} // namespace wm +} // namespace anbox #endif diff --git a/src/anbox/wm/window_state.cpp b/src/anbox/wm/window_state.cpp index 7067da6..d5b1494 100644 --- a/src/anbox/wm/window_state.cpp +++ b/src/anbox/wm/window_state.cpp @@ -19,30 +19,25 @@ namespace anbox { namespace wm { -WindowState::WindowState() : - display_(Display::Invalid), - has_surface_(false), - frame_(graphics::Rect::Invalid), - package_name_(""), - task_(Task::Invalid), - stack_(Stack::Invalid) { -} +WindowState::WindowState() + : display_(Display::Invalid), + has_surface_(false), + frame_(graphics::Rect::Invalid), + package_name_(""), + task_(Task::Invalid), + stack_(Stack::Invalid) {} -WindowState::WindowState(const Display::Id &display, - bool has_surface, +WindowState::WindowState(const Display::Id &display, bool has_surface, const graphics::Rect &frame, - const std::string &package_name, - const Task::Id &task, - const Stack::Id &stack) : - display_(display), - has_surface_(has_surface), - frame_(frame), - package_name_(package_name), - task_(task), - stack_(stack) { -} + const std::string &package_name, const Task::Id &task, + const Stack::Id &stack) + : display_(display), + has_surface_(has_surface), + frame_(frame), + package_name_(package_name), + task_(task), + stack_(stack) {} -WindowState::~WindowState() { -} -} // namespace wm -} // namespace anbox +WindowState::~WindowState() {} +} // namespace wm +} // namespace anbox diff --git a/src/anbox/wm/window_state.h b/src/anbox/wm/window_state.h index 603ed3a..ca24b8d 100644 --- a/src/anbox/wm/window_state.h +++ b/src/anbox/wm/window_state.h @@ -20,44 +20,40 @@ #include "anbox/graphics/rect.h" #include "anbox/wm/display.h" -#include "anbox/wm/task.h" #include "anbox/wm/stack.h" +#include "anbox/wm/task.h" -#include #include +#include namespace anbox { namespace wm { class WindowState { -public: - typedef std::vector List; + public: + typedef std::vector List; - WindowState(); - WindowState(const Display::Id &display, - bool has_surface, - const graphics::Rect &frame, - const std::string &package_name, - const Task::Id &task, - const Stack::Id &stack); - ~WindowState(); + WindowState(); + WindowState(const Display::Id &display, bool has_surface, + const graphics::Rect &frame, const std::string &package_name, + const Task::Id &task, const Stack::Id &stack); + ~WindowState(); - Display::Id display() const { return display_; } - bool has_surface() const { return has_surface_; } - graphics::Rect frame() const { return frame_; } - std::string package_name() const { return package_name_; } - Task::Id task() const { return task_; } - Stack::Id stack() const { return stack_; } - -private: - Display::Id display_; - bool has_surface_; - graphics::Rect frame_; - std::string package_name_; - Task::Id task_; - Stack::Id stack_; + Display::Id display() const { return display_; } + bool has_surface() const { return has_surface_; } + graphics::Rect frame() const { return frame_; } + std::string package_name() const { return package_name_; } + Task::Id task() const { return task_; } + Stack::Id stack() const { return stack_; } + private: + Display::Id display_; + bool has_surface_; + graphics::Rect frame_; + std::string package_name_; + Task::Id task_; + Stack::Id stack_; }; -} // namespace wm -} // namespace anbox +} // namespace wm +} // namespace anbox #endif diff --git a/src/container_main.cpp b/src/container_main.cpp index bbc7bcf..cbfe9b8 100644 --- a/src/container_main.cpp +++ b/src/container_main.cpp @@ -18,9 +18,9 @@ #include "anbox/container/service.h" int main(int argc, char **argv) { - (void) argc; - (void) argv; - anbox::container::Service service; + (void)argc; + (void)argv; + anbox::container::Service service; - return 0; + return 0; } diff --git a/src/main.cpp b/src/main.cpp index 78a5c79..1657cdd 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -19,6 +19,6 @@ #include "anbox/utils.h" int main(int argc, char **argv) { - anbox::Daemon daemon; - return daemon.Run(anbox::utils::collect_arguments(argc, argv)); + anbox::Daemon daemon; + return daemon.Run(anbox::utils::collect_arguments(argc, argv)); }