| OLD | NEW |
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 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 "ui/keyboard/keyboard_util.h" | 5 #include "ui/keyboard/keyboard_util.h" |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 | 8 |
| 9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
| 10 #include "base/lazy_instance.h" | 10 #include "base/lazy_instance.h" |
| 11 #include "base/logging.h" | 11 #include "base/logging.h" |
| 12 #include "base/metrics/histogram.h" | 12 #include "base/metrics/histogram.h" |
| 13 #include "base/strings/string16.h" | 13 #include "base/strings/string16.h" |
| 14 #include "grit/keyboard_resources.h" | 14 #include "grit/keyboard_resources.h" |
| 15 #include "grit/keyboard_resources_map.h" | 15 #include "grit/keyboard_resources_map.h" |
| 16 #include "ui/aura/client/aura_constants.h" | 16 #include "ui/aura/client/aura_constants.h" |
| 17 #include "ui/aura/window_event_dispatcher.h" | 17 #include "ui/aura/window_tree_host.h" |
| 18 #include "ui/base/ime/input_method.h" | 18 #include "ui/base/ime/input_method.h" |
| 19 #include "ui/base/ime/text_input_client.h" | 19 #include "ui/base/ime/text_input_client.h" |
| 20 #include "ui/events/event_processor.h" |
| 20 #include "ui/keyboard/keyboard_switches.h" | 21 #include "ui/keyboard/keyboard_switches.h" |
| 21 #include "url/gurl.h" | 22 #include "url/gurl.h" |
| 22 | 23 |
| 23 namespace { | 24 namespace { |
| 24 | 25 |
| 25 const char kKeyDown[] ="keydown"; | 26 const char kKeyDown[] ="keydown"; |
| 26 const char kKeyUp[] = "keyup"; | 27 const char kKeyUp[] = "keyup"; |
| 27 | 28 |
| 28 void SendProcessKeyEvent(ui::EventType type, | 29 void SendProcessKeyEvent(ui::EventType type, |
| 29 aura::WindowEventDispatcher* dispatcher) { | 30 aura::WindowTreeHost* host) { |
| 30 ui::TranslatedKeyEvent event(type == ui::ET_KEY_PRESSED, | 31 ui::TranslatedKeyEvent event(type == ui::ET_KEY_PRESSED, |
| 31 ui::VKEY_PROCESSKEY, | 32 ui::VKEY_PROCESSKEY, |
| 32 ui::EF_NONE); | 33 ui::EF_NONE); |
| 33 ui::EventDispatchDetails details = dispatcher->OnEventFromSource(&event); | 34 ui::EventDispatchDetails details = |
| 35 host->event_processor()->OnEventFromSource(&event); |
| 34 CHECK(!details.dispatcher_destroyed); | 36 CHECK(!details.dispatcher_destroyed); |
| 35 } | 37 } |
| 36 | 38 |
| 37 base::LazyInstance<base::Time> g_keyboard_load_time_start = | 39 base::LazyInstance<base::Time> g_keyboard_load_time_start = |
| 38 LAZY_INSTANCE_INITIALIZER; | 40 LAZY_INSTANCE_INITIALIZER; |
| 39 | 41 |
| 40 bool g_accessibility_keyboard_enabled = false; | 42 bool g_accessibility_keyboard_enabled = false; |
| 41 | 43 |
| 42 base::LazyInstance<GURL> g_override_content_url = LAZY_INSTANCE_INITIALIZER; | 44 base::LazyInstance<GURL> g_override_content_url = LAZY_INSTANCE_INITIALIZER; |
| 43 | 45 |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 88 | 90 |
| 89 return true; | 91 return true; |
| 90 } | 92 } |
| 91 | 93 |
| 92 // TODO(varunjain): It would be cleaner to have something in the | 94 // TODO(varunjain): It would be cleaner to have something in the |
| 93 // ui::TextInputClient interface, say MoveCaretInDirection(). The code in | 95 // ui::TextInputClient interface, say MoveCaretInDirection(). The code in |
| 94 // here would get the ui::InputMethod from the root_window, and the | 96 // here would get the ui::InputMethod from the root_window, and the |
| 95 // ui::TextInputClient from that (see above in InsertText()). | 97 // ui::TextInputClient from that (see above in InsertText()). |
| 96 bool MoveCursor(int swipe_direction, | 98 bool MoveCursor(int swipe_direction, |
| 97 int modifier_flags, | 99 int modifier_flags, |
| 98 aura::WindowEventDispatcher* dispatcher) { | 100 aura::WindowTreeHost* host) { |
| 99 if (!dispatcher) | 101 if (!host) |
| 100 return false; | 102 return false; |
| 101 ui::KeyboardCode codex = ui::VKEY_UNKNOWN; | 103 ui::KeyboardCode codex = ui::VKEY_UNKNOWN; |
| 102 ui::KeyboardCode codey = ui::VKEY_UNKNOWN; | 104 ui::KeyboardCode codey = ui::VKEY_UNKNOWN; |
| 103 if (swipe_direction & kCursorMoveRight) | 105 if (swipe_direction & kCursorMoveRight) |
| 104 codex = ui::VKEY_RIGHT; | 106 codex = ui::VKEY_RIGHT; |
| 105 else if (swipe_direction & kCursorMoveLeft) | 107 else if (swipe_direction & kCursorMoveLeft) |
| 106 codex = ui::VKEY_LEFT; | 108 codex = ui::VKEY_LEFT; |
| 107 | 109 |
| 108 if (swipe_direction & kCursorMoveUp) | 110 if (swipe_direction & kCursorMoveUp) |
| 109 codey = ui::VKEY_UP; | 111 codey = ui::VKEY_UP; |
| 110 else if (swipe_direction & kCursorMoveDown) | 112 else if (swipe_direction & kCursorMoveDown) |
| 111 codey = ui::VKEY_DOWN; | 113 codey = ui::VKEY_DOWN; |
| 112 | 114 |
| 113 // First deal with the x movement. | 115 // First deal with the x movement. |
| 114 if (codex != ui::VKEY_UNKNOWN) { | 116 if (codex != ui::VKEY_UNKNOWN) { |
| 115 ui::KeyEvent press_event(ui::ET_KEY_PRESSED, codex, modifier_flags, 0); | 117 ui::KeyEvent press_event(ui::ET_KEY_PRESSED, codex, modifier_flags, 0); |
| 116 ui::EventDispatchDetails details = | 118 ui::EventDispatchDetails details = |
| 117 dispatcher->OnEventFromSource(&press_event); | 119 host->event_processor()->OnEventFromSource(&press_event); |
| 118 CHECK(!details.dispatcher_destroyed); | 120 CHECK(!details.dispatcher_destroyed); |
| 119 ui::KeyEvent release_event(ui::ET_KEY_RELEASED, codex, modifier_flags, 0); | 121 ui::KeyEvent release_event(ui::ET_KEY_RELEASED, codex, modifier_flags, 0); |
| 120 details = dispatcher->OnEventFromSource(&release_event); | 122 details = host->event_processor()->OnEventFromSource(&release_event); |
| 121 CHECK(!details.dispatcher_destroyed); | 123 CHECK(!details.dispatcher_destroyed); |
| 122 } | 124 } |
| 123 | 125 |
| 124 // Then deal with the y movement. | 126 // Then deal with the y movement. |
| 125 if (codey != ui::VKEY_UNKNOWN) { | 127 if (codey != ui::VKEY_UNKNOWN) { |
| 126 ui::KeyEvent press_event(ui::ET_KEY_PRESSED, codey, modifier_flags, 0); | 128 ui::KeyEvent press_event(ui::ET_KEY_PRESSED, codey, modifier_flags, 0); |
| 127 ui::EventDispatchDetails details = | 129 ui::EventDispatchDetails details = |
| 128 dispatcher->OnEventFromSource(&press_event); | 130 host->event_processor()->OnEventFromSource(&press_event); |
| 129 CHECK(!details.dispatcher_destroyed); | 131 CHECK(!details.dispatcher_destroyed); |
| 130 ui::KeyEvent release_event(ui::ET_KEY_RELEASED, codey, modifier_flags, 0); | 132 ui::KeyEvent release_event(ui::ET_KEY_RELEASED, codey, modifier_flags, 0); |
| 131 details = dispatcher->OnEventFromSource(&release_event); | 133 details = host->event_processor()->OnEventFromSource(&release_event); |
| 132 CHECK(!details.dispatcher_destroyed); | 134 CHECK(!details.dispatcher_destroyed); |
| 133 } | 135 } |
| 134 return true; | 136 return true; |
| 135 } | 137 } |
| 136 | 138 |
| 137 bool SendKeyEvent(const std::string type, | 139 bool SendKeyEvent(const std::string type, |
| 138 int key_value, | 140 int key_value, |
| 139 int key_code, | 141 int key_code, |
| 140 std::string key_name, | 142 std::string key_name, |
| 141 int modifiers, | 143 int modifiers, |
| 142 aura::WindowEventDispatcher* dispatcher) { | 144 aura::WindowTreeHost* host) { |
| 143 ui::EventType event_type = ui::ET_UNKNOWN; | 145 ui::EventType event_type = ui::ET_UNKNOWN; |
| 144 if (type == kKeyDown) | 146 if (type == kKeyDown) |
| 145 event_type = ui::ET_KEY_PRESSED; | 147 event_type = ui::ET_KEY_PRESSED; |
| 146 else if (type == kKeyUp) | 148 else if (type == kKeyUp) |
| 147 event_type = ui::ET_KEY_RELEASED; | 149 event_type = ui::ET_KEY_RELEASED; |
| 148 if (event_type == ui::ET_UNKNOWN) | 150 if (event_type == ui::ET_UNKNOWN) |
| 149 return false; | 151 return false; |
| 150 | 152 |
| 151 ui::KeyboardCode code = static_cast<ui::KeyboardCode>(key_code); | 153 ui::KeyboardCode code = static_cast<ui::KeyboardCode>(key_code); |
| 152 | 154 |
| 153 if (code == ui::VKEY_UNKNOWN) { | 155 if (code == ui::VKEY_UNKNOWN) { |
| 154 // Handling of special printable characters (e.g. accented characters) for | 156 // Handling of special printable characters (e.g. accented characters) for |
| 155 // which there is no key code. | 157 // which there is no key code. |
| 156 if (event_type == ui::ET_KEY_RELEASED) { | 158 if (event_type == ui::ET_KEY_RELEASED) { |
| 157 ui::InputMethod* input_method = dispatcher->window()->GetProperty( | 159 ui::InputMethod* input_method = host->window()->GetProperty( |
| 158 aura::client::kRootWindowInputMethodKey); | 160 aura::client::kRootWindowInputMethodKey); |
| 159 if (!input_method) | 161 if (!input_method) |
| 160 return false; | 162 return false; |
| 161 | 163 |
| 162 ui::TextInputClient* tic = input_method->GetTextInputClient(); | 164 ui::TextInputClient* tic = input_method->GetTextInputClient(); |
| 163 | 165 |
| 164 SendProcessKeyEvent(ui::ET_KEY_PRESSED, dispatcher); | 166 SendProcessKeyEvent(ui::ET_KEY_PRESSED, host); |
| 165 tic->InsertChar(static_cast<uint16>(key_value), ui::EF_NONE); | 167 tic->InsertChar(static_cast<uint16>(key_value), ui::EF_NONE); |
| 166 SendProcessKeyEvent(ui::ET_KEY_RELEASED, dispatcher); | 168 SendProcessKeyEvent(ui::ET_KEY_RELEASED, host); |
| 167 } | 169 } |
| 168 } else { | 170 } else { |
| 169 if (event_type == ui::ET_KEY_RELEASED) { | 171 if (event_type == ui::ET_KEY_RELEASED) { |
| 170 // The number of key press events seen since the last backspace. | 172 // The number of key press events seen since the last backspace. |
| 171 static int keys_seen = 0; | 173 static int keys_seen = 0; |
| 172 if (code == ui::VKEY_BACK) { | 174 if (code == ui::VKEY_BACK) { |
| 173 // Log the rough lengths of characters typed between backspaces. This | 175 // Log the rough lengths of characters typed between backspaces. This |
| 174 // metric will be used to determine the error rate for the keyboard. | 176 // metric will be used to determine the error rate for the keyboard. |
| 175 UMA_HISTOGRAM_CUSTOM_COUNTS( | 177 UMA_HISTOGRAM_CUSTOM_COUNTS( |
| 176 "VirtualKeyboard.KeystrokesBetweenBackspaces", | 178 "VirtualKeyboard.KeystrokesBetweenBackspaces", |
| 177 keys_seen, 1, 1000, 50); | 179 keys_seen, 1, 1000, 50); |
| 178 keys_seen = 0; | 180 keys_seen = 0; |
| 179 } else { | 181 } else { |
| 180 ++keys_seen; | 182 ++keys_seen; |
| 181 } | 183 } |
| 182 } | 184 } |
| 183 | 185 |
| 184 ui::KeyEvent event(event_type, code, key_name, modifiers, false); | 186 ui::KeyEvent event(event_type, code, key_name, modifiers, false); |
| 185 ui::EventDispatchDetails details = dispatcher->OnEventFromSource(&event); | 187 ui::EventDispatchDetails details = |
| 188 host->event_processor()->OnEventFromSource(&event); |
| 186 CHECK(!details.dispatcher_destroyed); | 189 CHECK(!details.dispatcher_destroyed); |
| 187 } | 190 } |
| 188 return true; | 191 return true; |
| 189 } | 192 } |
| 190 | 193 |
| 191 const void MarkKeyboardLoadStarted() { | 194 const void MarkKeyboardLoadStarted() { |
| 192 if (!g_keyboard_load_time_start.Get().ToInternalValue()) | 195 if (!g_keyboard_load_time_start.Get().ToInternalValue()) |
| 193 g_keyboard_load_time_start.Get() = base::Time::Now(); | 196 g_keyboard_load_time_start.Get() = base::Time::Now(); |
| 194 } | 197 } |
| 195 | 198 |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 310 } | 313 } |
| 311 | 314 |
| 312 void LogKeyboardControlEvent(KeyboardControlEvent event) { | 315 void LogKeyboardControlEvent(KeyboardControlEvent event) { |
| 313 UMA_HISTOGRAM_ENUMERATION( | 316 UMA_HISTOGRAM_ENUMERATION( |
| 314 "VirtualKeyboard.KeyboardControlEvent", | 317 "VirtualKeyboard.KeyboardControlEvent", |
| 315 event, | 318 event, |
| 316 keyboard::KEYBOARD_CONTROL_MAX); | 319 keyboard::KEYBOARD_CONTROL_MAX); |
| 317 } | 320 } |
| 318 | 321 |
| 319 } // namespace keyboard | 322 } // namespace keyboard |
| OLD | NEW |