| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/extensions/api/input_ime/input_ime_api.h" | 5 #include "chrome/browser/extensions/api/input_ime/input_ime_api.h" |
| 6 | 6 |
| 7 #include "base/strings/string_number_conversions.h" | 7 #include "base/strings/string_number_conversions.h" |
| 8 #include "base/values.h" | 8 #include "base/values.h" |
| 9 #include "chrome/browser/chromeos/profiles/profile_helper.h" | 9 #include "chrome/browser/chromeos/profiles/profile_helper.h" |
| 10 #include "chrome/browser/extensions/extension_service.h" |
| 10 #include "chrome/browser/profiles/profile_manager.h" | 11 #include "chrome/browser/profiles/profile_manager.h" |
| 11 #include "chrome/common/extensions/api/input_ime.h" | 12 #include "chrome/common/extensions/api/input_ime.h" |
| 12 #include "chrome/common/extensions/api/input_ime/input_components_handler.h" | 13 #include "chrome/common/extensions/api/input_ime/input_components_handler.h" |
| 13 #include "extensions/browser/event_router.h" | 14 #include "extensions/browser/event_router.h" |
| 14 #include "extensions/browser/extension_function_registry.h" | 15 #include "extensions/browser/extension_function_registry.h" |
| 15 #include "extensions/browser/extension_registry.h" | 16 #include "extensions/browser/extension_registry.h" |
| 17 #include "extensions/browser/extension_system.h" |
| 18 #include "extensions/common/manifest_handlers/background_info.h" |
| 16 | 19 |
| 17 #if defined(USE_X11) | 20 #if defined(USE_X11) |
| 18 #include "chrome/browser/chromeos/input_method/input_method_engine.h" | 21 #include "chrome/browser/chromeos/input_method/input_method_engine.h" |
| 19 #endif | 22 #endif |
| 20 | 23 |
| 21 namespace input_ime = extensions::api::input_ime; | 24 namespace input_ime = extensions::api::input_ime; |
| 22 namespace KeyEventHandled = extensions::api::input_ime::KeyEventHandled; | 25 namespace KeyEventHandled = extensions::api::input_ime::KeyEventHandled; |
| 23 namespace DeleteSurroundingText = | 26 namespace DeleteSurroundingText = |
| 24 extensions::api::input_ime::DeleteSurroundingText; | 27 extensions::api::input_ime::DeleteSurroundingText; |
| 25 namespace UpdateMenuItems = extensions::api::input_ime::UpdateMenuItems; | 28 namespace UpdateMenuItems = extensions::api::input_ime::UpdateMenuItems; |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 73 const std::string& extension_id, | 76 const std::string& extension_id, |
| 74 const std::string& event_name, | 77 const std::string& event_name, |
| 75 scoped_ptr<base::ListValue> args) { | 78 scoped_ptr<base::ListValue> args) { |
| 76 scoped_ptr<extensions::Event> event(new extensions::Event( | 79 scoped_ptr<extensions::Event> event(new extensions::Event( |
| 77 event_name, args.Pass())); | 80 event_name, args.Pass())); |
| 78 event->restrict_to_browser_context = profile; | 81 event->restrict_to_browser_context = profile; |
| 79 extensions::EventRouter::Get(profile) | 82 extensions::EventRouter::Get(profile) |
| 80 ->DispatchEventToExtension(extension_id, event.Pass()); | 83 ->DispatchEventToExtension(extension_id, event.Pass()); |
| 81 } | 84 } |
| 82 | 85 |
| 86 void CallbackKeyEventHandle(chromeos::input_method::KeyEventHandle* key_data, |
| 87 bool handled) { |
| 88 base::Callback<void(bool consumed)>* callback = |
| 89 reinterpret_cast<base::Callback<void(bool consumed)>*>(key_data); |
| 90 callback->Run(handled); |
| 91 delete callback; |
| 92 } |
| 93 |
| 83 } // namespace | 94 } // namespace |
| 84 | 95 |
| 85 namespace chromeos { | 96 namespace chromeos { |
| 86 class ImeObserver : public InputMethodEngineInterface::Observer { | 97 class ImeObserver : public InputMethodEngineInterface::Observer { |
| 87 public: | 98 public: |
| 88 ImeObserver(Profile* profile, const std::string& extension_id) | 99 ImeObserver(Profile* profile, const std::string& extension_id) |
| 89 : profile_(profile), extension_id_(extension_id) {} | 100 : profile_(profile), extension_id_(extension_id), has_background_(false) { |
| 101 extensions::ExtensionSystem* extension_system = |
| 102 extensions::ExtensionSystem::Get(profile_); |
| 103 ExtensionService* extension_service = extension_system->extension_service(); |
| 104 const extensions::Extension* extension = |
| 105 extension_service->GetExtensionById(extension_id, false); |
| 106 DCHECK(extension); |
| 107 extensions::BackgroundInfo* info = static_cast<extensions::BackgroundInfo*>( |
| 108 extension->GetManifestData("background")); |
| 109 if (info) |
| 110 has_background_ = info->has_background_page(); |
| 111 } |
| 90 | 112 |
| 91 virtual ~ImeObserver() {} | 113 virtual ~ImeObserver() {} |
| 92 | 114 |
| 93 virtual void OnActivate(const std::string& engine_id) OVERRIDE { | 115 virtual void OnActivate(const std::string& engine_id) OVERRIDE { |
| 94 if (profile_ == NULL || extension_id_.empty()) | 116 if (profile_ == NULL || extension_id_.empty()) |
| 95 return; | 117 return; |
| 96 | 118 |
| 97 scoped_ptr<base::ListValue> args(input_ime::OnActivate::Create(engine_id)); | 119 scoped_ptr<base::ListValue> args(input_ime::OnActivate::Create(engine_id)); |
| 98 | 120 |
| 99 DispatchEventToExtension(profile_, extension_id_, | 121 DispatchEventToExtension(profile_, extension_id_, |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 156 | 178 |
| 157 virtual void OnKeyEvent( | 179 virtual void OnKeyEvent( |
| 158 const std::string& engine_id, | 180 const std::string& engine_id, |
| 159 const InputMethodEngineInterface::KeyboardEvent& event, | 181 const InputMethodEngineInterface::KeyboardEvent& event, |
| 160 chromeos::input_method::KeyEventHandle* key_data) OVERRIDE { | 182 chromeos::input_method::KeyEventHandle* key_data) OVERRIDE { |
| 161 if (profile_ == NULL || extension_id_.empty()) | 183 if (profile_ == NULL || extension_id_.empty()) |
| 162 return; | 184 return; |
| 163 | 185 |
| 164 // If there is no listener for the event, no need to dispatch the event to | 186 // If there is no listener for the event, no need to dispatch the event to |
| 165 // extension. Instead, releases the key event for default system behavior. | 187 // extension. Instead, releases the key event for default system behavior. |
| 166 if (!HasKeyEventListener()) { | 188 if (!ShouldForwardKeyEvent()) { |
| 167 // Continue processing the key event so that the physical keyboard can | 189 // Continue processing the key event so that the physical keyboard can |
| 168 // still work. | 190 // still work. |
| 169 base::Callback<void(bool consumed)>* callback = | 191 CallbackKeyEventHandle(key_data, false); |
| 170 reinterpret_cast<base::Callback<void(bool consumed)>*>(key_data); | |
| 171 callback->Run(false); | |
| 172 delete callback; | |
| 173 return; | 192 return; |
| 174 } | 193 } |
| 175 | 194 |
| 176 extensions::InputImeEventRouter* ime_event_router = | 195 extensions::InputImeEventRouter* ime_event_router = |
| 177 extensions::InputImeEventRouter::GetInstance(); | 196 extensions::InputImeEventRouter::GetInstance(); |
| 178 | 197 |
| 179 const std::string request_id = | 198 const std::string request_id = |
| 180 ime_event_router->AddRequest(engine_id, key_data); | 199 ime_event_router->AddRequest(engine_id, key_data); |
| 181 | 200 |
| 182 input_ime::KeyboardEvent key_data_value; | 201 input_ime::KeyboardEvent key_data_value; |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 274 | 293 |
| 275 scoped_ptr<base::ListValue> args(input_ime::OnReset::Create(engine_id)); | 294 scoped_ptr<base::ListValue> args(input_ime::OnReset::Create(engine_id)); |
| 276 | 295 |
| 277 DispatchEventToExtension(profile_, | 296 DispatchEventToExtension(profile_, |
| 278 extension_id_, | 297 extension_id_, |
| 279 input_ime::OnReset::kEventName, | 298 input_ime::OnReset::kEventName, |
| 280 args.Pass()); | 299 args.Pass()); |
| 281 } | 300 } |
| 282 | 301 |
| 283 private: | 302 private: |
| 284 bool HasKeyEventListener() const { | 303 // Returns true if the extension is ready to accept key event, otherwise |
| 285 return extensions::EventRouter::Get(profile_) | 304 // returns false. |
| 305 bool ShouldForwardKeyEvent() const { |
| 306 // Need to check the background page first since the |
| 307 // ExtensionHasEventListner returns true if the extension does not have a |
| 308 // background page. See crbug.com/394682. |
| 309 return has_background_ && extensions::EventRouter::Get(profile_) |
| 286 ->ExtensionHasEventListener(extension_id_, | 310 ->ExtensionHasEventListener(extension_id_, |
| 287 input_ime::OnKeyEvent::kEventName); | 311 input_ime::OnKeyEvent::kEventName); |
| 288 } | 312 } |
| 289 | 313 |
| 290 Profile* profile_; | 314 Profile* profile_; |
| 291 std::string extension_id_; | 315 std::string extension_id_; |
| 316 bool has_background_; |
| 292 | 317 |
| 293 DISALLOW_COPY_AND_ASSIGN(ImeObserver); | 318 DISALLOW_COPY_AND_ASSIGN(ImeObserver); |
| 294 }; | 319 }; |
| 295 | 320 |
| 296 } // namespace chromeos | 321 } // namespace chromeos |
| 297 | 322 |
| 298 namespace extensions { | 323 namespace extensions { |
| 299 | 324 |
| 300 InputImeEventRouter* | 325 InputImeEventRouter* |
| 301 InputImeEventRouter::GetInstance() { | 326 InputImeEventRouter::GetInstance() { |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 408 RequestMap::iterator request = request_map_.find(request_id); | 433 RequestMap::iterator request = request_map_.find(request_id); |
| 409 if (request == request_map_.end()) { | 434 if (request == request_map_.end()) { |
| 410 LOG(ERROR) << "Request ID not found: " << request_id; | 435 LOG(ERROR) << "Request ID not found: " << request_id; |
| 411 return; | 436 return; |
| 412 } | 437 } |
| 413 | 438 |
| 414 std::string engine_id = request->second.first; | 439 std::string engine_id = request->second.first; |
| 415 chromeos::input_method::KeyEventHandle* key_data = request->second.second; | 440 chromeos::input_method::KeyEventHandle* key_data = request->second.second; |
| 416 request_map_.erase(request); | 441 request_map_.erase(request); |
| 417 | 442 |
| 418 InputMethodEngineInterface* engine = GetEngine(extension_id, engine_id); | 443 CallbackKeyEventHandle(key_data, handled); |
| 419 if (!engine) { | |
| 420 LOG(ERROR) << "Engine does not exist: " << engine_id; | |
| 421 return; | |
| 422 } | |
| 423 | |
| 424 engine->KeyEventDone(key_data, handled); | |
| 425 } | 444 } |
| 426 | 445 |
| 427 std::string InputImeEventRouter::AddRequest( | 446 std::string InputImeEventRouter::AddRequest( |
| 428 const std::string& engine_id, | 447 const std::string& engine_id, |
| 429 chromeos::input_method::KeyEventHandle* key_data) { | 448 chromeos::input_method::KeyEventHandle* key_data) { |
| 430 std::string request_id = base::IntToString(next_request_id_); | 449 std::string request_id = base::IntToString(next_request_id_); |
| 431 ++next_request_id_; | 450 ++next_request_id_; |
| 432 | 451 |
| 433 request_map_[request_id] = std::make_pair(engine_id, key_data); | 452 request_map_[request_id] = std::make_pair(engine_id, key_data); |
| 434 | 453 |
| (...skipping 407 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 842 input_ime_event_router()->GetActiveEngine(details.extension_id); | 861 input_ime_event_router()->GetActiveEngine(details.extension_id); |
| 843 if (engine) | 862 if (engine) |
| 844 engine->NotifyImeReady(); | 863 engine->NotifyImeReady(); |
| 845 } | 864 } |
| 846 | 865 |
| 847 InputImeEventRouter* InputImeAPI::input_ime_event_router() { | 866 InputImeEventRouter* InputImeAPI::input_ime_event_router() { |
| 848 return InputImeEventRouter::GetInstance(); | 867 return InputImeEventRouter::GetInstance(); |
| 849 } | 868 } |
| 850 | 869 |
| 851 } // namespace extensions | 870 } // namespace extensions |
| OLD | NEW |