Improve launch and splash screen interactions

This commit is contained in:
Simon Fels 2017-05-03 07:57:54 +02:00
commit f4df33efe4
2 changed files with 32 additions and 26 deletions

View file

@ -34,9 +34,20 @@
namespace fs = boost::filesystem; namespace fs = boost::filesystem;
namespace { namespace {
const boost::posix_time::seconds max_wait_timeout{30}; const boost::posix_time::seconds max_wait_timeout{240};
const unsigned int max_restart_attempts{3}; const int max_restart_attempts{3};
const std::chrono::seconds restart_interval{1}; const std::chrono::seconds restart_interval{5};
}
bool anbox::cmds::Launch::try_launch_activity(const std::shared_ptr<dbus::stub::ApplicationManager> &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() anbox::cmds::Launch::Launch()
@ -77,13 +88,14 @@ anbox::cmds::Launch::Launch()
std::shared_ptr<ui::SplashScreen> ss; std::shared_ptr<ui::SplashScreen> ss;
// Instead of relying on the user session init system to start our // 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 // if not already running. This will help to mitigate problems with
// a crashing or a not yet started session manager instance. // a crashing or a not yet started session manager instance.
std::shared_ptr<dbus::stub::ApplicationManager> stub; std::shared_ptr<dbus::stub::ApplicationManager> stub;
for (auto n = 0; n < max_restart_attempts; n++) { for (auto n = 0; n < max_restart_attempts; n++) {
try { try {
stub = dbus::stub::ApplicationManager::create_for_bus(bus); stub = dbus::stub::ApplicationManager::create_for_bus(bus);
break;
} catch (std::exception &err) { } catch (std::exception &err) {
WARNING("Anbox session manager service isn't running, trying to start it."); 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()); 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 { 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 child = core::posix::fork([&]() {
auto grandchild = core::posix::exec(exe_path, args, env, flags); auto grandchild = core::posix::exec(exe_path, args, env, flags);
grandchild.dont_kill_on_cleanup(); grandchild.dont_kill_on_cleanup();
@ -116,9 +132,9 @@ anbox::cmds::Launch::Launch()
catch (...) { catch (...) {
ERROR("Failed to start session manager instance"); ERROR("Failed to start session manager instance");
} }
}
std::this_thread::sleep_for(restart_interval); std::this_thread::sleep_for(restart_interval);
}
} }
if (!stub) { if (!stub) {
@ -126,36 +142,23 @@ anbox::cmds::Launch::Launch()
return EXIT_FAILURE; return EXIT_FAILURE;
} }
auto dispatcher = anbox::common::create_dispatcher_for_runtime(rt);
bool success = false; bool success = false;
auto dispatcher = anbox::common::create_dispatcher_for_runtime(rt);
dispatcher->dispatch([&]() { dispatcher->dispatch([&]() {
if (stub->ready()) { if (stub->ready()) {
try {
stub->launch(intent_, graphics::Rect::Invalid, stack_);
success = true;
} catch (std::exception &err) {
ERROR("err %s", err.what());
}
ss.reset(); ss.reset();
success = try_launch_activity(stub);
trap->stop(); trap->stop();
return; 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) { stub->ready().changed().connect([&](bool ready) {
if (!ready) if (!ready)
return; 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(); ss.reset();
success = try_launch_activity(stub);
trap->stop(); trap->stop();
}); });
}); });
@ -163,8 +166,8 @@ anbox::cmds::Launch::Launch()
boost::asio::deadline_timer timer(rt->service()); boost::asio::deadline_timer timer(rt->service());
timer.expires_from_now(max_wait_timeout); timer.expires_from_now(max_wait_timeout);
timer.async_wait([&](const boost::system::error_code&) { timer.async_wait([&](const boost::system::error_code&) {
WARNING("Stop waiting as we're already waiting for too long. Something is wrong"); WARNING("Stopped waiting as we're already waited for too long. Something");
WARNING("with your setup and the container may have failed to boot."); WARNING("is wrong with your setup or the container has failed to boot.");
trap->stop(); trap->stop();
}); });

View file

@ -23,6 +23,7 @@
#include <memory> #include <memory>
#include "anbox/android/intent.h" #include "anbox/android/intent.h"
#include "anbox/dbus/stub/application_manager.h"
#include "anbox/wm/stack.h" #include "anbox/wm/stack.h"
#include "anbox/cli.h" #include "anbox/cli.h"
@ -33,6 +34,8 @@ class Launch : public cli::CommandWithFlagsAndAction {
Launch(); Launch();
private: private:
bool try_launch_activity(const std::shared_ptr<dbus::stub::ApplicationManager> &stub);
android::Intent intent_; android::Intent intent_;
wm::Stack::Id stack_; wm::Stack::Id stack_;
}; };