SyncPointerCapture (3/n): Add Capture event to InputChannel

This CL adds the ability to send a CAPTURE event through the
InputChannel, and adds the appropriate processing logic to
InputPublisher and InputConsumer.

This will be used by the InputDispatcher to notify windows when they
have either lost or gained Pointer Capture.

Bug: 141749603
Test: atest libinput_tests
Change-Id: I102833e6f0fd1e8e9c4b3c12e7a5a737eeda2377
diff --git a/libs/input/InputTransport.cpp b/libs/input/InputTransport.cpp
index 85df405..acea473 100644
--- a/libs/input/InputTransport.cpp
+++ b/libs/input/InputTransport.cpp
@@ -105,6 +105,8 @@
                 return true;
             case Type::FOCUS:
                 return true;
+            case Type::CAPTURE:
+                return true;
         }
     }
     return false;
@@ -120,6 +122,8 @@
             return sizeof(Header) + body.finished.size();
         case Type::FOCUS:
             return sizeof(Header) + body.focus.size();
+        case Type::CAPTURE:
+            return sizeof(Header) + body.capture.size();
     }
     return sizeof(Header);
 }
@@ -238,6 +242,11 @@
             msg->body.focus.inTouchMode = body.focus.inTouchMode;
             break;
         }
+        case InputMessage::Type::CAPTURE: {
+            msg->body.capture.eventId = body.capture.eventId;
+            msg->body.capture.pointerCaptureEnabled = body.capture.pointerCaptureEnabled;
+            break;
+        }
     }
 }
 
@@ -571,6 +580,23 @@
     return mChannel->sendMessage(&msg);
 }
 
+status_t InputPublisher::publishCaptureEvent(uint32_t seq, int32_t eventId,
+                                             bool pointerCaptureEnabled) {
+    if (ATRACE_ENABLED()) {
+        std::string message =
+                StringPrintf("publishCaptureEvent(inputChannel=%s, pointerCaptureEnabled=%s)",
+                             mChannel->getName().c_str(), toString(pointerCaptureEnabled));
+        ATRACE_NAME(message.c_str());
+    }
+
+    InputMessage msg;
+    msg.header.type = InputMessage::Type::CAPTURE;
+    msg.header.seq = seq;
+    msg.body.capture.eventId = eventId;
+    msg.body.capture.pointerCaptureEnabled = pointerCaptureEnabled ? 1 : 0;
+    return mChannel->sendMessage(&msg);
+}
+
 status_t InputPublisher::receiveFinishedSignal(uint32_t* outSeq, bool* outHandled) {
     if (DEBUG_TRANSPORT_ACTIONS) {
         ALOGD("channel '%s' publisher ~ receiveFinishedSignal", mChannel->getName().c_str());
@@ -739,6 +765,16 @@
                 *outEvent = focusEvent;
                 break;
             }
+
+            case InputMessage::Type::CAPTURE: {
+                CaptureEvent* captureEvent = factory->createCaptureEvent();
+                if (!captureEvent) return NO_MEMORY;
+
+                initializeCaptureEvent(captureEvent, &mMsg);
+                *outSeq = mMsg.header.seq;
+                *outEvent = captureEvent;
+                break;
+            }
         }
     }
     return OK;
@@ -1171,6 +1207,10 @@
                       msg->body.focus.inTouchMode == 1);
 }
 
+void InputConsumer::initializeCaptureEvent(CaptureEvent* event, const InputMessage* msg) {
+    event->initialize(msg->body.capture.eventId, msg->body.capture.pointerCaptureEnabled == 1);
+}
+
 void InputConsumer::initializeMotionEvent(MotionEvent* event, const InputMessage* msg) {
     uint32_t pointerCount = msg->body.motion.pointerCount;
     PointerProperties pointerProperties[pointerCount];
@@ -1274,6 +1314,12 @@
                                                        toString(msg.body.focus.inTouchMode));
                     break;
                 }
+                case InputMessage::Type::CAPTURE: {
+                    out += android::base::StringPrintf("hasCapture=%s",
+                                                       toString(msg.body.capture
+                                                                        .pointerCaptureEnabled));
+                    break;
+                }
             }
             out += "\n";
         }