diff options
-rw-r--r-- | libs/gui/WindowInfo.cpp | 59 | ||||
-rw-r--r-- | libs/gui/include/gui/WindowInfo.h | 48 | ||||
-rw-r--r-- | libs/gui/tests/EndToEndNativeInputTest.cpp | 25 | ||||
-rw-r--r-- | libs/gui/tests/WindowInfo_test.cpp | 18 | ||||
-rw-r--r-- | services/inputflinger/benchmarks/InputDispatcher_benchmarks.cpp | 5 | ||||
-rw-r--r-- | services/inputflinger/dispatcher/FocusResolver.cpp | 4 | ||||
-rw-r--r-- | services/inputflinger/dispatcher/InputDispatcher.cpp | 88 | ||||
-rw-r--r-- | services/inputflinger/dispatcher/TouchState.cpp | 6 | ||||
-rw-r--r-- | services/inputflinger/tests/FocusResolver_test.cpp | 12 | ||||
-rw-r--r-- | services/inputflinger/tests/InputDispatcher_test.cpp | 241 | ||||
-rw-r--r-- | services/surfaceflinger/Layer.cpp | 17 | ||||
-rw-r--r-- | services/surfaceflinger/LayerProtoHelper.cpp | 11 | ||||
-rw-r--r-- | services/surfaceflinger/Tracing/TransactionProtoParser.cpp | 23 |
13 files changed, 320 insertions, 237 deletions
diff --git a/libs/gui/WindowInfo.cpp b/libs/gui/WindowInfo.cpp index a8667867b2..2c25e7e2ac 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::frameContainsPoint(int32_t x, int32_t y) const { } bool WindowInfo::supportsSplitTouch() const { - return flags.test(Flag::SPLIT_TOUCH); + return inputConfig.test(InputConfig::SPLIT_TOUCH); } bool WindowInfo::isSpy() const { @@ -58,20 +65,19 @@ bool WindowInfo::overlaps(const WindowInfo* other) const { } 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 @@ status_t WindowInfo::writeToParcel(android::Parcel* parcel) const { } 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 @@ status_t WindowInfo::writeToParcel(android::Parcel* parcel) const { 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 @@ status_t WindowInfo::readFromParcel(const android::Parcel* parcel) { 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 @@ status_t WindowInfo::readFromParcel(const android::Parcel* parcel) { 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 @@ status_t WindowInfo::readFromParcel(const android::Parcel* parcel) { 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/include/gui/WindowInfo.h b/libs/gui/include/gui/WindowInfo.h index eb64ac9b25..1b3419a25b 100644 --- a/libs/gui/include/gui/WindowInfo.h +++ b/libs/gui/include/gui/WindowInfo.h @@ -151,6 +151,34 @@ struct WindowInfo : public Parcelable { // 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, + NOT_TOUCH_MODAL = 1 << 3, + SPLIT_TOUCH = 1 << 4, + DUPLICATE_TOUCH_TO_WALLPAPER = 1 << 5, + IS_WALLPAPER = 1 << 6, + PAUSE_DISPATCHING = 1 << 7, + // 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 << 8, + WATCH_OUTSIDE_TOUCH = 1 << 9, + SLIPPERY = 1 << 10, + // clang-format on + }; + /* These values are filled in by the WM and passed through SurfaceFlinger * unless specified otherwise. */ @@ -164,8 +192,6 @@ struct WindowInfo : public Parcelable { // 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 +224,24 @@ struct WindowInfo : public Parcelable { * 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/EndToEndNativeInputTest.cpp b/libs/gui/tests/EndToEndNativeInputTest.cpp index 06a0acae49..1151aa3f0f 100644 --- a/libs/gui/tests/EndToEndNativeInputTest.cpp +++ b/libs/gui/tests/EndToEndNativeInputTest.cpp @@ -266,13 +266,10 @@ private: 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.setInputConfig(WindowInfo::InputConfig::NOT_TOUCH_MODAL, true); + mInputInfo.setInputConfig(WindowInfo::InputConfig::NOT_VISIBLE, false); mInputInfo.touchableRegion.orSelf(Rect(0, 0, width, height)); @@ -750,7 +747,7 @@ TEST_F(InputSurfacesTest, touch_flag_obscured) { // 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 +767,8 @@ TEST_F(InputSurfacesTest, touch_flag_partially_obscured_with_crop) { // 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 +791,8 @@ TEST_F(InputSurfacesTest, touch_not_obscured_with_crop) { // 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 +812,7 @@ TEST_F(InputSurfacesTest, touch_not_obscured_with_zero_sized_bql) { 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 +827,7 @@ TEST_F(InputSurfacesTest, touch_not_obscured_with_zero_sized_blast) { 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 +880,7 @@ TEST_F(InputSurfacesTest, strict_unobscured_input_obscured_window) { [&](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 +899,7 @@ TEST_F(InputSurfacesTest, strict_unobscured_input_partially_obscured_window) { [&](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/WindowInfo_test.cpp b/libs/gui/tests/WindowInfo_test.cpp index ff3ba2aae0..ff9bae2800 100644 --- a/libs/gui/tests/WindowInfo_test.cpp +++ b/libs/gui/tests/WindowInfo_test.cpp @@ -49,8 +49,8 @@ TEST(WindowInfo, Parcelling) { 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 @@ TEST(WindowInfo, Parcelling) { 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 @@ TEST(WindowInfo, Parcelling) { 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 @@ TEST(WindowInfo, Parcelling) { 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/services/inputflinger/benchmarks/InputDispatcher_benchmarks.cpp b/services/inputflinger/benchmarks/InputDispatcher_benchmarks.cpp index 41e9ce2e41..cd20a646a7 100644 --- a/services/inputflinger/benchmarks/InputDispatcher_benchmarks.cpp +++ b/services/inputflinger/benchmarks/InputDispatcher_benchmarks.cpp @@ -193,7 +193,6 @@ public: 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 @@ public: 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 600f02ba80..a02b3e8779 100644 --- a/services/inputflinger/dispatcher/FocusResolver.cpp +++ b/services/inputflinger/dispatcher/FocusResolver.cpp @@ -148,11 +148,11 @@ FocusResolver::Focusability FocusResolver::isTokenFocusable( 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 7062aefc0d..a26256318a 100644 --- a/services/inputflinger/dispatcher/InputDispatcher.cpp +++ b/services/inputflinger/dispatcher/InputDispatcher.cpp @@ -500,16 +500,17 @@ bool isUserActivityEvent(const EventEntry& eventEntry) { // 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); + const bool isModalWindow = !inputConfig.test(WindowInfo::InputConfig::NOT_FOCUSABLE) && + !inputConfig.test(WindowInfo::InputConfig::NOT_TOUCH_MODAL); if (!isModalWindow && !windowInfo.touchableRegionContainsPoint(x, y)) { return false; } @@ -1047,7 +1048,8 @@ sp<WindowInfoHandle> InputDispatcher::findTouchedWindowAtLocked(int32_t displayI 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 +1902,8 @@ InputEventInjectionResult InputDispatcher::findFocusedWindowTargetsLocked( 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 +2104,7 @@ InputEventInjectionResult InputDispatcher::findTouchedWindowTargetsLocked( 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 +2327,16 @@ InputEventInjectionResult InputDispatcher::findTouchedWindowTargetsLocked( 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 +2605,10 @@ static bool canBeObscuredBy(const sp<WindowInfoHandle>& windowHandle, } 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 +2620,7 @@ static bool canBeObscuredBy(const sp<WindowInfoHandle>& windowHandle, // 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 +2701,17 @@ InputDispatcher::TouchOcclusionInfo InputDispatcher::computeTouchOcclusionInfoLo 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 +4579,9 @@ void InputDispatcher::updateWindowHandlesForDisplayLocked( 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 +4652,16 @@ void InputDispatcher::setInputWindowsLocked( } // 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 +4711,8 @@ void InputDispatcher::setInputWindowsLocked( // 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 +5207,27 @@ void InputDispatcher::dumpDispatchStateLocked(std::string& dump) { 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 b63fe104fa..61e78ccbe4 100644 --- a/services/inputflinger/dispatcher/TouchState.cpp +++ b/services/inputflinger/dispatcher/TouchState.cpp @@ -100,7 +100,8 @@ bool TouchState::isSlippery() const { 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 @@ bool TouchState::isSlippery() const { 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 662be8063e..ffce9f68cc 100644 --- a/services/inputflinger/tests/FocusResolver_test.cpp +++ b/services/inputflinger/tests/FocusResolver_test.cpp @@ -37,12 +37,16 @@ public: 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 813acd8f72..da65e176e5 100644 --- a/services/inputflinger/tests/InputDispatcher_test.cpp +++ b/services/inputflinger/tests/InputDispatcher_test.cpp @@ -987,7 +987,6 @@ public: 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,14 @@ public: 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; + setVisible(true); + setFocusable(false); + setDupTouchToWallpaper(false); + setPaused(false); + setTrustedOverlay(false); } sp<FakeWindowHandle> clone( @@ -1017,15 +1016,41 @@ public: 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 setTouchModal(bool touchModal) { + mInfo.setInputConfig(WindowInfo::InputConfig::NOT_TOUCH_MODAL, !touchModal); + } + + void setSplitTouch(bool splitTouch) { + mInfo.setInputConfig(WindowInfo::InputConfig::SPLIT_TOUCH, splitTouch); + } + + 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 +1074,19 @@ public: void setTouchableRegion(const Region& region) { mInfo.touchableRegion = region; } - void setType(WindowInfo::Type type) { mInfo.type = type; } - - void setHasWallpaper(bool hasWallpaper) { mInfo.hasWallpaper = hasWallpaper; } - - void addFlags(Flags<WindowInfo::Flag> flags) { mInfo.flags |= flags; } + void setIsWallpaper(bool isWallpaper) { + mInfo.setInputConfig(WindowInfo::InputConfig::IS_WALLPAPER, isWallpaper); + } - 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); @@ -1552,7 +1579,7 @@ TEST_F(InputDispatcherTest, SetInputWindowOnce_SingleWindowTouch) { 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); + window->setTouchModal(false); mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}}); ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, @@ -1575,7 +1602,7 @@ TEST_F(InputDispatcherTest, SetInputWindowTwice_SingleWindowTouch) { 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); + window->setTouchModal(false); mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}}); mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}}); @@ -1610,17 +1637,17 @@ TEST_F(InputDispatcherTest, SetInputWindow_MultiWindowsTouch) { * 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 +1688,10 @@ TEST_F(InputDispatcherTest, WhenWallpaperDisappears_NoCrash) { 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 +1732,11 @@ TEST_F(InputDispatcherTest, WallpaperWindow_ReceivesMultiTouch) { 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 +1790,21 @@ TEST_F(InputDispatcherTest, TwoWindows_SplitWallpaperTouch) { 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->setTouchModal(false); + leftWindow->setSplitTouch(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->setTouchModal(false); + rightWindow->setSplitTouch(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 +1878,11 @@ TEST_F(InputDispatcherTest, HoverMoveEnterMouseClickAndHoverMoveExit) { 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); + windowLeft->setTouchModal(false); 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); + windowRight->setTouchModal(false); mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application); @@ -1960,7 +1989,7 @@ TEST_F(InputDispatcherTest, HoverEnterMouseClickAndHoverExit) { 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); + window->setTouchModal(false); mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application); @@ -2042,11 +2071,11 @@ TEST_F(InputDispatcherTest, DispatchMouseEventsUnderCursor) { 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); + windowLeft->setTouchModal(false); 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); + windowRight->setTouchModal(false); mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application); @@ -2152,14 +2181,14 @@ public: // 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->setTouchModal(false); 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->setTouchModal(false); secondWindow->setFrame(Rect(100, 200, 200, 400), displayTransform); addWindow(secondWindow); return {std::move(firstWindow), std::move(secondWindow)}; @@ -2380,13 +2409,15 @@ TEST_F(InputDispatcherTest, TransferTouchFocus_TwoPointersSplitTouch) { 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); + firstWindow->setTouchModal(false); + firstWindow->setSplitTouch(true); // 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); + secondWindow->setTouchModal(false); + secondWindow->setSplitTouch(true); // Add the windows to the dispatcher mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {firstWindow, secondWindow}}}); @@ -2452,13 +2483,15 @@ TEST_F(InputDispatcherTest, TransferTouch_TwoPointersSplitTouch) { 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); + firstWindow->setTouchModal(false); + firstWindow->setSplitTouch(true); // 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); + secondWindow->setTouchModal(false); + secondWindow->setSplitTouch(true); // Add the windows to the dispatcher mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {firstWindow, secondWindow}}}); @@ -2523,26 +2556,26 @@ TEST_F(InputDispatcherTest, TransferTouchFocus_CloneSurface) { 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); + firstWindowInPrimary->setTouchModal(false); 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); + secondWindowInPrimary->setTouchModal(false); sp<FakeWindowHandle> mirrorWindowInPrimary = firstWindowInPrimary->clone(application, mDispatcher, ADISPLAY_ID_DEFAULT); mirrorWindowInPrimary->setFrame(Rect(0, 100, 100, 200)); - mirrorWindowInPrimary->setFlags(WindowInfo::Flag::NOT_TOUCH_MODAL); + mirrorWindowInPrimary->setTouchModal(false); sp<FakeWindowHandle> firstWindowInSecondary = firstWindowInPrimary->clone(application, mDispatcher, SECOND_DISPLAY_ID); firstWindowInSecondary->setFrame(Rect(0, 0, 100, 100)); - firstWindowInSecondary->setFlags(WindowInfo::Flag::NOT_TOUCH_MODAL); + firstWindowInSecondary->setTouchModal(false); sp<FakeWindowHandle> secondWindowInSecondary = secondWindowInPrimary->clone(application, mDispatcher, SECOND_DISPLAY_ID); secondWindowInPrimary->setFrame(Rect(100, 0, 200, 100)); - secondWindowInPrimary->setFlags(WindowInfo::Flag::NOT_TOUCH_MODAL); + secondWindowInPrimary->setTouchModal(false); // Update window info, let it find window handle of second display first. mDispatcher->setInputWindows( @@ -2587,26 +2620,26 @@ TEST_F(InputDispatcherTest, TransferTouch_CloneSurface) { 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); + firstWindowInPrimary->setTouchModal(false); 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); + secondWindowInPrimary->setTouchModal(false); sp<FakeWindowHandle> mirrorWindowInPrimary = firstWindowInPrimary->clone(application, mDispatcher, ADISPLAY_ID_DEFAULT); mirrorWindowInPrimary->setFrame(Rect(0, 100, 100, 200)); - mirrorWindowInPrimary->setFlags(WindowInfo::Flag::NOT_TOUCH_MODAL); + mirrorWindowInPrimary->setTouchModal(false); sp<FakeWindowHandle> firstWindowInSecondary = firstWindowInPrimary->clone(application, mDispatcher, SECOND_DISPLAY_ID); firstWindowInSecondary->setFrame(Rect(0, 0, 100, 100)); - firstWindowInSecondary->setFlags(WindowInfo::Flag::NOT_TOUCH_MODAL); + firstWindowInSecondary->setTouchModal(false); sp<FakeWindowHandle> secondWindowInSecondary = secondWindowInPrimary->clone(application, mDispatcher, SECOND_DISPLAY_ID); secondWindowInPrimary->setFrame(Rect(100, 0, 200, 100)); - secondWindowInPrimary->setFlags(WindowInfo::Flag::NOT_TOUCH_MODAL); + secondWindowInPrimary->setTouchModal(false); // Update window info, let it find window handle of second display first. mDispatcher->setInputWindows( @@ -2704,13 +2737,15 @@ TEST_F(InputDispatcherTest, PointerCancel_SendCancelWhenSplitTouch) { 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); + firstWindow->setTouchModal(false); + firstWindow->setSplitTouch(true); // 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); + secondWindow->setTouchModal(false); + secondWindow->setSplitTouch(true); // Add the windows to the dispatcher mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {firstWindow, secondWindow}}}); @@ -3377,7 +3412,8 @@ TEST_F(InputDispatcherTest, SlipperyWindow_SetsFlagPartiallyObscured) { sp<FakeWindowHandle> slipperyExitWindow = new FakeWindowHandle(application, mDispatcher, "Top", ADISPLAY_ID_DEFAULT); - slipperyExitWindow->setFlags(WindowInfo::Flag::NOT_TOUCH_MODAL | WindowInfo::Flag::SLIPPERY); + slipperyExitWindow->setTouchModal(false); + 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 @@ -3985,12 +4021,12 @@ class InputDispatcherOnPointerDownOutsideFocus : public InputDispatcherTest { 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); + mUnfocusedWindow->setTouchModal(false); mFocusedWindow = new FakeWindowHandle(application, mDispatcher, "Second", ADISPLAY_ID_DEFAULT); mFocusedWindow->setFrame(Rect(50, 50, 100, 100)); - mFocusedWindow->setFlags(WindowInfo::Flag::NOT_TOUCH_MODAL); + mFocusedWindow->setTouchModal(false); // Set focused application. mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application); @@ -4099,12 +4135,14 @@ class InputDispatcherMultiWindowSameTokenTests : public InputDispatcherTest { 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->setTouchModal(false); + mWindow1->setSplitTouch(true); 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->setTouchModal(false); + mWindow2->setSplitTouch(true); mWindow2->setFrame(Rect(100, 100, 200, 200)); mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mWindow1, mWindow2}}}); @@ -4303,7 +4341,7 @@ class InputDispatcherSingleWindowAnr : public InputDispatcherTest { 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); + mWindow->setTouchModal(false); // Set focused application. mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, mApplication); @@ -4754,15 +4792,16 @@ class InputDispatcherMultiWindowAnr : public InputDispatcherTest { // 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->setTouchModal(false); + mUnfocusedWindow->setSplitTouch(true); + 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); + mFocusedWindow->setTouchModal(false); + mFocusedWindow->setSplitTouch(true); // Set focused application. mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, mApplication); @@ -5496,7 +5535,7 @@ protected: 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 +5649,7 @@ TEST_F(InputDispatcherUntrustedTouchesTest, 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 +5660,7 @@ TEST_F(InputDispatcherUntrustedTouchesTest, 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 +5910,11 @@ protected: 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); + mWindow->setTouchModal(false); mSecondWindow = new FakeWindowHandle(mApp, mDispatcher, "TestWindow2", ADISPLAY_ID_DEFAULT); mSecondWindow->setFrame(Rect(100, 0, 200, 100)); - mSecondWindow->setFlags(WindowInfo::Flag::NOT_TOUCH_MODAL); + mSecondWindow->setTouchModal(false); mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, mApp); mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mWindow, mSecondWindow}}}); @@ -6130,7 +6169,7 @@ TEST_F(InputDispatcherDropInputFeatureTest, ObscuredWindowDropsInput) { 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 +6215,7 @@ TEST_F(InputDispatcherDropInputFeatureTest, UnobscuredWindowGetsInput) { 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 +6321,7 @@ TEST_F(InputDispatcherTouchModeChangedTests, EventIsNotGeneratedIfNotChangingTou 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 +6330,7 @@ public: new FakeWindowHandle(application, mDispatcher, name.c_str(), ADISPLAY_ID_DEFAULT); spy->setInputFeatures(WindowInfo::Feature::SPY); spy->setTrustedOverlay(true); - spy->addFlags(flags); + spy->setTouchModal(false); return spy; } @@ -6300,8 +6339,9 @@ public: 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); + window->setTouchModal(false); + window->setSplitTouch(true); return window; } @@ -6316,7 +6356,7 @@ using InputDispatcherSpyWindowDeathTest = InputDispatcherSpyWindowTest; 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 +6366,7 @@ TEST_F(InputDispatcherSpyWindowDeathTest, UntrustedSpy_AbortsDispatcher) { * 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 +6389,9 @@ TEST_F(InputDispatcherSpyWindowTest, NoForegroundWindow) { */ 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 +6442,8 @@ TEST_F(InputDispatcherSpyWindowTest, ReceivesInputInOrder) { */ 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 +6460,7 @@ TEST_F(InputDispatcherSpyWindowTest, NotTouchable) { */ 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}}}); @@ -6450,8 +6491,10 @@ TEST_F(InputDispatcherSpyWindowTest, TouchableRegion) { */ 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. + auto spy = createSpy(); + // Our current policy dictates that modal windows must be focusable. + spy->setFocusable(true); + spy->setTouchModal(true); spy->setFrame(Rect{0, 0, 20, 20}); mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {spy, window}}}); @@ -6470,7 +6513,9 @@ TEST_F(InputDispatcherSpyWindowTest, ModalWindow) { 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->setTouchModal(false); spy->setOwnerInfo(56, 78); spy->setFrame(Rect{0, 0, 20, 20}); mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {spy, window}}}); @@ -6490,8 +6535,8 @@ TEST_F(InputDispatcherSpyWindowTest, WatchOutsideTouches) { */ 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 +6568,7 @@ TEST_F(InputDispatcherSpyWindowTest, PilferPointers) { */ 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 +6592,9 @@ TEST_F(InputDispatcherSpyWindowTest, CanPilferAfterWindowIsRemovedMidStream) { * 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(); + spy->setTouchModal(false); auto window = createForeground(); - window->setFlags(WindowInfo::Flag::NOT_TOUCH_MODAL | WindowInfo::Flag::SPLIT_TOUCH); mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {spy, window}}}); @@ -6615,7 +6660,7 @@ TEST_F(InputDispatcherSpyWindowTest, ReceivesMultiplePointers) { 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 +6695,7 @@ TEST_F(InputDispatcherSpyWindowTest, ReceivesMultiplePointers) { 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}}}); @@ -6684,14 +6729,15 @@ TEST_F(InputDispatcherSpyWindowTest, ReceivesSecondPointerAsDown) { */ 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 does not set split touch. 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->setTouchModal(true); + spy->setSplitTouch(false); // 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 +6775,7 @@ TEST_F(InputDispatcherSpyWindowTest, SplitIfNoForegroundWindowTouched) { * 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 +6804,8 @@ public: ADISPLAY_ID_DEFAULT); overlay->setFocusable(false); overlay->setOwnerInfo(111, 111); - overlay->setFlags(WindowInfo::Flag::NOT_TOUCHABLE | WindowInfo::Flag::SPLIT_TOUCH); + overlay->setTouchable(false); + overlay->setSplitTouch(true); overlay->setInputFeatures(WindowInfo::Feature::INTERCEPTS_STYLUS); overlay->setTrustedOverlay(true); @@ -6769,7 +6816,7 @@ public: ADISPLAY_ID_DEFAULT); window->setFocusable(true); window->setOwnerInfo(222, 222); - window->setFlags(WindowInfo::Flag::SPLIT_TOUCH); + window->setSplitTouch(true); 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 973029cb19..d0d79e9dd3 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -2159,8 +2159,8 @@ Rect Layer::getInputBounds() const { 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.inputConfig |= + WindowInfo::InputConfig::NOT_TOUCH_MODAL | WindowInfo::InputConfig::NOT_FOCUSABLE; 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 +2307,7 @@ WindowInfo Layer::fillInputInfo(const ui::Transform& displayTransform, bool disp 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.inputConfig |= WindowInfo::InputConfig::NOT_TOUCH_MODAL; mDrawingState.inputInfo.displayId = getLayerStack().id; } @@ -2325,7 +2325,9 @@ WindowInfo Layer::fillInputInfo(const ui::Transform& displayTransform, bool disp // 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 +2349,9 @@ WindowInfo Layer::fillInputInfo(const ui::Transform& displayTransform, bool disp // 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 +2483,7 @@ void Layer::updateClonedInputInfo(const std::map<sp<Layer>, sp<Layer>>& clonedLa } // 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 3bd0643a6d..0506c47555 100644 --- a/services/surfaceflinger/LayerProtoHelper.cpp +++ b/services/surfaceflinger/LayerProtoHelper.cpp @@ -175,12 +175,12 @@ void LayerProtoHelper::writeToProto( } 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 @@ void LayerProtoHelper::writeToProto( [&]() { 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/Tracing/TransactionProtoParser.cpp b/services/surfaceflinger/Tracing/TransactionProtoParser.cpp index fb5a6b3eb7..1e5c3e70c8 100644 --- a/services/surfaceflinger/Tracing/TransactionProtoParser.cpp +++ b/services/surfaceflinger/Tracing/TransactionProtoParser.cpp @@ -197,13 +197,16 @@ proto::LayerState TransactionProtoParser::toProto(const layer_state_t& layer) { 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 @@ void TransactionProtoParser::fromProto(const proto::LayerState& proto, layer_sta 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(), |