Perform hit test before allowing the pointer icon to be set
Since we do not want to allow apps that are not receiving a pointer to
change the pointer icon, do a hit test before setting the pointer icon,
and drop any requests from windows that are not receiving the pointer.
Bug: 293587049
Bug: 266579357
Test: manual with mouse, ensure app can set the pointer icon
Change-Id: Ica0e7a19f4ed4e127b0e51a7a9b1f638dc056a72
diff --git a/services/core/jni/com_android_server_input_InputManagerService.cpp b/services/core/jni/com_android_server_input_InputManagerService.cpp
index 7de50e8..6f65965 100644
--- a/services/core/jni/com_android_server_input_InputManagerService.cpp
+++ b/services/core/jni/com_android_server_input_InputManagerService.cpp
@@ -26,6 +26,7 @@
// Log debug messages about InputDispatcherPolicy
#define DEBUG_INPUT_DISPATCHER_POLICY 0
+#include <android-base/logging.h>
#include <android-base/parseint.h>
#include <android-base/stringprintf.h>
#include <android/os/IInputConstants.h>
@@ -309,7 +310,8 @@
void requestPointerCapture(const sp<IBinder>& windowToken, bool enabled);
void setCustomPointerIcon(const SpriteIcon& icon);
bool setPointerIcon(std::variant<std::unique_ptr<SpriteIcon>, PointerIconStyle> icon,
- int32_t displayId, DeviceId deviceId);
+ int32_t displayId, DeviceId deviceId, int32_t pointerId,
+ const sp<IBinder>& inputToken);
void setMotionClassifierEnabled(bool enabled);
std::optional<std::string> getBluetoothAddress(int32_t deviceId);
void setStylusButtonMotionEventsEnabled(bool enabled);
@@ -1351,7 +1353,15 @@
bool NativeInputManager::setPointerIcon(
std::variant<std::unique_ptr<SpriteIcon>, PointerIconStyle> icon, int32_t displayId,
- DeviceId deviceId) {
+ DeviceId deviceId, int32_t pointerId, const sp<IBinder>& inputToken) {
+ if (!mInputManager->getDispatcher().isPointerInWindow(inputToken, displayId, deviceId,
+ pointerId)) {
+ LOG(WARNING) << "Attempted to change the pointer icon for deviceId " << deviceId
+ << " on display " << displayId << " from input token " << inputToken.get()
+ << ", but the pointer is not in the window.";
+ return false;
+ }
+
return mInputManager->getChoreographer().setPointerIcon(std::move(icon), displayId, deviceId);
}
@@ -2540,10 +2550,9 @@
} else {
icon = pointerIcon.style;
}
- // TODO(b/293587049): Perform hit test to ensure the pointer is dispatched to the channel.
- sp<IBinder> inputToken = ibinderForJavaObject(env, inputTokenObj);
- return im->setPointerIcon(std::move(icon), displayId, deviceId);
+ return im->setPointerIcon(std::move(icon), displayId, deviceId, pointerId,
+ ibinderForJavaObject(env, inputTokenObj));
}
static jboolean nativeCanDispatchToDisplay(JNIEnv* env, jobject nativeImplObj, jint deviceId,