summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/com/android/internal/widget/PointerLocationView.java175
1 files changed, 89 insertions, 86 deletions
diff --git a/core/java/com/android/internal/widget/PointerLocationView.java b/core/java/com/android/internal/widget/PointerLocationView.java
index e65b4b65945f..c0a7383c9f06 100644
--- a/core/java/com/android/internal/widget/PointerLocationView.java
+++ b/core/java/com/android/internal/widget/PointerLocationView.java
@@ -16,14 +16,19 @@
package com.android.internal.widget;
+import static java.lang.Float.NaN;
+
import android.compat.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.content.res.Configuration;
+import android.graphics.Bitmap;
import android.graphics.Canvas;
+import android.graphics.Color;
import android.graphics.Insets;
import android.graphics.Paint;
import android.graphics.Paint.FontMetricsInt;
import android.graphics.Path;
+import android.graphics.PorterDuff;
import android.graphics.RectF;
import android.graphics.Region;
import android.hardware.input.InputManager;
@@ -65,11 +70,14 @@ public class PointerLocationView extends View implements InputDeviceListener,
private static final PointerState EMPTY_POINTER_STATE = new PointerState();
public static class PointerState {
- // Trace of previous points.
- private float[] mTraceX = new float[32];
- private float[] mTraceY = new float[32];
- private boolean[] mTraceCurrent = new boolean[32];
- private int mTraceCount;
+ private float mCurrentX = NaN;
+ private float mCurrentY = NaN;
+ private float mPreviousX = NaN;
+ private float mPreviousY = NaN;
+ private float mFirstX = NaN;
+ private float mFirstY = NaN;
+ private boolean mPreviousPointIsHistorical;
+ private boolean mCurrentPointIsHistorical;
// True if the pointer is down.
@UnsupportedAppUsage
@@ -96,31 +104,20 @@ public class PointerLocationView extends View implements InputDeviceListener,
public PointerState() {
}
- public void clearTrace() {
- mTraceCount = 0;
- }
-
- public void addTrace(float x, float y, boolean current) {
- 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;
-
- boolean[] newTraceCurrent = new boolean[traceCapacity];
- System.arraycopy(mTraceCurrent, 0, newTraceCurrent, 0, mTraceCount);
- mTraceCurrent= newTraceCurrent;
+ public void addTrace(float x, float y, boolean isHistorical) {
+ if (Float.isNaN(mFirstX)) {
+ mFirstX = x;
+ }
+ if (Float.isNaN(mFirstY)) {
+ mFirstY = y;
}
- mTraceX[mTraceCount] = x;
- mTraceY[mTraceCount] = y;
- mTraceCurrent[mTraceCount] = current;
- mTraceCount += 1;
+ mPreviousX = mCurrentX;
+ mPreviousY = mCurrentY;
+ mCurrentX = x;
+ mCurrentY = y;
+ mPreviousPointIsHistorical = mCurrentPointIsHistorical;
+ mCurrentPointIsHistorical = isHistorical;
}
}
@@ -149,6 +146,12 @@ public class PointerLocationView extends View implements InputDeviceListener,
private final SparseArray<PointerState> mPointers = new SparseArray<PointerState>();
private final PointerCoords mTempCoords = new PointerCoords();
+ // Draw the trace of all pointers in the current gesture in a separate layer
+ // that is not cleared on every frame so that we don't have to re-draw the
+ // entire trace on each frame.
+ private final Bitmap mTraceBitmap;
+ private final Canvas mTraceCanvas;
+
private final Region mSystemGestureExclusion = new Region();
private final Region mSystemGestureExclusionRejected = new Region();
private final Path mSystemGestureExclusionPath = new Path();
@@ -197,6 +200,10 @@ public class PointerLocationView extends View implements InputDeviceListener,
mPathPaint.setARGB(255, 0, 96, 255);
mPathPaint.setStyle(Paint.Style.STROKE);
+ mTraceBitmap = Bitmap.createBitmap(getResources().getDisplayMetrics().widthPixels,
+ getResources().getDisplayMetrics().heightPixels, Bitmap.Config.ARGB_8888);
+ mTraceCanvas = new Canvas(mTraceBitmap);
+
configureDensityDependentFactors();
mSystemGestureExclusionPaint = new Paint();
@@ -256,7 +263,7 @@ public class PointerLocationView extends View implements InputDeviceListener,
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
mTextPaint.getFontMetricsInt(mTextMetrics);
- mHeaderBottom = mHeaderPaddingTop-mTextMetrics.ascent+mTextMetrics.descent+2;
+ mHeaderBottom = mHeaderPaddingTop - mTextMetrics.ascent + mTextMetrics.descent + 2;
if (false) {
Log.i("foo", "Metrics: ascent=" + mTextMetrics.ascent
+ " descent=" + mTextMetrics.descent
@@ -269,6 +276,7 @@ public class PointerLocationView extends View implements InputDeviceListener,
// 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);
@@ -285,6 +293,8 @@ public class PointerLocationView extends View implements InputDeviceListener,
protected void onDraw(Canvas canvas) {
final int NP = mPointers.size();
+ canvas.drawBitmap(mTraceBitmap, 0, 0, null);
+
if (!mSystemGestureExclusion.isEmpty()) {
mSystemGestureExclusionPath.reset();
mSystemGestureExclusion.getBoundaryPath(mSystemGestureExclusionPath);
@@ -303,32 +313,9 @@ public class PointerLocationView extends View implements InputDeviceListener,
// Pointer trace.
for (int p = 0; p < NP; p++) {
final PointerState ps = mPointers.valueAt(p);
+ float lastX = ps.mCurrentX, lastY = ps.mCurrentY;
- // 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.mTraceX[i];
- float y = ps.mTraceY[i];
- if (Float.isNaN(x) || Float.isNaN(y)) {
- haveLast = false;
- continue;
- }
- if (haveLast) {
- canvas.drawLine(lastX, lastY, x, y, mPathPaint);
- final Paint paint = ps.mTraceCurrent[i - 1] ? mCurrentPointPaint : mPaint;
- canvas.drawPoint(lastX, lastY, paint);
- drawn = true;
- }
- lastX = x;
- lastY = y;
- haveLast = true;
- }
-
- if (drawn) {
+ if (!Float.isNaN(lastX) && !Float.isNaN(lastY)) {
// Draw velocity vector.
mPaint.setARGB(255, 255, 64, 128);
float xVel = ps.mXVelocity * (1000 / 60);
@@ -353,7 +340,7 @@ public class PointerLocationView extends View implements InputDeviceListener,
Math.max(getHeight(), getWidth()), mTargetPaint);
// Draw current point.
- int pressureLevel = (int)(ps.mCoords.pressure * 255);
+ int pressureLevel = (int) (ps.mCoords.pressure * 255);
mPaint.setARGB(255, pressureLevel, 255, 255 - pressureLevel);
canvas.drawPoint(ps.mCoords.x, ps.mCoords.y, mPaint);
@@ -424,8 +411,7 @@ public class PointerLocationView extends View implements InputDeviceListener,
.append(" / ").append(mMaxNumPointers)
.toString(), 1, base, mTextPaint);
- final int count = ps.mTraceCount;
- if ((mCurDown && ps.mCurDown) || count == 0) {
+ if ((mCurDown && ps.mCurDown) || Float.isNaN(ps.mCurrentX)) {
canvas.drawRect(itemW, mHeaderPaddingTop, (itemW * 2) - 1, bottom,
mTextBackgroundPaint);
canvas.drawText(mText.clear()
@@ -437,8 +423,8 @@ public class PointerLocationView extends View implements InputDeviceListener,
.append("Y: ").append(ps.mCoords.y, 1)
.toString(), 1 + itemW * 2, base, mTextPaint);
} else {
- float dx = ps.mTraceX[count - 1] - ps.mTraceX[0];
- float dy = ps.mTraceY[count - 1] - ps.mTraceY[0];
+ float dx = ps.mCurrentX - ps.mFirstX;
+ float dy = ps.mCurrentY - ps.mFirstY;
canvas.drawRect(itemW, mHeaderPaddingTop, (itemW * 2) - 1, bottom,
Math.abs(dx) < mVC.getScaledTouchSlop()
? mTextBackgroundPaint : mTextLevelPaint);
@@ -565,9 +551,9 @@ public class PointerLocationView extends View implements InputDeviceListener,
.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(" Orientation=").append((float) (coords.orientation * 180 / Math.PI), 1)
.append("deg")
- .append(" Tilt=").append((float)(
+ .append(" Tilt=").append((float) (
coords.getAxisValue(MotionEvent.AXIS_TILT) * 180 / Math.PI), 1)
.append("deg")
.append(" Distance=").append(coords.getAxisValue(MotionEvent.AXIS_DISTANCE), 1)
@@ -598,6 +584,7 @@ public class PointerLocationView extends View implements InputDeviceListener,
mCurNumPointers = 0;
mMaxNumPointers = 0;
mVelocity.clear();
+ mTraceCanvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
if (mAltVelocity != null) {
mAltVelocity.clear();
}
@@ -646,7 +633,8 @@ public class PointerLocationView extends View implements InputDeviceListener,
logCoords("Pointer", action, i, coords, id, event);
}
if (ps != null) {
- ps.addTrace(coords.x, coords.y, false);
+ ps.addTrace(coords.x, coords.y, true);
+ updateDrawTrace(ps);
}
}
}
@@ -659,7 +647,8 @@ public class PointerLocationView extends View implements InputDeviceListener,
logCoords("Pointer", action, i, coords, id, event);
}
if (ps != null) {
- ps.addTrace(coords.x, coords.y, true);
+ ps.addTrace(coords.x, coords.y, false);
+ updateDrawTrace(ps);
ps.mXVelocity = mVelocity.getXVelocity(id);
ps.mYVelocity = mVelocity.getYVelocity(id);
if (mAltVelocity != null) {
@@ -702,13 +691,26 @@ public class PointerLocationView extends View implements InputDeviceListener,
if (mActivePointerId == id) {
mActivePointerId = event.getPointerId(index == 0 ? 1 : 0);
}
- ps.addTrace(Float.NaN, Float.NaN, false);
+ ps.addTrace(Float.NaN, Float.NaN, true);
}
}
invalidate();
}
+ private void updateDrawTrace(PointerState ps) {
+ mPaint.setARGB(255, 128, 255, 255);
+ float x = ps.mCurrentX;
+ float y = ps.mCurrentY;
+ float lastX = ps.mPreviousX;
+ float lastY = ps.mPreviousY;
+ if (!Float.isNaN(x) && !Float.isNaN(y) && !Float.isNaN(lastX) && !Float.isNaN(lastY)) {
+ mTraceCanvas.drawLine(lastX, lastY, x, y, mPathPaint);
+ Paint paint = ps.mPreviousPointIsHistorical ? mPaint : mCurrentPointPaint;
+ mTraceCanvas.drawPoint(lastX, lastY, paint);
+ }
+ }
+
@Override
public boolean onTouchEvent(MotionEvent event) {
onPointerEvent(event);
@@ -767,7 +769,7 @@ public class PointerLocationView extends View implements InputDeviceListener,
return true;
default:
return KeyEvent.isGamepadButton(keyCode)
- || KeyEvent.isModifierKey(keyCode);
+ || KeyEvent.isModifierKey(keyCode);
}
}
@@ -887,7 +889,7 @@ public class PointerLocationView extends View implements InputDeviceListener,
public FasterStringBuilder append(int value, int zeroPadWidth) {
final boolean negative = value < 0;
if (negative) {
- value = - value;
+ value = -value;
if (value < 0) {
append("-2147483648");
return this;
@@ -973,26 +975,27 @@ public class PointerLocationView extends View implements InputDeviceListener,
private ISystemGestureExclusionListener mSystemGestureExclusionListener =
new ISystemGestureExclusionListener.Stub() {
- @Override
- public void onSystemGestureExclusionChanged(int displayId, Region systemGestureExclusion,
- Region systemGestureExclusionUnrestricted) {
- Region exclusion = Region.obtain(systemGestureExclusion);
- Region rejected = Region.obtain();
- if (systemGestureExclusionUnrestricted != null) {
- rejected.set(systemGestureExclusionUnrestricted);
- rejected.op(exclusion, Region.Op.DIFFERENCE);
- }
- Handler handler = getHandler();
- if (handler != null) {
- handler.post(() -> {
- mSystemGestureExclusion.set(exclusion);
- mSystemGestureExclusionRejected.set(rejected);
- exclusion.recycle();
- invalidate();
- });
- }
- }
- };
+ @Override
+ public void onSystemGestureExclusionChanged(int displayId,
+ Region systemGestureExclusion,
+ Region systemGestureExclusionUnrestricted) {
+ Region exclusion = Region.obtain(systemGestureExclusion);
+ Region rejected = Region.obtain();
+ if (systemGestureExclusionUnrestricted != null) {
+ rejected.set(systemGestureExclusionUnrestricted);
+ rejected.op(exclusion, Region.Op.DIFFERENCE);
+ }
+ Handler handler = getHandler();
+ if (handler != null) {
+ handler.post(() -> {
+ mSystemGestureExclusion.set(exclusion);
+ mSystemGestureExclusionRejected.set(rejected);
+ exclusion.recycle();
+ invalidate();
+ });
+ }
+ }
+ };
@Override
protected void onConfigurationChanged(Configuration newConfig) {