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/logging.h" | 10 #include "base/logging.h" |
11 #include "base/metrics/histogram.h" | 11 #include "base/metrics/histogram.h" |
12 #include "base/strings/string16.h" | 12 #include "base/strings/string16.h" |
13 #include "grit/keyboard_resources.h" | 13 #include "grit/keyboard_resources.h" |
14 #include "grit/keyboard_resources_map.h" | 14 #include "grit/keyboard_resources_map.h" |
15 #include "ui/aura/client/aura_constants.h" | 15 #include "ui/aura/client/aura_constants.h" |
16 #include "ui/aura/root_window.h" | 16 #include "ui/aura/root_window.h" |
17 #include "ui/base/ime/input_method.h" | 17 #include "ui/base/ime/input_method.h" |
18 #include "ui/base/ime/text_input_client.h" | 18 #include "ui/base/ime/text_input_client.h" |
19 #include "ui/keyboard/keyboard_switches.h" | 19 #include "ui/keyboard/keyboard_switches.h" |
20 | 20 |
21 namespace { | 21 namespace { |
22 | 22 |
23 const char kKeyDown[] ="keydown"; | 23 const char kKeyDown[] ="keydown"; |
24 const char kKeyUp[] = "keyup"; | 24 const char kKeyUp[] = "keyup"; |
25 | 25 |
26 void SendProcessKeyEvent(ui::EventType type, aura::RootWindow* root_window) { | 26 void SendProcessKeyEvent(ui::EventType type, |
| 27 aura::WindowEventDispatcher* dispatcher) { |
27 ui::TranslatedKeyEvent event(type == ui::ET_KEY_PRESSED, | 28 ui::TranslatedKeyEvent event(type == ui::ET_KEY_PRESSED, |
28 ui::VKEY_PROCESSKEY, | 29 ui::VKEY_PROCESSKEY, |
29 ui::EF_NONE); | 30 ui::EF_NONE); |
30 root_window->AsRootWindowHostDelegate()->OnHostKeyEvent(&event); | 31 dispatcher->AsRootWindowHostDelegate()->OnHostKeyEvent(&event); |
31 } | 32 } |
32 | 33 |
33 } // namespace | 34 } // namespace |
34 | 35 |
35 namespace keyboard { | 36 namespace keyboard { |
36 | 37 |
37 bool IsKeyboardEnabled() { | 38 bool IsKeyboardEnabled() { |
38 return CommandLine::ForCurrentProcess()->HasSwitch( | 39 return CommandLine::ForCurrentProcess()->HasSwitch( |
39 switches::kEnableVirtualKeyboard); | 40 switches::kEnableVirtualKeyboard); |
40 } | 41 } |
41 | 42 |
42 bool InsertText(const base::string16& text, aura::RootWindow* root_window) { | 43 bool InsertText(const base::string16& text, aura::Window* root_window) { |
43 if (!root_window) | 44 if (!root_window) |
44 return false; | 45 return false; |
45 | 46 |
46 ui::InputMethod* input_method = root_window->GetProperty( | 47 ui::InputMethod* input_method = root_window->GetProperty( |
47 aura::client::kRootWindowInputMethodKey); | 48 aura::client::kRootWindowInputMethodKey); |
48 if (!input_method) | 49 if (!input_method) |
49 return false; | 50 return false; |
50 | 51 |
51 ui::TextInputClient* tic = input_method->GetTextInputClient(); | 52 ui::TextInputClient* tic = input_method->GetTextInputClient(); |
52 if (!tic || tic->GetTextInputType() == ui::TEXT_INPUT_TYPE_NONE) | 53 if (!tic || tic->GetTextInputType() == ui::TEXT_INPUT_TYPE_NONE) |
53 return false; | 54 return false; |
54 | 55 |
55 tic->InsertText(text); | 56 tic->InsertText(text); |
56 | 57 |
57 return true; | 58 return true; |
58 } | 59 } |
59 | 60 |
60 // TODO(varunjain): It would be cleaner to have something in the | 61 // TODO(varunjain): It would be cleaner to have something in the |
61 // ui::TextInputClient interface, say MoveCaretInDirection(). The code in | 62 // ui::TextInputClient interface, say MoveCaretInDirection(). The code in |
62 // here would get the ui::InputMethod from the root_window, and the | 63 // here would get the ui::InputMethod from the root_window, and the |
63 // ui::TextInputClient from that (see above in InsertText()). | 64 // ui::TextInputClient from that (see above in InsertText()). |
64 bool MoveCursor(int swipe_direction, | 65 bool MoveCursor(int swipe_direction, |
65 int modifier_flags, | 66 int modifier_flags, |
66 aura::RootWindow* root_window) { | 67 aura::WindowEventDispatcher* dispatcher) { |
67 if (!root_window) | 68 if (!dispatcher) |
68 return false; | 69 return false; |
69 ui::KeyboardCode codex = ui::VKEY_UNKNOWN; | 70 ui::KeyboardCode codex = ui::VKEY_UNKNOWN; |
70 ui::KeyboardCode codey = ui::VKEY_UNKNOWN; | 71 ui::KeyboardCode codey = ui::VKEY_UNKNOWN; |
71 if (swipe_direction & kCursorMoveRight) | 72 if (swipe_direction & kCursorMoveRight) |
72 codex = ui::VKEY_RIGHT; | 73 codex = ui::VKEY_RIGHT; |
73 else if (swipe_direction & kCursorMoveLeft) | 74 else if (swipe_direction & kCursorMoveLeft) |
74 codex = ui::VKEY_LEFT; | 75 codex = ui::VKEY_LEFT; |
75 | 76 |
76 if (swipe_direction & kCursorMoveUp) | 77 if (swipe_direction & kCursorMoveUp) |
77 codey = ui::VKEY_UP; | 78 codey = ui::VKEY_UP; |
78 else if (swipe_direction & kCursorMoveDown) | 79 else if (swipe_direction & kCursorMoveDown) |
79 codey = ui::VKEY_DOWN; | 80 codey = ui::VKEY_DOWN; |
80 | 81 |
81 // First deal with the x movement. | 82 // First deal with the x movement. |
82 if (codex != ui::VKEY_UNKNOWN) { | 83 if (codex != ui::VKEY_UNKNOWN) { |
83 ui::KeyEvent press_event(ui::ET_KEY_PRESSED, codex, modifier_flags, 0); | 84 ui::KeyEvent press_event(ui::ET_KEY_PRESSED, codex, modifier_flags, 0); |
84 root_window->AsRootWindowHostDelegate()->OnHostKeyEvent(&press_event); | 85 dispatcher->AsRootWindowHostDelegate()->OnHostKeyEvent(&press_event); |
85 ui::KeyEvent release_event(ui::ET_KEY_RELEASED, codex, modifier_flags, 0); | 86 ui::KeyEvent release_event(ui::ET_KEY_RELEASED, codex, modifier_flags, 0); |
86 root_window->AsRootWindowHostDelegate()->OnHostKeyEvent(&release_event); | 87 dispatcher->AsRootWindowHostDelegate()->OnHostKeyEvent(&release_event); |
87 } | 88 } |
88 | 89 |
89 // Then deal with the y movement. | 90 // Then deal with the y movement. |
90 if (codey != ui::VKEY_UNKNOWN) { | 91 if (codey != ui::VKEY_UNKNOWN) { |
91 ui::KeyEvent press_event(ui::ET_KEY_PRESSED, codey, modifier_flags, 0); | 92 ui::KeyEvent press_event(ui::ET_KEY_PRESSED, codey, modifier_flags, 0); |
92 root_window->AsRootWindowHostDelegate()->OnHostKeyEvent(&press_event); | 93 dispatcher->AsRootWindowHostDelegate()->OnHostKeyEvent(&press_event); |
93 ui::KeyEvent release_event(ui::ET_KEY_RELEASED, codey, modifier_flags, 0); | 94 ui::KeyEvent release_event(ui::ET_KEY_RELEASED, codey, modifier_flags, 0); |
94 root_window->AsRootWindowHostDelegate()->OnHostKeyEvent(&release_event); | 95 dispatcher->AsRootWindowHostDelegate()->OnHostKeyEvent(&release_event); |
95 } | 96 } |
96 return true; | 97 return true; |
97 } | 98 } |
98 | 99 |
99 bool SendKeyEvent(const std::string type, | 100 bool SendKeyEvent(const std::string type, |
100 int key_value, | 101 int key_value, |
101 int key_code, | 102 int key_code, |
102 bool shift_modifier, | 103 bool shift_modifier, |
103 aura::RootWindow* root_window) { | 104 aura::WindowEventDispatcher* dispatcher) { |
104 ui::EventType event_type = ui::ET_UNKNOWN; | 105 ui::EventType event_type = ui::ET_UNKNOWN; |
105 if (type == kKeyDown) | 106 if (type == kKeyDown) |
106 event_type = ui::ET_KEY_PRESSED; | 107 event_type = ui::ET_KEY_PRESSED; |
107 else if (type == kKeyUp) | 108 else if (type == kKeyUp) |
108 event_type = ui::ET_KEY_RELEASED; | 109 event_type = ui::ET_KEY_RELEASED; |
109 if (event_type == ui::ET_UNKNOWN) | 110 if (event_type == ui::ET_UNKNOWN) |
110 return false; | 111 return false; |
111 | 112 |
112 int flags = ui::EF_NONE; | 113 int flags = ui::EF_NONE; |
113 if (shift_modifier) | 114 if (shift_modifier) |
114 flags = ui::EF_SHIFT_DOWN; | 115 flags = ui::EF_SHIFT_DOWN; |
115 | 116 |
116 ui::KeyboardCode code = static_cast<ui::KeyboardCode>(key_code); | 117 ui::KeyboardCode code = static_cast<ui::KeyboardCode>(key_code); |
117 | 118 |
118 if (code == ui::VKEY_UNKNOWN) { | 119 if (code == ui::VKEY_UNKNOWN) { |
119 // Handling of special printable characters (e.g. accented characters) for | 120 // Handling of special printable characters (e.g. accented characters) for |
120 // which there is no key code. | 121 // which there is no key code. |
121 if (event_type == ui::ET_KEY_RELEASED) { | 122 if (event_type == ui::ET_KEY_RELEASED) { |
122 ui::InputMethod* input_method = root_window->GetProperty( | 123 ui::InputMethod* input_method = dispatcher->GetProperty( |
123 aura::client::kRootWindowInputMethodKey); | 124 aura::client::kRootWindowInputMethodKey); |
124 if (!input_method) | 125 if (!input_method) |
125 return false; | 126 return false; |
126 | 127 |
127 ui::TextInputClient* tic = input_method->GetTextInputClient(); | 128 ui::TextInputClient* tic = input_method->GetTextInputClient(); |
128 | 129 |
129 SendProcessKeyEvent(ui::ET_KEY_PRESSED, root_window); | 130 SendProcessKeyEvent(ui::ET_KEY_PRESSED, dispatcher); |
130 tic->InsertChar(static_cast<uint16>(key_value), ui::EF_NONE); | 131 tic->InsertChar(static_cast<uint16>(key_value), ui::EF_NONE); |
131 SendProcessKeyEvent(ui::ET_KEY_RELEASED, root_window); | 132 SendProcessKeyEvent(ui::ET_KEY_RELEASED, dispatcher); |
132 } | 133 } |
133 } else { | 134 } else { |
134 if (event_type == ui::ET_KEY_RELEASED) { | 135 if (event_type == ui::ET_KEY_RELEASED) { |
135 // The number of key press events seen since the last backspace. | 136 // The number of key press events seen since the last backspace. |
136 static int keys_seen = 0; | 137 static int keys_seen = 0; |
137 if (code == ui::VKEY_BACK) { | 138 if (code == ui::VKEY_BACK) { |
138 // Log the rough lengths of characters typed between backspaces. This | 139 // Log the rough lengths of characters typed between backspaces. This |
139 // metric will be used to determine the error rate for the keyboard. | 140 // metric will be used to determine the error rate for the keyboard. |
140 UMA_HISTOGRAM_CUSTOM_COUNTS( | 141 UMA_HISTOGRAM_CUSTOM_COUNTS( |
141 "VirtualKeyboard.KeystrokesBetweenBackspaces", | 142 "VirtualKeyboard.KeystrokesBetweenBackspaces", |
142 keys_seen, 1, 1000, 50); | 143 keys_seen, 1, 1000, 50); |
143 keys_seen = 0; | 144 keys_seen = 0; |
144 } else { | 145 } else { |
145 ++keys_seen; | 146 ++keys_seen; |
146 } | 147 } |
147 } | 148 } |
148 | 149 |
149 ui::KeyEvent event(event_type, code, flags, false); | 150 ui::KeyEvent event(event_type, code, flags, false); |
150 root_window->AsRootWindowHostDelegate()->OnHostKeyEvent(&event); | 151 dispatcher->AsRootWindowHostDelegate()->OnHostKeyEvent(&event); |
151 } | 152 } |
152 return true; | 153 return true; |
153 } | 154 } |
154 | 155 |
155 const GritResourceMap* GetKeyboardExtensionResources(size_t* size) { | 156 const GritResourceMap* GetKeyboardExtensionResources(size_t* size) { |
156 // This looks a lot like the contents of a resource map; however it is | 157 // This looks a lot like the contents of a resource map; however it is |
157 // necessary to have a custom path for the extension path, so the resource | 158 // necessary to have a custom path for the extension path, so the resource |
158 // map cannot be used directly. | 159 // map cannot be used directly. |
159 static const GritResourceMap kKeyboardResources[] = { | 160 static const GritResourceMap kKeyboardResources[] = { |
160 {"keyboard/api_adapter.js", IDR_KEYBOARD_API_ADAPTER_JS}, | 161 {"keyboard/api_adapter.js", IDR_KEYBOARD_API_ADAPTER_JS}, |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
220 } | 221 } |
221 | 222 |
222 void LogKeyboardControlEvent(KeyboardControlEvent event) { | 223 void LogKeyboardControlEvent(KeyboardControlEvent event) { |
223 UMA_HISTOGRAM_ENUMERATION( | 224 UMA_HISTOGRAM_ENUMERATION( |
224 "VirtualKeyboard.KeyboardControlEvent", | 225 "VirtualKeyboard.KeyboardControlEvent", |
225 event, | 226 event, |
226 keyboard::KEYBOARD_CONTROL_MAX); | 227 keyboard::KEYBOARD_CONTROL_MAX); |
227 } | 228 } |
228 | 229 |
229 } // namespace keyboard | 230 } // namespace keyboard |
OLD | NEW |