X-Git-Url: https://gerrit.akraino.org/r/gitweb?a=blobdiff_plain;f=src%2Ftype3_AndroidCloud%2Fanbox-master%2Fsrc%2Fanbox%2Fdbus%2Fskeleton%2Fapplication_manager.cpp;fp=src%2Ftype3_AndroidCloud%2Fanbox-master%2Fsrc%2Fanbox%2Fdbus%2Fskeleton%2Fapplication_manager.cpp;h=1ed355c684046a1fa038218fad9cf43d5ec61359;hb=e26c1ec581be598521517829adba8c8dd23a768f;hp=0000000000000000000000000000000000000000;hpb=6699c1aea74eeb0eb400e6299079f0c7576f716f;p=iec.git diff --git a/src/type3_AndroidCloud/anbox-master/src/anbox/dbus/skeleton/application_manager.cpp b/src/type3_AndroidCloud/anbox-master/src/anbox/dbus/skeleton/application_manager.cpp new file mode 100644 index 0000000..1ed355c --- /dev/null +++ b/src/type3_AndroidCloud/anbox-master/src/anbox/dbus/skeleton/application_manager.cpp @@ -0,0 +1,189 @@ +/* + * 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/skeleton/application_manager.h" +#include "anbox/dbus/interface.h" +#include "anbox/dbus/sd_bus_helpers.hpp" +#include "anbox/android/intent.h" +#include "anbox/logger.h" + +#include + +#include + +namespace { +int parse_string_from_message(sd_bus_message *m, std::string &str) { + const char *contents = nullptr; + auto r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, contents); + if (r < 0) + return r; + + const char *value; + r = sd_bus_message_read(m, "s", &value); + if (r < 0) + return r; + + str = value; + + r = sd_bus_message_exit_container(m); + if (r < 0) + return r; + + return 0; +} +} // namespace + +namespace anbox { +namespace dbus { +namespace skeleton { +const sd_bus_vtable ApplicationManager::vtable[] = { + sdbus_vtable_create_start(0), + sdbus_vtable_create_method("Launch", "a{sv}s", "", ApplicationManager::method_launch, SD_BUS_VTABLE_UNPRIVILEGED), + sdbus_vtable_create_property("Ready", "b", ApplicationManager::property_ready_get, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), + sdbus_vtable_create_end() +}; + +int ApplicationManager::method_launch(sd_bus_message *m, void *userdata, sd_bus_error *ret_error) { + auto r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "{sv}"); + if (r < 0) + return r; + + android::Intent intent; + + while ((r = sd_bus_message_enter_container(m, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) { + const char *key = nullptr; + + r = sd_bus_message_read(m, "s", &key); + if (r < 0) + return r; + + if (strcmp(key, "package") == 0) { + r = parse_string_from_message(m, intent.package); + if (r < 0) + return r; + } else if (strcmp(key, "component") == 0) { + r = parse_string_from_message(m, intent.component); + if (r < 0) + return r; + } else if (strcmp(key, "action") == 0) { + r = parse_string_from_message(m, intent.action); + if (r < 0) + return r; + } else if (strcmp(key, "type") == 0) { + r = parse_string_from_message(m, intent.type); + if (r < 0) + return r; + } else if (strcmp(key, "uri") == 0) { + r = parse_string_from_message(m, intent.uri); + if (r < 0) + return r; + } + + r = sd_bus_message_exit_container(m); + if (r < 0) + return r; + } + + r = sd_bus_message_exit_container(m); + if (r < 0) + return r; + + const char *stack = nullptr; + r = sd_bus_message_read(m, "s", &stack); + if (r < 0) + return r; + + wm::Stack::Id launch_stack = wm::Stack::Id::Default; + if (stack && strlen(stack) > 0) { + auto s = std::string(stack); + std::istringstream i(s); + i >> launch_stack; + } + + if (intent.package.length() == 0) { + sd_bus_error_set_const(ret_error, "org.anbox.InvalidArgument", "No package specified"); + return -EINVAL; + } + + auto thiz = static_cast(userdata); + try { + thiz->launch(intent, graphics::Rect::Invalid, launch_stack); + } catch (std::exception &err) { + ERROR("Failed to launch application: %s", err.what()); + sd_bus_error_set_const(ret_error, "org.anbox.InternalError", err.what()); + return -EIO; + } + + return sd_bus_reply_method_return(m, ""); +} + +int ApplicationManager::property_ready_get(sd_bus *bus, const char *path, const char *interface, + const char *property, sd_bus_message *reply, + void *userdata, sd_bus_error *ret_error) { + + (void) bus; + (void) path; + (void) interface; + (void) property; + (void) ret_error; + + auto thiz = static_cast(userdata); + + return sd_bus_message_append(reply, "b", thiz->impl_->ready().get()); +} + +ApplicationManager::ApplicationManager(const BusPtr& bus, const std::shared_ptr &impl) + : bus_(bus), impl_(impl) { + + const auto r = sd_bus_add_object_vtable(bus_->raw(), + &obj_slot_, + interface::Service::path(), + interface::ApplicationManager::name(), + vtable, + this); + if (r < 0) + std::runtime_error("Failed to setup application manager DBus service"); + + impl_->ready().changed().connect([&](bool value) { + (void) value; + + sd_bus_emit_properties_changed(bus_->raw(), + interface::Service::path(), + interface::ApplicationManager::name(), + interface::ApplicationManager::Properties::Ready::name(), + nullptr); + }); +} + +ApplicationManager::~ApplicationManager() {} + +void ApplicationManager::launch(const android::Intent &intent, + const graphics::Rect &launch_bounds, + const wm::Stack::Id &stack) { + if (!impl_->ready()) + throw std::runtime_error("Anbox not yet ready to launch applications"); + + DEBUG("Launching %s", intent); + impl_->launch(intent, launch_bounds, stack); +} + +core::Property& ApplicationManager::ready() { + return impl_->ready(); +} +} // namespace skeleton +} // namespace dbus +} // namespace anbox