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 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 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 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 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 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 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 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 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 197 InputAPI::InputAPI(content::BrowserContext* context) {} 198 199 InputAPI::~InputAPI() { 200 } 201 202 static base::LazyInstance<BrowserContextKeyedAPIFactory<InputAPI> > g_factory = 203 LAZY_INSTANCE_INITIALIZER; 204 205 // static 206 BrowserContextKeyedAPIFactory<InputAPI>* InputAPI::GetFactoryInstance() { 207 return g_factory.Pointer(); 208 } 209 210 } // namespace extensions 211