Add boot time display mode to native framework
Bug: 203520442
Test: m
Test: atest libsurfaceflinger_unittest
Test: atest libgui_test
Change-Id: I61ad0c75576a4e1ee54d657e6906bc5d6c10afaf
diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp
index a931709..0227043 100644
--- a/libs/gui/ISurfaceComposer.cpp
+++ b/libs/gui/ISurfaceComposer.cpp
@@ -428,6 +428,94 @@
return static_cast<status_t>(reply.readInt32());
}
+ // TODO(b/213909104) : Add unit tests to verify surface flinger boot time APIs
+ status_t getBootDisplayModeSupport(bool* outSupport) const override {
+ Parcel data, reply;
+ status_t error = data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
+ if (error != NO_ERROR) {
+ ALOGE("getBootDisplayModeSupport: failed to write interface token: %d", error);
+ return error;
+ }
+ error = remote()->transact(BnSurfaceComposer::GET_BOOT_DISPLAY_MODE_SUPPORT, data, &reply);
+ if (error != NO_ERROR) {
+ ALOGE("getBootDisplayModeSupport: failed to transact: %d", error);
+ return error;
+ }
+ bool support;
+ error = reply.readBool(&support);
+ if (error != NO_ERROR) {
+ ALOGE("getBootDisplayModeSupport: failed to read support: %d", error);
+ return error;
+ }
+ *outSupport = support;
+ return NO_ERROR;
+ }
+
+ status_t setBootDisplayMode(const sp<IBinder>& display,
+ ui::DisplayModeId displayModeId) override {
+ Parcel data, reply;
+ status_t result = data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
+ if (result != NO_ERROR) {
+ ALOGE("setBootDisplayMode failed to writeInterfaceToken: %d", result);
+ return result;
+ }
+ result = data.writeStrongBinder(display);
+ if (result != NO_ERROR) {
+ ALOGE("setBootDisplayMode failed to writeStrongBinder: %d", result);
+ return result;
+ }
+ result = data.writeInt32(displayModeId);
+ if (result != NO_ERROR) {
+ ALOGE("setBootDisplayMode failed to writeIint32: %d", result);
+ return result;
+ }
+ result = remote()->transact(BnSurfaceComposer::SET_BOOT_DISPLAY_MODE, data, &reply);
+ if (result != NO_ERROR) {
+ ALOGE("setBootDisplayMode failed to transact: %d", result);
+ }
+ return result;
+ }
+
+ status_t clearBootDisplayMode(const sp<IBinder>& display) override {
+ Parcel data, reply;
+ status_t result = data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
+ if (result != NO_ERROR) {
+ ALOGE("clearBootDisplayMode failed to writeInterfaceToken: %d", result);
+ return result;
+ }
+ result = data.writeStrongBinder(display);
+ if (result != NO_ERROR) {
+ ALOGE("clearBootDisplayMode failed to writeStrongBinder: %d", result);
+ return result;
+ }
+ result = remote()->transact(BnSurfaceComposer::CLEAR_BOOT_DISPLAY_MODE, data, &reply);
+ if (result != NO_ERROR) {
+ ALOGE("clearBootDisplayMode failed to transact: %d", result);
+ }
+ return result;
+ }
+
+ status_t getPreferredBootDisplayMode(const sp<IBinder>& display,
+ ui::DisplayModeId* displayModeId) override {
+ Parcel data, reply;
+ status_t result = data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
+ if (result != NO_ERROR) {
+ ALOGE("getPreferredBootDisplayMode failed to writeInterfaceToken: %d", result);
+ return result;
+ }
+ result = data.writeStrongBinder(display);
+ if (result != NO_ERROR) {
+ ALOGE("getPreferredBootDisplayMode failed to writeStrongBinder: %d", result);
+ return result;
+ }
+ result = remote()->transact(BnSurfaceComposer::GET_PREFERRED_BOOT_DISPLAY_MODE, data,
+ &reply);
+ if (result == NO_ERROR) {
+ reply.writeInt32(*displayModeId);
+ }
+ return result;
+ }
+
void setAutoLowLatencyMode(const sp<IBinder>& display, bool on) override {
Parcel data, reply;
status_t result = data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
@@ -1521,6 +1609,56 @@
result = reply->writeInt32(result);
return result;
}
+ case GET_BOOT_DISPLAY_MODE_SUPPORT: {
+ CHECK_INTERFACE(ISurfaceComposer, data, reply);
+ bool support = false;
+ status_t result = getBootDisplayModeSupport(&support);
+ if (result == NO_ERROR) {
+ reply->writeBool(support);
+ }
+ return result;
+ }
+ case SET_BOOT_DISPLAY_MODE: {
+ CHECK_INTERFACE(ISurfaceComposer, data, reply);
+ sp<IBinder> display = nullptr;
+ status_t result = data.readStrongBinder(&display);
+ if (result != NO_ERROR) {
+ ALOGE("setBootDisplayMode failed to readStrongBinder: %d", result);
+ return result;
+ }
+ ui::DisplayModeId displayModeId;
+ result = data.readInt32(&displayModeId);
+ if (result != NO_ERROR) {
+ ALOGE("setBootDisplayMode failed to readInt32: %d", result);
+ return result;
+ }
+ return setBootDisplayMode(display, displayModeId);
+ }
+ case CLEAR_BOOT_DISPLAY_MODE: {
+ CHECK_INTERFACE(ISurfaceComposer, data, reply);
+ sp<IBinder> display = nullptr;
+ status_t result = data.readStrongBinder(&display);
+ if (result != NO_ERROR) {
+ ALOGE("clearBootDisplayMode failed to readStrongBinder: %d", result);
+ return result;
+ }
+ return clearBootDisplayMode(display);
+ }
+ case GET_PREFERRED_BOOT_DISPLAY_MODE: {
+ CHECK_INTERFACE(ISurfaceComposer, data, reply);
+ sp<IBinder> display = nullptr;
+ status_t result = data.readStrongBinder(&display);
+ if (result != NO_ERROR) {
+ ALOGE("getPreferredBootDisplayMode failed to readStrongBinder: %d", result);
+ return result;
+ }
+ ui::DisplayModeId displayModeId;
+ result = getPreferredBootDisplayMode(display, &displayModeId);
+ if (result == NO_ERROR) {
+ reply->writeInt32(displayModeId);
+ }
+ return result;
+ }
case SET_AUTO_LOW_LATENCY_MODE: {
CHECK_INTERFACE(ISurfaceComposer, data, reply);
sp<IBinder> display = nullptr;
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index b10c384..6dbdcd0 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -2075,6 +2075,25 @@
return ComposerService::getComposerService()->setActiveColorMode(display, colorMode);
}
+status_t SurfaceComposerClient::getBootDisplayModeSupport(bool* support) {
+ return ComposerService::getComposerService()->getBootDisplayModeSupport(support);
+}
+
+status_t SurfaceComposerClient::setBootDisplayMode(const sp<IBinder>& display,
+ ui::DisplayModeId displayModeId) {
+ return ComposerService::getComposerService()->setBootDisplayMode(display, displayModeId);
+}
+
+status_t SurfaceComposerClient::clearBootDisplayMode(const sp<IBinder>& display) {
+ return ComposerService::getComposerService()->clearBootDisplayMode(display);
+}
+
+status_t SurfaceComposerClient::getPreferredBootDisplayMode(const sp<IBinder>& display,
+ ui::DisplayModeId* displayModeId) {
+ return ComposerService::getComposerService()->getPreferredBootDisplayMode(display,
+ displayModeId);
+}
+
void SurfaceComposerClient::setAutoLowLatencyMode(const sp<IBinder>& display, bool on) {
ComposerService::getComposerService()->setAutoLowLatencyMode(display, on);
}
diff --git a/libs/gui/include/gui/ISurfaceComposer.h b/libs/gui/include/gui/ISurfaceComposer.h
index 69dce9d..f37580c 100644
--- a/libs/gui/include/gui/ISurfaceComposer.h
+++ b/libs/gui/include/gui/ISurfaceComposer.h
@@ -224,6 +224,35 @@
ui::ColorMode colorMode) = 0;
/**
+ * Sets the user-preferred display mode that a device should boot in.
+ */
+ virtual status_t setBootDisplayMode(const sp<IBinder>& display, ui::DisplayModeId) = 0;
+
+ /**
+ * Clears the user-preferred display mode. The device should now boot in system preferred
+ * display mode.
+ */
+ virtual status_t clearBootDisplayMode(const sp<IBinder>& display) = 0;
+
+ /**
+ * Gets the display mode in which the device boots if there is no user-preferred display mode.
+ */
+ virtual status_t getPreferredBootDisplayMode(const sp<IBinder>& display,
+ ui::DisplayModeId*) = 0;
+
+ /**
+ * Gets whether boot time display mode operations are supported on the device.
+ *
+ * outSupport
+ * An output parameter for whether boot time display mode operations are supported.
+ *
+ * Returns NO_ERROR upon success. Otherwise,
+ * NAME_NOT_FOUND if the display is invalid, or
+ * BAD_VALUE if the output parameter is invalid.
+ */
+ virtual status_t getBootDisplayModeSupport(bool* outSupport) const = 0;
+
+ /**
* Switches Auto Low Latency Mode on/off on the connected display, if it is
* available. This should only be called if the display supports Auto Low
* Latency Mode as reported in #getDynamicDisplayInfo.
@@ -645,6 +674,10 @@
REMOVE_WINDOW_INFOS_LISTENER,
GET_PRIMARY_PHYSICAL_DISPLAY_ID,
GET_DISPLAY_DECORATION_SUPPORT,
+ GET_BOOT_DISPLAY_MODE_SUPPORT,
+ SET_BOOT_DISPLAY_MODE,
+ CLEAR_BOOT_DISPLAY_MODE,
+ GET_PREFERRED_BOOT_DISPLAY_MODE,
// Always append new enum to the end.
};
diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h
index b739b3c..4eef111 100644
--- a/libs/gui/include/gui/SurfaceComposerClient.h
+++ b/libs/gui/include/gui/SurfaceComposerClient.h
@@ -167,6 +167,15 @@
static status_t setActiveColorMode(const sp<IBinder>& display,
ui::ColorMode colorMode);
+ // Gets if boot display mode operations are supported on a device
+ static status_t getBootDisplayModeSupport(bool* support);
+ // Sets the user-preferred display mode that a device should boot in
+ static status_t setBootDisplayMode(const sp<IBinder>& display, ui::DisplayModeId);
+ // Clears the user-preferred display mode
+ static status_t clearBootDisplayMode(const sp<IBinder>& display);
+ // Gets the display mode in which the device boots if there is no user-preferred display mode
+ static status_t getPreferredBootDisplayMode(const sp<IBinder>& display, ui::DisplayModeId*);
+
// Switches on/off Auto Low Latency Mode on the connected display. This should only be
// called if the connected display supports Auto Low Latency Mode as reported by
// #getAutoLowLatencyModeSupport
diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp
index d5e089a..999874b 100644
--- a/libs/gui/tests/Surface_test.cpp
+++ b/libs/gui/tests/Surface_test.cpp
@@ -755,6 +755,15 @@
}
status_t setActiveColorMode(const sp<IBinder>& /*display*/,
ColorMode /*colorMode*/) override { return NO_ERROR; }
+ status_t getBootDisplayModeSupport(bool* /*outSupport*/) const override { return NO_ERROR; }
+ status_t setBootDisplayMode(const sp<IBinder>& /*display*/, ui::DisplayModeId /*id*/) override {
+ return NO_ERROR;
+ }
+ status_t clearBootDisplayMode(const sp<IBinder>& /*display*/) override { return NO_ERROR; }
+ status_t getPreferredBootDisplayMode(const sp<IBinder>& /*display*/,
+ ui::DisplayModeId* /*id*/) override {
+ return NO_ERROR;
+ }
void setAutoLowLatencyMode(const sp<IBinder>& /*display*/, bool /*on*/) override {}
void setGameContentType(const sp<IBinder>& /*display*/, bool /*on*/) override {}
diff --git a/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h b/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h
index dc5c5c8..bd3022b 100644
--- a/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h
+++ b/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h
@@ -106,6 +106,9 @@
status_t(PhysicalDisplayId, hal::HWConfigId,
const hal::VsyncPeriodChangeConstraints&,
hal::VsyncPeriodChangeTimeline*));
+ MOCK_METHOD2(setBootDisplayMode, status_t(PhysicalDisplayId, hal::HWConfigId));
+ MOCK_METHOD1(clearBootDisplayMode, status_t(PhysicalDisplayId));
+ MOCK_METHOD1(getPreferredBootDisplayMode, hal::HWConfigId(PhysicalDisplayId));
MOCK_METHOD2(setAutoLowLatencyMode, status_t(PhysicalDisplayId, bool));
MOCK_METHOD2(getSupportedContentTypes,
status_t(PhysicalDisplayId, std::vector<hal::ContentType>*));
@@ -124,6 +127,7 @@
(const, override));
MOCK_METHOD(std::optional<hal::HWDisplayId>, fromPhysicalDisplayId, (PhysicalDisplayId),
(const, override));
+ MOCK_METHOD(bool, getBootDisplayModeSupport, (), (override));
};
} // namespace mock
diff --git a/services/surfaceflinger/DisplayHardware/AidlComposerHal.cpp b/services/surfaceflinger/DisplayHardware/AidlComposerHal.cpp
index 3c578bc..1448e56 100644
--- a/services/surfaceflinger/DisplayHardware/AidlComposerHal.cpp
+++ b/services/surfaceflinger/DisplayHardware/AidlComposerHal.cpp
@@ -237,6 +237,7 @@
case OptionalFeature::RefreshRateSwitching:
case OptionalFeature::ExpectedPresentTime:
case OptionalFeature::DisplayBrightnessCommand:
+ case OptionalFeature::BootDisplayConfig:
return true;
}
}
@@ -1009,6 +1010,38 @@
return V2_4::Error::UNSUPPORTED;
}
+Error AidlComposer::setBootDisplayConfig(Display display, Config config) {
+ const auto status = mAidlComposerClient->setBootDisplayConfig(translate<int64_t>(display),
+ translate<int32_t>(config));
+ if (!status.isOk()) {
+ ALOGE("setBootDisplayConfig failed %s", status.getDescription().c_str());
+ return static_cast<Error>(status.getServiceSpecificError());
+ }
+ return Error::NONE;
+}
+
+Error AidlComposer::clearBootDisplayConfig(Display display) {
+ const auto status = mAidlComposerClient->clearBootDisplayConfig(translate<int64_t>(display));
+ if (!status.isOk()) {
+ ALOGE("clearBootDisplayConfig failed %s", status.getDescription().c_str());
+ return static_cast<Error>(status.getServiceSpecificError());
+ }
+ return Error::NONE;
+}
+
+Error AidlComposer::getPreferredBootDisplayConfig(Display display, Config* config) {
+ int32_t displayConfig;
+ const auto status =
+ mAidlComposerClient->getPreferredBootDisplayConfig(translate<int64_t>(display),
+ &displayConfig);
+ if (!status.isOk()) {
+ ALOGE("getPreferredBootDisplayConfig failed %s", status.getDescription().c_str());
+ return static_cast<Error>(status.getServiceSpecificError());
+ }
+ *config = translate<uint32_t>(displayConfig);
+ return Error::NONE;
+}
+
Error AidlComposer::getClientTargetProperty(
Display display, IComposerClient::ClientTargetProperty* outClientTargetProperty,
float* whitePointNits) {
diff --git a/services/surfaceflinger/DisplayHardware/AidlComposerHal.h b/services/surfaceflinger/DisplayHardware/AidlComposerHal.h
index cdd16e2..6770017 100644
--- a/services/surfaceflinger/DisplayHardware/AidlComposerHal.h
+++ b/services/surfaceflinger/DisplayHardware/AidlComposerHal.h
@@ -213,6 +213,9 @@
Error setLayerWhitePointNits(Display display, Layer layer, float whitePointNits) override;
Error setLayerBlockingRegion(Display display, Layer layer,
const std::vector<IComposerClient::Rect>& blocking) override;
+ Error setBootDisplayConfig(Display displayId, Config) override;
+ Error clearBootDisplayConfig(Display displayId) override;
+ Error getPreferredBootDisplayConfig(Display displayId, Config*) override;
private:
// Many public functions above simply write a command into the command
diff --git a/services/surfaceflinger/DisplayHardware/ComposerHal.h b/services/surfaceflinger/DisplayHardware/ComposerHal.h
index bb4b784..22f424f 100644
--- a/services/surfaceflinger/DisplayHardware/ComposerHal.h
+++ b/services/surfaceflinger/DisplayHardware/ComposerHal.h
@@ -81,6 +81,7 @@
ExpectedPresentTime,
// Whether setDisplayBrightness is able to be applied as part of a display command.
DisplayBrightnessCommand,
+ BootDisplayConfig,
};
virtual bool isSupported(OptionalFeature) const = 0;
@@ -248,6 +249,7 @@
const std::vector<uint8_t>& value) = 0;
virtual V2_4::Error getLayerGenericMetadataKeys(
std::vector<IComposerClient::LayerGenericMetadataKey>* outKeys) = 0;
+
virtual Error getClientTargetProperty(
Display display, IComposerClient::ClientTargetProperty* outClientTargetProperty,
float* outWhitePointNits) = 0;
@@ -256,6 +258,9 @@
virtual Error setLayerWhitePointNits(Display display, Layer layer, float whitePointNits) = 0;
virtual Error setLayerBlockingRegion(Display display, Layer layer,
const std::vector<IComposerClient::Rect>& blocking) = 0;
+ virtual Error setBootDisplayConfig(Display displayId, Config) = 0;
+ virtual Error clearBootDisplayConfig(Display displayId) = 0;
+ virtual Error getPreferredBootDisplayConfig(Display displayId, Config*) = 0;
};
} // namespace android::Hwc2
diff --git a/services/surfaceflinger/DisplayHardware/HWC2.cpp b/services/surfaceflinger/DisplayHardware/HWC2.cpp
index 34f2e76..05e3aef 100644
--- a/services/surfaceflinger/DisplayHardware/HWC2.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWC2.cpp
@@ -539,6 +539,21 @@
});
}
+Error Display::setBootDisplayConfig(hal::HWConfigId configId) {
+ auto intError = mComposer.setBootDisplayConfig(mId, configId);
+ return static_cast<Error>(intError);
+}
+
+Error Display::clearBootDisplayConfig() {
+ auto intError = mComposer.clearBootDisplayConfig(mId);
+ return static_cast<Error>(intError);
+}
+
+Error Display::getPreferredBootDisplayConfig(hal::HWConfigId* configId) const {
+ auto intError = mComposer.getPreferredBootDisplayConfig(mId, configId);
+ return static_cast<Error>(intError);
+}
+
Error Display::setAutoLowLatencyMode(bool on) {
auto intError = mComposer.setAutoLowLatencyMode(mId, on);
return static_cast<Error>(intError);
diff --git a/services/surfaceflinger/DisplayHardware/HWC2.h b/services/surfaceflinger/DisplayHardware/HWC2.h
index 01a482d..57eb128 100644
--- a/services/surfaceflinger/DisplayHardware/HWC2.h
+++ b/services/surfaceflinger/DisplayHardware/HWC2.h
@@ -149,6 +149,11 @@
[[clang::warn_unused_result]] virtual hal::Error setActiveConfigWithConstraints(
hal::HWConfigId configId, const hal::VsyncPeriodChangeConstraints& constraints,
hal::VsyncPeriodChangeTimeline* outTimeline) = 0;
+ [[clang::warn_unused_result]] virtual hal::Error setBootDisplayConfig(
+ hal::HWConfigId configId) = 0;
+ [[clang::warn_unused_result]] virtual hal::Error clearBootDisplayConfig() = 0;
+ [[clang::warn_unused_result]] virtual hal::Error getPreferredBootDisplayConfig(
+ hal::HWConfigId* configId) const = 0;
[[clang::warn_unused_result]] virtual hal::Error setAutoLowLatencyMode(bool on) = 0;
[[clang::warn_unused_result]] virtual hal::Error getSupportedContentTypes(
std::vector<hal::ContentType>*) const = 0;
@@ -218,6 +223,9 @@
hal::Error setActiveConfigWithConstraints(hal::HWConfigId configId,
const hal::VsyncPeriodChangeConstraints& constraints,
hal::VsyncPeriodChangeTimeline* outTimeline) override;
+ hal::Error setBootDisplayConfig(hal::HWConfigId configId) override;
+ hal::Error clearBootDisplayConfig() override;
+ hal::Error getPreferredBootDisplayConfig(hal::HWConfigId* configId) const override;
hal::Error setAutoLowLatencyMode(bool on) override;
hal::Error getSupportedContentTypes(
std::vector<hal::ContentType>* outSupportedContentTypes) const override;
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index 057db46..44e4597 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -801,6 +801,52 @@
});
}
+bool HWComposer::getBootDisplayModeSupport() {
+ return mComposer->isSupported(Hwc2::Composer::OptionalFeature::BootDisplayConfig);
+}
+
+status_t HWComposer::setBootDisplayMode(PhysicalDisplayId displayId,
+ hal::HWConfigId displayModeId) {
+ RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
+ const auto error = mDisplayData[displayId].hwcDisplay->setBootDisplayConfig(displayModeId);
+ if (error == hal::Error::UNSUPPORTED) {
+ RETURN_IF_HWC_ERROR(error, displayId, INVALID_OPERATION);
+ }
+ if (error == hal::Error::BAD_PARAMETER) {
+ RETURN_IF_HWC_ERROR(error, displayId, BAD_VALUE);
+ }
+ RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
+ return NO_ERROR;
+}
+
+status_t HWComposer::clearBootDisplayMode(PhysicalDisplayId displayId) {
+ RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
+ const auto error = mDisplayData[displayId].hwcDisplay->clearBootDisplayConfig();
+ if (error == hal::Error::UNSUPPORTED) {
+ RETURN_IF_HWC_ERROR(error, displayId, INVALID_OPERATION);
+ }
+ if (error == hal::Error::BAD_PARAMETER) {
+ RETURN_IF_HWC_ERROR(error, displayId, BAD_VALUE);
+ }
+ RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
+ return NO_ERROR;
+}
+
+hal::HWConfigId HWComposer::getPreferredBootDisplayMode(PhysicalDisplayId displayId) {
+ RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
+ hal::HWConfigId displayModeId = -1;
+ const auto error =
+ mDisplayData[displayId].hwcDisplay->getPreferredBootDisplayConfig(&displayModeId);
+ if (error == hal::Error::UNSUPPORTED) {
+ RETURN_IF_HWC_ERROR(error, displayId, INVALID_OPERATION);
+ }
+ if (error == hal::Error::BAD_PARAMETER) {
+ RETURN_IF_HWC_ERROR(error, displayId, BAD_VALUE);
+ }
+ RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
+ return displayModeId;
+}
+
status_t HWComposer::setAutoLowLatencyMode(PhysicalDisplayId displayId, bool on) {
RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
const auto error = mDisplayData[displayId].hwcDisplay->setAutoLowLatencyMode(on);
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h
index 4fae06d..9e57602 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.h
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.h
@@ -255,6 +255,12 @@
virtual std::optional<PhysicalDisplayId> toPhysicalDisplayId(hal::HWDisplayId) const = 0;
virtual std::optional<hal::HWDisplayId> fromPhysicalDisplayId(PhysicalDisplayId) const = 0;
+
+ // Composer 3.0
+ virtual bool getBootDisplayModeSupport() = 0;
+ virtual status_t setBootDisplayMode(PhysicalDisplayId, hal::HWConfigId) = 0;
+ virtual status_t clearBootDisplayMode(PhysicalDisplayId) = 0;
+ virtual hal::HWConfigId getPreferredBootDisplayMode(PhysicalDisplayId) = 0;
};
namespace impl {
@@ -381,6 +387,12 @@
const std::unordered_map<std::string, bool>& getSupportedLayerGenericMetadata() const override;
+ // Composer 3.0
+ bool getBootDisplayModeSupport() override;
+ status_t setBootDisplayMode(PhysicalDisplayId, hal::HWConfigId) override;
+ status_t clearBootDisplayMode(PhysicalDisplayId) override;
+ hal::HWConfigId getPreferredBootDisplayMode(PhysicalDisplayId) override;
+
// for debugging ----------------------------------------------------------
void dump(std::string& out) const override;
diff --git a/services/surfaceflinger/DisplayHardware/HidlComposerHal.cpp b/services/surfaceflinger/DisplayHardware/HidlComposerHal.cpp
index 0ab1cfb..d3acecb 100644
--- a/services/surfaceflinger/DisplayHardware/HidlComposerHal.cpp
+++ b/services/surfaceflinger/DisplayHardware/HidlComposerHal.cpp
@@ -162,6 +162,7 @@
return mClient_2_4 != nullptr;
case OptionalFeature::ExpectedPresentTime:
case OptionalFeature::DisplayBrightnessCommand:
+ case OptionalFeature::BootDisplayConfig:
return false;
}
}
@@ -1216,6 +1217,18 @@
return error;
}
+Error HidlComposer::setBootDisplayConfig(Display /*displayId*/, Config) {
+ return Error::UNSUPPORTED;
+}
+
+Error HidlComposer::clearBootDisplayConfig(Display /*displayId*/) {
+ return Error::UNSUPPORTED;
+}
+
+Error HidlComposer::getPreferredBootDisplayConfig(Display /*displayId*/, Config*) {
+ return Error::UNSUPPORTED;
+}
+
Error HidlComposer::getClientTargetProperty(
Display display, IComposerClient::ClientTargetProperty* outClientTargetProperty,
float* outWhitePointNits) {
diff --git a/services/surfaceflinger/DisplayHardware/HidlComposerHal.h b/services/surfaceflinger/DisplayHardware/HidlComposerHal.h
index 8282d8a..c8c7800 100644
--- a/services/surfaceflinger/DisplayHardware/HidlComposerHal.h
+++ b/services/surfaceflinger/DisplayHardware/HidlComposerHal.h
@@ -323,6 +323,9 @@
Error setLayerWhitePointNits(Display display, Layer layer, float whitePointNits) override;
Error setLayerBlockingRegion(Display display, Layer layer,
const std::vector<IComposerClient::Rect>& blocking) override;
+ Error setBootDisplayConfig(Display displayId, Config) override;
+ Error clearBootDisplayConfig(Display displayId) override;
+ Error getPreferredBootDisplayConfig(Display displayId, Config*) override;
private:
class CommandWriter : public CommandWriterBase {
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 63fbe78..e84016f 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -1426,6 +1426,52 @@
return NO_ERROR;
}
+status_t SurfaceFlinger::getBootDisplayModeSupport(bool* outSupport) const {
+ auto future = mScheduler->schedule([=]() MAIN_THREAD mutable -> status_t {
+ *outSupport = getHwComposer().getBootDisplayModeSupport();
+ return NO_ERROR;
+ });
+ return future.get();
+}
+
+status_t SurfaceFlinger::setBootDisplayMode(const sp<IBinder>& displayToken, ui::DisplayModeId id) {
+ auto future = mScheduler->schedule([=]() MAIN_THREAD -> status_t {
+ if (const auto displayId = getPhysicalDisplayIdLocked(displayToken)) {
+ return getHwComposer().setBootDisplayMode(*displayId, id);
+ } else {
+ ALOGE("%s: Invalid display token %p", __FUNCTION__, displayToken.get());
+ return BAD_VALUE;
+ }
+ });
+ return future.get();
+}
+
+status_t SurfaceFlinger::clearBootDisplayMode(const sp<IBinder>& displayToken) {
+ auto future = mScheduler->schedule([=]() MAIN_THREAD -> status_t {
+ if (const auto displayId = getPhysicalDisplayIdLocked(displayToken)) {
+ return getHwComposer().clearBootDisplayMode(*displayId);
+ } else {
+ ALOGE("%s: Invalid display token %p", __FUNCTION__, displayToken.get());
+ return BAD_VALUE;
+ }
+ });
+ return future.get();
+}
+
+status_t SurfaceFlinger::getPreferredBootDisplayMode(const sp<IBinder>& displayToken,
+ ui::DisplayModeId* id) {
+ auto future = mScheduler->schedule([=]() MAIN_THREAD mutable -> status_t {
+ if (const auto displayId = getPhysicalDisplayIdLocked(displayToken)) {
+ *id = getHwComposer().getPreferredBootDisplayMode(*displayId);
+ return NO_ERROR;
+ } else {
+ ALOGE("%s: Invalid display token %p", __FUNCTION__, displayToken.get());
+ return BAD_VALUE;
+ }
+ });
+ return future.get();
+}
+
void SurfaceFlinger::setAutoLowLatencyMode(const sp<IBinder>& displayToken, bool on) {
const char* const whence = __func__;
static_cast<void>(mScheduler->schedule([=]() MAIN_THREAD {
@@ -5404,6 +5450,10 @@
case SET_DESIRED_DISPLAY_MODE_SPECS:
case GET_DESIRED_DISPLAY_MODE_SPECS:
case SET_ACTIVE_COLOR_MODE:
+ case GET_BOOT_DISPLAY_MODE_SUPPORT:
+ case SET_BOOT_DISPLAY_MODE:
+ case CLEAR_BOOT_DISPLAY_MODE:
+ case GET_PREFERRED_BOOT_DISPLAY_MODE:
case GET_AUTO_LOW_LATENCY_MODE_SUPPORT:
case SET_AUTO_LOW_LATENCY_MODE:
case GET_GAME_CONTENT_TYPE_SUPPORT:
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 61cfb4e..08d3463 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -531,6 +531,11 @@
status_t getDisplayNativePrimaries(const sp<IBinder>& displayToken,
ui::DisplayPrimaries&) override;
status_t setActiveColorMode(const sp<IBinder>& displayToken, ui::ColorMode colorMode) override;
+ status_t getBootDisplayModeSupport(bool* outSupport) const override;
+ status_t setBootDisplayMode(const sp<IBinder>& displayToken, ui::DisplayModeId id) override;
+ status_t clearBootDisplayMode(const sp<IBinder>& displayToken) override;
+ status_t getPreferredBootDisplayMode(const sp<IBinder>& displayToken,
+ ui::DisplayModeId* id) override;
void setAutoLowLatencyMode(const sp<IBinder>& displayToken, bool on) override;
void setGameContentType(const sp<IBinder>& displayToken, bool on) override;
void setPowerMode(const sp<IBinder>& displayToken, int mode) override;
diff --git a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h
index ecdadf7..4273401 100644
--- a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h
+++ b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h
@@ -135,6 +135,10 @@
V2_4::Error(Display, Config, const IComposerClient::VsyncPeriodChangeConstraints&,
VsyncPeriodChangeTimeline*));
MOCK_METHOD2(setAutoLowLatencyMode, V2_4::Error(Display, bool));
+ MOCK_METHOD2(getBootDisplayConfigSupport, Error(Display, bool*));
+ MOCK_METHOD2(setBootDisplayConfig, Error(Display, Config));
+ MOCK_METHOD1(clearBootDisplayConfig, Error(Display));
+ MOCK_METHOD2(getPreferredBootDisplayConfig, Error(Display, Config*));
MOCK_METHOD2(getSupportedContentTypes,
V2_4::Error(Display, std::vector<IComposerClient::ContentType>*));
MOCK_METHOD2(setContentType, V2_4::Error(Display, IComposerClient::ContentType));
diff --git a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockHWC2.h b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockHWC2.h
index 7ac0c78..9015944 100644
--- a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockHWC2.h
+++ b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockHWC2.h
@@ -86,6 +86,9 @@
(hal::HWConfigId, const hal::VsyncPeriodChangeConstraints &,
hal::VsyncPeriodChangeTimeline *),
(override));
+ MOCK_METHOD(hal::Error, setBootDisplayConfig, (hal::HWConfigId), (override));
+ MOCK_METHOD(hal::Error, clearBootDisplayConfig, (), (override));
+ MOCK_METHOD(hal::Error, getPreferredBootDisplayConfig, (hal::HWConfigId *), (const, override));
MOCK_METHOD(hal::Error, setAutoLowLatencyMode, (bool), (override));
MOCK_METHOD(hal::Error, getSupportedContentTypes, (std::vector<hal::ContentType> *),
(const, override));