FTL: Extend enum utilities imported from IF
Generalize compile-time and run-time lookup of enumerator names by
recognizing ftl_first and ftl_last to customize the range.
Add enum_range<E>() for iteration using range-based `for` loop.
Bug: 185536303
Test: Check assembly for small LUT in .rodata, and unrolled loops.
Test: ftl_test, libinput_tests, inputflinger_tests
Test: m libinputflinger
Change-Id: I0581611f4cfcf5837b0293867cb323742afb2c87
diff --git a/include/ftl/Flags.h b/include/ftl/Flags.h
index 27c8476..ae70831 100644
--- a/include/ftl/Flags.h
+++ b/include/ftl/Flags.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2020 The Android Open Source Project
+ * 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.
@@ -14,79 +14,22 @@
* limitations under the License.
*/
-#include <android-base/stringprintf.h>
+#pragma once
-#include <array>
+#include <ftl/enum.h>
+#include <ftl/string.h>
+
#include <cstdint>
-#include <optional>
+#include <iterator>
#include <string>
#include <type_traits>
-#include <ftl/NamedEnum.h>
#include "utils/BitSet.h"
-#pragma once
+// TODO(b/185536303): Align with FTL style and namespace.
namespace android {
-namespace details {
-
-template <typename F>
-inline constexpr auto flag_count = sizeof(F) * __CHAR_BIT__;
-
-template <typename F, typename T, T... I>
-constexpr auto generate_flag_values(std::integer_sequence<T, I...> seq) {
- constexpr size_t count = seq.size();
-
- std::array<F, count> values{};
- for (size_t i = 0, v = 0; v < count; ++i) {
- values[v++] = static_cast<F>(T{1} << i);
- }
-
- return values;
-}
-
-template <typename F>
-inline constexpr auto flag_values = generate_flag_values<F>(
- std::make_integer_sequence<std::underlying_type_t<F>, flag_count<F>>{});
-
-template <typename F, std::size_t... I>
-constexpr auto generate_flag_names(std::index_sequence<I...>) noexcept {
- return std::array<std::optional<std::string_view>, sizeof...(I)>{
- {enum_value_name<F, flag_values<F>[I]>()...}};
-}
-
-template <typename F>
-inline constexpr auto flag_names =
- generate_flag_names<F>(std::make_index_sequence<flag_count<F>>{});
-
-// 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;
-} // namespace details
-
-template <auto V>
-constexpr auto flag_name() {
- using F = decltype(V);
- return details::enum_value_name<F, V>();
-}
-
-template <typename F>
-constexpr std::optional<std::string_view> flag_name(F flag) {
- using U = std::underlying_type_t<F>;
- auto idx = static_cast<size_t>(__builtin_ctzl(static_cast<U>(flag)));
- return details::flag_names<F>[idx];
-}
-
/* A class for handling flags defined by an enum or enum class in a type-safe way. */
template <typename F>
class Flags {
@@ -94,7 +37,7 @@
// further to avoid this restriction but in general we want to encourage the use of enums
// anyways.
static_assert(std::is_enum_v<F>, "Flags type must be an enum");
- using U = typename std::underlying_type_t<F>;
+ using U = std::underlying_type_t<F>;
public:
constexpr Flags(F f) : mFlags(static_cast<U>(f)) {}
@@ -106,11 +49,10 @@
// 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<!details::is_enum_class_v<F>, T>* = nullptr)
- : mFlags(t) {}
+ constexpr Flags(T t, std::enable_if_t<!ftl::is_scoped_enum_v<F>, T>* = nullptr) : mFlags(t) {}
+
template <typename T = U>
- explicit constexpr Flags(T t,
- typename std::enable_if_t<details::is_enum_class_v<F>, T>* = nullptr)
+ explicit constexpr Flags(T t, std::enable_if_t<ftl::is_scoped_enum_v<F>, T>* = nullptr)
: mFlags(t) {}
class Iterator {
@@ -229,16 +171,16 @@
bool first = true;
U unstringified = 0;
for (const F f : *this) {
- std::optional<std::string_view> flagString = flag_name(f);
- if (flagString) {
- appendFlag(result, flagString.value(), first);
+ if (const auto flagName = ftl::flag_name(f)) {
+ appendFlag(result, flagName.value(), first);
} else {
unstringified |= static_cast<U>(f);
}
}
if (unstringified != 0) {
- appendFlag(result, base::StringPrintf("0x%08x", unstringified), first);
+ constexpr auto radix = sizeof(U) == 1 ? ftl::Radix::kBin : ftl::Radix::kHex;
+ appendFlag(result, ftl::to_string(unstringified, radix), first);
}
if (first) {
@@ -265,15 +207,14 @@
// 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<details::is_enum_class_v<F>>>
+template <typename F, typename = std::enable_if_t<ftl::is_scoped_enum_v<F>>>
inline Flags<F> operator~(F f) {
- using U = typename std::underlying_type_t<F>;
- return static_cast<F>(~static_cast<U>(f));
+ return static_cast<F>(~ftl::enum_cast(f));
}
-template <typename F, typename = std::enable_if_t<details::is_enum_class_v<F>>>
+
+template <typename F, typename = std::enable_if_t<ftl::is_scoped_enum_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));
+ return static_cast<F>(ftl::enum_cast(lhs) | ftl::enum_cast(rhs));
}
} // namespace flag_operators
diff --git a/include/ftl/NamedEnum.h b/include/ftl/NamedEnum.h
deleted file mode 100644
index 6e98fee..0000000
--- a/include/ftl/NamedEnum.h
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * 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 <array>
-#include <cstdint>
-#include <optional>
-#include <string>
-
-#pragma once
-
-namespace android {
-
-namespace details {
-template <typename E, E V>
-constexpr std::optional<std::string_view> enum_value_name() {
- // Should look something like (but all on one line):
- // std::optional<std::string_view>
- // android::details::enum_value_name()
- // [E = android::test::TestEnums, V = android::test::TestEnums::ONE]
- std::string_view view = __PRETTY_FUNCTION__;
- size_t templateStart = view.rfind("[");
- size_t templateEnd = view.rfind("]");
- if (templateStart == std::string::npos || templateEnd == std::string::npos) {
- return std::nullopt;
- }
-
- // Extract the template parameters without the enclosing braces.
- // Example (cont'd): E = android::test::TestEnums, V = android::test::TestEnums::ONE
- view = view.substr(templateStart + 1, templateEnd - templateStart - 1);
- size_t valStart = view.rfind("V = ");
- if (valStart == std::string::npos) {
- return std::nullopt;
- }
-
- // Example (cont'd): V = android::test::TestEnums::ONE
- view = view.substr(valStart);
- // Check invalid enum values with cast, like V = (android::test::TestEnums)8.
- if (view.find('(') != std::string::npos) {
- return std::nullopt;
- }
- size_t nameStart = view.rfind("::");
- if (nameStart == std::string::npos) {
- return std::nullopt;
- }
-
- // Chop off the initial "::"
- nameStart += 2;
- return view.substr(nameStart);
-}
-
-template <typename E, typename T, T... I>
-constexpr auto generate_enum_values(std::integer_sequence<T, I...> seq) {
- constexpr size_t count = seq.size();
-
- std::array<E, count> values{};
- for (size_t i = 0, v = 0; v < count; ++i) {
- values[v++] = static_cast<E>(T{0} + i);
- }
-
- return values;
-}
-
-template <typename E, std::size_t N>
-inline constexpr auto enum_values =
- generate_enum_values<E>(std::make_integer_sequence<std::underlying_type_t<E>, N>{});
-
-template <typename E, std::size_t N, std::size_t... I>
-constexpr auto generate_enum_names(std::index_sequence<I...>) noexcept {
- return std::array<std::optional<std::string_view>, sizeof...(I)>{
- {enum_value_name<E, enum_values<E, N>[I]>()...}};
-}
-
-template <typename E, std::size_t N>
-inline constexpr auto enum_names = generate_enum_names<E, N>(std::make_index_sequence<N>{});
-
-} // namespace details
-
-class NamedEnum {
-public:
- // By default allowed enum value range is 0 ~ 7.
- template <typename E>
- static constexpr size_t max = 8;
-
- template <auto V>
- static constexpr auto enum_name() {
- using E = decltype(V);
- return details::enum_value_name<E, V>();
- }
-
- template <typename E>
- static constexpr std::optional<std::string_view> enum_name(E val) {
- auto idx = static_cast<size_t>(val);
- return idx < max<E> ? details::enum_names<E, max<E>>[idx] : std::nullopt;
- }
-
- // Helper function for parsing enum value to string.
- // Example : enum class TestEnums { ZERO = 0x0 };
- // NamedEnum::string(TestEnums::ZERO) returns string of "ZERO".
- // Note the default maximum enum is 8, if the enum ID to be parsed if greater than 8 like 16,
- // it should be declared to specialized the maximum enum by below:
- // template <> constexpr size_t NamedEnum::max<TestEnums> = 16;
- // If the enum class definition is sparse and contains enum values starting from a large value,
- // Do not specialize it to a large number to avoid performance issues.
- // The recommended maximum enum number to specialize is 64.
- template <typename E>
- static const std::string string(E val, const char* fallbackFormat = "%02d") {
- std::string result;
- std::optional<std::string_view> enumString = enum_name(val);
- result += enumString ? enumString.value() : base::StringPrintf(fallbackFormat, val);
- return result;
- }
-};
-
-} // namespace android
diff --git a/include/ftl/enum.h b/include/ftl/enum.h
new file mode 100644
index 0000000..dfe3a09
--- /dev/null
+++ b/include/ftl/enum.h
@@ -0,0 +1,299 @@
+/*
+ * Copyright 2021 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.
+ */
+
+#pragma once
+
+#include <cstddef>
+#include <limits>
+#include <optional>
+#include <string_view>
+#include <type_traits>
+#include <utility>
+
+#include <ftl/string.h>
+
+// Returns the name of enumerator E::V (i.e. "V") as std::optional<std::string_view> by parsing the
+// compiler-generated string literal for the signature of this function. The function is defined in
+// the global namespace with a short name and inferred return type to reduce bloat in the read-only
+// data segment.
+template <typename E, E V>
+constexpr auto ftl_enum() {
+ static_assert(std::is_enum_v<E>);
+
+ using R = std::optional<std::string_view>;
+ using namespace std::literals;
+
+ // The "pretty" signature has the following format:
+ //
+ // auto ftl_enum() [E = android::test::Enum, V = android::test::Enum::kValue]
+ //
+ std::string_view view = __PRETTY_FUNCTION__;
+ const auto template_begin = view.rfind('[');
+ const auto template_end = view.rfind(']');
+ if (template_begin == view.npos || template_end == view.npos) return R{};
+
+ // Extract the template parameters without the enclosing brackets. Example (cont'd):
+ //
+ // E = android::test::Enum, V = android::test::Enum::kValue
+ //
+ view = view.substr(template_begin + 1, template_end - template_begin - 1);
+ const auto value_begin = view.rfind("V = "sv);
+ if (value_begin == view.npos) return R{};
+
+ // Example (cont'd):
+ //
+ // V = android::test::Enum::kValue
+ //
+ view = view.substr(value_begin);
+ const auto name_begin = view.rfind("::"sv);
+ if (name_begin == view.npos) return R{};
+
+ // Chop off the leading "::".
+ const auto name = view.substr(name_begin + 2);
+
+ // A value that is not enumerated has the format "Enum)42".
+ return name.find(')') == view.npos ? R{name} : R{};
+}
+
+namespace android::ftl {
+
+// Trait for determining whether a type is specifically a scoped enum or not. By definition, a
+// scoped enum is one that is not implicitly convertible to its underlying type.
+//
+// TODO: Replace with std::is_scoped_enum in C++23.
+//
+template <typename T, bool = std::is_enum_v<T>>
+struct is_scoped_enum : std::false_type {};
+
+template <typename T>
+struct is_scoped_enum<T, true> : std::negation<std::is_convertible<T, std::underlying_type_t<T>>> {
+};
+
+template <typename T>
+inline constexpr bool is_scoped_enum_v = is_scoped_enum<T>::value;
+
+// Shorthand for casting an enumerator to its integral value.
+//
+// enum class E { A, B, C };
+// static_assert(ftl::enum_cast(E::B) == 1);
+//
+template <typename E>
+constexpr auto enum_cast(E v) {
+ return static_cast<std::underlying_type_t<E>>(v);
+}
+
+// Traits for retrieving an enum's range. An enum specifies its range by defining enumerators named
+// ftl_first and ftl_last. If omitted, ftl_first defaults to 0, whereas ftl_last defaults to N - 1
+// where N is the bit width of the underlying type, but only if that type is unsigned, assuming the
+// enumerators are flags. Also, note that unscoped enums must define both bounds, as casting out-of-
+// range values results in undefined behavior if the underlying type is not fixed.
+//
+// enum class E { A, B, C, F = 5, ftl_last = F };
+//
+// static_assert(ftl::enum_begin_v<E> == E::A);
+// static_assert(ftl::enum_last_v<E> == E::F);
+// static_assert(ftl::enum_size_v<E> == 6);
+//
+// enum class F : std::uint16_t { X = 0b1, Y = 0b10, Z = 0b100 };
+//
+// static_assert(ftl::enum_begin_v<F> == F{0});
+// static_assert(ftl::enum_last_v<F> == F{15});
+// static_assert(ftl::enum_size_v<F> == 16);
+//
+template <typename E, typename = void>
+struct enum_begin {
+ static_assert(is_scoped_enum_v<E>, "Missing ftl_first enumerator");
+ static constexpr E value{0};
+};
+
+template <typename E>
+struct enum_begin<E, std::void_t<decltype(E::ftl_first)>> {
+ static constexpr E value = E::ftl_first;
+};
+
+template <typename E>
+inline constexpr E enum_begin_v = enum_begin<E>::value;
+
+template <typename E, typename = void>
+struct enum_end {
+ using U = std::underlying_type_t<E>;
+ static_assert(is_scoped_enum_v<E> && std::is_unsigned_v<U>, "Missing ftl_last enumerator");
+
+ static constexpr E value{std::numeric_limits<U>::digits};
+};
+
+template <typename E>
+struct enum_end<E, std::void_t<decltype(E::ftl_last)>> {
+ static constexpr E value = E{enum_cast(E::ftl_last) + 1};
+};
+
+template <typename E>
+inline constexpr E enum_end_v = enum_end<E>::value;
+
+template <typename E>
+inline constexpr E enum_last_v = E{enum_cast(enum_end_v<E>) - 1};
+
+template <typename E>
+struct enum_size {
+ static constexpr auto kBegin = enum_cast(enum_begin_v<E>);
+ static constexpr auto kEnd = enum_cast(enum_end_v<E>);
+ static_assert(kBegin < kEnd, "Invalid range");
+
+ static constexpr std::size_t value = kEnd - kBegin;
+ static_assert(value <= 64, "Excessive range size");
+};
+
+template <typename E>
+inline constexpr std::size_t enum_size_v = enum_size<E>::value;
+
+namespace details {
+
+template <auto V>
+struct Identity {
+ static constexpr auto value = V;
+};
+
+template <typename E>
+using make_enum_sequence = std::make_integer_sequence<std::underlying_type_t<E>, enum_size_v<E>>;
+
+template <typename E, template <E> class = Identity, typename = make_enum_sequence<E>>
+struct EnumRange;
+
+template <typename E, template <E> class F, typename T, T... Vs>
+struct EnumRange<E, F, std::integer_sequence<T, Vs...>> {
+ static constexpr auto kBegin = enum_cast(enum_begin_v<E>);
+ static constexpr auto kSize = enum_size_v<E>;
+
+ using R = decltype(F<E{}>::value);
+ const R values[kSize] = {F<static_cast<E>(Vs + kBegin)>::value...};
+
+ constexpr const auto* begin() const { return values; }
+ constexpr const auto* end() const { return values + kSize; }
+};
+
+template <auto V>
+struct EnumName {
+ static constexpr auto value = ftl_enum<decltype(V), V>();
+};
+
+template <auto I>
+struct FlagName {
+ using E = decltype(I);
+ using U = std::underlying_type_t<E>;
+
+ static constexpr E V{U{1} << enum_cast(I)};
+ static constexpr auto value = ftl_enum<E, V>();
+};
+
+} // namespace details
+
+// Returns an iterable over the range of an enum.
+//
+// enum class E { A, B, C, F = 5, ftl_last = F };
+//
+// std::string string;
+// for (E v : ftl::enum_range<E>()) {
+// string += ftl::enum_name(v).value_or("?");
+// }
+//
+// assert(string == "ABC??F");
+//
+template <typename E>
+constexpr auto enum_range() {
+ return details::EnumRange<E>{};
+}
+
+// Returns a stringified enumerator at compile time.
+//
+// enum class E { A, B, C };
+// static_assert(ftl::enum_name<E::B>() == "B");
+//
+template <auto V>
+constexpr std::string_view enum_name() {
+ constexpr auto kName = ftl_enum<decltype(V), V>();
+ static_assert(kName, "Unknown enumerator");
+ return *kName;
+}
+
+// Returns a stringified enumerator, possibly at compile time.
+//
+// enum class E { A, B, C, F = 5, ftl_last = F };
+//
+// static_assert(ftl::enum_name(E::C).value_or("?") == "C");
+// static_assert(ftl::enum_name(E{3}).value_or("?") == "?");
+//
+template <typename E>
+constexpr std::optional<std::string_view> enum_name(E v) {
+ const auto value = enum_cast(v);
+
+ constexpr auto kBegin = enum_cast(enum_begin_v<E>);
+ constexpr auto kLast = enum_cast(enum_last_v<E>);
+ if (value < kBegin || value > kLast) return {};
+
+ constexpr auto kRange = details::EnumRange<E, details::EnumName>{};
+ return kRange.values[value - kBegin];
+}
+
+// Returns a stringified flag enumerator, possibly at compile time.
+//
+// enum class F : std::uint16_t { X = 0b1, Y = 0b10, Z = 0b100 };
+//
+// static_assert(ftl::flag_name(F::Z).value_or("?") == "Z");
+// static_assert(ftl::flag_name(F{0b111}).value_or("?") == "?");
+//
+template <typename E>
+constexpr std::optional<std::string_view> flag_name(E v) {
+ const auto value = enum_cast(v);
+
+ // TODO: Replace with std::popcount and std::countr_zero in C++20.
+ if (__builtin_popcountl(value) != 1) return {};
+
+ constexpr auto kRange = details::EnumRange<E, details::FlagName>{};
+ return kRange.values[__builtin_ctzl(value)];
+}
+
+// Returns a stringified enumerator, or its integral value if not named.
+//
+// enum class E { A, B, C, F = 5, ftl_last = F };
+//
+// assert(ftl::enum_string(E::C) == "C");
+// assert(ftl::enum_string(E{3}) == "3");
+//
+template <typename E>
+inline std::string enum_string(E v) {
+ if (const auto name = enum_name(v)) {
+ return std::string(*name);
+ }
+ return to_string(enum_cast(v));
+}
+
+// Returns a stringified flag enumerator, or its integral value if not named.
+//
+// enum class F : std::uint16_t { X = 0b1, Y = 0b10, Z = 0b100 };
+//
+// assert(ftl::flag_string(F::Z) == "Z");
+// assert(ftl::flag_string(F{7}) == "0b111");
+//
+template <typename E>
+inline std::string flag_string(E v) {
+ if (const auto name = flag_name(v)) {
+ return std::string(*name);
+ }
+ constexpr auto radix = sizeof(E) == 1 ? Radix::kBin : Radix::kHex;
+ return to_string(enum_cast(v), radix);
+}
+
+} // namespace android::ftl
diff --git a/include/input/DisplayViewport.h b/include/input/DisplayViewport.h
index a6213f3..9148fee 100644
--- a/include/input/DisplayViewport.h
+++ b/include/input/DisplayViewport.h
@@ -18,7 +18,8 @@
#define _LIBINPUT_DISPLAY_VIEWPORT_H
#include <android-base/stringprintf.h>
-#include <ftl/NamedEnum.h>
+#include <ftl/enum.h>
+#include <ftl/string.h>
#include <gui/constants.h>
#include <input/Input.h>
@@ -44,6 +45,8 @@
INTERNAL = 1,
EXTERNAL = 2,
VIRTUAL = 3,
+
+ ftl_last = VIRTUAL
};
/*
@@ -132,9 +135,8 @@
"physicalFrame=[%d, %d, %d, %d], "
"deviceSize=[%d, %d], "
"isActive=[%d]",
- NamedEnum::string(type).c_str(), displayId, uniqueId.c_str(),
- physicalPort ? StringPrintf("%" PRIu8, *physicalPort).c_str()
- : "<none>",
+ ftl::enum_string(type).c_str(), displayId, uniqueId.c_str(),
+ physicalPort ? ftl::to_string(*physicalPort).c_str() : "<none>",
orientation, logicalLeft, logicalTop, logicalRight, logicalBottom,
physicalLeft, physicalTop, physicalRight, physicalBottom, deviceWidth,
deviceHeight, isActive);
diff --git a/include/input/InputDevice.h b/include/input/InputDevice.h
index 7f0324a..22aae19 100644
--- a/include/input/InputDevice.h
+++ b/include/input/InputDevice.h
@@ -84,6 +84,9 @@
GAME_ROTATION_VECTOR = ASENSOR_TYPE_GAME_ROTATION_VECTOR,
GYROSCOPE_UNCALIBRATED = ASENSOR_TYPE_GYROSCOPE_UNCALIBRATED,
SIGNIFICANT_MOTION = ASENSOR_TYPE_SIGNIFICANT_MOTION,
+
+ ftl_first = ACCELEROMETER,
+ ftl_last = SIGNIFICANT_MOTION
};
enum class InputDeviceSensorAccuracy : int32_t {
@@ -105,6 +108,8 @@
PLAYER_ID = 1,
RGB = 2,
MULTI_COLOR = 3,
+
+ ftl_last = MULTI_COLOR
};
struct InputDeviceSensorInfo {
diff --git a/include/input/InputTransport.h b/include/input/InputTransport.h
index 9a150eb..7632b30 100644
--- a/include/input/InputTransport.h
+++ b/include/input/InputTransport.h
@@ -73,6 +73,8 @@
DRAG,
TIMELINE,
TOUCH_MODE,
+
+ ftl_last = TOUCH_MODE
};
struct Header {
diff --git a/libs/ftl/Android.bp b/libs/ftl/Android.bp
index 3026921..5a80ad0 100644
--- a/libs/ftl/Android.bp
+++ b/libs/ftl/Android.bp
@@ -14,10 +14,10 @@
address: true,
},
srcs: [
- "cast_test.cpp",
"Flags_test.cpp",
+ "cast_test.cpp",
+ "enum_test.cpp",
"future_test.cpp",
- "NamedEnum_test.cpp",
"small_map_test.cpp",
"small_vector_test.cpp",
"static_vector_test.cpp",
diff --git a/libs/ftl/Flags_test.cpp b/libs/ftl/Flags_test.cpp
index 8c00b52..d241fa2 100644
--- a/libs/ftl/Flags_test.cpp
+++ b/libs/ftl/Flags_test.cpp
@@ -23,7 +23,7 @@
using namespace android::flag_operators;
-enum class TestFlags { ONE = 0x1, TWO = 0x2, THREE = 0x4 };
+enum class TestFlags : uint8_t { ONE = 0x1, TWO = 0x2, THREE = 0x4 };
TEST(Flags, Test) {
Flags<TestFlags> flags = TestFlags::ONE;
@@ -165,7 +165,7 @@
TEST(Flags, String_UnknownValues) {
auto flags = Flags<TestFlags>(0b1011);
- ASSERT_EQ(flags.string(), "ONE | TWO | 0x00000008");
+ ASSERT_EQ(flags.string(), "ONE | TWO | 0b1000");
}
TEST(FlagsIterator, IteratesOverAllFlags) {
@@ -210,18 +210,4 @@
ASSERT_EQ(++iter, flags.end());
}
-TEST(FlagNames, RuntimeFlagName) {
- TestFlags f = TestFlags::ONE;
- ASSERT_EQ(flag_name(f), "ONE");
-}
-
-TEST(FlagNames, RuntimeUnknownFlagName) {
- TestFlags f = static_cast<TestFlags>(0x8);
- ASSERT_EQ(flag_name(f), std::nullopt);
-}
-
-TEST(FlagNames, CompileTimeFlagName) {
- static_assert(flag_name<TestFlags::TWO>() == "TWO");
-}
-
-} // namespace android::test
\ No newline at end of file
+} // namespace android::test
diff --git a/libs/ftl/NamedEnum_test.cpp b/libs/ftl/NamedEnum_test.cpp
deleted file mode 100644
index dff2b8a..0000000
--- a/libs/ftl/NamedEnum_test.cpp
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * 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 <ftl/NamedEnum.h>
-
-namespace android {
-
-// Test enum class maximum enum value smaller than default maximum of 8.
-enum class TestEnums { ZERO = 0x0, ONE = 0x1, TWO = 0x2, THREE = 0x3, SEVEN = 0x7 };
-// Big enum contains enum values greater than default maximum of 8.
-enum class TestBigEnums { ZERO = 0x0, FIFTEEN = 0xF };
-
-// Declared to specialize the maximum enum since the enum size exceeds 8 by default.
-template <>
-constexpr size_t NamedEnum::max<TestBigEnums> = 16;
-
-namespace test {
-using android::TestBigEnums;
-using android::TestEnums;
-
-TEST(NamedEnum, RuntimeNamedEnum) {
- TestEnums e = TestEnums::ZERO;
- ASSERT_EQ(NamedEnum::enum_name(e), "ZERO");
-
- e = TestEnums::ONE;
- ASSERT_EQ(NamedEnum::enum_name(e), "ONE");
-
- e = TestEnums::THREE;
- ASSERT_EQ(NamedEnum::enum_name(e), "THREE");
-
- e = TestEnums::SEVEN;
- ASSERT_EQ(NamedEnum::enum_name(e), "SEVEN");
-}
-
-// Test big enum
-TEST(NamedEnum, RuntimeBigNamedEnum) {
- TestBigEnums e = TestBigEnums::ZERO;
- ASSERT_EQ(NamedEnum::enum_name(e), "ZERO");
-
- e = TestBigEnums::FIFTEEN;
- ASSERT_EQ(NamedEnum::enum_name(e), "FIFTEEN");
-}
-
-TEST(NamedEnum, RuntimeNamedEnumAsString) {
- TestEnums e = TestEnums::ZERO;
- ASSERT_EQ(NamedEnum::string(e), "ZERO");
-
- e = TestEnums::ONE;
- ASSERT_EQ(NamedEnum::string(e), "ONE");
-
- e = TestEnums::THREE;
- ASSERT_EQ(NamedEnum::string(e), "THREE");
-
- e = TestEnums::SEVEN;
- ASSERT_EQ(NamedEnum::string(e), "SEVEN");
-}
-
-TEST(NamedEnum, RuntimeBigNamedEnumAsString) {
- TestBigEnums e = TestBigEnums::ZERO;
- ASSERT_EQ(NamedEnum::string(e), "ZERO");
-
- e = TestBigEnums::FIFTEEN;
- ASSERT_EQ(NamedEnum::string(e), "FIFTEEN");
-}
-
-TEST(NamedEnum, RuntimeUnknownNamedEnum) {
- TestEnums e = static_cast<TestEnums>(0x5);
- ASSERT_EQ(NamedEnum::enum_name(e), std::nullopt);
- e = static_cast<TestEnums>(0x9);
- ASSERT_EQ(NamedEnum::enum_name(e), std::nullopt);
-}
-
-TEST(NamedEnum, RuntimeUnknownNamedEnumAsString) {
- TestEnums e = static_cast<TestEnums>(0x5);
- ASSERT_EQ(NamedEnum::string(e), "05");
- e = static_cast<TestEnums>(0x9);
- ASSERT_EQ(NamedEnum::string(e, "0x%08x"), "0x00000009");
-}
-
-TEST(NamedEnum, CompileTimeFlagName) {
- static_assert(NamedEnum::enum_name<TestEnums::TWO>() == "TWO");
- static_assert(NamedEnum::enum_name<TestEnums::THREE>() == "THREE");
-}
-
-} // namespace test
-
-} // namespace android
diff --git a/libs/ftl/enum_test.cpp b/libs/ftl/enum_test.cpp
new file mode 100644
index 0000000..1fd43ab
--- /dev/null
+++ b/libs/ftl/enum_test.cpp
@@ -0,0 +1,164 @@
+/*
+ * Copyright 2021 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 <ftl/enum.h>
+#include <gtest/gtest.h>
+
+namespace android::test {
+
+// Keep in sync with example usage in header file.
+namespace {
+
+enum class E { A, B, C, F = 5, ftl_last = F };
+
+static_assert(ftl::enum_begin_v<E> == E::A);
+static_assert(ftl::enum_last_v<E> == E::F);
+static_assert(ftl::enum_size_v<E> == 6);
+
+static_assert(ftl::enum_name<E::B>() == "B");
+static_assert(ftl::enum_name<E::ftl_last>() == "F");
+static_assert(ftl::enum_name(E::C).value_or("?") == "C");
+static_assert(ftl::enum_name(E{3}).value_or("?") == "?");
+
+enum class F : std::uint16_t { X = 0b1, Y = 0b10, Z = 0b100 };
+
+static_assert(ftl::enum_begin_v<F> == F{0});
+static_assert(ftl::enum_last_v<F> == F{15});
+static_assert(ftl::enum_size_v<F> == 16);
+
+static_assert(ftl::flag_name(F::Z).value_or("?") == "Z");
+static_assert(ftl::flag_name(F{0b111}).value_or("?") == "?");
+
+// If a scoped enum is unsigned, its implicit range corresponds to its bit indices.
+enum class Flags : std::uint8_t {
+ kNone = 0,
+ kFlag1 = 0b0000'0010,
+ kFlag4 = 0b0001'0000,
+ kFlag7 = 0b1000'0000,
+ kMask = kFlag1 | kFlag4 | kFlag7,
+ kAll = 0b1111'1111
+};
+
+static_assert(ftl::enum_begin_v<Flags> == Flags{0});
+static_assert(ftl::enum_last_v<Flags> == Flags{7});
+static_assert(ftl::enum_size_v<Flags> == 8);
+
+static_assert(ftl::enum_name<Flags::kNone>() == "kNone");
+static_assert(ftl::enum_name<Flags::kFlag4>() == "kFlag4");
+static_assert(ftl::enum_name<Flags::kFlag7>() == "kFlag7");
+
+// Though not flags, the enumerators are within the implicit range of bit indices.
+enum class Planet : std::uint8_t {
+ kMercury,
+ kVenus,
+ kEarth,
+ kMars,
+ kJupiter,
+ kSaturn,
+ kUranus,
+ kNeptune
+};
+
+constexpr Planet kPluto{ftl::enum_cast(Planet::kNeptune) + 1}; // Honorable mention.
+
+static_assert(ftl::enum_begin_v<Planet> == Planet::kMercury);
+static_assert(ftl::enum_last_v<Planet> == Planet::kNeptune);
+static_assert(ftl::enum_size_v<Planet> == 8);
+
+static_assert(ftl::enum_name<Planet::kMercury>() == "kMercury");
+static_assert(ftl::enum_name<Planet::kSaturn>() == "kSaturn");
+
+// Unscoped enum must define explicit range, even if the underlying type is fixed.
+enum Temperature : int {
+ kRoom = 20,
+ kFridge = 4,
+ kFreezer = -18,
+
+ ftl_first = kFreezer,
+ ftl_last = kRoom
+};
+
+static_assert(ftl::enum_begin_v<Temperature> == kFreezer);
+static_assert(ftl::enum_last_v<Temperature> == kRoom);
+static_assert(ftl::enum_size_v<Temperature> == 39);
+
+static_assert(ftl::enum_name<kFreezer>() == "kFreezer");
+static_assert(ftl::enum_name<kFridge>() == "kFridge");
+static_assert(ftl::enum_name<kRoom>() == "kRoom");
+
+} // namespace
+
+TEST(Enum, Range) {
+ std::string string;
+ for (E v : ftl::enum_range<E>()) {
+ string += ftl::enum_name(v).value_or("?");
+ }
+ EXPECT_EQ(string, "ABC??F");
+}
+
+TEST(Enum, Name) {
+ {
+ EXPECT_EQ(ftl::flag_name(Flags::kFlag1), "kFlag1");
+ EXPECT_EQ(ftl::flag_name(Flags::kFlag7), "kFlag7");
+
+ EXPECT_EQ(ftl::flag_name(Flags::kNone), std::nullopt);
+ EXPECT_EQ(ftl::flag_name(Flags::kMask), std::nullopt);
+ EXPECT_EQ(ftl::flag_name(Flags::kAll), std::nullopt);
+ }
+ {
+ EXPECT_EQ(ftl::enum_name(Planet::kEarth), "kEarth");
+ EXPECT_EQ(ftl::enum_name(Planet::kNeptune), "kNeptune");
+
+ EXPECT_EQ(ftl::enum_name(kPluto), std::nullopt);
+ }
+ {
+ EXPECT_EQ(ftl::enum_name(kRoom), "kRoom");
+ EXPECT_EQ(ftl::enum_name(kFridge), "kFridge");
+ EXPECT_EQ(ftl::enum_name(kFreezer), "kFreezer");
+
+ EXPECT_EQ(ftl::enum_name(static_cast<Temperature>(-30)), std::nullopt);
+ EXPECT_EQ(ftl::enum_name(static_cast<Temperature>(0)), std::nullopt);
+ EXPECT_EQ(ftl::enum_name(static_cast<Temperature>(100)), std::nullopt);
+ }
+}
+
+TEST(Enum, String) {
+ {
+ EXPECT_EQ(ftl::flag_string(Flags::kFlag1), "kFlag1");
+ EXPECT_EQ(ftl::flag_string(Flags::kFlag7), "kFlag7");
+
+ EXPECT_EQ(ftl::flag_string(Flags::kNone), "0b0");
+ EXPECT_EQ(ftl::flag_string(Flags::kMask), "0b10010010");
+ EXPECT_EQ(ftl::flag_string(Flags::kAll), "0b11111111");
+ }
+ {
+ EXPECT_EQ(ftl::enum_string(Planet::kEarth), "kEarth");
+ EXPECT_EQ(ftl::enum_string(Planet::kNeptune), "kNeptune");
+
+ EXPECT_EQ(ftl::enum_string(kPluto), "8");
+ }
+ {
+ EXPECT_EQ(ftl::enum_string(kRoom), "kRoom");
+ EXPECT_EQ(ftl::enum_string(kFridge), "kFridge");
+ EXPECT_EQ(ftl::enum_string(kFreezer), "kFreezer");
+
+ EXPECT_EQ(ftl::enum_string(static_cast<Temperature>(-30)), "-30");
+ EXPECT_EQ(ftl::enum_string(static_cast<Temperature>(0)), "0");
+ EXPECT_EQ(ftl::enum_string(static_cast<Temperature>(100)), "100");
+ }
+}
+
+} // namespace android::test
diff --git a/libs/gui/include/gui/WindowInfo.h b/libs/gui/include/gui/WindowInfo.h
index f090c63..47f6c05 100644
--- a/libs/gui/include/gui/WindowInfo.h
+++ b/libs/gui/include/gui/WindowInfo.h
@@ -71,8 +71,9 @@
SLIPPERY = 0x20000000,
LAYOUT_ATTACHED_IN_DECOR = 0x40000000,
DRAWS_SYSTEM_BAR_BACKGROUNDS = 0x80000000,
- }; // Window types from WindowManager.LayoutParams
+ };
+ // Window types from WindowManager.LayoutParams
enum class Type : int32_t {
UNKNOWN = 0,
FIRST_APPLICATION_WINDOW = 1,
@@ -87,40 +88,50 @@
APPLICATION_ATTACHED_DIALOG = FIRST_SUB_WINDOW + 3,
APPLICATION_MEDIA_OVERLAY = FIRST_SUB_WINDOW + 4,
LAST_SUB_WINDOW = 1999,
- FIRST_SYSTEM_WINDOW = 2000,
- 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,
+
+#define FIRST_SYSTEM_WINDOW_ 2000
+
+ 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,
+
+ FIRST_SYSTEM_WINDOW = FIRST_SYSTEM_WINDOW_,
LAST_SYSTEM_WINDOW = 2999,
+
+#undef FIRST_SYSTEM_WINDOW_
+
+ // Small range to limit LUT size.
+ ftl_first = FIRST_SYSTEM_WINDOW,
+ ftl_last = FIRST_SYSTEM_WINDOW + 15
};
- enum class Feature {
+ enum class Feature : uint32_t {
DISABLE_TOUCH_PAD_GESTURES = 0x00000001,
NO_INPUT_CHANNEL = 0x00000002,
DISABLE_USER_ACTIVITY = 0x00000004,
@@ -265,4 +276,4 @@
WindowInfo mInfo;
};
-} // namespace android::gui
\ No newline at end of file
+} // namespace android::gui
diff --git a/libs/input/InputDevice.cpp b/libs/input/InputDevice.cpp
index 220c8e1..69ae9a0 100644
--- a/libs/input/InputDevice.cpp
+++ b/libs/input/InputDevice.cpp
@@ -21,7 +21,7 @@
#include <ctype.h>
#include <android-base/stringprintf.h>
-#include <ftl/NamedEnum.h>
+#include <ftl/enum.h>
#include <input/InputDevice.h>
#include <input/InputEventLabels.h>
@@ -228,7 +228,7 @@
void InputDeviceInfo::addSensorInfo(const InputDeviceSensorInfo& info) {
if (mSensors.find(info.type) != mSensors.end()) {
ALOGW("Sensor type %s already exists, will be replaced by new sensor added.",
- NamedEnum::string(info.type).c_str());
+ ftl::enum_string(info.type).c_str());
}
mSensors.insert_or_assign(info.type, info);
}
diff --git a/libs/input/InputTransport.cpp b/libs/input/InputTransport.cpp
index 1e93dfb..91ab008 100644
--- a/libs/input/InputTransport.cpp
+++ b/libs/input/InputTransport.cpp
@@ -30,10 +30,10 @@
#include <android-base/stringprintf.h>
#include <binder/Parcel.h>
#include <cutils/properties.h>
+#include <ftl/enum.h>
#include <log/log.h>
#include <utils/Trace.h>
-#include <ftl/NamedEnum.h>
#include <input/InputTransport.h>
using android::base::StringPrintf;
@@ -714,7 +714,7 @@
}
ALOGE("channel '%s' publisher ~ Received unexpected %s message from consumer",
- mChannel->getName().c_str(), NamedEnum::string(msg.header.type).c_str());
+ mChannel->getName().c_str(), ftl::enum_string(msg.header.type).c_str());
return android::base::Error(UNKNOWN_ERROR);
}
@@ -856,7 +856,7 @@
case InputMessage::Type::TIMELINE: {
LOG_ALWAYS_FATAL("Consumed a %s message, which should never be seen by "
"InputConsumer!",
- NamedEnum::string(mMsg.header.type).c_str());
+ ftl::enum_string(mMsg.header.type).c_str());
break;
}
@@ -1449,14 +1449,14 @@
out = out + "mChannel = " + mChannel->getName() + "\n";
out = out + "mMsgDeferred: " + toString(mMsgDeferred) + "\n";
if (mMsgDeferred) {
- out = out + "mMsg : " + NamedEnum::string(mMsg.header.type) + "\n";
+ out = out + "mMsg : " + ftl::enum_string(mMsg.header.type) + "\n";
}
out += "Batches:\n";
for (const Batch& batch : mBatches) {
out += " Batch:\n";
for (const InputMessage& msg : batch.samples) {
out += android::base::StringPrintf(" Message %" PRIu32 ": %s ", msg.header.seq,
- NamedEnum::string(msg.header.type).c_str());
+ ftl::enum_string(msg.header.type).c_str());
switch (msg.header.type) {
case InputMessage::Type::KEY: {
out += android::base::StringPrintf("action=%s keycode=%" PRId32,
diff --git a/libs/input/KeyLayoutMap.cpp b/libs/input/KeyLayoutMap.cpp
index c365ab0..7c25cda 100644
--- a/libs/input/KeyLayoutMap.cpp
+++ b/libs/input/KeyLayoutMap.cpp
@@ -16,10 +16,8 @@
#define LOG_TAG "KeyLayoutMap"
-#include <stdlib.h>
-
#include <android/keycodes.h>
-#include <ftl/NamedEnum.h>
+#include <ftl/enum.h>
#include <input/InputEventLabels.h>
#include <input/KeyLayoutMap.h>
#include <input/Keyboard.h>
@@ -28,6 +26,10 @@
#include <utils/Timers.h>
#include <utils/Tokenizer.h>
+#include <cstdlib>
+#include <string_view>
+#include <unordered_map>
+
// Enables debug output for the parser.
#define DEBUG_PARSER 0
@@ -39,36 +41,38 @@
namespace android {
+namespace {
-static const char* WHITESPACE = " \t\r";
+constexpr const char* WHITESPACE = " \t\r";
-#define SENSOR_ENTRY(type) NamedEnum::string(type), type
-static const std::unordered_map<std::string, InputDeviceSensorType> SENSOR_LIST =
- {{SENSOR_ENTRY(InputDeviceSensorType::ACCELEROMETER)},
- {SENSOR_ENTRY(InputDeviceSensorType::MAGNETIC_FIELD)},
- {SENSOR_ENTRY(InputDeviceSensorType::ORIENTATION)},
- {SENSOR_ENTRY(InputDeviceSensorType::GYROSCOPE)},
- {SENSOR_ENTRY(InputDeviceSensorType::LIGHT)},
- {SENSOR_ENTRY(InputDeviceSensorType::PRESSURE)},
- {SENSOR_ENTRY(InputDeviceSensorType::TEMPERATURE)},
- {SENSOR_ENTRY(InputDeviceSensorType::PROXIMITY)},
- {SENSOR_ENTRY(InputDeviceSensorType::GRAVITY)},
- {SENSOR_ENTRY(InputDeviceSensorType::LINEAR_ACCELERATION)},
- {SENSOR_ENTRY(InputDeviceSensorType::ROTATION_VECTOR)},
- {SENSOR_ENTRY(InputDeviceSensorType::RELATIVE_HUMIDITY)},
- {SENSOR_ENTRY(InputDeviceSensorType::AMBIENT_TEMPERATURE)},
- {SENSOR_ENTRY(InputDeviceSensorType::MAGNETIC_FIELD_UNCALIBRATED)},
- {SENSOR_ENTRY(InputDeviceSensorType::GAME_ROTATION_VECTOR)},
- {SENSOR_ENTRY(InputDeviceSensorType::GYROSCOPE_UNCALIBRATED)},
- {SENSOR_ENTRY(InputDeviceSensorType::SIGNIFICANT_MOTION)}};
-
-// --- KeyLayoutMap ---
-
-KeyLayoutMap::KeyLayoutMap() {
+template <InputDeviceSensorType S>
+constexpr auto sensorPair() {
+ return std::make_pair(ftl::enum_name<S>(), S);
}
-KeyLayoutMap::~KeyLayoutMap() {
-}
+static const std::unordered_map<std::string_view, InputDeviceSensorType> SENSOR_LIST =
+ {sensorPair<InputDeviceSensorType::ACCELEROMETER>(),
+ sensorPair<InputDeviceSensorType::MAGNETIC_FIELD>(),
+ sensorPair<InputDeviceSensorType::ORIENTATION>(),
+ sensorPair<InputDeviceSensorType::GYROSCOPE>(),
+ sensorPair<InputDeviceSensorType::LIGHT>(),
+ sensorPair<InputDeviceSensorType::PRESSURE>(),
+ sensorPair<InputDeviceSensorType::TEMPERATURE>(),
+ sensorPair<InputDeviceSensorType::PROXIMITY>(),
+ sensorPair<InputDeviceSensorType::GRAVITY>(),
+ sensorPair<InputDeviceSensorType::LINEAR_ACCELERATION>(),
+ sensorPair<InputDeviceSensorType::ROTATION_VECTOR>(),
+ sensorPair<InputDeviceSensorType::RELATIVE_HUMIDITY>(),
+ sensorPair<InputDeviceSensorType::AMBIENT_TEMPERATURE>(),
+ sensorPair<InputDeviceSensorType::MAGNETIC_FIELD_UNCALIBRATED>(),
+ sensorPair<InputDeviceSensorType::GAME_ROTATION_VECTOR>(),
+ sensorPair<InputDeviceSensorType::GYROSCOPE_UNCALIBRATED>(),
+ sensorPair<InputDeviceSensorType::SIGNIFICANT_MOTION>()};
+
+} // namespace
+
+KeyLayoutMap::KeyLayoutMap() = default;
+KeyLayoutMap::~KeyLayoutMap() = default;
base::Result<std::shared_ptr<KeyLayoutMap>> KeyLayoutMap::loadContents(const std::string& filename,
const char* contents) {
@@ -160,8 +164,8 @@
const Sensor& sensor = it->second;
#if DEBUG_MAPPING
- ALOGD("mapSensor: absCode=%d, sensorType=0x%0x, sensorDataIndex=0x%x.", absCode,
- NamedEnum::string(sensor.sensorType), sensor.sensorDataIndex);
+ ALOGD("mapSensor: absCode=%d, sensorType=%s, sensorDataIndex=0x%x.", absCode,
+ ftl::enum_string(sensor.sensorType).c_str(), sensor.sensorDataIndex);
#endif
return std::make_pair(sensor.sensorType, sensor.sensorDataIndex);
}
@@ -513,7 +517,7 @@
}
static std::optional<InputDeviceSensorType> getSensorType(const char* token) {
- auto it = SENSOR_LIST.find(std::string(token));
+ auto it = SENSOR_LIST.find(token);
if (it == SENSOR_LIST.end()) {
return std::nullopt;
}
@@ -581,8 +585,8 @@
int32_t sensorDataIndex = indexOpt.value();
#if DEBUG_PARSER
- ALOGD("Parsed sensor: abs code=%d, sensorType=%d, sensorDataIndex=%d.", code,
- NamedEnum::string(sensorType).c_str(), sensorDataIndex);
+ ALOGD("Parsed sensor: abs code=%d, sensorType=%s, sensorDataIndex=%d.", code,
+ ftl::enum_string(sensorType).c_str(), sensorDataIndex);
#endif
Sensor sensor;
@@ -591,4 +595,5 @@
map.emplace(code, sensor);
return NO_ERROR;
}
-};
+
+} // namespace android
diff --git a/services/inputflinger/InputReaderBase.cpp b/services/inputflinger/InputReaderBase.cpp
index 05ef489..a864cf8 100644
--- a/services/inputflinger/InputReaderBase.cpp
+++ b/services/inputflinger/InputReaderBase.cpp
@@ -19,12 +19,12 @@
//#define LOG_NDEBUG 0
#include "InputReaderBase.h"
-#include <ftl/NamedEnum.h>
#include "input/DisplayViewport.h"
#include "input/Input.h"
-#include <android/log.h>
#include <android-base/stringprintf.h>
+#include <android/log.h>
+#include <ftl/enum.h>
#define INDENT " "
#define INDENT2 " "
@@ -117,7 +117,7 @@
}
if (count > 1) {
ALOGW("Found %zu viewports with type %s, but expected 1 at most", count,
- NamedEnum::string(type).c_str());
+ ftl::enum_string(type).c_str());
}
return result;
}
diff --git a/services/inputflinger/dispatcher/Entry.h b/services/inputflinger/dispatcher/Entry.h
index 547021c..5365a78 100644
--- a/services/inputflinger/dispatcher/Entry.h
+++ b/services/inputflinger/dispatcher/Entry.h
@@ -40,6 +40,8 @@
POINTER_CAPTURE_CHANGED,
DRAG,
TOUCH_MODE_CHANGED,
+
+ ftl_last = TOUCH_MODE_CHANGED
};
int32_t id;
diff --git a/services/inputflinger/dispatcher/FocusResolver.cpp b/services/inputflinger/dispatcher/FocusResolver.cpp
index 4a75773..600f02b 100644
--- a/services/inputflinger/dispatcher/FocusResolver.cpp
+++ b/services/inputflinger/dispatcher/FocusResolver.cpp
@@ -27,7 +27,7 @@
#include <android-base/stringprintf.h>
#include <binder/Binder.h>
-#include <ftl/NamedEnum.h>
+#include <ftl/enum.h>
#include <gui/WindowInfo.h>
#include <log/log.h>
@@ -65,7 +65,7 @@
if (result == Focusability::OK) {
return std::nullopt;
}
- removeFocusReason = NamedEnum::string(result);
+ removeFocusReason = ftl::enum_string(result);
}
// We don't have a focused window or the currently focused window is no longer focusable. Check
@@ -79,7 +79,7 @@
if (result == Focusability::OK) {
return updateFocusedWindow(displayId,
"Window became focusable. Previous reason: " +
- NamedEnum::string(previousResult),
+ ftl::enum_string(previousResult),
requestedFocus, request->windowName);
}
}
@@ -116,7 +116,7 @@
request.token, request.windowName);
}
ALOGW("setFocusedWindow %s on display %" PRId32 " ignored, reason: %s",
- request.windowName.c_str(), displayId, NamedEnum::string(result).c_str());
+ request.windowName.c_str(), displayId, ftl::enum_string(result).c_str());
return std::nullopt;
}
@@ -134,7 +134,7 @@
// The requested window is not currently focusable. Wait for the window to become focusable
// but remove focus from the current window so that input events can go into a pending queue
// and be sent to the window when it becomes focused.
- return updateFocusedWindow(displayId, "Waiting for window because " + NamedEnum::string(result),
+ return updateFocusedWindow(displayId, "Waiting for window because " + ftl::enum_string(result),
nullptr);
}
@@ -212,7 +212,7 @@
for (const auto& [displayId, request] : mFocusRequestByDisplay) {
auto it = mLastFocusResultByDisplay.find(displayId);
std::string result =
- it != mLastFocusResultByDisplay.end() ? NamedEnum::string(it->second) : "";
+ it != mLastFocusResultByDisplay.end() ? ftl::enum_string(it->second) : "";
dump += base::StringPrintf(INDENT2 "displayId=%" PRId32 ", name='%s' result='%s'\n",
displayId, request.windowName.c_str(), result.c_str());
}
diff --git a/services/inputflinger/dispatcher/FocusResolver.h b/services/inputflinger/dispatcher/FocusResolver.h
index 1d6cd9a..6d11a77 100644
--- a/services/inputflinger/dispatcher/FocusResolver.h
+++ b/services/inputflinger/dispatcher/FocusResolver.h
@@ -77,6 +77,8 @@
NO_WINDOW,
NOT_FOCUSABLE,
NOT_VISIBLE,
+
+ ftl_last = NOT_VISIBLE
};
// Checks if the window token can be focused on a display. The token can be focused if there is
@@ -113,4 +115,4 @@
std::optional<android::gui::FocusRequest> getFocusRequest(int32_t displayId);
};
-} // namespace android::inputdispatcher
\ No newline at end of file
+} // namespace android::inputdispatcher
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp
index 92ba52c..9da7192 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.cpp
+++ b/services/inputflinger/dispatcher/InputDispatcher.cpp
@@ -27,6 +27,7 @@
#include <binder/Binder.h>
#include <binder/IServiceManager.h>
#include <com/android/internal/compat/IPlatformCompatNative.h>
+#include <ftl/enum.h>
#include <gui/SurfaceComposerClient.h>
#include <input/InputDevice.h>
#include <log/log.h>
@@ -1151,7 +1152,7 @@
case EventEntry::Type::TOUCH_MODE_CHANGED:
case EventEntry::Type::CONFIGURATION_CHANGED:
case EventEntry::Type::DEVICE_RESET: {
- LOG_ALWAYS_FATAL("Should not drop %s events", NamedEnum::string(entry.type).c_str());
+ LOG_ALWAYS_FATAL("Should not drop %s events", ftl::enum_string(entry.type).c_str());
break;
}
}
@@ -1573,7 +1574,7 @@
ALOGD("notifySensorEvent eventTime=%" PRId64 ", hwTimestamp=%" PRId64 ", deviceId=%d, "
"source=0x%x, sensorType=%s",
entry->eventTime, entry->hwTimestamp, entry->deviceId, entry->source,
- NamedEnum::string(entry->sensorType).c_str());
+ ftl::enum_string(entry->sensorType).c_str());
}
auto command = [this, entry]() REQUIRES(mLock) {
scoped_unlock unlock(mLock);
@@ -1590,7 +1591,7 @@
bool InputDispatcher::flushSensor(int deviceId, InputDeviceSensorType sensorType) {
if (DEBUG_OUTBOUND_EVENT_DETAILS) {
ALOGD("flushSensor deviceId=%d, sensorType=%s", deviceId,
- NamedEnum::string(sensorType).c_str());
+ ftl::enum_string(sensorType).c_str());
}
{ // acquire lock
std::scoped_lock _l(mLock);
@@ -1811,7 +1812,7 @@
case EventEntry::Type::DEVICE_RESET:
case EventEntry::Type::SENSOR:
case EventEntry::Type::DRAG: {
- ALOGE("%s events do not have a target display", NamedEnum::string(entry.type).c_str());
+ ALOGE("%s events do not have a target display", ftl::enum_string(entry.type).c_str());
return ADISPLAY_ID_NONE;
}
}
@@ -1863,7 +1864,7 @@
if (focusedWindowHandle == nullptr && focusedApplicationHandle == nullptr) {
ALOGI("Dropping %s event because there is no focused window or focused application in "
"display %" PRId32 ".",
- NamedEnum::string(entry.type).c_str(), displayId);
+ ftl::enum_string(entry.type).c_str(), displayId);
return InputEventInjectionResult::FAILED;
}
@@ -1888,7 +1889,7 @@
} else if (currentTime > *mNoFocusedWindowTimeoutTime) {
// Already raised ANR. Drop the event
ALOGE("Dropping %s event because there is no focused window",
- NamedEnum::string(entry.type).c_str());
+ ftl::enum_string(entry.type).c_str());
return InputEventInjectionResult::FAILED;
} else {
// Still waiting for the focused window
@@ -2676,8 +2677,7 @@
"frame=[%" PRId32 ",%" PRId32 "][%" PRId32 ",%" PRId32
"], touchableRegion=%s, window={%s}, flags={%s}, inputFeatures={%s}, "
"hasToken=%s, applicationInfo.name=%s, applicationInfo.token=%s\n",
- (isTouchedWindow) ? "[TOUCHED] " : "",
- NamedEnum::string(info->type, "%" PRId32).c_str(),
+ 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,
@@ -2804,7 +2804,7 @@
case EventEntry::Type::POINTER_CAPTURE_CHANGED:
case EventEntry::Type::DRAG: {
LOG_ALWAYS_FATAL("%s events are not user activity",
- NamedEnum::string(eventEntry.type).c_str());
+ ftl::enum_string(eventEntry.type).c_str());
break;
}
}
@@ -2849,7 +2849,7 @@
if (inputTarget.flags & InputTarget::FLAG_SPLIT) {
LOG_ALWAYS_FATAL_IF(eventEntry->type != EventEntry::Type::MOTION,
"Entry type %s should not have FLAG_SPLIT",
- NamedEnum::string(eventEntry->type).c_str());
+ ftl::enum_string(eventEntry->type).c_str());
const MotionEntry& originalMotionEntry = static_cast<const MotionEntry&>(*eventEntry);
if (inputTarget.pointerIds.count() != originalMotionEntry.pointerCount) {
@@ -3037,7 +3037,7 @@
case EventEntry::Type::CONFIGURATION_CHANGED:
case EventEntry::Type::DEVICE_RESET: {
LOG_ALWAYS_FATAL("%s events should not go to apps",
- NamedEnum::string(newEntry.type).c_str());
+ ftl::enum_string(newEntry.type).c_str());
break;
}
}
@@ -3276,7 +3276,7 @@
case EventEntry::Type::DEVICE_RESET:
case EventEntry::Type::SENSOR: {
LOG_ALWAYS_FATAL("Should never start dispatch cycles for %s events",
- NamedEnum::string(eventEntry.type).c_str());
+ ftl::enum_string(eventEntry.type).c_str());
return;
}
}
@@ -3592,14 +3592,14 @@
case EventEntry::Type::POINTER_CAPTURE_CHANGED:
case EventEntry::Type::DRAG: {
LOG_ALWAYS_FATAL("Canceling %s events is not supported",
- NamedEnum::string(cancelationEventEntry->type).c_str());
+ ftl::enum_string(cancelationEventEntry->type).c_str());
break;
}
case EventEntry::Type::CONFIGURATION_CHANGED:
case EventEntry::Type::DEVICE_RESET:
case EventEntry::Type::SENSOR: {
LOG_ALWAYS_FATAL("%s event should not be found inside Connections's queue",
- NamedEnum::string(cancelationEventEntry->type).c_str());
+ ftl::enum_string(cancelationEventEntry->type).c_str());
break;
}
}
@@ -3659,7 +3659,7 @@
case EventEntry::Type::SENSOR:
case EventEntry::Type::DRAG: {
LOG_ALWAYS_FATAL("%s event should not be found inside Connections's queue",
- NamedEnum::string(downEventEntry->type).c_str());
+ ftl::enum_string(downEventEntry->type).c_str());
break;
}
}
@@ -4007,7 +4007,7 @@
ALOGD("notifySensor - id=%" PRIx32 " eventTime=%" PRId64 ", deviceId=%d, source=0x%x, "
" sensorType=%s",
args->id, args->eventTime, args->deviceId, args->source,
- NamedEnum::string(args->sensorType).c_str());
+ ftl::enum_string(args->sensorType).c_str());
}
bool needWake;
@@ -5115,7 +5115,7 @@
toString(windowInfo->hasWallpaper),
toString(windowInfo->visible), windowInfo->alpha,
windowInfo->flags.string().c_str(),
- NamedEnum::string(windowInfo->type).c_str(),
+ ftl::enum_string(windowInfo->type).c_str(),
windowInfo->frameLeft, windowInfo->frameTop,
windowInfo->frameRight, windowInfo->frameBottom,
windowInfo->globalScaleFactor,
diff --git a/services/inputflinger/reader/EventHub.cpp b/services/inputflinger/reader/EventHub.cpp
index 0f0ad0a..d10f8b6 100644
--- a/services/inputflinger/reader/EventHub.cpp
+++ b/services/inputflinger/reader/EventHub.cpp
@@ -40,6 +40,7 @@
#include <android-base/stringprintf.h>
#include <android-base/strings.h>
#include <cutils/properties.h>
+#include <ftl/enum.h>
#include <input/KeyCharacterMap.h>
#include <input/KeyLayoutMap.h>
#include <input/VirtualKeyMap.h>
@@ -263,7 +264,7 @@
*/
static std::vector<std::filesystem::path> findSysfsNodes(const std::filesystem::path& sysfsRoot,
SysfsClass clazz) {
- std::string nodeStr = NamedEnum::string(clazz);
+ std::string nodeStr = ftl::enum_string(clazz);
std::for_each(nodeStr.begin(), nodeStr.end(),
[](char& c) { c = std::tolower(static_cast<unsigned char>(c)); });
std::vector<std::filesystem::path> nodes;
diff --git a/services/inputflinger/reader/controller/PeripheralController.cpp b/services/inputflinger/reader/controller/PeripheralController.cpp
index 9c8a29a..a693496 100644
--- a/services/inputflinger/reader/controller/PeripheralController.cpp
+++ b/services/inputflinger/reader/controller/PeripheralController.cpp
@@ -17,9 +17,9 @@
#include <locale>
#include <regex>
-#include "../Macros.h"
+#include <ftl/enum.h>
-#include <ftl/NamedEnum.h>
+#include "../Macros.h"
#include "PeripheralController.h"
// Log detailed debug messages about input device lights.
@@ -286,7 +286,7 @@
for (const auto& [lightId, light] : mLights) {
dump += StringPrintf(INDENT4 "Id: %d", lightId);
dump += StringPrintf(INDENT4 "Name: %s", light->name.c_str());
- dump += StringPrintf(INDENT4 "Type: %s", NamedEnum::string(light->type).c_str());
+ dump += StringPrintf(INDENT4 "Type: %s", ftl::enum_string(light->type).c_str());
light->dump(dump);
}
}
@@ -487,7 +487,7 @@
auto& light = it->second;
if (DEBUG_LIGHT_DETAILS) {
ALOGD("setLightColor lightId %d type %s color 0x%x", lightId,
- NamedEnum::string(light->type).c_str(), color);
+ ftl::enum_string(light->type).c_str(), color);
}
return light->setLightColor(color);
}
@@ -501,7 +501,7 @@
std::optional<int32_t> color = light->getLightColor();
if (DEBUG_LIGHT_DETAILS) {
ALOGD("getLightColor lightId %d type %s color 0x%x", lightId,
- NamedEnum::string(light->type).c_str(), color.value_or(0));
+ ftl::enum_string(light->type).c_str(), color.value_or(0));
}
return color;
}
diff --git a/services/inputflinger/reader/include/EventHub.h b/services/inputflinger/reader/include/EventHub.h
index 7a00bac..1f96294 100644
--- a/services/inputflinger/reader/include/EventHub.h
+++ b/services/inputflinger/reader/include/EventHub.h
@@ -146,6 +146,8 @@
enum class SysfsClass : uint32_t {
POWER_SUPPLY = 0,
LEDS = 1,
+
+ ftl_last = LEDS
};
enum class LightColor : uint32_t {
diff --git a/services/inputflinger/reader/mapper/SensorInputMapper.cpp b/services/inputflinger/reader/mapper/SensorInputMapper.cpp
index a507632..a1bd548 100644
--- a/services/inputflinger/reader/mapper/SensorInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/SensorInputMapper.cpp
@@ -16,8 +16,9 @@
#include <locale>
-#include "../Macros.h"
+#include <ftl/enum.h>
+#include "../Macros.h"
#include "SensorInputMapper.h"
// Log detailed debug messages about each sensor event notification to the dispatcher.
@@ -93,7 +94,7 @@
dump += StringPrintf(INDENT3 " mHasHardwareTimestamp %d\n", mHasHardwareTimestamp);
dump += INDENT3 "Sensors:\n";
for (const auto& [sensorType, sensor] : mSensors) {
- dump += StringPrintf(INDENT4 "%s\n", NamedEnum::string(sensorType).c_str());
+ dump += StringPrintf(INDENT4 "%s\n", ftl::enum_string(sensorType).c_str());
dump += StringPrintf(INDENT5 "enabled: %d\n", sensor.enabled);
dump += StringPrintf(INDENT5 "samplingPeriod: %lld\n", sensor.samplingPeriod.count());
dump += StringPrintf(INDENT5 "maxBatchReportLatency: %lld\n",
@@ -208,10 +209,10 @@
axis.max /* maxRange */, axis.scale /* resolution */,
0.0f /* power */, 0 /* minDelay */,
0 /* fifoReservedEventCount */, 0 /* fifoMaxEventCount */,
- NamedEnum::string(sensorType), 0 /* maxDelay */, 0 /* flags */,
+ ftl::enum_string(sensorType), 0 /* maxDelay */, 0 /* flags */,
getDeviceId());
- std::string prefix = "sensor." + NamedEnum::string(sensorType);
+ std::string prefix = "sensor." + ftl::enum_string(sensorType);
transform(prefix.begin(), prefix.end(), prefix.begin(), ::tolower);
int32_t reportingMode = 0;
@@ -335,7 +336,7 @@
std::chrono::microseconds maxBatchReportLatency) {
if (DEBUG_SENSOR_EVENT_DETAILS) {
ALOGD("Enable Sensor %s samplingPeriod %lld maxBatchReportLatency %lld",
- NamedEnum::string(sensorType).c_str(), samplingPeriod.count(),
+ ftl::enum_string(sensorType).c_str(), samplingPeriod.count(),
maxBatchReportLatency.count());
}
@@ -359,7 +360,7 @@
void SensorInputMapper::disableSensor(InputDeviceSensorType sensorType) {
if (DEBUG_SENSOR_EVENT_DETAILS) {
- ALOGD("Disable Sensor %s", NamedEnum::string(sensorType).c_str());
+ ALOGD("Disable Sensor %s", ftl::enum_string(sensorType).c_str());
}
if (!setSensorEnabled(sensorType, false /* enabled */)) {
@@ -393,13 +394,12 @@
nsecs_t timestamp = mHasHardwareTimestamp ? mHardwareTimestamp : when;
if (DEBUG_SENSOR_EVENT_DETAILS) {
ALOGD("Sensor %s timestamp %" PRIu64 " values [%f %f %f]",
- NamedEnum::string(sensorType).c_str(), timestamp, values[0], values[1],
- values[2]);
+ ftl::enum_string(sensorType).c_str(), timestamp, values[0], values[1], values[2]);
}
if (sensor.lastSampleTimeNs.has_value() &&
timestamp - sensor.lastSampleTimeNs.value() < sensor.samplingPeriod.count()) {
if (DEBUG_SENSOR_EVENT_DETAILS) {
- ALOGD("Sensor %s Skip a sample.", NamedEnum::string(sensorType).c_str());
+ ALOGD("Sensor %s Skip a sample.", ftl::enum_string(sensorType).c_str());
}
} else {
// Convert to Android unit
diff --git a/services/inputflinger/reader/mapper/TouchInputMapper.cpp b/services/inputflinger/reader/mapper/TouchInputMapper.cpp
index ac5f6b6..419b0d0 100644
--- a/services/inputflinger/reader/mapper/TouchInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/TouchInputMapper.cpp
@@ -18,9 +18,10 @@
#include "../Macros.h"
// clang-format on
-#include <ftl/NamedEnum.h>
#include "TouchInputMapper.h"
+#include <ftl/enum.h>
+
#include "CursorButtonAccumulator.h"
#include "CursorScrollAccumulator.h"
#include "TouchButtonAccumulator.h"
@@ -259,7 +260,7 @@
void TouchInputMapper::dump(std::string& dump) {
dump += StringPrintf(INDENT2 "Touch Input Mapper (mode - %s):\n",
- NamedEnum::string(mDeviceMode).c_str());
+ ftl::enum_string(mDeviceMode).c_str());
dumpParameters(dump);
dumpVirtualKeys(dump);
dumpRawPointerAxes(dump);
@@ -515,9 +516,9 @@
void TouchInputMapper::dumpParameters(std::string& dump) {
dump += INDENT3 "Parameters:\n";
- dump += INDENT4 "GestureMode: " + NamedEnum::string(mParameters.gestureMode) + "\n";
+ dump += INDENT4 "GestureMode: " + ftl::enum_string(mParameters.gestureMode) + "\n";
- dump += INDENT4 "DeviceType: " + NamedEnum::string(mParameters.deviceType) + "\n";
+ dump += INDENT4 "DeviceType: " + ftl::enum_string(mParameters.deviceType) + "\n";
dump += StringPrintf(INDENT4 "AssociatedDisplay: hasAssociatedDisplay=%s, isExternal=%s, "
"displayId='%s'\n",
@@ -525,7 +526,7 @@
toString(mParameters.associatedDisplayIsExternal),
mParameters.uniqueDisplayId.c_str());
dump += StringPrintf(INDENT4 "OrientationAware: %s\n", toString(mParameters.orientationAware));
- dump += INDENT4 "Orientation: " + NamedEnum::string(mParameters.orientation) + "\n";
+ dump += INDENT4 "Orientation: " + ftl::enum_string(mParameters.orientation) + "\n";
}
void TouchInputMapper::configureRawPointerAxes() {
diff --git a/services/inputflinger/reader/mapper/TouchInputMapper.h b/services/inputflinger/reader/mapper/TouchInputMapper.h
index e104220..a56468f 100644
--- a/services/inputflinger/reader/mapper/TouchInputMapper.h
+++ b/services/inputflinger/reader/mapper/TouchInputMapper.h
@@ -185,6 +185,8 @@
UNSCALED, // unscaled mapping (touchpad)
NAVIGATION, // unscaled mapping with assist gesture (touch navigation)
POINTER, // pointer mapping (pointer)
+
+ ftl_last = POINTER
};
DeviceMode mDeviceMode;
@@ -198,6 +200,8 @@
TOUCH_PAD,
TOUCH_NAVIGATION,
POINTER,
+
+ ftl_last = POINTER
};
DeviceType deviceType;
@@ -210,6 +214,8 @@
ORIENTATION_90 = DISPLAY_ORIENTATION_90,
ORIENTATION_180 = DISPLAY_ORIENTATION_180,
ORIENTATION_270 = DISPLAY_ORIENTATION_270,
+
+ ftl_last = ORIENTATION_270
};
Orientation orientation;
@@ -219,6 +225,8 @@
enum class GestureMode {
SINGLE_TOUCH,
MULTI_TOUCH,
+
+ ftl_last = MULTI_TOUCH
};
GestureMode gestureMode;
@@ -818,4 +826,4 @@
} // namespace android
-#endif // _UI_INPUTREADER_TOUCH_INPUT_MAPPER_H
\ No newline at end of file
+#endif // _UI_INPUTREADER_TOUCH_INPUT_MAPPER_H
diff --git a/services/surfaceflinger/ClientCache.cpp b/services/surfaceflinger/ClientCache.cpp
index f310738..1ef8f78 100644
--- a/services/surfaceflinger/ClientCache.cpp
+++ b/services/surfaceflinger/ClientCache.cpp
@@ -21,12 +21,12 @@
#include <cinttypes>
+#include <android-base/stringprintf.h>
+
#include "ClientCache.h"
namespace android {
-using base::StringAppendF;
-
ANDROID_SINGLETON_STATIC_INSTANCE(ClientCache);
ClientCache::ClientCache() : mDeathRecipient(new CacheDeathRecipient) {}
@@ -212,16 +212,15 @@
void ClientCache::dump(std::string& result) {
std::lock_guard lock(mMutex);
- for (auto i : mBuffers) {
- const sp<IBinder>& cacheOwner = i.second.first;
- StringAppendF(&result," Cache owner: %p\n", cacheOwner.get());
- auto &buffers = i.second.second;
- for (auto& [id, clientCacheBuffer] : buffers) {
- StringAppendF(&result, "\t ID: %d, Width/Height: %d,%d\n", (int)id,
- (int)clientCacheBuffer.buffer->getBuffer()->getWidth(),
- (int)clientCacheBuffer.buffer->getBuffer()->getHeight());
+ for (const auto& [_, cache] : mBuffers) {
+ base::StringAppendF(&result, " Cache owner: %p\n", cache.first.get());
+
+ for (const auto& [id, entry] : cache.second) {
+ const auto& buffer = entry.buffer->getBuffer();
+ base::StringAppendF(&result, "\tID: %" PRIu64 ", size: %ux%u\n", id, buffer->getWidth(),
+ buffer->getHeight());
}
}
}
-}; // namespace android
+} // namespace android
diff --git a/services/surfaceflinger/CompositionEngine/src/planner/LayerState.cpp b/services/surfaceflinger/CompositionEngine/src/planner/LayerState.cpp
index 936dba3..2532e3d 100644
--- a/services/surfaceflinger/CompositionEngine/src/planner/LayerState.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/planner/LayerState.cpp
@@ -93,11 +93,7 @@
void LayerState::dump(std::string& result) const {
for (const StateInterface* field : getNonUniqueFields()) {
- if (auto viewOpt = flag_name(field->getField()); viewOpt) {
- base::StringAppendF(&result, " %16s: ", std::string(*viewOpt).c_str());
- } else {
- result.append("<UNKNOWN FIELD>:\n");
- }
+ base::StringAppendF(&result, " %16s: ", ftl::flag_string(field->getField()).c_str());
bool first = true;
for (const std::string& line : field->toStrings()) {
@@ -126,11 +122,7 @@
continue;
}
- if (auto viewOpt = flag_name(thisField->getField()); viewOpt) {
- base::StringAppendF(&result, " %16s: ", std::string(*viewOpt).c_str());
- } else {
- result.append("<UNKNOWN FIELD>:\n");
- }
+ base::StringAppendF(&result, " %16s: ", ftl::flag_string(thisField->getField()).c_str());
const auto& thisStrings = thisField->toStrings();
const auto& otherStrings = otherField->toStrings();