1 // Copyright (c) 2011 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 #include "chrome/browser/extensions/extension_input_api.h" 6 7 #include <string> 8 9 #include "base/string_util.h" 10 #include "base/values.h" 11 #include "chrome/browser/extensions/extension_tabs_module.h" 12 #include "chrome/browser/extensions/key_identifier_conversion_views.h" 13 #include "chrome/browser/ui/browser.h" 14 #include "chrome/browser/ui/browser_window.h" 15 #include "chrome/browser/ui/views/frame/browser_view.h" 16 #include "content/browser/renderer_host/render_view_host.h" 17 #include "content/common/native_web_keyboard_event.h" 18 #include "third_party/WebKit/Source/WebKit/chromium/public/WebInputEvent.h" 19 #include "views/events/event.h" 20 #include "views/ime/input_method.h" 21 #include "views/widget/root_view.h" 22 #include "views/widget/widget.h" 23 24 namespace { 25 26 // Keys. 27 const char kType[] = "type"; 28 const char kKeyIdentifier[] = "keyIdentifier"; 29 const char kAlt[] = "altKey"; 30 const char kCtrl[] = "ctrlKey"; 31 const char kMeta[] = "metaKey"; 32 const char kShift[] = "shiftKey"; 33 const char kKeyDown[] = "keydown"; 34 const char kKeyUp[] = "keyup"; 35 36 // Errors. 37 const char kUnknownEventTypeError[] = "Unknown event type."; 38 const char kUnknownOrUnsupportedKeyIdentiferError[] = "Unknown or unsupported " 39 "key identifier."; 40 const char kUnsupportedModifier[] = "Unsupported modifier."; 41 const char kNoValidRecipientError[] = "No valid recipient for event."; 42 const char kKeyEventUnprocessedError[] = "Event was not handled."; 43 44 ui::EventType GetTypeFromString(const std::string& type) { 45 if (type == kKeyDown) { 46 return ui::ET_KEY_PRESSED; 47 } else if (type == kKeyUp) { 48 return ui::ET_KEY_RELEASED; 49 } 50 return ui::ET_UNKNOWN; 51 } 52 53 } // namespace 54 55 void InputFunction::Run() { 56 SendResponse(RunImpl()); 57 } 58 59 views::RootView* SendKeyboardEventInputFunction::GetRootView() { 60 Browser* browser = GetCurrentBrowser(); 61 if (!browser) 62 return NULL; 63 64 BrowserWindow* window = browser->window(); 65 if (!window) 66 return NULL; 67 68 BrowserView* browser_view = BrowserView::GetBrowserViewForNativeWindow( 69 window->GetNativeHandle()); 70 if (!browser_view) 71 return NULL; 72 73 return browser_view->GetRootView(); 74 } 75 76 bool SendKeyboardEventInputFunction::RunImpl() { 77 DictionaryValue* args; 78 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &args)); 79 80 std::string type_name; 81 EXTENSION_FUNCTION_VALIDATE(args->GetString(kType, &type_name)); 82 ui::EventType type = GetTypeFromString(type_name); 83 if (type == ui::ET_UNKNOWN) { 84 error_ = kUnknownEventTypeError; 85 return false; 86 } 87 88 std::string identifier; 89 EXTENSION_FUNCTION_VALIDATE(args->GetString(kKeyIdentifier, &identifier)); 90 TrimWhitespaceASCII(identifier, TRIM_ALL, &identifier); 91 92 const views::KeyEvent& prototype_event = 93 KeyEventFromKeyIdentifier(identifier); 94 if (prototype_event.key_code() == ui::VKEY_UNKNOWN) { 95 error_ = kUnknownOrUnsupportedKeyIdentiferError; 96 return false; 97 } 98 99 int flags = prototype_event.flags(); 100 bool alt = false; 101 if (args->GetBoolean(kAlt, &alt)) 102 flags |= alt ? ui::EF_ALT_DOWN : 0; 103 bool ctrl = false; 104 if (args->GetBoolean(kCtrl, &ctrl)) 105 flags |= ctrl ? ui::EF_CONTROL_DOWN : 0; 106 bool shift = false; 107 if (args->GetBoolean(kShift, &shift)) 108 flags |= shift ? ui::EF_SHIFT_DOWN : 0; 109 bool meta = false; 110 if (args->GetBoolean(kMeta, &meta)) { 111 // Views does not have a Meta event flag, so return an error for now. 112 if (meta) { 113 error_ = kUnsupportedModifier; 114 return false; 115 } 116 } 117 118 views::RootView* root_view = GetRootView(); 119 if (!root_view) { 120 error_ = kNoValidRecipientError; 121 return false; 122 } 123 124 views::KeyEvent event(type, prototype_event.key_code(), flags); 125 views::InputMethod* ime = root_view->GetWidget()->GetInputMethod(); 126 if (ime) { 127 ime->DispatchKeyEvent(event); 128 } else if (!root_view->ProcessKeyEvent(event)) { 129 error_ = kKeyEventUnprocessedError; 130 return false; 131 } 132 133 return true; 134 } 135