diff options
author | Jason Gerecke <killertofu@gmail.com> | 2014-03-10 09:47:59 -0700 |
---|---|---|
committer | Michael Wright <michaelwr@google.com> | 2014-03-10 16:33:48 -0700 |
commit | d52207423225bcd99e94276e9d0fc2cb5f905602 (patch) | |
tree | fa265cc3aa6ecdbd1d4769a9818f8f8c7f7b1b6e | |
parent | 857aa7be880c53d78f72a9f227cbdf72ee68d587 (diff) | |
download | frameworks_base-d52207423225bcd99e94276e9d0fc2cb5f905602.zip frameworks_base-d52207423225bcd99e94276e9d0fc2cb5f905602.tar.gz frameworks_base-d52207423225bcd99e94276e9d0fc2cb5f905602.tar.bz2 |
Support unique calibration per orientation
Updates the format of the calibration XML to store the Surface rotation
that a specific calibration applies to. Also updates the API to require
a rotation value for get/set, and has the native framework supply this
according to the current rotation whenever it changes.
Change-Id: I72b6703f646dd18db537365c5c9843f720a5f41e
5 files changed, 130 insertions, 50 deletions
diff --git a/core/java/android/hardware/input/IInputManager.aidl b/core/java/android/hardware/input/IInputManager.aidl index 4214115..465d142 100644 --- a/core/java/android/hardware/input/IInputManager.aidl +++ b/core/java/android/hardware/input/IInputManager.aidl @@ -41,8 +41,8 @@ interface IInputManager { boolean injectInputEvent(in InputEvent ev, int mode); // Calibrate input device position - TouchCalibration getTouchCalibrationForInputDevice(String inputDeviceDescriptor); - void setTouchCalibrationForInputDevice(String inputDeviceDescriptor, + TouchCalibration getTouchCalibrationForInputDevice(String inputDeviceDescriptor, int rotation); + void setTouchCalibrationForInputDevice(String inputDeviceDescriptor, int rotation, in TouchCalibration calibration); // Keyboard layouts configuration. diff --git a/core/java/android/hardware/input/InputManager.java b/core/java/android/hardware/input/InputManager.java index ece5d82..e3a3830 100644 --- a/core/java/android/hardware/input/InputManager.java +++ b/core/java/android/hardware/input/InputManager.java @@ -508,9 +508,9 @@ public final class InputManager { * * @hide */ - public TouchCalibration getTouchCalibration(String inputDeviceDescriptor) { + public TouchCalibration getTouchCalibration(String inputDeviceDescriptor, int surfaceRotation) { try { - return mIm.getTouchCalibrationForInputDevice(inputDeviceDescriptor); + return mIm.getTouchCalibrationForInputDevice(inputDeviceDescriptor, surfaceRotation); } catch (RemoteException ex) { Log.w(TAG, "Could not get calibration matrix for input device.", ex); return TouchCalibration.IDENTITY; @@ -529,9 +529,10 @@ public final class InputManager { * * @hide */ - public void setTouchCalibration(String inputDeviceDescriptor, TouchCalibration calibration) { + public void setTouchCalibration(String inputDeviceDescriptor, int surfaceRotation, + TouchCalibration calibration) { try { - mIm.setTouchCalibrationForInputDevice(inputDeviceDescriptor, calibration); + mIm.setTouchCalibrationForInputDevice(inputDeviceDescriptor, surfaceRotation, calibration); } catch (RemoteException ex) { Log.w(TAG, "Could not set calibration matrix for input device.", ex); } diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java index 69d8442..316bd57 100644 --- a/services/core/java/com/android/server/input/InputManagerService.java +++ b/services/core/java/com/android/server/input/InputManagerService.java @@ -77,6 +77,7 @@ import android.view.InputDevice; import android.view.InputEvent; import android.view.KeyEvent; import android.view.PointerIcon; +import android.view.Surface; import android.view.ViewConfiguration; import android.view.WindowManagerPolicy; import android.widget.Toast; @@ -703,18 +704,19 @@ public class InputManagerService extends IInputManager.Stub } @Override // Binder call & native callback - public TouchCalibration getTouchCalibrationForInputDevice(String inputDeviceDescriptor) { + public TouchCalibration getTouchCalibrationForInputDevice(String inputDeviceDescriptor, + int surfaceRotation) { if (inputDeviceDescriptor == null) { throw new IllegalArgumentException("inputDeviceDescriptor must not be null"); } synchronized (mDataStore) { - return mDataStore.getTouchCalibration(inputDeviceDescriptor); + return mDataStore.getTouchCalibration(inputDeviceDescriptor, surfaceRotation); } } @Override // Binder call - public void setTouchCalibrationForInputDevice(String inputDeviceDescriptor, + public void setTouchCalibrationForInputDevice(String inputDeviceDescriptor, int surfaceRotation, TouchCalibration calibration) { if (!checkCallingPermission(android.Manifest.permission.SET_INPUT_CALIBRATION, "setTouchCalibrationForInputDevice()")) { @@ -726,10 +728,14 @@ public class InputManagerService extends IInputManager.Stub if (calibration == 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) { try { - if (mDataStore.setTouchCalibration(inputDeviceDescriptor, calibration)) { + if (mDataStore.setTouchCalibration(inputDeviceDescriptor, surfaceRotation, + calibration)) { nativeReloadCalibration(mPtr); } } finally { diff --git a/services/core/java/com/android/server/input/PersistentDataStore.java b/services/core/java/com/android/server/input/PersistentDataStore.java index 9ea369d..92fa813 100644 --- a/services/core/java/com/android/server/input/PersistentDataStore.java +++ b/services/core/java/com/android/server/input/PersistentDataStore.java @@ -24,6 +24,7 @@ import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlSerializer; +import android.view.Surface; import android.hardware.input.TouchCalibration; import android.util.AtomicFile; 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); if (state == null) { 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); - if (state.setTouchCalibration(calibration)) { + + if (state.setTouchCalibration(surfaceRotation, calibration)) { setDirty(); return true; } + return false; } @@ -298,20 +304,30 @@ final class PersistentDataStore { private static final String[] CALIBRATION_NAME = { "x_scale", "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 ArrayList<String> mKeyboardLayouts = new ArrayList<String>(); - public TouchCalibration getTouchCalibration() { - return mTouchCalibration; + public TouchCalibration getTouchCalibration(int surfaceRotation) { + try { + return mTouchCalibration[surfaceRotation]; + } catch (ArrayIndexOutOfBoundsException ex) { + Slog.w(InputManagerService.TAG, "Cannot get touch calibration.", ex); + return null; + } } - public boolean setTouchCalibration(TouchCalibration calibration) { - if (calibration.equals(mTouchCalibration)) { + public boolean setTouchCalibration(int surfaceRotation, TouchCalibration calibration) { + 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; } - mTouchCalibration = calibration; - return true; } public String getCurrentKeyboardLayout() { @@ -427,28 +443,49 @@ final class PersistentDataStore { } } else if (parser.getName().equals("calibration")) { String format = parser.getAttributeValue(null, "format"); + String rotation = parser.getAttributeValue(null, "rotation"); + int r = -1; + if (format == null) { throw new XmlPullParserException( "Missing format attribute on calibration."); } - if (format.equals("affine")) { - float[] matrix = TouchCalibration.IDENTITY.getAffineTransform(); - int depth = parser.getDepth(); - while (XmlUtils.nextElementWithin(parser, depth)) { - 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; - } + if (!format.equals("affine")) { + throw new XmlPullParserException( + "Unsupported format for calibration."); + } + if (rotation != null) { + try { + r = stringToSurfaceRotation(rotation); + } catch (IllegalArgumentException e) { + throw new XmlPullParserException( + "Unsupported rotation for calibration."); + } + } + + float[] matrix = TouchCalibration.IDENTITY.getAffineTransform(); + int depth = parser.getDepth(); + while (XmlUtils.nextElementWithin(parser, depth)) { + 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 { - 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.startTag(null, "calibration"); - serializer.attribute(null, "format", "affine"); - float[] transform = mTouchCalibration.getAffineTransform(); - for (int i = 0; i < transform.length && i < CALIBRATION_NAME.length; i++) { - serializer.startTag(null, CALIBRATION_NAME[i]); - serializer.text(Float.toString(transform[i])); - serializer.endTag(null, CALIBRATION_NAME[i]); + for (int i = 0; i < mTouchCalibration.length; i++) { + if (mTouchCalibration[i] != null) { + String rotation = surfaceRotationToString(i); + float[] transform = mTouchCalibration[i].getAffineTransform(); + + serializer.startTag(null, "calibration"); + 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"); + } + } + } + + 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; } - serializer.endTag(null, "calibration"); + throw new IllegalArgumentException("Unsupported surface rotation string '" + s + "'"); } } } diff --git a/services/core/jni/com_android_server_input_InputManagerService.cpp b/services/core/jni/com_android_server_input_InputManagerService.cpp index 35c6583..e1069ae 100644 --- a/services/core/jni/com_android_server_input_InputManagerService.cpp +++ b/services/core/jni/com_android_server_input_InputManagerService.cpp @@ -198,8 +198,10 @@ public: virtual void notifyInputDevicesChanged(const Vector<InputDeviceInfo>& inputDevices); virtual sp<KeyCharacterMap> getKeyboardLayoutOverlay(const InputDeviceIdentifier& identifier); virtual String8 getDeviceAlias(const InputDeviceIdentifier& identifier); - TouchAffineTransformation getTouchAffineTransformation(JNIEnv *env, jfloatArray matrixArr); - TouchAffineTransformation getTouchAffineTransformation(const String8& inputDeviceDescriptor); + virtual TouchAffineTransformation getTouchAffineTransformation(JNIEnv *env, + jfloatArray matrixArr); + virtual TouchAffineTransformation getTouchAffineTransformation( + const String8& inputDeviceDescriptor, int32_t surfaceRotation); /* --- InputDispatcherPolicyInterface implementation --- */ @@ -781,13 +783,14 @@ TouchAffineTransformation NativeInputManager::getTouchAffineTransformation( } TouchAffineTransformation NativeInputManager::getTouchAffineTransformation( - const String8& inputDeviceDescriptor) { + const String8& inputDeviceDescriptor, int32_t surfaceRotation) { JNIEnv* env = jniEnv(); ScopedLocalRef<jstring> descriptorObj(env, env->NewStringUTF(inputDeviceDescriptor.string())); jobject cal = env->CallObjectMethod(mServiceObj, - gServiceClassInfo.getTouchCalibrationForInputDevice, descriptorObj.get()); + gServiceClassInfo.getTouchCalibrationForInputDevice, descriptorObj.get(), + surfaceRotation); jfloatArray matrixArr = jfloatArray(env->CallObjectMethod(cal, gTouchCalibrationClassInfo.getAffineTransform)); @@ -1506,7 +1509,7 @@ int register_android_server_InputManager(JNIEnv* env) { GET_METHOD_ID(gServiceClassInfo.getTouchCalibrationForInputDevice, clazz, "getTouchCalibrationForInputDevice", - "(Ljava/lang/String;)Landroid/hardware/input/TouchCalibration;"); + "(Ljava/lang/String;I)Landroid/hardware/input/TouchCalibration;"); // InputDevice |