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;
     }