HWComposer: setPowerMode to DOZE even if support is unknown
If a display has not been turned on since boot, we do not know whether
it supports doze. Rather than treating this as not supported, make
Display::supportsDoze return an error if the capabilities have not been
queried yet. If supportsDoze returns this error, try to set the mode to
DOZE(_SUSPEND) anyway. This allows properly waking from AOD.
If the call to Display::setPowerMode fails, this means it truly is not
supported, so fallback to the old behavior of turning it ON.
Fixes: 274722476
Test: manual
Test: GraphicsComposerAidlTest#SetPowerModeUnsupported
Change-Id: Ia88603565713ea4b6ec5142b693d2df1302131ea
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index 3177b33..a9bb928 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -616,19 +616,29 @@
ALOGV("setPowerMode: Calling HWC %s", to_string(mode).c_str());
{
bool supportsDoze = false;
- auto error = hwcDisplay->supportsDoze(&supportsDoze);
- if (error != hal::Error::NONE) {
- LOG_HWC_ERROR("supportsDoze", error, displayId);
- }
+ const auto queryDozeError = hwcDisplay->supportsDoze(&supportsDoze);
- if (!supportsDoze) {
+ // queryDozeError might be NO_RESOURCES, in the case of a display that has never
+ // been turned on. In that case, attempt to set to DOZE anyway.
+ if (!supportsDoze && queryDozeError == hal::Error::NONE) {
mode = hal::PowerMode::ON;
}
- error = hwcDisplay->setPowerMode(mode);
+ auto error = hwcDisplay->setPowerMode(mode);
if (error != hal::Error::NONE) {
LOG_HWC_ERROR(("setPowerMode(" + to_string(mode) + ")").c_str(), error,
displayId);
+ // If the display had never been turned on, so its doze
+ // support was unknown, it may truly not support doze. Try
+ // switching it to ON instead.
+ if (queryDozeError == hal::Error::NO_RESOURCES) {
+ ALOGD("%s: failed to set %s to %s. Trying again with ON", __func__,
+ to_string(displayId).c_str(), to_string(mode).c_str());
+ error = hwcDisplay->setPowerMode(hal::PowerMode::ON);
+ if (error != hal::Error::NONE) {
+ LOG_HWC_ERROR("setPowerMode(ON)", error, displayId);
+ }
+ }
}
}
break;