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/macros.h" 13 #include "base/memory/singleton.h" 14 #include "base/scoped_observer.h" 15 #include "base/values.h" 16 #include "build/build_config.h" 17 #include "chrome/browser/profiles/profile.h" 18 #include "chrome/browser/ui/input_method/input_method_engine_base.h" 19 #include "chrome/common/extensions/api/input_ime.h" 20 #include "components/keyed_service/core/keyed_service.h" 21 #include "extensions/browser/browser_context_keyed_api_factory.h" 22 #include "extensions/browser/event_router.h" 23 #include "extensions/browser/event_router_factory.h" 24 #include "extensions/browser/extension_function.h" 25 #include "extensions/browser/extension_registry_factory.h" 26 #include "extensions/browser/extension_registry_observer.h" 27 #include "extensions/common/extension.h" 28 #include "ui/base/ime/ime_bridge_observer.h" 29 #include "ui/base/ime/ime_engine_handler_interface.h" 30 #include "ui/base/ime/text_input_flags.h" 31 32 #if defined(OS_CHROMEOS) 33 #include "chrome/browser/extensions/api/input_ime/input_ime_api_chromeos.h" 34 #elif defined(OS_LINUX) || defined(OS_WIN) || defined(OS_BSD) 35 #include "chrome/browser/extensions/api/input_ime/input_ime_api_nonchromeos.h" 36 #endif // defined(OS_CHROMEOS) 37 38 class Profile; 39 40 namespace ui { 41 class IMEEngineHandlerInterface; 42 43 class ImeObserver : public input_method::InputMethodEngineBase::Observer { 44 public: 45 ImeObserver(const std::string& extension_id, Profile* profile); 46 47 ~ImeObserver() override = default; 48 49 // input_method::InputMethodEngineBase::Observer overrides. 50 void OnActivate(const std::string& component_id) override; 51 void OnFocus(const IMEEngineHandlerInterface::InputContext& context) override; 52 void OnBlur(int context_id) override; 53 void OnKeyEvent( 54 const std::string& component_id, 55 const input_method::InputMethodEngineBase::KeyboardEvent& event, 56 IMEEngineHandlerInterface::KeyEventDoneCallback key_data) override; 57 void OnReset(const std::string& component_id) override; 58 void OnDeactivated(const std::string& component_id) override; 59 void OnCompositionBoundsChanged( 60 const std::vector<gfx::Rect>& bounds) override; 61 void OnSurroundingTextChanged(const std::string& component_id, 62 const base::string16& text, 63 int cursor_pos, 64 int anchor_pos, 65 int offset_pos) override; 66 67 protected: 68 // Helper function used to forward the given event to the |profile_|'s event 69 // router, which dipatches the event the extension with |extension_id_|. 70 virtual void DispatchEventToExtension( 71 extensions::events::HistogramValue histogram_value, 72 const std::string& event_name, 73 std::unique_ptr<base::ListValue> args) = 0; 74 75 // Returns the type of the current screen. 76 virtual std::string GetCurrentScreenType() = 0; 77 78 // Returns true if the extension is ready to accept key event, otherwise 79 // returns false. 80 bool ShouldForwardKeyEvent() const; 81 82 // Returns true if there are any listeners on the given event. 83 // TODO(https://crbug.com/835699): Merge this with |ExtensionHasListener|. 84 bool HasListener(const std::string& event_name) const; 85 86 // Returns true if the extension has any listeners on the given event. 87 bool ExtensionHasListener(const std::string& event_name) const; 88 89 // Functions used to convert InputContext struct to string 90 std::string ConvertInputContextType( 91 IMEEngineHandlerInterface::InputContext input_context); 92 virtual bool ConvertInputContextAutoCorrect( 93 IMEEngineHandlerInterface::InputContext input_context); 94 virtual bool ConvertInputContextAutoComplete( 95 IMEEngineHandlerInterface::InputContext input_context); 96 virtual bool ConvertInputContextSpellCheck( 97 IMEEngineHandlerInterface::InputContext input_context); 98 99 std::string extension_id_; 100 Profile* profile_; 101 102 private: 103 extensions::api::input_ime::AutoCapitalizeType 104 ConvertInputContextAutoCapitalize( 105 IMEEngineHandlerInterface::InputContext input_context); 106 107 DISALLOW_COPY_AND_ASSIGN(ImeObserver); 108 }; 109 110 } // namespace ui 111 112 namespace extensions { 113 class InputImeEventRouter; 114 class ExtensionRegistry; 115 116 class InputImeEventRouterFactory { 117 public: 118 static InputImeEventRouterFactory* GetInstance(); 119 InputImeEventRouter* GetRouter(Profile* profile); 120 void RemoveProfile(Profile* profile); 121 122 private: 123 friend struct base::DefaultSingletonTraits<InputImeEventRouterFactory>; 124 InputImeEventRouterFactory(); 125 ~InputImeEventRouterFactory(); 126 127 std::map<Profile*, InputImeEventRouter*, ProfileCompare> router_map_; 128 129 DISALLOW_COPY_AND_ASSIGN(InputImeEventRouterFactory); 130 }; 131 132 class InputImeKeyEventHandledFunction : public ExtensionFunction { 133 public: 134 DECLARE_EXTENSION_FUNCTION("input.ime.keyEventHandled", 135 INPUT_IME_KEYEVENTHANDLED) 136 137 protected: 138 ~InputImeKeyEventHandledFunction() override = default; 139 140 // ExtensionFunction: 141 ResponseAction Run() override; 142 }; 143 144 class InputImeSetCompositionFunction : public ExtensionFunction { 145 public: 146 DECLARE_EXTENSION_FUNCTION("input.ime.setComposition", 147 INPUT_IME_SETCOMPOSITION) 148 149 protected: 150 ~InputImeSetCompositionFunction() override = default; 151 152 // ExtensionFunction: 153 ResponseAction Run() override; 154 }; 155 156 class InputImeCommitTextFunction : public ExtensionFunction { 157 public: 158 DECLARE_EXTENSION_FUNCTION("input.ime.commitText", INPUT_IME_COMMITTEXT) 159 160 protected: 161 ~InputImeCommitTextFunction() override = default; 162 163 // ExtensionFunction: 164 ResponseAction Run() override; 165 }; 166 167 class InputImeSendKeyEventsFunction : public ExtensionFunction { 168 public: 169 DECLARE_EXTENSION_FUNCTION("input.ime.sendKeyEvents", INPUT_IME_SENDKEYEVENTS) 170 171 protected: 172 ~InputImeSendKeyEventsFunction() override = default; 173 174 // ExtensionFunction: 175 ResponseAction Run() override; 176 }; 177 178 class InputImeAPI : public BrowserContextKeyedAPI, 179 public ExtensionRegistryObserver, 180 public EventRouter::Observer { 181 public: 182 explicit InputImeAPI(content::BrowserContext* context); 183 ~InputImeAPI() override; 184 185 static BrowserContextKeyedAPIFactory<InputImeAPI>* GetFactoryInstance(); 186 187 // BrowserContextKeyedAPI implementation. 188 void Shutdown() override; 189 190 // ExtensionRegistryObserver implementation. 191 void OnExtensionLoaded(content::BrowserContext* browser_context, 192 const Extension* extension) override; 193 void OnExtensionUnloaded(content::BrowserContext* browser_context, 194 const Extension* extension, 195 UnloadedExtensionReason reason) override; 196 197 // EventRouter::Observer implementation. 198 void OnListenerAdded(const EventListenerInfo& details) override; 199 200 private: 201 friend class BrowserContextKeyedAPIFactory<InputImeAPI>; 202 InputImeEventRouter* input_ime_event_router(); 203 204 // BrowserContextKeyedAPI implementation. 205 static const char* service_name() { 206 return "InputImeAPI"; 207 } 208 static const bool kServiceIsNULLWhileTesting = true; 209 210 content::BrowserContext* const browser_context_; 211 212 // Listen to extension load, unloaded notifications. 213 ScopedObserver<ExtensionRegistry, ExtensionRegistryObserver> 214 extension_registry_observer_{this}; 215 216 std::unique_ptr<ui::IMEBridgeObserver> observer_; 217 }; 218 219 template <> 220 struct BrowserContextFactoryDependencies<InputImeAPI> { 221 static void DeclareFactoryDependencies( 222 BrowserContextKeyedAPIFactory<InputImeAPI>* factory) { 223 factory->DependsOn(EventRouterFactory::GetInstance()); 224 factory->DependsOn(ExtensionRegistryFactory::GetInstance()); 225 } 226 }; 227 228 InputImeEventRouter* GetInputImeEventRouter(Profile* profile); 229 230 // Append the extension function name to the error message so that we know where 231 // the error is from during debugging. 232 std::string InformativeError(const std::string& error, 233 const char* function_name); 234 } // namespace extensions 235 236 #endif // CHROME_BROWSER_EXTENSIONS_API_INPUT_IME_INPUT_IME_API_H_ 237