Merge "SF: Configure input windows with the first input-enabled display"
diff --git a/libs/gui/DisplayEventDispatcher.cpp b/libs/gui/DisplayEventDispatcher.cpp
index 26db59b..39d380d 100644
--- a/libs/gui/DisplayEventDispatcher.cpp
+++ b/libs/gui/DisplayEventDispatcher.cpp
@@ -126,7 +126,7 @@
ALOGV("dispatcher %p ~ Vsync pulse: timestamp=%" PRId64
", displayId=%s, count=%d, vsyncId=%" PRId64,
this, ns2ms(vsyncTimestamp), to_string(vsyncDisplayId).c_str(), vsyncCount,
- vsyncEventData.id);
+ vsyncEventData.preferredVsyncId());
mWaitingForVsync = false;
mLastVsyncCount = vsyncCount;
dispatchVsync(vsyncTimestamp, vsyncDisplayId, vsyncCount, vsyncEventData);
@@ -146,18 +146,6 @@
return 1; // keep the callback
}
-void DisplayEventDispatcher::populateFrameTimelines(const DisplayEventReceiver::Event& event,
- VsyncEventData* outVsyncEventData) const {
- for (size_t i = 0; i < VsyncEventData::kFrameTimelinesLength; i++) {
- DisplayEventReceiver::Event::VSync::FrameTimeline receiverTimeline =
- event.vsync.frameTimelines[i];
- outVsyncEventData->frameTimelines[i] =
- VsyncEventData::FrameTimeline(receiverTimeline.vsyncId,
- receiverTimeline.deadlineTimestamp,
- receiverTimeline.expectedVSyncTimestamp);
- }
-}
-
bool DisplayEventDispatcher::processPendingEvents(nsecs_t* outTimestamp,
PhysicalDisplayId* outDisplayId,
uint32_t* outCount,
@@ -178,12 +166,7 @@
*outTimestamp = ev.header.timestamp;
*outDisplayId = ev.header.displayId;
*outCount = ev.vsync.count;
- outVsyncEventData->id = ev.vsync.vsyncId;
- outVsyncEventData->deadlineTimestamp = ev.vsync.deadlineTimestamp;
- outVsyncEventData->frameInterval = ev.vsync.frameInterval;
- outVsyncEventData->preferredFrameTimelineIndex =
- ev.vsync.preferredFrameTimelineIndex;
- populateFrameTimelines(ev, outVsyncEventData);
+ *outVsyncEventData = ev.vsync.vsyncData;
break;
case DisplayEventReceiver::DISPLAY_EVENT_HOTPLUG:
dispatchHotplug(ev.header.timestamp, ev.header.displayId, ev.hotplug.connected);
diff --git a/libs/gui/DisplayEventReceiver.cpp b/libs/gui/DisplayEventReceiver.cpp
index bb659bf..bfb7769 100644
--- a/libs/gui/DisplayEventReceiver.cpp
+++ b/libs/gui/DisplayEventReceiver.cpp
@@ -85,15 +85,14 @@
return mInitError.has_value() ? mInitError.value() : NO_INIT;
}
-status_t DisplayEventReceiver::getLatestVsyncEventData(VsyncEventData* outVsyncEventData) const {
+status_t DisplayEventReceiver::getLatestVsyncEventData(
+ ParcelableVsyncEventData* outVsyncEventData) const {
if (mEventConnection != nullptr) {
- VsyncEventData vsyncEventData;
- auto status = mEventConnection->getLatestVsyncEventData(&vsyncEventData);
+ auto status = mEventConnection->getLatestVsyncEventData(outVsyncEventData);
if (!status.isOk()) {
ALOGE("Failed to get latest vsync event data: %s", status.exceptionMessage().c_str());
return status.transactionError();
}
- *outVsyncEventData = vsyncEventData;
return NO_ERROR;
}
return NO_INIT;
diff --git a/libs/gui/VsyncEventData.cpp b/libs/gui/VsyncEventData.cpp
index aad81d0..23f0921 100644
--- a/libs/gui/VsyncEventData.cpp
+++ b/libs/gui/VsyncEventData.cpp
@@ -23,52 +23,46 @@
namespace android::gui {
-status_t VsyncEventData::readFromParcel(const Parcel* parcel) {
+int64_t VsyncEventData::preferredVsyncId() const {
+ return frameTimelines[preferredFrameTimelineIndex].vsyncId;
+}
+
+int64_t VsyncEventData::preferredDeadlineTimestamp() const {
+ return frameTimelines[preferredFrameTimelineIndex].deadlineTimestamp;
+}
+
+int64_t VsyncEventData::preferredExpectedPresentationTime() const {
+ return frameTimelines[preferredFrameTimelineIndex].expectedPresentationTime;
+}
+
+status_t ParcelableVsyncEventData::readFromParcel(const Parcel* parcel) {
if (parcel == nullptr) {
ALOGE("%s: Null parcel", __func__);
return BAD_VALUE;
}
- SAFE_PARCEL(parcel->readInt64, &id)
- SAFE_PARCEL(parcel->readInt64, &deadlineTimestamp);
- SAFE_PARCEL(parcel->readInt64, &frameInterval);
+ SAFE_PARCEL(parcel->readInt64, &vsync.frameInterval);
uint64_t uintPreferredFrameTimelineIndex;
SAFE_PARCEL(parcel->readUint64, &uintPreferredFrameTimelineIndex);
- preferredFrameTimelineIndex = static_cast<size_t>(uintPreferredFrameTimelineIndex);
+ vsync.preferredFrameTimelineIndex = static_cast<size_t>(uintPreferredFrameTimelineIndex);
- std::vector<FrameTimeline> timelines;
- SAFE_PARCEL(parcel->readParcelableVector, &timelines);
- std::copy_n(timelines.begin(), timelines.size(), frameTimelines.begin());
-
- return OK;
-}
-status_t VsyncEventData::writeToParcel(Parcel* parcel) const {
- SAFE_PARCEL(parcel->writeInt64, id)
- SAFE_PARCEL(parcel->writeInt64, deadlineTimestamp);
- SAFE_PARCEL(parcel->writeInt64, frameInterval);
- SAFE_PARCEL(parcel->writeUint64, preferredFrameTimelineIndex);
- SAFE_PARCEL(parcel->writeParcelableVector,
- std::vector(frameTimelines.begin(), frameTimelines.end()));
-
- return OK;
-}
-status_t VsyncEventData::FrameTimeline::readFromParcel(const Parcel* parcel) {
- if (parcel == nullptr) {
- ALOGE("%s: Null parcel", __func__);
- return BAD_VALUE;
+ for (int i = 0; i < VsyncEventData::kFrameTimelinesLength; i++) {
+ SAFE_PARCEL(parcel->readInt64, &vsync.frameTimelines[i].vsyncId);
+ SAFE_PARCEL(parcel->readInt64, &vsync.frameTimelines[i].deadlineTimestamp);
+ SAFE_PARCEL(parcel->readInt64, &vsync.frameTimelines[i].expectedPresentationTime);
}
- SAFE_PARCEL(parcel->readInt64, &id)
- SAFE_PARCEL(parcel->readInt64, &deadlineTimestamp);
- SAFE_PARCEL(parcel->readInt64, &expectedPresentTime);
-
return OK;
}
-status_t VsyncEventData::FrameTimeline::writeToParcel(Parcel* parcel) const {
- SAFE_PARCEL(parcel->writeInt64, id);
- SAFE_PARCEL(parcel->writeInt64, deadlineTimestamp);
- SAFE_PARCEL(parcel->writeInt64, expectedPresentTime);
+status_t ParcelableVsyncEventData::writeToParcel(Parcel* parcel) const {
+ SAFE_PARCEL(parcel->writeInt64, vsync.frameInterval);
+ SAFE_PARCEL(parcel->writeUint64, vsync.preferredFrameTimelineIndex);
+ for (int i = 0; i < VsyncEventData::kFrameTimelinesLength; i++) {
+ SAFE_PARCEL(parcel->writeInt64, vsync.frameTimelines[i].vsyncId);
+ SAFE_PARCEL(parcel->writeInt64, vsync.frameTimelines[i].deadlineTimestamp);
+ SAFE_PARCEL(parcel->writeInt64, vsync.frameTimelines[i].expectedPresentationTime);
+ }
return OK;
}
diff --git a/libs/gui/WindowInfo.cpp b/libs/gui/WindowInfo.cpp
index a866786..80bd638 100644
--- a/libs/gui/WindowInfo.cpp
+++ b/libs/gui/WindowInfo.cpp
@@ -18,7 +18,6 @@
#define LOG_TAG "WindowInfo"
#define LOG_NDEBUG 0
-#include <android-base/stringprintf.h>
#include <binder/Parcel.h>
#include <gui/WindowInfo.h>
@@ -27,6 +26,14 @@
namespace android::gui {
// --- WindowInfo ---
+void WindowInfo::setInputConfig(Flags<InputConfig> config, bool value) {
+ if (value) {
+ inputConfig |= config;
+ return;
+ }
+ inputConfig &= ~config;
+}
+
void WindowInfo::addTouchableRegion(const Rect& region) {
touchableRegion.orSelf(region);
}
@@ -40,7 +47,7 @@
}
bool WindowInfo::supportsSplitTouch() const {
- return flags.test(Flag::SPLIT_TOUCH);
+ return !inputConfig.test(InputConfig::PREVENT_SPLITTING);
}
bool WindowInfo::isSpy() const {
@@ -58,20 +65,19 @@
}
bool WindowInfo::operator==(const WindowInfo& info) const {
- return info.token == token && info.id == id && info.name == name && info.flags == flags &&
- info.type == type && info.dispatchingTimeout == dispatchingTimeout &&
- info.frameLeft == frameLeft && info.frameTop == frameTop &&
- info.frameRight == frameRight && info.frameBottom == frameBottom &&
- info.surfaceInset == surfaceInset && info.globalScaleFactor == globalScaleFactor &&
- info.transform == transform && info.touchableRegion.hasSameRects(touchableRegion) &&
- info.visible == visible && info.trustedOverlay == trustedOverlay &&
- info.focusable == focusable && info.touchOcclusionMode == touchOcclusionMode &&
- info.hasWallpaper == hasWallpaper && info.paused == paused &&
- info.ownerPid == ownerPid && info.ownerUid == ownerUid &&
- info.packageName == packageName && info.inputFeatures == inputFeatures &&
+ return info.token == token && info.id == id && info.name == name &&
+ info.dispatchingTimeout == dispatchingTimeout && info.frameLeft == frameLeft &&
+ info.frameTop == frameTop && info.frameRight == frameRight &&
+ info.frameBottom == frameBottom && info.surfaceInset == surfaceInset &&
+ info.globalScaleFactor == globalScaleFactor && info.transform == transform &&
+ info.touchableRegion.hasSameRects(touchableRegion) &&
+ info.touchOcclusionMode == touchOcclusionMode && info.ownerPid == ownerPid &&
+ info.ownerUid == ownerUid && info.packageName == packageName &&
+ info.inputFeatures == inputFeatures && info.inputConfig == inputConfig &&
info.displayId == displayId &&
info.replaceTouchableRegionWithCrop == replaceTouchableRegionWithCrop &&
- info.applicationInfo == applicationInfo;
+ info.applicationInfo == applicationInfo && info.layoutParamsType == layoutParamsType &&
+ info.layoutParamsFlags == layoutParamsFlags;
}
status_t WindowInfo::writeToParcel(android::Parcel* parcel) const {
@@ -85,13 +91,18 @@
}
parcel->writeInt32(1);
+ // Ensure that the size of the flags that we use is 32 bits for writing into the parcel.
+ static_assert(sizeof(inputFeatures) == 4u);
+ static_assert(sizeof(inputConfig) == 4u);
+
// clang-format off
status_t status = parcel->writeStrongBinder(token) ?:
parcel->writeInt64(dispatchingTimeout.count()) ?:
parcel->writeInt32(id) ?:
parcel->writeUtf8AsUtf16(name) ?:
- parcel->writeInt32(flags.get()) ?:
- parcel->writeInt32(static_cast<std::underlying_type_t<WindowInfo::Type>>(type)) ?:
+ parcel->writeInt32(layoutParamsFlags.get()) ?:
+ parcel->writeInt32(
+ static_cast<std::underlying_type_t<WindowInfo::Type>>(layoutParamsType)) ?:
parcel->writeInt32(frameLeft) ?:
parcel->writeInt32(frameTop) ?:
parcel->writeInt32(frameRight) ?:
@@ -105,16 +116,12 @@
parcel->writeFloat(transform.dtdy()) ?:
parcel->writeFloat(transform.dsdy()) ?:
parcel->writeFloat(transform.ty()) ?:
- parcel->writeBool(visible) ?:
- parcel->writeBool(focusable) ?:
- parcel->writeBool(hasWallpaper) ?:
- parcel->writeBool(paused) ?:
- parcel->writeBool(trustedOverlay) ?:
parcel->writeInt32(static_cast<int32_t>(touchOcclusionMode)) ?:
parcel->writeInt32(ownerPid) ?:
parcel->writeInt32(ownerUid) ?:
parcel->writeUtf8AsUtf16(packageName) ?:
parcel->writeInt32(inputFeatures.get()) ?:
+ parcel->writeInt32(inputConfig.get()) ?:
parcel->writeInt32(displayId) ?:
applicationInfo.writeToParcel(parcel) ?:
parcel->write(touchableRegion) ?:
@@ -141,8 +148,8 @@
return status;
}
- flags = Flags<Flag>(parcel->readInt32());
- type = static_cast<Type>(parcel->readInt32());
+ layoutParamsFlags = Flags<Flag>(parcel->readInt32());
+ layoutParamsType = static_cast<Type>(parcel->readInt32());
float dsdx, dtdx, tx, dtdy, dsdy, ty;
int32_t touchOcclusionModeInt;
// clang-format off
@@ -159,11 +166,6 @@
parcel->readFloat(&dtdy) ?:
parcel->readFloat(&dsdy) ?:
parcel->readFloat(&ty) ?:
- parcel->readBool(&visible) ?:
- parcel->readBool(&focusable) ?:
- parcel->readBool(&hasWallpaper) ?:
- parcel->readBool(&paused) ?:
- parcel->readBool(&trustedOverlay) ?:
parcel->readInt32(&touchOcclusionModeInt) ?:
parcel->readInt32(&ownerPid) ?:
parcel->readInt32(&ownerUid) ?:
@@ -177,6 +179,7 @@
touchOcclusionMode = static_cast<TouchOcclusionMode>(touchOcclusionModeInt);
inputFeatures = Flags<Feature>(parcel->readInt32());
+ inputConfig = Flags<InputConfig>(parcel->readInt32());
// clang-format off
status = parcel->readInt32(&displayId) ?:
applicationInfo.readFromParcel(parcel) ?:
diff --git a/libs/gui/aidl/android/gui/IDisplayEventConnection.aidl b/libs/gui/aidl/android/gui/IDisplayEventConnection.aidl
index e9a6a0c..9781ca9 100644
--- a/libs/gui/aidl/android/gui/IDisplayEventConnection.aidl
+++ b/libs/gui/aidl/android/gui/IDisplayEventConnection.aidl
@@ -17,7 +17,7 @@
package android.gui;
import android.gui.BitTube;
-import android.gui.VsyncEventData;
+import android.gui.ParcelableVsyncEventData;
/** @hide */
interface IDisplayEventConnection {
@@ -43,5 +43,5 @@
/*
* getLatestVsyncEventData() gets the latest vsync event data.
*/
- VsyncEventData getLatestVsyncEventData();
+ ParcelableVsyncEventData getLatestVsyncEventData();
}
diff --git a/libs/gui/aidl/android/gui/VsyncEventData.aidl b/libs/gui/aidl/android/gui/ParcelableVsyncEventData.aidl
similarity index 89%
rename from libs/gui/aidl/android/gui/VsyncEventData.aidl
rename to libs/gui/aidl/android/gui/ParcelableVsyncEventData.aidl
index 7343515..ba76671 100644
--- a/libs/gui/aidl/android/gui/VsyncEventData.aidl
+++ b/libs/gui/aidl/android/gui/ParcelableVsyncEventData.aidl
@@ -16,4 +16,4 @@
package android.gui;
-parcelable VsyncEventData cpp_header "gui/VsyncEventData.h";
+parcelable ParcelableVsyncEventData cpp_header "gui/VsyncEventData.h";
diff --git a/libs/gui/include/gui/DisplayEventReceiver.h b/libs/gui/include/gui/DisplayEventReceiver.h
index e752062..cf7a4e5 100644
--- a/libs/gui/include/gui/DisplayEventReceiver.h
+++ b/libs/gui/include/gui/DisplayEventReceiver.h
@@ -35,6 +35,7 @@
// ----------------------------------------------------------------------------
using gui::IDisplayEventConnection;
+using gui::ParcelableVsyncEventData;
using gui::VsyncEventData;
namespace gui {
@@ -76,16 +77,7 @@
struct VSync {
uint32_t count;
- nsecs_t expectedVSyncTimestamp __attribute__((aligned(8)));
- nsecs_t deadlineTimestamp __attribute__((aligned(8)));
- nsecs_t frameInterval __attribute__((aligned(8)));
- int64_t vsyncId;
- size_t preferredFrameTimelineIndex __attribute__((aligned(8)));
- struct FrameTimeline {
- nsecs_t expectedVSyncTimestamp __attribute__((aligned(8)));
- nsecs_t deadlineTimestamp __attribute__((aligned(8)));
- int64_t vsyncId;
- } frameTimelines[VsyncEventData::kFrameTimelinesLength];
+ VsyncEventData vsyncData;
};
struct Hotplug {
@@ -175,7 +167,7 @@
/**
* getLatestVsyncEventData() gets the latest vsync event data.
*/
- status_t getLatestVsyncEventData(VsyncEventData* outVsyncEventData) const;
+ status_t getLatestVsyncEventData(ParcelableVsyncEventData* outVsyncEventData) const;
private:
sp<IDisplayEventConnection> mEventConnection;
diff --git a/libs/gui/include/gui/VsyncEventData.h b/libs/gui/include/gui/VsyncEventData.h
index abac61c..8e99539 100644
--- a/libs/gui/include/gui/VsyncEventData.h
+++ b/libs/gui/include/gui/VsyncEventData.h
@@ -21,52 +21,44 @@
#include <array>
namespace android::gui {
-struct VsyncEventData : public Parcelable {
+// Plain Old Data (POD) vsync data structure. For example, it can be easily used in the
+// DisplayEventReceiver::Event union.
+struct VsyncEventData {
// Max amount of frame timelines is arbitrarily set to be reasonable.
static constexpr int64_t kFrameTimelinesLength = 7;
- // The Vsync Id corresponsing to this vsync event. This will be used to
- // populate ISurfaceComposer::setFrameTimelineVsync and
- // SurfaceComposerClient::setFrameTimelineVsync
- // TODO(b/198191703): Remove when JNI DisplayEventReceiver uses frameTimelines array.
- int64_t id = FrameTimelineInfo::INVALID_VSYNC_ID;
-
- // The deadline in CLOCK_MONOTONIC that the app needs to complete its
- // frame by (both on the CPU and the GPU)
- // TODO(b/198191703): Remove when JNI DisplayEventReceiver uses frameTimelines array.
- int64_t deadlineTimestamp = std::numeric_limits<int64_t>::max();
-
// The current frame interval in ns when this frame was scheduled.
- int64_t frameInterval = 0;
+ int64_t frameInterval;
- struct FrameTimeline : public Parcelable {
- FrameTimeline() = default;
- FrameTimeline(int64_t id, int64_t deadlineTimestamp, int64_t expectedPresentTime)
- : id(id),
- deadlineTimestamp(deadlineTimestamp),
- expectedPresentTime(expectedPresentTime) {}
+ // Index into the frameTimelines that represents the platform's preferred frame timeline.
+ uint32_t preferredFrameTimelineIndex;
+ struct alignas(8) FrameTimeline {
// The Vsync Id corresponsing to this vsync event. This will be used to
// populate ISurfaceComposer::setFrameTimelineVsync and
// SurfaceComposerClient::setFrameTimelineVsync
- int64_t id = FrameTimelineInfo::INVALID_VSYNC_ID;
+ int64_t vsyncId;
- // The deadline in CLOCK_MONOTONIC that the app needs to complete its
- // frame by (both on the CPU and the GPU)
- int64_t deadlineTimestamp = std::numeric_limits<int64_t>::max();
+ // The deadline in CLOCK_MONOTONIC in nanos that the app needs to complete its
+ // frame by (both on the CPU and the GPU).
+ int64_t deadlineTimestamp;
- // The anticipated Vsync present time.
- int64_t expectedPresentTime = 0;
+ // The anticipated Vsync presentation time in nanos.
+ int64_t expectedPresentationTime;
+ } frameTimelines[kFrameTimelinesLength]; // Sorted possible frame timelines.
- status_t readFromParcel(const Parcel*) override;
- status_t writeToParcel(Parcel*) const override;
- };
+ // Gets the preferred frame timeline's vsync ID.
+ int64_t preferredVsyncId() const;
- // Sorted possible frame timelines.
- std::array<FrameTimeline, kFrameTimelinesLength> frameTimelines;
+ // Gets the preferred frame timeline's deadline timestamp.
+ int64_t preferredDeadlineTimestamp() const;
- // Index into the frameTimelines that represents the platform's preferred frame timeline.
- size_t preferredFrameTimelineIndex = std::numeric_limits<size_t>::max();
+ // Gets the preferred frame timeline's expected vsync timestamp.
+ int64_t preferredExpectedPresentationTime() const;
+};
+
+struct ParcelableVsyncEventData : public Parcelable {
+ VsyncEventData vsync;
status_t readFromParcel(const Parcel*) override;
status_t writeToParcel(Parcel*) const override;
diff --git a/libs/gui/include/gui/WindowInfo.h b/libs/gui/include/gui/WindowInfo.h
index eb64ac9..b9bffaa 100644
--- a/libs/gui/include/gui/WindowInfo.h
+++ b/libs/gui/include/gui/WindowInfo.h
@@ -151,6 +151,33 @@
// clang-format on
};
+ // Flags used to determine configuration of this input window.
+ // Input windows can be configured with two sets of flags: InputFeature (WindowInfo::Feature
+ // defined above), and InputConfig. When adding a new configuration for an input window:
+ // - If you are adding a new flag that's visible and accessible to apps, it should be added
+ // as an InputFeature.
+ // - If you are adding an internal behaviour that is used within the system or shell and is
+ // not exposed to apps, it should be added as an InputConfig.
+ enum class InputConfig : uint32_t {
+ // clang-format off
+ NONE = 0,
+ NOT_VISIBLE = 1 << 0,
+ NOT_FOCUSABLE = 1 << 1,
+ NOT_TOUCHABLE = 1 << 2,
+ PREVENT_SPLITTING = 1 << 3,
+ DUPLICATE_TOUCH_TO_WALLPAPER = 1 << 4,
+ IS_WALLPAPER = 1 << 5,
+ PAUSE_DISPATCHING = 1 << 6,
+ // This flag is set when the window is of a trusted type that is allowed to silently
+ // overlay other windows for the purpose of implementing the secure views feature.
+ // Trusted overlays, such as IME windows, can partly obscure other windows without causing
+ // motion events to be delivered to them with AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED.
+ TRUSTED_OVERLAY = 1 << 7,
+ WATCH_OUTSIDE_TOUCH = 1 << 8,
+ SLIPPERY = 1 << 9,
+ // clang-format on
+ };
+
/* These values are filled in by the WM and passed through SurfaceFlinger
* unless specified otherwise.
*/
@@ -164,8 +191,6 @@
// This uniquely identifies the input window.
int32_t id = -1;
std::string name;
- Flags<Flag> flags;
- Type type = Type::UNKNOWN;
std::chrono::nanoseconds dispatchingTimeout = std::chrono::seconds(5);
/* These values are filled in by SurfaceFlinger. */
@@ -198,26 +223,24 @@
* to absolute coordinates by SurfaceFlinger once the frame is computed.
*/
Region touchableRegion;
- bool visible = false;
- bool focusable = false;
- bool hasWallpaper = false;
- bool paused = false;
- /* This flag is set when the window is of a trusted type that is allowed to silently
- * overlay other windows for the purpose of implementing the secure views feature.
- * Trusted overlays, such as IME windows, can partly obscure other windows without causing
- * motion events to be delivered to them with AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED.
- */
- bool trustedOverlay = false;
+
TouchOcclusionMode touchOcclusionMode = TouchOcclusionMode::BLOCK_UNTRUSTED;
int32_t ownerPid = -1;
int32_t ownerUid = -1;
std::string packageName;
Flags<Feature> inputFeatures;
+ Flags<InputConfig> inputConfig;
int32_t displayId = ADISPLAY_ID_NONE;
InputApplicationInfo applicationInfo;
bool replaceTouchableRegionWithCrop = false;
wp<IBinder> touchableRegionCropHandle;
+ // The window's layout params flags and type set by WM.
+ Type layoutParamsType = Type::UNKNOWN;
+ Flags<Flag> layoutParamsFlags;
+
+ void setInputConfig(Flags<InputConfig> config, bool value);
+
void addTouchableRegion(const Rect& region);
bool touchableRegionContainsPoint(int32_t x, int32_t y) const;
diff --git a/libs/gui/tests/DisplayEventStructLayout_test.cpp b/libs/gui/tests/DisplayEventStructLayout_test.cpp
index bcd39db..da88463 100644
--- a/libs/gui/tests/DisplayEventStructLayout_test.cpp
+++ b/libs/gui/tests/DisplayEventStructLayout_test.cpp
@@ -20,9 +20,10 @@
namespace android::test {
#define CHECK_OFFSET(type, member, expected_offset) \
- static_assert((offsetof(type, member) == (expected_offset)), "")
+ static_assert((offsetof(type, member) == (expected_offset)))
TEST(DisplayEventStructLayoutTest, TestEventAlignment) {
+ static_assert(std::is_pod<DisplayEventReceiver::Event::VSync>::value);
CHECK_OFFSET(DisplayEventReceiver::Event, vsync, 24);
CHECK_OFFSET(DisplayEventReceiver::Event, hotplug, 24);
CHECK_OFFSET(DisplayEventReceiver::Event, modeChange, 24);
@@ -32,10 +33,29 @@
CHECK_OFFSET(DisplayEventReceiver::Event::Header, timestamp, 16);
CHECK_OFFSET(DisplayEventReceiver::Event::VSync, count, 0);
- CHECK_OFFSET(DisplayEventReceiver::Event::VSync, expectedVSyncTimestamp, 8);
- CHECK_OFFSET(DisplayEventReceiver::Event::VSync, deadlineTimestamp, 16);
- CHECK_OFFSET(DisplayEventReceiver::Event::VSync, frameInterval, 24);
- CHECK_OFFSET(DisplayEventReceiver::Event::VSync, vsyncId, 32);
+ CHECK_OFFSET(DisplayEventReceiver::Event::VSync, vsyncData.frameInterval, 8);
+ CHECK_OFFSET(DisplayEventReceiver::Event::VSync, vsyncData.preferredFrameTimelineIndex, 16);
+ CHECK_OFFSET(DisplayEventReceiver::Event::VSync, vsyncData.frameTimelines, 24);
+ CHECK_OFFSET(DisplayEventReceiver::Event::VSync, vsyncData.frameTimelines[0].vsyncId, 24);
+ CHECK_OFFSET(DisplayEventReceiver::Event::VSync, vsyncData.frameTimelines[0].deadlineTimestamp,
+ 32);
+ CHECK_OFFSET(DisplayEventReceiver::Event::VSync,
+ vsyncData.frameTimelines[0].expectedPresentationTime, 40);
+ // Also test the offsets of the last frame timeline. A loop is not used because the non-const
+ // index cannot be used in static_assert.
+ const int lastFrameTimelineOffset = /* Start of array */ 24 +
+ (VsyncEventData::kFrameTimelinesLength - 1) * /* Size of FrameTimeline */ 24;
+ CHECK_OFFSET(DisplayEventReceiver::Event::VSync,
+ vsyncData.frameTimelines[VsyncEventData::kFrameTimelinesLength - 1].vsyncId,
+ lastFrameTimelineOffset);
+ CHECK_OFFSET(DisplayEventReceiver::Event::VSync,
+ vsyncData.frameTimelines[VsyncEventData::kFrameTimelinesLength - 1]
+ .deadlineTimestamp,
+ lastFrameTimelineOffset + 8);
+ CHECK_OFFSET(DisplayEventReceiver::Event::VSync,
+ vsyncData.frameTimelines[VsyncEventData::kFrameTimelinesLength - 1]
+ .expectedPresentationTime,
+ lastFrameTimelineOffset + 16);
CHECK_OFFSET(DisplayEventReceiver::Event::Hotplug, connected, 0);
diff --git a/libs/gui/tests/EndToEndNativeInputTest.cpp b/libs/gui/tests/EndToEndNativeInputTest.cpp
index 06a0aca..fcfe21b 100644
--- a/libs/gui/tests/EndToEndNativeInputTest.cpp
+++ b/libs/gui/tests/EndToEndNativeInputTest.cpp
@@ -266,14 +266,8 @@
void populateInputInfo(int width, int height) {
mInputInfo.token = mClientChannel->getConnectionToken();
mInputInfo.name = "Test info";
- mInputInfo.flags = WindowInfo::Flag::NOT_TOUCH_MODAL;
- mInputInfo.type = WindowInfo::Type::BASE_APPLICATION;
mInputInfo.dispatchingTimeout = 5s;
mInputInfo.globalScaleFactor = 1.0;
- mInputInfo.focusable = true;
- mInputInfo.hasWallpaper = false;
- mInputInfo.paused = false;
-
mInputInfo.touchableRegion.orSelf(Rect(0, 0, width, height));
InputApplicationInfo aInfo;
@@ -750,7 +744,7 @@
// 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.flags = WindowInfo::Flag::NOT_TOUCHABLE;
+ nonTouchableSurface->mInputInfo.setInputConfig(WindowInfo::InputConfig::NOT_TOUCHABLE, true);
nonTouchableSurface->mInputInfo.ownerUid = 22222;
// Overriding occlusion mode otherwise the touch would be discarded at InputDispatcher by
// the default obscured/untrusted touch filter introduced in S.
@@ -770,8 +764,8 @@
// 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.flags = WindowInfo::Flag::NOT_TOUCHABLE;
- parentSurface->mInputInfo.flags = WindowInfo::Flag::NOT_TOUCHABLE;
+ nonTouchableSurface->mInputInfo.setInputConfig(WindowInfo::InputConfig::NOT_TOUCHABLE, true);
+ parentSurface->mInputInfo.setInputConfig(WindowInfo::InputConfig::NOT_TOUCHABLE, true);
nonTouchableSurface->mInputInfo.ownerUid = 22222;
parentSurface->mInputInfo.ownerUid = 22222;
nonTouchableSurface->showAt(0, 0);
@@ -794,8 +788,8 @@
// 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.flags = WindowInfo::Flag::NOT_TOUCHABLE;
- parentSurface->mInputInfo.flags = WindowInfo::Flag::NOT_TOUCHABLE;
+ nonTouchableSurface->mInputInfo.setInputConfig(WindowInfo::InputConfig::NOT_TOUCHABLE, true);
+ parentSurface->mInputInfo.setInputConfig(WindowInfo::InputConfig::NOT_TOUCHABLE, true);
nonTouchableSurface->mInputInfo.ownerUid = 22222;
parentSurface->mInputInfo.ownerUid = 22222;
nonTouchableSurface->showAt(0, 0);
@@ -815,7 +809,7 @@
std::unique_ptr<InputSurface> bufferSurface =
InputSurface::makeBufferInputSurface(mComposerClient, 0, 0);
- bufferSurface->mInputInfo.flags = WindowInfo::Flag::NOT_TOUCHABLE;
+ bufferSurface->mInputInfo.setInputConfig(WindowInfo::InputConfig::NOT_TOUCHABLE, true);
bufferSurface->mInputInfo.ownerUid = 22222;
surface->showAt(10, 10);
@@ -830,7 +824,7 @@
std::unique_ptr<BlastInputSurface> bufferSurface =
BlastInputSurface::makeBlastInputSurface(mComposerClient, 0, 0);
- bufferSurface->mInputInfo.flags = WindowInfo::Flag::NOT_TOUCHABLE;
+ bufferSurface->mInputInfo.setInputConfig(WindowInfo::InputConfig::NOT_TOUCHABLE, true);
bufferSurface->mInputInfo.ownerUid = 22222;
surface->showAt(10, 10);
@@ -883,7 +877,7 @@
[&](auto &t, auto &sc) { t.setDropInputMode(sc, gui::DropInputMode::OBSCURED); });
surface->showAt(100, 100);
std::unique_ptr<InputSurface> obscuringSurface = makeSurface(100, 100);
- obscuringSurface->mInputInfo.flags = WindowInfo::Flag::NOT_TOUCHABLE;
+ obscuringSurface->mInputInfo.setInputConfig(WindowInfo::InputConfig::NOT_TOUCHABLE, true);
obscuringSurface->mInputInfo.ownerUid = 22222;
obscuringSurface->showAt(100, 100);
injectTap(101, 101);
@@ -902,7 +896,7 @@
[&](auto &t, auto &sc) { t.setDropInputMode(sc, gui::DropInputMode::OBSCURED); });
surface->showAt(100, 100);
std::unique_ptr<InputSurface> obscuringSurface = makeSurface(100, 100);
- obscuringSurface->mInputInfo.flags = WindowInfo::Flag::NOT_TOUCHABLE;
+ obscuringSurface->mInputInfo.setInputConfig(WindowInfo::InputConfig::NOT_TOUCHABLE, true);
obscuringSurface->mInputInfo.ownerUid = 22222;
obscuringSurface->showAt(190, 190);
diff --git a/libs/gui/tests/VsyncEventData_test.cpp b/libs/gui/tests/VsyncEventData_test.cpp
index a670d42..f114522 100644
--- a/libs/gui/tests/VsyncEventData_test.cpp
+++ b/libs/gui/tests/VsyncEventData_test.cpp
@@ -22,54 +22,37 @@
namespace android {
+using gui::ParcelableVsyncEventData;
using gui::VsyncEventData;
using FrameTimeline = gui::VsyncEventData::FrameTimeline;
namespace test {
-TEST(VsyncEventData, Parcelling) {
- VsyncEventData data;
- data.id = 123;
- data.deadlineTimestamp = 456;
- data.frameInterval = 789;
- data.preferredFrameTimelineIndex = 1;
- FrameTimeline timeline0 = FrameTimeline(1, 2, 3);
- FrameTimeline timeline1 = FrameTimeline(4, 5, 6);
- data.frameTimelines[0] = timeline0;
- data.frameTimelines[1] = timeline1;
+TEST(ParcelableVsyncEventData, Parcelling) {
+ ParcelableVsyncEventData data;
+ data.vsync.frameInterval = 789;
+ data.vsync.preferredFrameTimelineIndex = 1;
+ FrameTimeline timeline0 = FrameTimeline{1, 2, 3};
+ FrameTimeline timeline1 = FrameTimeline{4, 5, 6};
+ data.vsync.frameTimelines[0] = timeline0;
+ data.vsync.frameTimelines[1] = timeline1;
Parcel p;
data.writeToParcel(&p);
p.setDataPosition(0);
- VsyncEventData data2;
+ ParcelableVsyncEventData data2;
data2.readFromParcel(&p);
- ASSERT_EQ(data.id, data2.id);
- ASSERT_EQ(data.deadlineTimestamp, data2.deadlineTimestamp);
- ASSERT_EQ(data.frameInterval, data2.frameInterval);
- ASSERT_EQ(data.preferredFrameTimelineIndex, data2.preferredFrameTimelineIndex);
- for (int i = 0; i < data.frameTimelines.size(); i++) {
- ASSERT_EQ(data.frameTimelines[i].id, data2.frameTimelines[i].id);
- ASSERT_EQ(data.frameTimelines[i].deadlineTimestamp,
- data2.frameTimelines[i].deadlineTimestamp);
- ASSERT_EQ(data.frameTimelines[i].expectedPresentTime,
- data2.frameTimelines[i].expectedPresentTime);
+ ASSERT_EQ(data.vsync.frameInterval, data2.vsync.frameInterval);
+ ASSERT_EQ(data.vsync.preferredFrameTimelineIndex, data2.vsync.preferredFrameTimelineIndex);
+ for (int i = 0; i < VsyncEventData::kFrameTimelinesLength; i++) {
+ ASSERT_EQ(data.vsync.frameTimelines[i].vsyncId, data2.vsync.frameTimelines[i].vsyncId);
+ ASSERT_EQ(data.vsync.frameTimelines[i].deadlineTimestamp,
+ data2.vsync.frameTimelines[i].deadlineTimestamp);
+ ASSERT_EQ(data.vsync.frameTimelines[i].expectedPresentationTime,
+ data2.vsync.frameTimelines[i].expectedPresentationTime);
}
}
-TEST(FrameTimeline, Parcelling) {
- FrameTimeline timeline = FrameTimeline(1, 2, 3);
-
- Parcel p;
- timeline.writeToParcel(&p);
- p.setDataPosition(0);
-
- FrameTimeline timeline2;
- timeline2.readFromParcel(&p);
- ASSERT_EQ(timeline.id, timeline2.id);
- ASSERT_EQ(timeline.deadlineTimestamp, timeline2.deadlineTimestamp);
- ASSERT_EQ(timeline.expectedPresentTime, timeline2.expectedPresentTime);
-}
-
} // namespace test
} // namespace android
diff --git a/libs/gui/tests/WindowInfo_test.cpp b/libs/gui/tests/WindowInfo_test.cpp
index ff3ba2a..ff9bae2 100644
--- a/libs/gui/tests/WindowInfo_test.cpp
+++ b/libs/gui/tests/WindowInfo_test.cpp
@@ -49,8 +49,8 @@
i.windowToken = new BBinder();
i.id = 1;
i.name = "Foobar";
- i.flags = WindowInfo::Flag::SLIPPERY;
- i.type = WindowInfo::Type::INPUT_METHOD;
+ i.layoutParamsFlags = WindowInfo::Flag::SLIPPERY;
+ i.layoutParamsType = WindowInfo::Type::INPUT_METHOD;
i.dispatchingTimeout = 12s;
i.frameLeft = 93;
i.frameTop = 34;
@@ -60,15 +60,12 @@
i.globalScaleFactor = 0.3;
i.alpha = 0.7;
i.transform.set({0.4, -1, 100, 0.5, 0, 40, 0, 0, 1});
- i.visible = false;
- i.focusable = false;
- i.hasWallpaper = false;
- i.paused = false;
i.touchOcclusionMode = TouchOcclusionMode::ALLOW;
i.ownerPid = 19;
i.ownerUid = 24;
i.packageName = "com.example.package";
i.inputFeatures = WindowInfo::Feature::DISABLE_USER_ACTIVITY;
+ i.inputConfig = WindowInfo::InputConfig::NOT_FOCUSABLE;
i.displayId = 34;
i.replaceTouchableRegionWithCrop = true;
i.touchableRegionCropHandle = touchableRegionCropHandle;
@@ -85,8 +82,8 @@
ASSERT_EQ(i.windowToken, i2.windowToken);
ASSERT_EQ(i.id, i2.id);
ASSERT_EQ(i.name, i2.name);
- ASSERT_EQ(i.flags, i2.flags);
- ASSERT_EQ(i.type, i2.type);
+ ASSERT_EQ(i.layoutParamsFlags, i2.layoutParamsFlags);
+ ASSERT_EQ(i.layoutParamsType, i2.layoutParamsType);
ASSERT_EQ(i.dispatchingTimeout, i2.dispatchingTimeout);
ASSERT_EQ(i.frameLeft, i2.frameLeft);
ASSERT_EQ(i.frameTop, i2.frameTop);
@@ -96,15 +93,12 @@
ASSERT_EQ(i.globalScaleFactor, i2.globalScaleFactor);
ASSERT_EQ(i.alpha, i2.alpha);
ASSERT_EQ(i.transform, i2.transform);
- ASSERT_EQ(i.visible, i2.visible);
- ASSERT_EQ(i.focusable, i2.focusable);
- ASSERT_EQ(i.hasWallpaper, i2.hasWallpaper);
- ASSERT_EQ(i.paused, i2.paused);
ASSERT_EQ(i.touchOcclusionMode, i2.touchOcclusionMode);
ASSERT_EQ(i.ownerPid, i2.ownerPid);
ASSERT_EQ(i.ownerUid, i2.ownerUid);
ASSERT_EQ(i.packageName, i2.packageName);
ASSERT_EQ(i.inputFeatures, i2.inputFeatures);
+ ASSERT_EQ(i.inputConfig, i2.inputConfig);
ASSERT_EQ(i.displayId, i2.displayId);
ASSERT_EQ(i.replaceTouchableRegionWithCrop, i2.replaceTouchableRegionWithCrop);
ASSERT_EQ(i.touchableRegionCropHandle, i2.touchableRegionCropHandle);
diff --git a/libs/nativedisplay/AChoreographer.cpp b/libs/nativedisplay/AChoreographer.cpp
index b182a4a..3ce381b 100644
--- a/libs/nativedisplay/AChoreographer.cpp
+++ b/libs/nativedisplay/AChoreographer.cpp
@@ -103,9 +103,7 @@
struct ChoreographerFrameCallbackDataImpl {
int64_t frameTimeNanos{0};
- std::array<VsyncEventData::FrameTimeline, VsyncEventData::kFrameTimelinesLength> frameTimelines;
-
- size_t preferredFrameTimelineIndex;
+ VsyncEventData vsyncEventData;
const Choreographer* choreographer;
};
@@ -450,8 +448,7 @@
ChoreographerFrameCallbackDataImpl Choreographer::createFrameCallbackData(nsecs_t timestamp) const {
return {.frameTimeNanos = timestamp,
- .preferredFrameTimelineIndex = mLastVsyncEventData.preferredFrameTimelineIndex,
- .frameTimelines = mLastVsyncEventData.frameTimelines,
+ .vsyncEventData = mLastVsyncEventData,
.choreographer = this};
}
@@ -634,7 +631,7 @@
AChoreographerFrameCallbackData_to_ChoreographerFrameCallbackDataImpl(data);
LOG_ALWAYS_FATAL_IF(!frameCallbackData->choreographer->inCallback(),
"Data is only valid in callback");
- return frameCallbackData->frameTimelines.size();
+ return VsyncEventData::kFrameTimelinesLength;
}
size_t AChoreographerFrameCallbackData_getPreferredFrameTimelineIndex(
const AChoreographerFrameCallbackData* data) {
@@ -642,7 +639,7 @@
AChoreographerFrameCallbackData_to_ChoreographerFrameCallbackDataImpl(data);
LOG_ALWAYS_FATAL_IF(!frameCallbackData->choreographer->inCallback(),
"Data is only valid in callback");
- return frameCallbackData->preferredFrameTimelineIndex;
+ return frameCallbackData->vsyncEventData.preferredFrameTimelineIndex;
}
AVsyncId AChoreographerFrameCallbackData_getFrameTimelineVsyncId(
const AChoreographerFrameCallbackData* data, size_t index) {
@@ -650,8 +647,8 @@
AChoreographerFrameCallbackData_to_ChoreographerFrameCallbackDataImpl(data);
LOG_ALWAYS_FATAL_IF(!frameCallbackData->choreographer->inCallback(),
"Data is only valid in callback");
- LOG_ALWAYS_FATAL_IF(index >= frameCallbackData->frameTimelines.size(), "Index out of bounds");
- return frameCallbackData->frameTimelines[index].id;
+ LOG_ALWAYS_FATAL_IF(index >= VsyncEventData::kFrameTimelinesLength, "Index out of bounds");
+ return frameCallbackData->vsyncEventData.frameTimelines[index].vsyncId;
}
int64_t AChoreographerFrameCallbackData_getFrameTimelineExpectedPresentTimeNanos(
const AChoreographerFrameCallbackData* data, size_t index) {
@@ -659,8 +656,8 @@
AChoreographerFrameCallbackData_to_ChoreographerFrameCallbackDataImpl(data);
LOG_ALWAYS_FATAL_IF(!frameCallbackData->choreographer->inCallback(),
"Data is only valid in callback");
- LOG_ALWAYS_FATAL_IF(index >= frameCallbackData->frameTimelines.size(), "Index out of bounds");
- return frameCallbackData->frameTimelines[index].expectedPresentTime;
+ LOG_ALWAYS_FATAL_IF(index >= VsyncEventData::kFrameTimelinesLength, "Index out of bounds");
+ return frameCallbackData->vsyncEventData.frameTimelines[index].expectedPresentationTime;
}
int64_t AChoreographerFrameCallbackData_getFrameTimelineDeadlineNanos(
const AChoreographerFrameCallbackData* data, size_t index) {
@@ -668,8 +665,8 @@
AChoreographerFrameCallbackData_to_ChoreographerFrameCallbackDataImpl(data);
LOG_ALWAYS_FATAL_IF(!frameCallbackData->choreographer->inCallback(),
"Data is only valid in callback");
- LOG_ALWAYS_FATAL_IF(index >= frameCallbackData->frameTimelines.size(), "Index out of bounds");
- return frameCallbackData->frameTimelines[index].deadlineTimestamp;
+ LOG_ALWAYS_FATAL_IF(index >= VsyncEventData::kFrameTimelinesLength, "Index out of bounds");
+ return frameCallbackData->vsyncEventData.frameTimelines[index].deadlineTimestamp;
}
AChoreographer* AChoreographer_create() {
diff --git a/services/inputflinger/benchmarks/InputDispatcher_benchmarks.cpp b/services/inputflinger/benchmarks/InputDispatcher_benchmarks.cpp
index 41e9ce2..cd20a64 100644
--- a/services/inputflinger/benchmarks/InputDispatcher_benchmarks.cpp
+++ b/services/inputflinger/benchmarks/InputDispatcher_benchmarks.cpp
@@ -193,7 +193,6 @@
void updateInfo() {
mInfo.token = mClientChannel->getConnectionToken();
mInfo.name = "FakeWindowHandle";
- mInfo.type = WindowInfo::Type::APPLICATION;
mInfo.dispatchingTimeout = DISPATCHING_TIMEOUT;
mInfo.frameLeft = mFrame.left;
mInfo.frameTop = mFrame.top;
@@ -202,10 +201,6 @@
mInfo.globalScaleFactor = 1.0;
mInfo.touchableRegion.clear();
mInfo.addTouchableRegion(mFrame);
- mInfo.visible = true;
- mInfo.focusable = true;
- mInfo.hasWallpaper = false;
- mInfo.paused = false;
mInfo.ownerPid = INJECTOR_PID;
mInfo.ownerUid = INJECTOR_UID;
mInfo.displayId = ADISPLAY_ID_DEFAULT;
diff --git a/services/inputflinger/dispatcher/FocusResolver.cpp b/services/inputflinger/dispatcher/FocusResolver.cpp
index 600f02b..a02b3e8 100644
--- a/services/inputflinger/dispatcher/FocusResolver.cpp
+++ b/services/inputflinger/dispatcher/FocusResolver.cpp
@@ -148,11 +148,11 @@
continue;
}
windowFound = true;
- if (window->getInfo()->visible) {
+ if (!window->getInfo()->inputConfig.test(gui::WindowInfo::InputConfig::NOT_VISIBLE)) {
// Check if at least a single window is visible.
visibleWindowFound = true;
}
- if (!window->getInfo()->focusable) {
+ if (window->getInfo()->inputConfig.test(gui::WindowInfo::InputConfig::NOT_FOCUSABLE)) {
// Check if all windows with the window token are focusable.
allWindowsAreFocusable = false;
break;
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp
index 7062aef..58c9303 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.cpp
+++ b/services/inputflinger/dispatcher/InputDispatcher.cpp
@@ -500,17 +500,16 @@
// Returns true if the given window can accept pointer events at the given display location.
bool windowAcceptsTouchAt(const WindowInfo& windowInfo, int32_t displayId, int32_t x, int32_t y,
bool isStylus) {
- if (windowInfo.displayId != displayId || !windowInfo.visible) {
+ const auto inputConfig = windowInfo.inputConfig;
+ if (windowInfo.displayId != displayId ||
+ inputConfig.test(WindowInfo::InputConfig::NOT_VISIBLE)) {
return false;
}
- const auto flags = windowInfo.flags;
const bool windowCanInterceptTouch = isStylus && windowInfo.interceptsStylus();
- if (flags.test(WindowInfo::Flag::NOT_TOUCHABLE) && !windowCanInterceptTouch) {
+ if (inputConfig.test(WindowInfo::InputConfig::NOT_TOUCHABLE) && !windowCanInterceptTouch) {
return false;
}
- const bool isModalWindow = !flags.test(WindowInfo::Flag::NOT_FOCUSABLE) &&
- !flags.test(WindowInfo::Flag::NOT_TOUCH_MODAL);
- if (!isModalWindow && !windowInfo.touchableRegionContainsPoint(x, y)) {
+ if (!windowInfo.touchableRegionContainsPoint(x, y)) {
return false;
}
return true;
@@ -1047,7 +1046,8 @@
return windowHandle;
}
- if (addOutsideTargets && info.flags.test(WindowInfo::Flag::WATCH_OUTSIDE_TOUCH)) {
+ if (addOutsideTargets &&
+ info.inputConfig.test(WindowInfo::InputConfig::WATCH_OUTSIDE_TOUCH)) {
touchState->addOrUpdateWindow(windowHandle, InputTarget::FLAG_DISPATCH_AS_OUTSIDE,
BitSet32(0));
}
@@ -1900,7 +1900,8 @@
return InputEventInjectionResult::PERMISSION_DENIED;
}
- if (focusedWindowHandle->getInfo()->paused) {
+ if (focusedWindowHandle->getInfo()->inputConfig.test(
+ WindowInfo::InputConfig::PAUSE_DISPATCHING)) {
ALOGI("Waiting because %s is paused", focusedWindowHandle->getName().c_str());
return InputEventInjectionResult::PENDING;
}
@@ -2101,7 +2102,7 @@
for (const sp<WindowInfoHandle>& windowHandle : newTouchedWindows) {
const WindowInfo& info = *windowHandle->getInfo();
- if (info.paused) {
+ if (info.inputConfig.test(WindowInfo::InputConfig::PAUSE_DISPATCHING)) {
ALOGI("Not sending touch event to %s because it is paused",
windowHandle->getName().c_str());
continue;
@@ -2324,13 +2325,16 @@
if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
sp<WindowInfoHandle> foregroundWindowHandle =
tempTouchState.getFirstForegroundWindowHandle();
- if (foregroundWindowHandle && foregroundWindowHandle->getInfo()->hasWallpaper) {
+ if (foregroundWindowHandle &&
+ foregroundWindowHandle->getInfo()->inputConfig.test(
+ WindowInfo::InputConfig::DUPLICATE_TOUCH_TO_WALLPAPER)) {
const std::vector<sp<WindowInfoHandle>>& windowHandles =
getWindowHandlesLocked(displayId);
for (const sp<WindowInfoHandle>& windowHandle : windowHandles) {
const WindowInfo* info = windowHandle->getInfo();
if (info->displayId == displayId &&
- windowHandle->getInfo()->type == WindowInfo::Type::WALLPAPER) {
+ windowHandle->getInfo()->inputConfig.test(
+ WindowInfo::InputConfig::IS_WALLPAPER)) {
tempTouchState
.addOrUpdateWindow(windowHandle,
InputTarget::FLAG_WINDOW_IS_OBSCURED |
@@ -2599,9 +2603,10 @@
}
auto info = windowHandle->getInfo();
auto otherInfo = otherHandle->getInfo();
- if (!otherInfo->visible) {
+ if (otherInfo->inputConfig.test(WindowInfo::InputConfig::NOT_VISIBLE)) {
return false;
- } else if (otherInfo->alpha == 0 && otherInfo->flags.test(WindowInfo::Flag::NOT_TOUCHABLE)) {
+ } else if (otherInfo->alpha == 0 &&
+ otherInfo->inputConfig.test(WindowInfo::InputConfig::NOT_TOUCHABLE)) {
// Those act as if they were invisible, so we don't need to flag them.
// We do want to potentially flag touchable windows even if they have 0
// opacity, since they can consume touches and alter the effects of the
@@ -2613,7 +2618,7 @@
// If ownerUid is the same we don't generate occlusion events as there
// is no security boundary within an uid.
return false;
- } else if (otherInfo->trustedOverlay) {
+ } else if (otherInfo->inputConfig.test(gui::WindowInfo::InputConfig::TRUSTED_OVERLAY)) {
return false;
} else if (otherInfo->displayId != info->displayId) {
return false;
@@ -2694,17 +2699,17 @@
std::string InputDispatcher::dumpWindowForTouchOcclusion(const WindowInfo* info,
bool isTouchedWindow) const {
return StringPrintf(INDENT2
- "* %stype=%s, package=%s/%" PRId32 ", id=%" PRId32 ", mode=%s, alpha=%.2f, "
+ "* %spackage=%s/%" PRId32 ", id=%" PRId32 ", mode=%s, alpha=%.2f, "
"frame=[%" PRId32 ",%" PRId32 "][%" PRId32 ",%" PRId32
- "], touchableRegion=%s, window={%s}, flags={%s}, inputFeatures={%s}, "
+ "], touchableRegion=%s, window={%s}, inputConfig={%s}, inputFeatures={%s}, "
"hasToken=%s, applicationInfo.name=%s, applicationInfo.token=%s\n",
- isTouchedWindow ? "[TOUCHED] " : "", ftl::enum_string(info->type).c_str(),
- info->packageName.c_str(), info->ownerUid, info->id,
- toString(info->touchOcclusionMode).c_str(), info->alpha, info->frameLeft,
- info->frameTop, info->frameRight, info->frameBottom,
- dumpRegion(info->touchableRegion).c_str(), info->name.c_str(),
- info->flags.string().c_str(), info->inputFeatures.string().c_str(),
- toString(info->token != nullptr), info->applicationInfo.name.c_str(),
+ isTouchedWindow ? "[TOUCHED] " : "", info->packageName.c_str(),
+ info->ownerUid, info->id, toString(info->touchOcclusionMode).c_str(),
+ info->alpha, info->frameLeft, info->frameTop, info->frameRight,
+ info->frameBottom, dumpRegion(info->touchableRegion).c_str(),
+ info->name.c_str(), info->inputConfig.string().c_str(),
+ info->inputFeatures.string().c_str(), toString(info->token != nullptr),
+ info->applicationInfo.name.c_str(),
toString(info->applicationInfo.token).c_str());
}
@@ -4572,8 +4577,9 @@
if (getInputChannelLocked(handle->getToken()) == nullptr) {
const bool noInputChannel =
info->inputFeatures.test(WindowInfo::Feature::NO_INPUT_CHANNEL);
- const bool canReceiveInput = !info->flags.test(WindowInfo::Flag::NOT_TOUCHABLE) ||
- !info->flags.test(WindowInfo::Flag::NOT_FOCUSABLE);
+ const bool canReceiveInput =
+ !info->inputConfig.test(WindowInfo::InputConfig::NOT_TOUCHABLE) ||
+ !info->inputConfig.test(WindowInfo::InputConfig::NOT_FOCUSABLE);
if (canReceiveInput && !noInputChannel) {
ALOGV("Window handle %s has no registered input channel",
handle->getName().c_str());
@@ -4644,12 +4650,16 @@
}
// Ensure all spy windows are trusted overlays
- LOG_ALWAYS_FATAL_IF(info.isSpy() && !info.trustedOverlay,
+ LOG_ALWAYS_FATAL_IF(info.isSpy() &&
+ !info.inputConfig.test(
+ WindowInfo::InputConfig::TRUSTED_OVERLAY),
"%s has feature SPY, but is not a trusted overlay.",
window->getName().c_str());
// Ensure all stylus interceptors are trusted overlays
- LOG_ALWAYS_FATAL_IF(info.interceptsStylus() && !info.trustedOverlay,
+ LOG_ALWAYS_FATAL_IF(info.interceptsStylus() &&
+ !info.inputConfig.test(
+ WindowInfo::InputConfig::TRUSTED_OVERLAY),
"%s has feature INTERCEPTS_STYLUS, but is not a trusted overlay.",
window->getName().c_str());
}
@@ -4699,7 +4709,8 @@
// Since we are about to drop the touch, cancel the events for the wallpaper as
// well.
if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND &&
- touchedWindow.windowHandle->getInfo()->hasWallpaper) {
+ touchedWindow.windowHandle->getInfo()->inputConfig.test(
+ gui::WindowInfo::InputConfig::DUPLICATE_TOUCH_TO_WALLPAPER)) {
sp<WindowInfoHandle> wallpaper = state.getWallpaperWindow();
if (wallpaper != nullptr) {
sp<Connection> wallpaperConnection =
@@ -5194,34 +5205,27 @@
const WindowInfo* windowInfo = windowHandle->getInfo();
dump += StringPrintf(INDENT3 "%zu: name='%s', id=%" PRId32 ", displayId=%d, "
- "paused=%s, focusable=%s, "
- "hasWallpaper=%s, visible=%s, alpha=%.2f, "
- "flags=%s, type=%s, "
+ "inputConfig=%s, alpha=%.2f, "
"frame=[%d,%d][%d,%d], globalScale=%f, "
"applicationInfo.name=%s, "
"applicationInfo.token=%s, "
"touchableRegion=",
i, windowInfo->name.c_str(), windowInfo->id,
- windowInfo->displayId, toString(windowInfo->paused),
- toString(windowInfo->focusable),
- toString(windowInfo->hasWallpaper),
- toString(windowInfo->visible), windowInfo->alpha,
- windowInfo->flags.string().c_str(),
- ftl::enum_string(windowInfo->type).c_str(),
- windowInfo->frameLeft, windowInfo->frameTop,
- windowInfo->frameRight, windowInfo->frameBottom,
- windowInfo->globalScaleFactor,
+ windowInfo->displayId,
+ windowInfo->inputConfig.string().c_str(),
+ windowInfo->alpha, windowInfo->frameLeft,
+ windowInfo->frameTop, windowInfo->frameRight,
+ windowInfo->frameBottom, windowInfo->globalScaleFactor,
windowInfo->applicationInfo.name.c_str(),
toString(windowInfo->applicationInfo.token).c_str());
dump += dumpRegion(windowInfo->touchableRegion);
dump += StringPrintf(", inputFeatures=%s",
windowInfo->inputFeatures.string().c_str());
dump += StringPrintf(", ownerPid=%d, ownerUid=%d, dispatchingTimeout=%" PRId64
- "ms, trustedOverlay=%s, hasToken=%s, "
+ "ms, hasToken=%s, "
"touchOcclusionMode=%s\n",
windowInfo->ownerPid, windowInfo->ownerUid,
millis(windowInfo->dispatchingTimeout),
- toString(windowInfo->trustedOverlay),
toString(windowInfo->token != nullptr),
toString(windowInfo->touchOcclusionMode).c_str());
windowInfo->transform.dump(dump, "transform", INDENT4);
diff --git a/services/inputflinger/dispatcher/TouchState.cpp b/services/inputflinger/dispatcher/TouchState.cpp
index b63fe10..61e78cc 100644
--- a/services/inputflinger/dispatcher/TouchState.cpp
+++ b/services/inputflinger/dispatcher/TouchState.cpp
@@ -100,7 +100,8 @@
for (const TouchedWindow& window : windows) {
if (window.targetFlags & InputTarget::FLAG_FOREGROUND) {
if (haveSlipperyForegroundWindow ||
- !window.windowHandle->getInfo()->flags.test(WindowInfo::Flag::SLIPPERY)) {
+ !window.windowHandle->getInfo()->inputConfig.test(
+ WindowInfo::InputConfig::SLIPPERY)) {
return false;
}
haveSlipperyForegroundWindow = true;
@@ -112,7 +113,8 @@
sp<WindowInfoHandle> TouchState::getWallpaperWindow() const {
for (size_t i = 0; i < windows.size(); i++) {
const TouchedWindow& window = windows[i];
- if (window.windowHandle->getInfo()->type == WindowInfo::Type::WALLPAPER) {
+ if (window.windowHandle->getInfo()->inputConfig.test(
+ gui::WindowInfo::InputConfig::IS_WALLPAPER)) {
return window.windowHandle;
}
}
diff --git a/services/inputflinger/tests/FocusResolver_test.cpp b/services/inputflinger/tests/FocusResolver_test.cpp
index 662be80..ffce9f6 100644
--- a/services/inputflinger/tests/FocusResolver_test.cpp
+++ b/services/inputflinger/tests/FocusResolver_test.cpp
@@ -37,12 +37,16 @@
bool visible) {
mInfo.token = token;
mInfo.name = name;
- mInfo.visible = visible;
- mInfo.focusable = focusable;
+ setFocusable(focusable);
+ setVisible(visible);
}
- void setFocusable(bool focusable) { mInfo.focusable = focusable; }
- void setVisible(bool visible) { mInfo.visible = visible; }
+ void setFocusable(bool focusable) {
+ mInfo.setInputConfig(gui::WindowInfo::InputConfig::NOT_FOCUSABLE, !focusable);
+ }
+ void setVisible(bool visible) {
+ mInfo.setInputConfig(gui::WindowInfo::InputConfig::NOT_VISIBLE, !visible);
+ }
};
TEST(FocusResolverTest, SetFocusedWindow) {
diff --git a/services/inputflinger/tests/InputDispatcher_test.cpp b/services/inputflinger/tests/InputDispatcher_test.cpp
index 813acd8..ae8358a 100644
--- a/services/inputflinger/tests/InputDispatcher_test.cpp
+++ b/services/inputflinger/tests/InputDispatcher_test.cpp
@@ -987,7 +987,6 @@
mInfo.token = *token;
mInfo.id = sId++;
mInfo.name = name;
- mInfo.type = WindowInfo::Type::APPLICATION;
mInfo.dispatchingTimeout = DISPATCHING_TIMEOUT;
mInfo.alpha = 1.0;
mInfo.frameLeft = 0;
@@ -998,14 +997,10 @@
mInfo.globalScaleFactor = 1.0;
mInfo.touchableRegion.clear();
mInfo.addTouchableRegion(Rect(0, 0, WIDTH, HEIGHT));
- mInfo.visible = true;
- mInfo.focusable = false;
- mInfo.hasWallpaper = false;
- mInfo.paused = false;
mInfo.ownerPid = INJECTOR_PID;
mInfo.ownerUid = INJECTOR_UID;
mInfo.displayId = displayId;
- mInfo.trustedOverlay = false;
+ mInfo.inputConfig = WindowInfo::InputConfig::NONE;
}
sp<FakeWindowHandle> clone(
@@ -1017,15 +1012,37 @@
return handle;
}
- void setFocusable(bool focusable) { mInfo.focusable = focusable; }
+ void setTouchable(bool touchable) {
+ mInfo.setInputConfig(WindowInfo::InputConfig::NOT_TOUCHABLE, !touchable);
+ }
- void setVisible(bool visible) { mInfo.visible = visible; }
+ void setFocusable(bool focusable) {
+ mInfo.setInputConfig(WindowInfo::InputConfig::NOT_FOCUSABLE, !focusable);
+ }
+
+ void setVisible(bool visible) {
+ mInfo.setInputConfig(WindowInfo::InputConfig::NOT_VISIBLE, !visible);
+ }
void setDispatchingTimeout(std::chrono::nanoseconds timeout) {
mInfo.dispatchingTimeout = timeout;
}
- void setPaused(bool paused) { mInfo.paused = paused; }
+ void setPaused(bool paused) {
+ mInfo.setInputConfig(WindowInfo::InputConfig::PAUSE_DISPATCHING, paused);
+ }
+
+ void setPreventSplitting(bool preventSplitting) {
+ mInfo.setInputConfig(WindowInfo::InputConfig::PREVENT_SPLITTING, preventSplitting);
+ }
+
+ void setSlippery(bool slippery) {
+ mInfo.setInputConfig(WindowInfo::InputConfig::SLIPPERY, slippery);
+ }
+
+ void setWatchOutsideTouch(bool watchOutside) {
+ mInfo.setInputConfig(WindowInfo::InputConfig::WATCH_OUTSIDE_TOUCH, watchOutside);
+ }
void setAlpha(float alpha) { mInfo.alpha = alpha; }
@@ -1049,17 +1066,19 @@
void setTouchableRegion(const Region& region) { mInfo.touchableRegion = region; }
- void setType(WindowInfo::Type type) { mInfo.type = type; }
+ void setIsWallpaper(bool isWallpaper) {
+ mInfo.setInputConfig(WindowInfo::InputConfig::IS_WALLPAPER, isWallpaper);
+ }
- void setHasWallpaper(bool hasWallpaper) { mInfo.hasWallpaper = hasWallpaper; }
-
- void addFlags(Flags<WindowInfo::Flag> flags) { mInfo.flags |= flags; }
-
- void setFlags(Flags<WindowInfo::Flag> flags) { mInfo.flags = flags; }
+ void setDupTouchToWallpaper(bool hasWallpaper) {
+ mInfo.setInputConfig(WindowInfo::InputConfig::DUPLICATE_TOUCH_TO_WALLPAPER, hasWallpaper);
+ }
void setInputFeatures(Flags<WindowInfo::Feature> features) { mInfo.inputFeatures = features; }
- void setTrustedOverlay(bool trustedOverlay) { mInfo.trustedOverlay = trustedOverlay; }
+ void setTrustedOverlay(bool trustedOverlay) {
+ mInfo.setInputConfig(WindowInfo::InputConfig::TRUSTED_OVERLAY, trustedOverlay);
+ }
void setWindowTransform(float dsdx, float dtdx, float dtdy, float dsdy) {
mInfo.transform.set(dsdx, dtdx, dtdy, dsdy);
@@ -1540,19 +1559,15 @@
}
/**
- * Calling setInputWindows once with FLAG_NOT_TOUCH_MODAL should not cause any issues.
- * To ensure that window receives only events that were directly inside of it, add
- * FLAG_NOT_TOUCH_MODAL. This will enforce using the touchableRegion of the input
- * when finding touched windows.
+ * Calling setInputWindows once should not cause any issues.
* This test serves as a sanity check for the next test, where setInputWindows is
* called twice.
*/
-TEST_F(InputDispatcherTest, SetInputWindowOnce_SingleWindowTouch) {
+TEST_F(InputDispatcherTest, SetInputWindowOnceWithSingleTouchWindow) {
std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
sp<FakeWindowHandle> window =
new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
window->setFrame(Rect(0, 0, 100, 100));
- window->setFlags(WindowInfo::Flag::NOT_TOUCH_MODAL);
mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
@@ -1566,16 +1581,12 @@
/**
* Calling setInputWindows twice, with the same info, should not cause any issues.
- * To ensure that window receives only events that were directly inside of it, add
- * FLAG_NOT_TOUCH_MODAL. This will enforce using the touchableRegion of the input
- * when finding touched windows.
*/
TEST_F(InputDispatcherTest, SetInputWindowTwice_SingleWindowTouch) {
std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
sp<FakeWindowHandle> window =
new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
window->setFrame(Rect(0, 0, 100, 100));
- window->setFlags(WindowInfo::Flag::NOT_TOUCH_MODAL);
mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
@@ -1610,17 +1621,17 @@
* Two windows: A top window, and a wallpaper behind the window.
* Touch goes to the top window, and then top window disappears. Ensure that wallpaper window
* gets ACTION_CANCEL.
- * 1. foregroundWindow <-- has wallpaper (hasWallpaper=true)
- * 2. wallpaperWindow <-- is wallpaper (type=InputWindowInfo::Type::WALLPAPER)
+ * 1. foregroundWindow <-- dup touch to wallpaper
+ * 2. wallpaperWindow <-- is wallpaper
*/
TEST_F(InputDispatcherTest, WhenForegroundWindowDisappears_WallpaperTouchIsCanceled) {
std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
sp<FakeWindowHandle> foregroundWindow =
new FakeWindowHandle(application, mDispatcher, "Foreground", ADISPLAY_ID_DEFAULT);
- foregroundWindow->setHasWallpaper(true);
+ foregroundWindow->setDupTouchToWallpaper(true);
sp<FakeWindowHandle> wallpaperWindow =
new FakeWindowHandle(application, mDispatcher, "Wallpaper", ADISPLAY_ID_DEFAULT);
- wallpaperWindow->setType(WindowInfo::Type::WALLPAPER);
+ wallpaperWindow->setIsWallpaper(true);
constexpr int expectedWallpaperFlags =
AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED | AMOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
@@ -1661,10 +1672,10 @@
std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
sp<FakeWindowHandle> foregroundWindow =
new FakeWindowHandle(application, mDispatcher, "Foreground", ADISPLAY_ID_DEFAULT);
- foregroundWindow->setHasWallpaper(true);
+ foregroundWindow->setDupTouchToWallpaper(true);
sp<FakeWindowHandle> wallpaperWindow =
new FakeWindowHandle(application, mDispatcher, "Wallpaper", ADISPLAY_ID_DEFAULT);
- wallpaperWindow->setType(WindowInfo::Type::WALLPAPER);
+ wallpaperWindow->setIsWallpaper(true);
constexpr int expectedWallpaperFlags =
AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED | AMOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
@@ -1705,11 +1716,11 @@
std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
sp<FakeWindowHandle> window =
new FakeWindowHandle(application, mDispatcher, "Top", ADISPLAY_ID_DEFAULT);
- window->setHasWallpaper(true);
+ window->setDupTouchToWallpaper(true);
sp<FakeWindowHandle> wallpaperWindow =
new FakeWindowHandle(application, mDispatcher, "Wallpaper", ADISPLAY_ID_DEFAULT);
- wallpaperWindow->setType(WindowInfo::Type::WALLPAPER);
+ wallpaperWindow->setIsWallpaper(true);
constexpr int expectedWallpaperFlags =
AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED | AMOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
@@ -1763,19 +1774,17 @@
sp<FakeWindowHandle> leftWindow =
new FakeWindowHandle(application, mDispatcher, "Left", ADISPLAY_ID_DEFAULT);
leftWindow->setFrame(Rect(0, 0, 200, 200));
- leftWindow->setFlags(WindowInfo::Flag::SPLIT_TOUCH | WindowInfo::Flag::NOT_TOUCH_MODAL);
- leftWindow->setHasWallpaper(true);
+ leftWindow->setDupTouchToWallpaper(true);
sp<FakeWindowHandle> rightWindow =
new FakeWindowHandle(application, mDispatcher, "Right", ADISPLAY_ID_DEFAULT);
rightWindow->setFrame(Rect(200, 0, 400, 200));
- rightWindow->setFlags(WindowInfo::Flag::SPLIT_TOUCH | WindowInfo::Flag::NOT_TOUCH_MODAL);
- rightWindow->setHasWallpaper(true);
+ rightWindow->setDupTouchToWallpaper(true);
sp<FakeWindowHandle> wallpaperWindow =
new FakeWindowHandle(application, mDispatcher, "Wallpaper", ADISPLAY_ID_DEFAULT);
wallpaperWindow->setFrame(Rect(0, 0, 400, 200));
- wallpaperWindow->setType(WindowInfo::Type::WALLPAPER);
+ wallpaperWindow->setIsWallpaper(true);
constexpr int expectedWallpaperFlags =
AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED | AMOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
@@ -1849,11 +1858,9 @@
sp<FakeWindowHandle> windowLeft =
new FakeWindowHandle(application, mDispatcher, "Left", ADISPLAY_ID_DEFAULT);
windowLeft->setFrame(Rect(0, 0, 600, 800));
- windowLeft->setFlags(WindowInfo::Flag::NOT_TOUCH_MODAL);
sp<FakeWindowHandle> windowRight =
new FakeWindowHandle(application, mDispatcher, "Right", ADISPLAY_ID_DEFAULT);
windowRight->setFrame(Rect(600, 0, 1200, 800));
- windowRight->setFlags(WindowInfo::Flag::NOT_TOUCH_MODAL);
mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
@@ -1960,7 +1967,6 @@
sp<FakeWindowHandle> window =
new FakeWindowHandle(application, mDispatcher, "Window", ADISPLAY_ID_DEFAULT);
window->setFrame(Rect(0, 0, 1200, 800));
- window->setFlags(WindowInfo::Flag::NOT_TOUCH_MODAL);
mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
@@ -2042,11 +2048,9 @@
sp<FakeWindowHandle> windowLeft =
new FakeWindowHandle(application, mDispatcher, "Left", ADISPLAY_ID_DEFAULT);
windowLeft->setFrame(Rect(0, 0, 600, 800));
- windowLeft->setFlags(WindowInfo::Flag::NOT_TOUCH_MODAL);
sp<FakeWindowHandle> windowRight =
new FakeWindowHandle(application, mDispatcher, "Right", ADISPLAY_ID_DEFAULT);
windowRight->setFrame(Rect(600, 0, 1200, 800));
- windowRight->setFlags(WindowInfo::Flag::NOT_TOUCH_MODAL);
mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
@@ -2152,14 +2156,12 @@
// Add two windows to the display. Their frames are represented in the display space.
sp<FakeWindowHandle> firstWindow =
new FakeWindowHandle(application, mDispatcher, "First Window", ADISPLAY_ID_DEFAULT);
- firstWindow->addFlags(WindowInfo::Flag::NOT_TOUCH_MODAL);
firstWindow->setFrame(Rect(0, 0, 100, 200), displayTransform);
addWindow(firstWindow);
sp<FakeWindowHandle> secondWindow =
new FakeWindowHandle(application, mDispatcher, "Second Window",
ADISPLAY_ID_DEFAULT);
- secondWindow->addFlags(WindowInfo::Flag::NOT_TOUCH_MODAL);
secondWindow->setFrame(Rect(100, 200, 200, 400), displayTransform);
addWindow(secondWindow);
return {std::move(firstWindow), std::move(secondWindow)};
@@ -2302,8 +2304,10 @@
// Create a couple of windows
sp<FakeWindowHandle> firstWindow =
new FakeWindowHandle(application, mDispatcher, "First Window", ADISPLAY_ID_DEFAULT);
+ firstWindow->setPreventSplitting(true);
sp<FakeWindowHandle> secondWindow =
new FakeWindowHandle(application, mDispatcher, "Second Window", ADISPLAY_ID_DEFAULT);
+ secondWindow->setPreventSplitting(true);
// Add the windows to the dispatcher
mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {firstWindow, secondWindow}}});
@@ -2376,17 +2380,13 @@
TEST_F(InputDispatcherTest, TransferTouchFocus_TwoPointersSplitTouch) {
std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
- // Create a non touch modal window that supports split touch
sp<FakeWindowHandle> firstWindow =
new FakeWindowHandle(application, mDispatcher, "First Window", ADISPLAY_ID_DEFAULT);
firstWindow->setFrame(Rect(0, 0, 600, 400));
- firstWindow->setFlags(WindowInfo::Flag::NOT_TOUCH_MODAL | WindowInfo::Flag::SPLIT_TOUCH);
- // Create a non touch modal window that supports split touch
sp<FakeWindowHandle> secondWindow =
new FakeWindowHandle(application, mDispatcher, "Second Window", ADISPLAY_ID_DEFAULT);
secondWindow->setFrame(Rect(0, 400, 600, 800));
- secondWindow->setFlags(WindowInfo::Flag::NOT_TOUCH_MODAL | WindowInfo::Flag::SPLIT_TOUCH);
// Add the windows to the dispatcher
mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {firstWindow, secondWindow}}});
@@ -2448,17 +2448,13 @@
TEST_F(InputDispatcherTest, TransferTouch_TwoPointersSplitTouch) {
std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
- // Create a non touch modal window that supports split touch
sp<FakeWindowHandle> firstWindow =
new FakeWindowHandle(application, mDispatcher, "First Window", ADISPLAY_ID_DEFAULT);
firstWindow->setFrame(Rect(0, 0, 600, 400));
- firstWindow->setFlags(WindowInfo::Flag::NOT_TOUCH_MODAL | WindowInfo::Flag::SPLIT_TOUCH);
- // Create a non touch modal window that supports split touch
sp<FakeWindowHandle> secondWindow =
new FakeWindowHandle(application, mDispatcher, "Second Window", ADISPLAY_ID_DEFAULT);
secondWindow->setFrame(Rect(0, 400, 600, 800));
- secondWindow->setFlags(WindowInfo::Flag::NOT_TOUCH_MODAL | WindowInfo::Flag::SPLIT_TOUCH);
// Add the windows to the dispatcher
mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {firstWindow, secondWindow}}});
@@ -2523,26 +2519,21 @@
sp<FakeWindowHandle> firstWindowInPrimary =
new FakeWindowHandle(application, mDispatcher, "D_1_W1", ADISPLAY_ID_DEFAULT);
firstWindowInPrimary->setFrame(Rect(0, 0, 100, 100));
- firstWindowInPrimary->setFlags(WindowInfo::Flag::NOT_TOUCH_MODAL);
sp<FakeWindowHandle> secondWindowInPrimary =
new FakeWindowHandle(application, mDispatcher, "D_1_W2", ADISPLAY_ID_DEFAULT);
secondWindowInPrimary->setFrame(Rect(100, 0, 200, 100));
- secondWindowInPrimary->setFlags(WindowInfo::Flag::NOT_TOUCH_MODAL);
sp<FakeWindowHandle> mirrorWindowInPrimary =
firstWindowInPrimary->clone(application, mDispatcher, ADISPLAY_ID_DEFAULT);
mirrorWindowInPrimary->setFrame(Rect(0, 100, 100, 200));
- mirrorWindowInPrimary->setFlags(WindowInfo::Flag::NOT_TOUCH_MODAL);
sp<FakeWindowHandle> firstWindowInSecondary =
firstWindowInPrimary->clone(application, mDispatcher, SECOND_DISPLAY_ID);
firstWindowInSecondary->setFrame(Rect(0, 0, 100, 100));
- firstWindowInSecondary->setFlags(WindowInfo::Flag::NOT_TOUCH_MODAL);
sp<FakeWindowHandle> secondWindowInSecondary =
secondWindowInPrimary->clone(application, mDispatcher, SECOND_DISPLAY_ID);
secondWindowInPrimary->setFrame(Rect(100, 0, 200, 100));
- secondWindowInPrimary->setFlags(WindowInfo::Flag::NOT_TOUCH_MODAL);
// Update window info, let it find window handle of second display first.
mDispatcher->setInputWindows(
@@ -2587,26 +2578,21 @@
sp<FakeWindowHandle> firstWindowInPrimary =
new FakeWindowHandle(application, mDispatcher, "D_1_W1", ADISPLAY_ID_DEFAULT);
firstWindowInPrimary->setFrame(Rect(0, 0, 100, 100));
- firstWindowInPrimary->setFlags(WindowInfo::Flag::NOT_TOUCH_MODAL);
sp<FakeWindowHandle> secondWindowInPrimary =
new FakeWindowHandle(application, mDispatcher, "D_1_W2", ADISPLAY_ID_DEFAULT);
secondWindowInPrimary->setFrame(Rect(100, 0, 200, 100));
- secondWindowInPrimary->setFlags(WindowInfo::Flag::NOT_TOUCH_MODAL);
sp<FakeWindowHandle> mirrorWindowInPrimary =
firstWindowInPrimary->clone(application, mDispatcher, ADISPLAY_ID_DEFAULT);
mirrorWindowInPrimary->setFrame(Rect(0, 100, 100, 200));
- mirrorWindowInPrimary->setFlags(WindowInfo::Flag::NOT_TOUCH_MODAL);
sp<FakeWindowHandle> firstWindowInSecondary =
firstWindowInPrimary->clone(application, mDispatcher, SECOND_DISPLAY_ID);
firstWindowInSecondary->setFrame(Rect(0, 0, 100, 100));
- firstWindowInSecondary->setFlags(WindowInfo::Flag::NOT_TOUCH_MODAL);
sp<FakeWindowHandle> secondWindowInSecondary =
secondWindowInPrimary->clone(application, mDispatcher, SECOND_DISPLAY_ID);
secondWindowInPrimary->setFrame(Rect(100, 0, 200, 100));
- secondWindowInPrimary->setFlags(WindowInfo::Flag::NOT_TOUCH_MODAL);
// Update window info, let it find window handle of second display first.
mDispatcher->setInputWindows(
@@ -2700,17 +2686,13 @@
TEST_F(InputDispatcherTest, PointerCancel_SendCancelWhenSplitTouch) {
std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
- // Create first non touch modal window that supports split touch
sp<FakeWindowHandle> firstWindow =
new FakeWindowHandle(application, mDispatcher, "First Window", ADISPLAY_ID_DEFAULT);
firstWindow->setFrame(Rect(0, 0, 600, 400));
- firstWindow->setFlags(WindowInfo::Flag::NOT_TOUCH_MODAL | WindowInfo::Flag::SPLIT_TOUCH);
- // Create second non touch modal window that supports split touch
sp<FakeWindowHandle> secondWindow =
new FakeWindowHandle(application, mDispatcher, "Second Window", ADISPLAY_ID_DEFAULT);
secondWindow->setFrame(Rect(0, 400, 600, 800));
- secondWindow->setFlags(WindowInfo::Flag::NOT_TOUCH_MODAL | WindowInfo::Flag::SPLIT_TOUCH);
// Add the windows to the dispatcher
mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {firstWindow, secondWindow}}});
@@ -3230,9 +3212,9 @@
std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
sp<FakeWindowHandle> window =
new FakeWindowHandle(application, mDispatcher, "TestWindow", ADISPLAY_ID_DEFAULT);
+ window->setFocusable(false);
mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
- // Window is not focusable.
mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
setFocusedWindow(window);
@@ -3240,7 +3222,7 @@
ASSERT_EQ(InputEventInjectionResult::TIMED_OUT, injectKeyDown(mDispatcher))
<< "Inject key event should return InputEventInjectionResult::TIMED_OUT";
- // window is invalid, so it should not receive any input event.
+ // window is not focusable, so it should not receive any input event.
window->assertNoEvents();
}
@@ -3377,7 +3359,7 @@
sp<FakeWindowHandle> slipperyExitWindow =
new FakeWindowHandle(application, mDispatcher, "Top", ADISPLAY_ID_DEFAULT);
- slipperyExitWindow->setFlags(WindowInfo::Flag::NOT_TOUCH_MODAL | WindowInfo::Flag::SLIPPERY);
+ slipperyExitWindow->setSlippery(true);
// Make sure this one overlaps the bottom window
slipperyExitWindow->setFrame(Rect(25, 25, 75, 75));
// Change the owner uid/pid of the window so that it is considered to be occluding the bottom
@@ -3983,14 +3965,10 @@
mUnfocusedWindow =
new FakeWindowHandle(application, mDispatcher, "Top", ADISPLAY_ID_DEFAULT);
mUnfocusedWindow->setFrame(Rect(0, 0, 30, 30));
- // Adding FLAG_NOT_TOUCH_MODAL to ensure taps outside this window are not sent to this
- // window.
- mUnfocusedWindow->setFlags(WindowInfo::Flag::NOT_TOUCH_MODAL);
mFocusedWindow =
new FakeWindowHandle(application, mDispatcher, "Second", ADISPLAY_ID_DEFAULT);
mFocusedWindow->setFrame(Rect(50, 50, 100, 100));
- mFocusedWindow->setFlags(WindowInfo::Flag::NOT_TOUCH_MODAL);
// Set focused application.
mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
@@ -4097,14 +4075,10 @@
std::make_shared<FakeApplicationHandle>();
mWindow1 = new FakeWindowHandle(application, mDispatcher, "Fake Window 1",
ADISPLAY_ID_DEFAULT);
- // Adding FLAG_NOT_TOUCH_MODAL otherwise all taps will go to the top most window.
- // We also need FLAG_SPLIT_TOUCH or we won't be able to get touches for both windows.
- mWindow1->setFlags(WindowInfo::Flag::NOT_TOUCH_MODAL | WindowInfo::Flag::SPLIT_TOUCH);
mWindow1->setFrame(Rect(0, 0, 100, 100));
mWindow2 = new FakeWindowHandle(application, mDispatcher, "Fake Window 2",
ADISPLAY_ID_DEFAULT, mWindow1->getToken());
- mWindow2->setFlags(WindowInfo::Flag::NOT_TOUCH_MODAL | WindowInfo::Flag::SPLIT_TOUCH);
mWindow2->setFrame(Rect(100, 100, 200, 200));
mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mWindow1, mWindow2}}});
@@ -4301,9 +4275,6 @@
mWindow->setFrame(Rect(0, 0, 30, 30));
mWindow->setDispatchingTimeout(30ms);
mWindow->setFocusable(true);
- // Adding FLAG_NOT_TOUCH_MODAL to ensure taps outside this window are not sent to this
- // window.
- mWindow->setFlags(WindowInfo::Flag::NOT_TOUCH_MODAL);
// Set focused application.
mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, mApplication);
@@ -4751,18 +4722,13 @@
mUnfocusedWindow =
new FakeWindowHandle(mApplication, mDispatcher, "Unfocused", ADISPLAY_ID_DEFAULT);
mUnfocusedWindow->setFrame(Rect(0, 0, 30, 30));
- // Adding FLAG_NOT_TOUCH_MODAL to ensure taps outside this window are not sent to this
- // window.
// Adding FLAG_WATCH_OUTSIDE_TOUCH to receive ACTION_OUTSIDE when another window is tapped
- mUnfocusedWindow->setFlags(WindowInfo::Flag::NOT_TOUCH_MODAL |
- WindowInfo::Flag::WATCH_OUTSIDE_TOUCH |
- WindowInfo::Flag::SPLIT_TOUCH);
+ mUnfocusedWindow->setWatchOutsideTouch(true);
mFocusedWindow =
new FakeWindowHandle(mApplication, mDispatcher, "Focused", ADISPLAY_ID_DEFAULT);
mFocusedWindow->setDispatchingTimeout(30ms);
mFocusedWindow->setFrame(Rect(50, 50, 100, 100));
- mFocusedWindow->setFlags(WindowInfo::Flag::NOT_TOUCH_MODAL | WindowInfo::Flag::SPLIT_TOUCH);
// Set focused application.
mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, mApplication);
@@ -5496,7 +5462,7 @@
sp<FakeWindowHandle> getOccludingWindow(int32_t uid, std::string name, TouchOcclusionMode mode,
float alpha = 1.0f) {
sp<FakeWindowHandle> window = getWindow(uid, name);
- window->setFlags(WindowInfo::Flag::NOT_TOUCHABLE);
+ window->setTouchable(false);
window->setTouchOcclusionMode(mode);
window->setAlpha(alpha);
return window;
@@ -5610,7 +5576,7 @@
WindowWithZeroOpacityAndWatchOutside_ReceivesOutsideEvent) {
const sp<FakeWindowHandle>& w =
getOccludingWindow(APP_B_UID, "B", TouchOcclusionMode::BLOCK_UNTRUSTED, 0.0f);
- w->addFlags(WindowInfo::Flag::WATCH_OUTSIDE_TOUCH);
+ w->setWatchOutsideTouch(true);
mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {w, mTouchWindow}}});
touch();
@@ -5621,7 +5587,7 @@
TEST_F(InputDispatcherUntrustedTouchesTest, OutsideEvent_HasZeroCoordinates) {
const sp<FakeWindowHandle>& w =
getOccludingWindow(APP_B_UID, "B", TouchOcclusionMode::BLOCK_UNTRUSTED, 0.0f);
- w->addFlags(WindowInfo::Flag::WATCH_OUTSIDE_TOUCH);
+ w->setWatchOutsideTouch(true);
mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {w, mTouchWindow}}});
touch();
@@ -5871,11 +5837,9 @@
mApp = std::make_shared<FakeApplicationHandle>();
mWindow = new FakeWindowHandle(mApp, mDispatcher, "TestWindow", ADISPLAY_ID_DEFAULT);
mWindow->setFrame(Rect(0, 0, 100, 100));
- mWindow->setFlags(WindowInfo::Flag::NOT_TOUCH_MODAL);
mSecondWindow = new FakeWindowHandle(mApp, mDispatcher, "TestWindow2", ADISPLAY_ID_DEFAULT);
mSecondWindow->setFrame(Rect(100, 0, 200, 100));
- mSecondWindow->setFlags(WindowInfo::Flag::NOT_TOUCH_MODAL);
mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, mApp);
mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mWindow, mSecondWindow}}});
@@ -6130,7 +6094,7 @@
ADISPLAY_ID_DEFAULT);
obscuringWindow->setFrame(Rect(0, 0, 50, 50));
obscuringWindow->setOwnerInfo(111, 111);
- obscuringWindow->setFlags(WindowInfo::Flag::NOT_TOUCHABLE);
+ obscuringWindow->setTouchable(false);
std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
sp<FakeWindowHandle> window =
new FakeWindowHandle(application, mDispatcher, "Test window", ADISPLAY_ID_DEFAULT);
@@ -6176,7 +6140,7 @@
ADISPLAY_ID_DEFAULT);
obscuringWindow->setFrame(Rect(0, 0, 50, 50));
obscuringWindow->setOwnerInfo(111, 111);
- obscuringWindow->setFlags(WindowInfo::Flag::NOT_TOUCHABLE);
+ obscuringWindow->setTouchable(false);
std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
sp<FakeWindowHandle> window =
new FakeWindowHandle(application, mDispatcher, "Test window", ADISPLAY_ID_DEFAULT);
@@ -6282,7 +6246,7 @@
class InputDispatcherSpyWindowTest : public InputDispatcherTest {
public:
- sp<FakeWindowHandle> createSpy(const Flags<WindowInfo::Flag> flags) {
+ sp<FakeWindowHandle> createSpy() {
std::shared_ptr<FakeApplicationHandle> application =
std::make_shared<FakeApplicationHandle>();
std::string name = "Fake Spy ";
@@ -6291,7 +6255,6 @@
new FakeWindowHandle(application, mDispatcher, name.c_str(), ADISPLAY_ID_DEFAULT);
spy->setInputFeatures(WindowInfo::Feature::SPY);
spy->setTrustedOverlay(true);
- spy->addFlags(flags);
return spy;
}
@@ -6300,7 +6263,6 @@
std::make_shared<FakeApplicationHandle>();
sp<FakeWindowHandle> window =
new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
- window->addFlags(WindowInfo::Flag::NOT_TOUCH_MODAL | WindowInfo::Flag::SPLIT_TOUCH);
window->setFocusable(true);
return window;
}
@@ -6316,7 +6278,7 @@
TEST_F(InputDispatcherSpyWindowDeathTest, UntrustedSpy_AbortsDispatcher) {
ScopedSilentDeath _silentDeath;
- auto spy = createSpy(WindowInfo::Flag::NOT_TOUCH_MODAL);
+ auto spy = createSpy();
spy->setTrustedOverlay(false);
ASSERT_DEATH(mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {spy}}}),
".* not a trusted overlay");
@@ -6326,7 +6288,7 @@
* Input injection into a display with a spy window but no foreground windows should succeed.
*/
TEST_F(InputDispatcherSpyWindowTest, NoForegroundWindow) {
- auto spy = createSpy(WindowInfo::Flag::NOT_TOUCH_MODAL);
+ auto spy = createSpy();
mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {spy}}});
ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
@@ -6349,9 +6311,9 @@
*/
TEST_F(InputDispatcherSpyWindowTest, ReceivesInputInOrder) {
auto window = createForeground();
- auto spy1 = createSpy(WindowInfo::Flag::NOT_TOUCH_MODAL);
- auto spy2 = createSpy(WindowInfo::Flag::NOT_TOUCH_MODAL);
- auto spy3 = createSpy(WindowInfo::Flag::NOT_TOUCH_MODAL);
+ auto spy1 = createSpy();
+ auto spy2 = createSpy();
+ auto spy3 = createSpy();
mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {spy1, spy2, window, spy3}}});
const std::vector<sp<FakeWindowHandle>> channels{spy1, spy2, window, spy3};
const size_t numChannels = channels.size();
@@ -6402,7 +6364,8 @@
*/
TEST_F(InputDispatcherSpyWindowTest, NotTouchable) {
auto window = createForeground();
- auto spy = createSpy(WindowInfo::Flag::NOT_TOUCHABLE);
+ auto spy = createSpy();
+ spy->setTouchable(false);
mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {spy, window}}});
ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
@@ -6419,7 +6382,7 @@
*/
TEST_F(InputDispatcherSpyWindowTest, TouchableRegion) {
auto window = createForeground();
- auto spy = createSpy(WindowInfo::Flag::NOT_TOUCH_MODAL);
+ auto spy = createSpy();
spy->setTouchableRegion(Region{{0, 0, 20, 20}});
mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {spy, window}}});
@@ -6445,32 +6408,14 @@
}
/**
- * A spy window that is a modal window will receive gestures outside of its frame and touchable
- * region.
- */
-TEST_F(InputDispatcherSpyWindowTest, ModalWindow) {
- auto window = createForeground();
- auto spy = createSpy(static_cast<WindowInfo::Flag>(0));
- // This spy window does not have the NOT_TOUCH_MODAL flag set.
- spy->setFrame(Rect{0, 0, 20, 20});
- mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {spy, window}}});
-
- // Inject an event outside the spy window's frame and touchable region.
- ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
- injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT))
- << "Inject motion event should return InputEventInjectionResult::SUCCEEDED";
- window->consumeMotionDown();
- spy->consumeMotionDown();
-}
-
-/**
* A spy window can listen for touches outside its touchable region using the WATCH_OUTSIDE_TOUCHES
* flag, but it will get zero-ed out coordinates if the foreground has a different owner.
*/
TEST_F(InputDispatcherSpyWindowTest, WatchOutsideTouches) {
auto window = createForeground();
window->setOwnerInfo(12, 34);
- auto spy = createSpy(WindowInfo::Flag::NOT_TOUCH_MODAL | WindowInfo::Flag::WATCH_OUTSIDE_TOUCH);
+ auto spy = createSpy();
+ spy->setWatchOutsideTouch(true);
spy->setOwnerInfo(56, 78);
spy->setFrame(Rect{0, 0, 20, 20});
mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {spy, window}}});
@@ -6490,8 +6435,8 @@
*/
TEST_F(InputDispatcherSpyWindowTest, PilferPointers) {
auto window = createForeground();
- auto spy1 = createSpy(WindowInfo::Flag::NOT_TOUCH_MODAL);
- auto spy2 = createSpy(WindowInfo::Flag::NOT_TOUCH_MODAL);
+ auto spy1 = createSpy();
+ auto spy2 = createSpy();
mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {spy1, spy2, window}}});
ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
@@ -6523,7 +6468,7 @@
*/
TEST_F(InputDispatcherSpyWindowTest, CanPilferAfterWindowIsRemovedMidStream) {
auto window = createForeground();
- auto spy = createSpy(WindowInfo::Flag::NOT_TOUCH_MODAL);
+ auto spy = createSpy();
mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {spy, window}}});
ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
@@ -6547,9 +6492,8 @@
* the spy, but not to any other windows.
*/
TEST_F(InputDispatcherSpyWindowTest, ContinuesToReceiveGestureAfterPilfer) {
- auto spy = createSpy(WindowInfo::Flag::NOT_TOUCH_MODAL | WindowInfo::Flag::SPLIT_TOUCH);
+ auto spy = createSpy();
auto window = createForeground();
- window->setFlags(WindowInfo::Flag::NOT_TOUCH_MODAL | WindowInfo::Flag::SPLIT_TOUCH);
mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {spy, window}}});
@@ -6615,7 +6559,7 @@
windowLeft->setFrame({0, 0, 100, 200});
auto windowRight = createForeground();
windowRight->setFrame({100, 0, 200, 200});
- auto spy = createSpy(WindowInfo::Flag::NOT_TOUCH_MODAL);
+ auto spy = createSpy();
spy->setFrame({0, 0, 200, 200});
mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {spy, windowLeft, windowRight}}});
@@ -6650,7 +6594,7 @@
TEST_F(InputDispatcherSpyWindowTest, ReceivesSecondPointerAsDown) {
auto window = createForeground();
window->setFrame({0, 0, 200, 200});
- auto spyRight = createSpy(WindowInfo::Flag::NOT_TOUCH_MODAL);
+ auto spyRight = createSpy();
spyRight->setFrame({100, 0, 200, 200});
mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {spyRight, window}}});
@@ -6683,15 +6627,13 @@
* windows should be allowed to control split touch.
*/
TEST_F(InputDispatcherSpyWindowTest, SplitIfNoForegroundWindowTouched) {
- // Create a touch modal spy that spies on the entire display.
- // This spy window does not set the SPLIT_TOUCH flag. However, we still expect to split touches
+ // This spy window prevents touch splitting. However, we still expect to split touches
// because a foreground window has not disabled splitting.
- auto spy = createSpy(static_cast<WindowInfo::Flag>(0));
+ auto spy = createSpy();
+ spy->setPreventSplitting(true);
- // Create a non touch modal window that supports split touch.
auto window = createForeground();
window->setFrame(Rect(0, 0, 100, 100));
- window->setFlags(WindowInfo::Flag::NOT_TOUCH_MODAL | WindowInfo::Flag::SPLIT_TOUCH);
mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {spy, window}}});
@@ -6729,7 +6671,7 @@
* do not receive key events.
*/
TEST_F(InputDispatcherSpyWindowTest, UnfocusableSpyDoesNotReceiveKeyEvents) {
- auto spy = createSpy(static_cast<WindowInfo::Flag>(0));
+ auto spy = createSpy();
spy->setFocusable(false);
auto window = createForeground();
@@ -6758,7 +6700,7 @@
ADISPLAY_ID_DEFAULT);
overlay->setFocusable(false);
overlay->setOwnerInfo(111, 111);
- overlay->setFlags(WindowInfo::Flag::NOT_TOUCHABLE | WindowInfo::Flag::SPLIT_TOUCH);
+ overlay->setTouchable(false);
overlay->setInputFeatures(WindowInfo::Feature::INTERCEPTS_STYLUS);
overlay->setTrustedOverlay(true);
@@ -6769,7 +6711,6 @@
ADISPLAY_ID_DEFAULT);
window->setFocusable(true);
window->setOwnerInfo(222, 222);
- window->setFlags(WindowInfo::Flag::SPLIT_TOUCH);
mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {overlay, window}}});
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 973029c..8081096 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -2159,8 +2159,7 @@
void Layer::fillInputFrameInfo(WindowInfo& info, const ui::Transform& screenToDisplay) {
Rect tmpBounds = getInputBounds();
if (!tmpBounds.isValid()) {
- info.flags = WindowInfo::Flag::NOT_TOUCH_MODAL | WindowInfo::Flag::NOT_FOCUSABLE;
- info.focusable = false;
+ info.setInputConfig(WindowInfo::InputConfig::NOT_FOCUSABLE, true);
info.touchableRegion.clear();
// A layer could have invalid input bounds and still expect to receive touch input if it has
// replaceTouchableRegionWithCrop. For that case, the input transform needs to be calculated
@@ -2307,7 +2306,6 @@
mDrawingState.inputInfo.ownerUid = mOwnerUid;
mDrawingState.inputInfo.ownerPid = mOwnerPid;
mDrawingState.inputInfo.inputFeatures = WindowInfo::Feature::NO_INPUT_CHANNEL;
- mDrawingState.inputInfo.flags = WindowInfo::Flag::NOT_TOUCH_MODAL;
mDrawingState.inputInfo.displayId = getLayerStack().id;
}
@@ -2325,7 +2323,9 @@
// We are just using these layers for occlusion detection in
// InputDispatcher, and obviously if they aren't visible they can't occlude
// anything.
- info.visible = hasInputInfo() ? canReceiveInput() : isVisible();
+ const bool visible = hasInputInfo() ? canReceiveInput() : isVisible();
+ info.setInputConfig(WindowInfo::InputConfig::NOT_VISIBLE, !visible);
+
info.alpha = getAlpha();
fillTouchOcclusionMode(info);
handleDropInputMode(info);
@@ -2347,8 +2347,9 @@
// Inherit the trusted state from the parent hierarchy, but don't clobber the trusted state
// if it was set by WM for a known system overlay
- info.trustedOverlay = info.trustedOverlay || isTrustedOverlay();
-
+ if (isTrustedOverlay()) {
+ info.inputConfig |= WindowInfo::InputConfig::TRUSTED_OVERLAY;
+ }
// If the layer is a clone, we need to crop the input region to cloned root to prevent
// touches from going outside the cloned area.
@@ -2480,7 +2481,7 @@
}
// Cloned layers shouldn't handle watch outside since their z order is not determined by
// WM or the client.
- mDrawingState.inputInfo.flags &= ~WindowInfo::Flag::WATCH_OUTSIDE_TOUCH;
+ mDrawingState.inputInfo.setInputConfig(WindowInfo::InputConfig::WATCH_OUTSIDE_TOUCH, false);
}
void Layer::updateClonedRelatives(const std::map<sp<Layer>, sp<Layer>>& clonedLayersMap) {
diff --git a/services/surfaceflinger/LayerProtoHelper.cpp b/services/surfaceflinger/LayerProtoHelper.cpp
index 3bd0643..0506c47 100644
--- a/services/surfaceflinger/LayerProtoHelper.cpp
+++ b/services/surfaceflinger/LayerProtoHelper.cpp
@@ -175,12 +175,12 @@
}
InputWindowInfoProto* proto = getInputWindowInfoProto();
- proto->set_layout_params_flags(inputInfo.flags.get());
+ proto->set_layout_params_flags(inputInfo.layoutParamsFlags.get());
using U = std::underlying_type_t<WindowInfo::Type>;
// TODO(b/129481165): This static assert can be safely removed once conversion warnings
// are re-enabled.
static_assert(std::is_same_v<U, int32_t>);
- proto->set_layout_params_type(static_cast<U>(inputInfo.type));
+ proto->set_layout_params_type(static_cast<U>(inputInfo.layoutParamsType));
LayerProtoHelper::writeToProto({inputInfo.frameLeft, inputInfo.frameTop, inputInfo.frameRight,
inputInfo.frameBottom},
@@ -189,9 +189,10 @@
[&]() { return proto->mutable_touchable_region(); });
proto->set_surface_inset(inputInfo.surfaceInset);
- proto->set_visible(inputInfo.visible);
- proto->set_focusable(inputInfo.focusable);
- proto->set_has_wallpaper(inputInfo.hasWallpaper);
+ using InputConfig = gui::WindowInfo::InputConfig;
+ proto->set_visible(!inputInfo.inputConfig.test(InputConfig::NOT_VISIBLE));
+ proto->set_focusable(!inputInfo.inputConfig.test(InputConfig::NOT_FOCUSABLE));
+ proto->set_has_wallpaper(inputInfo.inputConfig.test(InputConfig::DUPLICATE_TOUCH_TO_WALLPAPER));
proto->set_global_scale_factor(inputInfo.globalScaleFactor);
LayerProtoHelper::writeToProtoDeprecated(inputInfo.transform, proto->mutable_transform());
diff --git a/services/surfaceflinger/Scheduler/EventThread.cpp b/services/surfaceflinger/Scheduler/EventThread.cpp
index 2d0da46..5ba8a1b 100644
--- a/services/surfaceflinger/Scheduler/EventThread.cpp
+++ b/services/surfaceflinger/Scheduler/EventThread.cpp
@@ -87,9 +87,10 @@
to_string(event.header.displayId).c_str(),
event.hotplug.connected ? "connected" : "disconnected");
case DisplayEventReceiver::DISPLAY_EVENT_VSYNC:
- return StringPrintf("VSync{displayId=%s, count=%u, expectedVSyncTimestamp=%" PRId64 "}",
+ return StringPrintf("VSync{displayId=%s, count=%u, expectedPresentationTime=%" PRId64
+ "}",
to_string(event.header.displayId).c_str(), event.vsync.count,
- event.vsync.expectedVSyncTimestamp);
+ event.vsync.vsyncData.preferredExpectedPresentationTime());
case DisplayEventReceiver::DISPLAY_EVENT_MODE_CHANGE:
return StringPrintf("ModeChanged{displayId=%s, modeId=%u}",
to_string(event.header.displayId).c_str(), event.modeChange.modeId);
@@ -107,13 +108,19 @@
}
DisplayEventReceiver::Event makeVSync(PhysicalDisplayId displayId, nsecs_t timestamp,
- uint32_t count, nsecs_t expectedVSyncTimestamp,
+ uint32_t count, nsecs_t expectedPresentationTime,
nsecs_t deadlineTimestamp) {
DisplayEventReceiver::Event event;
event.header = {DisplayEventReceiver::DISPLAY_EVENT_VSYNC, displayId, timestamp};
event.vsync.count = count;
- event.vsync.expectedVSyncTimestamp = expectedVSyncTimestamp;
- event.vsync.deadlineTimestamp = deadlineTimestamp;
+ event.vsync.vsyncData.preferredFrameTimelineIndex = 0;
+ // Temporarily store the current vsync information in frameTimelines[0], marked as
+ // platform-preferred. When the event is dispatched later, the frame interval at that time is
+ // used with this information to generate multiple frame timeline choices.
+ event.vsync.vsyncData.frameTimelines[0] = {.vsyncId = FrameTimelineInfo::INVALID_VSYNC_ID,
+ .deadlineTimestamp = deadlineTimestamp,
+ .expectedPresentationTime =
+ expectedPresentationTime};
return event;
}
@@ -186,9 +193,10 @@
return binder::Status::ok();
}
-binder::Status EventThreadConnection::getLatestVsyncEventData(VsyncEventData* outVsyncEventData) {
+binder::Status EventThreadConnection::getLatestVsyncEventData(
+ ParcelableVsyncEventData* outVsyncEventData) {
ATRACE_CALL();
- *outVsyncEventData = mEventThread->getLatestVsyncEventData(this);
+ outVsyncEventData->vsync = mEventThread->getLatestVsyncEventData(this);
return binder::Status::ok();
}
@@ -338,10 +346,16 @@
VsyncEventData EventThread::getLatestVsyncEventData(
const sp<EventThreadConnection>& connection) const {
- nsecs_t frameInterval = mGetVsyncPeriodFunction(connection->mOwnerUid);
VsyncEventData vsyncEventData;
+ nsecs_t frameInterval = mGetVsyncPeriodFunction(connection->mOwnerUid);
vsyncEventData.frameInterval = frameInterval;
- generateFrameTimeline(vsyncEventData, frameInterval, systemTime(SYSTEM_TIME_MONOTONIC));
+ VSyncSource::VSyncData vsyncData;
+ {
+ std::lock_guard<std::mutex> lock(mMutex);
+ vsyncData = mVSyncSource->getLatestVSyncData();
+ }
+ generateFrameTimeline(vsyncEventData, frameInterval, systemTime(SYSTEM_TIME_MONOTONIC),
+ vsyncData.expectedPresentationTime, vsyncData.deadlineTimestamp);
return vsyncEventData;
}
@@ -370,7 +384,7 @@
LOG_FATAL_IF(!mVSyncState);
mPendingEvents.push_back(makeVSync(mVSyncState->displayId, timestamp, ++mVSyncState->count,
- vsyncData.expectedVSyncTimestamp,
+ vsyncData.expectedPresentationTime,
vsyncData.deadlineTimestamp));
mCondition.notify_all();
}
@@ -518,7 +532,8 @@
const sp<EventThreadConnection>& connection) const {
const auto throttleVsync = [&] {
return mThrottleVsyncCallback &&
- mThrottleVsyncCallback(event.vsync.expectedVSyncTimestamp, connection->mOwnerUid);
+ mThrottleVsyncCallback(event.vsync.vsyncData.preferredExpectedPresentationTime(),
+ connection->mOwnerUid);
};
switch (event.header.type) {
@@ -568,79 +583,49 @@
}
int64_t EventThread::generateToken(nsecs_t timestamp, nsecs_t deadlineTimestamp,
- nsecs_t expectedVSyncTimestamp) const {
+ nsecs_t expectedPresentationTime) const {
if (mTokenManager != nullptr) {
return mTokenManager->generateTokenForPredictions(
- {timestamp, deadlineTimestamp, expectedVSyncTimestamp});
+ {timestamp, deadlineTimestamp, expectedPresentationTime});
}
return FrameTimelineInfo::INVALID_VSYNC_ID;
}
-void EventThread::generateFrameTimeline(
- nsecs_t frameInterval, nsecs_t timestamp, nsecs_t preferredExpectedVSyncTimestamp,
- nsecs_t preferredDeadlineTimestamp,
- std::function<void(int64_t index)> setPreferredFrameTimelineIndex,
- std::function<void(int64_t index, int64_t vsyncId, nsecs_t expectedVSyncTimestamp,
- nsecs_t deadlineTimestamp)>
- setFrameTimeline) const {
+void EventThread::generateFrameTimeline(VsyncEventData& outVsyncEventData, nsecs_t frameInterval,
+ nsecs_t timestamp,
+ nsecs_t preferredExpectedPresentationTime,
+ nsecs_t preferredDeadlineTimestamp) const {
// Add 1 to ensure the preferredFrameTimelineIndex entry (when multiplier == 0) is included.
for (int64_t multiplier = -VsyncEventData::kFrameTimelinesLength + 1, currentIndex = 0;
currentIndex < VsyncEventData::kFrameTimelinesLength; multiplier++) {
- nsecs_t deadline = preferredDeadlineTimestamp + multiplier * frameInterval;
+ nsecs_t deadlineTimestamp = preferredDeadlineTimestamp + multiplier * frameInterval;
// Valid possible frame timelines must have future values.
- if (deadline > timestamp) {
+ if (deadlineTimestamp > timestamp) {
if (multiplier == 0) {
- setPreferredFrameTimelineIndex(currentIndex);
+ outVsyncEventData.preferredFrameTimelineIndex = currentIndex;
}
- nsecs_t expectedVSyncTimestamp =
- preferredExpectedVSyncTimestamp + multiplier * frameInterval;
- setFrameTimeline(currentIndex,
- generateToken(timestamp, deadline, expectedVSyncTimestamp),
- expectedVSyncTimestamp, deadline);
+ nsecs_t expectedPresentationTime =
+ preferredExpectedPresentationTime + multiplier * frameInterval;
+ outVsyncEventData.frameTimelines[currentIndex] =
+ {.vsyncId =
+ generateToken(timestamp, deadlineTimestamp, expectedPresentationTime),
+ .deadlineTimestamp = deadlineTimestamp,
+ .expectedPresentationTime = expectedPresentationTime};
currentIndex++;
}
}
}
-void EventThread::generateFrameTimeline(DisplayEventReceiver::Event& event) const {
- generateFrameTimeline(
- event.vsync.frameInterval, event.header.timestamp, event.vsync.expectedVSyncTimestamp,
- event.vsync.deadlineTimestamp,
- [&](int index) { event.vsync.preferredFrameTimelineIndex = index; },
- [&](int64_t index, int64_t vsyncId, nsecs_t expectedVSyncTimestamp,
- nsecs_t deadlineTimestamp) {
- event.vsync.frameTimelines[index] = {.vsyncId = vsyncId,
- .deadlineTimestamp = deadlineTimestamp,
- .expectedVSyncTimestamp =
- expectedVSyncTimestamp};
- });
-}
-
-void EventThread::generateFrameTimeline(VsyncEventData& out, const nsecs_t frameInterval,
- const nsecs_t timestamp) const {
- VSyncSource::VSyncData vsyncData;
- {
- std::lock_guard<std::mutex> lock(mMutex);
- vsyncData = mVSyncSource->getLatestVSyncData();
- }
- generateFrameTimeline(
- frameInterval, timestamp, vsyncData.expectedVSyncTimestamp, vsyncData.deadlineTimestamp,
- [&](int index) { out.preferredFrameTimelineIndex = index; },
- [&](int64_t index, int64_t vsyncId, nsecs_t expectedVSyncTimestamp,
- nsecs_t deadlineTimestamp) {
- out.frameTimelines[index] =
- VsyncEventData::FrameTimeline(vsyncId, deadlineTimestamp,
- expectedVSyncTimestamp);
- });
-}
-
void EventThread::dispatchEvent(const DisplayEventReceiver::Event& event,
const DisplayEventConsumers& consumers) {
for (const auto& consumer : consumers) {
DisplayEventReceiver::Event copy = event;
if (event.header.type == DisplayEventReceiver::DISPLAY_EVENT_VSYNC) {
- copy.vsync.frameInterval = mGetVsyncPeriodFunction(consumer->mOwnerUid);
- generateFrameTimeline(copy);
+ const int64_t frameInterval = mGetVsyncPeriodFunction(consumer->mOwnerUid);
+ copy.vsync.vsyncData.frameInterval = frameInterval;
+ generateFrameTimeline(copy.vsync.vsyncData, frameInterval, copy.header.timestamp,
+ event.vsync.vsyncData.preferredExpectedPresentationTime(),
+ event.vsync.vsyncData.preferredDeadlineTimestamp());
}
switch (consumer->postEvent(copy)) {
case NO_ERROR:
diff --git a/services/surfaceflinger/Scheduler/EventThread.h b/services/surfaceflinger/Scheduler/EventThread.h
index a858169..c406478 100644
--- a/services/surfaceflinger/Scheduler/EventThread.h
+++ b/services/surfaceflinger/Scheduler/EventThread.h
@@ -45,6 +45,7 @@
class TokenManager;
} // namespace frametimeline
+using gui::ParcelableVsyncEventData;
using gui::VsyncEventData;
// ---------------------------------------------------------------------------
@@ -66,7 +67,7 @@
public:
class VSyncData {
public:
- nsecs_t expectedVSyncTimestamp;
+ nsecs_t expectedPresentationTime;
nsecs_t deadlineTimestamp;
};
@@ -99,7 +100,7 @@
binder::Status stealReceiveChannel(gui::BitTube* outChannel) override;
binder::Status setVsyncRate(int rate) override;
binder::Status requestNextVsync() override; // asynchronous
- binder::Status getLatestVsyncEventData(VsyncEventData* outVsyncEventData) override;
+ binder::Status getLatestVsyncEventData(ParcelableVsyncEventData* outVsyncEventData) override;
// Called in response to requestNextVsync.
const ResyncCallback resyncCallback;
@@ -217,17 +218,10 @@
void onVSyncEvent(nsecs_t timestamp, VSyncSource::VSyncData vsyncData) override;
int64_t generateToken(nsecs_t timestamp, nsecs_t deadlineTimestamp,
- nsecs_t expectedVSyncTimestamp) const;
- void generateFrameTimeline(DisplayEventReceiver::Event& event) const;
- void generateFrameTimeline(VsyncEventData& out, const nsecs_t frameInterval,
- const nsecs_t timestamp) const;
- void generateFrameTimeline(
- nsecs_t frameInterval, nsecs_t timestamp, nsecs_t preferredExpectedVSyncTimestamp,
- nsecs_t preferredDeadlineTimestamp,
- std::function<void(int64_t index)> setPreferredFrameTimelineIndex,
- std::function<void(int64_t index, int64_t vsyncId, nsecs_t expectedVSyncTimestamp,
- nsecs_t deadlineTimestamp)>
- setFrameTimeline) const;
+ nsecs_t expectedPresentationTime) const;
+ void generateFrameTimeline(VsyncEventData& outVsyncEventData, nsecs_t frameInterval,
+ nsecs_t timestamp, nsecs_t preferredExpectedPresentationTime,
+ nsecs_t preferredDeadlineTimestamp) const;
const std::unique_ptr<VSyncSource> mVSyncSource GUARDED_BY(mMutex);
frametimeline::TokenManager* const mTokenManager;
diff --git a/services/surfaceflinger/Scheduler/MessageQueue.cpp b/services/surfaceflinger/Scheduler/MessageQueue.cpp
index a020e2c..712cd5b 100644
--- a/services/surfaceflinger/Scheduler/MessageQueue.cpp
+++ b/services/surfaceflinger/Scheduler/MessageQueue.cpp
@@ -191,7 +191,8 @@
for (int i = 0; i < n; i++) {
if (buffer[i].header.type == DisplayEventReceiver::DISPLAY_EVENT_VSYNC) {
auto& vsync = buffer[i].vsync;
- mHandler->dispatchFrame(vsync.vsyncId, vsync.expectedVSyncTimestamp);
+ mHandler->dispatchFrame(vsync.vsyncData.preferredVsyncId(),
+ vsync.vsyncData.preferredExpectedPresentationTime());
break;
}
}
diff --git a/services/surfaceflinger/Tracing/TransactionProtoParser.cpp b/services/surfaceflinger/Tracing/TransactionProtoParser.cpp
index fb5a6b3..1e5c3e7 100644
--- a/services/surfaceflinger/Tracing/TransactionProtoParser.cpp
+++ b/services/surfaceflinger/Tracing/TransactionProtoParser.cpp
@@ -197,13 +197,16 @@
if (layer.windowInfoHandle) {
const gui::WindowInfo* inputInfo = layer.windowInfoHandle->getInfo();
proto::LayerState_WindowInfo* windowInfoProto = proto.mutable_window_info_handle();
- windowInfoProto->set_layout_params_flags(inputInfo->flags.get());
- windowInfoProto->set_layout_params_type(static_cast<int32_t>(inputInfo->type));
+ windowInfoProto->set_layout_params_flags(inputInfo->layoutParamsFlags.get());
+ windowInfoProto->set_layout_params_type(
+ static_cast<int32_t>(inputInfo->layoutParamsType));
LayerProtoHelper::writeToProto(inputInfo->touchableRegion,
windowInfoProto->mutable_touchable_region());
windowInfoProto->set_surface_inset(inputInfo->surfaceInset);
- windowInfoProto->set_focusable(inputInfo->focusable);
- windowInfoProto->set_has_wallpaper(inputInfo->hasWallpaper);
+ windowInfoProto->set_focusable(
+ !inputInfo->inputConfig.test(gui::WindowInfo::InputConfig::NOT_FOCUSABLE));
+ windowInfoProto->set_has_wallpaper(inputInfo->inputConfig.test(
+ gui::WindowInfo::InputConfig::DUPLICATE_TOUCH_TO_WALLPAPER));
windowInfoProto->set_global_scale_factor(inputInfo->globalScaleFactor);
proto::LayerState_Transform* transformProto = windowInfoProto->mutable_transform();
transformProto->set_dsdx(inputInfo->transform.dsdx());
@@ -472,13 +475,17 @@
gui::WindowInfo inputInfo;
const proto::LayerState_WindowInfo& windowInfoProto = proto.window_info_handle();
- inputInfo.flags = static_cast<gui::WindowInfo::Flag>(windowInfoProto.layout_params_flags());
- inputInfo.type = static_cast<gui::WindowInfo::Type>(windowInfoProto.layout_params_type());
+ inputInfo.layoutParamsFlags =
+ static_cast<gui::WindowInfo::Flag>(windowInfoProto.layout_params_flags());
+ inputInfo.layoutParamsType =
+ static_cast<gui::WindowInfo::Type>(windowInfoProto.layout_params_type());
LayerProtoHelper::readFromProto(windowInfoProto.touchable_region(),
inputInfo.touchableRegion);
inputInfo.surfaceInset = windowInfoProto.surface_inset();
- inputInfo.focusable = windowInfoProto.focusable();
- inputInfo.hasWallpaper = windowInfoProto.has_wallpaper();
+ inputInfo.setInputConfig(gui::WindowInfo::InputConfig::NOT_FOCUSABLE,
+ !windowInfoProto.focusable());
+ inputInfo.setInputConfig(gui::WindowInfo::InputConfig::DUPLICATE_TOUCH_TO_WALLPAPER,
+ windowInfoProto.has_wallpaper());
inputInfo.globalScaleFactor = windowInfoProto.global_scale_factor();
const proto::LayerState_Transform& transformProto = windowInfoProto.transform();
inputInfo.transform.set(transformProto.dsdx(), transformProto.dtdx(), transformProto.dtdy(),
diff --git a/services/surfaceflinger/tests/DisplayEventReceiver_test.cpp b/services/surfaceflinger/tests/DisplayEventReceiver_test.cpp
index 01adbc8..0e54664 100644
--- a/services/surfaceflinger/tests/DisplayEventReceiver_test.cpp
+++ b/services/surfaceflinger/tests/DisplayEventReceiver_test.cpp
@@ -28,23 +28,24 @@
TEST_F(DisplayEventReceiverTest, getLatestVsyncEventData) {
const nsecs_t now = systemTime();
- VsyncEventData vsyncEventData;
- EXPECT_EQ(NO_ERROR, mDisplayEventReceiver.getLatestVsyncEventData(&vsyncEventData));
+ ParcelableVsyncEventData parcelableVsyncEventData;
+ EXPECT_EQ(NO_ERROR, mDisplayEventReceiver.getLatestVsyncEventData(&parcelableVsyncEventData));
+ const VsyncEventData& vsyncEventData = parcelableVsyncEventData.vsync;
EXPECT_NE(std::numeric_limits<size_t>::max(), vsyncEventData.preferredFrameTimelineIndex);
EXPECT_GT(vsyncEventData.frameTimelines[0].deadlineTimestamp, now)
<< "Deadline timestamp should be greater than frame time";
- for (size_t i = 0; i < vsyncEventData.frameTimelines.size(); i++) {
- EXPECT_NE(FrameTimelineInfo::INVALID_VSYNC_ID, vsyncEventData.frameTimelines[i].id);
- EXPECT_GT(vsyncEventData.frameTimelines[i].expectedPresentTime,
+ for (size_t i = 0; i < VsyncEventData::kFrameTimelinesLength; i++) {
+ EXPECT_NE(FrameTimelineInfo::INVALID_VSYNC_ID, vsyncEventData.frameTimelines[i].vsyncId);
+ EXPECT_GT(vsyncEventData.frameTimelines[i].expectedPresentationTime,
vsyncEventData.frameTimelines[i].deadlineTimestamp)
<< "Expected vsync timestamp should be greater than deadline";
if (i > 0) {
EXPECT_GT(vsyncEventData.frameTimelines[i].deadlineTimestamp,
vsyncEventData.frameTimelines[i - 1].deadlineTimestamp)
<< "Deadline timestamp out of order for frame timeline " << i;
- EXPECT_GT(vsyncEventData.frameTimelines[i].expectedPresentTime,
- vsyncEventData.frameTimelines[i - 1].expectedPresentTime)
+ EXPECT_GT(vsyncEventData.frameTimelines[i].expectedPresentationTime,
+ vsyncEventData.frameTimelines[i - 1].expectedPresentationTime)
<< "Expected vsync timestamp out of order for frame timeline " << i;
}
}
diff --git a/services/surfaceflinger/tests/LayerCallback_test.cpp b/services/surfaceflinger/tests/LayerCallback_test.cpp
index 5c16fee..8a2305b 100644
--- a/services/surfaceflinger/tests/LayerCallback_test.cpp
+++ b/services/surfaceflinger/tests/LayerCallback_test.cpp
@@ -141,11 +141,12 @@
continue;
}
- vsync = {event.vsync.vsyncId, event.vsync.expectedVSyncTimestamp};
+ vsync = {event.vsync.vsyncData.preferredVsyncId(),
+ event.vsync.vsyncData.preferredExpectedPresentationTime()};
}
EXPECT_GE(vsync.vsyncId, 1);
- EXPECT_GT(event.vsync.expectedVSyncTimestamp, systemTime());
+ EXPECT_GT(vsync.expectedPresentTime, systemTime());
return vsync;
}
diff --git a/services/surfaceflinger/tests/unittests/DispSyncSourceTest.cpp b/services/surfaceflinger/tests/unittests/DispSyncSourceTest.cpp
index 0b6b475..ec27eda 100644
--- a/services/surfaceflinger/tests/unittests/DispSyncSourceTest.cpp
+++ b/services/surfaceflinger/tests/unittests/DispSyncSourceTest.cpp
@@ -229,7 +229,7 @@
ASSERT_TRUE(callbackData.has_value());
const auto [when, vsyncData] = callbackData.value();
EXPECT_EQ(when,
- vsyncData.expectedVSyncTimestamp - mWorkDuration.count() -
+ vsyncData.expectedPresentationTime - mWorkDuration.count() -
mReadyDuration.count());
}
}
@@ -261,7 +261,7 @@
ASSERT_TRUE(callbackData.has_value());
const auto [when, vsyncData] = callbackData.value();
EXPECT_EQ(when,
- vsyncData.expectedVSyncTimestamp - mWorkDuration.count() -
+ vsyncData.expectedPresentationTime - mWorkDuration.count() -
mReadyDuration.count());
}
@@ -283,7 +283,7 @@
const auto callbackData = mVSyncEventCallRecorder.waitForCall();
ASSERT_TRUE(callbackData.has_value());
const auto [when, vsyncData] = callbackData.value();
- EXPECT_EQ(when, vsyncData.expectedVSyncTimestamp - newDuration.count());
+ EXPECT_EQ(when, vsyncData.expectedPresentationTime - newDuration.count());
}
EXPECT_CALL(*mVSyncDispatch, cancel(_)).Times(1);
@@ -307,9 +307,9 @@
const auto vsyncData = mDispSyncSource->getLatestVSyncData();
ASSERT_GT(vsyncData.deadlineTimestamp, now);
- ASSERT_GT(vsyncData.expectedVSyncTimestamp, vsyncData.deadlineTimestamp);
+ ASSERT_GT(vsyncData.expectedPresentationTime, vsyncData.deadlineTimestamp);
EXPECT_EQ(vsyncData.deadlineTimestamp,
- vsyncData.expectedVSyncTimestamp - vsyncInternalDuration);
+ vsyncData.expectedPresentationTime - vsyncInternalDuration);
}
} // namespace
diff --git a/services/surfaceflinger/tests/unittests/EventThreadTest.cpp b/services/surfaceflinger/tests/unittests/EventThreadTest.cpp
index cc0a40f..14d8f98 100644
--- a/services/surfaceflinger/tests/unittests/EventThreadTest.cpp
+++ b/services/surfaceflinger/tests/unittests/EventThreadTest.cpp
@@ -99,7 +99,7 @@
nsecs_t expectedTimestamp, unsigned expectedCount);
void expectVsyncEventReceivedByConnection(nsecs_t expectedTimestamp, unsigned expectedCount);
void expectVsyncEventFrameTimelinesCorrect(nsecs_t expectedTimestamp,
- nsecs_t preferredDeadline);
+ VSyncSource::VSyncData preferredVsyncData);
void expectHotplugEventReceivedByConnection(PhysicalDisplayId expectedDisplayId,
bool expectedConnected);
void expectConfigChangedEventReceivedByConnection(PhysicalDisplayId expectedDisplayId,
@@ -252,40 +252,42 @@
expectedCount);
}
-void EventThreadTest::expectVsyncEventFrameTimelinesCorrect(nsecs_t expectedTimestamp,
- nsecs_t preferredDeadline) {
+void EventThreadTest::expectVsyncEventFrameTimelinesCorrect(
+ nsecs_t expectedTimestamp, VSyncSource::VSyncData preferredVsyncData) {
auto args = mConnectionEventCallRecorder.waitForCall();
ASSERT_TRUE(args.has_value()) << " did not receive an event for timestamp "
<< expectedTimestamp;
const auto& event = std::get<0>(args.value());
for (int i = 0; i < VsyncEventData::kFrameTimelinesLength; i++) {
- auto prediction =
- mTokenManager->getPredictionsForToken(event.vsync.frameTimelines[i].vsyncId);
+ auto prediction = mTokenManager->getPredictionsForToken(
+ event.vsync.vsyncData.frameTimelines[i].vsyncId);
EXPECT_TRUE(prediction.has_value());
- EXPECT_EQ(prediction.value().endTime, event.vsync.frameTimelines[i].deadlineTimestamp)
+ EXPECT_EQ(prediction.value().endTime,
+ event.vsync.vsyncData.frameTimelines[i].deadlineTimestamp)
<< "Deadline timestamp does not match cached value";
EXPECT_EQ(prediction.value().presentTime,
- event.vsync.frameTimelines[i].expectedVSyncTimestamp)
- << "Expected vsync timestamp does not match cached value";
+ event.vsync.vsyncData.frameTimelines[i].expectedPresentationTime)
+ << "Expected vsync.vsyncData timestamp does not match cached value";
if (i > 0) {
- EXPECT_GT(event.vsync.frameTimelines[i].deadlineTimestamp,
- event.vsync.frameTimelines[i - 1].deadlineTimestamp)
+ EXPECT_GT(event.vsync.vsyncData.frameTimelines[i].deadlineTimestamp,
+ event.vsync.vsyncData.frameTimelines[i - 1].deadlineTimestamp)
<< "Deadline timestamp out of order for frame timeline " << i;
- EXPECT_GT(event.vsync.frameTimelines[i].expectedVSyncTimestamp,
- event.vsync.frameTimelines[i - 1].expectedVSyncTimestamp)
- << "Expected vsync timestamp out of order for frame timeline " << i;
+ EXPECT_GT(event.vsync.vsyncData.frameTimelines[i].expectedPresentationTime,
+ event.vsync.vsyncData.frameTimelines[i - 1].expectedPresentationTime)
+ << "Expected vsync.vsyncData timestamp out of order for frame timeline " << i;
}
// Vsync ID order lines up with registration into test token manager.
- EXPECT_EQ(i, event.vsync.frameTimelines[i].vsyncId)
+ EXPECT_EQ(i, event.vsync.vsyncData.frameTimelines[i].vsyncId)
<< "Vsync ID incorrect for frame timeline " << i;
- if (i == event.vsync.preferredFrameTimelineIndex) {
- EXPECT_EQ(event.vsync.frameTimelines[i].deadlineTimestamp, preferredDeadline)
+ if (i == event.vsync.vsyncData.preferredFrameTimelineIndex) {
+ EXPECT_EQ(event.vsync.vsyncData.frameTimelines[i].deadlineTimestamp,
+ preferredVsyncData.deadlineTimestamp)
<< "Preferred deadline timestamp incorrect" << i;
- EXPECT_EQ(event.vsync.frameTimelines[i].expectedVSyncTimestamp,
- event.vsync.expectedVSyncTimestamp)
- << "Preferred expected vsync timestamp incorrect" << i;
+ EXPECT_EQ(event.vsync.vsyncData.frameTimelines[i].expectedPresentationTime,
+ preferredVsyncData.expectedPresentationTime)
+ << "Preferred expected vsync.vsyncData timestamp incorrect" << i;
}
}
}
@@ -397,16 +399,17 @@
// Use the received callback to signal a vsync event.
// The interceptor should receive the event, as well as the connection.
- mCallback->onVSyncEvent(123, {456, 789});
+ VSyncSource::VSyncData vsyncData = {456, 789};
+ mCallback->onVSyncEvent(123, vsyncData);
expectInterceptCallReceived(123);
- expectVsyncEventFrameTimelinesCorrect(123, 789);
+ expectVsyncEventFrameTimelinesCorrect(123, vsyncData);
}
TEST_F(EventThreadTest, getLatestVsyncEventData) {
const nsecs_t now = systemTime();
const nsecs_t preferredDeadline = now + 10000000;
- const nsecs_t preferredExpectedVSyncTimestamp = now + 20000000;
- const VSyncSource::VSyncData preferredData = {preferredExpectedVSyncTimestamp,
+ const nsecs_t preferredExpectedPresentationTime = now + 20000000;
+ const VSyncSource::VSyncData preferredData = {preferredExpectedPresentationTime,
preferredDeadline};
EXPECT_CALL(*mVSyncSource, getLatestVSyncData()).WillOnce(Return(preferredData));
@@ -415,14 +418,14 @@
<< "Deadline timestamp should be greater than frame time";
for (size_t i = 0; i < VsyncEventData::kFrameTimelinesLength; i++) {
auto prediction =
- mTokenManager->getPredictionsForToken(vsyncEventData.frameTimelines[i].id);
+ mTokenManager->getPredictionsForToken(vsyncEventData.frameTimelines[i].vsyncId);
EXPECT_TRUE(prediction.has_value());
EXPECT_EQ(prediction.value().endTime, vsyncEventData.frameTimelines[i].deadlineTimestamp)
<< "Deadline timestamp does not match cached value";
EXPECT_EQ(prediction.value().presentTime,
- vsyncEventData.frameTimelines[i].expectedPresentTime)
+ vsyncEventData.frameTimelines[i].expectedPresentationTime)
<< "Expected vsync timestamp does not match cached value";
- EXPECT_GT(vsyncEventData.frameTimelines[i].expectedPresentTime,
+ EXPECT_GT(vsyncEventData.frameTimelines[i].expectedPresentationTime,
vsyncEventData.frameTimelines[i].deadlineTimestamp)
<< "Expected vsync timestamp should be greater than deadline";
@@ -430,19 +433,19 @@
EXPECT_GT(vsyncEventData.frameTimelines[i].deadlineTimestamp,
vsyncEventData.frameTimelines[i - 1].deadlineTimestamp)
<< "Deadline timestamp out of order for frame timeline " << i;
- EXPECT_GT(vsyncEventData.frameTimelines[i].expectedPresentTime,
- vsyncEventData.frameTimelines[i - 1].expectedPresentTime)
+ EXPECT_GT(vsyncEventData.frameTimelines[i].expectedPresentationTime,
+ vsyncEventData.frameTimelines[i - 1].expectedPresentationTime)
<< "Expected vsync timestamp out of order for frame timeline " << i;
}
// Vsync ID order lines up with registration into test token manager.
- EXPECT_EQ(i, vsyncEventData.frameTimelines[i].id)
+ EXPECT_EQ(i, vsyncEventData.frameTimelines[i].vsyncId)
<< "Vsync ID incorrect for frame timeline " << i;
if (i == vsyncEventData.preferredFrameTimelineIndex) {
EXPECT_EQ(vsyncEventData.frameTimelines[i].deadlineTimestamp, preferredDeadline)
<< "Preferred deadline timestamp incorrect" << i;
- EXPECT_EQ(vsyncEventData.frameTimelines[i].expectedPresentTime,
- preferredExpectedVSyncTimestamp)
+ EXPECT_EQ(vsyncEventData.frameTimelines[i].expectedPresentationTime,
+ preferredExpectedPresentationTime)
<< "Preferred expected vsync timestamp incorrect" << i;
}
}