Move hotplug processing to the main thread

Queue up all hotplug events for processing in the main thread, as part
of a display transaction (eDisplayTransactionNeeded).

This is needed so that everything done for each individual hotplug disconnect or
connect is done at the same time,  such as creating and destroying the
corresponding DisplayDevice.

This fixes an issue with a hotplug disconnect event followed by an
immediate connect event for the same display not being handled properly.

Bug: 38464421
Test: Immediate disconnect/connect handled correctly.
Change-Id: I96266db8b02ffd6ad9eb4897d6c8510657775991
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index e5364c4..77977aa 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -638,6 +638,7 @@
      * Display management
      */
     void processDisplayChangesLocked();
+    void processDisplayHotplugEventsLocked();
 
     /* ------------------------------------------------------------------------
      * VSync
@@ -739,6 +740,14 @@
     sp<Fence> mPreviousPresentFence = Fence::NO_FENCE;
     bool mHadClientComposition = false;
 
+    struct HotplugEvent {
+        hwc2_display_t display;
+        HWC2::Connection connection = HWC2::Connection::Invalid;
+        bool isPrimaryDisplay;
+    };
+    // protected by mStateLock
+    std::vector<HotplugEvent> mPendingHotplugEvents;
+
     // this may only be written from the main thread with mStateLock held
     // it may be read from other threads with mStateLock held
     DefaultKeyedVector< wp<IBinder>, sp<DisplayDevice> > mDisplays;