Merge "Support unique calibration per orientation"
This commit is contained in:
committed by
Android (Google) Code Review
commit
9bec0f5cc1
@@ -41,8 +41,8 @@ interface IInputManager {
|
|||||||
boolean injectInputEvent(in InputEvent ev, int mode);
|
boolean injectInputEvent(in InputEvent ev, int mode);
|
||||||
|
|
||||||
// Calibrate input device position
|
// Calibrate input device position
|
||||||
TouchCalibration getTouchCalibrationForInputDevice(String inputDeviceDescriptor);
|
TouchCalibration getTouchCalibrationForInputDevice(String inputDeviceDescriptor, int rotation);
|
||||||
void setTouchCalibrationForInputDevice(String inputDeviceDescriptor,
|
void setTouchCalibrationForInputDevice(String inputDeviceDescriptor, int rotation,
|
||||||
in TouchCalibration calibration);
|
in TouchCalibration calibration);
|
||||||
|
|
||||||
// Keyboard layouts configuration.
|
// Keyboard layouts configuration.
|
||||||
|
|||||||
@@ -508,9 +508,9 @@ public final class InputManager {
|
|||||||
*
|
*
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
public TouchCalibration getTouchCalibration(String inputDeviceDescriptor) {
|
public TouchCalibration getTouchCalibration(String inputDeviceDescriptor, int surfaceRotation) {
|
||||||
try {
|
try {
|
||||||
return mIm.getTouchCalibrationForInputDevice(inputDeviceDescriptor);
|
return mIm.getTouchCalibrationForInputDevice(inputDeviceDescriptor, surfaceRotation);
|
||||||
} catch (RemoteException ex) {
|
} catch (RemoteException ex) {
|
||||||
Log.w(TAG, "Could not get calibration matrix for input device.", ex);
|
Log.w(TAG, "Could not get calibration matrix for input device.", ex);
|
||||||
return TouchCalibration.IDENTITY;
|
return TouchCalibration.IDENTITY;
|
||||||
@@ -529,9 +529,10 @@ public final class InputManager {
|
|||||||
*
|
*
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
public void setTouchCalibration(String inputDeviceDescriptor, TouchCalibration calibration) {
|
public void setTouchCalibration(String inputDeviceDescriptor, int surfaceRotation,
|
||||||
|
TouchCalibration calibration) {
|
||||||
try {
|
try {
|
||||||
mIm.setTouchCalibrationForInputDevice(inputDeviceDescriptor, calibration);
|
mIm.setTouchCalibrationForInputDevice(inputDeviceDescriptor, surfaceRotation, calibration);
|
||||||
} catch (RemoteException ex) {
|
} catch (RemoteException ex) {
|
||||||
Log.w(TAG, "Could not set calibration matrix for input device.", ex);
|
Log.w(TAG, "Could not set calibration matrix for input device.", ex);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -77,6 +77,7 @@ import android.view.InputDevice;
|
|||||||
import android.view.InputEvent;
|
import android.view.InputEvent;
|
||||||
import android.view.KeyEvent;
|
import android.view.KeyEvent;
|
||||||
import android.view.PointerIcon;
|
import android.view.PointerIcon;
|
||||||
|
import android.view.Surface;
|
||||||
import android.view.ViewConfiguration;
|
import android.view.ViewConfiguration;
|
||||||
import android.view.WindowManagerPolicy;
|
import android.view.WindowManagerPolicy;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
@@ -703,18 +704,19 @@ public class InputManagerService extends IInputManager.Stub
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override // Binder call & native callback
|
@Override // Binder call & native callback
|
||||||
public TouchCalibration getTouchCalibrationForInputDevice(String inputDeviceDescriptor) {
|
public TouchCalibration getTouchCalibrationForInputDevice(String inputDeviceDescriptor,
|
||||||
|
int surfaceRotation) {
|
||||||
if (inputDeviceDescriptor == null) {
|
if (inputDeviceDescriptor == null) {
|
||||||
throw new IllegalArgumentException("inputDeviceDescriptor must not be null");
|
throw new IllegalArgumentException("inputDeviceDescriptor must not be null");
|
||||||
}
|
}
|
||||||
|
|
||||||
synchronized (mDataStore) {
|
synchronized (mDataStore) {
|
||||||
return mDataStore.getTouchCalibration(inputDeviceDescriptor);
|
return mDataStore.getTouchCalibration(inputDeviceDescriptor, surfaceRotation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override // Binder call
|
@Override // Binder call
|
||||||
public void setTouchCalibrationForInputDevice(String inputDeviceDescriptor,
|
public void setTouchCalibrationForInputDevice(String inputDeviceDescriptor, int surfaceRotation,
|
||||||
TouchCalibration calibration) {
|
TouchCalibration calibration) {
|
||||||
if (!checkCallingPermission(android.Manifest.permission.SET_INPUT_CALIBRATION,
|
if (!checkCallingPermission(android.Manifest.permission.SET_INPUT_CALIBRATION,
|
||||||
"setTouchCalibrationForInputDevice()")) {
|
"setTouchCalibrationForInputDevice()")) {
|
||||||
@@ -726,10 +728,14 @@ public class InputManagerService extends IInputManager.Stub
|
|||||||
if (calibration == null) {
|
if (calibration == null) {
|
||||||
throw new IllegalArgumentException("calibration must not be null");
|
throw new IllegalArgumentException("calibration must not be null");
|
||||||
}
|
}
|
||||||
|
if (surfaceRotation < Surface.ROTATION_0 || surfaceRotation > Surface.ROTATION_270) {
|
||||||
|
throw new IllegalArgumentException("surfaceRotation value out of bounds");
|
||||||
|
}
|
||||||
|
|
||||||
synchronized (mDataStore) {
|
synchronized (mDataStore) {
|
||||||
try {
|
try {
|
||||||
if (mDataStore.setTouchCalibration(inputDeviceDescriptor, calibration)) {
|
if (mDataStore.setTouchCalibration(inputDeviceDescriptor, surfaceRotation,
|
||||||
|
calibration)) {
|
||||||
nativeReloadCalibration(mPtr);
|
nativeReloadCalibration(mPtr);
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import org.xmlpull.v1.XmlPullParser;
|
|||||||
import org.xmlpull.v1.XmlPullParserException;
|
import org.xmlpull.v1.XmlPullParserException;
|
||||||
import org.xmlpull.v1.XmlSerializer;
|
import org.xmlpull.v1.XmlSerializer;
|
||||||
|
|
||||||
|
import android.view.Surface;
|
||||||
import android.hardware.input.TouchCalibration;
|
import android.hardware.input.TouchCalibration;
|
||||||
import android.util.AtomicFile;
|
import android.util.AtomicFile;
|
||||||
import android.util.Slog;
|
import android.util.Slog;
|
||||||
@@ -83,22 +84,27 @@ final class PersistentDataStore {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public TouchCalibration getTouchCalibration(String inputDeviceDescriptor) {
|
public TouchCalibration getTouchCalibration(String inputDeviceDescriptor, int surfaceRotation) {
|
||||||
InputDeviceState state = getInputDeviceState(inputDeviceDescriptor, false);
|
InputDeviceState state = getInputDeviceState(inputDeviceDescriptor, false);
|
||||||
if (state == null) {
|
if (state == null) {
|
||||||
return TouchCalibration.IDENTITY;
|
return TouchCalibration.IDENTITY;
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
return state.getTouchCalibration();
|
TouchCalibration cal = state.getTouchCalibration(surfaceRotation);
|
||||||
|
if (cal == null) {
|
||||||
|
return TouchCalibration.IDENTITY;
|
||||||
}
|
}
|
||||||
|
return cal;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean setTouchCalibration(String inputDeviceDescriptor, TouchCalibration calibration) {
|
public boolean setTouchCalibration(String inputDeviceDescriptor, int surfaceRotation, TouchCalibration calibration) {
|
||||||
InputDeviceState state = getInputDeviceState(inputDeviceDescriptor, true);
|
InputDeviceState state = getInputDeviceState(inputDeviceDescriptor, true);
|
||||||
if (state.setTouchCalibration(calibration)) {
|
|
||||||
|
if (state.setTouchCalibration(surfaceRotation, calibration)) {
|
||||||
setDirty();
|
setDirty();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -298,20 +304,30 @@ final class PersistentDataStore {
|
|||||||
private static final String[] CALIBRATION_NAME = { "x_scale",
|
private static final String[] CALIBRATION_NAME = { "x_scale",
|
||||||
"x_ymix", "x_offset", "y_xmix", "y_scale", "y_offset" };
|
"x_ymix", "x_offset", "y_xmix", "y_scale", "y_offset" };
|
||||||
|
|
||||||
private TouchCalibration mTouchCalibration = TouchCalibration.IDENTITY;
|
private TouchCalibration[] mTouchCalibration = new TouchCalibration[4];
|
||||||
private String mCurrentKeyboardLayout;
|
private String mCurrentKeyboardLayout;
|
||||||
private ArrayList<String> mKeyboardLayouts = new ArrayList<String>();
|
private ArrayList<String> mKeyboardLayouts = new ArrayList<String>();
|
||||||
|
|
||||||
public TouchCalibration getTouchCalibration() {
|
public TouchCalibration getTouchCalibration(int surfaceRotation) {
|
||||||
return mTouchCalibration;
|
try {
|
||||||
|
return mTouchCalibration[surfaceRotation];
|
||||||
|
} catch (ArrayIndexOutOfBoundsException ex) {
|
||||||
|
Slog.w(InputManagerService.TAG, "Cannot get touch calibration.", ex);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean setTouchCalibration(TouchCalibration calibration) {
|
public boolean setTouchCalibration(int surfaceRotation, TouchCalibration calibration) {
|
||||||
if (calibration.equals(mTouchCalibration)) {
|
try {
|
||||||
|
if (!calibration.equals(mTouchCalibration[surfaceRotation])) {
|
||||||
|
mTouchCalibration[surfaceRotation] = calibration;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
} catch (ArrayIndexOutOfBoundsException ex) {
|
||||||
|
Slog.w(InputManagerService.TAG, "Cannot set touch calibration.", ex);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
mTouchCalibration = calibration;
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getCurrentKeyboardLayout() {
|
public String getCurrentKeyboardLayout() {
|
||||||
@@ -427,28 +443,49 @@ final class PersistentDataStore {
|
|||||||
}
|
}
|
||||||
} else if (parser.getName().equals("calibration")) {
|
} else if (parser.getName().equals("calibration")) {
|
||||||
String format = parser.getAttributeValue(null, "format");
|
String format = parser.getAttributeValue(null, "format");
|
||||||
|
String rotation = parser.getAttributeValue(null, "rotation");
|
||||||
|
int r = -1;
|
||||||
|
|
||||||
if (format == null) {
|
if (format == null) {
|
||||||
throw new XmlPullParserException(
|
throw new XmlPullParserException(
|
||||||
"Missing format attribute on calibration.");
|
"Missing format attribute on calibration.");
|
||||||
}
|
}
|
||||||
if (format.equals("affine")) {
|
if (!format.equals("affine")) {
|
||||||
float[] matrix = TouchCalibration.IDENTITY.getAffineTransform();
|
throw new XmlPullParserException(
|
||||||
int depth = parser.getDepth();
|
"Unsupported format for calibration.");
|
||||||
while (XmlUtils.nextElementWithin(parser, depth)) {
|
}
|
||||||
String tag = parser.getName().toLowerCase();
|
if (rotation != null) {
|
||||||
String value = parser.nextText();
|
try {
|
||||||
|
r = stringToSurfaceRotation(rotation);
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
throw new XmlPullParserException(
|
||||||
|
"Unsupported rotation for calibration.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < matrix.length && i < CALIBRATION_NAME.length; i++) {
|
float[] matrix = TouchCalibration.IDENTITY.getAffineTransform();
|
||||||
if (tag.equals(CALIBRATION_NAME[i])) {
|
int depth = parser.getDepth();
|
||||||
matrix[i] = Float.parseFloat(value);
|
while (XmlUtils.nextElementWithin(parser, depth)) {
|
||||||
break;
|
String tag = parser.getName().toLowerCase();
|
||||||
}
|
String value = parser.nextText();
|
||||||
|
|
||||||
|
for (int i = 0; i < matrix.length && i < CALIBRATION_NAME.length; i++) {
|
||||||
|
if (tag.equals(CALIBRATION_NAME[i])) {
|
||||||
|
matrix[i] = Float.parseFloat(value);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mTouchCalibration = new TouchCalibration(matrix[0], matrix[1], matrix[2],
|
}
|
||||||
matrix[3], matrix[4], matrix[5]);
|
|
||||||
|
if (r == -1) {
|
||||||
|
// Assume calibration applies to all rotations
|
||||||
|
for (r = 0; r < mTouchCalibration.length; r++) {
|
||||||
|
mTouchCalibration[r] = new TouchCalibration(matrix[0],
|
||||||
|
matrix[1], matrix[2], matrix[3], matrix[4], matrix[5]);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
throw new XmlPullParserException("Unsupported format for calibration.");
|
mTouchCalibration[r] = new TouchCalibration(matrix[0],
|
||||||
|
matrix[1], matrix[2], matrix[3], matrix[4], matrix[5]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -473,15 +510,48 @@ final class PersistentDataStore {
|
|||||||
serializer.endTag(null, "keyboard-layout");
|
serializer.endTag(null, "keyboard-layout");
|
||||||
}
|
}
|
||||||
|
|
||||||
serializer.startTag(null, "calibration");
|
for (int i = 0; i < mTouchCalibration.length; i++) {
|
||||||
serializer.attribute(null, "format", "affine");
|
if (mTouchCalibration[i] != null) {
|
||||||
float[] transform = mTouchCalibration.getAffineTransform();
|
String rotation = surfaceRotationToString(i);
|
||||||
for (int i = 0; i < transform.length && i < CALIBRATION_NAME.length; i++) {
|
float[] transform = mTouchCalibration[i].getAffineTransform();
|
||||||
serializer.startTag(null, CALIBRATION_NAME[i]);
|
|
||||||
serializer.text(Float.toString(transform[i]));
|
serializer.startTag(null, "calibration");
|
||||||
serializer.endTag(null, CALIBRATION_NAME[i]);
|
serializer.attribute(null, "format", "affine");
|
||||||
|
serializer.attribute(null, "rotation", rotation);
|
||||||
|
for (int j = 0; j < transform.length && j < CALIBRATION_NAME.length; j++) {
|
||||||
|
serializer.startTag(null, CALIBRATION_NAME[j]);
|
||||||
|
serializer.text(Float.toString(transform[j]));
|
||||||
|
serializer.endTag(null, CALIBRATION_NAME[j]);
|
||||||
|
}
|
||||||
|
serializer.endTag(null, "calibration");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
serializer.endTag(null, "calibration");
|
}
|
||||||
|
|
||||||
|
private static String surfaceRotationToString(int surfaceRotation) {
|
||||||
|
switch (surfaceRotation) {
|
||||||
|
case Surface.ROTATION_0: return "0";
|
||||||
|
case Surface.ROTATION_90: return "90";
|
||||||
|
case Surface.ROTATION_180: return "180";
|
||||||
|
case Surface.ROTATION_270: return "270";
|
||||||
|
}
|
||||||
|
throw new IllegalArgumentException("Unsupported surface rotation value" + surfaceRotation);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int stringToSurfaceRotation(String s) {
|
||||||
|
if ("0".equals(s)) {
|
||||||
|
return Surface.ROTATION_0;
|
||||||
|
}
|
||||||
|
if ("90".equals(s)) {
|
||||||
|
return Surface.ROTATION_90;
|
||||||
|
}
|
||||||
|
if ("180".equals(s)) {
|
||||||
|
return Surface.ROTATION_180;
|
||||||
|
}
|
||||||
|
if ("270".equals(s)) {
|
||||||
|
return Surface.ROTATION_270;
|
||||||
|
}
|
||||||
|
throw new IllegalArgumentException("Unsupported surface rotation string '" + s + "'");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -198,8 +198,10 @@ public:
|
|||||||
virtual void notifyInputDevicesChanged(const Vector<InputDeviceInfo>& inputDevices);
|
virtual void notifyInputDevicesChanged(const Vector<InputDeviceInfo>& inputDevices);
|
||||||
virtual sp<KeyCharacterMap> getKeyboardLayoutOverlay(const InputDeviceIdentifier& identifier);
|
virtual sp<KeyCharacterMap> getKeyboardLayoutOverlay(const InputDeviceIdentifier& identifier);
|
||||||
virtual String8 getDeviceAlias(const InputDeviceIdentifier& identifier);
|
virtual String8 getDeviceAlias(const InputDeviceIdentifier& identifier);
|
||||||
TouchAffineTransformation getTouchAffineTransformation(JNIEnv *env, jfloatArray matrixArr);
|
virtual TouchAffineTransformation getTouchAffineTransformation(JNIEnv *env,
|
||||||
TouchAffineTransformation getTouchAffineTransformation(const String8& inputDeviceDescriptor);
|
jfloatArray matrixArr);
|
||||||
|
virtual TouchAffineTransformation getTouchAffineTransformation(
|
||||||
|
const String8& inputDeviceDescriptor, int32_t surfaceRotation);
|
||||||
|
|
||||||
/* --- InputDispatcherPolicyInterface implementation --- */
|
/* --- InputDispatcherPolicyInterface implementation --- */
|
||||||
|
|
||||||
@@ -781,13 +783,14 @@ TouchAffineTransformation NativeInputManager::getTouchAffineTransformation(
|
|||||||
}
|
}
|
||||||
|
|
||||||
TouchAffineTransformation NativeInputManager::getTouchAffineTransformation(
|
TouchAffineTransformation NativeInputManager::getTouchAffineTransformation(
|
||||||
const String8& inputDeviceDescriptor) {
|
const String8& inputDeviceDescriptor, int32_t surfaceRotation) {
|
||||||
JNIEnv* env = jniEnv();
|
JNIEnv* env = jniEnv();
|
||||||
|
|
||||||
ScopedLocalRef<jstring> descriptorObj(env, env->NewStringUTF(inputDeviceDescriptor.string()));
|
ScopedLocalRef<jstring> descriptorObj(env, env->NewStringUTF(inputDeviceDescriptor.string()));
|
||||||
|
|
||||||
jobject cal = env->CallObjectMethod(mServiceObj,
|
jobject cal = env->CallObjectMethod(mServiceObj,
|
||||||
gServiceClassInfo.getTouchCalibrationForInputDevice, descriptorObj.get());
|
gServiceClassInfo.getTouchCalibrationForInputDevice, descriptorObj.get(),
|
||||||
|
surfaceRotation);
|
||||||
|
|
||||||
jfloatArray matrixArr = jfloatArray(env->CallObjectMethod(cal,
|
jfloatArray matrixArr = jfloatArray(env->CallObjectMethod(cal,
|
||||||
gTouchCalibrationClassInfo.getAffineTransform));
|
gTouchCalibrationClassInfo.getAffineTransform));
|
||||||
@@ -1506,7 +1509,7 @@ int register_android_server_InputManager(JNIEnv* env) {
|
|||||||
|
|
||||||
GET_METHOD_ID(gServiceClassInfo.getTouchCalibrationForInputDevice, clazz,
|
GET_METHOD_ID(gServiceClassInfo.getTouchCalibrationForInputDevice, clazz,
|
||||||
"getTouchCalibrationForInputDevice",
|
"getTouchCalibrationForInputDevice",
|
||||||
"(Ljava/lang/String;)Landroid/hardware/input/TouchCalibration;");
|
"(Ljava/lang/String;I)Landroid/hardware/input/TouchCalibration;");
|
||||||
|
|
||||||
// InputDevice
|
// InputDevice
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user