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