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_EXTENSIONS_API_INPUT_IME_INPUT_IME_API_H_
6#define CHROME_BROWSER_EXTENSIONS_API_INPUT_IME_INPUT_IME_API_H_
7
8#include <map>
9#include <string>
10#include <vector>
11
12#include "base/memory/singleton.h"
13#include "base/scoped_observer.h"
14#include "base/values.h"
15#include "chrome/browser/chromeos/input_method/input_method_engine_interface.h"
16#include "chrome/browser/profiles/profile.h"
17#include "components/keyed_service/core/keyed_service.h"
18#include "extensions/browser/browser_context_keyed_api_factory.h"
19#include "extensions/browser/event_router.h"
20#include "extensions/browser/extension_function.h"
21#include "extensions/browser/extension_registry_observer.h"
22#include "extensions/common/extension.h"
23
24class Profile;
25
26namespace chromeos {
27class InputMethodEngineInterface;
28class ImeObserver;
29}  // namespace chromeos
30
31namespace extensions {
32class ExtensionRegistry;
33struct InputComponentInfo;
34
35class InputImeEventRouter {
36 public:
37  static InputImeEventRouter* GetInstance();
38
39  bool RegisterImeExtension(
40      Profile* profile,
41      const std::string& extension_id,
42      const std::vector<extensions::InputComponentInfo>& input_components);
43  void UnregisterAllImes(const std::string& extension_id);
44
45  chromeos::InputMethodEngineInterface* GetEngine(
46      const std::string& extension_id,
47      const std::string& component_id);
48  chromeos::InputMethodEngineInterface* GetActiveEngine(
49      const std::string& extension_id);
50
51
52  // Called when a key event was handled.
53  void OnKeyEventHandled(const std::string& extension_id,
54                         const std::string& request_id,
55                         bool handled);
56
57  std::string AddRequest(const std::string& component_id,
58                         chromeos::input_method::KeyEventHandle* key_data);
59
60 private:
61  friend struct DefaultSingletonTraits<InputImeEventRouter>;
62  typedef std::map<std::string, std::pair<std::string,
63          chromeos::input_method::KeyEventHandle*> > RequestMap;
64
65  InputImeEventRouter();
66  ~InputImeEventRouter();
67
68  // The engine map from extension_id to an engine.
69  std::map<std::string, chromeos::InputMethodEngineInterface*> engine_map_;
70
71  unsigned int next_request_id_;
72  RequestMap request_map_;
73
74  DISALLOW_COPY_AND_ASSIGN(InputImeEventRouter);
75};
76
77class InputImeSetCompositionFunction : public SyncExtensionFunction {
78 public:
79  DECLARE_EXTENSION_FUNCTION("input.ime.setComposition",
80                             INPUT_IME_SETCOMPOSITION)
81
82 protected:
83  virtual ~InputImeSetCompositionFunction() {}
84
85  // ExtensionFunction:
86  virtual bool RunSync() OVERRIDE;
87};
88
89class InputImeClearCompositionFunction : public SyncExtensionFunction {
90 public:
91  DECLARE_EXTENSION_FUNCTION("input.ime.clearComposition",
92                             INPUT_IME_CLEARCOMPOSITION)
93
94 protected:
95  virtual ~InputImeClearCompositionFunction() {}
96
97  // ExtensionFunction:
98  virtual bool RunSync() OVERRIDE;
99};
100
101class InputImeCommitTextFunction : public SyncExtensionFunction {
102 public:
103  DECLARE_EXTENSION_FUNCTION("input.ime.commitText", INPUT_IME_COMMITTEXT)
104
105 protected:
106  virtual ~InputImeCommitTextFunction() {}
107
108  // ExtensionFunction:
109  virtual bool RunSync() OVERRIDE;
110};
111
112class InputImeSetCandidateWindowPropertiesFunction
113    : public SyncExtensionFunction {
114 public:
115  DECLARE_EXTENSION_FUNCTION("input.ime.setCandidateWindowProperties",
116                             INPUT_IME_SETCANDIDATEWINDOWPROPERTIES)
117
118 protected:
119  virtual ~InputImeSetCandidateWindowPropertiesFunction() {}
120
121  // ExtensionFunction:
122  virtual bool RunSync() OVERRIDE;
123};
124
125class InputImeSetCandidatesFunction : public SyncExtensionFunction {
126 public:
127  DECLARE_EXTENSION_FUNCTION("input.ime.setCandidates", INPUT_IME_SETCANDIDATES)
128
129 protected:
130  virtual ~InputImeSetCandidatesFunction() {}
131
132  // ExtensionFunction:
133  virtual bool RunSync() OVERRIDE;
134};
135
136class InputImeSetCursorPositionFunction : public SyncExtensionFunction {
137 public:
138  DECLARE_EXTENSION_FUNCTION("input.ime.setCursorPosition",
139                             INPUT_IME_SETCURSORPOSITION)
140
141 protected:
142  virtual ~InputImeSetCursorPositionFunction() {}
143
144  // ExtensionFunction:
145  virtual bool RunSync() OVERRIDE;
146};
147
148class InputImeSetMenuItemsFunction : public SyncExtensionFunction {
149 public:
150  DECLARE_EXTENSION_FUNCTION("input.ime.setMenuItems", INPUT_IME_SETMENUITEMS)
151
152 protected:
153  virtual ~InputImeSetMenuItemsFunction() {}
154
155  // ExtensionFunction:
156  virtual bool RunSync() OVERRIDE;
157};
158
159class InputImeUpdateMenuItemsFunction : public SyncExtensionFunction {
160 public:
161  DECLARE_EXTENSION_FUNCTION("input.ime.updateMenuItems",
162                             INPUT_IME_UPDATEMENUITEMS)
163
164 protected:
165  virtual ~InputImeUpdateMenuItemsFunction() {}
166
167  // ExtensionFunction:
168  virtual bool RunSync() OVERRIDE;
169};
170
171class InputImeDeleteSurroundingTextFunction : public SyncExtensionFunction {
172 public:
173  DECLARE_EXTENSION_FUNCTION("input.ime.deleteSurroundingText",
174                             INPUT_IME_DELETESURROUNDINGTEXT)
175 protected:
176  virtual ~InputImeDeleteSurroundingTextFunction() {}
177
178  // ExtensionFunction:
179  virtual bool RunSync() OVERRIDE;
180};
181
182class InputImeKeyEventHandledFunction : public AsyncExtensionFunction {
183 public:
184  DECLARE_EXTENSION_FUNCTION("input.ime.keyEventHandled",
185                             INPUT_IME_KEYEVENTHANDLED)
186
187 protected:
188  virtual ~InputImeKeyEventHandledFunction() {}
189
190  // ExtensionFunction:
191  virtual bool RunAsync() OVERRIDE;
192};
193
194class InputImeSendKeyEventsFunction : public AsyncExtensionFunction {
195 public:
196  DECLARE_EXTENSION_FUNCTION("input.ime.sendKeyEvents",
197                             INPUT_IME_SENDKEYEVENTS)
198
199 protected:
200  virtual ~InputImeSendKeyEventsFunction() {}
201
202  // ExtensionFunction:
203  virtual bool RunAsync() OVERRIDE;
204};
205
206class InputImeHideInputViewFunction : public AsyncExtensionFunction {
207 public:
208  DECLARE_EXTENSION_FUNCTION("input.ime.hideInputView",
209                             INPUT_IME_HIDEINPUTVIEW)
210
211 protected:
212  virtual ~InputImeHideInputViewFunction() {}
213
214  // ExtensionFunction:
215  virtual bool RunAsync() OVERRIDE;
216};
217
218class InputImeAPI : public BrowserContextKeyedAPI,
219                    public ExtensionRegistryObserver,
220                    public EventRouter::Observer {
221 public:
222  explicit InputImeAPI(content::BrowserContext* context);
223  virtual ~InputImeAPI();
224
225  // BrowserContextKeyedAPI implementation.
226  static BrowserContextKeyedAPIFactory<InputImeAPI>* GetFactoryInstance();
227
228  // ExtensionRegistryObserver implementation.
229  virtual void OnExtensionLoaded(content::BrowserContext* browser_context,
230                                 const Extension* extension) OVERRIDE;
231  virtual void OnExtensionUnloaded(
232      content::BrowserContext* browser_context,
233      const Extension* extension,
234      UnloadedExtensionInfo::Reason reason) OVERRIDE;
235
236  // EventRouter::Observer implementation.
237  virtual void OnListenerAdded(const EventListenerInfo& details) OVERRIDE;
238
239 private:
240  friend class BrowserContextKeyedAPIFactory<InputImeAPI>;
241  InputImeEventRouter* input_ime_event_router();
242
243  // BrowserContextKeyedAPI implementation.
244  static const char* service_name() {
245    return "InputImeAPI";
246  }
247  static const bool kServiceIsNULLWhileTesting = true;
248
249  content::BrowserContext* const browser_context_;
250
251  // Listen to extension load, unloaded notifications.
252  ScopedObserver<ExtensionRegistry, ExtensionRegistryObserver>
253      extension_registry_observer_;
254};
255
256}  // namespace extensions
257
258#endif  // CHROME_BROWSER_EXTENSIONS_API_INPUT_IME_INPUT_IME_API_H_
259