Synchronize clipboard bi-directional with the android container

This commit is contained in:
Simon Fels 2017-01-15 12:38:22 +01:00
commit db3499fd89
16 changed files with 213 additions and 4 deletions

View file

@ -21,6 +21,9 @@
#include "anbox_rpc.pb.h"
#include "anbox_bridge.pb.h"
#define LOG_TAG "Anboxd"
#include <cutils/log.h>
namespace anbox {
PlatformApiStub::PlatformApiStub(const std::shared_ptr<rpc::Channel> &rpc_channel) :
rpc_channel_(rpc_channel) {
@ -87,4 +90,55 @@ void PlatformApiStub::update_application_list(const ApplicationListUpdate &updat
rpc_channel_->send_event(seq);
}
void PlatformApiStub::on_clipboard_data_set(Request<protobuf::rpc::Void> *request) {
request->wh.result_received();
}
void PlatformApiStub::set_clipboard_data(const ClipboardData &data) {
auto c = std::make_shared<Request<protobuf::rpc::Void>>();
protobuf::bridge::ClipboardData message;
message.set_text(data.text);
{
std::lock_guard<decltype(mutex_)> lock(mutex_);
c->wh.expect_result();
}
rpc_channel_->call_method("set_clipboard_data", &message, c->response.get(),
google::protobuf::NewCallback(
this, &PlatformApiStub::on_clipboard_data_set, c.get()));
c->wh.wait_for_all();
if (c->response->has_error()) throw std::runtime_error(c->response->error());
}
void PlatformApiStub::on_clipboard_data_get(Request<protobuf::bridge::ClipboardData> *request) {
request->wh.result_received();
}
PlatformApiStub::ClipboardData PlatformApiStub::get_clipboard_data() {
auto c = std::make_shared<Request<protobuf::bridge::ClipboardData>>();
protobuf::rpc::Void message;
received_clipboard_data_ = ClipboardData{};
{
std::lock_guard<decltype(mutex_)> lock(mutex_);
c->wh.expect_result();
}
rpc_channel_->call_method("get_clipboard_data", &message, c->response.get(),
google::protobuf::NewCallback(
this, &PlatformApiStub::on_clipboard_data_get, c.get()));
c->wh.wait_for_all();
if (c->response->has_error()) throw std::runtime_error(c->response->error());
return ClipboardData{c->response->text()};
}
} // namespace anbox

View file

@ -29,6 +29,9 @@ namespace protobuf {
namespace rpc {
class Void;
} // namespace rpc
namespace bridge {
class ClipboardData;
} // namespace bridge
} // namespace protobuf
namespace rpc {
class Channel;
@ -80,17 +83,29 @@ public:
void update_application_list(const ApplicationListUpdate &update);
struct ClipboardData {
std::string text;
};
void set_clipboard_data(const ClipboardData &data);
ClipboardData get_clipboard_data();
private:
template<typename Response>
struct Request {
Request() : response(std::make_shared<Response>()), success(true) { }
std::shared_ptr<Response> response;
bool success;
common::WaitHandle wh;
};
mutable std::mutex mutex_;
void on_clipboard_data_set(Request<protobuf::rpc::Void> *request);
void on_clipboard_data_get(Request<protobuf::bridge::ClipboardData> *request);
mutable std::mutex mutex_;
std::shared_ptr<rpc::Channel> rpc_channel_;
ClipboardData received_clipboard_data_;
};
} // namespace anbox

View file

@ -124,4 +124,25 @@ status_t PlatformService::update_application_list(const Parcel &data) {
return OK;
}
status_t PlatformService::set_clipboard_data(const Parcel &data) {
if (data.readInt32() == 0)
return OK;
String8 text(data.readString16());
const auto clip_data = anbox::PlatformApiStub::ClipboardData{text.string()};
platform_api_stub_->set_clipboard_data(clip_data);
return OK;
}
status_t PlatformService::get_clipboard_data(const Parcel &data, Parcel *reply) {
(void) data;
const auto clip_data = platform_api_stub_->get_clipboard_data();
if (clip_data.text.empty()) {
reply->writeInt32(0);
return OK;
}
reply->writeInt32(1);
reply->writeString16(String16(clip_data.text.c_str(), clip_data.text.length()));
return OK;
}
} // namespace android

View file

@ -35,6 +35,8 @@ public:
status_t boot_finished() override;
status_t update_window_state(const Parcel &data) override;
status_t update_application_list(const Parcel &data) override;
status_t set_clipboard_data(const Parcel &data) override;
status_t get_clipboard_data(const Parcel &data, Parcel *reply) override;
private:
anbox::PlatformApiStub::WindowStateUpdate::Window unpack_window_state(const Parcel &data);

View file

@ -40,6 +40,18 @@ status_t BpPlatformService::update_application_list(const Parcel&) {
return remote()->transact(IPlatformService::UPDATE_APPLICATION_LIST, data, &reply);
}
status_t BpPlatformService::set_clipboard_data(const Parcel&) {
Parcel data, reply;
data.writeInterfaceToken(IPlatformService::getInterfaceDescriptor());
return remote()->transact(IPlatformService::SET_CLIPBOARD_DATA, data, &reply);
}
status_t BpPlatformService::get_clipboard_data(const Parcel&, Parcel*) {
Parcel data, reply;
data.writeInterfaceToken(IPlatformService::getInterfaceDescriptor());
return remote()->transact(IPlatformService::GET_CLIPBOARD_DATA, data, &reply);
}
IMPLEMENT_META_INTERFACE(PlatformService, "org.anbox.IPlatformService");
status_t BnPlatformService::onTransact(uint32_t code, const Parcel &data,
@ -54,6 +66,12 @@ status_t BnPlatformService::onTransact(uint32_t code, const Parcel &data,
case UPDATE_APPLICATION_LIST:
CHECK_INTERFACE(IPlatformService, data, reply);
return update_application_list(data);
case SET_CLIPBOARD_DATA:
CHECK_INTERFACE(IPlatformService, data, reply);
return set_clipboard_data(data);
case GET_CLIPBOARD_DATA:
CHECK_INTERFACE(IPlatformService, data, reply);
return get_clipboard_data(data, reply);
default:
break;
}

View file

@ -37,11 +37,15 @@ public:
BOOT_FINISHED = IBinder::FIRST_CALL_TRANSACTION,
UPDATE_WINDOW_STATE = IBinder::FIRST_CALL_TRANSACTION + 1,
UPDATE_APPLICATION_LIST = IBinder::FIRST_CALL_TRANSACTION + 2,
SET_CLIPBOARD_DATA = IBinder::FIRST_CALL_TRANSACTION + 3,
GET_CLIPBOARD_DATA = IBinder::FIRST_CALL_TRANSACTION + 4,
};
virtual status_t boot_finished() = 0;
virtual status_t update_window_state(const Parcel &data) = 0;
virtual status_t update_application_list(const Parcel &data) = 0;
virtual status_t set_clipboard_data(const Parcel &data) = 0;
virtual status_t get_clipboard_data(const Parcel &data, Parcel *reply) = 0;
};
class BpPlatformService : public BpInterface<IPlatformService> {
@ -51,6 +55,8 @@ public:
status_t boot_finished() override;
status_t update_window_state(const Parcel &data) override;
status_t update_application_list(const Parcel &data) override;
status_t set_clipboard_data(const Parcel &data) override;
status_t get_clipboard_data(const Parcel &data, Parcel *reply) override;
};
class BnPlatformService : public BnInterface<IPlatformService> {