Merge "Error fix from enabling Clang thread-safety checks in Cuttlefish" into main
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index 220fef6..4e3889a 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -170,6 +170,7 @@
#define ALT_PSTORE_LAST_KMSG "/sys/fs/pstore/console-ramoops-0"
#define BLK_DEV_SYS_DIR "/sys/block"
+#define AFLAGS "/system/bin/aflags"
#define RECOVERY_DIR "/cache/recovery"
#define RECOVERY_DATA_DIR "/data/misc/recovery"
#define UPDATE_ENGINE_LOG_DIR "/data/misc/update_engine_log"
@@ -1792,6 +1793,10 @@
RunCommand("ACONFIG FLAGS", {PRINT_FLAGS},
CommandOptions::WithTimeout(10).Always().DropRoot().Build());
+ RunCommand("ACONFIG FLAGS DUMP", {AFLAGS, "list"},
+ CommandOptions::WithTimeout(10).Always().AsRootIfAvailable().Build());
+ RunCommand("WHICH ACONFIG FLAG STORAGE", {AFLAGS, "which-backing"},
+ CommandOptions::WithTimeout(10).Always().AsRootIfAvailable().Build());
RunCommand("STORAGED IO INFO", {"storaged", "-u", "-p"});
diff --git a/libs/binder/BackendUnifiedServiceManager.cpp b/libs/binder/BackendUnifiedServiceManager.cpp
index 5680798..52b485a 100644
--- a/libs/binder/BackendUnifiedServiceManager.cpp
+++ b/libs/binder/BackendUnifiedServiceManager.cpp
@@ -34,37 +34,47 @@
using IAccessor = android::os::IAccessor;
static const char* kStaticCachableList[] = {
+ // go/keep-sorted start
+ "accessibility",
+ "account",
"activity",
- "android.hardware.thermal.IThermal/default",
- "android.hardware.power.IPower/default",
- "android.frameworks.stats.IStats/default",
- "android.system.suspend.ISystemSuspend/default",
+ "alarm",
+ "android.system.keystore2.IKeystoreService/default",
"appops",
"audio",
"batterystats",
"carrier_config",
"connectivity",
+ "content",
"content_capture",
"device_policy",
"display",
"dropbox",
"econtroller",
+ "graphicsstats",
+ "input",
+ "input_method",
"isub",
+ "jobscheduler",
"legacy_permission",
"location",
"media.extractor",
"media.metrics",
"media.player",
"media.resource_manager",
+ "media_resource_monitor",
+ "mount",
"netd_listener",
"netstats",
"network_management",
"nfc",
+ "notification",
+ "package",
"package_native",
"performance_hint",
"permission",
- "permissionmgr",
"permission_checker",
+ "permissionmgr",
"phone",
"platform_compat",
"power",
@@ -76,9 +86,12 @@
"time_detector",
"trust",
"uimode",
+ "user",
"virtualdevice",
"virtualdevice_native",
"webviewupdate",
+ "window",
+ // go/keep-sorted end
};
bool BinderCacheWithInvalidation::isClientSideCachingEnabled(const std::string& serviceName) {
diff --git a/libs/gui/BLASTBufferQueue.cpp b/libs/gui/BLASTBufferQueue.cpp
index f5b3618..25e6a52 100644
--- a/libs/gui/BLASTBufferQueue.cpp
+++ b/libs/gui/BLASTBufferQueue.cpp
@@ -31,7 +31,6 @@
#include <sys/epoll.h>
#include <sys/eventfd.h>
-#include <gui/FenceMonitor.h>
#include <gui/FrameRateUtils.h>
#include <gui/GLConsumer.h>
#include <gui/IProducerListener.h>
@@ -476,16 +475,6 @@
ATRACE_CALL();
BQA_LOGV("releaseBufferCallback %s", id.to_string().c_str());
- if (CC_UNLIKELY(atrace_is_tag_enabled(ATRACE_TAG_GRAPHICS))) {
- if (!mFenceMonitor) {
- std::string monitorName = "release :";
- monitorName.append(mName.c_str());
- mFenceMonitor.emplace(monitorName.c_str());
- }
-
- mFenceMonitor->queueFence(releaseFence);
- }
-
// Calculate how many buffers we need to hold before we release them back
// to the buffer queue. This will prevent higher latency when we are running
// on a lower refresh rate than the max supported. We only do that for EGL
diff --git a/libs/gui/FenceMonitor.cpp b/libs/gui/FenceMonitor.cpp
index e38f1a8..230c81a 100644
--- a/libs/gui/FenceMonitor.cpp
+++ b/libs/gui/FenceMonitor.cpp
@@ -25,18 +25,9 @@
namespace android::gui {
FenceMonitor::FenceMonitor(const char* name) : mName(name), mFencesQueued(0), mFencesSignaled(0) {
- mThread = std::thread(&FenceMonitor::loop, this);
-}
-
-FenceMonitor::~FenceMonitor() {
- {
- std::lock_guard<std::mutex> lock(mMutex);
- mStopped = true;
- mCondition.notify_one();
- }
- if (mThread.joinable()) {
- mThread.join();
- }
+ std::thread thread(&FenceMonitor::loop, this);
+ pthread_setname_np(thread.native_handle(), mName);
+ thread.detach();
}
void FenceMonitor::queueFence(const sp<Fence>& fence) {
@@ -44,26 +35,24 @@
std::lock_guard<std::mutex> lock(mMutex);
if (fence->getSignalTime() != Fence::SIGNAL_TIME_PENDING) {
- snprintf(message, sizeof(message), "%s fence %u has signaled", mName.c_str(),
- mFencesQueued);
+ snprintf(message, sizeof(message), "%s fence %u has signaled", mName, mFencesQueued);
ATRACE_NAME(message);
// Need an increment on both to make the trace number correct.
mFencesQueued++;
mFencesSignaled++;
return;
}
- snprintf(message, sizeof(message), "Trace %s fence %u", mName.c_str(), mFencesQueued);
+ snprintf(message, sizeof(message), "Trace %s fence %u", mName, mFencesQueued);
ATRACE_NAME(message);
mQueue.push_back(fence);
mCondition.notify_one();
mFencesQueued++;
- ATRACE_INT(mName.c_str(), int32_t(mQueue.size()));
+ ATRACE_INT(mName, int32_t(mQueue.size()));
}
void FenceMonitor::loop() {
- pthread_setname_np(pthread_self(), mName.c_str());
- while (!mStopped) {
+ while (true) {
threadLoop();
}
}
@@ -73,18 +62,15 @@
uint32_t fenceNum;
{
std::unique_lock<std::mutex> lock(mMutex);
- while (mQueue.empty() && !mStopped) {
+ while (mQueue.empty()) {
mCondition.wait(lock);
}
- if (mStopped) {
- return;
- }
fence = mQueue[0];
fenceNum = mFencesSignaled;
}
{
char message[64];
- snprintf(message, sizeof(message), "waiting for %s %u", mName.c_str(), fenceNum);
+ snprintf(message, sizeof(message), "waiting for %s %u", mName, fenceNum);
ATRACE_NAME(message);
status_t result = fence->waitForever(message);
@@ -96,8 +82,8 @@
std::lock_guard<std::mutex> lock(mMutex);
mQueue.pop_front();
mFencesSignaled++;
- ATRACE_INT(mName.c_str(), int32_t(mQueue.size()));
+ ATRACE_INT(mName, int32_t(mQueue.size()));
}
}
-} // namespace android::gui
+} // namespace android::gui
\ No newline at end of file
diff --git a/libs/gui/include/gui/BLASTBufferQueue.h b/libs/gui/include/gui/BLASTBufferQueue.h
index ba58a15..8592cff 100644
--- a/libs/gui/include/gui/BLASTBufferQueue.h
+++ b/libs/gui/include/gui/BLASTBufferQueue.h
@@ -20,7 +20,6 @@
#include <com_android_graphics_libgui_flags.h>
#include <gui/BufferItem.h>
#include <gui/BufferItemConsumer.h>
-#include <gui/FenceMonitor.h>
#include <gui/IGraphicBufferConsumer.h>
#include <gui/IGraphicBufferProducer.h>
#include <gui/SurfaceComposerClient.h>
@@ -317,8 +316,6 @@
std::unordered_set<uint64_t> mSyncedFrameNumbers GUARDED_BY(mMutex);
- std::optional<gui::FenceMonitor> mFenceMonitor GUARDED_BY(mMutex);
-
#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BUFFER_RELEASE_CHANNEL)
class BufferReleaseReader {
public:
diff --git a/libs/gui/include/gui/FenceMonitor.h b/libs/gui/include/gui/FenceMonitor.h
index ac5cc0a..62cedde 100644
--- a/libs/gui/include/gui/FenceMonitor.h
+++ b/libs/gui/include/gui/FenceMonitor.h
@@ -19,7 +19,6 @@
#include <cstdint>
#include <deque>
#include <mutex>
-#include <thread>
#include <ui/Fence.h>
@@ -29,20 +28,17 @@
public:
explicit FenceMonitor(const char* name);
void queueFence(const sp<Fence>& fence);
- ~FenceMonitor();
private:
void loop();
void threadLoop();
- std::string mName;
+ const char* mName;
uint32_t mFencesQueued;
uint32_t mFencesSignaled;
std::deque<sp<Fence>> mQueue;
std::condition_variable mCondition;
std::mutex mMutex;
- std::thread mThread;
- std::atomic_bool mStopped = false;
};
-} // namespace android::gui
+} // namespace android::gui
\ No newline at end of file
diff --git a/libs/gui/include/gui/Flags.h b/libs/gui/include/gui/Flags.h
new file mode 100644
index 0000000..735375a
--- /dev/null
+++ b/libs/gui/include/gui/Flags.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <com_android_graphics_libgui_flags.h>
+
+#define WB_CAMERA3_AND_PROCESSORS_WITH_DEPENDENCIES \
+ (COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CAMERA3_AND_PROCESSORS) && \
+ COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ) && \
+ COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS))
\ No newline at end of file
diff --git a/libs/gui/include/gui/Surface.h b/libs/gui/include/gui/Surface.h
index e74f9ad..14a3513 100644
--- a/libs/gui/include/gui/Surface.h
+++ b/libs/gui/include/gui/Surface.h
@@ -34,8 +34,6 @@
#include <shared_mutex>
#include <unordered_set>
-#include <com_android_graphics_libgui_flags.h>
-
namespace android {
class GraphicBuffer;
diff --git a/services/inputflinger/dispatcher/CancelationOptions.h b/services/inputflinger/dispatcher/CancelationOptions.h
index 4a0889f..568d348 100644
--- a/services/inputflinger/dispatcher/CancelationOptions.h
+++ b/services/inputflinger/dispatcher/CancelationOptions.h
@@ -32,7 +32,8 @@
CANCEL_POINTER_EVENTS = 1,
CANCEL_NON_POINTER_EVENTS = 2,
CANCEL_FALLBACK_EVENTS = 3,
- ftl_last = CANCEL_FALLBACK_EVENTS,
+ CANCEL_HOVER_EVENTS = 4,
+ ftl_last = CANCEL_HOVER_EVENTS
};
// The criterion to use to determine which events should be canceled.
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp
index 75b494b..05139cf 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.cpp
+++ b/services/inputflinger/dispatcher/InputDispatcher.cpp
@@ -748,7 +748,8 @@
}
touchedWindow.dispatchMode = InputTarget::DispatchMode::AS_IS;
}
- touchedWindow.addHoveringPointer(entry.deviceId, pointer);
+ const auto [x, y] = resolveTouchedPosition(entry);
+ touchedWindow.addHoveringPointer(entry.deviceId, pointer, x, y);
if (canReceiveForegroundTouches(*newWindow->getInfo())) {
touchedWindow.targetFlags |= InputTarget::Flags::FOREGROUND;
}
@@ -875,6 +876,8 @@
return {false, true};
case CancelationOptions::Mode::CANCEL_FALLBACK_EVENTS:
return {false, true};
+ case CancelationOptions::Mode::CANCEL_HOVER_EVENTS:
+ return {true, false};
}
}
@@ -2511,7 +2514,8 @@
if (isHoverAction) {
// The "windowHandle" is the target of this hovering pointer.
- tempTouchState.addHoveringPointerToWindow(windowHandle, entry.deviceId, pointer);
+ tempTouchState.addHoveringPointerToWindow(windowHandle, entry.deviceId, pointer, x,
+ y);
}
// Set target flags.
@@ -5419,6 +5423,32 @@
}
}
+ // Check if the hovering should stop because the window is no longer eligible to receive it
+ // (for example, if the touchable region changed)
+ if (const auto& it = mTouchStatesByDisplay.find(displayId); it != mTouchStatesByDisplay.end()) {
+ TouchState& state = it->second;
+ for (TouchedWindow& touchedWindow : state.windows) {
+ std::vector<DeviceId> erasedDevices = touchedWindow.eraseHoveringPointersIf(
+ [this, displayId, &touchedWindow](const PointerProperties& properties, float x,
+ float y) REQUIRES(mLock) {
+ const bool isStylus = properties.toolType == ToolType::STYLUS;
+ const ui::Transform displayTransform = getTransformLocked(displayId);
+ const bool stillAcceptsTouch =
+ windowAcceptsTouchAt(*touchedWindow.windowHandle->getInfo(),
+ displayId, x, y, isStylus, displayTransform);
+ return !stillAcceptsTouch;
+ });
+
+ for (DeviceId deviceId : erasedDevices) {
+ CancelationOptions options(CancelationOptions::Mode::CANCEL_HOVER_EVENTS,
+ "WindowInfo changed",
+ traceContext.getTracker());
+ options.deviceId = deviceId;
+ synthesizeCancelationEventsForWindowLocked(touchedWindow.windowHandle, options);
+ }
+ }
+ }
+
// Release information for windows that are no longer present.
// This ensures that unused input channels are released promptly.
// Otherwise, they might stick around until the window handle is destroyed
diff --git a/services/inputflinger/dispatcher/InputState.cpp b/services/inputflinger/dispatcher/InputState.cpp
index 4df23c5..9b5a79b 100644
--- a/services/inputflinger/dispatcher/InputState.cpp
+++ b/services/inputflinger/dispatcher/InputState.cpp
@@ -638,6 +638,8 @@
return memento.source & AINPUT_SOURCE_CLASS_POINTER;
case CancelationOptions::Mode::CANCEL_NON_POINTER_EVENTS:
return !(memento.source & AINPUT_SOURCE_CLASS_POINTER);
+ case CancelationOptions::Mode::CANCEL_HOVER_EVENTS:
+ return memento.hovering;
default:
return false;
}
diff --git a/services/inputflinger/dispatcher/TouchState.cpp b/services/inputflinger/dispatcher/TouchState.cpp
index 0c9ad3c..2bf63be 100644
--- a/services/inputflinger/dispatcher/TouchState.cpp
+++ b/services/inputflinger/dispatcher/TouchState.cpp
@@ -112,17 +112,18 @@
}
void TouchState::addHoveringPointerToWindow(const sp<WindowInfoHandle>& windowHandle,
- DeviceId deviceId, const PointerProperties& pointer) {
+ DeviceId deviceId, const PointerProperties& pointer,
+ float x, float y) {
for (TouchedWindow& touchedWindow : windows) {
if (touchedWindow.windowHandle == windowHandle) {
- touchedWindow.addHoveringPointer(deviceId, pointer);
+ touchedWindow.addHoveringPointer(deviceId, pointer, x, y);
return;
}
}
TouchedWindow touchedWindow;
touchedWindow.windowHandle = windowHandle;
- touchedWindow.addHoveringPointer(deviceId, pointer);
+ touchedWindow.addHoveringPointer(deviceId, pointer, x, y);
windows.push_back(touchedWindow);
}
diff --git a/services/inputflinger/dispatcher/TouchState.h b/services/inputflinger/dispatcher/TouchState.h
index 5a70dd5..451d917 100644
--- a/services/inputflinger/dispatcher/TouchState.h
+++ b/services/inputflinger/dispatcher/TouchState.h
@@ -49,7 +49,8 @@
DeviceId deviceId, const std::vector<PointerProperties>& touchingPointers,
std::optional<nsecs_t> firstDownTimeInTarget);
void addHoveringPointerToWindow(const sp<android::gui::WindowInfoHandle>& windowHandle,
- DeviceId deviceId, const PointerProperties& pointer);
+ DeviceId deviceId, const PointerProperties& pointer, float x,
+ float y);
void removeHoveringPointer(DeviceId deviceId, int32_t pointerId);
void clearHoveringPointers(DeviceId deviceId);
diff --git a/services/inputflinger/dispatcher/TouchedWindow.cpp b/services/inputflinger/dispatcher/TouchedWindow.cpp
index 1f86f66..fa5be1a 100644
--- a/services/inputflinger/dispatcher/TouchedWindow.cpp
+++ b/services/inputflinger/dispatcher/TouchedWindow.cpp
@@ -36,6 +36,13 @@
}) != pointers.end();
}
+bool hasPointerId(const std::vector<TouchedWindow::HoveringPointer>& pointers, int32_t pointerId) {
+ return std::find_if(pointers.begin(), pointers.end(),
+ [&pointerId](const TouchedWindow::HoveringPointer& pointer) {
+ return pointer.properties.id == pointerId;
+ }) != pointers.end();
+}
+
} // namespace
bool TouchedWindow::hasHoveringPointers() const {
@@ -78,16 +85,18 @@
return hasPointerId(state.hoveringPointers, pointerId);
}
-void TouchedWindow::addHoveringPointer(DeviceId deviceId, const PointerProperties& pointer) {
- std::vector<PointerProperties>& hoveringPointers = mDeviceStates[deviceId].hoveringPointers;
+void TouchedWindow::addHoveringPointer(DeviceId deviceId, const PointerProperties& properties,
+ float x, float y) {
+ std::vector<HoveringPointer>& hoveringPointers = mDeviceStates[deviceId].hoveringPointers;
const size_t initialSize = hoveringPointers.size();
- std::erase_if(hoveringPointers, [&pointer](const PointerProperties& properties) {
- return properties.id == pointer.id;
+ std::erase_if(hoveringPointers, [&properties](const HoveringPointer& pointer) {
+ return pointer.properties.id == properties.id;
});
if (hoveringPointers.size() != initialSize) {
- LOG(ERROR) << __func__ << ": " << pointer << ", device " << deviceId << " was in " << *this;
+ LOG(ERROR) << __func__ << ": " << properties << ", device " << deviceId << " was in "
+ << *this;
}
- hoveringPointers.push_back(pointer);
+ hoveringPointers.push_back({properties, x, y});
}
Result<void> TouchedWindow::addTouchingPointers(DeviceId deviceId,
@@ -173,8 +182,8 @@
return true;
}
}
- for (const PointerProperties& properties : state.hoveringPointers) {
- if (properties.toolType == ToolType::STYLUS) {
+ for (const HoveringPointer& pointer : state.hoveringPointers) {
+ if (pointer.properties.toolType == ToolType::STYLUS) {
return true;
}
}
@@ -270,8 +279,8 @@
}
DeviceState& state = stateIt->second;
- std::erase_if(state.hoveringPointers, [&pointerId](const PointerProperties& properties) {
- return properties.id == pointerId;
+ std::erase_if(state.hoveringPointers, [&pointerId](const HoveringPointer& pointer) {
+ return pointer.properties.id == pointerId;
});
if (!state.hasPointers()) {
@@ -279,6 +288,22 @@
}
}
+std::vector<DeviceId> TouchedWindow::eraseHoveringPointersIf(
+ std::function<bool(const PointerProperties&, float /*x*/, float /*y*/)> condition) {
+ std::vector<DeviceId> erasedDevices;
+ for (auto& [deviceId, state] : mDeviceStates) {
+ std::erase_if(state.hoveringPointers, [&](const HoveringPointer& pointer) {
+ if (condition(pointer.properties, pointer.x, pointer.y)) {
+ erasedDevices.push_back(deviceId);
+ return true;
+ }
+ return false;
+ });
+ }
+
+ return erasedDevices;
+}
+
void TouchedWindow::removeAllHoveringPointersForDevice(DeviceId deviceId) {
const auto stateIt = mDeviceStates.find(deviceId);
if (stateIt == mDeviceStates.end()) {
@@ -312,6 +337,11 @@
return out;
}
+std::ostream& operator<<(std::ostream& out, const TouchedWindow::HoveringPointer& pointer) {
+ out << pointer.properties << " at (" << pointer.x << ", " << pointer.y << ")";
+ return out;
+}
+
std::ostream& operator<<(std::ostream& out, const TouchedWindow& window) {
out << window.dump();
return out;
diff --git a/services/inputflinger/dispatcher/TouchedWindow.h b/services/inputflinger/dispatcher/TouchedWindow.h
index 4f0ad16..c38681e 100644
--- a/services/inputflinger/dispatcher/TouchedWindow.h
+++ b/services/inputflinger/dispatcher/TouchedWindow.h
@@ -38,7 +38,7 @@
bool hasHoveringPointers() const;
bool hasHoveringPointers(DeviceId deviceId) const;
bool hasHoveringPointer(DeviceId deviceId, int32_t pointerId) const;
- void addHoveringPointer(DeviceId deviceId, const PointerProperties& pointer);
+ void addHoveringPointer(DeviceId deviceId, const PointerProperties& pointer, float x, float y);
void removeHoveringPointer(DeviceId deviceId, int32_t pointerId);
// Touching
@@ -69,6 +69,15 @@
void clearHoveringPointers(DeviceId deviceId);
std::string dump() const;
+ struct HoveringPointer {
+ PointerProperties properties;
+ float x;
+ float y;
+ };
+
+ std::vector<DeviceId> eraseHoveringPointersIf(
+ std::function<bool(const PointerProperties&, float /*x*/, float /*y*/)> condition);
+
private:
struct DeviceState {
std::vector<PointerProperties> touchingPointers;
@@ -78,7 +87,7 @@
// NOTE: This is not initialized in case of HOVER entry/exit and DISPATCH_AS_OUTSIDE
// scenario.
std::optional<nsecs_t> downTimeInTarget;
- std::vector<PointerProperties> hoveringPointers;
+ std::vector<HoveringPointer> hoveringPointers;
bool hasPointers() const { return !touchingPointers.empty() || !hoveringPointers.empty(); };
};
diff --git a/services/inputflinger/tests/InputDispatcher_test.cpp b/services/inputflinger/tests/InputDispatcher_test.cpp
index f066b03..c5702e9 100644
--- a/services/inputflinger/tests/InputDispatcher_test.cpp
+++ b/services/inputflinger/tests/InputDispatcher_test.cpp
@@ -1913,6 +1913,99 @@
window->consumeMotionEvent(WithMotionAction(ACTION_SCROLL));
}
+/**
+ * Two windows: a trusted overlay and a regular window underneath. Both windows are visible.
+ * Mouse is hovered, and the hover event should only go to the overlay.
+ * However, next, the touchable region of the trusted overlay shrinks. The mouse position hasn't
+ * changed, but the cursor would now end up hovering above the regular window underneatch.
+ * If the mouse is now clicked, this would generate an ACTION_DOWN event, which would go to the
+ * regular window. However, the trusted overlay is also watching for outside touch.
+ * The trusted overlay should get two events:
+ * 1) The ACTION_OUTSIDE event, since the click is now not inside its touchable region
+ * 2) The HOVER_EXIT event, since the mouse pointer is no longer hovering inside this window
+ *
+ * This test reproduces a crash where there is an overlap between dispatch modes for the trusted
+ * overlay touch target, since the event is causing both an ACTION_OUTSIDE, and as a HOVER_EXIT.
+ */
+TEST_F(InputDispatcherTest, MouseClickUnderShrinkingTrustedOverlay) {
+ std::shared_ptr<FakeApplicationHandle> app = std::make_shared<FakeApplicationHandle>();
+ sp<FakeWindowHandle> overlay = sp<FakeWindowHandle>::make(app, mDispatcher, "Trusted overlay",
+ ui::LogicalDisplayId::DEFAULT);
+ overlay->setTrustedOverlay(true);
+ overlay->setWatchOutsideTouch(true);
+ overlay->setFrame(Rect(0, 0, 200, 200));
+
+ sp<FakeWindowHandle> window = sp<FakeWindowHandle>::make(app, mDispatcher, "Regular window",
+ ui::LogicalDisplayId::DEFAULT);
+ window->setFrame(Rect(0, 0, 200, 200));
+
+ mDispatcher->onWindowInfosChanged({{*overlay->getInfo(), *window->getInfo()}, {}, 0, 0});
+ // Hover the mouse into the overlay
+ mDispatcher->notifyMotion(MotionArgsBuilder(ACTION_HOVER_MOVE, AINPUT_SOURCE_MOUSE)
+ .pointer(PointerBuilder(0, ToolType::MOUSE).x(100).y(110))
+ .build());
+ overlay->consumeMotionEvent(WithMotionAction(ACTION_HOVER_ENTER));
+
+ // Now, shrink the touchable region of the overlay! This will cause the cursor to suddenly have
+ // the regular window as the touch target
+ overlay->setTouchableRegion(Region({0, 0, 0, 0}));
+ mDispatcher->onWindowInfosChanged({{*overlay->getInfo(), *window->getInfo()}, {}, 0, 0});
+
+ // Now we can click with the mouse. The click should go into the regular window
+ mDispatcher->notifyMotion(MotionArgsBuilder(ACTION_DOWN, AINPUT_SOURCE_MOUSE)
+ .pointer(PointerBuilder(0, ToolType::MOUSE).x(100).y(110))
+ .build());
+ overlay->consumeMotionEvent(WithMotionAction(ACTION_HOVER_EXIT));
+ overlay->consumeMotionEvent(WithMotionAction(ACTION_OUTSIDE));
+ window->consumeMotionEvent(WithMotionAction(ACTION_DOWN));
+}
+
+/**
+ * Similar to above, but also has a spy on top that also catches the HOVER
+ * events. Also, instead of ACTION_DOWN, we are continuing to send the hovering
+ * stream to ensure that the spy receives hover events correctly.
+ */
+TEST_F(InputDispatcherTest, MouseClickUnderShrinkingTrustedOverlayWithSpy) {
+ std::shared_ptr<FakeApplicationHandle> app = std::make_shared<FakeApplicationHandle>();
+ sp<FakeWindowHandle> spyWindow =
+ sp<FakeWindowHandle>::make(app, mDispatcher, "Spy", ui::LogicalDisplayId::DEFAULT);
+ spyWindow->setFrame(Rect(0, 0, 200, 200));
+ spyWindow->setTrustedOverlay(true);
+ spyWindow->setSpy(true);
+ sp<FakeWindowHandle> overlay = sp<FakeWindowHandle>::make(app, mDispatcher, "Trusted overlay",
+ ui::LogicalDisplayId::DEFAULT);
+ overlay->setTrustedOverlay(true);
+ overlay->setWatchOutsideTouch(true);
+ overlay->setFrame(Rect(0, 0, 200, 200));
+
+ sp<FakeWindowHandle> window = sp<FakeWindowHandle>::make(app, mDispatcher, "Regular window",
+ ui::LogicalDisplayId::DEFAULT);
+ window->setFrame(Rect(0, 0, 200, 200));
+
+ mDispatcher->onWindowInfosChanged(
+ {{*spyWindow->getInfo(), *overlay->getInfo(), *window->getInfo()}, {}, 0, 0});
+ // Hover the mouse into the overlay
+ mDispatcher->notifyMotion(MotionArgsBuilder(ACTION_HOVER_MOVE, AINPUT_SOURCE_MOUSE)
+ .pointer(PointerBuilder(0, ToolType::MOUSE).x(100).y(110))
+ .build());
+ spyWindow->consumeMotionEvent(WithMotionAction(ACTION_HOVER_ENTER));
+ overlay->consumeMotionEvent(WithMotionAction(ACTION_HOVER_ENTER));
+
+ // Now, shrink the touchable region of the overlay! This will cause the cursor to suddenly have
+ // the regular window as the touch target
+ overlay->setTouchableRegion(Region({0, 0, 0, 0}));
+ mDispatcher->onWindowInfosChanged(
+ {{*spyWindow->getInfo(), *overlay->getInfo(), *window->getInfo()}, {}, 0, 0});
+
+ // Now we can click with the mouse. The click should go into the regular window
+ mDispatcher->notifyMotion(MotionArgsBuilder(ACTION_HOVER_MOVE, AINPUT_SOURCE_MOUSE)
+ .pointer(PointerBuilder(0, ToolType::MOUSE).x(110).y(110))
+ .build());
+ spyWindow->consumeMotionEvent(WithMotionAction(ACTION_HOVER_MOVE));
+ overlay->consumeMotionEvent(WithMotionAction(ACTION_HOVER_EXIT));
+ window->consumeMotionEvent(WithMotionAction(ACTION_HOVER_ENTER));
+}
+
using InputDispatcherMultiDeviceTest = InputDispatcherTest;
/**
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index c17ea3b..dcb0812 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -355,26 +355,6 @@
// transaction
// ----------------------------------------------------------------------------
-uint32_t Layer::doTransaction(uint32_t flags) {
- SFTRACE_CALL();
-
- const State& s(getDrawingState());
-
- if (s.sequence != mLastCommittedTxSequence) {
- // invalidate and recompute the visible regions if needed
- mLastCommittedTxSequence = s.sequence;
- flags |= eVisibleRegion;
- }
-
- if (!mPotentialCursor && (flags & Layer::eVisibleRegion)) {
- mFlinger->mUpdateInputInfo = true;
- }
-
- commitTransaction();
-
- return flags;
-}
-
void Layer::commitTransaction() {
// Set the present state for all bufferlessSurfaceFramesTX to Presented. The
// bufferSurfaceFrameTX will be presented in latchBuffer.
@@ -389,12 +369,6 @@
mDrawingState.bufferlessSurfaceFramesTX.clear();
}
-uint32_t Layer::clearTransactionFlags(uint32_t mask) {
- const auto flags = mTransactionFlags & mask;
- mTransactionFlags &= ~mask;
- return flags;
-}
-
void Layer::setTransactionFlags(uint32_t mask) {
mTransactionFlags |= mask;
}
@@ -769,10 +743,6 @@
// Older fences for the same layer stack can be dropped when a new fence arrives.
// An assumption here is that RenderEngine performs work sequentially, so an
// incoming fence will not fire before an existing fence.
- SFTRACE_NAME(
- ftl::Concat("Adding additional fence for: ", ftl::truncated<20>(mName.c_str()),
- ", Replacing?: ", mAdditionalPreviousReleaseFences.contains(layerStack))
- .c_str());
mAdditionalPreviousReleaseFences.emplace_or_replace(layerStack,
std::move(futureFenceResult));
}
@@ -871,16 +841,6 @@
return true;
}
-bool Layer::setBufferCrop(const Rect& bufferCrop) {
- if (mDrawingState.bufferCrop == bufferCrop) return false;
-
- mDrawingState.sequence++;
- mDrawingState.bufferCrop = bufferCrop;
-
- setTransactionFlags(eTransactionNeeded);
- return true;
-}
-
void Layer::releasePreviousBuffer() {
mReleasePreviousBuffer = true;
if (!mBufferInfo.mBuffer ||
@@ -1495,10 +1455,6 @@
mBufferInfo.mFrameLatencyNeeded = false;
}
-bool Layer::willReleaseBufferOnLatch() const {
- return !mDrawingState.buffer && mBufferInfo.mBuffer;
-}
-
bool Layer::latchBufferImpl(bool& recomputeVisibleRegions, nsecs_t latchTime, bool bgColorOnly) {
SFTRACE_FORMAT_INSTANT("latchBuffer %s - %" PRIu64, getDebugName(),
getDrawingState().frameNumber);
@@ -1559,34 +1515,10 @@
return true;
}
-bool Layer::isProtected() const {
- return (mBufferInfo.mBuffer != nullptr) &&
- (mBufferInfo.mBuffer->getUsage() & GRALLOC_USAGE_PROTECTED);
-}
-
bool Layer::getTransformToDisplayInverse() const {
return mBufferInfo.mTransformToDisplayInverse;
}
-Rect Layer::getBufferCrop() const {
- // this is the crop rectangle that applies to the buffer
- // itself (as opposed to the window)
- if (!mBufferInfo.mCrop.isEmpty()) {
- // if the buffer crop is defined, we use that
- return mBufferInfo.mCrop;
- } else if (mBufferInfo.mBuffer != nullptr) {
- // otherwise we use the whole buffer
- return mBufferInfo.mBuffer->getBounds();
- } else {
- // if we don't have a buffer yet, we use an empty/invalid crop
- return Rect();
- }
-}
-
-uint32_t Layer::getBufferTransform() const {
- return mBufferInfo.mTransform;
-}
-
ui::Dataspace Layer::translateDataspace(ui::Dataspace dataspace) {
ui::Dataspace updatedDataspace = dataspace;
// translate legacy dataspaces to modern dataspaces
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 9caa20c..9bc557e 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -88,12 +88,6 @@
// Windows that are not in focus, but voted for a specific mode ID.
static constexpr int32_t PRIORITY_NOT_FOCUSED_WITH_MODE = 2;
- enum { // flags for doTransaction()
- eDontUpdateGeometryState = 0x00000001,
- eVisibleRegion = 0x00000002,
- eInputInfoChanged = 0x00000004
- };
-
using FrameRate = scheduler::LayerInfo::FrameRate;
using FrameRateCompatibility = scheduler::FrameRateCompatibility;
using FrameRateSelectionStrategy = scheduler::LayerInfo::FrameRateSelectionStrategy;
@@ -171,9 +165,6 @@
static bool isLayerFocusedBasedOnPriority(int32_t priority);
static void miniDumpHeader(std::string& result);
- // Provide unique string for each class type in the Layer hierarchy
- const char* getType() const { return "Layer"; }
-
// This second set of geometry attributes are controlled by
// setGeometryAppliesWithResize, and their default mode is to be
// immediate. If setGeometryAppliesWithResize is specified
@@ -200,7 +191,6 @@
bool willPresent);
sp<LayerFE> getCompositionEngineLayerFE(const frontend::LayerHierarchy::TraversalPath&);
- sp<LayerFE> getOrCreateCompositionEngineLayerFE(const frontend::LayerHierarchy::TraversalPath&);
// If we have received a new buffer this frame, we will pass its surface
// damage down to hardware composer. Otherwise, we must send a region with
@@ -208,18 +198,7 @@
Region getVisibleRegion(const DisplayDevice*) const;
void updateLastLatchTime(nsecs_t latchtime);
- /*
- * isProtected - true if the layer may contain protected contents in the
- * GRALLOC_USAGE_PROTECTED sense.
- */
- bool isProtected() const;
- /*
- * usesSourceCrop - true if content should use a source crop
- */
- bool usesSourceCrop() const { return hasBufferOrSidebandStream(); }
-
Rect getCrop(const Layer::State& s) const { return s.crop; }
- bool needsFiltering(const DisplayDevice*) const;
// from graphics API
static ui::Dataspace translateDataspace(ui::Dataspace dataspace);
@@ -242,23 +221,6 @@
bool latchBufferImpl(bool& /*recomputeVisibleRegions*/, nsecs_t /*latchTime*/,
bool bgColorOnly);
- /*
- * Returns true if the currently presented buffer will be released when this layer state
- * is latched. This will return false if there is no buffer currently presented.
- */
- bool willReleaseBufferOnLatch() const;
-
- /*
- * returns the rectangle that crops the content of the layer and scales it
- * to the layer's size.
- */
- Rect getBufferCrop() const;
-
- /*
- * Returns the transform applied to the buffer.
- */
- uint32_t getBufferTransform() const;
-
sp<GraphicBuffer> getBuffer() const;
/**
* Returns active buffer size in the correct orientation. Buffer size is determined by undoing
@@ -313,8 +275,6 @@
const char* getDebugName() const;
- uint32_t getTransactionFlags() const { return mTransactionFlags; }
-
static bool computeTrustedPresentationState(const FloatRect& bounds,
const FloatRect& sourceBounds,
const Region& coveredRegion,
@@ -332,9 +292,6 @@
// Sets the masked bits.
void setTransactionFlags(uint32_t mask);
- // Clears and returns the masked bits.
- uint32_t clearTransactionFlags(uint32_t mask);
-
int32_t getSequence() const { return sequence; }
// For tracing.
@@ -348,14 +305,6 @@
void writeCompositionStateToProto(perfetto::protos::LayerProto* layerProto,
ui::LayerStack layerStack);
- gui::WindowInfo::Type getWindowType() const { return mWindowType; }
-
- /*
- * doTransaction - process the transaction. This is a good place to figure
- * out which attributes of the surface have changed.
- */
- uint32_t doTransaction(uint32_t transactionFlags);
-
inline const State& getDrawingState() const { return mDrawingState; }
inline State& getDrawingState() { return mDrawingState; }
@@ -366,13 +315,6 @@
void getFrameStats(FrameStats* outStats) const;
void onDisconnect();
- ui::Transform getTransform() const;
-
- half4 getColor() const;
- int32_t getBackgroundBlurRadius() const;
- bool drawShadows() const { return mEffectiveShadowRadius > 0.f; };
-
- bool isHandleAlive() const { return mHandleAlive; }
bool onHandleDestroyed() { return mHandleAlive = false; }
/**
@@ -383,7 +325,6 @@
*/
Rect getCroppedBufferSize(const Layer::State& s) const;
- void setFrameTimelineInfoForBuffer(const FrameTimelineInfo& /*info*/) {}
void setFrameTimelineVsyncForBufferTransaction(const FrameTimelineInfo& info, nsecs_t postTime,
gui::GameMode gameMode);
void setFrameTimelineVsyncForBufferlessTransaction(const FrameTimelineInfo& info,
@@ -412,14 +353,9 @@
// this to be called once.
sp<IBinder> getHandle();
const std::string& getName() const { return mName; }
- void setInputInfo(const gui::WindowInfo& info);
virtual uid_t getOwnerUid() const { return mOwnerUid; }
- pid_t getOwnerPid() { return mOwnerPid; }
-
- int32_t getOwnerAppId() { return mOwnerAppId; }
-
// Used to check if mUsedVsyncIdForRefreshRateSelection should be expired when it stop updating.
nsecs_t mMaxTimeForUseVsyncId = 0;
// True when DrawState.useVsyncIdForRefreshRateSelection previously set to true during updating
@@ -431,9 +367,6 @@
// the same.
const int32_t sequence;
- bool mPendingHWCDestroy{false};
-
- bool setBufferCrop(const Rect& /* bufferCrop */);
// See mPendingBufferTransactions
void decrementPendingBufferCount();
std::atomic<int32_t>* getPendingBufferCounter() { return &mPendingBufferTransactions; }
@@ -513,10 +446,6 @@
int64_t mEnteredTrustedPresentationStateTime = -1;
uint32_t mTransactionFlags{0};
- // Updated in doTransaction, used to track the last sequence number we
- // committed. Currently this is really only used for updating visible
- // regions.
- int32_t mLastCommittedTxSequence = -1;
// Timestamp history for UIAutomation. Thread safe.
FrameTracker mFrameTracker;
@@ -632,7 +561,7 @@
// You can understand the trace this way:
// - If the integer increases, a buffer arrived at the server.
// - If the integer decreases in latchBuffer, that buffer was latched
- // - If the integer decreases in setBuffer or doTransaction, a buffer was dropped
+ // - If the integer decreases in setBuffer, a buffer was dropped
std::atomic<int32_t> mPendingBufferTransactions{0};
// Contains requested position and matrix updates. This will be applied if the client does
diff --git a/services/surfaceflinger/TransactionCallbackInvoker.cpp b/services/surfaceflinger/TransactionCallbackInvoker.cpp
index 2b20648..c6856ae 100644
--- a/services/surfaceflinger/TransactionCallbackInvoker.cpp
+++ b/services/surfaceflinger/TransactionCallbackInvoker.cpp
@@ -30,7 +30,6 @@
#include <binder/IInterface.h>
#include <common/FlagManager.h>
#include <common/trace.h>
-#include <ftl/concat.h>
#include <utils/RefBase.h>
namespace android {
@@ -130,9 +129,6 @@
if (FlagManager::getInstance().ce_fence_promise()) {
for (auto& future : handle->previousReleaseFences) {
- SFTRACE_NAME(ftl::Concat("Merging fence for layer: ",
- ftl::truncated<20>(handle->name.c_str()))
- .c_str());
mergeFence(handle->name.c_str(), future.get().value_or(Fence::NO_FENCE), prevFence);
}
} else {