Commit b171ff9c authored by moshayedi's avatar moshayedi Committed by Commit bot

IME for Mus: Use ui::InputMethodChromeOS to provide logic for ime driver.

The goal of this CL is to modify content_browser's IMEDriver so we have access
to ui::InputMethodChromeOS's functionality in mus+ash.

This CL:
- Modifies ui::InputMethodChromeOS so it can call an ack callback after
  processing events.
- Introduces InputMethodBridge to acts as a bridge between
  ui::mojom::InputMethod and ui::InputMethodChromeOS.
- Introduces RemoteTextInputClient to send commands received from
  ui::InputMethodChromeOS to a remote client over mojo IPC.
- Modifies content_browser's IMEDriver implementation to use
  ui::InputMethodChromeOS via InputMethodBridge.
- Some unittests to verify that InputMethodBridge works correctly.

BUG=665981

Review-Url: https://codereview.chromium.org/2557493002
Cr-Commit-Position: refs/heads/master@{#437955}
parent 561b5ae6
...@@ -1892,8 +1892,14 @@ split_static_library("ui") { ...@@ -1892,8 +1892,14 @@ split_static_library("ui") {
# apart from aura::Window, which is also not supported). # apart from aura::Window, which is also not supported).
if (!is_mac) { if (!is_mac) {
sources += [ sources += [
"views/ime_driver_mus.cc", "views/ime_driver/ime_driver_mus.cc",
"views/ime_driver_mus.h", "views/ime_driver/ime_driver_mus.h",
"views/ime_driver/input_method_bridge_chromeos.cc",
"views/ime_driver/input_method_bridge_chromeos.h",
"views/ime_driver/remote_text_input_client.cc",
"views/ime_driver/remote_text_input_client.h",
"views/ime_driver/simple_input_method.cc",
"views/ime_driver/simple_input_method.h",
"views/tabs/window_finder_mus.cc", "views/tabs/window_finder_mus.cc",
"views/tabs/window_finder_mus.h", "views/tabs/window_finder_mus.h",
] ]
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
#include "chrome/browser/ui/views/chrome_constrained_window_views_client.h" #include "chrome/browser/ui/views/chrome_constrained_window_views_client.h"
#include "chrome/browser/ui/views/chrome_views_delegate.h" #include "chrome/browser/ui/views/chrome_views_delegate.h"
#include "chrome/browser/ui/views/ime_driver_mus.h" #include "chrome/browser/ui/views/ime_driver/ime_driver_mus.h"
#include "components/constrained_window/constrained_window_views.h" #include "components/constrained_window/constrained_window_views.h"
#if defined(USE_AURA) #if defined(USE_AURA)
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#include "chrome/browser/ui/views/ime_driver_mus.h" #include "chrome/browser/ui/views/ime_driver/ime_driver_mus.h"
#include "content/public/browser/browser_thread.h" #include "content/public/browser/browser_thread.h"
#include "content/public/common/service_manager_connection.h" #include "content/public/common/service_manager_connection.h"
...@@ -10,41 +10,17 @@ ...@@ -10,41 +10,17 @@
#include "services/service_manager/public/cpp/connector.h" #include "services/service_manager/public/cpp/connector.h"
#include "services/ui/public/interfaces/constants.mojom.h" #include "services/ui/public/interfaces/constants.mojom.h"
#include "services/ui/public/interfaces/ime/ime.mojom.h" #include "services/ui/public/interfaces/ime/ime.mojom.h"
#include "ui/base/ime/ime_bridge.h"
namespace { #if defined(OS_CHROMEOS)
#include "chrome/browser/ui/views/ime_driver/input_method_bridge_chromeos.h"
#else
#include "chrome/browser/ui/views/ime_driver/simple_input_method.h"
#endif // defined(OS_CHROMEOS)
class InputMethod : public ui::mojom::InputMethod { IMEDriver::IMEDriver() {
public: ui::IMEBridge::Initialize();
explicit InputMethod(ui::mojom::TextInputClientPtr client) }
: client_(std::move(client)) {}
~InputMethod() override {}
private:
// ui::mojom::InputMethod:
void OnTextInputModeChanged(
ui::mojom::TextInputMode text_input_mode) override {}
void OnTextInputTypeChanged(
ui::mojom::TextInputType text_input_type) override {}
void OnCaretBoundsChanged(const gfx::Rect& caret_bounds) override {}
void ProcessKeyEvent(std::unique_ptr<ui::Event> key_event,
const ProcessKeyEventCallback& callback) override {
DCHECK(key_event->IsKeyEvent());
if (key_event->AsKeyEvent()->is_char()) {
client_->InsertChar(std::move(key_event));
callback.Run(true);
} else {
callback.Run(false);
}
}
void CancelComposition() override {}
ui::mojom::TextInputClientPtr client_;
DISALLOW_COPY_AND_ASSIGN(InputMethod);
};
} // namespace
IMEDriver::~IMEDriver() {} IMEDriver::~IMEDriver() {}
...@@ -52,7 +28,7 @@ IMEDriver::~IMEDriver() {} ...@@ -52,7 +28,7 @@ IMEDriver::~IMEDriver() {}
void IMEDriver::Register() { void IMEDriver::Register() {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI); DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
ui::mojom::IMEDriverPtr ime_driver_ptr; ui::mojom::IMEDriverPtr ime_driver_ptr;
mojo::MakeStrongBinding(base::WrapUnique(new IMEDriver), mojo::MakeStrongBinding(base::MakeUnique<IMEDriver>(),
GetProxy(&ime_driver_ptr)); GetProxy(&ime_driver_ptr));
ui::mojom::IMERegistrarPtr ime_registrar; ui::mojom::IMERegistrarPtr ime_registrar;
content::ServiceManagerConnection::GetForProcess() content::ServiceManagerConnection::GetForProcess()
...@@ -65,13 +41,18 @@ void IMEDriver::StartSession( ...@@ -65,13 +41,18 @@ void IMEDriver::StartSession(
int32_t session_id, int32_t session_id,
ui::mojom::TextInputClientPtr client, ui::mojom::TextInputClientPtr client,
ui::mojom::InputMethodRequest input_method_request) { ui::mojom::InputMethodRequest input_method_request) {
#if defined(OS_CHROMEOS)
input_method_bindings_[session_id] =
base::MakeUnique<mojo::Binding<ui::mojom::InputMethod>>(
new InputMethodBridge(std::move(client)),
std::move(input_method_request));
#else
input_method_bindings_[session_id] = input_method_bindings_[session_id] =
base::MakeUnique<mojo::Binding<ui::mojom::InputMethod>>( base::MakeUnique<mojo::Binding<ui::mojom::InputMethod>>(
new InputMethod(std::move(client)), std::move(input_method_request)); new SimpleInputMethod());
#endif
} }
IMEDriver::IMEDriver() {}
void IMEDriver::CancelSession(int32_t session_id) { void IMEDriver::CancelSession(int32_t session_id) {
input_method_bindings_.erase(session_id); input_method_bindings_.erase(session_id);
} }
...@@ -2,8 +2,8 @@ ...@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#ifndef CHROME_BROWSER_UI_VIEWS_IME_DRIVER_MUS_H_ #ifndef CHROME_BROWSER_UI_VIEWS_IME_DRIVER_IME_DRIVER_MUS_H_
#define CHROME_BROWSER_UI_VIEWS_IME_DRIVER_MUS_H_ #define CHROME_BROWSER_UI_VIEWS_IME_DRIVER_IME_DRIVER_MUS_H_
#include <stdint.h> #include <stdint.h>
...@@ -15,14 +15,13 @@ ...@@ -15,14 +15,13 @@
class IMEDriver : public ui::mojom::IMEDriver { class IMEDriver : public ui::mojom::IMEDriver {
public: public:
IMEDriver();
~IMEDriver() override; ~IMEDriver() override;
// Instantiate the IME driver and register it to the UI service. // Instantiate the IME driver and register it to the UI service.
static void Register(); static void Register();
private: private:
IMEDriver();
// ui::mojom::IMEDriver: // ui::mojom::IMEDriver:
void StartSession( void StartSession(
int32_t session_id, int32_t session_id,
...@@ -36,4 +35,4 @@ class IMEDriver : public ui::mojom::IMEDriver { ...@@ -36,4 +35,4 @@ class IMEDriver : public ui::mojom::IMEDriver {
DISALLOW_COPY_AND_ASSIGN(IMEDriver); DISALLOW_COPY_AND_ASSIGN(IMEDriver);
}; };
#endif // CHROME_BROWSER_UI_VIEWS_IME_DRIVER_MUS_H_ #endif // CHROME_BROWSER_UI_VIEWS_IME_DRIVER_IME_DRIVER_MUS_H_
// Copyright 2016 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 "chrome/browser/ui/views/ime_driver/input_method_bridge_chromeos.h"
#include "chrome/browser/ui/views/ime_driver/remote_text_input_client.h"
InputMethodBridge::InputMethodBridge(ui::mojom::TextInputClientPtr client)
: client_(base::MakeUnique<RemoteTextInputClient>(std::move(client))),
input_method_chromeos_(
base::MakeUnique<ui::InputMethodChromeOS>(nullptr)) {
input_method_chromeos_->SetFocusedTextInputClient(client_.get());
}
InputMethodBridge::~InputMethodBridge() {}
void InputMethodBridge::OnTextInputModeChanged(
ui::mojom::TextInputMode text_input_mode) {
// TODO(moshayedi): crbug.com/631527. Consider removing this, as
// ui::InputMethodChromeOS doesn't have this.
}
void InputMethodBridge::OnTextInputTypeChanged(
ui::mojom::TextInputType text_input_type) {
input_method_chromeos_->OnTextInputTypeChanged(client_.get());
}
void InputMethodBridge::OnCaretBoundsChanged(const gfx::Rect& caret_bounds) {
input_method_chromeos_->OnCaretBoundsChanged(client_.get());
}
void InputMethodBridge::ProcessKeyEvent(
std::unique_ptr<ui::Event> event,
const ProcessKeyEventCallback& callback) {
DCHECK(event->IsKeyEvent());
ui::KeyEvent* key_event = event->AsKeyEvent();
if (!key_event->is_char()) {
input_method_chromeos_->DispatchKeyEvent(
key_event, base::MakeUnique<base::Callback<void(bool)>>(callback));
} else {
callback.Run(false);
}
}
void InputMethodBridge::CancelComposition() {
input_method_chromeos_->CancelComposition(client_.get());
}
// Copyright 2016 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.
#ifndef CHROME_BROWSER_UI_VIEWS_IME_DRIVER_INPUT_METHOD_BRIDGE_CHROMEOS_H_
#define CHROME_BROWSER_UI_VIEWS_IME_DRIVER_INPUT_METHOD_BRIDGE_CHROMEOS_H_
#include "services/ui/public/interfaces/ime/ime.mojom.h"
#include "ui/base/ime/input_method_chromeos.h"
// This bridges between mojo InputMethod API and ui::InputMethodChromeOS. It
// forwards the received events to an instance of ui::InputMethodChromeOS.
class InputMethodBridge : public ui::mojom::InputMethod {
public:
explicit InputMethodBridge(ui::mojom::TextInputClientPtr client);
~InputMethodBridge() override;
// ui::mojom::InputMethod:
void OnTextInputModeChanged(
ui::mojom::TextInputMode text_input_mode) override;
void OnTextInputTypeChanged(
ui::mojom::TextInputType text_input_type) override;
void OnCaretBoundsChanged(const gfx::Rect& caret_bounds) override;
void ProcessKeyEvent(std::unique_ptr<ui::Event> key_event,
const ProcessKeyEventCallback& callback) override;
void CancelComposition() override;
private:
std::unique_ptr<ui::TextInputClient> client_;
std::unique_ptr<ui::InputMethodChromeOS> input_method_chromeos_;
DISALLOW_COPY_AND_ASSIGN(InputMethodBridge);
};
#endif // CHROME_BROWSER_UI_VIEWS_IME_DRIVER_INPUT_METHOD_BRIDGE_CHROMEOS_H_
// Copyright 2016 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 <stdint.h>
#include "base/bind.h"
#include "base/macros.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/ui/views/ime_driver/input_method_bridge_chromeos.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/base/ime/ime_bridge.h"
#include "ui/events/event.h"
#include "ui/events/event_constants.h"
#include "ui/events/event_utils.h"
#include "ui/events/keycodes/dom/dom_code.h"
#include "ui/events/keycodes/dom/dom_key.h"
#include "ui/events/keycodes/keyboard_code_conversion.h"
#include "ui/events/keycodes/keyboard_codes.h"
enum class CompositionEventType {
SET,
CONFIRM,
CLEAR,
INSERT_TEXT,
INSERT_CHAR
};
struct CompositionEvent {
CompositionEventType type;
base::string16 text_data;
base::char16 char_data;
};
class TestTextInputClient : public ui::mojom::TextInputClient {
public:
explicit TestTextInputClient(ui::mojom::TextInputClientRequest request)
: binding_(this, std::move(request)) {}
CompositionEvent WaitUntilCompositionEvent() {
if (!receieved_event_.has_value()) {
run_loop_ = base::MakeUnique<base::RunLoop>();
run_loop_->Run();
run_loop_.reset();
}
CompositionEvent result = receieved_event_.value();
receieved_event_.reset();
return result;
}
private:
void SetCompositionText(const ui::CompositionText& composition) override {
CompositionEvent ev = {CompositionEventType::SET, composition.text, 0};
receieved_event_ = ev;
if (run_loop_)
run_loop_->Quit();
}
void ConfirmCompositionText() override {
CompositionEvent ev = {CompositionEventType::CONFIRM, base::string16(), 0};
receieved_event_ = ev;
if (run_loop_)
run_loop_->Quit();
}
void ClearCompositionText() override {
CompositionEvent ev = {CompositionEventType::CLEAR, base::string16(), 0};
receieved_event_ = ev;
if (run_loop_)
run_loop_->Quit();
}
void InsertText(const std::string& text) override {
CompositionEvent ev = {CompositionEventType::INSERT_TEXT,
base::UTF8ToUTF16(text), 0};
receieved_event_ = ev;
if (run_loop_)
run_loop_->Quit();
}
void InsertChar(std::unique_ptr<ui::Event> event) override {
ASSERT_TRUE(event->IsKeyEvent());
CompositionEvent ev = {CompositionEventType::INSERT_CHAR, base::string16(),
event->AsKeyEvent()->GetCharacter()};
receieved_event_ = ev;
if (run_loop_)
run_loop_->Quit();
}
mojo::Binding<ui::mojom::TextInputClient> binding_;
std::unique_ptr<base::RunLoop> run_loop_;
base::Optional<CompositionEvent> receieved_event_;
DISALLOW_COPY_AND_ASSIGN(TestTextInputClient);
};
class InputMethodBridgeChromeOSTest : public testing::Test {
public:
InputMethodBridgeChromeOSTest()
: thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP) {}
~InputMethodBridgeChromeOSTest() override {}
void SetUp() override {
ui::IMEBridge::Initialize();
ui::mojom::TextInputClientPtr client_ptr;
client_ = base::MakeUnique<TestTextInputClient>(GetProxy(&client_ptr));
input_method_ = base::MakeUnique<InputMethodBridge>(std::move(client_ptr));
}
bool ProcessKeyEvent(std::unique_ptr<ui::Event> event) {
handled_.reset();
input_method_->ProcessKeyEvent(
std::move(event),
base::Bind(&InputMethodBridgeChromeOSTest::ProcessKeyEventCallback,
base::Unretained(this)));
if (!handled_.has_value()) {
run_loop_ = base::MakeUnique<base::RunLoop>();
run_loop_->Run();
run_loop_.reset();
}
return handled_.value();
}
std::unique_ptr<ui::Event> UnicodeKeyPress(ui::KeyboardCode vkey,
ui::DomCode code,
int flags,
base::char16 character) const {
return base::MakeUnique<ui::KeyEvent>(ui::ET_KEY_PRESSED, vkey, code, flags,
ui::DomKey::FromCharacter(character),
ui::EventTimeForNow());
}
protected:
void ProcessKeyEventCallback(bool handled) {
handled_ = handled;
if (run_loop_)
run_loop_->Quit();
}
content::TestBrowserThreadBundle thread_bundle_;
std::unique_ptr<TestTextInputClient> client_;
std::unique_ptr<InputMethodBridge> input_method_;
std::unique_ptr<base::RunLoop> run_loop_;
base::Optional<bool> handled_;
DISALLOW_COPY_AND_ASSIGN(InputMethodBridgeChromeOSTest);
};
// Tests if hexadecimal composition provided by ui::CharacterComposer works
// correctly. ui::CharacterComposer is tried if no input method extensions
// have been registered yet.
TEST_F(InputMethodBridgeChromeOSTest, HexadecimalComposition) {
struct {
ui::KeyboardCode vkey;
ui::DomCode code;
int flags;
base::char16 character;
std::string composition_text;
} kTestSequence[] = {
{ui::VKEY_U, ui::DomCode::US_U, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN,
'U', "u"},
{ui::VKEY_3, ui::DomCode::DIGIT3, 0, '3', "u3"},
{ui::VKEY_0, ui::DomCode::DIGIT0, 0, '0', "u30"},
{ui::VKEY_4, ui::DomCode::DIGIT4, 0, '4', "u304"},
{ui::VKEY_2, ui::DomCode::DIGIT2, 0, '2', "u3042"},
};
// Send the Ctrl-Shift-U,3,4,0,2 sequence.
for (size_t i = 0; i < arraysize(kTestSequence); i++) {
EXPECT_TRUE(ProcessKeyEvent(
UnicodeKeyPress(kTestSequence[i].vkey, kTestSequence[i].code,
kTestSequence[i].flags, kTestSequence[i].character)));
CompositionEvent ev = client_->WaitUntilCompositionEvent();
EXPECT_EQ(CompositionEventType::SET, ev.type);
EXPECT_EQ(base::UTF8ToUTF16(kTestSequence[i].composition_text),
ev.text_data);
}
// Press the return key and verify that the composition text was converted
// to the desired text.
EXPECT_TRUE(ProcessKeyEvent(
UnicodeKeyPress(ui::VKEY_RETURN, ui::DomCode::ENTER, 0, '\r')));
CompositionEvent ev = client_->WaitUntilCompositionEvent();
EXPECT_EQ(CompositionEventType::INSERT_TEXT, ev.type);
EXPECT_EQ(base::string16(1, 0x3042), ev.text_data);
}
// Test that Ctrl-C, Ctrl-X, and Ctrl-V are not handled.
TEST_F(InputMethodBridgeChromeOSTest, ClipboardAccelerators) {
EXPECT_FALSE(ProcessKeyEvent(UnicodeKeyPress(ui::VKEY_C, ui::DomCode::US_C,
ui::EF_CONTROL_DOWN, 'C')));
EXPECT_FALSE(ProcessKeyEvent(UnicodeKeyPress(ui::VKEY_X, ui::DomCode::US_X,
ui::EF_CONTROL_DOWN, 'X')));
EXPECT_FALSE(ProcessKeyEvent(UnicodeKeyPress(ui::VKEY_V, ui::DomCode::US_V,
ui::EF_CONTROL_DOWN, 'V')));
}
// Copyright 2016 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.
// Reduce number of log messages by logging each NOTIMPLEMENTED() only once.
// This has to be before any other includes, else default is picked up.
// See base/logging.h for details on this.
#define NOTIMPLEMENTED_POLICY 5
#include "chrome/browser/ui/views/ime_driver/remote_text_input_client.h"
#include "base/strings/utf_string_conversions.h"
RemoteTextInputClient::RemoteTextInputClient(
ui::mojom::TextInputClientPtr remote_client)
: remote_client_(std::move(remote_client)) {}
RemoteTextInputClient::~RemoteTextInputClient() {}
void RemoteTextInputClient::SetCompositionText(
const ui::CompositionText& composition) {
remote_client_->SetCompositionText(composition);
}
void RemoteTextInputClient::ConfirmCompositionText() {
remote_client_->ConfirmCompositionText();
}
void RemoteTextInputClient::ClearCompositionText() {
remote_client_->ClearCompositionText();
}
void RemoteTextInputClient::InsertText(const base::string16& text) {
remote_client_->InsertText(base::UTF16ToUTF8(text));
}
void RemoteTextInputClient::InsertChar(const ui::KeyEvent& event) {
remote_client_->InsertChar(ui::Event::Clone(event));
}
ui::TextInputType RemoteTextInputClient::GetTextInputType() const {
// TODO(moshayedi): crbug.com/631527.
NOTIMPLEMENTED();
return ui::TEXT_INPUT_TYPE_TEXT;
}
ui::TextInputMode RemoteTextInputClient::GetTextInputMode() const {
// TODO(moshayedi): crbug.com/631527.
NOTIMPLEMENTED();
return ui::TEXT_INPUT_MODE_DEFAULT;
}
base::i18n::TextDirection RemoteTextInputClient::GetTextDirection() const {
// TODO(moshayedi): crbug.com/631527.
NOTIMPLEMENTED();
return base::i18n::UNKNOWN_DIRECTION;
}
int RemoteTextInputClient::GetTextInputFlags() const {
// TODO(moshayedi): crbug.com/631527.
NOTIMPLEMENTED();
return 0;
}
bool RemoteTextInputClient::CanComposeInline() const {
// If we return false here, ui::InputMethodChromeOS will try to create a
// composition window. But here we are at IMEDriver, and composition
// window shouldn't be created by IMEDriver.
return true;
}
gfx::Rect RemoteTextInputClient::GetCaretBounds() const {
// TODO(moshayedi): crbug.com/631527.
NOTIMPLEMENTED();
return gfx::Rect();
}
bool RemoteTextInputClient::GetCompositionCharacterBounds(
uint32_t index,
gfx::Rect* rect) const {
// TODO(moshayedi): crbug.com/631527.
NOTIMPLEMENTED();
return false;
}
bool RemoteTextInputClient::HasCompositionText() const {
// TODO(moshayedi): crbug.com/631527.
NOTIMPLEMENTED();
return false;
}
bool RemoteTextInputClient::GetTextRange(gfx::Range* range) const {
// TODO(moshayedi): crbug.com/631527.
NOTIMPLEMENTED();
return false;
}
bool RemoteTextInputClient::GetCompositionTextRange(gfx::Range* range) const {
// TODO(moshayedi): crbug.com/631527.
NOTIMPLEMENTED();
return false;
}
bool RemoteTextInputClient::GetSelectionRange(gfx::Range* range) const {
// TODO(moshayedi): crbug.com/631527.
NOTIMPLEMENTED();
return false;
}
bool RemoteTextInputClient::SetSelectionRange(const gfx::Range& range) {
// TODO(moshayedi): crbug.com/631527.
NOTIMPLEMENTED();
return false;
}
bool RemoteTextInputClient::DeleteRange(const gfx::Range& range) {
// TODO(moshayedi): crbug.com/631527.
NOTIMPLEMENTED();
return false;
}
bool RemoteTextInputClient::GetTextFromRange(const gfx::Range& range,
base::string16* text) const {
// TODO(moshayedi): crbug.com/631527.
NOTIMPLEMENTED();
return false;
}
void RemoteTextInputClient::OnInputMethodChanged() {
// TODO(moshayedi): crbug.com/631527.
NOTIMPLEMENTED();
}
bool RemoteTextInputClient::ChangeTextDirectionAndLayoutAlignment(
base::i18n::TextDirection direction) {
// TODO(moshayedi): crbug.com/631527.
NOTIMPLEMENTED();
return false;
}
void RemoteTextInputClient::ExtendSelectionAndDelete(size_t before,
size_t after) {
// TODO(moshayedi): crbug.com/631527.
NOTIMPLEMENTED();
}
void RemoteTextInputClient::EnsureCaretNotInRect(const gfx::Rect& rect) {
// TODO(moshayedi): crbug.com/631527.
NOTIMPLEMENTED();
}
bool RemoteTextInputClient::IsTextEditCommandEnabled(
ui::TextEditCommand command) const {
// TODO(moshayedi): crbug.com/631527.
NOTIMPLEMENTED();
return false;
}
void RemoteTextInputClient::SetTextEditCommandForNextKeyEvent(
ui::TextEditCommand command) {
// TODO(moshayedi): crbug.com/631527.
NOTIMPLEMENTED();
}
// Copyright 2016 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.
#ifndef CHROME_BROWSER_UI_VIEWS_IME_DRIVER_REMOTE_TEXT_INPUT_CLIENT_H_
#define CHROME_BROWSER_UI_VIEWS_IME_DRIVER_REMOTE_TEXT_INPUT_CLIENT_H_
#include "services/ui/public/interfaces/ime/ime.mojom.h"
#include "ui/base/ime/text_input_client.h"
// This implementation of ui::TextInputClient sends all updates via mojo IPC to
// a remote client. This is intended to be passed to the overrides of
// ui::InputMethod::SetFocusedTextInputClient().
class RemoteTextInputClient : public ui::TextInputClient {
public:
explicit RemoteTextInputClient(ui::mojom::TextInputClientPtr remote_client);
~RemoteTextInputClient() override;
private:
// ui::TextInputClient:
void SetCompositionText(const ui::CompositionText& composition) override;
void ConfirmCompositionText() override;
void ClearCompositionText() override;
void InsertText(const base::string16& text) override;
void InsertChar(const ui::KeyEvent& event) override;
ui::TextInputType GetTextInputType() const override;
ui::TextInputMode GetTextInputMode() const override;
base::i18n::TextDirection GetTextDirection() const override;
int GetTextInputFlags() const override;
bool CanComposeInline() const override;
gfx::Rect GetCaretBounds() const override;
bool GetCompositionCharacterBounds(uint32_t index,
gfx::Rect* rect) const override;
bool HasCompositionText() const override;
bool GetTextRange(gfx::Range* range) const override;
bool GetCompositionTextRange(gfx::Range* range) const override;
bool GetSelectionRange(gfx::Range* range) const override;
bool SetSelectionRange(const gfx::Range& range) override;
bool DeleteRange(const gfx::Range& range) override;
bool GetTextFromRange(const gfx::Range& range,
base::string16* text) const override;
void OnInputMethodChanged() override;
bool ChangeTextDirectionAndLayoutAlignment(
base::i18n::TextDirection direction) override;
void ExtendSelectionAndDelete(size_t before, size_t after) override;
void EnsureCaretNotInRect(const gfx::Rect& rect) override;
bool IsTextEditCommandEnabled(ui::TextEditCommand command) const override;
void SetTextEditCommandForNextKeyEvent(ui::TextEditCommand command) override;
ui::mojom::TextInputClientPtr remote_client_;
DISALLOW_COPY_AND_ASSIGN(RemoteTextInputClient);
};
#endif // CHROME_BROWSER_UI_VIEWS_IME_DRIVER_REMOTE_TEXT_INPUT_CLIENT_H_
// Copyright 2016 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 "chrome/browser/ui/views/ime_driver/simple_input_method.h"
SimpleInputMethod::SimpleInputMethod() {}
SimpleInputMethod::~SimpleInputMethod() {}
void SimpleInputMethod::OnTextInputModeChanged(
ui::mojom::TextInputMode text_input_mode) {}
void SimpleInputMethod::OnTextInputTypeChanged(
ui::mojom::TextInputType text_input_type) {}
void SimpleInputMethod::OnCaretBoundsChanged(const gfx::Rect& caret_bounds) {}
void SimpleInputMethod::ProcessKeyEvent(
std::unique_ptr<ui::Event> key_event,
const ProcessKeyEventCallback& callback) {
callback.Run(false);
}
void SimpleInputMethod::CancelComposition() {}
// Copyright 2016 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.
#ifndef CHROME_BROWSER_UI_VIEWS_IME_DRIVER_SIMPLE_INPUT_METHOD_H_
#define CHROME_BROWSER_UI_VIEWS_IME_DRIVER_SIMPLE_INPUT_METHOD_H_
#include "services/ui/public/interfaces/ime/ime.mojom.h"
// This is to be used on platforms where a proper implementation of
// ui::mojom::InputMethod is missing. It doesn't handle any events and calls
// the callback with false, which will result in client code handling events
// locally.
class SimpleInputMethod : public ui::mojom::InputMethod {
public:
SimpleInputMethod();
~SimpleInputMethod() override;
// ui::mojom::InputMethod:
void OnTextInputModeChanged(
ui::mojom::TextInputMode text_input_mode) override;
void OnTextInputTypeChanged(
ui::mojom::TextInputType text_input_type) override;
void OnCaretBoundsChanged(const gfx::Rect& caret_bounds) override;
void ProcessKeyEvent(std::unique_ptr<ui::Event> key_event,
const ProcessKeyEventCallback& callback) override;
void CancelComposition() override;
private:
DISALLOW_COPY_AND_ASSIGN(SimpleInputMethod);
};
#endif // CHROME_BROWSER_UI_VIEWS_IME_DRIVER_SIMPLE_INPUT_METHOD_H_
...@@ -4757,6 +4757,9 @@ test("unit_tests") { ...@@ -4757,6 +4757,9 @@ test("unit_tests") {
"../browser/ui/views/apps/app_info_dialog/app_info_permissions_panel_unittest.cc", "../browser/ui/views/apps/app_info_dialog/app_info_permissions_panel_unittest.cc",
"../browser/ui/views/website_settings/website_settings_popup_view_unittest.cc", "../browser/ui/views/website_settings/website_settings_popup_view_unittest.cc",
] ]
if (is_chromeos) {
sources += [ "../browser/ui/views/ime_driver/input_method_bridge_chromeos_unittest.cc" ]
}
if (!is_chromeos && (!is_mac || mac_views_browser)) { if (!is_chromeos && (!is_mac || mac_views_browser)) {
sources += [ sources += [
"../browser/ui/views/frame/opaque_browser_frame_view_layout_unittest.cc", "../browser/ui/views/frame/opaque_browser_frame_view_layout_unittest.cc",
......
...@@ -38,9 +38,7 @@ void TextInputClientImpl::InsertText(const std::string& text) { ...@@ -38,9 +38,7 @@ void TextInputClientImpl::InsertText(const std::string& text) {
void TextInputClientImpl::InsertChar(std::unique_ptr<ui::Event> event) { void TextInputClientImpl::InsertChar(std::unique_ptr<ui::Event> event) {
DCHECK(event->IsKeyEvent()); DCHECK(event->IsKeyEvent());
ui::KeyEvent* key_event = event->AsKeyEvent(); text_input_client_->InsertChar(*event->AsKeyEvent());
DCHECK(key_event->is_char());
text_input_client_->InsertChar(*key_event);
} }
} // namespace aura } // namespace aura
...@@ -57,34 +57,9 @@ InputMethodChromeOS::~InputMethodChromeOS() { ...@@ -57,34 +57,9 @@ InputMethodChromeOS::~InputMethodChromeOS() {
ui::IMEBridge::Get()->SetInputContextHandler(NULL); ui::IMEBridge::Get()->SetInputContextHandler(NULL);
} }
bool InputMethodChromeOS::OnUntranslatedIMEMessage( void InputMethodChromeOS::DispatchKeyEvent(
const base::NativeEvent& event, ui::KeyEvent* event,
NativeEventResult* result) { std::unique_ptr<AckCallback> ack_callback) {
return false;
}
void InputMethodChromeOS::ProcessKeyEventDone(ui::KeyEvent* event,
bool is_handled) {
DCHECK(event);
if (event->type() == ET_KEY_PRESSED) {
if (is_handled) {
// IME event has a priority to be handled, so that character composer
// should be reset.
character_composer_.Reset();
} else {
// If IME does not handle key event, passes keyevent to character composer
// to be able to compose complex characters.
is_handled = ExecuteCharacterComposer(*event);
}
}
if (event->type() == ET_KEY_PRESSED || event->type() == ET_KEY_RELEASED)
ProcessKeyEventPostIME(event, is_handled);
handling_key_event_ = false;
}
void InputMethodChromeOS::DispatchKeyEvent(ui::KeyEvent* event) {
DCHECK(event->IsKeyEvent()); DCHECK(event->IsKeyEvent());
DCHECK(!(event->flags() & ui::EF_IS_SYNTHESIZED)); DCHECK(!(event->flags() & ui::EF_IS_SYNTHESIZED));
...@@ -114,28 +89,68 @@ void InputMethodChromeOS::DispatchKeyEvent(ui::KeyEvent* event) { ...@@ -114,28 +89,68 @@ void InputMethodChromeOS::DispatchKeyEvent(ui::KeyEvent* event) {
// Treating as PostIME event if character composer handles key event and // Treating as PostIME event if character composer handles key event and
// generates some IME event, // generates some IME event,
ProcessKeyEventPostIME(event, true); ProcessKeyEventPostIME(event, true);
if (ack_callback)
ack_callback->Run(true);
return; return;
} }
ProcessUnfilteredKeyPressEvent(event); ProcessUnfilteredKeyPressEvent(event);
} else { } else {
ignore_result(DispatchKeyEventPostIME(event)); ignore_result(DispatchKeyEventPostIME(event));
} }
if (ack_callback)
ack_callback->Run(false);
return; return;
} }
handling_key_event_ = true; handling_key_event_ = true;
if (GetEngine()->IsInterestedInKeyEvent()) { if (GetEngine()->IsInterestedInKeyEvent()) {
ui::IMEEngineHandlerInterface::KeyEventDoneCallback callback = ui::IMEEngineHandlerInterface::KeyEventDoneCallback callback = base::Bind(
base::Bind(&InputMethodChromeOS::ProcessKeyEventDone, &InputMethodChromeOS::ProcessKeyEventDone,
weak_ptr_factory_.GetWeakPtr(), weak_ptr_factory_.GetWeakPtr(),
// Pass the ownership of the new copied event. // Pass the ownership of the new copied event.
base::Owned(new ui::KeyEvent(*event))); base::Owned(new ui::KeyEvent(*event)), Passed(&ack_callback));
GetEngine()->ProcessKeyEvent(*event, callback); GetEngine()->ProcessKeyEvent(*event, callback);
} else { } else {
ProcessKeyEventDone(event, false); ProcessKeyEventDone(event, std::move(ack_callback), false);
} }
} }
bool InputMethodChromeOS::OnUntranslatedIMEMessage(
const base::NativeEvent& event,
NativeEventResult* result) {
return false;
}
void InputMethodChromeOS::ProcessKeyEventDone(
ui::KeyEvent* event,
std::unique_ptr<AckCallback> ack_callback,
bool is_handled) {
DCHECK(event);
if (event->type() == ET_KEY_PRESSED) {
if (is_handled) {
// IME event has a priority to be handled, so that character composer
// should be reset.
character_composer_.Reset();
} else {
// If IME does not handle key event, passes keyevent to character composer
// to be able to compose complex characters.
is_handled = ExecuteCharacterComposer(*event);
}
}
if (ack_callback)
ack_callback->Run(is_handled);
if (event->type() == ET_KEY_PRESSED || event->type() == ET_KEY_RELEASED)
ProcessKeyEventPostIME(event, is_handled);
handling_key_event_ = false;
}
void InputMethodChromeOS::DispatchKeyEvent(ui::KeyEvent* event) {
DispatchKeyEvent(event, nullptr);
}
void InputMethodChromeOS::OnTextInputTypeChanged( void InputMethodChromeOS::OnTextInputTypeChanged(
const TextInputClient* client) { const TextInputClient* client) {
if (!IsTextInputClientFocused(client)) if (!IsTextInputClientFocused(client))
......
...@@ -27,6 +27,10 @@ class UI_BASE_IME_EXPORT InputMethodChromeOS : public InputMethodBase { ...@@ -27,6 +27,10 @@ class UI_BASE_IME_EXPORT InputMethodChromeOS : public InputMethodBase {
explicit InputMethodChromeOS(internal::InputMethodDelegate* delegate); explicit InputMethodChromeOS(internal::InputMethodDelegate* delegate);
~InputMethodChromeOS() override; ~InputMethodChromeOS() override;
using AckCallback = base::Callback<void(bool)>;
void DispatchKeyEvent(ui::KeyEvent* event,
std::unique_ptr<AckCallback> ack_callback);
// Overridden from InputMethod: // Overridden from InputMethod:
bool OnUntranslatedIMEMessage(const base::NativeEvent& event, bool OnUntranslatedIMEMessage(const base::NativeEvent& event,
NativeEventResult* result) override; NativeEventResult* result) override;
...@@ -100,7 +104,9 @@ class UI_BASE_IME_EXPORT InputMethodChromeOS : public InputMethodBase { ...@@ -100,7 +104,9 @@ class UI_BASE_IME_EXPORT InputMethodChromeOS : public InputMethodBase {
void HidePreeditText(); void HidePreeditText();
// Callback function for IMEEngineHandlerInterface::ProcessKeyEvent. // Callback function for IMEEngineHandlerInterface::ProcessKeyEvent.
void ProcessKeyEventDone(ui::KeyEvent* event, bool is_handled); void ProcessKeyEventDone(ui::KeyEvent* event,
std::unique_ptr<AckCallback> ack_callback,
bool is_handled);
// Returns whether an non-password input field is focused. // Returns whether an non-password input field is focused.
bool IsNonPasswordInputFieldFocused(); bool IsNonPasswordInputFieldFocused();
......
...@@ -38,9 +38,7 @@ void TextInputClientImpl::InsertText(const std::string& text) { ...@@ -38,9 +38,7 @@ void TextInputClientImpl::InsertText(const std::string& text) {
void TextInputClientImpl::InsertChar(std::unique_ptr<ui::Event> event) { void TextInputClientImpl::InsertChar(std::unique_ptr<ui::Event> event) {
DCHECK(event->IsKeyEvent()); DCHECK(event->IsKeyEvent());
ui::KeyEvent* key_event = event->AsKeyEvent(); text_input_client_->InsertChar(*event->AsKeyEvent());
DCHECK(key_event->is_char());
text_input_client_->InsertChar(*key_event);
} }
} // namespace views } // namespace views
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