[SF] Update DeviceProductInfo on hotplug reconnect
This change populates DeviceProductInfo on hotplug, even if we are
in legacy multi-display mode. This behaviour is guarded by sysprop
ro.surface_flinger.update_edid_on_hotplug_reconnect which is
turned off by default.
Bug: 160952291
Test: 1. connect display
2. adb shell dumpsys SurfaceFlinger | grep deviceProductInfo
3. connect different display
4. adb shell dumpsys SurfaceFlinger | grep deviceProductInfo
5. make sure DeviceProductInfo has changed.
Change-Id: I94751f678b1dd1196727ad38ab5e398fb6cf0393
diff --git a/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h b/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h
index b5cda68..84c027b 100644
--- a/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h
+++ b/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h
@@ -81,6 +81,7 @@
MOCK_METHOD2(onHotplug,
std::optional<DisplayIdentificationInfo>(hal::HWDisplayId, hal::Connection));
+ MOCK_CONST_METHOD0(updatesDeviceProductInfoOnHotplugReconnect, bool());
MOCK_METHOD2(onVsync, bool(hal::HWDisplayId, int64_t));
MOCK_METHOD2(setVsyncEnabled, void(PhysicalDisplayId, hal::Vsync));
MOCK_CONST_METHOD1(getRefreshTimestamp, nsecs_t(PhysicalDisplayId));
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index 2fdbd3a..1548d18 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -26,6 +26,7 @@
#include "HWComposer.h"
+#include <android-base/properties.h>
#include <compositionengine/Output.h>
#include <compositionengine/OutputLayer.h>
#include <compositionengine/impl/OutputLayerCompositionState.h>
@@ -38,6 +39,7 @@
#include "../Layer.h" // needed only for debugging
#include "../Promise.h"
#include "../SurfaceFlinger.h"
+#include "../SurfaceFlingerProperties.h"
#include "ComposerHal.h"
#include "HWC2.h"
@@ -143,12 +145,13 @@
namespace impl {
-HWComposer::HWComposer(std::unique_ptr<Hwc2::Composer> composer) : mComposer(std::move(composer)) {
-}
+HWComposer::HWComposer(std::unique_ptr<Hwc2::Composer> composer)
+ : mComposer(std::move(composer)),
+ mUpdateDeviceProductInfoOnHotplugReconnect(
+ android::sysprop::update_device_product_info_on_hotplug_reconnect(false)) {}
HWComposer::HWComposer(const std::string& composerServiceName)
- : mComposer(std::make_unique<Hwc2::impl::Composer>(composerServiceName)) {
-}
+ : HWComposer(std::make_unique<Hwc2::impl::Composer>(composerServiceName)) {}
HWComposer::~HWComposer() {
mDisplayData.clear();
@@ -204,6 +207,10 @@
}
}
+bool HWComposer::updatesDeviceProductInfoOnHotplugReconnect() const {
+ return mUpdateDeviceProductInfoOnHotplugReconnect;
+}
+
bool HWComposer::onVsync(hal::HWDisplayId hwcDisplayId, int64_t timestamp) {
const auto displayId = toPhysicalDisplayId(hwcDisplayId);
if (!displayId) {
@@ -888,6 +895,16 @@
info = DisplayIdentificationInfo{.id = *displayId,
.name = std::string(),
.deviceProductInfo = std::nullopt};
+ if (mUpdateDeviceProductInfoOnHotplugReconnect) {
+ uint8_t port;
+ DisplayIdentificationData data;
+ getDisplayIdentificationData(hwcDisplayId, &port, &data);
+ if (auto newInfo = parseDisplayIdentificationData(port, data)) {
+ info->deviceProductInfo = std::move(newInfo->deviceProductInfo);
+ } else {
+ ALOGE("Failed to parse identification data for display %" PRIu64, hwcDisplayId);
+ }
+ }
} else {
uint8_t port;
DisplayIdentificationData data;
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h
index 028a9a4..d8af5bf 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.h
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.h
@@ -173,6 +173,10 @@
virtual std::optional<DisplayIdentificationInfo> onHotplug(hal::HWDisplayId,
hal::Connection) = 0;
+ // If true we'll update the DeviceProductInfo on subsequent hotplug connected events.
+ // TODO(b/157555476): Remove when the framework has proper support for headless mode
+ virtual bool updatesDeviceProductInfoOnHotplugReconnect() const = 0;
+
virtual bool onVsync(hal::HWDisplayId, int64_t timestamp) = 0;
virtual void setVsyncEnabled(PhysicalDisplayId, hal::Vsync enabled) = 0;
@@ -303,10 +307,12 @@
// Events handling ---------------------------------------------------------
- // Returns stable display ID (and display name on connection of new or previously disconnected
+ // Returns PhysicalDisplayId (and display name on connection of new or previously disconnected
// display), or std::nullopt if hotplug event was ignored.
std::optional<DisplayIdentificationInfo> onHotplug(hal::HWDisplayId, hal::Connection) override;
+ bool updatesDeviceProductInfoOnHotplugReconnect() const override;
+
bool onVsync(hal::HWDisplayId, int64_t timestamp) override;
void setVsyncEnabled(PhysicalDisplayId, hal::Vsync enabled) override;
@@ -400,6 +406,8 @@
bool mHasMultiDisplaySupport = false;
RandomDisplayIdGenerator<HalVirtualDisplayId> mVirtualIdGenerator{getMaxVirtualDisplayCount()};
+
+ const bool mUpdateDeviceProductInfoOnHotplugReconnect;
};
} // namespace impl
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 2ff26a9..82d7b65 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -2313,7 +2313,7 @@
void SurfaceFlinger::processDisplayHotplugEventsLocked() {
for (const auto& event : mPendingHotplugEvents) {
- const std::optional<DisplayIdentificationInfo> info =
+ std::optional<DisplayIdentificationInfo> info =
getHwComposer().onHotplug(event.hwcDisplayId, event.connection);
if (!info) {
@@ -2335,9 +2335,9 @@
state.physical = {.id = displayId,
.type = getHwComposer().getDisplayConnectionType(displayId),
.hwcDisplayId = event.hwcDisplayId,
- .deviceProductInfo = info->deviceProductInfo};
+ .deviceProductInfo = std::move(info->deviceProductInfo)};
state.isSecure = true; // All physical displays are currently considered secure.
- state.displayName = info->name;
+ state.displayName = std::move(info->name);
sp<IBinder> token = new BBinder();
mCurrentState.displays.add(token, state);
@@ -2349,7 +2349,10 @@
const auto token = it->second;
auto& state = mCurrentState.displays.editValueFor(token);
- state.sequenceId = DisplayDeviceState{}.sequenceId;
+ state.sequenceId = DisplayDeviceState{}.sequenceId; // Generate new sequenceId
+ if (getHwComposer().updatesDeviceProductInfoOnHotplugReconnect()) {
+ state.physical->deviceProductInfo = std::move(info->deviceProductInfo);
+ }
}
} else {
ALOGV("Removing display %s", to_string(displayId).c_str());
diff --git a/services/surfaceflinger/SurfaceFlingerProperties.cpp b/services/surfaceflinger/SurfaceFlingerProperties.cpp
index 9d78702..97725ec 100644
--- a/services/surfaceflinger/SurfaceFlingerProperties.cpp
+++ b/services/surfaceflinger/SurfaceFlingerProperties.cpp
@@ -371,5 +371,10 @@
return primaries;
}
+bool update_device_product_info_on_hotplug_reconnect(bool defaultValue) {
+ return SurfaceFlingerProperties::update_device_product_info_on_hotplug_reconnect().value_or(
+ defaultValue);
+}
+
} // namespace sysprop
} // namespace android
diff --git a/services/surfaceflinger/SurfaceFlingerProperties.h b/services/surfaceflinger/SurfaceFlingerProperties.h
index c63adfe..37a6b40 100644
--- a/services/surfaceflinger/SurfaceFlingerProperties.h
+++ b/services/surfaceflinger/SurfaceFlingerProperties.h
@@ -95,6 +95,9 @@
int32_t display_update_imminent_timeout_ms(int32_t defaultValue);
android::ui::DisplayPrimaries getDisplayNativePrimaries();
+
+bool update_device_product_info_on_hotplug_reconnect(bool defaultValue);
+
} // namespace sysprop
} // namespace android
#endif // SURFACEFLINGERPROPERTIES_H_
diff --git a/services/surfaceflinger/sysprop/SurfaceFlingerProperties.sysprop b/services/surfaceflinger/sysprop/SurfaceFlingerProperties.sysprop
index 7666f7f..421484f 100644
--- a/services/surfaceflinger/sysprop/SurfaceFlingerProperties.sysprop
+++ b/services/surfaceflinger/sysprop/SurfaceFlingerProperties.sysprop
@@ -435,3 +435,13 @@
access: Readonly
prop_name: "ro.surface_flinger.display_update_imminent_timeout_ms"
}
+
+
+# Updates the DeviceProductInfo when a hoplug reconnect event is processed
+prop {
+ api_name: "update_device_product_info_on_hotplug_reconnect"
+ type: Boolean
+ scope: Public
+ access: Readonly
+ prop_name: "ro.surface_flinger.update_device_product_info_on_hotplug_reconnect"
+}
diff --git a/services/surfaceflinger/sysprop/api/SurfaceFlingerProperties-current.txt b/services/surfaceflinger/sysprop/api/SurfaceFlingerProperties-current.txt
index ba60a7d..da66ece 100644
--- a/services/surfaceflinger/sysprop/api/SurfaceFlingerProperties-current.txt
+++ b/services/surfaceflinger/sysprop/api/SurfaceFlingerProperties-current.txt
@@ -124,6 +124,10 @@
prop_name: "ro.surface_flinger.supports_background_blur"
}
prop {
+ api_name: "update_device_product_info_on_hotplug_reconnect"
+ prop_name: "ro.surface_flinger.update_device_product_info_on_hotplug_reconnect"
+ }
+ prop {
api_name: "use_color_management"
prop_name: "ro.surface_flinger.use_color_management"
}