drm_hwcomposer: Introduce main lock

Further development will require more asynchronous processing.
Introduce project-wide single mutex for these purposes.
Use it instead for callback handling instead of callback_lock.

Signed-off-by: Roman Stratiienko <roman.o.stratiienko@globallogic.com>
diff --git a/drm/ResourceManager.h b/drm/ResourceManager.h
index 773b350..f54d682 100644
--- a/drm/ResourceManager.h
+++ b/drm/ResourceManager.h
@@ -48,6 +48,10 @@
     return &uevent_listener_;
   }
 
+  auto &GetMainLock() {
+    return main_lock_;
+  }
+
  private:
   int AddDrmDevice(std::string const &path);
 
@@ -57,6 +61,8 @@
   bool scale_with_gpu_{};
 
   UEventListener uevent_listener_;
+
+  std::mutex main_lock_;
 };
 }  // namespace android
 
diff --git a/hwc2_device/DrmHwcTwo.cpp b/hwc2_device/DrmHwcTwo.cpp
index 5bbb48a..42e131a 100644
--- a/hwc2_device/DrmHwcTwo.cpp
+++ b/hwc2_device/DrmHwcTwo.cpp
@@ -66,8 +66,11 @@
     }
   }
 
-  resource_manager_.GetUEventListener()->RegisterHotplugHandler(
-      [this] { HandleHotplugUEvent(); });
+  resource_manager_.GetUEventListener()->RegisterHotplugHandler([this] {
+    const std::lock_guard<std::mutex> lock(GetResMan().GetMainLock());
+
+    HandleHotplugUEvent();
+  });
 
   return ret;
 }
