TYPE3
[iec.git] / src / type3_AndroidCloud / anbox-master / src / anbox / dbus / stub / application_manager.cpp
1 /*
2  * Copyright (C) 2016 Simon Fels <morphis@gravedo.de>
3  *
4  * This program is free software: you can redistribute it and/or modify it
5  * under the terms of the GNU General Public License version 3, as published
6  * by the Free Software Foundation.
7  *
8  * This program is distributed in the hope that it will be useful, but
9  * WITHOUT ANY WARRANTY; without even the implied warranties of
10  * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
11  * PURPOSE.  See the GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License along
14  * with this program.  If not, see <http://www.gnu.org/licenses/>.
15  *
16  */
17
18 #include "anbox/dbus/interface.h"
19 #include "anbox/dbus/stub/application_manager.h"
20 #include "anbox/logger.h"
21
22 #include <sstream>
23
24 namespace anbox {
25 namespace dbus {
26 namespace stub {
27 std::shared_ptr<ApplicationManager> ApplicationManager::create_for_bus(const BusPtr& bus) {
28   return std::shared_ptr<ApplicationManager>(new ApplicationManager(bus));
29 }
30
31 ApplicationManager::ApplicationManager(const BusPtr& bus)
32     : bus_(bus) {
33
34   if (!bus_->has_service_with_name(interface::Service::name()))
35     throw std::runtime_error("Application manager service is not running yet");
36
37   update_properties();
38 }
39
40 ApplicationManager::~ApplicationManager() {}
41
42 void ApplicationManager::update_properties() {
43   int ready = 0;
44   const auto r = sd_bus_get_property_trivial(bus_->raw(),
45                                              interface::Service::name(),
46                                              interface::Service::path(),
47                                              interface::ApplicationManager::name(),
48                                              interface::ApplicationManager::Properties::Ready::name(),
49                                              nullptr,
50                                              'b',
51                                              &ready);
52   if (r < 0)
53     throw std::runtime_error("Failed to retrieve ready property from application manager");
54
55   ready_.set(ready);
56 }
57
58 void ApplicationManager::launch(const android::Intent &intent,
59                                 const graphics::Rect &launch_bounds,
60                                 const wm::Stack::Id &stack) {
61   (void) launch_bounds;
62
63   sd_bus_message *m = nullptr;
64   auto r = sd_bus_message_new_method_call(bus_->raw(),
65                                           &m,
66                                           interface::Service::name(),
67                                           interface::Service::path(),
68                                           interface::ApplicationManager::name(),
69                                           interface::ApplicationManager::Methods::Launch::name());
70   if (r < 0)
71     throw std::runtime_error("Failed to construct DBus message");
72
73   r = sd_bus_message_open_container(m, 'a', "{sv}");
74   if (r < 0)
75     throw std::runtime_error("Failed to construct DBus message");
76
77   if (intent.package.length() > 0) {
78     r = sd_bus_message_append(m, "{sv}", "package", "s", intent.package.c_str());
79     if (r < 0)
80       throw std::runtime_error("Failed to construct DBus message");
81   }
82
83   if (intent.component.length() > 0) {
84     r = sd_bus_message_append(m, "{sv}", "component", "s", intent.component.c_str());
85     if (r < 0)
86       throw std::runtime_error("Failed to construct DBus message");
87   }
88
89   if (intent.action.length() > 0) {
90     r = sd_bus_message_append(m, "{sv}", "action", "s", intent.action.c_str());
91     if (r < 0)
92       throw std::runtime_error("Failed to construct DBus message");
93   }
94
95   if (intent.type.length() > 0) {
96     r = sd_bus_message_append(m, "{sv}", "type", "s", intent.type.c_str());
97     if (r < 0)
98       throw std::runtime_error("Failed to construct DBus message");
99   }
100
101   if (intent.uri.length() > 0) {
102     r = sd_bus_message_append(m, "{sv}", "uri", "s", intent.uri.c_str());
103     if (r < 0)
104       throw std::runtime_error("Failed to construct DBus message");
105   }
106
107   r = sd_bus_message_close_container(m);
108   if (r < 0)
109     throw std::runtime_error("Failed to construct DBus message");
110
111   std::ostringstream launch_stack;
112   launch_stack << stack;
113   r = sd_bus_message_append(m, "s", launch_stack.str().c_str());
114   if (r < 0)
115     throw std::runtime_error("Failed to construct DBus message");
116
117   #pragma GCC diagnostic push
118   #pragma GCC diagnostic warning "-Wpragmas"
119   #pragma GCC diagnostic warning "-Wc99-extensions"
120   sd_bus_error error = SD_BUS_ERROR_NULL;
121   #pragma GCC diagnostic pop
122
123   r = sd_bus_call(bus_->raw(), m, 0, &error, nullptr);
124   if (r < 0) {
125     const auto msg = utils::string_format("%s", error.message);
126     sd_bus_error_free(&error);
127     throw std::runtime_error(msg);
128   }
129 }
130
131 core::Property<bool>& ApplicationManager::ready() {
132   return ready_;
133 }
134 }  // namespace skeleton
135 }  // namespace dbus
136 }  // namespace anbox