172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// Use of this source code is governed by a BSD-style license that can be 3bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// found in the LICENSE file. 4bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 5bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "chrome/browser/extensions/extension_input_api.h" 6bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 7bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include <string> 8bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "base/string_util.h" 10bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "base/values.h" 11bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "chrome/browser/extensions/extension_tabs_module.h" 1272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/extensions/key_identifier_conversion_views.h" 134a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch#include "chrome/browser/ui/browser.h" 14ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/ui/browser_window.h" 1572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/ui/views/frame/browser_view.h" 16dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/renderer_host/render_view_host.h" 17ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/native_web_keyboard_event.h" 1872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "third_party/WebKit/Source/WebKit/chromium/public/WebInputEvent.h" 1972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "views/events/event.h" 20ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "views/ime/input_method.h" 21bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "views/widget/root_view.h" 22ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "views/widget/widget.h" 23bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 24bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsennamespace { 25bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 26bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// Keys. 27bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenconst char kType[] = "type"; 28bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenconst char kKeyIdentifier[] = "keyIdentifier"; 29bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenconst char kAlt[] = "altKey"; 30bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenconst char kCtrl[] = "ctrlKey"; 31bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenconst char kMeta[] = "metaKey"; 32bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenconst char kShift[] = "shiftKey"; 33bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenconst char kKeyDown[] = "keydown"; 34bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenconst char kKeyUp[] = "keyup"; 35bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 36bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// Errors. 37bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenconst char kUnknownEventTypeError[] = "Unknown event type."; 38bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenconst char kUnknownOrUnsupportedKeyIdentiferError[] = "Unknown or unsupported " 39bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen "key identifier."; 4072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenconst char kUnsupportedModifier[] = "Unsupported modifier."; 41bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenconst char kNoValidRecipientError[] = "No valid recipient for event."; 42bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenconst char kKeyEventUnprocessedError[] = "Event was not handled."; 43bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 4472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenui::EventType GetTypeFromString(const std::string& type) { 45bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen if (type == kKeyDown) { 4672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return ui::ET_KEY_PRESSED; 47bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen } else if (type == kKeyUp) { 4872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return ui::ET_KEY_RELEASED; 49bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen } 5072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return ui::ET_UNKNOWN; 51bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen} 52bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 53bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen} // namespace 54bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 55bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenvoid InputFunction::Run() { 56bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen SendResponse(RunImpl()); 57bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen} 58bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 59bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenviews::RootView* SendKeyboardEventInputFunction::GetRootView() { 60bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen Browser* browser = GetCurrentBrowser(); 61bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen if (!browser) 62bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen return NULL; 63bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 64bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen BrowserWindow* window = browser->window(); 65bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen if (!window) 66bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen return NULL; 67bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 68bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen BrowserView* browser_view = BrowserView::GetBrowserViewForNativeWindow( 69bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen window->GetNativeHandle()); 70bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen if (!browser_view) 71bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen return NULL; 72bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 73bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen return browser_view->GetRootView(); 74bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen} 75bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 76bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenbool SendKeyboardEventInputFunction::RunImpl() { 77bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen DictionaryValue* args; 78bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &args)); 79bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 80bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen std::string type_name; 81bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen EXTENSION_FUNCTION_VALIDATE(args->GetString(kType, &type_name)); 8272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ui::EventType type = GetTypeFromString(type_name); 8372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (type == ui::ET_UNKNOWN) { 84bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen error_ = kUnknownEventTypeError; 85bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen return false; 86bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen } 87bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 88bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen std::string identifier; 89bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen EXTENSION_FUNCTION_VALIDATE(args->GetString(kKeyIdentifier, &identifier)); 9072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen TrimWhitespaceASCII(identifier, TRIM_ALL, &identifier); 9172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 9272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen const views::KeyEvent& prototype_event = 9372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen KeyEventFromKeyIdentifier(identifier); 9472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (prototype_event.key_code() == ui::VKEY_UNKNOWN) { 95bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen error_ = kUnknownOrUnsupportedKeyIdentiferError; 96bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen return false; 97bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen } 98bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 9972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen int flags = prototype_event.flags(); 100bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen bool alt = false; 101bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen if (args->GetBoolean(kAlt, &alt)) 10272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen flags |= alt ? ui::EF_ALT_DOWN : 0; 103bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen bool ctrl = false; 104bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen if (args->GetBoolean(kCtrl, &ctrl)) 10572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen flags |= ctrl ? ui::EF_CONTROL_DOWN : 0; 106bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen bool shift = false; 107bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen if (args->GetBoolean(kShift, &shift)) 10872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen flags |= shift ? ui::EF_SHIFT_DOWN : 0; 10972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen bool meta = false; 11072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (args->GetBoolean(kMeta, &meta)) { 11172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Views does not have a Meta event flag, so return an error for now. 11272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (meta) { 11372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen error_ = kUnsupportedModifier; 11472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return false; 11572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 11672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 117bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 118bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen views::RootView* root_view = GetRootView(); 119bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen if (!root_view) { 120bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen error_ = kNoValidRecipientError; 121bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen return false; 122bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen } 123bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 12472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen views::KeyEvent event(type, prototype_event.key_code(), flags); 125ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen views::InputMethod* ime = root_view->GetWidget()->GetInputMethod(); 126ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (ime) { 127ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ime->DispatchKeyEvent(event); 128ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } else if (!root_view->ProcessKeyEvent(event)) { 129bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen error_ = kKeyEventUnprocessedError; 130bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen return false; 131bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen } 132bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 133bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen return true; 134bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen} 135