From bcdbdbac6ac7a9675011783717ecee1839702b03 Mon Sep 17 00:00:00 2001 From: Simon Fels Date: Tue, 2 May 2017 07:21:47 +0200 Subject: [PATCH 01/20] external: prevent a child process from killing a process on cleanup --- .../include/core/posix/child_process.h | 6 ++++++ .../process-cpp-minimal/src/core/posix/child_process.cpp | 9 ++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/external/process-cpp-minimal/include/core/posix/child_process.h b/external/process-cpp-minimal/include/core/posix/child_process.h index d6b3b31..fde7977 100644 --- a/external/process-cpp-minimal/include/core/posix/child_process.h +++ b/external/process-cpp-minimal/include/core/posix/child_process.h @@ -114,6 +114,12 @@ public: */ wait::Result wait_for(const wait::Flags& flags); + /** + * @brief Mark the child process to not to be killed when the ChildProcess + * instance goes away. + */ + void dont_kill_on_cleanup(); + #ifndef ANDROID /** * @brief Access this process's stderr. diff --git a/external/process-cpp-minimal/src/core/posix/child_process.cpp b/external/process-cpp-minimal/src/core/posix/child_process.cpp index b121b89..ad16571 100644 --- a/external/process-cpp-minimal/src/core/posix/child_process.cpp +++ b/external/process-cpp-minimal/src/core/posix/child_process.cpp @@ -303,7 +303,7 @@ struct ChildProcess::Private ~Private() { // Check if we are in the original parent process. - if (original_parent_pid == getpid()) + if (original_parent_pid == getpid() && !dont_kill_on_cleanup) { // If so, check if we are considering a valid pid here. // If so, we kill the original child. @@ -333,6 +333,8 @@ struct ChildProcess::Private // is called from the child process. pid_t original_parent_pid; pid_t original_child_pid; + + bool dont_kill_on_cleanup = false; }; ChildProcess ChildProcess::invalid() @@ -395,6 +397,11 @@ wait::Result ChildProcess::wait_for(const wait::Flags& flags) return result; } +void ChildProcess::dont_kill_on_cleanup() +{ + d->dont_kill_on_cleanup = true; +} + #ifndef ANDROID std::istream& ChildProcess::cerr() { From 83bf973d98de9efd38cc42f9043b808a583bb616 Mon Sep 17 00:00:00 2001 From: Simon Fels Date: Tue, 2 May 2017 07:22:13 +0200 Subject: [PATCH 02/20] dbus: stub: don't register an object but retrieve the already registered one --- src/anbox/dbus/skeleton/service.cpp | 6 ++---- src/anbox/dbus/stub/application_manager.cpp | 2 +- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/anbox/dbus/skeleton/service.cpp b/src/anbox/dbus/skeleton/service.cpp index 40910c1..8f309c2 100644 --- a/src/anbox/dbus/skeleton/service.cpp +++ b/src/anbox/dbus/skeleton/service.cpp @@ -25,10 +25,8 @@ 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()); + 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); } diff --git a/src/anbox/dbus/stub/application_manager.cpp b/src/anbox/dbus/stub/application_manager.cpp index e11176f..743d73e 100644 --- a/src/anbox/dbus/stub/application_manager.cpp +++ b/src/anbox/dbus/stub/application_manager.cpp @@ -25,7 +25,7 @@ namespace dbus { namespace stub { std::shared_ptr ApplicationManager::create_for_bus(const core::dbus::Bus::Ptr &bus) { auto service = core::dbus::Service::use_service_or_throw_if_not_available(bus, anbox::dbus::interface::Service::name()); - auto object = service->add_object_for_path(anbox::dbus::interface::Service::path()); + auto object = service->object_for_path(anbox::dbus::interface::Service::path()); return std::make_shared(bus, service, object); } From d2eae3a832ce9c3e4f5218f73cfdcd1c1e33dc05 Mon Sep 17 00:00:00 2001 From: Simon Fels Date: Tue, 2 May 2017 07:23:18 +0200 Subject: [PATCH 03/20] cmds/launch: start session manager if not already running --- src/anbox/cmds/launch.cpp | 48 +++++++++++++++++++++++++++++++++++---- 1 file changed, 44 insertions(+), 4 deletions(-) diff --git a/src/anbox/cmds/launch.cpp b/src/anbox/cmds/launch.cpp index a73e2b6..f4e8202 100644 --- a/src/anbox/cmds/launch.cpp +++ b/src/anbox/cmds/launch.cpp @@ -26,12 +26,16 @@ #include +#include "core/posix/exec.h" +#include "core/posix/fork.h" #include "core/posix/signal.h" namespace fs = boost::filesystem; namespace { const boost::posix_time::seconds max_wait_timeout{30}; +const unsigned int max_restart_attempts{3}; +const std::chrono::seconds restart_interval{1}; } anbox::cmds::Launch::Launch() @@ -69,11 +73,47 @@ anbox::cmds::Launch::Launch() auto bus = std::make_shared(core::dbus::WellKnownBus::session); bus->install_executor(core::dbus::asio::make_executor(bus, rt->service())); + // Instead of relying on the user session init system to start our + // session manager process we also attempt to start it on 0our own + // if not already running. This will help to mitigate problems with + // a crashing or a not yet started session manager instance. std::shared_ptr stub; - try { - stub = dbus::stub::ApplicationManager::create_for_bus(bus); - } catch (...) { - ERROR("Anbox session manager service isn't running!"); + for (auto n = 0; n < max_restart_attempts; n++) { + try { + stub = dbus::stub::ApplicationManager::create_for_bus(bus); + } catch (std::exception &err) { + WARNING("Anbox session manager service isn't running, trying to start it."); + + std::vector args = {"session-manager"}; + + std::map env; + core::posix::this_process::env::for_each([&](const std::string &name, const std::string &value) { + env.insert({name, value}); + }); + + const auto exe_path = utils::process_get_exe_path(::getpid()); + + try { + const auto flags = core::posix::StandardStream::stdout | core::posix::StandardStream::stderr; + auto child = core::posix::fork([&]() { + auto grandchild = core::posix::exec(exe_path, args, env, flags); + grandchild.dont_kill_on_cleanup(); + return core::posix::exit::Status::success; + }, flags); + child.wait_for(core::posix::wait::Flags::untraced); + + DEBUG("Started session manager, will now try to connect .."); + } + catch (...) { + ERROR("Failed to start session manager instance"); + } + } + + std::this_thread::sleep_for(restart_interval); + } + + if (!stub) { + ERROR("Couldn't get a connection with the session manager"); return EXIT_FAILURE; } From 855a391a5bf579f647fa47d8d5d7c9223528edaa Mon Sep 17 00:00:00 2001 From: Simon Fels Date: Tue, 2 May 2017 08:13:33 +0200 Subject: [PATCH 04/20] android: only print intent information when available --- src/anbox/android/intent.cpp | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/src/anbox/android/intent.cpp b/src/anbox/android/intent.cpp index aa40f2c..8344dc0 100644 --- a/src/anbox/android/intent.cpp +++ b/src/anbox/android/intent.cpp @@ -22,16 +22,25 @@ 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 << "]]"; + out << "["; + if (intent.action.length() > 0) + out << " " << "action=" << intent.action << " "; + if (intent.uri.length() > 0) + out << " " << "uri=" << intent.uri << " "; + if (intent.type.length() > 0) + out << " " << "type=" << intent.type << " "; + if (intent.flags > 0) + out << " " << "flags=" << intent.flags << " "; + if (intent.package.length() > 0) + out << " " << "package=" << intent.package << " "; + if (intent.component.length() > 0) + out << "component=" << intent.component << " "; + if (intent.categories.size() > 0) { + out << "categories=[ "; + for (const auto &category : intent.categories) out << category << " "; + out << "] "; + } + out << "]"; return out; } } // namespace android From c44e2a84d84a60c257af8e768ad28e2916e2fc83 Mon Sep 17 00:00:00 2001 From: Simon Fels Date: Tue, 2 May 2017 19:48:17 +0200 Subject: [PATCH 05/20] Add simple splash screen implementation --- src/CMakeLists.txt | 2 + src/anbox/ui/splash_screen.cpp | 85 ++++++++++++++++++++++++++++++++++ src/anbox/ui/splash_screen.h | 42 +++++++++++++++++ 3 files changed, 129 insertions(+) create mode 100644 src/anbox/ui/splash_screen.cpp create mode 100644 src/anbox/ui/splash_screen.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 5675ccb..6dac24c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -203,6 +203,8 @@ set(SOURCES anbox/utils/environment_file.cpp + anbox/ui/splash_screen.cpp + anbox/do_not_copy_or_move.h anbox/optional.h anbox/defer_action.h) diff --git a/src/anbox/ui/splash_screen.cpp b/src/anbox/ui/splash_screen.cpp new file mode 100644 index 0000000..fc94dba --- /dev/null +++ b/src/anbox/ui/splash_screen.cpp @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2017 Simon Fels + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 3, as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + * + */ + +#include "anbox/ui/splash_screen.h" +#include "anbox/utils.h" + +#include + +namespace anbox { +namespace ui { +SplashScreen::SplashScreen() { + if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS) < 0) { + const auto message = utils::string_format("Failed to initialize SDL: %s", SDL_GetError()); + BOOST_THROW_EXCEPTION(std::runtime_error(message)); + } + + const auto width = 1024, height = 768; + window_ = SDL_CreateWindow("", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, + width, 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)); + } + + auto surface = SDL_GetWindowSurface(window_); + SDL_FillRect(surface, nullptr, SDL_MapRGB(surface->format, 0xee, 0xee, 0xee)); + SDL_UpdateWindowSurface(window_); + + auto renderer = SDL_CreateRenderer(window_, -1, SDL_RENDERER_ACCELERATED); + auto img = IMG_LoadTexture(renderer, "/snap/anbox/current/snap/gui/icon.png"); + + const auto tex_width = 128, tex_height = 128; + SDL_Rect r{(width - tex_width) / 2, (height - tex_height) / 2, 128, 128}; + + SDL_SetRenderDrawColor(renderer, 0xee, 0xee, 0xee, 0xff); + SDL_RenderClear(renderer); + SDL_RenderCopy(renderer, img, nullptr, &r); + SDL_RenderPresent(renderer); + + SDL_ShowWindow(window_); + + event_thread_ = std::thread(&SplashScreen::process_events, this); +} + +SplashScreen::~SplashScreen() { + if (event_thread_running_) { + event_thread_running_ = false; + if (event_thread_.joinable()) + event_thread_.join(); + } + + if (window_) + SDL_DestroyWindow(window_); +} + +void SplashScreen::process_events() { + event_thread_running_ = true; + while (event_thread_running_) { + SDL_Event event; + while (SDL_WaitEventTimeout(&event, 100)) { + switch (event.type) { + case SDL_QUIT: + break; + default: + break; + } + } + } +} +} // namespace ui +} // namespace anbox diff --git a/src/anbox/ui/splash_screen.h b/src/anbox/ui/splash_screen.h new file mode 100644 index 0000000..bee6f6d --- /dev/null +++ b/src/anbox/ui/splash_screen.h @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2017 Simon Fels + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 3, as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + * + */ + +#ifndef ANBOX_UI_SPLASH_SCREEN_H_ +#define ANBOX_UI_SPLASH_SCREEN_H_ + +#include + +#include + +namespace anbox { +namespace ui { +class SplashScreen { + public: + SplashScreen(); + ~SplashScreen(); + + private: + void process_events(); + + std::thread event_thread_; + bool event_thread_running_; + SDL_Window *window_; +}; +} // namespace ui +} // namespace anbox + +#endif From ee105c396300b1ba7ae12c9499ad13089d3b5d14 Mon Sep 17 00:00:00 2001 From: Simon Fels Date: Wed, 3 May 2017 07:57:00 +0200 Subject: [PATCH 06/20] Hook splash screen into our launcher --- src/anbox/cmds/launch.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/anbox/cmds/launch.cpp b/src/anbox/cmds/launch.cpp index f4e8202..b484817 100644 --- a/src/anbox/cmds/launch.cpp +++ b/src/anbox/cmds/launch.cpp @@ -19,6 +19,7 @@ #include "anbox/common/wait_handle.h" #include "anbox/dbus/stub/application_manager.h" #include "anbox/common/dispatcher.h" +#include "anbox/ui/splash_screen.h" #include "anbox/runtime.h" #include "anbox/logger.h" @@ -73,6 +74,8 @@ anbox::cmds::Launch::Launch() auto bus = std::make_shared(core::dbus::WellKnownBus::session); bus->install_executor(core::dbus::asio::make_executor(bus, rt->service())); + std::shared_ptr ss; + // Instead of relying on the user session init system to start our // session manager process we also attempt to start it on 0our own // if not already running. This will help to mitigate problems with @@ -84,6 +87,12 @@ anbox::cmds::Launch::Launch() } catch (std::exception &err) { WARNING("Anbox session manager service isn't running, trying to start it."); + // Give us a splash screen as long as we're trying to connect + // with the session manager so the user knows something is + // happening after he started Anbox. + if (!ss) + ss = std::make_shared(); + std::vector args = {"session-manager"}; std::map env; @@ -129,6 +138,7 @@ anbox::cmds::Launch::Launch() } catch (std::exception &err) { ERROR("err %s", err.what()); } + ss.reset(); trap->stop(); return; } @@ -145,6 +155,7 @@ anbox::cmds::Launch::Launch() ERROR("Failed to launch activity: %s", err.what()); success = false; } + ss.reset(); trap->stop(); }); }); From bcb00e31afbbd6eec00fd2c2a16c703b41aad8f0 Mon Sep 17 00:00:00 2001 From: Simon Fels Date: Wed, 3 May 2017 07:57:33 +0200 Subject: [PATCH 07/20] Add necessary dependency on SDL2 image --- CMakeLists.txt | 1 + src/CMakeLists.txt | 3 +++ 2 files changed, 4 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 957664b..bf489a7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -64,6 +64,7 @@ find_package(GLESv2 REQUIRED) find_package(Protobuf REQUIRED) pkg_check_modules(SDL2 sdl2 REQUIRED) +pkg_check_modules(SDL2_IMAGE SDL2_image REQUIRED) pkg_check_modules(DBUS_CPP dbus-cpp REQUIRED) pkg_check_modules(DBUS dbus-1 REQUIRED) pkg_check_modules(LXC lxc REQUIRED) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6dac24c..f8017a4 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -7,6 +7,7 @@ include_directories( ${DBUS_CPP_INCLUDE_DIRS} ${DBUS_INCLUDE_DIRS} ${SDL2_INCLUDE_DIRS} + ${SDL2_IMAGE_INCLUDE_DIRS} ${LXC_INCLUDE_DIRS} ${MIRCLIENT_INCLUDE_DIRS} ${CMAKE_CURRENT_BINARY_DIR} @@ -217,6 +218,8 @@ target_link_libraries(anbox-core ${DBUS_CPP_LIBRARIES} ${SDL2_LDFLAGS} ${SDL2_LIBRARIES} + ${SDL2_IMAGE_LDFLAGS} + ${SDL2_IMAGE_LIBRARIES} ${LXC_LDFLAGS} ${LXC_LIBRARIES} ${MIRCLIENT_LDFLAGS} From f4df33efe4219db2114204e19105d7818f363944 Mon Sep 17 00:00:00 2001 From: Simon Fels Date: Wed, 3 May 2017 07:57:54 +0200 Subject: [PATCH 08/20] Improve launch and splash screen interactions --- src/anbox/cmds/launch.cpp | 55 +++++++++++++++++++++------------------ src/anbox/cmds/launch.h | 3 +++ 2 files changed, 32 insertions(+), 26 deletions(-) diff --git a/src/anbox/cmds/launch.cpp b/src/anbox/cmds/launch.cpp index b484817..66de05e 100644 --- a/src/anbox/cmds/launch.cpp +++ b/src/anbox/cmds/launch.cpp @@ -34,9 +34,20 @@ namespace fs = boost::filesystem; namespace { -const boost::posix_time::seconds max_wait_timeout{30}; -const unsigned int max_restart_attempts{3}; -const std::chrono::seconds restart_interval{1}; +const boost::posix_time::seconds max_wait_timeout{240}; +const int max_restart_attempts{3}; +const std::chrono::seconds restart_interval{5}; +} + +bool anbox::cmds::Launch::try_launch_activity(const std::shared_ptr &stub) { + try { + DEBUG("Sending launch intent %s to Android ..", intent_); + stub->launch(intent_, graphics::Rect::Invalid, stack_); + } catch (std::exception &err) { + ERROR("Failed to launch activity: %s", err.what()); + return false; + } + return true; } anbox::cmds::Launch::Launch() @@ -77,13 +88,14 @@ anbox::cmds::Launch::Launch() std::shared_ptr ss; // Instead of relying on the user session init system to start our - // session manager process we also attempt to start it on 0our own + // session manager process we also attempt to start it on our own // if not already running. This will help to mitigate problems with // a crashing or a not yet started session manager instance. std::shared_ptr stub; for (auto n = 0; n < max_restart_attempts; n++) { try { stub = dbus::stub::ApplicationManager::create_for_bus(bus); + break; } catch (std::exception &err) { WARNING("Anbox session manager service isn't running, trying to start it."); @@ -101,9 +113,13 @@ anbox::cmds::Launch::Launch() }); const auto exe_path = utils::process_get_exe_path(::getpid()); + if (!fs::exists(exe_path)) { + ERROR("Can't find correct anbox executable to run. Found %s but does not exist", exe_path); + return EXIT_FAILURE; + } try { - const auto flags = core::posix::StandardStream::stdout | core::posix::StandardStream::stderr; + const auto flags = core::posix::StandardStream::empty; // core::posix::StandardStream::stdout | core::posix::StandardStream::stderr; auto child = core::posix::fork([&]() { auto grandchild = core::posix::exec(exe_path, args, env, flags); grandchild.dont_kill_on_cleanup(); @@ -116,9 +132,9 @@ anbox::cmds::Launch::Launch() catch (...) { ERROR("Failed to start session manager instance"); } - } - std::this_thread::sleep_for(restart_interval); + std::this_thread::sleep_for(restart_interval); + } } if (!stub) { @@ -126,36 +142,23 @@ anbox::cmds::Launch::Launch() return EXIT_FAILURE; } - auto dispatcher = anbox::common::create_dispatcher_for_runtime(rt); - bool success = false; - + auto dispatcher = anbox::common::create_dispatcher_for_runtime(rt); dispatcher->dispatch([&]() { if (stub->ready()) { - try { - stub->launch(intent_, graphics::Rect::Invalid, stack_); - success = true; - } catch (std::exception &err) { - ERROR("err %s", err.what()); - } ss.reset(); + success = try_launch_activity(stub); trap->stop(); return; } - DEBUG("Android hasn't fully booted yet. Waiting a bit.."); + DEBUG("Android hasn't fully booted yet. Waiting a bit .."); stub->ready().changed().connect([&](bool ready) { if (!ready) return; - try { - stub->launch(intent_, graphics::Rect::Invalid, stack_); - success = true; - } catch (std::exception &err) { - ERROR("Failed to launch activity: %s", err.what()); - success = false; - } ss.reset(); + success = try_launch_activity(stub); trap->stop(); }); }); @@ -163,8 +166,8 @@ anbox::cmds::Launch::Launch() boost::asio::deadline_timer timer(rt->service()); timer.expires_from_now(max_wait_timeout); timer.async_wait([&](const boost::system::error_code&) { - WARNING("Stop waiting as we're already waiting for too long. Something is wrong"); - WARNING("with your setup and the container may have failed to boot."); + WARNING("Stopped waiting as we're already waited for too long. Something"); + WARNING("is wrong with your setup or the container has failed to boot."); trap->stop(); }); diff --git a/src/anbox/cmds/launch.h b/src/anbox/cmds/launch.h index b7a6dfe..7fc71c9 100644 --- a/src/anbox/cmds/launch.h +++ b/src/anbox/cmds/launch.h @@ -23,6 +23,7 @@ #include #include "anbox/android/intent.h" +#include "anbox/dbus/stub/application_manager.h" #include "anbox/wm/stack.h" #include "anbox/cli.h" @@ -33,6 +34,8 @@ class Launch : public cli::CommandWithFlagsAndAction { Launch(); private: + bool try_launch_activity(const std::shared_ptr &stub); + android::Intent intent_; wm::Stack::Id stack_; }; From f0945502795c5a5e624f7c0206574cdd823aa2cb Mon Sep 17 00:00:00 2001 From: Simon Fels Date: Wed, 3 May 2017 08:20:31 +0200 Subject: [PATCH 09/20] Use correct resource path and check for errors on splash screen creation --- src/anbox/config.cpp | 8 ++++++++ src/anbox/config.h | 3 +++ src/anbox/ui/splash_screen.cpp | 14 +++++++++++++- 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/src/anbox/config.cpp b/src/anbox/config.cpp index 7c0961e..d6be507 100644 --- a/src/anbox/config.cpp +++ b/src/anbox/config.cpp @@ -41,6 +41,10 @@ void anbox::SystemConfiguration::set_data_path(const std::string &path) { data_path = path; } +void anbox::SystemConfiguration::set_resource_path(const std::string &path) { + resource_path = path; +} + fs::path anbox::SystemConfiguration::data_dir() const { return data_path; } @@ -76,6 +80,10 @@ std::string anbox::SystemConfiguration::application_item_dir() const { return dir.string(); } +std::string anbox::SystemConfiguration::resource_dir() const { + return resource_path.string(); +} + anbox::SystemConfiguration& anbox::SystemConfiguration::instance() { static SystemConfiguration config; return config; diff --git a/src/anbox/config.h b/src/anbox/config.h index 91f72c6..e3417d8 100644 --- a/src/anbox/config.h +++ b/src/anbox/config.h @@ -31,6 +31,7 @@ class SystemConfiguration { virtual ~SystemConfiguration() = default; void set_data_path(const std::string &path); + void set_resource_path(const std::string &path); boost::filesystem::path data_dir() const; std::string rootfs_dir() const; @@ -40,11 +41,13 @@ class SystemConfiguration { std::string container_socket_path() const; std::string input_device_dir() const; std::string application_item_dir() const; + std::string resource_dir() const; protected: SystemConfiguration() = default; boost::filesystem::path data_path = "/var/lib/anbox"; + boost::filesystem::path resource_path = "/usr/share/anbox"; }; } // namespace anbox diff --git a/src/anbox/ui/splash_screen.cpp b/src/anbox/ui/splash_screen.cpp index fc94dba..c8c7f86 100644 --- a/src/anbox/ui/splash_screen.cpp +++ b/src/anbox/ui/splash_screen.cpp @@ -16,6 +16,7 @@ */ #include "anbox/ui/splash_screen.h" +#include "anbox/config.h" #include "anbox/utils.h" #include @@ -37,11 +38,22 @@ SplashScreen::SplashScreen() { } auto surface = SDL_GetWindowSurface(window_); + if (!surface) + BOOST_THROW_EXCEPTION(std::runtime_error("Could not retrieve surface for our window")); + SDL_FillRect(surface, nullptr, SDL_MapRGB(surface->format, 0xee, 0xee, 0xee)); SDL_UpdateWindowSurface(window_); auto renderer = SDL_CreateRenderer(window_, -1, SDL_RENDERER_ACCELERATED); - auto img = IMG_LoadTexture(renderer, "/snap/anbox/current/snap/gui/icon.png"); + if (!renderer) + BOOST_THROW_EXCEPTION(std::runtime_error("Could not create renderer")); + + const auto icon_path = utils::string_format("%s/ui/icon.png", SystemConfiguration::instance().resource_dir()); + auto img = IMG_LoadTexture(renderer, icon_path.c_str()); + if (!img) { + const auto msg = utils::string_format("Failed to create texture from %s", icon_path); + BOOST_THROW_EXCEPTION(std::runtime_error(msg)); + } const auto tex_width = 128, tex_height = 128; SDL_Rect r{(width - tex_width) / 2, (height - tex_height) / 2, 128, 128}; From f838e759d843613e014775d3f8b15af7af7b428e Mon Sep 17 00:00:00 2001 From: Simon Fels Date: Wed, 3 May 2017 08:25:12 +0200 Subject: [PATCH 10/20] Install necessary resource files --- CMakeLists.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index bf489a7..7be7fdb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -104,3 +104,6 @@ if (NOT "${HOST_CMAKE_C_COMPILER}" STREQUAL "") message(STATUS "Host C compiler: ${HOST_CMAKE_C_COMPILER}") message(STATUS "Host C compiler: ${HOST_CMAKE_CXX_COMPILER}") endif() + +install(FILES snap/gui/icon.png DESTINATION share/anbox/ui) + From 48758d8955473df351cd91822f9606c3175e29f7 Mon Sep 17 00:00:00 2001 From: Simon Fels Date: Wed, 3 May 2017 08:25:33 +0200 Subject: [PATCH 11/20] Set correct resource path when starting from within a snap --- src/anbox/cmds/launch.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/anbox/cmds/launch.cpp b/src/anbox/cmds/launch.cpp index 66de05e..f309491 100644 --- a/src/anbox/cmds/launch.cpp +++ b/src/anbox/cmds/launch.cpp @@ -20,6 +20,7 @@ #include "anbox/dbus/stub/application_manager.h" #include "anbox/common/dispatcher.h" #include "anbox/ui/splash_screen.h" +#include "anbox/config.h" #include "anbox/runtime.h" #include "anbox/logger.h" @@ -85,6 +86,12 @@ anbox::cmds::Launch::Launch() auto bus = std::make_shared(core::dbus::WellKnownBus::session); bus->install_executor(core::dbus::asio::make_executor(bus, rt->service())); + const auto snap_path = utils::get_env_value("SNAP"); + if (!snap_path.empty()) { + const auto resource_path = utils::string_format("%s/share/anbox", snap_path); + SystemConfiguration::instance().set_resource_path(resource_path) + } + std::shared_ptr ss; // Instead of relying on the user session init system to start our From 817f80d6bdb2dcc2c341014b6ba9d46cbc4d04ce Mon Sep 17 00:00:00 2001 From: Simon Fels Date: Wed, 3 May 2017 08:28:56 +0200 Subject: [PATCH 12/20] Add missing build dependency on libsdl2-image-dev --- snapcraft.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/snapcraft.yaml b/snapcraft.yaml index 12cf904..dfd0660 100644 --- a/snapcraft.yaml +++ b/snapcraft.yaml @@ -111,6 +111,7 @@ parts: - libprotobuf-dev - libproperties-cpp-dev - libsdl2-dev + - libsdl2-image-dev - pkg-config - protobuf-compiler stage-packages: From f61a7f91d694b5be88f51c81589408baff3f1299 Mon Sep 17 00:00:00 2001 From: Simon Fels Date: Wed, 3 May 2017 20:47:40 +0200 Subject: [PATCH 13/20] Use a full screen loading image which includes some text --- CMakeLists.txt | 2 +- data/ui/loading-screen.png | Bin 0 -> 13724 bytes snapcraft.yaml | 1 + src/anbox/cmds/launch.cpp | 4 ++-- src/anbox/ui/splash_screen.cpp | 8 +++----- 5 files changed, 7 insertions(+), 8 deletions(-) create mode 100644 data/ui/loading-screen.png diff --git a/CMakeLists.txt b/CMakeLists.txt index 7be7fdb..02064fc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -105,5 +105,5 @@ if (NOT "${HOST_CMAKE_C_COMPILER}" STREQUAL "") message(STATUS "Host C compiler: ${HOST_CMAKE_CXX_COMPILER}") endif() -install(FILES snap/gui/icon.png DESTINATION share/anbox/ui) +install(FILES data/ui/loading-screen.png DESTINATION share/anbox/ui) diff --git a/data/ui/loading-screen.png b/data/ui/loading-screen.png new file mode 100644 index 0000000000000000000000000000000000000000..267836181738c1cc4d05732af9e84d0bac877908 GIT binary patch literal 13724 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 literal 0 HcmV?d00001 diff --git a/snapcraft.yaml b/snapcraft.yaml index dfd0660..7c4d150 100644 --- a/snapcraft.yaml +++ b/snapcraft.yaml @@ -124,4 +124,5 @@ parts: make test prime: - usr/bin/anbox + - usr/share/anbox - usr/lib/*-linux-*/ diff --git a/src/anbox/cmds/launch.cpp b/src/anbox/cmds/launch.cpp index f309491..16f71dd 100644 --- a/src/anbox/cmds/launch.cpp +++ b/src/anbox/cmds/launch.cpp @@ -88,8 +88,8 @@ anbox::cmds::Launch::Launch() const auto snap_path = utils::get_env_value("SNAP"); if (!snap_path.empty()) { - const auto resource_path = utils::string_format("%s/share/anbox", snap_path); - SystemConfiguration::instance().set_resource_path(resource_path) + const auto resource_path = utils::string_format("%s/usr/share/anbox", snap_path); + SystemConfiguration::instance().set_resource_path(resource_path); } std::shared_ptr ss; diff --git a/src/anbox/ui/splash_screen.cpp b/src/anbox/ui/splash_screen.cpp index c8c7f86..c4ca6cf 100644 --- a/src/anbox/ui/splash_screen.cpp +++ b/src/anbox/ui/splash_screen.cpp @@ -48,18 +48,16 @@ SplashScreen::SplashScreen() { if (!renderer) BOOST_THROW_EXCEPTION(std::runtime_error("Could not create renderer")); - const auto icon_path = utils::string_format("%s/ui/icon.png", SystemConfiguration::instance().resource_dir()); + const auto icon_path = utils::string_format("%s/ui/loading-screen.png", SystemConfiguration::instance().resource_dir()); auto img = IMG_LoadTexture(renderer, icon_path.c_str()); if (!img) { const auto msg = utils::string_format("Failed to create texture from %s", icon_path); BOOST_THROW_EXCEPTION(std::runtime_error(msg)); } - const auto tex_width = 128, tex_height = 128; - SDL_Rect r{(width - tex_width) / 2, (height - tex_height) / 2, 128, 128}; - - SDL_SetRenderDrawColor(renderer, 0xee, 0xee, 0xee, 0xff); SDL_RenderClear(renderer); + + SDL_Rect r{0, 0, 1024, 768}; SDL_RenderCopy(renderer, img, nullptr, &r); SDL_RenderPresent(renderer); From 352d774760fad55ef7b952481a5bff2dda782c05 Mon Sep 17 00:00:00 2001 From: Simon Fels Date: Wed, 3 May 2017 20:48:15 +0200 Subject: [PATCH 14/20] Prefer empty check over length one --- src/anbox/android/intent.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/anbox/android/intent.cpp b/src/anbox/android/intent.cpp index 8344dc0..2fcd8f0 100644 --- a/src/anbox/android/intent.cpp +++ b/src/anbox/android/intent.cpp @@ -23,19 +23,19 @@ namespace anbox { namespace android { std::ostream &operator<<(std::ostream &out, const Intent &intent) { out << "["; - if (intent.action.length() > 0) + if (!intent.action.empty()) out << " " << "action=" << intent.action << " "; - if (intent.uri.length() > 0) + if (!intent.uri.empty()) out << " " << "uri=" << intent.uri << " "; - if (intent.type.length() > 0) + if (!intent.type.empty()) out << " " << "type=" << intent.type << " "; if (intent.flags > 0) out << " " << "flags=" << intent.flags << " "; - if (intent.package.length() > 0) + if (!intent.package.empty()) out << " " << "package=" << intent.package << " "; - if (intent.component.length() > 0) + if (!intent.component.empty()) out << "component=" << intent.component << " "; - if (intent.categories.size() > 0) { + if (!intent.categories.size() > 0) { out << "categories=[ "; for (const auto &category : intent.categories) out << category << " "; out << "] "; From 7fe8cfeb38ae9436153d5862b0234e1d65eb5fed Mon Sep 17 00:00:00 2001 From: Simon Fels Date: Wed, 3 May 2017 21:09:30 +0200 Subject: [PATCH 15/20] Use already defined width and height variables --- src/anbox/ui/splash_screen.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/anbox/ui/splash_screen.cpp b/src/anbox/ui/splash_screen.cpp index c4ca6cf..d40ebf5 100644 --- a/src/anbox/ui/splash_screen.cpp +++ b/src/anbox/ui/splash_screen.cpp @@ -57,7 +57,7 @@ SplashScreen::SplashScreen() { SDL_RenderClear(renderer); - SDL_Rect r{0, 0, 1024, 768}; + SDL_Rect r{0, 0, width, height}; SDL_RenderCopy(renderer, img, nullptr, &r); SDL_RenderPresent(renderer); From dfdad4aa6c626c7441e20e3b1fea359037afa65d Mon Sep 17 00:00:00 2001 From: Simon Fels Date: Fri, 5 May 2017 07:05:25 +0200 Subject: [PATCH 16/20] Integrate review feedback --- src/anbox/cmds/launch.cpp | 15 +++++++++++---- src/anbox/config.cpp | 2 +- src/anbox/config.h | 2 +- src/anbox/ui/splash_screen.cpp | 7 +------ 4 files changed, 14 insertions(+), 12 deletions(-) diff --git a/src/anbox/cmds/launch.cpp b/src/anbox/cmds/launch.cpp index 16f71dd..afbd2ab 100644 --- a/src/anbox/cmds/launch.cpp +++ b/src/anbox/cmds/launch.cpp @@ -88,8 +88,8 @@ anbox::cmds::Launch::Launch() const auto snap_path = utils::get_env_value("SNAP"); if (!snap_path.empty()) { - const auto resource_path = utils::string_format("%s/usr/share/anbox", snap_path); - SystemConfiguration::instance().set_resource_path(resource_path); + const auto resource_path = fs::path(snap_path) / "usr" / "share" / "anbox"; + SystemConfiguration::instance().set_resource_path(resource_path.string()); } std::shared_ptr ss; @@ -126,12 +126,17 @@ anbox::cmds::Launch::Launch() } try { - const auto flags = core::posix::StandardStream::empty; // core::posix::StandardStream::stdout | core::posix::StandardStream::stderr; + const auto flags = core::posix::StandardStream::stdout | core::posix::StandardStream::stderr; auto child = core::posix::fork([&]() { auto grandchild = core::posix::exec(exe_path, args, env, flags); grandchild.dont_kill_on_cleanup(); return core::posix::exit::Status::success; }, flags); + + // We don't wait for the grandchild but the child as we use double forking + // here to break through the process hierarchy and make the grandchild a + // direct child of the init process so it keeps running on its own and + // indepent of our short living process here. child.wait_for(core::posix::wait::Flags::untraced); DEBUG("Started session manager, will now try to connect .."); @@ -173,8 +178,10 @@ anbox::cmds::Launch::Launch() boost::asio::deadline_timer timer(rt->service()); timer.expires_from_now(max_wait_timeout); timer.async_wait([&](const boost::system::error_code&) { - WARNING("Stopped waiting as we're already waited for too long. Something"); + WARNING("Stopped waiting as we've already waited for too long. Something"); WARNING("is wrong with your setup or the container has failed to boot."); + WARNING("If you think you found a bug please don't hesitate to file on"); + WARNING("at https://github.com/anbox/anbox/issues/new"); trap->stop(); }); diff --git a/src/anbox/config.cpp b/src/anbox/config.cpp index d6be507..a13aa43 100644 --- a/src/anbox/config.cpp +++ b/src/anbox/config.cpp @@ -41,7 +41,7 @@ void anbox::SystemConfiguration::set_data_path(const std::string &path) { data_path = path; } -void anbox::SystemConfiguration::set_resource_path(const std::string &path) { +void anbox::SystemConfiguration::set_resource_path(const fs::path &path) { resource_path = path; } diff --git a/src/anbox/config.h b/src/anbox/config.h index e3417d8..47a518e 100644 --- a/src/anbox/config.h +++ b/src/anbox/config.h @@ -31,7 +31,7 @@ class SystemConfiguration { virtual ~SystemConfiguration() = default; void set_data_path(const std::string &path); - void set_resource_path(const std::string &path); + void set_resource_path(const boost::filesystem &path); boost::filesystem::path data_dir() const; std::string rootfs_dir() const; diff --git a/src/anbox/ui/splash_screen.cpp b/src/anbox/ui/splash_screen.cpp index d40ebf5..b52c817 100644 --- a/src/anbox/ui/splash_screen.cpp +++ b/src/anbox/ui/splash_screen.cpp @@ -82,12 +82,7 @@ void SplashScreen::process_events() { while (event_thread_running_) { SDL_Event event; while (SDL_WaitEventTimeout(&event, 100)) { - switch (event.type) { - case SDL_QUIT: - break; - default: - break; - } + // Keep running until we're terminated } } } From 68dba196bab47e98d30c17d715bcb1f143bf4d3b Mon Sep 17 00:00:00 2001 From: Simon Fels Date: Fri, 5 May 2017 07:53:43 +0200 Subject: [PATCH 17/20] Add libsdl2-image-dev as build dependency for travis --- scripts/clean-build.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/clean-build.sh b/scripts/clean-build.sh index d7219d7..ab659bb 100755 --- a/scripts/clean-build.sh +++ b/scripts/clean-build.sh @@ -32,6 +32,7 @@ apt-get install -qq -y \ libproperties-cpp-dev \ libprotobuf-dev \ libsdl2-dev \ + libsdl2-image-dev \ lxc-dev \ pkg-config \ protobuf-compiler From 189003ef953912a8a6c4d7f40335afac18502c49 Mon Sep 17 00:00:00 2001 From: Simon Fels Date: Fri, 5 May 2017 18:41:52 +0200 Subject: [PATCH 18/20] Correct exception handling --- src/anbox/cmds/launch.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/anbox/cmds/launch.cpp b/src/anbox/cmds/launch.cpp index afbd2ab..f373c61 100644 --- a/src/anbox/cmds/launch.cpp +++ b/src/anbox/cmds/launch.cpp @@ -44,10 +44,14 @@ bool anbox::cmds::Launch::try_launch_activity(const std::shared_ptrlaunch(intent_, graphics::Rect::Invalid, stack_); - } catch (std::exception &err) { + } catch (const std::exception &err) { ERROR("Failed to launch activity: %s", err.what()); return false; + } catch (...) { + ERROR("Failed to launch activity"); + return false; } + return true; } From 8c1247c0a8fd57fb1e37f064bf4c0956f84d58b7 Mon Sep 17 00:00:00 2001 From: Simon Fels Date: Fri, 5 May 2017 18:45:52 +0200 Subject: [PATCH 19/20] Use boost::filesystem::path correctly --- src/anbox/cmds/launch.cpp | 2 +- src/anbox/config.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/anbox/cmds/launch.cpp b/src/anbox/cmds/launch.cpp index f373c61..69830aa 100644 --- a/src/anbox/cmds/launch.cpp +++ b/src/anbox/cmds/launch.cpp @@ -93,7 +93,7 @@ anbox::cmds::Launch::Launch() const auto snap_path = utils::get_env_value("SNAP"); if (!snap_path.empty()) { const auto resource_path = fs::path(snap_path) / "usr" / "share" / "anbox"; - SystemConfiguration::instance().set_resource_path(resource_path.string()); + SystemConfiguration::instance().set_resource_path(resource_path); } std::shared_ptr ss; diff --git a/src/anbox/config.h b/src/anbox/config.h index 47a518e..0fce571 100644 --- a/src/anbox/config.h +++ b/src/anbox/config.h @@ -31,7 +31,7 @@ class SystemConfiguration { virtual ~SystemConfiguration() = default; void set_data_path(const std::string &path); - void set_resource_path(const boost::filesystem &path); + void set_resource_path(const boost::filesystem::path &path); boost::filesystem::path data_dir() const; std::string rootfs_dir() const; From dbcc5cfba02faa56604d7959e11010cbff5b22d2 Mon Sep 17 00:00:00 2001 From: Simon Fels Date: Sun, 7 May 2017 11:46:59 +0200 Subject: [PATCH 20/20] Fix incorrect logical expression for intent check --- src/anbox/android/intent.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/anbox/android/intent.cpp b/src/anbox/android/intent.cpp index 2fcd8f0..4f5e659 100644 --- a/src/anbox/android/intent.cpp +++ b/src/anbox/android/intent.cpp @@ -35,7 +35,7 @@ std::ostream &operator<<(std::ostream &out, const Intent &intent) { out << " " << "package=" << intent.package << " "; if (!intent.component.empty()) out << "component=" << intent.component << " "; - if (!intent.categories.size() > 0) { + if (intent.categories.size() > 0) { out << "categories=[ "; for (const auto &category : intent.categories) out << category << " "; out << "] ";