Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save robertkirkman/21ae17b3aa0e1b48ca67864f7cb0c158 to your computer and use it in GitHub Desktop.
Save robertkirkman/21ae17b3aa0e1b48ca67864f7cb0c158 to your computer and use it in GitHub Desktop.
"Show taps" cosmetic skin for the "Pointer location" Android 14 developer mode widget
diff --git a/core/java/com/android/internal/widget/PointerLocationView.java b/core/java/com/android/internal/widget/PointerLocationView.java
index e65b4b65..6e6a9517 100644
--- a/core/java/com/android/internal/widget/PointerLocationView.java
+++ b/core/java/com/android/internal/widget/PointerLocationView.java
@@ -18,7 +18,10 @@ package com.android.internal.widget;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.Context;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
import android.content.res.Configuration;
+import android.content.res.XmlResourceParser;
import android.graphics.Canvas;
import android.graphics.Insets;
import android.graphics.Paint;
@@ -26,6 +29,8 @@ import android.graphics.Paint.FontMetricsInt;
import android.graphics.Path;
import android.graphics.RectF;
import android.graphics.Region;
+import android.graphics.drawable.AnimationDrawable;
+import android.graphics.drawable.Drawable;
import android.hardware.input.InputManager;
import android.hardware.input.InputManager.InputDeviceListener;
import android.os.Handler;
@@ -47,6 +52,9 @@ import android.view.WindowInsets;
import android.view.WindowManagerGlobal;
import android.view.WindowManagerPolicyConstants.PointerEventListener;
+import com.android.internal.R;
+import com.android.internal.util.XmlUtils;
+
public class PointerLocationView extends View implements InputDeviceListener,
PointerEventListener {
private static final String TAG = "Pointer";
@@ -165,6 +173,10 @@ public class PointerLocationView extends View implements InputDeviceListener,
private float mDensity;
+ private Drawable mPointerTexture;
+ private int mPointerRadius;
+ private boolean mShowPointerLocationIsShowTapsClone = true;
+
public PointerLocationView(Context c) {
super(c);
setFocusableInTouchMode(true);
@@ -218,6 +230,40 @@ public class PointerLocationView extends View implements InputDeviceListener,
} else {
mAltVelocity = null;
}
+
+ // This code is based on getSystemIcon() and loadResource() from frameworks/base/core/java/android/view/PointerIcon.java,
+ // which is the boilerplate that spawns the desirable dot-shaped cursor texture used by the "Show Taps" mode.
+ final TypedArray pointerStyledAttributes = c.obtainStyledAttributes(null, R.styleable.Pointer, 0, R.style.Pointer);
+ final int resourceId = pointerStyledAttributes.getResourceId(R.styleable.Pointer_pointerIconSpotTouch, -1);
+ pointerStyledAttributes.recycle();
+ if (resourceId == -1) {
+ Log.w(TAG, "Missing theme resources for pointer icon TYPE_SPOT_TOUCH");
+ mShowPointerLocationIsShowTapsClone = false;
+ }
+ final Resources resources = c.getResources();
+ final XmlResourceParser parser = resources.getXml(resourceId);
+ int bitmapRes = 0;
+ try {
+ XmlUtils.beginDocument(parser, "pointer-icon");
+ final TypedArray pointerIconAttributes = resources.obtainAttributes(parser, R.styleable.PointerIcon);
+ bitmapRes = pointerIconAttributes.getResourceId(R.styleable.PointerIcon_bitmap, 0);
+ pointerIconAttributes.recycle();
+ } catch (Exception ex) {
+ Log.w(TAG, "Exception parsing pointer icon resource.");
+ mShowPointerLocationIsShowTapsClone = false;
+ } finally {
+ parser.close();
+ }
+ if (bitmapRes == 0) {
+ Log.w(TAG, "<pointer-icon> is missing bitmap attribute.");
+ mShowPointerLocationIsShowTapsClone = false;
+ }
+ mPointerTexture = c.getDrawable(bitmapRes);
+ if (mPointerTexture instanceof AnimationDrawable) {
+ final AnimationDrawable animationDrawable = (AnimationDrawable)mPointerTexture;
+ mPointerTexture = animationDrawable.getFrame(0);
+ }
+ mPointerRadius = mPointerTexture.getIntrinsicWidth() / 2;
}
public void setPrintCoords(boolean state) {
@@ -285,6 +331,24 @@ public class PointerLocationView extends View implements InputDeviceListener,
protected void onDraw(Canvas canvas) {
final int NP = mPointers.size();
+ if (mShowPointerLocationIsShowTapsClone) {
+ // draw the same texture that is used by the "Show Taps" mode
+ for (int p = 0; p < NP; p++) {
+ final PointerState ps = mPointers.valueAt(p);
+ if (mCurDown && ps.mCurDown) {
+ mPointerTexture.setBounds((int)ps.mCoords.x - mPointerRadius,
+ (int)ps.mCoords.y - mPointerRadius,
+ (int)ps.mCoords.x + mPointerRadius,
+ (int)ps.mCoords.y + mPointerRadius);
+ mPointerTexture.draw(canvas);
+ }
+ }
+ // finish frame for this view without rendering any of the undesired lines
+ return;
+ }
+
+ // below this point is the original renderer for the "Show Pointer Location" mode
+
if (!mSystemGestureExclusion.isEmpty()) {
mSystemGestureExclusionPath.reset();
mSystemGestureExclusion.getBoundaryPath(mSystemGestureExclusionPath);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment