Merge "Guard against racy ComposerClient reconnection" into oc-mr1-dev
diff --git a/graphics/composer/2.1/default/Hwc.cpp b/graphics/composer/2.1/default/Hwc.cpp
index 8ca0eb3..862dff1 100644
--- a/graphics/composer/2.1/default/Hwc.cpp
+++ b/graphics/composer/2.1/default/Hwc.cpp
@@ -18,6 +18,7 @@
#include "Hwc.h"
+#include <chrono>
#include <type_traits>
#include <log/log.h>
@@ -25,6 +26,8 @@
#include "hardware/hwcomposer.h"
#include "hwc2on1adapter/HWC2On1Adapter.h"
+using namespace std::chrono_literals;
+
namespace android {
namespace hardware {
namespace graphics {
@@ -218,7 +221,24 @@
sp<ComposerClient> client;
{
- std::lock_guard<std::mutex> lock(mClientMutex);
+ std::unique_lock<std::mutex> lock(mClientMutex);
+
+ if (mClient != nullptr) {
+ // In surface flinger we delete a composer client on one thread and
+ // then create a new client on another thread. Although surface
+ // flinger ensures the calls are made in that sequence (destroy and
+ // then create), sometimes the calls land in the composer service
+ // inverted (create and then destroy). Wait for a brief period to
+ // see if the existing client is destroyed.
+ ALOGI("HwcHal::createClient: Client already exists. Waiting for"
+ " it to be destroyed.");
+ mClientDestroyedWait.wait_for(lock, 1s,
+ [this] { return mClient == nullptr; });
+ std::string doneMsg = mClient == nullptr ?
+ "Existing client was destroyed." :
+ "Existing client was never destroyed!";
+ ALOGI("HwcHal::createClient: Done waiting. %s", doneMsg.c_str());
+ }
// only one client is allowed
if (mClient == nullptr) {
@@ -245,6 +265,7 @@
{
std::lock_guard<std::mutex> lock(mClientMutex);
mClient = nullptr;
+ mClientDestroyedWait.notify_all();
}
void HwcHal::hotplugHook(hwc2_callback_data_t callbackData,
diff --git a/graphics/composer/2.1/default/Hwc.h b/graphics/composer/2.1/default/Hwc.h
index b45389a..7561327 100644
--- a/graphics/composer/2.1/default/Hwc.h
+++ b/graphics/composer/2.1/default/Hwc.h
@@ -17,8 +17,9 @@
#ifndef ANDROID_HARDWARE_GRAPHICS_COMPOSER_V2_1_HWC_H
#define ANDROID_HARDWARE_GRAPHICS_COMPOSER_V2_1_HWC_H
-#include <mutex>
+#include <condition_variable>
#include <memory>
+#include <mutex>
#include <unordered_set>
#include <vector>
@@ -211,6 +212,7 @@
} mDispatch;
std::mutex mClientMutex;
+ std::condition_variable mClientDestroyedWait;
wp<ComposerClient> mClient;
// If the HWC implementation version is < 2.0, use an adapter to interface