Home | History | Annotate | Download | only in input_method
      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