Merge "[Lut HAL backend] implementation 3rd patch." into main
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index b012243..4758607 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -4656,7 +4656,7 @@
void Dumpstate::TakeScreenshot(const std::string& path) {
const std::string& real_path = path.empty() ? screenshot_path_ : path;
int status =
- RunCommand("", {"/system/bin/screencap", "-p", real_path},
+ RunCommand("", {"screencap", "-p", real_path},
CommandOptions::WithTimeout(10).Always().DropRoot().RedirectStderr().Build());
if (status == 0) {
MYLOGD("Screenshot saved on %s\n", real_path.c_str());
diff --git a/include/android/keycodes.h b/include/android/keycodes.h
index 79cdbca..495e0bd 100644
--- a/include/android/keycodes.h
+++ b/include/android/keycodes.h
@@ -843,6 +843,44 @@
AKEYCODE_EMOJI_PICKER = 317,
/** Take Screenshot */
AKEYCODE_SCREENSHOT = 318,
+ /** To start dictate to an input field */
+ AKEYCODE_DICTATE = 319,
+ /** AC New */
+ AKEYCODE_NEW = 320,
+ /** AC Close */
+ AKEYCODE_CLOSE = 321,
+ /** To toggle 'Do Not Disturb' mode */
+ AKEYCODE_DO_NOT_DISTURB = 322,
+ /** To Print */
+ AKEYCODE_PRINT = 323,
+ /** To Lock the screen */
+ AKEYCODE_LOCK = 324,
+ /** To toggle fullscreen mode (on the current application) */
+ AKEYCODE_FULLSCREEN = 325,
+ /** F13 key */
+ AKEYCODE_F13 = 326,
+ /** F14 key */
+ AKEYCODE_F14 = 327,
+ /** F15 key */
+ AKEYCODE_F15 = 328,
+ /** F16 key */
+ AKEYCODE_F16 = 329,
+ /** F17 key */
+ AKEYCODE_F17 = 330,
+ /** F18 key */
+ AKEYCODE_F18 = 331,
+ /** F19 key */
+ AKEYCODE_F19 = 332,
+ /** F20 key */
+ AKEYCODE_F20 = 333,
+ /** F21 key */
+ AKEYCODE_F21 = 334,
+ /** F22 key */
+ AKEYCODE_F22 = 335,
+ /** F23 key */
+ AKEYCODE_F23 = 336,
+ /** F24 key */
+ AKEYCODE_F24 = 337,
// NOTE: If you add a new keycode here you must also add it to several other files.
// Refer to frameworks/base/core/java/android/view/KeyEvent.java for the full list.
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index 807f850..a0a8b35 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -2133,13 +2133,13 @@
}
SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setInputWindowInfo(
- const sp<SurfaceControl>& sc, const WindowInfo& info) {
+ const sp<SurfaceControl>& sc, sp<WindowInfoHandle> info) {
layer_state_t* s = getLayerState(sc);
if (!s) {
mStatus = BAD_INDEX;
return *this;
}
- s->windowInfoHandle = new WindowInfoHandle(info);
+ s->windowInfoHandle = std::move(info);
s->what |= layer_state_t::eInputInfoChanged;
return *this;
}
diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h
index e9262b3..7c6b341 100644
--- a/libs/gui/include/gui/SurfaceComposerClient.h
+++ b/libs/gui/include/gui/SurfaceComposerClient.h
@@ -687,7 +687,8 @@
// ONLY FOR BLAST ADAPTER
Transaction& notifyProducerDisconnect(const sp<SurfaceControl>& sc);
- Transaction& setInputWindowInfo(const sp<SurfaceControl>& sc, const gui::WindowInfo& info);
+ Transaction& setInputWindowInfo(const sp<SurfaceControl>& sc,
+ sp<gui::WindowInfoHandle> info);
Transaction& setFocusedWindow(const gui::FocusRequest& request);
Transaction& addWindowInfosReportedListener(
diff --git a/libs/gui/tests/EndToEndNativeInputTest.cpp b/libs/gui/tests/EndToEndNativeInputTest.cpp
index 17630e3..0e84d68 100644
--- a/libs/gui/tests/EndToEndNativeInputTest.cpp
+++ b/libs/gui/tests/EndToEndNativeInputTest.cpp
@@ -112,7 +112,7 @@
mInputFlinger = getInputFlinger();
if (noInputChannel) {
- mInputInfo.setInputConfig(WindowInfo::InputConfig::NO_INPUT_CHANNEL, true);
+ mInputInfo->editInfo()->setInputConfig(WindowInfo::InputConfig::NO_INPUT_CHANNEL, true);
} else {
android::os::InputChannelCore tempChannel;
android::binder::Status result =
@@ -121,21 +121,21 @@
ADD_FAILURE() << "binder call to createInputChannel failed";
}
mClientChannel = InputChannel::create(std::move(tempChannel));
- mInputInfo.token = mClientChannel->getConnectionToken();
+ mInputInfo->editInfo()->token = mClientChannel->getConnectionToken();
mInputConsumer = new InputConsumer(mClientChannel);
}
- mInputInfo.name = "Test info";
- mInputInfo.dispatchingTimeout = 5s;
- mInputInfo.globalScaleFactor = 1.0;
- mInputInfo.touchableRegion.orSelf(Rect(0, 0, width, height));
+ mInputInfo->editInfo()->name = "Test info";
+ mInputInfo->editInfo()->dispatchingTimeout = 5s;
+ mInputInfo->editInfo()->globalScaleFactor = 1.0;
+ mInputInfo->editInfo()->touchableRegion.orSelf(Rect(0, 0, width, height));
InputApplicationInfo aInfo;
aInfo.token = new BBinder();
aInfo.name = "Test app info";
aInfo.dispatchingTimeoutMillis =
std::chrono::duration_cast<std::chrono::milliseconds>(DISPATCHING_TIMEOUT).count();
- mInputInfo.applicationInfo = aInfo;
+ mInputInfo->editInfo()->applicationInfo = aInfo;
}
static std::unique_ptr<InputSurface> makeColorInputSurface(const sp<SurfaceComposerClient>& scc,
@@ -183,20 +183,6 @@
return std::make_unique<InputSurface>(surfaceControl, width, height);
}
- InputEvent* consumeEvent(std::chrono::milliseconds timeout = 3000ms) {
- mClientChannel->waitForMessage(timeout);
-
- InputEvent* ev;
- uint32_t seqId;
- status_t consumed = mInputConsumer->consume(&mInputEventFactory, true, -1, &seqId, &ev);
- if (consumed != OK) {
- return nullptr;
- }
- status_t status = mInputConsumer->sendFinishedSignal(seqId, true);
- EXPECT_EQ(OK, status) << "Could not send finished signal";
- return ev;
- }
-
void assertFocusChange(bool hasFocus) {
InputEvent* ev = consumeEvent();
ASSERT_NE(ev, nullptr);
@@ -314,8 +300,8 @@
void requestFocus(ui::LogicalDisplayId displayId = ui::LogicalDisplayId::DEFAULT) {
SurfaceComposerClient::Transaction t;
FocusRequest request;
- request.token = mInputInfo.token;
- request.windowName = mInputInfo.name;
+ request.token = mInputInfo->getInfo()->token;
+ request.windowName = mInputInfo->getInfo()->name;
request.timestamp = systemTime(SYSTEM_TIME_MONOTONIC);
request.displayId = displayId.val();
t.setFocusedWindow(request);
@@ -323,14 +309,30 @@
}
public:
+ // But should be private
+ sp<gui::WindowInfoHandle> mInputInfo = sp<gui::WindowInfoHandle>::make();
sp<SurfaceControl> mSurfaceControl;
+
+private:
std::shared_ptr<InputChannel> mClientChannel;
sp<IInputFlinger> mInputFlinger;
- WindowInfo mInputInfo;
-
PreallocatedInputEventFactory mInputEventFactory;
InputConsumer* mInputConsumer;
+
+ InputEvent* consumeEvent(std::chrono::milliseconds timeout = 3000ms) {
+ mClientChannel->waitForMessage(timeout);
+
+ InputEvent* ev;
+ uint32_t seqId;
+ status_t consumed = mInputConsumer->consume(&mInputEventFactory, true, -1, &seqId, &ev);
+ if (consumed != OK) {
+ return nullptr;
+ }
+ status_t status = mInputConsumer->sendFinishedSignal(seqId, true);
+ EXPECT_EQ(OK, status) << "Could not send finished signal";
+ return ev;
+ }
};
class BlastInputSurface : public InputSurface {
@@ -458,7 +460,7 @@
injectTap(101, 101);
- EXPECT_NE(surface->consumeEvent(), nullptr);
+ surface->expectTap(1, 1);
}
/**
@@ -521,7 +523,7 @@
std::unique_ptr<InputSurface> fgSurface = makeSurface(100, 100);
bgSurface->showAt(100, 100);
- fgSurface->mInputInfo.surfaceInset = 5;
+ fgSurface->mInputInfo->editInfo()->surfaceInset = 5;
fgSurface->showAt(100, 100);
injectTap(106, 106);
@@ -536,8 +538,8 @@
std::unique_ptr<InputSurface> fgSurface = makeSurface(100, 100);
bgSurface->showAt(100, 100);
- fgSurface->mInputInfo.surfaceInset = 5;
- fgSurface->mInputInfo.replaceTouchableRegionWithCrop = true;
+ fgSurface->mInputInfo->editInfo()->surfaceInset = 5;
+ fgSurface->mInputInfo->editInfo()->replaceTouchableRegionWithCrop = true;
fgSurface->showAt(100, 100);
injectTap(106, 106);
@@ -553,7 +555,7 @@
std::unique_ptr<InputSurface> childSurface = makeSurface(100, 100);
parentSurface->showAt(100, 100);
- childSurface->mInputInfo.surfaceInset = 10;
+ childSurface->mInputInfo->editInfo()->surfaceInset = 10;
childSurface->showAt(100, 100);
childSurface->doTransaction([&](auto& t, auto& sc) {
@@ -574,7 +576,7 @@
std::unique_ptr<InputSurface> fgSurface = makeSurface(100, 100);
bgSurface->showAt(100, 100);
- fgSurface->mInputInfo.surfaceInset = 5;
+ fgSurface->mInputInfo->editInfo()->surfaceInset = 5;
fgSurface->showAt(100, 100);
fgSurface->doTransaction([&](auto& t, auto& sc) { t.setMatrix(sc, 2.0, 0, 0, 4.0); });
@@ -593,7 +595,7 @@
bgSurface->showAt(100, 100);
// In case we pass the very big inset without any checking.
- fgSurface->mInputInfo.surfaceInset = INT32_MAX;
+ fgSurface->mInputInfo->editInfo()->surfaceInset = INT32_MAX;
fgSurface->showAt(100, 100);
fgSurface->doTransaction([&](auto& t, auto& sc) { t.setMatrix(sc, 2.0, 0, 0, 2.0); });
@@ -606,13 +608,13 @@
TEST_F(InputSurfacesTest, touchable_region) {
std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
- surface->mInputInfo.touchableRegion.set(Rect{19, 29, 21, 31});
+ surface->mInputInfo->editInfo()->touchableRegion.set(Rect{19, 29, 21, 31});
surface->showAt(11, 22);
// A tap within the surface but outside the touchable region should not be sent to the surface.
injectTap(20, 30);
- EXPECT_EQ(surface->consumeEvent(/*timeout=*/200ms), nullptr);
+ surface->assertNoEvent();
injectTap(31, 52);
surface->expectTap(20, 30);
@@ -627,7 +629,8 @@
// Since the surface is offset from the origin, the touchable region will be transformed into
// display space, which would trigger an overflow or an underflow. Ensure that we are protected
// against such a situation.
- fgSurface->mInputInfo.touchableRegion.orSelf(Rect{INT32_MIN, INT32_MIN, INT32_MAX, INT32_MAX});
+ fgSurface->mInputInfo->editInfo()->touchableRegion.orSelf(
+ Rect{INT32_MIN, INT32_MIN, INT32_MAX, INT32_MAX});
fgSurface->showAt(100, 100);
@@ -642,7 +645,8 @@
std::unique_ptr<InputSurface> fgSurface = makeSurface(100, 100);
bgSurface->showAt(0, 0);
- fgSurface->mInputInfo.touchableRegion.orSelf(Rect{INT32_MIN, INT32_MIN, INT32_MAX, INT32_MAX});
+ fgSurface->mInputInfo->editInfo()->touchableRegion.orSelf(
+ Rect{INT32_MIN, INT32_MIN, INT32_MAX, INT32_MAX});
fgSurface->showAt(0, 0);
fgSurface->doTransaction([&](auto& t, auto& sc) { t.setMatrix(sc, 2.0, 0, 0, 2.0); });
@@ -812,7 +816,7 @@
TEST_F(InputSurfacesTest, rotate_surface_with_scale_and_insets) {
std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
- surface->mInputInfo.surfaceInset = 5;
+ surface->mInputInfo->editInfo()->surfaceInset = 5;
surface->showAt(100, 100);
surface->doTransaction([](auto& t, auto& sc) {
@@ -841,11 +845,12 @@
// Add non touchable window to fully cover touchable window. Window behind gets touch, but
// with flag AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED
std::unique_ptr<InputSurface> nonTouchableSurface = makeSurface(100, 100);
- nonTouchableSurface->mInputInfo.setInputConfig(WindowInfo::InputConfig::NOT_TOUCHABLE, true);
- nonTouchableSurface->mInputInfo.ownerUid = gui::Uid{22222};
+ nonTouchableSurface->mInputInfo->editInfo()
+ ->setInputConfig(WindowInfo::InputConfig::NOT_TOUCHABLE, true);
+ nonTouchableSurface->mInputInfo->editInfo()->ownerUid = gui::Uid{22222};
// Overriding occlusion mode otherwise the touch would be discarded at InputDispatcher by
// the default obscured/untrusted touch filter introduced in S.
- nonTouchableSurface->mInputInfo.touchOcclusionMode = TouchOcclusionMode::ALLOW;
+ nonTouchableSurface->mInputInfo->editInfo()->touchOcclusionMode = TouchOcclusionMode::ALLOW;
nonTouchableSurface->showAt(100, 100);
injectTap(190, 199);
@@ -861,10 +866,12 @@
// AMOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED
std::unique_ptr<InputSurface> parentSurface = makeSurface(100, 100);
std::unique_ptr<InputSurface> nonTouchableSurface = makeSurface(100, 100);
- nonTouchableSurface->mInputInfo.setInputConfig(WindowInfo::InputConfig::NOT_TOUCHABLE, true);
- parentSurface->mInputInfo.setInputConfig(WindowInfo::InputConfig::NOT_TOUCHABLE, true);
- nonTouchableSurface->mInputInfo.ownerUid = gui::Uid{22222};
- parentSurface->mInputInfo.ownerUid = gui::Uid{22222};
+ nonTouchableSurface->mInputInfo->editInfo()
+ ->setInputConfig(WindowInfo::InputConfig::NOT_TOUCHABLE, true);
+ parentSurface->mInputInfo->editInfo()->setInputConfig(WindowInfo::InputConfig::NOT_TOUCHABLE,
+ true);
+ nonTouchableSurface->mInputInfo->editInfo()->ownerUid = gui::Uid{22222};
+ parentSurface->mInputInfo->editInfo()->ownerUid = gui::Uid{22222};
nonTouchableSurface->showAt(0, 0);
parentSurface->showAt(100, 100);
@@ -885,10 +892,12 @@
// the touchable window. Window behind gets touch with no obscured flags.
std::unique_ptr<InputSurface> parentSurface = makeSurface(100, 100);
std::unique_ptr<InputSurface> nonTouchableSurface = makeSurface(100, 100);
- nonTouchableSurface->mInputInfo.setInputConfig(WindowInfo::InputConfig::NOT_TOUCHABLE, true);
- parentSurface->mInputInfo.setInputConfig(WindowInfo::InputConfig::NOT_TOUCHABLE, true);
- nonTouchableSurface->mInputInfo.ownerUid = gui::Uid{22222};
- parentSurface->mInputInfo.ownerUid = gui::Uid{22222};
+ nonTouchableSurface->mInputInfo->editInfo()
+ ->setInputConfig(WindowInfo::InputConfig::NOT_TOUCHABLE, true);
+ parentSurface->mInputInfo->editInfo()->setInputConfig(WindowInfo::InputConfig::NOT_TOUCHABLE,
+ true);
+ nonTouchableSurface->mInputInfo->editInfo()->ownerUid = gui::Uid{22222};
+ parentSurface->mInputInfo->editInfo()->ownerUid = gui::Uid{22222};
nonTouchableSurface->showAt(0, 0);
parentSurface->showAt(50, 50);
@@ -906,8 +915,9 @@
std::unique_ptr<InputSurface> bufferSurface =
InputSurface::makeBufferInputSurface(mComposerClient, 0, 0);
- bufferSurface->mInputInfo.setInputConfig(WindowInfo::InputConfig::NOT_TOUCHABLE, true);
- bufferSurface->mInputInfo.ownerUid = gui::Uid{22222};
+ bufferSurface->mInputInfo->editInfo()->setInputConfig(WindowInfo::InputConfig::NOT_TOUCHABLE,
+ true);
+ bufferSurface->mInputInfo->editInfo()->ownerUid = gui::Uid{22222};
surface->showAt(10, 10);
bufferSurface->showAt(50, 50, Rect::EMPTY_RECT);
@@ -921,8 +931,9 @@
std::unique_ptr<BlastInputSurface> bufferSurface =
BlastInputSurface::makeBlastInputSurface(mComposerClient, 0, 0);
- bufferSurface->mInputInfo.setInputConfig(WindowInfo::InputConfig::NOT_TOUCHABLE, true);
- bufferSurface->mInputInfo.ownerUid = gui::Uid{22222};
+ bufferSurface->mInputInfo->editInfo()->setInputConfig(WindowInfo::InputConfig::NOT_TOUCHABLE,
+ true);
+ bufferSurface->mInputInfo->editInfo()->ownerUid = gui::Uid{22222};
surface->showAt(10, 10);
bufferSurface->showAt(50, 50, Rect::EMPTY_RECT);
@@ -965,13 +976,14 @@
TEST_F(InputSurfacesTest, strict_unobscured_input_obscured_window) {
std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
- surface->mInputInfo.ownerUid = gui::Uid{11111};
+ surface->mInputInfo->editInfo()->ownerUid = gui::Uid{11111};
surface->doTransaction(
[&](auto& t, auto& sc) { t.setDropInputMode(sc, gui::DropInputMode::OBSCURED); });
surface->showAt(100, 100);
std::unique_ptr<InputSurface> obscuringSurface = makeSurface(100, 100);
- obscuringSurface->mInputInfo.setInputConfig(WindowInfo::InputConfig::NOT_TOUCHABLE, true);
- obscuringSurface->mInputInfo.ownerUid = gui::Uid{22222};
+ obscuringSurface->mInputInfo->editInfo()->setInputConfig(WindowInfo::InputConfig::NOT_TOUCHABLE,
+ true);
+ obscuringSurface->mInputInfo->editInfo()->ownerUid = gui::Uid{22222};
obscuringSurface->showAt(100, 100);
injectTap(101, 101);
surface->assertNoEvent();
@@ -984,13 +996,14 @@
TEST_F(InputSurfacesTest, strict_unobscured_input_partially_obscured_window) {
std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
- surface->mInputInfo.ownerUid = gui::Uid{11111};
+ surface->mInputInfo->editInfo()->ownerUid = gui::Uid{11111};
surface->doTransaction(
[&](auto& t, auto& sc) { t.setDropInputMode(sc, gui::DropInputMode::OBSCURED); });
surface->showAt(100, 100);
std::unique_ptr<InputSurface> obscuringSurface = makeSurface(100, 100);
- obscuringSurface->mInputInfo.setInputConfig(WindowInfo::InputConfig::NOT_TOUCHABLE, true);
- obscuringSurface->mInputInfo.ownerUid = gui::Uid{22222};
+ obscuringSurface->mInputInfo->editInfo()->setInputConfig(WindowInfo::InputConfig::NOT_TOUCHABLE,
+ true);
+ obscuringSurface->mInputInfo->editInfo()->ownerUid = gui::Uid{22222};
obscuringSurface->showAt(190, 190);
injectTap(101, 101);
@@ -1054,7 +1067,7 @@
BlastInputSurface::makeBlastInputSurface(mComposerClient, 0, 0);
surface->showAt(100, 100);
- bufferSurface->mInputInfo.touchableRegion.orSelf(Rect(0, 0, 200, 200));
+ bufferSurface->mInputInfo->editInfo()->touchableRegion.orSelf(Rect(0, 0, 200, 200));
bufferSurface->showAt(100, 100, Rect::EMPTY_RECT);
injectTap(101, 101);
@@ -1097,8 +1110,8 @@
InputSurface::makeContainerInputSurface(mComposerClient, 100, 100);
containerSurface->doTransaction(
[&](auto& t, auto& sc) { t.reparent(sc, parentContainer->mSurfaceControl); });
- containerSurface->mInputInfo.replaceTouchableRegionWithCrop = true;
- containerSurface->mInputInfo.touchableRegionCropHandle = nullptr;
+ containerSurface->mInputInfo->editInfo()->replaceTouchableRegionWithCrop = true;
+ containerSurface->mInputInfo->editInfo()->touchableRegionCropHandle = nullptr;
parentContainer->showAt(10, 10, Rect(0, 0, 20, 20));
containerSurface->showAt(10, 10, Rect(0, 0, 5, 5));
@@ -1124,8 +1137,8 @@
InputSurface::makeContainerInputSurface(mComposerClient, 100, 100);
containerSurface->doTransaction(
[&](auto& t, auto& sc) { t.reparent(sc, parentContainer->mSurfaceControl); });
- containerSurface->mInputInfo.replaceTouchableRegionWithCrop = true;
- containerSurface->mInputInfo.touchableRegionCropHandle = nullptr;
+ containerSurface->mInputInfo->editInfo()->replaceTouchableRegionWithCrop = true;
+ containerSurface->mInputInfo->editInfo()->touchableRegionCropHandle = nullptr;
parentContainer->doTransaction(
[&](auto& t, auto& sc) { t.reparent(sc, bgContainer->mSurfaceControl); });
bgContainer->showAt(0, 0, Rect(0, 0, 100, 100));
@@ -1152,8 +1165,8 @@
std::unique_ptr<InputSurface> containerSurface =
InputSurface::makeContainerInputSurface(mComposerClient, 100, 100);
- containerSurface->mInputInfo.replaceTouchableRegionWithCrop = true;
- containerSurface->mInputInfo.touchableRegionCropHandle =
+ containerSurface->mInputInfo->editInfo()->replaceTouchableRegionWithCrop = true;
+ containerSurface->mInputInfo->editInfo()->touchableRegionCropHandle =
cropLayer->mSurfaceControl->getHandle();
containerSurface->showAt(10, 10, Rect::INVALID_RECT);
diff --git a/libs/input/InputEventLabels.cpp b/libs/input/InputEventLabels.cpp
index 8db0ca5..b537feb 100644
--- a/libs/input/InputEventLabels.cpp
+++ b/libs/input/InputEventLabels.cpp
@@ -350,7 +350,26 @@
DEFINE_KEYCODE(MACRO_3), \
DEFINE_KEYCODE(MACRO_4), \
DEFINE_KEYCODE(EMOJI_PICKER), \
- DEFINE_KEYCODE(SCREENSHOT)
+ DEFINE_KEYCODE(SCREENSHOT), \
+ DEFINE_KEYCODE(DICTATE), \
+ DEFINE_KEYCODE(NEW), \
+ DEFINE_KEYCODE(CLOSE), \
+ DEFINE_KEYCODE(DO_NOT_DISTURB), \
+ DEFINE_KEYCODE(PRINT), \
+ DEFINE_KEYCODE(LOCK), \
+ DEFINE_KEYCODE(FULLSCREEN), \
+ DEFINE_KEYCODE(F13), \
+ DEFINE_KEYCODE(F14), \
+ DEFINE_KEYCODE(F15), \
+ DEFINE_KEYCODE(F16), \
+ DEFINE_KEYCODE(F17), \
+ DEFINE_KEYCODE(F18), \
+ DEFINE_KEYCODE(F19),\
+ DEFINE_KEYCODE(F20), \
+ DEFINE_KEYCODE(F21), \
+ DEFINE_KEYCODE(F22), \
+ DEFINE_KEYCODE(F23), \
+ DEFINE_KEYCODE(F24)
// NOTE: If you add a new axis here you must also add it to several other files.
// Refer to frameworks/base/core/java/android/view/MotionEvent.java for the full list.
diff --git a/libs/sensor/Sensor.cpp b/libs/sensor/Sensor.cpp
index eddd568..797efbe 100644
--- a/libs/sensor/Sensor.cpp
+++ b/libs/sensor/Sensor.cpp
@@ -306,7 +306,18 @@
}
if (halVersion > SENSORS_DEVICE_API_VERSION_1_0 && hwSensor.requiredPermission) {
mRequiredPermission = hwSensor.requiredPermission;
- if (!strcmp(mRequiredPermission, SENSOR_PERMISSION_BODY_SENSORS)) {
+ bool requiresBodySensorPermission =
+ !strcmp(mRequiredPermission, SENSOR_PERMISSION_BODY_SENSORS);
+ if (android::permission::flags::replace_body_sensor_permission_enabled()) {
+ if (requiresBodySensorPermission) {
+ ALOGE("Sensor %s using deprecated Body Sensor permission", mName.c_str());
+ }
+
+ AppOpsManager appOps;
+ // Lookup to see if an AppOp exists for the permission. If none
+ // does, the default value of -1 is used.
+ mRequiredAppOp = appOps.permissionToOpCode(String16(mRequiredPermission));
+ } else if (requiresBodySensorPermission) {
AppOpsManager appOps;
mRequiredAppOp = appOps.permissionToOpCode(String16(SENSOR_PERMISSION_BODY_SENSORS));
}
diff --git a/services/inputflinger/tests/InputMapperTest.cpp b/services/inputflinger/tests/InputMapperTest.cpp
index 7dff144..ca797dc 100644
--- a/services/inputflinger/tests/InputMapperTest.cpp
+++ b/services/inputflinger/tests/InputMapperTest.cpp
@@ -53,13 +53,13 @@
}
void InputMapperUnitTest::setupAxis(int axis, bool valid, int32_t min, int32_t max,
- int32_t resolution) {
+ int32_t resolution, int32_t flat, int32_t fuzz) {
EXPECT_CALL(mMockEventHub, getAbsoluteAxisInfo(EVENTHUB_ID, axis))
.WillRepeatedly(Return(valid ? std::optional<RawAbsoluteAxisInfo>{{
.minValue = min,
.maxValue = max,
- .flat = 0,
- .fuzz = 0,
+ .flat = flat,
+ .fuzz = fuzz,
.resolution = resolution,
}}
: std::nullopt));
diff --git a/services/inputflinger/tests/InputMapperTest.h b/services/inputflinger/tests/InputMapperTest.h
index fc27e4f..b6c5812 100644
--- a/services/inputflinger/tests/InputMapperTest.h
+++ b/services/inputflinger/tests/InputMapperTest.h
@@ -43,7 +43,8 @@
virtual void SetUp() override { SetUpWithBus(0); }
virtual void SetUpWithBus(int bus);
- void setupAxis(int axis, bool valid, int32_t min, int32_t max, int32_t resolution);
+ void setupAxis(int axis, bool valid, int32_t min, int32_t max, int32_t resolution,
+ int32_t flat = 0, int32_t fuzz = 0);
void expectScanCodes(bool present, std::set<int> scanCodes);
diff --git a/services/inputflinger/tests/SensorInputMapper_test.cpp b/services/inputflinger/tests/SensorInputMapper_test.cpp
index 01814a6..2c12653 100644
--- a/services/inputflinger/tests/SensorInputMapper_test.cpp
+++ b/services/inputflinger/tests/SensorInputMapper_test.cpp
@@ -16,168 +16,164 @@
#include "SensorInputMapper.h"
+#include <cstdint>
+#include <list>
+#include <optional>
+#include <utility>
#include <vector>
#include <EventHub.h>
#include <NotifyArgs.h>
+#include <ftl/enum.h>
+#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <input/Input.h>
#include <input/InputDevice.h>
+#include <input/PrintTools.h>
#include <linux/input-event-codes.h>
#include "InputMapperTest.h"
+#include "TestEventMatchers.h"
namespace android {
-class SensorInputMapperTest : public InputMapperTest {
+using testing::AllOf;
+using testing::ElementsAre;
+using testing::Return;
+using testing::VariantWith;
+
+namespace {
+
+constexpr int32_t ACCEL_RAW_MIN = -32768;
+constexpr int32_t ACCEL_RAW_MAX = 32768;
+constexpr int32_t ACCEL_RAW_FUZZ = 16;
+constexpr int32_t ACCEL_RAW_FLAT = 0;
+constexpr int32_t ACCEL_RAW_RESOLUTION = 8192;
+
+constexpr int32_t GYRO_RAW_MIN = -2097152;
+constexpr int32_t GYRO_RAW_MAX = 2097152;
+constexpr int32_t GYRO_RAW_FUZZ = 16;
+constexpr int32_t GYRO_RAW_FLAT = 0;
+constexpr int32_t GYRO_RAW_RESOLUTION = 1024;
+
+constexpr float GRAVITY_MS2_UNIT = 9.80665f;
+constexpr float DEGREE_RADIAN_UNIT = 0.0174533f;
+
+} // namespace
+
+class SensorInputMapperTest : public InputMapperUnitTest {
protected:
- static const int32_t ACCEL_RAW_MIN;
- static const int32_t ACCEL_RAW_MAX;
- static const int32_t ACCEL_RAW_FUZZ;
- static const int32_t ACCEL_RAW_FLAT;
- static const int32_t ACCEL_RAW_RESOLUTION;
+ void SetUp() override {
+ InputMapperUnitTest::SetUp();
+ EXPECT_CALL(mMockEventHub, getDeviceClasses(EVENTHUB_ID))
+ .WillRepeatedly(Return(InputDeviceClass::SENSOR));
+ // The mapper requests info on all ABS axes, including ones which aren't actually used, so
+ // just return nullopt for all axes we don't explicitly set up.
+ EXPECT_CALL(mMockEventHub, getAbsoluteAxisInfo(EVENTHUB_ID, testing::_))
+ .WillRepeatedly(Return(std::nullopt));
+ }
- static const int32_t GYRO_RAW_MIN;
- static const int32_t GYRO_RAW_MAX;
- static const int32_t GYRO_RAW_FUZZ;
- static const int32_t GYRO_RAW_FLAT;
- static const int32_t GYRO_RAW_RESOLUTION;
-
- static const float GRAVITY_MS2_UNIT;
- static const float DEGREE_RADIAN_UNIT;
-
- void prepareAccelAxes();
- void prepareGyroAxes();
- void setAccelProperties();
- void setGyroProperties();
- void SetUp() override { InputMapperTest::SetUp(DEVICE_CLASSES | InputDeviceClass::SENSOR); }
+ void setupSensor(int32_t absCode, InputDeviceSensorType type, int32_t sensorDataIndex) {
+ EXPECT_CALL(mMockEventHub, mapSensor(EVENTHUB_ID, absCode))
+ .WillRepeatedly(Return(std::make_pair(type, sensorDataIndex)));
+ }
};
-const int32_t SensorInputMapperTest::ACCEL_RAW_MIN = -32768;
-const int32_t SensorInputMapperTest::ACCEL_RAW_MAX = 32768;
-const int32_t SensorInputMapperTest::ACCEL_RAW_FUZZ = 16;
-const int32_t SensorInputMapperTest::ACCEL_RAW_FLAT = 0;
-const int32_t SensorInputMapperTest::ACCEL_RAW_RESOLUTION = 8192;
-
-const int32_t SensorInputMapperTest::GYRO_RAW_MIN = -2097152;
-const int32_t SensorInputMapperTest::GYRO_RAW_MAX = 2097152;
-const int32_t SensorInputMapperTest::GYRO_RAW_FUZZ = 16;
-const int32_t SensorInputMapperTest::GYRO_RAW_FLAT = 0;
-const int32_t SensorInputMapperTest::GYRO_RAW_RESOLUTION = 1024;
-
-const float SensorInputMapperTest::GRAVITY_MS2_UNIT = 9.80665f;
-const float SensorInputMapperTest::DEGREE_RADIAN_UNIT = 0.0174533f;
-
-void SensorInputMapperTest::prepareAccelAxes() {
- mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_X, ACCEL_RAW_MIN, ACCEL_RAW_MAX, ACCEL_RAW_FUZZ,
- ACCEL_RAW_FLAT, ACCEL_RAW_RESOLUTION);
- mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_Y, ACCEL_RAW_MIN, ACCEL_RAW_MAX, ACCEL_RAW_FUZZ,
- ACCEL_RAW_FLAT, ACCEL_RAW_RESOLUTION);
- mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_Z, ACCEL_RAW_MIN, ACCEL_RAW_MAX, ACCEL_RAW_FUZZ,
- ACCEL_RAW_FLAT, ACCEL_RAW_RESOLUTION);
-}
-
-void SensorInputMapperTest::prepareGyroAxes() {
- mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_RX, GYRO_RAW_MIN, GYRO_RAW_MAX, GYRO_RAW_FUZZ,
- GYRO_RAW_FLAT, GYRO_RAW_RESOLUTION);
- mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_RY, GYRO_RAW_MIN, GYRO_RAW_MAX, GYRO_RAW_FUZZ,
- GYRO_RAW_FLAT, GYRO_RAW_RESOLUTION);
- mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_RZ, GYRO_RAW_MIN, GYRO_RAW_MAX, GYRO_RAW_FUZZ,
- GYRO_RAW_FLAT, GYRO_RAW_RESOLUTION);
-}
-
-void SensorInputMapperTest::setAccelProperties() {
- mFakeEventHub->addSensorAxis(EVENTHUB_ID, /* absCode */ 0, InputDeviceSensorType::ACCELEROMETER,
- /* sensorDataIndex */ 0);
- mFakeEventHub->addSensorAxis(EVENTHUB_ID, /* absCode */ 1, InputDeviceSensorType::ACCELEROMETER,
- /* sensorDataIndex */ 1);
- mFakeEventHub->addSensorAxis(EVENTHUB_ID, /* absCode */ 2, InputDeviceSensorType::ACCELEROMETER,
- /* sensorDataIndex */ 2);
- mFakeEventHub->setMscEvent(EVENTHUB_ID, MSC_TIMESTAMP);
- addConfigurationProperty("sensor.accelerometer.reportingMode", "0");
- addConfigurationProperty("sensor.accelerometer.maxDelay", "100000");
- addConfigurationProperty("sensor.accelerometer.minDelay", "5000");
- addConfigurationProperty("sensor.accelerometer.power", "1.5");
-}
-
-void SensorInputMapperTest::setGyroProperties() {
- mFakeEventHub->addSensorAxis(EVENTHUB_ID, /* absCode */ 3, InputDeviceSensorType::GYROSCOPE,
- /* sensorDataIndex */ 0);
- mFakeEventHub->addSensorAxis(EVENTHUB_ID, /* absCode */ 4, InputDeviceSensorType::GYROSCOPE,
- /* sensorDataIndex */ 1);
- mFakeEventHub->addSensorAxis(EVENTHUB_ID, /* absCode */ 5, InputDeviceSensorType::GYROSCOPE,
- /* sensorDataIndex */ 2);
- mFakeEventHub->setMscEvent(EVENTHUB_ID, MSC_TIMESTAMP);
- addConfigurationProperty("sensor.gyroscope.reportingMode", "0");
- addConfigurationProperty("sensor.gyroscope.maxDelay", "100000");
- addConfigurationProperty("sensor.gyroscope.minDelay", "5000");
- addConfigurationProperty("sensor.gyroscope.power", "0.8");
-}
-
TEST_F(SensorInputMapperTest, GetSources) {
- SensorInputMapper& mapper = constructAndAddMapper<SensorInputMapper>();
+ mMapper = createInputMapper<SensorInputMapper>(*mDeviceContext,
+ mFakePolicy->getReaderConfiguration());
- ASSERT_EQ(static_cast<uint32_t>(AINPUT_SOURCE_SENSOR), mapper.getSources());
+ ASSERT_EQ(static_cast<uint32_t>(AINPUT_SOURCE_SENSOR), mMapper->getSources());
}
TEST_F(SensorInputMapperTest, ProcessAccelerometerSensor) {
- setAccelProperties();
- prepareAccelAxes();
- SensorInputMapper& mapper = constructAndAddMapper<SensorInputMapper>();
+ EXPECT_CALL(mMockEventHub, hasMscEvent(EVENTHUB_ID, MSC_TIMESTAMP))
+ .WillRepeatedly(Return(true));
+ setupSensor(ABS_X, InputDeviceSensorType::ACCELEROMETER, /*sensorDataIndex=*/0);
+ setupSensor(ABS_Y, InputDeviceSensorType::ACCELEROMETER, /*sensorDataIndex=*/1);
+ setupSensor(ABS_Z, InputDeviceSensorType::ACCELEROMETER, /*sensorDataIndex=*/2);
+ setupAxis(ABS_X, /*valid=*/true, ACCEL_RAW_MIN, ACCEL_RAW_MAX, ACCEL_RAW_RESOLUTION,
+ ACCEL_RAW_FLAT, ACCEL_RAW_FUZZ);
+ setupAxis(ABS_Y, /*valid=*/true, ACCEL_RAW_MIN, ACCEL_RAW_MAX, ACCEL_RAW_RESOLUTION,
+ ACCEL_RAW_FLAT, ACCEL_RAW_FUZZ);
+ setupAxis(ABS_Z, /*valid=*/true, ACCEL_RAW_MIN, ACCEL_RAW_MAX, ACCEL_RAW_RESOLUTION,
+ ACCEL_RAW_FLAT, ACCEL_RAW_FUZZ);
+ mPropertyMap.addProperty("sensor.accelerometer.reportingMode", "0");
+ mPropertyMap.addProperty("sensor.accelerometer.maxDelay", "100000");
+ mPropertyMap.addProperty("sensor.accelerometer.minDelay", "5000");
+ mPropertyMap.addProperty("sensor.accelerometer.power", "1.5");
+ mMapper = createInputMapper<SensorInputMapper>(*mDeviceContext,
+ mFakePolicy->getReaderConfiguration());
- ASSERT_TRUE(mapper.enableSensor(InputDeviceSensorType::ACCELEROMETER,
- std::chrono::microseconds(10000),
- std::chrono::microseconds(0)));
- ASSERT_TRUE(mFakeEventHub->isDeviceEnabled(EVENTHUB_ID));
- process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_X, 20000);
- process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_Y, -20000);
- process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_Z, 40000);
- process(mapper, ARBITRARY_TIME, READ_TIME, EV_MSC, MSC_TIMESTAMP, 1000);
- process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
+ EXPECT_CALL(mMockEventHub, enableDevice(EVENTHUB_ID));
+ ASSERT_TRUE(mMapper->enableSensor(InputDeviceSensorType::ACCELEROMETER,
+ std::chrono::microseconds(10000),
+ std::chrono::microseconds(0)));
+ std::list<NotifyArgs> args;
+ args += process(ARBITRARY_TIME, EV_ABS, ABS_X, 20000);
+ args += process(ARBITRARY_TIME, EV_ABS, ABS_Y, -20000);
+ args += process(ARBITRARY_TIME, EV_ABS, ABS_Z, 40000);
+ args += process(ARBITRARY_TIME, EV_MSC, MSC_TIMESTAMP, 1000);
+ args += process(ARBITRARY_TIME, EV_SYN, SYN_REPORT, 0);
- NotifySensorArgs args;
std::vector<float> values = {20000.0f / ACCEL_RAW_RESOLUTION * GRAVITY_MS2_UNIT,
-20000.0f / ACCEL_RAW_RESOLUTION * GRAVITY_MS2_UNIT,
40000.0f / ACCEL_RAW_RESOLUTION * GRAVITY_MS2_UNIT};
- ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifySensorWasCalled(&args));
- ASSERT_EQ(args.source, AINPUT_SOURCE_SENSOR);
- ASSERT_EQ(args.deviceId, DEVICE_ID);
- ASSERT_EQ(args.sensorType, InputDeviceSensorType::ACCELEROMETER);
- ASSERT_EQ(args.accuracy, InputDeviceSensorAccuracy::ACCURACY_HIGH);
- ASSERT_EQ(args.hwTimestamp, ARBITRARY_TIME);
- ASSERT_EQ(args.values, values);
- mapper.flushSensor(InputDeviceSensorType::ACCELEROMETER);
+ ASSERT_EQ(args.size(), 1u);
+ const NotifySensorArgs& arg = std::get<NotifySensorArgs>(args.front());
+ ASSERT_EQ(arg.source, AINPUT_SOURCE_SENSOR);
+ ASSERT_EQ(arg.deviceId, DEVICE_ID);
+ ASSERT_EQ(arg.sensorType, InputDeviceSensorType::ACCELEROMETER);
+ ASSERT_EQ(arg.accuracy, InputDeviceSensorAccuracy::ACCURACY_HIGH);
+ ASSERT_EQ(arg.hwTimestamp, ARBITRARY_TIME);
+ ASSERT_EQ(arg.values, values);
+ mMapper->flushSensor(InputDeviceSensorType::ACCELEROMETER);
}
TEST_F(SensorInputMapperTest, ProcessGyroscopeSensor) {
- setGyroProperties();
- prepareGyroAxes();
- SensorInputMapper& mapper = constructAndAddMapper<SensorInputMapper>();
+ EXPECT_CALL(mMockEventHub, hasMscEvent(EVENTHUB_ID, MSC_TIMESTAMP))
+ .WillRepeatedly(Return(true));
+ setupSensor(ABS_RX, InputDeviceSensorType::GYROSCOPE, /*sensorDataIndex=*/0);
+ setupSensor(ABS_RY, InputDeviceSensorType::GYROSCOPE, /*sensorDataIndex=*/1);
+ setupSensor(ABS_RZ, InputDeviceSensorType::GYROSCOPE, /*sensorDataIndex=*/2);
+ setupAxis(ABS_RX, /*valid=*/true, GYRO_RAW_MIN, GYRO_RAW_MAX, GYRO_RAW_RESOLUTION,
+ GYRO_RAW_FLAT, GYRO_RAW_FUZZ);
+ setupAxis(ABS_RY, /*valid=*/true, GYRO_RAW_MIN, GYRO_RAW_MAX, GYRO_RAW_RESOLUTION,
+ GYRO_RAW_FLAT, GYRO_RAW_FUZZ);
+ setupAxis(ABS_RZ, /*valid=*/true, GYRO_RAW_MIN, GYRO_RAW_MAX, GYRO_RAW_RESOLUTION,
+ GYRO_RAW_FLAT, GYRO_RAW_FUZZ);
+ mPropertyMap.addProperty("sensor.gyroscope.reportingMode", "0");
+ mPropertyMap.addProperty("sensor.gyroscope.maxDelay", "100000");
+ mPropertyMap.addProperty("sensor.gyroscope.minDelay", "5000");
+ mPropertyMap.addProperty("sensor.gyroscope.power", "0.8");
+ mMapper = createInputMapper<SensorInputMapper>(*mDeviceContext,
+ mFakePolicy->getReaderConfiguration());
- ASSERT_TRUE(mapper.enableSensor(InputDeviceSensorType::GYROSCOPE,
- std::chrono::microseconds(10000),
- std::chrono::microseconds(0)));
- ASSERT_TRUE(mFakeEventHub->isDeviceEnabled(EVENTHUB_ID));
- process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_RX, 20000);
- process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_RY, -20000);
- process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_RZ, 40000);
- process(mapper, ARBITRARY_TIME, READ_TIME, EV_MSC, MSC_TIMESTAMP, 1000);
- process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
+ EXPECT_CALL(mMockEventHub, enableDevice(EVENTHUB_ID));
+ ASSERT_TRUE(mMapper->enableSensor(InputDeviceSensorType::GYROSCOPE,
+ std::chrono::microseconds(10000),
+ std::chrono::microseconds(0)));
+ std::list<NotifyArgs> args;
+ args += process(ARBITRARY_TIME, EV_ABS, ABS_RX, 20000);
+ args += process(ARBITRARY_TIME, EV_ABS, ABS_RY, -20000);
+ args += process(ARBITRARY_TIME, EV_ABS, ABS_RZ, 40000);
+ args += process(ARBITRARY_TIME, EV_MSC, MSC_TIMESTAMP, 1000);
+ args += process(ARBITRARY_TIME, EV_SYN, SYN_REPORT, 0);
- NotifySensorArgs args;
std::vector<float> values = {20000.0f / GYRO_RAW_RESOLUTION * DEGREE_RADIAN_UNIT,
-20000.0f / GYRO_RAW_RESOLUTION * DEGREE_RADIAN_UNIT,
40000.0f / GYRO_RAW_RESOLUTION * DEGREE_RADIAN_UNIT};
- ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifySensorWasCalled(&args));
- ASSERT_EQ(args.source, AINPUT_SOURCE_SENSOR);
- ASSERT_EQ(args.deviceId, DEVICE_ID);
- ASSERT_EQ(args.sensorType, InputDeviceSensorType::GYROSCOPE);
- ASSERT_EQ(args.accuracy, InputDeviceSensorAccuracy::ACCURACY_HIGH);
- ASSERT_EQ(args.hwTimestamp, ARBITRARY_TIME);
- ASSERT_EQ(args.values, values);
- mapper.flushSensor(InputDeviceSensorType::GYROSCOPE);
+ ASSERT_EQ(args.size(), 1u);
+ const NotifySensorArgs& arg = std::get<NotifySensorArgs>(args.front());
+ ASSERT_EQ(arg.source, AINPUT_SOURCE_SENSOR);
+ ASSERT_EQ(arg.deviceId, DEVICE_ID);
+ ASSERT_EQ(arg.sensorType, InputDeviceSensorType::GYROSCOPE);
+ ASSERT_EQ(arg.accuracy, InputDeviceSensorAccuracy::ACCURACY_HIGH);
+ ASSERT_EQ(arg.hwTimestamp, ARBITRARY_TIME);
+ ASSERT_EQ(arg.values, values);
+ mMapper->flushSensor(InputDeviceSensorType::GYROSCOPE);
}
} // namespace android
\ No newline at end of file
diff --git a/services/surfaceflinger/CompositionEngine/Android.bp b/services/surfaceflinger/CompositionEngine/Android.bp
index 8067ace..82eafd4 100644
--- a/services/surfaceflinger/CompositionEngine/Android.bp
+++ b/services/surfaceflinger/CompositionEngine/Android.bp
@@ -42,6 +42,7 @@
"libutils",
],
static_libs: [
+ "libguiflags",
"libmath",
"librenderengine",
"libtimestats",
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/DisplayCreationArgs.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/DisplayCreationArgs.h
index 98bccd8..252adaa 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/DisplayCreationArgs.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/DisplayCreationArgs.h
@@ -46,6 +46,12 @@
// content.
bool isProtected = false;
+ // True if this display has picture processing hardware and pipelines.
+ bool hasPictureProcessing = false;
+
+ // The number of layer-specific picture-processing pipelines.
+ int32_t maxLayerPictureProfiles = 0;
+
// Optional pointer to the power advisor interface, if one is needed for
// this display.
adpf::PowerAdvisor* powerAdvisor = nullptr;
@@ -82,6 +88,16 @@
return *this;
}
+ DisplayCreationArgsBuilder& setHasPictureProcessing(bool hasPictureProcessing) {
+ mArgs.hasPictureProcessing = hasPictureProcessing;
+ return *this;
+ }
+
+ DisplayCreationArgsBuilder& setMaxLayerPictureProfiles(int32_t maxLayerPictureProfiles) {
+ mArgs.maxLayerPictureProfiles = maxLayerPictureProfiles;
+ return *this;
+ }
+
DisplayCreationArgsBuilder& setPowerAdvisor(adpf::PowerAdvisor* powerAdvisor) {
mArgs.powerAdvisor = powerAdvisor;
return *this;
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFE.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFE.h
index 4e080b3..a5e9dde 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFE.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFE.h
@@ -148,9 +148,6 @@
virtual std::optional<LayerSettings> prepareClientComposition(
ClientCompositionTargetSettings&) const = 0;
- // Called after the layer is displayed to update the presentation fence
- virtual void onLayerDisplayed(ftl::SharedFuture<FenceResult>, ui::LayerStack layerStack) = 0;
-
// Initializes a promise for a buffer release fence and provides the future for that
// fence. This should only be called when a promise has not yet been created, or
// after the previous promise has already been fulfilled. Attempting to call this
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFECompositionState.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFECompositionState.h
index 8a91a07..fb8fed0 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFECompositionState.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFECompositionState.h
@@ -25,6 +25,7 @@
#include <ui/BlurRegion.h>
#include <ui/FloatRect.h>
#include <ui/LayerStack.h>
+#include <ui/PictureProfileHandle.h>
#include <ui/Rect.h>
#include <ui/Region.h>
#include <ui/ShadowSettings.h>
@@ -219,6 +220,14 @@
float currentHdrSdrRatio = 1.f;
float desiredHdrSdrRatio = 1.f;
+ // A picture profile handle refers to a PictureProfile configured on the display, which is a
+ // set of parameters that configures the picture processing hardware that is used to enhance
+ // the quality of buffer contents.
+ PictureProfileHandle pictureProfileHandle{PictureProfileHandle::NONE};
+
+ // A layer's priority in terms of limited picture processing pipeline utilization.
+ int64_t pictureProfilePriority;
+
gui::CachingHint cachingHint = gui::CachingHint::Enabled;
std::shared_ptr<gui::DisplayLuts> luts;
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/Output.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/Output.h
index 556aa24..bda7856 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/Output.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/Output.h
@@ -16,6 +16,8 @@
#pragma once
+#include <ftl/future.h>
+#include <ftl/optional.h>
#include <cstdint>
#include <iterator>
#include <optional>
@@ -26,18 +28,18 @@
#include <vector>
#include <compositionengine/LayerFE.h>
-#include <ftl/future.h>
#include <renderengine/LayerSettings.h>
+#include <ui/DisplayIdentification.h>
#include <ui/Fence.h>
#include <ui/FenceTime.h>
#include <ui/GraphicTypes.h>
#include <ui/LayerStack.h>
+#include <ui/PictureProfileHandle.h>
#include <ui/Region.h>
#include <ui/Transform.h>
#include <utils/StrongPointer.h>
#include <utils/Vector.h>
-#include <ui/DisplayIdentification.h>
#include "DisplayHardware/HWComposer.h"
namespace android {
@@ -167,7 +169,7 @@
virtual bool isValid() const = 0;
// Returns the DisplayId the output represents, if it has one
- virtual std::optional<DisplayId> getDisplayId() const = 0;
+ virtual ftl::Optional<DisplayId> getDisplayId() const = 0;
// Enables (or disables) composition on this output
virtual void setCompositionEnabled(bool) = 0;
@@ -331,6 +333,9 @@
virtual bool canPredictCompositionStrategy(const CompositionRefreshArgs&) = 0;
virtual const aidl::android::hardware::graphics::composer3::OverlayProperties*
getOverlaySupport() = 0;
+ virtual bool hasPictureProcessing() const = 0;
+ virtual int32_t getMaxLayerPictureProfiles() const = 0;
+ virtual void applyPictureProfile() = 0;
};
} // namespace compositionengine
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/OutputLayer.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/OutputLayer.h
index 80c5124..2e7a7d9 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/OutputLayer.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/OutputLayer.h
@@ -21,6 +21,7 @@
#include <string>
#include <vector>
+#include <ui/PictureProfileHandle.h>
#include <ui/Transform.h>
#include <utils/StrongPointer.h>
@@ -86,6 +87,16 @@
// longer cares about.
virtual void uncacheBuffers(const std::vector<uint64_t>& bufferIdsToUncache) = 0;
+ // Get the relative priority of the layer's picture profile with respect to the importance of
+ // the visual content to the user experience. Lower is higher priority.
+ virtual int64_t getPictureProfilePriority() const = 0;
+
+ // The picture profile handle for the layer.
+ virtual const PictureProfileHandle& getPictureProfileHandle() const = 0;
+
+ // Commit the picture profile to the composition state.
+ virtual void commitPictureProfileToCompositionState() = 0;
+
// Recalculates the state of the output layer from the output-independent
// layer. If includeGeometry is false, the geometry state can be skipped.
// internalDisplayRotationFlags must be set to the rotation flags for the
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Display.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Display.h
index 104a61b..5519aaf 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Display.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Display.h
@@ -45,7 +45,7 @@
virtual ~Display();
// compositionengine::Output overrides
- std::optional<DisplayId> getDisplayId() const override;
+ ftl::Optional<DisplayId> getDisplayId() const override;
bool isValid() const override;
void dump(std::string&) const override;
using compositionengine::impl::Output::setReleasedLayers;
@@ -100,11 +100,16 @@
void setHintSessionGpuStart(TimePoint startTime) override;
void setHintSessionGpuFence(std::unique_ptr<FenceTime>&& gpuFence) override;
void setHintSessionRequiresRenderEngine(bool requiresRenderEngine) override;
+ const aidl::android::hardware::graphics::composer3::OverlayProperties* getOverlaySupport()
+ override;
+ bool hasPictureProcessing() const override;
+ int32_t getMaxLayerPictureProfiles() const override;
+
DisplayId mId;
bool mIsDisconnected = false;
adpf::PowerAdvisor* mPowerAdvisor = nullptr;
- const aidl::android::hardware::graphics::composer3::OverlayProperties* getOverlaySupport()
- override;
+ bool mHasPictureProcessing = false;
+ int32_t mMaxLayerPictureProfiles = 0;
};
// This template factory function standardizes the implementation details of the
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Output.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Output.h
index 69e1efc..0ccdd22 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Output.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Output.h
@@ -16,6 +16,11 @@
#pragma once
+#include <ftl/optional.h>
+#include <memory>
+#include <utility>
+#include <vector>
+
#include <compositionengine/CompositionEngine.h>
#include <compositionengine/LayerFECompositionState.h>
#include <compositionengine/Output.h>
@@ -28,10 +33,6 @@
#include <renderengine/DisplaySettings.h>
#include <renderengine/LayerSettings.h>
-#include <memory>
-#include <utility>
-#include <vector>
-
namespace android::compositionengine::impl {
// The implementation class contains the common implementation, but does not
@@ -43,7 +44,7 @@
// compositionengine::Output overrides
bool isValid() const override;
- std::optional<DisplayId> getDisplayId() const override;
+ ftl::Optional<DisplayId> getDisplayId() const override;
void setCompositionEnabled(bool) override;
void setLayerCachingEnabled(bool) override;
void setLayerCachingTexturePoolEnabled(bool) override;
@@ -84,13 +85,14 @@
bool supportsOffloadPresent() const override { return false; }
void offloadPresentNextFrame() override;
- void uncacheBuffers(const std::vector<uint64_t>& bufferIdsToUncache) override;
void rebuildLayerStacks(const CompositionRefreshArgs&, LayerFESet&) override;
void collectVisibleLayers(const CompositionRefreshArgs&,
compositionengine::Output::CoverageState&) override;
void ensureOutputLayerIfVisible(sp<compositionengine::LayerFE>&,
compositionengine::Output::CoverageState&) override;
void setReleasedLayers(const compositionengine::CompositionRefreshArgs&) override;
+ void uncacheBuffers(const std::vector<uint64_t>& bufferIdsToUncache) override;
+ void commitPictureProfilesToCompositionState();
void updateCompositionState(const compositionengine::CompositionRefreshArgs&) override;
void planComposition() override;
@@ -151,6 +153,9 @@
void setHintSessionRequiresRenderEngine(bool requiresRenderEngine) override;
bool isPowerHintSessionEnabled() override;
bool isPowerHintSessionGpuReportingEnabled() override;
+ bool hasPictureProcessing() const override;
+ int32_t getMaxLayerPictureProfiles() const override;
+ void applyPictureProfile() override;
void dumpBase(std::string&) const;
// Implemented by the final implementation for the final state it uses.
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputCompositionState.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputCompositionState.h
index f8ffde1..c76b344 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputCompositionState.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputCompositionState.h
@@ -35,6 +35,7 @@
#include <compositionengine/CompositionRefreshArgs.h>
#include <compositionengine/ProjectionSpace.h>
#include <ui/LayerStack.h>
+#include <ui/PictureProfileHandle.h>
#include <ui/Rect.h>
#include <ui/Region.h>
#include <ui/Transform.h>
@@ -170,6 +171,8 @@
ICEPowerCallback* powerCallback = nullptr;
+ PictureProfileHandle pictureProfileHandle;
+
// Debugging
void dump(std::string& result) const;
};
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayer.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayer.h
index bfa387d..712b551 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayer.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayer.h
@@ -25,6 +25,7 @@
#include <compositionengine/LayerFE.h>
#include <compositionengine/OutputLayer.h>
#include <ui/FloatRect.h>
+#include <ui/PictureProfileHandle.h>
#include <ui/Rect.h>
#include <ui/DisplayIdentification.h>
@@ -48,6 +49,9 @@
void setHwcLayer(std::shared_ptr<HWC2::Layer>) override;
void uncacheBuffers(const std::vector<uint64_t>& bufferIdsToUncache) override;
+ int64_t getPictureProfilePriority() const override;
+ const PictureProfileHandle& getPictureProfileHandle() const override;
+ void commitPictureProfileToCompositionState() override;
void updateCompositionState(bool includeGeometry, bool forceClientComposition,
ui::Transform::RotationFlags,
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayerCompositionState.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayerCompositionState.h
index 28216a4..c558739 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayerCompositionState.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayerCompositionState.h
@@ -22,6 +22,7 @@
#include <renderengine/ExternalTexture.h>
#include <ui/FloatRect.h>
#include <ui/GraphicTypes.h>
+#include <ui/PictureProfileHandle.h>
#include <ui/Rect.h>
#include <ui/Region.h>
@@ -101,6 +102,9 @@
// order to save power.
Region outputSpaceBlockingRegionHint;
+ // The picture profile for this layer.
+ PictureProfileHandle pictureProfileHandle;
+
// Overrides the buffer, acquire fence, and display frame stored in LayerFECompositionState
struct {
std::shared_ptr<renderengine::ExternalTexture> buffer = nullptr;
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/LayerFE.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/LayerFE.h
index 05a5d38..c7ff704 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/LayerFE.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/LayerFE.h
@@ -50,9 +50,6 @@
std::optional<compositionengine::LayerFE::LayerSettings>(
compositionengine::LayerFE::ClientCompositionTargetSettings&));
- MOCK_METHOD(void, onLayerDisplayed, (ftl::SharedFuture<FenceResult>, ui::LayerStack),
- (override));
-
MOCK_METHOD0(createReleaseFenceFuture, ftl::Future<FenceResult>());
MOCK_METHOD1(setReleaseFence, void(const FenceResult&));
MOCK_METHOD0(getReleaseFencePromiseStatus, LayerFE::ReleaseFencePromiseStatus());
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/Output.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/Output.h
index 33cdc54..f2c265a 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/Output.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/Output.h
@@ -34,7 +34,7 @@
virtual ~Output();
MOCK_CONST_METHOD0(isValid, bool());
- MOCK_CONST_METHOD0(getDisplayId, std::optional<DisplayId>());
+ MOCK_CONST_METHOD0(getDisplayId, ftl::Optional<DisplayId>());
MOCK_METHOD1(setCompositionEnabled, void(bool));
MOCK_METHOD1(setLayerCachingEnabled, void(bool));
@@ -142,6 +142,9 @@
MOCK_METHOD(bool, isPowerHintSessionGpuReportingEnabled, ());
MOCK_METHOD((const aidl::android::hardware::graphics::composer3::OverlayProperties*),
getOverlaySupport, ());
+ MOCK_METHOD(bool, hasPictureProcessing, (), (const));
+ MOCK_METHOD(int32_t, getMaxLayerPictureProfiles, (), (const));
+ MOCK_METHOD(void, applyPictureProfile, ());
};
} // namespace android::compositionengine::mock
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/OutputLayer.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/OutputLayer.h
index 12f2094..9333ebb 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/OutputLayer.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/OutputLayer.h
@@ -63,7 +63,9 @@
(ndk::ScopedFileDescriptor,
(std::vector<std::pair<
int, aidl::android::hardware::graphics::composer3::LutProperties>>)));
-
+ MOCK_METHOD(int64_t, getPictureProfilePriority, (), (const));
+ MOCK_METHOD(const PictureProfileHandle&, getPictureProfileHandle, (), (const));
+ MOCK_METHOD(void, commitPictureProfileToCompositionState, ());
MOCK_CONST_METHOD1(dump, void(std::string&));
};
diff --git a/services/surfaceflinger/CompositionEngine/src/Display.cpp b/services/surfaceflinger/CompositionEngine/src/Display.cpp
index 6a97c49..e37ce0a 100644
--- a/services/surfaceflinger/CompositionEngine/src/Display.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/Display.cpp
@@ -54,6 +54,8 @@
void Display::setConfiguration(const compositionengine::DisplayCreationArgs& args) {
mId = args.id;
mPowerAdvisor = args.powerAdvisor;
+ mHasPictureProcessing = args.hasPictureProcessing;
+ mMaxLayerPictureProfiles = args.maxLayerPictureProfiles;
editState().isSecure = args.isSecure;
editState().isProtected = args.isProtected;
editState().displaySpace.setBounds(args.pixels);
@@ -80,7 +82,7 @@
return mId.isVirtual();
}
-std::optional<DisplayId> Display::getDisplayId() const {
+ftl::Optional<DisplayId> Display::getDisplayId() const {
return mId;
}
@@ -203,15 +205,16 @@
}
void Display::applyDisplayBrightness(bool applyImmediately) {
- if (const auto displayId = ftl::Optional(getDisplayId()).and_then(PhysicalDisplayId::tryCast);
- displayId && getState().displayBrightness) {
+ if (!getState().displayBrightness) {
+ return;
+ }
+ if (auto displayId = PhysicalDisplayId::tryCast(mId)) {
auto& hwc = getCompositionEngine().getHwComposer();
- const status_t result =
- hwc.setDisplayBrightness(*displayId, *getState().displayBrightness,
- getState().displayBrightnessNits,
- Hwc2::Composer::DisplayBrightnessOptions{
- .applyImmediately = applyImmediately})
- .get();
+ status_t result = hwc.setDisplayBrightness(*displayId, *getState().displayBrightness,
+ getState().displayBrightnessNits,
+ Hwc2::Composer::DisplayBrightnessOptions{
+ .applyImmediately = applyImmediately})
+ .get();
ALOGE_IF(result != NO_ERROR, "setDisplayBrightness failed for %s: %d, (%s)",
getName().c_str(), result, strerror(-result));
}
@@ -288,8 +291,8 @@
}
bool Display::getSkipColorTransform() const {
- const auto& hwc = getCompositionEngine().getHwComposer();
- if (const auto halDisplayId = HalDisplayId::tryCast(mId)) {
+ auto& hwc = getCompositionEngine().getHwComposer();
+ if (auto halDisplayId = HalDisplayId::tryCast(mId)) {
return hwc.hasDisplayCapability(*halDisplayId,
DisplayCapability::SKIP_CLIENT_COLOR_TRANSFORM);
}
@@ -462,6 +465,14 @@
return &getCompositionEngine().getHwComposer().getOverlaySupport();
}
+bool Display::hasPictureProcessing() const {
+ return mHasPictureProcessing;
+}
+
+int32_t Display::getMaxLayerPictureProfiles() const {
+ return mMaxLayerPictureProfiles;
+}
+
void Display::finishFrame(GpuCompositionResult&& result) {
// We only need to actually compose the display if:
// 1) It is being handled by hardware composer, which may need this to
@@ -476,8 +487,8 @@
}
bool Display::supportsOffloadPresent() const {
- if (const auto halDisplayId = HalDisplayId::tryCast(mId)) {
- const auto& hwc = getCompositionEngine().getHwComposer();
+ if (auto halDisplayId = HalDisplayId::tryCast(mId)) {
+ auto& hwc = getCompositionEngine().getHwComposer();
return hwc.hasDisplayCapability(*halDisplayId, DisplayCapability::MULTI_THREADED_PRESENT);
}
diff --git a/services/surfaceflinger/CompositionEngine/src/LayerFECompositionState.cpp b/services/surfaceflinger/CompositionEngine/src/LayerFECompositionState.cpp
index 2d10866..348111d 100644
--- a/services/surfaceflinger/CompositionEngine/src/LayerFECompositionState.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/LayerFECompositionState.cpp
@@ -127,6 +127,9 @@
}
dumpVal(out, "colorTransform", colorTransform);
dumpVal(out, "caching hint", toString(cachingHint));
+ if (pictureProfileHandle) {
+ dumpVal(out, "pictureProfile", toString(pictureProfileHandle));
+ }
out.append("\n");
}
diff --git a/services/surfaceflinger/CompositionEngine/src/Output.cpp b/services/surfaceflinger/CompositionEngine/src/Output.cpp
index bb45613..98b6666 100644
--- a/services/surfaceflinger/CompositionEngine/src/Output.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/Output.cpp
@@ -32,9 +32,12 @@
#include <compositionengine/impl/planner/Planner.h>
#include <ftl/algorithm.h>
#include <ftl/future.h>
+#include <ftl/optional.h>
#include <scheduler/FrameTargeter.h>
#include <scheduler/Time.h>
+#include <com_android_graphics_libgui_flags.h>
+
#include <optional>
#include <thread>
@@ -111,7 +114,7 @@
mRenderSurface->isValid();
}
-std::optional<DisplayId> Output::getDisplayId() const {
+ftl::Optional<DisplayId> Output::getDisplayId() const {
return {};
}
@@ -433,7 +436,7 @@
ftl::Future<std::monostate> Output::present(
const compositionengine::CompositionRefreshArgs& refreshArgs) {
const auto stringifyExpectedPresentTime = [this, &refreshArgs]() -> std::string {
- return ftl::Optional(getDisplayId())
+ return getDisplayId()
.and_then(PhysicalDisplayId::tryCast)
.and_then([&refreshArgs](PhysicalDisplayId id) {
return refreshArgs.frameTargets.get(id);
@@ -500,15 +503,6 @@
updateHwcAsyncWorker();
}
-void Output::uncacheBuffers(std::vector<uint64_t> const& bufferIdsToUncache) {
- if (bufferIdsToUncache.empty()) {
- return;
- }
- for (auto outputLayer : getOutputLayersOrderedByZ()) {
- outputLayer->uncacheBuffers(bufferIdsToUncache);
- }
-}
-
void Output::rebuildLayerStacks(const compositionengine::CompositionRefreshArgs& refreshArgs,
LayerFESet& layerFESet) {
auto& outputState = editState();
@@ -776,11 +770,11 @@
// The layer is visible. Either reuse the existing outputLayer if we have
// one, or create a new one if we do not.
- auto result = ensureOutputLayer(prevOutputLayerIndex, layerFE);
+ auto outputLayer = ensureOutputLayer(prevOutputLayerIndex, layerFE);
// Store the layer coverage information into the layer state as some of it
// is useful later.
- auto& outputLayerState = result->editState();
+ auto& outputLayerState = outputLayer->editState();
outputLayerState.visibleRegion = visibleRegion;
outputLayerState.visibleNonTransparentRegion = visibleNonTransparentRegion;
outputLayerState.coveredRegion = coveredRegion;
@@ -798,6 +792,52 @@
}
}
+void Output::uncacheBuffers(std::vector<uint64_t> const& bufferIdsToUncache) {
+ if (bufferIdsToUncache.empty()) {
+ return;
+ }
+ for (auto outputLayer : getOutputLayersOrderedByZ()) {
+ outputLayer->uncacheBuffers(bufferIdsToUncache);
+ }
+}
+
+void Output::commitPictureProfilesToCompositionState() {
+ if (!com_android_graphics_libgui_flags_apply_picture_profiles()) {
+ return;
+ }
+ if (!hasPictureProcessing()) {
+ return;
+ }
+ auto compare = [](const ::android::compositionengine::OutputLayer* lhs,
+ const ::android::compositionengine::OutputLayer* rhs) {
+ return lhs->getPictureProfilePriority() > rhs->getPictureProfilePriority();
+ };
+ std::priority_queue<::android::compositionengine::OutputLayer*,
+ std::vector<::android::compositionengine::OutputLayer*>, decltype(compare)>
+ layersWithProfiles;
+ for (auto outputLayer : getOutputLayersOrderedByZ()) {
+ if (outputLayer->getPictureProfileHandle()) {
+ layersWithProfiles.push(outputLayer);
+ }
+ }
+
+ // TODO(b/337330263): Use the default display picture profile from SurfaceFlinger
+ editState().pictureProfileHandle = PictureProfileHandle::NONE;
+
+ // When layer-specific picture processing is supported, apply as many high priority profiles as
+ // possible to the layers, and ignore the low priority layers.
+ if (getMaxLayerPictureProfiles() > 0) {
+ for (int i = 0; i < getMaxLayerPictureProfiles() && !layersWithProfiles.empty();
+ layersWithProfiles.pop(), ++i) {
+ layersWithProfiles.top()->commitPictureProfileToCompositionState();
+ }
+ // No layer-specific picture processing, so apply the highest priority picture profile to
+ // the entire display.
+ } else if (!layersWithProfiles.empty()) {
+ editState().pictureProfileHandle = layersWithProfiles.top()->getPictureProfileHandle();
+ }
+}
+
void Output::setReleasedLayers(const compositionengine::CompositionRefreshArgs&) {
// The base class does nothing with this call.
}
@@ -826,6 +866,7 @@
forceClientComposition = false;
}
}
+ commitPictureProfilesToCompositionState();
}
void Output::planComposition() {
@@ -847,7 +888,7 @@
return;
}
- if (auto frameTargetPtrOpt = ftl::Optional(getDisplayId())
+ if (auto frameTargetPtrOpt = getDisplayId()
.and_then(PhysicalDisplayId::tryCast)
.and_then([&refreshArgs](PhysicalDisplayId id) {
return refreshArgs.frameTargets.get(id);
@@ -858,6 +899,8 @@
editState().frameInterval = refreshArgs.frameInterval;
editState().powerCallback = refreshArgs.powerCallback;
+ applyPictureProfile();
+
compositionengine::OutputLayer* peekThroughLayer = nullptr;
sp<GraphicBuffer> previousOverride = nullptr;
bool includeGeometry = refreshArgs.updatingGeometryThisFrame;
@@ -1763,5 +1806,34 @@
return getState().displayBrightnessNits / getState().sdrWhitePointNits;
}
+bool Output::hasPictureProcessing() const {
+ return false;
+}
+
+int32_t Output::getMaxLayerPictureProfiles() const {
+ return 0;
+}
+
+void Output::applyPictureProfile() {
+ if (!com_android_graphics_libgui_flags_apply_picture_profiles()) {
+ return;
+ }
+
+ // TODO(b/337330263): Move this into the Display class and add a Display unit test.
+ if (!getState().pictureProfileHandle) {
+ return;
+ }
+ if (!getDisplayId()) {
+ return;
+ }
+ if (auto displayId = PhysicalDisplayId::tryCast(*getDisplayId())) {
+ auto& hwc = getCompositionEngine().getHwComposer();
+ const status_t error =
+ hwc.setDisplayPictureProfileHandle(*displayId, getState().pictureProfileHandle);
+ ALOGE_IF(error, "setDisplayPictureProfileHandle failed for %s: %d, (%s)", getName().c_str(),
+ error, strerror(-error));
+ }
+}
+
} // namespace impl
} // namespace android::compositionengine
diff --git a/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp b/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp
index c062df3..f6d9a1a 100644
--- a/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
#include <DisplayHardware/Hal.h>
#include <android-base/stringprintf.h>
#include <compositionengine/DisplayColorProfile.h>
@@ -22,11 +23,12 @@
#include <compositionengine/impl/OutputCompositionState.h>
#include <compositionengine/impl/OutputLayer.h>
#include <compositionengine/impl/OutputLayerCompositionState.h>
+#include <ui/FloatRect.h>
+#include <ui/HdrRenderTypeUtils.h>
#include <cstdint>
#include "system/graphics-base-v1.0.h"
-#include "ui/FloatRect.h"
-#include <ui/HdrRenderTypeUtils.h>
+#include <com_android_graphics_libgui_flags.h>
// TODO(b/129481165): remove the #pragma below and fix conversion issues
#pragma clang diagnostic push
@@ -424,6 +426,16 @@
}
}
+void OutputLayer::commitPictureProfileToCompositionState() {
+ if (!com_android_graphics_libgui_flags_apply_picture_profiles()) {
+ return;
+ }
+ const auto* layerState = getLayerFE().getCompositionState();
+ if (layerState) {
+ editState().pictureProfileHandle = getLayerFE().getCompositionState()->pictureProfileHandle;
+ }
+}
+
void OutputLayer::writeStateToHWC(bool includeGeometry, bool skipLayer, uint32_t z,
bool zIsOverridden, bool isPeekingThrough) {
const auto& state = getState();
@@ -645,6 +657,21 @@
ALOGE("[%s] Failed to set brightness %f: %s (%d)", getLayerFE().getDebugName(),
dimmingRatio, to_string(error).c_str(), static_cast<int32_t>(error));
}
+
+ if (com_android_graphics_libgui_flags_apply_picture_profiles() &&
+ outputDependentState.pictureProfileHandle) {
+ if (auto error =
+ hwcLayer->setPictureProfileHandle(outputDependentState.pictureProfileHandle);
+ error != hal::Error::NONE) {
+ ALOGE("[%s] Failed to set picture profile handle: %s (%d)", getLayerFE().getDebugName(),
+ toString(outputDependentState.pictureProfileHandle).c_str(),
+ static_cast<int32_t>(error));
+ }
+ // Reset the picture profile state, as it needs to be re-committed on each present cycle
+ // when Output decides that the limited picture-processing hardware should be used by this
+ // layer.
+ editState().pictureProfileHandle = PictureProfileHandle::NONE;
+ }
}
void OutputLayer::writeOutputIndependentPerFrameStateToHWC(
@@ -750,6 +777,16 @@
}
}
+int64_t OutputLayer::getPictureProfilePriority() const {
+ const auto* layerState = getLayerFE().getCompositionState();
+ return layerState ? layerState->pictureProfilePriority : 0;
+}
+
+const PictureProfileHandle& OutputLayer::getPictureProfileHandle() const {
+ const auto* layerState = getLayerFE().getCompositionState();
+ return layerState ? layerState->pictureProfileHandle : PictureProfileHandle::NONE;
+}
+
void OutputLayer::writeBufferStateToHWC(HWC2::Layer* hwcLayer,
const LayerFECompositionState& outputIndependentState,
bool skipLayer) {
@@ -832,14 +869,14 @@
return;
}
- const auto* layerFEState = getLayerFE().getCompositionState();
- if (!layerFEState) {
+ const auto* layerState = getLayerFE().getCompositionState();
+ if (!layerState) {
return;
}
const auto& outputState = getOutput().getState();
- Rect frame = layerFEState->cursorFrame;
+ Rect frame = layerState->cursorFrame;
frame.intersect(outputState.layerStackSpace.getContent(), &frame);
Rect position = outputState.transform.transform(frame);
diff --git a/services/surfaceflinger/CompositionEngine/src/OutputLayerCompositionState.cpp b/services/surfaceflinger/CompositionEngine/src/OutputLayerCompositionState.cpp
index da1f7e4..deef747 100644
--- a/services/surfaceflinger/CompositionEngine/src/OutputLayerCompositionState.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/OutputLayerCompositionState.cpp
@@ -72,6 +72,9 @@
dumpVal(out, "dataspace", toString(dataspace), dataspace);
dumpVal(out, "whitePointNits", whitePointNits);
dumpVal(out, "dimmingRatio", dimmingRatio);
+ if (pictureProfileHandle) {
+ dumpVal(out, "pictureProfile", toString(pictureProfileHandle));
+ }
dumpVal(out, "override buffer", overrideInfo.buffer.get());
dumpVal(out, "override acquire fence", overrideInfo.acquireFence.get());
dumpVal(out, "override display frame", overrideInfo.displayFrame);
diff --git a/services/surfaceflinger/CompositionEngine/tests/OutputLayerTest.cpp b/services/surfaceflinger/CompositionEngine/tests/OutputLayerTest.cpp
index f2c5672..dbffe80 100644
--- a/services/surfaceflinger/CompositionEngine/tests/OutputLayerTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/OutputLayerTest.cpp
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+#include <com_android_graphics_libgui_flags.h>
#include <compositionengine/impl/HwcBufferCache.h>
#include <compositionengine/impl/OutputLayer.h>
#include <compositionengine/impl/OutputLayerCompositionState.h>
@@ -1332,6 +1333,71 @@
/*zIsOverridden*/ false, /*isPeekingThrough*/ false);
}
+TEST_F(OutputLayerWriteStateToHWCTest, setsPictureProfileWhenCommitted) {
+ if (!com_android_graphics_libgui_flags_apply_picture_profiles()) {
+ GTEST_SKIP() << "Feature flag disabled, skipping";
+ }
+ mLayerFEState.compositionType = Composition::DEVICE;
+ mLayerFEState.pictureProfileHandle = PictureProfileHandle(1);
+
+ expectGeometryCommonCalls();
+ expectPerFrameCommonCalls();
+ expectSetHdrMetadataAndBufferCalls();
+ expectSetCompositionTypeCall(Composition::DEVICE);
+
+ EXPECT_CALL(*mHwcLayer, setPictureProfileHandle(PictureProfileHandle(1)));
+
+ mOutputLayer.commitPictureProfileToCompositionState();
+ mOutputLayer.writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, 0,
+ /*zIsOverridden*/ false, /*isPeekingThrough*/ false);
+}
+
+TEST_F(OutputLayerWriteStateToHWCTest, doesNotSetPictureProfileWhenNotCommitted) {
+ if (!com_android_graphics_libgui_flags_apply_picture_profiles()) {
+ GTEST_SKIP() << "Feature flag disabled, skipping";
+ }
+ mLayerFEState.compositionType = Composition::DEVICE;
+ mLayerFEState.pictureProfileHandle = PictureProfileHandle(1);
+
+ expectGeometryCommonCalls();
+ expectPerFrameCommonCalls();
+ expectSetHdrMetadataAndBufferCalls();
+ expectSetCompositionTypeCall(Composition::DEVICE);
+
+ EXPECT_CALL(*mHwcLayer, setPictureProfileHandle(_)).Times(0);
+
+ mOutputLayer.writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, 0,
+ /*zIsOverridden*/ false, /*isPeekingThrough*/ false);
+}
+
+TEST_F(OutputLayerWriteStateToHWCTest, doesNotSetPictureProfileWhenNotCommittedLater) {
+ if (!com_android_graphics_libgui_flags_apply_picture_profiles()) {
+ GTEST_SKIP() << "Feature flag disabled, skipping";
+ }
+ mLayerFEState.compositionType = Composition::DEVICE;
+ mLayerFEState.pictureProfileHandle = PictureProfileHandle(1);
+
+ expectGeometryCommonCalls();
+ expectPerFrameCommonCalls();
+ expectSetHdrMetadataAndBufferCalls();
+ expectSetCompositionTypeCall(Composition::DEVICE);
+
+ EXPECT_CALL(*mHwcLayer, setPictureProfileHandle(PictureProfileHandle(1)));
+
+ mOutputLayer.commitPictureProfileToCompositionState();
+ mOutputLayer.writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, 0,
+ /*zIsOverridden*/ false, /*isPeekingThrough*/ false);
+
+ expectGeometryCommonCalls();
+ expectPerFrameCommonCalls();
+ expectSetHdrMetadataAndBufferCalls(kExpectedHwcSlot, nullptr, kFence);
+
+ EXPECT_CALL(*mHwcLayer, setPictureProfileHandle(PictureProfileHandle(1))).Times(0);
+ // No committing of picture profile before writing the state
+ mOutputLayer.writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, 0,
+ /*zIsOverridden*/ false, /*isPeekingThrough*/ false);
+}
+
/*
* OutputLayer::uncacheBuffers
*/
diff --git a/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp b/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
index fe7dd9a..99e68eb 100644
--- a/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
@@ -15,6 +15,7 @@
*/
#include <android-base/stringprintf.h>
+#include <com_android_graphics_libgui_flags.h>
#include <com_android_graphics_surfaceflinger_flags.h>
#include <compositionengine/LayerFECompositionState.h>
#include <compositionengine/impl/Output.h>
@@ -37,11 +38,14 @@
#include <cstdint>
#include <variant>
+#include <com_android_graphics_surfaceflinger_flags.h>
+
#include <common/FlagManager.h>
#include <common/test/FlagUtils.h>
#include "CallOrderStateMachineHelper.h"
#include "RegionMatcher.h"
#include "mock/DisplayHardware/MockHWC2.h"
+#include "mock/DisplayHardware/MockHWComposer.h"
namespace android::compositionengine {
namespace {
@@ -142,6 +146,24 @@
public:
using impl::Output::injectOutputLayerForTest;
virtual void injectOutputLayerForTest(std::unique_ptr<compositionengine::OutputLayer>) = 0;
+
+ virtual ftl::Optional<DisplayId> getDisplayId() const override { return mId; }
+
+ virtual bool hasPictureProcessing() const override { return mHasPictureProcessing; }
+ virtual int32_t getMaxLayerPictureProfiles() const override {
+ return mMaxLayerPictureProfiles;
+ }
+
+ void setDisplayIdForTest(DisplayId value) { mId = value; }
+
+ void setHasPictureProcessingForTest(bool value) { mHasPictureProcessing = value; }
+
+ void setMaxLayerPictureProfilesForTest(int32_t value) { mMaxLayerPictureProfiles = value; }
+
+ private:
+ ftl::Optional<DisplayId> mId;
+ bool mHasPictureProcessing;
+ int32_t mMaxLayerPictureProfiles;
};
static std::shared_ptr<Output> createOutput(
@@ -157,6 +179,7 @@
mOutput->editState().displaySpace.setBounds(
ui::Size(kDefaultDisplaySize.getWidth(), kDefaultDisplaySize.getHeight()));
EXPECT_CALL(mCompositionEngine, getRenderEngine()).WillRepeatedly(ReturnRef(mRenderEngine));
+ EXPECT_CALL(mCompositionEngine, getHwComposer()).WillRepeatedly(ReturnRef(mHwComposer));
}
void injectOutputLayer(InjectedLayer& layer) {
@@ -169,6 +192,7 @@
static const Rect kDefaultDisplaySize;
+ StrictMock<::android::mock::HWComposer> mHwComposer;
StrictMock<mock::CompositionEngine> mCompositionEngine;
StrictMock<renderengine::mock::RenderEngine> mRenderEngine;
mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
@@ -5043,6 +5067,123 @@
mOutput->writeCompositionState(args);
}
+TEST_F(OutputUpdateAndWriteCompositionStateTest, assignsDisplayProfileBasedOnLayerPriority) {
+ if (!com_android_graphics_libgui_flags_apply_picture_profiles()) {
+ GTEST_SKIP() << "Feature flag disabled, skipping";
+ }
+
+ mOutput->setDisplayIdForTest(PhysicalDisplayId::fromPort(1));
+ // Has only one display-global picture processing pipeline
+ mOutput->setHasPictureProcessingForTest(true);
+ mOutput->setMaxLayerPictureProfilesForTest(0);
+
+ InjectedLayer layer1;
+ injectOutputLayer(layer1);
+ PictureProfileHandle profileForLayer1(1);
+ EXPECT_CALL(*layer1.outputLayer, getPictureProfilePriority()).WillRepeatedly(Return(3));
+ EXPECT_CALL(*layer1.outputLayer, getPictureProfileHandle())
+ .WillRepeatedly(ReturnRef(profileForLayer1));
+
+ InjectedLayer layer2;
+ injectOutputLayer(layer2);
+ PictureProfileHandle profileForLayer2(2);
+ EXPECT_CALL(*layer2.outputLayer, getPictureProfilePriority()).WillRepeatedly(Return(1));
+ EXPECT_CALL(*layer2.outputLayer, getPictureProfileHandle())
+ .WillRepeatedly(ReturnRef(profileForLayer2));
+
+ InjectedLayer layer3;
+ injectOutputLayer(layer3);
+ PictureProfileHandle profileForLayer3(3);
+ EXPECT_CALL(*layer3.outputLayer, getPictureProfilePriority()).WillRepeatedly(Return(2));
+ EXPECT_CALL(*layer3.outputLayer, getPictureProfileHandle())
+ .WillRepeatedly(ReturnRef(profileForLayer3));
+
+ // Because StrictMock
+ EXPECT_CALL(*layer1.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
+ EXPECT_CALL(*layer1.outputLayer, updateCompositionState(_, _, _, _));
+ EXPECT_CALL(*layer1.outputLayer, writeStateToHWC(_, _, _, _, _));
+ EXPECT_CALL(*layer2.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
+ EXPECT_CALL(*layer2.outputLayer, updateCompositionState(_, _, _, _));
+ EXPECT_CALL(*layer2.outputLayer, writeStateToHWC(_, _, _, _, _));
+ EXPECT_CALL(*layer3.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
+ EXPECT_CALL(*layer3.outputLayer, updateCompositionState(_, _, _, _));
+ EXPECT_CALL(*layer3.outputLayer, writeStateToHWC(_, _, _, _, _));
+
+ // No layer picture profiles should be committed
+ EXPECT_CALL(*layer1.outputLayer, commitPictureProfileToCompositionState).Times(0);
+ EXPECT_CALL(*layer2.outputLayer, commitPictureProfileToCompositionState).Times(0);
+ EXPECT_CALL(*layer3.outputLayer, commitPictureProfileToCompositionState).Times(0);
+
+ // Sets display picture profile to the highest priority layer's profile
+ EXPECT_CALL(mHwComposer, setDisplayPictureProfileHandle(_, Eq(profileForLayer2)));
+
+ mOutput->editState().isEnabled = true;
+ CompositionRefreshArgs args;
+ args.updatingGeometryThisFrame = false;
+ args.devOptForceClientComposition = false;
+ mOutput->updateCompositionState(args);
+ mOutput->planComposition();
+ mOutput->writeCompositionState(args);
+}
+
+TEST_F(OutputUpdateAndWriteCompositionStateTest, assignsLayerProfileBasedOnLayerPriority) {
+ if (!com_android_graphics_libgui_flags_apply_picture_profiles()) {
+ GTEST_SKIP() << "Feature flag disabled, skipping";
+ }
+ mOutput->setDisplayIdForTest(PhysicalDisplayId::fromPort(1));
+ // Has 2 layer-specific picture processing pipelines
+ mOutput->setHasPictureProcessingForTest(true);
+ mOutput->setMaxLayerPictureProfilesForTest(2);
+
+ InjectedLayer layer1;
+ injectOutputLayer(layer1);
+ PictureProfileHandle profileForLayer1(1);
+ EXPECT_CALL(*layer1.outputLayer, getPictureProfilePriority()).WillRepeatedly(Return(3));
+ EXPECT_CALL(*layer1.outputLayer, getPictureProfileHandle())
+ .WillRepeatedly(ReturnRef(profileForLayer1));
+
+ InjectedLayer layer2;
+ injectOutputLayer(layer2);
+ PictureProfileHandle profileForLayer2(2);
+ EXPECT_CALL(*layer2.outputLayer, getPictureProfilePriority()).WillRepeatedly(Return(1));
+ EXPECT_CALL(*layer2.outputLayer, getPictureProfileHandle())
+ .WillRepeatedly(ReturnRef(profileForLayer2));
+
+ InjectedLayer layer3;
+ injectOutputLayer(layer3);
+ PictureProfileHandle profileForLayer3(3);
+ EXPECT_CALL(*layer3.outputLayer, getPictureProfilePriority()).WillRepeatedly(Return(2));
+ EXPECT_CALL(*layer3.outputLayer, getPictureProfileHandle())
+ .WillRepeatedly(ReturnRef(profileForLayer3));
+
+ // Because StrictMock
+ EXPECT_CALL(*layer1.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
+ EXPECT_CALL(*layer1.outputLayer, updateCompositionState(_, _, _, _));
+ EXPECT_CALL(*layer1.outputLayer, writeStateToHWC(_, _, _, _, _));
+ EXPECT_CALL(*layer2.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
+ EXPECT_CALL(*layer2.outputLayer, updateCompositionState(_, _, _, _));
+ EXPECT_CALL(*layer2.outputLayer, writeStateToHWC(_, _, _, _, _));
+ EXPECT_CALL(*layer3.outputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
+ EXPECT_CALL(*layer3.outputLayer, updateCompositionState(_, _, _, _));
+ EXPECT_CALL(*layer3.outputLayer, writeStateToHWC(_, _, _, _, _));
+
+ // The two highest priority layers should have their picture profiles committed
+ EXPECT_CALL(*layer1.outputLayer, commitPictureProfileToCompositionState).Times(0);
+ EXPECT_CALL(*layer2.outputLayer, commitPictureProfileToCompositionState);
+ EXPECT_CALL(*layer3.outputLayer, commitPictureProfileToCompositionState);
+
+ // No display picture profile is sent
+ EXPECT_CALL(mHwComposer, setDisplayPictureProfileHandle).Times(0);
+
+ mOutput->editState().isEnabled = true;
+ CompositionRefreshArgs args;
+ args.updatingGeometryThisFrame = false;
+ args.devOptForceClientComposition = false;
+ mOutput->updateCompositionState(args);
+ mOutput->planComposition();
+ mOutput->writeCompositionState(args);
+}
+
TEST_F(GenerateClientCompositionRequestsTest, handlesLandscapeModeSplitScreenRequests) {
// In split-screen landscape mode, the screen is rotated 90 degrees, with
// one layer on the left covering the left side of the output, and one layer
diff --git a/services/surfaceflinger/LayerFE.cpp b/services/surfaceflinger/LayerFE.cpp
index a346981..231b40b 100644
--- a/services/surfaceflinger/LayerFE.cpp
+++ b/services/surfaceflinger/LayerFE.cpp
@@ -27,7 +27,6 @@
#include "LayerFE.h"
#include "SurfaceFlinger.h"
#include "ui/FenceResult.h"
-#include "ui/LayerStack.h"
namespace android {
@@ -343,11 +342,6 @@
caster.shadow = state;
}
-void LayerFE::onLayerDisplayed(ftl::SharedFuture<FenceResult> futureFenceResult,
- ui::LayerStack layerStack) {
- mCompositionResult.releaseFences.emplace_back(std::move(futureFenceResult), layerStack);
-}
-
CompositionResult&& LayerFE::stealCompositionResult() {
return std::move(mCompositionResult);
}
diff --git a/services/surfaceflinger/LayerFE.h b/services/surfaceflinger/LayerFE.h
index 658f949..5081e10 100644
--- a/services/surfaceflinger/LayerFE.h
+++ b/services/surfaceflinger/LayerFE.h
@@ -22,14 +22,12 @@
#include "compositionengine/LayerFE.h"
#include "compositionengine/LayerFECompositionState.h"
#include "renderengine/LayerSettings.h"
-#include "ui/LayerStack.h"
#include <ftl/future.h>
namespace android {
struct CompositionResult {
- std::vector<std::pair<ftl::SharedFuture<FenceResult>, ui::LayerStack>> releaseFences;
sp<Fence> lastClientCompositionFence = nullptr;
};
@@ -41,7 +39,6 @@
// compositionengine::LayerFE overrides
const compositionengine::LayerFECompositionState* getCompositionState() const override;
bool onPreComposition(bool updatingOutputGeometryThisFrame) override;
- void onLayerDisplayed(ftl::SharedFuture<FenceResult>, ui::LayerStack) override;
const char* getDebugName() const override;
int32_t getSequence() const override;
bool hasRoundedCorners() const override;
diff --git a/services/surfaceflinger/tests/Credentials_test.cpp b/services/surfaceflinger/tests/Credentials_test.cpp
index e6fed63..7b6e4bf 100644
--- a/services/surfaceflinger/tests/Credentials_test.cpp
+++ b/services/surfaceflinger/tests/Credentials_test.cpp
@@ -341,9 +341,9 @@
WindowInfosListenerUtils windowInfosListenerUtils;
std::string name = "Test Layer";
sp<IBinder> token = sp<BBinder>::make();
- WindowInfo windowInfo;
- windowInfo.name = name;
- windowInfo.token = token;
+ auto windowInfo = sp<gui::WindowInfoHandle>::make();
+ windowInfo->editInfo()->name = name;
+ windowInfo->editInfo()->token = token;
sp<SurfaceControl> surfaceControl =
mComposerClient->createSurface(String8(name.c_str()), 100, 100, PIXEL_FORMAT_RGBA_8888,
ISurfaceComposerClient::eFXSurfaceBufferState);
@@ -370,7 +370,8 @@
UIDFaker f(AID_SYSTEM);
auto windowIsPresentAndNotTrusted = [&](const std::vector<WindowInfo>& windowInfos) {
auto foundWindowInfo =
- WindowInfosListenerUtils::findMatchingWindowInfo(windowInfo, windowInfos);
+ WindowInfosListenerUtils::findMatchingWindowInfo(*windowInfo->getInfo(),
+ windowInfos);
if (!foundWindowInfo) {
return false;
}
@@ -386,7 +387,8 @@
Transaction().setTrustedOverlay(surfaceControl, true).apply(/*synchronous=*/true);
auto windowIsPresentAndTrusted = [&](const std::vector<WindowInfo>& windowInfos) {
auto foundWindowInfo =
- WindowInfosListenerUtils::findMatchingWindowInfo(windowInfo, windowInfos);
+ WindowInfosListenerUtils::findMatchingWindowInfo(*windowInfo->getInfo(),
+ windowInfos);
if (!foundWindowInfo) {
return false;
}
diff --git a/services/surfaceflinger/tests/WindowInfosListener_test.cpp b/services/surfaceflinger/tests/WindowInfosListener_test.cpp
index ad9a674..2dd0dd9 100644
--- a/services/surfaceflinger/tests/WindowInfosListener_test.cpp
+++ b/services/surfaceflinger/tests/WindowInfosListener_test.cpp
@@ -50,9 +50,9 @@
TEST_F(WindowInfosListenerTest, WindowInfoAddedAndRemoved) {
std::string name = "Test Layer";
sp<IBinder> token = sp<BBinder>::make();
- WindowInfo windowInfo;
- windowInfo.name = name;
- windowInfo.token = token;
+ auto windowInfo = sp<gui::WindowInfoHandle>::make();
+ windowInfo->editInfo()->name = name;
+ windowInfo->editInfo()->token = token;
sp<SurfaceControl> surfaceControl =
mClient->createSurface(String8(name.c_str()), 100, 100, PIXEL_FORMAT_RGBA_8888,
ISurfaceComposerClient::eFXSurfaceBufferState);
@@ -65,14 +65,14 @@
.apply();
auto windowPresent = [&](const std::vector<WindowInfo>& windowInfos) {
- return findMatchingWindowInfo(windowInfo, windowInfos);
+ return findMatchingWindowInfo(*windowInfo->getInfo(), windowInfos);
};
ASSERT_TRUE(waitForWindowInfosPredicate(windowPresent));
Transaction().reparent(surfaceControl, nullptr).apply();
auto windowNotPresent = [&](const std::vector<WindowInfo>& windowInfos) {
- return !findMatchingWindowInfo(windowInfo, windowInfos);
+ return !findMatchingWindowInfo(*windowInfo->getInfo(), windowInfos);
};
ASSERT_TRUE(waitForWindowInfosPredicate(windowNotPresent));
}
@@ -80,9 +80,9 @@
TEST_F(WindowInfosListenerTest, WindowInfoChanged) {
std::string name = "Test Layer";
sp<IBinder> token = sp<BBinder>::make();
- WindowInfo windowInfo;
- windowInfo.name = name;
- windowInfo.token = token;
+ auto windowInfo = sp<gui::WindowInfoHandle>::make();
+ windowInfo->editInfo()->name = name;
+ windowInfo->editInfo()->token = token;
sp<SurfaceControl> surfaceControl =
mClient->createSurface(String8(name.c_str()), 100, 100, PIXEL_FORMAT_RGBA_8888,
ISurfaceComposerClient::eFXSurfaceBufferState);
@@ -96,7 +96,7 @@
.apply();
auto windowIsPresentAndTouchableRegionEmpty = [&](const std::vector<WindowInfo>& windowInfos) {
- auto foundWindowInfo = findMatchingWindowInfo(windowInfo, windowInfos);
+ auto foundWindowInfo = findMatchingWindowInfo(*windowInfo->getInfo(), windowInfos);
if (!foundWindowInfo) {
return false;
}
@@ -104,19 +104,19 @@
};
ASSERT_TRUE(waitForWindowInfosPredicate(windowIsPresentAndTouchableRegionEmpty));
- windowInfo.addTouchableRegion({0, 0, 50, 50});
+ windowInfo->editInfo()->addTouchableRegion({0, 0, 50, 50});
Transaction().setInputWindowInfo(surfaceControl, windowInfo).apply();
auto windowIsPresentAndTouchableRegionMatches =
[&](const std::vector<WindowInfo>& windowInfos) {
- auto foundWindowInfo = findMatchingWindowInfo(windowInfo, windowInfos);
+ auto foundWindowInfo = findMatchingWindowInfo(*windowInfo->getInfo(), windowInfos);
if (!foundWindowInfo) {
return false;
}
auto touchableRegion =
foundWindowInfo->transform.transform(foundWindowInfo->touchableRegion);
- return touchableRegion.hasSameRects(windowInfo.touchableRegion);
+ return touchableRegion.hasSameRects(windowInfo->getInfo()->touchableRegion);
};
ASSERT_TRUE(waitForWindowInfosPredicate(windowIsPresentAndTouchableRegionMatches));
}