Set pointer acceleration for virtual devices

Bug: 202273865
Test: atest FrameworksServicesTests:InputControllerTest

Change-Id: Ida5db8b34e7b75f5db96d0c31484c76276803af0
This commit is contained in:
Christine Franks
2022-01-05 17:08:54 -08:00
parent 615951d16e
commit a7fe83fdc6
5 changed files with 62 additions and 1 deletions

View File

@@ -89,6 +89,12 @@ public abstract class InputManagerInternal {
/** Gets the current position of the mouse cursor. */
public abstract PointF getCursorPosition();
/**
* Sets the pointer acceleration.
* See {@code frameworks/native/include/input/VelocityControl.h#VelocityControlParameters}.
*/
public abstract void setPointerAcceleration(float acceleration);
/**
* Sets the eligibility of windows on a given display for pointer capture. If a display is
* marked ineligible, requests to enable pointer capture for windows on that display will be

View File

@@ -27,6 +27,7 @@ import android.hardware.input.VirtualMouseRelativeEvent;
import android.hardware.input.VirtualMouseScrollEvent;
import android.hardware.input.VirtualTouchEvent;
import android.os.IBinder;
import android.os.IInputConstants;
import android.os.RemoteException;
import android.util.ArrayMap;
import android.util.Slog;
@@ -126,6 +127,7 @@ class InputController {
final InputManagerInternal inputManagerInternal =
LocalServices.getService(InputManagerInternal.class);
inputManagerInternal.setVirtualMousePointerDisplayId(displayId);
inputManagerInternal.setPointerAcceleration(1);
mActivePointerDisplayId = displayId;
}
try {
@@ -210,6 +212,8 @@ class InputController {
final InputManagerInternal inputManagerInternal =
LocalServices.getService(InputManagerInternal.class);
inputManagerInternal.setVirtualMousePointerDisplayId(Display.INVALID_DISPLAY);
inputManagerInternal.setPointerAcceleration(
IInputConstants.DEFAULT_POINTER_ACCELERATION);
mActivePointerDisplayId = Display.INVALID_DISPLAY;
}

View File

@@ -317,6 +317,7 @@ public class InputManagerService extends IInputManager.Stub
IBinder fromChannelToken, IBinder toChannelToken, boolean isDragDrop);
private static native boolean nativeTransferTouch(long ptr, IBinder destChannelToken);
private static native void nativeSetPointerSpeed(long ptr, int speed);
private static native void nativeSetPointerAcceleration(long ptr, float acceleration);
private static native void nativeSetShowTouches(long ptr, boolean enabled);
private static native void nativeSetInteractive(long ptr, boolean interactive);
private static native void nativeReloadCalibration(long ptr);
@@ -1797,6 +1798,10 @@ public class InputManagerService extends IInputManager.Stub
nativeSetPointerSpeed(mPtr, speed);
}
private void setPointerAcceleration(float acceleration) {
nativeSetPointerAcceleration(mPtr, acceleration);
}
private void registerPointerSpeedSettingObserver() {
mContext.getContentResolver().registerContentObserver(
Settings.System.getUriFor(Settings.System.POINTER_SPEED), true,
@@ -3486,6 +3491,11 @@ public class InputManagerService extends IInputManager.Stub
return mWindowManagerCallbacks.getCursorPosition();
}
@Override
public void setPointerAcceleration(float acceleration) {
InputManagerService.this.setPointerAcceleration(acceleration);
}
@Override
public void setDisplayEligibilityForPointerCapture(int displayId, boolean isEligible) {
InputManagerService.this.setDisplayEligibilityForPointerCapture(displayId, isEligible);

View File

@@ -277,6 +277,7 @@ public:
void setInputDispatchMode(bool enabled, bool frozen);
void setSystemUiLightsOut(bool lightsOut);
void setPointerSpeed(int32_t speed);
void setPointerAcceleration(float acceleration);
void setInputDeviceEnabled(uint32_t deviceId, bool enabled);
void setShowTouches(bool enabled);
void setInteractive(bool interactive);
@@ -363,6 +364,9 @@ private:
// Pointer speed.
int32_t pointerSpeed;
// Pointer acceleration.
float pointerAcceleration;
// True if pointer gestures are enabled.
bool pointerGesturesEnabled;
@@ -412,6 +416,7 @@ NativeInputManager::NativeInputManager(jobject contextObj,
AutoMutex _l(mLock);
mLocked.systemUiLightsOut = false;
mLocked.pointerSpeed = 0;
mLocked.pointerAcceleration = android::os::IInputConstants::DEFAULT_POINTER_ACCELERATION;
mLocked.pointerGesturesEnabled = true;
mLocked.showTouches = false;
mLocked.pointerDisplayId = ADISPLAY_ID_DEFAULT;
@@ -439,6 +444,7 @@ void NativeInputManager::dump(std::string& dump) {
dump += StringPrintf(INDENT "System UI Lights Out: %s\n",
toString(mLocked.systemUiLightsOut));
dump += StringPrintf(INDENT "Pointer Speed: %" PRId32 "\n", mLocked.pointerSpeed);
dump += StringPrintf(INDENT "Pointer Acceleration: %0.3f\n", mLocked.pointerAcceleration);
dump += StringPrintf(INDENT "Pointer Gestures Enabled: %s\n",
toString(mLocked.pointerGesturesEnabled));
dump += StringPrintf(INDENT "Show Touches: %s\n", toString(mLocked.showTouches));
@@ -628,6 +634,7 @@ void NativeInputManager::getReaderConfiguration(InputReaderConfiguration* outCon
outConfig->pointerVelocityControlParameters.scale = exp2f(mLocked.pointerSpeed
* POINTER_SPEED_EXPONENT);
outConfig->pointerVelocityControlParameters.acceleration = mLocked.pointerAcceleration;
outConfig->pointerGesturesEnabled = mLocked.pointerGesturesEnabled;
outConfig->showTouches = mLocked.showTouches;
@@ -1066,6 +1073,22 @@ void NativeInputManager::setPointerSpeed(int32_t speed) {
InputReaderConfiguration::CHANGE_POINTER_SPEED);
}
void NativeInputManager::setPointerAcceleration(float acceleration) {
{ // acquire lock
AutoMutex _l(mLock);
if (mLocked.pointerAcceleration == acceleration) {
return;
}
ALOGI("Setting pointer acceleration to %0.3f", acceleration);
mLocked.pointerAcceleration = acceleration;
} // release lock
mInputManager->getReader().requestRefreshConfiguration(
InputReaderConfiguration::CHANGE_POINTER_SPEED);
}
void NativeInputManager::setInputDeviceEnabled(uint32_t deviceId, bool enabled) {
{ // acquire lock
AutoMutex _l(mLock);
@@ -1882,6 +1905,13 @@ static void nativeSetPointerSpeed(JNIEnv* /* env */, jclass /* clazz */, jlong p
im->setPointerSpeed(speed);
}
static void nativeSetPointerAcceleration(JNIEnv* /* env */, jclass /* clazz */, jlong ptr,
jfloat acceleration) {
NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
im->setPointerAcceleration(acceleration);
}
static void nativeSetShowTouches(JNIEnv* /* env */,
jclass /* clazz */, jlong ptr, jboolean enabled) {
NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
@@ -2373,6 +2403,7 @@ static const JNINativeMethod gInputManagerMethods[] = {
(void*)nativeTransferTouchFocus},
{"nativeTransferTouch", "(JLandroid/os/IBinder;)Z", (void*)nativeTransferTouch},
{"nativeSetPointerSpeed", "(JI)V", (void*)nativeSetPointerSpeed},
{"nativeSetPointerAcceleration", "(JF)V", (void*)nativeSetPointerAcceleration},
{"nativeSetShowTouches", "(JZ)V", (void*)nativeSetShowTouches},
{"nativeSetInteractive", "(JZ)V", (void*)nativeSetInteractive},
{"nativeReloadCalibration", "(J)V", (void*)nativeReloadCalibration},

View File

@@ -19,11 +19,13 @@ package com.android.server.companion.virtual;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import android.hardware.input.InputManagerInternal;
import android.os.Binder;
import android.os.IBinder;
import android.os.IInputConstants;
import android.platform.test.annotations.Presubmit;
import android.view.Display;
@@ -64,9 +66,13 @@ public class InputControllerTest {
final IBinder deviceToken = new Binder();
mInputController.createMouse("name", /*vendorId= */ 1, /*productId= */ 1, deviceToken,
/* displayId= */ 1);
verify(mInputManagerInternalMock).setVirtualMousePointerDisplayId(eq(1));
verify(mInputManagerInternalMock).setPointerAcceleration(eq(1f));
mInputController.unregisterInputDevice(deviceToken);
verify(mInputManagerInternalMock).setVirtualMousePointerDisplayId(
eq(Display.INVALID_DISPLAY));
verify(mInputManagerInternalMock).setPointerAcceleration(
eq((float) IInputConstants.DEFAULT_POINTER_ACCELERATION));
}
@Test
@@ -75,10 +81,14 @@ public class InputControllerTest {
mInputController.createMouse("name", /*vendorId= */ 1, /*productId= */ 1, deviceToken,
/* displayId= */ 1);
verify(mInputManagerInternalMock).setVirtualMousePointerDisplayId(eq(1));
mInputController.createMouse("name", /*vendorId= */ 1, /*productId= */ 1, deviceToken,
verify(mInputManagerInternalMock).setPointerAcceleration(eq(1f));
final IBinder deviceToken2 = new Binder();
mInputController.createMouse("name", /*vendorId= */ 1, /*productId= */ 1, deviceToken2,
/* displayId= */ 2);
verify(mInputManagerInternalMock).setVirtualMousePointerDisplayId(eq(2));
mInputController.unregisterInputDevice(deviceToken);
verify(mInputManagerInternalMock).setVirtualMousePointerDisplayId(eq(1));
verify(mInputManagerInternalMock, times(0)).setPointerAcceleration(
eq((float) IInputConstants.DEFAULT_POINTER_ACCELERATION));
}
}