Forward Android ready status through our app manager dbus object
This commit is contained in:
parent
79b0f5b63e
commit
03acb32ece
11 changed files with 159 additions and 22 deletions
|
|
@ -24,10 +24,13 @@
|
|||
|
||||
#include <string>
|
||||
|
||||
#include <core/property.h>
|
||||
|
||||
namespace anbox {
|
||||
class ApplicationManager : public DoNotCopyOrMove {
|
||||
public:
|
||||
virtual void launch(const android::Intent &intent, const graphics::Rect &launch_bounds = graphics::Rect::Invalid) = 0;
|
||||
virtual core::Property<bool>& ready() = 0;
|
||||
};
|
||||
} // namespace anbox
|
||||
|
||||
|
|
|
|||
|
|
@ -92,6 +92,10 @@ void AndroidApiStub::launch(const android::Intent &intent,
|
|||
if (c->response->has_error()) throw std::runtime_error(c->response->error());
|
||||
}
|
||||
|
||||
core::Property<bool>& AndroidApiStub::ready() {
|
||||
return ready_;
|
||||
}
|
||||
|
||||
void AndroidApiStub::application_launched(
|
||||
Request<protobuf::rpc::Void> *request) {
|
||||
(void)request;
|
||||
|
|
|
|||
|
|
@ -43,13 +43,14 @@ class AndroidApiStub : public anbox::ApplicationManager {
|
|||
void set_rpc_channel(const std::shared_ptr<rpc::Channel> &channel);
|
||||
void reset_rpc_channel();
|
||||
|
||||
void launch(const android::Intent &intent, const graphics::Rect &launch_bounds = graphics::Rect::Invalid) override;
|
||||
|
||||
void set_focused_task(const std::int32_t &id);
|
||||
void remove_task(const std::int32_t &id);
|
||||
void resize_task(const std::int32_t &id, const anbox::graphics::Rect &rect,
|
||||
const std::int32_t &resize_mode);
|
||||
|
||||
void launch(const android::Intent &intent, const graphics::Rect &launch_bounds = graphics::Rect::Invalid) override;
|
||||
core::Property<bool>& ready() override;
|
||||
|
||||
private:
|
||||
void ensure_rpc_channel();
|
||||
|
||||
|
|
@ -72,6 +73,7 @@ class AndroidApiStub : public anbox::ApplicationManager {
|
|||
common::WaitHandle remove_task_handle_;
|
||||
common::WaitHandle resize_task_handle_;
|
||||
graphics::Rect launch_bounds_ = graphics::Rect::Invalid;
|
||||
core::Property<bool> ready_;
|
||||
};
|
||||
} // namespace bridge
|
||||
} // namespace anbox
|
||||
|
|
|
|||
|
|
@ -16,14 +16,24 @@
|
|||
*/
|
||||
|
||||
#include "anbox/cmds/launch.h"
|
||||
#include "anbox/common/wait_handle.h"
|
||||
#include "anbox/dbus/stub/application_manager.h"
|
||||
#include "anbox/common/dispatcher.h"
|
||||
#include "anbox/runtime.h"
|
||||
#include "anbox/logger.h"
|
||||
|
||||
#include <core/dbus/asio/executor.h>
|
||||
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
#include "core/posix/signal.h"
|
||||
|
||||
namespace fs = boost::filesystem;
|
||||
|
||||
namespace {
|
||||
const boost::posix_time::seconds max_wait_timeout{30};
|
||||
}
|
||||
|
||||
anbox::cmds::Launch::Launch()
|
||||
: CommandWithFlagsAndAction{
|
||||
cli::Name{"launch"}, cli::Usage{"launch"},
|
||||
|
|
@ -46,13 +56,69 @@ anbox::cmds::Launch::Launch()
|
|||
intent_.component));
|
||||
|
||||
action([this](const cli::Command::Context&) {
|
||||
auto bus =
|
||||
std::make_shared<core::dbus::Bus>(core::dbus::WellKnownBus::session);
|
||||
bus->install_executor(core::dbus::asio::make_executor(bus));
|
||||
auto stub = dbus::stub::ApplicationManager::create_for_bus(bus);
|
||||
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<int>(signal));
|
||||
trap->stop();
|
||||
});
|
||||
|
||||
stub->launch(intent_);
|
||||
auto rt = Runtime::create();
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
auto bus = std::make_shared<core::dbus::Bus>(core::dbus::WellKnownBus::session);
|
||||
bus->install_executor(core::dbus::asio::make_executor(bus, rt->service()));
|
||||
|
||||
std::shared_ptr<dbus::stub::ApplicationManager> stub;
|
||||
try {
|
||||
stub = dbus::stub::ApplicationManager::create_for_bus(bus);
|
||||
} catch (...) {
|
||||
ERROR("Anbox session manager service isn't running!");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
auto dispatcher = anbox::common::create_dispatcher_for_runtime(rt);
|
||||
|
||||
bool success = false;
|
||||
|
||||
dispatcher->dispatch([&]() {
|
||||
if (stub->ready()) {
|
||||
try {
|
||||
stub->launch(intent_);
|
||||
success = true;
|
||||
} catch (std::exception &err) {
|
||||
ERROR("err %s", err.what());
|
||||
}
|
||||
trap->stop();
|
||||
return;
|
||||
}
|
||||
|
||||
DEBUG("Android hasn't fully booted yet. Waiting a bit..");
|
||||
|
||||
stub->ready().changed().connect([&](bool ready) {
|
||||
if (!ready)
|
||||
return;
|
||||
try {
|
||||
stub->launch(intent_);
|
||||
success = true;
|
||||
} catch (std::exception &err) {
|
||||
ERROR("Failed to launch activity: %s", err.what());
|
||||
success = false;
|
||||
}
|
||||
trap->stop();
|
||||
});
|
||||
});
|
||||
|
||||
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.");
|
||||
trap->stop();
|
||||
});
|
||||
|
||||
rt->start();
|
||||
trap->run();
|
||||
rt->stop();
|
||||
|
||||
return success ? EXIT_SUCCESS : EXIT_FAILURE;
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -176,8 +176,10 @@ anbox::cmds::SessionManager::SessionManager(const BusFactory &bus_factory)
|
|||
|
||||
auto server = std::make_shared<bridge::PlatformApiSkeleton>(
|
||||
pending_calls, policy, window_manager, launcher_storage);
|
||||
server->register_boot_finished_handler(
|
||||
[&]() { DEBUG("Android successfully booted"); });
|
||||
server->register_boot_finished_handler([&]() {
|
||||
DEBUG("Android successfully booted");
|
||||
android_api_stub->ready().set(true);
|
||||
});
|
||||
return std::make_shared<bridge::PlatformMessageProcessor>(
|
||||
sender, server, pending_calls);
|
||||
}));
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
#define ANBOX_DBUS_INTERFACE_H_
|
||||
|
||||
#include <core/dbus/macros.h>
|
||||
#include <core/dbus/property.h>
|
||||
|
||||
#include <chrono>
|
||||
#include <string>
|
||||
|
|
@ -42,6 +43,9 @@ struct ApplicationManager {
|
|||
}
|
||||
};
|
||||
};
|
||||
struct Properties {
|
||||
DBUS_CPP_READABLE_PROPERTY_DEF(Ready, ApplicationManager, bool)
|
||||
};
|
||||
};
|
||||
} // namespace interface
|
||||
} // namespace dbus
|
||||
|
|
|
|||
|
|
@ -20,15 +20,19 @@
|
|||
#include "anbox/dbus/interface.h"
|
||||
#include "anbox/logger.h"
|
||||
|
||||
#include <core/property.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<anbox::ApplicationManager> &impl)
|
||||
: bus_(bus), object_(object), impl_(impl) {
|
||||
object_->install_method_handler<
|
||||
anbox::dbus::interface::ApplicationManager::Methods::Launch>(
|
||||
: bus_(bus), object_(object), impl_(impl),
|
||||
properties_{ object_->get_property<anbox::dbus::interface::ApplicationManager::Properties::Ready>() },
|
||||
signals_{ object_->get_signal<core::dbus::interfaces::Properties::Signals::PropertiesChanged>() } {
|
||||
|
||||
object_->install_method_handler<anbox::dbus::interface::ApplicationManager::Methods::Launch>(
|
||||
[this](const core::dbus::Message::Ptr &msg) {
|
||||
auto reader = msg->reader();
|
||||
|
||||
|
|
@ -59,13 +63,38 @@ ApplicationManager::ApplicationManager(
|
|||
|
||||
bus_->send(reply);
|
||||
});
|
||||
|
||||
// Forward AndroidApi status to our dbus property
|
||||
properties_.ready->install([&]() { return impl_->ready().get(); });
|
||||
impl_->ready().changed().connect([&](bool value) {
|
||||
properties_.ready->set(value);
|
||||
on_property_value_changed<anbox::dbus::interface::ApplicationManager::Properties::Ready>(value);
|
||||
});
|
||||
}
|
||||
|
||||
ApplicationManager::~ApplicationManager() {}
|
||||
|
||||
template<typename Property>
|
||||
void ApplicationManager::on_property_value_changed(const typename Property::ValueType& value)
|
||||
{
|
||||
typedef std::map<std::string, core::dbus::types::Variant> Dictionary;
|
||||
|
||||
static const std::vector<std::string> the_empty_list_of_invalidated_properties;
|
||||
|
||||
Dictionary dict; dict[Property::name()] = core::dbus::types::Variant::encode(value);
|
||||
|
||||
signals_.properties_changed->emit(
|
||||
std::make_tuple(core::dbus::traits::Service<anbox::dbus::interface::ApplicationManager>::interface_name(),
|
||||
dict, the_empty_list_of_invalidated_properties));
|
||||
}
|
||||
|
||||
void ApplicationManager::launch(const android::Intent &intent, const graphics::Rect &launch_bounds) {
|
||||
impl_->launch(intent, launch_bounds);
|
||||
}
|
||||
|
||||
core::Property<bool>& ApplicationManager::ready() {
|
||||
return impl_->ready();
|
||||
}
|
||||
} // namespace skeleton
|
||||
} // namespace dbus
|
||||
} // namespace anbox
|
||||
|
|
|
|||
|
|
@ -23,6 +23,9 @@
|
|||
#include <core/dbus/bus.h>
|
||||
#include <core/dbus/object.h>
|
||||
#include <core/dbus/service.h>
|
||||
#include <core/dbus/property.h>
|
||||
|
||||
#include "anbox/dbus/interface.h"
|
||||
|
||||
namespace anbox {
|
||||
namespace dbus {
|
||||
|
|
@ -35,12 +38,23 @@ class ApplicationManager : public anbox::ApplicationManager {
|
|||
~ApplicationManager();
|
||||
|
||||
void launch(const android::Intent &intent, const graphics::Rect &launch_bounds = graphics::Rect::Invalid) override;
|
||||
core::Property<bool>& ready() override;
|
||||
|
||||
private:
|
||||
template<typename Property>
|
||||
void on_property_value_changed(const typename Property::ValueType& value);
|
||||
|
||||
core::dbus::Bus::Ptr bus_;
|
||||
core::dbus::Service::Ptr service_;
|
||||
core::dbus::Object::Ptr object_;
|
||||
std::shared_ptr<anbox::ApplicationManager> impl_;
|
||||
struct {
|
||||
std::shared_ptr<core::dbus::Property<anbox::dbus::interface::ApplicationManager::Properties::Ready>> ready;
|
||||
} properties_;
|
||||
struct {
|
||||
core::dbus::Signal<core::dbus::interfaces::Properties::Signals::PropertiesChanged,
|
||||
core::dbus::interfaces::Properties::Signals::PropertiesChanged::ArgumentType>::Ptr properties_changed;
|
||||
} signals_;
|
||||
};
|
||||
} // namespace skeleton
|
||||
} // namespace dbus
|
||||
|
|
|
|||
|
|
@ -39,8 +39,7 @@ Service::Service(
|
|||
: bus_(bus),
|
||||
service_(service),
|
||||
object_(object),
|
||||
application_manager_(std::make_shared<ApplicationManager>(
|
||||
bus_, object_, application_manager)) {}
|
||||
application_manager_(std::make_shared<ApplicationManager>(bus_, object_, application_manager)) {}
|
||||
|
||||
Service::~Service() {}
|
||||
} // namespace skeleton
|
||||
|
|
|
|||
|
|
@ -22,19 +22,22 @@
|
|||
namespace anbox {
|
||||
namespace dbus {
|
||||
namespace stub {
|
||||
std::shared_ptr<ApplicationManager> 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());
|
||||
std::shared_ptr<ApplicationManager> 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());
|
||||
return std::make_shared<ApplicationManager>(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) {}
|
||||
: bus_(bus), service_(service), object_(object),
|
||||
properties_{ object_->get_property<anbox::dbus::interface::ApplicationManager::Properties::Ready>() } {
|
||||
|
||||
// Forward changes on the dbus property to our users
|
||||
ready_.install([&]() { return properties_.ready->get(); });
|
||||
properties_.ready->changed().connect([&](bool value) { ready_.set(value); });
|
||||
}
|
||||
|
||||
ApplicationManager::~ApplicationManager() {}
|
||||
|
||||
|
|
@ -48,6 +51,10 @@ void ApplicationManager::launch(const android::Intent &intent, const graphics::R
|
|||
|
||||
if (result.is_error()) throw std::runtime_error(result.error().print());
|
||||
}
|
||||
|
||||
core::Property<bool>& ApplicationManager::ready() {
|
||||
return ready_;
|
||||
}
|
||||
} // namespace skeleton
|
||||
} // namespace dbus
|
||||
} // namespace anbox
|
||||
|
|
|
|||
|
|
@ -24,6 +24,8 @@
|
|||
#include <core/dbus/object.h>
|
||||
#include <core/dbus/service.h>
|
||||
|
||||
#include "anbox/dbus/interface.h"
|
||||
|
||||
namespace anbox {
|
||||
namespace dbus {
|
||||
namespace stub {
|
||||
|
|
@ -38,11 +40,16 @@ class ApplicationManager : public anbox::ApplicationManager {
|
|||
~ApplicationManager();
|
||||
|
||||
void launch(const android::Intent &intent, const graphics::Rect &launch_bounds = graphics::Rect::Invalid) override;
|
||||
core::Property<bool>& ready() override;
|
||||
|
||||
private:
|
||||
core::dbus::Bus::Ptr bus_;
|
||||
core::dbus::Service::Ptr service_;
|
||||
core::dbus::Object::Ptr object_;
|
||||
core::Property<bool> ready_;
|
||||
struct {
|
||||
std::shared_ptr<core::dbus::Property<anbox::dbus::interface::ApplicationManager::Properties::Ready>> ready;
|
||||
} properties_;
|
||||
};
|
||||
} // namespace stub
|
||||
} // namespace dbus
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue