Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2579fc0c authored by Michael Wright's avatar Michael Wright Committed by Android (Google) Code Review
Browse files

Merge "Move things in InputWindowInfo to enum classes"

parents 77663478 44753b15
Loading
Loading
Loading
Loading

include/input/Flags.h

0 → 100644
+179 −0
Original line number Diff line number Diff line
/*
 * 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
+84 −84
Original line number Diff line number Diff line
@@ -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
+2 −3
Original line number Diff line number Diff line
@@ -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;
+135 −133

File changed.

Preview size limit exceeded, changes collapsed.

+1 −0
Original line number Diff line number Diff line
@@ -2,6 +2,7 @@
cc_test {
    name: "libinput_tests",
    srcs: [
        "Flags_test.cpp",
        "IdGenerator_test.cpp",
        "InputChannel_test.cpp",
        "InputDevice_test.cpp",
Loading