Commit 90a2a9a9 authored by Yuichiro Hanada's avatar Yuichiro Hanada Committed by Commit Bot

Define type mapping for KeyEventData.

A new mojo method to send a key event from ArcInputMethodService in
Android to arc::ArcImeService will be added soon.
This CL moves KeyEventData struct to ime.mojom and define type mapping
between KeyEventData and ui::KeyEvent.

Bug: b:148193316
Test: component_unittests
Test: manual - InputConnection.SendKeyEvent still works.
Change-Id: I81ff4c11e1794c6e4c3e906596b770d01f21a6b6
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2208310Reviewed-by: default avatarDaniel Cheng <dcheng@chromium.org>
Reviewed-by: default avatarSadrul Chowdhury <sadrul@chromium.org>
Reviewed-by: default avatarYusuke Sato <yusukes@chromium.org>
Reviewed-by: default avatarTetsui Ohkubo <tetsui@chromium.org>
Commit-Queue: Yuichiro Hanada <yhanada@chromium.org>
Cr-Commit-Position: refs/heads/master@{#773585}
parent 04c9cb0b
......@@ -253,23 +253,22 @@ void InputConnectionImpl::SetSelection(const gfx::Range& new_selection_range) {
client->SetEditableSelectionRange(new_selection_range);
}
void InputConnectionImpl::SendKeyEvent(mojom::KeyEventDataPtr data_ptr) {
void InputConnectionImpl::SendKeyEvent(
std::unique_ptr<ui::KeyEvent> key_event) {
DCHECK(key_event);
chromeos::InputMethodEngine::KeyboardEvent event;
if (data_ptr->pressed)
if (key_event->type() == ui::ET_KEY_PRESSED)
event.type = "keydown";
else
event.type = "keyup";
ui::KeyboardCode key_code = static_cast<ui::KeyboardCode>(data_ptr->key_code);
ui::DomCode dom_code = ui::UsLayoutKeyboardCodeToDomCode(key_code);
event.key = ui::KeycodeConverter::DomCodeToCodeString(dom_code);
event.code = ui::KeyboardCodeToDomKeycode(key_code);
event.key_code = data_ptr->key_code;
event.alt_key = data_ptr->is_alt_down;
event.ctrl_key = data_ptr->is_control_down;
event.shift_key = data_ptr->is_shift_down;
event.caps_lock = data_ptr->is_capslock_on;
event.key = key_event->GetCodeString();
event.code = ui::KeyboardCodeToDomKeycode(key_event->key_code());
event.key_code = key_event->key_code();
event.alt_key = key_event->IsAltDown();
event.ctrl_key = key_event->IsControlDown();
event.shift_key = key_event->IsShiftDown();
event.caps_lock = key_event->IsCapsLockOn();
std::string error;
if (!ime_engine_->SendKeyEvents(input_context_id_, {event}, &error)) {
......
......@@ -49,7 +49,7 @@ class InputConnectionImpl : public mojom::InputConnection {
void RequestTextInputState(
mojom::InputConnection::RequestTextInputStateCallback callback) override;
void SetSelection(const gfx::Range& new_selection_range) override;
void SendKeyEvent(mojom::KeyEventDataPtr data_ptr) override;
void SendKeyEvent(std::unique_ptr<ui::KeyEvent> key_event) override;
void SetCompositionRange(const gfx::Range& new_composition_range) override;
private:
......
......@@ -344,47 +344,38 @@ TEST_F(InputConnectionImplTest, SendKeyEvent) {
context_handler()->Reset();
{
mojom::KeyEventDataPtr data = mojom::KeyEventData::New();
data->pressed = true;
data->key_code = ui::VKEY_RETURN;
data->is_shift_down = false;
data->is_control_down = false;
data->is_alt_down = false;
data->is_capslock_on = false;
connection->SendKeyEvent(std::move(data));
auto sent = std::make_unique<ui::KeyEvent>(ui::ET_KEY_PRESSED,
ui::VKEY_RETURN, ui::EF_NONE);
connection->SendKeyEvent(std::move(sent));
EXPECT_EQ(1, context_handler()->send_key_event_call_count());
const auto& event = context_handler()->last_sent_key_event();
EXPECT_EQ(ui::VKEY_RETURN, event.key_code());
EXPECT_EQ(ui::DomCode::ENTER, event.code());
EXPECT_EQ("Enter", event.GetCodeString());
EXPECT_EQ(ui::ET_KEY_PRESSED, event.type());
EXPECT_EQ(0, ui::EF_SHIFT_DOWN & event.flags());
EXPECT_EQ(0, ui::EF_CONTROL_DOWN & event.flags());
EXPECT_EQ(0, ui::EF_ALT_DOWN & event.flags());
EXPECT_EQ(0, ui::EF_CAPS_LOCK_ON & event.flags());
const auto& received = context_handler()->last_sent_key_event();
EXPECT_EQ(ui::VKEY_RETURN, received.key_code());
EXPECT_EQ(ui::DomCode::ENTER, received.code());
EXPECT_EQ("Enter", received.GetCodeString());
EXPECT_EQ(ui::ET_KEY_PRESSED, received.type());
EXPECT_EQ(0, ui::EF_SHIFT_DOWN & received.flags());
EXPECT_EQ(0, ui::EF_CONTROL_DOWN & received.flags());
EXPECT_EQ(0, ui::EF_ALT_DOWN & received.flags());
EXPECT_EQ(0, ui::EF_CAPS_LOCK_ON & received.flags());
}
{
mojom::KeyEventDataPtr data = mojom::KeyEventData::New();
data->pressed = false;
data->key_code = ui::VKEY_A;
data->is_shift_down = true;
data->is_control_down = true;
data->is_alt_down = true;
data->is_capslock_on = true;
connection->SendKeyEvent(std::move(data));
auto sent = std::make_unique<ui::KeyEvent>(
ui::ET_KEY_RELEASED, ui::VKEY_A,
ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN |
ui::EF_CAPS_LOCK_ON);
connection->SendKeyEvent(std::move(sent));
EXPECT_EQ(2, context_handler()->send_key_event_call_count());
const auto& event = context_handler()->last_sent_key_event();
EXPECT_EQ(ui::VKEY_A, event.key_code());
EXPECT_EQ(ui::DomCode::US_A, event.code());
EXPECT_EQ("KeyA", event.GetCodeString());
EXPECT_EQ(ui::ET_KEY_RELEASED, event.type());
EXPECT_NE(0, ui::EF_SHIFT_DOWN & event.flags());
EXPECT_NE(0, ui::EF_CONTROL_DOWN & event.flags());
EXPECT_NE(0, ui::EF_ALT_DOWN & event.flags());
EXPECT_NE(0, ui::EF_CAPS_LOCK_ON & event.flags());
const auto& received = context_handler()->last_sent_key_event();
EXPECT_EQ(ui::VKEY_A, received.key_code());
EXPECT_EQ(ui::DomCode::US_A, received.code());
EXPECT_EQ("KeyA", received.GetCodeString());
EXPECT_EQ(ui::ET_KEY_RELEASED, received.type());
EXPECT_NE(0, ui::EF_SHIFT_DOWN & received.flags());
EXPECT_NE(0, ui::EF_CONTROL_DOWN & received.flags());
EXPECT_NE(0, ui::EF_ALT_DOWN & received.flags());
EXPECT_NE(0, ui::EF_CAPS_LOCK_ON & received.flags());
}
engine()->FocusOut();
}
......
......@@ -26,6 +26,7 @@ include_rules = [
"+third_party/skia",
"+ui/base",
"+ui/display",
"+ui/events",
"+ui/gfx/geometry",
"+ui/gfx/range/range.h",
]
......
......@@ -113,20 +113,28 @@ if (is_chromeos) {
}
source_set("mojom_traits") {
sources = [ "ime_mojom_traits.h" ]
sources = [
"ime_mojom_traits.cc",
"ime_mojom_traits.h",
]
deps = [
":mojom",
"//ui/base/ime:text_input_types",
"//ui/events",
]
}
source_set("unit_tests") {
testonly = true
sources = [ "video_accelerator_mojom_traits_unittest.cc" ]
sources = [
"ime_mojom_traits_unittest.cc",
"video_accelerator_mojom_traits_unittest.cc",
]
deps = [
":mojom",
":mojom_traits",
"//media",
"//mojo/public/cpp/test_support:test_utils",
"//testing/gtest",
......
......@@ -43,6 +43,19 @@ struct CompositionSegment {
bool emphasized;
};
// Represents the information of a key event.
struct KeyEventData {
// Whether the event is a press event or a release event.
bool pressed;
// The key touched in the event represented in |ui::KeyboardCode|.
int32 key_code;
// The flags for modifiers state.
bool is_shift_down;
bool is_control_down;
bool is_alt_down;
bool is_capslock_on;
};
// Next method ID: 6
interface ImeHost {
// Notifies Chrome that the text input focus is changed.
......
mojom = "//components/arc/mojom/ime.mojom"
public_headers = [ "//ui/base/ime/text_input_type.h" ]
public_headers = [
"//ui/base/ime/text_input_type.h",
"//ui/events/event.h",
]
traits_headers = [ "//components/arc/mojom/ime_mojom_traits.h" ]
type_mappings = [ "arc.mojom.TextInputType=::ui::TextInputType" ]
type_mappings = [
"arc.mojom.TextInputType=::ui::TextInputType",
"arc.mojom.KeyEventData=::std::unique_ptr<::ui::KeyEvent>[move_only]",
]
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/arc/mojom/ime_mojom_traits.h"
#include "ui/events/keycodes/keyboard_code_conversion.h"
namespace mojo {
using KeyEventUniquePtr = std::unique_ptr<ui::KeyEvent>;
bool StructTraits<arc::mojom::KeyEventDataDataView, KeyEventUniquePtr>::Read(
arc::mojom::KeyEventDataDataView data,
KeyEventUniquePtr* out) {
const ui::EventType type =
data.pressed() ? ui::ET_KEY_PRESSED : ui::ET_KEY_RELEASED;
// TODO(yhanada): Currently we have no way to know the correct keyboard layout
// here, so assuming US layout. Find a way to get the more precise DomCode.
const ui::DomCode dom_code = ui::UsLayoutKeyboardCodeToDomCode(
static_cast<ui::KeyboardCode>(data.key_code()));
int flags = 0;
if (data.is_shift_down())
flags |= ui::EF_SHIFT_DOWN;
if (data.is_control_down())
flags |= ui::EF_CONTROL_DOWN;
if (data.is_alt_down())
flags |= ui::EF_ALT_DOWN;
if (data.is_capslock_on())
flags |= ui::EF_CAPS_LOCK_ON;
ui::KeyboardCode key_code;
ui::DomKey dom_key;
if (!DomCodeToUsLayoutDomKey(dom_code, flags, &dom_key, &key_code))
return false;
*out = std::make_unique<ui::KeyEvent>(type, key_code, dom_code, flags,
dom_key, base::TimeTicks::Now());
return true;
}
} // namespace mojo
......@@ -5,8 +5,9 @@
#ifndef COMPONENTS_ARC_MOJOM_IME_MOJOM_TRAITS_H_
#define COMPONENTS_ARC_MOJOM_IME_MOJOM_TRAITS_H_
#include "components/arc/mojom/ime.mojom-shared.h"
#include "components/arc/mojom/ime.mojom.h"
#include "ui/base/ime/text_input_type.h"
#include "ui/events/event.h"
namespace mojo {
......@@ -107,6 +108,32 @@ struct EnumTraits<arc::mojom::TextInputType, ui::TextInputType> {
}
};
using KeyEventUniquePtr = std::unique_ptr<ui::KeyEvent>;
template <>
struct StructTraits<arc::mojom::KeyEventDataDataView, KeyEventUniquePtr> {
static bool pressed(const KeyEventUniquePtr& key_event) {
return key_event->type() == ui::ET_KEY_PRESSED;
}
static int32_t key_code(const KeyEventUniquePtr& key_event) {
return key_event->key_code();
}
static bool is_shift_down(const KeyEventUniquePtr& key_event) {
return key_event->IsShiftDown();
}
static bool is_control_down(const KeyEventUniquePtr& key_event) {
return key_event->IsControlDown();
}
static bool is_alt_down(const KeyEventUniquePtr& key_event) {
return key_event->IsAltDown();
}
static bool is_capslock_on(const KeyEventUniquePtr& key_event) {
return key_event->IsCapsLockOn();
}
static bool Read(arc::mojom::KeyEventDataDataView data,
KeyEventUniquePtr* out);
};
} // namespace mojo
#endif // COMPONENTS_ARC_MOJOM_IME_MOJOM_TRAITS_H_
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/arc/mojom/ime_mojom_traits.h"
#include "mojo/public/cpp/test_support/test_utils.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/events/event.h"
#include "ui/events/keycodes/dom/dom_code.h"
namespace mojo {
namespace {
void ExpectKeyEventsEqual(const ui::KeyEvent& expected,
const ui::KeyEvent& actual) {
EXPECT_EQ(expected.type(), actual.type());
EXPECT_EQ(expected.key_code(), actual.key_code());
EXPECT_EQ(expected.code(), actual.code());
EXPECT_EQ(expected.IsShiftDown(), actual.IsShiftDown());
EXPECT_EQ(expected.IsAltDown(), actual.IsAltDown());
EXPECT_EQ(expected.IsControlDown(), actual.IsControlDown());
EXPECT_EQ(expected.IsCapsLockOn(), actual.IsCapsLockOn());
}
} // namespace
TEST(KeyEventStructTraitsTest, Convert) {
const ui::KeyEvent kTestData[] = {
{ui::ET_KEY_PRESSED, ui::VKEY_A, ui::DomCode::US_A, ui::EF_CONTROL_DOWN},
{ui::ET_KEY_PRESSED, ui::VKEY_B, ui::DomCode::US_B, ui::EF_ALT_DOWN},
{ui::ET_KEY_RELEASED, ui::VKEY_B, ui::DomCode::US_B, ui::EF_SHIFT_DOWN},
{ui::ET_KEY_PRESSED, ui::VKEY_A, ui::DomCode::US_A, ui::EF_CAPS_LOCK_ON},
};
for (size_t idx = 0; idx < base::size(kTestData); ++idx) {
auto copy = std::make_unique<ui::KeyEvent>(kTestData[idx]);
std::unique_ptr<ui::KeyEvent> output;
mojo::test::SerializeAndDeserialize<arc::mojom::KeyEventData>(&copy,
&output);
ExpectKeyEventsEqual(*copy, *output);
}
}
} // namespace mojo
......@@ -59,20 +59,6 @@ struct TextInputState {
[MinVersion=6] Range? composition_text_range;
};
// Represents the information of a key event.
[MinVersion=7]
struct KeyEventData {
// Whether the event is a press event or a release event.
bool pressed;
// The key touched in the event represented in |ui::KeyboardCode|.
int32 key_code;
// The flags for modifiers state.
bool is_shift_down;
bool is_control_down;
bool is_alt_down;
bool is_capslock_on;
};
// This interface provides methods to control a text field.
// It is generated for each focused text field and passed to Android.
// This interface will be closed when the focus moves to another text field.
......
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