Add pointer capture eligibility native APIs

Bug: 202273865
Test: manual
Change-Id: I98a31f4cae1a12f45f789cb1344a258e3de30317
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp
index 3f3c0db..441a1de 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.cpp
+++ b/services/inputflinger/dispatcher/InputDispatcher.cpp
@@ -5645,6 +5645,15 @@
             return;
         }
 
+        if (enabled) {
+            if (std::find(mIneligibleDisplaysForPointerCapture.begin(),
+                          mIneligibleDisplaysForPointerCapture.end(),
+                          mFocusedDisplayId) != mIneligibleDisplaysForPointerCapture.end()) {
+                ALOGW("Ignoring request to enable Pointer Capture: display is not eligible");
+                return;
+            }
+        }
+
         setPointerCaptureLocked(enabled);
     } // release lock
 
@@ -5652,6 +5661,16 @@
     mLooper->wake();
 }
 
+void InputDispatcher::setDisplayEligibilityForPointerCapture(int32_t displayId, bool isEligible) {
+    { // acquire lock
+        std::scoped_lock _l(mLock);
+        std::erase(mIneligibleDisplaysForPointerCapture, displayId);
+        if (!isEligible) {
+            mIneligibleDisplaysForPointerCapture.push_back(displayId);
+        }
+    } // release lock
+}
+
 std::optional<int32_t> InputDispatcher::findGestureMonitorDisplayByTokenLocked(
         const sp<IBinder>& token) {
     for (const auto& it : mGestureMonitorsByDisplay) {
@@ -6311,6 +6330,8 @@
         // Call focus resolver to clean up stale requests. This must be called after input windows
         // have been removed for the removed display.
         mFocusResolver.displayRemoved(displayId);
+        // Reset pointer capture eligibility, regardless of previous state.
+        std::erase(mIneligibleDisplaysForPointerCapture, displayId);
     } // release lock
 
     // Wake up poll loop since it may need to make new input dispatching choices.