am 8d60866e: Input device calibration and capabilities.
Merge commit '8d60866e2100db70ecf0502c14768a384514d7e9' into gingerbread-plus-aosp * commit '8d60866e2100db70ecf0502c14768a384514d7e9': Input device calibration and capabilities.
This commit is contained in:
@@ -177208,14 +177208,19 @@
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<constructor name="InputDevice"
|
||||
type="android.view.InputDevice"
|
||||
<implements name="android.os.Parcelable">
|
||||
</implements>
|
||||
<method name="describeContents"
|
||||
return="int"
|
||||
abstract="false"
|
||||
native="false"
|
||||
synchronized="false"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
</constructor>
|
||||
</method>
|
||||
<method name="getDevice"
|
||||
return="android.view.InputDevice"
|
||||
abstract="false"
|
||||
@@ -177229,6 +177234,28 @@
|
||||
<parameter name="id" type="int">
|
||||
</parameter>
|
||||
</method>
|
||||
<method name="getDeviceIds"
|
||||
return="int[]"
|
||||
abstract="false"
|
||||
native="false"
|
||||
synchronized="false"
|
||||
static="true"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
</method>
|
||||
<method name="getId"
|
||||
return="int"
|
||||
abstract="false"
|
||||
native="false"
|
||||
synchronized="false"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
</method>
|
||||
<method name="getKeyCharacterMap"
|
||||
return="android.view.KeyCharacterMap"
|
||||
abstract="false"
|
||||
@@ -177261,7 +177288,7 @@
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<parameter name="range" type="int">
|
||||
<parameter name="rangeType" type="int">
|
||||
</parameter>
|
||||
</method>
|
||||
<method name="getName"
|
||||
@@ -177286,8 +177313,8 @@
|
||||
visibility="public"
|
||||
>
|
||||
</method>
|
||||
<method name="hasKey"
|
||||
return="boolean"
|
||||
<method name="writeToParcel"
|
||||
return="void"
|
||||
abstract="false"
|
||||
native="false"
|
||||
synchronized="false"
|
||||
@@ -177296,9 +177323,21 @@
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<parameter name="keyCode" type="int">
|
||||
<parameter name="out" type="android.os.Parcel">
|
||||
</parameter>
|
||||
<parameter name="flags" type="int">
|
||||
</parameter>
|
||||
</method>
|
||||
<field name="CREATOR"
|
||||
type="android.os.Parcelable.Creator"
|
||||
transient="false"
|
||||
volatile="false"
|
||||
static="true"
|
||||
final="true"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
</field>
|
||||
<field name="KEYBOARD_TYPE_ALPHABETIC"
|
||||
type="int"
|
||||
transient="false"
|
||||
@@ -177627,14 +177666,6 @@
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<constructor name="InputDevice.MotionRange"
|
||||
type="android.view.InputDevice.MotionRange"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
</constructor>
|
||||
<method name="getFlat"
|
||||
return="float"
|
||||
abstract="false"
|
||||
|
||||
@@ -29,6 +29,7 @@ import android.view.KeyEvent;
|
||||
import android.view.InputEvent;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.InputChannel;
|
||||
import android.view.InputDevice;
|
||||
|
||||
/**
|
||||
* System private interface to the window manager.
|
||||
@@ -125,6 +126,10 @@ interface IWindowManager
|
||||
// Report whether the hardware supports the given keys; returns true if successful
|
||||
boolean hasKeys(in int[] keycodes, inout boolean[] keyExists);
|
||||
|
||||
// Get input device information.
|
||||
InputDevice getInputDevice(int deviceId);
|
||||
int[] getInputDeviceIds();
|
||||
|
||||
// For testing
|
||||
void setInTouchMode(boolean showFocus);
|
||||
|
||||
|
||||
20
core/java/android/view/InputDevice.aidl
Normal file
20
core/java/android/view/InputDevice.aidl
Normal file
@@ -0,0 +1,20 @@
|
||||
/* //device/java/android/android.view.InputDevice.aidl
|
||||
**
|
||||
** Copyright 2007, The Android Open Source Project
|
||||
**
|
||||
** Licensed under the Apache License, Version 2.0 (the "License");
|
||||
** you may not use this file except in compliance with the License.
|
||||
** You may obtain a copy of the License at
|
||||
**
|
||||
** http://www.apache.org/licenses/LICENSE-2.0
|
||||
**
|
||||
** Unless required by applicable law or agreed to in writing, software
|
||||
** distributed under the License is distributed on an "AS IS" BASIS,
|
||||
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
** See the License for the specific language governing permissions and
|
||||
** limitations under the License.
|
||||
*/
|
||||
|
||||
package android.view;
|
||||
|
||||
parcelable InputDevice;
|
||||
@@ -16,6 +16,12 @@
|
||||
|
||||
package android.view;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.os.RemoteException;
|
||||
import android.os.ServiceManager;
|
||||
import android.util.Log;
|
||||
|
||||
/**
|
||||
* Describes the capabilities of a particular input device.
|
||||
* <p>
|
||||
@@ -32,12 +38,14 @@ package android.view;
|
||||
* the appropriate interpretation.
|
||||
* </p>
|
||||
*/
|
||||
public final class InputDevice {
|
||||
public final class InputDevice implements Parcelable {
|
||||
private int mId;
|
||||
private String mName;
|
||||
private int mSources;
|
||||
private int mKeyboardType;
|
||||
|
||||
private MotionRange[] mMotionRanges;
|
||||
|
||||
/**
|
||||
* A mask for input source classes.
|
||||
*
|
||||
@@ -246,6 +254,8 @@ public final class InputDevice {
|
||||
*/
|
||||
public static final int MOTION_RANGE_ORIENTATION = 8;
|
||||
|
||||
private static final int MOTION_RANGE_LAST = MOTION_RANGE_ORIENTATION;
|
||||
|
||||
/**
|
||||
* There is no keyboard.
|
||||
*/
|
||||
@@ -261,6 +271,11 @@ public final class InputDevice {
|
||||
* The keyboard supports a complement of alphabetic keys.
|
||||
*/
|
||||
public static final int KEYBOARD_TYPE_ALPHABETIC = 2;
|
||||
|
||||
// Called by native code.
|
||||
private InputDevice() {
|
||||
mMotionRanges = new MotionRange[MOTION_RANGE_LAST + 1];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets information about the input device with the specified id.
|
||||
@@ -268,8 +283,35 @@ public final class InputDevice {
|
||||
* @return The input device or null if not found.
|
||||
*/
|
||||
public static InputDevice getDevice(int id) {
|
||||
// TODO
|
||||
return null;
|
||||
IWindowManager wm = IWindowManager.Stub.asInterface(ServiceManager.getService("window"));
|
||||
try {
|
||||
return wm.getInputDevice(id);
|
||||
} catch (RemoteException ex) {
|
||||
throw new RuntimeException(
|
||||
"Could not get input device information from Window Manager.", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the ids of all input devices in the system.
|
||||
* @return The input device ids.
|
||||
*/
|
||||
public static int[] getDeviceIds() {
|
||||
IWindowManager wm = IWindowManager.Stub.asInterface(ServiceManager.getService("window"));
|
||||
try {
|
||||
return wm.getInputDeviceIds();
|
||||
} catch (RemoteException ex) {
|
||||
throw new RuntimeException(
|
||||
"Could not get input device ids from Window Manager.", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the input device id.
|
||||
* @return The input device id.
|
||||
*/
|
||||
public int getId() {
|
||||
return mId;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -307,23 +349,23 @@ public final class InputDevice {
|
||||
/**
|
||||
* Gets information about the range of values for a particular {@link MotionEvent}
|
||||
* coordinate.
|
||||
* @param range The motion range constant.
|
||||
* @param rangeType The motion range constant.
|
||||
* @return The range of values, or null if the requested coordinate is not
|
||||
* supported by the device.
|
||||
*/
|
||||
public MotionRange getMotionRange(int range) {
|
||||
// TODO
|
||||
return null;
|
||||
public MotionRange getMotionRange(int rangeType) {
|
||||
if (rangeType < 0 || rangeType > MOTION_RANGE_LAST) {
|
||||
throw new IllegalArgumentException("Requested range is out of bounds.");
|
||||
}
|
||||
|
||||
return mMotionRanges[rangeType];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the device supports a particular button or key.
|
||||
* @param keyCode The key code.
|
||||
* @return True if the device supports the key.
|
||||
*/
|
||||
public boolean hasKey(int keyCode) {
|
||||
// TODO
|
||||
return false;
|
||||
private void addMotionRange(int rangeType, float min, float max, float flat, float fuzz) {
|
||||
if (rangeType >= 0 && rangeType <= MOTION_RANGE_LAST) {
|
||||
MotionRange range = new MotionRange(min, max, flat, fuzz);
|
||||
mMotionRanges[rangeType] = range;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -331,13 +373,24 @@ public final class InputDevice {
|
||||
* coordinate.
|
||||
*/
|
||||
public static final class MotionRange {
|
||||
private float mMin;
|
||||
private float mMax;
|
||||
private float mFlat;
|
||||
private float mFuzz;
|
||||
|
||||
private MotionRange(float min, float max, float flat, float fuzz) {
|
||||
mMin = min;
|
||||
mMax = max;
|
||||
mFlat = flat;
|
||||
mFuzz = fuzz;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the minimum value for the coordinate.
|
||||
* @return The minimum value.
|
||||
*/
|
||||
public float getMin() {
|
||||
// TODO
|
||||
return 0;
|
||||
return mMin;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -345,8 +398,7 @@ public final class InputDevice {
|
||||
* @return The minimum value.
|
||||
*/
|
||||
public float getMax() {
|
||||
// TODO
|
||||
return 0;
|
||||
return mMax;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -354,8 +406,7 @@ public final class InputDevice {
|
||||
* @return The range of values.
|
||||
*/
|
||||
public float getRange() {
|
||||
// TODO
|
||||
return 0;
|
||||
return mMax - mMin;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -365,8 +416,7 @@ public final class InputDevice {
|
||||
* @return The extent of the center flat position.
|
||||
*/
|
||||
public float getFlat() {
|
||||
// TODO
|
||||
return 0;
|
||||
return mFlat;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -376,8 +426,127 @@ public final class InputDevice {
|
||||
* @return The error tolerance.
|
||||
*/
|
||||
public float getFuzz() {
|
||||
// TODO
|
||||
return 0;
|
||||
return mFuzz;
|
||||
}
|
||||
}
|
||||
|
||||
public static final Parcelable.Creator<InputDevice> CREATOR
|
||||
= new Parcelable.Creator<InputDevice>() {
|
||||
public InputDevice createFromParcel(Parcel in) {
|
||||
InputDevice result = new InputDevice();
|
||||
result.readFromParcel(in);
|
||||
return result;
|
||||
}
|
||||
|
||||
public InputDevice[] newArray(int size) {
|
||||
return new InputDevice[size];
|
||||
}
|
||||
};
|
||||
|
||||
private void readFromParcel(Parcel in) {
|
||||
mId = in.readInt();
|
||||
mName = in.readString();
|
||||
mSources = in.readInt();
|
||||
mKeyboardType = in.readInt();
|
||||
|
||||
for (;;) {
|
||||
int rangeType = in.readInt();
|
||||
if (rangeType < 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
addMotionRange(rangeType,
|
||||
in.readFloat(), in.readFloat(), in.readFloat(), in.readFloat());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel out, int flags) {
|
||||
out.writeInt(mId);
|
||||
out.writeString(mName);
|
||||
out.writeInt(mSources);
|
||||
out.writeInt(mKeyboardType);
|
||||
|
||||
for (int i = 0; i <= MOTION_RANGE_LAST; i++) {
|
||||
MotionRange range = mMotionRanges[i];
|
||||
if (range != null) {
|
||||
out.writeInt(i);
|
||||
out.writeFloat(range.mMin);
|
||||
out.writeFloat(range.mMax);
|
||||
out.writeFloat(range.mFlat);
|
||||
out.writeFloat(range.mFuzz);
|
||||
}
|
||||
}
|
||||
out.writeInt(-1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder description = new StringBuilder();
|
||||
description.append("Input Device ").append(mId).append(": ").append(mName).append("\n");
|
||||
|
||||
description.append(" Keyboard Type: ");
|
||||
switch (mKeyboardType) {
|
||||
case KEYBOARD_TYPE_NONE:
|
||||
description.append("none");
|
||||
break;
|
||||
case KEYBOARD_TYPE_NON_ALPHABETIC:
|
||||
description.append("non-alphabetic");
|
||||
break;
|
||||
case KEYBOARD_TYPE_ALPHABETIC:
|
||||
description.append("alphabetic");
|
||||
break;
|
||||
}
|
||||
description.append("\n");
|
||||
|
||||
description.append(" Sources:");
|
||||
appendSourceDescriptionIfApplicable(description, SOURCE_KEYBOARD, "keyboard");
|
||||
appendSourceDescriptionIfApplicable(description, SOURCE_DPAD, "dpad");
|
||||
appendSourceDescriptionIfApplicable(description, SOURCE_GAMEPAD, "gamepad");
|
||||
appendSourceDescriptionIfApplicable(description, SOURCE_TOUCHSCREEN, "touchscreen");
|
||||
appendSourceDescriptionIfApplicable(description, SOURCE_MOUSE, "mouse");
|
||||
appendSourceDescriptionIfApplicable(description, SOURCE_TRACKBALL, "trackball");
|
||||
appendSourceDescriptionIfApplicable(description, SOURCE_TOUCHPAD, "touchpad");
|
||||
appendSourceDescriptionIfApplicable(description, SOURCE_JOYSTICK_LEFT, "joystick_left");
|
||||
appendSourceDescriptionIfApplicable(description, SOURCE_JOYSTICK_RIGHT, "joystick_right");
|
||||
description.append("\n");
|
||||
|
||||
appendRangeDescriptionIfApplicable(description, MOTION_RANGE_X, "x");
|
||||
appendRangeDescriptionIfApplicable(description, MOTION_RANGE_Y, "y");
|
||||
appendRangeDescriptionIfApplicable(description, MOTION_RANGE_PRESSURE, "pressure");
|
||||
appendRangeDescriptionIfApplicable(description, MOTION_RANGE_SIZE, "size");
|
||||
appendRangeDescriptionIfApplicable(description, MOTION_RANGE_TOUCH_MAJOR, "touchMajor");
|
||||
appendRangeDescriptionIfApplicable(description, MOTION_RANGE_TOUCH_MINOR, "touchMinor");
|
||||
appendRangeDescriptionIfApplicable(description, MOTION_RANGE_TOOL_MAJOR, "toolMajor");
|
||||
appendRangeDescriptionIfApplicable(description, MOTION_RANGE_TOOL_MINOR, "toolMinor");
|
||||
appendRangeDescriptionIfApplicable(description, MOTION_RANGE_ORIENTATION, "orientation");
|
||||
|
||||
return description.toString();
|
||||
}
|
||||
|
||||
private void appendSourceDescriptionIfApplicable(StringBuilder description, int source,
|
||||
String sourceName) {
|
||||
if ((mSources & source) == source) {
|
||||
description.append(" ");
|
||||
description.append(sourceName);
|
||||
}
|
||||
}
|
||||
|
||||
private void appendRangeDescriptionIfApplicable(StringBuilder description,
|
||||
int rangeType, String rangeName) {
|
||||
MotionRange range = mMotionRanges[rangeType];
|
||||
if (range != null) {
|
||||
description.append(" Range[").append(rangeName);
|
||||
description.append("]: min=").append(range.mMin);
|
||||
description.append(" max=").append(range.mMax);
|
||||
description.append(" flat=").append(range.mFlat);
|
||||
description.append(" fuzz=").append(range.mFuzz);
|
||||
description.append("\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,8 +19,10 @@ package com.android.internal.widget;
|
||||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.RectF;
|
||||
import android.graphics.Paint.FontMetricsInt;
|
||||
import android.util.Log;
|
||||
import android.view.InputDevice;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.VelocityTracker;
|
||||
import android.view.View;
|
||||
@@ -29,17 +31,45 @@ import android.view.ViewConfiguration;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class PointerLocationView extends View {
|
||||
private static final String TAG = "Pointer";
|
||||
|
||||
public static class PointerState {
|
||||
private final ArrayList<Float> mXs = new ArrayList<Float>();
|
||||
private final ArrayList<Float> mYs = new ArrayList<Float>();
|
||||
// Trace of previous points.
|
||||
private float[] mTraceX = new float[32];
|
||||
private float[] mTraceY = new float[32];
|
||||
private int mTraceCount;
|
||||
|
||||
// True if the pointer is down.
|
||||
private boolean mCurDown;
|
||||
private int mCurX;
|
||||
private int mCurY;
|
||||
private float mCurPressure;
|
||||
private float mCurSize;
|
||||
private int mCurWidth;
|
||||
|
||||
// Most recent coordinates.
|
||||
private MotionEvent.PointerCoords mCoords = new MotionEvent.PointerCoords();
|
||||
|
||||
// Most recent velocity.
|
||||
private float mXVelocity;
|
||||
private float mYVelocity;
|
||||
|
||||
public void clearTrace() {
|
||||
mTraceCount = 0;
|
||||
}
|
||||
|
||||
public void addTrace(float x, float y) {
|
||||
int traceCapacity = mTraceX.length;
|
||||
if (mTraceCount == traceCapacity) {
|
||||
traceCapacity *= 2;
|
||||
float[] newTraceX = new float[traceCapacity];
|
||||
System.arraycopy(mTraceX, 0, newTraceX, 0, mTraceCount);
|
||||
mTraceX = newTraceX;
|
||||
|
||||
float[] newTraceY = new float[traceCapacity];
|
||||
System.arraycopy(mTraceY, 0, newTraceY, 0, mTraceCount);
|
||||
mTraceY = newTraceY;
|
||||
}
|
||||
|
||||
mTraceX[mTraceCount] = x;
|
||||
mTraceY[mTraceCount] = y;
|
||||
mTraceCount += 1;
|
||||
}
|
||||
}
|
||||
|
||||
private final ViewConfiguration mVC;
|
||||
@@ -54,11 +84,12 @@ public class PointerLocationView extends View {
|
||||
private boolean mCurDown;
|
||||
private int mCurNumPointers;
|
||||
private int mMaxNumPointers;
|
||||
private final ArrayList<PointerState> mPointers
|
||||
= new ArrayList<PointerState>();
|
||||
private final ArrayList<PointerState> mPointers = new ArrayList<PointerState>();
|
||||
|
||||
private final VelocityTracker mVelocity;
|
||||
|
||||
private final FasterStringBuilder mText = new FasterStringBuilder();
|
||||
|
||||
private boolean mPrintCoords = true;
|
||||
|
||||
public PointerLocationView(Context c) {
|
||||
@@ -94,6 +125,18 @@ public class PointerLocationView extends View {
|
||||
mPointers.add(ps);
|
||||
|
||||
mVelocity = VelocityTracker.obtain();
|
||||
|
||||
logInputDeviceCapabilities();
|
||||
}
|
||||
|
||||
private void logInputDeviceCapabilities() {
|
||||
int[] deviceIds = InputDevice.getDeviceIds();
|
||||
for (int i = 0; i < deviceIds.length; i++) {
|
||||
InputDevice device = InputDevice.getDevice(deviceIds[i]);
|
||||
if (device != null) {
|
||||
Log.i(TAG, device.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setPrintCoords(boolean state) {
|
||||
@@ -113,6 +156,21 @@ public class PointerLocationView extends View {
|
||||
+ " bottom=" + mTextMetrics.bottom);
|
||||
}
|
||||
}
|
||||
|
||||
// Draw an oval. When angle is 0 radians, orients the major axis vertically,
|
||||
// angles less than or greater than 0 radians rotate the major axis left or right.
|
||||
private RectF mReusableOvalRect = new RectF();
|
||||
private void drawOval(Canvas canvas, float x, float y, float major, float minor,
|
||||
float angle, Paint paint) {
|
||||
canvas.save(Canvas.MATRIX_SAVE_FLAG);
|
||||
canvas.rotate((float) (angle * 180 / Math.PI), x, y);
|
||||
mReusableOvalRect.left = x - minor / 2;
|
||||
mReusableOvalRect.right = x + minor / 2;
|
||||
mReusableOvalRect.top = y - major / 2;
|
||||
mReusableOvalRect.bottom = y + major / 2;
|
||||
canvas.drawOval(mReusableOvalRect, paint);
|
||||
canvas.restore();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDraw(Canvas canvas) {
|
||||
@@ -124,76 +182,80 @@ public class PointerLocationView extends View {
|
||||
|
||||
final int NP = mPointers.size();
|
||||
|
||||
// Labels
|
||||
if (NP > 0) {
|
||||
final PointerState ps = mPointers.get(0);
|
||||
canvas.drawRect(0, 0, itemW-1, bottom,mTextBackgroundPaint);
|
||||
canvas.drawText("P: " + mCurNumPointers + " / " + mMaxNumPointers,
|
||||
1, base, mTextPaint);
|
||||
canvas.drawText(mText.clear()
|
||||
.append("P: ").append(mCurNumPointers)
|
||||
.append(" / ").append(mMaxNumPointers)
|
||||
.toString(), 1, base, mTextPaint);
|
||||
|
||||
final int N = ps.mXs.size();
|
||||
final int N = ps.mTraceCount;
|
||||
if ((mCurDown && ps.mCurDown) || N == 0) {
|
||||
canvas.drawRect(itemW, 0, (itemW * 2) - 1, bottom, mTextBackgroundPaint);
|
||||
canvas.drawText("X: " + ps.mCurX, 1 + itemW, base, mTextPaint);
|
||||
canvas.drawText(mText.clear()
|
||||
.append("X: ").append(ps.mCoords.x, 1)
|
||||
.toString(), 1 + itemW, base, mTextPaint);
|
||||
canvas.drawRect(itemW * 2, 0, (itemW * 3) - 1, bottom, mTextBackgroundPaint);
|
||||
canvas.drawText("Y: " + ps.mCurY, 1 + itemW * 2, base, mTextPaint);
|
||||
canvas.drawText(mText.clear()
|
||||
.append("Y: ").append(ps.mCoords.y, 1)
|
||||
.toString(), 1 + itemW * 2, base, mTextPaint);
|
||||
} else {
|
||||
float dx = ps.mXs.get(N-1) - ps.mXs.get(0);
|
||||
float dy = ps.mYs.get(N-1) - ps.mYs.get(0);
|
||||
float dx = ps.mTraceX[N - 1] - ps.mTraceX[0];
|
||||
float dy = ps.mTraceY[N - 1] - ps.mTraceY[0];
|
||||
canvas.drawRect(itemW, 0, (itemW * 2) - 1, bottom,
|
||||
Math.abs(dx) < mVC.getScaledTouchSlop()
|
||||
? mTextBackgroundPaint : mTextLevelPaint);
|
||||
canvas.drawText("dX: " + String.format("%.1f", dx), 1 + itemW, base, mTextPaint);
|
||||
canvas.drawText(mText.clear()
|
||||
.append("dX: ").append(dx, 1)
|
||||
.toString(), 1 + itemW, base, mTextPaint);
|
||||
canvas.drawRect(itemW * 2, 0, (itemW * 3) - 1, bottom,
|
||||
Math.abs(dy) < mVC.getScaledTouchSlop()
|
||||
? mTextBackgroundPaint : mTextLevelPaint);
|
||||
canvas.drawText("dY: " + String.format("%.1f", dy), 1 + itemW * 2, base, mTextPaint);
|
||||
canvas.drawText(mText.clear()
|
||||
.append("dY: ").append(dy, 1)
|
||||
.toString(), 1 + itemW * 2, base, mTextPaint);
|
||||
}
|
||||
|
||||
canvas.drawRect(itemW * 3, 0, (itemW * 4) - 1, bottom, mTextBackgroundPaint);
|
||||
int velocity = (int) (ps.mXVelocity * 1000);
|
||||
canvas.drawText("Xv: " + velocity, 1 + itemW * 3, base, mTextPaint);
|
||||
canvas.drawText(mText.clear()
|
||||
.append("Xv: ").append(ps.mXVelocity, 3)
|
||||
.toString(), 1 + itemW * 3, base, mTextPaint);
|
||||
|
||||
canvas.drawRect(itemW * 4, 0, (itemW * 5) - 1, bottom, mTextBackgroundPaint);
|
||||
velocity = (int) (ps.mYVelocity * 1000);
|
||||
canvas.drawText("Yv: " + velocity, 1 + itemW * 4, base, mTextPaint);
|
||||
canvas.drawText(mText.clear()
|
||||
.append("Yv: ").append(ps.mYVelocity, 3)
|
||||
.toString(), 1 + itemW * 4, base, mTextPaint);
|
||||
|
||||
canvas.drawRect(itemW * 5, 0, (itemW * 6) - 1, bottom, mTextBackgroundPaint);
|
||||
canvas.drawRect(itemW * 5, 0, (itemW * 5) + (ps.mCurPressure * itemW) - 1,
|
||||
canvas.drawRect(itemW * 5, 0, (itemW * 5) + (ps.mCoords.pressure * itemW) - 1,
|
||||
bottom, mTextLevelPaint);
|
||||
canvas.drawText("Prs: " + String.format("%.2f", ps.mCurPressure), 1 + itemW * 5,
|
||||
base, mTextPaint);
|
||||
canvas.drawText(mText.clear()
|
||||
.append("Prs: ").append(ps.mCoords.pressure, 2)
|
||||
.toString(), 1 + itemW * 5, base, mTextPaint);
|
||||
|
||||
canvas.drawRect(itemW * 6, 0, w, bottom, mTextBackgroundPaint);
|
||||
canvas.drawRect(itemW * 6, 0, (itemW * 6) + (ps.mCurSize * itemW) - 1,
|
||||
canvas.drawRect(itemW * 6, 0, (itemW * 6) + (ps.mCoords.size * itemW) - 1,
|
||||
bottom, mTextLevelPaint);
|
||||
canvas.drawText("Size: " + String.format("%.2f", ps.mCurSize), 1 + itemW * 6,
|
||||
base, mTextPaint);
|
||||
canvas.drawText(mText.clear()
|
||||
.append("Size: ").append(ps.mCoords.size, 2)
|
||||
.toString(), 1 + itemW * 6, base, mTextPaint);
|
||||
}
|
||||
|
||||
for (int p=0; p<NP; p++) {
|
||||
// Pointer trace.
|
||||
for (int p = 0; p < NP; p++) {
|
||||
final PointerState ps = mPointers.get(p);
|
||||
|
||||
if (mCurDown && ps.mCurDown) {
|
||||
canvas.drawLine(0, (int)ps.mCurY, getWidth(), (int)ps.mCurY, mTargetPaint);
|
||||
canvas.drawLine((int)ps.mCurX, 0, (int)ps.mCurX, getHeight(), mTargetPaint);
|
||||
int pressureLevel = (int)(ps.mCurPressure*255);
|
||||
mPaint.setARGB(255, pressureLevel, 128, 255-pressureLevel);
|
||||
canvas.drawPoint(ps.mCurX, ps.mCurY, mPaint);
|
||||
canvas.drawCircle(ps.mCurX, ps.mCurY, ps.mCurWidth, mPaint);
|
||||
}
|
||||
}
|
||||
|
||||
for (int p=0; p<NP; p++) {
|
||||
final PointerState ps = mPointers.get(p);
|
||||
|
||||
final int N = ps.mXs.size();
|
||||
float lastX=0, lastY=0;
|
||||
// Draw path.
|
||||
final int N = ps.mTraceCount;
|
||||
float lastX = 0, lastY = 0;
|
||||
boolean haveLast = false;
|
||||
boolean drawn = false;
|
||||
mPaint.setARGB(255, 128, 255, 255);
|
||||
for (int i=0; i<N; i++) {
|
||||
float x = ps.mXs.get(i);
|
||||
float y = ps.mYs.get(i);
|
||||
for (int i=0; i < N; i++) {
|
||||
float x = ps.mTraceX[i];
|
||||
float y = ps.mTraceY[i];
|
||||
if (Float.isNaN(x)) {
|
||||
haveLast = false;
|
||||
continue;
|
||||
@@ -208,21 +270,57 @@ public class PointerLocationView extends View {
|
||||
haveLast = true;
|
||||
}
|
||||
|
||||
// Draw velocity vector.
|
||||
if (drawn) {
|
||||
mPaint.setARGB(255, 255, 64, 128);
|
||||
float xVel = ps.mXVelocity * (1000/60);
|
||||
float yVel = ps.mYVelocity * (1000/60);
|
||||
canvas.drawLine(lastX, lastY, lastX+xVel, lastY+yVel, mPaint);
|
||||
float xVel = ps.mXVelocity * (1000 / 60);
|
||||
float yVel = ps.mYVelocity * (1000 / 60);
|
||||
canvas.drawLine(lastX, lastY, lastX + xVel, lastY + yVel, mPaint);
|
||||
}
|
||||
|
||||
if (mCurDown && ps.mCurDown) {
|
||||
// Draw crosshairs.
|
||||
canvas.drawLine(0, ps.mCoords.y, getWidth(), ps.mCoords.y, mTargetPaint);
|
||||
canvas.drawLine(ps.mCoords.x, 0, ps.mCoords.x, getHeight(), mTargetPaint);
|
||||
|
||||
// Draw current point.
|
||||
int pressureLevel = (int)(ps.mCoords.pressure * 255);
|
||||
mPaint.setARGB(255, pressureLevel, 255, 255 - pressureLevel);
|
||||
canvas.drawPoint(ps.mCoords.x, ps.mCoords.y, mPaint);
|
||||
|
||||
// Draw current touch ellipse.
|
||||
mPaint.setARGB(255, pressureLevel, 255 - pressureLevel, 128);
|
||||
drawOval(canvas, ps.mCoords.x, ps.mCoords.y, ps.mCoords.touchMajor,
|
||||
ps.mCoords.touchMinor, ps.mCoords.orientation, mPaint);
|
||||
|
||||
// Draw current tool ellipse.
|
||||
mPaint.setARGB(255, pressureLevel, 128, 255 - pressureLevel);
|
||||
drawOval(canvas, ps.mCoords.x, ps.mCoords.y, ps.mCoords.toolMajor,
|
||||
ps.mCoords.toolMinor, ps.mCoords.orientation, mPaint);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void logPointerCoords(MotionEvent.PointerCoords coords, int id) {
|
||||
Log.i(TAG, mText.clear()
|
||||
.append("Pointer ").append(id + 1)
|
||||
.append(": (").append(coords.x, 3).append(", ").append(coords.y, 3)
|
||||
.append(") Pressure=").append(coords.pressure, 3)
|
||||
.append(" Size=").append(coords.size, 3)
|
||||
.append(" TouchMajor=").append(coords.touchMajor, 3)
|
||||
.append(" TouchMinor=").append(coords.touchMinor, 3)
|
||||
.append(" ToolMajor=").append(coords.toolMajor, 3)
|
||||
.append(" ToolMinor=").append(coords.toolMinor, 3)
|
||||
.append(" Orientation=").append((float)(coords.orientation * 180 / Math.PI), 1)
|
||||
.append("deg").toString());
|
||||
}
|
||||
|
||||
public void addTouchEvent(MotionEvent event) {
|
||||
synchronized (mPointers) {
|
||||
int action = event.getAction();
|
||||
|
||||
//Log.i("Pointer", "Motion: action=0x" + Integer.toHexString(action)
|
||||
//Log.i(TAG, "Motion: action=0x" + Integer.toHexString(action)
|
||||
// + " pointers=" + event.getPointerCount());
|
||||
|
||||
int NP = mPointers.size();
|
||||
@@ -235,35 +333,33 @@ public class PointerLocationView extends View {
|
||||
//} else {
|
||||
// mRect.setEmpty();
|
||||
//}
|
||||
if (action == MotionEvent.ACTION_DOWN) {
|
||||
mVelocity.clear();
|
||||
if (action == MotionEvent.ACTION_DOWN
|
||||
|| (action & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_POINTER_DOWN) {
|
||||
final int index = (action & MotionEvent.ACTION_POINTER_INDEX_MASK)
|
||||
>> MotionEvent.ACTION_POINTER_INDEX_SHIFT; // will be 0 for down
|
||||
if (action == MotionEvent.ACTION_DOWN) {
|
||||
for (int p=0; p<NP; p++) {
|
||||
final PointerState ps = mPointers.get(p);
|
||||
ps.clearTrace();
|
||||
ps.mCurDown = false;
|
||||
}
|
||||
mCurDown = true;
|
||||
mMaxNumPointers = 0;
|
||||
mVelocity.clear();
|
||||
}
|
||||
|
||||
for (int p=0; p<NP; p++) {
|
||||
final PointerState ps = mPointers.get(p);
|
||||
ps.mXs.clear();
|
||||
ps.mYs.clear();
|
||||
ps.mCurDown = false;
|
||||
}
|
||||
mPointers.get(0).mCurDown = true;
|
||||
mMaxNumPointers = 0;
|
||||
if (mPrintCoords) {
|
||||
Log.i("Pointer", "Pointer 1: DOWN");
|
||||
}
|
||||
}
|
||||
|
||||
if ((action&MotionEvent.ACTION_MASK) == MotionEvent.ACTION_POINTER_DOWN) {
|
||||
final int index = (action&MotionEvent.ACTION_POINTER_INDEX_MASK)
|
||||
>> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
|
||||
final int id = event.getPointerId(index);
|
||||
while (NP <= id) {
|
||||
PointerState ps = new PointerState();
|
||||
mPointers.add(ps);
|
||||
NP++;
|
||||
}
|
||||
|
||||
final PointerState ps = mPointers.get(id);
|
||||
ps.mCurDown = true;
|
||||
if (mPrintCoords) {
|
||||
Log.i("Pointer", "Pointer " + (id+1) + ": DOWN");
|
||||
Log.i(TAG, mText.clear().append("Pointer ")
|
||||
.append(id + 1).append(": DOWN").toString());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -284,58 +380,38 @@ public class PointerLocationView extends View {
|
||||
final PointerState ps = mPointers.get(id);
|
||||
final int N = event.getHistorySize();
|
||||
for (int j=0; j<N; j++) {
|
||||
event.getHistoricalPointerCoords(i, j, ps.mCoords);
|
||||
if (mPrintCoords) {
|
||||
Log.i("Pointer", "Pointer " + (id+1) + ": ("
|
||||
+ event.getHistoricalX(i, j)
|
||||
+ ", " + event.getHistoricalY(i, j) + ")"
|
||||
+ " Prs=" + event.getHistoricalPressure(i, j)
|
||||
+ " Size=" + event.getHistoricalSize(i, j));
|
||||
logPointerCoords(ps.mCoords, id);
|
||||
}
|
||||
ps.mXs.add(event.getHistoricalX(i, j));
|
||||
ps.mYs.add(event.getHistoricalY(i, j));
|
||||
ps.addTrace(event.getHistoricalX(i, j), event.getHistoricalY(i, j));
|
||||
}
|
||||
event.getPointerCoords(i, ps.mCoords);
|
||||
if (mPrintCoords) {
|
||||
Log.i("Pointer", "Pointer " + (id+1) + ": ("
|
||||
+ event.getX(i) + ", " + event.getY(i) + ")"
|
||||
+ " Prs=" + event.getPressure(i)
|
||||
+ " Size=" + event.getSize(i));
|
||||
logPointerCoords(ps.mCoords, id);
|
||||
}
|
||||
ps.mXs.add(event.getX(i));
|
||||
ps.mYs.add(event.getY(i));
|
||||
ps.mCurX = (int)event.getX(i);
|
||||
ps.mCurY = (int)event.getY(i);
|
||||
//Log.i("Pointer", "Pointer #" + p + ": (" + ps.mCurX
|
||||
// + "," + ps.mCurY + ")");
|
||||
ps.mCurPressure = event.getPressure(i);
|
||||
ps.mCurSize = event.getSize(i);
|
||||
ps.mCurWidth = (int)(ps.mCurSize*(getWidth()/3));
|
||||
ps.addTrace(ps.mCoords.x, ps.mCoords.y);
|
||||
ps.mXVelocity = mVelocity.getXVelocity(id);
|
||||
ps.mYVelocity = mVelocity.getYVelocity(id);
|
||||
}
|
||||
|
||||
if ((action&MotionEvent.ACTION_MASK) == MotionEvent.ACTION_POINTER_UP) {
|
||||
final int index = (action&MotionEvent.ACTION_POINTER_INDEX_MASK)
|
||||
>> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
|
||||
if (action == MotionEvent.ACTION_UP
|
||||
|| (action & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_POINTER_UP) {
|
||||
final int index = (action & MotionEvent.ACTION_POINTER_INDEX_MASK)
|
||||
>> MotionEvent.ACTION_POINTER_INDEX_SHIFT; // will be 0 for UP
|
||||
|
||||
final int id = event.getPointerId(index);
|
||||
final PointerState ps = mPointers.get(id);
|
||||
ps.mXs.add(Float.NaN);
|
||||
ps.mYs.add(Float.NaN);
|
||||
ps.mCurDown = false;
|
||||
if (mPrintCoords) {
|
||||
Log.i("Pointer", "Pointer " + (id+1) + ": UP");
|
||||
Log.i(TAG, mText.clear().append("Pointer ")
|
||||
.append(id + 1).append(": UP").toString());
|
||||
}
|
||||
}
|
||||
|
||||
if (action == MotionEvent.ACTION_UP) {
|
||||
for (int i=0; i<NI; i++) {
|
||||
final int id = event.getPointerId(i);
|
||||
final PointerState ps = mPointers.get(id);
|
||||
if (ps.mCurDown) {
|
||||
ps.mCurDown = false;
|
||||
if (mPrintCoords) {
|
||||
Log.i("Pointer", "Pointer " + (id+1) + ": UP");
|
||||
}
|
||||
}
|
||||
|
||||
if (action == MotionEvent.ACTION_UP) {
|
||||
mCurDown = false;
|
||||
} else {
|
||||
ps.addTrace(Float.NaN, Float.NaN);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -356,8 +432,120 @@ public class PointerLocationView extends View {
|
||||
|
||||
@Override
|
||||
public boolean onTrackballEvent(MotionEvent event) {
|
||||
Log.i("Pointer", "Trackball: " + event);
|
||||
Log.i(TAG, "Trackball: " + event);
|
||||
return super.onTrackballEvent(event);
|
||||
}
|
||||
|
||||
// HACK
|
||||
// A quick and dirty string builder implementation optimized for GC.
|
||||
// Using the basic StringBuilder implementation causes the application grind to a halt when
|
||||
// more than a couple of pointers are down due to the number of temporary objects allocated
|
||||
// while formatting strings for drawing or logging.
|
||||
private static final class FasterStringBuilder {
|
||||
private char[] mChars;
|
||||
private int mLength;
|
||||
|
||||
public FasterStringBuilder() {
|
||||
mChars = new char[64];
|
||||
}
|
||||
|
||||
public FasterStringBuilder clear() {
|
||||
mLength = 0;
|
||||
return this;
|
||||
}
|
||||
|
||||
public FasterStringBuilder append(String value) {
|
||||
final int valueLength = value.length();
|
||||
final int index = reserve(valueLength);
|
||||
value.getChars(0, valueLength, mChars, index);
|
||||
mLength += valueLength;
|
||||
return this;
|
||||
}
|
||||
|
||||
public FasterStringBuilder append(int value) {
|
||||
return append(value, 0);
|
||||
}
|
||||
|
||||
public FasterStringBuilder append(int value, int zeroPadWidth) {
|
||||
final boolean negative = value < 0;
|
||||
if (negative) {
|
||||
value = - value;
|
||||
if (value < 0) {
|
||||
append("-2147483648");
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
int index = reserve(11);
|
||||
final char[] chars = mChars;
|
||||
|
||||
if (value == 0) {
|
||||
chars[index++] = '0';
|
||||
mLength += 1;
|
||||
return this;
|
||||
}
|
||||
|
||||
if (negative) {
|
||||
chars[index++] = '-';
|
||||
}
|
||||
|
||||
int divisor = 1000000000;
|
||||
int numberWidth = 10;
|
||||
while (value < divisor) {
|
||||
divisor /= 10;
|
||||
numberWidth -= 1;
|
||||
if (numberWidth < zeroPadWidth) {
|
||||
chars[index++] = '0';
|
||||
}
|
||||
}
|
||||
|
||||
do {
|
||||
int digit = value / divisor;
|
||||
value -= digit * divisor;
|
||||
divisor /= 10;
|
||||
chars[index++] = (char) (digit + '0');
|
||||
} while (divisor != 0);
|
||||
|
||||
mLength = index;
|
||||
return this;
|
||||
}
|
||||
|
||||
public FasterStringBuilder append(float value, int precision) {
|
||||
int scale = 1;
|
||||
for (int i = 0; i < precision; i++) {
|
||||
scale *= 10;
|
||||
}
|
||||
value = (float) (Math.rint(value * scale) / scale);
|
||||
|
||||
append((int) value);
|
||||
|
||||
if (precision != 0) {
|
||||
append(".");
|
||||
value = Math.abs(value);
|
||||
value -= Math.floor(value);
|
||||
append((int) (value * scale), precision);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new String(mChars, 0, mLength);
|
||||
}
|
||||
|
||||
private int reserve(int length) {
|
||||
final int oldLength = mLength;
|
||||
final int newLength = mLength + length;
|
||||
final char[] oldChars = mChars;
|
||||
final int oldCapacity = oldChars.length;
|
||||
if (newLength > oldCapacity) {
|
||||
final int newCapacity = oldCapacity * 2;
|
||||
final char[] newChars = new char[newCapacity];
|
||||
System.arraycopy(oldChars, 0, newChars, 0, oldLength);
|
||||
mChars = newChars;
|
||||
}
|
||||
return oldLength;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,6 +82,14 @@ struct RawAbsoluteAxisInfo {
|
||||
int32_t fuzz; // error tolerance, eg. fuzz == 4 means value is +/- 4 due to noise
|
||||
|
||||
inline int32_t getRange() { return maxValue - minValue; }
|
||||
|
||||
inline void clear() {
|
||||
valid = false;
|
||||
minValue = 0;
|
||||
maxValue = 0;
|
||||
flat = 0;
|
||||
fuzz = 0;
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
@@ -453,6 +453,10 @@ public:
|
||||
inline void setKeyboardType(int32_t keyboardType) { mKeyboardType = keyboardType; }
|
||||
inline int32_t getKeyboardType() const { return mKeyboardType; }
|
||||
|
||||
inline const KeyedVector<int32_t, MotionRange> getMotionRanges() const {
|
||||
return mMotionRanges;
|
||||
}
|
||||
|
||||
private:
|
||||
int32_t mId;
|
||||
String8 mName;
|
||||
|
||||
@@ -35,6 +35,34 @@ namespace android {
|
||||
class InputDevice;
|
||||
class InputMapper;
|
||||
|
||||
/* Describes a virtual key. */
|
||||
struct VirtualKeyDefinition {
|
||||
int32_t scanCode;
|
||||
|
||||
// configured position data, specified in display coords
|
||||
int32_t centerX;
|
||||
int32_t centerY;
|
||||
int32_t width;
|
||||
int32_t height;
|
||||
};
|
||||
|
||||
|
||||
/* Specifies input device calibration settings. */
|
||||
class InputDeviceCalibration {
|
||||
public:
|
||||
InputDeviceCalibration();
|
||||
|
||||
void clear();
|
||||
void addProperty(const String8& key, const String8& value);
|
||||
|
||||
bool tryGetProperty(const String8& key, String8& outValue) const;
|
||||
bool tryGetProperty(const String8& key, int32_t& outValue) const;
|
||||
bool tryGetProperty(const String8& key, float& outValue) const;
|
||||
|
||||
private:
|
||||
KeyedVector<String8, String8> mProperties;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Input reader policy interface.
|
||||
@@ -73,17 +101,6 @@ public:
|
||||
ACTION_APP_SWITCH_COMING = 0x00000002,
|
||||
};
|
||||
|
||||
/* Describes a virtual key. */
|
||||
struct VirtualKeyDefinition {
|
||||
int32_t scanCode;
|
||||
|
||||
// configured position data, specified in display coords
|
||||
int32_t centerX;
|
||||
int32_t centerY;
|
||||
int32_t width;
|
||||
int32_t height;
|
||||
};
|
||||
|
||||
/* Gets information about the display with the specified id.
|
||||
* Returns true if the display info is available, false otherwise.
|
||||
*/
|
||||
@@ -135,6 +152,10 @@ public:
|
||||
virtual void getVirtualKeyDefinitions(const String8& deviceName,
|
||||
Vector<VirtualKeyDefinition>& outVirtualKeyDefinitions) = 0;
|
||||
|
||||
/* Gets the calibration for an input device. */
|
||||
virtual void getInputDeviceCalibration(const String8& deviceName,
|
||||
InputDeviceCalibration& outCalibration) = 0;
|
||||
|
||||
/* Gets the excluded device names for the platform. */
|
||||
virtual void getExcludedDeviceNames(Vector<String8>& outExcludedDeviceNames) = 0;
|
||||
};
|
||||
@@ -327,6 +348,10 @@ public:
|
||||
|
||||
int32_t getMetaState();
|
||||
|
||||
inline const InputDeviceCalibration& getCalibration() {
|
||||
return mCalibration;
|
||||
}
|
||||
|
||||
private:
|
||||
InputReaderContext* mContext;
|
||||
int32_t mId;
|
||||
@@ -338,6 +363,8 @@ private:
|
||||
|
||||
typedef int32_t (InputMapper::*GetStateFunc)(uint32_t sourceMask, int32_t code);
|
||||
int32_t getState(uint32_t sourceMask, int32_t code, GetStateFunc getStateFunc);
|
||||
|
||||
InputDeviceCalibration mCalibration;
|
||||
};
|
||||
|
||||
|
||||
@@ -538,12 +565,12 @@ protected:
|
||||
}
|
||||
};
|
||||
|
||||
// Raw data for a single pointer.
|
||||
struct PointerData {
|
||||
uint32_t id;
|
||||
int32_t x;
|
||||
int32_t y;
|
||||
int32_t pressure;
|
||||
int32_t size;
|
||||
int32_t touchMajor;
|
||||
int32_t touchMinor;
|
||||
int32_t toolMajor;
|
||||
@@ -551,6 +578,7 @@ protected:
|
||||
int32_t orientation;
|
||||
};
|
||||
|
||||
// Raw data for a collection of pointers including a pointer id mapping table.
|
||||
struct TouchData {
|
||||
uint32_t pointerCount;
|
||||
PointerData pointers[MAX_POINTERS];
|
||||
@@ -584,18 +612,82 @@ protected:
|
||||
bool useAveragingTouchFilter;
|
||||
} mParameters;
|
||||
|
||||
// Raw axis information.
|
||||
struct Axes {
|
||||
// Immutable calibration parameters in parsed form.
|
||||
struct Calibration {
|
||||
// Touch Area
|
||||
enum TouchAreaCalibration {
|
||||
TOUCH_AREA_CALIBRATION_DEFAULT,
|
||||
TOUCH_AREA_CALIBRATION_NONE,
|
||||
TOUCH_AREA_CALIBRATION_GEOMETRIC,
|
||||
TOUCH_AREA_CALIBRATION_PRESSURE,
|
||||
};
|
||||
|
||||
TouchAreaCalibration touchAreaCalibration;
|
||||
|
||||
// Tool Area
|
||||
enum ToolAreaCalibration {
|
||||
TOOL_AREA_CALIBRATION_DEFAULT,
|
||||
TOOL_AREA_CALIBRATION_NONE,
|
||||
TOOL_AREA_CALIBRATION_GEOMETRIC,
|
||||
TOOL_AREA_CALIBRATION_LINEAR,
|
||||
};
|
||||
|
||||
ToolAreaCalibration toolAreaCalibration;
|
||||
bool haveToolAreaLinearScale;
|
||||
float toolAreaLinearScale;
|
||||
bool haveToolAreaLinearBias;
|
||||
float toolAreaLinearBias;
|
||||
bool haveToolAreaIsSummed;
|
||||
int32_t toolAreaIsSummed;
|
||||
|
||||
// Pressure
|
||||
enum PressureCalibration {
|
||||
PRESSURE_CALIBRATION_DEFAULT,
|
||||
PRESSURE_CALIBRATION_NONE,
|
||||
PRESSURE_CALIBRATION_PHYSICAL,
|
||||
PRESSURE_CALIBRATION_AMPLITUDE,
|
||||
};
|
||||
enum PressureSource {
|
||||
PRESSURE_SOURCE_DEFAULT,
|
||||
PRESSURE_SOURCE_PRESSURE,
|
||||
PRESSURE_SOURCE_TOUCH,
|
||||
};
|
||||
|
||||
PressureCalibration pressureCalibration;
|
||||
PressureSource pressureSource;
|
||||
bool havePressureScale;
|
||||
float pressureScale;
|
||||
|
||||
// Size
|
||||
enum SizeCalibration {
|
||||
SIZE_CALIBRATION_DEFAULT,
|
||||
SIZE_CALIBRATION_NONE,
|
||||
SIZE_CALIBRATION_NORMALIZED,
|
||||
};
|
||||
|
||||
SizeCalibration sizeCalibration;
|
||||
|
||||
// Orientation
|
||||
enum OrientationCalibration {
|
||||
ORIENTATION_CALIBRATION_DEFAULT,
|
||||
ORIENTATION_CALIBRATION_NONE,
|
||||
ORIENTATION_CALIBRATION_INTERPOLATED,
|
||||
};
|
||||
|
||||
OrientationCalibration orientationCalibration;
|
||||
} mCalibration;
|
||||
|
||||
// Raw axis information from the driver.
|
||||
struct RawAxes {
|
||||
RawAbsoluteAxisInfo x;
|
||||
RawAbsoluteAxisInfo y;
|
||||
RawAbsoluteAxisInfo pressure;
|
||||
RawAbsoluteAxisInfo size;
|
||||
RawAbsoluteAxisInfo touchMajor;
|
||||
RawAbsoluteAxisInfo touchMinor;
|
||||
RawAbsoluteAxisInfo toolMajor;
|
||||
RawAbsoluteAxisInfo toolMinor;
|
||||
RawAbsoluteAxisInfo orientation;
|
||||
} mAxes;
|
||||
} mRawAxes;
|
||||
|
||||
// Current and previous touch sample data.
|
||||
TouchData mCurrentTouch;
|
||||
@@ -620,10 +712,13 @@ protected:
|
||||
float yScale;
|
||||
float yPrecision;
|
||||
|
||||
int32_t pressureOrigin;
|
||||
float geometricScale;
|
||||
|
||||
float toolAreaLinearScale;
|
||||
float toolAreaLinearBias;
|
||||
|
||||
float pressureScale;
|
||||
|
||||
int32_t sizeOrigin;
|
||||
float sizeScale;
|
||||
|
||||
float orientationScale;
|
||||
@@ -632,12 +727,22 @@ protected:
|
||||
struct OrientedRanges {
|
||||
InputDeviceInfo::MotionRange x;
|
||||
InputDeviceInfo::MotionRange y;
|
||||
|
||||
bool havePressure;
|
||||
InputDeviceInfo::MotionRange pressure;
|
||||
|
||||
bool haveSize;
|
||||
InputDeviceInfo::MotionRange size;
|
||||
|
||||
bool haveTouchArea;
|
||||
InputDeviceInfo::MotionRange touchMajor;
|
||||
InputDeviceInfo::MotionRange touchMinor;
|
||||
|
||||
bool haveToolArea;
|
||||
InputDeviceInfo::MotionRange toolMajor;
|
||||
InputDeviceInfo::MotionRange toolMinor;
|
||||
|
||||
bool haveOrientation;
|
||||
InputDeviceInfo::MotionRange orientation;
|
||||
} orientedRanges;
|
||||
|
||||
@@ -653,9 +758,14 @@ protected:
|
||||
} currentVirtualKey;
|
||||
} mLocked;
|
||||
|
||||
virtual void configureAxes();
|
||||
virtual void configureParameters();
|
||||
virtual void configureRawAxes();
|
||||
virtual void logRawAxes();
|
||||
virtual bool configureSurfaceLocked();
|
||||
virtual void configureVirtualKeysLocked();
|
||||
virtual void parseCalibration();
|
||||
virtual void resolveCalibration();
|
||||
virtual void logCalibration();
|
||||
|
||||
enum TouchResult {
|
||||
// Dispatch the touch normally.
|
||||
@@ -713,7 +823,8 @@ private:
|
||||
TouchResult consumeOffScreenTouches(nsecs_t when, uint32_t policyFlags);
|
||||
void dispatchTouches(nsecs_t when, uint32_t policyFlags);
|
||||
void dispatchTouch(nsecs_t when, uint32_t policyFlags, TouchData* touch,
|
||||
BitSet32 idBits, uint32_t changedId, int32_t motionEventAction);
|
||||
BitSet32 idBits, uint32_t changedId, uint32_t pointerCount,
|
||||
int32_t motionEventAction);
|
||||
|
||||
void applyPolicyAndDispatchVirtualKey(nsecs_t when, uint32_t policyFlags,
|
||||
int32_t keyEventAction, int32_t keyEventFlags,
|
||||
@@ -738,7 +849,7 @@ public:
|
||||
virtual void process(const RawEvent* rawEvent);
|
||||
|
||||
protected:
|
||||
virtual void configureAxes();
|
||||
virtual void configureRawAxes();
|
||||
|
||||
private:
|
||||
struct Accumulator {
|
||||
@@ -767,7 +878,7 @@ private:
|
||||
int32_t mX;
|
||||
int32_t mY;
|
||||
int32_t mPressure;
|
||||
int32_t mSize;
|
||||
int32_t mToolWidth;
|
||||
|
||||
void initialize();
|
||||
|
||||
@@ -784,7 +895,7 @@ public:
|
||||
virtual void process(const RawEvent* rawEvent);
|
||||
|
||||
protected:
|
||||
virtual void configureAxes();
|
||||
virtual void configureRawAxes();
|
||||
|
||||
private:
|
||||
struct Accumulator {
|
||||
|
||||
@@ -139,11 +139,7 @@ uint32_t EventHub::getDeviceClasses(int32_t deviceId) const
|
||||
|
||||
status_t EventHub::getAbsoluteAxisInfo(int32_t deviceId, int axis,
|
||||
RawAbsoluteAxisInfo* outAxisInfo) const {
|
||||
outAxisInfo->valid = false;
|
||||
outAxisInfo->minValue = 0;
|
||||
outAxisInfo->maxValue = 0;
|
||||
outAxisInfo->flat = 0;
|
||||
outAxisInfo->fuzz = 0;
|
||||
outAxisInfo->clear();
|
||||
|
||||
AutoMutex _l(mLock);
|
||||
device_t* device = getDevice(deviceId);
|
||||
@@ -709,8 +705,7 @@ int EventHub::open_device(const char *deviceName)
|
||||
LOGV("Getting absolute controllers...");
|
||||
if (ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(abs_bitmask)), abs_bitmask) >= 0) {
|
||||
// Is this a new modern multi-touch driver?
|
||||
if (test_bit(ABS_MT_TOUCH_MAJOR, abs_bitmask)
|
||||
&& test_bit(ABS_MT_POSITION_X, abs_bitmask)
|
||||
if (test_bit(ABS_MT_POSITION_X, abs_bitmask)
|
||||
&& test_bit(ABS_MT_POSITION_Y, abs_bitmask)) {
|
||||
device->classes |= INPUT_DEVICE_CLASS_TOUCHSCREEN | INPUT_DEVICE_CLASS_TOUCHSCREEN_MT;
|
||||
|
||||
|
||||
@@ -405,12 +405,15 @@ void InputDispatcher::processMotionLockedInterruptible(
|
||||
sampleCount += 1;
|
||||
}
|
||||
for (uint32_t i = 0; i < entry->pointerCount; i++) {
|
||||
LOGD(" Pointer %d: id=%d, x=%f, y=%f, pressure=%f, size=%f",
|
||||
LOGD(" Pointer %d: id=%d, x=%f, y=%f, pressure=%f, size=%f, "
|
||||
"touchMajor=%f, touchMinor=%d, toolMajor=%f, toolMinor=%f, "
|
||||
"orientation=%f",
|
||||
i, entry->pointerIds[i],
|
||||
sample->pointerCoords[i].x,
|
||||
sample->pointerCoords[i].y,
|
||||
sample->pointerCoords[i].pressure,
|
||||
sample->pointerCoords[i].size);
|
||||
sample->pointerCoords[i].x, sample->pointerCoords[i].y,
|
||||
sample->pointerCoords[i].pressure, sample->pointerCoords[i].size,
|
||||
sample->pointerCoords[i].touchMajor, sample->pointerCoords[i].touchMinor,
|
||||
sample->pointerCoords[i].toolMajor, sample->pointerCoords[i].toolMinor,
|
||||
sample->pointerCoords[i].orientation);
|
||||
}
|
||||
|
||||
// Keep in mind that due to batching, it is possible for the number of samples actually
|
||||
@@ -1080,9 +1083,14 @@ void InputDispatcher::notifyMotion(nsecs_t eventTime, int32_t deviceId, int32_t
|
||||
eventTime, deviceId, source, policyFlags, action, metaState, edgeFlags,
|
||||
xPrecision, yPrecision, downTime);
|
||||
for (uint32_t i = 0; i < pointerCount; i++) {
|
||||
LOGD(" Pointer %d: id=%d, x=%f, y=%f, pressure=%f, size=%f",
|
||||
LOGD(" Pointer %d: id=%d, x=%f, y=%f, pressure=%f, size=%f, "
|
||||
"touchMajor=%f, touchMinor=%d, toolMajor=%f, toolMinor=%f, "
|
||||
"orientation=%f",
|
||||
i, pointerIds[i], pointerCoords[i].x, pointerCoords[i].y,
|
||||
pointerCoords[i].pressure, pointerCoords[i].size);
|
||||
pointerCoords[i].pressure, pointerCoords[i].size,
|
||||
pointerCoords[i].touchMajor, pointerCoords[i].touchMinor,
|
||||
pointerCoords[i].toolMajor, pointerCoords[i].toolMinor,
|
||||
pointerCoords[i].orientation);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -718,8 +718,6 @@ int32_t AInputDevice_getKeyboardType(AInputDevice* device);
|
||||
int32_t AInputDevice_getMotionRange(AInputDevice* device, int32_t rangeType,
|
||||
float* outMin, float* outMax, float* outFlat, float* outFuzz);
|
||||
|
||||
//TODO hasKey, keymap stuff, etc...
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -30,6 +30,7 @@ import android.os.SystemProperties;
|
||||
import android.util.Slog;
|
||||
import android.util.Xml;
|
||||
import android.view.InputChannel;
|
||||
import android.view.InputDevice;
|
||||
import android.view.InputEvent;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.MotionEvent;
|
||||
@@ -45,6 +46,7 @@ import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Properties;
|
||||
|
||||
/*
|
||||
* Wraps the C++ InputManager and provides its callbacks.
|
||||
@@ -82,6 +84,8 @@ public class InputManager {
|
||||
private static native void nativeSetInputDispatchMode(boolean enabled, boolean frozen);
|
||||
private static native void nativeSetFocusedApplication(InputApplication application);
|
||||
private static native void nativePreemptInputDispatch();
|
||||
private static native InputDevice nativeGetInputDevice(int deviceId);
|
||||
private static native int[] nativeGetInputDeviceIds();
|
||||
private static native String nativeDump();
|
||||
|
||||
// Input event injection constants defined in InputDispatcher.h.
|
||||
@@ -302,6 +306,23 @@ public class InputManager {
|
||||
return nativeInjectInputEvent(event, injectorPid, injectorUid, syncMode, timeoutMillis);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets information about the input device with the specified id.
|
||||
* @param id The device id.
|
||||
* @return The input device or null if not found.
|
||||
*/
|
||||
public InputDevice getInputDevice(int deviceId) {
|
||||
return nativeGetInputDevice(deviceId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the ids of all input devices in the system.
|
||||
* @return The input device ids.
|
||||
*/
|
||||
public int[] getInputDeviceIds() {
|
||||
return nativeGetInputDeviceIds();
|
||||
}
|
||||
|
||||
public void setInputWindows(InputWindow[] windows) {
|
||||
nativeSetInputWindows(windows);
|
||||
}
|
||||
@@ -335,6 +356,11 @@ public class InputManager {
|
||||
public int height;
|
||||
}
|
||||
|
||||
private static final class InputDeviceCalibration {
|
||||
public String[] keys;
|
||||
public String[] values;
|
||||
}
|
||||
|
||||
/*
|
||||
* Callbacks from native.
|
||||
*/
|
||||
@@ -343,6 +369,7 @@ public class InputManager {
|
||||
|
||||
private static final boolean DEBUG_VIRTUAL_KEYS = false;
|
||||
private static final String EXCLUDED_DEVICES_PATH = "etc/excluded-input-devices.xml";
|
||||
private static final String CALIBRATION_DIR_PATH = "usr/idc/";
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public void virtualKeyDownFeedback() {
|
||||
@@ -438,8 +465,8 @@ public class InputManager {
|
||||
final int N = it.length-6;
|
||||
for (int i=0; i<=N; i+=6) {
|
||||
if (!"0x01".equals(it[i])) {
|
||||
Slog.w(TAG, "Unknown virtual key type at elem #" + i
|
||||
+ ": " + it[i]);
|
||||
Slog.w(TAG, "Unknown virtual key type at elem #"
|
||||
+ i + ": " + it[i] + " for device " + deviceName);
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
@@ -455,21 +482,46 @@ public class InputManager {
|
||||
+ key.height);
|
||||
keys.add(key);
|
||||
} catch (NumberFormatException e) {
|
||||
Slog.w(TAG, "Bad number at region " + i + " in: "
|
||||
+ str, e);
|
||||
Slog.w(TAG, "Bad number in virtual key definition at region "
|
||||
+ i + " in: " + str + " for device " + deviceName, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
br.close();
|
||||
} catch (FileNotFoundException e) {
|
||||
Slog.i(TAG, "No virtual keys found");
|
||||
Slog.i(TAG, "No virtual keys found for device " + deviceName + ".");
|
||||
} catch (IOException e) {
|
||||
Slog.w(TAG, "Error reading virtual keys", e);
|
||||
Slog.w(TAG, "Error reading virtual keys for device " + deviceName + ".", e);
|
||||
}
|
||||
|
||||
return keys.toArray(new VirtualKeyDefinition[keys.size()]);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public InputDeviceCalibration getInputDeviceCalibration(String deviceName) {
|
||||
// Calibration is specified as a sequence of colon-delimited key value pairs.
|
||||
Properties properties = new Properties();
|
||||
File calibrationFile = new File(Environment.getRootDirectory(),
|
||||
CALIBRATION_DIR_PATH + deviceName + ".idc");
|
||||
if (calibrationFile.exists()) {
|
||||
try {
|
||||
properties.load(new FileInputStream(calibrationFile));
|
||||
} catch (IOException ex) {
|
||||
Slog.w(TAG, "Error reading input device calibration properties for device "
|
||||
+ deviceName + " from " + calibrationFile + ".", ex);
|
||||
}
|
||||
} else {
|
||||
Slog.i(TAG, "No input device calibration properties found for device "
|
||||
+ deviceName + ".");
|
||||
return null;
|
||||
}
|
||||
|
||||
InputDeviceCalibration calibration = new InputDeviceCalibration();
|
||||
calibration.keys = properties.keySet().toArray(new String[properties.size()]);
|
||||
calibration.values = properties.values().toArray(new String[properties.size()]);
|
||||
return calibration;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public String[] getExcludedDeviceNames() {
|
||||
ArrayList<String> names = new ArrayList<String>();
|
||||
|
||||
@@ -4392,6 +4392,14 @@ public class WindowManagerService extends IWindowManager.Stub
|
||||
return mInputManager.monitorInput(inputChannelName);
|
||||
}
|
||||
|
||||
public InputDevice getInputDevice(int deviceId) {
|
||||
return mInputManager.getInputDevice(deviceId);
|
||||
}
|
||||
|
||||
public int[] getInputDeviceIds() {
|
||||
return mInputManager.getInputDeviceIds();
|
||||
}
|
||||
|
||||
public void enableScreenAfterBoot() {
|
||||
synchronized(mWindowMap) {
|
||||
if (mSystemBooted) {
|
||||
|
||||
@@ -138,6 +138,7 @@ static struct {
|
||||
jmethodID filterTouchEvents;
|
||||
jmethodID filterJumpyTouchEvents;
|
||||
jmethodID getVirtualKeyDefinitions;
|
||||
jmethodID getInputDeviceCalibration;
|
||||
jmethodID getExcludedDeviceNames;
|
||||
jmethodID getMaxEventsPerSecond;
|
||||
} gCallbacksClassInfo;
|
||||
@@ -152,6 +153,13 @@ static struct {
|
||||
jfieldID height;
|
||||
} gVirtualKeyDefinitionClassInfo;
|
||||
|
||||
static struct {
|
||||
jclass clazz;
|
||||
|
||||
jfieldID keys;
|
||||
jfieldID values;
|
||||
} gInputDeviceCalibrationClassInfo;
|
||||
|
||||
static struct {
|
||||
jclass clazz;
|
||||
|
||||
@@ -189,6 +197,19 @@ static struct {
|
||||
jclass clazz;
|
||||
} gMotionEventClassInfo;
|
||||
|
||||
static struct {
|
||||
jclass clazz;
|
||||
|
||||
jmethodID ctor;
|
||||
jmethodID addMotionRange;
|
||||
|
||||
jfieldID mId;
|
||||
jfieldID mName;
|
||||
jfieldID mSources;
|
||||
jfieldID mKeyboardType;
|
||||
jfieldID mMotionRanges;
|
||||
} gInputDeviceClassInfo;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
static inline nsecs_t now() {
|
||||
@@ -235,7 +256,9 @@ public:
|
||||
virtual bool filterTouchEvents();
|
||||
virtual bool filterJumpyTouchEvents();
|
||||
virtual void getVirtualKeyDefinitions(const String8& deviceName,
|
||||
Vector<InputReaderPolicyInterface::VirtualKeyDefinition>& outVirtualKeyDefinitions);
|
||||
Vector<VirtualKeyDefinition>& outVirtualKeyDefinitions);
|
||||
virtual void getInputDeviceCalibration(const String8& deviceName,
|
||||
InputDeviceCalibration& outCalibration);
|
||||
virtual void getExcludedDeviceNames(Vector<String8>& outExcludedDeviceNames);
|
||||
|
||||
/* --- InputDispatcherPolicyInterface implementation --- */
|
||||
@@ -761,7 +784,9 @@ bool NativeInputManager::filterJumpyTouchEvents() {
|
||||
}
|
||||
|
||||
void NativeInputManager::getVirtualKeyDefinitions(const String8& deviceName,
|
||||
Vector<InputReaderPolicyInterface::VirtualKeyDefinition>& outVirtualKeyDefinitions) {
|
||||
Vector<VirtualKeyDefinition>& outVirtualKeyDefinitions) {
|
||||
outVirtualKeyDefinitions.clear();
|
||||
|
||||
JNIEnv* env = jniEnv();
|
||||
|
||||
jstring deviceNameStr = env->NewStringUTF(deviceName.string());
|
||||
@@ -793,7 +818,51 @@ void NativeInputManager::getVirtualKeyDefinitions(const String8& deviceName,
|
||||
}
|
||||
}
|
||||
|
||||
void NativeInputManager::getInputDeviceCalibration(const String8& deviceName,
|
||||
InputDeviceCalibration& outCalibration) {
|
||||
outCalibration.clear();
|
||||
|
||||
JNIEnv* env = jniEnv();
|
||||
|
||||
jstring deviceNameStr = env->NewStringUTF(deviceName.string());
|
||||
if (! checkAndClearExceptionFromCallback(env, "getInputDeviceCalibration")) {
|
||||
jobject result = env->CallObjectMethod(mCallbacksObj,
|
||||
gCallbacksClassInfo.getInputDeviceCalibration, deviceNameStr);
|
||||
if (! checkAndClearExceptionFromCallback(env, "getInputDeviceCalibration") && result) {
|
||||
jobjectArray keys = jobjectArray(env->GetObjectField(result,
|
||||
gInputDeviceCalibrationClassInfo.keys));
|
||||
jobjectArray values = jobjectArray(env->GetObjectField(result,
|
||||
gInputDeviceCalibrationClassInfo.values));
|
||||
|
||||
jsize length = env->GetArrayLength(keys);
|
||||
for (jsize i = 0; i < length; i++) {
|
||||
jstring keyStr = jstring(env->GetObjectArrayElement(keys, i));
|
||||
jstring valueStr = jstring(env->GetObjectArrayElement(values, i));
|
||||
|
||||
const char* keyChars = env->GetStringUTFChars(keyStr, NULL);
|
||||
String8 key(keyChars);
|
||||
env->ReleaseStringUTFChars(keyStr, keyChars);
|
||||
|
||||
const char* valueChars = env->GetStringUTFChars(valueStr, NULL);
|
||||
String8 value(valueChars);
|
||||
env->ReleaseStringUTFChars(valueStr, valueChars);
|
||||
|
||||
outCalibration.addProperty(key, value);
|
||||
|
||||
env->DeleteLocalRef(keyStr);
|
||||
env->DeleteLocalRef(valueStr);
|
||||
}
|
||||
env->DeleteLocalRef(keys);
|
||||
env->DeleteLocalRef(values);
|
||||
env->DeleteLocalRef(result);
|
||||
}
|
||||
env->DeleteLocalRef(deviceNameStr);
|
||||
}
|
||||
}
|
||||
|
||||
void NativeInputManager::getExcludedDeviceNames(Vector<String8>& outExcludedDeviceNames) {
|
||||
outExcludedDeviceNames.clear();
|
||||
|
||||
JNIEnv* env = jniEnv();
|
||||
|
||||
jobjectArray result = jobjectArray(env->CallObjectMethod(mCallbacksObj,
|
||||
@@ -2199,6 +2268,66 @@ static void android_server_InputManager_nativePreemptInputDispatch(JNIEnv* env,
|
||||
gNativeInputManager->preemptInputDispatch();
|
||||
}
|
||||
|
||||
static jobject android_server_InputManager_nativeGetInputDevice(JNIEnv* env,
|
||||
jclass clazz, jint deviceId) {
|
||||
if (checkInputManagerUnitialized(env)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
InputDeviceInfo deviceInfo;
|
||||
status_t status = gNativeInputManager->getInputManager()->getInputDeviceInfo(
|
||||
deviceId, & deviceInfo);
|
||||
if (status) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
jobject deviceObj = env->NewObject(gInputDeviceClassInfo.clazz, gInputDeviceClassInfo.ctor);
|
||||
if (! deviceObj) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
jstring deviceNameObj = env->NewStringUTF(deviceInfo.getName().string());
|
||||
if (! deviceNameObj) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
env->SetIntField(deviceObj, gInputDeviceClassInfo.mId, deviceInfo.getId());
|
||||
env->SetObjectField(deviceObj, gInputDeviceClassInfo.mName, deviceNameObj);
|
||||
env->SetIntField(deviceObj, gInputDeviceClassInfo.mSources, deviceInfo.getSources());
|
||||
env->SetIntField(deviceObj, gInputDeviceClassInfo.mKeyboardType, deviceInfo.getKeyboardType());
|
||||
|
||||
const KeyedVector<int, InputDeviceInfo::MotionRange>& ranges = deviceInfo.getMotionRanges();
|
||||
for (size_t i = 0; i < ranges.size(); i++) {
|
||||
int rangeType = ranges.keyAt(i);
|
||||
const InputDeviceInfo::MotionRange& range = ranges.valueAt(i);
|
||||
env->CallVoidMethod(deviceObj, gInputDeviceClassInfo.addMotionRange,
|
||||
rangeType, range.min, range.max, range.flat, range.fuzz);
|
||||
if (env->ExceptionCheck()) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return deviceObj;
|
||||
}
|
||||
|
||||
static jintArray android_server_InputManager_nativeGetInputDeviceIds(JNIEnv* env,
|
||||
jclass clazz) {
|
||||
if (checkInputManagerUnitialized(env)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Vector<int> deviceIds;
|
||||
gNativeInputManager->getInputManager()->getInputDeviceIds(deviceIds);
|
||||
|
||||
jintArray deviceIdsObj = env->NewIntArray(deviceIds.size());
|
||||
if (! deviceIdsObj) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
env->SetIntArrayRegion(deviceIdsObj, 0, deviceIds.size(), deviceIds.array());
|
||||
return deviceIdsObj;
|
||||
}
|
||||
|
||||
static jstring android_server_InputManager_nativeDump(JNIEnv* env, jclass clazz) {
|
||||
if (checkInputManagerUnitialized(env)) {
|
||||
return NULL;
|
||||
@@ -2242,6 +2371,10 @@ static JNINativeMethod gInputManagerMethods[] = {
|
||||
(void*) android_server_InputManager_nativeSetInputDispatchMode },
|
||||
{ "nativePreemptInputDispatch", "()V",
|
||||
(void*) android_server_InputManager_nativePreemptInputDispatch },
|
||||
{ "nativeGetInputDevice", "(I)Landroid/view/InputDevice;",
|
||||
(void*) android_server_InputManager_nativeGetInputDevice },
|
||||
{ "nativeGetInputDeviceIds", "()[I",
|
||||
(void*) android_server_InputManager_nativeGetInputDeviceIds },
|
||||
{ "nativeDump", "()Ljava/lang/String;",
|
||||
(void*) android_server_InputManager_nativeDump },
|
||||
};
|
||||
@@ -2311,6 +2444,10 @@ int register_android_server_InputManager(JNIEnv* env) {
|
||||
"getVirtualKeyDefinitions",
|
||||
"(Ljava/lang/String;)[Lcom/android/server/InputManager$VirtualKeyDefinition;");
|
||||
|
||||
GET_METHOD_ID(gCallbacksClassInfo.getInputDeviceCalibration, gCallbacksClassInfo.clazz,
|
||||
"getInputDeviceCalibration",
|
||||
"(Ljava/lang/String;)Lcom/android/server/InputManager$InputDeviceCalibration;");
|
||||
|
||||
GET_METHOD_ID(gCallbacksClassInfo.getExcludedDeviceNames, gCallbacksClassInfo.clazz,
|
||||
"getExcludedDeviceNames", "()[Ljava/lang/String;");
|
||||
|
||||
@@ -2337,6 +2474,17 @@ int register_android_server_InputManager(JNIEnv* env) {
|
||||
GET_FIELD_ID(gVirtualKeyDefinitionClassInfo.height, gVirtualKeyDefinitionClassInfo.clazz,
|
||||
"height", "I");
|
||||
|
||||
// InputDeviceCalibration
|
||||
|
||||
FIND_CLASS(gInputDeviceCalibrationClassInfo.clazz,
|
||||
"com/android/server/InputManager$InputDeviceCalibration");
|
||||
|
||||
GET_FIELD_ID(gInputDeviceCalibrationClassInfo.keys, gInputDeviceCalibrationClassInfo.clazz,
|
||||
"keys", "[Ljava/lang/String;");
|
||||
|
||||
GET_FIELD_ID(gInputDeviceCalibrationClassInfo.values, gInputDeviceCalibrationClassInfo.clazz,
|
||||
"values", "[Ljava/lang/String;");
|
||||
|
||||
// InputWindow
|
||||
|
||||
FIND_CLASS(gInputWindowClassInfo.clazz, "com/android/server/InputWindow");
|
||||
@@ -2407,10 +2555,35 @@ int register_android_server_InputManager(JNIEnv* env) {
|
||||
|
||||
FIND_CLASS(gKeyEventClassInfo.clazz, "android/view/KeyEvent");
|
||||
|
||||
// MotionEVent
|
||||
// MotionEvent
|
||||
|
||||
FIND_CLASS(gMotionEventClassInfo.clazz, "android/view/MotionEvent");
|
||||
|
||||
// InputDevice
|
||||
|
||||
FIND_CLASS(gInputDeviceClassInfo.clazz, "android/view/InputDevice");
|
||||
|
||||
GET_METHOD_ID(gInputDeviceClassInfo.ctor, gInputDeviceClassInfo.clazz,
|
||||
"<init>", "()V");
|
||||
|
||||
GET_METHOD_ID(gInputDeviceClassInfo.addMotionRange, gInputDeviceClassInfo.clazz,
|
||||
"addMotionRange", "(IFFFF)V");
|
||||
|
||||
GET_FIELD_ID(gInputDeviceClassInfo.mId, gInputDeviceClassInfo.clazz,
|
||||
"mId", "I");
|
||||
|
||||
GET_FIELD_ID(gInputDeviceClassInfo.mName, gInputDeviceClassInfo.clazz,
|
||||
"mName", "Ljava/lang/String;");
|
||||
|
||||
GET_FIELD_ID(gInputDeviceClassInfo.mSources, gInputDeviceClassInfo.clazz,
|
||||
"mSources", "I");
|
||||
|
||||
GET_FIELD_ID(gInputDeviceClassInfo.mKeyboardType, gInputDeviceClassInfo.clazz,
|
||||
"mKeyboardType", "I");
|
||||
|
||||
GET_FIELD_ID(gInputDeviceClassInfo.mMotionRanges, gInputDeviceClassInfo.clazz,
|
||||
"mMotionRanges", "[Landroid/view/InputDevice$MotionRange;");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user