Merge "Remove root layer when clearing mLayersPendingRemoval" into tm-dev am: b089aa579f am: 0da4fbd671 am: b92f0b82d6
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/native/+/17837364
Change-Id: I2228d68dcf2e4b7943626d37c92b4a4a6c5da503
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/cmds/installd/Android.bp b/cmds/installd/Android.bp
index c9f680b..bf5e893 100644
--- a/cmds/installd/Android.bp
+++ b/cmds/installd/Android.bp
@@ -81,8 +81,9 @@
"cert-*",
"-cert-err58-cpp",
],
- tidy_flags: [
- "-warnings-as-errors=clang-analyzer-security*,cert-*",
+ tidy_checks_as_errors: [
+ "clang-analyzer-security*",
+ "cert-*",
],
}
diff --git a/libs/binder/ndk/include_ndk/android/binder_ibinder_jni.h b/libs/binder/ndk/include_ndk/android/binder_ibinder_jni.h
index 6880d86..8e288b3 100644
--- a/libs/binder/ndk/include_ndk/android/binder_ibinder_jni.h
+++ b/libs/binder/ndk/include_ndk/android/binder_ibinder_jni.h
@@ -56,6 +56,12 @@
* If the binder is null, null is returned. If this binder object was originally an IBinder object,
* the original java object will be returned.
*
+ * WARNING: this function returns global and local references. This can be
+ * figured out using GetObjectRefType. Though, when this function is called
+ * from within a Java context, the local ref will automatically be cleaned
+ * up. If this is called outside of a Java frame,
+ * PushObjectFrame/PopObjectFrame can simulate this automatic cleanup.
+ *
* Available since API level 29.
*
* \param env Java environment. Must not be null.
diff --git a/libs/binder/rust/tests/serialization.cpp b/libs/binder/rust/tests/serialization.cpp
index ec780f2..3f59dab 100644
--- a/libs/binder/rust/tests/serialization.cpp
+++ b/libs/binder/rust/tests/serialization.cpp
@@ -381,7 +381,7 @@
string expected = "TestingFileDescriptors";
vector<char> buf(expected.length());
base::ReadFully(file_descriptors[0].release(), buf.data(), buf.size());
- ASSERT_EQ(expected, string(buf.data()));
+ ASSERT_EQ(expected, string(buf.data(), expected.length()));
}
TEST_F(SerializationTest, SerializeIBinder) {
diff --git a/libs/binder/rust/tests/serialization.rs b/libs/binder/rust/tests/serialization.rs
index b62da7b..f6bdf5c 100644
--- a/libs/binder/rust/tests/serialization.rs
+++ b/libs/binder/rust/tests/serialization.rs
@@ -117,8 +117,8 @@
) -> Result<(), StatusCode> {
match code {
bindings::Transaction_TEST_BOOL => {
- assert_eq!(parcel.read::<bool>()?, true);
- assert_eq!(parcel.read::<bool>()?, false);
+ assert!(parcel.read::<bool>()?);
+ assert!(!parcel.read::<bool>()?);
assert_eq!(parcel.read::<Vec<bool>>()?, unsafe {
bindings::TESTDATA_BOOL
});
diff --git a/libs/cputimeinstate/cputimeinstate.cpp b/libs/cputimeinstate/cputimeinstate.cpp
index 7e9bb7d..d169043 100644
--- a/libs/cputimeinstate/cputimeinstate.cpp
+++ b/libs/cputimeinstate/cputimeinstate.cpp
@@ -300,11 +300,11 @@
}
std::vector<tis_val_t> vals(gNCpus);
- time_key_t key = {.uid = uid};
for (uint32_t i = 0; i <= (maxFreqCount - 1) / FREQS_PER_ENTRY; ++i) {
- key.bucket = i;
+ const time_key_t key = {.uid = uid, .bucket = i};
if (findMapEntry(gTisMapFd, &key, vals.data())) {
- if (errno != ENOENT || getFirstMapKey(gTisMapFd, &key)) return {};
+ time_key_t tmpKey;
+ if (errno != ENOENT || getFirstMapKey(gTisMapFd, &tmpKey)) return {};
continue;
}
@@ -412,10 +412,11 @@
concurrent_time_t ret = {.active = std::vector<uint64_t>(gNCpus, 0)};
for (const auto &cpuList : gPolicyCpus) ret.policy.emplace_back(cpuList.size(), 0);
std::vector<concurrent_val_t> vals(gNCpus);
- time_key_t key = {.uid = uid};
- for (key.bucket = 0; key.bucket <= (gNCpus - 1) / CPUS_PER_ENTRY; ++key.bucket) {
+ for (uint32_t i = 0; i <= (gNCpus - 1) / CPUS_PER_ENTRY; ++i) {
+ const time_key_t key = {.uid = uid, .bucket = i};
if (findMapEntry(gConcurrentMapFd, &key, vals.data())) {
- if (errno != ENOENT || getFirstMapKey(gConcurrentMapFd, &key)) return {};
+ time_key_t tmpKey;
+ if (errno != ENOENT || getFirstMapKey(gConcurrentMapFd, &tmpKey)) return {};
continue;
}
auto offset = key.bucket * CPUS_PER_ENTRY;
diff --git a/libs/gui/ScreenCaptureResults.cpp b/libs/gui/ScreenCaptureResults.cpp
index e91f74f..fe38706 100644
--- a/libs/gui/ScreenCaptureResults.cpp
+++ b/libs/gui/ScreenCaptureResults.cpp
@@ -36,6 +36,7 @@
}
SAFE_PARCEL(parcel->writeBool, capturedSecureLayers);
+ SAFE_PARCEL(parcel->writeBool, capturedHdrLayers);
SAFE_PARCEL(parcel->writeUint32, static_cast<uint32_t>(capturedDataspace));
SAFE_PARCEL(parcel->writeInt32, result);
return NO_ERROR;
@@ -57,6 +58,7 @@
}
SAFE_PARCEL(parcel->readBool, &capturedSecureLayers);
+ SAFE_PARCEL(parcel->readBool, &capturedHdrLayers);
uint32_t dataspace = 0;
SAFE_PARCEL(parcel->readUint32, &dataspace);
capturedDataspace = static_cast<ui::Dataspace>(dataspace);
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index 7a63af0..6642ec6 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -1495,6 +1495,18 @@
s->bufferData = std::move(bufferData);
registerSurfaceControlForCallback(sc);
+ // With the current infrastructure, a release callback will not be invoked if there's no
+ // transaction callback in the case when a buffer is latched and not released early. This is
+ // because the legacy implementation didn't have a release callback and sent releases in the
+ // transaction callback. Because of this, we need to make sure to have a transaction callback
+ // set up when a buffer is sent in a transaction to ensure the caller gets the release
+ // callback, regardless if they set up a transaction callback.
+ //
+ // TODO (b/230380821): Remove when release callbacks are separated from transaction callbacks
+ addTransactionCompletedCallback([](void*, nsecs_t, const sp<Fence>&,
+ const std::vector<SurfaceControlStats>&) {},
+ nullptr);
+
mContainsBuffer = true;
return *this;
}
diff --git a/libs/gui/include/gui/ScreenCaptureResults.h b/libs/gui/include/gui/ScreenCaptureResults.h
index 99c35c1..724c11c 100644
--- a/libs/gui/include/gui/ScreenCaptureResults.h
+++ b/libs/gui/include/gui/ScreenCaptureResults.h
@@ -33,6 +33,7 @@
sp<GraphicBuffer> buffer;
sp<Fence> fence = Fence::NO_FENCE;
bool capturedSecureLayers{false};
+ bool capturedHdrLayers{false};
ui::Dataspace capturedDataspace{ui::Dataspace::V0_SRGB};
status_t result = OK;
};
diff --git a/services/inputflinger/reader/InputReader.cpp b/services/inputflinger/reader/InputReader.cpp
index 31d331b..9c5a129 100644
--- a/services/inputflinger/reader/InputReader.cpp
+++ b/services/inputflinger/reader/InputReader.cpp
@@ -47,8 +47,8 @@
mEventHub(eventHub),
mPolicy(policy),
mQueuedListener(listener),
- mGlobalMetaState(0),
- mLedMetaState(AMETA_NUM_LOCK_ON),
+ mGlobalMetaState(AMETA_NONE),
+ mLedMetaState(AMETA_NONE),
mGeneration(1),
mNextInputDeviceId(END_RESERVED_ID),
mDisableVirtualKeysTimeout(LLONG_MIN),
diff --git a/services/inputflinger/reader/mapper/CursorInputMapper.cpp b/services/inputflinger/reader/mapper/CursorInputMapper.cpp
index dc5fcec..a9a4c71 100644
--- a/services/inputflinger/reader/mapper/CursorInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/CursorInputMapper.cpp
@@ -27,6 +27,9 @@
namespace android {
+// The default velocity control parameters that has no effect.
+static const VelocityControlParameters FLAT_VELOCITY_CONTROL_PARAMS{};
+
// --- CursorMotionAccumulator ---
CursorMotionAccumulator::CursorMotionAccumulator() {
@@ -154,8 +157,9 @@
mHWheelScale = 1.0f;
}
- if ((!changes && config->pointerCaptureRequest.enable) ||
- (changes & InputReaderConfiguration::CHANGE_POINTER_CAPTURE)) {
+ const bool configurePointerCapture = (!changes && config->pointerCaptureRequest.enable) ||
+ (changes & InputReaderConfiguration::CHANGE_POINTER_CAPTURE);
+ if (configurePointerCapture) {
if (config->pointerCaptureRequest.enable) {
if (mParameters.mode == Parameters::MODE_POINTER) {
mParameters.mode = Parameters::MODE_POINTER_RELATIVE;
@@ -180,10 +184,18 @@
}
}
- if (!changes || (changes & InputReaderConfiguration::CHANGE_POINTER_SPEED)) {
- mPointerVelocityControl.setParameters(config->pointerVelocityControlParameters);
- mWheelXVelocityControl.setParameters(config->wheelVelocityControlParameters);
- mWheelYVelocityControl.setParameters(config->wheelVelocityControlParameters);
+ if (!changes || (changes & InputReaderConfiguration::CHANGE_POINTER_SPEED) ||
+ configurePointerCapture) {
+ if (config->pointerCaptureRequest.enable) {
+ // Disable any acceleration or scaling when Pointer Capture is enabled.
+ mPointerVelocityControl.setParameters(FLAT_VELOCITY_CONTROL_PARAMS);
+ mWheelXVelocityControl.setParameters(FLAT_VELOCITY_CONTROL_PARAMS);
+ mWheelYVelocityControl.setParameters(FLAT_VELOCITY_CONTROL_PARAMS);
+ } else {
+ mPointerVelocityControl.setParameters(config->pointerVelocityControlParameters);
+ mWheelXVelocityControl.setParameters(config->wheelVelocityControlParameters);
+ mWheelYVelocityControl.setParameters(config->wheelVelocityControlParameters);
+ }
}
if (!changes || (changes & InputReaderConfiguration::CHANGE_DISPLAY_INFO)) {
diff --git a/services/inputflinger/tests/InputReader_test.cpp b/services/inputflinger/tests/InputReader_test.cpp
index bda7755..a26a0bc 100644
--- a/services/inputflinger/tests/InputReader_test.cpp
+++ b/services/inputflinger/tests/InputReader_test.cpp
@@ -375,6 +375,11 @@
float getPointerGestureMovementSpeedRatio() { return mConfig.pointerGestureMovementSpeedRatio; }
+ void setVelocityControlParams(const VelocityControlParameters& params) {
+ mConfig.pointerVelocityControlParameters = params;
+ mConfig.wheelVelocityControlParameters = params;
+ }
+
private:
uint32_t mNextPointerCaptureSequenceNumber = 0;
@@ -2949,7 +2954,10 @@
}
void configureDevice(uint32_t changes) {
- if (!changes || (changes & InputReaderConfiguration::CHANGE_DISPLAY_INFO)) {
+ if (!changes ||
+ (changes &
+ (InputReaderConfiguration::CHANGE_DISPLAY_INFO |
+ InputReaderConfiguration::CHANGE_POINTER_CAPTURE))) {
mReader->requestRefreshConfiguration(changes);
mReader->loopOnce();
}
@@ -3364,9 +3372,8 @@
KeyboardInputMapper& mapper =
addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
AINPUT_KEYBOARD_TYPE_ALPHABETIC);
- // Initial metastate to AMETA_NONE.
- ASSERT_EQ(AMETA_NUM_LOCK_ON, mapper.getMetaState());
- mapper.updateMetaState(AKEYCODE_NUM_LOCK);
+ // Initial metastate is AMETA_NONE.
+ ASSERT_EQ(AMETA_NONE, mapper.getMetaState());
// Key down by scan code.
process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_HOME, 1);
@@ -3491,9 +3498,8 @@
addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
AINPUT_KEYBOARD_TYPE_ALPHABETIC);
- // Initial metastate to AMETA_NONE.
- ASSERT_EQ(AMETA_NUM_LOCK_ON, mapper.getMetaState());
- mapper.updateMetaState(AKEYCODE_NUM_LOCK);
+ // Initial metastate is AMETA_NONE.
+ ASSERT_EQ(AMETA_NONE, mapper.getMetaState());
// Metakey down.
process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_LEFTSHIFT, 1);
@@ -3738,9 +3744,8 @@
KeyboardInputMapper& mapper =
addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
AINPUT_KEYBOARD_TYPE_ALPHABETIC);
- // Initialize metastate to AMETA_NUM_LOCK_ON.
- ASSERT_EQ(AMETA_NUM_LOCK_ON, mapper.getMetaState());
- mapper.updateMetaState(AKEYCODE_NUM_LOCK);
+ // Initial metastate is AMETA_NONE.
+ ASSERT_EQ(AMETA_NONE, mapper.getMetaState());
// Initialization should have turned all of the lights off.
ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_CAPSL));
@@ -3806,8 +3811,6 @@
addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC);
- // Initial metastate should be AMETA_NONE as no meta keys added.
- ASSERT_EQ(AMETA_NONE, mapper.getMetaState());
// Meta state should be AMETA_NONE after reset
mapper.reset(ARBITRARY_TIME);
ASSERT_EQ(AMETA_NONE, mapper.getMetaState());
@@ -3922,9 +3925,8 @@
KeyboardInputMapper& mapper =
addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
AINPUT_KEYBOARD_TYPE_ALPHABETIC);
- // Initial metastate to AMETA_NONE.
- ASSERT_EQ(AMETA_NUM_LOCK_ON, mapper.getMetaState());
- mapper.updateMetaState(AKEYCODE_NUM_LOCK);
+ // Initial metastate is AMETA_NONE.
+ ASSERT_EQ(AMETA_NONE, mapper.getMetaState());
// Initialization should have turned all of the lights off.
ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_CAPSL));
@@ -3991,9 +3993,8 @@
KeyboardInputMapper& mapper =
addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
AINPUT_KEYBOARD_TYPE_ALPHABETIC);
- // Initialize metastate to AMETA_NUM_LOCK_ON.
- ASSERT_EQ(AMETA_NUM_LOCK_ON, mapper.getMetaState());
- mapper.updateMetaState(AKEYCODE_NUM_LOCK);
+ // Initial metastate is AMETA_NONE.
+ ASSERT_EQ(AMETA_NONE, mapper.getMetaState());
mReader->toggleCapsLockState(DEVICE_ID);
ASSERT_EQ(AMETA_CAPS_LOCK_ON, mapper.getMetaState());
@@ -4033,7 +4034,13 @@
device2->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(), 0 /*changes*/);
device2->reset(ARBITRARY_TIME);
- // Initial metastate is AMETA_NUM_LOCK_ON, turn it off.
+ // Initial metastate is AMETA_NONE.
+ ASSERT_EQ(AMETA_NONE, mapper1.getMetaState());
+ ASSERT_EQ(AMETA_NONE, mapper2.getMetaState());
+
+ // Toggle num lock on and off.
+ process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_NUMLOCK, 1);
+ process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_NUMLOCK, 0);
ASSERT_TRUE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_NUML));
ASSERT_EQ(AMETA_NUM_LOCK_ON, mapper1.getMetaState());
ASSERT_EQ(AMETA_NUM_LOCK_ON, mapper2.getMetaState());
@@ -4914,6 +4921,54 @@
ASSERT_NO_FATAL_FAILURE(assertPosition(*mFakePointerController, 110.0f, 220.0f));
}
+/**
+ * When Pointer Capture is enabled, we expect to report unprocessed relative movements, so any
+ * pointer acceleration or speed processing should not be applied.
+ */
+TEST_F(CursorInputMapperTest, PointerCaptureDisablesVelocityProcessing) {
+ addConfigurationProperty("cursor.mode", "pointer");
+ const VelocityControlParameters testParams(5.f /*scale*/, 0.f /*low threshold*/,
+ 100.f /*high threshold*/, 10.f /*acceleration*/);
+ mFakePolicy->setVelocityControlParams(testParams);
+ CursorInputMapper& mapper = addMapperAndConfigure<CursorInputMapper>();
+
+ NotifyDeviceResetArgs resetArgs;
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
+ ASSERT_EQ(ARBITRARY_TIME, resetArgs.eventTime);
+ ASSERT_EQ(DEVICE_ID, resetArgs.deviceId);
+
+ NotifyMotionArgs args;
+
+ // Move and verify scale is applied.
+ process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 10);
+ process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_Y, 20);
+ process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
+ ASSERT_EQ(AINPUT_SOURCE_MOUSE, args.source);
+ ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, args.action);
+ const float relX = args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X);
+ const float relY = args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y);
+ ASSERT_GT(relX, 10);
+ ASSERT_GT(relY, 20);
+
+ // Enable Pointer Capture
+ mFakePolicy->setPointerCapture(true);
+ configureDevice(InputReaderConfiguration::CHANGE_POINTER_CAPTURE);
+ NotifyPointerCaptureChangedArgs captureArgs;
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyCaptureWasCalled(&captureArgs));
+ ASSERT_TRUE(captureArgs.request.enable);
+
+ // Move and verify scale is not applied.
+ process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 10);
+ process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_Y, 20);
+ process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
+ ASSERT_EQ(AINPUT_SOURCE_MOUSE_RELATIVE, args.source);
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
+ ASSERT_EQ(10, args.pointerCoords[0].getX());
+ ASSERT_EQ(20, args.pointerCoords[0].getY());
+}
+
TEST_F(CursorInputMapperTest, Process_ShouldHandleDisplayId) {
CursorInputMapper& mapper = addMapperAndConfigure<CursorInputMapper>();
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index a5ef0e4..e72e21c 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -6713,6 +6713,9 @@
auto dataspace = renderArea.getReqDataSpace();
auto parent = renderArea.getParentLayer();
auto renderIntent = RenderIntent::TONE_MAP_COLORIMETRIC;
+ auto sdrWhitePointNits = DisplayDevice::sDefaultMaxLumiance;
+ auto displayBrightnessNits = DisplayDevice::sDefaultMaxLumiance;
+
if ((dataspace == ui::Dataspace::UNKNOWN) && (parent != nullptr)) {
Mutex::Autolock lock(mStateLock);
auto display = findDisplay([layerStack = parent->getLayerStack()](const auto& display) {
@@ -6726,6 +6729,8 @@
const ui::ColorMode colorMode = display->getCompositionDisplay()->getState().colorMode;
dataspace = pickDataspaceFromColorMode(colorMode);
renderIntent = display->getCompositionDisplay()->getState().renderIntent;
+ sdrWhitePointNits = display->getCompositionDisplay()->getState().sdrWhitePointNits;
+ displayBrightnessNits = display->getCompositionDisplay()->getState().displayBrightnessNits;
}
captureResults.capturedDataspace = dataspace;
@@ -6784,7 +6789,7 @@
BlurSetting::Disabled
: compositionengine::LayerFE::ClientCompositionTargetSettings::
BlurSetting::Enabled,
- DisplayDevice::sDefaultMaxLumiance,
+ isHdrDataspace(dataspace) ? displayBrightnessNits : sdrWhitePointNits,
};
std::vector<compositionengine::LayerFE::LayerSettings> results =
@@ -6799,6 +6804,7 @@
if (regionSampling) {
settings.backgroundBlurRadius = 0;
}
+ captureResults.capturedHdrLayers |= isHdrDataspace(settings.sourceDataspace);
}
clientCompositionLayers.insert(clientCompositionLayers.end(),
diff --git a/services/surfaceflinger/tests/ScreenCapture_test.cpp b/services/surfaceflinger/tests/ScreenCapture_test.cpp
index f9b3185..6a7d8b8 100644
--- a/services/surfaceflinger/tests/ScreenCapture_test.cpp
+++ b/services/surfaceflinger/tests/ScreenCapture_test.cpp
@@ -112,7 +112,7 @@
args.captureSecureLayers = true;
ASSERT_EQ(NO_ERROR, ScreenCapture::captureDisplay(args, mCaptureResults));
ASSERT_TRUE(mCaptureResults.capturedSecureLayers);
- ScreenCapture sc(mCaptureResults.buffer);
+ ScreenCapture sc(mCaptureResults.buffer, mCaptureResults.capturedHdrLayers);
sc.expectColor(Rect(0, 0, 32, 32), Color::RED);
}
@@ -147,7 +147,7 @@
args.captureSecureLayers = true;
ASSERT_EQ(NO_ERROR, ScreenCapture::captureDisplay(args, mCaptureResults));
ASSERT_TRUE(mCaptureResults.capturedSecureLayers);
- ScreenCapture sc(mCaptureResults.buffer);
+ ScreenCapture sc(mCaptureResults.buffer, mCaptureResults.capturedHdrLayers);
sc.expectColor(Rect(0, 0, 10, 10), Color::BLUE);
}
@@ -374,7 +374,7 @@
ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(child, Color::RED, 32, 32));
SurfaceComposerClient::Transaction().apply(true);
ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(args, captureResults));
- ScreenCapture sc(captureResults.buffer);
+ ScreenCapture sc(captureResults.buffer, captureResults.capturedHdrLayers);
sc.expectColor(Rect(0, 0, 9, 9), Color::RED);
}
@@ -860,6 +860,46 @@
mCapture->expectColor(Rect(0, 0, 32, 32), Color::RED);
}
+TEST_F(ScreenCaptureTest, CaptureNonHdrLayer) {
+ sp<SurfaceControl> layer;
+ ASSERT_NO_FATAL_FAILURE(layer = createLayer("test layer", 32, 32,
+ ISurfaceComposerClient::eFXSurfaceBufferState,
+ mBGSurfaceControl.get()));
+ ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(layer, Color::BLACK, 32, 32));
+ Transaction()
+ .show(layer)
+ .setLayer(layer, INT32_MAX)
+ .setDataspace(layer, ui::Dataspace::V0_SRGB)
+ .apply();
+
+ LayerCaptureArgs captureArgs;
+ captureArgs.layerHandle = layer->getHandle();
+
+ ScreenCapture::captureLayers(&mCapture, captureArgs);
+ mCapture->expectColor(Rect(0, 0, 32, 32), Color::BLACK);
+ ASSERT_FALSE(mCapture->capturedHdrLayers());
+}
+
+TEST_F(ScreenCaptureTest, CaptureHdrLayer) {
+ sp<SurfaceControl> layer;
+ ASSERT_NO_FATAL_FAILURE(layer = createLayer("test layer", 32, 32,
+ ISurfaceComposerClient::eFXSurfaceBufferState,
+ mBGSurfaceControl.get()));
+ ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(layer, Color::BLACK, 32, 32));
+ Transaction()
+ .show(layer)
+ .setLayer(layer, INT32_MAX)
+ .setDataspace(layer, ui::Dataspace::BT2020_ITU_PQ)
+ .apply();
+
+ LayerCaptureArgs captureArgs;
+ captureArgs.layerHandle = layer->getHandle();
+
+ ScreenCapture::captureLayers(&mCapture, captureArgs);
+ mCapture->expectColor(Rect(0, 0, 32, 32), Color::BLACK);
+ ASSERT_TRUE(mCapture->capturedHdrLayers());
+}
+
// In the following tests we verify successful skipping of a parent layer,
// so we use the same verification logic and only change how we mutate
// the parent layer to verify that various properties are ignored.
diff --git a/services/surfaceflinger/tests/TransactionTestHarnesses.h b/services/surfaceflinger/tests/TransactionTestHarnesses.h
index 60cffb1..8ce63bc 100644
--- a/services/surfaceflinger/tests/TransactionTestHarnesses.h
+++ b/services/surfaceflinger/tests/TransactionTestHarnesses.h
@@ -79,7 +79,8 @@
BufferItem item;
itemConsumer->acquireBuffer(&item, 0, true);
- auto sc = std::make_unique<ScreenCapture>(item.mGraphicBuffer);
+ constexpr bool kContainsHdr = false;
+ auto sc = std::make_unique<ScreenCapture>(item.mGraphicBuffer, kContainsHdr);
itemConsumer->releaseBuffer(item);
SurfaceComposerClient::destroyDisplay(vDisplay);
return sc;
diff --git a/services/surfaceflinger/tests/utils/ScreenshotUtils.h b/services/surfaceflinger/tests/utils/ScreenshotUtils.h
index ee7e92c..f879430 100644
--- a/services/surfaceflinger/tests/utils/ScreenshotUtils.h
+++ b/services/surfaceflinger/tests/utils/ScreenshotUtils.h
@@ -60,7 +60,8 @@
DisplayCaptureArgs& captureArgs) {
ScreenCaptureResults captureResults;
ASSERT_EQ(NO_ERROR, captureDisplay(captureArgs, captureResults));
- *sc = std::make_unique<ScreenCapture>(captureResults.buffer);
+ *sc = std::make_unique<ScreenCapture>(captureResults.buffer,
+ captureResults.capturedHdrLayers);
}
static status_t captureLayers(LayerCaptureArgs& captureArgs,
@@ -81,9 +82,12 @@
static void captureLayers(std::unique_ptr<ScreenCapture>* sc, LayerCaptureArgs& captureArgs) {
ScreenCaptureResults captureResults;
ASSERT_EQ(NO_ERROR, captureLayers(captureArgs, captureResults));
- *sc = std::make_unique<ScreenCapture>(captureResults.buffer);
+ *sc = std::make_unique<ScreenCapture>(captureResults.buffer,
+ captureResults.capturedHdrLayers);
}
+ bool capturedHdrLayers() const { return mContainsHdr; }
+
void expectColor(const Rect& rect, const Color& color, uint8_t tolerance = 0) {
ASSERT_NE(nullptr, mOutBuffer);
ASSERT_NE(nullptr, mPixels);
@@ -181,7 +185,8 @@
EXPECT_EQ(height, mOutBuffer->getHeight());
}
- explicit ScreenCapture(const sp<GraphicBuffer>& outBuffer) : mOutBuffer(outBuffer) {
+ explicit ScreenCapture(const sp<GraphicBuffer>& outBuffer, bool containsHdr)
+ : mOutBuffer(outBuffer), mContainsHdr(containsHdr) {
if (mOutBuffer) {
mOutBuffer->lock(GRALLOC_USAGE_SW_READ_OFTEN, reinterpret_cast<void**>(&mPixels));
}
@@ -193,6 +198,7 @@
private:
sp<GraphicBuffer> mOutBuffer;
+ bool mContainsHdr = mContainsHdr;
uint8_t* mPixels = nullptr;
};
} // namespace