Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ff5bf879 authored by Prabir Pradhan's avatar Prabir Pradhan Committed by Android Build Cherrypicker Worker
Browse files

PointerIcon: Add leniency to hotspot validation for scaled icons

When icons are loaded for the current display density, the icon bitmap
is always scaled to an integer pixel size, but the hotspot can be scaled
more precisely using floats. To account for the difference in precision,
add leniency to the hotspot validation checks when the icons are scaled.

Bug: 332973446
Test: adb shell wm density 142
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:f3c4cd5db78b2082eba3b3029d69302783d65e3d)
Merged-In: I4af5d6619aa7f5245054047ad079694b11919754
Change-Id: I4af5d6619aa7f5245054047ad079694b11919754
parent d7a24e9a
Loading
Loading
Loading
Loading
+12 −5
Original line number Diff line number Diff line
@@ -284,7 +284,7 @@ public final class PointerIcon implements Parcelable {
        if (bitmap == null) {
            throw new IllegalArgumentException("bitmap must not be null");
        }
        validateHotSpot(bitmap, hotSpotX, hotSpotY);
        validateHotSpot(bitmap, hotSpotX, hotSpotY, false /* isScaled */);

        PointerIcon icon = new PointerIcon(TYPE_CUSTOM);
        icon.mBitmap = bitmap;
@@ -517,7 +517,9 @@ public final class PointerIcon implements Parcelable {

        BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
        final Bitmap bitmap = getBitmapFromDrawable(bitmapDrawable);
        validateHotSpot(bitmap, hotSpotX, hotSpotY);
        // The bitmap and hotspot are loaded from the context, which means it is implicitly scaled
        // to the current display density, so treat this as a scaled icon when verifying hotspot.
        validateHotSpot(bitmap, hotSpotX, hotSpotY, true /* isScaled */);
        // Set the properties now that we have successfully loaded the icon.
        mBitmap = bitmap;
        mHotSpotX = hotSpotX;
@@ -531,11 +533,16 @@ public final class PointerIcon implements Parcelable {
                + ", hotspotX=" + mHotSpotX + ", hotspotY=" + mHotSpotY + "}";
    }

    private static void validateHotSpot(Bitmap bitmap, float hotSpotX, float hotSpotY) {
        if (hotSpotX < 0 || hotSpotX >= bitmap.getWidth()) {
    private static void validateHotSpot(Bitmap bitmap, float hotSpotX, float hotSpotY,
            boolean isScaled) {
        // Be more lenient when checking the hotspot for scaled icons to account for the restriction
        // that bitmaps must have an integer size.
        if (hotSpotX < 0 || (isScaled ? (int) hotSpotX > bitmap.getWidth()
                : hotSpotX >= bitmap.getWidth())) {
            throw new IllegalArgumentException("x hotspot lies outside of the bitmap area");
        }
        if (hotSpotY < 0 || hotSpotY >= bitmap.getHeight()) {
        if (hotSpotY < 0 || (isScaled ? (int) hotSpotY > bitmap.getHeight()
                : hotSpotY >= bitmap.getHeight())) {
            throw new IllegalArgumentException("y hotspot lies outside of the bitmap area");
        }
    }