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