提交 03acb32e 编写于 作者: S Simon Fels

Forward Android ready status through our app manager dbus object

上级 79b0f5b6
......@@ -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();
});
auto rt = Runtime::create();
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();
});
stub->launch(intent_);
rt->start();
trap->run();
rt->stop();
return EXIT_SUCCESS;
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
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册