Commit ecb602d3 authored by Darren Shen's avatar Darren Shen Committed by Commit Bot

ime: Handle replies from IME service.

The IME service shared library replies with text editing operations
like CommitText and SetComposition. These operations need to be
forwarded back to NativeInputMethodEngine so that they can be executed.

Change-Id: I18ee486fe012b7f69683b6b3250ff370c648f79e
Bug: b/161490915
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2422104
Commit-Queue: Darren Shen <shend@chromium.org>
Reviewed-by: default avatarMatthew Denton <mpdenton@chromium.org>
Cr-Commit-Position: refs/heads/master@{#823771}
parent 86837e75
...@@ -394,6 +394,42 @@ void NativeInputMethodEngine::ImeObserver::OnInputMethodOptionsChanged( ...@@ -394,6 +394,42 @@ void NativeInputMethodEngine::ImeObserver::OnInputMethodOptionsChanged(
base_observer_->OnInputMethodOptionsChanged(engine_id); base_observer_->OnInputMethodOptionsChanged(engine_id);
} }
void NativeInputMethodEngine::ImeObserver::CommitText(const std::string& text) {
GetInputContext()->CommitText(NormalizeString(text));
}
void NativeInputMethodEngine::ImeObserver::SetComposition(
const std::string& text) {
ui::CompositionText composition;
composition.text = base::UTF8ToUTF16(NormalizeString(text));
GetInputContext()->UpdateCompositionText(
composition, /*cursor_pos=*/composition.text.length(), /*visible=*/true);
}
void NativeInputMethodEngine::ImeObserver::SetCompositionRange(
uint32_t start_byte_index,
uint32_t end_byte_index) {
const auto ordered_range = std::minmax(start_byte_index, end_byte_index);
GetInputContext()->SetComposingRange(
ordered_range.first, ordered_range.second,
{ui::ImeTextSpan(
ui::ImeTextSpan::Type::kComposition, /*start_offset=*/0,
/*end_offset=*/ordered_range.second - ordered_range.first)});
}
void NativeInputMethodEngine::ImeObserver::FinishComposition() {
GetInputContext()->ConfirmCompositionText(/*reset_engine=*/false,
/*keep_selection=*/true);
}
void NativeInputMethodEngine::ImeObserver::DeleteSurroundingText(
uint32_t num_bytes_before_cursor,
uint32_t num_bytes_after_cursor) {
GetInputContext()->DeleteSurroundingText(
/*offset=*/-static_cast<int>(num_bytes_before_cursor),
/*length=*/num_bytes_before_cursor + num_bytes_after_cursor);
}
void NativeInputMethodEngine::ImeObserver::FlushForTesting() { void NativeInputMethodEngine::ImeObserver::FlushForTesting() {
remote_manager_.FlushForTesting(); remote_manager_.FlushForTesting();
if (remote_to_engine_.is_bound()) if (remote_to_engine_.is_bound())
......
...@@ -115,6 +115,12 @@ class NativeInputMethodEngine : public InputMethodEngine { ...@@ -115,6 +115,12 @@ class NativeInputMethodEngine : public InputMethodEngine {
void ResetForRulebased() override {} void ResetForRulebased() override {}
void GetRulebasedKeypressCountForTesting( void GetRulebasedKeypressCountForTesting(
GetRulebasedKeypressCountForTestingCallback callback) override {} GetRulebasedKeypressCountForTestingCallback callback) override {}
void CommitText(const std::string& text) override;
void SetComposition(const std::string& text) override;
void SetCompositionRange(uint32_t start_byte_index,
uint32_t end_byte_index) override;
void FinishComposition() override;
void DeleteSurroundingText(uint32_t before, uint32_t after) override;
// Flush all relevant Mojo pipes. // Flush all relevant Mojo pipes.
void FlushForTesting(); void FlushForTesting();
......
...@@ -100,5 +100,7 @@ source_set("services_unittests") { ...@@ -100,5 +100,7 @@ source_set("services_unittests") {
"decoder/proto_conversion_unittest.cc", "decoder/proto_conversion_unittest.cc",
"decoder/system_engine_unittest.cc", "decoder/system_engine_unittest.cc",
"ime_service_unittest.cc", "ime_service_unittest.cc",
"mock_input_channel.cc",
"mock_input_channel.h",
] ]
} }
...@@ -21,7 +21,8 @@ namespace { ...@@ -21,7 +21,8 @@ namespace {
ImeEngineMainEntry* g_fake_main_entry_for_testing = nullptr; ImeEngineMainEntry* g_fake_main_entry_for_testing = nullptr;
using ReplyCallback = using ReplyCallback =
base::RepeatingCallback<void(const std::vector<uint8_t>&)>; base::RepeatingCallback<void(const std::vector<uint8_t>&,
mojo::Remote<mojom::InputChannel>& remote)>;
// A client delegate passed to the shared library in order for the // A client delegate passed to the shared library in order for the
// shared library to send replies back to the engine. // shared library to send replies back to the engine.
...@@ -47,7 +48,7 @@ class ClientDelegate : public ImeClientDelegate { ...@@ -47,7 +48,7 @@ class ClientDelegate : public ImeClientDelegate {
if (client_remote_ && client_remote_.is_bound()) { if (client_remote_ && client_remote_.is_bound()) {
std::vector<uint8_t> msg(data, data + size); std::vector<uint8_t> msg(data, data + size);
client_remote_->ProcessMessage(msg, base::DoNothing()); client_remote_->ProcessMessage(msg, base::DoNothing());
callback_.Run(msg); callback_.Run(msg, client_remote_);
} }
} }
...@@ -206,7 +207,8 @@ void SystemEngine::ProcessMessage(const std::vector<uint8_t>& message, ...@@ -206,7 +207,8 @@ void SystemEngine::ProcessMessage(const std::vector<uint8_t>& message,
std::move(callback).Run(result); std::move(callback).Run(result);
} }
void SystemEngine::OnReply(const std::vector<uint8_t>& message) { void SystemEngine::OnReply(const std::vector<uint8_t>& message,
mojo::Remote<mojom::InputChannel>& remote) {
ime::Wrapper wrapper; ime::Wrapper wrapper;
if (!wrapper.ParseFromArray(message.data(), message.size()) || if (!wrapper.ParseFromArray(message.data(), message.size()) ||
!wrapper.has_public_message()) { !wrapper.has_public_message()) {
...@@ -223,6 +225,30 @@ void SystemEngine::OnReply(const std::vector<uint8_t>& message) { ...@@ -223,6 +225,30 @@ void SystemEngine::OnReply(const std::vector<uint8_t>& message) {
pending_key_event_callbacks_.erase(it); pending_key_event_callbacks_.erase(it);
break; break;
} }
case ime::PublicMessage::kSetComposition: {
remote->SetComposition(reply.set_composition().text());
break;
}
case ime::PublicMessage::kSetCompositionRange: {
remote->SetCompositionRange(
reply.set_composition_range().start_byte_index(),
reply.set_composition_range().end_byte_index());
break;
}
case ime::PublicMessage::kFinishComposition: {
remote->FinishComposition();
break;
}
case ime::PublicMessage::kDeleteSurroundingText: {
remote->DeleteSurroundingText(
reply.delete_surrounding_text().num_bytes_before_cursor(),
reply.delete_surrounding_text().num_bytes_after_cursor());
break;
}
case ime::PublicMessage::kCommitText: {
remote->CommitText(reply.commit_text().text());
break;
}
default: default:
NOTREACHED(); NOTREACHED();
break; break;
......
...@@ -54,7 +54,8 @@ class SystemEngine : public InputEngine { ...@@ -54,7 +54,8 @@ class SystemEngine : public InputEngine {
// Called when there's a reply from the shared library. // Called when there's a reply from the shared library.
// Deserializes |message| and converts it into Mojo calls to the receiver. // Deserializes |message| and converts it into Mojo calls to the receiver.
void OnReply(const std::vector<uint8_t>& message); void OnReply(const std::vector<uint8_t>& message,
mojo::Remote<mojom::InputChannel>& remote);
// Shared library handle of the implementation for input logic with decoders. // Shared library handle of the implementation for input logic with decoders.
base::ScopedNativeLibrary library_; base::ScopedNativeLibrary library_;
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include "base/bind.h" #include "base/bind.h"
#include "base/strings/utf_string_conversions.h" #include "base/strings/utf_string_conversions.h"
#include "base/test/task_environment.h" #include "base/test/task_environment.h"
#include "chromeos/services/ime/mock_input_channel.h"
#include "chromeos/services/ime/public/mojom/input_engine.mojom.h" #include "chromeos/services/ime/public/mojom/input_engine.mojom.h"
#include "mojo/public/cpp/bindings/pending_receiver.h" #include "mojo/public/cpp/bindings/pending_receiver.h"
#include "mojo/public/cpp/bindings/pending_remote.h" #include "mojo/public/cpp/bindings/pending_remote.h"
...@@ -43,42 +44,6 @@ void TestGetRulebasedKeypressCountForTestingCallback(int32_t* res_out, ...@@ -43,42 +44,6 @@ void TestGetRulebasedKeypressCountForTestingCallback(int32_t* res_out,
*res_out = response; *res_out = response;
} }
class TestClientChannel : mojom::InputChannel {
public:
TestClientChannel() : receiver_(this) {}
mojo::PendingRemote<mojom::InputChannel> CreatePendingRemote() {
return receiver_.BindNewPipeAndPassRemote();
}
// mojom::InputChannel implementation.
MOCK_METHOD2(ProcessMessage,
void(const std::vector<uint8_t>& message,
ProcessMessageCallback));
MOCK_METHOD1(OnInputMethodChanged, void(const std::string& engine_id));
MOCK_METHOD1(OnFocus, void(mojom::InputFieldInfoPtr input_field_info));
MOCK_METHOD0(OnBlur, void());
MOCK_METHOD2(ProcessKeypressForRulebased,
void(const mojom::PhysicalKeyEventPtr event,
ProcessKeypressForRulebasedCallback));
MOCK_METHOD2(OnKeyEvent,
void(const mojom::PhysicalKeyEventPtr event,
OnKeyEventCallback));
MOCK_METHOD3(OnSurroundingTextChanged,
void(const std::string& text,
uint32_t offset,
mojom::SelectionRangePtr selection_range));
MOCK_METHOD0(OnCompositionCanceled, void());
MOCK_METHOD0(ResetForRulebased, void());
MOCK_METHOD1(GetRulebasedKeypressCountForTesting,
void(GetRulebasedKeypressCountForTestingCallback));
private:
mojo::Receiver<mojom::InputChannel> receiver_;
DISALLOW_COPY_AND_ASSIGN(TestClientChannel);
};
class ImeServiceTest : public testing::Test { class ImeServiceTest : public testing::Test {
public: public:
ImeServiceTest() : service_(remote_service_.BindNewPipeAndPassReceiver()) {} ImeServiceTest() : service_(remote_service_.BindNewPipeAndPassReceiver()) {}
...@@ -109,7 +74,7 @@ class ImeServiceTest : public testing::Test { ...@@ -109,7 +74,7 @@ class ImeServiceTest : public testing::Test {
// activating an IME engine with an invalid IME spec. // activating an IME engine with an invalid IME spec.
TEST_F(ImeServiceTest, ConnectInvalidImeEngine) { TEST_F(ImeServiceTest, ConnectInvalidImeEngine) {
bool success = true; bool success = true;
TestClientChannel test_channel; MockInputChannel test_channel;
mojo::Remote<mojom::InputChannel> remote_engine; mojo::Remote<mojom::InputChannel> remote_engine;
remote_manager_->ConnectToImeEngine( remote_manager_->ConnectToImeEngine(
...@@ -122,8 +87,8 @@ TEST_F(ImeServiceTest, ConnectInvalidImeEngine) { ...@@ -122,8 +87,8 @@ TEST_F(ImeServiceTest, ConnectInvalidImeEngine) {
TEST_F(ImeServiceTest, MultipleClientsRulebased) { TEST_F(ImeServiceTest, MultipleClientsRulebased) {
bool success = false; bool success = false;
TestClientChannel test_channel_1; MockInputChannel test_channel_1;
TestClientChannel test_channel_2; MockInputChannel test_channel_2;
mojo::Remote<mojom::InputChannel> remote_engine_1; mojo::Remote<mojom::InputChannel> remote_engine_1;
mojo::Remote<mojom::InputChannel> remote_engine_2; mojo::Remote<mojom::InputChannel> remote_engine_2;
...@@ -166,7 +131,7 @@ TEST_F(ImeServiceTest, MultipleClientsRulebased) { ...@@ -166,7 +131,7 @@ TEST_F(ImeServiceTest, MultipleClientsRulebased) {
TEST_F(ImeServiceTest, RuleBasedDoesNotHandleModifierKeys) { TEST_F(ImeServiceTest, RuleBasedDoesNotHandleModifierKeys) {
bool success = false; bool success = false;
TestClientChannel test_channel; MockInputChannel test_channel;
mojo::Remote<mojom::InputChannel> to_engine_remote; mojo::Remote<mojom::InputChannel> to_engine_remote;
remote_manager_->ConnectToImeEngine( remote_manager_->ConnectToImeEngine(
...@@ -196,7 +161,7 @@ TEST_F(ImeServiceTest, RuleBasedDoesNotHandleModifierKeys) { ...@@ -196,7 +161,7 @@ TEST_F(ImeServiceTest, RuleBasedDoesNotHandleModifierKeys) {
TEST_F(ImeServiceTest, RuleBasedDoesNotHandleCtrlShortCut) { TEST_F(ImeServiceTest, RuleBasedDoesNotHandleCtrlShortCut) {
bool success = false; bool success = false;
TestClientChannel test_channel; MockInputChannel test_channel;
mojo::Remote<mojom::InputChannel> to_engine_remote; mojo::Remote<mojom::InputChannel> to_engine_remote;
remote_manager_->ConnectToImeEngine( remote_manager_->ConnectToImeEngine(
...@@ -226,7 +191,7 @@ TEST_F(ImeServiceTest, RuleBasedDoesNotHandleCtrlShortCut) { ...@@ -226,7 +191,7 @@ TEST_F(ImeServiceTest, RuleBasedDoesNotHandleCtrlShortCut) {
TEST_F(ImeServiceTest, RuleBasedDoesNotHandleAltShortCut) { TEST_F(ImeServiceTest, RuleBasedDoesNotHandleAltShortCut) {
bool success = false; bool success = false;
TestClientChannel test_channel; MockInputChannel test_channel;
mojo::Remote<mojom::InputChannel> to_engine_remote; mojo::Remote<mojom::InputChannel> to_engine_remote;
remote_manager_->ConnectToImeEngine( remote_manager_->ConnectToImeEngine(
...@@ -256,7 +221,7 @@ TEST_F(ImeServiceTest, RuleBasedDoesNotHandleAltShortCut) { ...@@ -256,7 +221,7 @@ TEST_F(ImeServiceTest, RuleBasedDoesNotHandleAltShortCut) {
TEST_F(ImeServiceTest, RuleBasedHandlesAltRight) { TEST_F(ImeServiceTest, RuleBasedHandlesAltRight) {
bool success = false; bool success = false;
TestClientChannel test_channel; MockInputChannel test_channel;
mojo::Remote<mojom::InputChannel> to_engine_remote; mojo::Remote<mojom::InputChannel> to_engine_remote;
remote_manager_->ConnectToImeEngine( remote_manager_->ConnectToImeEngine(
...@@ -287,7 +252,7 @@ TEST_F(ImeServiceTest, RuleBasedHandlesAltRight) { ...@@ -287,7 +252,7 @@ TEST_F(ImeServiceTest, RuleBasedHandlesAltRight) {
// Tests that the rule-based Arabic keyboard can work correctly. // Tests that the rule-based Arabic keyboard can work correctly.
TEST_F(ImeServiceTest, RuleBasedArabic) { TEST_F(ImeServiceTest, RuleBasedArabic) {
bool success = false; bool success = false;
TestClientChannel test_channel; MockInputChannel test_channel;
mojo::Remote<mojom::InputChannel> to_engine_remote; mojo::Remote<mojom::InputChannel> to_engine_remote;
remote_manager_->ConnectToImeEngine( remote_manager_->ConnectToImeEngine(
...@@ -358,7 +323,7 @@ TEST_F(ImeServiceTest, RuleBasedArabic) { ...@@ -358,7 +323,7 @@ TEST_F(ImeServiceTest, RuleBasedArabic) {
// Tests that the rule-based DevaPhone keyboard can work correctly. // Tests that the rule-based DevaPhone keyboard can work correctly.
TEST_F(ImeServiceTest, RuleBasedDevaPhone) { TEST_F(ImeServiceTest, RuleBasedDevaPhone) {
bool success = false; bool success = false;
TestClientChannel test_channel; MockInputChannel test_channel;
mojo::Remote<mojom::InputChannel> to_engine_remote; mojo::Remote<mojom::InputChannel> to_engine_remote;
remote_manager_->ConnectToImeEngine( remote_manager_->ConnectToImeEngine(
...@@ -436,7 +401,7 @@ TEST_F(ImeServiceTest, RuleBasedDevaPhone) { ...@@ -436,7 +401,7 @@ TEST_F(ImeServiceTest, RuleBasedDevaPhone) {
// Tests escapable characters. See https://crbug.com/1014384. // Tests escapable characters. See https://crbug.com/1014384.
TEST_F(ImeServiceTest, RuleBasedDoesNotEscapeCharacters) { TEST_F(ImeServiceTest, RuleBasedDoesNotEscapeCharacters) {
bool success = false; bool success = false;
TestClientChannel test_channel; MockInputChannel test_channel;
mojo::Remote<mojom::InputChannel> to_engine_remote; mojo::Remote<mojom::InputChannel> to_engine_remote;
remote_manager_->ConnectToImeEngine( remote_manager_->ConnectToImeEngine(
...@@ -494,7 +459,7 @@ TEST_F(ImeServiceTest, RuleBasedDoesNotEscapeCharacters) { ...@@ -494,7 +459,7 @@ TEST_F(ImeServiceTest, RuleBasedDoesNotEscapeCharacters) {
// Tests that AltGr works with rule-based. See crbug.com/1035145. // Tests that AltGr works with rule-based. See crbug.com/1035145.
TEST_F(ImeServiceTest, KhmerKeyboardAltGr) { TEST_F(ImeServiceTest, KhmerKeyboardAltGr) {
bool success = false; bool success = false;
TestClientChannel test_channel; MockInputChannel test_channel;
mojo::Remote<mojom::InputChannel> to_engine_remote; mojo::Remote<mojom::InputChannel> to_engine_remote;
remote_manager_->ConnectToImeEngine( remote_manager_->ConnectToImeEngine(
......
...@@ -195,5 +195,26 @@ void InputEngine::GetRulebasedKeypressCountForTesting( ...@@ -195,5 +195,26 @@ void InputEngine::GetRulebasedKeypressCountForTesting(
std::move(callback).Run(engine ? engine->process_key_count() : -1); std::move(callback).Run(engine ? engine->process_key_count() : -1);
} }
void InputEngine::CommitText(const std::string& text) {
NOTIMPLEMENTED(); // Not used in the rulebased engine.
}
void InputEngine::SetComposition(const std::string& text) {
NOTIMPLEMENTED(); // Not used in the rulebased engine.
}
void InputEngine::SetCompositionRange(uint32_t start, uint32_t end) {
NOTIMPLEMENTED(); // Not used in the rulebased engine.
}
void InputEngine::FinishComposition() {
NOTIMPLEMENTED(); // Not used in the rulebased engine.
}
void InputEngine::DeleteSurroundingText(uint32_t num_bytes_before_cursor,
uint32_t num_bytes_after_cursor) {
NOTIMPLEMENTED(); // Not used in the rulebased engine.
}
} // namespace ime } // namespace ime
} // namespace chromeos } // namespace chromeos
...@@ -62,6 +62,13 @@ class InputEngine : public mojom::InputChannel { ...@@ -62,6 +62,13 @@ class InputEngine : public mojom::InputChannel {
void ResetForRulebased() override; void ResetForRulebased() override;
void GetRulebasedKeypressCountForTesting( void GetRulebasedKeypressCountForTesting(
GetRulebasedKeypressCountForTestingCallback callback) override; GetRulebasedKeypressCountForTestingCallback callback) override;
void CommitText(const std::string& text) override;
void SetComposition(const std::string& text) override;
void SetCompositionRange(uint32_t start_byte_index,
uint32_t end_byte_index) override;
void FinishComposition() override;
void DeleteSurroundingText(uint32_t num_bytes_before_cursor,
uint32_t num_bytes_after_cursor) override;
// TODO(https://crbug.com/837156): Implement a state for the interface. // TODO(https://crbug.com/837156): Implement a state for the interface.
......
// 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 "chromeos/services/ime/mock_input_channel.h"
namespace chromeos {
namespace ime {
MockInputChannel::MockInputChannel() : receiver_(this) {}
MockInputChannel::~MockInputChannel() = default;
mojo::PendingRemote<mojom::InputChannel>
MockInputChannel::CreatePendingRemote() {
return receiver_.BindNewPipeAndPassRemote();
}
bool MockInputChannel::IsBound() const {
return receiver_.is_bound();
}
void MockInputChannel::FlushForTesting() {
return receiver_.FlushForTesting();
}
} // namespace ime
} // namespace chromeos
// 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.
#ifndef CHROMEOS_SERVICES_IME_MOCK_INPUT_CHANNEL_H_
#define CHROMEOS_SERVICES_IME_MOCK_INPUT_CHANNEL_H_
#include "chromeos/services/ime/public/mojom/input_engine.mojom.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "mojo/public/cpp/bindings/receiver.h"
#include "testing/gmock/include/gmock/gmock.h"
namespace chromeos {
namespace ime {
// A mock receiver InputChannel.
class MockInputChannel : public mojom::InputChannel {
public:
MockInputChannel();
~MockInputChannel();
MockInputChannel(const MockInputChannel&) = delete;
MockInputChannel& operator=(const MockInputChannel&) = delete;
mojo::PendingRemote<mojom::InputChannel> CreatePendingRemote();
bool IsBound() const;
void FlushForTesting();
// mojom::InputChannel:
void ProcessMessage(const std::vector<uint8_t>& message,
ProcessMessageCallback callback) override {
std::move(callback).Run({});
}
MOCK_METHOD(void,
OnInputMethodChanged,
(const std::string& engine_id),
(override));
MOCK_METHOD(void,
OnFocus,
(mojom::InputFieldInfoPtr input_field_info),
(override));
MOCK_METHOD(void, OnBlur, (), (override));
MOCK_METHOD(void,
ProcessKeypressForRulebased,
(const mojom::PhysicalKeyEventPtr event,
ProcessKeypressForRulebasedCallback),
(override));
MOCK_METHOD(void,
OnKeyEvent,
(const mojom::PhysicalKeyEventPtr event, OnKeyEventCallback),
(override));
MOCK_METHOD(void,
OnSurroundingTextChanged,
(const std::string& text,
uint32_t offset,
mojom::SelectionRangePtr selection_range),
(override));
MOCK_METHOD(void, OnCompositionCanceled, (), (override));
MOCK_METHOD(void, ResetForRulebased, (), (override));
MOCK_METHOD(void,
GetRulebasedKeypressCountForTesting,
(GetRulebasedKeypressCountForTestingCallback),
(override));
MOCK_METHOD(void, CommitText, (const std::string& text), (override));
MOCK_METHOD(void, SetComposition, (const std::string& text), (override));
MOCK_METHOD(void,
SetCompositionRange,
(uint32_t start_byte_index, uint32_t end_byte_index),
(override));
MOCK_METHOD(void, FinishComposition, (), (override));
MOCK_METHOD(void,
DeleteSurroundingText,
(uint32_t num_bytes_before_cursor,
uint32_t num_bytes_after_cursor),
(override));
private:
mojo::Receiver<mojom::InputChannel> receiver_;
};
} // namespace ime
} // namespace chromeos
#endif // CHROMEOS_SERVICES_IME_MOCK_INPUT_CHANNEL_H_
...@@ -159,6 +159,8 @@ interface InputEngineManager { ...@@ -159,6 +159,8 @@ interface InputEngineManager {
// In order to encapsulate all the communication, (e.g. access to some // In order to encapsulate all the communication, (e.g. access to some
// closed-sourced input engine with decoders), implement the method that takes // closed-sourced input engine with decoders), implement the method that takes
// a serialized protobuf message (instead of a plaintext) as its argument. // a serialized protobuf message (instead of a plaintext) as its argument.
// TODO(crbug.com/1145326): Split this into two separate APIs for the sending or
// receiving end.
interface InputChannel { interface InputChannel {
// Returns a serialized protobuf result after processing a serialized // Returns a serialized protobuf result after processing a serialized
// protobuf message. // protobuf message.
...@@ -205,6 +207,42 @@ interface InputChannel { ...@@ -205,6 +207,42 @@ interface InputChannel {
// Gets the keypress count for rulebased logic. // Gets the keypress count for rulebased logic.
GetRulebasedKeypressCountForTesting() => (int32 count); GetRulebasedKeypressCountForTesting() => (int32 count);
// Asks the input field to commit `text`. If there is a composition, then that
// composition is removed and `text` is inserted. Otherwise, `text` is
// inserted at the current cursor position, deleting any text in the current
// selection if any. In both cases, the cursor moves to the end of `text`.
CommitText(string text);
// Asks the input field to set composition with `text`. Replaces the current
// composition if there is one. Otherwise, start a composition at the current
// cursor position, deleting any text in the current selection if any.
// The cursor is moved to the end of |text|.
SetComposition(string text);
// Asks the input field to mark the range of text spanned by
// `start_byte_index` and `end_byte_index` as the current composition,
// where index 0 indicates the beginning of the input field contents.
// If there was already a composition, then that composition is committed
// first, as if FinishComposition was called.
// The order of `start_byte_index` and `end_byte_index` does not matter.
// If both `start_byte_index` and `end_byte_index` are the same, then this i
// the same as calling `FinishComposition`.
// The composition range does not have to overlap with the cursor selection.
// The cursor position remains unchanged.
SetCompositionRange(uint32 start_byte_index, uint32 end_byte_index);
// Asks the input field to commit the current composition text. If there is
// composition, this is equivalent to calling `CommitText` with the
// composition text. If there is no current composition then this is a no-op.
// The cursor position remains unchanged.
FinishComposition();
// Asks the input field to delete text around the cursor.
// This operation fails if there is currently a composition.
// TODO(b/161490915): Determine the right behaviour when there is a selection.
DeleteSurroundingText(uint32 num_bytes_before_cursor,
uint32 num_bytes_after_cursor);
}; };
// Implemented in the browser process, used to perform network requests or // Implemented in the browser process, used to perform network requests or
......
...@@ -34,6 +34,11 @@ message PublicMessage { ...@@ -34,6 +34,11 @@ message PublicMessage {
OnBlur on_blur = 6; OnBlur on_blur = 6;
OnCompositionCanceled on_composition_canceled = 7; OnCompositionCanceled on_composition_canceled = 7;
OnInputMethodChanged on_input_method_changed = 8; OnInputMethodChanged on_input_method_changed = 8;
CommitText commit_text = 9;
SetComposition set_composition = 10;
SetCompositionRange set_composition_range = 11;
FinishComposition finish_composition = 12;
DeleteSurroundingText delete_surrounding_text = 13;
} }
} }
...@@ -141,3 +146,33 @@ message OnSurroundingTextChanged { ...@@ -141,3 +146,33 @@ message OnSurroundingTextChanged {
// Protobuf version of InputEngine::OnCompositionCanceled in // Protobuf version of InputEngine::OnCompositionCanceled in
// chromeos/services/ime/public/mojom/input_engine.mojom // chromeos/services/ime/public/mojom/input_engine.mojom
message OnCompositionCanceled {} message OnCompositionCanceled {}
// Protobuf version of InputEngine::CommitText in
// chromeos/services/ime/public/mojom/input_engine.mojom
message CommitText {
optional string text = 1;
}
// Protobuf version of InputEngine::SetComposition in
// chromeos/services/ime/public/mojom/input_engine.mojom
message SetComposition {
optional string text = 1;
}
// Protobuf version of InputEngine::SetCompositionRange in
// chromeos/services/ime/public/mojom/input_engine.mojom
message SetCompositionRange {
optional uint32 start_byte_index = 1;
optional uint32 end_byte_index = 2;
}
// Protobuf version of InputEngine::FinishComposition in
// chromeos/services/ime/public/mojom/input_engine.mojom
message FinishComposition {}
// Protobuf version of InputEngine::DeleteSurroundingText in
// chromeos/services/ime/public/mojom/input_engine.mojom
message DeleteSurroundingText {
optional uint32 num_bytes_before_cursor = 1;
optional uint32 num_bytes_after_cursor = 2;
}
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