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

ime: Send surrounding text changes to IME service.

Add Mojo and protobuf messages for Chrome to send surrounding text
changes to the IME service.

Change-Id: I0ff2fdb302c884be2ff9640d7990bdfcba8d87ca
Bug: b/161490915
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2422021Reviewed-by: default avatarKeith Lee <keithlee@chromium.org>
Reviewed-by: default avatarAlex Gough <ajgo@chromium.org>
Commit-Queue: Darren Shen <shend@chromium.org>
Cr-Commit-Position: refs/heads/master@{#820065}
parent 2f034b9f
...@@ -253,6 +253,13 @@ void NativeInputMethodEngine::ImeObserver::OnSurroundingTextChanged( ...@@ -253,6 +253,13 @@ void NativeInputMethodEngine::ImeObserver::OnSurroundingTextChanged(
assistive_suggester_->OnSurroundingTextChanged(text, cursor_pos, assistive_suggester_->OnSurroundingTextChanged(text, cursor_pos,
anchor_pos); anchor_pos);
} }
if (ShouldUseFstMojoEngine(engine_id) && remote_to_engine_.is_bound()) {
auto selection = ime::mojom::SelectionRange::New();
selection->anchor = anchor_pos;
selection->focus = cursor_pos;
remote_to_engine_->OnSurroundingTextChanged(
base::UTF16ToUTF8(text), offset_pos, std::move(selection));
}
base_observer_->OnSurroundingTextChanged(engine_id, text, cursor_pos, base_observer_->OnSurroundingTextChanged(engine_id, text, cursor_pos,
anchor_pos, offset_pos); anchor_pos, offset_pos);
} }
......
...@@ -93,6 +93,10 @@ class NativeInputMethodEngine : public InputMethodEngine { ...@@ -93,6 +93,10 @@ class NativeInputMethodEngine : public InputMethodEngine {
void ProcessMessage(const std::vector<uint8_t>& message, void ProcessMessage(const std::vector<uint8_t>& message,
ProcessMessageCallback callback) override; ProcessMessageCallback callback) override;
void OnFocus() override {} void OnFocus() override {}
void OnSurroundingTextChanged(
const std::string& text,
uint32_t offset,
ime::mojom::SelectionRangePtr selection_range) override {}
void ProcessKeypressForRulebased( void ProcessKeypressForRulebased(
ime::mojom::PhysicalKeyEventPtr event, ime::mojom::PhysicalKeyEventPtr event,
ProcessKeypressForRulebasedCallback callback) override {} ProcessKeypressForRulebasedCallback callback) override {}
......
...@@ -156,6 +156,18 @@ void DecoderEngine::OnKeyEvent(mojom::PhysicalKeyEventPtr event, ...@@ -156,6 +156,18 @@ void DecoderEngine::OnKeyEvent(mojom::PhysicalKeyEventPtr event,
base::DoNothing()); base::DoNothing());
} }
void DecoderEngine::OnSurroundingTextChanged(
const std::string& text,
uint32_t offset,
mojom::SelectionRangePtr selection_range) {
const uint64_t seq_id = current_seq_id_;
++current_seq_id_;
ProcessMessage(WrapAndSerializeMessage(OnSurroundingTextChangedToProto(
seq_id, text, offset, std::move(selection_range))),
base::DoNothing());
}
void DecoderEngine::ProcessMessage(const std::vector<uint8_t>& message, void DecoderEngine::ProcessMessage(const std::vector<uint8_t>& message,
ProcessMessageCallback callback) { ProcessMessageCallback callback) {
// TODO(https://crbug.com/837156): Set a default protobuf message. // TODO(https://crbug.com/837156): Set a default protobuf message.
......
...@@ -35,6 +35,10 @@ class DecoderEngine : public InputEngine { ...@@ -35,6 +35,10 @@ class DecoderEngine : public InputEngine {
void OnFocus() override; void OnFocus() override;
void OnKeyEvent(mojom::PhysicalKeyEventPtr event, void OnKeyEvent(mojom::PhysicalKeyEventPtr event,
OnKeyEventCallback callback) override; OnKeyEventCallback callback) override;
void OnSurroundingTextChanged(
const std::string& text,
uint32_t offset,
mojom::SelectionRangePtr selection_range) override;
private: private:
// Try to load the decoding functions from some decoder shared library. // Try to load the decoding functions from some decoder shared library.
......
...@@ -57,6 +57,10 @@ class StubInputChannel : public mojom::InputChannel { ...@@ -57,6 +57,10 @@ class StubInputChannel : public mojom::InputChannel {
ProcessKeypressForRulebasedCallback callback) final {} ProcessKeypressForRulebasedCallback callback) final {}
void OnKeyEvent(ime::mojom::PhysicalKeyEventPtr event, void OnKeyEvent(ime::mojom::PhysicalKeyEventPtr event,
OnKeyEventCallback callback) final {} OnKeyEventCallback callback) final {}
void OnSurroundingTextChanged(
const std::string& text,
uint32_t offset,
ime::mojom::SelectionRangePtr selection_range) final {}
void ResetForRulebased() final {} void ResetForRulebased() final {}
void GetRulebasedKeypressCountForTesting( void GetRulebasedKeypressCountForTesting(
GetRulebasedKeypressCountForTestingCallback callback) final {} GetRulebasedKeypressCountForTestingCallback callback) final {}
...@@ -141,5 +145,23 @@ TEST_F(DecoderEngineTest, OnKeyEventRepliesWithCallback) { ...@@ -141,5 +145,23 @@ TEST_F(DecoderEngineTest, OnKeyEventRepliesWithCallback) {
EXPECT_TRUE(consumed_by_test); EXPECT_TRUE(consumed_by_test);
} }
TEST_F(DecoderEngineTest, OnSurroundingTextChangedSendsMessageToSharedLib) {
DecoderEngine engine(/*platform=*/nullptr);
StubInputChannel stub_channel;
mojo::Receiver<mojom::InputChannel> receiver(&stub_channel);
mojo::Remote<mojom::InputChannel> client;
ASSERT_TRUE(engine.BindRequest(kImeSpec, client.BindNewPipeAndPassReceiver(),
receiver.BindNewPipeAndPassRemote(), {}));
const auto selection = mojom::SelectionRange::New(/*anchor=*/3, /*focus=*/2);
ime::Wrapper expected_proto;
*expected_proto.mutable_public_message() = OnSurroundingTextChangedToProto(
/*seq_id=*/0, "hello", /*offset=*/1, selection->Clone());
EXPECT_CALL(mock_main_entry_, Process).With(EqualsProto(expected_proto));
client->OnSurroundingTextChanged("hello", /*offset=*/1, selection->Clone());
client.FlushForTesting();
}
} // namespace ime } // namespace ime
} // namespace chromeos } // namespace chromeos
...@@ -46,5 +46,23 @@ ime::PublicMessage OnKeyEventToProto(uint64_t seq_id, ...@@ -46,5 +46,23 @@ ime::PublicMessage OnKeyEventToProto(uint64_t seq_id,
return message; return message;
} }
ime::PublicMessage OnSurroundingTextChangedToProto(
uint64_t seq_id,
const std::string& text,
uint32_t offset,
mojom::SelectionRangePtr selection_range) {
ime::PublicMessage message;
message.set_seq_id(seq_id);
ime::OnSurroundingTextChanged& params =
*message.mutable_on_surrounding_text_changed();
params.set_text(text);
params.set_offset(offset);
params.mutable_selection_range()->set_anchor(selection_range->anchor);
params.mutable_selection_range()->set_focus(selection_range->focus);
return message;
}
} // namespace ime } // namespace ime
} // namespace chromeos } // namespace chromeos
...@@ -20,6 +20,14 @@ ime::PublicMessage OnFocusToProto(uint64_t seq_id); ...@@ -20,6 +20,14 @@ ime::PublicMessage OnFocusToProto(uint64_t seq_id);
ime::PublicMessage OnKeyEventToProto(uint64_t seq_id, ime::PublicMessage OnKeyEventToProto(uint64_t seq_id,
mojom::PhysicalKeyEventPtr event); mojom::PhysicalKeyEventPtr event);
// Converts arguments of a Mojo call to InputChannel::OnSurroundingTextChanged
// into a proto.
ime::PublicMessage OnSurroundingTextChangedToProto(
uint64_t seq_id,
const std::string& text,
uint32_t focus,
mojom::SelectionRangePtr selection_range);
} // namespace ime } // namespace ime
} // namespace chromeos } // namespace chromeos
......
...@@ -48,5 +48,26 @@ TEST(ProtoConversionTest, OnKeyEventToProto) { ...@@ -48,5 +48,26 @@ TEST(ProtoConversionTest, OnKeyEventToProto) {
expected_message.SerializeAsString()); expected_message.SerializeAsString());
} }
TEST(ProtoConversionTest, OnSurroundingTextChangedToProto) {
const auto selection = mojom::SelectionRange::New(/*anchor=*/3, /*focus=*/2);
ime::PublicMessage expected_message;
expected_message.set_seq_id(42);
expected_message.mutable_on_surrounding_text_changed()->set_text("hello");
expected_message.mutable_on_surrounding_text_changed()->set_offset(1);
expected_message.mutable_on_surrounding_text_changed()
->mutable_selection_range()
->set_anchor(3);
expected_message.mutable_on_surrounding_text_changed()
->mutable_selection_range()
->set_focus(2);
ime::PublicMessage actual_message = OnSurroundingTextChangedToProto(
/*seq_id=*/42, "hello", /*offset=*/1, selection->Clone());
EXPECT_EQ(actual_message.SerializeAsString(),
expected_message.SerializeAsString());
}
} // namespace ime } // namespace ime
} // namespace chromeos } // namespace chromeos
...@@ -62,6 +62,10 @@ class TestClientChannel : mojom::InputChannel { ...@@ -62,6 +62,10 @@ class TestClientChannel : mojom::InputChannel {
MOCK_METHOD2(OnKeyEvent, MOCK_METHOD2(OnKeyEvent,
void(const mojom::PhysicalKeyEventPtr event, void(const mojom::PhysicalKeyEventPtr event,
OnKeyEventCallback)); OnKeyEventCallback));
MOCK_METHOD3(OnSurroundingTextChanged,
void(const std::string& text,
uint32_t offset,
mojom::SelectionRangePtr selection_range));
MOCK_METHOD0(ResetForRulebased, void()); MOCK_METHOD0(ResetForRulebased, void());
MOCK_METHOD1(GetRulebasedKeypressCountForTesting, MOCK_METHOD1(GetRulebasedKeypressCountForTesting,
void(GetRulebasedKeypressCountForTestingCallback)); void(GetRulebasedKeypressCountForTestingCallback));
......
...@@ -111,6 +111,13 @@ void InputEngine::OnFocus() { ...@@ -111,6 +111,13 @@ void InputEngine::OnFocus() {
NOTIMPLEMENTED(); // Not used in the rulebased engine. NOTIMPLEMENTED(); // Not used in the rulebased engine.
} }
void InputEngine::OnSurroundingTextChanged(
const std::string& text,
uint32_t offset,
mojom::SelectionRangePtr selection_range) {
NOTIMPLEMENTED(); // Not used in the rulebased engine.
}
void InputEngine::ProcessKeypressForRulebased( void InputEngine::ProcessKeypressForRulebased(
mojom::PhysicalKeyEventPtr event, mojom::PhysicalKeyEventPtr event,
ProcessKeypressForRulebasedCallback callback) { ProcessKeypressForRulebasedCallback callback) {
......
...@@ -47,6 +47,10 @@ class InputEngine : public mojom::InputChannel { ...@@ -47,6 +47,10 @@ class InputEngine : public mojom::InputChannel {
void ProcessMessage(const std::vector<uint8_t>& message, void ProcessMessage(const std::vector<uint8_t>& message,
ProcessMessageCallback callback) override; ProcessMessageCallback callback) override;
void OnFocus() override; void OnFocus() override;
void OnSurroundingTextChanged(
const std::string& text,
uint32_t offset,
mojom::SelectionRangePtr selection_range) override;
void ProcessKeypressForRulebased( void ProcessKeypressForRulebased(
mojom::PhysicalKeyEventPtr event, mojom::PhysicalKeyEventPtr event,
ProcessKeypressForRulebasedCallback callback) override; ProcessKeypressForRulebasedCallback callback) override;
......
...@@ -82,6 +82,16 @@ struct PhysicalKeyEvent { ...@@ -82,6 +82,16 @@ struct PhysicalKeyEvent {
ModifierState modifier_state; ModifierState modifier_state;
}; };
// Represents a directional text selection range.
// |anchor| is the index of where the selection began and |focus| is where the
// selection ended. The |anchor| can be before |focus| or vice versa depending
// on the direction the selection is in.
// See https://developer.mozilla.org/en-US/docs/Web/API/Selection
struct SelectionRange {
uint32 anchor;
uint32 focus;
};
// Manages access to a set of IME engines, implemented by the IME service // Manages access to a set of IME engines, implemented by the IME service
// itself. The IME framework in the browser process is responsible for brokering // itself. The IME framework in the browser process is responsible for brokering
// the connection between the IME service and the IME extension, but does not // the connection between the IME service and the IME extension, but does not
...@@ -118,6 +128,18 @@ interface InputChannel { ...@@ -118,6 +128,18 @@ interface InputChannel {
// Process a PhysicalKeyEvent for non-rule-based engines. // Process a PhysicalKeyEvent for non-rule-based engines.
OnKeyEvent(PhysicalKeyEvent event) => (bool consumed); OnKeyEvent(PhysicalKeyEvent event) => (bool consumed);
// Informs the IME that the surrounding text has changed.
// |text| is the text around the current text cursor position, including any
// composition text. To improve efficiency, |text| may not contain all the
// text that is in the current input field, but it's guaranteed to contain at
// least the text within the text selection.
// |offset| is the index of |text| relative to the full input field. If set to
// 0, then |text| represents the full contents of the input field.
// |selection_range| is relative to |text|.
OnSurroundingTextChanged(string text,
uint32 offset,
SelectionRange selection_range);
// Process a PhysicalKeyEvent using the rule-based engine and return a // Process a PhysicalKeyEvent using the rule-based engine and return a
// KeypressResponseForRulebased object with a list of operations to be handled // KeypressResponseForRulebased object with a list of operations to be handled
// by the caller. // by the caller.
......
...@@ -32,6 +32,7 @@ message PublicMessage { ...@@ -32,6 +32,7 @@ message PublicMessage {
OnFocus on_focus = 2; OnFocus on_focus = 2;
OnKeyEvent on_key_event = 3; OnKeyEvent on_key_event = 3;
OnKeyEventReply on_key_event_reply = 4; OnKeyEventReply on_key_event_reply = 4;
OnSurroundingTextChanged on_surrounding_text_changed = 5;
} }
} }
...@@ -78,3 +79,18 @@ message ModifierState { ...@@ -78,3 +79,18 @@ message ModifierState {
optional bool meta = 5; optional bool meta = 5;
optional bool shift = 6; optional bool shift = 6;
} }
// Protobuf version of InputEngine::SelectionRange in
// chromeos/services/ime/public/mojom/input_engine.mojom
message SelectionRange {
optional uint32 anchor = 1;
optional uint32 focus = 2;
}
// Protobuf version of InputEngine::OnSurroundingTextChanged in
// chromeos/services/ime/public/mojom/input_engine.mojom
message OnSurroundingTextChanged {
optional string text = 1;
optional uint32 offset = 2;
optional SelectionRange selection_range = 3;
}
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