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 <string>
|
||||||
|
|
||||||
|
#include <core/property.h>
|
||||||
|
|
||||||
namespace anbox {
|
namespace anbox {
|
||||||
class ApplicationManager : public DoNotCopyOrMove {
|
class ApplicationManager : public DoNotCopyOrMove {
|
||||||
public:
|
public:
|
||||||
virtual void launch(const android::Intent &intent, const graphics::Rect &launch_bounds = graphics::Rect::Invalid) = 0;
|
virtual void launch(const android::Intent &intent, const graphics::Rect &launch_bounds = graphics::Rect::Invalid) = 0;
|
||||||
|
virtual core::Property<bool>& ready() = 0;
|
||||||
};
|
};
|
||||||
} // namespace anbox
|
} // 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());
|
if (c->response->has_error()) throw std::runtime_error(c->response->error());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
core::Property<bool>& AndroidApiStub::ready() {
|
||||||
|
return ready_;
|
||||||
|
}
|
||||||
|
|
||||||
void AndroidApiStub::application_launched(
|
void AndroidApiStub::application_launched(
|
||||||
Request<protobuf::rpc::Void> *request) {
|
Request<protobuf::rpc::Void> *request) {
|
||||||
(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 set_rpc_channel(const std::shared_ptr<rpc::Channel> &channel);
|
||||||
void reset_rpc_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 set_focused_task(const std::int32_t &id);
|
||||||
void remove_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,
|
void resize_task(const std::int32_t &id, const anbox::graphics::Rect &rect,
|
||||||
const std::int32_t &resize_mode);
|
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:
|
private:
|
||||||
void ensure_rpc_channel();
|
void ensure_rpc_channel();
|
||||||
|
|
||||||
|
|
@ -72,6 +73,7 @@ class AndroidApiStub : public anbox::ApplicationManager {
|
||||||
common::WaitHandle remove_task_handle_;
|
common::WaitHandle remove_task_handle_;
|
||||||
common::WaitHandle resize_task_handle_;
|
common::WaitHandle resize_task_handle_;
|
||||||
graphics::Rect launch_bounds_ = graphics::Rect::Invalid;
|
graphics::Rect launch_bounds_ = graphics::Rect::Invalid;
|
||||||
|
core::Property<bool> ready_;
|
||||||
};
|
};
|
||||||
} // namespace bridge
|
} // namespace bridge
|
||||||
} // namespace anbox
|
} // namespace anbox
|
||||||
|
|
|
||||||
|
|
@ -16,14 +16,24 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "anbox/cmds/launch.h"
|
#include "anbox/cmds/launch.h"
|
||||||
|
#include "anbox/common/wait_handle.h"
|
||||||
#include "anbox/dbus/stub/application_manager.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 <core/dbus/asio/executor.h>
|
||||||
|
|
||||||
#include <boost/filesystem.hpp>
|
#include <boost/filesystem.hpp>
|
||||||
|
|
||||||
|
#include "core/posix/signal.h"
|
||||||
|
|
||||||
namespace fs = boost::filesystem;
|
namespace fs = boost::filesystem;
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
const boost::posix_time::seconds max_wait_timeout{30};
|
||||||
|
}
|
||||||
|
|
||||||
anbox::cmds::Launch::Launch()
|
anbox::cmds::Launch::Launch()
|
||||||
: CommandWithFlagsAndAction{
|
: CommandWithFlagsAndAction{
|
||||||
cli::Name{"launch"}, cli::Usage{"launch"},
|
cli::Name{"launch"}, cli::Usage{"launch"},
|
||||||
|
|
@ -46,13 +56,69 @@ anbox::cmds::Launch::Launch()
|
||||||
intent_.component));
|
intent_.component));
|
||||||
|
|
||||||
action([this](const cli::Command::Context&) {
|
action([this](const cli::Command::Context&) {
|
||||||
auto bus =
|
auto trap = core::posix::trap_signals_for_process({core::posix::Signal::sig_term, core::posix::Signal::sig_int});
|
||||||
std::make_shared<core::dbus::Bus>(core::dbus::WellKnownBus::session);
|
trap->signal_raised().connect([trap](const core::posix::Signal& signal) {
|
||||||
bus->install_executor(core::dbus::asio::make_executor(bus));
|
INFO("Signal %i received. Good night.", static_cast<int>(signal));
|
||||||
auto stub = dbus::stub::ApplicationManager::create_for_bus(bus);
|
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>(
|
auto server = std::make_shared<bridge::PlatformApiSkeleton>(
|
||||||
pending_calls, policy, window_manager, launcher_storage);
|
pending_calls, policy, window_manager, launcher_storage);
|
||||||
server->register_boot_finished_handler(
|
server->register_boot_finished_handler([&]() {
|
||||||
[&]() { DEBUG("Android successfully booted"); });
|
DEBUG("Android successfully booted");
|
||||||
|
android_api_stub->ready().set(true);
|
||||||
|
});
|
||||||
return std::make_shared<bridge::PlatformMessageProcessor>(
|
return std::make_shared<bridge::PlatformMessageProcessor>(
|
||||||
sender, server, pending_calls);
|
sender, server, pending_calls);
|
||||||
}));
|
}));
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@
|
||||||
#define ANBOX_DBUS_INTERFACE_H_
|
#define ANBOX_DBUS_INTERFACE_H_
|
||||||
|
|
||||||
#include <core/dbus/macros.h>
|
#include <core/dbus/macros.h>
|
||||||
|
#include <core/dbus/property.h>
|
||||||
|
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
@ -42,6 +43,9 @@ struct ApplicationManager {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
struct Properties {
|
||||||
|
DBUS_CPP_READABLE_PROPERTY_DEF(Ready, ApplicationManager, bool)
|
||||||
|
};
|
||||||
};
|
};
|
||||||
} // namespace interface
|
} // namespace interface
|
||||||
} // namespace dbus
|
} // namespace dbus
|
||||||
|
|
|
||||||
|
|
@ -20,15 +20,19 @@
|
||||||
#include "anbox/dbus/interface.h"
|
#include "anbox/dbus/interface.h"
|
||||||
#include "anbox/logger.h"
|
#include "anbox/logger.h"
|
||||||
|
|
||||||
|
#include <core/property.h>
|
||||||
|
|
||||||
namespace anbox {
|
namespace anbox {
|
||||||
namespace dbus {
|
namespace dbus {
|
||||||
namespace skeleton {
|
namespace skeleton {
|
||||||
ApplicationManager::ApplicationManager(
|
ApplicationManager::ApplicationManager(
|
||||||
const core::dbus::Bus::Ptr &bus, const core::dbus::Object::Ptr &object,
|
const core::dbus::Bus::Ptr &bus, const core::dbus::Object::Ptr &object,
|
||||||
const std::shared_ptr<anbox::ApplicationManager> &impl)
|
const std::shared_ptr<anbox::ApplicationManager> &impl)
|
||||||
: bus_(bus), object_(object), impl_(impl) {
|
: bus_(bus), object_(object), impl_(impl),
|
||||||
object_->install_method_handler<
|
properties_{ object_->get_property<anbox::dbus::interface::ApplicationManager::Properties::Ready>() },
|
||||||
anbox::dbus::interface::ApplicationManager::Methods::Launch>(
|
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) {
|
[this](const core::dbus::Message::Ptr &msg) {
|
||||||
auto reader = msg->reader();
|
auto reader = msg->reader();
|
||||||
|
|
||||||
|
|
@ -59,13 +63,38 @@ ApplicationManager::ApplicationManager(
|
||||||
|
|
||||||
bus_->send(reply);
|
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() {}
|
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) {
|
void ApplicationManager::launch(const android::Intent &intent, const graphics::Rect &launch_bounds) {
|
||||||
impl_->launch(intent, launch_bounds);
|
impl_->launch(intent, launch_bounds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
core::Property<bool>& ApplicationManager::ready() {
|
||||||
|
return impl_->ready();
|
||||||
|
}
|
||||||
} // namespace skeleton
|
} // namespace skeleton
|
||||||
} // namespace dbus
|
} // namespace dbus
|
||||||
} // namespace anbox
|
} // namespace anbox
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,9 @@
|
||||||
#include <core/dbus/bus.h>
|
#include <core/dbus/bus.h>
|
||||||
#include <core/dbus/object.h>
|
#include <core/dbus/object.h>
|
||||||
#include <core/dbus/service.h>
|
#include <core/dbus/service.h>
|
||||||
|
#include <core/dbus/property.h>
|
||||||
|
|
||||||
|
#include "anbox/dbus/interface.h"
|
||||||
|
|
||||||
namespace anbox {
|
namespace anbox {
|
||||||
namespace dbus {
|
namespace dbus {
|
||||||
|
|
@ -35,12 +38,23 @@ class ApplicationManager : public anbox::ApplicationManager {
|
||||||
~ApplicationManager();
|
~ApplicationManager();
|
||||||
|
|
||||||
void launch(const android::Intent &intent, const graphics::Rect &launch_bounds = graphics::Rect::Invalid) override;
|
void launch(const android::Intent &intent, const graphics::Rect &launch_bounds = graphics::Rect::Invalid) override;
|
||||||
|
core::Property<bool>& ready() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
template<typename Property>
|
||||||
|
void on_property_value_changed(const typename Property::ValueType& value);
|
||||||
|
|
||||||
core::dbus::Bus::Ptr bus_;
|
core::dbus::Bus::Ptr bus_;
|
||||||
core::dbus::Service::Ptr service_;
|
core::dbus::Service::Ptr service_;
|
||||||
core::dbus::Object::Ptr object_;
|
core::dbus::Object::Ptr object_;
|
||||||
std::shared_ptr<anbox::ApplicationManager> impl_;
|
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 skeleton
|
||||||
} // namespace dbus
|
} // namespace dbus
|
||||||
|
|
|
||||||
|
|
@ -39,8 +39,7 @@ Service::Service(
|
||||||
: bus_(bus),
|
: bus_(bus),
|
||||||
service_(service),
|
service_(service),
|
||||||
object_(object),
|
object_(object),
|
||||||
application_manager_(std::make_shared<ApplicationManager>(
|
application_manager_(std::make_shared<ApplicationManager>(bus_, object_, application_manager)) {}
|
||||||
bus_, object_, application_manager)) {}
|
|
||||||
|
|
||||||
Service::~Service() {}
|
Service::~Service() {}
|
||||||
} // namespace skeleton
|
} // namespace skeleton
|
||||||
|
|
|
||||||
|
|
@ -22,19 +22,22 @@
|
||||||
namespace anbox {
|
namespace anbox {
|
||||||
namespace dbus {
|
namespace dbus {
|
||||||
namespace stub {
|
namespace stub {
|
||||||
std::shared_ptr<ApplicationManager> ApplicationManager::create_for_bus(
|
std::shared_ptr<ApplicationManager> ApplicationManager::create_for_bus(const core::dbus::Bus::Ptr &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 service = core::dbus::Service::use_service(
|
auto object = service->add_object_for_path(anbox::dbus::interface::Service::path());
|
||||||
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);
|
return std::make_shared<ApplicationManager>(bus, service, object);
|
||||||
}
|
}
|
||||||
|
|
||||||
ApplicationManager::ApplicationManager(const core::dbus::Bus::Ptr &bus,
|
ApplicationManager::ApplicationManager(const core::dbus::Bus::Ptr &bus,
|
||||||
const core::dbus::Service::Ptr &service,
|
const core::dbus::Service::Ptr &service,
|
||||||
const core::dbus::Object::Ptr &object)
|
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() {}
|
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());
|
if (result.is_error()) throw std::runtime_error(result.error().print());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
core::Property<bool>& ApplicationManager::ready() {
|
||||||
|
return ready_;
|
||||||
|
}
|
||||||
} // namespace skeleton
|
} // namespace skeleton
|
||||||
} // namespace dbus
|
} // namespace dbus
|
||||||
} // namespace anbox
|
} // namespace anbox
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,8 @@
|
||||||
#include <core/dbus/object.h>
|
#include <core/dbus/object.h>
|
||||||
#include <core/dbus/service.h>
|
#include <core/dbus/service.h>
|
||||||
|
|
||||||
|
#include "anbox/dbus/interface.h"
|
||||||
|
|
||||||
namespace anbox {
|
namespace anbox {
|
||||||
namespace dbus {
|
namespace dbus {
|
||||||
namespace stub {
|
namespace stub {
|
||||||
|
|
@ -38,11 +40,16 @@ class ApplicationManager : public anbox::ApplicationManager {
|
||||||
~ApplicationManager();
|
~ApplicationManager();
|
||||||
|
|
||||||
void launch(const android::Intent &intent, const graphics::Rect &launch_bounds = graphics::Rect::Invalid) override;
|
void launch(const android::Intent &intent, const graphics::Rect &launch_bounds = graphics::Rect::Invalid) override;
|
||||||
|
core::Property<bool>& ready() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
core::dbus::Bus::Ptr bus_;
|
core::dbus::Bus::Ptr bus_;
|
||||||
core::dbus::Service::Ptr service_;
|
core::dbus::Service::Ptr service_;
|
||||||
core::dbus::Object::Ptr object_;
|
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 stub
|
||||||
} // namespace dbus
|
} // namespace dbus
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue