From 0f5006493bd171f28d147aaa7c5db98456193920 Mon Sep 17 00:00:00 2001 From: Simon Fels Date: Tue, 15 Nov 2016 07:54:19 +0100 Subject: [PATCH] Implement RPC for window state synchronization --- android/service/platform_api_stub.cpp | 30 +---------- android/service/platform_api_stub.h | 9 ++-- android/service/platform_service.cpp | 52 +++++++++++++++++-- android/service/platform_service.h | 11 +++- .../service/platform_service_interface.cpp | 13 +---- android/service/platform_service_interface.h | 8 ++- src/anbox/bridge/platform_api_skeleton.h | 7 +-- .../bridge/platform_message_processor.cpp | 2 - src/anbox/protobuf/anbox_bridge.proto | 16 ++++++ src/anbox/ubuntu/platform_api_skeleton.cpp | 12 +---- src/anbox/ubuntu/platform_api_skeleton.h | 7 +-- 11 files changed, 89 insertions(+), 78 deletions(-) diff --git a/android/service/platform_api_stub.cpp b/android/service/platform_api_stub.cpp index 289c859..e18e045 100644 --- a/android/service/platform_api_stub.cpp +++ b/android/service/platform_api_stub.cpp @@ -55,7 +55,7 @@ void PlatformApiStub::handle_boot_finished_response(Request boot_finished_wait_handle_.result_received(); } -void PlatformApiStub::update_window_state() { +void PlatformApiStub::update_window_state(const anbox::protobuf::bridge::WindowStateUpdate &window_state) { auto c = std::make_shared>(); ALOGI("Updating window state"); @@ -65,11 +65,9 @@ void PlatformApiStub::update_window_state() { update_window_state_wait_handle_.expect_result(); } - protobuf::rpc::Void message; - rpc_channel_->call_method( "update_window_state", - &message, c->response.get(), + &window_state, c->response.get(), google::protobuf::NewCallback(this, &PlatformApiStub::handle_update_window_state_response, c.get())); update_window_state_wait_handle_.wait_for_all(); @@ -78,28 +76,4 @@ void PlatformApiStub::update_window_state() { void PlatformApiStub::handle_update_window_state_response(Request *request) { update_window_state_wait_handle_.result_received(); } - -void PlatformApiStub::remove_window() { - auto c = std::make_shared>(); - - ALOGI("Remove window"); - - { - std::lock_guard lock(mutex_); - remove_window_wait_handle_.expect_result(); - } - - protobuf::rpc::Void message; - - rpc_channel_->call_method( - "remove_window", - &message, c->response.get(), - google::protobuf::NewCallback(this, &PlatformApiStub::handle_remove_window_response, c.get())); - - remove_window_wait_handle_.wait_for_all(); -} - -void PlatformApiStub::handle_remove_window_response(Request *request) { - update_window_state_wait_handle_.result_received(); -} } // namespace anbox diff --git a/android/service/platform_api_stub.h b/android/service/platform_api_stub.h index 02271ba..e13a99c 100644 --- a/android/service/platform_api_stub.h +++ b/android/service/platform_api_stub.h @@ -26,7 +26,11 @@ namespace anbox { namespace protobuf { namespace rpc { class Void; +class WindowStateUpdate; } // namespace rpc +namespace bridge { +class WindowStateUpdate; +} // namespace bridge } // namespace protobuf namespace rpc { class Channel; @@ -36,8 +40,7 @@ public: PlatformApiStub(const std::shared_ptr &rpc_channel); void boot_finished(); - void update_window_state(); - void remove_window(); + void update_window_state(const anbox::protobuf::bridge::WindowStateUpdate &window_state); private: template @@ -49,12 +52,10 @@ private: void handle_boot_finished_response(Request *request); void handle_update_window_state_response(Request *request); - void handle_remove_window_response(Request *request); mutable std::mutex mutex_; common::WaitHandle boot_finished_wait_handle_; common::WaitHandle update_window_state_wait_handle_; - common::WaitHandle remove_window_wait_handle_; std::shared_ptr rpc_channel_; }; diff --git a/android/service/platform_service.cpp b/android/service/platform_service.cpp index 858708f..d8c9823 100644 --- a/android/service/platform_service.cpp +++ b/android/service/platform_service.cpp @@ -19,9 +19,14 @@ #include "android/service/platform_api_stub.h" #include "anbox/rpc/channel.h" +#include "anbox_rpc.pb.h" +#include "anbox_bridge.pb.h" + #define LOG_TAG "Anboxd" #include +#include + using namespace android; namespace android { @@ -34,13 +39,50 @@ status_t PlatformService::boot_finished() { return OK; } -status_t PlatformService::update_window_state() { - platform_api_stub_->update_window_state(); - return OK; +void PlatformService::unpack_window_state(anbox::protobuf::bridge::WindowStateUpdate_WindowState *window, const Parcel &data) { + window->set_has_surface(data.readByte() != 0); + + String8 package_name(data.readString16()); + + auto frame_left = data.readInt32(); + auto frame_top = data.readInt32(); + auto frame_right = data.readInt32(); + auto frame_bottom = data.readInt32(); + auto task_id = data.readInt32(); + auto stack_id = data.readInt32(); + + window->set_package_name(package_name.string()); + window->set_frame_left(frame_left); + window->set_frame_top(frame_top); + window->set_frame_right(frame_right); + window->set_frame_bottom(frame_bottom); + window->set_task_id(task_id); + window->set_stack_id(stack_id); } -status_t PlatformService::remove_window() { - platform_api_stub_->remove_window(); +status_t PlatformService::update_window_state(const Parcel &data) { + anbox::protobuf::bridge::WindowStateUpdate window_state; + + const auto num_displays = data.readInt32(); + for (auto n = 0; n < num_displays; n++) { + const auto display_id = data.readInt32(); + + for (auto m = 0; m < num_windows; m++) { + auto window = window_state.add_windows(); + window->set_display_id(display_id); + unpack_window_state(window, data); + } + } + + const auto num_removed_windows = data.readInt32(); + for (auto n = 0; n < num_removed_windows; n++) { + auto window = window_state.add_removed_windows(); + window->set_display_id(0); + unpack_window_state(window, data); + } + + platform_api_stub_->update_window_state(window_state); + return OK; } } // namespace android diff --git a/android/service/platform_service.h b/android/service/platform_service.h index cf07a17..2578a58 100644 --- a/android/service/platform_service.h +++ b/android/service/platform_service.h @@ -20,10 +20,17 @@ #include "android/service/platform_service_interface.h" +#include + #include namespace anbox { class PlatformApiStub; +namespace protobuf { +namespace bridge { +class WindowStateUpdate_WindowState; +} // namespace bridge +} // namespace protobuf } // namespace anbox namespace android { @@ -34,10 +41,10 @@ public: PlatformService(const std::shared_ptr &platform_api_stub); status_t boot_finished() override; - status_t update_window_state() override; - status_t remove_window() override; + status_t update_window_state(const Parcel &data) override; private: + void unpack_window_state(anbox::protobuf::bridge::WindowStateUpdate_WindowState *window, const Parcel &data); std::shared_ptr platform_api_stub_; }; } // namespace android diff --git a/android/service/platform_service_interface.cpp b/android/service/platform_service_interface.cpp index 14e83cd..ff2e92c 100644 --- a/android/service/platform_service_interface.cpp +++ b/android/service/platform_service_interface.cpp @@ -28,18 +28,12 @@ status_t BpPlatformService::boot_finished() { return remote()->transact(IPlatformService::BOOT_FINISHED, data, &reply); } -status_t BpPlatformService::update_window_state() { +status_t BpPlatformService::update_window_state(const Parcel&) { Parcel data, reply; data.writeInterfaceToken(IPlatformService::getInterfaceDescriptor()); return remote()->transact(IPlatformService::UPDATE_WINDOW_STATE, data, &reply); } -status_t BpPlatformService::remove_window() { - Parcel data, reply; - data.writeInterfaceToken(IPlatformService::getInterfaceDescriptor()); - return remote()->transact(IPlatformService::REMOVE_WINDOW, data, &reply); -} - IMPLEMENT_META_INTERFACE(PlatformService, "org.anbox.IPlatformService"); status_t BnPlatformService::onTransact(uint32_t code, const Parcel &data, @@ -50,10 +44,7 @@ status_t BnPlatformService::onTransact(uint32_t code, const Parcel &data, return boot_finished(); case UPDATE_WINDOW_STATE: CHECK_INTERFACE(IPlatformService, data, reply); - return update_window_state(); - case REMOVE_WINDOW: - CHECK_INTERFACE(IPlatformService, data, reply); - return remove_window(); + return update_window_state(data); default: break; } diff --git a/android/service/platform_service_interface.h b/android/service/platform_service_interface.h index 343354e..876cf95 100644 --- a/android/service/platform_service_interface.h +++ b/android/service/platform_service_interface.h @@ -33,14 +33,13 @@ public: DECLARE_META_INTERFACE(PlatformService); enum { + // Keep this synchronized with frameworks/base/services/java/com/android/server/wm/AnboxPlatformServiceProxy.java BOOT_FINISHED = IBinder::FIRST_CALL_TRANSACTION, UPDATE_WINDOW_STATE = IBinder::FIRST_CALL_TRANSACTION + 1, - REMOVE_WINDOW = IBinder::FIRST_CALL_TRANSACTION + 2, }; virtual status_t boot_finished() = 0; - virtual status_t update_window_state() = 0; - virtual status_t remove_window() = 0; + virtual status_t update_window_state(const Parcel &data) = 0; }; class BpPlatformService : public BpInterface { @@ -48,8 +47,7 @@ public: BpPlatformService(const sp &binder); status_t boot_finished() override; - status_t update_window_state() override; - status_t remove_window() override; + status_t update_window_state(const Parcel &data) override; }; class BnPlatformService : public BnInterface { diff --git a/src/anbox/bridge/platform_api_skeleton.h b/src/anbox/bridge/platform_api_skeleton.h index b07c5d6..57cc93a 100644 --- a/src/anbox/bridge/platform_api_skeleton.h +++ b/src/anbox/bridge/platform_api_skeleton.h @@ -33,6 +33,7 @@ class Void; } // namespace rpc namespace bridge { class Notification; +class WindowStateUpdate; } // namespace bridge } // namespace protobuf namespace rpc { @@ -48,14 +49,10 @@ public: anbox::protobuf::rpc::Void *response, google::protobuf::Closure *done) = 0; - virtual void update_window_state(anbox::protobuf::rpc::Void const *request, + virtual void update_window_state(anbox::protobuf::bridge::WindowStateUpdate const *request, anbox::protobuf::rpc::Void *response, google::protobuf::Closure *done) = 0; - virtual void remove_window(anbox::protobuf::rpc::Void const *request, - anbox::protobuf::rpc::Void *response, - google::protobuf::Closure *done) = 0; - private: std::shared_ptr pending_calls_; }; diff --git a/src/anbox/bridge/platform_message_processor.cpp b/src/anbox/bridge/platform_message_processor.cpp index bfe7e42..59d6f28 100644 --- a/src/anbox/bridge/platform_message_processor.cpp +++ b/src/anbox/bridge/platform_message_processor.cpp @@ -38,8 +38,6 @@ void PlatformMessageProcessor::dispatch(rpc::Invocation const& invocation) { invoke(this, server_.get(), &PlatformApiSkeleton::boot_finished, invocation); else if (invocation.method_name() == "update_window_state") invoke(this, server_.get(), &PlatformApiSkeleton::update_window_state, invocation); - else if (invocation.method_name() == "remove_window") - invoke(this, server_.get(), &PlatformApiSkeleton::remove_window, invocation); } void PlatformMessageProcessor::process_event_sequence(const std::string&) { diff --git a/src/anbox/protobuf/anbox_bridge.proto b/src/anbox/protobuf/anbox_bridge.proto index 2102278..0dce0df 100644 --- a/src/anbox/protobuf/anbox_bridge.proto +++ b/src/anbox/protobuf/anbox_bridge.proto @@ -26,3 +26,19 @@ message SetDnsServers { } repeated Server servers = 2; } + +message WindowStateUpdate { + message WindowState { + required int32 display_id = 1; + required bool has_surface = 2; + required string package_name = 3; + required int32 frame_left = 4; + required int32 frame_top = 5; + required int32 frame_right = 6; + required int32 frame_bottom = 7; + required int32 task_id = 8; + required int32 stack_id = 9; + } + repeated WindowState windows = 1; + repeated WindowState removed_windows = 2; +} diff --git a/src/anbox/ubuntu/platform_api_skeleton.cpp b/src/anbox/ubuntu/platform_api_skeleton.cpp index 5cf0261..459ae17 100644 --- a/src/anbox/ubuntu/platform_api_skeleton.cpp +++ b/src/anbox/ubuntu/platform_api_skeleton.cpp @@ -45,7 +45,7 @@ void PlatformApiSekeleton::boot_finished(anbox::protobuf::rpc::Void const *reque done->Run(); } -void PlatformApiSekeleton::update_window_state(anbox::protobuf::rpc::Void const *request, +void PlatformApiSekeleton::update_window_state(anbox::protobuf::bridge::WindowStateUpdate const *request, anbox::protobuf::rpc::Void *response, google::protobuf::Closure *done) { (void) request; @@ -53,16 +53,6 @@ void PlatformApiSekeleton::update_window_state(anbox::protobuf::rpc::Void const DEBUG(""); - done->Run(); -} - -void PlatformApiSekeleton::remove_window(anbox::protobuf::rpc::Void const *request, - anbox::protobuf::rpc::Void *response, - google::protobuf::Closure *done) { - (void) request; - (void) response; - - DEBUG(""); done->Run(); } diff --git a/src/anbox/ubuntu/platform_api_skeleton.h b/src/anbox/ubuntu/platform_api_skeleton.h index 5e33a71..338760e 100644 --- a/src/anbox/ubuntu/platform_api_skeleton.h +++ b/src/anbox/ubuntu/platform_api_skeleton.h @@ -26,6 +26,7 @@ class Dispatcher; } // namespace common namespace bridge { class AndroidApiStub; +class WindowStateUpdate; } // namespace bridge namespace rpc { class PendingCallCache; @@ -40,14 +41,10 @@ public: anbox::protobuf::rpc::Void *response, google::protobuf::Closure *done) override; - void update_window_state(anbox::protobuf::rpc::Void const *request, + void update_window_state(anbox::protobuf::bridge::WindowStateUpdate const *request, anbox::protobuf::rpc::Void *response, google::protobuf::Closure *done) override; - void remove_window(anbox::protobuf::rpc::Void const *request, - anbox::protobuf::rpc::Void *response, - google::protobuf::Closure *done) override; - void on_boot_finished(const std::function &action); private: