53071d6d15
new file: core/java/android/os/LatencyTimer.java modified: core/java/android/view/MotionEvent.java modified: core/java/android/view/ViewRoot.java modified: services/java/com/android/server/InputDevice.java modified: services/java/com/android/server/KeyInputQueue.java modified: services/java/com/android/server/WindowManagerService.java
214 lines
7.5 KiB
Java
214 lines
7.5 KiB
Java
/*
|
|
* Copyright (C) 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 com.android.server;
|
|
|
|
import android.util.Log;
|
|
import android.view.Display;
|
|
import android.view.MotionEvent;
|
|
import android.view.Surface;
|
|
import android.view.WindowManagerPolicy;
|
|
|
|
public class InputDevice {
|
|
/** Amount that trackball needs to move in order to generate a key event. */
|
|
static final int TRACKBALL_MOVEMENT_THRESHOLD = 6;
|
|
|
|
final int id;
|
|
final int classes;
|
|
final String name;
|
|
final AbsoluteInfo absX;
|
|
final AbsoluteInfo absY;
|
|
final AbsoluteInfo absPressure;
|
|
final AbsoluteInfo absSize;
|
|
|
|
long mDownTime = 0;
|
|
int mMetaKeysState = 0;
|
|
|
|
final MotionState mAbs = new MotionState(0, 0);
|
|
final MotionState mRel = new MotionState(TRACKBALL_MOVEMENT_THRESHOLD,
|
|
TRACKBALL_MOVEMENT_THRESHOLD);
|
|
|
|
static class MotionState {
|
|
int xPrecision;
|
|
int yPrecision;
|
|
float xMoveScale;
|
|
float yMoveScale;
|
|
MotionEvent currentMove = null;
|
|
boolean changed = false;
|
|
boolean down = false;
|
|
boolean lastDown = false;
|
|
long downTime = 0;
|
|
int x = 0;
|
|
int y = 0;
|
|
int pressure = 1;
|
|
int size = 0;
|
|
|
|
MotionState(int mx, int my) {
|
|
xPrecision = mx;
|
|
yPrecision = my;
|
|
xMoveScale = mx != 0 ? (1.0f/mx) : 1.0f;
|
|
yMoveScale = my != 0 ? (1.0f/my) : 1.0f;
|
|
}
|
|
|
|
MotionEvent generateMotion(InputDevice device, long curTime, long curTimeNano,
|
|
boolean isAbs, Display display, int orientation,
|
|
int metaState) {
|
|
if (!changed) {
|
|
return null;
|
|
}
|
|
|
|
float scaledX = x;
|
|
float scaledY = y;
|
|
float temp;
|
|
float scaledPressure = 1.0f;
|
|
float scaledSize = 0;
|
|
int edgeFlags = 0;
|
|
if (isAbs) {
|
|
int w = display.getWidth()-1;
|
|
int h = display.getHeight()-1;
|
|
if (orientation == Surface.ROTATION_90
|
|
|| orientation == Surface.ROTATION_270) {
|
|
int tmp = w;
|
|
w = h;
|
|
h = tmp;
|
|
}
|
|
if (device.absX != null) {
|
|
scaledX = ((scaledX-device.absX.minValue)
|
|
/ device.absX.range) * w;
|
|
}
|
|
if (device.absY != null) {
|
|
scaledY = ((scaledY-device.absY.minValue)
|
|
/ device.absY.range) * h;
|
|
}
|
|
if (device.absPressure != null) {
|
|
scaledPressure =
|
|
((pressure-device.absPressure.minValue)
|
|
/ (float)device.absPressure.range);
|
|
}
|
|
if (device.absSize != null) {
|
|
scaledSize =
|
|
((size-device.absSize.minValue)
|
|
/ (float)device.absSize.range);
|
|
}
|
|
switch (orientation) {
|
|
case Surface.ROTATION_90:
|
|
temp = scaledX;
|
|
scaledX = scaledY;
|
|
scaledY = w-temp;
|
|
break;
|
|
case Surface.ROTATION_180:
|
|
scaledX = w-scaledX;
|
|
scaledY = h-scaledY;
|
|
break;
|
|
case Surface.ROTATION_270:
|
|
temp = scaledX;
|
|
scaledX = h-scaledY;
|
|
scaledY = temp;
|
|
break;
|
|
}
|
|
|
|
if (scaledX == 0) {
|
|
edgeFlags += MotionEvent.EDGE_LEFT;
|
|
} else if (scaledX == display.getWidth() - 1.0f) {
|
|
edgeFlags += MotionEvent.EDGE_RIGHT;
|
|
}
|
|
|
|
if (scaledY == 0) {
|
|
edgeFlags += MotionEvent.EDGE_TOP;
|
|
} else if (scaledY == display.getHeight() - 1.0f) {
|
|
edgeFlags += MotionEvent.EDGE_BOTTOM;
|
|
}
|
|
|
|
} else {
|
|
scaledX *= xMoveScale;
|
|
scaledY *= yMoveScale;
|
|
switch (orientation) {
|
|
case Surface.ROTATION_90:
|
|
temp = scaledX;
|
|
scaledX = scaledY;
|
|
scaledY = -temp;
|
|
break;
|
|
case Surface.ROTATION_180:
|
|
scaledX = -scaledX;
|
|
scaledY = -scaledY;
|
|
break;
|
|
case Surface.ROTATION_270:
|
|
temp = scaledX;
|
|
scaledX = -scaledY;
|
|
scaledY = temp;
|
|
break;
|
|
}
|
|
}
|
|
|
|
changed = false;
|
|
if (down != lastDown) {
|
|
int action;
|
|
lastDown = down;
|
|
if (down) {
|
|
action = MotionEvent.ACTION_DOWN;
|
|
downTime = curTime;
|
|
} else {
|
|
action = MotionEvent.ACTION_UP;
|
|
}
|
|
currentMove = null;
|
|
if (!isAbs) {
|
|
x = y = 0;
|
|
}
|
|
return MotionEvent.obtainNano(downTime, curTime, curTimeNano, action,
|
|
scaledX, scaledY, scaledPressure, scaledSize, metaState,
|
|
xPrecision, yPrecision, device.id, edgeFlags);
|
|
} else {
|
|
if (currentMove != null) {
|
|
if (false) Log.i("InputDevice", "Adding batch x=" + scaledX
|
|
+ " y=" + scaledY + " to " + currentMove);
|
|
currentMove.addBatch(curTime, scaledX, scaledY,
|
|
scaledPressure, scaledSize, metaState);
|
|
if (WindowManagerPolicy.WATCH_POINTER) {
|
|
Log.i("KeyInputQueue", "Updating: " + currentMove);
|
|
}
|
|
return null;
|
|
}
|
|
MotionEvent me = MotionEvent.obtainNano(downTime, curTime, curTimeNano,
|
|
MotionEvent.ACTION_MOVE, scaledX, scaledY,
|
|
scaledPressure, scaledSize, metaState,
|
|
xPrecision, yPrecision, device.id, edgeFlags);
|
|
currentMove = me;
|
|
return me;
|
|
}
|
|
}
|
|
}
|
|
|
|
static class AbsoluteInfo {
|
|
int minValue;
|
|
int maxValue;
|
|
int range;
|
|
int flat;
|
|
int fuzz;
|
|
};
|
|
|
|
InputDevice(int _id, int _classes, String _name,
|
|
AbsoluteInfo _absX, AbsoluteInfo _absY,
|
|
AbsoluteInfo _absPressure, AbsoluteInfo _absSize) {
|
|
id = _id;
|
|
classes = _classes;
|
|
name = _name;
|
|
absX = _absX;
|
|
absY = _absY;
|
|
absPressure = _absPressure;
|
|
absSize = _absSize;
|
|
}
|
|
};
|