Merge "Add a preference panel for mouse speed." into honeycomb-mr2

This commit is contained in:
Jeff Brown
2011-06-02 17:26:05 -07:00
committed by Android (Google) Code Review
15 changed files with 232 additions and 35 deletions

View File

@ -1024,6 +1024,17 @@
visibility="public" visibility="public"
> >
</field> </field>
<field name="SET_POINTER_SPEED"
type="java.lang.String"
transient="false"
volatile="false"
value="&quot;android.permission.SET_POINTER_SPEED&quot;"
static="true"
final="true"
deprecated="not deprecated"
visibility="public"
>
</field>
<field name="SET_PREFERRED_APPLICATIONS" <field name="SET_PREFERRED_APPLICATIONS"
type="java.lang.String" type="java.lang.String"
transient="false" transient="false"

View File

@ -1790,6 +1790,16 @@ public final class Settings {
*/ */
public static final String SIP_ASK_ME_EACH_TIME = "SIP_ASK_ME_EACH_TIME"; public static final String SIP_ASK_ME_EACH_TIME = "SIP_ASK_ME_EACH_TIME";
/**
* Pointer speed setting.
* This is an integer value in a range between -7 and +7, so there are 15 possible values.
* -7 = slowest
* 0 = default speed
* +7 = fastest
* @hide
*/
public static final String POINTER_SPEED = "pointer_speed";
/** /**
* Settings to backup. This is here so that it's in the same place as the settings * Settings to backup. This is here so that it's in the same place as the settings
* keys and easy to update. * keys and easy to update.
@ -1854,6 +1864,7 @@ public final class Settings {
USE_PTP_INTERFACE, USE_PTP_INTERFACE,
SIP_CALL_OPTIONS, SIP_CALL_OPTIONS,
SIP_RECEIVE_CALLS, SIP_RECEIVE_CALLS,
POINTER_SPEED,
}; };
// Settings moved to Settings.Secure // Settings moved to Settings.Secure

View File

@ -205,4 +205,9 @@ interface IWindowManager
* Called by the status bar to notify Views of changes to System UI visiblity. * Called by the status bar to notify Views of changes to System UI visiblity.
*/ */
void statusBarVisibilityChanged(int visibility); void statusBarVisibilityChanged(int visibility);
/**
* Called by the settings application to temporarily set the pointer speed.
*/
void setPointerSpeed(int speed);
} }

View File

@ -1071,6 +1071,13 @@
android:description="@string/permdesc_setOrientation" android:description="@string/permdesc_setOrientation"
android:protectionLevel="signature" /> android:protectionLevel="signature" />
<!-- Allows low-level access to setting the pointer speed.
Not for use by normal applications. -->
<permission android:name="android.permission.SET_POINTER_SPEED"
android:label="@string/permlab_setPointerSpeed"
android:description="@string/permdesc_setPointerSpeed"
android:protectionLevel="signature" />
<!-- Allows an application to install packages. --> <!-- Allows an application to install packages. -->
<permission android:name="android.permission.INSTALL_PACKAGES" <permission android:name="android.permission.INSTALL_PACKAGES"
android:label="@string/permlab_installPackages" android:label="@string/permlab_installPackages"

View File

@ -699,6 +699,13 @@
the rotation of the screen at any time. Should never be needed for the rotation of the screen at any time. Should never be needed for
normal applications.</string> normal applications.</string>
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. [CHAR LIMIT=30] -->
<string name="permlab_setPointerSpeed">change pointer speed</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. [CHAR LIMIT=NONE] -->
<string name="permdesc_setPointerSpeed">Allows an application to change
the mouse or trackpad pointer speed at any time. Should never be needed for
normal applications.</string>
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. --> <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permlab_signalPersistentProcesses">send Linux signals to applications</string> <string name="permlab_signalPersistentProcesses">send Linux signals to applications</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. --> <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->

View File

