TYPE3
[iec.git] / src / type3_AndroidCloud / anbox-master / src / anbox / container / management_api_stub.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/container/management_api_stub.h"
19 #include "anbox/logger.h"
20 #include "anbox/rpc/channel.h"
21
22 #include "anbox_container.pb.h"
23 #include "anbox_rpc.pb.h"
24
25 #ifdef USE_PROTOBUF_CALLBACK_HEADER
26 #include <google/protobuf/stubs/callback.h>
27 #endif
28
29 namespace anbox {
30 namespace container {
31
32 const std::chrono::milliseconds ManagementApiStub::stop_waiting_timeout{3000};
33
34 ManagementApiStub::ManagementApiStub(
35     const std::shared_ptr<rpc::Channel> &channel)
36     : channel_(channel) {}
37
38 ManagementApiStub::~ManagementApiStub() {}
39
40 void ManagementApiStub::start_container(const Configuration &configuration) {
41   auto c = std::make_shared<Request<protobuf::rpc::Void>>();
42
43   protobuf::container::StartContainer message;
44   auto message_configuration = new protobuf::container::Configuration;
45
46   for (const auto &item : configuration.bind_mounts) {
47     auto bind_mount_message = message_configuration->add_bind_mounts();
48     bind_mount_message->set_source(item.first);
49     bind_mount_message->set_target(item.second);
50   }
51
52   for (const auto &item : configuration.devices) {
53     auto device_message = message_configuration->add_devices();
54     device_message->set_path(item.first);
55     device_message->set_permission(item.second.permission);
56   }
57
58   for (const auto &prop : configuration.extra_properties)
59     message_configuration->add_extra_properties(prop);
60
61   message.set_allocated_configuration(message_configuration);
62
63   {
64     std::lock_guard<decltype(mutex_)> lock(mutex_);
65     c->wh.expect_result();
66   }
67
68   channel_->call_method("start_container", &message, c->response.get(),
69       google::protobuf::NewCallback(this, &ManagementApiStub::container_started, c.get()));
70
71   c->wh.wait_for_all();
72
73   if (c->response->has_error()) throw std::runtime_error(c->response->error());
74 }
75
76 void ManagementApiStub::container_started(Request<protobuf::rpc::Void> *request) {
77   request->wh.result_received();
78 }
79
80 void ManagementApiStub::stop_container() {
81   auto c = std::make_shared<Request<protobuf::rpc::Void>>();
82
83   protobuf::container::StopContainer message;
84   message.set_force(false);
85
86   {
87     std::lock_guard<decltype(mutex_)> lock(mutex_);
88     c->wh.expect_result();
89   }
90
91   channel_->call_method("stop_container", &message, c->response.get(),
92       google::protobuf::NewCallback(this, &ManagementApiStub::container_stopped, c.get()));
93
94   // If container manager dies before session manager, the session manager
95   // cannot exit if it waits for all, so just wait for 3 seconds.
96   c->wh.wait_for_pending(stop_waiting_timeout);
97
98   if (c->response->has_error()) throw std::runtime_error(c->response->error());
99 }
100
101 void ManagementApiStub::container_stopped(Request<protobuf::rpc::Void> *request) {
102   request->wh.result_received();
103 }
104
105 }  // namespace container
106 }  // namespace anbox