Support mouse pointer on external displays (2/3)

Limit mouse boundary to one display viewport.
Currently if desktop mode is enable, selects the topmost freeform display,
or find first external display if there is no freeform display.
Return the default display if desktop mode is not enable.

- Add getPointerDisplayId to find the preferred display.
- Limit update viewports from InputReader. Also implements updatePointerDisplay
  to find and associate with the specified display viewport.
- Reload cursor resources if resolution or display changed.

Bug: 113559891
Test: atest inputfliger_tests
Test: ActivityView test app
Change-Id: Ief3410a517be457dfe6f1180342bb1dc88833635
diff --git a/libs/input/SpriteController.cpp b/libs/input/SpriteController.cpp
index eb2bc98..c1868d3 100644
--- a/libs/input/SpriteController.cpp
+++ b/libs/input/SpriteController.cpp
@@ -144,13 +144,16 @@
         }
     }
 
-    // Resize sprites if needed.
+    // Resize and/or reparent sprites if needed.
     SurfaceComposerClient::Transaction t;
     bool needApplyTransaction = false;
     for (size_t i = 0; i < numSprites; i++) {
         SpriteUpdate& update = updates.editItemAt(i);
+        if (update.state.surfaceControl == nullptr) {
+            continue;
+        }
 
-        if (update.state.surfaceControl != NULL && update.state.wantSurfaceVisible()) {
+        if (update.state.wantSurfaceVisible()) {
             int32_t desiredWidth = update.state.icon.bitmap.width();
             int32_t desiredHeight = update.state.icon.bitmap.height();
             if (update.state.surfaceWidth < desiredWidth
@@ -170,6 +173,12 @@
                 }
             }
         }
+
+        // If surface is a new one, we have to set right layer stack.
+        if (update.surfaceChanged || update.state.dirty & DIRTY_DISPLAY_ID) {
+            t.setLayerStack(update.state.surfaceControl, update.state.displayId);
+            needApplyTransaction = true;
+        }
     }
     if (needApplyTransaction) {
         t.apply();
@@ -236,7 +245,7 @@
         if (update.state.surfaceControl != NULL && (becomingVisible || becomingHidden
                 || (wantSurfaceVisibleAndDrawn && (update.state.dirty & (DIRTY_ALPHA
                         | DIRTY_POSITION | DIRTY_TRANSFORMATION_MATRIX | DIRTY_LAYER
-                        | DIRTY_VISIBILITY | DIRTY_HOTSPOT))))) {
+                        | DIRTY_VISIBILITY | DIRTY_HOTSPOT | DIRTY_DISPLAY_ID))))) {
             needApplyTransaction = true;
 
             if (wantSurfaceVisibleAndDrawn
@@ -445,6 +454,15 @@
     }
 }
 
+void SpriteController::SpriteImpl::setDisplayId(int32_t displayId) {
+    AutoMutex _l(mController->mLock);
+
+    if (mLocked.state.displayId != displayId) {
+        mLocked.state.displayId = displayId;
+        invalidateLocked(DIRTY_DISPLAY_ID);
+    }
+}
+
 void SpriteController::SpriteImpl::invalidateLocked(uint32_t dirty) {
     bool wasDirty = mLocked.state.dirty;
     mLocked.state.dirty |= dirty;