Merge "Update permissions for gpu_work_period tracepoint" into tm-dev
diff --git a/cmds/installd/InstalldNativeService.cpp b/cmds/installd/InstalldNativeService.cpp
index 4e12579..1c5aa4f 100644
--- a/cmds/installd/InstalldNativeService.cpp
+++ b/cmds/installd/InstalldNativeService.cpp
@@ -3429,7 +3429,7 @@
auto temp_path = StringPrintf("%smisc/installd/ioctl_check", android_data_dir.c_str());
if (access(temp_path.c_str(), F_OK) != 0) {
int fd = open(temp_path.c_str(), O_CREAT | O_TRUNC | O_RDWR | O_CLOEXEC, 0644);
- result = set_quota_project_id(temp_path, 0, true) == 0;
+ result = set_quota_project_id(temp_path, 0, false) == 0;
close(fd);
// delete the temp file
remove(temp_path.c_str());
diff --git a/cmds/installd/tests/installd_service_test.cpp b/cmds/installd/tests/installd_service_test.cpp
index 38cb370..162e668 100644
--- a/cmds/installd/tests/installd_service_test.cpp
+++ b/cmds/installd/tests/installd_service_test.cpp
@@ -465,7 +465,7 @@
EXPECT_TRUE(create_cache_path(buf, "/path/to/file.apk", "isa"));
EXPECT_EQ("/data/dalvik-cache/isa/path@to@file.apk@classes.dex", std::string(buf));
}
-TEST_F(ServiceTest, GetAppSize) {
+TEST_F(ServiceTest, GetAppSizeManualForMedia) {
struct stat s;
std::string externalPicDir =
@@ -509,6 +509,97 @@
system(removeCommand.c_str());
}
}
+TEST_F(ServiceTest, GetAppSizeProjectID_UID) {
+ struct stat s;
+ std::string externalPicDir =
+ StringPrintf("%s/Pictures", create_data_media_path(nullptr, 0).c_str());
+ if (stat(externalPicDir.c_str(), &s) == 0) {
+ // fetch the appId from the uid of the external storage owning app
+ int32_t externalStorageAppId = multiuser_get_app_id(s.st_uid);
+ // Fetch Package Name for the external storage owning app uid
+ std::string pkg = get_package_name(s.st_uid);
+
+ std::vector<int64_t> externalStorageSize, externalStorageSizeAfterAddingCacheFile;
+ std::vector<int64_t> ceDataInodes;
+
+ std::vector<std::string> codePaths;
+ std::vector<std::string> packageNames;
+ // set up parameters
+ packageNames.push_back(pkg);
+ ceDataInodes.push_back(0);
+ // initialise the mounts
+ service->invalidateMounts();
+ auto using_project_ids =
+ StringPrintf("%smisc/installd/using_project_ids", android_data_dir.c_str());
+ bool usingProjectIds = access(using_project_ids.c_str(), F_OK) == 0;
+ if (!usingProjectIds) {
+ service->setFirstBoot();
+ }
+
+ if (access(using_project_ids.c_str(), F_OK) != 0) {
+ // projectids is not used, so check that ioctl features should be absent
+ auto temp_path = StringPrintf("%smisc/installd/ioctl_check", android_data_dir.c_str());
+
+ if (access(temp_path.c_str(), F_OK) != 0) {
+ open(temp_path.c_str(), O_CREAT | O_TRUNC | O_RDWR | O_CLOEXEC, 0644);
+ bool result = set_quota_project_id(temp_path, 0, false) == 0;
+ // delete the temp file
+ // remove the external file
+ remove(temp_path.c_str());
+ // since using_project_ids file is not present, so ioctl settings should be absent
+ // that is denoted by the result of setting project id flag as false
+ ASSERT_FALSE(result);
+ }
+ }
+ // call the getAppSize to get the current size of the external storage owning app
+ service->getAppSize(std::nullopt, packageNames, 0, InstalldNativeService::FLAG_USE_QUOTA,
+ externalStorageAppId, ceDataInodes, codePaths, &externalStorageSize);
+ // add a file with 20MB size to the external storage
+ std::string externalStorageCacheDir =
+ StringPrintf("%s/%s/cache", create_data_user_ce_path(nullptr, 0).c_str(),
+ pkg.c_str());
+ std::string cacheFileLocation =
+ StringPrintf("%s/%s", externalStorageCacheDir.c_str(), "External.jpg");
+ std::string externalFileContentCommand =
+ StringPrintf("dd if=/dev/zero of=%s bs=1M count=20", cacheFileLocation.c_str());
+ system(externalFileContentCommand.c_str());
+ // call the getAppSize again to get the new size of the external storage owning app
+ service->getAppSize(std::nullopt, packageNames, 0, InstalldNativeService::FLAG_USE_QUOTA,
+ externalStorageAppId, ceDataInodes, codePaths,
+ &externalStorageSizeAfterAddingCacheFile);
+ // check that the size of cache and data increases when cache file is added
+ int64_t sizeDiffData = externalStorageSizeAfterAddingCacheFile[1] - externalStorageSize[1];
+ int64_t sizeDiffCache = externalStorageSizeAfterAddingCacheFile[2] - externalStorageSize[2];
+ ASSERT_TRUE(sizeDiffData == sizeDiffCache);
+ // remove the external file
+ std::string removeCommand = StringPrintf("rm -f %s", cacheFileLocation.c_str());
+ system(removeCommand.c_str());
+ // remove the setFirstBoot setting
+ std::string removeCommand2 = "rm -f /data/misc/installd/using_project_ids";
+ system(removeCommand2.c_str());
+ // Do now without project id
+ std::vector<int64_t> sizeWithUID, sizeWithUIDAfterAddingCacheFile;
+ // call the getAppSize to get the current size of the external storage owning app
+ service->getAppSize(std::nullopt, packageNames, 0, InstalldNativeService::FLAG_USE_QUOTA,
+ externalStorageAppId, ceDataInodes, codePaths, &sizeWithUID);
+ // add a file with 20MB size to the external storage
+ system(externalFileContentCommand.c_str());
+ // call the getAppSize again to get the new size of the external storage owning app
+ service->getAppSize(std::nullopt, packageNames, 0, InstalldNativeService::FLAG_USE_QUOTA,
+ externalStorageAppId, ceDataInodes, codePaths,
+ &sizeWithUIDAfterAddingCacheFile);
+ // check that the size of cache and data increases when cache file is added
+ sizeDiffData = sizeWithUIDAfterAddingCacheFile[1] - sizeWithUID[1];
+ sizeDiffCache = sizeWithUIDAfterAddingCacheFile[2] - sizeWithUID[2];
+ ASSERT_TRUE(sizeDiffData == sizeDiffCache);
+ // remove the external file
+ system(removeCommand.c_str());
+ // reset the using_project_id if it was initially set
+ if (usingProjectIds) {
+ service->setFirstBoot();
+ }
+ }
+}
TEST_F(ServiceTest, GetAppSizeWrongSizes) {
int32_t externalStorageAppId = -1;
std::vector<int64_t> externalStorageSize;
diff --git a/libs/binder/Binder.cpp b/libs/binder/Binder.cpp
index 01b25d3..39befbe 100644
--- a/libs/binder/Binder.cpp
+++ b/libs/binder/Binder.cpp
@@ -582,6 +582,10 @@
BBinder::~BBinder()
{
+ if (!wasParceled() && getExtension()) {
+ ALOGW("Binder %p destroyed with extension attached before being parceled.", this);
+ }
+
Extras* e = mExtras.load(std::memory_order_relaxed);
if (e) delete e;
}
diff --git a/libs/binder/tests/binderBinderUnitTest.cpp b/libs/binder/tests/binderBinderUnitTest.cpp
index 1be0c59..ce2770f 100644
--- a/libs/binder/tests/binderBinderUnitTest.cpp
+++ b/libs/binder/tests/binderBinderUnitTest.cpp
@@ -41,3 +41,10 @@
EXPECT_EQ(kObject1, binder->detachObject(kObjectId1));
EXPECT_EQ(nullptr, binder->attachObject(kObjectId1, kObject2, nullptr, nullptr));
}
+
+TEST(Binder, AttachExtension) {
+ auto binder = sp<BBinder>::make();
+ auto ext = sp<BBinder>::make();
+ binder->setExtension(ext);
+ EXPECT_EQ(ext, binder->getExtension());
+}
diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp
index 5532c6e..2da48b8 100644
--- a/libs/gui/ISurfaceComposer.cpp
+++ b/libs/gui/ISurfaceComposer.cpp
@@ -226,81 +226,6 @@
return result;
}
- sp<IBinder> createDisplay(const String8& displayName, bool secure) override {
- Parcel data, reply;
- data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
- status_t status = data.writeString8(displayName);
- if (status) {
- return nullptr;
- }
- status = data.writeBool(secure);
- if (status) {
- return nullptr;
- }
-
- status = remote()->transact(BnSurfaceComposer::CREATE_DISPLAY, data, &reply);
- if (status) {
- return nullptr;
- }
- sp<IBinder> display;
- status = reply.readNullableStrongBinder(&display);
- if (status) {
- return nullptr;
- }
- return display;
- }
-
- void destroyDisplay(const sp<IBinder>& display) override {
- Parcel data, reply;
- data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
- data.writeStrongBinder(display);
- remote()->transact(BnSurfaceComposer::DESTROY_DISPLAY, data, &reply);
- }
-
- std::vector<PhysicalDisplayId> getPhysicalDisplayIds() const override {
- Parcel data, reply;
- data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
- if (remote()->transact(BnSurfaceComposer::GET_PHYSICAL_DISPLAY_IDS, data, &reply) ==
- NO_ERROR) {
- std::vector<uint64_t> rawIds;
- if (reply.readUint64Vector(&rawIds) == NO_ERROR) {
- std::vector<PhysicalDisplayId> displayIds;
- displayIds.reserve(rawIds.size());
-
- for (const uint64_t rawId : rawIds) {
- if (const auto id = DisplayId::fromValue<PhysicalDisplayId>(rawId)) {
- displayIds.push_back(*id);
- }
- }
- return displayIds;
- }
- }
-
- return {};
- }
-
- status_t getPrimaryPhysicalDisplayId(PhysicalDisplayId* displayId) const override {
- Parcel data, reply;
- SAFE_PARCEL(data.writeInterfaceToken, ISurfaceComposer::getInterfaceDescriptor());
- SAFE_PARCEL(remote()->transact, BnSurfaceComposer::GET_PRIMARY_PHYSICAL_DISPLAY_ID, data,
- &reply);
- uint64_t rawId;
- SAFE_PARCEL(reply.readUint64, &rawId);
- if (const auto id = DisplayId::fromValue<PhysicalDisplayId>(rawId)) {
- *displayId = *id;
- return NO_ERROR;
- }
- return NAME_NOT_FOUND;
- }
-
- sp<IBinder> getPhysicalDisplayToken(PhysicalDisplayId displayId) const override {
- Parcel data, reply;
- data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
- data.writeUint64(displayId.value);
- remote()->transact(BnSurfaceComposer::GET_PHYSICAL_DISPLAY_TOKEN, data, &reply);
- return reply.readStrongBinder();
- }
-
void setPowerMode(const sp<IBinder>& display, int mode) override {
Parcel data, reply;
data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
@@ -1467,29 +1392,6 @@
reply->writeStrongBinder(IInterface::asBinder(connection));
return NO_ERROR;
}
- case CREATE_DISPLAY: {
- CHECK_INTERFACE(ISurfaceComposer, data, reply);
- String8 displayName;
- SAFE_PARCEL(data.readString8, &displayName);
- bool secure = false;
- SAFE_PARCEL(data.readBool, &secure);
- sp<IBinder> display = createDisplay(displayName, secure);
- SAFE_PARCEL(reply->writeStrongBinder, display);
- return NO_ERROR;
- }
- case DESTROY_DISPLAY: {
- CHECK_INTERFACE(ISurfaceComposer, data, reply);
- sp<IBinder> display = data.readStrongBinder();
- destroyDisplay(display);
- return NO_ERROR;
- }
- case GET_PHYSICAL_DISPLAY_TOKEN: {
- CHECK_INTERFACE(ISurfaceComposer, data, reply);
- const auto id = DisplayId::fromValue<PhysicalDisplayId>(data.readUint64());
- if (!id) return BAD_VALUE;
- reply->writeStrongBinder(getPhysicalDisplayToken(*id));
- return NO_ERROR;
- }
case GET_DISPLAY_STATE: {
CHECK_INTERFACE(ISurfaceComposer, data, reply);
ui::DisplayState state;
@@ -1826,24 +1728,6 @@
}
return error;
}
- case GET_PHYSICAL_DISPLAY_IDS: {
- CHECK_INTERFACE(ISurfaceComposer, data, reply);
- std::vector<PhysicalDisplayId> ids = getPhysicalDisplayIds();
- std::vector<uint64_t> rawIds(ids.size());
- std::transform(ids.begin(), ids.end(), rawIds.begin(),
- [](PhysicalDisplayId id) { return id.value; });
- return reply->writeUint64Vector(rawIds);
- }
- case GET_PRIMARY_PHYSICAL_DISPLAY_ID: {
- CHECK_INTERFACE(ISurfaceComposer, data, reply);
- PhysicalDisplayId id;
- status_t result = getPrimaryPhysicalDisplayId(&id);
- if (result != NO_ERROR) {
- ALOGE("getPrimaryPhysicalDisplayId: Failed to get id");
- return result;
- }
- return reply->writeUint64(id.value);
- }
case ADD_REGION_SAMPLING_LISTENER: {
CHECK_INTERFACE(ISurfaceComposer, data, reply);
Rect samplingArea;
diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp
index 1fb11e0..ff8f529 100644
--- a/libs/gui/Surface.cpp
+++ b/libs/gui/Surface.cpp
@@ -45,6 +45,7 @@
#include <gui/ISurfaceComposer.h>
#include <gui/LayerState.h>
#include <private/gui/ComposerService.h>
+#include <private/gui/ComposerServiceAIDL.h>
namespace android {
@@ -343,7 +344,7 @@
status_t Surface::getWideColorSupport(bool* supported) {
ATRACE_CALL();
- const sp<IBinder> display = composerService()->getInternalDisplayToken();
+ const sp<IBinder> display = ComposerServiceAIDL::getInstance().getInternalDisplayToken();
if (display == nullptr) {
return NAME_NOT_FOUND;
}
@@ -356,7 +357,7 @@
status_t Surface::getHdrSupport(bool* supported) {
ATRACE_CALL();
- const sp<IBinder> display = composerService()->getInternalDisplayToken();
+ const sp<IBinder> display = ComposerServiceAIDL::getInstance().getInternalDisplayToken();
if (display == nullptr) {
return NAME_NOT_FOUND;
}
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index 6c197c4..ec7a948 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -1022,32 +1022,59 @@
// ---------------------------------------------------------------------------
sp<IBinder> SurfaceComposerClient::createDisplay(const String8& displayName, bool secure) {
- return ComposerService::getComposerService()->createDisplay(displayName,
- secure);
+ sp<IBinder> display = nullptr;
+ binder::Status status =
+ ComposerServiceAIDL::getComposerService()->createDisplay(std::string(
+ displayName.string()),
+ secure, &display);
+ return status.isOk() ? display : nullptr;
}
void SurfaceComposerClient::destroyDisplay(const sp<IBinder>& display) {
- return ComposerService::getComposerService()->destroyDisplay(display);
+ ComposerServiceAIDL::getComposerService()->destroyDisplay(display);
}
std::vector<PhysicalDisplayId> SurfaceComposerClient::getPhysicalDisplayIds() {
- return ComposerService::getComposerService()->getPhysicalDisplayIds();
+ std::vector<int64_t> displayIds;
+ std::vector<PhysicalDisplayId> physicalDisplayIds;
+ binder::Status status =
+ ComposerServiceAIDL::getComposerService()->getPhysicalDisplayIds(&displayIds);
+ if (status.isOk()) {
+ physicalDisplayIds.reserve(displayIds.size());
+ for (auto item : displayIds) {
+ auto id = DisplayId::fromValue<PhysicalDisplayId>(static_cast<uint64_t>(item));
+ physicalDisplayIds.push_back(*id);
+ }
+ }
+ return physicalDisplayIds;
}
status_t SurfaceComposerClient::getPrimaryPhysicalDisplayId(PhysicalDisplayId* id) {
- return ComposerService::getComposerService()->getPrimaryPhysicalDisplayId(id);
+ int64_t displayId;
+ binder::Status status =
+ ComposerServiceAIDL::getComposerService()->getPrimaryPhysicalDisplayId(&displayId);
+ if (status.isOk()) {
+ *id = *DisplayId::fromValue<PhysicalDisplayId>(static_cast<uint64_t>(displayId));
+ }
+ return status.transactionError();
}
std::optional<PhysicalDisplayId> SurfaceComposerClient::getInternalDisplayId() {
- return ComposerService::getComposerService()->getInternalDisplayId();
+ ComposerServiceAIDL& instance = ComposerServiceAIDL::getInstance();
+ return instance.getInternalDisplayId();
}
sp<IBinder> SurfaceComposerClient::getPhysicalDisplayToken(PhysicalDisplayId displayId) {
- return ComposerService::getComposerService()->getPhysicalDisplayToken(displayId);
+ sp<IBinder> display = nullptr;
+ binder::Status status =
+ ComposerServiceAIDL::getComposerService()->getPhysicalDisplayToken(displayId.value,
+ &display);
+ return status.isOk() ? display : nullptr;
}
sp<IBinder> SurfaceComposerClient::getInternalDisplayToken() {
- return ComposerService::getComposerService()->getInternalDisplayToken();
+ ComposerServiceAIDL& instance = ComposerServiceAIDL::getInstance();
+ return instance.getInternalDisplayToken();
}
void SurfaceComposerClient::Transaction::setAnimationTransaction() {
diff --git a/libs/gui/aidl/android/gui/ISurfaceComposer.aidl b/libs/gui/aidl/android/gui/ISurfaceComposer.aidl
index 07921a5..345c47d 100644
--- a/libs/gui/aidl/android/gui/ISurfaceComposer.aidl
+++ b/libs/gui/aidl/android/gui/ISurfaceComposer.aidl
@@ -22,6 +22,28 @@
/** @hide */
interface ISurfaceComposer {
+
+ /* create a virtual display
+ * requires ACCESS_SURFACE_FLINGER permission.
+ */
+ @nullable IBinder createDisplay(@utf8InCpp String displayName, boolean secure);
+
+ /* destroy a virtual display
+ * requires ACCESS_SURFACE_FLINGER permission.
+ */
+ void destroyDisplay(IBinder display);
+
+ /* get stable IDs for connected physical displays.
+ */
+ long[] getPhysicalDisplayIds();
+
+ long getPrimaryPhysicalDisplayId();
+
+ /* get token for a physical display given its stable ID obtained via getPhysicalDisplayIds or a
+ * DisplayEventReceiver hotplug event.
+ */
+ @nullable IBinder getPhysicalDisplayToken(long displayId);
+
/**
* Capture the specified screen. This requires READ_FRAME_BUFFER
* permission. This function will fail if there is a secure window on
diff --git a/libs/gui/include/gui/ISurfaceComposer.h b/libs/gui/include/gui/ISurfaceComposer.h
index b11e674..91d44da 100644
--- a/libs/gui/include/gui/ISurfaceComposer.h
+++ b/libs/gui/include/gui/ISurfaceComposer.h
@@ -138,40 +138,6 @@
VsyncSource vsyncSource = eVsyncSourceApp,
EventRegistrationFlags eventRegistration = {}) = 0;
- /* create a virtual display
- * requires ACCESS_SURFACE_FLINGER permission.
- */
- virtual sp<IBinder> createDisplay(const String8& displayName,
- bool secure) = 0;
-
- /* destroy a virtual display
- * requires ACCESS_SURFACE_FLINGER permission.
- */
- virtual void destroyDisplay(const sp<IBinder>& display) = 0;
-
- /* get stable IDs for connected physical displays.
- */
- virtual std::vector<PhysicalDisplayId> getPhysicalDisplayIds() const = 0;
-
- virtual status_t getPrimaryPhysicalDisplayId(PhysicalDisplayId*) const = 0;
-
- // TODO(b/74619554): Remove this stopgap once the framework is display-agnostic.
- std::optional<PhysicalDisplayId> getInternalDisplayId() const {
- const auto displayIds = getPhysicalDisplayIds();
- return displayIds.empty() ? std::nullopt : std::make_optional(displayIds.front());
- }
-
- /* get token for a physical display given its stable ID obtained via getPhysicalDisplayIds or a
- * DisplayEventReceiver hotplug event.
- */
- virtual sp<IBinder> getPhysicalDisplayToken(PhysicalDisplayId displayId) const = 0;
-
- // TODO(b/74619554): Remove this stopgap once the framework is display-agnostic.
- sp<IBinder> getInternalDisplayToken() const {
- const auto displayId = getInternalDisplayId();
- return displayId ? getPhysicalDisplayToken(*displayId) : nullptr;
- }
-
/* open/close transactions. requires ACCESS_SURFACE_FLINGER permission */
virtual status_t setTransactionState(
const FrameTimelineInfo& frameTimelineInfo, const Vector<ComposerState>& state,
@@ -597,9 +563,9 @@
CREATE_CONNECTION,
GET_STATIC_DISPLAY_INFO,
CREATE_DISPLAY_EVENT_CONNECTION,
- CREATE_DISPLAY,
- DESTROY_DISPLAY,
- GET_PHYSICAL_DISPLAY_TOKEN,
+ CREATE_DISPLAY, // Deprecated. Autogenerated by .aidl now.
+ DESTROY_DISPLAY, // Deprecated. Autogenerated by .aidl now.
+ GET_PHYSICAL_DISPLAY_TOKEN, // Deprecated. Autogenerated by .aidl now.
SET_TRANSACTION_STATE,
AUTHENTICATE_SURFACE,
GET_SUPPORTED_FRAME_TIMESTAMPS,
@@ -627,7 +593,7 @@
GET_PROTECTED_CONTENT_SUPPORT,
IS_WIDE_COLOR_DISPLAY,
GET_DISPLAY_NATIVE_PRIMARIES,
- GET_PHYSICAL_DISPLAY_IDS,
+ GET_PHYSICAL_DISPLAY_IDS, // Deprecated. Autogenerated by .aidl now.
ADD_REGION_SAMPLING_LISTENER,
REMOVE_REGION_SAMPLING_LISTENER,
SET_DESIRED_DISPLAY_MODE_SPECS,
@@ -659,7 +625,7 @@
REMOVE_TUNNEL_MODE_ENABLED_LISTENER,
ADD_WINDOW_INFOS_LISTENER,
REMOVE_WINDOW_INFOS_LISTENER,
- GET_PRIMARY_PHYSICAL_DISPLAY_ID,
+ GET_PRIMARY_PHYSICAL_DISPLAY_ID, // Deprecated. Autogenerated by .aidl now.
GET_DISPLAY_DECORATION_SUPPORT,
GET_BOOT_DISPLAY_MODE_SUPPORT,
SET_BOOT_DISPLAY_MODE,
diff --git a/libs/gui/include/private/gui/ComposerServiceAIDL.h b/libs/gui/include/private/gui/ComposerServiceAIDL.h
index fee37ee..b32cf2a 100644
--- a/libs/gui/include/private/gui/ComposerServiceAIDL.h
+++ b/libs/gui/include/private/gui/ComposerServiceAIDL.h
@@ -50,6 +50,27 @@
// Get a connection to the Composer Service. This will block until
// a connection is established. Returns null if permission is denied.
static sp<gui::ISurfaceComposer> getComposerService();
+
+ // the following two methods are moved from ISurfaceComposer.h
+ // TODO(b/74619554): Remove this stopgap once the framework is display-agnostic.
+ std::optional<PhysicalDisplayId> getInternalDisplayId() const {
+ std::vector<int64_t> displayIds;
+ binder::Status status = mComposerService->getPhysicalDisplayIds(&displayIds);
+ return (!status.isOk() || displayIds.empty())
+ ? std::nullopt
+ : DisplayId::fromValue<PhysicalDisplayId>(
+ static_cast<uint64_t>(displayIds.front()));
+ }
+
+ // TODO(b/74619554): Remove this stopgap once the framework is display-agnostic.
+ sp<IBinder> getInternalDisplayToken() const {
+ const auto displayId = getInternalDisplayId();
+ if (!displayId) return nullptr;
+ sp<IBinder> display;
+ binder::Status status =
+ mComposerService->getPhysicalDisplayToken(displayId->value, &display);
+ return status.isOk() ? display : nullptr;
+ }
};
// ---------------------------------------------------------------------------
diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp
index a885e92..07ac2d4 100644
--- a/libs/gui/tests/Surface_test.cpp
+++ b/libs/gui/tests/Surface_test.cpp
@@ -260,9 +260,7 @@
sp<ANativeWindow> anw(mSurface);
// Verify the screenshot works with no protected buffers.
- sp<ISurfaceComposer> sf(ComposerService::getComposerService());
-
- const sp<IBinder> display = sf->getInternalDisplayToken();
+ const sp<IBinder> display = ComposerServiceAIDL::getInstance().getInternalDisplayToken();
ASSERT_FALSE(display == nullptr);
DisplayCaptureArgs captureArgs;
@@ -696,12 +694,6 @@
ISurfaceComposer::VsyncSource, ISurfaceComposer::EventRegistrationFlags) override {
return nullptr;
}
- sp<IBinder> createDisplay(const String8& /*displayName*/,
- bool /*secure*/) override { return nullptr; }
- void destroyDisplay(const sp<IBinder>& /*display */) override {}
- std::vector<PhysicalDisplayId> getPhysicalDisplayIds() const override { return {}; }
- status_t getPrimaryPhysicalDisplayId(PhysicalDisplayId*) const override { return NO_ERROR; }
- sp<IBinder> getPhysicalDisplayToken(PhysicalDisplayId) const override { return nullptr; }
status_t setTransactionState(const FrameTimelineInfo& /*frameTimelineInfo*/,
const Vector<ComposerState>& /*state*/,
const Vector<DisplayState>& /*displays*/, uint32_t /*flags*/,
diff --git a/libs/renderengine/Android.bp b/libs/renderengine/Android.bp
index 84e84dd..cb92df3 100644
--- a/libs/renderengine/Android.bp
+++ b/libs/renderengine/Android.bp
@@ -27,6 +27,7 @@
"-DEGL_EGLEXT_PROTOTYPES",
],
shared_libs: [
+ "android.hardware.graphics.composer3-V1-ndk",
"libbase",
"libcutils",
"libEGL",
diff --git a/libs/renderengine/benchmark/Android.bp b/libs/renderengine/benchmark/Android.bp
index 471159f..249fec5 100644
--- a/libs/renderengine/benchmark/Android.bp
+++ b/libs/renderengine/benchmark/Android.bp
@@ -43,6 +43,7 @@
],
shared_libs: [
+ "android.hardware.graphics.composer3-V1-ndk",
"libbase",
"libcutils",
"libjnigraphics",
diff --git a/libs/renderengine/include/renderengine/DisplaySettings.h b/libs/renderengine/include/renderengine/DisplaySettings.h
index 40ba5ad..bf50644 100644
--- a/libs/renderengine/include/renderengine/DisplaySettings.h
+++ b/libs/renderengine/include/renderengine/DisplaySettings.h
@@ -16,6 +16,7 @@
#pragma once
+#include <aidl/android/hardware/graphics/composer3/DimmingStage.h>
#include <iosfwd>
#include <math/mat4.h>
@@ -68,6 +69,10 @@
// All layers will be dimmed by (max(layer white points) / targetLuminanceNits).
// If the target luminance is unknown, then no display-level dimming occurs.
float targetLuminanceNits = -1.f;
+
+ // Configures when dimming should be applied for each layer.
+ aidl::android::hardware::graphics::composer3::DimmingStage dimmingStage =
+ aidl::android::hardware::graphics::composer3::DimmingStage::NONE;
};
static inline bool operator==(const DisplaySettings& lhs, const DisplaySettings& rhs) {
diff --git a/libs/renderengine/skia/SkiaGLRenderEngine.cpp b/libs/renderengine/skia/SkiaGLRenderEngine.cpp
index df9f8ab..a77a798 100644
--- a/libs/renderengine/skia/SkiaGLRenderEngine.cpp
+++ b/libs/renderengine/skia/SkiaGLRenderEngine.cpp
@@ -737,7 +737,9 @@
return roundedRect;
}
-static bool equalsWithinMargin(float expected, float value, float margin) {
+// Arbitrary default margin which should be close enough to zero.
+constexpr float kDefaultMargin = 0.0001f;
+static bool equalsWithinMargin(float expected, float value, float margin = kDefaultMargin) {
LOG_ALWAYS_FATAL_IF(margin < 0.f, "Margin is negative!");
return std::abs(expected - value) < margin;
}
@@ -995,10 +997,13 @@
? displayDimmingRatio
: (layer.whitePointNits / maxLayerWhitePoint) * displayDimmingRatio;
+ const bool dimInLinearSpace = display.dimmingStage !=
+ aidl::android::hardware::graphics::composer3::DimmingStage::GAMMA_OETF;
+
const bool requiresLinearEffect = layer.colorTransform != mat4() ||
(mUseColorManagement &&
needsToneMapping(layer.sourceDataspace, display.outputDataspace)) ||
- !equalsWithinMargin(1.f, layerDimmingRatio, 0.001f);
+ (dimInLinearSpace && !equalsWithinMargin(1.f, layerDimmingRatio));
// quick abort from drawing the remaining portion of the layer
if (layer.skipContentDraw ||
@@ -1104,7 +1109,9 @@
.undoPremultipliedAlpha = !item.isOpaque &&
item.usePremultipliedAlpha,
.requiresLinearEffect = requiresLinearEffect,
- .layerDimmingRatio = layerDimmingRatio}));
+ .layerDimmingRatio = dimInLinearSpace
+ ? layerDimmingRatio
+ : 1.f}));
// Turn on dithering when dimming beyond this (arbitrary) threshold...
static constexpr float kDimmingThreshold = 0.2f;
@@ -1177,7 +1184,20 @@
// An A8 buffer will already have the proper color filter attached to
// its paint, including the displayColorTransform as needed.
if (!paint.getColorFilter()) {
- paint.setColorFilter(displayColorTransform);
+ if (!dimInLinearSpace && !equalsWithinMargin(1.0, layerDimmingRatio)) {
+ // If we don't dim in linear space, then when we gamma correct the dimming ratio we
+ // can assume a gamma 2.2 transfer function.
+ static constexpr float kInverseGamma22 = 1.f / 2.2f;
+ const auto gammaCorrectedDimmingRatio =
+ std::pow(layerDimmingRatio, kInverseGamma22);
+ const auto dimmingMatrix =
+ mat4::scale(vec4(gammaCorrectedDimmingRatio, gammaCorrectedDimmingRatio,
+ gammaCorrectedDimmingRatio, 1.f));
+ paint.setColorFilter(SkColorFilters::Matrix(
+ toSkColorMatrix(display.colorTransform * dimmingMatrix)));
+ } else {
+ paint.setColorFilter(displayColorTransform);
+ }
}
if (!roundRectClip.isEmpty()) {
diff --git a/libs/renderengine/tests/Android.bp b/libs/renderengine/tests/Android.bp
index d91af1e..e66fee1 100644
--- a/libs/renderengine/tests/Android.bp
+++ b/libs/renderengine/tests/Android.bp
@@ -47,6 +47,7 @@
],
shared_libs: [
+ "android.hardware.graphics.composer3-V1-ndk",
"libbase",
"libcutils",
"libEGL",
diff --git a/libs/renderengine/tests/RenderEngineTest.cpp b/libs/renderengine/tests/RenderEngineTest.cpp
index 38ae2fd..2493242 100644
--- a/libs/renderengine/tests/RenderEngineTest.cpp
+++ b/libs/renderengine/tests/RenderEngineTest.cpp
@@ -2405,15 +2405,18 @@
TEST_P(RenderEngineTest, testDimming) {
if (GetParam()->type() == renderengine::RenderEngine::RenderEngineType::GLES) {
- return;
+ GTEST_SKIP();
}
+
initializeRenderEngine();
+ const ui::Dataspace dataspace = ui::Dataspace::V0_SRGB_LINEAR;
+
const auto displayRect = Rect(3, 1);
const renderengine::DisplaySettings display{
.physicalDisplay = displayRect,
.clip = displayRect,
- .outputDataspace = ui::Dataspace::V0_SRGB_LINEAR,
+ .outputDataspace = dataspace,
.targetLuminanceNits = 1000.f,
};
@@ -2432,7 +2435,7 @@
},
},
.alpha = 1.0f,
- .sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR,
+ .sourceDataspace = dataspace,
.whitePointNits = 200.f,
};
@@ -2447,7 +2450,7 @@
},
},
.alpha = 1.0f,
- .sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR,
+ .sourceDataspace = dataspace,
.whitePointNits = 1000.f / 51.f,
};
@@ -2462,7 +2465,7 @@
},
},
.alpha = 1.0f,
- .sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR,
+ .sourceDataspace = dataspace,
// When the white point is not set for a layer, just ignore it and treat it as the same
// as the max layer
.whitePointNits = -1.f,
@@ -2476,6 +2479,84 @@
expectBufferColor(Rect(2, 0, 3, 1), 51, 0, 0, 255, 1);
}
+TEST_P(RenderEngineTest, testDimming_inGammaSpace) {
+ if (GetParam()->type() == renderengine::RenderEngine::RenderEngineType::GLES) {
+ GTEST_SKIP();
+ }
+ initializeRenderEngine();
+
+ const ui::Dataspace dataspace = static_cast<ui::Dataspace>(ui::Dataspace::STANDARD_BT709 |
+ ui::Dataspace::TRANSFER_GAMMA2_2 |
+ ui::Dataspace::RANGE_FULL);
+
+ const auto displayRect = Rect(3, 1);
+ const renderengine::DisplaySettings display{
+ .physicalDisplay = displayRect,
+ .clip = displayRect,
+ .outputDataspace = dataspace,
+ .targetLuminanceNits = 1000.f,
+ .dimmingStage = aidl::android::hardware::graphics::composer3::DimmingStage::GAMMA_OETF,
+ };
+
+ const auto greenBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 255, 0, 255));
+ const auto blueBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 0, 255, 255));
+ const auto redBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(255, 0, 0, 255));
+
+ const renderengine::LayerSettings greenLayer{
+ .geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f),
+ .source =
+ renderengine::PixelSource{
+ .buffer =
+ renderengine::Buffer{
+ .buffer = greenBuffer,
+ .usePremultipliedAlpha = true,
+ },
+ },
+ .alpha = 1.0f,
+ .sourceDataspace = dataspace,
+ .whitePointNits = 200.f,
+ };
+
+ const renderengine::LayerSettings blueLayer{
+ .geometry.boundaries = FloatRect(1.f, 0.f, 2.f, 1.f),
+ .source =
+ renderengine::PixelSource{
+ .buffer =
+ renderengine::Buffer{
+ .buffer = blueBuffer,
+ .usePremultipliedAlpha = true,
+ },
+ },
+ .alpha = 1.0f,
+ .sourceDataspace = dataspace,
+ .whitePointNits = 1000.f / 51.f,
+ };
+
+ const renderengine::LayerSettings redLayer{
+ .geometry.boundaries = FloatRect(2.f, 0.f, 3.f, 1.f),
+ .source =
+ renderengine::PixelSource{
+ .buffer =
+ renderengine::Buffer{
+ .buffer = redBuffer,
+ .usePremultipliedAlpha = true,
+ },
+ },
+ .alpha = 1.0f,
+ .sourceDataspace = dataspace,
+ // When the white point is not set for a layer, just ignore it and treat it as the same
+ // as the max layer
+ .whitePointNits = -1.f,
+ };
+
+ std::vector<renderengine::LayerSettings> layers{greenLayer, blueLayer, redLayer};
+ invokeDraw(display, layers);
+
+ expectBufferColor(Rect(1, 1), 0, 122, 0, 255, 1);
+ expectBufferColor(Rect(1, 0, 2, 1), 0, 0, 42, 255, 1);
+ expectBufferColor(Rect(2, 0, 3, 1), 122, 0, 0, 255, 1);
+}
+
TEST_P(RenderEngineTest, testDimming_withoutTargetLuminance) {
initializeRenderEngine();
if (GetParam()->type() == renderengine::RenderEngine::RenderEngineType::GLES) {
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Display.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Display.h
index e12d1b4..8bb8e92 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Display.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Display.h
@@ -77,7 +77,7 @@
virtual void applyChangedTypesToLayers(const ChangedTypes&);
virtual void applyDisplayRequests(const DisplayRequests&);
virtual void applyLayerRequestsToLayers(const LayerRequests&);
- virtual void applyClientTargetRequests(const ClientTargetProperty&, float brightness);
+ virtual void applyClientTargetRequests(const ClientTargetProperty&);
// Internal
virtual void setConfiguration(const compositionengine::DisplayCreationArgs&);
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputCompositionState.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputCompositionState.h
index 66dd825..2438f80 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputCompositionState.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputCompositionState.h
@@ -17,6 +17,7 @@
#pragma once
#include <cstdint>
+#include "aidl/android/hardware/graphics/composer3/DimmingStage.h"
#include <math/mat4.h>
#include <ui/FenceTime.h>
@@ -133,6 +134,10 @@
// Brightness of the client target, normalized to display brightness
float clientTargetBrightness{1.f};
+ // Stage in which the client target should apply dimming
+ aidl::android::hardware::graphics::composer3::DimmingStage clientTargetDimmingStage{
+ aidl::android::hardware::graphics::composer3::DimmingStage::NONE};
+
// Display brightness that will take effect this frame.
// This is slightly distinct from nits, in that nits cannot be passed to hw composer.
std::optional<float> displayBrightness = std::nullopt;
diff --git a/services/surfaceflinger/CompositionEngine/src/Display.cpp b/services/surfaceflinger/CompositionEngine/src/Display.cpp
index 2165e1d..54daf38 100644
--- a/services/surfaceflinger/CompositionEngine/src/Display.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/Display.cpp
@@ -252,7 +252,7 @@
applyChangedTypesToLayers(changes->changedTypes);
applyDisplayRequests(changes->displayRequests);
applyLayerRequestsToLayers(changes->layerRequests);
- applyClientTargetRequests(changes->clientTargetProperty, changes->clientTargetBrightness);
+ applyClientTargetRequests(changes->clientTargetProperty);
}
// Determine what type of composition we are doing from the final state
@@ -327,16 +327,19 @@
}
}
-void Display::applyClientTargetRequests(const ClientTargetProperty& clientTargetProperty,
- float brightness) {
- if (clientTargetProperty.dataspace == ui::Dataspace::UNKNOWN) {
+void Display::applyClientTargetRequests(const ClientTargetProperty& clientTargetProperty) {
+ if (static_cast<ui::Dataspace>(clientTargetProperty.clientTargetProperty.dataspace) ==
+ ui::Dataspace::UNKNOWN) {
return;
}
- editState().dataspace = clientTargetProperty.dataspace;
- editState().clientTargetBrightness = brightness;
- getRenderSurface()->setBufferDataspace(clientTargetProperty.dataspace);
- getRenderSurface()->setBufferPixelFormat(clientTargetProperty.pixelFormat);
+ editState().dataspace =
+ static_cast<ui::Dataspace>(clientTargetProperty.clientTargetProperty.dataspace);
+ editState().clientTargetBrightness = clientTargetProperty.brightness;
+ editState().clientTargetDimmingStage = clientTargetProperty.dimmingStage;
+ getRenderSurface()->setBufferDataspace(editState().dataspace);
+ getRenderSurface()->setBufferPixelFormat(
+ static_cast<ui::PixelFormat>(clientTargetProperty.clientTargetProperty.pixelFormat));
}
compositionengine::Output::FrameFences Display::presentAndGetFrameFences() {
diff --git a/services/surfaceflinger/CompositionEngine/src/Output.cpp b/services/surfaceflinger/CompositionEngine/src/Output.cpp
index 4e67a63..25155b9 100644
--- a/services/surfaceflinger/CompositionEngine/src/Output.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/Output.cpp
@@ -1080,6 +1080,7 @@
mDisplayColorProfile->getHdrCapabilities().getDesiredMaxLuminance();
clientCompositionDisplay.targetLuminanceNits =
outputState.clientTargetBrightness * outputState.displayBrightnessNits;
+ clientCompositionDisplay.dimmingStage = outputState.clientTargetDimmingStage;
// Compute the global color transform matrix.
clientCompositionDisplay.colorTransform = outputState.colorTransformMatrix;
diff --git a/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp b/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp
index 5cc0f97..d2c945c 100644
--- a/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp
@@ -634,8 +634,11 @@
{{nullptr, Composition::CLIENT}},
hal::DisplayRequest::FLIP_CLIENT_TARGET,
{{nullptr, hal::LayerRequest::CLEAR_CLIENT_TARGET}},
- {hal::PixelFormat::RGBA_8888, hal::Dataspace::UNKNOWN},
- -1.f,
+ {.clientTargetProperty =
+ {aidl::android::hardware::graphics::common::PixelFormat::RGBA_8888,
+ aidl::android::hardware::graphics::common::Dataspace::UNKNOWN},
+ .brightness = -1.f,
+ .dimmingStage = aidl::android::hardware::graphics::composer3::DimmingStage::NONE},
};
// Since two calls are made to anyLayersRequireClientComposition with different return
@@ -822,23 +825,37 @@
using DisplayApplyClientTargetRequests = DisplayWithLayersTestCommon;
TEST_F(DisplayApplyLayerRequestsToLayersTest, applyClientTargetRequests) {
- Display::ClientTargetProperty clientTargetProperty = {
- .pixelFormat = hal::PixelFormat::RGB_565,
- .dataspace = hal::Dataspace::STANDARD_BT470M,
- };
-
static constexpr float kWhitePointNits = 800.f;
+ Display::ClientTargetProperty clientTargetProperty = {
+ .clientTargetProperty =
+ {
+ .pixelFormat =
+ aidl::android::hardware::graphics::common::PixelFormat::RGB_565,
+ .dataspace = aidl::android::hardware::graphics::common::Dataspace::
+ STANDARD_BT470M,
+ },
+ .brightness = kWhitePointNits,
+ .dimmingStage = aidl::android::hardware::graphics::composer3::DimmingStage::GAMMA_OETF,
+ };
+
mock::RenderSurface* renderSurface = new StrictMock<mock::RenderSurface>();
mDisplay->setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(renderSurface));
- EXPECT_CALL(*renderSurface, setBufferPixelFormat(clientTargetProperty.pixelFormat));
- EXPECT_CALL(*renderSurface, setBufferDataspace(clientTargetProperty.dataspace));
- mDisplay->applyClientTargetRequests(clientTargetProperty, kWhitePointNits);
+ EXPECT_CALL(*renderSurface,
+ setBufferPixelFormat(static_cast<ui::PixelFormat>(
+ clientTargetProperty.clientTargetProperty.pixelFormat)));
+ EXPECT_CALL(*renderSurface,
+ setBufferDataspace(static_cast<ui::Dataspace>(
+ clientTargetProperty.clientTargetProperty.dataspace)));
+ mDisplay->applyClientTargetRequests(clientTargetProperty);
auto& state = mDisplay->getState();
- EXPECT_EQ(clientTargetProperty.dataspace, state.dataspace);
+ EXPECT_EQ(clientTargetProperty.clientTargetProperty.dataspace,
+ static_cast<aidl::android::hardware::graphics::common::Dataspace>(state.dataspace));
EXPECT_EQ(kWhitePointNits, state.clientTargetBrightness);
+ EXPECT_EQ(aidl::android::hardware::graphics::composer3::DimmingStage::GAMMA_OETF,
+ state.clientTargetDimmingStage);
}
/*
diff --git a/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp b/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
index dd3858b..66f3753 100644
--- a/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
@@ -3475,6 +3475,15 @@
: public CallOrderStateMachineHelper<TestType, OutputWithDisplayBrightnessNits> {
auto withDisplayBrightnessNits(float nits) {
getInstance()->mOutput.mState.displayBrightnessNits = nits;
+ return nextState<OutputWithDimmingStage>();
+ }
+ };
+
+ struct OutputWithDimmingStage
+ : public CallOrderStateMachineHelper<TestType, OutputWithDimmingStage> {
+ auto withDimmingStage(
+ aidl::android::hardware::graphics::composer3::DimmingStage dimmingStage) {
+ getInstance()->mOutput.mState.clientTargetDimmingStage = dimmingStage;
return nextState<SkipColorTransformState>();
}
};
@@ -3507,16 +3516,20 @@
verify().ifMixedCompositionIs(true)
.andIfUsesHdr(true)
.withDisplayBrightnessNits(kUnknownLuminance)
+ .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
.andIfSkipColorTransform(false)
- .thenExpectDisplaySettingsUsed({.physicalDisplay = kDefaultOutputDestinationClip,
- .clip = kDefaultOutputViewport,
- .maxLuminance = kDefaultMaxLuminance,
- .currentLuminanceNits = kDefaultMaxLuminance,
- .outputDataspace = kDefaultOutputDataspace,
- .colorTransform = kDefaultColorTransformMat,
- .deviceHandlesColorTransform = true,
- .orientation = kDefaultOutputOrientationFlags,
- .targetLuminanceNits = kClientTargetLuminanceNits})
+ .thenExpectDisplaySettingsUsed(
+ {.physicalDisplay = kDefaultOutputDestinationClip,
+ .clip = kDefaultOutputViewport,
+ .maxLuminance = kDefaultMaxLuminance,
+ .currentLuminanceNits = kDefaultMaxLuminance,
+ .outputDataspace = kDefaultOutputDataspace,
+ .colorTransform = kDefaultColorTransformMat,
+ .deviceHandlesColorTransform = true,
+ .orientation = kDefaultOutputOrientationFlags,
+ .targetLuminanceNits = kClientTargetLuminanceNits,
+ .dimmingStage =
+ aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR})
.execute()
.expectAFenceWasReturned();
}
@@ -3526,16 +3539,45 @@
verify().ifMixedCompositionIs(true)
.andIfUsesHdr(true)
.withDisplayBrightnessNits(kDisplayLuminance)
+ .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
+
+ .andIfSkipColorTransform(false)
+ .thenExpectDisplaySettingsUsed(
+ {.physicalDisplay = kDefaultOutputDestinationClip,
+ .clip = kDefaultOutputViewport,
+ .maxLuminance = kDefaultMaxLuminance,
+ .currentLuminanceNits = kDisplayLuminance,
+ .outputDataspace = kDefaultOutputDataspace,
+ .colorTransform = kDefaultColorTransformMat,
+ .deviceHandlesColorTransform = true,
+ .orientation = kDefaultOutputOrientationFlags,
+ .targetLuminanceNits = kClientTargetLuminanceNits,
+ .dimmingStage =
+ aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR})
+ .execute()
+ .expectAFenceWasReturned();
+}
+
+TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
+ forHdrMixedCompositionWithDimmingStage) {
+ verify().ifMixedCompositionIs(true)
+ .andIfUsesHdr(true)
+ .withDisplayBrightnessNits(kUnknownLuminance)
+ .withDimmingStage(
+ aidl::android::hardware::graphics::composer3::DimmingStage::GAMMA_OETF)
+
.andIfSkipColorTransform(false)
.thenExpectDisplaySettingsUsed({.physicalDisplay = kDefaultOutputDestinationClip,
.clip = kDefaultOutputViewport,
.maxLuminance = kDefaultMaxLuminance,
- .currentLuminanceNits = kDisplayLuminance,
+ .currentLuminanceNits = kDefaultMaxLuminance,
.outputDataspace = kDefaultOutputDataspace,
.colorTransform = kDefaultColorTransformMat,
.deviceHandlesColorTransform = true,
.orientation = kDefaultOutputOrientationFlags,
- .targetLuminanceNits = kClientTargetLuminanceNits})
+ .targetLuminanceNits = kClientTargetLuminanceNits,
+ .dimmingStage = aidl::android::hardware::graphics::
+ composer3::DimmingStage::GAMMA_OETF})
.execute()
.expectAFenceWasReturned();
}
@@ -3544,16 +3586,21 @@
verify().ifMixedCompositionIs(true)
.andIfUsesHdr(false)
.withDisplayBrightnessNits(kUnknownLuminance)
+ .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
+
.andIfSkipColorTransform(false)
- .thenExpectDisplaySettingsUsed({.physicalDisplay = kDefaultOutputDestinationClip,
- .clip = kDefaultOutputViewport,
- .maxLuminance = kDefaultMaxLuminance,
- .currentLuminanceNits = kDefaultMaxLuminance,
- .outputDataspace = kDefaultOutputDataspace,
- .colorTransform = kDefaultColorTransformMat,
- .deviceHandlesColorTransform = true,
- .orientation = kDefaultOutputOrientationFlags,
- .targetLuminanceNits = kClientTargetLuminanceNits})
+ .thenExpectDisplaySettingsUsed(
+ {.physicalDisplay = kDefaultOutputDestinationClip,
+ .clip = kDefaultOutputViewport,
+ .maxLuminance = kDefaultMaxLuminance,
+ .currentLuminanceNits = kDefaultMaxLuminance,
+ .outputDataspace = kDefaultOutputDataspace,
+ .colorTransform = kDefaultColorTransformMat,
+ .deviceHandlesColorTransform = true,
+ .orientation = kDefaultOutputOrientationFlags,
+ .targetLuminanceNits = kClientTargetLuminanceNits,
+ .dimmingStage =
+ aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR})
.execute()
.expectAFenceWasReturned();
}
@@ -3562,16 +3609,21 @@
verify().ifMixedCompositionIs(false)
.andIfUsesHdr(true)
.withDisplayBrightnessNits(kUnknownLuminance)
+ .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
+
.andIfSkipColorTransform(false)
- .thenExpectDisplaySettingsUsed({.physicalDisplay = kDefaultOutputDestinationClip,
- .clip = kDefaultOutputViewport,
- .maxLuminance = kDefaultMaxLuminance,
- .currentLuminanceNits = kDefaultMaxLuminance,
- .outputDataspace = kDefaultOutputDataspace,
- .colorTransform = kDefaultColorTransformMat,
- .deviceHandlesColorTransform = false,
- .orientation = kDefaultOutputOrientationFlags,
- .targetLuminanceNits = kClientTargetLuminanceNits})
+ .thenExpectDisplaySettingsUsed(
+ {.physicalDisplay = kDefaultOutputDestinationClip,
+ .clip = kDefaultOutputViewport,
+ .maxLuminance = kDefaultMaxLuminance,
+ .currentLuminanceNits = kDefaultMaxLuminance,
+ .outputDataspace = kDefaultOutputDataspace,
+ .colorTransform = kDefaultColorTransformMat,
+ .deviceHandlesColorTransform = false,
+ .orientation = kDefaultOutputOrientationFlags,
+ .targetLuminanceNits = kClientTargetLuminanceNits,
+ .dimmingStage =
+ aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR})
.execute()
.expectAFenceWasReturned();
}
@@ -3580,16 +3632,21 @@
verify().ifMixedCompositionIs(false)
.andIfUsesHdr(false)
.withDisplayBrightnessNits(kUnknownLuminance)
+ .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
+
.andIfSkipColorTransform(false)
- .thenExpectDisplaySettingsUsed({.physicalDisplay = kDefaultOutputDestinationClip,
- .clip = kDefaultOutputViewport,
- .maxLuminance = kDefaultMaxLuminance,
- .currentLuminanceNits = kDefaultMaxLuminance,
- .outputDataspace = kDefaultOutputDataspace,
- .colorTransform = kDefaultColorTransformMat,
- .deviceHandlesColorTransform = false,
- .orientation = kDefaultOutputOrientationFlags,
- .targetLuminanceNits = kClientTargetLuminanceNits})
+ .thenExpectDisplaySettingsUsed(
+ {.physicalDisplay = kDefaultOutputDestinationClip,
+ .clip = kDefaultOutputViewport,
+ .maxLuminance = kDefaultMaxLuminance,
+ .currentLuminanceNits = kDefaultMaxLuminance,
+ .outputDataspace = kDefaultOutputDataspace,
+ .colorTransform = kDefaultColorTransformMat,
+ .deviceHandlesColorTransform = false,
+ .orientation = kDefaultOutputOrientationFlags,
+ .targetLuminanceNits = kClientTargetLuminanceNits,
+ .dimmingStage =
+ aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR})
.execute()
.expectAFenceWasReturned();
}
@@ -3599,16 +3656,21 @@
verify().ifMixedCompositionIs(false)
.andIfUsesHdr(true)
.withDisplayBrightnessNits(kUnknownLuminance)
+ .withDimmingStage(aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR)
+
.andIfSkipColorTransform(true)
- .thenExpectDisplaySettingsUsed({.physicalDisplay = kDefaultOutputDestinationClip,
- .clip = kDefaultOutputViewport,
- .maxLuminance = kDefaultMaxLuminance,
- .currentLuminanceNits = kDefaultMaxLuminance,
- .outputDataspace = kDefaultOutputDataspace,
- .colorTransform = kDefaultColorTransformMat,
- .deviceHandlesColorTransform = true,
- .orientation = kDefaultOutputOrientationFlags,
- .targetLuminanceNits = kClientTargetLuminanceNits})
+ .thenExpectDisplaySettingsUsed(
+ {.physicalDisplay = kDefaultOutputDestinationClip,
+ .clip = kDefaultOutputViewport,
+ .maxLuminance = kDefaultMaxLuminance,
+ .currentLuminanceNits = kDefaultMaxLuminance,
+ .outputDataspace = kDefaultOutputDataspace,
+ .colorTransform = kDefaultColorTransformMat,
+ .deviceHandlesColorTransform = true,
+ .orientation = kDefaultOutputOrientationFlags,
+ .targetLuminanceNits = kClientTargetLuminanceNits,
+ .dimmingStage =
+ aidl::android::hardware::graphics::composer3::DimmingStage::LINEAR})
.execute()
.expectAFenceWasReturned();
}
diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp
index f5a4b3d..9116fd3 100644
--- a/services/surfaceflinger/DisplayDevice.cpp
+++ b/services/surfaceflinger/DisplayDevice.cpp
@@ -471,9 +471,8 @@
return;
}
- const auto [lowFps, highFps] = mRefreshRateConfigs->getSupportedRefreshRateRange();
- mRefreshRateOverlay = std::make_unique<RefreshRateOverlay>(*mFlinger, lowFps.getIntValue(),
- highFps.getIntValue(), showSpinnner);
+ const auto fpsRange = mRefreshRateConfigs->getSupportedRefreshRateRange();
+ mRefreshRateOverlay = std::make_unique<RefreshRateOverlay>(fpsRange, showSpinnner);
mRefreshRateOverlay->setLayerStack(getLayerStack());
mRefreshRateOverlay->setViewport(getSize());
mRefreshRateOverlay->changeRefreshRate(getActiveMode()->getFps());
diff --git a/services/surfaceflinger/DisplayHardware/AidlComposerHal.cpp b/services/surfaceflinger/DisplayHardware/AidlComposerHal.cpp
index 297a776..117540d 100644
--- a/services/surfaceflinger/DisplayHardware/AidlComposerHal.cpp
+++ b/services/surfaceflinger/DisplayHardware/AidlComposerHal.cpp
@@ -41,6 +41,7 @@
using aidl::android::hardware::graphics::composer3::BnComposerCallback;
using aidl::android::hardware::graphics::composer3::Capability;
+using aidl::android::hardware::graphics::composer3::ClientTargetPropertyWithBrightness;
using aidl::android::hardware::graphics::composer3::PowerMode;
using aidl::android::hardware::graphics::composer3::VirtualDisplay;
@@ -155,15 +156,6 @@
.refreshTimeNanos = x.refreshTimeNanos,
};
}
-
-template <>
-IComposerClient::ClientTargetProperty translate(ClientTargetProperty x) {
- return IComposerClient::ClientTargetProperty{
- .pixelFormat = translate<PixelFormat>(x.pixelFormat),
- .dataspace = translate<Dataspace>(x.dataspace),
- };
-}
-
mat4 makeMat4(std::vector<float> in) {
return mat4(static_cast<const float*>(in.data()));
}
@@ -1082,12 +1074,8 @@
}
Error AidlComposer::getClientTargetProperty(
- Display display, IComposerClient::ClientTargetProperty* outClientTargetProperty,
- float* outBrightness) {
- const auto property = mReader.takeClientTargetProperty(translate<int64_t>(display));
- *outClientTargetProperty =
- translate<IComposerClient::ClientTargetProperty>(property.clientTargetProperty);
- *outBrightness = property.brightness;
+ Display display, ClientTargetPropertyWithBrightness* outClientTargetProperty) {
+ *outClientTargetProperty = mReader.takeClientTargetProperty(translate<int64_t>(display));
return Error::NONE;
}
diff --git a/services/surfaceflinger/DisplayHardware/AidlComposerHal.h b/services/surfaceflinger/DisplayHardware/AidlComposerHal.h
index 28ff167..0099024 100644
--- a/services/surfaceflinger/DisplayHardware/AidlComposerHal.h
+++ b/services/surfaceflinger/DisplayHardware/AidlComposerHal.h
@@ -208,9 +208,10 @@
bool mandatory, const std::vector<uint8_t>& value) override;
V2_4::Error getLayerGenericMetadataKeys(
std::vector<IComposerClient::LayerGenericMetadataKey>* outKeys) override;
- Error getClientTargetProperty(Display display,
- IComposerClient::ClientTargetProperty* outClientTargetProperty,
- float* outBrightness) override;
+ Error getClientTargetProperty(
+ Display display,
+ aidl::android::hardware::graphics::composer3::ClientTargetPropertyWithBrightness*
+ outClientTargetProperty) override;
// AIDL Composer HAL
Error setLayerBrightness(Display display, Layer layer, float brightness) override;
diff --git a/services/surfaceflinger/DisplayHardware/ComposerHal.h b/services/surfaceflinger/DisplayHardware/ComposerHal.h
index 2dc0830..fd26e0b 100644
--- a/services/surfaceflinger/DisplayHardware/ComposerHal.h
+++ b/services/surfaceflinger/DisplayHardware/ComposerHal.h
@@ -33,6 +33,7 @@
#include <aidl/android/hardware/graphics/common/DisplayDecorationSupport.h>
#include <aidl/android/hardware/graphics/composer3/Capability.h>
+#include <aidl/android/hardware/graphics/composer3/ClientTargetPropertyWithBrightness.h>
#include <aidl/android/hardware/graphics/composer3/Color.h>
#include <aidl/android/hardware/graphics/composer3/Composition.h>
#include <aidl/android/hardware/graphics/composer3/DisplayCapability.h>
@@ -264,8 +265,7 @@
std::vector<IComposerClient::LayerGenericMetadataKey>* outKeys) = 0;
virtual Error getClientTargetProperty(
- Display display, IComposerClient::ClientTargetProperty* outClientTargetProperty,
- float* outBrightness) = 0;
+ Display display, V3_0::ClientTargetPropertyWithBrightness* outClientTargetProperty) = 0;
// AIDL Composer
virtual Error setLayerBrightness(Display display, Layer layer, float brightness) = 0;
diff --git a/services/surfaceflinger/DisplayHardware/HWC2.cpp b/services/surfaceflinger/DisplayHardware/HWC2.cpp
index c0432bf..d8f2334 100644
--- a/services/surfaceflinger/DisplayHardware/HWC2.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWC2.cpp
@@ -585,10 +585,10 @@
return static_cast<Error>(intError);
}
-Error Display::getClientTargetProperty(ClientTargetProperty* outClientTargetProperty,
- float* outWhitePointNits) {
- const auto error =
- mComposer.getClientTargetProperty(mId, outClientTargetProperty, outWhitePointNits);
+Error Display::getClientTargetProperty(
+ aidl::android::hardware::graphics::composer3::ClientTargetPropertyWithBrightness*
+ outClientTargetProperty) {
+ const auto error = mComposer.getClientTargetProperty(mId, outClientTargetProperty);
return static_cast<Error>(error);
}
diff --git a/services/surfaceflinger/DisplayHardware/HWC2.h b/services/surfaceflinger/DisplayHardware/HWC2.h
index a805566..2154553 100644
--- a/services/surfaceflinger/DisplayHardware/HWC2.h
+++ b/services/surfaceflinger/DisplayHardware/HWC2.h
@@ -39,6 +39,7 @@
#include <aidl/android/hardware/graphics/common/DisplayDecorationSupport.h>
#include <aidl/android/hardware/graphics/composer3/Capability.h>
+#include <aidl/android/hardware/graphics/composer3/ClientTargetPropertyWithBrightness.h>
#include <aidl/android/hardware/graphics/composer3/Color.h>
#include <aidl/android/hardware/graphics/composer3/Composition.h>
#include <aidl/android/hardware/graphics/composer3/DisplayCapability.h>
@@ -160,7 +161,8 @@
std::vector<hal::ContentType>*) const = 0;
[[nodiscard]] virtual hal::Error setContentType(hal::ContentType) = 0;
[[nodiscard]] virtual hal::Error getClientTargetProperty(
- hal::ClientTargetProperty* outClientTargetProperty, float* outWhitePointNits) = 0;
+ aidl::android::hardware::graphics::composer3::ClientTargetPropertyWithBrightness*
+ outClientTargetProperty) = 0;
[[nodiscard]] virtual hal::Error getDisplayDecorationSupport(
std::optional<aidl::android::hardware::graphics::common::DisplayDecorationSupport>*
support) = 0;
@@ -238,8 +240,9 @@
hal::Error getSupportedContentTypes(
std::vector<hal::ContentType>* outSupportedContentTypes) const override;
hal::Error setContentType(hal::ContentType) override;
- hal::Error getClientTargetProperty(hal::ClientTargetProperty* outClientTargetProperty,
- float* outWhitePointNits) override;
+ hal::Error getClientTargetProperty(
+ aidl::android::hardware::graphics::composer3::ClientTargetPropertyWithBrightness*
+ outClientTargetProperty) override;
hal::Error getDisplayDecorationSupport(
std::optional<aidl::android::hardware::graphics::common::DisplayDecorationSupport>*
support) override;
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index 459291a..9580964 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -479,12 +479,11 @@
RETURN_IF_HWC_ERROR_FOR("getRequests", error, displayId, BAD_INDEX);
DeviceRequestedChanges::ClientTargetProperty clientTargetProperty;
- float brightness = 1.f;
- error = hwcDisplay->getClientTargetProperty(&clientTargetProperty, &brightness);
+ error = hwcDisplay->getClientTargetProperty(&clientTargetProperty);
outChanges->emplace(DeviceRequestedChanges{std::move(changedTypes), std::move(displayRequests),
std::move(layerRequests),
- std::move(clientTargetProperty), brightness});
+ std::move(clientTargetProperty)});
error = hwcDisplay->acceptChanges();
RETURN_IF_HWC_ERROR_FOR("acceptChanges", error, displayId, BAD_INDEX);
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h
index 0e15a7c..389c3be 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.h
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.h
@@ -45,6 +45,7 @@
#include <aidl/android/hardware/graphics/common/DisplayDecorationSupport.h>
#include <aidl/android/hardware/graphics/composer3/Capability.h>
+#include <aidl/android/hardware/graphics/composer3/ClientTargetPropertyWithBrightness.h>
#include <aidl/android/hardware/graphics/composer3/Composition.h>
#include <aidl/android/hardware/graphics/composer3/DisplayCapability.h>
@@ -78,7 +79,8 @@
using ChangedTypes =
std::unordered_map<HWC2::Layer*,
aidl::android::hardware::graphics::composer3::Composition>;
- using ClientTargetProperty = hal::ClientTargetProperty;
+ using ClientTargetProperty =
+ aidl::android::hardware::graphics::composer3::ClientTargetPropertyWithBrightness;
using DisplayRequests = hal::DisplayRequest;
using LayerRequests = std::unordered_map<HWC2::Layer*, hal::LayerRequest>;
@@ -86,7 +88,6 @@
DisplayRequests displayRequests;
LayerRequests layerRequests;
ClientTargetProperty clientTargetProperty;
- float clientTargetBrightness;
};
struct HWCDisplayMode {
diff --git a/services/surfaceflinger/DisplayHardware/HidlComposerHal.cpp b/services/surfaceflinger/DisplayHardware/HidlComposerHal.cpp
index d9af553..fd456ff 100644
--- a/services/surfaceflinger/DisplayHardware/HidlComposerHal.cpp
+++ b/services/surfaceflinger/DisplayHardware/HidlComposerHal.cpp
@@ -37,6 +37,8 @@
#include <cinttypes>
using aidl::android::hardware::graphics::composer3::Capability;
+using aidl::android::hardware::graphics::composer3::ClientTargetPropertyWithBrightness;
+using aidl::android::hardware::graphics::composer3::DimmingStage;
using aidl::android::hardware::graphics::composer3::DisplayCapability;
namespace android {
@@ -1302,10 +1304,17 @@
}
Error HidlComposer::getClientTargetProperty(
- Display display, IComposerClient::ClientTargetProperty* outClientTargetProperty,
- float* outBrightness) {
- mReader.takeClientTargetProperty(display, outClientTargetProperty);
- *outBrightness = 1.f;
+ Display display, ClientTargetPropertyWithBrightness* outClientTargetProperty) {
+ IComposerClient::ClientTargetProperty property;
+ mReader.takeClientTargetProperty(display, &property);
+ outClientTargetProperty->display = display;
+ outClientTargetProperty->clientTargetProperty.dataspace =
+ static_cast<::aidl::android::hardware::graphics::common::Dataspace>(property.dataspace);
+ outClientTargetProperty->clientTargetProperty.pixelFormat =
+ static_cast<::aidl::android::hardware::graphics::common::PixelFormat>(
+ property.pixelFormat);
+ outClientTargetProperty->brightness = 1.f;
+ outClientTargetProperty->dimmingStage = DimmingStage::NONE;
return Error::NONE;
}
diff --git a/services/surfaceflinger/DisplayHardware/HidlComposerHal.h b/services/surfaceflinger/DisplayHardware/HidlComposerHal.h
index 5869ae5..68c1c15 100644
--- a/services/surfaceflinger/DisplayHardware/HidlComposerHal.h
+++ b/services/surfaceflinger/DisplayHardware/HidlComposerHal.h
@@ -317,9 +317,10 @@
bool mandatory, const std::vector<uint8_t>& value) override;
V2_4::Error getLayerGenericMetadataKeys(
std::vector<IComposerClient::LayerGenericMetadataKey>* outKeys) override;
- Error getClientTargetProperty(Display display,
- IComposerClient::ClientTargetProperty* outClientTargetProperty,
- float* outBrightness) override;
+ Error getClientTargetProperty(
+ Display display,
+ aidl::android::hardware::graphics::composer3::ClientTargetPropertyWithBrightness*
+ outClientTargetProperty) override;
// AIDL Composer HAL
Error setLayerBrightness(Display display, Layer layer, float brightness) override;
diff --git a/services/surfaceflinger/RefreshRateOverlay.cpp b/services/surfaceflinger/RefreshRateOverlay.cpp
index 81c1566..80aa072 100644
--- a/services/surfaceflinger/RefreshRateOverlay.cpp
+++ b/services/surfaceflinger/RefreshRateOverlay.cpp
@@ -14,22 +14,20 @@
* limitations under the License.
*/
-// TODO(b/129481165): remove the #pragma below and fix conversion issues
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wconversion"
-#pragma clang diagnostic ignored "-Wextra"
-
#include <algorithm>
#include "RefreshRateOverlay.h"
#include "Client.h"
#include "Layer.h"
-#include <SkBlendMode.h>
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wconversion"
+#include <SkCanvas.h>
#include <SkPaint.h>
+#pragma clang diagnostic pop
+#include <SkBlendMode.h>
#include <SkRect.h>
#include <SkSurface.h>
-#include <gui/IProducerListener.h>
#include <gui/SurfaceComposerClient.h>
#include <gui/SurfaceControl.h>
@@ -37,29 +35,40 @@
#define LOG_TAG "RefreshRateOverlay"
namespace android {
+namespace {
-void RefreshRateOverlay::SevenSegmentDrawer::drawSegment(Segment segment, int left, SkColor& color,
+constexpr int kDigitWidth = 64;
+constexpr int kDigitHeight = 100;
+constexpr int kDigitSpace = 16;
+
+// Layout is digit, space, digit, space, digit, space, spinner.
+constexpr int kBufferWidth = 4 * kDigitWidth + 3 * kDigitSpace;
+constexpr int kBufferHeight = kDigitHeight;
+
+} // namespace
+
+void RefreshRateOverlay::SevenSegmentDrawer::drawSegment(Segment segment, int left, SkColor color,
SkCanvas& canvas) {
const SkRect rect = [&]() {
switch (segment) {
case Segment::Upper:
- return SkRect::MakeLTRB(left, 0, left + DIGIT_WIDTH, DIGIT_SPACE);
+ return SkRect::MakeLTRB(left, 0, left + kDigitWidth, kDigitSpace);
case Segment::UpperLeft:
- return SkRect::MakeLTRB(left, 0, left + DIGIT_SPACE, DIGIT_HEIGHT / 2);
+ return SkRect::MakeLTRB(left, 0, left + kDigitSpace, kDigitHeight / 2);
case Segment::UpperRight:
- return SkRect::MakeLTRB(left + DIGIT_WIDTH - DIGIT_SPACE, 0, left + DIGIT_WIDTH,
- DIGIT_HEIGHT / 2);
+ return SkRect::MakeLTRB(left + kDigitWidth - kDigitSpace, 0, left + kDigitWidth,
+ kDigitHeight / 2);
case Segment::Middle:
- return SkRect::MakeLTRB(left, DIGIT_HEIGHT / 2 - DIGIT_SPACE / 2,
- left + DIGIT_WIDTH, DIGIT_HEIGHT / 2 + DIGIT_SPACE / 2);
+ return SkRect::MakeLTRB(left, kDigitHeight / 2 - kDigitSpace / 2,
+ left + kDigitWidth, kDigitHeight / 2 + kDigitSpace / 2);
case Segment::LowerLeft:
- return SkRect::MakeLTRB(left, DIGIT_HEIGHT / 2, left + DIGIT_SPACE, DIGIT_HEIGHT);
+ return SkRect::MakeLTRB(left, kDigitHeight / 2, left + kDigitSpace, kDigitHeight);
case Segment::LowerRight:
- return SkRect::MakeLTRB(left + DIGIT_WIDTH - DIGIT_SPACE, DIGIT_HEIGHT / 2,
- left + DIGIT_WIDTH, DIGIT_HEIGHT);
+ return SkRect::MakeLTRB(left + kDigitWidth - kDigitSpace, kDigitHeight / 2,
+ left + kDigitWidth, kDigitHeight);
case Segment::Bottom:
- return SkRect::MakeLTRB(left, DIGIT_HEIGHT - DIGIT_SPACE, left + DIGIT_WIDTH,
- DIGIT_HEIGHT);
+ return SkRect::MakeLTRB(left, kDigitHeight - kDigitSpace, left + kDigitWidth,
+ kDigitHeight);
}
}();
@@ -69,7 +78,7 @@
canvas.drawRect(rect, paint);
}
-void RefreshRateOverlay::SevenSegmentDrawer::drawDigit(int digit, int left, SkColor& color,
+void RefreshRateOverlay::SevenSegmentDrawer::drawDigit(int digit, int left, SkColor color,
SkCanvas& canvas) {
if (digit < 0 || digit > 9) return;
@@ -94,37 +103,45 @@
drawSegment(Segment::Bottom, left, color, canvas);
}
-std::vector<sp<GraphicBuffer>> RefreshRateOverlay::SevenSegmentDrawer::draw(
- int number, SkColor& color, ui::Transform::RotationFlags rotation, bool showSpinner) {
+auto RefreshRateOverlay::SevenSegmentDrawer::draw(int number, SkColor color,
+ ui::Transform::RotationFlags rotation,
+ bool showSpinner) -> Buffers {
if (number < 0 || number > 1000) return {};
const auto hundreds = number / 100;
const auto tens = (number / 10) % 10;
const auto ones = number % 10;
- std::vector<sp<GraphicBuffer>> buffers;
- const auto loopCount = showSpinner ? 6 : 1;
- for (int i = 0; i < loopCount; i++) {
+ const size_t loopCount = showSpinner ? 6 : 1;
+
+ Buffers buffers;
+ buffers.reserve(loopCount);
+
+ for (size_t i = 0; i < loopCount; i++) {
// Pre-rotate the buffer before it reaches SurfaceFlinger.
SkMatrix canvasTransform = SkMatrix();
- auto [bufferWidth, bufferHeight] = [&] {
+ const auto [bufferWidth, bufferHeight] = [&]() -> std::pair<int, int> {
switch (rotation) {
case ui::Transform::ROT_90:
- canvasTransform.setTranslate(BUFFER_HEIGHT, 0);
- canvasTransform.preRotate(90);
- return std::make_tuple(BUFFER_HEIGHT, BUFFER_WIDTH);
+ canvasTransform.setTranslate(kBufferHeight, 0);
+ canvasTransform.preRotate(90.f);
+ return {kBufferHeight, kBufferWidth};
case ui::Transform::ROT_270:
- canvasTransform.setRotate(270, BUFFER_WIDTH / 2.0, BUFFER_WIDTH / 2.0);
- return std::make_tuple(BUFFER_HEIGHT, BUFFER_WIDTH);
+ canvasTransform.setRotate(270.f, kBufferWidth / 2.f, kBufferWidth / 2.f);
+ return {kBufferHeight, kBufferWidth};
default:
- return std::make_tuple(BUFFER_WIDTH, BUFFER_HEIGHT);
+ return {kBufferWidth, kBufferHeight};
}
}();
+
sp<GraphicBuffer> buffer =
- new GraphicBuffer(bufferWidth, bufferHeight, HAL_PIXEL_FORMAT_RGBA_8888, 1,
+ new GraphicBuffer(static_cast<uint32_t>(bufferWidth),
+ static_cast<uint32_t>(bufferHeight), HAL_PIXEL_FORMAT_RGBA_8888,
+ 1,
GRALLOC_USAGE_SW_WRITE_RARELY | GRALLOC_USAGE_HW_COMPOSER |
GRALLOC_USAGE_HW_TEXTURE,
"RefreshRateOverlayBuffer");
+
const status_t bufferStatus = buffer->initCheck();
LOG_ALWAYS_FATAL_IF(bufferStatus != OK, "RefreshRateOverlay: Buffer failed to allocate: %d",
bufferStatus);
@@ -137,15 +154,15 @@
if (hundreds != 0) {
drawDigit(hundreds, left, color, *canvas);
}
- left += DIGIT_WIDTH + DIGIT_SPACE;
+ left += kDigitWidth + kDigitSpace;
if (tens != 0) {
drawDigit(tens, left, color, *canvas);
}
- left += DIGIT_WIDTH + DIGIT_SPACE;
+ left += kDigitWidth + kDigitSpace;
drawDigit(ones, left, color, *canvas);
- left += DIGIT_WIDTH + DIGIT_SPACE;
+ left += kDigitWidth + kDigitSpace;
if (showSpinner) {
switch (i) {
@@ -172,51 +189,48 @@
void* pixels = nullptr;
buffer->lock(GRALLOC_USAGE_SW_WRITE_RARELY, reinterpret_cast<void**>(&pixels));
+
const SkImageInfo& imageInfo = surface->imageInfo();
- size_t dstRowBytes = buffer->getStride() * imageInfo.bytesPerPixel();
+ const size_t dstRowBytes =
+ buffer->getStride() * static_cast<size_t>(imageInfo.bytesPerPixel());
+
canvas->readPixels(imageInfo, pixels, dstRowBytes, 0, 0);
buffer->unlock();
- buffers.emplace_back(buffer);
+ buffers.push_back(std::move(buffer));
}
return buffers;
}
-RefreshRateOverlay::RefreshRateOverlay(SurfaceFlinger& flinger, uint32_t lowFps, uint32_t highFps,
- bool showSpinner)
- : mFlinger(flinger),
- mClient(new Client(&mFlinger)),
+RefreshRateOverlay::RefreshRateOverlay(FpsRange fpsRange, bool showSpinner)
+ : mFpsRange(fpsRange),
mShowSpinner(showSpinner),
- mLowFps(lowFps),
- mHighFps(highFps) {
- createLayer();
-}
-
-bool RefreshRateOverlay::createLayer() {
- mSurfaceControl =
- SurfaceComposerClient::getDefault()
- ->createSurface(String8("RefreshRateOverlay"), SevenSegmentDrawer::getWidth(),
- SevenSegmentDrawer::getHeight(), PIXEL_FORMAT_RGBA_8888,
- ISurfaceComposerClient::eFXSurfaceBufferState);
-
+ mSurfaceControl(SurfaceComposerClient::getDefault()
+ ->createSurface(String8("RefreshRateOverlay"), kBufferWidth,
+ kBufferHeight, PIXEL_FORMAT_RGBA_8888,
+ ISurfaceComposerClient::eFXSurfaceBufferState)) {
if (!mSurfaceControl) {
- ALOGE("failed to create buffer state layer");
- return false;
+ ALOGE("%s: Failed to create buffer state layer", __func__);
+ return;
}
+ constexpr float kFrameRate = 0.f;
+ constexpr int8_t kCompatibility = static_cast<int8_t>(Layer::FrameRateCompatibility::NoVote);
+ constexpr int8_t kSeamlessness = ANATIVEWINDOW_CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS;
+
SurfaceComposerClient::Transaction()
- .setFrameRate(mSurfaceControl, 0.0f,
- static_cast<int8_t>(Layer::FrameRateCompatibility::NoVote),
- static_cast<int8_t>(scheduler::Seamlessness::OnlySeamless))
+ .setFrameRate(mSurfaceControl, kFrameRate, kCompatibility, kSeamlessness)
.setLayer(mSurfaceControl, INT32_MAX - 2)
.setTrustedOverlay(mSurfaceControl, true)
.apply();
-
- return true;
}
-const std::vector<sp<GraphicBuffer>>& RefreshRateOverlay::getOrCreateBuffers(uint32_t fps) {
- ui::Transform::RotationFlags transformHint =
+auto RefreshRateOverlay::getOrCreateBuffers(Fps fps) -> const Buffers& {
+ static const Buffers kNoBuffers;
+ if (!mSurfaceControl) return kNoBuffers;
+
+ const auto transformHint =
static_cast<ui::Transform::RotationFlags>(mSurfaceControl->getTransformHint());
+
// Tell SurfaceFlinger about the pre-rotation on the buffer.
const auto transform = [&] {
switch (transformHint) {
@@ -233,40 +247,49 @@
t.setTransform(mSurfaceControl, transform);
t.apply();
- if (mBufferCache.find(transformHint) == mBufferCache.end() ||
- mBufferCache.at(transformHint).find(fps) == mBufferCache.at(transformHint).end()) {
- // Ensure the range is > 0, so we don't divide by 0.
- const auto rangeLength = std::max(1u, mHighFps - mLowFps);
- // Clip values outside the range [mLowFps, mHighFps]. The current fps may be outside
- // of this range if the display has changed its set of supported refresh rates.
- fps = std::max(fps, mLowFps);
- fps = std::min(fps, mHighFps);
- const auto fpsScale = static_cast<float>(fps - mLowFps) / rangeLength;
- SkColor4f colorBase = SkColor4f::FromColor(HIGH_FPS_COLOR) * fpsScale;
- SkColor4f lowFpsColor = SkColor4f::FromColor(LOW_FPS_COLOR) * (1 - fpsScale);
- colorBase.fR = colorBase.fR + lowFpsColor.fR;
- colorBase.fG = colorBase.fG + lowFpsColor.fG;
- colorBase.fB = colorBase.fB + lowFpsColor.fB;
- colorBase.fA = ALPHA;
- SkColor color = colorBase.toSkColor();
- auto buffers = SevenSegmentDrawer::draw(fps, color, transformHint, mShowSpinner);
- mBufferCache[transformHint].emplace(fps, buffers);
+ BufferCache::const_iterator it = mBufferCache.find({fps.getIntValue(), transformHint});
+ if (it == mBufferCache.end()) {
+ const int minFps = mFpsRange.min.getIntValue();
+ const int maxFps = mFpsRange.max.getIntValue();
+
+ // Clamp to the range. The current fps may be outside of this range if the display has
+ // changed its set of supported refresh rates.
+ const int intFps = std::clamp(fps.getIntValue(), minFps, maxFps);
+
+ // Ensure non-zero range to avoid division by zero.
+ const float fpsScale = static_cast<float>(intFps - minFps) / std::max(1, maxFps - minFps);
+
+ constexpr SkColor kMinFpsColor = SK_ColorRED;
+ constexpr SkColor kMaxFpsColor = SK_ColorGREEN;
+ constexpr float kAlpha = 0.8f;
+
+ SkColor4f colorBase = SkColor4f::FromColor(kMaxFpsColor) * fpsScale;
+ const SkColor4f minFpsColor = SkColor4f::FromColor(kMinFpsColor) * (1 - fpsScale);
+
+ colorBase.fR = colorBase.fR + minFpsColor.fR;
+ colorBase.fG = colorBase.fG + minFpsColor.fG;
+ colorBase.fB = colorBase.fB + minFpsColor.fB;
+ colorBase.fA = kAlpha;
+
+ const SkColor color = colorBase.toSkColor();
+
+ auto buffers = SevenSegmentDrawer::draw(intFps, color, transformHint, mShowSpinner);
+ it = mBufferCache.try_emplace({intFps, transformHint}, std::move(buffers)).first;
}
- return mBufferCache[transformHint][fps];
+ return it->second;
}
void RefreshRateOverlay::setViewport(ui::Size viewport) {
constexpr int32_t kMaxWidth = 1000;
- const auto width = std::min(kMaxWidth, std::min(viewport.width, viewport.height));
+ const auto width = std::min({kMaxWidth, viewport.width, viewport.height});
const auto height = 2 * width;
Rect frame((3 * width) >> 4, height >> 5);
frame.offsetBy(width >> 5, height >> 4);
SurfaceComposerClient::Transaction t;
- t.setMatrix(mSurfaceControl,
- frame.getWidth() / static_cast<float>(SevenSegmentDrawer::getWidth()), 0, 0,
- frame.getHeight() / static_cast<float>(SevenSegmentDrawer::getHeight()));
+ t.setMatrix(mSurfaceControl, frame.getWidth() / static_cast<float>(kBufferWidth), 0, 0,
+ frame.getHeight() / static_cast<float>(kBufferHeight));
t.setPosition(mSurfaceControl, frame.left, frame.top);
t.apply();
}
@@ -278,25 +301,22 @@
}
void RefreshRateOverlay::changeRefreshRate(Fps fps) {
- mCurrentFps = fps.getIntValue();
- auto buffer = getOrCreateBuffers(*mCurrentFps)[mFrame];
+ mCurrentFps = fps;
+ const auto buffer = getOrCreateBuffers(fps)[mFrame];
SurfaceComposerClient::Transaction t;
t.setBuffer(mSurfaceControl, buffer);
t.apply();
}
void RefreshRateOverlay::animate() {
- if (!mCurrentFps.has_value()) return;
+ if (!mShowSpinner || !mCurrentFps) return;
const auto& buffers = getOrCreateBuffers(*mCurrentFps);
mFrame = (mFrame + 1) % buffers.size();
- auto buffer = buffers[mFrame];
+ const auto buffer = buffers[mFrame];
SurfaceComposerClient::Transaction t;
t.setBuffer(mSurfaceControl, buffer);
t.apply();
}
} // namespace android
-
-// TODO(b/129481165): remove the #pragma below and fix conversion issues
-#pragma clang diagnostic pop // ignored "-Wconversion -Wextra"
diff --git a/services/surfaceflinger/RefreshRateOverlay.h b/services/surfaceflinger/RefreshRateOverlay.h
index 381df37..a465a36 100644
--- a/services/surfaceflinger/RefreshRateOverlay.h
+++ b/services/surfaceflinger/RefreshRateOverlay.h
@@ -16,32 +16,27 @@
#pragma once
-#include <SkCanvas.h>
#include <SkColor.h>
-#include <unordered_map>
+#include <vector>
-#include <math/vec4.h>
-#include <renderengine/RenderEngine.h>
+#include <ftl/small_map.h>
#include <ui/LayerStack.h>
-#include <ui/Rect.h>
#include <ui/Size.h>
+#include <ui/Transform.h>
#include <utils/StrongPointer.h>
#include <scheduler/Fps.h>
+class SkCanvas;
+
namespace android {
-class Client;
class GraphicBuffer;
-class IBinder;
-class IGraphicBufferProducer;
-class Layer;
-class SurfaceFlinger;
class SurfaceControl;
class RefreshRateOverlay {
public:
- RefreshRateOverlay(SurfaceFlinger&, uint32_t lowFps, uint32_t highFps, bool showSpinner);
+ RefreshRateOverlay(FpsRange, bool showSpinner);
void setLayerStack(ui::LayerStack);
void setViewport(ui::Size);
@@ -49,52 +44,38 @@
void animate();
private:
+ using Buffers = std::vector<sp<GraphicBuffer>>;
+
class SevenSegmentDrawer {
public:
- static std::vector<sp<GraphicBuffer>> draw(int number, SkColor& color,
- ui::Transform::RotationFlags, bool showSpinner);
- static uint32_t getHeight() { return BUFFER_HEIGHT; }
- static uint32_t getWidth() { return BUFFER_WIDTH; }
+ static Buffers draw(int number, SkColor, ui::Transform::RotationFlags, bool showSpinner);
private:
enum class Segment { Upper, UpperLeft, UpperRight, Middle, LowerLeft, LowerRight, Bottom };
- static void drawSegment(Segment segment, int left, SkColor& color, SkCanvas& canvas);
- static void drawDigit(int digit, int left, SkColor& color, SkCanvas& canvas);
-
- static constexpr uint32_t DIGIT_HEIGHT = 100;
- static constexpr uint32_t DIGIT_WIDTH = 64;
- static constexpr uint32_t DIGIT_SPACE = 16;
- static constexpr uint32_t BUFFER_HEIGHT = DIGIT_HEIGHT;
- static constexpr uint32_t BUFFER_WIDTH =
- 4 * DIGIT_WIDTH + 3 * DIGIT_SPACE; // Digit|Space|Digit|Space|Digit|Space|Spinner
+ static void drawSegment(Segment, int left, SkColor, SkCanvas&);
+ static void drawDigit(int digit, int left, SkColor, SkCanvas&);
};
- bool createLayer();
+ const Buffers& getOrCreateBuffers(Fps);
- const std::vector<sp<GraphicBuffer>>& getOrCreateBuffers(uint32_t fps);
+ struct Key {
+ int fps;
+ ui::Transform::RotationFlags flags;
- SurfaceFlinger& mFlinger;
- const sp<Client> mClient;
- sp<IBinder> mIBinder;
- sp<IGraphicBufferProducer> mGbp;
+ bool operator==(Key other) const { return fps == other.fps && flags == other.flags; }
+ };
- std::unordered_map<ui::Transform::RotationFlags,
- std::unordered_map<int, std::vector<sp<GraphicBuffer>>>>
- mBufferCache;
- std::optional<int> mCurrentFps;
- int mFrame = 0;
- static constexpr float ALPHA = 0.8f;
- const SkColor LOW_FPS_COLOR = SK_ColorRED;
- const SkColor HIGH_FPS_COLOR = SK_ColorGREEN;
+ using BufferCache = ftl::SmallMap<Key, Buffers, 9>;
+ BufferCache mBufferCache;
+ std::optional<Fps> mCurrentFps;
+ size_t mFrame = 0;
+
+ const FpsRange mFpsRange; // For color interpolation.
const bool mShowSpinner;
- // Interpolate the colors between these values.
- const uint32_t mLowFps;
- const uint32_t mHighFps;
-
- sp<SurfaceControl> mSurfaceControl;
+ const sp<SurfaceControl> mSurfaceControl;
};
} // namespace android
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 5adc177..ff977b2 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -1276,8 +1276,9 @@
}
void SurfaceFlinger::disableExpensiveRendering() {
+ const char* const whence = __func__;
auto future = mScheduler->schedule([=]() FTL_FAKE_GUARD(mStateLock) {
- ATRACE_CALL();
+ ATRACE_NAME(whence);
if (mPowerAdvisor.isUsingExpensiveRendering()) {
for (const auto& [_, display] : mDisplays) {
constexpr bool kDisable = false;
@@ -5466,8 +5467,6 @@
// access to SF.
case BOOT_FINISHED:
case CLEAR_ANIMATION_FRAME_STATS:
- case CREATE_DISPLAY:
- case DESTROY_DISPLAY:
case GET_ANIMATION_FRAME_STATS:
case OVERRIDE_HDR_TYPES:
case GET_HDR_CAPABILITIES:
@@ -5489,7 +5488,6 @@
case REMOVE_TUNNEL_MODE_ENABLED_LISTENER:
case NOTIFY_POWER_BOOST:
case SET_GLOBAL_SHADOW_SETTINGS:
- case GET_PRIMARY_PHYSICAL_DISPLAY_ID:
case ACQUIRE_FRAME_RATE_FLEXIBILITY_TOKEN: {
// OVERRIDE_HDR_TYPES is used by CTS tests, which acquire the necessary
// permission dynamically. Don't use the permission cache for this check.
@@ -5520,8 +5518,6 @@
case AUTHENTICATE_SURFACE:
case GET_ACTIVE_COLOR_MODE:
case GET_ACTIVE_DISPLAY_MODE:
- case GET_PHYSICAL_DISPLAY_IDS:
- case GET_PHYSICAL_DISPLAY_TOKEN:
case GET_DISPLAY_COLOR_MODES:
case GET_DISPLAY_NATIVE_PRIMARIES:
case GET_STATIC_DISPLAY_INFO:
@@ -5607,10 +5603,15 @@
}
return PERMISSION_DENIED;
}
+ case CREATE_DISPLAY:
+ case DESTROY_DISPLAY:
+ case GET_PRIMARY_PHYSICAL_DISPLAY_ID:
+ case GET_PHYSICAL_DISPLAY_IDS:
+ case GET_PHYSICAL_DISPLAY_TOKEN:
case CAPTURE_LAYERS:
case CAPTURE_DISPLAY:
case CAPTURE_DISPLAY_BY_ID:
- LOG_FATAL("Deprecated opcode: %d", code);
+ LOG_FATAL("Deprecated opcode: %d, migrated to AIDL", code);
return PERMISSION_DENIED;
}
@@ -7315,6 +7316,59 @@
}
// gui::ISurfaceComposer
+
+binder::Status SurfaceComposerAIDL::createDisplay(const std::string& displayName, bool secure,
+ sp<IBinder>* outDisplay) {
+ status_t status = checkAccessPermission();
+ if (status == OK) {
+ String8 displayName8 = String8::format("%s", displayName.c_str());
+ *outDisplay = mFlinger->createDisplay(displayName8, secure);
+ return binder::Status::ok();
+ }
+ return binder::Status::fromStatusT(status);
+}
+
+binder::Status SurfaceComposerAIDL::destroyDisplay(const sp<IBinder>& display) {
+ status_t status = checkAccessPermission();
+ if (status == OK) {
+ mFlinger->destroyDisplay(display);
+ return binder::Status::ok();
+ }
+ return binder::Status::fromStatusT(status);
+}
+
+binder::Status SurfaceComposerAIDL::getPhysicalDisplayIds(std::vector<int64_t>* outDisplayIds) {
+ std::vector<PhysicalDisplayId> physicalDisplayIds = mFlinger->getPhysicalDisplayIds();
+ std::vector<int64_t> displayIds;
+ displayIds.reserve(physicalDisplayIds.size());
+ for (auto item : physicalDisplayIds) {
+ displayIds.push_back(static_cast<int64_t>(item.value));
+ }
+ *outDisplayIds = displayIds;
+ return binder::Status::ok();
+}
+
+binder::Status SurfaceComposerAIDL::getPrimaryPhysicalDisplayId(int64_t* outDisplayId) {
+ status_t status = checkAccessPermission();
+ if (status != OK) {
+ return binder::Status::fromStatusT(status);
+ }
+
+ PhysicalDisplayId id;
+ status = mFlinger->getPrimaryPhysicalDisplayId(&id);
+ if (status == NO_ERROR) {
+ *outDisplayId = id.value;
+ }
+ return binder::Status::fromStatusT(status);
+}
+
+binder::Status SurfaceComposerAIDL::getPhysicalDisplayToken(int64_t displayId,
+ sp<IBinder>* outDisplay) {
+ const auto id = DisplayId::fromValue<PhysicalDisplayId>(static_cast<uint64_t>(displayId));
+ *outDisplay = mFlinger->getPhysicalDisplayToken(*id);
+ return binder::Status::ok();
+}
+
binder::Status SurfaceComposerAIDL::captureDisplay(
const DisplayCaptureArgs& args, const sp<IScreenCaptureListener>& captureListener) {
status_t status = mFlinger->captureDisplay(args, captureListener);
@@ -7341,6 +7395,16 @@
return binder::Status::fromStatusT(status);
}
+status_t SurfaceComposerAIDL::checkAccessPermission(bool usePermissionCache) {
+ if (!mFlinger->callingThreadHasUnscopedSurfaceFlingerAccess(usePermissionCache)) {
+ IPCThreadState* ipc = IPCThreadState::self();
+ ALOGE("Permission Denial: can't access SurfaceFlinger pid=%d, uid=%d", ipc->getCallingPid(),
+ ipc->getCallingUid());
+ return PERMISSION_DENIED;
+ }
+ return OK;
+}
+
} // namespace android
#if defined(__gl_h_)
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 97b0e8d..bc3d83e 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -518,17 +518,30 @@
bool callingThreadHasUnscopedSurfaceFlingerAccess(bool usePermissionCache = true)
EXCLUDES(mStateLock);
+ // the following two methods are moved from ISurfaceComposer.h
+ // TODO(b/74619554): Remove this stopgap once the framework is display-agnostic.
+ std::optional<PhysicalDisplayId> getInternalDisplayId() const {
+ const auto displayIds = getPhysicalDisplayIds();
+ return displayIds.empty() ? std::nullopt : std::make_optional(displayIds.front());
+ }
+
+ // TODO(b/74619554): Remove this stopgap once the framework is display-agnostic.
+ sp<IBinder> getInternalDisplayToken() const {
+ const auto displayId = getInternalDisplayId();
+ return displayId ? getPhysicalDisplayToken(*displayId) : nullptr;
+ }
+
// Implements ISurfaceComposer
sp<ISurfaceComposerClient> createConnection() override;
- sp<IBinder> createDisplay(const String8& displayName, bool secure) override;
- void destroyDisplay(const sp<IBinder>& displayToken) override;
- std::vector<PhysicalDisplayId> getPhysicalDisplayIds() const override EXCLUDES(mStateLock) {
+ sp<IBinder> createDisplay(const String8& displayName, bool secure);
+ void destroyDisplay(const sp<IBinder>& displayToken);
+ std::vector<PhysicalDisplayId> getPhysicalDisplayIds() const EXCLUDES(mStateLock) {
Mutex::Autolock lock(mStateLock);
return getPhysicalDisplayIdsLocked();
}
- status_t getPrimaryPhysicalDisplayId(PhysicalDisplayId*) const override EXCLUDES(mStateLock);
+ status_t getPrimaryPhysicalDisplayId(PhysicalDisplayId*) const EXCLUDES(mStateLock);
- sp<IBinder> getPhysicalDisplayToken(PhysicalDisplayId displayId) const override;
+ sp<IBinder> getPhysicalDisplayToken(PhysicalDisplayId displayId) const;
status_t setTransactionState(const FrameTimelineInfo& frameTimelineInfo,
const Vector<ComposerState>& state,
const Vector<DisplayState>& displays, uint32_t flags,
@@ -1438,6 +1451,13 @@
public:
SurfaceComposerAIDL(sp<SurfaceFlinger> sf) { mFlinger = sf; }
+ binder::Status createDisplay(const std::string& displayName, bool secure,
+ sp<IBinder>* outDisplay) override;
+ binder::Status destroyDisplay(const sp<IBinder>& display) override;
+ binder::Status getPhysicalDisplayIds(std::vector<int64_t>* outDisplayIds) override;
+ binder::Status getPrimaryPhysicalDisplayId(int64_t* outDisplayId) override;
+ binder::Status getPhysicalDisplayToken(int64_t displayId, sp<IBinder>* outDisplay) override;
+
binder::Status captureDisplay(const DisplayCaptureArgs&,
const sp<IScreenCaptureListener>&) override;
binder::Status captureDisplayById(int64_t, const sp<IScreenCaptureListener>&) override;
@@ -1445,6 +1465,10 @@
const sp<IScreenCaptureListener>&) override;
private:
+ static const constexpr bool kUsePermissionCache = true;
+ status_t checkAccessPermission(bool usePermissionCache = kUsePermissionCache);
+
+private:
sp<SurfaceFlinger> mFlinger;
};
diff --git a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h
index c1d41bb..e215550 100644
--- a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h
+++ b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h
@@ -151,8 +151,10 @@
const std::vector<uint8_t>&));
MOCK_METHOD1(getLayerGenericMetadataKeys,
V2_4::Error(std::vector<IComposerClient::LayerGenericMetadataKey>*));
- MOCK_METHOD3(getClientTargetProperty,
- Error(Display, IComposerClient::ClientTargetProperty*, float*));
+ MOCK_METHOD2(getClientTargetProperty,
+ Error(Display,
+ aidl::android::hardware::graphics::composer3::
+ ClientTargetPropertyWithBrightness*));
MOCK_METHOD3(setLayerBrightness, Error(Display, Layer, float));
MOCK_METHOD3(setLayerBlockingRegion,
Error(Display, Layer, const std::vector<IComposerClient::Rect>&));
diff --git a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockHWC2.h b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockHWC2.h
index ac2ab199c..4c2aa34 100644
--- a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockHWC2.h
+++ b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockHWC2.h
@@ -93,8 +93,10 @@
MOCK_METHOD(hal::Error, getSupportedContentTypes, (std::vector<hal::ContentType> *),
(const, override));
MOCK_METHOD(hal::Error, setContentType, (hal::ContentType), (override));
- MOCK_METHOD(hal::Error, getClientTargetProperty, (hal::ClientTargetProperty *, float *),
- (override));
+ MOCK_METHOD(
+ hal::Error, getClientTargetProperty,
+ (aidl::android::hardware::graphics::composer3::ClientTargetPropertyWithBrightness *),
+ (override));
MOCK_METHOD(
hal::Error, getDisplayDecorationSupport,
(std::optional<aidl::android::hardware::graphics::common::DisplayDecorationSupport> *),