@ -125,4 +125,7 @@
<!-- Default for Settings.Secure.LONG_PRESS_TIMEOUT_MILLIS --> <!-- Default for Settings.Secure.LONG_PRESS_TIMEOUT_MILLIS -->
<integer name="def_long_press_timeout_millis">500</integer> <integer name="def_long_press_timeout_millis">500</integer>
<!-- Default for Settings.System.POINTER_SPEED -->
<integer name="def_pointer_speed">0</integer>
</resources> </resources>

View File

@ -1214,6 +1214,9 @@ public class DatabaseHelper extends SQLiteOpenHelper {
loadBooleanSetting(stmt, Settings.System.NOTIFICATIONS_USE_RING_VOLUME, loadBooleanSetting(stmt, Settings.System.NOTIFICATIONS_USE_RING_VOLUME,
R.bool.def_notifications_use_ring_volume); R.bool.def_notifications_use_ring_volume);
loadIntegerSetting(stmt, Settings.System.POINTER_SPEED,
R.integer.def_pointer_speed);
} finally { } finally {
if (stmt != null) stmt.close(); if (stmt != null) stmt.close();
} }

View File

@ -33,6 +33,7 @@
#include <hardware_legacy/power.h> #include <hardware_legacy/power.h>
#include <cutils/atomic.h>
#include <cutils/properties.h> #include <cutils/properties.h>
#include <utils/Log.h> #include <utils/Log.h>
#include <utils/Timers.h> #include <utils/Timers.h>
@ -127,6 +128,7 @@ EventHub::EventHub(void) :
mError(NO_INIT), mBuiltInKeyboardId(-1), mNextDeviceId(1), mError(NO_INIT), mBuiltInKeyboardId(-1), mNextDeviceId(1),
mOpeningDevices(0), mClosingDevices(0), mOpeningDevices(0), mClosingDevices(0),
mOpened(false), mNeedToSendFinishedDeviceScan(false), mOpened(false), mNeedToSendFinishedDeviceScan(false),
mNeedToReopenDevices(0), mNeedToScanDevices(false),
mInputFdIndex(1) { mInputFdIndex(1) {
acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_ID); acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_ID);
@ -380,12 +382,10 @@ status_t EventHub::mapAxis(int32_t deviceId, int scancode, AxisInfo* outAxisInfo
return NAME_NOT_FOUND; return NAME_NOT_FOUND;
} }
void EventHub::addExcludedDevice(const char* deviceName) void EventHub::setExcludedDevices(const Vector<String8>& devices) {
{
AutoMutex _l(mLock); AutoMutex _l(mLock);
String8 name(deviceName); mExcludedDevices = devices;
mExcludedDevices.push_back(name);
} }
bool EventHub::hasLed(int32_t deviceId, int32_t led) const { bool EventHub::hasLed(int32_t deviceId, int32_t led) const {
@ -453,9 +453,11 @@ size_t EventHub::getEvents(int timeoutMillis, RawEvent* buffer, size_t bufferSiz
assert(bufferSize >= 1); assert(bufferSize >= 1);
if (!mOpened) { if (!mOpened) {
android_atomic_acquire_store(0, &mNeedToReopenDevices);
mError = openPlatformInput() ? NO_ERROR : UNKNOWN_ERROR; mError = openPlatformInput() ? NO_ERROR : UNKNOWN_ERROR;
mOpened = true; mOpened = true;
mNeedToSendFinishedDeviceScan = true; mNeedToScanDevices = true;
} }
struct input_event readBuffer[bufferSize]; struct input_event readBuffer[bufferSize];
@ -465,6 +467,20 @@ size_t EventHub::getEvents(int timeoutMillis, RawEvent* buffer, size_t bufferSiz
for (;;) { for (;;) {
nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC); nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
// Reopen input devices if needed.
if (android_atomic_acquire_load(&mNeedToReopenDevices)) {
android_atomic_acquire_store(0, &mNeedToReopenDevices);
LOGI("Reopening all input devices due to a configuration change.");
AutoMutex _l(mLock);
while (mDevices.size() > 1) {
closeDeviceAtIndexLocked(mDevices.size() - 1);
}
mNeedToScanDevices = true;
break; // return to the caller before we actually rescan
}
// Report any devices that had last been added/removed. // Report any devices that had last been added/removed.
while (mClosingDevices) { while (mClosingDevices) {
Device* device = mClosingDevices; Device* device = mClosingDevices;
@ -482,6 +498,12 @@ size_t EventHub::getEvents(int timeoutMillis, RawEvent* buffer, size_t bufferSiz
} }
} }
if (mNeedToScanDevices) {
mNeedToScanDevices = false;
scanDevices();
mNeedToSendFinishedDeviceScan = true;
}
while (mOpeningDevices != NULL) { while (mOpeningDevices != NULL) {
Device* device = mOpeningDevices; Device* device = mOpeningDevices;
LOGV("Reporting device opened: id=%d, name=%s\n", LOGV("Reporting device opened: id=%d, name=%s\n",
@ -683,13 +705,14 @@ bool EventHub::openPlatformInput(void) {
pollfd.revents = 0; pollfd.revents = 0;
mFds.push(pollfd); mFds.push(pollfd);
mDevices.push(NULL); mDevices.push(NULL);
return true;
}
res = scanDir(DEVICE_PATH); void EventHub::scanDevices() {
int res = scanDir(DEVICE_PATH);
if(res < 0) { if(res < 0) {
LOGE("scan dir failed for %s\n", DEVICE_PATH); LOGE("scan dir failed for %s\n", DEVICE_PATH);
} }
return true;
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@ -742,12 +765,10 @@ int EventHub::openDevice(const char *devicePath) {
} }
// Check to see if the device is on our excluded list // Check to see if the device is on our excluded list
List<String8>::iterator iter = mExcludedDevices.begin(); for (size_t i = 0; i < mExcludedDevices.size(); i++) {
List<String8>::iterator end = mExcludedDevices.end(); const String8& item = mExcludedDevices.itemAt(i);
for ( ; iter != end; iter++) { if (identifier.name == item) {
const char* test = *iter; LOGI("ignoring event id %s driver %s\n", devicePath, item.string());
if (identifier.name == test) {
LOGI("ignoring event id %s driver %s\n", devicePath, test);
close(fd); close(fd);
return -1; return -1;
} }
@ -1210,6 +1231,10 @@ int EventHub::scanDir(const char *dirname)
return 0; return 0;
} }
void EventHub::reopenDevices() {
android_atomic_release_store(1, &mNeedToReopenDevices);
}
void EventHub::dump(String8& dump) { void EventHub::dump(String8& dump) {
dump.append("Event Hub State:\n"); dump.append("Event Hub State:\n");

View File

@ -178,9 +178,9 @@ public:
virtual status_t mapAxis(int32_t deviceId, int scancode, virtual status_t mapAxis(int32_t deviceId, int scancode,
AxisInfo* outAxisInfo) const = 0; AxisInfo* outAxisInfo) const = 0;
// exclude a particular device from opening // Sets devices that are excluded from opening.
// this can be used to ignore input devices for sensors // This can be used to ignore input devices for sensors.
virtual void addExcludedDevice(const char* deviceName) = 0; virtual void setExcludedDevices(const Vector<String8>& devices) = 0;
/* /*
* Wait for events to become available and returns them. * Wait for events to become available and returns them.
@ -215,6 +215,8 @@ public:
virtual void getVirtualKeyDefinitions(int32_t deviceId, virtual void getVirtualKeyDefinitions(int32_t deviceId,
Vector<VirtualKeyDefinition>& outVirtualKeys) const = 0; Vector<VirtualKeyDefinition>& outVirtualKeys) const = 0;
virtual void reopenDevices() = 0;
virtual void dump(String8& dump) = 0; virtual void dump(String8& dump) = 0;
}; };
@ -242,7 +244,7 @@ public:
virtual status_t mapAxis(int32_t deviceId, int scancode, virtual status_t mapAxis(int32_t deviceId, int scancode,
AxisInfo* outAxisInfo) const; AxisInfo* outAxisInfo) const;
virtual void addExcludedDevice(const char* deviceName); virtual void setExcludedDevices(const Vector<String8>& devices);
virtual int32_t getScanCodeState(int32_t deviceId, int32_t scanCode) const; virtual int32_t getScanCodeState(int32_t deviceId, int32_t scanCode) const;
virtual int32_t getKeyCodeState(int32_t deviceId, int32_t keyCode) const; virtual int32_t getKeyCodeState(int32_t deviceId, int32_t keyCode) const;
@ -259,6 +261,8 @@ public:
virtual void getVirtualKeyDefinitions(int32_t deviceId, virtual void getVirtualKeyDefinitions(int32_t deviceId,
Vector<VirtualKeyDefinition>& outVirtualKeys) const; Vector<VirtualKeyDefinition>& outVirtualKeys) const;
virtual void reopenDevices();
virtual void dump(String8& dump); virtual void dump(String8& dump);
protected: protected:
@ -271,6 +275,7 @@ private:
int closeDevice(const char *devicePath); int closeDevice(const char *devicePath);
int closeDeviceAtIndexLocked(int index); int closeDeviceAtIndexLocked(int index);
int scanDir(const char *dirname); int scanDir(const char *dirname);
void scanDevices();
int readNotify(int nfd); int readNotify(int nfd);
status_t mError; status_t mError;
@ -333,7 +338,9 @@ private:
bool mOpened; bool mOpened;
bool mNeedToSendFinishedDeviceScan; bool mNeedToSendFinishedDeviceScan;
List<String8> mExcludedDevices; volatile int32_t mNeedToReopenDevices; // must be modified atomically
bool mNeedToScanDevices;
Vector<String8> mExcludedDevices;
// device ids that report particular switches. // device ids that report particular switches.
int32_t mSwitches[SW_MAX + 1]; int32_t mSwitches[SW_MAX + 1];

View File

@ -38,6 +38,7 @@
#include "InputReader.h" #include "InputReader.h"
#include <cutils/atomic.h>
#include <cutils/log.h> #include <cutils/log.h>
#include <ui/Keyboard.h> #include <ui/Keyboard.h>
#include <ui/VirtualKeyMap.h> #include <ui/VirtualKeyMap.h>
@ -219,10 +220,9 @@ InputReader::InputReader(const sp<EventHubInterface>& eventHub,
const sp<InputReaderPolicyInterface>& policy, const sp<InputReaderPolicyInterface>& policy,
const sp<InputDispatcherInterface>& dispatcher) : const sp<InputDispatcherInterface>& dispatcher) :
mEventHub(eventHub), mPolicy(policy), mDispatcher(dispatcher), mEventHub(eventHub), mPolicy(policy), mDispatcher(dispatcher),
mGlobalMetaState(0), mDisableVirtualKeysTimeout(LLONG_MIN), mNextTimeout(LLONG_MAX) { mGlobalMetaState(0), mDisableVirtualKeysTimeout(LLONG_MIN), mNextTimeout(LLONG_MAX),
mPolicy->getReaderConfiguration(&mConfig); mRefreshConfiguration(0) {
configure(true /*firstTime*/);
configureExcludedDevices();
updateGlobalMetaState(); updateGlobalMetaState();
updateInputConfiguration(); updateInputConfiguration();
} }
@ -234,6 +234,11 @@ InputReader::~InputReader() {
} }
void InputReader::loopOnce() { void InputReader::loopOnce() {
if (android_atomic_acquire_load(&mRefreshConfiguration)) {
android_atomic_release_store(0, &mRefreshConfiguration);
configure(false /*firstTime*/);
}
int32_t timeoutMillis = -1; int32_t timeoutMillis = -1;
if (mNextTimeout != LLONG_MAX) { if (mNextTimeout != LLONG_MAX) {
nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC); nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
@ -454,9 +459,12 @@ void InputReader::handleConfigurationChanged(nsecs_t when) {
mDispatcher->notifyConfigurationChanged(when); mDispatcher->notifyConfigurationChanged(when);
} }
void InputReader::configureExcludedDevices() { void InputReader::configure(bool firstTime) {
for (size_t i = 0; i < mConfig.excludedDeviceNames.size(); i++) { mPolicy->getReaderConfiguration(&mConfig);
mEventHub->addExcludedDevice(mConfig.excludedDeviceNames[i]); mEventHub->setExcludedDevices(mConfig.excludedDeviceNames);
if (!firstTime) {
mEventHub->reopenDevices();
} }
} }
@ -677,6 +685,10 @@ bool InputReader::markSupportedKeyCodes(int32_t deviceId, uint32_t sourceMask, s
} // release device registy reader lock } // release device registy reader lock
} }
void InputReader::refreshConfiguration() {
android_atomic_release_store(1, &mRefreshConfiguration);
}
void InputReader::dump(String8& dump) { void InputReader::dump(String8& dump) {
mEventHub->dump(dump); mEventHub->dump(dump);
dump.append("\n"); dump.append("\n");

View File

@ -145,7 +145,7 @@ struct InputReaderConfiguration {
pointerGestureMultitouchMinSpeed(150.0f), // 150 pixels per second pointerGestureMultitouchMinSpeed(150.0f), // 150 pixels per second
pointerGestureSwipeTransitionAngleCosine(0.5f), // cosine of 45degrees pointerGestureSwipeTransitionAngleCosine(0.5f), // cosine of 45degrees
pointerGestureSwipeMaxWidthRatio(0.333f), pointerGestureSwipeMaxWidthRatio(0.333f),
pointerGestureMovementSpeedRatio(0.5f), pointerGestureMovementSpeedRatio(0.3f),
pointerGestureZoomSpeedRatio(0.3f) { } pointerGestureZoomSpeedRatio(0.3f) { }
}; };
@ -234,6 +234,9 @@ public:
/* Determine whether physical keys exist for the given framework-domain key codes. */ /* Determine whether physical keys exist for the given framework-domain key codes. */
virtual bool hasKeys(int32_t deviceId, uint32_t sourceMask, virtual bool hasKeys(int32_t deviceId, uint32_t sourceMask,
size_t numCodes, const int32_t* keyCodes, uint8_t* outFlags) = 0; size_t numCodes, const int32_t* keyCodes, uint8_t* outFlags) = 0;
/* Reopens and reconfigures all input devices. */
virtual void refreshConfiguration() = 0;
}; };
@ -298,6 +301,8 @@ public:
virtual bool hasKeys(int32_t deviceId, uint32_t sourceMask, virtual bool hasKeys(int32_t deviceId, uint32_t sourceMask,
size_t numCodes, const int32_t* keyCodes, uint8_t* outFlags); size_t numCodes, const int32_t* keyCodes, uint8_t* outFlags);
virtual void refreshConfiguration();
protected: protected:
// These methods are protected virtual so they can be overridden and instrumented // These methods are protected virtual so they can be overridden and instrumented
// by test cases. // by test cases.
@ -339,18 +344,17 @@ private:
void timeoutExpired(nsecs_t when); void timeoutExpired(nsecs_t when);
void handleConfigurationChanged(nsecs_t when); void handleConfigurationChanged(nsecs_t when);
void configureExcludedDevices();
// state management for all devices // state management for all devices
Mutex mStateLock; Mutex mStateLock;
int32_t mGlobalMetaState; int32_t mGlobalMetaState; // guarded by mStateLock
virtual void updateGlobalMetaState(); virtual void updateGlobalMetaState();
virtual int32_t getGlobalMetaState(); virtual int32_t getGlobalMetaState();
virtual void fadePointer(); virtual void fadePointer();
InputConfiguration mInputConfiguration; InputConfiguration mInputConfiguration; // guarded by mStateLock
void updateInputConfiguration(); void updateInputConfiguration();
nsecs_t mDisableVirtualKeysTimeout; // only accessed by reader thread nsecs_t mDisableVirtualKeysTimeout; // only accessed by reader thread
@ -358,9 +362,12 @@ private:
virtual bool shouldDropVirtualKey(nsecs_t now, virtual bool shouldDropVirtualKey(nsecs_t now,
InputDevice* device, int32_t keyCode, int32_t scanCode); InputDevice* device, int32_t keyCode, int32_t scanCode);
nsecs_t mNextTimeout; // only accessed by reader thread nsecs_t mNextTimeout; // only accessed by reader thread, not guarded
virtual void requestTimeoutAtTime(nsecs_t when); virtual void requestTimeoutAtTime(nsecs_t when);
volatile int32_t mRefreshConfiguration; // atomic
void configure(bool firstTime);
// state queries // state queries
typedef int32_t (InputDevice::*GetStateFunc)(uint32_t sourceMask, int32_t code); typedef int32_t (InputDevice::*GetStateFunc)(uint32_t sourceMask, int32_t code);
int32_t getState(int32_t deviceId, uint32_t sourceMask, int32_t code, int32_t getState(int32_t deviceId, uint32_t sourceMask, int32_t code,

View File

@ -617,8 +617,8 @@ private:
return NAME_NOT_FOUND; return NAME_NOT_FOUND;
} }
virtual void addExcludedDevice(const char* deviceName) { virtual void setExcludedDevices(const Vector<String8>& devices) {
mExcludedDevices.add(String8(deviceName)); mExcludedDevices = devices;
} }
virtual size_t getEvents(int timeoutMillis, RawEvent* buffer, size_t bufferSize) { virtual size_t getEvents(int timeoutMillis, RawEvent* buffer, size_t bufferSize) {
@ -716,6 +716,9 @@ private:
virtual void dump(String8& dump) { virtual void dump(String8& dump) {
} }
virtual void reopenDevices() {
}
}; };

View File

@ -23,10 +23,14 @@ import org.xmlpull.v1.XmlPullParser;
import android.content.Context; import android.content.Context;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.content.res.Configuration; import android.content.res.Configuration;
import android.database.ContentObserver;
import android.os.Environment; import android.os.Environment;
import android.os.Handler;
import android.os.Looper; import android.os.Looper;
import android.os.MessageQueue; import android.os.MessageQueue;
import android.os.SystemProperties; import android.os.SystemProperties;
import android.provider.Settings;
import android.provider.Settings.SettingNotFoundException;
import android.util.Slog; import android.util.Slog;
import android.util.Xml; import android.util.Xml;
import android.view.InputChannel; import android.view.InputChannel;
@ -85,6 +89,7 @@ public class InputManager {
private static native int[] nativeGetInputDeviceIds(); private static native int[] nativeGetInputDeviceIds();
private static native boolean nativeTransferTouchFocus(InputChannel fromChannel, private static native boolean nativeTransferTouchFocus(InputChannel fromChannel,
InputChannel toChannel); InputChannel toChannel);
private static native void nativeSetPointerSpeed(int speed);
private static native String nativeDump(); private static native String nativeDump();
// Input event injection constants defined in InputDispatcher.h. // Input event injection constants defined in InputDispatcher.h.
@ -127,6 +132,9 @@ public class InputManager {
public void start() { public void start() {
Slog.i(TAG, "Starting input manager"); Slog.i(TAG, "Starting input manager");
nativeStart(); nativeStart();
registerPointerSpeedSettingObserver();
updatePointerSpeedFromSettings();
} }
public void setDisplaySize(int displayId, int width, int height) { public void setDisplaySize(int displayId, int width, int height) {
@ -359,6 +367,42 @@ public class InputManager {
return nativeTransferTouchFocus(fromChannel, toChannel); return nativeTransferTouchFocus(fromChannel, toChannel);
} }
/**
* Set the pointer speed.
* @param speed The pointer speed as a value between -7 (slowest) and 7 (fastest)
* where 0 is the default speed.
*/
public void setPointerSpeed(int speed) {
speed = Math.min(Math.max(speed, -7), 7);
nativeSetPointerSpeed(speed);
}
public void updatePointerSpeedFromSettings() {
int speed = getPointerSpeedSetting(0);
setPointerSpeed(speed);
}
private void registerPointerSpeedSettingObserver() {
mContext.getContentResolver().registerContentObserver(
Settings.System.getUriFor(Settings.System.POINTER_SPEED), true,
new ContentObserver(mWindowManagerService.mH) {
@Override
public void onChange(boolean selfChange) {
updatePointerSpeedFromSettings();
}
});
}
private int getPointerSpeedSetting(int defaultValue) {
int speed = defaultValue;
try {
speed = Settings.System.getInt(mContext.getContentResolver(),
Settings.System.POINTER_SPEED);
} catch (SettingNotFoundException snfe) {
}
return speed;
}
public void dump(PrintWriter pw) { public void dump(PrintWriter pw) {
String dumpStr = nativeDump(); String dumpStr = nativeDump();
if (dumpStr != null) { if (dumpStr != null) {

View File

@ -5947,6 +5947,19 @@ public class WindowManagerService extends IWindowManager.Stub
} }
} }
/**
* Temporarily set the pointer speed. Does not save the new setting.
* Used by the settings application.
*/
public void setPointerSpeed(int speed) {
if (!checkCallingPermission(android.Manifest.permission.SET_POINTER_SPEED,
"setPointerSpeed()")) {
throw new SecurityException("Requires SET_POINTER_SPEED permission");
}
mInputManager.setPointerSpeed(speed);
}
private WindowState getFocusedWindow() { private WindowState getFocusedWindow() {
synchronized (mWindowMap) { synchronized (mWindowMap) {
return getFocusedWindowLocked(); return getFocusedWindowLocked();

View File

@ -53,6 +53,11 @@
namespace android { namespace android {
// The exponent used to calculate the pointer speed scaling factor.
// The scaling factor is calculated as 2 ^ (speed * exponent),
// where the speed ranges from -7 to + 7 and is supplied by the user.
static const float POINTER_SPEED_EXPONENT = 1.0f / 3;
static struct { static struct {
jclass clazz; jclass clazz;
@ -179,6 +184,7 @@ public:
void setFocusedApplication(JNIEnv* env, jobject applicationObj); void setFocusedApplication(JNIEnv* env, jobject applicationObj);
void setInputDispatchMode(bool enabled, bool frozen); void setInputDispatchMode(bool enabled, bool frozen);
void setSystemUiVisibility(int32_t visibility); void setSystemUiVisibility(int32_t visibility);
void setPointerSpeed(int32_t speed);
/* --- InputReaderPolicyInterface implementation --- */ /* --- InputReaderPolicyInterface implementation --- */
@ -227,6 +233,9 @@ private:
// System UI visibility. // System UI visibility.
int32_t systemUiVisibility; int32_t systemUiVisibility;
// Pointer speed.
int32_t pointerSpeed;
// Sprite controller singleton, created on first use. // Sprite controller singleton, created on first use.
sp<SpriteController> spriteController; sp<SpriteController> spriteController;
@ -266,6 +275,7 @@ NativeInputManager::NativeInputManager(jobject contextObj,
mLocked.displayOrientation = ROTATION_0; mLocked.displayOrientation = ROTATION_0;
mLocked.systemUiVisibility = ASYSTEM_UI_VISIBILITY_STATUS_BAR_VISIBLE; mLocked.systemUiVisibility = ASYSTEM_UI_VISIBILITY_STATUS_BAR_VISIBLE;
mLocked.pointerSpeed = 0;
} }
sp<EventHub> eventHub = new EventHub(); sp<EventHub> eventHub = new EventHub();
@ -429,6 +439,13 @@ void NativeInputManager::getReaderConfiguration(InputReaderConfiguration* outCon
if (!checkAndClearExceptionFromCallback(env, "getTouchSlop")) { if (!checkAndClearExceptionFromCallback(env, "getTouchSlop")) {
outConfig->pointerGestureTapSlop = touchSlop; outConfig->pointerGestureTapSlop = touchSlop;
} }
{ // acquire lock
AutoMutex _l(mLock);
outConfig->pointerVelocityControlParameters.scale = exp2f(mLocked.pointerSpeed
* POINTER_SPEED_EXPONENT);
} // release lock
} }
sp<PointerControllerInterface> NativeInputManager::obtainPointerController(int32_t deviceId) { sp<PointerControllerInterface> NativeInputManager::obtainPointerController(int32_t deviceId) {
@ -634,6 +651,17 @@ void NativeInputManager::updateInactivityTimeoutLocked(const sp<PointerControlle
: PointerController::INACTIVITY_TIMEOUT_NORMAL); : PointerController::INACTIVITY_TIMEOUT_NORMAL);
} }
void NativeInputManager::setPointerSpeed(int32_t speed) {
AutoMutex _l(mLock);
if (mLocked.pointerSpeed != speed) {
LOGI("Setting pointer speed to %d.", speed);
mLocked.pointerSpeed = speed;
mInputManager->getReader()->refreshConfiguration();
}
}
bool NativeInputManager::isScreenOn() { bool NativeInputManager::isScreenOn() {
return android_server_PowerManagerService_isScreenOn(); return android_server_PowerManagerService_isScreenOn();
} }
@ -1180,6 +1208,15 @@ static jboolean android_server_InputManager_nativeTransferTouchFocus(JNIEnv* env
transferTouchFocus(fromChannel, toChannel); transferTouchFocus(fromChannel, toChannel);
} }
static void android_server_InputManager_nativeSetPointerSpeed(JNIEnv* env,
jclass clazz, jint speed) {
if (checkInputManagerUnitialized(env)) {
return;
}
gNativeInputManager->setPointerSpeed(speed);
}
static jstring android_server_InputManager_nativeDump(JNIEnv* env, jclass clazz) { static jstring android_server_InputManager_nativeDump(JNIEnv* env, jclass clazz) {
if (checkInputManagerUnitialized(env)) { if (checkInputManagerUnitialized(env)) {
return NULL; return NULL;
@ -1234,6 +1271,8 @@ static JNINativeMethod gInputManagerMethods[] = {
(void*) android_server_InputManager_nativeGetInputConfiguration }, (void*) android_server_InputManager_nativeGetInputConfiguration },
{ "nativeTransferTouchFocus", "(Landroid/view/InputChannel;Landroid/view/InputChannel;)Z", { "nativeTransferTouchFocus", "(Landroid/view/InputChannel;Landroid/view/InputChannel;)Z",
(void*) android_server_InputManager_nativeTransferTouchFocus }, (void*) android_server_InputManager_nativeTransferTouchFocus },
{ "nativeSetPointerSpeed", "(I)V",
(void*) android_server_InputManager_nativeSetPointerSpeed },
{ "nativeDump", "()Ljava/lang/String;", { "nativeDump", "()Ljava/lang/String;",
(void*) android_server_InputManager_nativeDump }, (void*) android_server_InputManager_nativeDump },
}; };