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
diff --git a/libs/input/tests/Android.bp b/libs/input/tests/Android.bp
index 3b57146..9782c1a 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 0000000..800404d
--- /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 cdea922..e7a4587 100644
--- a/libs/input/tests/InputWindow_test.cpp
+++ b/libs/input/tests/InputWindow_test.cpp
@@ -44,8 +44,8 @@
     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 @@
     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 @@
     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);