diff options
author | 2020-07-08 13:48:11 +0100 | |
---|---|---|
committer | 2020-07-17 15:34:54 +0100 | |
commit | 44753b15e754a33be9203b1dddbbdcae78afd493 (patch) | |
tree | 69d0209c5c7e8cdb6bff089567fd8708fa00e06a | |
parent | 6aa5a3b5c2cbfcf3c7101409b9e866ccde9adf4e (diff) |
Move things in InputWindowInfo to enum classes
Also introduce a new Flag class to make it possible to deal with flags
while treating the individual flags as part of an enum class in a type
safe manner.
Bug: 160010896
Test: atest inputflinger_tests, atest libinput_tests
Change-Id: I915a1c1e3b31f1c0fd99b83ba5fad7e537cd6f84
-rw-r--r-- | include/input/Flags.h | 179 | ||||
-rw-r--r-- | include/input/InputWindow.h | 168 | ||||
-rw-r--r-- | libs/gui/tests/EndToEndNativeInputTest.cpp | 5 | ||||
-rw-r--r-- | libs/input/InputWindow.cpp | 268 | ||||
-rw-r--r-- | libs/input/tests/Android.bp | 1 | ||||
-rw-r--r-- | libs/input/tests/Flags_test.cpp | 200 | ||||
-rw-r--r-- | libs/input/tests/InputWindow_test.cpp | 10 | ||||
-rw-r--r-- | services/inputflinger/benchmarks/InputDispatcher_benchmarks.cpp | 4 | ||||
-rw-r--r-- | services/inputflinger/dispatcher/InputDispatcher.cpp | 67 | ||||
-rw-r--r-- | services/inputflinger/dispatcher/TouchState.cpp | 3 | ||||
-rw-r--r-- | services/inputflinger/tests/InputDispatcher_test.cpp | 53 | ||||
-rw-r--r-- | services/inputflinger/tests/InputFlingerService_test.cpp | 11 | ||||
-rw-r--r-- | services/surfaceflinger/Layer.cpp | 12 | ||||
-rw-r--r-- | services/surfaceflinger/Layer.h | 4 | ||||
-rw-r--r-- | services/surfaceflinger/LayerProtoHelper.cpp | 8 | ||||
-rw-r--r-- | services/surfaceflinger/Scheduler/Scheduler.cpp | 6 | ||||
-rw-r--r-- | services/surfaceflinger/SurfaceFlinger.cpp | 8 |
17 files changed, 698 insertions, 309 deletions
diff --git a/include/input/Flags.h b/include/input/Flags.h new file mode 100644 index 0000000000..f3198c9e91 --- /dev/null +++ b/include/input/Flags.h @@ -0,0 +1,179 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <android-base/stringprintf.h> + +#include <cstdint> +#include <optional> +#include <string> +#include <type_traits> + +#include "utils/BitSet.h" + +#ifndef __UI_INPUT_FLAGS_H +#define __UI_INPUT_FLAGS_H + +namespace android { + +// A trait for determining whether a type is specifically an enum class or not. +template <typename T, bool = std::is_enum_v<T>> +struct is_enum_class : std::false_type {}; + +// By definition, an enum class is an enum that is not implicitly convertible to its underlying +// type. +template <typename T> +struct is_enum_class<T, true> + : std::bool_constant<!std::is_convertible_v<T, std::underlying_type_t<T>>> {}; + +template <typename T> +inline constexpr bool is_enum_class_v = is_enum_class<T>::value; + +/* A class for handling flags defined by an enum or enum class in a type-safe way. */ +template <class F, typename = std::enable_if_t<std::is_enum_v<F>>> +class Flags { + // F must be an enum or its underlying type is undefined. Theoretically we could specialize this + // further to avoid this restriction but in general we want to encourage the use of enums + // anyways. + using U = typename std::underlying_type_t<F>; + +public: + constexpr Flags(F f) : flags(static_cast<U>(f)) {} + constexpr Flags() : flags(0) {} + constexpr Flags(const Flags<F>& f) : flags(f.flags) {} + + // Provide a non-explicit construct for non-enum classes since they easily convert to their + // underlying types (e.g. when used with bitwise operators). For enum classes, however, we + // should force them to be explicitly constructed from their underlying types to make full use + // of the type checker. + template <typename T = U> + constexpr Flags(T t, typename std::enable_if_t<!is_enum_class_v<F>, T>* = nullptr) : flags(t) {} + template <typename T = U> + explicit constexpr Flags(T t, typename std::enable_if_t<is_enum_class_v<F>, T>* = nullptr) + : flags(t) {} + /* + * Tests whether the given flag is set. + */ + bool test(F flag) const { + U f = static_cast<U>(flag); + return (f & flags) == f; + } + + /* Tests whether any of the given flags are set */ + bool any(Flags<F> f) { return (flags & f.flags) != 0; } + + /* Tests whether all of the given flags are set */ + bool all(Flags<F> f) { return (flags & f.flags) == f.flags; } + + Flags<F> operator|(Flags<F> rhs) const { return static_cast<F>(flags | rhs.flags); } + Flags<F>& operator|=(Flags<F> rhs) { + flags = flags | rhs.flags; + return *this; + } + + Flags<F> operator&(Flags<F> rhs) const { return static_cast<F>(flags & rhs.flags); } + Flags<F>& operator&=(Flags<F> rhs) { + flags = flags & rhs.flags; + return *this; + } + + Flags<F> operator^(Flags<F> rhs) const { return static_cast<F>(flags ^ rhs.flags); } + Flags<F>& operator^=(Flags<F> rhs) { + flags = flags ^ rhs.flags; + return *this; + } + + Flags<F> operator~() { return static_cast<F>(~flags); } + + bool operator==(Flags<F> rhs) const { return flags == rhs.flags; } + bool operator!=(Flags<F> rhs) const { return !operator==(rhs); } + + Flags<F>& operator=(const Flags<F>& rhs) { + flags = rhs.flags; + return *this; + } + + /* + * Returns the stored set of flags. + * + * Note that this returns the underlying type rather than the base enum class. This is because + * the value is no longer necessarily a strict member of the enum since the returned value could + * be multiple enum variants OR'd together. + */ + U get() const { return flags; } + + std::string string() const { return string(defaultStringify); } + + std::string string(std::function<std::optional<std::string>(F)> stringify) const { + // The type can't be larger than 64-bits otherwise it won't fit in BitSet64. + static_assert(sizeof(U) <= sizeof(uint64_t)); + std::string result; + bool first = true; + U unstringified = 0; + for (BitSet64 bits(flags); !bits.isEmpty();) { + uint64_t bit = bits.clearLastMarkedBit(); // counts from left + const U flag = 1 << (64 - bit - 1); + std::optional<std::string> flagString = stringify(static_cast<F>(flag)); + if (flagString) { + appendFlag(result, flagString.value(), first); + } else { + unstringified |= flag; + } + } + + if (unstringified != 0) { + appendFlag(result, base::StringPrintf("0x%08x", unstringified), first); + } + + if (first) { + result += "0x0"; + } + + return result; + } + +private: + U flags; + + static std::optional<std::string> defaultStringify(F) { return std::nullopt; } + static void appendFlag(std::string& str, const std::string& flag, bool& first) { + if (first) { + first = false; + } else { + str += " | "; + } + str += flag; + } +}; + +// This namespace provides operator overloads for enum classes to make it easier to work with them +// as flags. In order to use these, add them via a `using namespace` declaration. +namespace flag_operators { + +template <typename F, typename = std::enable_if_t<is_enum_class_v<F>>> +inline Flags<F> operator~(F f) { + using U = typename std::underlying_type_t<F>; + return static_cast<F>(~static_cast<U>(f)); +} +template <typename F, typename = std::enable_if_t<is_enum_class_v<F>>> +Flags<F> operator|(F lhs, F rhs) { + using U = typename std::underlying_type_t<F>; + return static_cast<F>(static_cast<U>(lhs) | static_cast<U>(rhs)); +} + +} // namespace flag_operators +} // namespace android + +#endif // __UI_INPUT_FLAGS_H
\ No newline at end of file diff --git a/include/input/InputWindow.h b/include/input/InputWindow.h index 18cca2c26c..233c7aea4f 100644 --- a/include/input/InputWindow.h +++ b/include/input/InputWindow.h @@ -19,6 +19,7 @@ #include <binder/Parcel.h> #include <binder/Parcelable.h> +#include <input/Flags.h> #include <input/Input.h> #include <input/InputTransport.h> #include <ui/Rect.h> @@ -38,92 +39,92 @@ struct InputWindowInfo : public Parcelable { InputWindowInfo() = default; // Window flags from WindowManager.LayoutParams - enum : uint32_t { - FLAG_ALLOW_LOCK_WHILE_SCREEN_ON = 0x00000001, - FLAG_DIM_BEHIND = 0x00000002, - FLAG_BLUR_BEHIND = 0x00000004, - FLAG_NOT_FOCUSABLE = 0x00000008, - FLAG_NOT_TOUCHABLE = 0x00000010, - FLAG_NOT_TOUCH_MODAL = 0x00000020, - FLAG_TOUCHABLE_WHEN_WAKING = 0x00000040, - FLAG_KEEP_SCREEN_ON = 0x00000080, - FLAG_LAYOUT_IN_SCREEN = 0x00000100, - FLAG_LAYOUT_NO_LIMITS = 0x00000200, - FLAG_FULLSCREEN = 0x00000400, - FLAG_FORCE_NOT_FULLSCREEN = 0x00000800, - FLAG_DITHER = 0x00001000, - FLAG_SECURE = 0x00002000, - FLAG_SCALED = 0x00004000, - FLAG_IGNORE_CHEEK_PRESSES = 0x00008000, - FLAG_LAYOUT_INSET_DECOR = 0x00010000, - FLAG_ALT_FOCUSABLE_IM = 0x00020000, - FLAG_WATCH_OUTSIDE_TOUCH = 0x00040000, - FLAG_SHOW_WHEN_LOCKED = 0x00080000, - FLAG_SHOW_WALLPAPER = 0x00100000, - FLAG_TURN_SCREEN_ON = 0x00200000, - FLAG_DISMISS_KEYGUARD = 0x00400000, - FLAG_SPLIT_TOUCH = 0x00800000, - FLAG_HARDWARE_ACCELERATED = 0x01000000, - FLAG_LAYOUT_IN_OVERSCAN = 0x02000000, - FLAG_TRANSLUCENT_STATUS = 0x04000000, - FLAG_TRANSLUCENT_NAVIGATION = 0x08000000, - FLAG_LOCAL_FOCUS_MODE = 0x10000000, - FLAG_SLIPPERY = 0x20000000, - FLAG_LAYOUT_ATTACHED_IN_DECOR = 0x40000000, - FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS = 0x80000000, - }; - - // Window types from WindowManager.LayoutParams - enum { + enum class Flag : uint32_t { + ALLOW_LOCK_WHILE_SCREEN_ON = 0x00000001, + DIM_BEHIND = 0x00000002, + BLUR_BEHIND = 0x00000004, + NOT_FOCUSABLE = 0x00000008, + NOT_TOUCHABLE = 0x00000010, + NOT_TOUCH_MODAL = 0x00000020, + TOUCHABLE_WHEN_WAKING = 0x00000040, + KEEP_SCREEN_ON = 0x00000080, + LAYOUT_IN_SCREEN = 0x00000100, + LAYOUT_NO_LIMITS = 0x00000200, + FULLSCREEN = 0x00000400, + FORCE_NOT_FULLSCREEN = 0x00000800, + DITHER = 0x00001000, + SECURE = 0x00002000, + SCALED = 0x00004000, + IGNORE_CHEEK_PRESSES = 0x00008000, + LAYOUT_INSET_DECOR = 0x00010000, + ALT_FOCUSABLE_IM = 0x00020000, + WATCH_OUTSIDE_TOUCH = 0x00040000, + SHOW_WHEN_LOCKED = 0x00080000, + SHOW_WALLPAPER = 0x00100000, + TURN_SCREEN_ON = 0x00200000, + DISMISS_KEYGUARD = 0x00400000, + SPLIT_TOUCH = 0x00800000, + HARDWARE_ACCELERATED = 0x01000000, + LAYOUT_IN_OVERSCAN = 0x02000000, + TRANSLUCENT_STATUS = 0x04000000, + TRANSLUCENT_NAVIGATION = 0x08000000, + LOCAL_FOCUS_MODE = 0x10000000, + SLIPPERY = 0x20000000, + LAYOUT_ATTACHED_IN_DECOR = 0x40000000, + DRAWS_SYSTEM_BAR_BACKGROUNDS = 0x80000000, + }; // Window types from WindowManager.LayoutParams + + enum class Type : int32_t { + UNKNOWN = 0, FIRST_APPLICATION_WINDOW = 1, - TYPE_BASE_APPLICATION = 1, - TYPE_APPLICATION = 2, - TYPE_APPLICATION_STARTING = 3, + BASE_APPLICATION = 1, + APPLICATION = 2, + APPLICATION_STARTING = 3, LAST_APPLICATION_WINDOW = 99, FIRST_SUB_WINDOW = 1000, - TYPE_APPLICATION_PANEL = FIRST_SUB_WINDOW, - TYPE_APPLICATION_MEDIA = FIRST_SUB_WINDOW + 1, - TYPE_APPLICATION_SUB_PANEL = FIRST_SUB_WINDOW + 2, - TYPE_APPLICATION_ATTACHED_DIALOG = FIRST_SUB_WINDOW + 3, - TYPE_APPLICATION_MEDIA_OVERLAY = FIRST_SUB_WINDOW + 4, + APPLICATION_PANEL = FIRST_SUB_WINDOW, + APPLICATION_MEDIA = FIRST_SUB_WINDOW + 1, + APPLICATION_SUB_PANEL = FIRST_SUB_WINDOW + 2, + APPLICATION_ATTACHED_DIALOG = FIRST_SUB_WINDOW + 3, + APPLICATION_MEDIA_OVERLAY = FIRST_SUB_WINDOW + 4, LAST_SUB_WINDOW = 1999, FIRST_SYSTEM_WINDOW = 2000, - TYPE_STATUS_BAR = FIRST_SYSTEM_WINDOW, - TYPE_SEARCH_BAR = FIRST_SYSTEM_WINDOW + 1, - TYPE_PHONE = FIRST_SYSTEM_WINDOW + 2, - TYPE_SYSTEM_ALERT = FIRST_SYSTEM_WINDOW + 3, - TYPE_KEYGUARD = FIRST_SYSTEM_WINDOW + 4, - TYPE_TOAST = FIRST_SYSTEM_WINDOW + 5, - TYPE_SYSTEM_OVERLAY = FIRST_SYSTEM_WINDOW + 6, - TYPE_PRIORITY_PHONE = FIRST_SYSTEM_WINDOW + 7, - TYPE_SYSTEM_DIALOG = FIRST_SYSTEM_WINDOW + 8, - TYPE_KEYGUARD_DIALOG = FIRST_SYSTEM_WINDOW + 9, - TYPE_SYSTEM_ERROR = FIRST_SYSTEM_WINDOW + 10, - TYPE_INPUT_METHOD = FIRST_SYSTEM_WINDOW + 11, - TYPE_INPUT_METHOD_DIALOG = FIRST_SYSTEM_WINDOW + 12, - TYPE_WALLPAPER = FIRST_SYSTEM_WINDOW + 13, - TYPE_STATUS_BAR_PANEL = FIRST_SYSTEM_WINDOW + 14, - TYPE_SECURE_SYSTEM_OVERLAY = FIRST_SYSTEM_WINDOW + 15, - TYPE_DRAG = FIRST_SYSTEM_WINDOW + 16, - TYPE_STATUS_BAR_SUB_PANEL = FIRST_SYSTEM_WINDOW + 17, - TYPE_POINTER = FIRST_SYSTEM_WINDOW + 18, - TYPE_NAVIGATION_BAR = FIRST_SYSTEM_WINDOW + 19, - TYPE_VOLUME_OVERLAY = FIRST_SYSTEM_WINDOW + 20, - TYPE_BOOT_PROGRESS = FIRST_SYSTEM_WINDOW + 21, - TYPE_INPUT_CONSUMER = FIRST_SYSTEM_WINDOW + 22, - TYPE_NAVIGATION_BAR_PANEL = FIRST_SYSTEM_WINDOW + 24, - TYPE_MAGNIFICATION_OVERLAY = FIRST_SYSTEM_WINDOW + 27, - TYPE_ACCESSIBILITY_OVERLAY = FIRST_SYSTEM_WINDOW + 32, - TYPE_DOCK_DIVIDER = FIRST_SYSTEM_WINDOW + 34, - TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY = FIRST_SYSTEM_WINDOW + 39, - TYPE_NOTIFICATION_SHADE = FIRST_SYSTEM_WINDOW + 40, + STATUS_BAR = FIRST_SYSTEM_WINDOW, + SEARCH_BAR = FIRST_SYSTEM_WINDOW + 1, + PHONE = FIRST_SYSTEM_WINDOW + 2, + SYSTEM_ALERT = FIRST_SYSTEM_WINDOW + 3, + KEYGUARD = FIRST_SYSTEM_WINDOW + 4, + TOAST = FIRST_SYSTEM_WINDOW + 5, + SYSTEM_OVERLAY = FIRST_SYSTEM_WINDOW + 6, + PRIORITY_PHONE = FIRST_SYSTEM_WINDOW + 7, + SYSTEM_DIALOG = FIRST_SYSTEM_WINDOW + 8, + KEYGUARD_DIALOG = FIRST_SYSTEM_WINDOW + 9, + SYSTEM_ERROR = FIRST_SYSTEM_WINDOW + 10, + INPUT_METHOD = FIRST_SYSTEM_WINDOW + 11, + INPUT_METHOD_DIALOG = FIRST_SYSTEM_WINDOW + 12, + WALLPAPER = FIRST_SYSTEM_WINDOW + 13, + STATUS_BAR_PANEL = FIRST_SYSTEM_WINDOW + 14, + SECURE_SYSTEM_OVERLAY = FIRST_SYSTEM_WINDOW + 15, + DRAG = FIRST_SYSTEM_WINDOW + 16, + STATUS_BAR_SUB_PANEL = FIRST_SYSTEM_WINDOW + 17, + POINTER = FIRST_SYSTEM_WINDOW + 18, + NAVIGATION_BAR = FIRST_SYSTEM_WINDOW + 19, + VOLUME_OVERLAY = FIRST_SYSTEM_WINDOW + 20, + BOOT_PROGRESS = FIRST_SYSTEM_WINDOW + 21, + INPUT_CONSUMER = FIRST_SYSTEM_WINDOW + 22, + NAVIGATION_BAR_PANEL = FIRST_SYSTEM_WINDOW + 24, + MAGNIFICATION_OVERLAY = FIRST_SYSTEM_WINDOW + 27, + ACCESSIBILITY_OVERLAY = FIRST_SYSTEM_WINDOW + 32, + DOCK_DIVIDER = FIRST_SYSTEM_WINDOW + 34, + ACCESSIBILITY_MAGNIFICATION_OVERLAY = FIRST_SYSTEM_WINDOW + 39, + NOTIFICATION_SHADE = FIRST_SYSTEM_WINDOW + 40, LAST_SYSTEM_WINDOW = 2999, }; - enum { - INPUT_FEATURE_DISABLE_TOUCH_PAD_GESTURES = 0x00000001, - INPUT_FEATURE_NO_INPUT_CHANNEL = 0x00000002, - INPUT_FEATURE_DISABLE_USER_ACTIVITY = 0x00000004, + enum class Feature { + DISABLE_TOUCH_PAD_GESTURES = 0x00000001, + NO_INPUT_CHANNEL = 0x00000002, + DISABLE_USER_ACTIVITY = 0x00000004, }; /* These values are filled in by the WM and passed through SurfaceFlinger @@ -135,8 +136,8 @@ struct InputWindowInfo : public Parcelable { // This uniquely identifies the input window. int32_t id = -1; std::string name; - int32_t layoutParamsFlags = 0; - int32_t layoutParamsType = 0; + Flags<Flag> flags; + Type type = Type::UNKNOWN; std::chrono::nanoseconds dispatchingTimeout = std::chrono::seconds(5); /* These values are filled in by SurfaceFlinger. */ @@ -182,7 +183,7 @@ struct InputWindowInfo : public Parcelable { bool trustedOverlay = false; int32_t ownerPid = -1; int32_t ownerUid = -1; - int32_t inputFeatures = 0; + Flags<Feature> inputFeatures; int32_t displayId = ADISPLAY_ID_NONE; int32_t portalToDisplayId = ADISPLAY_ID_NONE; InputApplicationInfo applicationInfo; @@ -204,9 +205,9 @@ struct InputWindowInfo : public Parcelable { status_t writeToParcel(android::Parcel* parcel) const override; status_t readFromParcel(const android::Parcel* parcel) override; -}; -std::string inputWindowFlagsToString(uint32_t flags); + static std::optional<std::string> flagToString(Flag f); +}; /* * Handle for a window that can receive input. @@ -267,7 +268,6 @@ protected: InputWindowInfo mInfo; }; - } // namespace android #endif // _UI_INPUT_WINDOW_H diff --git a/libs/gui/tests/EndToEndNativeInputTest.cpp b/libs/gui/tests/EndToEndNativeInputTest.cpp index 152f7ad56c..383d5916a4 100644 --- a/libs/gui/tests/EndToEndNativeInputTest.cpp +++ b/libs/gui/tests/EndToEndNativeInputTest.cpp @@ -186,8 +186,8 @@ private: void populateInputInfo(int width, int height) { mInputInfo.token = mServerChannel->getConnectionToken(); mInputInfo.name = "Test info"; - mInputInfo.layoutParamsFlags = InputWindowInfo::FLAG_NOT_TOUCH_MODAL; - mInputInfo.layoutParamsType = InputWindowInfo::TYPE_BASE_APPLICATION; + mInputInfo.flags = InputWindowInfo::Flag::NOT_TOUCH_MODAL; + mInputInfo.type = InputWindowInfo::Type::BASE_APPLICATION; mInputInfo.dispatchingTimeout = 5s; mInputInfo.globalScaleFactor = 1.0; mInputInfo.canReceiveKeys = true; @@ -200,7 +200,6 @@ private: // TODO: Fill in from SF? mInputInfo.ownerPid = 11111; mInputInfo.ownerUid = 11111; - mInputInfo.inputFeatures = 0; mInputInfo.displayId = 0; InputApplicationInfo aInfo; diff --git a/libs/input/InputWindow.cpp b/libs/input/InputWindow.cpp index ae9b3f0994..36c1f8068d 100644 --- a/libs/input/InputWindow.cpp +++ b/libs/input/InputWindow.cpp @@ -14,6 +14,7 @@ * limitations under the License. */ +#include <type_traits> #define LOG_TAG "InputWindow" #define LOG_NDEBUG 0 @@ -26,117 +27,6 @@ namespace android { -const char* inputWindowFlagToString(uint32_t flag) { - switch (flag) { - case InputWindowInfo::FLAG_ALLOW_LOCK_WHILE_SCREEN_ON: { - return "ALLOW_LOCK_WHILE_SCREEN_ON"; - } - case InputWindowInfo::FLAG_DIM_BEHIND: { - return "DIM_BEHIND"; - } - case InputWindowInfo::FLAG_BLUR_BEHIND: { - return "BLUR_BEHIND"; - } - case InputWindowInfo::FLAG_NOT_FOCUSABLE: { - return "NOT_FOCUSABLE"; - } - case InputWindowInfo::FLAG_NOT_TOUCHABLE: { - return "NOT_TOUCHABLE"; - } - case InputWindowInfo::FLAG_NOT_TOUCH_MODAL: { - return "NOT_TOUCH_MODAL"; - } - case InputWindowInfo::FLAG_TOUCHABLE_WHEN_WAKING: { - return "TOUCHABLE_WHEN_WAKING"; - } - case InputWindowInfo::FLAG_KEEP_SCREEN_ON: { - return "KEEP_SCREEN_ON"; - } - case InputWindowInfo::FLAG_LAYOUT_IN_SCREEN: { - return "LAYOUT_IN_SCREEN"; - } - case InputWindowInfo::FLAG_LAYOUT_NO_LIMITS: { - return "LAYOUT_NO_LIMITS"; - } - case InputWindowInfo::FLAG_FULLSCREEN: { - return "FULLSCREEN"; - } - case InputWindowInfo::FLAG_FORCE_NOT_FULLSCREEN: { - return "FORCE_NOT_FULLSCREEN"; - } - case InputWindowInfo::FLAG_DITHER: { - return "DITHER"; - } - case InputWindowInfo::FLAG_SECURE: { - return "SECURE"; - } - case InputWindowInfo::FLAG_SCALED: { - return "SCALED"; - } - case InputWindowInfo::FLAG_IGNORE_CHEEK_PRESSES: { - return "IGNORE_CHEEK_PRESSES"; - } - case InputWindowInfo::FLAG_LAYOUT_INSET_DECOR: { - return "LAYOUT_INSET_DECOR"; - } - case InputWindowInfo::FLAG_ALT_FOCUSABLE_IM: { - return "ALT_FOCUSABLE_IM"; - } - case InputWindowInfo::FLAG_WATCH_OUTSIDE_TOUCH: { - return "WATCH_OUTSIDE_TOUCH"; - } - case InputWindowInfo::FLAG_SHOW_WHEN_LOCKED: { - return "SHOW_WHEN_LOCKED"; - } - case InputWindowInfo::FLAG_SHOW_WALLPAPER: { - return "SHOW_WALLPAPER"; - } - case InputWindowInfo::FLAG_TURN_SCREEN_ON: { - return "TURN_SCREEN_ON"; - } - case InputWindowInfo::FLAG_DISMISS_KEYGUARD: { - return "DISMISS_KEYGUARD"; - } - case InputWindowInfo::FLAG_SPLIT_TOUCH: { - return "SPLIT_TOUCH"; - } - case InputWindowInfo::FLAG_HARDWARE_ACCELERATED: { - return "HARDWARE_ACCELERATED"; - } - case InputWindowInfo::FLAG_LAYOUT_IN_OVERSCAN: { - return "LAYOUT_IN_OVERSCAN"; - } - case InputWindowInfo::FLAG_TRANSLUCENT_STATUS: { - return "TRANSLUCENT_STATUS"; - } - case InputWindowInfo::FLAG_TRANSLUCENT_NAVIGATION: { - return "TRANSLUCENT_NAVIGATION"; - } - case InputWindowInfo::FLAG_LOCAL_FOCUS_MODE: { - return "LOCAL_FOCUS_MODE"; - } - case InputWindowInfo::FLAG_SLIPPERY: { - return "SLIPPERY"; - } - case InputWindowInfo::FLAG_LAYOUT_ATTACHED_IN_DECOR: { - return "LAYOUT_ATTACHED_IN_DECOR"; - } - case InputWindowInfo::FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS: { - return "DRAWS_SYSTEM_BAR_BACKGROUNDS"; - } - } - return "UNKNOWN"; -} - -std::string inputWindowFlagsToString(uint32_t flags) { - std::string result; - for (BitSet32 bits(flags); !bits.isEmpty();) { - uint32_t bit = bits.clearLastMarkedBit(); // counts from left - const uint32_t flag = 1 << (32 - bit - 1); - result += android::base::StringPrintf("%s | ", inputWindowFlagToString(flag)); - } - return result; -} // --- InputWindowInfo --- void InputWindowInfo::addTouchableRegion(const Rect& region) { @@ -153,7 +43,7 @@ bool InputWindowInfo::frameContainsPoint(int32_t x, int32_t y) const { } bool InputWindowInfo::supportsSplitTouch() const { - return layoutParamsFlags & FLAG_SPLIT_TOUCH; + return flags.test(Flag::SPLIT_TOUCH); } bool InputWindowInfo::overlaps(const InputWindowInfo* other) const { @@ -162,14 +52,12 @@ bool InputWindowInfo::overlaps(const InputWindowInfo* other) const { } bool InputWindowInfo::operator==(const InputWindowInfo& info) const { - return info.token == token && info.id == id && info.name == name && - info.layoutParamsFlags == layoutParamsFlags && - info.layoutParamsType == layoutParamsType && - info.dispatchingTimeout == dispatchingTimeout && info.frameLeft == frameLeft && - info.frameTop == frameTop && info.frameRight == frameRight && - info.frameBottom == frameBottom && info.surfaceInset == surfaceInset && - info.globalScaleFactor == globalScaleFactor && info.windowXScale == windowXScale && - info.windowYScale == windowYScale && + 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.windowXScale == windowXScale && info.windowYScale == windowYScale && info.touchableRegion.hasSameRects(touchableRegion) && info.visible == visible && info.canReceiveKeys == canReceiveKeys && info.trustedOverlay == trustedOverlay && info.hasFocus == hasFocus && info.hasWallpaper == hasWallpaper && @@ -197,8 +85,8 @@ status_t InputWindowInfo::writeToParcel(android::Parcel* parcel) const { parcel->writeInt64(dispatchingTimeout.count()) ?: parcel->writeInt32(id) ?: parcel->writeUtf8AsUtf16(name) ?: - parcel->writeInt32(layoutParamsFlags) ?: - parcel->writeInt32(layoutParamsType) ?: + parcel->writeInt32(flags.get()) ?: + parcel->writeInt32(static_cast<std::underlying_type_t<InputWindowInfo::Type>>(type)) ?: parcel->writeInt32(frameLeft) ?: parcel->writeInt32(frameTop) ?: parcel->writeInt32(frameRight) ?: @@ -215,7 +103,7 @@ status_t InputWindowInfo::writeToParcel(android::Parcel* parcel) const { parcel->writeBool(trustedOverlay) ?: parcel->writeInt32(ownerPid) ?: parcel->writeInt32(ownerUid) ?: - parcel->writeInt32(inputFeatures) ?: + parcel->writeInt32(inputFeatures.get()) ?: parcel->writeInt32(displayId) ?: parcel->writeInt32(portalToDisplayId) ?: applicationInfo.writeToParcel(parcel) ?: @@ -236,12 +124,15 @@ status_t InputWindowInfo::readFromParcel(const android::Parcel* parcel) { } token = parcel->readStrongBinder(); - dispatchingTimeout = decltype(dispatchingTimeout)(parcel->readInt64()); - status_t status = parcel->readInt32(&id) ?: - parcel->readUtf8FromUtf16(&name) ?: - parcel->readInt32(&layoutParamsFlags) ?: - parcel->readInt32(&layoutParamsType) ?: - parcel->readInt32(&frameLeft) ?: + dispatchingTimeout = static_cast<decltype(dispatchingTimeout)>(parcel->readInt64()); + status_t status = parcel->readInt32(&id) ?: parcel->readUtf8FromUtf16(&name); + if (status != OK) { + return status; + } + + flags = Flags<Flag>(parcel->readInt32()); + type = static_cast<Type>(parcel->readInt32()); + status = parcel->readInt32(&frameLeft) ?: parcel->readInt32(&frameTop) ?: parcel->readInt32(&frameRight) ?: parcel->readInt32(&frameBottom) ?: @@ -256,17 +147,26 @@ status_t InputWindowInfo::readFromParcel(const android::Parcel* parcel) { parcel->readBool(&paused) ?: parcel->readBool(&trustedOverlay) ?: parcel->readInt32(&ownerPid) ?: - parcel->readInt32(&ownerUid) ?: - parcel->readInt32(&inputFeatures) ?: - parcel->readInt32(&displayId) ?: + parcel->readInt32(&ownerUid); + + if (status != OK) { + return status; + } + + inputFeatures = Flags<Feature>(parcel->readInt32()); + status = parcel->readInt32(&displayId) ?: parcel->readInt32(&portalToDisplayId) ?: applicationInfo.readFromParcel(parcel) ?: parcel->read(touchableRegion) ?: parcel->readBool(&replaceTouchableRegionWithCrop); + if (status != OK) { + return status; + } + touchableRegionCropHandle = parcel->readStrongBinder(); - return status; + return OK; } // --- InputWindowHandle --- @@ -299,4 +199,106 @@ void InputWindowHandle::updateFrom(sp<InputWindowHandle> handle) { mInfo = handle->mInfo; } +std::optional<std::string> InputWindowInfo::flagToString(Flag flag) { + switch (flag) { + case InputWindowInfo::Flag::ALLOW_LOCK_WHILE_SCREEN_ON: { + return "ALLOW_LOCK_WHILE_SCREEN_ON"; + } + case InputWindowInfo::Flag::DIM_BEHIND: { + return "DIM_BEHIND"; + } + case InputWindowInfo::Flag::BLUR_BEHIND: { + return "BLUR_BEHIND"; + } + case InputWindowInfo::Flag::NOT_FOCUSABLE: { + return "NOT_FOCUSABLE"; + } + case InputWindowInfo::Flag::NOT_TOUCHABLE: { + return "NOT_TOUCHABLE"; + } + case InputWindowInfo::Flag::NOT_TOUCH_MODAL: { + return "NOT_TOUCH_MODAL"; + } + case InputWindowInfo::Flag::TOUCHABLE_WHEN_WAKING: { + return "TOUCHABLE_WHEN_WAKING"; + } + case InputWindowInfo::Flag::KEEP_SCREEN_ON: { + return "KEEP_SCREEN_ON"; + } + case InputWindowInfo::Flag::LAYOUT_IN_SCREEN: { + return "LAYOUT_IN_SCREEN"; + } + case InputWindowInfo::Flag::LAYOUT_NO_LIMITS: { + return "LAYOUT_NO_LIMITS"; + } + case InputWindowInfo::Flag::FULLSCREEN: { + return "FULLSCREEN"; + } + case InputWindowInfo::Flag::FORCE_NOT_FULLSCREEN: { + return "FORCE_NOT_FULLSCREEN"; + } + case InputWindowInfo::Flag::DITHER: { + return "DITHER"; + } + case InputWindowInfo::Flag::SECURE: { + return "SECURE"; + } + case InputWindowInfo::Flag::SCALED: { + return "SCALED"; + } + case InputWindowInfo::Flag::IGNORE_CHEEK_PRESSES: { + return "IGNORE_CHEEK_PRESSES"; + } + case InputWindowInfo::Flag::LAYOUT_INSET_DECOR: { + return "LAYOUT_INSET_DECOR"; + } + case InputWindowInfo::Flag::ALT_FOCUSABLE_IM: { + return "ALT_FOCUSABLE_IM"; + } + case InputWindowInfo::Flag::WATCH_OUTSIDE_TOUCH: { + return "WATCH_OUTSIDE_TOUCH"; + } + case InputWindowInfo::Flag::SHOW_WHEN_LOCKED: { + return "SHOW_WHEN_LOCKED"; + } + case InputWindowInfo::Flag::SHOW_WALLPAPER: { + return "SHOW_WALLPAPER"; + } + case InputWindowInfo::Flag::TURN_SCREEN_ON: { + return "TURN_SCREEN_ON"; + } + case InputWindowInfo::Flag::DISMISS_KEYGUARD: { + return "DISMISS_KEYGUARD"; + } + case InputWindowInfo::Flag::SPLIT_TOUCH: { + return "SPLIT_TOUCH"; + } + case InputWindowInfo::Flag::HARDWARE_ACCELERATED: { + return "HARDWARE_ACCELERATED"; + } + case InputWindowInfo::Flag::LAYOUT_IN_OVERSCAN: { + return "LAYOUT_IN_OVERSCAN"; + } + case InputWindowInfo::Flag::TRANSLUCENT_STATUS: { + return "TRANSLUCENT_STATUS"; + } + case InputWindowInfo::Flag::TRANSLUCENT_NAVIGATION: { + return "TRANSLUCENT_NAVIGATION"; + } + case InputWindowInfo::Flag::LOCAL_FOCUS_MODE: { + return "LOCAL_FOCUS_MODE"; + } + case InputWindowInfo::Flag::SLIPPERY: { + return "SLIPPERY"; + } + case InputWindowInfo::Flag::LAYOUT_ATTACHED_IN_DECOR: { + return "LAYOUT_ATTACHED_IN_DECOR"; + } + case InputWindowInfo::Flag::DRAWS_SYSTEM_BAR_BACKGROUNDS: { + return "DRAWS_SYSTEM_BAR_BACKGROUNDS"; + } + } + return std::nullopt; +} + } // namespace android diff --git a/libs/input/tests/Android.bp b/libs/input/tests/Android.bp index 3b57146461..9782c1a05a 100644 --- a/libs/input/tests/Android.bp +++ b/libs/input/tests/Android.bp @@ -2,6 +2,7 @@ cc_test { name: "libinput_tests", srcs: [ + "Flags_test.cpp", "IdGenerator_test.cpp", "InputChannel_test.cpp", "InputDevice_test.cpp", diff --git a/libs/input/tests/Flags_test.cpp b/libs/input/tests/Flags_test.cpp new file mode 100644 index 0000000000..800404df59 --- /dev/null +++ b/libs/input/tests/Flags_test.cpp @@ -0,0 +1,200 @@ +/* + * Copyright 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <gtest/gtest.h> +#include <input/Flags.h> + +#include <type_traits> + +namespace android::test { + +using namespace android::flag_operators; + +enum class TestFlags { ONE = 0x1, TWO = 0x2, THREE = 0x4 }; + +static std::optional<std::string> toStringComplete(TestFlags f) { + switch (f) { + case TestFlags::ONE: + return "ONE"; + case TestFlags::TWO: + return "TWO"; + case TestFlags::THREE: + return "THREE"; + } + return std::nullopt; +} + +static std::optional<std::string> toStringIncomplete(TestFlags f) { + switch (f) { + case TestFlags::ONE: + return "ONE"; + case TestFlags::TWO: + return "TWO"; + case TestFlags::THREE: + default: + return std::nullopt; + } +} + +TEST(Flags, Test) { + Flags<TestFlags> flags = TestFlags::ONE; + ASSERT_TRUE(flags.test(TestFlags::ONE)); + ASSERT_FALSE(flags.test(TestFlags::TWO)); + ASSERT_FALSE(flags.test(TestFlags::THREE)); +} + +TEST(Flags, Any) { + Flags<TestFlags> flags = TestFlags::ONE | TestFlags::TWO; + ASSERT_TRUE(flags.any(TestFlags::ONE)); + ASSERT_TRUE(flags.any(TestFlags::TWO)); + ASSERT_FALSE(flags.any(TestFlags::THREE)); + ASSERT_TRUE(flags.any(TestFlags::ONE | TestFlags::TWO)); + ASSERT_TRUE(flags.any(TestFlags::TWO | TestFlags::THREE)); + ASSERT_TRUE(flags.any(TestFlags::ONE | TestFlags::THREE)); + ASSERT_TRUE(flags.any(TestFlags::ONE | TestFlags::TWO | TestFlags::THREE)); +} + +TEST(Flags, All) { + Flags<TestFlags> flags = TestFlags::ONE | TestFlags::TWO; + ASSERT_TRUE(flags.all(TestFlags::ONE)); + ASSERT_TRUE(flags.all(TestFlags::TWO)); + ASSERT_FALSE(flags.all(TestFlags::THREE)); + ASSERT_TRUE(flags.all(TestFlags::ONE | TestFlags::TWO)); + ASSERT_FALSE(flags.all(TestFlags::TWO | TestFlags::THREE)); + ASSERT_FALSE(flags.all(TestFlags::ONE | TestFlags::THREE)); + ASSERT_FALSE(flags.all(TestFlags::ONE | TestFlags::TWO | TestFlags::THREE)); +} + +TEST(Flags, DefaultConstructor_hasNoFlagsSet) { + Flags<TestFlags> flags; + ASSERT_FALSE(flags.any(TestFlags::ONE | TestFlags::TWO | TestFlags::THREE)); +} + +TEST(Flags, NotOperator_onEmptyFlagsSetsAllFlags) { + Flags<TestFlags> flags; + flags = ~flags; + ASSERT_TRUE(flags.all(TestFlags::ONE | TestFlags::TWO | TestFlags::THREE)); +} + +TEST(Flags, NotOperator_onNonEmptyFlagsInvertsFlags) { + Flags<TestFlags> flags = TestFlags::TWO; + flags = ~flags; + ASSERT_TRUE(flags.all(TestFlags::ONE | TestFlags::THREE)); + ASSERT_FALSE(flags.test(TestFlags::TWO)); +} + +TEST(Flags, OrOperator_withNewFlag) { + Flags<TestFlags> flags = TestFlags::ONE; + Flags<TestFlags> flags2 = flags | TestFlags::TWO; + ASSERT_FALSE(flags2.test(TestFlags::THREE)); + ASSERT_TRUE(flags2.all(TestFlags::ONE | TestFlags::TWO)); +} + +TEST(Flags, OrOperator_withExistingFlag) { + Flags<TestFlags> flags = TestFlags::ONE | TestFlags::THREE; + Flags<TestFlags> flags2 = flags | TestFlags::THREE; + ASSERT_FALSE(flags2.test(TestFlags::TWO)); + ASSERT_TRUE(flags2.all(TestFlags::ONE | TestFlags::THREE)); +} + +TEST(Flags, OrEqualsOperator_withNewFlag) { + Flags<TestFlags> flags; + flags |= TestFlags::THREE; + ASSERT_TRUE(flags.test(TestFlags::THREE)); + ASSERT_FALSE(flags.any(TestFlags::ONE | TestFlags::TWO)); +} + +TEST(Flags, OrEqualsOperator_withExistingFlag) { + Flags<TestFlags> flags = TestFlags::ONE | TestFlags::THREE; + flags |= TestFlags::THREE; + ASSERT_TRUE(flags.all(TestFlags::ONE | TestFlags::THREE)); + ASSERT_FALSE(flags.test(TestFlags::TWO)); +} + +TEST(Flags, AndOperator_withOneSetFlag) { + Flags<TestFlags> flags = TestFlags::ONE | TestFlags::THREE; + Flags<TestFlags> andFlags = flags & TestFlags::THREE; + ASSERT_TRUE(andFlags.test(TestFlags::THREE)); + ASSERT_FALSE(andFlags.any(TestFlags::ONE | TestFlags::TWO)); +} + +TEST(Flags, AndOperator_withMultipleSetFlags) { + Flags<TestFlags> flags = TestFlags::ONE | TestFlags::THREE; + Flags<TestFlags> andFlags = flags & (TestFlags::ONE | TestFlags::THREE); + ASSERT_TRUE(andFlags.all(TestFlags::ONE | TestFlags::THREE)); + ASSERT_FALSE(andFlags.test(TestFlags::TWO)); +} + +TEST(Flags, AndOperator_withNoSetFlags) { + Flags<TestFlags> flags = TestFlags::ONE | TestFlags::THREE; + Flags<TestFlags> andFlags = flags & TestFlags::TWO; + ASSERT_FALSE(andFlags.any(TestFlags::ONE | TestFlags::TWO | TestFlags::THREE)); +} + +TEST(Flags, Equality) { + Flags<TestFlags> flags1 = TestFlags::ONE | TestFlags::TWO; + Flags<TestFlags> flags2 = TestFlags::ONE | TestFlags::TWO; + ASSERT_EQ(flags1, flags2); +} + +TEST(Flags, Inequality) { + Flags<TestFlags> flags1 = TestFlags::ONE | TestFlags::TWO; + Flags<TestFlags> flags2 = TestFlags::ONE | TestFlags::THREE; + ASSERT_NE(flags1, flags2); +} + +TEST(Flags, EqualsOperator) { + Flags<TestFlags> flags; + flags = TestFlags::ONE; + ASSERT_TRUE(flags.test(TestFlags::ONE)); + ASSERT_FALSE(flags.any(TestFlags::TWO | TestFlags::THREE)); +} + +TEST(Flags, EqualsOperator_DontShareState) { + Flags<TestFlags> flags1 = TestFlags::ONE | TestFlags::TWO; + Flags<TestFlags> flags2 = flags1; + ASSERT_EQ(flags1, flags2); + + flags1 &= TestFlags::TWO; + ASSERT_NE(flags1, flags2); +} + +TEST(Flags, String_NoFlagsWithDefaultStringify) { + Flags<TestFlags> flags; + ASSERT_EQ(flags.string(), "0x0"); +} + +TEST(Flags, String_NoFlagsWithNonDefaultStringify) { + Flags<TestFlags> flags; + ASSERT_EQ(flags.string(toStringComplete), "0x0"); +} + +TEST(Flags, String_WithDefaultStringify) { + Flags<TestFlags> flags = TestFlags::ONE | TestFlags::TWO; + ASSERT_EQ(flags.string(), "0x00000003"); +} + +TEST(Flags, String_WithCompleteStringify) { + Flags<TestFlags> flags = TestFlags::ONE | TestFlags::TWO; + ASSERT_EQ(flags.string(toStringComplete), "ONE | TWO"); +} + +TEST(Flags, String_WithIncompleteStringify) { + Flags<TestFlags> flags = TestFlags::ONE | TestFlags::THREE; + ASSERT_EQ(flags.string(toStringIncomplete), "ONE | 0x00000004"); +} + +} // namespace android::test
\ No newline at end of file diff --git a/libs/input/tests/InputWindow_test.cpp b/libs/input/tests/InputWindow_test.cpp index cdea922bd2..e7a4587bfc 100644 --- a/libs/input/tests/InputWindow_test.cpp +++ b/libs/input/tests/InputWindow_test.cpp @@ -44,8 +44,8 @@ TEST(InputWindowInfo, Parcelling) { i.token = new BBinder(); i.id = 1; i.name = "Foobar"; - i.layoutParamsFlags = 7; - i.layoutParamsType = 39; + i.flags = InputWindowInfo::Flag::SLIPPERY; + i.type = InputWindowInfo::Type::INPUT_METHOD; i.dispatchingTimeout = 12s; i.frameLeft = 93; i.frameTop = 34; @@ -62,7 +62,7 @@ TEST(InputWindowInfo, Parcelling) { i.paused = false; i.ownerPid = 19; i.ownerUid = 24; - i.inputFeatures = 29; + i.inputFeatures = InputWindowInfo::Feature::DISABLE_USER_ACTIVITY; i.displayId = 34; i.portalToDisplayId = 2; i.replaceTouchableRegionWithCrop = true; @@ -76,8 +76,8 @@ TEST(InputWindowInfo, Parcelling) { ASSERT_EQ(i.token, i2.token); ASSERT_EQ(i.id, i2.id); ASSERT_EQ(i.name, i2.name); - ASSERT_EQ(i.layoutParamsFlags, i2.layoutParamsFlags); - ASSERT_EQ(i.layoutParamsType, i2.layoutParamsType); + ASSERT_EQ(i.flags, i2.flags); + ASSERT_EQ(i.type, i2.type); ASSERT_EQ(i.dispatchingTimeout, i2.dispatchingTimeout); ASSERT_EQ(i.frameLeft, i2.frameLeft); ASSERT_EQ(i.frameTop, i2.frameTop); diff --git a/services/inputflinger/benchmarks/InputDispatcher_benchmarks.cpp b/services/inputflinger/benchmarks/InputDispatcher_benchmarks.cpp index 7d8ab753f3..a15b7b25ef 100644 --- a/services/inputflinger/benchmarks/InputDispatcher_benchmarks.cpp +++ b/services/inputflinger/benchmarks/InputDispatcher_benchmarks.cpp @@ -157,8 +157,7 @@ public: virtual bool updateInfo() override { mInfo.token = mServerChannel->getConnectionToken(); mInfo.name = "FakeWindowHandle"; - mInfo.layoutParamsFlags = 0; - mInfo.layoutParamsType = InputWindowInfo::TYPE_APPLICATION; + mInfo.type = InputWindowInfo::Type::APPLICATION; mInfo.dispatchingTimeout = DISPATCHING_TIMEOUT; mInfo.frameLeft = mFrame.left; mInfo.frameTop = mFrame.top; @@ -174,7 +173,6 @@ public: mInfo.paused = false; mInfo.ownerPid = INJECTOR_PID; mInfo.ownerUid = INJECTOR_UID; - mInfo.inputFeatures = 0; mInfo.displayId = ADISPLAY_ID_DEFAULT; return true; diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp index 5df4aec7d5..36bbc6dd17 100644 --- a/services/inputflinger/dispatcher/InputDispatcher.cpp +++ b/services/inputflinger/dispatcher/InputDispatcher.cpp @@ -45,28 +45,29 @@ static constexpr bool DEBUG_FOCUS = false; #include "InputDispatcher.h" -#include "Connection.h" - -#include <errno.h> -#include <inttypes.h> -#include <limits.h> -#include <statslog.h> -#include <stddef.h> -#include <time.h> -#include <unistd.h> -#include <queue> -#include <sstream> - #include <android-base/chrono_utils.h> #include <android-base/stringprintf.h> #include <binder/Binder.h> #include <input/InputDevice.h> +#include <input/InputWindow.h> #include <log/log.h> #include <openssl/hmac.h> #include <openssl/rand.h> #include <powermanager/PowerManager.h> +#include <statslog.h> +#include <unistd.h> #include <utils/Trace.h> +#include <cerrno> +#include <cinttypes> +#include <climits> +#include <cstddef> +#include <ctime> +#include <queue> +#include <sstream> + +#include "Connection.h" + #define INDENT " " #define INDENT2 " " #define INDENT3 " " @@ -816,13 +817,12 @@ sp<InputWindowHandle> InputDispatcher::findTouchedWindowAtLocked(int32_t display for (const sp<InputWindowHandle>& windowHandle : windowHandles) { const InputWindowInfo* windowInfo = windowHandle->getInfo(); if (windowInfo->displayId == displayId) { - int32_t flags = windowInfo->layoutParamsFlags; + auto flags = windowInfo->flags; if (windowInfo->visible) { - if (!(flags & InputWindowInfo::FLAG_NOT_TOUCHABLE)) { - bool isTouchModal = (flags & - (InputWindowInfo::FLAG_NOT_FOCUSABLE | - InputWindowInfo::FLAG_NOT_TOUCH_MODAL)) == 0; + if (!flags.test(InputWindowInfo::Flag::NOT_TOUCHABLE)) { + bool isTouchModal = !flags.test(InputWindowInfo::Flag::NOT_FOCUSABLE) && + !flags.test(InputWindowInfo::Flag::NOT_TOUCH_MODAL); if (isTouchModal || windowInfo->touchableRegionContainsPoint(x, y)) { int32_t portalToDisplayId = windowInfo->portalToDisplayId; if (portalToDisplayId != ADISPLAY_ID_NONE && @@ -839,7 +839,7 @@ sp<InputWindowHandle> InputDispatcher::findTouchedWindowAtLocked(int32_t display } } - if (addOutsideTargets && (flags & InputWindowInfo::FLAG_WATCH_OUTSIDE_TOUCH)) { + if (addOutsideTargets && flags.test(InputWindowInfo::Flag::WATCH_OUTSIDE_TOUCH)) { touchState->addOrUpdateWindow(windowHandle, InputTarget::FLAG_DISPATCH_AS_OUTSIDE, BitSet32(0)); @@ -1888,7 +1888,7 @@ int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime, for (const sp<InputWindowHandle>& windowHandle : windowHandles) { const InputWindowInfo* info = windowHandle->getInfo(); if (info->displayId == displayId && - windowHandle->getInfo()->layoutParamsType == InputWindowInfo::TYPE_WALLPAPER) { + windowHandle->getInfo()->type == InputWindowInfo::Type::WALLPAPER) { tempTouchState .addOrUpdateWindow(windowHandle, InputTarget::FLAG_WINDOW_IS_OBSCURED | @@ -2170,7 +2170,7 @@ void InputDispatcher::pokeUserActivityLocked(const EventEntry& eventEntry) { getValueByKey(mFocusedWindowHandlesByDisplay, displayId); if (focusedWindowHandle != nullptr) { const InputWindowInfo* info = focusedWindowHandle->getInfo(); - if (info->inputFeatures & InputWindowInfo::INPUT_FEATURE_DISABLE_USER_ACTIVITY) { + if (info->inputFeatures.test(InputWindowInfo::Feature::DISABLE_USER_ACTIVITY)) { #if DEBUG_DISPATCH_CYCLE ALOGD("Not poking user activity: disabled by window '%s'.", info->name.c_str()); #endif @@ -3647,10 +3647,9 @@ void InputDispatcher::updateWindowHandlesForDisplayLocked( if ((getInputChannelLocked(handle->getToken()) == nullptr && info->portalToDisplayId == ADISPLAY_ID_NONE)) { const bool noInputChannel = - info->inputFeatures & InputWindowInfo::INPUT_FEATURE_NO_INPUT_CHANNEL; - const bool canReceiveInput = - !(info->layoutParamsFlags & InputWindowInfo::FLAG_NOT_TOUCHABLE) || - !(info->layoutParamsFlags & InputWindowInfo::FLAG_NOT_FOCUSABLE); + info->inputFeatures.test(InputWindowInfo::Feature::NO_INPUT_CHANNEL); + const bool canReceiveInput = !info->flags.test(InputWindowInfo::Flag::NOT_TOUCHABLE) || + !info->flags.test(InputWindowInfo::Flag::NOT_FOCUSABLE); if (canReceiveInput && !noInputChannel) { ALOGV("Window handle %s has no registered input channel", handle->getName().c_str()); @@ -4140,7 +4139,7 @@ void InputDispatcher::dumpDispatchStateLocked(std::string& dump) { dump += StringPrintf(INDENT3 "%zu: name='%s', displayId=%d, " "portalToDisplayId=%d, paused=%s, hasFocus=%s, " "hasWallpaper=%s, visible=%s, canReceiveKeys=%s, " - "flags=0x%08x, type=0x%08x, " + "flags=%s, type=0x%08x, " "frame=[%d,%d][%d,%d], globalScale=%f, " "windowScale=(%f,%f), touchableRegion=", i, windowInfo->name.c_str(), windowInfo->displayId, @@ -4150,20 +4149,20 @@ void InputDispatcher::dumpDispatchStateLocked(std::string& dump) { toString(windowInfo->hasWallpaper), toString(windowInfo->visible), toString(windowInfo->canReceiveKeys), - windowInfo->layoutParamsFlags, - windowInfo->layoutParamsType, windowInfo->frameLeft, - windowInfo->frameTop, windowInfo->frameRight, - windowInfo->frameBottom, windowInfo->globalScaleFactor, - windowInfo->windowXScale, windowInfo->windowYScale); + windowInfo->flags.string(InputWindowInfo::flagToString) + .c_str(), + static_cast<int32_t>(windowInfo->type), + windowInfo->frameLeft, windowInfo->frameTop, + windowInfo->frameRight, windowInfo->frameBottom, + windowInfo->globalScaleFactor, windowInfo->windowXScale, + windowInfo->windowYScale); dumpRegion(dump, windowInfo->touchableRegion); - dump += StringPrintf(", inputFeatures=0x%08x", windowInfo->inputFeatures); + dump += StringPrintf(", inputFeatures=%s", + windowInfo->inputFeatures.string().c_str()); dump += StringPrintf(", ownerPid=%d, ownerUid=%d, dispatchingTimeout=%" PRId64 "ms\n", windowInfo->ownerPid, windowInfo->ownerUid, millis(windowInfo->dispatchingTimeout)); - dump += StringPrintf(INDENT4 " flags: %s\n", - inputWindowFlagsToString(windowInfo->layoutParamsFlags) - .c_str()); } } else { dump += INDENT2 "Windows: <none>\n"; diff --git a/services/inputflinger/dispatcher/TouchState.cpp b/services/inputflinger/dispatcher/TouchState.cpp index 2baceba582..81b3cf025b 100644 --- a/services/inputflinger/dispatcher/TouchState.cpp +++ b/services/inputflinger/dispatcher/TouchState.cpp @@ -137,8 +137,7 @@ bool TouchState::isSlippery() const { for (const TouchedWindow& window : windows) { if (window.targetFlags & InputTarget::FLAG_FOREGROUND) { if (haveSlipperyForegroundWindow || - !(window.windowHandle->getInfo()->layoutParamsFlags & - InputWindowInfo::FLAG_SLIPPERY)) { + !window.windowHandle->getInfo()->flags.test(InputWindowInfo::Flag::SLIPPERY)) { return false; } haveSlipperyForegroundWindow = true; diff --git a/services/inputflinger/tests/InputDispatcher_test.cpp b/services/inputflinger/tests/InputDispatcher_test.cpp index 86b486818f..c749806190 100644 --- a/services/inputflinger/tests/InputDispatcher_test.cpp +++ b/services/inputflinger/tests/InputDispatcher_test.cpp @@ -29,6 +29,7 @@ #include <vector> using android::base::StringPrintf; +using namespace android::flag_operators; namespace android::inputdispatcher { @@ -766,8 +767,7 @@ public: mInfo.token = token; mInfo.id = sId++; mInfo.name = name; - mInfo.layoutParamsFlags = 0; - mInfo.layoutParamsType = InputWindowInfo::TYPE_APPLICATION; + mInfo.type = InputWindowInfo::Type::APPLICATION; mInfo.dispatchingTimeout = DISPATCHING_TIMEOUT; mInfo.frameLeft = 0; mInfo.frameTop = 0; @@ -783,7 +783,6 @@ public: mInfo.paused = false; mInfo.ownerPid = INJECTOR_PID; mInfo.ownerUid = INJECTOR_UID; - mInfo.inputFeatures = 0; mInfo.displayId = displayId; } @@ -806,7 +805,7 @@ public: mInfo.addTouchableRegion(frame); } - void setLayoutParamFlags(int32_t flags) { mInfo.layoutParamsFlags = flags; } + void setFlags(Flags<InputWindowInfo::Flag> flags) { mInfo.flags = flags; } void setWindowScale(float xScale, float yScale) { mInfo.windowXScale = xScale; @@ -1165,7 +1164,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->setLayoutParamFlags(InputWindowInfo::FLAG_NOT_TOUCH_MODAL); + window->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL); mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}}); ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, @@ -1188,7 +1187,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->setLayoutParamFlags(InputWindowInfo::FLAG_NOT_TOUCH_MODAL); + window->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL); mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}}); mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}}); @@ -1298,11 +1297,11 @@ TEST_F(InputDispatcherTest, HoverMoveEnterMouseClickAndHoverMoveExit) { sp<FakeWindowHandle> windowLeft = new FakeWindowHandle(application, mDispatcher, "Left", ADISPLAY_ID_DEFAULT); windowLeft->setFrame(Rect(0, 0, 600, 800)); - windowLeft->setLayoutParamFlags(InputWindowInfo::FLAG_NOT_TOUCH_MODAL); + windowLeft->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL); sp<FakeWindowHandle> windowRight = new FakeWindowHandle(application, mDispatcher, "Right", ADISPLAY_ID_DEFAULT); windowRight->setFrame(Rect(600, 0, 1200, 800)); - windowRight->setLayoutParamFlags(InputWindowInfo::FLAG_NOT_TOUCH_MODAL); + windowRight->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL); mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application); @@ -1409,7 +1408,7 @@ TEST_F(InputDispatcherTest, HoverEnterMouseClickAndHoverExit) { sp<FakeWindowHandle> window = new FakeWindowHandle(application, mDispatcher, "Window", ADISPLAY_ID_DEFAULT); window->setFrame(Rect(0, 0, 1200, 800)); - window->setLayoutParamFlags(InputWindowInfo::FLAG_NOT_TOUCH_MODAL); + window->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL); mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application); @@ -1491,11 +1490,11 @@ TEST_F(InputDispatcherTest, DispatchMouseEventsUnderCursor) { sp<FakeWindowHandle> windowLeft = new FakeWindowHandle(application, mDispatcher, "Left", ADISPLAY_ID_DEFAULT); windowLeft->setFrame(Rect(0, 0, 600, 800)); - windowLeft->setLayoutParamFlags(InputWindowInfo::FLAG_NOT_TOUCH_MODAL); + windowLeft->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL); sp<FakeWindowHandle> windowRight = new FakeWindowHandle(application, mDispatcher, "Right", ADISPLAY_ID_DEFAULT); windowRight->setFrame(Rect(600, 0, 1200, 800)); - windowRight->setLayoutParamFlags(InputWindowInfo::FLAG_NOT_TOUCH_MODAL); + windowRight->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL); mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application); @@ -1654,15 +1653,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->setLayoutParamFlags(InputWindowInfo::FLAG_NOT_TOUCH_MODAL - | InputWindowInfo::FLAG_SPLIT_TOUCH); + firstWindow->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL | + InputWindowInfo::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->setLayoutParamFlags(InputWindowInfo::FLAG_NOT_TOUCH_MODAL - | InputWindowInfo::FLAG_SPLIT_TOUCH); + secondWindow->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL | + InputWindowInfo::Flag::SPLIT_TOUCH); // Add the windows to the dispatcher mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {firstWindow, secondWindow}}}); @@ -2347,12 +2346,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->setLayoutParamFlags(InputWindowInfo::FLAG_NOT_TOUCH_MODAL); + mUnfocusedWindow->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL); mFocusedWindow = new FakeWindowHandle(application, mDispatcher, "Second", ADISPLAY_ID_DEFAULT); mFocusedWindow->setFrame(Rect(50, 50, 100, 100)); - mFocusedWindow->setLayoutParamFlags(InputWindowInfo::FLAG_NOT_TOUCH_MODAL); + mFocusedWindow->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL); // Set focused application. mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application); @@ -2440,14 +2439,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->setLayoutParamFlags(InputWindowInfo::FLAG_NOT_TOUCH_MODAL | - InputWindowInfo::FLAG_SPLIT_TOUCH); + mWindow1->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL | + InputWindowInfo::Flag::SPLIT_TOUCH); mWindow1->setFrame(Rect(0, 0, 100, 100)); mWindow2 = new FakeWindowHandle(application, mDispatcher, "Fake Window 2", ADISPLAY_ID_DEFAULT, mWindow1->getToken()); - mWindow2->setLayoutParamFlags(InputWindowInfo::FLAG_NOT_TOUCH_MODAL | - InputWindowInfo::FLAG_SPLIT_TOUCH); + mWindow2->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL | + InputWindowInfo::Flag::SPLIT_TOUCH); mWindow2->setFrame(Rect(100, 100, 200, 200)); mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mWindow1, mWindow2}}}); @@ -2671,7 +2670,7 @@ class InputDispatcherSingleWindowAnr : public InputDispatcherTest { mWindow->setFocus(true); // Adding FLAG_NOT_TOUCH_MODAL to ensure taps outside this window are not sent to this // window. - mWindow->setLayoutParamFlags(InputWindowInfo::FLAG_NOT_TOUCH_MODAL); + mWindow->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL); // Set focused application. mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, mApplication); @@ -3053,16 +3052,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->setLayoutParamFlags(InputWindowInfo::FLAG_NOT_TOUCH_MODAL | - InputWindowInfo::FLAG_WATCH_OUTSIDE_TOUCH | - InputWindowInfo::FLAG_SPLIT_TOUCH); + mUnfocusedWindow->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL | + InputWindowInfo::Flag::WATCH_OUTSIDE_TOUCH | + InputWindowInfo::Flag::SPLIT_TOUCH); mFocusedWindow = new FakeWindowHandle(mApplication, mDispatcher, "Focused", ADISPLAY_ID_DEFAULT); mFocusedWindow->setDispatchingTimeout(30ms); mFocusedWindow->setFrame(Rect(50, 50, 100, 100)); - mFocusedWindow->setLayoutParamFlags(InputWindowInfo::FLAG_NOT_TOUCH_MODAL | - InputWindowInfo::FLAG_SPLIT_TOUCH); + mFocusedWindow->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL | + InputWindowInfo::Flag::SPLIT_TOUCH); // Set focused application. mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, mApplication); diff --git a/services/inputflinger/tests/InputFlingerService_test.cpp b/services/inputflinger/tests/InputFlingerService_test.cpp index 6d50519768..193fe77878 100644 --- a/services/inputflinger/tests/InputFlingerService_test.cpp +++ b/services/inputflinger/tests/InputFlingerService_test.cpp @@ -57,8 +57,8 @@ namespace android { static const sp<IBinder> TestInfoToken = new BBinder(); static constexpr int32_t TestInfoId = 1; static const std::string TestInfoName = "InputFlingerServiceTestInputWindowInfo"; -static constexpr int32_t TestInfoLayoutParamsFlags = 0xABCD; -static constexpr int32_t TestInfoLayoutParamsType = 39; +static constexpr Flags<InputWindowInfo::Flag> TestInfoFlags = InputWindowInfo::Flag::NOT_FOCUSABLE; +static constexpr InputWindowInfo::Type TestInfoType = InputWindowInfo::Type::INPUT_METHOD; static constexpr std::chrono::duration TestInfoDispatchingTimeout = 2532ms; static constexpr int32_t TestInfoFrameLeft = 93; static constexpr int32_t TestInfoFrameTop = 34; @@ -79,7 +79,8 @@ static constexpr bool TestInfoHasWallpaper = false; static constexpr bool TestInfoPaused = false; static constexpr int32_t TestInfoOwnerPid = 19; static constexpr int32_t TestInfoOwnerUid = 24; -static constexpr int32_t TestInfoInputFeatures = 29; +static constexpr InputWindowInfo::Feature TestInfoInputFeatures = + InputWindowInfo::Feature::NO_INPUT_CHANNEL; static constexpr int32_t TestInfoDisplayId = 34; static constexpr int32_t TestInfoPortalToDisplayId = 2; static constexpr bool TestInfoReplaceTouchableRegionWithCrop = true; @@ -265,8 +266,8 @@ void InputFlingerServiceTest::SetUp() { mInfo.token = TestInfoToken; mInfo.id = TestInfoId; mInfo.name = TestInfoName; - mInfo.layoutParamsFlags = TestInfoLayoutParamsFlags; - mInfo.layoutParamsType = TestInfoLayoutParamsType; + mInfo.flags = TestInfoFlags; + mInfo.type = TestInfoType; mInfo.dispatchingTimeout = TestInfoDispatchingTimeout; mInfo.frameLeft = TestInfoFrameLeft; mInfo.frameTop = TestInfoFrameTop; diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index 67becab0d5..70822bd02b 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -67,12 +67,14 @@ #include "MonitoredProducer.h" #include "SurfaceFlinger.h" #include "TimeStats/TimeStats.h" +#include "input/InputWindow.h" #define DEBUG_RESIZE 0 namespace android { using base::StringAppendF; +using namespace android::flag_operators; std::atomic<int32_t> Layer::sSequence{1}; @@ -80,7 +82,8 @@ Layer::Layer(const LayerCreationArgs& args) : mFlinger(args.flinger), mName(args.name), mClientRef(args.client), - mWindowType(args.metadata.getInt32(METADATA_WINDOW_TYPE, 0)) { + mWindowType(static_cast<InputWindowInfo::Type>( + args.metadata.getInt32(METADATA_WINDOW_TYPE, 0))) { uint32_t layerFlags = 0; if (args.flags & ISurfaceComposerClient::eHidden) layerFlags |= layer_state_t::eLayerHidden; if (args.flags & ISurfaceComposerClient::eOpaque) layerFlags |= layer_state_t::eLayerOpaque; @@ -2371,9 +2374,8 @@ InputWindowInfo Layer::fillInputInfo() { mDrawingState.inputInfo.name = getName(); mDrawingState.inputInfo.ownerUid = mCallingUid; mDrawingState.inputInfo.ownerPid = mCallingPid; - mDrawingState.inputInfo.inputFeatures = - InputWindowInfo::INPUT_FEATURE_NO_INPUT_CHANNEL; - mDrawingState.inputInfo.layoutParamsFlags = InputWindowInfo::FLAG_NOT_TOUCH_MODAL; + mDrawingState.inputInfo.inputFeatures = InputWindowInfo::Feature::NO_INPUT_CHANNEL; + mDrawingState.inputInfo.flags = InputWindowInfo::Flag::NOT_TOUCH_MODAL; mDrawingState.inputInfo.displayId = getLayerStack(); } @@ -2575,7 +2577,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.layoutParamsFlags &= ~InputWindowInfo::FLAG_WATCH_OUTSIDE_TOUCH; + mDrawingState.inputInfo.flags &= ~InputWindowInfo::Flag::WATCH_OUTSIDE_TOUCH; } void Layer::updateClonedRelatives(const std::map<sp<Layer>, sp<Layer>>& clonedLayersMap) { diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index 6bcbfca5e3..99b1bb199a 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -286,7 +286,7 @@ public: void onFirstRef() override; - int getWindowType() const { return mWindowType; } + InputWindowInfo::Type getWindowType() const { return mWindowType; } void setPrimaryDisplayOnly() { mPrimaryDisplayOnly = true; } bool getPrimaryDisplayOnly() const { return mPrimaryDisplayOnly; } @@ -1038,7 +1038,7 @@ protected: bool mChildrenChanged{false}; // Window types from WindowManager.LayoutParams - const int mWindowType; + const InputWindowInfo::Type mWindowType; private: virtual void setTransformHint(ui::Transform::RotationFlags) {} diff --git a/services/surfaceflinger/LayerProtoHelper.cpp b/services/surfaceflinger/LayerProtoHelper.cpp index 0fe1421926..dd65cf4271 100644 --- a/services/surfaceflinger/LayerProtoHelper.cpp +++ b/services/surfaceflinger/LayerProtoHelper.cpp @@ -131,8 +131,12 @@ void LayerProtoHelper::writeToProto( } InputWindowInfoProto* proto = getInputWindowInfoProto(); - proto->set_layout_params_flags(inputInfo.layoutParamsFlags); - proto->set_layout_params_type(inputInfo.layoutParamsType); + proto->set_layout_params_flags(inputInfo.flags.get()); + using U = std::underlying_type_t<InputWindowInfo::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)); LayerProtoHelper::writeToProto({inputInfo.frameLeft, inputInfo.frameTop, inputInfo.frameRight, inputInfo.frameBottom}, diff --git a/services/surfaceflinger/Scheduler/Scheduler.cpp b/services/surfaceflinger/Scheduler/Scheduler.cpp index ab63d64895..8dd4b0a26a 100644 --- a/services/surfaceflinger/Scheduler/Scheduler.cpp +++ b/services/surfaceflinger/Scheduler/Scheduler.cpp @@ -432,7 +432,7 @@ void Scheduler::registerLayer(Layer* layer) { const auto minFps = mRefreshRateConfigs.getMinRefreshRate().getFps(); const auto maxFps = mRefreshRateConfigs.getMaxRefreshRate().getFps(); - if (layer->getWindowType() == InputWindowInfo::TYPE_STATUS_BAR) { + if (layer->getWindowType() == InputWindowInfo::Type::STATUS_BAR) { mLayerHistory->registerLayer(layer, minFps, maxFps, scheduler::LayerHistory::LayerVoteType::NoVote); } else if (!mUseContentDetection) { @@ -445,12 +445,12 @@ void Scheduler::registerLayer(Layer* layer) { // In V1 of content detection, all layers are registered as Heuristic (unless it's // wallpaper). const auto highFps = - layer->getWindowType() == InputWindowInfo::TYPE_WALLPAPER ? minFps : maxFps; + layer->getWindowType() == InputWindowInfo::Type::WALLPAPER ? minFps : maxFps; mLayerHistory->registerLayer(layer, minFps, highFps, scheduler::LayerHistory::LayerVoteType::Heuristic); } else { - if (layer->getWindowType() == InputWindowInfo::TYPE_WALLPAPER) { + if (layer->getWindowType() == InputWindowInfo::Type::WALLPAPER) { // Running Wallpaper at Min is considered as part of content detection. mLayerHistory->registerLayer(layer, minFps, maxFps, scheduler::LayerHistory::LayerVoteType::Min); diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index aa7b90348a..93bc11a168 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -90,6 +90,7 @@ #include <functional> #include <mutex> #include <optional> +#include <type_traits> #include <unordered_map> #include "BufferLayer.h" @@ -3981,7 +3982,12 @@ status_t SurfaceFlinger::createLayer(const String8& name, const sp<Client>& clie if (metadata.has(METADATA_WINDOW_TYPE)) { int32_t windowType = metadata.getInt32(METADATA_WINDOW_TYPE, 0); if (windowType == 441731) { - metadata.setInt32(METADATA_WINDOW_TYPE, InputWindowInfo::TYPE_NAVIGATION_BAR_PANEL); + using U = std::underlying_type_t<InputWindowInfo::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>); + metadata.setInt32(METADATA_WINDOW_TYPE, + static_cast<U>(InputWindowInfo::Type::NAVIGATION_BAR_PANEL)); primaryDisplayOnly = true; } } |