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 // Constructs an InputMethodManager instance. The client is responsible for 34 // calling |SetState| in response to relevant changes in browser state. 35 explicit InputMethodManagerImpl(scoped_ptr<InputMethodDelegate> delegate); 36 virtual ~InputMethodManagerImpl(); 37 38 // Attach CandidateWindowController, and ImeKeyboard objects to the 39 // InputMethodManagerImpl object. You don't have to call this 40 // function if you attach them yourself (e.g. in unit tests) using 41 // the protected setters. 42 void Init(base::SequencedTaskRunner* ui_task_runner); 43 44 // Receives notification of an InputMethodManager::State transition. 45 void SetState(State new_state); 46 47 // InputMethodManager override: 48 virtual void AddObserver(InputMethodManager::Observer* observer) OVERRIDE; 49 virtual void AddCandidateWindowObserver( 50 InputMethodManager::CandidateWindowObserver* observer) OVERRIDE; 51 virtual void RemoveObserver(InputMethodManager::Observer* observer) OVERRIDE; 52 virtual void RemoveCandidateWindowObserver( 53 InputMethodManager::CandidateWindowObserver* observer) OVERRIDE; 54 virtual scoped_ptr<InputMethodDescriptors> 55 GetSupportedInputMethods() const OVERRIDE; 56 virtual scoped_ptr<InputMethodDescriptors> 57 GetActiveInputMethods() const OVERRIDE; 58 virtual const std::vector<std::string>& GetActiveInputMethodIds() const 59 OVERRIDE; 60 virtual size_t GetNumActiveInputMethods() const OVERRIDE; 61 virtual const InputMethodDescriptor* GetInputMethodFromId( 62 const std::string& input_method_id) const OVERRIDE; 63 virtual void EnableLoginLayouts( 64 const std::string& language_code, 65 const std::vector<std::string>& initial_layouts) OVERRIDE; 66 virtual bool ReplaceEnabledInputMethods( 67 const std::vector<std::string>& new_active_input_method_ids) OVERRIDE; 68 virtual bool EnableInputMethod(const std::string& new_active_input_method_id) 69 OVERRIDE; 70 virtual void ChangeInputMethod(const std::string& input_method_id) OVERRIDE; 71 virtual void ActivateInputMethodMenuItem(const std::string& key) OVERRIDE; 72 virtual void AddInputMethodExtension( 73 Profile* profile, 74 const std::string& id, 75 InputMethodEngineInterface* instance) OVERRIDE; 76 virtual void RemoveInputMethodExtension(Profile* profile, 77 const std::string& id) OVERRIDE; 78 virtual void GetInputMethodExtensions( 79 InputMethodDescriptors* result) OVERRIDE; 80 virtual void SetEnabledExtensionImes(std::vector<std::string>* ids) OVERRIDE; 81 virtual void SetInputMethodLoginDefault() OVERRIDE; 82 virtual void SetInputMethodLoginDefaultFromVPD( 83 const std::string& locale, const std::string& layout) OVERRIDE; 84 virtual bool SwitchToNextInputMethod() OVERRIDE; 85 virtual bool SwitchToPreviousInputMethod( 86 const ui::Accelerator& accelerator) OVERRIDE; 87 virtual bool SwitchInputMethod(const ui::Accelerator& accelerator) OVERRIDE; 88 virtual InputMethodDescriptor GetCurrentInputMethod() const OVERRIDE; 89 virtual bool IsISOLevel5ShiftUsedByCurrentInputMethod() const OVERRIDE; 90 virtual bool IsAltGrUsedByCurrentInputMethod() const OVERRIDE; 91 92 virtual ImeKeyboard* GetImeKeyboard() OVERRIDE; 93 virtual InputMethodUtil* GetInputMethodUtil() OVERRIDE; 94 virtual ComponentExtensionIMEManager* 95 GetComponentExtensionIMEManager() OVERRIDE; 96 virtual bool IsLoginKeyboard(const std::string& layout) const OVERRIDE; 97 98 virtual bool MigrateInputMethods( 99 std::vector<std::string>* input_method_ids) OVERRIDE; 100 101 // Sets |candidate_window_controller_|. 102 void SetCandidateWindowControllerForTesting( 103 CandidateWindowController* candidate_window_controller); 104 // Sets |keyboard_|. 105 void SetImeKeyboardForTesting(ImeKeyboard* keyboard); 106 // Initialize |component_extension_manager_|. 107 void InitializeComponentExtensionForTesting( 108 scoped_ptr<ComponentExtensionIMEManagerDelegate> delegate); 109 110 private: 111 friend class InputMethodManagerImplTest; 112 113 // CandidateWindowController::Observer overrides: 114 virtual void CandidateClicked(int index) OVERRIDE; 115 virtual void CandidateWindowOpened() OVERRIDE; 116 virtual void CandidateWindowClosed() OVERRIDE; 117 118 // Temporarily deactivates all input methods (e.g. Chinese, Japanese, Arabic) 119 // since they are not necessary to input a login password. Users are still 120 // able to use/switch active keyboard layouts (e.g. US qwerty, US dvorak, 121 // French). 122 void OnScreenLocked(); 123 124 // Resumes the original state by activating input methods and/or changing the 125 // current input method as needed. 126 void OnScreenUnlocked(); 127 128 // Returns true if |input_method_id| is in |active_input_method_ids_|. 129 bool InputMethodIsActivated(const std::string& input_method_id); 130 131 // Returns true if the given input method config value is a string list 132 // that only contains an input method ID of a keyboard layout. 133 bool ContainsOnlyKeyboardLayout(const std::vector<std::string>& value); 134 135 // Creates and initializes |candidate_window_controller_| if it hasn't been 136 // done. 137 void MaybeInitializeCandidateWindowController(); 138 139 // If |current_input_method_id_| is not in |input_method_ids|, switch to 140 // input_method_ids[0]. If the ID is equal to input_method_ids[N], switch to 141 // input_method_ids[N+1]. 142 void SwitchToNextInputMethodInternal( 143 const std::vector<std::string>& input_method_ids, 144 const std::string& current_input_method_id); 145 146 // Change system input method. 147 // Returns true if the system input method is changed. 148 bool ChangeInputMethodInternal(const std::string& input_method_id, 149 bool show_message); 150 151 // Gets whether the XKB extension is loaded successfully by checking the XKB 152 // input methods in input methods in |component_extension_ime_manager_|. 153 bool IsXkbComponentExtensionAvailable() const; 154 155 // Called when the ComponentExtensionIMEManagerDelegate is initialized. 156 void OnComponentExtensionInitialized( 157 scoped_ptr<ComponentExtensionIMEManagerDelegate> delegate); 158 void InitializeComponentExtension(); 159 160 // Loads necessary component extensions. 161 // TODO(nona): Support dynamical unloading. 162 void LoadNecessaryComponentExtensions(); 163 164 // Adds new input method to given list if possible 165 bool EnableInputMethodImpl( 166 const std::string& input_method_id, 167 std::vector<std::string>* new_active_input_method_ids) const; 168 169 // Starts or stops the system input method framework as needed. 170 // (after list of enabled input methods has been updated) 171 void ReconfigureIMFramework(); 172 173 // Gets the current active user profile. 174 // Note: this method is deprecated as ActiveUserProfile might change 175 // during asynchronous operations that leads to strange crashes. 176 // Use with caution! 177 Profile* GetProfile() const; 178 179 scoped_ptr<InputMethodDelegate> delegate_; 180 181 // The current browser status. 182 State state_; 183 184 // A list of objects that monitor the manager. 185 ObserverList<InputMethodManager::Observer> observers_; 186 ObserverList<CandidateWindowObserver> candidate_window_observers_; 187 188 // The input method which was/is selected. 189 InputMethodDescriptor previous_input_method_; 190 InputMethodDescriptor current_input_method_; 191 // The active input method ids cache. 192 std::vector<std::string> active_input_method_ids_; 193 194 // The list of enabled extension IMEs. 195 std::vector<std::string> enabled_extension_imes_; 196 197 // For screen locker. When the screen is locked, |previous_input_method_|, 198 // |current_input_method_|, and |active_input_method_ids_| above are copied 199 // to these "saved" variables. 200 InputMethodDescriptor saved_previous_input_method_; 201 InputMethodDescriptor saved_current_input_method_; 202 std::vector<std::string> saved_active_input_method_ids_; 203 204 // Extra input methods that have been explicitly added to the menu, such as 205 // those created by extension. 206 std::map<std::string, InputMethodDescriptor> extra_input_methods_; 207 208 // The candidate window. This will be deleted when the APP_TERMINATING 209 // message is sent. 210 scoped_ptr<CandidateWindowController> candidate_window_controller_; 211 212 // The object which can create an InputMethodDescriptor object. 213 InputMethodWhitelist whitelist_; 214 215 // An object which provides miscellaneous input method utility functions. Note 216 // that |util_| is required to initialize |keyboard_|. 217 InputMethodUtil util_; 218 219 // An object which provides component extension ime management functions. 220 scoped_ptr<ComponentExtensionIMEManager> component_extension_ime_manager_; 221 222 // An object for switching XKB layouts and keyboard status like caps lock and 223 // auto-repeat interval. 224 scoped_ptr<ImeKeyboard> keyboard_; 225 226 std::string pending_input_method_; 227 228 base::ThreadChecker thread_checker_; 229 230 base::WeakPtrFactory<InputMethodManagerImpl> weak_ptr_factory_; 231 232 // The engine map: 233 // { Profile : { input_method_id : Engine } }. 234 typedef std::map<std::string, InputMethodEngineInterface*> 235 EngineMap; 236 typedef std::map<Profile*, EngineMap, ProfileCompare> ProfileEngineMap; 237 ProfileEngineMap profile_engine_map_; 238 239 DISALLOW_COPY_AND_ASSIGN(InputMethodManagerImpl); 240 }; 241 242 } // namespace input_method 243 } // namespace chromeos 244 245 #endif // CHROME_BROWSER_CHROMEOS_INPUT_METHOD_INPUT_METHOD_MANAGER_IMPL_H_ 246