1 // Copyright 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/extensions/api/input/input.h"
6
7 #include "base/command_line.h"
8 #include "base/lazy_instance.h"
9 #include "base/metrics/histogram.h"
10 #include "base/strings/string16.h"
11 #include "chrome/browser/profiles/profile_manager.h"
12 #include "chrome/browser/ui/chrome_pages.h"
13 #include "chrome/common/url_constants.h"
14 #include "content/public/browser/browser_thread.h"
15 #include "content/public/browser/user_metrics.h"
16 #include "extensions/browser/extension_function_registry.h"
17 #include "ui/events/event.h"
18 #include "ui/keyboard/keyboard_controller.h"
19 #include "ui/keyboard/keyboard_switches.h"
20
21 #if defined(OS_CHROMEOS)
22 #include "chrome/browser/chromeos/login/lock/screen_locker.h"
23 #include "chrome/browser/chromeos/login/ui/user_adding_screen.h"
24 #include "components/user_manager/user_manager.h"
25 #endif // OS_CHROMEOS
26
27 #if defined(USE_ASH)
28 #include "ash/root_window_controller.h"
29 #include "ash/shell.h"
30 #include "ui/aura/window_tree_host.h"
31 #include "ui/keyboard/keyboard_util.h"
32 #endif
33
34 #if !defined(USE_ASH)
35 namespace {
36
37 const char kNotYetImplementedError[] =
38 "API is not implemented on this platform.";
39
40 } // namespace
41 #endif
42
43 namespace extensions {
44
RunSync()45 bool VirtualKeyboardPrivateInsertTextFunction::RunSync() {
46 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
47 #if defined(USE_ASH)
48 base::string16 text;
49 EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &text));
50
51 return keyboard::InsertText(text, ash::Shell::GetPrimaryRootWindow());
52 #else
53 error_ = kNotYetImplementedError;
54 return false;
55 #endif
56 }
57
RunSync()58 bool VirtualKeyboardPrivateMoveCursorFunction::RunSync() {
59 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
60 #if defined(USE_ASH)
61 if (!CommandLine::ForCurrentProcess()->HasSwitch(
62 keyboard::switches::kEnableSwipeSelection)) {
63 return false;
64 }
65
66 int swipe_direction;
67 int modifier_flags;
68 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &swipe_direction));
69 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(1, &modifier_flags));
70
71 return keyboard::MoveCursor(
72 swipe_direction,
73 modifier_flags,
74 ash::Shell::GetPrimaryRootWindow()->GetHost());
75 #else
76 error_ = kNotYetImplementedError;
77 return false;
78 #endif
79 }
80
RunSync()81 bool VirtualKeyboardPrivateSendKeyEventFunction::RunSync() {
82 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
83 #if defined(USE_ASH)
84 base::Value* options_value = NULL;
85 base::DictionaryValue* params = NULL;
86 std::string type;
87 int char_value;
88 int key_code;
89 std::string key_name;
90 int modifiers;
91
92 EXTENSION_FUNCTION_VALIDATE(args_->Get(0, &options_value));
93 EXTENSION_FUNCTION_VALIDATE(options_value->GetAsDictionary(¶ms));
94 EXTENSION_FUNCTION_VALIDATE(params->GetString("type", &type));
95 EXTENSION_FUNCTION_VALIDATE(params->GetInteger("charValue", &char_value));
96 EXTENSION_FUNCTION_VALIDATE(params->GetInteger("keyCode", &key_code));
97 EXTENSION_FUNCTION_VALIDATE(params->GetString("keyName", &key_name));
98 EXTENSION_FUNCTION_VALIDATE(params->GetInteger("modifiers", &modifiers));
99
100 return keyboard::SendKeyEvent(
101 type,
102 char_value,
103 key_code,
104 key_name,
105 modifiers,
106 ash::Shell::GetPrimaryRootWindow()->GetHost());
107 #else
108 error_ = kNotYetImplementedError;
109 return false;
110 #endif
111 }
112
RunSync()113 bool VirtualKeyboardPrivateHideKeyboardFunction::RunSync() {
114 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
115 #if defined(USE_ASH)
116 UMA_HISTOGRAM_ENUMERATION(
117 "VirtualKeyboard.KeyboardControlEvent",
118 keyboard::KEYBOARD_CONTROL_HIDE_USER,
119 keyboard::KEYBOARD_CONTROL_MAX);
120
121 // Pass HIDE_REASON_MANUAL since calls to HideKeyboard as part of this API
122 // would be user generated.
123 keyboard::KeyboardController::GetInstance()->HideKeyboard(
124 keyboard::KeyboardController::HIDE_REASON_MANUAL);
125
126 return true;
127 #else
128 error_ = kNotYetImplementedError;
129 return false;
130 #endif
131 }
132
RunSync()133 bool VirtualKeyboardPrivateLockKeyboardFunction::RunSync() {
134 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
135 #if defined(USE_ASH)
136 bool lock;
137 EXTENSION_FUNCTION_VALIDATE(args_->GetBoolean(0, &lock));
138 keyboard::KeyboardController::GetInstance()->set_lock_keyboard(lock);
139 return true;
140 #else
141 error_ = kNotYetImplementedError;
142 return false;
143 #endif
144 }
145
RunSync()146 bool VirtualKeyboardPrivateKeyboardLoadedFunction::RunSync() {
147 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
148 #if defined(USE_ASH)
149 keyboard::MarkKeyboardLoadFinished();
150 base::UserMetricsAction("VirtualKeyboardLoaded");
151 return true;
152 #else
153 error_ = kNotYetImplementedError;
154 return false;
155 #endif
156 }
157
RunSync()158 bool VirtualKeyboardPrivateGetKeyboardConfigFunction::RunSync() {
159 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
160 #if defined(USE_ASH)
161 base::DictionaryValue* results = new base::DictionaryValue();
162 results->SetString("layout", keyboard::GetKeyboardLayout());
163 results->SetBoolean("a11ymode", keyboard::GetAccessibilityKeyboardEnabled());
164 results->SetBoolean("experimental",
165 keyboard::IsExperimentalInputViewEnabled());
166 SetResult(results);
167 return true;
168 #else
169 error_ = kNotYetImplementedError;
170 return false;
171 #endif
172 }
173
RunSync()174 bool VirtualKeyboardPrivateOpenSettingsFunction::RunSync() {
175 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
176 #if defined(USE_ASH)
177 #if defined(OS_CHROMEOS)
178 // Do not try to open language options page if user is not logged in or
179 // locked.
180 if (!user_manager::UserManager::Get()->IsUserLoggedIn() ||
181 chromeos::UserAddingScreen::Get()->IsRunning() ||
182 (chromeos::ScreenLocker::default_screen_locker() &&
183 chromeos::ScreenLocker::default_screen_locker()->locked()))
184 return true;
185 #endif // OS_CHROMEOS
186
187 content::RecordAction(base::UserMetricsAction("OpenLanguageOptionsDialog"));
188 chrome::ShowSettingsSubPageForProfile(
189 ProfileManager::GetActiveUserProfile(), chrome::kLanguageOptionsSubPage);
190 return true;
191 #else
192 error_ = kNotYetImplementedError;
193 return false;
194 #endif
195 }
196
InputAPI(content::BrowserContext * context)197 InputAPI::InputAPI(content::BrowserContext* context) {}
198
~InputAPI()199 InputAPI::~InputAPI() {
200 }
201
202 static base::LazyInstance<BrowserContextKeyedAPIFactory<InputAPI> > g_factory =
203 LAZY_INSTANCE_INITIALIZER;
204
205 // static
GetFactoryInstance()206 BrowserContextKeyedAPIFactory<InputAPI>* InputAPI::GetFactoryInstance() {
207 return g_factory.Pointer();
208 }
209
210 } // namespace extensions
211