@@ -111,12 +114,9 @@
 HWC2::Error DrmHwcTwo::RegisterCallback(int32_t descriptor,
                                         hwc2_callback_data_t data,
                                         hwc2_function_pointer_t function) {
-  std::unique_lock<std::mutex> lock(callback_lock_);
-
   switch (static_cast<HWC2::Callback>(descriptor)) {
     case HWC2::Callback::Hotplug: {
       hotplug_callback_ = std::make_pair(HWC2_PFN_HOTPLUG(function), data);
-      lock.unlock();
       const auto &drm_devices = resource_manager_.GetDrmDevices();
       for (const auto &device : drm_devices)
         HandleInitialHotplugState(device.get());
@@ -143,14 +143,23 @@
 }
 
 void DrmHwcTwo::HandleDisplayHotplug(hwc2_display_t displayid, int state) {
-  const std::lock_guard<std::mutex> lock(callback_lock_);
+  auto &mutex = GetResMan().GetMainLock();
+  if (mutex.try_lock()) {
+    ALOGE("FIXME!!!: Main mutex must be locked in %s", __func__);
+    mutex.unlock();
+    return;
+  }
 
-  if (hotplug_callback_.first != nullptr &&
-      hotplug_callback_.second != nullptr) {
-    hotplug_callback_.first(hotplug_callback_.second, displayid,
-                            state == DRM_MODE_CONNECTED
-                                ? HWC2_CONNECTION_CONNECTED
-                                : HWC2_CONNECTION_DISCONNECTED);
+  auto hc = hotplug_callback_;
+  if (hc.first != nullptr && hc.second != nullptr) {
+    /* For some reason CLIENT will call HWC2 API in hotplug callback handler,
+     * which will cause deadlock . Unlock main mutex to prevent this.
+     */
+    mutex.unlock();
+    hc.first(hc.second, displayid,
+             state == DRM_MODE_CONNECTED ? HWC2_CONNECTION_CONNECTED
+                                         : HWC2_CONNECTION_DISCONNECTED);
+    mutex.lock();
   }
 }
 
diff --git a/hwc2_device/DrmHwcTwo.h b/hwc2_device/DrmHwcTwo.h
index d096160..f38ba05 100644
--- a/hwc2_device/DrmHwcTwo.h
+++ b/hwc2_device/DrmHwcTwo.h
@@ -37,8 +37,6 @@
 #endif
   std::pair<HWC2_PFN_REFRESH, hwc2_callback_data_t> refresh_callback_{};
 
-  std::mutex callback_lock_;
-
   static HwcDisplay *GetDisplay(DrmHwcTwo *hwc, hwc2_display_t display_handle) {
     auto it = hwc->displays_.find(display_handle);
     if (it == hwc->displays_.end())
@@ -57,6 +55,10 @@
                                hwc2_function_pointer_t function);
   HWC2::Error CreateDisplay(hwc2_display_t displ, HWC2::DisplayType type);
 
+  auto &GetResMan() {
+    return resource_manager_;
+  }
+
  private:
   void HandleDisplayHotplug(hwc2_display_t displayid, int state);
   void HandleInitialHotplugState(DrmDevice *drmDevice);
diff --git a/hwc2_device/HwcDisplay.cpp b/hwc2_device/HwcDisplay.cpp
index 9f7bcd8..c8f5e69 100644
--- a/hwc2_device/HwcDisplay.cpp
+++ b/hwc2_device/HwcDisplay.cpp
@@ -136,7 +136,7 @@
   }
 
   ret = vsync_worker_.Init(drm_, display, [this](int64_t timestamp) {
-    const std::lock_guard<std::mutex> lock(hwc2_->callback_lock_);
+    const std::lock_guard<std::mutex> lock(hwc2_->GetResMan().GetMainLock());
     /* vsync callback */
 #if PLATFORM_SDK_VERSION > 29
     if (hwc2_->vsync_2_4_callback_.first != nullptr &&
@@ -160,7 +160,8 @@
 
   ret = flattening_vsync_worker_
             .Init(drm_, display, [this](int64_t /*timestamp*/) {
-              const std::lock_guard<std::mutex> lock(hwc2_->callback_lock_);
+              const std::lock_guard<std::mutex> lock(
+                  hwc2_->GetResMan().GetMainLock());
               /* Frontend flattening */
               if (flattenning_state_ >
                       ClientFlattenningState::ClientRefreshRequested &&
diff --git a/hwc2_device/hwc2_device.cpp b/hwc2_device/hwc2_device.cpp
index ebf7eeb..6d258e8 100644
--- a/hwc2_device/hwc2_device.cpp
+++ b/hwc2_device/hwc2_device.cpp
@@ -63,15 +63,18 @@
 static T DeviceHook(hwc2_device_t *dev, Args... args) {
   ALOGV("Device hook: %s", GetFuncName(__PRETTY_FUNCTION__).c_str());
   DrmHwcTwo *hwc = ToDrmHwcTwo(dev);
+  const std::lock_guard<std::mutex> lock(hwc->GetResMan().GetMainLock());
   return static_cast<T>(((*hwc).*func)(std::forward<Args>(args)...));
 }
 
 template <typename HookType, HookType func, typename... Args>
 static int32_t DisplayHook(hwc2_device_t *dev, hwc2_display_t display_handle,
                            Args... args) {
-  HwcDisplay *display = DrmHwcTwo::GetDisplay(ToDrmHwcTwo(dev), display_handle);
   ALOGV("Display #%" PRIu64 " hook: %s", display_handle,
         GetFuncName(__PRETTY_FUNCTION__).c_str());
+  DrmHwcTwo *hwc = ToDrmHwcTwo(dev);
+  const std::lock_guard<std::mutex> lock(hwc->GetResMan().GetMainLock());
+  HwcDisplay *display = DrmHwcTwo::GetDisplay(hwc, display_handle);
   if (!display)
     return static_cast<int32_t>(HWC2::Error::BadDisplay);
 
@@ -81,9 +84,11 @@
 template <typename HookType, HookType func, typename... Args>
 static int32_t LayerHook(hwc2_device_t *dev, hwc2_display_t display_handle,
                          hwc2_layer_t layer_handle, Args... args) {
-  HwcDisplay *display = DrmHwcTwo::GetDisplay(ToDrmHwcTwo(dev), display_handle);
   ALOGV("Display #%" PRIu64 " Layer: #%" PRIu64 " hook: %s", display_handle,
         layer_handle, GetFuncName(__PRETTY_FUNCTION__).c_str());
+  DrmHwcTwo *hwc = ToDrmHwcTwo(dev);
+  const std::lock_guard<std::mutex> lock(hwc->GetResMan().GetMainLock());
+  HwcDisplay *display = DrmHwcTwo::GetDisplay(hwc, display_handle);
   if (!display)
     return static_cast<int32_t>(HWC2::Error::BadDisplay);