input_device_settings.cc revision 5821806d5e7f356e8fa4b058a389a808ea183019
1// Copyright (c) 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/chromeos/system/input_device_settings.h" 6 7#include <stdarg.h> 8#include <string> 9#include <vector> 10 11#include "base/bind.h" 12#include "base/chromeos/chromeos_version.h" 13#include "base/command_line.h" 14#include "base/file_path.h" 15#include "base/file_util.h" 16#include "base/message_loop.h" 17#include "base/process_util.h" 18#include "base/stringprintf.h" 19#include "base/threading/sequenced_worker_pool.h" 20#include "content/public/browser/browser_thread.h" 21 22namespace chromeos { 23namespace system { 24 25namespace { 26const char kTpControl[] = "/opt/google/touchpad/tpcontrol"; 27const char kMouseControl[] = "/opt/google/mouse/mousecontrol"; 28 29bool ScriptExists(const std::string& script) { 30 DCHECK(content::BrowserThread::GetBlockingPool()->RunsTasksOnCurrentThread()); 31 return file_util::PathExists(FilePath(script)); 32} 33 34// Executes the input control script asynchronously, if it exists. 35void ExecuteScriptOnFileThread(const std::vector<std::string>& argv) { 36 DCHECK(content::BrowserThread::GetBlockingPool()->RunsTasksOnCurrentThread()); 37 DCHECK(!argv.empty()); 38 const std::string& script(argv[0]); 39 40 // Script must exist on device. 41 DCHECK(!base::chromeos::IsRunningOnChromeOS() || ScriptExists(script)); 42 43 if (!ScriptExists(script)) 44 return; 45 46 base::LaunchOptions options; 47 options.wait = true; 48 base::LaunchProcess(CommandLine(argv), options, NULL); 49} 50 51void ExecuteScript(int argc, ...) { 52 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 53 std::vector<std::string> argv; 54 va_list vl; 55 va_start(vl, argc); 56 for (int i = 0; i < argc; ++i) { 57 argv.push_back(va_arg(vl, const char*)); 58 } 59 va_end(vl); 60 61 content::BrowserThread::GetBlockingPool()->PostTask(FROM_HERE, 62 base::Bind(&ExecuteScriptOnFileThread, argv)); 63} 64 65void SetPointerSensitivity(const char* script, int value) { 66 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 67 DCHECK(value > 0 && value < 6); 68 ExecuteScript(3, script, "sensitivity", StringPrintf("%d", value).c_str()); 69} 70 71void SetTPControl(const char* control, bool enabled) { 72 ExecuteScript(3, kTpControl, control, enabled ? "on" : "off"); 73} 74 75void DeviceExistsBlockingPool(const char* script, bool* exists) { 76 DCHECK(content::BrowserThread::GetBlockingPool()->RunsTasksOnCurrentThread()); 77 *exists = false; 78 if (!ScriptExists(script)) 79 return; 80 81 std::vector<std::string> argv; 82 argv.push_back(script); 83 argv.push_back("status"); 84 std::string output; 85 // Output is empty if the device is not found. 86 *exists = base::GetAppOutput(CommandLine(argv), &output) && !output.empty(); 87 DVLOG(1) << "DeviceExistsBlockingPool:" << script << "=" << *exists; 88} 89 90void RunCallbackUIThread(bool* exists, const DeviceExistsCallback& callback) { 91 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 92 DVLOG(1) << "RunCallbackUIThread " << *exists; 93 callback.Run(*exists); 94} 95 96void DeviceExists(const char* script, const DeviceExistsCallback& callback) { 97 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 98 99 bool* exists = new bool(false); 100 content::BrowserThread::GetBlockingPool()->PostTaskAndReply(FROM_HERE, 101 base::Bind(&DeviceExistsBlockingPool, script, exists), 102 base::Bind(&RunCallbackUIThread, base::Owned(exists), callback)); 103} 104 105} // namespace 106 107namespace touchpad_settings { 108 109void TouchpadExists(const DeviceExistsCallback& callback) { 110 DeviceExists(kTpControl, callback); 111} 112 113// Sets the touchpad sensitivity in the range [1, 5]. 114void SetSensitivity(int value) { 115 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 116 SetPointerSensitivity(kTpControl, value); 117} 118 119void SetTapToClick(bool enabled) { 120 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 121 SetTPControl("taptoclick", enabled); 122} 123 124void SetThreeFingerClick(bool enabled) { 125 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 126 127 SetTPControl("three_finger_click", enabled); 128 // For Alex/ZGB. 129 SetTPControl("t5r2_three_finger_click", enabled); 130} 131 132void SetThreeFingerSwipe(bool enabled) { 133 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 134 SetTPControl("three_finger_swipe", enabled); 135} 136 137void SetTapDragging(bool enabled) { 138 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 139 SetTPControl("tap_dragging", enabled); 140} 141 142} // namespace touchpad_settings 143 144namespace mouse_settings { 145 146void MouseExists(const DeviceExistsCallback& callback) { 147 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 148 DeviceExists(kMouseControl, callback); 149} 150 151// Sets the touchpad sensitivity in the range [1, 5]. 152void SetSensitivity(int value) { 153 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 154 SetPointerSensitivity(kMouseControl, value); 155} 156 157void SetPrimaryButtonRight(bool right) { 158 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 159 ExecuteScript(3, kMouseControl, "swap_left_right", right ? "1" : "0"); 160} 161 162} // namespace mouse_settings 163 164} // namespace system 165} // namespace chromeos 166