diff options
author | 2021-02-09 18:51:25 -0800 | |
---|---|---|
committer | 2021-09-09 12:35:48 -0700 | |
commit | 7578845a3480cb4237f28729994e19a09caceb55 (patch) | |
tree | 05830c1a55e5ab6b4ca3c901c61ac78fc15d61b1 | |
parent | 7be9eaacb54dbdfaf9522f93b104dd0469a0b543 (diff) |
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
27 files changed, 669 insertions, 477 deletions
diff --git a/include/ftl/Flags.h b/include/ftl/Flags.h index 27c84769cb..ae708313fd 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 <ftl/enum.h> +#include <ftl/string.h> -#include <array> #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 @@ class Flags { // 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 @@ public: // 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 @@ public: 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 @@ private: // 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 6e98feeb87..0000000000 --- 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 0000000000..dfe3a0976b --- /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 a6213f3ddd..9148fee532 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 @@ enum class ViewportType : int32_t { INTERNAL = 1, EXTERNAL = 2, VIRTUAL = 3, + + ftl_last = VIRTUAL }; /* @@ -132,9 +135,8 @@ struct DisplayViewport { "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 7f0324a4a8..22aae196c6 100644 --- a/include/input/InputDevice.h +++ b/include/input/InputDevice.h @@ -84,6 +84,9 @@ enum class InputDeviceSensorType : int32_t { 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 @@ enum class InputDeviceLightType : int32_t { 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 9a150eb0e2..7632b30bd2 100644 --- a/include/input/InputTransport.h +++ b/include/input/InputTransport.h @@ -73,6 +73,8 @@ struct InputMessage { DRAG, TIMELINE, TOUCH_MODE, + + ftl_last = TOUCH_MODE }; struct Header { diff --git a/libs/ftl/Android.bp b/libs/ftl/Android.bp index 3026921044..5a80ad067c 100644 --- a/libs/ftl/Android.bp +++ b/libs/ftl/Android.bp @@ -14,10 +14,10 @@ cc_test { 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 8c00b5299b..d241fa272a 100644 --- a/libs/ftl/Flags_test.cpp +++ b/libs/ftl/Flags_test.cpp @@ -23,7 +23,7 @@ namespace android::test { 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_KnownValues) { 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 @@ TEST(FlagsIterator, PreFixIncrement) { 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 dff2b8aaa1..0000000000 --- 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 0000000000..1fd43abbc6 --- /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 f090c63228..47f6c05bff 100644 --- a/libs/gui/include/gui/WindowInfo.h +++ b/libs/gui/include/gui/WindowInfo.h @@ -71,8 +71,9 @@ struct WindowInfo : public Parcelable { 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 @@ struct WindowInfo : public Parcelable { 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 @@ protected: 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 220c8e1e6e..69ae9a02ec 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::addMotionRange(const MotionRange& range) { 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 1e93dfb488..91ab008161 100644 --- a/libs/input/InputTransport.cpp +++ b/libs/input/InputTransport.cpp @@ -30,10 +30,10 @@ static constexpr bool DEBUG_TRANSPORT_ACTIONS = false; #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 @@ android::base::Result<InputPublisher::ConsumerResponse> InputPublisher::receiveC } 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 @@ status_t InputConsumer::consume(InputEventFactoryInterface* factory, bool consum 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 @@ std::string InputConsumer::dump() const { 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 c365ab070e..7c25cda9ac 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,37 +41,39 @@ namespace android { +namespace { -static 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() { -} +constexpr const char* WHITESPACE = " \t\r"; -KeyLayoutMap::~KeyLayoutMap() { +template <InputDeviceSensorType S> +constexpr auto sensorPair() { + return std::make_pair(ftl::enum_name<S>(), S); } +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) { Tokenizer* tokenizer; @@ -160,8 +164,8 @@ base::Result<std::pair<InputDeviceSensorType, int32_t>> KeyLayoutMap::mapSensor( 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 @@ status_t KeyLayoutMap::Parser::parseLed() { } 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 @@ status_t KeyLayoutMap::Parser::parseSensor() { 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 @@ status_t KeyLayoutMap::Parser::parseSensor() { map.emplace(code, sensor); return NO_ERROR; } -}; + +} // namespace android diff --git a/services/inputflinger/InputReaderBase.cpp b/services/inputflinger/InputReaderBase.cpp index 05ef489133..a864cf8202 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 @@ std::optional<DisplayViewport> InputReaderConfiguration::getDisplayViewportByTyp } 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 547021ca22..5365a78b0a 100644 --- a/services/inputflinger/dispatcher/Entry.h +++ b/services/inputflinger/dispatcher/Entry.h @@ -40,6 +40,8 @@ struct EventEntry { 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 4a75773201..600f02ba80 100644 --- a/services/inputflinger/dispatcher/FocusResolver.cpp +++ b/services/inputflinger/dispatcher/FocusResolver.cpp @@ -27,7 +27,7 @@ static constexpr bool DEBUG_FOCUS = false; #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 @@ std::optional<FocusResolver::FocusChanges> FocusResolver::setInputWindows( 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 @@ std::optional<FocusResolver::FocusChanges> FocusResolver::setInputWindows( 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 @@ std::optional<FocusResolver::FocusChanges> FocusResolver::setFocusedWindow( 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 @@ std::optional<FocusResolver::FocusChanges> FocusResolver::setFocusedWindow( // 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 @@ std::string FocusResolver::dump() const { 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 1d6cd9a5fa..6d11a77aad 100644 --- a/services/inputflinger/dispatcher/FocusResolver.h +++ b/services/inputflinger/dispatcher/FocusResolver.h @@ -77,6 +77,8 @@ private: 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 @@ private: 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 92ba52c3f4..9da71925ce 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 @@ void InputDispatcher::dropInboundEventLocked(const EventEntry& entry, DropReason 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 @@ void InputDispatcher::dispatchSensorLocked(nsecs_t currentTime, 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 @@ void InputDispatcher::dispatchSensorLocked(nsecs_t currentTime, 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 @@ int32_t InputDispatcher::getTargetDisplayId(const EventEntry& entry) { 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 @@ InputEventInjectionResult InputDispatcher::findFocusedWindowTargetsLocked( 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 @@ InputEventInjectionResult InputDispatcher::findFocusedWindowTargetsLocked( } 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 @@ std::string InputDispatcher::dumpWindowForTouchOcclusion(const WindowInfo* info, "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 @@ void InputDispatcher::pokeUserActivityLocked(const EventEntry& eventEntry) { 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 @@ void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime, 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 @@ void InputDispatcher::enqueueDispatchEntryLocked(const sp<Connection>& connectio 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 @@ void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime, 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 @@ void InputDispatcher::synthesizeCancelationEventsForConnectionLocked( 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 @@ void InputDispatcher::synthesizePointerDownEventsForConnectionLocked( 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 @@ void InputDispatcher::notifySensor(const NotifySensorArgs* args) { 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 @@ void InputDispatcher::dumpDispatchStateLocked(std::string& dump) { 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 0f0ad0a102..d10f8b6605 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> allFilesInPath(const std::filesystem:: */ 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 9c8a29a059..a6934960c9 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 @@ void PeripheralController::dump(std::string& dump) { 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 @@ bool PeripheralController::setLightColor(int32_t lightId, int32_t color) { 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> PeripheralController::getLightColor(int32_t lightId) { 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 7a00bace6e..1f96294e96 100644 --- a/services/inputflinger/reader/include/EventHub.h +++ b/services/inputflinger/reader/include/EventHub.h @@ -146,6 +146,8 @@ enum class InputDeviceClass : uint32_t { 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 a507632d0e..a1bd548403 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 @@ void SensorInputMapper::dump(std::string& dump) { 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 @@ SensorInputMapper::Sensor SensorInputMapper::createSensor(InputDeviceSensorType 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 @@ bool SensorInputMapper::enableSensor(InputDeviceSensorType sensorType, 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 @@ bool SensorInputMapper::enableSensor(InputDeviceSensorType sensorType, 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 @@ void SensorInputMapper::sync(nsecs_t when, bool force) { 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 ac5f6b652b..419b0d0eed 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::populateDeviceInfo(InputDeviceInfo* info) { 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::configureParameters() { 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 @@ void TouchInputMapper::dumpParameters(std::string& dump) { 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 e104220e47..a56468f445 100644 --- a/services/inputflinger/reader/mapper/TouchInputMapper.h +++ b/services/inputflinger/reader/mapper/TouchInputMapper.h @@ -185,6 +185,8 @@ protected: 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 @@ protected: TOUCH_PAD, TOUCH_NAVIGATION, POINTER, + + ftl_last = POINTER }; DeviceType deviceType; @@ -210,6 +214,8 @@ protected: 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 @@ protected: enum class GestureMode { SINGLE_TOUCH, MULTI_TOUCH, + + ftl_last = MULTI_TOUCH }; GestureMode gestureMode; @@ -818,4 +826,4 @@ private: } // 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 f310738423..1ef8f78894 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::CacheDeathRecipient::binderDied(const wp<IBinder>& who) { 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 936dba3b29..2532e3df5d 100644 --- a/services/surfaceflinger/CompositionEngine/src/planner/LayerState.cpp +++ b/services/surfaceflinger/CompositionEngine/src/planner/LayerState.cpp @@ -93,11 +93,7 @@ Flags<LayerStateField> LayerState::getDifferingFields(const LayerState& other) c 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 @@ std::optional<std::string> LayerState::compare(const LayerState& other) const { 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(); |