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 24namespace { 25 26// Keys. 27const char kType[] = "type"; 28const char kKeyIdentifier[] = "keyIdentifier"; 29const char kAlt[] = "altKey"; 30const char kCtrl[] = "ctrlKey"; 31const char kMeta[] = "metaKey"; 32const char kShift[] = "shiftKey"; 33const char kKeyDown[] = "keydown"; 34const char kKeyUp[] = "keyup"; 35 36// Errors. 37const char kUnknownEventTypeError[] = "Unknown event type."; 38const char kUnknownOrUnsupportedKeyIdentiferError[] = "Unknown or unsupported " 39 "key identifier."; 40const char kUnsupportedModifier[] = "Unsupported modifier."; 41const char kNoValidRecipientError[] = "No valid recipient for event."; 42const char kKeyEventUnprocessedError[] = "Event was not handled."; 43 44ui::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 55void InputFunction::Run() { 56 SendResponse(RunImpl()); 57} 58 59views::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 76bool 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