1 // Copyright 2017 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef ASH_IME_IME_CONTROLLER_IMPL_H_ 6 #define ASH_IME_IME_CONTROLLER_IMPL_H_ 7 8 #include <memory> 9 #include <vector> 10 11 #include "ash/ash_export.h" 12 #include "ash/public/cpp/cast_config_controller.h" 13 #include "ash/public/cpp/ime_controller.h" 14 #include "ash/public/cpp/ime_controller_client.h" 15 #include "ash/public/cpp/ime_info.h" 16 #include "base/macros.h" 17 #include "base/observer_list.h" 18 #include "mojo/public/cpp/bindings/pending_receiver.h" 19 #include "mojo/public/cpp/bindings/pending_remote.h" 20 #include "mojo/public/cpp/bindings/receiver_set.h" 21 #include "mojo/public/cpp/bindings/remote.h" 22 #include "ui/base/ime/chromeos/ime_keyset.h" 23 #include "ui/display/display_observer.h" 24 25 namespace ui { 26 class Accelerator; 27 } 28 29 namespace ash { 30 31 class ModeIndicatorObserver; 32 33 // Connects ash IME users (e.g. the system tray) to the IME implementation, 34 // which might live in Chrome browser or in a separate mojo service. 35 class ASH_EXPORT ImeControllerImpl : public ImeController, 36 public display::DisplayObserver, 37 public CastConfigController::Observer { 38 public: 39 class Observer { 40 public: 41 // Called when the caps lock state has changed. 42 virtual void OnCapsLockChanged(bool enabled) = 0; 43 44 // Called when the keyboard layout name has changed. 45 virtual void OnKeyboardLayoutNameChanged( 46 const std::string& layout_name) = 0; 47 }; 48 49 ImeControllerImpl(); 50 ~ImeControllerImpl() override; 51 52 void AddObserver(Observer* observer); 53 void RemoveObserver(Observer* observer); 54 current_ime()55 const ImeInfo& current_ime() const { return current_ime_; } 56 available_imes()57 const std::vector<ImeInfo>& available_imes() const { return available_imes_; } 58 is_extra_input_options_enabled()59 bool is_extra_input_options_enabled() const { 60 return is_extra_input_options_enabled_; 61 } is_emoji_enabled()62 bool is_emoji_enabled() const { return is_emoji_enabled_; } is_handwriting_enabled()63 bool is_handwriting_enabled() const { return is_handwriting_enabled_; } is_voice_enabled()64 bool is_voice_enabled() const { return is_voice_enabled_; } 65 managed_by_policy()66 bool managed_by_policy() const { return managed_by_policy_; } is_menu_active()67 bool is_menu_active() const { return is_menu_active_; } 68 current_ime_menu_items()69 const std::vector<ImeMenuItem>& current_ime_menu_items() const { 70 return current_ime_menu_items_; 71 } 72 73 // Binds the mojo interface to this object. 74 void BindReceiver(mojo::PendingReceiver<ImeController> receiver); 75 76 // Returns true if switching to next/previous IME is allowed. 77 bool CanSwitchIme() const; 78 79 // Wrappers for ImeControllerClient methods. 80 void SwitchToNextIme(); 81 void SwitchToLastUsedIme(); 82 void SwitchImeById(const std::string& ime_id, bool show_message); 83 void ActivateImeMenuItem(const std::string& key); 84 void SetCapsLockEnabled(bool caps_enabled); 85 void OverrideKeyboardKeyset(chromeos::input_method::ImeKeyset keyset); 86 void OverrideKeyboardKeyset( 87 chromeos::input_method::ImeKeyset keyset, 88 ImeControllerClient::OverrideKeyboardKeysetCallback callback); 89 90 // Returns true if the switch is allowed and the keystroke should be 91 // consumed. 92 bool CanSwitchImeWithAccelerator(const ui::Accelerator& accelerator) const; 93 94 void SwitchImeWithAccelerator(const ui::Accelerator& accelerator); 95 96 // ImeController: 97 void SetClient(ImeControllerClient* client) override; 98 void RefreshIme(const std::string& current_ime_id, 99 std::vector<ImeInfo> available_imes, 100 std::vector<ImeMenuItem> menu_items) override; 101 void SetImesManagedByPolicy(bool managed) override; 102 void ShowImeMenuOnShelf(bool show) override; 103 void UpdateCapsLockState(bool caps_enabled) override; 104 void OnKeyboardLayoutNameChanged(const std::string& layout_name) override; 105 106 void SetExtraInputOptionsEnabledState(bool is_extra_input_options_enabled, 107 bool is_emoji_enabled, 108 bool is_handwriting_enabled, 109 bool is_voice_enabled) override; 110 // Show the mode indicator UI with the given text at the anchor bounds. 111 // The anchor bounds is in the universal screen coordinates in DIP. 112 void ShowModeIndicator(const gfx::Rect& anchor_bounds, 113 const base::string16& ime_short_name) override; 114 115 // display::DisplayObserver: 116 void OnDisplayMetricsChanged(const display::Display& display, 117 uint32_t changed_metrics) override; 118 119 // CastConfigController::Observer: 120 void OnDevicesUpdated(const std::vector<SinkAndRoute>& devices) override; 121 122 // Synchronously returns the cached caps lock state. 123 bool IsCapsLockEnabled() const; 124 125 // Synchronously returns the cached keyboard layout name keyboard_layout_name()126 const std::string& keyboard_layout_name() const { 127 return keyboard_layout_name_; 128 } 129 mode_indicator_observer()130 ModeIndicatorObserver* mode_indicator_observer() const { 131 return mode_indicator_observer_.get(); 132 } 133 134 private: 135 // Returns the IDs of the subset of input methods which are active and are 136 // associated with |accelerator|. For example, two Japanese IMEs can be 137 // returned for ui::VKEY_DBE_SBCSCHAR if both are active. 138 std::vector<std::string> GetCandidateImesForAccelerator( 139 const ui::Accelerator& accelerator) const; 140 141 // Client interface back to IME code in chrome. 142 ImeControllerClient* client_ = nullptr; 143 144 // Copy of the current IME so we can return it by reference. 145 ImeInfo current_ime_; 146 147 // "Available" IMEs are both installed and enabled by the user in settings. 148 std::vector<ImeInfo> available_imes_; 149 150 // True if the available IMEs are currently managed by enterprise policy. 151 // For example, can occur at the login screen with device-level policy. 152 bool managed_by_policy_ = false; 153 154 // Additional menu items for properties of the currently selected IME. 155 std::vector<ImeMenuItem> current_ime_menu_items_; 156 157 // A slightly delayed state value that is updated by asynchronously reported 158 // changes from the ImeControllerClient client (source of truth) which is in 159 // another process. This is required for synchronous method calls in ash. 160 bool is_caps_lock_enabled_ = false; 161 162 // A slightly delayed state value that is updated by asynchronously reported 163 // changes from the ImeControllerClient client (source of truth) which is in 164 // another process. This is required for synchronous method calls in ash. 165 std::string keyboard_layout_name_; 166 167 // True if the extended inputs should be available in general (emoji, 168 // handwriting, voice). 169 bool is_extra_input_options_enabled_ = false; 170 171 // True if emoji input should be available from the IME menu. 172 bool is_emoji_enabled_ = false; 173 174 // True if handwriting input should be available from the IME menu. 175 bool is_handwriting_enabled_ = false; 176 177 // True if voice input should be available from the IME menu. 178 bool is_voice_enabled_ = false; 179 180 // True if the IME menu is active. IME related items in system tray should be 181 // removed if |is_menu_active_| is true. 182 bool is_menu_active_ = false; 183 184 base::ObserverList<Observer>::Unchecked observers_; 185 186 std::unique_ptr<ModeIndicatorObserver> mode_indicator_observer_; 187 188 DISALLOW_COPY_AND_ASSIGN(ImeControllerImpl); 189 }; 190 191 } // namespace ash 192 193 #endif // ASH_IME_IME_CONTROLLER_H_ 194