blob: 0a6c8a05f5c739a54d1b3d7f064d6a99d2d844c6 [file] [log] [blame]
// Copyright 2019 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_CHROMEOS_INPUT_METHOD_NATIVE_INPUT_METHOD_ENGINE_H_
#define CHROME_BROWSER_CHROMEOS_INPUT_METHOD_NATIVE_INPUT_METHOD_ENGINE_H_
#include "base/scoped_observation.h"
#include "chrome/browser/chromeos/input_method/assistive_suggester.h"
#include "chrome/browser/chromeos/input_method/autocorrect_manager.h"
#include "chrome/browser/chromeos/input_method/grammar_manager.h"
#include "chrome/browser/chromeos/input_method/input_method_engine.h"
#include "chrome/browser/chromeos/input_method/suggestions_collector.h"
#include "chrome/browser/ui/ash/keyboard/chrome_keyboard_controller_client.h"
#include "chromeos/services/ime/public/cpp/suggestions.h"
#include "chromeos/services/ime/public/mojom/input_engine.mojom-forward.h"
#include "components/prefs/pref_change_registrar.h"
#include "components/prefs/pref_service.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "ui/base/ime/character_composer.h"
namespace chromeos {
// An InputMethodEngine used for the official Chrome OS build. It's a bridge
// between the Chrome OS input framework and the IME service. Although it
// currently depends on the Chrome extension system, it will not need to in
// the future after all the extensions code are migrated to the IME service.
// The design of this class is not good, mainly because we are inheriting
// from InputMethodEngineBase, which was designed for extension-based engines.
//
// In the final design, there should be some common interface between
// NativeInputMethodEngine and "ExtensionInputMethodEngine" (which is
// InputMethodEngineBase in the current design). All extensions-related logic
// will reside in the ExtensionInputMethodEngine inheritance tree. There will
// be no "ImeObserver" for the native engine either, as it is only used as
// a way for ExtensionInputMethodEngine to delegate to the extensions code,
// which is not required for the native engine.
class NativeInputMethodEngine
: public InputMethodEngine,
public ChromeKeyboardControllerClient::Observer {
public:
NativeInputMethodEngine();
~NativeInputMethodEngine() override;
// InputMethodEngine:
void Initialize(std::unique_ptr<InputMethodEngineBase::Observer> observer,
const char* extension_id,
Profile* profile) override;
// ChromeKeyboardControllerClient:
void OnKeyboardEnabledChanged(bool enabled) override;
// ProfileObserver:
void OnProfileWillBeDestroyed(Profile* profile) override;
// Flush all relevant Mojo pipes.
void FlushForTesting();
// Returns whether this is connected to the input engine.
bool IsConnectedForTesting() const;
AssistiveSuggester* get_assistive_suggester_for_testing() {
return assistive_suggester_;
}
AutocorrectManager* get_autocorrect_manager_for_testing() {
return autocorrect_manager_;
}
// Used to show special UI to user for interacting with autocorrected text.
// NOTE: Technically redundant to require client to supply `corrected_word` as
// it can be retrieved from current text editing state known to IMF. However,
// due to async situation between browser-process IMF and render-process
// TextInputClient, it may just be a stale value if obtained that way.
// TODO(crbug/1194424): Remove technically redundant `corrected_word` param to
// avoid situation with multiple conflicting sources of truth.
void OnAutocorrect(const std::u16string& typed_word,
const std::u16string& corrected_word,
int start_index);
private:
class ImeObserver : public InputMethodEngineBase::Observer,
public ime::mojom::InputChannel {
public:
// |ime_base_observer| is to forward events to extension during this
// migration. It will be removed when the official extension is completely
// migrated.
ImeObserver(
PrefService* prefs,
std::unique_ptr<InputMethodEngineBase::Observer> ime_base_observer,
std::unique_ptr<AssistiveSuggester> assistive_suggester,
std::unique_ptr<AutocorrectManager> autocorrect_manager,
std::unique_ptr<SuggestionsCollector> suggestions_collector,
std::unique_ptr<GrammarManager> grammar_manager);
~ImeObserver() override;
// InputMethodEngineBase::Observer:
void OnActivate(const std::string& engine_id) override;
void OnFocus(
const std::string& engine_id,
int context_id,
const IMEEngineHandlerInterface::InputContext& context) override;
void OnBlur(const std::string& engine_id, int context_id) override;
void OnKeyEvent(
const std::string& engine_id,
const ui::KeyEvent& event,
ui::IMEEngineHandlerInterface::KeyEventDoneCallback callback) override;
void OnReset(const std::string& engine_id) override;
void OnDeactivated(const std::string& engine_id) override;
void OnCompositionBoundsChanged(
const std::vector<gfx::Rect>& bounds) override;
void OnSurroundingTextChanged(const std::string& engine_id,
const std::u16string& text,
int cursor_pos,
int anchor_pos,
int offset_pos) override;
void OnCandidateClicked(
const std::string& component_id,
int candidate_id,
InputMethodEngineBase::MouseButtonEvent button) override;
void OnAssistiveWindowButtonClicked(
const ui::ime::AssistiveWindowButton& button) override;
void OnMenuItemActivated(const std::string& component_id,
const std::string& menu_id) override;
void OnScreenProjectionChanged(bool is_projected) override;
void OnSuggestionsChanged(
const std::vector<std::string>& suggestions) override;
void OnInputMethodOptionsChanged(const std::string& engine_id) override;
// mojom::InputChannel:
void ProcessMessage(const std::vector<uint8_t>& message,
ProcessMessageCallback callback) override;
void OnInputMethodChanged(const std::string& engine_id) override {}
void OnFocus(ime::mojom::InputFieldInfoPtr input_field_info) override {}
void OnBlur() override {}
void OnSurroundingTextChanged(
const std::string& text,
uint32_t offset,
ime::mojom::SelectionRangePtr selection_range) override {}
void OnCompositionCanceledBySystem() override {}
void ProcessKeypressForRulebased(
ime::mojom::PhysicalKeyEventPtr event,
ProcessKeypressForRulebasedCallback callback) override {}
void OnKeyEvent(ime::mojom::PhysicalKeyEventPtr event,
OnKeyEventCallback callback) override {}
void CommitText(
const std::string& text,
ime::mojom::CommitTextCursorBehavior cursor_behavior) 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;
void HandleAutocorrect(
ime::mojom::AutocorrectSpanPtr autocorrect_span) override;
void RequestSuggestions(ime::mojom::SuggestionsRequestPtr request,
RequestSuggestionsCallback callback) override;
void DisplaySuggestions(
const std::vector<ime::TextSuggestion>& suggestions) override;
void RecordUkm(ime::mojom::UkmEntryPtr entry) override;
// Called when suggestions are collected from the system via
// suggestions_collector_.
void OnSuggestionsGathered(RequestSuggestionsCallback request_callback,
ime::mojom::SuggestionsResponsePtr response);
// Flush all relevant Mojo pipes.
void FlushForTesting();
// Returns whether this is connected to the input engine.
bool IsConnectedForTesting() const { return remote_to_engine_.is_bound(); }
void OnProfileWillBeDestroyed();
private:
// Called when this is connected to the input engine. |bound| indicates
// the success of the connection.
void OnConnected(base::Time start, std::string engine_id, bool bound);
// Called when there's a connection error.
void OnError(base::Time start);
// Called when a rule-based key press is processed by Mojo.
void OnRuleBasedKeyEventResponse(
base::Time start,
ui::IMEEngineHandlerInterface::KeyEventDoneCallback callback,
ime::mojom::KeypressResponseForRulebasedPtr response);
PrefService* prefs_ = nullptr;
std::unique_ptr<InputMethodEngineBase::Observer> ime_base_observer_;
mojo::Remote<ime::mojom::InputEngineManager> remote_manager_;
mojo::Receiver<ime::mojom::InputChannel> receiver_from_engine_;
mojo::Remote<ime::mojom::InputChannel> remote_to_engine_;
std::unique_ptr<AssistiveSuggester> assistive_suggester_;
std::unique_ptr<AutocorrectManager> autocorrect_manager_;
std::unique_ptr<SuggestionsCollector> suggestions_collector_;
std::unique_ptr<GrammarManager> grammar_manager_;
ui::CharacterComposer character_composer_;
};
ImeObserver* GetNativeObserver() const;
void OnInputMethodOptionsChanged() override;
AssistiveSuggester* assistive_suggester_ = nullptr;
AutocorrectManager* autocorrect_manager_ = nullptr;
base::ScopedObservation<ChromeKeyboardControllerClient,
ChromeKeyboardControllerClient::Observer>
chrome_keyboard_controller_client_observer_{this};
};
} // namespace chromeos
#endif // CHROME_BROWSER_CHROMEOS_INPUT_METHOD_NATIVE_INPUT_METHOD_ENGINE_H_