Add support for drawing drop shadow for PointerIcons in native code.
Bug: 305193969
Test: Manual
Flag: ACONFIG com.android.systemui.enable_vector_cursors DEVELOPMENT
Change-Id: Id19c11ccc4b528afdad19f6b68b36411108853c4
diff --git a/core/jni/android_view_PointerIcon.cpp b/core/jni/android_view_PointerIcon.cpp
index c6a3b52..86b0009 100644
--- a/core/jni/android_view_PointerIcon.cpp
+++ b/core/jni/android_view_PointerIcon.cpp
@@ -37,6 +37,7 @@
jfieldID mHotSpotY;
jfieldID mBitmapFrames;
jfieldID mDurationPerFrame;
+ jfieldID mDrawNativeDropShadow;
} gPointerIconClassInfo;
@@ -51,6 +52,8 @@
env->GetIntField(pointerIconObj, gPointerIconClassInfo.mType));
icon.hotSpotX = env->GetFloatField(pointerIconObj, gPointerIconClassInfo.mHotSpotX);
icon.hotSpotY = env->GetFloatField(pointerIconObj, gPointerIconClassInfo.mHotSpotY);
+ icon.drawNativeDropShadow =
+ env->GetBooleanField(pointerIconObj, gPointerIconClassInfo.mDrawNativeDropShadow);
ScopedLocalRef<jobject> bitmapObj(
env, env->GetObjectField(pointerIconObj, gPointerIconClassInfo.mBitmap));
@@ -95,6 +98,9 @@
gPointerIconClassInfo.mBitmapFrames = GetFieldIDOrDie(env, gPointerIconClassInfo.clazz,
"mBitmapFrames", "[Landroid/graphics/Bitmap;");
+ gPointerIconClassInfo.mDrawNativeDropShadow =
+ GetFieldIDOrDie(env, gPointerIconClassInfo.clazz, "mDrawNativeDropShadow", "Z");
+
gPointerIconClassInfo.mDurationPerFrame = GetFieldIDOrDie(env, gPointerIconClassInfo.clazz,
"mDurationPerFrame", "I");
diff --git a/core/jni/android_view_PointerIcon.h b/core/jni/android_view_PointerIcon.h
index ee446fb..1b6a397 100644
--- a/core/jni/android_view_PointerIcon.h
+++ b/core/jni/android_view_PointerIcon.h
@@ -39,6 +39,7 @@
float hotSpotY;
std::vector<graphics::Bitmap> bitmapFrames;
int32_t durationPerFrame;
+ bool drawNativeDropShadow;
inline bool isNullIcon() { return style == PointerIconStyle::TYPE_NULL; }
@@ -49,6 +50,7 @@
hotSpotY = 0;
bitmapFrames.clear();
durationPerFrame = 0;
+ drawNativeDropShadow = false;
}
};
diff --git a/libs/input/SpriteIcon.cpp b/libs/input/SpriteIcon.cpp
index b7e51e2..59e36e4 100644
--- a/libs/input/SpriteIcon.cpp
+++ b/libs/input/SpriteIcon.cpp
@@ -34,6 +34,9 @@
graphics::Paint paint;
paint.setBlendMode(ABLEND_MODE_SRC);
+ if (drawNativeDropShadow) {
+ paint.setImageFilter(AIMAGE_FILTER_DROP_SHADOW_FOR_POINTER_ICON);
+ }
graphics::Canvas canvas(outBuffer, (int32_t)surface->getBuffersDataSpace());
canvas.drawBitmap(bitmap, 0, 0, &paint);
diff --git a/libs/input/SpriteIcon.h b/libs/input/SpriteIcon.h
index 5f085bb..9e6cc81 100644
--- a/libs/input/SpriteIcon.h
+++ b/libs/input/SpriteIcon.h
@@ -29,16 +29,22 @@
struct SpriteIcon {
inline SpriteIcon() : style(PointerIconStyle::TYPE_NULL), hotSpotX(0), hotSpotY(0) {}
inline SpriteIcon(const graphics::Bitmap& bitmap, PointerIconStyle style, float hotSpotX,
- float hotSpotY)
- : bitmap(bitmap), style(style), hotSpotX(hotSpotX), hotSpotY(hotSpotY) {}
+ float hotSpotY, bool drawNativeDropShadow)
+ : bitmap(bitmap),
+ style(style),
+ hotSpotX(hotSpotX),
+ hotSpotY(hotSpotY),
+ drawNativeDropShadow(drawNativeDropShadow) {}
graphics::Bitmap bitmap;
PointerIconStyle style;
float hotSpotX;
float hotSpotY;
+ bool drawNativeDropShadow;
inline SpriteIcon copy() const {
- return SpriteIcon(bitmap.copy(ANDROID_BITMAP_FORMAT_RGBA_8888), style, hotSpotX, hotSpotY);
+ return SpriteIcon(bitmap.copy(ANDROID_BITMAP_FORMAT_RGBA_8888), style, hotSpotX, hotSpotY,
+ drawNativeDropShadow);
}
inline void reset() {
@@ -46,6 +52,7 @@
style = PointerIconStyle::TYPE_NULL;
hotSpotX = 0;
hotSpotY = 0;
+ drawNativeDropShadow = false;
}
inline bool isValid() const { return bitmap.isValid() && !bitmap.isEmpty(); }
diff --git a/services/core/jni/com_android_server_input_InputManagerService.cpp b/services/core/jni/com_android_server_input_InputManagerService.cpp
index cbc301b..34f9efe 100644
--- a/services/core/jni/com_android_server_input_InputManagerService.cpp
+++ b/services/core/jni/com_android_server_input_InputManagerService.cpp
@@ -238,7 +238,7 @@
// to the underlying bitmap, so even if the java object is released, we will still have access
// to it.
return SpriteIcon(pointerIcon.bitmap, pointerIcon.style, pointerIcon.hotSpotX,
- pointerIcon.hotSpotY);
+ pointerIcon.hotSpotY, pointerIcon.drawNativeDropShadow);
}
enum {
@@ -1733,13 +1733,14 @@
animationData.durationPerFrame =
milliseconds_to_nanoseconds(pointerIcon.durationPerFrame);
animationData.animationFrames.reserve(numFrames);
- animationData.animationFrames.push_back(SpriteIcon(
- pointerIcon.bitmap, pointerIcon.style,
- pointerIcon.hotSpotX, pointerIcon.hotSpotY));
+ animationData.animationFrames.emplace_back(pointerIcon.bitmap, pointerIcon.style,
+ pointerIcon.hotSpotX, pointerIcon.hotSpotY,
+ pointerIcon.drawNativeDropShadow);
for (size_t i = 0; i < numFrames - 1; ++i) {
- animationData.animationFrames.push_back(SpriteIcon(
- pointerIcon.bitmapFrames[i], pointerIcon.style,
- pointerIcon.hotSpotX, pointerIcon.hotSpotY));
+ animationData.animationFrames.emplace_back(pointerIcon.bitmapFrames[i],
+ pointerIcon.style, pointerIcon.hotSpotX,
+ pointerIcon.hotSpotY,
+ pointerIcon.drawNativeDropShadow);
}
}
}
@@ -2570,7 +2571,7 @@
icon = std::make_unique<SpriteIcon>(pointerIcon.bitmap.copy(
ANDROID_BITMAP_FORMAT_RGBA_8888),
pointerIcon.style, pointerIcon.hotSpotX,
- pointerIcon.hotSpotY);
+ pointerIcon.hotSpotY, pointerIcon.drawNativeDropShadow);
} else {
icon = pointerIcon.style;
}