Commit c362db0a authored by Ryan Daum's avatar Ryan Daum Committed by Commit Bot

[chromecast] Add keyboard event support for webviews

  * Convert gRPC keyboard events to ui::KeyEvents and dispatch
  * Add support for creating synthetic keyboard events to the
    test client.

(Note: Due to issues with webview focus I haven't been able to confirm
that  the events dispatch correctly, but the logic mirrors other input
events.)

Bug: internal b/161811385
Test: manual
Change-Id: I75f8b237cbde4f28c69f1a4d7257c4e8fe06d34d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2416570Reviewed-by: default avatarKevin Schoedel <kpschoedel@chromium.org>
Reviewed-by: default avatarDaniel Nicoara <dnicoara@chromium.org>
Commit-Queue: Ryan Daum <rdaum@chromium.org>
Cr-Commit-Position: refs/heads/master@{#807920}
parent ad9eb162
......@@ -15,7 +15,10 @@ executable("wayland_webview_client") {
"//components/exo/wayland:client_support",
"//skia",
"//third_party/wayland:wayland_client",
"//ui/events:dom_keyboard_layout",
"//ui/events:dom_keycode_converter",
"//ui/events:event_constants",
"//ui/events:events_base",
"//ui/events/types:headers",
"//ui/gl",
]
......
......@@ -17,6 +17,8 @@
#include "chromecast/browser/webview/proto/webview.pb.h"
#include "third_party/grpc/src/include/grpcpp/grpcpp.h"
#include "third_party/skia/include/gpu/GrDirectContext.h"
#include "ui/events/keycodes/dom/keycode_converter.h"
#include "ui/events/keycodes/keyboard_code_conversion.h"
#include "ui/gl/gl_bindings.h"
namespace chromecast {
......@@ -34,6 +36,7 @@ constexpr char kListCommand[] = "list";
constexpr char kNavigateCommand[] = "navigate";
constexpr char kResizeCommand[] = "resize";
constexpr char kPositionCommand[] = "position";
constexpr char kKeyCommand[] = "key";
void FrameCallback(void* data, wl_callback* callback, uint32_t time) {
WebviewClient* webview_client = static_cast<WebviewClient*>(data);
......@@ -51,6 +54,7 @@ void BufferReleaseCallback(void* data, wl_buffer* /* buffer */) {
} // namespace
using chromecast::webview::InputEvent;
using chromecast::webview::KeyInput;
using chromecast::webview::TouchInput;
using chromecast::webview::WebviewRequest;
using chromecast::webview::WebviewResponse;
......@@ -312,6 +316,8 @@ void WebviewClient::InputCallback() {
SendBackRequest(tokens);
else if (tokens[1] == kForwardCommand)
SendForwardRequest(tokens);
else if (tokens[1] == kKeyCommand)
SendKeyRequest(tokens);
std::cout << "Enter command: ";
std::cout.flush();
......@@ -434,6 +440,59 @@ void WebviewClient::SendResizeRequest(const std::vector<std::string>& tokens) {
CreateBuffer(gfx::Size(width, height), drm_format_, bo_usage_);
}
void WebviewClient::SendKeyRequest(const std::vector<std::string>& tokens) {
int id;
if (tokens.size() != 3 || !base::StringToInt(tokens[0], &id) ||
tokens[2].empty()) {
LOG(ERROR) << "Usage: ID key [dom_code]";
return;
}
const auto& webview = webviews_[id];
ui::DomCode dom_code = ui::KeycodeConverter::CodeStringToDomCode(tokens[2]);
if (dom_code == ui::DomCode::NONE) {
LOG(ERROR) << "Unknown DomCode CodeString: " << tokens[2];
return;
}
ui::DomKey dom_key;
ui::KeyboardCode keyboard_code;
if (!ui::DomCodeToUsLayoutDomKey(dom_code, 0 /* flags */, &dom_key,
&keyboard_code)) {
LOG(ERROR) << "Could not convert DomCode to US Layout key: " << tokens[2];
return;
}
SendKeyEvent(webview.get(), base::Time::Now().ToDeltaSinceWindowsEpoch(),
dom_key, dom_code, keyboard_code, true);
SendKeyEvent(webview.get(), base::Time::Now().ToDeltaSinceWindowsEpoch(),
dom_key, dom_code, keyboard_code, false);
}
void WebviewClient::SendKeyEvent(const Webview* webview,
const base::TimeDelta& time,
ui::DomKey dom_key,
ui::DomCode dom_code,
ui::KeyboardCode keyboard_code,
bool down) {
auto key_input = std::make_unique<KeyInput>();
key_input->set_key_code(keyboard_code);
key_input->set_dom_code(static_cast<int32_t>(dom_code));
key_input->set_dom_key(static_cast<int32_t>(dom_key));
auto key_event = std::make_unique<InputEvent>();
key_event->set_event_type(down ? ui::EventType::ET_KEY_PRESSED
: ui::EventType::ET_KEY_RELEASED);
key_event->set_timestamp(time.InMicroseconds());
key_event->set_allocated_key(key_input.release());
WebviewRequest key_request;
key_request.set_allocated_input(key_event.release());
if (!webview->client->Write(key_request))
LOG(ERROR) << "Key request failed";
}
void WebviewClient::SendTouchInput(const Webview* webview,
int x,
int y,
......
......@@ -16,6 +16,9 @@
#include "components/exo/wayland/clients/client_base.h"
#include "third_party/grpc/src/include/grpcpp/grpcpp.h"
#include "ui/events/event_constants.h"
#include "ui/events/keycodes/dom/dom_code.h"
#include "ui/events/keycodes/dom/dom_key.h"
#include "ui/events/keycodes/keyboard_codes.h"
#include "ui/events/types/event_type.h"
#include "ui/gfx/geometry/point.h"
......@@ -85,12 +88,21 @@ class WebviewClient : public exo::wayland::clients::ClientBase {
void SendForwardRequest(const std::vector<std::string>& tokens);
void SendNavigationRequest(const std::vector<std::string>& tokens);
void SendResizeRequest(const std::vector<std::string>& tokens);
void SendKeyRequest(const std::vector<std::string>& tokens);
void SendTouchInput(const Webview* webview,
int x,
int y,
ui::EventType event_type,
uint32_t time,
int32_t id);
void SendKeyEvent(const Webview* webview,
const base::TimeDelta& time,
ui::DomKey dom_key,
ui::DomCode dom_code,
ui::KeyboardCode keyboard_code,
bool down);
void SetPosition(const std::vector<std::string>& tokens);
void TakeExclusiveAccess();
void WlDisplayCallback();
......
......@@ -270,6 +270,20 @@ void WebContentController::ProcessInputEvent(const webview::InputEvent& ev) {
client_->OnError("mouse() not supplied for mouse event");
}
break;
case ui::ET_KEY_PRESSED:
case ui::ET_KEY_RELEASED:
if (ev.has_key()) {
ui::KeyEvent evt(type,
static_cast<ui::KeyboardCode>(ev.key().key_code()),
static_cast<ui::DomCode>(ev.key().dom_code()),
ev.flags(), ui::DomKey(ev.key().dom_key()),
base::TimeTicks() +
base::TimeDelta::FromMicroseconds(ev.timestamp()));
handler->OnKeyEvent(&evt);
} else {
client_->OnError("key() not supplied for key event");
}
break;
default:
break;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment