Merge "Dynamic logs for motions in UnwantedInteractionBlocker" into tm-qpr-dev
diff --git a/libs/gui/tests/EndToEndNativeInputTest.cpp b/libs/gui/tests/EndToEndNativeInputTest.cpp
index c6cdeb7..2637f59 100644
--- a/libs/gui/tests/EndToEndNativeInputTest.cpp
+++ b/libs/gui/tests/EndToEndNativeInputTest.cpp
@@ -1184,18 +1184,23 @@
std::vector<sp<IGraphicBufferProducer>> mProducers;
};
-TEST_F(MultiDisplayTests, drop_input_if_layer_on_invalid_display) {
+TEST_F(MultiDisplayTests, drop_touch_if_layer_on_invalid_display) {
ui::LayerStack layerStack = ui::LayerStack::fromValue(42);
// Do not create a display associated with the LayerStack.
std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
surface->doTransaction([&](auto &t, auto &sc) { t.setLayerStack(sc, layerStack); });
surface->showAt(100, 100);
+ // Touches should be dropped if the layer is on an invalid display.
injectTapOnDisplay(101, 101, layerStack.id);
- surface->requestFocus(layerStack.id);
- injectKeyOnDisplay(AKEYCODE_V, layerStack.id);
-
EXPECT_EQ(surface->consumeEvent(100), nullptr);
+
+ // However, we still let the window be focused and receive keys.
+ surface->requestFocus(layerStack.id);
+ surface->assertFocusChange(true);
+
+ injectKeyOnDisplay(AKEYCODE_V, layerStack.id);
+ surface->expectKey(AKEYCODE_V);
}
TEST_F(MultiDisplayTests, virtual_display_receives_input) {
diff --git a/services/inputflinger/UnwantedInteractionBlocker.cpp b/services/inputflinger/UnwantedInteractionBlocker.cpp
index 4744db0..4e0f0c3 100644
--- a/services/inputflinger/UnwantedInteractionBlocker.cpp
+++ b/services/inputflinger/UnwantedInteractionBlocker.cpp
@@ -92,8 +92,8 @@
static bool isPalmRejectionEnabled() {
std::string value = toLower(
server_configurable_flags::GetServerConfigurableFlag(INPUT_NATIVE_BOOT,
- PALM_REJECTION_ENABLED, "false"));
- if (value == "true" || value == "1") {
+ PALM_REJECTION_ENABLED, "0"));
+ if (value == "1") {
return true;
}
return false;
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp
index 5e9427a..d8120fc 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.cpp
+++ b/services/inputflinger/dispatcher/InputDispatcher.cpp
@@ -2195,10 +2195,7 @@
// Update the temporary touch state.
BitSet32 pointerIds;
- if (isSplit) {
- uint32_t pointerId = entry.pointerProperties[pointerIndex].id;
- pointerIds.markBit(pointerId);
- }
+ pointerIds.markBit(entry.pointerProperties[pointerIndex].id);
tempTouchState.addOrUpdateWindow(windowHandle, targetFlags, pointerIds);
}
@@ -2275,9 +2272,7 @@
}
BitSet32 pointerIds;
- if (isSplit) {
- pointerIds.markBit(entry.pointerProperties[0].id);
- }
+ pointerIds.markBit(entry.pointerProperties[0].id);
tempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds);
}
}
@@ -2453,21 +2448,28 @@
}
} else if (maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
// One pointer went up.
- if (isSplit) {
- int32_t pointerIndex = getMotionEventActionPointerIndex(action);
- uint32_t pointerId = entry.pointerProperties[pointerIndex].id;
+ int32_t pointerIndex = getMotionEventActionPointerIndex(action);
+ uint32_t pointerId = entry.pointerProperties[pointerIndex].id;
- for (size_t i = 0; i < tempTouchState.windows.size();) {
- TouchedWindow& touchedWindow = tempTouchState.windows[i];
- if (touchedWindow.targetFlags & InputTarget::FLAG_SPLIT) {
- touchedWindow.pointerIds.clearBit(pointerId);
- if (touchedWindow.pointerIds.isEmpty()) {
- tempTouchState.windows.erase(tempTouchState.windows.begin() + i);
- continue;
- }
- }
- i += 1;
+ for (size_t i = 0; i < tempTouchState.windows.size();) {
+ TouchedWindow& touchedWindow = tempTouchState.windows[i];
+ touchedWindow.pointerIds.clearBit(pointerId);
+ if (touchedWindow.pointerIds.isEmpty()) {
+ tempTouchState.windows.erase(tempTouchState.windows.begin() + i);
+ continue;
}
+ i += 1;
+ }
+ } else if (!isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN) {
+ // If no split, we suppose all touched windows should receive pointer down.
+ const int32_t pointerIndex = getMotionEventActionPointerIndex(action);
+ for (size_t i = 0; i < tempTouchState.windows.size(); i++) {
+ TouchedWindow& touchedWindow = tempTouchState.windows[i];
+ // Ignore drag window for it should just track one pointer.
+ if (mDragState && mDragState->dragWindow == touchedWindow.windowHandle) {
+ continue;
+ }
+ touchedWindow.pointerIds.markBit(entry.pointerProperties[pointerIndex].id);
}
}
@@ -4470,6 +4472,14 @@
if (it == mDisplayInfos.end()) return;
const auto& transformToDisplay = it->second.transform.inverse() * injectedTransform;
+ if (entry.xCursorPosition != AMOTION_EVENT_INVALID_CURSOR_POSITION &&
+ entry.yCursorPosition != AMOTION_EVENT_INVALID_CURSOR_POSITION) {
+ const vec2 cursor =
+ MotionEvent::calculateTransformedXY(entry.source, transformToDisplay,
+ {entry.xCursorPosition, entry.yCursorPosition});
+ entry.xCursorPosition = cursor.x;
+ entry.yCursorPosition = cursor.y;
+ }
for (uint32_t i = 0; i < entry.pointerCount; i++) {
entry.pointerCoords[i] =
MotionEvent::calculateTransformedCoords(entry.source, transformToDisplay,
@@ -5079,14 +5089,13 @@
// Store the dragging window.
if (isDragDrop) {
- if (pointerIds.count() > 1) {
- ALOGW("The drag and drop cannot be started when there is more than 1 pointer on the"
- " window.");
+ if (pointerIds.count() != 1) {
+ ALOGW("The drag and drop cannot be started when there is no pointer or more than 1"
+ " pointer on the window.");
return false;
}
- // If the window didn't not support split or the source is mouse, the pointerIds count
- // would be 0, so we have to track the pointer 0.
- const int32_t id = pointerIds.count() == 0 ? 0 : pointerIds.firstMarkedBit();
+ // Track the pointer id for drag window and generate the drag state.
+ const int32_t id = pointerIds.firstMarkedBit();
mDragState = std::make_unique<DragState>(toWindowHandle, id);
}
@@ -6322,6 +6331,13 @@
{ // acquire lock
std::scoped_lock _l(mLock);
+
+ // Ensure that we have an entry created for all existing displays so that if a displayId has
+ // no windows, we can tell that the windows were removed from the display.
+ for (const auto& [displayId, _] : mWindowHandlesByDisplay) {
+ handlesPerDisplay[displayId];
+ }
+
mDisplayInfos.clear();
for (const auto& displayInfo : displayInfos) {
mDisplayInfos.emplace(displayInfo.displayId, displayInfo);
diff --git a/services/inputflinger/dispatcher/InputTarget.cpp b/services/inputflinger/dispatcher/InputTarget.cpp
index d39113b..2df97d9 100644
--- a/services/inputflinger/dispatcher/InputTarget.cpp
+++ b/services/inputflinger/dispatcher/InputTarget.cpp
@@ -43,8 +43,8 @@
}
void InputTarget::addPointers(BitSet32 newPointerIds, const ui::Transform& transform) {
- // The pointerIds can be empty, but still a valid InputTarget. This can happen for Monitors
- // and non splittable windows since we will just use all the pointers from the input event.
+ // The pointerIds can be empty, but still a valid InputTarget. This can happen when there is no
+ // valid pointer property from the input event.
if (newPointerIds.isEmpty()) {
setDefaultPointerTransform(transform);
return;
diff --git a/services/inputflinger/dispatcher/TouchedWindow.h b/services/inputflinger/dispatcher/TouchedWindow.h
index 4c31ec3..6783022 100644
--- a/services/inputflinger/dispatcher/TouchedWindow.h
+++ b/services/inputflinger/dispatcher/TouchedWindow.h
@@ -29,7 +29,7 @@
struct TouchedWindow {
sp<gui::WindowInfoHandle> windowHandle;
int32_t targetFlags;
- BitSet32 pointerIds; // zero unless target flag FLAG_SPLIT is set
+ BitSet32 pointerIds;
};
} // namespace inputdispatcher
diff --git a/services/inputflinger/tests/InputDispatcher_test.cpp b/services/inputflinger/tests/InputDispatcher_test.cpp
index df43071..df1a230 100644
--- a/services/inputflinger/tests/InputDispatcher_test.cpp
+++ b/services/inputflinger/tests/InputDispatcher_test.cpp
@@ -2293,6 +2293,35 @@
thirdWindow->consumeMotionDown();
}
+TEST_F(InputDispatcherTest, OnWindowInfosChanged_RemoveAllWindowsOnDisplay) {
+ std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
+ sp<FakeWindowHandle> window =
+ new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
+ window->setFocusable(true);
+
+ mDispatcher->onWindowInfosChanged({*window->getInfo()}, {});
+ setFocusedWindow(window);
+
+ window->consumeFocusEvent(true);
+
+ NotifyKeyArgs keyDown = generateKeyArgs(AKEY_EVENT_ACTION_DOWN, ADISPLAY_ID_DEFAULT);
+ NotifyKeyArgs keyUp = generateKeyArgs(AKEY_EVENT_ACTION_UP, ADISPLAY_ID_DEFAULT);
+ mDispatcher->notifyKey(&keyDown);
+ mDispatcher->notifyKey(&keyUp);
+
+ window->consumeKeyDown(ADISPLAY_ID_DEFAULT);
+ window->consumeKeyUp(ADISPLAY_ID_DEFAULT);
+
+ // All windows are removed from the display. Ensure that we can no longer dispatch to it.
+ mDispatcher->onWindowInfosChanged({}, {});
+
+ window->consumeFocusEvent(false);
+
+ mDispatcher->notifyKey(&keyDown);
+ mDispatcher->notifyKey(&keyUp);
+ window->assertNoEvents();
+}
+
/**
* Ensure the correct coordinate spaces are used by InputDispatcher.
*
@@ -6096,6 +6125,8 @@
sp<FakeWindowHandle> mWindow;
sp<FakeWindowHandle> mSecondWindow;
sp<FakeWindowHandle> mDragWindow;
+ // Mouse would force no-split, set the id as non-zero to verify if drag state could track it.
+ static constexpr int32_t MOUSE_POINTER_ID = 1;
void SetUp() override {
InputDispatcherTest::SetUp();
@@ -6110,11 +6141,41 @@
mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mWindow, mSecondWindow}}});
}
- void injectDown() {
- ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
- injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
- {50, 50}))
- << "Inject motion event should return InputEventInjectionResult::SUCCEEDED";
+ void injectDown(int fromSource = AINPUT_SOURCE_TOUCHSCREEN) {
+ switch (fromSource) {
+ case AINPUT_SOURCE_TOUCHSCREEN:
+ ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
+ injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN,
+ ADISPLAY_ID_DEFAULT, {50, 50}))
+ << "Inject motion event should return InputEventInjectionResult::SUCCEEDED";
+ break;
+ case AINPUT_SOURCE_STYLUS:
+ ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
+ injectMotionEvent(
+ mDispatcher,
+ MotionEventBuilder(AMOTION_EVENT_ACTION_DOWN,
+ AINPUT_SOURCE_STYLUS)
+ .buttonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY)
+ .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_STYLUS)
+ .x(50)
+ .y(50))
+ .build()));
+ break;
+ case AINPUT_SOURCE_MOUSE:
+ ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
+ injectMotionEvent(
+ mDispatcher,
+ MotionEventBuilder(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_MOUSE)
+ .buttonState(AMOTION_EVENT_BUTTON_PRIMARY)
+ .pointer(PointerBuilder(MOUSE_POINTER_ID,
+ AMOTION_EVENT_TOOL_TYPE_MOUSE)
+ .x(50)
+ .y(50))
+ .build()));
+ break;
+ default:
+ FAIL() << "Source " << fromSource << " doesn't support drag and drop";
+ }
// Window should receive motion event.
mWindow->consumeMotionDown(ADISPLAY_ID_DEFAULT);
@@ -6123,9 +6184,9 @@
// Start performing drag, we will create a drag window and transfer touch to it.
// @param sendDown : if true, send a motion down on first window before perform drag and drop.
// Returns true on success.
- bool performDrag(bool sendDown = true) {
+ bool startDrag(bool sendDown = true, int fromSource = AINPUT_SOURCE_TOUCHSCREEN) {
if (sendDown) {
- injectDown();
+ injectDown(fromSource);
}
// The drag window covers the entire display
@@ -6143,36 +6204,10 @@
}
return transferred;
}
-
- // Start performing drag, we will create a drag window and transfer touch to it.
- void performStylusDrag() {
- ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
- injectMotionEvent(mDispatcher,
- MotionEventBuilder(AMOTION_EVENT_ACTION_DOWN,
- AINPUT_SOURCE_STYLUS)
- .buttonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY)
- .pointer(PointerBuilder(0,
- AMOTION_EVENT_TOOL_TYPE_STYLUS)
- .x(50)
- .y(50))
- .build()));
- mWindow->consumeMotionDown(ADISPLAY_ID_DEFAULT);
-
- // The drag window covers the entire display
- mDragWindow = new FakeWindowHandle(mApp, mDispatcher, "DragWindow", ADISPLAY_ID_DEFAULT);
- mDispatcher->setInputWindows(
- {{ADISPLAY_ID_DEFAULT, {mDragWindow, mWindow, mSecondWindow}}});
-
- // Transfer touch focus to the drag window
- mDispatcher->transferTouchFocus(mWindow->getToken(), mDragWindow->getToken(),
- true /* isDragDrop */);
- mWindow->consumeMotionCancel();
- mDragWindow->consumeMotionDown();
- }
};
TEST_F(InputDispatcherDragTests, DragEnterAndDragExit) {
- performDrag();
+ startDrag();
// Move on window.
ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
@@ -6210,7 +6245,7 @@
}
TEST_F(InputDispatcherDragTests, DragAndDrop) {
- performDrag();
+ startDrag();
// Move on window.
ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
@@ -6242,7 +6277,7 @@
}
TEST_F(InputDispatcherDragTests, StylusDragAndDrop) {
- performStylusDrag();
+ startDrag(true, AINPUT_SOURCE_STYLUS);
// Move on window and keep button pressed.
ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
@@ -6289,7 +6324,7 @@
}
TEST_F(InputDispatcherDragTests, DragAndDropOnInvalidWindow) {
- performDrag();
+ startDrag();
// Set second window invisible.
mSecondWindow->setVisible(false);
@@ -6325,6 +6360,9 @@
}
TEST_F(InputDispatcherDragTests, NoDragAndDropWhenMultiFingers) {
+ // Ensure window could track pointerIds if it didn't support split touch.
+ mWindow->setPreventSplitting(true);
+
ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
{50, 50}))
@@ -6345,7 +6383,7 @@
mWindow->consumeMotionPointerDown(1 /* pointerIndex */);
// Should not perform drag and drop when window has multi fingers.
- ASSERT_FALSE(performDrag(false));
+ ASSERT_FALSE(startDrag(false));
}
TEST_F(InputDispatcherDragTests, DragAndDropWhenSplitTouch) {
@@ -6373,7 +6411,7 @@
mWindow->consumeMotionDown(ADISPLAY_ID_DEFAULT);
// Perform drag and drop from first window.
- ASSERT_TRUE(performDrag(false));
+ ASSERT_TRUE(startDrag(false));
// Move on window.
const MotionEvent secondFingerMoveEvent =
@@ -6408,7 +6446,7 @@
}
TEST_F(InputDispatcherDragTests, DragAndDropWhenMultiDisplays) {
- performDrag();
+ startDrag();
// Update window of second display.
sp<FakeWindowHandle> windowInSecondary =
@@ -6459,6 +6497,55 @@
mSecondWindow->assertNoEvents();
}
+TEST_F(InputDispatcherDragTests, MouseDragAndDrop) {
+ startDrag(true, AINPUT_SOURCE_MOUSE);
+ // Move on window.
+ ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
+ injectMotionEvent(mDispatcher,
+ MotionEventBuilder(AMOTION_EVENT_ACTION_MOVE, AINPUT_SOURCE_MOUSE)
+ .buttonState(AMOTION_EVENT_BUTTON_PRIMARY)
+ .pointer(PointerBuilder(MOUSE_POINTER_ID,
+ AMOTION_EVENT_TOOL_TYPE_MOUSE)
+ .x(50)
+ .y(50))
+ .build()))
+ << "Inject motion event should return InputEventInjectionResult::SUCCEEDED";
+ mDragWindow->consumeMotionMove(ADISPLAY_ID_DEFAULT);
+ mWindow->consumeDragEvent(false, 50, 50);
+ mSecondWindow->assertNoEvents();
+
+ // Move to another window.
+ ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
+ injectMotionEvent(mDispatcher,
+ MotionEventBuilder(AMOTION_EVENT_ACTION_MOVE, AINPUT_SOURCE_MOUSE)
+ .buttonState(AMOTION_EVENT_BUTTON_PRIMARY)
+ .pointer(PointerBuilder(MOUSE_POINTER_ID,
+ AMOTION_EVENT_TOOL_TYPE_MOUSE)
+ .x(150)
+ .y(50))
+ .build()))
+ << "Inject motion event should return InputEventInjectionResult::SUCCEEDED";
+ mDragWindow->consumeMotionMove(ADISPLAY_ID_DEFAULT);
+ mWindow->consumeDragEvent(true, 150, 50);
+ mSecondWindow->consumeDragEvent(false, 50, 50);
+
+ // drop to another window.
+ ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
+ injectMotionEvent(mDispatcher,
+ MotionEventBuilder(AMOTION_EVENT_ACTION_UP, AINPUT_SOURCE_MOUSE)
+ .buttonState(0)
+ .pointer(PointerBuilder(MOUSE_POINTER_ID,
+ AMOTION_EVENT_TOOL_TYPE_MOUSE)
+ .x(150)
+ .y(50))
+ .build()))
+ << "Inject motion event should return InputEventInjectionResult::SUCCEEDED";
+ mDragWindow->consumeMotionUp(ADISPLAY_ID_DEFAULT);
+ mFakePolicy->assertDropTargetEquals(mSecondWindow->getToken());
+ mWindow->assertNoEvents();
+ mSecondWindow->assertNoEvents();
+}
+
class InputDispatcherDropInputFeatureTest : public InputDispatcherTest {};
TEST_F(InputDispatcherDropInputFeatureTest, WindowDropsInput) {
diff --git a/services/surfaceflinger/CompositionEngine/src/Output.cpp b/services/surfaceflinger/CompositionEngine/src/Output.cpp
index aa0b152..bc11d87 100644
--- a/services/surfaceflinger/CompositionEngine/src/Output.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/Output.cpp
@@ -1243,7 +1243,8 @@
ATRACE_NAME("ClientCompositionCacheHit");
outputCompositionState.reusedClientComposition = true;
setExpensiveRenderingExpected(false);
- return base::unique_fd();
+ // b/239944175 pass the fence associated with the buffer.
+ return base::unique_fd(std::move(fd));
}
ATRACE_NAME("ClientCompositionCacheMiss");
mClientCompositionRequestCache->add(tex->getBuffer()->getId(), clientCompositionDisplay,
diff --git a/services/surfaceflinger/DisplayHardware/PowerAdvisor.cpp b/services/surfaceflinger/DisplayHardware/PowerAdvisor.cpp
index 77dda6c..b9d4753 100644
--- a/services/surfaceflinger/DisplayHardware/PowerAdvisor.cpp
+++ b/services/surfaceflinger/DisplayHardware/PowerAdvisor.cpp
@@ -187,7 +187,7 @@
if (!mSupportsPowerHint.has_value()) {
std::lock_guard lock(mPowerHalMutex);
HalWrapper* const halWrapper = getPowerHal();
- mSupportsPowerHint = halWrapper->supportsPowerHintSession();
+ mSupportsPowerHint = halWrapper && halWrapper->supportsPowerHintSession();
}
return *mSupportsPowerHint;
}
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index be16942..bcc94d3 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -81,6 +81,7 @@
namespace android {
namespace {
constexpr int kDumpTableRowLength = 159;
+const ui::Transform kIdentityTransform;
} // namespace
using namespace ftl::flag_operators;
@@ -2162,7 +2163,8 @@
if ((traceFlags & LayerTracing::TRACE_INPUT) && needsInputInfo()) {
WindowInfo info;
if (useDrawing) {
- info = fillInputInfo(ui::Transform(), /* displayIsSecure */ true);
+ info = fillInputInfo(
+ InputDisplayArgs{.transform = &kIdentityTransform, .isSecure = true});
} else {
info = state.inputInfo;
}
@@ -2369,7 +2371,7 @@
}
}
-WindowInfo Layer::fillInputInfo(const ui::Transform& displayTransform, bool displayIsSecure) {
+WindowInfo Layer::fillInputInfo(const InputDisplayArgs& displayArgs) {
if (!hasInputInfo()) {
mDrawingState.inputInfo.name = getName();
mDrawingState.inputInfo.ownerUid = mOwnerUid;
@@ -2378,12 +2380,21 @@
mDrawingState.inputInfo.displayId = getLayerStack().id;
}
+ const ui::Transform& displayTransform =
+ displayArgs.transform != nullptr ? *displayArgs.transform : kIdentityTransform;
+
WindowInfo info = mDrawingState.inputInfo;
info.id = sequence;
info.displayId = getLayerStack().id;
fillInputFrameInfo(info, displayTransform);
+ if (displayArgs.transform == nullptr) {
+ // Do not let the window receive touches if it is not associated with a valid display
+ // transform. We still allow the window to receive keys and prevent ANRs.
+ info.inputConfig |= WindowInfo::InputConfig::NOT_TOUCHABLE;
+ }
+
// For compatibility reasons we let layers which can receive input
// receive input before they have actually submitted a buffer. Because
// of this we use canReceiveInput instead of isVisible to check the
@@ -2401,7 +2412,7 @@
// If the window will be blacked out on a display because the display does not have the secure
// flag and the layer has the secure flag set, then drop input.
- if (!displayIsSecure && isSecure()) {
+ if (!displayArgs.isSecure && isSecure()) {
info.inputConfig |= WindowInfo::InputConfig::DROP_INPUT;
}
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 24abad9..c547da0 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -844,7 +844,11 @@
bool getPremultipledAlpha() const;
void setInputInfo(const gui::WindowInfo& info);
- gui::WindowInfo fillInputInfo(const ui::Transform& displayTransform, bool displayIsSecure);
+ struct InputDisplayArgs {
+ const ui::Transform* transform = nullptr;
+ bool isSecure = false;
+ };
+ gui::WindowInfo fillInputInfo(const InputDisplayArgs& displayArgs);
/**
* Returns whether this layer has an explicitly set input-info.
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 6e74eef..8621d31 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -448,7 +448,7 @@
// Power hint session mode, representing which hint(s) to send: early, late, or both)
mPowerHintSessionMode =
{.late = base::GetBoolProperty("debug.sf.send_late_power_session_hint"s, true),
- .early = base::GetBoolProperty("debug.sf.send_early_power_session_hint"s, true)};
+ .early = base::GetBoolProperty("debug.sf.send_early_power_session_hint"s, false)};
}
LatchUnsignaledConfig SurfaceFlinger::getLatchUnsignaledConfig() {
@@ -2087,11 +2087,9 @@
// Save this once per commit + composite to ensure consistency
mPowerHintSessionEnabled = mPowerAdvisor->usePowerHintSession();
if (mPowerHintSessionEnabled) {
- nsecs_t vsyncPeriod;
- {
- Mutex::Autolock lock(mStateLock);
- vsyncPeriod = getVsyncPeriodFromHWC();
- }
+ const auto& display = FTL_FAKE_GUARD(mStateLock, getDefaultDisplayDeviceLocked()).get();
+ // get stable vsync period from display mode
+ const nsecs_t vsyncPeriod = display->getActiveMode()->getVsyncPeriod();
mPowerAdvisor->setCommitStart(frameTime);
mPowerAdvisor->setExpectedPresentTime(mExpectedPresentTime);
const nsecs_t idealSfWorkDuration =
@@ -3329,11 +3327,11 @@
mDrawingState.traverseInReverseZOrder([&](Layer* layer) {
if (!layer->needsInputInfo()) return;
- // Do not create WindowInfos for windows on displays that cannot receive input.
- if (const auto opt = displayInputInfos.get(layer->getLayerStack())) {
- const auto& info = opt->get();
- outWindowInfos.push_back(layer->fillInputInfo(info.transform, info.isSecure));
- }
+ const auto opt = displayInputInfos.get(layer->getLayerStack(),
+ [](const auto& info) -> Layer::InputDisplayArgs {
+ return {&info.transform, info.isSecure};
+ });
+ outWindowInfos.push_back(layer->fillInputInfo(opt.value_or(Layer::InputDisplayArgs{})));
});
sNumWindowInfos = outWindowInfos.size();
@@ -6639,8 +6637,13 @@
1 /* layerCount */, usage, "screenshot");
const status_t bufferStatus = buffer->initCheck();
- LOG_ALWAYS_FATAL_IF(bufferStatus != OK, "captureScreenCommon: Buffer failed to allocate: %d",
- bufferStatus);
+ if (bufferStatus != OK) {
+ // Animations may end up being really janky, but don't crash here.
+ // Otherwise an irreponsible process may cause an SF crash by allocating
+ // too much.
+ ALOGE("%s: Buffer failed to allocate: %d", __func__, bufferStatus);
+ return ftl::yield<FenceResult>(base::unexpected(bufferStatus)).share();
+ }
const std::shared_ptr<renderengine::ExternalTexture> texture = std::make_shared<
renderengine::impl::ExternalTexture>(buffer, getRenderEngine(),
renderengine::impl::ExternalTexture::Usage::