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(
assistive_suggester_->OnSurroundingTextChanged(text, cursor_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,
anchor_pos, offset_pos);
}
......
......@@ -93,6 +93,10 @@ class NativeInputMethodEngine : public InputMethodEngine {
void ProcessMessage(const std::vector<uint8_t>& message,
ProcessMessageCallback callback) override;
void OnFocus() override {}
void OnSurroundingTextChanged(
const std::string& text,
uint32_t offset,
ime::mojom::SelectionRangePtr selection_range) override {}
void ProcessKeypressForRulebased(
ime::mojom::PhysicalKeyEventPtr event,
ProcessKeypressForRulebasedCallback callback) override {}
......
......@@ -156,6 +156,18 @@ void DecoderEngine::OnKeyEvent(mojom::PhysicalKeyEventPtr event,
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,
ProcessMessageCallback callback) {
// TODO(https://crbug.com/837156): Set a default protobuf message.
......
......@@ -35,6 +35,10 @@ class DecoderEngine : public InputEngine {
void OnFocus() override;
void OnKeyEvent(mojom::PhysicalKeyEventPtr event,
OnKeyEventCallback callback) override;
void OnSurroundingTextChanged(
const std::string& text,
uint32_t offset,
mojom::SelectionRangePtr selection_range) override;
private:
// Try to load the decoding functions from some decoder shared library.
......
......@@ -57,6 +57,10 @@ class StubInputChannel : public mojom::InputChannel {
ProcessKeypressForRulebasedCallback callback) final {}
void OnKeyEvent(ime::mojom::PhysicalKeyEventPtr event,
OnKeyEventCallback callback) final {}
void OnSurroundingTextChanged(
const std::string& text,
uint32_t offset,
ime::mojom::SelectionRangePtr selection_range) final {}
void ResetForRulebased() final {}
void GetRulebasedKeypressCountForTesting(
GetRulebasedKeypressCountForTestingCallback callback) final {}
......@@ -141,5 +145,23 @@ TEST_F(DecoderEngineTest, OnKeyEventRepliesWithCallback) {
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 chromeos
......@@ -46,5 +46,23 @@ ime::PublicMessage OnKeyEventToProto(uint64_t seq_id,
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 chromeos
......@@ -20,6 +20,14 @@ ime::PublicMessage OnFocusToProto(uint64_t seq_id);
ime::PublicMessage OnKeyEventToProto(uint64_t seq_id,
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 chromeos
......
......@@ -48,5 +48,26 @@ TEST(ProtoConversionTest, OnKeyEventToProto) {
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 chromeos
......@@ -62,6 +62,10 @@ class TestClientChannel : mojom::InputChannel {
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(ResetForRulebased, void());
MOCK_METHOD1(GetRulebasedKeypressCountForTesting,
void(GetRulebasedKeypressCountForTestingCallback));
......
......@@ -111,6 +111,13 @@ void InputEngine::OnFocus() {
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(
mojom::PhysicalKeyEventPtr event,
ProcessKeypressForRulebasedCallback callback) {
......
......@@ -47,6 +47,10 @@ class InputEngine : public mojom::InputChannel {
void ProcessMessage(const std::vector<uint8_t>& message,
ProcessMessageCallback callback) override;
void OnFocus() override;
void OnSurroundingTextChanged(
const std::string& text,
uint32_t offset,
mojom::SelectionRangePtr selection_range) override;
void ProcessKeypressForRulebased(
mojom::PhysicalKeyEventPtr event,
ProcessKeypressForRulebasedCallback callback) override;
......
......@@ -82,6 +82,16 @@ struct PhysicalKeyEvent {
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
// 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
......@@ -118,6 +128,18 @@ interface InputChannel {
// Process a PhysicalKeyEvent for non-rule-based engines.
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
// KeypressResponseForRulebased object with a list of operations to be handled
// by the caller.
......
......@@ -32,6 +32,7 @@ message PublicMessage {
OnFocus on_focus = 2;
OnKeyEvent on_key_event = 3;
OnKeyEventReply on_key_event_reply = 4;
OnSurroundingTextChanged on_surrounding_text_changed = 5;
}
}
......@@ -78,3 +79,18 @@ message ModifierState {
optional bool meta = 5;
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