1 // Copyright (c) 2012 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 CHROME_BROWSER_CHROMEOS_INPUT_METHOD_INPUT_METHOD_MANAGER_IMPL_H_ 6 #define CHROME_BROWSER_CHROMEOS_INPUT_METHOD_INPUT_METHOD_MANAGER_IMPL_H_ 7 8 #include <map> 9 #include <string> 10 #include <vector> 11 12 #include "base/memory/scoped_ptr.h" 13 #include "base/observer_list.h" 14 #include "base/threading/thread_checker.h" 15 #include "chrome/browser/chromeos/input_method/candidate_window_controller.h" 16 #include "chrome/browser/chromeos/input_method/input_method_util.h" 17 #include "chrome/browser/profiles/profile.h" 18 #include "chromeos/ime/input_method_manager.h" 19 #include "chromeos/ime/input_method_whitelist.h" 20 21 namespace chromeos { 22 class ComponentExtensionIMEManager; 23 class ComponentExtensionIMEManagerDelegate; 24 class InputMethodEngine; 25 namespace input_method { 26 class InputMethodDelegate; 27 class ImeKeyboard; 28 29 // The implementation of InputMethodManager. 30 class InputMethodManagerImpl : public InputMethodManager, 31 public CandidateWindowController::Observer { 32 public: 33 class StateImpl : public InputMethodManager::State { 34 public: 35 StateImpl(InputMethodManagerImpl* manager, Profile* profile); 36 37 // Init new state as a copy of other. 38 void InitFrom(const StateImpl& other); 39 40 // Returns true if (manager_->state_ == this). 41 bool IsActive() const; 42 43 // Returns human-readable dump (for debug). 44 std::string Dump() const; 45 46 // Adds new input method to given list if possible 47 bool EnableInputMethodImpl( 48 const std::string& input_method_id, 49 std::vector<std::string>* new_active_input_method_ids) const; 50 51 // Returns true if |input_method_id| is in |active_input_method_ids|. 52 bool InputMethodIsActivated(const std::string& input_method_id) const; 53 54 // If |current_input_methodid_| is not in |input_method_ids|, switch to 55 // input_method_ids[0]. If the ID is equal to input_method_ids[N], switch to 56 // input_method_ids[N+1]. 57 void SwitchToNextInputMethodInternal( 58 const std::vector<std::string>& input_method_ids, 59 const std::string& current_input_methodid); 60 61 // Returns true if given input method requires pending extension. 62 bool MethodAwaitsExtensionLoad(const std::string& input_method_id) const; 63 64 // InputMethodManager::State overrides. 65 virtual scoped_refptr<InputMethodManager::State> Clone() const OVERRIDE; 66 virtual void AddInputMethodExtension( 67 const std::string& extension_id, 68 const InputMethodDescriptors& descriptors, 69 InputMethodEngineInterface* instance) OVERRIDE; 70 virtual void RemoveInputMethodExtension( 71 const std::string& extension_id) OVERRIDE; 72 virtual void ChangeInputMethod(const std::string& input_method_id, 73 bool show_message) OVERRIDE; 74 virtual bool EnableInputMethod( 75 const std::string& new_active_input_method_id) OVERRIDE; 76 virtual void EnableLoginLayouts( 77 const std::string& language_code, 78 const std::vector<std::string>& initial_layouts) OVERRIDE; 79 virtual void EnableLockScreenLayouts() OVERRIDE; 80 virtual void GetInputMethodExtensions( 81 InputMethodDescriptors* result) OVERRIDE; 82 virtual scoped_ptr<InputMethodDescriptors> GetActiveInputMethods() 83 const OVERRIDE; 84 virtual const std::vector<std::string>& GetActiveInputMethodIds() 85 const OVERRIDE; 86 virtual const InputMethodDescriptor* GetInputMethodFromId( 87 const std::string& input_method_id) const OVERRIDE; 88 virtual size_t GetNumActiveInputMethods() const OVERRIDE; 89 virtual void SetEnabledExtensionImes( 90 std::vector<std::string>* ids) OVERRIDE; 91 virtual void SetInputMethodLoginDefault() OVERRIDE; 92 virtual void SetInputMethodLoginDefaultFromVPD( 93 const std::string& locale, 94 const std::string& layout) OVERRIDE; 95 virtual bool SwitchToNextInputMethod() OVERRIDE; 96 virtual bool SwitchToPreviousInputMethod( 97 const ui::Accelerator& accelerator) OVERRIDE; 98 virtual bool SwitchInputMethod(const ui::Accelerator& accelerator) OVERRIDE; 99 virtual InputMethodDescriptor GetCurrentInputMethod() const OVERRIDE; 100 virtual bool ReplaceEnabledInputMethods( 101 const std::vector<std::string>& new_active_input_method_ids) OVERRIDE; 102 103 // ------------------------- Data members. 104 Profile* const profile; 105 106 // The input method which was/is selected. 107 InputMethodDescriptor previous_input_method; 108 InputMethodDescriptor current_input_method; 109 110 // The active input method ids cache. 111 std::vector<std::string> active_input_method_ids; 112 113 // The pending input method id for delayed 3rd party IME enabling. 114 std::string pending_input_method_id; 115 116 // The list of enabled extension IMEs. 117 std::vector<std::string> enabled_extension_imes; 118 119 // Extra input methods that have been explicitly added to the menu, such as 120 // those created by extension. 121 std::map<std::string, InputMethodDescriptor> extra_input_methods; 122 123 private: 124 InputMethodManagerImpl* const manager_; 125 126 protected: 127 friend base::RefCounted<chromeos::input_method::InputMethodManager::State>; 128 virtual ~StateImpl(); 129 }; 130 131 // Constructs an InputMethodManager instance. The client is responsible for 132 // calling |SetUISessionState| in response to relevant changes in browser 133 // state. 134 InputMethodManagerImpl(scoped_ptr<InputMethodDelegate> delegate, 135 bool enable_extension_loading); 136 virtual ~InputMethodManagerImpl(); 137 138 // Receives notification of an InputMethodManager::UISessionState transition. 139 void SetUISessionState(UISessionState new_ui_session); 140 141 // InputMethodManager override: 142 virtual UISessionState GetUISessionState() OVERRIDE; 143 virtual void AddObserver(InputMethodManager::Observer* observer) OVERRIDE; 144 virtual void AddCandidateWindowObserver( 145 InputMethodManager::CandidateWindowObserver* observer) OVERRIDE; 146 virtual void RemoveObserver(InputMethodManager::Observer* observer) OVERRIDE; 147 virtual void RemoveCandidateWindowObserver( 148 InputMethodManager::CandidateWindowObserver* observer) OVERRIDE; 149 virtual scoped_ptr<InputMethodDescriptors> 150 GetSupportedInputMethods() const OVERRIDE; 151 virtual void ActivateInputMethodMenuItem(const std::string& key) OVERRIDE; 152 virtual bool IsISOLevel5ShiftUsedByCurrentInputMethod() const OVERRIDE; 153 virtual bool IsAltGrUsedByCurrentInputMethod() const OVERRIDE; 154 155 virtual ImeKeyboard* GetImeKeyboard() OVERRIDE; 156 virtual InputMethodUtil* GetInputMethodUtil() OVERRIDE; 157 virtual ComponentExtensionIMEManager* 158 GetComponentExtensionIMEManager() OVERRIDE; 159 virtual bool IsLoginKeyboard(const std::string& layout) const OVERRIDE; 160 161 virtual bool MigrateInputMethods( 162 std::vector<std::string>* input_method_ids) OVERRIDE; 163 164 virtual scoped_refptr<InputMethodManager::State> CreateNewState( 165 Profile* profile) OVERRIDE; 166 167 virtual scoped_refptr<InputMethodManager::State> GetActiveIMEState() OVERRIDE; 168 virtual void SetState( 169 scoped_refptr<InputMethodManager::State> state) OVERRIDE; 170 171 // Sets |candidate_window_controller_|. 172 void SetCandidateWindowControllerForTesting( 173 CandidateWindowController* candidate_window_controller); 174 // Sets |keyboard_|. 175 void SetImeKeyboardForTesting(ImeKeyboard* keyboard); 176 // Initialize |component_extension_manager_|. 177 void InitializeComponentExtensionForTesting( 178 scoped_ptr<ComponentExtensionIMEManagerDelegate> delegate); 179 180 private: 181 friend class InputMethodManagerImplTest; 182 183 // CandidateWindowController::Observer overrides: 184 virtual void CandidateClicked(int index) OVERRIDE; 185 virtual void CandidateWindowOpened() OVERRIDE; 186 virtual void CandidateWindowClosed() OVERRIDE; 187 188 // Temporarily deactivates all input methods (e.g. Chinese, Japanese, Arabic) 189 // since they are not necessary to input a login password. Users are still 190 // able to use/switch active keyboard layouts (e.g. US qwerty, US dvorak, 191 // French). 192 void OnScreenLocked(); 193 194 // Resumes the original state by activating input methods and/or changing the 195 // current input method as needed. 196 void OnScreenUnlocked(); 197 198 // Returns true if the given input method config value is a string list 199 // that only contains an input method ID of a keyboard layout. 200 bool ContainsOnlyKeyboardLayout(const std::vector<std::string>& value); 201 202 // Creates and initializes |candidate_window_controller_| if it hasn't been 203 // done. 204 void MaybeInitializeCandidateWindowController(); 205 206 // Returns Input Method that best matches given id. 207 const InputMethodDescriptor* LookupInputMethod( 208 const std::string& input_method_id, 209 StateImpl* state); 210 211 // Change system input method. 212 void ChangeInputMethodInternal(const InputMethodDescriptor& descriptor, 213 bool show_message, 214 bool notify_menu); 215 216 // Loads necessary component extensions. 217 // TODO(nona): Support dynamical unloading. 218 void LoadNecessaryComponentExtensions(StateImpl* state); 219 220 // Starts or stops the system input method framework as needed. 221 // (after list of enabled input methods has been updated). 222 // If state is active, active input method is updated. 223 void ReconfigureIMFramework(StateImpl* state); 224 225 // Record input method usage histograms. 226 void RecordInputMethodUsage(std::string input_method_id); 227 228 scoped_ptr<InputMethodDelegate> delegate_; 229 230 // The current UI session status. 231 UISessionState ui_session_; 232 233 // A list of objects that monitor the manager. 234 ObserverList<InputMethodManager::Observer> observers_; 235 ObserverList<CandidateWindowObserver> candidate_window_observers_; 236 237 scoped_refptr<StateImpl> state_; 238 239 // The candidate window. This will be deleted when the APP_TERMINATING 240 // message is sent. 241 scoped_ptr<CandidateWindowController> candidate_window_controller_; 242 243 // An object which provides miscellaneous input method utility functions. Note 244 // that |util_| is required to initialize |keyboard_|. 245 InputMethodUtil util_; 246 247 // An object which provides component extension ime management functions. 248 scoped_ptr<ComponentExtensionIMEManager> component_extension_ime_manager_; 249 250 // An object for switching XKB layouts and keyboard status like caps lock and 251 // auto-repeat interval. 252 scoped_ptr<ImeKeyboard> keyboard_; 253 254 255 // Whether load IME extensions. 256 bool enable_extension_loading_; 257 258 // The engine map from extension_id to an engine. 259 typedef std::map<std::string, InputMethodEngineInterface*> EngineMap; 260 EngineMap engine_map_; 261 262 // The map from input method id to the input method stat id. 263 // The stat id has the format: <category#><first char after prefix><index> 264 // For example, Chinese Simplified Pinyin IME has the stat id: 265 // 2,'p',1 -> 211201 266 // 2 means it in INPUT_METHOD_CATEGORY_ZH; 267 // 112 means the first char after prefix is 'p' of 'pinyin'; 268 // 01 means it's the second pinyin as the first pinyin is for Traditional 269 // Chinese Pinyin IME. Note "zh-hant-t-i0-pinyin" < "zh-t-i0-pinyin". 270 std::map<std::string, int> stat_id_map_; 271 272 DISALLOW_COPY_AND_ASSIGN(InputMethodManagerImpl); 273 }; 274 275 } // namespace input_method 276 } // namespace chromeos 277 278 #endif // CHROME_BROWSER_CHROMEOS_INPUT_METHOD_INPUT_METHOD_MANAGER_IMPL_H_ 279