X-Git-Url: https://gerrit.akraino.org/r/gitweb?a=blobdiff_plain;f=src%2Ftype3_AndroidCloud%2Fanbox-master%2Fsrc%2Fanbox%2Fbridge%2Fandroid_api_stub.cpp;fp=src%2Ftype3_AndroidCloud%2Fanbox-master%2Fsrc%2Fanbox%2Fbridge%2Fandroid_api_stub.cpp;h=b81ebe5e421e5e0335cba08678d65f4cd093b33d;hb=e26c1ec581be598521517829adba8c8dd23a768f;hp=0000000000000000000000000000000000000000;hpb=6699c1aea74eeb0eb400e6299079f0c7576f716f;p=iec.git diff --git a/src/type3_AndroidCloud/anbox-master/src/anbox/bridge/android_api_stub.cpp b/src/type3_AndroidCloud/anbox-master/src/anbox/bridge/android_api_stub.cpp new file mode 100644 index 0000000..b81ebe5 --- /dev/null +++ b/src/type3_AndroidCloud/anbox-master/src/anbox/bridge/android_api_stub.cpp @@ -0,0 +1,227 @@ +/* + * 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/bridge/android_api_stub.h" +#include "anbox/system_configuration.h" +#include "anbox/logger.h" +#include "anbox/rpc/channel.h" +#include "anbox/utils.h" +#include "anbox/wm/stack.h" + +#include "anbox_bridge.pb.h" +#include "anbox_rpc.pb.h" + +#include +#ifdef USE_PROTOBUF_CALLBACK_HEADER +#include +#endif + + +namespace fs = boost::filesystem; + +namespace { +constexpr const std::chrono::milliseconds default_rpc_call_timeout{30000}; +} // namespace + +namespace anbox { +namespace bridge { +AndroidApiStub::AndroidApiStub() {} + +AndroidApiStub::~AndroidApiStub() {} + +void AndroidApiStub::set_rpc_channel( + const std::shared_ptr &channel) { + channel_ = channel; +} + +void AndroidApiStub::reset_rpc_channel() { channel_.reset(); } + +void AndroidApiStub::ensure_rpc_channel() { + if (!channel_) throw std::runtime_error("No remote client connected"); +} + +void AndroidApiStub::launch(const android::Intent &intent, + const graphics::Rect &launch_bounds, + const wm::Stack::Id &stack) { + ensure_rpc_channel(); + + auto c = std::make_shared>(); + protobuf::bridge::LaunchApplication message; + + { + std::lock_guard lock(mutex_); + launch_wait_handle_.expect_result(); + } + + switch (stack) { + case wm::Stack::Id::Default: + message.set_stack(::anbox::protobuf::bridge::LaunchApplication_Stack_DEFAULT); + break; + case wm::Stack::Id::Fullscreen: + message.set_stack(::anbox::protobuf::bridge::LaunchApplication_Stack_FULLSCREEN); + break; + case wm::Stack::Id::Freeform: + message.set_stack(::anbox::protobuf::bridge::LaunchApplication_Stack_FREEFORM); + break; + default: + break; + } + + if (launch_bounds != graphics::Rect::Invalid) { + auto rect = message.mutable_launch_bounds(); + rect->set_left(launch_bounds_.left()); + rect->set_top(launch_bounds_.top()); + rect->set_right(launch_bounds_.right()); + rect->set_bottom(launch_bounds_.bottom()); + } + + auto launch_intent = message.mutable_intent(); + + if (!intent.action.empty()) launch_intent->set_action(intent.action); + + if (!intent.uri.empty()) launch_intent->set_uri(intent.uri); + + if (!intent.type.empty()) launch_intent->set_type(intent.type); + + if (!intent.package.empty()) launch_intent->set_package(intent.package); + + if (!intent.component.empty()) launch_intent->set_component(intent.component); + + for (const auto &category : intent.categories) { + auto c = launch_intent->add_categories(); + *c = category; + } + + channel_->call_method( + "launch_application", &message, c->response.get(), + google::protobuf::NewCallback(this, &AndroidApiStub::application_launched, + c.get())); + + launch_wait_handle_.wait_for_pending(default_rpc_call_timeout); + if (!launch_wait_handle_.has_result()) + throw std::runtime_error("RPC call timed out"); + + if (c->response->has_error()) throw std::runtime_error(c->response->error()); +} + +core::Property& AndroidApiStub::ready() { + return ready_; +} + +void AndroidApiStub::application_launched( + Request *request) { + (void)request; + launch_wait_handle_.result_received(); +} + +void AndroidApiStub::set_focused_task(const std::int32_t &id) { + ensure_rpc_channel(); + + auto c = std::make_shared>(); + + protobuf::bridge::SetFocusedTask message; + message.set_id(id); + + { + std::lock_guard lock(mutex_); + set_focused_task_handle_.expect_result(); + } + + channel_->call_method("set_focused_task", &message, c->response.get(), + google::protobuf::NewCallback( + this, &AndroidApiStub::focused_task_set, c.get())); + + set_focused_task_handle_.wait_for_pending(default_rpc_call_timeout); + if (!set_focused_task_handle_.has_result()) + throw std::runtime_error("RPC call timed out"); + + if (c->response->has_error()) throw std::runtime_error(c->response->error()); +} + +void AndroidApiStub::focused_task_set(Request *request) { + (void)request; + set_focused_task_handle_.result_received(); +} + +void AndroidApiStub::remove_task(const std::int32_t &id) { + ensure_rpc_channel(); + + auto c = std::make_shared>(); + + protobuf::bridge::RemoveTask message; + message.set_id(id); + + { + std::lock_guard lock(mutex_); + remove_task_handle_.expect_result(); + } + + channel_->call_method("remove_task", &message, c->response.get(), + google::protobuf::NewCallback( + this, &AndroidApiStub::task_removed, c.get())); + + remove_task_handle_.wait_for_pending(default_rpc_call_timeout); + if (!remove_task_handle_.has_result()) + throw std::runtime_error("RPC call timed out"); + + if (c->response->has_error()) throw std::runtime_error(c->response->error()); +} + +void AndroidApiStub::task_removed(Request *request) { + (void)request; + remove_task_handle_.result_received(); +} + +void AndroidApiStub::resize_task(const std::int32_t &id, + const anbox::graphics::Rect &rect, + const std::int32_t &resize_mode) { + ensure_rpc_channel(); + + auto c = std::make_shared>(); + + protobuf::bridge::ResizeTask message; + message.set_id(id); + message.set_resize_mode(resize_mode); + + auto r = message.mutable_rect(); + r->set_left(rect.left()); + r->set_top(rect.top()); + r->set_right(rect.right()); + r->set_bottom(rect.bottom()); + + { + std::lock_guard lock(mutex_); + resize_task_handle_.expect_result(); + } + + channel_->call_method("resize_task", &message, c->response.get(), + google::protobuf::NewCallback( + this, &AndroidApiStub::task_resized, c.get())); + + resize_task_handle_.wait_for_pending(default_rpc_call_timeout); + if (!resize_task_handle_.has_result()) + throw std::runtime_error("RPC call timed out"); + + if (c->response->has_error()) throw std::runtime_error(c->response->error()); +} + +void AndroidApiStub::task_resized(Request *request) { + (void)request; + resize_task_handle_.result_received(); +} +} // namespace bridge +} // namespace anbox