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 UI_BASE_IME_CHROMEOS_INPUT_METHOD_MANAGER_H_
6 #define UI_BASE_IME_CHROMEOS_INPUT_METHOD_MANAGER_H_
7 
8 #include <stddef.h>
9 
10 #include <map>
11 #include <memory>
12 #include <string>
13 #include <vector>
14 
15 #include "base/component_export.h"
16 #include "base/memory/ref_counted.h"
17 #include "chromeos/services/ime/public/mojom/input_engine.mojom.h"
18 #include "mojo/public/cpp/bindings/pending_receiver.h"
19 #include "ui/base/ime/chromeos/ime_keyset.h"
20 #include "ui/base/ime/chromeos/input_method_descriptor.h"
21 
22 class Profile;
23 
24 namespace ui {
25 class IMEEngineHandlerInterface;
26 class InputMethodKeyboardController;
27 }  // namespace ui
28 
29 namespace chromeos {
30 class ComponentExtensionIMEManager;
31 namespace input_method {
32 class InputMethodUtil;
33 class ImeKeyboard;
34 
35 // This class manages input methodshandles.  Classes can add themselves as
36 // observers. Clients can get an instance of this library class by:
37 // InputMethodManager::Get().
COMPONENT_EXPORT(UI_BASE_IME_CHROMEOS)38 class COMPONENT_EXPORT(UI_BASE_IME_CHROMEOS) InputMethodManager {
39  public:
40   enum class UIStyle {
41     kLogin,
42     kSecondaryLogin,
43     kLock,
44     kNormal,
45   };
46 
47   enum MenuItemStyle {
48     MENU_ITEM_STYLE_NONE,
49     MENU_ITEM_STYLE_CHECK,
50     MENU_ITEM_STYLE_RADIO,
51     MENU_ITEM_STYLE_SEPARATOR,
52   };
53 
54   struct MenuItem {
55     MenuItem();
56     MenuItem(const MenuItem& other);
57     virtual ~MenuItem();
58 
59     std::string id;
60     std::string label;
61     MenuItemStyle style;
62     bool visible;
63     bool enabled;
64     bool checked;
65 
66     unsigned int modified;
67     std::vector<MenuItem> children;
68   };
69 
70   enum ImeMenuFeature {
71     FEATURE_EMOJI = 1 << 0,
72     FEATURE_HANDWRITING = 1 << 1,
73     FEATURE_VOICE = 1 << 2,
74     FEATURE_ALL = ~0,
75   };
76 
77   class Observer {
78    public:
79     virtual ~Observer() = default;
80     // Called when the current input method is changed.  |show_message|
81     // indicates whether the user should be notified of this change.
82     virtual void InputMethodChanged(InputMethodManager* manager,
83                                     Profile* profile,
84                                     bool show_message) = 0;
85     // Called when the availability of any of the extra input methods (emoji,
86     // handwriting, voice) has changed. The overall state is toggle-able
87     // independently of the individual options.
88     virtual void OnExtraInputEnabledStateChange(
89         bool is_extra_input_options_enabled,
90         bool is_emoji_enabled,
91         bool is_handwriting_enabled,
92         bool is_voice_enabled) {}
93 
94     // Called when an input method extension is added or removed.
95     virtual void OnInputMethodExtensionAdded(const std::string& extension_id) {}
96     virtual void OnInputMethodExtensionRemoved(
97         const std::string& extension_id) {}
98   };
99 
100   // CandidateWindowObserver is notified of events related to the candidate
101   // window.  The "suggestion window" used by IMEs such as ibus-mozc does not
102   // count as the candidate window (this may change if we later want suggestion
103   // window events as well).  These events also won't occur when the virtual
104   // keyboard is used, since it controls its own candidate window.
105   class CandidateWindowObserver {
106    public:
107     virtual ~CandidateWindowObserver() = default;
108     // Called when the candidate window is opened.
109     virtual void CandidateWindowOpened(InputMethodManager* manager) = 0;
110     // Called when the candidate window is closed.
111     virtual void CandidateWindowClosed(InputMethodManager* manager) = 0;
112   };
113 
114   // ImeMenuObserver is notified of events related to the IME menu on the shelf
115   // bar.
116   class ImeMenuObserver {
117    public:
118     virtual ~ImeMenuObserver() = default;
119 
120     // Called when the IME menu is activated or deactivated.
121     virtual void ImeMenuActivationChanged(bool is_active) = 0;
122     // Called when the current input method or the list of active input method
123     // IDs is changed.
124     virtual void ImeMenuListChanged() = 0;
125     // Called when the input.ime.setMenuItems or input.ime.updateMenuItems API
126     // is called.
127     virtual void ImeMenuItemsChanged(const std::string& engine_id,
128                                      const std::vector<MenuItem>& items) = 0;
129 
130     DISALLOW_ASSIGN(ImeMenuObserver);
131   };
132 
133   class State : public base::RefCounted<InputMethodManager::State> {
134    public:
135     // Returns a copy of state.
136     virtual scoped_refptr<State> Clone() const = 0;
137 
138     // Adds an input method extension. This function does not takes ownership of
139     // |instance|.
140     virtual void AddInputMethodExtension(
141         const std::string& extension_id,
142         const InputMethodDescriptors& descriptors,
143         ui::IMEEngineHandlerInterface* instance) = 0;
144 
145     // Removes an input method extension.
146     virtual void RemoveInputMethodExtension(
147         const std::string& extension_id) = 0;
148 
149     // Changes the current input method to |input_method_id|. If
150     // |input_method_id|
151     // is not active, switch to the first one in the active input method list.
152     virtual void ChangeInputMethod(const std::string& input_method_id,
153                                    bool show_message) = 0;
154 
155     // Switching the input methods for JP106 language input keys.
156     virtual void ChangeInputMethodToJpKeyboard() = 0;
157     virtual void ChangeInputMethodToJpIme() = 0;
158     virtual void ToggleInputMethodForJpIme() = 0;
159 
160     // Adds one entry to the list of active input method IDs, and then starts or
161     // stops the system input method framework as needed.
162     virtual bool EnableInputMethod(
163         const std::string& new_active_input_method_id) = 0;
164 
165     // Enables "login" keyboard layouts (e.g. US Qwerty, US Dvorak, French
166     // Azerty) that are necessary for the |language_code| and then switches to
167     // |initial_layouts| if the given list is not empty. For example, if
168     // |language_code| is "en-US", US Qwerty, US International, US Extended, US
169     // Dvorak, and US Colemak layouts would be enabled. Likewise, for Germany
170     // locale, US Qwerty which corresponds to the hardware keyboard layout and
171     // several keyboard layouts for Germany would be enabled.
172     // Only layouts suitable for login screen are enabled.
173     virtual void EnableLoginLayouts(
174         const std::string& language_code,
175         const std::vector<std::string>& initial_layouts) = 0;
176 
177     // Filters current state layouts and leaves only suitable for lock screen.
178     virtual void EnableLockScreenLayouts() = 0;
179 
180     // Returns a list of descriptors for all Input Method Extensions.
181     virtual void GetInputMethodExtensions(InputMethodDescriptors* result) = 0;
182 
183     // Returns the list of input methods we can select (i.e. active) including
184     // extension input methods.
185     virtual std::unique_ptr<InputMethodDescriptors> GetActiveInputMethods()
186         const = 0;
187 
188     // Returns the list of input methods we can select (i.e. active) including
189     // extension input methods.
190     // The same as GetActiveInputMethods but returns reference to internal list.
191     virtual const std::vector<std::string>& GetActiveInputMethodIds() const = 0;
192 
193     // Returns the number of active input methods including extension input
194     // methods.
195     virtual size_t GetNumActiveInputMethods() const = 0;
196 
197     // Returns the input method descriptor from the given input method id
198     // string.
199     // If the given input method id is invalid, returns NULL.
200     virtual const InputMethodDescriptor* GetInputMethodFromId(
201         const std::string& input_method_id) const = 0;
202 
203     // Sets the list of extension IME ids which should be enabled.
204     virtual void SetEnabledExtensionImes(std::vector<std::string>* ids) = 0;
205 
206     // Sets current input method to login default (first owners, then hardware).
207     virtual void SetInputMethodLoginDefault() = 0;
208 
209     // Sets current input method to login default with the given locale and
210     // layout info from VPD.
211     virtual void SetInputMethodLoginDefaultFromVPD(
212         const std::string& locale,
213         const std::string& layout) = 0;
214 
215     // Switches the current input method (or keyboard layout) to the next one.
216     virtual void SwitchToNextInputMethod() = 0;
217 
218     // Switches the current input method (or keyboard layout) to the last used
219     // one.
220     virtual void SwitchToLastUsedInputMethod() = 0;
221 
222     // Gets the descriptor of the input method which is currently selected.
223     virtual InputMethodDescriptor GetCurrentInputMethod() const = 0;
224 
225     // Updates the list of active input method IDs, and then starts or stops the
226     // system input method framework as needed.
227     virtual bool ReplaceEnabledInputMethods(
228         const std::vector<std::string>& new_active_input_method_ids) = 0;
229 
230     // Sets the currently allowed input methods (e.g. due to policy). Invalid
231     // input method ids are ignored. Passing an empty vector means that all
232     // input methods are allowed, which is the default.  When
233     // |enable_allowed_input_menthods| is true, the allowed input methods are
234     // also automatically enabled.
235     virtual bool SetAllowedInputMethods(
236         const std::vector<std::string>& allowed_input_method_ids,
237         bool enable_allowed_input_methods) = 0;
238 
239     // Returns the currently allowed input methods, as set by
240     // SetAllowedInputMethodIds. An empty vector means that all input methods
241     // are allowed.
242     virtual const std::vector<std::string>& GetAllowedInputMethods() = 0;
243 
244     // Methods related to custom input view of the input method.
245     // Enables custom input view of the active input method.
246     virtual void EnableInputView() = 0;
247     // Disables custom input view of the active input method.
248     // The fallback system input view will be used.
249     virtual void DisableInputView() = 0;
250     // Returns the URL of the input view of the active input method.
251     virtual const GURL& GetInputViewUrl() const = 0;
252 
253     // Get the current UI screen type (e.g. login screen, lock screen, etc.).
254     virtual InputMethodManager::UIStyle GetUIStyle() const = 0;
255     virtual void SetUIStyle(InputMethodManager::UIStyle ui_style) = 0;
256 
257    protected:
258     friend base::RefCounted<InputMethodManager::State>;
259 
260     virtual ~State();
261   };
262 
263   virtual ~InputMethodManager() = default;
264 
265   // Gets the global instance of InputMethodManager. Initialize() must be called
266   // first.
267   static COMPONENT_EXPORT(UI_BASE_IME_CHROMEOS) InputMethodManager* Get();
268 
269   // Sets the global instance. |instance| will be owned by the internal pointer
270   // and deleted by Shutdown().
271   // TODO(nona): Instanciate InputMethodManagerImpl inside of this function once
272   //             crbug.com/164375 is fixed.
273   static COMPONENT_EXPORT(UI_BASE_IME_CHROMEOS) void Initialize(
274       InputMethodManager* instance);
275 
276   // Destroy the global instance.
277   static COMPONENT_EXPORT(UI_BASE_IME_CHROMEOS) void Shutdown();
278 
279   // Adds an observer to receive notifications of input method related
280   // changes as desribed in the Observer class above.
281   virtual void AddObserver(Observer* observer) = 0;
282   virtual void AddCandidateWindowObserver(
283       CandidateWindowObserver* observer) = 0;
284   virtual void AddImeMenuObserver(ImeMenuObserver* observer) = 0;
285   virtual void RemoveObserver(Observer* observer) = 0;
286   virtual void RemoveCandidateWindowObserver(
287       CandidateWindowObserver* observer) = 0;
288   virtual void RemoveImeMenuObserver(ImeMenuObserver* observer) = 0;
289 
290   // Returns all input methods that are supported, including ones not active.
291   // This function never returns NULL. Note that input method extensions are NOT
292   // included in the result.
293   virtual std::unique_ptr<InputMethodDescriptors> GetSupportedInputMethods()
294       const = 0;
295 
296   // Activates the input method property specified by the |key|.
297   virtual void ActivateInputMethodMenuItem(const std::string& key) = 0;
298 
299   // Connects a receiver to the InputEngineManager instance.
300   virtual void ConnectInputEngineManager(
301       mojo::PendingReceiver<chromeos::ime::mojom::InputEngineManager>
302           receiver) = 0;
303 
304   virtual bool IsISOLevel5ShiftUsedByCurrentInputMethod() const = 0;
305 
306   virtual bool IsAltGrUsedByCurrentInputMethod() const = 0;
307 
308   // Returns an X keyboard object which could be used to change the current XKB
309   // layout, change the caps lock status, and set the auto repeat rate/interval.
310   virtual ImeKeyboard* GetImeKeyboard() = 0;
311 
312   // Returns an InputMethodUtil object.
313   virtual InputMethodUtil* GetInputMethodUtil() = 0;
314 
315   // Returns a ComponentExtentionIMEManager object.
316   virtual ComponentExtensionIMEManager* GetComponentExtensionIMEManager() = 0;
317 
318   // If keyboard layout can be uset at login screen
319   virtual bool IsLoginKeyboard(const std::string& layout) const = 0;
320 
321   // Migrates the input method id to extension-based input method id.
322   virtual bool MigrateInputMethods(
323       std::vector<std::string>* input_method_ids) = 0;
324 
325   // Returns new empty state for the |profile|.
326   virtual scoped_refptr<State> CreateNewState(Profile* profile) = 0;
327 
328   // Returns active state.
329   virtual scoped_refptr<InputMethodManager::State> GetActiveIMEState() = 0;
330 
331   // Replaces active state.
332   virtual void SetState(scoped_refptr<State> state) = 0;
333 
334   // Activates or deactivates the IME Menu.
335   virtual void ImeMenuActivationChanged(bool is_active) = 0;
336 
337   // Notifies the input.ime.setMenuItems or input.ime.updateMenuItems API is
338   // called to update the IME menu items.
339   virtual void NotifyImeMenuItemsChanged(
340       const std::string& engine_id,
341       const std::vector<MenuItem>& items) = 0;
342 
343   // Notify the IME menu activation changed if the current profile's activation
344   // is different from previous.
345   virtual void MaybeNotifyImeMenuActivationChanged() = 0;
346 
347   // Overrides active keyset with the given keyset if the active IME supports
348   // the given keyset.
349   virtual void OverrideKeyboardKeyset(ImeKeyset keyset) = 0;
350 
351   // Enables or disables some advanced features, e.g. handwiring, voices input.
352   virtual void SetImeMenuFeatureEnabled(ImeMenuFeature feature,
353                                         bool enabled) = 0;
354 
355   // Returns the true if the given feature is enabled.
356   virtual bool GetImeMenuFeatureEnabled(ImeMenuFeature feature) const = 0;
357 
358   // Notifies when any of the extra inputs (emoji, handwriting, voice) enabled
359   // status has changed.
360   virtual void NotifyObserversImeExtraInputStateChange() = 0;
361 
362   // Gets the implementation of the keyboard controller.
363   virtual ui::InputMethodKeyboardController*
364   GetInputMethodKeyboardController() = 0;
365 
366   // Notifies an input method extension is added or removed.
367   virtual void NotifyInputMethodExtensionAdded(
368       const std::string& extension_id) = 0;
369   virtual void NotifyInputMethodExtensionRemoved(
370       const std::string& extension_id) = 0;
371 };
372 
373 }  // namespace input_method
374 }  // namespace chromeos
375 
376 #endif  // UI_BASE_IME_CHROMEOS_INPUT_METHOD_MANAGER_H_
377