Commit e508bc24 authored by Shu Chen's avatar Shu Chen Committed by Commit Bot

Refactoring the mojo stuff in InputMethodEngine.

1) Makes MojoHelper lives as long as InputMethodEngine.
   This is because the mojo connection breakage should NOT be triggered by
   InputMethodEngine::Disable. Otherwise, the engine client and IEFR will both
   handle the connection error and would have race conditions.
2) Makes sure InputMethodEngineBase doesn't call GetInputContextHandler() and
   let subclasses to override all the methods to callback to the engine client.

Bug: 937167
Change-Id: Ic567e5dca153eca9f1b2eb739c66f25a55a30088
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1545442Reviewed-by: default avatarScott Violet <sky@chromium.org>
Commit-Queue: Shu Chen <shuchen@chromium.org>
Cr-Commit-Position: refs/heads/master@{#646642}
parent 3c5dff09
...@@ -64,11 +64,17 @@ const int kDefaultPageSize = 9; ...@@ -64,11 +64,17 @@ const int kDefaultPageSize = 9;
class MojoHelper : public ime::mojom::ImeEngine, class MojoHelper : public ime::mojom::ImeEngine,
public ime::mojom::ImeEngineFactory { public ime::mojom::ImeEngineFactory {
public: public:
MojoHelper(InputMethodEngine* engine, explicit MojoHelper(InputMethodEngine* engine)
ime::mojom::ImeEngineFactoryRegistryPtr registry) : engine_(engine), factory_binding_(this), engine_binding_(this) {}
: engine_(engine), factory_binding_(this), engine_binding_(this) { ~MojoHelper() override = default;
void Activate(ime::mojom::ImeEngineFactoryRegistryPtr registry) {
ime::mojom::ImeEngineFactoryPtr factory_ptr; ime::mojom::ImeEngineFactoryPtr factory_ptr;
factory_binding_.Close();
factory_binding_.Bind(mojo::MakeRequest(&factory_ptr)); factory_binding_.Bind(mojo::MakeRequest(&factory_ptr));
factory_binding_.set_connection_error_handler(
base::BindOnce(&MojoHelper::OnConnectionLost, base::Unretained(this)));
if (registry) { if (registry) {
registry_ = std::move(registry); registry_ = std::move(registry);
} else { } else {
...@@ -79,11 +85,11 @@ class MojoHelper : public ime::mojom::ImeEngine, ...@@ -79,11 +85,11 @@ class MojoHelper : public ime::mojom::ImeEngine,
} }
registry_->ActivateFactory(std::move(factory_ptr)); registry_->ActivateFactory(std::move(factory_ptr));
} }
~MojoHelper() override = default;
// ime::mojom::ImeEngineFactory overrides: // ime::mojom::ImeEngineFactory overrides:
void CreateEngine(ime::mojom::ImeEngineRequest engine_request, void CreateEngine(ime::mojom::ImeEngineRequest engine_request,
ime::mojom::ImeEngineClientPtr client) override { ime::mojom::ImeEngineClientPtr client) override {
engine_binding_.Close();
engine_binding_.Bind(std::move(engine_request)); engine_binding_.Bind(std::move(engine_request));
engine_client_ = std::move(client); engine_client_ = std::move(client);
} }
...@@ -112,7 +118,11 @@ class MojoHelper : public ime::mojom::ImeEngine, ...@@ -112,7 +118,11 @@ class MojoHelper : public ime::mojom::ImeEngine,
engine_->SetCompositionBounds(bounds); engine_->SetCompositionBounds(bounds);
} }
ime::mojom::ImeEngineClientPtr& engine_client() { return engine_client_; } bool IsConnected() const { return engine_client_.is_bound(); }
ime::mojom::ImeEngineClientProxy* engine_client() {
return engine_client_.get();
}
void FlushForTesting() { void FlushForTesting() {
if (registry_) if (registry_)
...@@ -122,6 +132,14 @@ class MojoHelper : public ime::mojom::ImeEngine, ...@@ -122,6 +132,14 @@ class MojoHelper : public ime::mojom::ImeEngine,
} }
private: private:
void OnConnectionLost() {
// After the connection to |ImeEngineFactoryRegistry| is broken, break the
// connection to the client, so that the client can reconnect through Window
// Service.
engine_binding_.Close();
engine_client_.reset();
}
InputMethodEngine* engine_; InputMethodEngine* engine_;
mojo::Binding<ime::mojom::ImeEngineFactory> factory_binding_; mojo::Binding<ime::mojom::ImeEngineFactory> factory_binding_;
mojo::Binding<ime::mojom::ImeEngine> engine_binding_; mojo::Binding<ime::mojom::ImeEngine> engine_binding_;
...@@ -152,20 +170,16 @@ InputMethodEngine::InputMethodEngine() ...@@ -152,20 +170,16 @@ InputMethodEngine::InputMethodEngine()
: candidate_window_(new ui::CandidateWindow()), : candidate_window_(new ui::CandidateWindow()),
window_visible_(false), window_visible_(false),
is_mirroring_(false), is_mirroring_(false),
is_casting_(false) {} is_casting_(false) {
mojo_helper_ = std::make_unique<MojoHelper>(this);
}
InputMethodEngine::~InputMethodEngine() {} InputMethodEngine::~InputMethodEngine() {}
void InputMethodEngine::Enable(const std::string& component_id) { void InputMethodEngine::Enable(const std::string& component_id) {
InputMethodEngineBase::Enable(component_id); InputMethodEngineBase::Enable(component_id);
EnableInputView(); EnableInputView();
mojo_helper_ = std::make_unique<MojoHelper>( mojo_helper_->Activate(std::move(ime_engine_factory_registry_));
this, std::move(ime_engine_factory_registry_));
}
void InputMethodEngine::Disable() {
InputMethodEngineBase::Disable();
mojo_helper_.reset();
} }
bool InputMethodEngine::IsActive() const { bool InputMethodEngine::IsActive() const {
...@@ -355,19 +369,33 @@ void InputMethodEngine::UpdateComposition( ...@@ -355,19 +369,33 @@ void InputMethodEngine::UpdateComposition(
const ui::CompositionText& composition_text, const ui::CompositionText& composition_text,
uint32_t cursor_pos, uint32_t cursor_pos,
bool is_visible) { bool is_visible) {
ui::IMEInputContextHandlerInterface* input_context = if (mojo_helper_->IsConnected()) {
ui::IMEBridge::Get()->GetInputContextHandler(); NOTIMPLEMENTED_LOG_ONCE();
if (input_context) } else {
input_context->UpdateCompositionText(composition_text, cursor_pos, ui::IMEInputContextHandlerInterface* input_context =
is_visible); ui::IMEBridge::Get()->GetInputContextHandler();
if (input_context)
input_context->UpdateCompositionText(composition_text, cursor_pos,
is_visible);
}
} }
void InputMethodEngine::CommitTextToInputContext(int context_id, void InputMethodEngine::CommitTextToInputContext(int context_id,
const std::string& text) { const std::string& text) {
ui::IMEBridge::Get()->GetInputContextHandler()->CommitText(text); bool committed = false;
if (mojo_helper_->IsConnected()) {
NOTIMPLEMENTED_LOG_ONCE();
} else {
ui::IMEInputContextHandlerInterface* input_context =
ui::IMEBridge::Get()->GetInputContextHandler();
if (input_context) {
input_context->CommitText(text);
committed = true;
}
}
// Records histograms for committed characters. if (committed && !composition_text_->text.empty()) {
if (!composition_text_->text.empty()) { // Records histograms for committed characters.
base::string16 wtext = base::UTF8ToUTF16(text); base::string16 wtext = base::UTF8ToUTF16(text);
UMA_HISTOGRAM_CUSTOM_COUNTS("InputMethod.CommitLength", wtext.length(), 1, UMA_HISTOGRAM_CUSTOM_COUNTS("InputMethod.CommitLength", wtext.length(), 1,
25, 25); 25, 25);
...@@ -375,24 +403,42 @@ void InputMethodEngine::CommitTextToInputContext(int context_id, ...@@ -375,24 +403,42 @@ void InputMethodEngine::CommitTextToInputContext(int context_id,
} }
} }
void InputMethodEngine::DeleteSurroundingTextToInputContext(
int offset,
size_t number_of_chars) {
if (mojo_helper_->IsConnected()) {
NOTIMPLEMENTED_LOG_ONCE();
} else {
ui::IMEInputContextHandlerInterface* input_context =
ui::IMEBridge::Get()->GetInputContextHandler();
if (input_context)
input_context->DeleteSurroundingText(offset, number_of_chars);
}
}
bool InputMethodEngine::SendKeyEvent(ui::KeyEvent* event, bool InputMethodEngine::SendKeyEvent(ui::KeyEvent* event,
const std::string& code) { const std::string& code) {
DCHECK(event); DCHECK(event);
if (event->key_code() == ui::VKEY_UNKNOWN) if (event->key_code() == ui::VKEY_UNKNOWN)
event->set_key_code(ui::DomKeycodeToKeyboardCode(code)); event->set_key_code(ui::DomKeycodeToKeyboardCode(code));
ui::IMEInputContextHandlerInterface* input_context =
ui::IMEBridge::Get()->GetInputContextHandler();
if (!input_context)
return false;
// Marks the simulated key event is from the Virtual Keyboard. // Marks the simulated key event is from the Virtual Keyboard.
ui::Event::Properties properties; ui::Event::Properties properties;
properties[ui::kPropertyFromVK] = std::vector<uint8_t>(); properties[ui::kPropertyFromVK] = std::vector<uint8_t>();
event->SetProperties(properties); event->SetProperties(properties);
input_context->SendKeyEvent(event); bool sent = false;
return true; if (mojo_helper_->IsConnected()) {
NOTIMPLEMENTED_LOG_ONCE();
} else {
ui::IMEInputContextHandlerInterface* input_context =
ui::IMEBridge::Get()->GetInputContextHandler();
if (input_context) {
input_context->SendKeyEvent(event);
sent = true;
}
}
return sent;
} }
void InputMethodEngine::EnableInputView() { void InputMethodEngine::EnableInputView() {
......
...@@ -91,7 +91,6 @@ class InputMethodEngine : public ::input_method::InputMethodEngineBase { ...@@ -91,7 +91,6 @@ class InputMethodEngine : public ::input_method::InputMethodEngineBase {
// InputMethodEngineBase overrides. // InputMethodEngineBase overrides.
void Enable(const std::string& component_id) override; void Enable(const std::string& component_id) override;
void Disable() override;
bool IsActive() const override; bool IsActive() const override;
// ui::IMEEngineHandlerInterface overrides. // ui::IMEEngineHandlerInterface overrides.
...@@ -146,6 +145,8 @@ class InputMethodEngine : public ::input_method::InputMethodEngineBase { ...@@ -146,6 +145,8 @@ class InputMethodEngine : public ::input_method::InputMethodEngineBase {
bool is_visible) override; bool is_visible) override;
void CommitTextToInputContext(int context_id, void CommitTextToInputContext(int context_id,
const std::string& text) override; const std::string& text) override;
void DeleteSurroundingTextToInputContext(int offset,
size_t number_of_chars) override;
bool SendKeyEvent(ui::KeyEvent* event, const std::string& code) override; bool SendKeyEvent(ui::KeyEvent* event, const std::string& code) override;
// Enables overriding input view page to Virtual Keyboard window. // Enables overriding input view page to Virtual Keyboard window.
......
...@@ -107,6 +107,15 @@ void InputMethodEngine::CommitTextToInputContext(int context_id, ...@@ -107,6 +107,15 @@ void InputMethodEngine::CommitTextToInputContext(int context_id,
} }
} }
void InputMethodEngine::DeleteSurroundingTextToInputContext(
int offset,
size_t number_of_chars) {
ui::IMEInputContextHandlerInterface* input_context =
ui::IMEBridge::Get()->GetInputContextHandler();
if (input_context)
input_context->DeleteSurroundingText(offset, number_of_chars);
}
bool InputMethodEngine::SendKeyEvent(ui::KeyEvent* event, bool InputMethodEngine::SendKeyEvent(ui::KeyEvent* event,
const std::string& code) { const std::string& code) {
DCHECK(event); DCHECK(event);
......
...@@ -33,6 +33,8 @@ class InputMethodEngine : public InputMethodEngineBase, ...@@ -33,6 +33,8 @@ class InputMethodEngine : public InputMethodEngineBase,
bool is_visible) override; bool is_visible) override;
void CommitTextToInputContext(int context_id, void CommitTextToInputContext(int context_id,
const std::string& text) override; const std::string& text) override;
void DeleteSurroundingTextToInputContext(int offset,
size_t number_of_chars) override;
bool SendKeyEvent(ui::KeyEvent* ui_event, const std::string& code) override; bool SendKeyEvent(ui::KeyEvent* ui_event, const std::string& code) override;
bool IsActive() const override; bool IsActive() const override;
......
...@@ -211,9 +211,8 @@ void InputMethodEngineBase::Enable(const std::string& component_id) { ...@@ -211,9 +211,8 @@ void InputMethodEngineBase::Enable(const std::string& component_id) {
void InputMethodEngineBase::Disable() { void InputMethodEngineBase::Disable() {
std::string last_component_id{active_component_id_}; std::string last_component_id{active_component_id_};
active_component_id_.clear(); active_component_id_.clear();
if (ui::IMEBridge::Get()->GetInputContextHandler()) CommitTextToInputContext(context_id_,
ui::IMEBridge::Get()->GetInputContextHandler()->CommitText( base::UTF16ToUTF8(composition_text_->text));
base::UTF16ToUTF8(composition_text_->text));
composition_text_.reset(new ui::CompositionText()); composition_text_.reset(new ui::CompositionText());
observer_->OnDeactivated(last_component_id); observer_->OnDeactivated(last_component_id);
} }
...@@ -320,10 +319,7 @@ bool InputMethodEngineBase::DeleteSurroundingText(int context_id, ...@@ -320,10 +319,7 @@ bool InputMethodEngineBase::DeleteSurroundingText(int context_id,
// TODO(nona): Return false if there is ongoing composition. // TODO(nona): Return false if there is ongoing composition.
ui::IMEInputContextHandlerInterface* input_context = DeleteSurroundingTextToInputContext(offset, number_of_chars);
ui::IMEBridge::Get()->GetInputContextHandler();
if (input_context)
input_context->DeleteSurroundingText(offset, number_of_chars);
return true; return true;
} }
...@@ -418,21 +414,14 @@ void InputMethodEngineBase::KeyEventHandled(const std::string& extension_id, ...@@ -418,21 +414,14 @@ void InputMethodEngineBase::KeyEventHandled(const std::string& extension_id,
handling_key_event_ = false; handling_key_event_ = false;
// When finish handling key event, take care of the unprocessed commitText // When finish handling key event, take care of the unprocessed commitText
// and setComposition calls. // and setComposition calls.
ui::IMEInputContextHandlerInterface* input_context =
ui::IMEBridge::Get()->GetInputContextHandler();
if (commit_text_changed_) { if (commit_text_changed_) {
if (input_context) { CommitTextToInputContext(context_id_, text_);
input_context->CommitText(text_);
}
text_ = ""; text_ = "";
commit_text_changed_ = false; commit_text_changed_ = false;
} }
if (composition_changed_) { if (composition_changed_) {
if (input_context) { UpdateComposition(composition_, composition_.selection.start(), true);
input_context->UpdateCompositionText(
composition_, composition_.selection.start(), true);
}
composition_ = ui::CompositionText(); composition_ = ui::CompositionText();
composition_changed_ = false; composition_changed_ = false;
} }
......
...@@ -212,6 +212,9 @@ class InputMethodEngineBase : virtual public ui::IMEEngineHandlerInterface { ...@@ -212,6 +212,9 @@ class InputMethodEngineBase : virtual public ui::IMEEngineHandlerInterface {
// Notifies InputContextHanlder to commit |text|. // Notifies InputContextHanlder to commit |text|.
virtual void CommitTextToInputContext(int context_id, virtual void CommitTextToInputContext(int context_id,
const std::string& text) = 0; const std::string& text) = 0;
// Notifies InputContextHandler to delete surrounding text.
virtual void DeleteSurroundingTextToInputContext(int offset,
size_t number_of_chars) = 0;
// Sends the key event to the window tree host. // Sends the key event to the window tree host.
virtual bool SendKeyEvent(ui::KeyEvent* ui_event, virtual bool SendKeyEvent(ui::KeyEvent* ui_event,
const std::string& code) = 0; const std::string& code) = 0;
......
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