/* * Copyright (C) 2016 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/dbus/interface.h" #include "anbox/dbus/stub/application_manager.h" #include "anbox/logger.h" #include namespace anbox { namespace dbus { namespace stub { std::shared_ptr ApplicationManager::create_for_bus(const BusPtr& bus) { return std::shared_ptr(new ApplicationManager(bus)); } ApplicationManager::ApplicationManager(const BusPtr& bus) : bus_(bus) { if (!bus_->has_service_with_name(interface::Service::name())) throw std::runtime_error("Application manager service is not running yet"); update_properties(); } ApplicationManager::~ApplicationManager() {} void ApplicationManager::update_properties() { int ready = 0; const auto r = sd_bus_get_property_trivial(bus_->raw(), interface::Service::name(), interface::Service::path(), interface::ApplicationManager::name(), interface::ApplicationManager::Properties::Ready::name(), nullptr, 'b', &ready); if (r < 0) throw std::runtime_error("Failed to retrieve ready property from application manager"); ready_.set(ready); } void ApplicationManager::launch(const android::Intent &intent, const graphics::Rect &launch_bounds, const wm::Stack::Id &stack) { (void) launch_bounds; sd_bus_message *m = nullptr; auto r = sd_bus_message_new_method_call(bus_->raw(), &m, interface::Service::name(), interface::Service::path(), interface::ApplicationManager::name(), interface::ApplicationManager::Methods::Launch::name()); if (r < 0) throw std::runtime_error("Failed to construct DBus message"); r = sd_bus_message_open_container(m, 'a', "{sv}"); if (r < 0) throw std::runtime_error("Failed to construct DBus message"); if (intent.package.length() > 0) { r = sd_bus_message_append(m, "{sv}", "package", "s", intent.package.c_str()); if (r < 0) throw std::runtime_error("Failed to construct DBus message"); } if (intent.component.length() > 0) { r = sd_bus_message_append(m, "{sv}", "component", "s", intent.component.c_str()); if (r < 0) throw std::runtime_error("Failed to construct DBus message"); } if (intent.action.length() > 0) { r = sd_bus_message_append(m, "{sv}", "action", "s", intent.action.c_str()); if (r < 0) throw std::runtime_error("Failed to construct DBus message"); } if (intent.type.length() > 0) { r = sd_bus_message_append(m, "{sv}", "type", "s", intent.type.c_str()); if (r < 0) throw std::runtime_error("Failed to construct DBus message"); } if (intent.uri.length() > 0) { r = sd_bus_message_append(m, "{sv}", "uri", "s", intent.uri.c_str()); if (r < 0) throw std::runtime_error("Failed to construct DBus message"); } r = sd_bus_message_close_container(m); if (r < 0) throw std::runtime_error("Failed to construct DBus message"); std::ostringstream launch_stack; launch_stack << stack; r = sd_bus_message_append(m, "s", launch_stack.str().c_str()); if (r < 0) throw std::runtime_error("Failed to construct DBus message"); #pragma GCC diagnostic push #pragma GCC diagnostic warning "-Wpragmas" #pragma GCC diagnostic warning "-Wc99-extensions" sd_bus_error error = SD_BUS_ERROR_NULL; #pragma GCC diagnostic pop r = sd_bus_call(bus_->raw(), m, 0, &error, nullptr); if (r < 0) { const auto msg = utils::string_format("%s", error.message); sd_bus_error_free(&error); throw std::runtime_error(msg); } } core::Property& ApplicationManager::ready() { return ready_; } } // namespace skeleton } // namespace dbus } // namespace anbox