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