Merge "Merge changes Ib1c28c94,Id3485a2a,If5ad5acf,Idc9054bd,Ie4e7e25d am: 756621f54d am: aae80e18c3" into sc-dev-plus-aosp am: d2674a3906 am: 3c0f30e565

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/native/+/15128207

Change-Id: Id4a8839d6096d7484b0abc5b66a49cc7dc12d192
diff --git a/cmds/atrace/atrace.cpp b/cmds/atrace/atrace.cpp
index 79419d3..021fdb5 100644
--- a/cmds/atrace/atrace.cpp
+++ b/cmds/atrace/atrace.cpp
@@ -245,6 +245,7 @@
         { OPT,      "events/kmem/ion_heap_shrink/enable" },
         { OPT,      "events/ion/ion_stat/enable" },
         { OPT,      "events/gpu_mem/gpu_mem_total/enable" },
+        { OPT,      "events/fastrpc/fastrpc_dma_stat/enable" },
     } },
     { "thermal",  "Thermal event", 0, {
         { REQ,      "events/thermal/thermal_temperature/enable" },
diff --git a/include/input/Flags.h b/include/ftl/Flags.h
similarity index 98%
rename from include/input/Flags.h
rename to include/ftl/Flags.h
index b12a9ed..27c8476 100644
--- a/include/input/Flags.h
+++ b/include/ftl/Flags.h
@@ -22,11 +22,10 @@
 #include <string>
 #include <type_traits>
 
-#include "NamedEnum.h"
+#include <ftl/NamedEnum.h>
 #include "utils/BitSet.h"
 
-#ifndef __UI_INPUT_FLAGS_H
-#define __UI_INPUT_FLAGS_H
+#pragma once
 
 namespace android {
 
@@ -279,5 +278,3 @@
 
 } // namespace flag_operators
 } // namespace android
-
-#endif // __UI_INPUT_FLAGS_H
diff --git a/include/input/NamedEnum.h b/include/ftl/NamedEnum.h
similarity index 97%
rename from include/input/NamedEnum.h
rename to include/ftl/NamedEnum.h
index 6562348..f50ff46 100644
--- a/include/input/NamedEnum.h
+++ b/include/ftl/NamedEnum.h
@@ -21,8 +21,7 @@
 #include <optional>
 #include <string>
 
-#ifndef __UI_INPUT_NAMEDENUM_H
-#define __UI_INPUT_NAMEDENUM_H
+#pragma once
 
 namespace android {
 
@@ -124,5 +123,3 @@
 };
 
 } // namespace android
-
-#endif // __UI_INPUT_NAMEDENUM_H
\ No newline at end of file
diff --git a/include/ftl/cast.h b/include/ftl/cast.h
new file mode 100644
index 0000000..ff1b58a
--- /dev/null
+++ b/include/ftl/cast.h
@@ -0,0 +1,84 @@
+/*
+ * 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 <limits>
+#include <type_traits>
+
+#include <ftl/details/cast.h>
+
+namespace android::ftl {
+
+enum class CastSafety { kSafe, kUnderflow, kOverflow };
+
+// Returns whether static_cast<R>(v) is safe, or would result in underflow or overflow.
+//
+//   static_assert(ftl::cast_safety<uint8_t>(-1) == ftl::CastSafety::kUnderflow);
+//   static_assert(ftl::cast_safety<int8_t>(128u) == ftl::CastSafety::kOverflow);
+//
+//   static_assert(ftl::cast_safety<uint32_t>(-.1f) == ftl::CastSafety::kUnderflow);
+//   static_assert(ftl::cast_safety<int32_t>(static_cast<float>(INT32_MAX)) ==
+//                                           ftl::CastSafety::kOverflow);
+//
+//   static_assert(ftl::cast_safety<float>(-DBL_MAX) == ftl::CastSafety::kUnderflow);
+//
+template <typename R, typename T>
+constexpr CastSafety cast_safety(T v) {
+  static_assert(std::is_arithmetic_v<T>);
+  static_assert(std::is_arithmetic_v<R>);
+
+  constexpr bool kFromSigned = std::is_signed_v<T>;
+  constexpr bool kToSigned = std::is_signed_v<R>;
+
+  using details::max_exponent;
+
+  // If the R range contains the T range, then casting is always safe.
+  if constexpr ((kFromSigned == kToSigned && max_exponent<R> >= max_exponent<T>) ||
+                (!kFromSigned && kToSigned && max_exponent<R> > max_exponent<T>)) {
+    return CastSafety::kSafe;
+  }
+
+  using C = std::common_type_t<R, T>;
+
+  if constexpr (kFromSigned) {
+    using L = details::safe_limits<R, T>;
+
+    if constexpr (kToSigned) {
+      // Signed to signed.
+      if (v < L::lowest()) return CastSafety::kUnderflow;
+      return v <= L::max() ? CastSafety::kSafe : CastSafety::kOverflow;
+    } else {
+      // Signed to unsigned.
+      if (v < 0) return CastSafety::kUnderflow;
+      return static_cast<C>(v) <= static_cast<C>(L::max()) ? CastSafety::kSafe
+                                                           : CastSafety::kOverflow;
+    }
+  } else {
+    using L = std::numeric_limits<R>;
+
+    if constexpr (kToSigned) {
+      // Unsigned to signed.
+      return static_cast<C>(v) <= static_cast<C>(L::max()) ? CastSafety::kSafe
+                                                           : CastSafety::kOverflow;
+    } else {
+      // Unsigned to unsigned.
+      return v <= L::max() ? CastSafety::kSafe : CastSafety::kOverflow;
+    }
+  }
+}
+
+}  // namespace android::ftl
diff --git a/include/ftl/details/cast.h b/include/ftl/details/cast.h
new file mode 100644
index 0000000..87b9f1e
--- /dev/null
+++ b/include/ftl/details/cast.h
@@ -0,0 +1,57 @@
+/*
+ * 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 <limits>
+#include <type_traits>
+
+namespace android::ftl::details {
+
+// Exponent whose power of 2 is the (exclusive) upper bound of T.
+template <typename T, typename L = std::numeric_limits<T>>
+constexpr int max_exponent = std::is_floating_point_v<T> ? L::max_exponent : L::digits;
+
+// Extension of std::numeric_limits<T> that reduces the maximum for integral types T such that it
+// has an exact representation for floating-point types F. For example, the maximum int32_t value
+// is 2'147'483'647, but casting it to float commonly rounds up to 2'147'483'650.f, which cannot
+// be safely converted back lest the signed overflow invokes undefined behavior. This pitfall is
+// avoided by clearing the lower (31 - 24 =) 7 bits of precision to 2'147'483'520. Note that the
+// minimum is representable.
+template <typename T, typename F>
+struct safe_limits : std::numeric_limits<T> {
+  static constexpr T max() {
+    using Base = std::numeric_limits<T>;
+
+    if constexpr (std::is_integral_v<T> && std::is_floating_point_v<F>) {
+      // Assume the mantissa is 24 bits for float, or 53 bits for double.
+      using Float = std::numeric_limits<F>;
+      static_assert(Float::is_iec559);
+
+      // If the integer is wider than the mantissa, clear the excess bits of precision.
+      constexpr int kShift = Base::digits - Float::digits;
+      if constexpr (kShift > 0) {
+        using U = std::make_unsigned_t<T>;
+        constexpr U kOne = static_cast<U>(1);
+        return static_cast<U>(Base::max()) & ~((kOne << kShift) - kOne);
+      }
+    }
+
+    return Base::max();
+  }
+};
+
+}  // namespace android::ftl::details
diff --git a/include/ftl/small_map.h b/include/ftl/small_map.h
index 84c15eb..bcaba82 100644
--- a/include/ftl/small_map.h
+++ b/include/ftl/small_map.h
@@ -19,6 +19,7 @@
 #include <ftl/initializer_list.h>
 #include <ftl/small_vector.h>
 
+#include <algorithm>
 #include <functional>
 #include <optional>
 #include <type_traits>
@@ -28,7 +29,10 @@
 
 // Associative container with unique, unordered keys. Unlike std::unordered_map, key-value pairs are
 // stored in contiguous storage for cache efficiency. The map is allocated statically until its size
-// exceeds N, at which point mappings are relocated to dynamic memory.
+// exceeds N, at which point mappings are relocated to dynamic memory. The try_emplace operation has
+// a non-standard analogue try_replace that destructively emplaces. The API also defines an in-place
+// counterpart to insert_or_assign: emplace_or_replace. Lookup is done not via a subscript operator,
+// but immutable getters that can optionally transform the value.
 //
 // SmallMap<K, V, 0> unconditionally allocates on the heap.
 //
@@ -43,16 +47,19 @@
 //   assert(!map.dynamic());
 //
 //   assert(map.contains(123));
-//   assert(map.find(42, [](const std::string& s) { return s.size(); }) == 3u);
+//   assert(map.get(42, [](const std::string& s) { return s.size(); }) == 3u);
 //
-//   const auto opt = map.find(-1);
+//   const auto opt = map.get(-1);
 //   assert(opt);
 //
 //   std::string& ref = *opt;
 //   assert(ref.empty());
 //   ref = "xyz";
 //
-//   assert(map == SmallMap(ftl::init::map(-1, "xyz")(42, "???")(123, "abc")));
+//   map.emplace_or_replace(0, "vanilla", 2u, 3u);
+//   assert(map.dynamic());
+//
+//   assert(map == SmallMap(ftl::init::map(-1, "xyz")(0, "nil")(42, "???")(123, "abc")));
 //
 template <typename K, typename V, std::size_t N>
 class SmallMap final {
@@ -80,12 +87,7 @@
   // The syntax for listing pairs is as follows:
   //
   //   ftl::SmallMap map = ftl::init::map<int, std::string>(123, "abc")(-1)(42, 3u, '?');
-  //
   //   static_assert(std::is_same_v<decltype(map), ftl::SmallMap<int, std::string, 3>>);
-  //   assert(map.size() == 3u);
-  //   assert(map.contains(-1) && map.find(-1)->get().empty());
-  //   assert(map.contains(42) && map.find(42)->get() == "???");
-  //   assert(map.contains(123) && map.find(123)->get() == "abc");
   //
   // The types of the key and value are deduced if the first pair contains exactly two arguments:
   //
@@ -95,7 +97,7 @@
   template <typename U, std::size_t... Sizes, typename... Types>
   SmallMap(InitializerList<U, std::index_sequence<Sizes...>, Types...>&& list)
       : map_(std::move(list)) {
-    // TODO: Enforce unique keys.
+    deduplicate();
   }
 
   size_type max_size() const { return map_.max_size(); }
@@ -115,27 +117,27 @@
 
   // Returns whether a mapping exists for the given key.
   bool contains(const key_type& key) const {
-    return find(key, [](const mapped_type&) {});
+    return get(key, [](const mapped_type&) {});
   }
 
   // Returns a reference to the value for the given key, or std::nullopt if the key was not found.
   //
   //   ftl::SmallMap map = ftl::init::map('a', 'A')('b', 'B')('c', 'C');
   //
-  //   const auto opt = map.find('c');
+  //   const auto opt = map.get('c');
   //   assert(opt == 'C');
   //
   //   char d = 'd';
-  //   const auto ref = map.find('d').value_or(std::ref(d));
+  //   const auto ref = map.get('d').value_or(std::ref(d));
   //   ref.get() = 'D';
   //   assert(d == 'D');
   //
-  auto find(const key_type& key) const -> std::optional<std::reference_wrapper<const mapped_type>> {
-    return find(key, [](const mapped_type& v) { return std::cref(v); });
+  auto get(const key_type& key) const -> std::optional<std::reference_wrapper<const mapped_type>> {
+    return get(key, [](const mapped_type& v) { return std::cref(v); });
   }
 
-  auto find(const key_type& key) -> std::optional<std::reference_wrapper<mapped_type>> {
-    return find(key, [](mapped_type& v) { return std::ref(v); });
+  auto get(const key_type& key) -> std::optional<std::reference_wrapper<mapped_type>> {
+    return get(key, [](mapped_type& v) { return std::ref(v); });
   }
 
   // Returns the result R of a unary operation F on (a constant or mutable reference to) the value
@@ -144,11 +146,11 @@
   //
   //   ftl::SmallMap map = ftl::init::map('a', 'x')('b', 'y')('c', 'z');
   //
-  //   assert(map.find('c', [](char c) { return std::toupper(c); }) == 'Z');
-  //   assert(map.find('c', [](char& c) { c = std::toupper(c); }));
+  //   assert(map.get('c', [](char c) { return std::toupper(c); }) == 'Z');
+  //   assert(map.get('c', [](char& c) { c = std::toupper(c); }));
   //
   template <typename F, typename R = std::invoke_result_t<F, const mapped_type&>>
-  auto find(const key_type& key, F f) const
+  auto get(const key_type& key, F f) const
       -> std::conditional_t<std::is_void_v<R>, bool, std::optional<R>> {
     for (auto& [k, v] : *this) {
       if (k == key) {
@@ -165,12 +167,96 @@
   }
 
   template <typename F>
-  auto find(const key_type& key, F f) {
-    return std::as_const(*this).find(
+  auto get(const key_type& key, F f) {
+    return std::as_const(*this).get(
         key, [&f](const mapped_type& v) { return f(const_cast<mapped_type&>(v)); });
   }
 
+  // Returns an iterator to an existing mapping for the given key, or the end() iterator otherwise.
+  const_iterator find(const key_type& key) const { return const_cast<SmallMap&>(*this).find(key); }
+  iterator find(const key_type& key) { return find(key, begin()); }
+
+  // Inserts a mapping unless it exists. Returns an iterator to the inserted or existing mapping,
+  // and whether the mapping was inserted.
+  //
+  // On emplace, if the map reaches its static or dynamic capacity, then all iterators are
+  // invalidated. Otherwise, only the end() iterator is invalidated.
+  //
+  template <typename... Args>
+  std::pair<iterator, bool> try_emplace(const key_type& key, Args&&... args) {
+    if (const auto it = find(key); it != end()) {
+      return {it, false};
+    }
+
+    auto& ref = map_.emplace_back(std::piecewise_construct, std::forward_as_tuple(key),
+                                  std::forward_as_tuple(std::forward<Args>(args)...));
+    return {&ref, true};
+  }
+
+  // Replaces a mapping if it exists, and returns an iterator to it. Returns the end() iterator
+  // otherwise.
+  //
+  // The value is replaced via move constructor, so type V does not need to define copy/move
+  // assignment, e.g. its data members may be const.
+  //
+  // The arguments may directly or indirectly refer to the mapping being replaced.
+  //
+  // Iterators to the replaced mapping point to its replacement, and others remain valid.
+  //
+  template <typename... Args>
+  iterator try_replace(const key_type& key, Args&&... args) {
+    const auto it = find(key);
+    if (it == end()) return it;
+    map_.replace(it, std::piecewise_construct, std::forward_as_tuple(key),
+                 std::forward_as_tuple(std::forward<Args>(args)...));
+    return it;
+  }
+
+  // In-place counterpart of std::unordered_map's insert_or_assign. Returns true on emplace, or
+  // false on replace.
+  //
+  // The value is emplaced and replaced via move constructor, so type V does not need to define
+  // copy/move assignment, e.g. its data members may be const.
+  //
+  // On emplace, if the map reaches its static or dynamic capacity, then all iterators are
+  // invalidated. Otherwise, only the end() iterator is invalidated. On replace, iterators
+  // to the replaced mapping point to its replacement, and others remain valid.
+  //
+  template <typename... Args>
+  std::pair<iterator, bool> emplace_or_replace(const key_type& key, Args&&... args) {
+    const auto [it, ok] = try_emplace(key, std::forward<Args>(args)...);
+    if (ok) return {it, ok};
+    map_.replace(it, std::piecewise_construct, std::forward_as_tuple(key),
+                 std::forward_as_tuple(std::forward<Args>(args)...));
+    return {it, ok};
+  }
+
+  // Removes a mapping if it exists, and returns whether it did.
+  //
+  // The last() and end() iterators, as well as those to the erased mapping, are invalidated.
+  //
+  bool erase(const key_type& key) { return erase(key, begin()); }
+
  private:
+  iterator find(const key_type& key, iterator first) {
+    return std::find_if(first, end(), [&key](const auto& pair) { return pair.first == key; });
+  }
+
+  bool erase(const key_type& key, iterator first) {
+    const auto it = find(key, first);
+    if (it == end()) return false;
+    map_.unstable_erase(it);
+    return true;
+  }
+
+  void deduplicate() {
+    for (auto it = begin(); it != end();) {
+      if (const auto key = it->first; ++it != end()) {
+        while (erase(key, it));
+      }
+    }
+  }
+
   Map map_;
 };
 
@@ -186,7 +272,7 @@
 
   for (const auto& [k, v] : lhs) {
     const auto& lv = v;
-    if (!rhs.find(k, [&lv](const auto& rv) { return lv == rv; }).value_or(false)) {
+    if (!rhs.get(k, [&lv](const auto& rv) { return lv == rv; }).value_or(false)) {
       return false;
     }
   }
diff --git a/include/ftl/small_vector.h b/include/ftl/small_vector.h
index cb0ae35..0341435 100644
--- a/include/ftl/small_vector.h
+++ b/include/ftl/small_vector.h
@@ -348,7 +348,7 @@
   using Impl::pop_back;
 
   void unstable_erase(iterator it) {
-    if (it != last()) std::iter_swap(it, last());
+    if (it != last()) replace(it, std::move(back()));
     pop_back();
   }
 
diff --git a/include/ftl/string.h b/include/ftl/string.h
new file mode 100644
index 0000000..2d96b06
--- /dev/null
+++ b/include/ftl/string.h
@@ -0,0 +1,101 @@
+/*
+ * 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 <cassert>
+#include <charconv>
+#include <limits>
+#include <string>
+#include <string_view>
+#include <type_traits>
+
+namespace android::ftl {
+
+enum class Radix { kBin = 2, kDec = 10, kHex = 16 };
+
+template <typename T>
+struct to_chars_length {
+  static_assert(std::is_integral_v<T>);
+  // Maximum binary digits, plus minus sign and radix prefix.
+  static constexpr std::size_t value = std::numeric_limits<std::make_unsigned_t<T>>::digits + 3;
+};
+
+template <typename T>
+constexpr std::size_t to_chars_length_v = to_chars_length<T>::value;
+
+template <typename T = std::int64_t>
+using to_chars_buffer_t = char[to_chars_length_v<T>];
+
+// Lightweight (not allocating nor sprintf-based) alternative to std::to_string for integers, with
+// optional radix. See also ftl::to_string below.
+//
+//   ftl::to_chars_buffer_t<> buffer;
+//
+//   assert(ftl::to_chars(buffer, 123u) == "123");
+//   assert(ftl::to_chars(buffer, -42, ftl::Radix::kBin) == "-0b101010");
+//   assert(ftl::to_chars(buffer, 0xcafe, ftl::Radix::kHex) == "0xcafe");
+//   assert(ftl::to_chars(buffer, '*', ftl::Radix::kHex) == "0x2a");
+//
+template <typename T, std::size_t N>
+std::string_view to_chars(char (&buffer)[N], T v, Radix radix = Radix::kDec) {
+  static_assert(N >= to_chars_length_v<T>);
+
+  auto begin = buffer + 2;
+  const auto [end, err] = std::to_chars(begin, buffer + N, v, static_cast<int>(radix));
+  assert(err == std::errc());
+
+  if (radix == Radix::kDec) {
+    // TODO: Replace with {begin, end} in C++20.
+    return {begin, static_cast<std::size_t>(end - begin)};
+  }
+
+  const auto prefix = radix == Radix::kBin ? 'b' : 'x';
+  if constexpr (std::is_unsigned_v<T>) {
+    buffer[0] = '0';
+    buffer[1] = prefix;
+  } else {
+    if (*begin == '-') {
+      *buffer = '-';
+    } else {
+      --begin;
+    }
+
+    *begin-- = prefix;
+    *begin = '0';
+  }
+
+  // TODO: Replace with {buffer, end} in C++20.
+  return {buffer, static_cast<std::size_t>(end - buffer)};
+}
+
+// Lightweight (not sprintf-based) alternative to std::to_string for integers, with optional radix.
+//
+//   assert(ftl::to_string(123u) == "123");
+//   assert(ftl::to_string(-42, ftl::Radix::kBin) == "-0b101010");
+//   assert(ftl::to_string(0xcafe, ftl::Radix::kHex) == "0xcafe");
+//   assert(ftl::to_string('*', ftl::Radix::kHex) == "0x2a");
+//
+template <typename T>
+inline std::string to_string(T v, Radix radix = Radix::kDec) {
+  to_chars_buffer_t<T> buffer;
+  return std::string(to_chars(buffer, v, radix));
+}
+
+std::string to_string(bool) = delete;
+std::string to_string(bool, Radix) = delete;
+
+}  // namespace android::ftl
diff --git a/include/input/DisplayViewport.h b/include/input/DisplayViewport.h
index 5e40ca7..a6213f3 100644
--- a/include/input/DisplayViewport.h
+++ b/include/input/DisplayViewport.h
@@ -18,8 +18,9 @@
 #define _LIBINPUT_DISPLAY_VIEWPORT_H
 
 #include <android-base/stringprintf.h>
+#include <ftl/NamedEnum.h>
+#include <gui/constants.h>
 #include <input/Input.h>
-#include <input/NamedEnum.h>
 
 #include <cinttypes>
 #include <optional>
diff --git a/include/input/Input.h b/include/input/Input.h
index e8678d2..3bac763 100644
--- a/include/input/Input.h
+++ b/include/input/Input.h
@@ -106,15 +106,6 @@
 constexpr int32_t AMOTION_EVENT_FLAG_CANCELED = 0x20;
 
 enum {
-    /* Used when a motion event is not associated with any display.
-     * Typically used for non-pointer events. */
-    ADISPLAY_ID_NONE = -1,
-
-    /* The default display id. */
-    ADISPLAY_ID_DEFAULT = 0,
-};
-
-enum {
     /*
      * Indicates that an input device has switches.
      * This input source flag is hidden from the API because switches are only used by the system
@@ -338,12 +329,6 @@
  */
 constexpr float AMOTION_EVENT_INVALID_CURSOR_POSITION = std::numeric_limits<float>::quiet_NaN();
 
-/**
- * Invalid value for display size. Used when display size isn't available for an event or doesn't
- * matter. This is just a constant 0 so that it has no effect if unused.
- */
-constexpr int32_t AMOTION_EVENT_INVALID_DISPLAY_SIZE = 0;
-
 /*
  * Pointer coordinate data.
  */
@@ -368,8 +353,6 @@
     float getAxisValue(int32_t axis) const;
     status_t setAxisValue(int32_t axis, float value);
 
-    void scale(float globalScale);
-
     // Scale the pointer coordinates according to a global scale and a
     // window scale. The global scale will be applied to TOUCH/TOOL_MAJOR/MINOR
     // axes, however the window scaling will not.
diff --git a/libs/ftl/Android.bp b/libs/ftl/Android.bp
index 97626be..3026921 100644
--- a/libs/ftl/Android.bp
+++ b/libs/ftl/Android.bp
@@ -14,10 +14,14 @@
         address: true,
     },
     srcs: [
+        "cast_test.cpp",
+        "Flags_test.cpp",
         "future_test.cpp",
+        "NamedEnum_test.cpp",
         "small_map_test.cpp",
         "small_vector_test.cpp",
         "static_vector_test.cpp",
+        "string_test.cpp",
     ],
     cflags: [
         "-Wall",
@@ -25,4 +29,12 @@
         "-Wextra",
         "-Wpedantic",
     ],
+
+    header_libs: [
+        "libbase_headers",
+    ],
+
+    shared_libs: [
+        "libbase",
+    ],
 }
diff --git a/libs/input/tests/Flags_test.cpp b/libs/ftl/Flags_test.cpp
similarity index 99%
rename from libs/input/tests/Flags_test.cpp
rename to libs/ftl/Flags_test.cpp
index 6de030f..8c00b52 100644
--- a/libs/input/tests/Flags_test.cpp
+++ b/libs/ftl/Flags_test.cpp
@@ -15,7 +15,7 @@
  */
 
 #include <gtest/gtest.h>
-#include <input/Flags.h>
+#include <ftl/Flags.h>
 
 #include <type_traits>
 
diff --git a/libs/input/tests/NamedEnum_test.cpp b/libs/ftl/NamedEnum_test.cpp
similarity index 98%
rename from libs/input/tests/NamedEnum_test.cpp
rename to libs/ftl/NamedEnum_test.cpp
index 74a0044..dff2b8a 100644
--- a/libs/input/tests/NamedEnum_test.cpp
+++ b/libs/ftl/NamedEnum_test.cpp
@@ -15,7 +15,7 @@
  */
 
 #include <gtest/gtest.h>
-#include <input/NamedEnum.h>
+#include <ftl/NamedEnum.h>
 
 namespace android {
 
diff --git a/libs/ftl/cast_test.cpp b/libs/ftl/cast_test.cpp
new file mode 100644
index 0000000..2abcb8f
--- /dev/null
+++ b/libs/ftl/cast_test.cpp
@@ -0,0 +1,200 @@
+/*
+ * 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/cast.h>
+#include <gtest/gtest.h>
+
+#include <cfloat>
+#include <cmath>
+#include <limits>
+
+namespace android::test {
+
+using ftl::cast_safety;
+using ftl::CastSafety;
+
+template <typename T>
+constexpr T min = std::numeric_limits<T>::lowest();
+
+template <typename T>
+constexpr T max = std::numeric_limits<T>::max();
+
+template <typename T>
+constexpr T inf = std::numeric_limits<T>::infinity();
+
+template <typename T>
+constexpr T NaN = std::numeric_limits<T>::quiet_NaN();
+
+// Keep in sync with example usage in header file.
+
+static_assert(cast_safety<uint8_t>(-1) == CastSafety::kUnderflow);
+static_assert(cast_safety<int8_t>(128u) == CastSafety::kOverflow);
+
+static_assert(cast_safety<uint32_t>(-.1f) == CastSafety::kUnderflow);
+static_assert(cast_safety<int32_t>(static_cast<float>(INT32_MAX)) == CastSafety::kOverflow);
+
+static_assert(cast_safety<float>(-DBL_MAX) == CastSafety::kUnderflow);
+
+// Unsigned to unsigned.
+
+static_assert(cast_safety<uint8_t>(0u) == CastSafety::kSafe);
+static_assert(cast_safety<uint16_t>(max<uint8_t>) == CastSafety::kSafe);
+static_assert(cast_safety<uint8_t>(static_cast<uint32_t>(max<uint8_t>)) == CastSafety::kSafe);
+
+static_assert(cast_safety<uint32_t>(max<uint64_t>) == CastSafety::kOverflow);
+static_assert(cast_safety<uint8_t>(static_cast<uint32_t>(max<uint8_t>) + 1) ==
+              CastSafety::kOverflow);
+
+// Unsigned to signed.
+
+static_assert(cast_safety<int16_t>(0u) == CastSafety::kSafe);
+static_assert(cast_safety<int16_t>(max<uint8_t>) == CastSafety::kSafe);
+static_assert(cast_safety<int16_t>(max<uint16_t>) == CastSafety::kOverflow);
+
+static_assert(cast_safety<int64_t>(static_cast<uint64_t>(max<int64_t>) - 1) == CastSafety::kSafe);
+static_assert(cast_safety<int64_t>(static_cast<uint64_t>(max<int64_t>)) == CastSafety::kSafe);
+static_assert(cast_safety<int64_t>(static_cast<uint64_t>(max<int64_t>) + 1) ==
+              CastSafety::kOverflow);
+
+// Signed to unsigned.
+
+static_assert(cast_safety<uint16_t>(0) == CastSafety::kSafe);
+static_assert(cast_safety<uint16_t>(max<int8_t>) == CastSafety::kSafe);
+static_assert(cast_safety<uint16_t>(max<int16_t>) == CastSafety::kSafe);
+
+static_assert(cast_safety<uint32_t>(-1) == CastSafety::kUnderflow);
+static_assert(cast_safety<uint32_t>(max<int64_t>) == CastSafety::kOverflow);
+
+static_assert(cast_safety<uint32_t>(static_cast<int64_t>(max<uint32_t>) - 1) == CastSafety::kSafe);
+static_assert(cast_safety<uint32_t>(static_cast<int64_t>(max<uint32_t>)) == CastSafety::kSafe);
+static_assert(cast_safety<uint32_t>(static_cast<int64_t>(max<uint32_t>) + 1) ==
+              CastSafety::kOverflow);
+
+// Signed to signed.
+
+static_assert(cast_safety<int8_t>(-129) == CastSafety::kUnderflow);
+static_assert(cast_safety<int8_t>(-128) == CastSafety::kSafe);
+static_assert(cast_safety<int8_t>(127) == CastSafety::kSafe);
+static_assert(cast_safety<int8_t>(128) == CastSafety::kOverflow);
+
+static_assert(cast_safety<int32_t>(static_cast<int64_t>(min<int32_t>)) == CastSafety::kSafe);
+static_assert(cast_safety<int32_t>(static_cast<int64_t>(max<int32_t>)) == CastSafety::kSafe);
+
+static_assert(cast_safety<int16_t>(min<int32_t>) == CastSafety::kUnderflow);
+static_assert(cast_safety<int32_t>(max<int64_t>) == CastSafety::kOverflow);
+
+// Float to float.
+
+static_assert(cast_safety<double>(max<float>) == CastSafety::kSafe);
+static_assert(cast_safety<double>(min<float>) == CastSafety::kSafe);
+
+static_assert(cast_safety<float>(min<double>) == CastSafety::kUnderflow);
+static_assert(cast_safety<float>(max<double>) == CastSafety::kOverflow);
+
+TEST(CastSafety, FloatToFloat) {
+  EXPECT_EQ(cast_safety<float>(std::nexttoward(static_cast<double>(min<float>), min<double>)),
+            CastSafety::kUnderflow);
+  EXPECT_EQ(cast_safety<float>(std::nexttoward(static_cast<double>(max<float>), max<double>)),
+            CastSafety::kOverflow);
+}
+
+// Unsigned to float.
+
+static_assert(cast_safety<float>(0u) == CastSafety::kSafe);
+static_assert(cast_safety<float>(max<uint64_t>) == CastSafety::kSafe);
+
+static_assert(cast_safety<double>(0u) == CastSafety::kSafe);
+static_assert(cast_safety<double>(max<uint64_t>) == CastSafety::kSafe);
+
+// Signed to float.
+
+static_assert(cast_safety<float>(min<int64_t>) == CastSafety::kSafe);
+static_assert(cast_safety<float>(max<int64_t>) == CastSafety::kSafe);
+
+static_assert(cast_safety<double>(min<int64_t>) == CastSafety::kSafe);
+static_assert(cast_safety<double>(max<int64_t>) == CastSafety::kSafe);
+
+// Float to unsigned.
+
+static_assert(cast_safety<uint32_t>(0.f) == CastSafety::kSafe);
+static_assert(cast_safety<uint32_t>(min<float>) == CastSafety::kUnderflow);
+static_assert(cast_safety<uint32_t>(max<float>) == CastSafety::kOverflow);
+static_assert(cast_safety<uint32_t>(-.1f) == CastSafety::kUnderflow);
+
+static_assert(cast_safety<uint16_t>(-inf<float>) == CastSafety::kUnderflow);
+static_assert(cast_safety<uint32_t>(inf<float>) == CastSafety::kOverflow);
+static_assert(cast_safety<uint64_t>(NaN<float>) == CastSafety::kOverflow);
+
+static_assert(cast_safety<uint32_t>(static_cast<float>(max<int32_t>)) == CastSafety::kSafe);
+static_assert(cast_safety<uint32_t>(static_cast<float>(max<uint32_t>)) == CastSafety::kOverflow);
+static_assert(cast_safety<uint32_t>(static_cast<double>(max<int32_t>)) == CastSafety::kSafe);
+static_assert(cast_safety<uint32_t>(static_cast<double>(max<uint32_t>)) == CastSafety::kSafe);
+
+static_assert(cast_safety<uint64_t>(0.0) == CastSafety::kSafe);
+static_assert(cast_safety<uint64_t>(min<double>) == CastSafety::kUnderflow);
+static_assert(cast_safety<uint64_t>(max<double>) == CastSafety::kOverflow);
+static_assert(cast_safety<uint64_t>(-.1) == CastSafety::kUnderflow);
+
+static_assert(cast_safety<uint64_t>(static_cast<float>(max<int64_t>)) == CastSafety::kSafe);
+static_assert(cast_safety<uint64_t>(static_cast<float>(max<uint64_t>)) == CastSafety::kOverflow);
+static_assert(cast_safety<uint64_t>(static_cast<double>(max<int64_t>)) == CastSafety::kSafe);
+static_assert(cast_safety<uint64_t>(static_cast<double>(max<uint64_t>)) == CastSafety::kOverflow);
+
+// Float to signed.
+
+static_assert(cast_safety<int32_t>(0.f) == CastSafety::kSafe);
+static_assert(cast_safety<int32_t>(min<float>) == CastSafety::kUnderflow);
+static_assert(cast_safety<int32_t>(max<float>) == CastSafety::kOverflow);
+
+static_assert(cast_safety<int16_t>(-inf<double>) == CastSafety::kUnderflow);
+static_assert(cast_safety<int32_t>(inf<double>) == CastSafety::kOverflow);
+static_assert(cast_safety<int64_t>(NaN<double>) == CastSafety::kOverflow);
+
+static_assert(cast_safety<int32_t>(static_cast<float>(min<int32_t>)) == CastSafety::kSafe);
+static_assert(cast_safety<int32_t>(static_cast<float>(max<int32_t>)) == CastSafety::kOverflow);
+static_assert(cast_safety<int32_t>(static_cast<double>(min<int32_t>)) == CastSafety::kSafe);
+static_assert(cast_safety<int32_t>(static_cast<double>(max<int32_t>)) == CastSafety::kSafe);
+
+static_assert(cast_safety<int64_t>(0.0) == CastSafety::kSafe);
+static_assert(cast_safety<int64_t>(min<double>) == CastSafety::kUnderflow);
+static_assert(cast_safety<int64_t>(max<double>) == CastSafety::kOverflow);
+
+static_assert(cast_safety<int64_t>(static_cast<float>(min<int64_t>)) == CastSafety::kSafe);
+static_assert(cast_safety<int64_t>(static_cast<float>(max<int64_t>)) == CastSafety::kOverflow);
+static_assert(cast_safety<int64_t>(static_cast<double>(min<int64_t>)) == CastSafety::kSafe);
+static_assert(cast_safety<int64_t>(static_cast<double>(max<int64_t>)) == CastSafety::kOverflow);
+
+TEST(CastSafety, FloatToSigned) {
+  constexpr int32_t kMax = ftl::details::safe_limits<int32_t, float>::max();
+  static_assert(kMax == 2'147'483'520);
+  EXPECT_EQ(kMax, static_cast<int32_t>(std::nexttowardf(max<int32_t>, 0)));
+
+  EXPECT_EQ(cast_safety<int32_t>(std::nexttowardf(min<int32_t>, 0)), CastSafety::kSafe);
+  EXPECT_EQ(cast_safety<int32_t>(std::nexttowardf(max<int32_t>, 0)), CastSafety::kSafe);
+  EXPECT_EQ(cast_safety<int64_t>(std::nexttoward(min<int64_t>, 0)), CastSafety::kSafe);
+  EXPECT_EQ(cast_safety<int64_t>(std::nexttoward(max<int64_t>, 0)), CastSafety::kSafe);
+
+  EXPECT_EQ(cast_safety<int32_t>(std::nexttowardf(min<int32_t>, min<float>)),
+            CastSafety::kUnderflow);
+  EXPECT_EQ(cast_safety<int32_t>(std::nexttowardf(max<int32_t>, max<float>)),
+            CastSafety::kOverflow);
+  EXPECT_EQ(cast_safety<int64_t>(std::nexttoward(min<int64_t>, min<double>)),
+            CastSafety::kUnderflow);
+  EXPECT_EQ(cast_safety<int64_t>(std::nexttoward(max<int64_t>, max<double>)),
+            CastSafety::kOverflow);
+}
+
+}  // namespace android::test
diff --git a/libs/ftl/small_map_test.cpp b/libs/ftl/small_map_test.cpp
index 323b9f9..2e81022 100644
--- a/libs/ftl/small_map_test.cpp
+++ b/libs/ftl/small_map_test.cpp
@@ -18,6 +18,9 @@
 #include <gtest/gtest.h>
 
 #include <cctype>
+#include <string>
+
+using namespace std::string_literals;
 
 namespace android::test {
 
@@ -35,16 +38,19 @@
 
   EXPECT_TRUE(map.contains(123));
 
-  EXPECT_EQ(map.find(42, [](const std::string& s) { return s.size(); }), 3u);
+  EXPECT_EQ(map.get(42, [](const std::string& s) { return s.size(); }), 3u);
 
-  const auto opt = map.find(-1);
+  const auto opt = map.get(-1);
   ASSERT_TRUE(opt);
 
   std::string& ref = *opt;
   EXPECT_TRUE(ref.empty());
   ref = "xyz";
 
-  EXPECT_EQ(map, SmallMap(ftl::init::map(-1, "xyz")(42, "???")(123, "abc")));
+  map.emplace_or_replace(0, "vanilla", 2u, 3u);
+  EXPECT_TRUE(map.dynamic());
+
+  EXPECT_EQ(map, SmallMap(ftl::init::map(-1, "xyz")(0, "nil")(42, "???")(123, "abc")));
 }
 
 TEST(SmallMap, Construct) {
@@ -90,42 +96,253 @@
   }
 }
 
+TEST(SmallMap, UniqueKeys) {
+  {
+    // Duplicate mappings are discarded.
+    const SmallMap map = ftl::init::map<int, float>(1)(2)(3)(2)(3)(1)(3)(2)(1);
+
+    EXPECT_EQ(map.size(), 3u);
+    EXPECT_EQ(map.max_size(), 9u);
+
+    using Map = decltype(map);
+    EXPECT_EQ(map, Map(ftl::init::map(1, 0.f)(2, 0.f)(3, 0.f)));
+  }
+  {
+    // Duplicate mappings may be reordered.
+    const SmallMap map = ftl::init::map('a', 'A')(
+        'b', 'B')('b')('b')('c', 'C')('a')('d')('c')('e', 'E')('d', 'D')('a')('f', 'F');
+
+    EXPECT_EQ(map.size(), 6u);
+    EXPECT_EQ(map.max_size(), 12u);
+
+    using Map = decltype(map);
+    EXPECT_EQ(map, Map(ftl::init::map('a', 'A')('b', 'B')('c', 'C')('d', 'D')('e', 'E')('f', 'F')));
+  }
+}
+
 TEST(SmallMap, Find) {
   {
     // Constant reference.
-    const ftl::SmallMap map = ftl::init::map('a', 'A')('b', 'B')('c', 'C');
+    const SmallMap map = ftl::init::map('a', 'A')('b', 'B')('c', 'C');
 
-    const auto opt = map.find('b');
+    const auto opt = map.get('b');
     EXPECT_EQ(opt, 'B');
 
     const char d = 'D';
-    const auto ref = map.find('d').value_or(std::cref(d));
+    const auto ref = map.get('d').value_or(std::cref(d));
     EXPECT_EQ(ref.get(), 'D');
   }
   {
     // Mutable reference.
-    ftl::SmallMap map = ftl::init::map('a', 'A')('b', 'B')('c', 'C');
+    SmallMap map = ftl::init::map('a', 'A')('b', 'B')('c', 'C');
 
-    const auto opt = map.find('c');
+    const auto opt = map.get('c');
     EXPECT_EQ(opt, 'C');
 
     char d = 'd';
-    const auto ref = map.find('d').value_or(std::ref(d));
+    const auto ref = map.get('d').value_or(std::ref(d));
     ref.get() = 'D';
     EXPECT_EQ(d, 'D');
   }
   {
     // Constant unary operation.
-    const ftl::SmallMap map = ftl::init::map('a', 'x')('b', 'y')('c', 'z');
-    EXPECT_EQ(map.find('c', [](char c) { return std::toupper(c); }), 'Z');
+    const SmallMap map = ftl::init::map('a', 'x')('b', 'y')('c', 'z');
+    EXPECT_EQ(map.get('c', [](char c) { return std::toupper(c); }), 'Z');
   }
   {
     // Mutable unary operation.
-    ftl::SmallMap map = ftl::init::map('a', 'x')('b', 'y')('c', 'z');
-    EXPECT_TRUE(map.find('c', [](char& c) { c = std::toupper(c); }));
+    SmallMap map = ftl::init::map('a', 'x')('b', 'y')('c', 'z');
+    EXPECT_TRUE(map.get('c', [](char& c) { c = std::toupper(c); }));
 
     EXPECT_EQ(map, SmallMap(ftl::init::map('c', 'Z')('b', 'y')('a', 'x')));
   }
 }
 
+TEST(SmallMap, TryEmplace) {
+  SmallMap<int, std::string, 3> map;
+  using Pair = decltype(map)::value_type;
+
+  {
+    const auto [it, ok] = map.try_emplace(123, "abc");
+    ASSERT_TRUE(ok);
+    EXPECT_EQ(*it, Pair(123, "abc"s));
+  }
+  {
+    const auto [it, ok] = map.try_emplace(42, 3u, '?');
+    ASSERT_TRUE(ok);
+    EXPECT_EQ(*it, Pair(42, "???"s));
+  }
+  {
+    const auto [it, ok] = map.try_emplace(-1);
+    ASSERT_TRUE(ok);
+    EXPECT_EQ(*it, Pair(-1, std::string()));
+    EXPECT_FALSE(map.dynamic());
+  }
+  {
+    // Insertion fails if mapping exists.
+    const auto [it, ok] = map.try_emplace(42, "!!!");
+    EXPECT_FALSE(ok);
+    EXPECT_EQ(*it, Pair(42, "???"));
+    EXPECT_FALSE(map.dynamic());
+  }
+  {
+    // Insertion at capacity promotes the map.
+    const auto [it, ok] = map.try_emplace(999, "xyz");
+    ASSERT_TRUE(ok);
+    EXPECT_EQ(*it, Pair(999, "xyz"));
+    EXPECT_TRUE(map.dynamic());
+  }
+
+  EXPECT_EQ(map, SmallMap(ftl::init::map(-1, ""s)(42, "???"s)(123, "abc"s)(999, "xyz"s)));
+}
+
+namespace {
+
+// The mapped type does not require a copy/move assignment operator.
+struct String {
+  template <typename... Args>
+  String(Args... args) : str(args...) {}
+  const std::string str;
+
+  bool operator==(const String& other) const { return other.str == str; }
+};
+
+}  // namespace
+
+TEST(SmallMap, TryReplace) {
+  SmallMap<int, String, 3> map = ftl::init::map(1, "a")(2, "B");
+  using Pair = decltype(map)::value_type;
+
+  {
+    // Replacing fails unless mapping exists.
+    const auto it = map.try_replace(3, "c");
+    EXPECT_EQ(it, map.end());
+  }
+  {
+    // Replacement arguments can refer to the replaced mapping.
+    const auto ref = map.get(2, [](const auto& s) { return s.str[0]; });
+    ASSERT_TRUE(ref);
+
+    // Construct std::string from one character.
+    const auto it = map.try_replace(2, 1u, static_cast<char>(std::tolower(*ref)));
+    ASSERT_NE(it, map.end());
+    EXPECT_EQ(*it, Pair(2, "b"));
+  }
+
+  EXPECT_FALSE(map.dynamic());
+  EXPECT_TRUE(map.try_emplace(3, "abc").second);
+  EXPECT_TRUE(map.try_emplace(4, "d").second);
+  EXPECT_TRUE(map.dynamic());
+
+  {
+    // Replacing fails unless mapping exists.
+    const auto it = map.try_replace(5, "e");
+    EXPECT_EQ(it, map.end());
+  }
+  {
+    // Replacement arguments can refer to the replaced mapping.
+    const auto ref = map.get(3);
+    ASSERT_TRUE(ref);
+
+    // Construct std::string from substring.
+    const auto it = map.try_replace(3, ref->get().str, 2u, 1u);
+    ASSERT_NE(it, map.end());
+    EXPECT_EQ(*it, Pair(3, "c"));
+  }
+
+  EXPECT_EQ(map, SmallMap(ftl::init::map(4, "d"s)(3, "c"s)(2, "b"s)(1, "a"s)));
+}
+
+TEST(SmallMap, EmplaceOrReplace) {
+  SmallMap<int, String, 3> map = ftl::init::map(1, "a")(2, "B");
+  using Pair = decltype(map)::value_type;
+
+  {
+    // New mapping is emplaced.
+    const auto [it, emplace] = map.emplace_or_replace(3, "c");
+    EXPECT_TRUE(emplace);
+    EXPECT_EQ(*it, Pair(3, "c"));
+  }
+  {
+    // Replacement arguments can refer to the replaced mapping.
+    const auto ref = map.get(2, [](const auto& s) { return s.str[0]; });
+    ASSERT_TRUE(ref);
+
+    // Construct std::string from one character.
+    const auto [it, emplace] = map.emplace_or_replace(2, 1u, static_cast<char>(std::tolower(*ref)));
+    EXPECT_FALSE(emplace);
+    EXPECT_EQ(*it, Pair(2, "b"));
+  }
+
+  EXPECT_FALSE(map.dynamic());
+  EXPECT_FALSE(map.emplace_or_replace(3, "abc").second);  // Replace.
+  EXPECT_TRUE(map.emplace_or_replace(4, "d").second);     // Emplace.
+  EXPECT_TRUE(map.dynamic());
+
+  {
+    // New mapping is emplaced.
+    const auto [it, emplace] = map.emplace_or_replace(5, "e");
+    EXPECT_TRUE(emplace);
+    EXPECT_EQ(*it, Pair(5, "e"));
+  }
+  {
+    // Replacement arguments can refer to the replaced mapping.
+    const auto ref = map.get(3);
+    ASSERT_TRUE(ref);
+
+    // Construct std::string from substring.
+    const auto [it, emplace] = map.emplace_or_replace(3, ref->get().str, 2u, 1u);
+    EXPECT_FALSE(emplace);
+    EXPECT_EQ(*it, Pair(3, "c"));
+  }
+
+  EXPECT_EQ(map, SmallMap(ftl::init::map(5, "e"s)(4, "d"s)(3, "c"s)(2, "b"s)(1, "a"s)));
+}
+
+TEST(SmallMap, Erase) {
+  {
+    SmallMap map = ftl::init::map(1, '1')(2, '2')(3, '3')(4, '4');
+    EXPECT_FALSE(map.dynamic());
+
+    EXPECT_FALSE(map.erase(0));  // Key not found.
+
+    EXPECT_TRUE(map.erase(2));
+    EXPECT_EQ(map, SmallMap(ftl::init::map(1, '1')(3, '3')(4, '4')));
+
+    EXPECT_TRUE(map.erase(1));
+    EXPECT_EQ(map, SmallMap(ftl::init::map(3, '3')(4, '4')));
+
+    EXPECT_TRUE(map.erase(4));
+    EXPECT_EQ(map, SmallMap(ftl::init::map(3, '3')));
+
+    EXPECT_TRUE(map.erase(3));
+    EXPECT_FALSE(map.erase(3));  // Key not found.
+
+    EXPECT_TRUE(map.empty());
+    EXPECT_FALSE(map.dynamic());
+  }
+  {
+    SmallMap map = ftl::init::map(1, '1')(2, '2')(3, '3');
+    map.try_emplace(4, '4');
+    EXPECT_TRUE(map.dynamic());
+
+    EXPECT_FALSE(map.erase(0));  // Key not found.
+
+    EXPECT_TRUE(map.erase(2));
+    EXPECT_EQ(map, SmallMap(ftl::init::map(1, '1')(3, '3')(4, '4')));
+
+    EXPECT_TRUE(map.erase(1));
+    EXPECT_EQ(map, SmallMap(ftl::init::map(3, '3')(4, '4')));
+
+    EXPECT_TRUE(map.erase(4));
+    EXPECT_EQ(map, SmallMap(ftl::init::map(3, '3')));
+
+    EXPECT_TRUE(map.erase(3));
+    EXPECT_FALSE(map.erase(3));  // Key not found.
+
+    EXPECT_TRUE(map.empty());
+    EXPECT_TRUE(map.dynamic());
+  }
+}
+
 }  // namespace android::test
diff --git a/libs/ftl/string_test.cpp b/libs/ftl/string_test.cpp
new file mode 100644
index 0000000..f3d85c8
--- /dev/null
+++ b/libs/ftl/string_test.cpp
@@ -0,0 +1,187 @@
+/*
+ * 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/string.h>
+#include <gtest/gtest.h>
+
+#include <algorithm>
+#include <cstdint>
+#include <iterator>
+#include <limits>
+#include <sstream>
+#include <type_traits>
+
+namespace android::test {
+
+// Keep in sync with example usage in header file.
+TEST(String, ToChars) {
+  ftl::to_chars_buffer_t<> buffer;
+
+  EXPECT_EQ(ftl::to_chars(buffer, 123u), "123");
+  EXPECT_EQ(ftl::to_chars(buffer, -42, ftl::Radix::kBin), "-0b101010");
+  EXPECT_EQ(ftl::to_chars(buffer, 0xcafe, ftl::Radix::kHex), "0xcafe");
+  EXPECT_EQ(ftl::to_chars(buffer, '*', ftl::Radix::kHex), "0x2a");
+}
+
+namespace {
+
+template <typename F, typename T>
+void ToCharsTest() {
+  constexpr auto kRadix = F::kRadix;
+
+  using Limits = std::numeric_limits<T>;
+  constexpr auto kMin = Limits::min();
+  constexpr auto kMax = Limits::max();
+  constexpr auto kNeg = static_cast<T>(-42);
+  constexpr auto kPos = static_cast<T>(123);
+
+  ftl::to_chars_buffer_t<T> buffer;
+
+  EXPECT_EQ(ftl::to_chars(buffer, kMin, kRadix), F{}(kMin));
+  EXPECT_EQ(ftl::to_chars(buffer, kMax, kRadix), F{}(kMax));
+  EXPECT_EQ(ftl::to_chars(buffer, kNeg, kRadix), F{}(kNeg));
+  EXPECT_EQ(ftl::to_chars(buffer, kPos, kRadix), F{}(kPos));
+}
+
+template <typename...>
+struct Types {};
+
+template <typename F, typename Types>
+struct ToCharsTests;
+
+template <typename F, typename T, typename... Ts>
+struct ToCharsTests<F, Types<T, Ts...>> {
+  static void test() {
+    ToCharsTest<F, T>();
+    ToCharsTests<F, Types<Ts...>>::test();
+  }
+};
+
+template <typename F>
+struct ToCharsTests<F, Types<>> {
+  static void test() {}
+};
+
+template <typename T, typename U = std::make_unsigned_t<T>>
+U to_unsigned(std::ostream& stream, T v) {
+  if (std::is_same_v<T, U>) return v;
+
+  if (v < 0) {
+    stream << '-';
+    return std::numeric_limits<U>::max() - static_cast<U>(v) + 1;
+  } else {
+    return static_cast<U>(v);
+  }
+}
+
+struct Bin {
+  static constexpr auto kRadix = ftl::Radix::kBin;
+
+  template <typename T>
+  std::string operator()(T v) const {
+    std::ostringstream stream;
+    auto u = to_unsigned(stream, v);
+    stream << "0b";
+
+    if (u == 0) {
+      stream << 0;
+    } else {
+      std::ostringstream digits;
+      do {
+        digits << (u & 1);
+      } while (u >>= 1);
+
+      const auto str = digits.str();
+      std::copy(str.rbegin(), str.rend(), std::ostream_iterator<char>(stream));
+    }
+
+    return stream.str();
+  }
+};
+
+struct Dec {
+  static constexpr auto kRadix = ftl::Radix::kDec;
+
+  template <typename T>
+  std::string operator()(T v) const {
+    return std::to_string(v);
+  }
+};
+
+struct Hex {
+  static constexpr auto kRadix = ftl::Radix::kHex;
+
+  template <typename T>
+  std::string operator()(T v) const {
+    std::ostringstream stream;
+    const auto u = to_unsigned(stream, v);
+    stream << "0x" << std::hex << std::nouppercase;
+    stream << (sizeof(T) == 1 ? static_cast<unsigned>(u) : u);
+    return stream.str();
+  }
+};
+
+using IntegerTypes =
+    Types<char, unsigned char, signed char, std::uint8_t, std::uint16_t, std::uint32_t,
+          std::uint64_t, std::int8_t, std::int16_t, std::int32_t, std::int64_t>;
+
+}  // namespace
+
+TEST(String, ToCharsBin) {
+  ToCharsTests<Bin, IntegerTypes>::test();
+
+  {
+    const std::uint8_t x = 0b1111'1111;
+    ftl::to_chars_buffer_t<decltype(x)> buffer;
+    EXPECT_EQ(ftl::to_chars(buffer, x, ftl::Radix::kBin), "0b11111111");
+  }
+  {
+    const std::int16_t x = -0b1000'0000'0000'0000;
+    ftl::to_chars_buffer_t<decltype(x)> buffer;
+    EXPECT_EQ(ftl::to_chars(buffer, x, ftl::Radix::kBin), "-0b1000000000000000");
+  }
+}
+
+TEST(String, ToCharsDec) {
+  ToCharsTests<Dec, IntegerTypes>::test();
+
+  {
+    const std::uint32_t x = UINT32_MAX;
+    ftl::to_chars_buffer_t<decltype(x)> buffer;
+    EXPECT_EQ(ftl::to_chars(buffer, x), "4294967295");
+  }
+  {
+    const std::int32_t x = INT32_MIN;
+    ftl::to_chars_buffer_t<decltype(x)> buffer;
+    EXPECT_EQ(ftl::to_chars(buffer, x), "-2147483648");
+  }
+}
+
+TEST(String, ToCharsHex) {
+  ToCharsTests<Hex, IntegerTypes>::test();
+
+  {
+    const std::uint16_t x = 0xfade;
+    ftl::to_chars_buffer_t<decltype(x)> buffer;
+    EXPECT_EQ(ftl::to_chars(buffer, x, ftl::Radix::kHex), "0xfade");
+  }
+  {
+    ftl::to_chars_buffer_t<> buffer;
+    EXPECT_EQ(ftl::to_chars(buffer, INT64_MIN, ftl::Radix::kHex), "-0x8000000000000000");
+  }
+}
+
+}  // namespace android::test
diff --git a/libs/gui/Android.bp b/libs/gui/Android.bp
index 64203f7..2d8fff9 100644
--- a/libs/gui/Android.bp
+++ b/libs/gui/Android.bp
@@ -51,6 +51,51 @@
     ],
 }
 
+// AIDL files that should be exposed to java
+filegroup {
+    name: "guiconstants_aidl",
+    srcs: [
+        "android/**/TouchOcclusionMode.aidl",
+    ],
+}
+
+cc_library_static {
+    name: "libgui_window_info_static",
+    vendor_available: true,
+    host_supported: true,
+    srcs: [
+        ":guiconstants_aidl",
+        "android/gui/FocusRequest.aidl",
+        "android/gui/InputApplicationInfo.aidl",
+        "android/gui/WindowInfo.aidl",
+        "WindowInfo.cpp",
+    ],
+
+    shared_libs: [
+        "libbinder",
+    ],
+
+    local_include_dirs: [
+        "include",
+    ],
+
+    export_shared_lib_headers: [
+        "libbinder",
+    ],
+
+    static_libs: [
+        "libui-types",
+    ],
+
+    aidl: {
+        export_aidl_headers: true
+    },
+
+    include_dirs: [
+        "frameworks/native/include",
+    ],
+}
+
 filegroup {
     name: "libgui_aidl",
     srcs: ["aidl/**/*.aidl"],
@@ -77,12 +122,15 @@
         "libbinder",
     ],
 
+    static_libs: [
+        "libui-types",
+    ],
+
     aidl: {
         export_aidl_headers: true
     }
 }
 
-
 cc_library_shared {
     name: "libgui",
     vendor_available: true,
@@ -96,9 +144,11 @@
 
     static_libs: [
         "libgui_aidl_static",
+        "libgui_window_info_static",
     ],
     export_static_lib_headers: [
         "libgui_aidl_static",
+        "libgui_window_info_static",
     ],
 
     srcs: [
@@ -150,13 +200,11 @@
         "libbinder",
         "libbufferhub",
         "libbufferhubqueue", // TODO(b/70046255): Remove this once BufferHub is integrated into libgui.
-        "libinput",
         "libpdx_default_transport",
     ],
 
     export_shared_lib_headers: [
         "libbinder",
-        "libinput",
     ],
 
     export_header_lib_headers: [
@@ -168,7 +216,6 @@
         vendor: {
             cflags: [
                 "-DNO_BUFFERHUB",
-                "-DNO_INPUT",
             ],
             exclude_srcs: [
                 "BufferHubConsumer.cpp",
@@ -178,7 +225,6 @@
                 "android.frameworks.bufferhub@1.0",
                 "libbufferhub",
                 "libbufferhubqueue",
-                "libinput",
                 "libpdx_default_transport",
             ],
         },
diff --git a/libs/gui/BLASTBufferQueue.cpp b/libs/gui/BLASTBufferQueue.cpp
index 2970116..dbb1cb0 100644
--- a/libs/gui/BLASTBufferQueue.cpp
+++ b/libs/gui/BLASTBufferQueue.cpp
@@ -38,7 +38,7 @@
 using namespace std::chrono_literals;
 
 namespace {
-inline const char* toString(bool b) {
+inline const char* boolToString(bool b) {
     return b ? "true" : "false";
 }
 } // namespace
@@ -513,7 +513,7 @@
     BQA_LOGV("processNextBufferLocked size=%dx%d mFrameNumber=%" PRIu64
              " applyTransaction=%s mTimestamp=%" PRId64 "%s mPendingTransactions.size=%d"
              " graphicBufferId=%" PRIu64 "%s",
-             mSize.width, mSize.height, bufferItem.mFrameNumber, toString(applyTransaction),
+             mSize.width, mSize.height, bufferItem.mFrameNumber, boolToString(applyTransaction),
              bufferItem.mTimestamp, bufferItem.mIsAutoTimestamp ? "(auto)" : "",
              static_cast<uint32_t>(mPendingTransactions.size()), bufferItem.mGraphicBuffer->getId(),
              bufferItem.mAutoRefresh ? " mAutoRefresh" : "");
@@ -543,7 +543,7 @@
                mNumFrameAvailable + mNumAcquired - mPendingRelease.size());
 
     BQA_LOGV("onFrameAvailable framenumber=%" PRIu64 " nextTransactionSet=%s", item.mFrameNumber,
-             toString(nextTransactionSet));
+             boolToString(nextTransactionSet));
     processNextBufferLocked(nextTransactionSet /* useNextTransaction */);
 }
 
diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp
index 0d7795e..bab9ebf 100644
--- a/libs/gui/ISurfaceComposer.cpp
+++ b/libs/gui/ISurfaceComposer.cpp
@@ -123,11 +123,11 @@
         return remote()->transact(BnSurfaceComposer::CAPTURE_DISPLAY, data, &reply);
     }
 
-    status_t captureDisplay(uint64_t displayOrLayerStack,
+    status_t captureDisplay(DisplayId displayId,
                             const sp<IScreenCaptureListener>& captureListener) override {
         Parcel data, reply;
         data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
-        SAFE_PARCEL(data.writeUint64, displayOrLayerStack);
+        SAFE_PARCEL(data.writeUint64, displayId.value);
         SAFE_PARCEL(data.writeStrongBinder, IInterface::asBinder(captureListener));
 
         return remote()->transact(BnSurfaceComposer::CAPTURE_DISPLAY_BY_ID, data, &reply);
@@ -281,9 +281,14 @@
             NO_ERROR) {
             std::vector<uint64_t> rawIds;
             if (reply.readUint64Vector(&rawIds) == NO_ERROR) {
-                std::vector<PhysicalDisplayId> displayIds(rawIds.size());
-                std::transform(rawIds.begin(), rawIds.end(), displayIds.begin(),
-                               [](uint64_t rawId) { return PhysicalDisplayId(rawId); });
+                std::vector<PhysicalDisplayId> displayIds;
+                displayIds.reserve(rawIds.size());
+
+                for (const uint64_t rawId : rawIds) {
+                    if (const auto id = DisplayId::fromValue<PhysicalDisplayId>(rawId)) {
+                        displayIds.push_back(*id);
+                    }
+                }
                 return displayIds;
             }
         }
@@ -1327,12 +1332,15 @@
         }
         case CAPTURE_DISPLAY_BY_ID: {
             CHECK_INTERFACE(ISurfaceComposer, data, reply);
-            uint64_t displayOrLayerStack = 0;
+            uint64_t value;
+            SAFE_PARCEL(data.readUint64, &value);
+            const auto id = DisplayId::fromValue(value);
+            if (!id) return BAD_VALUE;
+
             sp<IScreenCaptureListener> captureListener;
-            SAFE_PARCEL(data.readUint64, &displayOrLayerStack);
             SAFE_PARCEL(data.readStrongBinder, &captureListener);
 
-            return captureDisplay(displayOrLayerStack, captureListener);
+            return captureDisplay(*id, captureListener);
         }
         case CAPTURE_LAYERS: {
             CHECK_INTERFACE(ISurfaceComposer, data, reply);
@@ -1399,9 +1407,9 @@
         }
         case GET_PHYSICAL_DISPLAY_TOKEN: {
             CHECK_INTERFACE(ISurfaceComposer, data, reply);
-            PhysicalDisplayId displayId(data.readUint64());
-            sp<IBinder> display = getPhysicalDisplayToken(displayId);
-            reply->writeStrongBinder(display);
+            const auto id = DisplayId::fromValue<PhysicalDisplayId>(data.readUint64());
+            if (!id) return BAD_VALUE;
+            reply->writeStrongBinder(getPhysicalDisplayToken(*id));
             return NO_ERROR;
         }
         case GET_DISPLAY_STATE: {
diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp
index d102e07..001570c 100644
--- a/libs/gui/LayerState.cpp
+++ b/libs/gui/LayerState.cpp
@@ -31,6 +31,9 @@
 
 namespace android {
 
+using gui::FocusRequest;
+using gui::WindowInfoHandle;
+
 layer_state_t::layer_state_t()
       : what(0),
         x(0),
@@ -94,9 +97,7 @@
     SAFE_PARCEL(output.writeFloat, color.r);
     SAFE_PARCEL(output.writeFloat, color.g);
     SAFE_PARCEL(output.writeFloat, color.b);
-#ifndef NO_INPUT
-    SAFE_PARCEL(inputHandle->writeToParcel, &output);
-#endif
+    SAFE_PARCEL(windowInfoHandle->writeToParcel, &output);
     SAFE_PARCEL(output.write, transparentRegion);
     SAFE_PARCEL(output.writeUint32, transform);
     SAFE_PARCEL(output.writeBool, transformToDisplayInverse);
@@ -205,9 +206,7 @@
     color.g = tmpFloat;
     SAFE_PARCEL(input.readFloat, &tmpFloat);
     color.b = tmpFloat;
-#ifndef NO_INPUT
-    SAFE_PARCEL(inputHandle->readFromParcel, &input);
-#endif
+    SAFE_PARCEL(windowInfoHandle->readFromParcel, &input);
 
     SAFE_PARCEL(input.read, transparentRegion);
     SAFE_PARCEL(input.readUint32, &transform);
@@ -491,14 +490,10 @@
     if (other.what & eHasListenerCallbacksChanged) {
         what |= eHasListenerCallbacksChanged;
     }
-
-#ifndef NO_INPUT
     if (other.what & eInputInfoChanged) {
         what |= eInputInfoChanged;
-        inputHandle = new InputWindowHandle(*other.inputHandle);
+        windowInfoHandle = new WindowInfoHandle(*other.windowInfoHandle);
     }
-#endif
-
     if (other.what & eCachedBufferChanged) {
         what |= eCachedBufferChanged;
         cachedBuffer = other.cachedBuffer;
@@ -589,11 +584,9 @@
 
 bool InputWindowCommands::merge(const InputWindowCommands& other) {
     bool changes = false;
-#ifndef NO_INPUT
     changes |= !other.focusRequests.empty();
     focusRequests.insert(focusRequests.end(), std::make_move_iterator(other.focusRequests.begin()),
                          std::make_move_iterator(other.focusRequests.end()));
-#endif
     changes |= other.syncInputWindows && !syncInputWindows;
     syncInputWindows |= other.syncInputWindows;
     return changes;
@@ -601,31 +594,23 @@
 
 bool InputWindowCommands::empty() const {
     bool empty = true;
-#ifndef NO_INPUT
     empty = focusRequests.empty() && !syncInputWindows;
-#endif
     return empty;
 }
 
 void InputWindowCommands::clear() {
-#ifndef NO_INPUT
     focusRequests.clear();
-#endif
     syncInputWindows = false;
 }
 
 status_t InputWindowCommands::write(Parcel& output) const {
-#ifndef NO_INPUT
     SAFE_PARCEL(output.writeParcelableVector, focusRequests);
-#endif
     SAFE_PARCEL(output.writeBool, syncInputWindows);
     return NO_ERROR;
 }
 
 status_t InputWindowCommands::read(const Parcel& input) {
-#ifndef NO_INPUT
     SAFE_PARCEL(input.readParcelableVector, &focusRequests);
-#endif
     SAFE_PARCEL(input.readBool, &syncInputWindows);
     return NO_ERROR;
 }
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index c255303..ec03c21 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -39,14 +39,11 @@
 #include <gui/LayerState.h>
 #include <gui/Surface.h>
 #include <gui/SurfaceComposerClient.h>
+#include <gui/WindowInfo.h>
 #include <private/gui/ParcelUtils.h>
 #include <ui/DisplayMode.h>
 #include <ui/DynamicDisplayInfo.h>
 
-#ifndef NO_INPUT
-#include <input/InputWindow.h>
-#endif
-
 #include <private/gui/ComposerService.h>
 
 // This server size should always be smaller than the server cache size
@@ -54,6 +51,9 @@
 
 namespace android {
 
+using gui::FocusRequest;
+using gui::WindowInfo;
+using gui::WindowInfoHandle;
 using ui::ColorMode;
 // ---------------------------------------------------------------------------
 
@@ -1491,16 +1491,14 @@
     return *this;
 }
 
-#ifndef NO_INPUT
 SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setInputWindowInfo(
-        const sp<SurfaceControl>& sc,
-        const InputWindowInfo& info) {
+        const sp<SurfaceControl>& sc, const WindowInfo& info) {
     layer_state_t* s = getLayerState(sc);
     if (!s) {
         mStatus = BAD_INDEX;
         return *this;
     }
-    s->inputHandle = new InputWindowHandle(info);
+    s->windowInfoHandle = new WindowInfoHandle(info);
     s->what |= layer_state_t::eInputInfoChanged;
     return *this;
 }
@@ -1516,8 +1514,6 @@
     return *this;
 }
 
-#endif
-
 SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setColorTransform(
     const sp<SurfaceControl>& sc, const mat3& matrix, const vec3& translation) {
     layer_state_t* s = getLayerState(sc);
@@ -2156,12 +2152,12 @@
     return s->captureDisplay(captureArgs, captureListener);
 }
 
-status_t ScreenshotClient::captureDisplay(uint64_t displayOrLayerStack,
+status_t ScreenshotClient::captureDisplay(DisplayId displayId,
                                           const sp<IScreenCaptureListener>& captureListener) {
     sp<ISurfaceComposer> s(ComposerService::getComposerService());
     if (s == nullptr) return NO_INIT;
 
-    return s->captureDisplay(displayOrLayerStack, captureListener);
+    return s->captureDisplay(displayId, captureListener);
 }
 
 status_t ScreenshotClient::captureLayers(const LayerCaptureArgs& captureArgs,
diff --git a/libs/input/InputWindow.cpp b/libs/gui/WindowInfo.cpp
similarity index 79%
rename from libs/input/InputWindow.cpp
rename to libs/gui/WindowInfo.cpp
index 9947720..ff0bb8a 100644
--- a/libs/input/InputWindow.cpp
+++ b/libs/gui/WindowInfo.cpp
@@ -15,43 +15,40 @@
  */
 
 #include <type_traits>
-#define LOG_TAG "InputWindow"
+#define LOG_TAG "WindowInfo"
 #define LOG_NDEBUG 0
 
 #include <android-base/stringprintf.h>
 #include <binder/Parcel.h>
-#include <input/InputTransport.h>
-#include <input/InputWindow.h>
+#include <gui/WindowInfo.h>
 
 #include <log/log.h>
 
-namespace android {
+namespace android::gui {
 
-
-// --- InputWindowInfo ---
-void InputWindowInfo::addTouchableRegion(const Rect& region) {
+// --- WindowInfo ---
+void WindowInfo::addTouchableRegion(const Rect& region) {
     touchableRegion.orSelf(region);
 }
 
-bool InputWindowInfo::touchableRegionContainsPoint(int32_t x, int32_t y) const {
-    return touchableRegion.contains(x,y);
+bool WindowInfo::touchableRegionContainsPoint(int32_t x, int32_t y) const {
+    return touchableRegion.contains(x, y);
 }
 
-bool InputWindowInfo::frameContainsPoint(int32_t x, int32_t y) const {
-    return x >= frameLeft && x < frameRight
-            && y >= frameTop && y < frameBottom;
+bool WindowInfo::frameContainsPoint(int32_t x, int32_t y) const {
+    return x >= frameLeft && x < frameRight && y >= frameTop && y < frameBottom;
 }
 
-bool InputWindowInfo::supportsSplitTouch() const {
+bool WindowInfo::supportsSplitTouch() const {
     return flags.test(Flag::SPLIT_TOUCH);
 }
 
-bool InputWindowInfo::overlaps(const InputWindowInfo* other) const {
-    return frameLeft < other->frameRight && frameRight > other->frameLeft
-            && frameTop < other->frameBottom && frameBottom > other->frameTop;
+bool WindowInfo::overlaps(const WindowInfo* other) const {
+    return frameLeft < other->frameRight && frameRight > other->frameLeft &&
+            frameTop < other->frameBottom && frameBottom > other->frameTop;
 }
 
-bool InputWindowInfo::operator==(const InputWindowInfo& info) const {
+bool WindowInfo::operator==(const WindowInfo& info) const {
     return info.token == token && info.id == id && info.name == name && info.flags == flags &&
             info.type == type && info.dispatchingTimeout == dispatchingTimeout &&
             info.frameLeft == frameLeft && info.frameTop == frameTop &&
@@ -69,7 +66,7 @@
             info.applicationInfo == applicationInfo;
 }
 
-status_t InputWindowInfo::writeToParcel(android::Parcel* parcel) const {
+status_t WindowInfo::writeToParcel(android::Parcel* parcel) const {
     if (parcel == nullptr) {
         ALOGE("%s: Null parcel", __func__);
         return BAD_VALUE;
@@ -86,7 +83,7 @@
         parcel->writeInt32(id) ?:
         parcel->writeUtf8AsUtf16(name) ?:
         parcel->writeInt32(flags.get()) ?:
-        parcel->writeInt32(static_cast<std::underlying_type_t<InputWindowInfo::Type>>(type)) ?:
+        parcel->writeInt32(static_cast<std::underlying_type_t<WindowInfo::Type>>(type)) ?:
         parcel->writeInt32(frameLeft) ?:
         parcel->writeInt32(frameTop) ?:
         parcel->writeInt32(frameRight) ?:
@@ -122,7 +119,7 @@
     return status;
 }
 
-status_t InputWindowInfo::readFromParcel(const android::Parcel* parcel) {
+status_t WindowInfo::readFromParcel(const android::Parcel* parcel) {
     if (parcel == nullptr) {
         ALOGE("%s: Null parcel", __func__);
         return BAD_VALUE;
@@ -176,11 +173,13 @@
     touchOcclusionMode = static_cast<TouchOcclusionMode>(touchOcclusionModeInt);
 
     inputFeatures = Flags<Feature>(parcel->readInt32());
+    // clang-format off
     status = parcel->readInt32(&displayId) ?:
         parcel->readInt32(&portalToDisplayId) ?:
         applicationInfo.readFromParcel(parcel) ?:
         parcel->read(touchableRegion) ?:
         parcel->readBool(&replaceTouchableRegionWithCrop);
+    // clang-format on
 
     if (status != OK) {
         return status;
@@ -192,33 +191,33 @@
     return OK;
 }
 
-// --- InputWindowHandle ---
+// --- WindowInfoHandle ---
 
-InputWindowHandle::InputWindowHandle() {}
+WindowInfoHandle::WindowInfoHandle() {}
 
-InputWindowHandle::~InputWindowHandle() {}
+WindowInfoHandle::~WindowInfoHandle() {}
 
-InputWindowHandle::InputWindowHandle(const InputWindowHandle& other) : mInfo(other.mInfo) {}
+WindowInfoHandle::WindowInfoHandle(const WindowInfoHandle& other) : mInfo(other.mInfo) {}
 
-InputWindowHandle::InputWindowHandle(const InputWindowInfo& other) : mInfo(other) {}
+WindowInfoHandle::WindowInfoHandle(const WindowInfo& other) : mInfo(other) {}
 
-status_t InputWindowHandle::writeToParcel(android::Parcel* parcel) const {
+status_t WindowInfoHandle::writeToParcel(android::Parcel* parcel) const {
     return mInfo.writeToParcel(parcel);
 }
 
-status_t InputWindowHandle::readFromParcel(const android::Parcel* parcel) {
+status_t WindowInfoHandle::readFromParcel(const android::Parcel* parcel) {
     return mInfo.readFromParcel(parcel);
 }
 
-void InputWindowHandle::releaseChannel() {
+void WindowInfoHandle::releaseChannel() {
     mInfo.token.clear();
 }
 
-sp<IBinder> InputWindowHandle::getToken() const {
+sp<IBinder> WindowInfoHandle::getToken() const {
     return mInfo.token;
 }
 
-void InputWindowHandle::updateFrom(sp<InputWindowHandle> handle) {
+void WindowInfoHandle::updateFrom(sp<WindowInfoHandle> handle) {
     mInfo = handle->mInfo;
 }
-} // namespace android
+} // namespace android::gui
diff --git a/libs/input/android/FocusRequest.aidl b/libs/gui/android/gui/FocusRequest.aidl
similarity index 98%
rename from libs/input/android/FocusRequest.aidl
rename to libs/gui/android/gui/FocusRequest.aidl
index 8812d34..9018635 100644
--- a/libs/input/android/FocusRequest.aidl
+++ b/libs/gui/android/gui/FocusRequest.aidl
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package android;
+package android.gui;
 
 /** @hide */
 parcelable FocusRequest {
diff --git a/libs/input/android/InputApplicationInfo.aidl b/libs/gui/android/gui/InputApplicationInfo.aidl
similarity index 96%
rename from libs/input/android/InputApplicationInfo.aidl
rename to libs/gui/android/gui/InputApplicationInfo.aidl
index 9336039..c0fd666 100644
--- a/libs/input/android/InputApplicationInfo.aidl
+++ b/libs/gui/android/gui/InputApplicationInfo.aidl
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package android;
+package android.gui;
 
 parcelable InputApplicationInfo {
     @nullable IBinder token;
diff --git a/libs/input/android/os/TouchOcclusionMode.aidl b/libs/gui/android/gui/TouchOcclusionMode.aidl
similarity index 98%
rename from libs/input/android/os/TouchOcclusionMode.aidl
rename to libs/gui/android/gui/TouchOcclusionMode.aidl
index 106f159..d91d052 100644
--- a/libs/input/android/os/TouchOcclusionMode.aidl
+++ b/libs/gui/android/gui/TouchOcclusionMode.aidl
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package android.os;
+package android.gui;
 
 
 /**
diff --git a/libs/input/android/InputWindowInfo.aidl b/libs/gui/android/gui/WindowInfo.aidl
similarity index 81%
rename from libs/input/android/InputWindowInfo.aidl
rename to libs/gui/android/gui/WindowInfo.aidl
index eeaf400..2c85d15 100644
--- a/libs/input/android/InputWindowInfo.aidl
+++ b/libs/gui/android/gui/WindowInfo.aidl
@@ -1,5 +1,4 @@
-/* //device/java/android/android/view/InputChannel.aidl
-**
+/*
 ** Copyright 2020, The Android Open Source Project
 **
 ** Licensed under the Apache License, Version 2.0 (the "License");
@@ -15,6 +14,6 @@
 ** limitations under the License.
 */
 
-package android;
+package android.gui;
 
-parcelable InputWindowInfo cpp_header "input/InputWindow.h";
+parcelable WindowInfo cpp_header "gui/WindowInfo.h";
diff --git a/libs/gui/include/gui/ISurfaceComposer.h b/libs/gui/include/gui/ISurfaceComposer.h
index 2a3f6a4..c0a2335 100644
--- a/libs/gui/include/gui/ISurfaceComposer.h
+++ b/libs/gui/include/gui/ISurfaceComposer.h
@@ -24,9 +24,9 @@
 #include <android/gui/ITunnelModeEnabledListener.h>
 #include <binder/IBinder.h>
 #include <binder/IInterface.h>
+#include <ftl/Flags.h>
 #include <gui/FrameTimelineInfo.h>
 #include <gui/ITransactionCompletedListener.h>
-#include <input/Flags.h>
 #include <math/vec4.h>
 #include <stdint.h>
 #include <sys/types.h>
@@ -115,6 +115,11 @@
 
     using EventRegistrationFlags = Flags<EventRegistration>;
 
+    template <typename T>
+    struct SpHash {
+        size_t operator()(const sp<T>& k) const { return std::hash<T*>()(k.get()); }
+    };
+
     /*
      * Create a connection with SurfaceFlinger.
      */
@@ -238,24 +243,17 @@
      * The subregion can be optionally rotated.  It will also be scaled to
      * match the size of the output buffer.
      */
-    virtual status_t captureDisplay(const DisplayCaptureArgs& args,
-                                    const sp<IScreenCaptureListener>& captureListener) = 0;
+    virtual status_t captureDisplay(const DisplayCaptureArgs&,
+                                    const sp<IScreenCaptureListener>&) = 0;
 
-    virtual status_t captureDisplay(uint64_t displayOrLayerStack,
-                                    const sp<IScreenCaptureListener>& captureListener) = 0;
-
-    template <class AA>
-    struct SpHash {
-        size_t operator()(const sp<AA>& k) const { return std::hash<AA*>()(k.get()); }
-    };
+    virtual status_t captureDisplay(DisplayId, const sp<IScreenCaptureListener>&) = 0;
 
     /**
      * Capture a subtree of the layer hierarchy, potentially ignoring the root node.
      * This requires READ_FRAME_BUFFER permission. This function will fail if there
      * is a secure window on screen
      */
-    virtual status_t captureLayers(const LayerCaptureArgs& args,
-                                   const sp<IScreenCaptureListener>& captureListener) = 0;
+    virtual status_t captureLayers(const LayerCaptureArgs&, const sp<IScreenCaptureListener>&) = 0;
 
     /* Clears the frame statistics for animations.
      *
diff --git a/include/input/InputApplication.h b/libs/gui/include/gui/InputApplication.h
similarity index 84%
rename from include/input/InputApplication.h
rename to libs/gui/include/gui/InputApplication.h
index 8e4fe79..679c2a1 100644
--- a/include/input/InputApplication.h
+++ b/libs/gui/include/gui/InputApplication.h
@@ -19,17 +19,17 @@
 
 #include <string>
 
-#include <android/InputApplicationInfo.h>
+#include <android/gui/InputApplicationInfo.h>
 
 #include <binder/IBinder.h>
 #include <binder/Parcel.h>
 #include <binder/Parcelable.h>
 
-#include <input/Input.h>
 #include <utils/RefBase.h>
 #include <utils/Timers.h>
 
 namespace android {
+
 /*
  * Handle for an application that can receive input.
  *
@@ -38,13 +38,9 @@
  */
 class InputApplicationHandle {
 public:
-    inline const InputApplicationInfo* getInfo() const {
-        return &mInfo;
-    }
+    inline const gui::InputApplicationInfo* getInfo() const { return &mInfo; }
 
-    inline std::string getName() const {
-        return !mInfo.name.empty() ? mInfo.name : "<invalid>";
-    }
+    inline std::string getName() const { return !mInfo.name.empty() ? mInfo.name : "<invalid>"; }
 
     inline std::chrono::nanoseconds getDispatchingTimeout(
             std::chrono::nanoseconds defaultValue) const {
@@ -52,9 +48,7 @@
                            : defaultValue;
     }
 
-    inline sp<IBinder> getApplicationToken() const {
-        return mInfo.token;
-    }
+    inline sp<IBinder> getApplicationToken() const { return mInfo.token; }
 
     bool operator==(const InputApplicationHandle& other) const {
         return getName() == other.getName() && getApplicationToken() == other.getApplicationToken();
@@ -77,7 +71,7 @@
     InputApplicationHandle() = default;
     virtual ~InputApplicationHandle() = default;
 
-    InputApplicationInfo mInfo;
+    gui::InputApplicationInfo mInfo;
 };
 
 } // namespace android
diff --git a/libs/gui/include/gui/LayerState.h b/libs/gui/include/gui/LayerState.h
index 7961f4b..92de74a 100644
--- a/libs/gui/include/gui/LayerState.h
+++ b/libs/gui/include/gui/LayerState.h
@@ -26,14 +26,12 @@
 #include <gui/ITransactionCompletedListener.h>
 #include <math/mat4.h>
 
-#ifndef NO_INPUT
-#include <android/FocusRequest.h>
-#include <input/InputWindow.h>
-#endif
+#include <android/gui/FocusRequest.h>
 
 #include <gui/ISurfaceComposer.h>
 #include <gui/LayerMetadata.h>
 #include <gui/SurfaceControl.h>
+#include <gui/WindowInfo.h>
 #include <math/vec3.h>
 #include <ui/BlurRegion.h>
 #include <ui/GraphicTypes.h>
@@ -176,9 +174,7 @@
     mat4 colorTransform;
     std::vector<BlurRegion> blurRegions;
 
-#ifndef NO_INPUT
-    sp<InputWindowHandle> inputHandle = new InputWindowHandle();
-#endif
+    sp<gui::WindowInfoHandle> windowInfoHandle = new gui::WindowInfoHandle();
 
     client_cache_t cachedBuffer;
 
@@ -288,9 +284,7 @@
 };
 
 struct InputWindowCommands {
-#ifndef NO_INPUT
-    std::vector<FocusRequest> focusRequests;
-#endif
+    std::vector<gui::FocusRequest> focusRequests;
     bool syncInputWindows{false};
 
     // Merges the passed in commands and returns true if there were any changes.
diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h
index eb81483..1dfc83b 100644
--- a/libs/gui/include/gui/SurfaceComposerClient.h
+++ b/libs/gui/include/gui/SurfaceComposerClient.h
@@ -502,11 +502,9 @@
         // Set the framenumber generated by the graphics producer to mimic BufferQueue behaviour.
         Transaction& setFrameNumber(const sp<SurfaceControl>& sc, uint64_t frameNumber);
 
-#ifndef NO_INPUT
-        Transaction& setInputWindowInfo(const sp<SurfaceControl>& sc, const InputWindowInfo& info);
-        Transaction& setFocusedWindow(const FocusRequest& request);
+        Transaction& setInputWindowInfo(const sp<SurfaceControl>& sc, const gui::WindowInfo& info);
+        Transaction& setFocusedWindow(const gui::FocusRequest& request);
         Transaction& syncInputWindows();
-#endif
 
         // Set a color transform matrix on the given layer on the built-in display.
         Transaction& setColorTransform(const sp<SurfaceControl>& sc, const mat3& matrix,
@@ -633,12 +631,9 @@
 
 class ScreenshotClient {
 public:
-    static status_t captureDisplay(const DisplayCaptureArgs& captureArgs,
-                                   const sp<IScreenCaptureListener>& captureListener);
-    static status_t captureDisplay(uint64_t displayOrLayerStack,
-                                   const sp<IScreenCaptureListener>& captureListener);
-    static status_t captureLayers(const LayerCaptureArgs& captureArgs,
-                                  const sp<IScreenCaptureListener>& captureListener);
+    static status_t captureDisplay(const DisplayCaptureArgs&, const sp<IScreenCaptureListener>&);
+    static status_t captureDisplay(DisplayId, const sp<IScreenCaptureListener>&);
+    static status_t captureLayers(const LayerCaptureArgs&, const sp<IScreenCaptureListener>&);
 };
 
 // ---------------------------------------------------------------------------
diff --git a/include/input/InputWindow.h b/libs/gui/include/gui/WindowInfo.h
similarity index 89%
rename from include/input/InputWindow.h
rename to libs/gui/include/gui/WindowInfo.h
index 121be6d..51ddc50 100644
--- a/include/input/InputWindow.h
+++ b/libs/gui/include/gui/WindowInfo.h
@@ -14,15 +14,13 @@
  * limitations under the License.
  */
 
-#ifndef _UI_INPUT_WINDOW_H
-#define _UI_INPUT_WINDOW_H
+#pragma once
 
-#include <android/os/TouchOcclusionMode.h>
+#include <android/gui/TouchOcclusionMode.h>
 #include <binder/Parcel.h>
 #include <binder/Parcelable.h>
-#include <input/Flags.h>
-#include <input/Input.h>
-#include <input/InputTransport.h>
+#include <ftl/Flags.h>
+#include <gui/constants.h>
 #include <ui/Rect.h>
 #include <ui/Region.h>
 #include <ui/Transform.h>
@@ -31,15 +29,13 @@
 
 #include "InputApplication.h"
 
-using android::os::TouchOcclusionMode;
-
-namespace android {
+namespace android::gui {
 
 /*
  * Describes the properties of a window that can receive input.
  */
-struct InputWindowInfo : public Parcelable {
-    InputWindowInfo() = default;
+struct WindowInfo : public Parcelable {
+    WindowInfo() = default;
 
     // Window flags from WindowManager.LayoutParams
     enum class Flag : uint32_t {
@@ -169,8 +165,8 @@
     ui::Transform transform;
 
     // Display size in its natural rotation. Used to rotate raw coordinates for compatibility.
-    int32_t displayWidth = AMOTION_EVENT_INVALID_DISPLAY_SIZE;
-    int32_t displayHeight = AMOTION_EVENT_INVALID_DISPLAY_SIZE;
+    int32_t displayWidth = 0;
+    int32_t displayHeight = 0;
 
     /*
      * This is filled in by the WM relative to the frame and then translated
@@ -206,9 +202,9 @@
 
     bool supportsSplitTouch() const;
 
-    bool overlaps(const InputWindowInfo* other) const;
+    bool overlaps(const WindowInfo* other) const;
 
-    bool operator==(const InputWindowInfo& inputChannel) const;
+    bool operator==(const WindowInfo& inputChannel) const;
 
     status_t writeToParcel(android::Parcel* parcel) const override;
 
@@ -221,13 +217,13 @@
  * Used by the native input dispatcher to indirectly refer to the window manager objects
  * that describe a window.
  */
-class InputWindowHandle : public RefBase {
+class WindowInfoHandle : public RefBase {
 public:
-    explicit InputWindowHandle();
-    InputWindowHandle(const InputWindowHandle& other);
-    InputWindowHandle(const InputWindowInfo& other);
+    explicit WindowInfoHandle();
+    WindowInfoHandle(const WindowInfoHandle& other);
+    WindowInfoHandle(const WindowInfo& other);
 
-    inline const InputWindowInfo* getInfo() const { return &mInfo; }
+    inline const WindowInfo* getInfo() const { return &mInfo; }
 
     sp<IBinder> getToken() const;
 
@@ -257,7 +253,7 @@
     /**
      * Updates from another input window handle.
      */
-    void updateFrom(const sp<InputWindowHandle> handle);
+    void updateFrom(const sp<WindowInfoHandle> handle);
 
     /**
      * Releases the channel used by the associated information when it is
@@ -270,10 +266,8 @@
     status_t writeToParcel(android::Parcel* parcel) const;
 
 protected:
-    virtual ~InputWindowHandle();
+    virtual ~WindowInfoHandle();
 
-    InputWindowInfo mInfo;
+    WindowInfo mInfo;
 };
-} // namespace android
-
-#endif // _UI_INPUT_WINDOW_H
+} // namespace android::gui
\ No newline at end of file
diff --git a/libs/gui/include/gui/constants.h b/libs/gui/include/gui/constants.h
new file mode 100644
index 0000000..8eab378
--- /dev/null
+++ b/libs/gui/include/gui/constants.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 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 <stdint.h>
+
+namespace android {
+
+/**
+ * Invalid value for display size. Used when display size isn't available.
+ */
+constexpr int32_t INVALID_DISPLAY_SIZE = 0;
+
+enum {
+    /* Used when an event is not associated with any display.
+     * Typically used for non-pointer events. */
+    ADISPLAY_ID_NONE = -1,
+
+    /* The default display id. */
+    ADISPLAY_ID_DEFAULT = 0,
+};
+
+} // namespace android
\ No newline at end of file
diff --git a/libs/gui/tests/Android.bp b/libs/gui/tests/Android.bp
index c801c62..3d26c3d 100644
--- a/libs/gui/tests/Android.bp
+++ b/libs/gui/tests/Android.bp
@@ -43,6 +43,7 @@
         "SurfaceTextureMultiContextGL_test.cpp",
         "Surface_test.cpp",
         "TextureRenderer.cpp",
+        "WindowInfo_test.cpp",
     ],
 
     shared_libs: [
diff --git a/libs/gui/tests/EndToEndNativeInputTest.cpp b/libs/gui/tests/EndToEndNativeInputTest.cpp
index 49c44a7..fc84c1b 100644
--- a/libs/gui/tests/EndToEndNativeInputTest.cpp
+++ b/libs/gui/tests/EndToEndNativeInputTest.cpp
@@ -37,9 +37,9 @@
 #include <gui/SurfaceControl.h>
 
 #include <android/os/IInputFlinger.h>
+#include <gui/WindowInfo.h>
 #include <input/Input.h>
 #include <input/InputTransport.h>
-#include <input/InputWindow.h>
 
 #include <ui/DisplayMode.h>
 #include <ui/Rect.h>
@@ -49,6 +49,11 @@
 
 using android::hardware::graphics::common::V1_1::BufferUsage;
 
+using android::gui::FocusRequest;
+using android::gui::InputApplicationInfo;
+using android::gui::TouchOcclusionMode;
+using android::gui::WindowInfo;
+
 namespace android::test {
 
 using Transaction = SurfaceComposerClient::Transaction;
@@ -221,8 +226,8 @@
     void populateInputInfo(int width, int height) {
         mInputInfo.token = mClientChannel->getConnectionToken();
         mInputInfo.name = "Test info";
-        mInputInfo.flags = InputWindowInfo::Flag::NOT_TOUCH_MODAL;
-        mInputInfo.type = InputWindowInfo::Type::BASE_APPLICATION;
+        mInputInfo.flags = WindowInfo::Flag::NOT_TOUCH_MODAL;
+        mInputInfo.type = WindowInfo::Type::BASE_APPLICATION;
         mInputInfo.dispatchingTimeout = 5s;
         mInputInfo.globalScaleFactor = 1.0;
         mInputInfo.focusable = true;
@@ -249,7 +254,7 @@
     std::shared_ptr<InputChannel> mClientChannel;
     sp<IInputFlinger> mInputFlinger;
 
-    InputWindowInfo mInputInfo;
+    WindowInfo mInputInfo;
 
     PreallocatedInputEventFactory mInputEventFactory;
     InputConsumer* mInputConsumer;
@@ -686,7 +691,7 @@
     // Add non touchable window to fully cover touchable window. Window behind gets touch, but
     // with flag AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED
     std::unique_ptr<InputSurface> nonTouchableSurface = makeSurface(100, 100);
-    nonTouchableSurface->mInputInfo.flags = InputWindowInfo::Flag::NOT_TOUCHABLE;
+    nonTouchableSurface->mInputInfo.flags = WindowInfo::Flag::NOT_TOUCHABLE;
     nonTouchableSurface->mInputInfo.ownerUid = 22222;
     // Overriding occlusion mode otherwise the touch would be discarded at InputDispatcher by
     // the default obscured/untrusted touch filter introduced in S.
@@ -706,8 +711,8 @@
     // AMOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED
     std::unique_ptr<InputSurface> parentSurface = makeSurface(100, 100);
     std::unique_ptr<InputSurface> nonTouchableSurface = makeSurface(100, 100);
-    nonTouchableSurface->mInputInfo.flags = InputWindowInfo::Flag::NOT_TOUCHABLE;
-    parentSurface->mInputInfo.flags = InputWindowInfo::Flag::NOT_TOUCHABLE;
+    nonTouchableSurface->mInputInfo.flags = WindowInfo::Flag::NOT_TOUCHABLE;
+    parentSurface->mInputInfo.flags = WindowInfo::Flag::NOT_TOUCHABLE;
     nonTouchableSurface->mInputInfo.ownerUid = 22222;
     parentSurface->mInputInfo.ownerUid = 22222;
     nonTouchableSurface->showAt(0, 0);
@@ -730,8 +735,8 @@
     // the touchable window. Window behind gets touch with no obscured flags.
     std::unique_ptr<InputSurface> parentSurface = makeSurface(100, 100);
     std::unique_ptr<InputSurface> nonTouchableSurface = makeSurface(100, 100);
-    nonTouchableSurface->mInputInfo.flags = InputWindowInfo::Flag::NOT_TOUCHABLE;
-    parentSurface->mInputInfo.flags = InputWindowInfo::Flag::NOT_TOUCHABLE;
+    nonTouchableSurface->mInputInfo.flags = WindowInfo::Flag::NOT_TOUCHABLE;
+    parentSurface->mInputInfo.flags = WindowInfo::Flag::NOT_TOUCHABLE;
     nonTouchableSurface->mInputInfo.ownerUid = 22222;
     parentSurface->mInputInfo.ownerUid = 22222;
     nonTouchableSurface->showAt(0, 0);
@@ -751,7 +756,7 @@
 
     std::unique_ptr<InputSurface> bufferSurface =
             InputSurface::makeBufferInputSurface(mComposerClient, 0, 0);
-    bufferSurface->mInputInfo.flags = InputWindowInfo::Flag::NOT_TOUCHABLE;
+    bufferSurface->mInputInfo.flags = WindowInfo::Flag::NOT_TOUCHABLE;
     bufferSurface->mInputInfo.ownerUid = 22222;
 
     surface->showAt(10, 10);
@@ -766,7 +771,7 @@
 
     std::unique_ptr<BlastInputSurface> bufferSurface =
             BlastInputSurface::makeBlastInputSurface(mComposerClient, 0, 0);
-    bufferSurface->mInputInfo.flags = InputWindowInfo::Flag::NOT_TOUCHABLE;
+    bufferSurface->mInputInfo.flags = WindowInfo::Flag::NOT_TOUCHABLE;
     bufferSurface->mInputInfo.ownerUid = 22222;
 
     surface->showAt(10, 10);
diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp
index 59b0c04..8d7a356 100644
--- a/libs/gui/tests/Surface_test.cpp
+++ b/libs/gui/tests/Surface_test.cpp
@@ -752,21 +752,19 @@
     }
     status_t setActiveColorMode(const sp<IBinder>& /*display*/,
         ColorMode /*colorMode*/) override { return NO_ERROR; }
-    status_t captureDisplay(const DisplayCaptureArgs& /* captureArgs */,
-                            const sp<IScreenCaptureListener>& /* captureListener */) override {
-        return NO_ERROR;
-    }
     void setAutoLowLatencyMode(const sp<IBinder>& /*display*/, bool /*on*/) override {}
     void setGameContentType(const sp<IBinder>& /*display*/, bool /*on*/) override {}
-    status_t captureDisplay(uint64_t /*displayOrLayerStack*/,
-                            const sp<IScreenCaptureListener>& /* captureListener */) override {
+
+    status_t captureDisplay(const DisplayCaptureArgs&, const sp<IScreenCaptureListener>&) override {
         return NO_ERROR;
     }
-    virtual status_t captureLayers(
-            const LayerCaptureArgs& /* captureArgs */,
-            const sp<IScreenCaptureListener>& /* captureListener */) override {
+    status_t captureDisplay(DisplayId, const sp<IScreenCaptureListener>&) override {
         return NO_ERROR;
     }
+    status_t captureLayers(const LayerCaptureArgs&, const sp<IScreenCaptureListener>&) override {
+        return NO_ERROR;
+    }
+
     status_t clearAnimationFrameStats() override { return NO_ERROR; }
     status_t getAnimationFrameStats(FrameStats* /*outStats*/) const override {
         return NO_ERROR;
diff --git a/libs/input/tests/InputWindow_test.cpp b/libs/gui/tests/WindowInfo_test.cpp
similarity index 89%
rename from libs/input/tests/InputWindow_test.cpp
rename to libs/gui/tests/WindowInfo_test.cpp
index 493f2f4..09c02ca 100644
--- a/libs/input/tests/InputWindow_test.cpp
+++ b/libs/gui/tests/WindowInfo_test.cpp
@@ -19,16 +19,20 @@
 #include <binder/Binder.h>
 #include <binder/Parcel.h>
 
-#include <input/InputWindow.h>
-#include <input/InputTransport.h>
+#include <gui/WindowInfo.h>
 
 using std::chrono_literals::operator""s;
 
 namespace android {
+
+using gui::InputApplicationInfo;
+using gui::TouchOcclusionMode;
+using gui::WindowInfo;
+
 namespace test {
 
-TEST(InputWindowInfo, ParcellingWithoutToken) {
-    InputWindowInfo i, i2;
+TEST(WindowInfo, ParcellingWithoutToken) {
+    WindowInfo i, i2;
     i.token = nullptr;
 
     Parcel p;
@@ -38,14 +42,14 @@
     ASSERT_TRUE(i2.token == nullptr);
 }
 
-TEST(InputWindowInfo, Parcelling) {
+TEST(WindowInfo, Parcelling) {
     sp<IBinder> touchableRegionCropHandle = new BBinder();
-    InputWindowInfo i;
+    WindowInfo i;
     i.token = new BBinder();
     i.id = 1;
     i.name = "Foobar";
-    i.flags = InputWindowInfo::Flag::SLIPPERY;
-    i.type = InputWindowInfo::Type::INPUT_METHOD;
+    i.flags = WindowInfo::Flag::SLIPPERY;
+    i.type = WindowInfo::Type::INPUT_METHOD;
     i.dispatchingTimeout = 12s;
     i.frameLeft = 93;
     i.frameTop = 34;
@@ -65,7 +69,7 @@
     i.ownerPid = 19;
     i.ownerUid = 24;
     i.packageName = "com.example.package";
-    i.inputFeatures = InputWindowInfo::Feature::DISABLE_USER_ACTIVITY;
+    i.inputFeatures = WindowInfo::Feature::DISABLE_USER_ACTIVITY;
     i.displayId = 34;
     i.portalToDisplayId = 2;
     i.replaceTouchableRegionWithCrop = true;
@@ -77,7 +81,7 @@
     Parcel p;
     i.writeToParcel(&p);
     p.setDataPosition(0);
-    InputWindowInfo i2;
+    WindowInfo i2;
     i2.readFromParcel(&p);
     ASSERT_EQ(i.token, i2.token);
     ASSERT_EQ(i.id, i2.id);
diff --git a/libs/input/Android.bp b/libs/input/Android.bp
index a63ec8f..1a142c9 100644
--- a/libs/input/Android.bp
+++ b/libs/input/Android.bp
@@ -30,7 +30,6 @@
         "android/os/IInputConstants.aidl",
         "android/os/InputEventInjectionResult.aidl",
         "android/os/InputEventInjectionSync.aidl",
-        "android/os/TouchOcclusionMode.aidl",
     ],
 }
 
@@ -69,26 +68,24 @@
 
     static_libs: [
         "libui-types",
+        "libgui_window_info_static",
     ],
 
     export_static_lib_headers: [
         "libui-types",
+        "libgui_window_info_static",
     ],
 
     target: {
         android: {
             srcs: [
                 "InputTransport.cpp",
-                "InputWindow.cpp",
-                "android/FocusRequest.aidl",
-                "android/InputApplicationInfo.aidl",
                 "android/os/BlockUntrustedTouchesMode.aidl",
                 "android/os/IInputConstants.aidl",
                 "android/os/IInputFlinger.aidl",
                 "android/os/InputEventInjectionResult.aidl",
                 "android/os/InputEventInjectionSync.aidl",
                 "android/os/ISetInputWindowsListener.aidl",
-                "android/os/TouchOcclusionMode.aidl",
             ],
 
             export_shared_lib_headers: ["libbinder"],
@@ -114,13 +111,9 @@
         linux_glibc: {
             srcs: [
                 "InputTransport.cpp",
-                "InputWindow.cpp",
-                "android/FocusRequest.aidl",
-                "android/InputApplicationInfo.aidl",
                 "android/os/IInputConstants.aidl",
                 "android/os/IInputFlinger.aidl",
                 "android/os/ISetInputWindowsListener.aidl",
-                "android/os/TouchOcclusionMode.aidl",
             ],
             static_libs: [
                 "libhostgraphics",
@@ -134,6 +127,9 @@
     aidl: {
         local_include_dirs: ["."],
         export_aidl_headers: true,
+        include_dirs: [
+            "frameworks/native/libs/gui",
+        ],
     },
 }
 
diff --git a/libs/input/Input.cpp b/libs/input/Input.cpp
index 266d7a3..9390467 100644
--- a/libs/input/Input.cpp
+++ b/libs/input/Input.cpp
@@ -24,6 +24,7 @@
 #include <string.h>
 
 #include <android-base/stringprintf.h>
+#include <gui/constants.h>
 #include <input/Input.h>
 #include <input/InputDevice.h>
 #include <input/InputEventLabels.h>
@@ -322,10 +323,6 @@
     scaleAxisValue(*this, AMOTION_EVENT_AXIS_RELATIVE_Y, windowYScale);
 }
 
-void PointerCoords::scale(float globalScaleFactor) {
-    scale(globalScaleFactor, globalScaleFactor, globalScaleFactor);
-}
-
 void PointerCoords::applyOffset(float xOffset, float yOffset) {
     setAxisValue(AMOTION_EVENT_AXIS_X, getX() + xOffset);
     setAxisValue(AMOTION_EVENT_AXIS_Y, getY() + yOffset);
diff --git a/libs/input/InputDevice.cpp b/libs/input/InputDevice.cpp
index 30c42a3..220c8e1 100644
--- a/libs/input/InputDevice.cpp
+++ b/libs/input/InputDevice.cpp
@@ -21,9 +21,9 @@
 #include <ctype.h>
 
 #include <android-base/stringprintf.h>
+#include <ftl/NamedEnum.h>
 #include <input/InputDevice.h>
 #include <input/InputEventLabels.h>
-#include <input/NamedEnum.h>
 
 using android::base::StringPrintf;
 
diff --git a/libs/input/InputTransport.cpp b/libs/input/InputTransport.cpp
index dd1c462..d6c1161 100644
--- a/libs/input/InputTransport.cpp
+++ b/libs/input/InputTransport.cpp
@@ -33,8 +33,8 @@
 #include <log/log.h>
 #include <utils/Trace.h>
 
+#include <ftl/NamedEnum.h>
 #include <input/InputTransport.h>
-#include <input/NamedEnum.h>
 
 using android::base::StringPrintf;
 
diff --git a/libs/input/KeyCharacterMap.cpp b/libs/input/KeyCharacterMap.cpp
index 44f3f34..3baeb55 100644
--- a/libs/input/KeyCharacterMap.cpp
+++ b/libs/input/KeyCharacterMap.cpp
@@ -28,10 +28,11 @@
 #include <input/KeyCharacterMap.h>
 #include <input/Keyboard.h>
 
-#include <utils/Log.h>
+#include <gui/constants.h>
 #include <utils/Errors.h>
-#include <utils/Tokenizer.h>
+#include <utils/Log.h>
 #include <utils/Timers.h>
+#include <utils/Tokenizer.h>
 
 // Enables debug output for the parser.
 #define DEBUG_PARSER 0
diff --git a/libs/input/KeyLayoutMap.cpp b/libs/input/KeyLayoutMap.cpp
index fa5a541..c365ab0 100644
--- a/libs/input/KeyLayoutMap.cpp
+++ b/libs/input/KeyLayoutMap.cpp
@@ -19,10 +19,10 @@
 #include <stdlib.h>
 
 #include <android/keycodes.h>
+#include <ftl/NamedEnum.h>
 #include <input/InputEventLabels.h>
 #include <input/KeyLayoutMap.h>
 #include <input/Keyboard.h>
-#include <input/NamedEnum.h>
 #include <utils/Errors.h>
 #include <utils/Log.h>
 #include <utils/Timers.h>
diff --git a/libs/input/android/os/IInputFlinger.aidl b/libs/input/android/os/IInputFlinger.aidl
index 1771d19..43b262f 100644
--- a/libs/input/android/os/IInputFlinger.aidl
+++ b/libs/input/android/os/IInputFlinger.aidl
@@ -16,9 +16,9 @@
 
 package android.os;
 
-import android.FocusRequest;
 import android.InputChannel;
-import android.InputWindowInfo;
+import android.gui.FocusRequest;
+import android.gui.WindowInfo;
 import android.os.ISetInputWindowsListener;
 
 /** @hide */
@@ -28,7 +28,7 @@
     // ordering when needed.
     // SurfaceFlinger calls this only every VSync, so overflow of binder's oneway buffer
     // shouldn't be a concern.
-    oneway void setInputWindows(in InputWindowInfo[] inputHandles,
+    oneway void setInputWindows(in WindowInfo[] windowInfoHandles,
             in @nullable ISetInputWindowsListener setInputWindowsListener);
     InputChannel createInputChannel(in @utf8InCpp String name);
     void removeInputChannel(in IBinder connectionToken);
diff --git a/libs/input/tests/Android.bp b/libs/input/tests/Android.bp
index 6ffc6a8..18ab1cb 100644
--- a/libs/input/tests/Android.bp
+++ b/libs/input/tests/Android.bp
@@ -11,26 +11,24 @@
 cc_test {
     name: "libinput_tests",
     srcs: [
-        "NamedEnum_test.cpp",
-        "Flags_test.cpp",
         "IdGenerator_test.cpp",
         "InputChannel_test.cpp",
         "InputDevice_test.cpp",
         "InputEvent_test.cpp",
         "InputPublisherAndConsumer_test.cpp",
-        "InputWindow_test.cpp",
         "TouchVideoFrame_test.cpp",
         "VelocityTracker_test.cpp",
         "VerifiedInputEvent_test.cpp",
     ],
+    static_libs: [
+        "libgui_window_info_static",
+        "libinput",
+    ],
     cflags: [
         "-Wall",
         "-Wextra",
         "-Werror",
     ],
-    static_libs: [
-        "libinput",
-    ],
     shared_libs: [
         "libbase",
         "libbinder",
diff --git a/libs/input/tests/InputEvent_test.cpp b/libs/input/tests/InputEvent_test.cpp
index cfb5986..f1a26ec 100644
--- a/libs/input/tests/InputEvent_test.cpp
+++ b/libs/input/tests/InputEvent_test.cpp
@@ -20,6 +20,7 @@
 #include <attestation/HmacKeyManager.h>
 #include <binder/Parcel.h>
 #include <gtest/gtest.h>
+#include <gui/constants.h>
 #include <input/Input.h>
 
 namespace android {
@@ -271,9 +272,8 @@
                       AMOTION_EVENT_EDGE_FLAG_TOP, AMETA_ALT_ON, AMOTION_EVENT_BUTTON_PRIMARY,
                       MotionClassification::NONE, mTransform, 2.0f, 2.1f,
                       AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
-                      AMOTION_EVENT_INVALID_DISPLAY_SIZE, AMOTION_EVENT_INVALID_DISPLAY_SIZE,
-                      ARBITRARY_DOWN_TIME, ARBITRARY_EVENT_TIME, 2, pointerProperties,
-                      pointerCoords);
+                      INVALID_DISPLAY_SIZE, INVALID_DISPLAY_SIZE, ARBITRARY_DOWN_TIME,
+                      ARBITRARY_EVENT_TIME, 2, pointerProperties, pointerCoords);
 
     pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X, 110);
     pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y, 111);
@@ -593,9 +593,8 @@
                      AMOTION_EVENT_EDGE_FLAG_NONE, AMETA_NONE, 0 /*buttonState*/,
                      MotionClassification::NONE, identityTransform, 0 /*xPrecision*/,
                      0 /*yPrecision*/, 3 + RADIUS /*xCursorPosition*/, 2 /*yCursorPosition*/,
-                     AMOTION_EVENT_INVALID_DISPLAY_SIZE, AMOTION_EVENT_INVALID_DISPLAY_SIZE,
-                     0 /*downTime*/, 0 /*eventTime*/, pointerCount, pointerProperties,
-                     pointerCoords);
+                     INVALID_DISPLAY_SIZE, INVALID_DISPLAY_SIZE, 0 /*downTime*/, 0 /*eventTime*/,
+                     pointerCount, pointerProperties, pointerCoords);
     float originalRawX = 0 + 3;
     float originalRawY = -RADIUS + 2;
 
@@ -795,9 +794,9 @@
                          DISPLAY_ID, INVALID_HMAC, AMOTION_EVENT_ACTION_DOWN, 0, 0,
                          AMOTION_EVENT_EDGE_FLAG_NONE, AMETA_NONE, 0, classification,
                          identityTransform, 0, 0, AMOTION_EVENT_INVALID_CURSOR_POSITION,
-                         AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_DISPLAY_SIZE,
-                         AMOTION_EVENT_INVALID_DISPLAY_SIZE, 0 /*downTime*/, 0 /*eventTime*/,
-                         pointerCount, pointerProperties, pointerCoords);
+                         AMOTION_EVENT_INVALID_CURSOR_POSITION, INVALID_DISPLAY_SIZE,
+                         INVALID_DISPLAY_SIZE, 0 /*downTime*/, 0 /*eventTime*/, pointerCount,
+                         pointerProperties, pointerCoords);
         ASSERT_EQ(classification, event.getClassification());
     }
 }
@@ -817,10 +816,9 @@
     event.initialize(InputEvent::nextId(), 0 /*deviceId*/, AINPUT_SOURCE_MOUSE, DISPLAY_ID,
                      INVALID_HMAC, AMOTION_EVENT_ACTION_DOWN, 0, 0, AMOTION_EVENT_EDGE_FLAG_NONE,
                      AMETA_NONE, 0, MotionClassification::NONE, identityTransform, 0, 0,
-                     280 /*xCursorPosition*/, 540 /*yCursorPosition*/,
-                     AMOTION_EVENT_INVALID_DISPLAY_SIZE, AMOTION_EVENT_INVALID_DISPLAY_SIZE,
-                     0 /*downTime*/, 0 /*eventTime*/, pointerCount, pointerProperties,
-                     pointerCoords);
+                     280 /*xCursorPosition*/, 540 /*yCursorPosition*/, INVALID_DISPLAY_SIZE,
+                     INVALID_DISPLAY_SIZE, 0 /*downTime*/, 0 /*eventTime*/, pointerCount,
+                     pointerProperties, pointerCoords);
     event.offsetLocation(20, 60);
     ASSERT_EQ(280, event.getRawXCursorPosition());
     ASSERT_EQ(540, event.getRawYCursorPosition());
diff --git a/libs/input/tests/InputPublisherAndConsumer_test.cpp b/libs/input/tests/InputPublisherAndConsumer_test.cpp
index a2cfaa1..d0c337c 100644
--- a/libs/input/tests/InputPublisherAndConsumer_test.cpp
+++ b/libs/input/tests/InputPublisherAndConsumer_test.cpp
@@ -23,6 +23,7 @@
 #include <attestation/HmacKeyManager.h>
 #include <cutils/ashmem.h>
 #include <gtest/gtest.h>
+#include <gui/constants.h>
 #include <input/InputTransport.h>
 #include <utils/StopWatch.h>
 #include <utils/Timers.h>
diff --git a/libs/input/tests/VelocityTracker_test.cpp b/libs/input/tests/VelocityTracker_test.cpp
index aefc2ec..8ae7dcc 100644
--- a/libs/input/tests/VelocityTracker_test.cpp
+++ b/libs/input/tests/VelocityTracker_test.cpp
@@ -23,6 +23,7 @@
 #include <android-base/stringprintf.h>
 #include <attestation/HmacKeyManager.h>
 #include <gtest/gtest.h>
+#include <gui/constants.h>
 #include <input/VelocityTracker.h>
 
 using namespace std::chrono_literals;
@@ -183,9 +184,9 @@
                          AMOTION_EVENT_EDGE_FLAG_NONE, AMETA_NONE, 0 /*buttonState*/,
                          MotionClassification::NONE, identityTransform, 0 /*xPrecision*/,
                          0 /*yPrecision*/, AMOTION_EVENT_INVALID_CURSOR_POSITION,
-                         AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_DISPLAY_SIZE,
-                         AMOTION_EVENT_INVALID_DISPLAY_SIZE, 0 /*downTime*/,
-                         entry.eventTime.count(), pointerCount, properties, coords);
+                         AMOTION_EVENT_INVALID_CURSOR_POSITION, INVALID_DISPLAY_SIZE,
+                         INVALID_DISPLAY_SIZE, 0 /*downTime*/, entry.eventTime.count(),
+                         pointerCount, properties, coords);
 
         events.emplace_back(event);
     }
diff --git a/libs/input/tests/VerifiedInputEvent_test.cpp b/libs/input/tests/VerifiedInputEvent_test.cpp
index f79098c..a0c9c17 100644
--- a/libs/input/tests/VerifiedInputEvent_test.cpp
+++ b/libs/input/tests/VerifiedInputEvent_test.cpp
@@ -16,6 +16,7 @@
 
 #include <attestation/HmacKeyManager.h>
 #include <gtest/gtest.h>
+#include <gui/constants.h>
 #include <input/Input.h>
 
 namespace android {
@@ -46,10 +47,9 @@
                      INVALID_HMAC, AMOTION_EVENT_ACTION_DOWN, 0 /*actionButton*/, flags,
                      AMOTION_EVENT_EDGE_FLAG_NONE, AMETA_NONE, 0 /*buttonState*/,
                      MotionClassification::NONE, transform, 0.1 /*xPrecision*/, 0.2 /*yPrecision*/,
-                     280 /*xCursorPosition*/, 540 /*yCursorPosition*/,
-                     AMOTION_EVENT_INVALID_DISPLAY_SIZE, AMOTION_EVENT_INVALID_DISPLAY_SIZE,
-                     100 /*downTime*/, 200 /*eventTime*/, pointerCount, pointerProperties,
-                     pointerCoords);
+                     280 /*xCursorPosition*/, 540 /*yCursorPosition*/, INVALID_DISPLAY_SIZE,
+                     INVALID_DISPLAY_SIZE, 100 /*downTime*/, 200 /*eventTime*/, pointerCount,
+                     pointerProperties, pointerCoords);
     return event;
 }
 
diff --git a/libs/nativedisplay/AChoreographer.cpp b/libs/nativedisplay/AChoreographer.cpp
index 0edb213..6a14d4f 100644
--- a/libs/nativedisplay/AChoreographer.cpp
+++ b/libs/nativedisplay/AChoreographer.cpp
@@ -20,7 +20,6 @@
 #include <android-base/thread_annotations.h>
 #include <gui/DisplayEventDispatcher.h>
 #include <gui/ISurfaceComposer.h>
-#include <gui/SurfaceComposerClient.h>
 #include <jni.h>
 #include <private/android/choreographer.h>
 #include <utils/Looper.h>
@@ -306,8 +305,9 @@
         // Fortunately, these events are small so sending packets across the
         // socket should be atomic across processes.
         DisplayEventReceiver::Event event;
-        event.header = DisplayEventReceiver::Event::Header{DisplayEventReceiver::DISPLAY_EVENT_NULL,
-                                                           PhysicalDisplayId(0), systemTime()};
+        event.header =
+                DisplayEventReceiver::Event::Header{DisplayEventReceiver::DISPLAY_EVENT_NULL,
+                                                    PhysicalDisplayId::fromPort(0), systemTime()};
         injectEvent(event);
     }
 }
diff --git a/libs/nativewindow/include/android/hardware_buffer.h b/libs/nativewindow/include/android/hardware_buffer.h
index d93a84c..d5e7cb2 100644
--- a/libs/nativewindow/include/android/hardware_buffer.h
+++ b/libs/nativewindow/include/android/hardware_buffer.h
@@ -556,6 +556,7 @@
                                    int32_t* _Nonnull outBytesPerPixel,
                                    int32_t* _Nonnull outBytesPerStride) __INTRODUCED_IN(29);
 
+
 /**
  * Get the system wide unique id for an AHardwareBuffer.
  *
diff --git a/libs/ui/Android.bp b/libs/ui/Android.bp
index 74d17ce..5a118ec 100644
--- a/libs/ui/Android.bp
+++ b/libs/ui/Android.bp
@@ -137,7 +137,6 @@
         "HdrCapabilities.cpp",
         "PixelFormat.cpp",
         "PublicFormat.cpp",
-        "Size.cpp",
         "StaticDisplayInfo.cpp",
     ],
 
diff --git a/libs/ui/Size.cpp b/libs/ui/Size.cpp
deleted file mode 100644
index d2996d1..0000000
--- a/libs/ui/Size.cpp
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright 2019 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 <ui/Size.h>
-
-namespace android::ui {
-
-const Size Size::INVALID{-1, -1};
-const Size Size::EMPTY{0, 0};
-
-} // namespace android::ui
diff --git a/libs/ui/include/ui/DisplayId.h b/libs/ui/include/ui/DisplayId.h
index f196ab9..9120972 100644
--- a/libs/ui/include/ui/DisplayId.h
+++ b/libs/ui/include/ui/DisplayId.h
@@ -38,12 +38,22 @@
 
     uint64_t value;
 
+    // For deserialization.
+    static constexpr std::optional<DisplayId> fromValue(uint64_t);
+
+    // As above, but also upcast to Id.
+    template <typename Id>
+    static constexpr std::optional<Id> fromValue(uint64_t value) {
+        if (const auto id = Id::tryCast(DisplayId(value))) {
+            return id;
+        }
+        return {};
+    }
+
 protected:
     explicit constexpr DisplayId(uint64_t id) : value(id) {}
 };
 
-static_assert(sizeof(DisplayId) == sizeof(uint64_t));
-
 inline bool operator==(DisplayId lhs, DisplayId rhs) {
     return lhs.value == rhs.value;
 }
@@ -80,11 +90,8 @@
 
     // TODO(b/162612135) Remove default constructor
     PhysicalDisplayId() = default;
-    // TODO(b/162612135) Remove constructor
-    explicit constexpr PhysicalDisplayId(uint64_t id) : DisplayId(id) {}
 
     constexpr uint16_t getManufacturerId() const { return static_cast<uint16_t>(value >> 40); }
-
     constexpr uint8_t getPort() const { return static_cast<uint8_t>(value); }
 
 private:
@@ -96,10 +103,9 @@
     explicit constexpr PhysicalDisplayId(DisplayId other) : DisplayId(other) {}
 };
 
-static_assert(sizeof(PhysicalDisplayId) == sizeof(uint64_t));
-
 struct VirtualDisplayId : DisplayId {
     using BaseId = uint32_t;
+
     // Flag indicating that this virtual display is backed by the GPU.
     static constexpr uint64_t FLAG_GPU = 1ULL << 61;
 
@@ -163,10 +169,23 @@
     explicit constexpr HalDisplayId(DisplayId other) : DisplayId(other) {}
 };
 
+constexpr std::optional<DisplayId> DisplayId::fromValue(uint64_t value) {
+    if (const auto id = fromValue<PhysicalDisplayId>(value)) {
+        return id;
+    }
+    if (const auto id = fromValue<VirtualDisplayId>(value)) {
+        return id;
+    }
+    return {};
+}
+
+static_assert(sizeof(DisplayId) == sizeof(uint64_t));
+static_assert(sizeof(HalDisplayId) == sizeof(uint64_t));
 static_assert(sizeof(VirtualDisplayId) == sizeof(uint64_t));
+
+static_assert(sizeof(PhysicalDisplayId) == sizeof(uint64_t));
 static_assert(sizeof(HalVirtualDisplayId) == sizeof(uint64_t));
 static_assert(sizeof(GpuVirtualDisplayId) == sizeof(uint64_t));
-static_assert(sizeof(HalDisplayId) == sizeof(uint64_t));
 
 } // namespace android
 
diff --git a/libs/ui/include/ui/Size.h b/libs/ui/include/ui/Size.h
index f1e8252..ecc192d 100644
--- a/libs/ui/include/ui/Size.h
+++ b/libs/ui/include/ui/Size.h
@@ -23,103 +23,70 @@
 #include <type_traits>
 #include <utility>
 
-namespace android {
-namespace ui {
+namespace android::ui {
 
-// Forward declare a few things.
-struct Size;
-bool operator==(const Size& lhs, const Size& rhs);
-
-/**
- * A simple value type representing a two-dimensional size
- */
+// A simple value type representing a two-dimensional size.
 struct Size {
-    int32_t width;
-    int32_t height;
+    int32_t width = -1;
+    int32_t height = -1;
 
-    // Special values
-    static const Size INVALID;
-    static const Size EMPTY;
+    constexpr Size() = default;
 
-    // ------------------------------------------------------------------------
-    // Construction
-    // ------------------------------------------------------------------------
-
-    Size() : Size(INVALID) {}
     template <typename T>
-    Size(T&& w, T&& h)
-          : width(Size::clamp<int32_t, T>(std::forward<T>(w))),
-            height(Size::clamp<int32_t, T>(std::forward<T>(h))) {}
-
-    // ------------------------------------------------------------------------
-    // Accessors
-    // ------------------------------------------------------------------------
+    constexpr Size(T w, T h) : width(clamp<int32_t>(w)), height(clamp<int32_t>(h)) {}
 
     int32_t getWidth() const { return width; }
     int32_t getHeight() const { return height; }
 
-    template <typename T>
-    void setWidth(T&& v) {
-        width = Size::clamp<int32_t, T>(std::forward<T>(v));
-    }
-    template <typename T>
-    void setHeight(T&& v) {
-        height = Size::clamp<int32_t, T>(std::forward<T>(v));
-    }
-
-    // ------------------------------------------------------------------------
-    // Assignment
-    // ------------------------------------------------------------------------
-
-    void set(const Size& size) { *this = size; }
-    template <typename T>
-    void set(T&& w, T&& h) {
-        set(Size(std::forward<T>(w), std::forward<T>(h)));
-    }
-
-    // Sets the value to INVALID
-    void makeInvalid() { set(INVALID); }
-
-    // Sets the value to EMPTY
-    void clear() { set(EMPTY); }
-
-    // ------------------------------------------------------------------------
-    // Semantic checks
-    // ------------------------------------------------------------------------
-
     // Valid means non-negative width and height
     bool isValid() const { return width >= 0 && height >= 0; }
 
     // Empty means zero width and height
-    bool isEmpty() const { return *this == EMPTY; }
+    bool isEmpty() const;
 
-    // ------------------------------------------------------------------------
-    // Clamp Helpers
-    // ------------------------------------------------------------------------
-
-    // Note: We use only features available in C++11 here for compatibility with
-    // external targets which include this file directly or indirectly and which
-    // themselves use C++11.
-
-    // C++11 compatible replacement for std::remove_cv_reference_t [C++20]
     template <typename T>
-    using remove_cv_reference_t =
-            typename std::remove_cv<typename std::remove_reference<T>::type>::type;
+    void setWidth(T v) {
+        width = clamp<int32_t>(v);
+    }
+
+    template <typename T>
+    void setHeight(T v) {
+        height = clamp<int32_t>(v);
+    }
+
+    void set(Size size) { *this = size; }
+
+    template <typename T>
+    void set(T w, T h) {
+        set(Size(w, h));
+    }
+
+    // Sets the value to kInvalidSize
+    void makeInvalid();
+
+    // Sets the value to kEmptySize
+    void clear();
+
+    // TODO: Replace with std::remove_cvref_t in C++20.
+    template <typename T>
+    using remove_cvref_t = std::remove_cv_t<std::remove_reference_t<T>>;
 
     // Takes a value of type FromType, and ensures it can be represented as a value of type ToType,
     // clamping the input value to the output range if necessary.
     template <typename ToType, typename FromType>
-    static Size::remove_cv_reference_t<ToType>
-    clamp(typename std::enable_if<
-            std::numeric_limits<Size::remove_cv_reference_t<ToType>>::is_specialized &&
-                    std::numeric_limits<Size::remove_cv_reference_t<FromType>>::is_specialized,
-            FromType>::type v) {
-        using BareToType = remove_cv_reference_t<ToType>;
-        using BareFromType = remove_cv_reference_t<FromType>;
-        static constexpr auto toHighest = std::numeric_limits<BareToType>::max();
-        static constexpr auto toLowest = std::numeric_limits<BareToType>::lowest();
-        static constexpr auto fromHighest = std::numeric_limits<BareFromType>::max();
-        static constexpr auto fromLowest = std::numeric_limits<BareFromType>::lowest();
+    static constexpr remove_cvref_t<ToType> clamp(FromType v) {
+        using BareToType = remove_cvref_t<ToType>;
+        using ToLimits = std::numeric_limits<BareToType>;
+
+        using BareFromType = remove_cvref_t<FromType>;
+        using FromLimits = std::numeric_limits<BareFromType>;
+
+        static_assert(ToLimits::is_specialized && FromLimits::is_specialized);
+
+        constexpr auto toHighest = ToLimits::max();
+        constexpr auto toLowest = ToLimits::lowest();
+        constexpr auto fromHighest = FromLimits::max();
+        constexpr auto fromLowest = FromLimits::lowest();
 
         // Get the closest representation of [toLowest, toHighest] in type
         // FromType to use to clamp the input value before conversion.
@@ -127,37 +94,35 @@
         // std::common_type<...> is used to get a value-preserving type for the
         // top end of the range.
         using CommonHighestType = std::common_type_t<BareToType, BareFromType>;
+        using CommonLimits = std::numeric_limits<CommonHighestType>;
 
         // std::make_signed<std::common_type<...>> is used to get a
         // value-preserving type for the bottom end of the range, except this is
         // a bit trickier for non-integer types like float.
-        using CommonLowestType =
-                std::conditional_t<std::numeric_limits<CommonHighestType>::is_integer,
-                                   std::make_signed_t<std::conditional_t<
-                                           std::numeric_limits<CommonHighestType>::is_integer,
-                                           CommonHighestType, int /* not used */>>,
-                                   CommonHighestType>;
+        using CommonLowestType = std::conditional_t<
+                CommonLimits::is_integer,
+                std::make_signed_t<std::conditional_t<CommonLimits::is_integer, CommonHighestType,
+                                                      int /* not used */>>,
+                CommonHighestType>;
 
         // We can then compute the clamp range in a way that can be later
         // trivially converted to either the 'from' or 'to' types, and be
-        // representabile in either.
-        static constexpr auto commonClampHighest =
-                std::min(static_cast<CommonHighestType>(fromHighest),
-                         static_cast<CommonHighestType>(toHighest));
-        static constexpr auto commonClampLowest =
-                std::max(static_cast<CommonLowestType>(fromLowest),
-                         static_cast<CommonLowestType>(toLowest));
+        // representable in either.
+        constexpr auto commonClampHighest = std::min(static_cast<CommonHighestType>(fromHighest),
+                                                     static_cast<CommonHighestType>(toHighest));
+        constexpr auto commonClampLowest = std::max(static_cast<CommonLowestType>(fromLowest),
+                                                    static_cast<CommonLowestType>(toLowest));
 
-        static constexpr auto fromClampHighest = static_cast<BareFromType>(commonClampHighest);
-        static constexpr auto fromClampLowest = static_cast<BareFromType>(commonClampLowest);
+        constexpr auto fromClampHighest = static_cast<BareFromType>(commonClampHighest);
+        constexpr auto fromClampLowest = static_cast<BareFromType>(commonClampLowest);
 
         // A clamp is needed only if the range we are clamping to is not the
         // same as the range of the input.
-        static constexpr bool isClampNeeded =
+        constexpr bool isClampNeeded =
                 (fromLowest != fromClampLowest) || (fromHighest != fromClampHighest);
 
         // If a clamp is not needed, the conversion is just a trivial cast.
-        if (!isClampNeeded) {
+        if constexpr (!isClampNeeded) {
             return static_cast<BareToType>(v);
         }
 
@@ -170,34 +135,46 @@
 
         // Otherwise clamping is done by using the already computed endpoints
         // for each type.
-        return (v <= fromClampLowest)
-                ? toClampLowest
-                : ((v >= fromClampHighest) ? toClampHighest : static_cast<BareToType>(v));
+        if (v <= fromClampLowest) {
+            return toClampLowest;
+        }
+
+        return v >= fromClampHighest ? toClampHighest : static_cast<BareToType>(v);
     }
 };
 
-// ------------------------------------------------------------------------
-// Comparisons
-// ------------------------------------------------------------------------
+constexpr Size kInvalidSize;
+constexpr Size kEmptySize{0, 0};
 
-inline bool operator==(const Size& lhs, const Size& rhs) {
+inline void Size::makeInvalid() {
+    set(kInvalidSize);
+}
+
+inline void Size::clear() {
+    set(kEmptySize);
+}
+
+inline bool operator==(Size lhs, Size rhs) {
     return lhs.width == rhs.width && lhs.height == rhs.height;
 }
 
-inline bool operator!=(const Size& lhs, const Size& rhs) {
-    return !operator==(lhs, rhs);
+inline bool Size::isEmpty() const {
+    return *this == kEmptySize;
 }
 
-inline bool operator<(const Size& lhs, const Size& rhs) {
+inline bool operator!=(Size lhs, Size rhs) {
+    return !(lhs == rhs);
+}
+
+inline bool operator<(Size lhs, Size rhs) {
     // Orders by increasing width, then height.
     if (lhs.width != rhs.width) return lhs.width < rhs.width;
     return lhs.height < rhs.height;
 }
 
 // Defining PrintTo helps with Google Tests.
-static inline void PrintTo(const Size& size, ::std::ostream* os) {
-    *os << "Size(" << size.width << ", " << size.height << ")";
+inline void PrintTo(Size size, std::ostream* stream) {
+    *stream << "Size(" << size.width << ", " << size.height << ')';
 }
 
-} // namespace ui
-} // namespace android
+} // namespace android::ui
diff --git a/libs/ui/tests/DisplayId_test.cpp b/libs/ui/tests/DisplayId_test.cpp
index 1d908b8..8ddee7e 100644
--- a/libs/ui/tests/DisplayId_test.cpp
+++ b/libs/ui/tests/DisplayId_test.cpp
@@ -32,6 +32,9 @@
     EXPECT_FALSE(GpuVirtualDisplayId::tryCast(id));
     EXPECT_TRUE(PhysicalDisplayId::tryCast(id));
     EXPECT_TRUE(HalDisplayId::tryCast(id));
+
+    EXPECT_EQ(id, DisplayId::fromValue(id.value));
+    EXPECT_EQ(id, DisplayId::fromValue<PhysicalDisplayId>(id.value));
 }
 
 TEST(DisplayIdTest, createPhysicalIdFromPort) {
@@ -43,6 +46,9 @@
     EXPECT_FALSE(GpuVirtualDisplayId::tryCast(id));
     EXPECT_TRUE(PhysicalDisplayId::tryCast(id));
     EXPECT_TRUE(HalDisplayId::tryCast(id));
+
+    EXPECT_EQ(id, DisplayId::fromValue(id.value));
+    EXPECT_EQ(id, DisplayId::fromValue<PhysicalDisplayId>(id.value));
 }
 
 TEST(DisplayIdTest, createGpuVirtualId) {
@@ -52,6 +58,9 @@
     EXPECT_FALSE(HalVirtualDisplayId::tryCast(id));
     EXPECT_FALSE(PhysicalDisplayId::tryCast(id));
     EXPECT_FALSE(HalDisplayId::tryCast(id));
+
+    EXPECT_EQ(id, DisplayId::fromValue(id.value));
+    EXPECT_EQ(id, DisplayId::fromValue<GpuVirtualDisplayId>(id.value));
 }
 
 TEST(DisplayIdTest, createHalVirtualId) {
@@ -61,6 +70,9 @@
     EXPECT_FALSE(GpuVirtualDisplayId::tryCast(id));
     EXPECT_FALSE(PhysicalDisplayId::tryCast(id));
     EXPECT_TRUE(HalDisplayId::tryCast(id));
+
+    EXPECT_EQ(id, DisplayId::fromValue(id.value));
+    EXPECT_EQ(id, DisplayId::fromValue<HalVirtualDisplayId>(id.value));
 }
 
 } // namespace android::ui
diff --git a/libs/ui/tests/Size_test.cpp b/libs/ui/tests/Size_test.cpp
index 5f75aea..acef47f 100644
--- a/libs/ui/tests/Size_test.cpp
+++ b/libs/ui/tests/Size_test.cpp
@@ -93,9 +93,8 @@
     }
 
     {
-        const auto& s = Size::INVALID;
-        EXPECT_FALSE(s.isValid());
-        EXPECT_FALSE(s.isEmpty());
+        EXPECT_FALSE(kInvalidSize.isValid());
+        EXPECT_FALSE(kInvalidSize.isEmpty());
     }
 
     {
@@ -112,9 +111,8 @@
     }
 
     {
-        const auto& s = Size::EMPTY;
-        EXPECT_TRUE(s.isValid());
-        EXPECT_TRUE(s.isEmpty());
+        EXPECT_TRUE(kEmptySize.isValid());
+        EXPECT_TRUE(kEmptySize.isEmpty());
     }
 
     {
diff --git a/services/automotive/display/AutomotiveDisplayProxyService.cpp b/services/automotive/display/AutomotiveDisplayProxyService.cpp
index d6fc695..d205231 100644
--- a/services/automotive/display/AutomotiveDisplayProxyService.cpp
+++ b/services/automotive/display/AutomotiveDisplayProxyService.cpp
@@ -34,7 +34,10 @@
     sp<IBinder> displayToken = nullptr;
     sp<SurfaceControl> surfaceControl = nullptr;
     if (it == mDisplays.end()) {
-        displayToken = SurfaceComposerClient::getPhysicalDisplayToken(PhysicalDisplayId(id));
+        if (const auto displayId = DisplayId::fromValue<PhysicalDisplayId>(id)) {
+            displayToken = SurfaceComposerClient::getPhysicalDisplayToken(*displayId);
+        }
+
         if (displayToken == nullptr) {
             ALOGE("Given display id, 0x%lX, is invalid.", (unsigned long)id);
             return nullptr;
@@ -157,7 +160,11 @@
     HwDisplayConfig activeConfig;
     HwDisplayState  activeState;
 
-    auto displayToken = SurfaceComposerClient::getPhysicalDisplayToken(PhysicalDisplayId(id));
+    sp<IBinder> displayToken;
+    if (const auto displayId = DisplayId::fromValue<PhysicalDisplayId>(id)) {
+        displayToken = SurfaceComposerClient::getPhysicalDisplayToken(*displayId);
+    }
+
     if (displayToken == nullptr) {
         ALOGE("Given display id, 0x%lX, is invalid.", (unsigned long)id);
     } else {
diff --git a/services/inputflinger/InputManager.cpp b/services/inputflinger/InputManager.cpp
index a50e5c7..e81dcfe 100644
--- a/services/inputflinger/InputManager.cpp
+++ b/services/inputflinger/InputManager.cpp
@@ -31,6 +31,10 @@
 
 namespace android {
 
+using gui::FocusRequest;
+using gui::WindowInfo;
+using gui::WindowInfoHandle;
+
 static int32_t exceptionCodeFromStatusT(status_t status) {
     switch (status) {
         case OK:
@@ -110,9 +114,9 @@
     return mDispatcher;
 }
 
-class BinderWindowHandle : public InputWindowHandle {
+class BinderWindowHandle : public WindowInfoHandle {
 public:
-    BinderWindowHandle(const InputWindowInfo& info) { mInfo = info; }
+    BinderWindowHandle(const WindowInfo& info) { mInfo = info; }
 
     bool updateInfo() override {
         return true;
@@ -120,13 +124,13 @@
 };
 
 binder::Status InputManager::setInputWindows(
-        const std::vector<InputWindowInfo>& infos,
+        const std::vector<WindowInfo>& infos,
         const sp<ISetInputWindowsListener>& setInputWindowsListener) {
-    std::unordered_map<int32_t, std::vector<sp<InputWindowHandle>>> handlesPerDisplay;
+    std::unordered_map<int32_t, std::vector<sp<WindowInfoHandle>>> handlesPerDisplay;
 
-    std::vector<sp<InputWindowHandle>> handles;
+    std::vector<sp<WindowInfoHandle>> handles;
     for (const auto& info : infos) {
-        handlesPerDisplay.emplace(info.displayId, std::vector<sp<InputWindowHandle>>());
+        handlesPerDisplay.emplace(info.displayId, std::vector<sp<WindowInfoHandle>>());
         handlesPerDisplay[info.displayId].push_back(new BinderWindowHandle(info));
     }
     mDispatcher->setInputWindows(handlesPerDisplay);
diff --git a/services/inputflinger/InputManager.h b/services/inputflinger/InputManager.h
index 49bea13..035a9a3 100644
--- a/services/inputflinger/InputManager.h
+++ b/services/inputflinger/InputManager.h
@@ -105,12 +105,12 @@
 
     status_t dump(int fd, const Vector<String16>& args) override;
     binder::Status setInputWindows(
-            const std::vector<InputWindowInfo>& handles,
+            const std::vector<gui::WindowInfo>& handles,
             const sp<ISetInputWindowsListener>& setInputWindowsListener) override;
 
     binder::Status createInputChannel(const std::string& name, InputChannel* outChannel) override;
     binder::Status removeInputChannel(const sp<IBinder>& connectionToken) override;
-    binder::Status setFocusedWindow(const FocusRequest&) override;
+    binder::Status setFocusedWindow(const gui::FocusRequest&) override;
 
 private:
     sp<InputReaderInterface> mReader;
diff --git a/services/inputflinger/InputReaderBase.cpp b/services/inputflinger/InputReaderBase.cpp
index 9cc777d..f26a9a9 100644
--- a/services/inputflinger/InputReaderBase.cpp
+++ b/services/inputflinger/InputReaderBase.cpp
@@ -19,9 +19,9 @@
 //#define LOG_NDEBUG 0
 
 #include "InputReaderBase.h"
+#include <ftl/NamedEnum.h>
 #include "input/DisplayViewport.h"
 #include "input/Input.h"
-#include "input/NamedEnum.h"
 
 #include <android/log.h>
 #include <android-base/stringprintf.h>
diff --git a/services/inputflinger/benchmarks/InputDispatcher_benchmarks.cpp b/services/inputflinger/benchmarks/InputDispatcher_benchmarks.cpp
index bc77b8a..55deec4 100644
--- a/services/inputflinger/benchmarks/InputDispatcher_benchmarks.cpp
+++ b/services/inputflinger/benchmarks/InputDispatcher_benchmarks.cpp
@@ -18,8 +18,11 @@
 
 #include <android/os/IInputConstants.h>
 #include <binder/Binder.h>
+#include <gui/constants.h>
 #include "../dispatcher/InputDispatcher.h"
 
+using android::gui::WindowInfo;
+using android::gui::WindowInfoHandle;
 using android::os::IInputConstants;
 using android::os::InputEventInjectionResult;
 using android::os::InputEventInjectionSync;
@@ -173,7 +176,7 @@
     PreallocatedInputEventFactory mEventFactory;
 };
 
-class FakeWindowHandle : public InputWindowHandle, public FakeInputReceiver {
+class FakeWindowHandle : public WindowInfoHandle, public FakeInputReceiver {
 public:
     static const int32_t WIDTH = 200;
     static const int32_t HEIGHT = 200;
@@ -188,7 +191,7 @@
     virtual bool updateInfo() override {
         mInfo.token = mClientChannel->getConnectionToken();
         mInfo.name = "FakeWindowHandle";
-        mInfo.type = InputWindowInfo::Type::APPLICATION;
+        mInfo.type = WindowInfo::Type::APPLICATION;
         mInfo.dispatchingTimeout = DISPATCHING_TIMEOUT;
         mInfo.frameLeft = mFrame.left;
         mInfo.frameTop = mFrame.top;
@@ -234,8 +237,8 @@
                      /* edgeFlags */ 0, AMETA_NONE, /* buttonState */ 0, MotionClassification::NONE,
                      identityTransform, /* xPrecision */ 0,
                      /* yPrecision */ 0, AMOTION_EVENT_INVALID_CURSOR_POSITION,
-                     AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_DISPLAY_SIZE,
-                     AMOTION_EVENT_INVALID_DISPLAY_SIZE, currentTime, currentTime,
+                     AMOTION_EVENT_INVALID_CURSOR_POSITION, INVALID_DISPLAY_SIZE,
+                     INVALID_DISPLAY_SIZE, currentTime, currentTime,
                      /*pointerCount*/ 1, pointerProperties, pointerCoords);
     return event;
 }
diff --git a/services/inputflinger/dispatcher/DragState.cpp b/services/inputflinger/dispatcher/DragState.cpp
index 2e2df43..e1844a4 100644
--- a/services/inputflinger/dispatcher/DragState.cpp
+++ b/services/inputflinger/dispatcher/DragState.cpp
@@ -16,9 +16,7 @@
 
 #include "DragState.h"
 #include <android-base/stringprintf.h>
-#include <input/InputWindow.h>
 
-using android::InputWindowHandle;
 using android::base::StringPrintf;
 
 namespace android::inputdispatcher {
diff --git a/services/inputflinger/dispatcher/DragState.h b/services/inputflinger/dispatcher/DragState.h
index 06453d8..b3c5709 100644
--- a/services/inputflinger/dispatcher/DragState.h
+++ b/services/inputflinger/dispatcher/DragState.h
@@ -17,22 +17,22 @@
 #ifndef _UI_INPUT_INPUTDISPATCHER_DRAGSTATE_H
 #define _UI_INPUT_INPUTDISPATCHER_DRAGSTATE_H
 
+#include <gui/WindowInfo.h>
 #include <utils/RefBase.h>
 #include <string>
 
 namespace android {
 
-class InputWindowHandle;
-
 namespace inputdispatcher {
+
 struct DragState {
-    DragState(const sp<android::InputWindowHandle>& windowHandle) : dragWindow(windowHandle) {}
+    DragState(const sp<android::gui::WindowInfoHandle>& windowHandle) : dragWindow(windowHandle) {}
     void dump(std::string& dump, const char* prefix = "");
 
     // The window being dragged.
-    const sp<InputWindowHandle> dragWindow;
+    const sp<android::gui::WindowInfoHandle> dragWindow;
     // The last drag hover window which could receive the drag event.
-    sp<InputWindowHandle> dragHoverWindowHandle;
+    sp<android::gui::WindowInfoHandle> dragHoverWindowHandle;
     // Indicates the if received first event to check for button state.
     bool isStartDrag = false;
     // Indicate if the stylus button is down at the start of the drag.
diff --git a/services/inputflinger/dispatcher/Entry.cpp b/services/inputflinger/dispatcher/Entry.cpp
index 881024f..8d6bd8a 100644
--- a/services/inputflinger/dispatcher/Entry.cpp
+++ b/services/inputflinger/dispatcher/Entry.cpp
@@ -176,10 +176,11 @@
     }
     return StringPrintf("KeyEvent(deviceId=%d, eventTime=%" PRIu64
                         ", source=0x%08x, displayId=%" PRId32 ", action=%s, "
-                        "flags=0x%08x, keyCode=%d, scanCode=%d, metaState=0x%08x, "
+                        "flags=0x%08x, keyCode=%s(%d), scanCode=%d, metaState=0x%08x, "
                         "repeatCount=%d), policyFlags=0x%08x",
                         deviceId, eventTime, source, displayId, KeyEvent::actionToString(action),
-                        flags, keyCode, scanCode, metaState, repeatCount, policyFlags);
+                        flags, KeyEvent::getLabel(keyCode), keyCode, scanCode, metaState,
+                        repeatCount, policyFlags);
 }
 
 void KeyEntry::recycle() {
diff --git a/services/inputflinger/dispatcher/Entry.h b/services/inputflinger/dispatcher/Entry.h
index ebbd8e9..89d7659 100644
--- a/services/inputflinger/dispatcher/Entry.h
+++ b/services/inputflinger/dispatcher/Entry.h
@@ -20,8 +20,8 @@
 #include "InjectionState.h"
 #include "InputTarget.h"
 
+#include <gui/InputApplication.h>
 #include <input/Input.h>
-#include <input/InputApplication.h>
 #include <stdint.h>
 #include <utils/Timers.h>
 #include <functional>
diff --git a/services/inputflinger/dispatcher/FocusResolver.cpp b/services/inputflinger/dispatcher/FocusResolver.cpp
index fb19435..4a75773 100644
--- a/services/inputflinger/dispatcher/FocusResolver.cpp
+++ b/services/inputflinger/dispatcher/FocusResolver.cpp
@@ -27,12 +27,15 @@
 
 #include <android-base/stringprintf.h>
 #include <binder/Binder.h>
-#include <input/InputWindow.h>
-#include <input/NamedEnum.h>
+#include <ftl/NamedEnum.h>
+#include <gui/WindowInfo.h>
 #include <log/log.h>
 
 #include "FocusResolver.h"
 
+using android::gui::FocusRequest;
+using android::gui::WindowInfoHandle;
+
 namespace android::inputdispatcher {
 
 sp<IBinder> FocusResolver::getFocusedWindowToken(int32_t displayId) const {
@@ -52,7 +55,7 @@
  * we will check if the previous focus request is eligible to receive focus.
  */
 std::optional<FocusResolver::FocusChanges> FocusResolver::setInputWindows(
-        int32_t displayId, const std::vector<sp<InputWindowHandle>>& windows) {
+        int32_t displayId, const std::vector<sp<WindowInfoHandle>>& windows) {
     std::string removeFocusReason;
 
     // Check if the currently focused window is still focusable.
@@ -87,7 +90,7 @@
 }
 
 std::optional<FocusResolver::FocusChanges> FocusResolver::setFocusedWindow(
-        const FocusRequest& request, const std::vector<sp<InputWindowHandle>>& windows) {
+        const FocusRequest& request, const std::vector<sp<WindowInfoHandle>>& windows) {
     const int32_t displayId = request.displayId;
     const sp<IBinder> currentFocus = getFocusedWindowToken(displayId);
     if (currentFocus == request.token) {
@@ -136,11 +139,11 @@
 }
 
 FocusResolver::Focusability FocusResolver::isTokenFocusable(
-        const sp<IBinder>& token, const std::vector<sp<InputWindowHandle>>& windows) {
+        const sp<IBinder>& token, const std::vector<sp<WindowInfoHandle>>& windows) {
     bool allWindowsAreFocusable = true;
     bool visibleWindowFound = false;
     bool windowFound = false;
-    for (const sp<InputWindowHandle>& window : windows) {
+    for (const sp<WindowInfoHandle>& window : windows) {
         if (window->getToken() != token) {
             continue;
         }
diff --git a/services/inputflinger/dispatcher/FocusResolver.h b/services/inputflinger/dispatcher/FocusResolver.h
index afe16b3..1d6cd9a 100644
--- a/services/inputflinger/dispatcher/FocusResolver.h
+++ b/services/inputflinger/dispatcher/FocusResolver.h
@@ -20,9 +20,9 @@
 #include <optional>
 #include <unordered_map>
 
-#include <android/FocusRequest.h>
+#include <android/gui/FocusRequest.h>
 #include <binder/Binder.h>
-#include <input/InputWindow.h>
+#include <gui/WindowInfo.h>
 
 namespace android::inputdispatcher {
 
@@ -58,9 +58,10 @@
         std::string reason;
     };
     std::optional<FocusResolver::FocusChanges> setInputWindows(
-            int32_t displayId, const std::vector<sp<InputWindowHandle>>& windows);
+            int32_t displayId, const std::vector<sp<android::gui::WindowInfoHandle>>& windows);
     std::optional<FocusResolver::FocusChanges> setFocusedWindow(
-            const FocusRequest& request, const std::vector<sp<InputWindowHandle>>& windows);
+            const android::gui::FocusRequest& request,
+            const std::vector<sp<android::gui::WindowInfoHandle>>& windows);
 
     // Display has been removed from the system, clean up old references.
     void displayRemoved(int32_t displayId);
@@ -87,8 +88,9 @@
     // we expect the focusability of the windows to match since its hard to reason why one window
     // can receive focus events and the other cannot when both are backed by the same input channel.
     //
-    static Focusability isTokenFocusable(const sp<IBinder>& token,
-                                         const std::vector<sp<InputWindowHandle>>& windows);
+    static Focusability isTokenFocusable(
+            const sp<IBinder>& token,
+            const std::vector<sp<android::gui::WindowInfoHandle>>& windows);
 
     // Focus tracking for keys, trackball, etc. A window token can be associated with one or
     // more InputWindowHandles. If a window is mirrored, the window and its mirror will share
@@ -99,7 +101,7 @@
 
     // This map will store the focus request per display. When the input window handles are updated,
     // the current request will be checked to see if it can be processed at that time.
-    std::unordered_map<int32_t /* displayId */, FocusRequest> mFocusRequestByDisplay;
+    std::unordered_map<int32_t /* displayId */, android::gui::FocusRequest> mFocusRequestByDisplay;
 
     // Last reason for not granting a focus request. This is used to add more debug information
     // in the event logs.
@@ -108,7 +110,7 @@
     std::optional<FocusResolver::FocusChanges> updateFocusedWindow(
             int32_t displayId, const std::string& reason, const sp<IBinder>& token,
             const std::string& tokenName = "");
-    std::optional<FocusRequest> getFocusRequest(int32_t displayId);
+    std::optional<android::gui::FocusRequest> getFocusRequest(int32_t displayId);
 };
 
 } // namespace android::inputdispatcher
\ No newline at end of file
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp
index 15c810d..cecfb33 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.cpp
+++ b/services/inputflinger/dispatcher/InputDispatcher.cpp
@@ -56,7 +56,6 @@
 #include <binder/IServiceManager.h>
 #include <com/android/internal/compat/IPlatformCompatNative.h>
 #include <input/InputDevice.h>
-#include <input/InputWindow.h>
 #include <log/log.h>
 #include <log/log_event_list.h>
 #include <powermanager/PowerManager.h>
@@ -82,6 +81,10 @@
 using android::base::HwTimeoutMultiplier;
 using android::base::Result;
 using android::base::StringPrintf;
+using android::gui::FocusRequest;
+using android::gui::TouchOcclusionMode;
+using android::gui::WindowInfo;
+using android::gui::WindowInfoHandle;
 using android::os::BlockUntrustedTouchesMode;
 using android::os::IInputConstants;
 using android::os::InputEventInjectionResult;
@@ -292,7 +295,7 @@
     return it != map.end() ? it->second : V{};
 }
 
-static bool haveSameToken(const sp<InputWindowHandle>& first, const sp<InputWindowHandle>& second) {
+static bool haveSameToken(const sp<WindowInfoHandle>& first, const sp<WindowInfoHandle>& second) {
     if (first == second) {
         return true;
     }
@@ -304,7 +307,7 @@
     return first->getToken() == second->getToken();
 }
 
-static bool haveSameApplicationToken(const InputWindowInfo* first, const InputWindowInfo* second) {
+static bool haveSameApplicationToken(const WindowInfo* first, const WindowInfo* second) {
     if (first == nullptr || second == nullptr) {
         return false;
     }
@@ -626,7 +629,7 @@
         return; // The focused application has changed.
     }
 
-    const sp<InputWindowHandle>& focusedWindowHandle =
+    const sp<WindowInfoHandle>& focusedWindowHandle =
             getFocusedWindowHandleLocked(mAwaitedApplicationDisplayId);
     if (focusedWindowHandle != nullptr) {
         return; // We now have a focused window. No need for ANR.
@@ -675,7 +678,7 @@
 }
 
 std::chrono::nanoseconds InputDispatcher::getDispatchingTimeoutLocked(const sp<IBinder>& token) {
-    sp<InputWindowHandle> window = getWindowHandleLocked(token);
+    sp<WindowInfoHandle> window = getWindowHandleLocked(token);
     if (window != nullptr) {
         return window->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT);
     }
@@ -887,7 +890,7 @@
                 motionEntry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
         int32_t y = static_cast<int32_t>(
                 motionEntry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
-        sp<InputWindowHandle> touchedWindowHandle =
+        sp<WindowInfoHandle> touchedWindowHandle =
                 findTouchedWindowAtLocked(displayId, x, y, nullptr);
         if (touchedWindowHandle != nullptr &&
             touchedWindowHandle->getApplicationToken() !=
@@ -900,8 +903,7 @@
         }
 
         // Alternatively, maybe there's a gesture monitor that could handle this event
-        std::vector<TouchedMonitor> gestureMonitors =
-                findTouchedGestureMonitorsLocked(displayId, {});
+        std::vector<TouchedMonitor> gestureMonitors = findTouchedGestureMonitorsLocked(displayId);
         for (TouchedMonitor& gestureMonitor : gestureMonitors) {
             sp<Connection> connection =
                     getConnectionLocked(gestureMonitor.monitor.inputChannel->getConnectionToken());
@@ -992,46 +994,34 @@
     }
 }
 
-sp<InputWindowHandle> InputDispatcher::findTouchedWindowAtLocked(int32_t displayId, int32_t x,
-                                                                 int32_t y, TouchState* touchState,
-                                                                 bool addOutsideTargets,
-                                                                 bool addPortalWindows,
-                                                                 bool ignoreDragWindow) {
-    if ((addPortalWindows || addOutsideTargets) && touchState == nullptr) {
-        LOG_ALWAYS_FATAL(
-                "Must provide a valid touch state if adding portal windows or outside targets");
+sp<WindowInfoHandle> InputDispatcher::findTouchedWindowAtLocked(int32_t displayId, int32_t x,
+                                                                int32_t y, TouchState* touchState,
+                                                                bool addOutsideTargets,
+                                                                bool ignoreDragWindow) {
+    if (addOutsideTargets && touchState == nullptr) {
+        LOG_ALWAYS_FATAL("Must provide a valid touch state if adding outside targets");
     }
     // Traverse windows from front to back to find touched window.
-    const std::vector<sp<InputWindowHandle>>& windowHandles = getWindowHandlesLocked(displayId);
-    for (const sp<InputWindowHandle>& windowHandle : windowHandles) {
+    const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
+    for (const sp<WindowInfoHandle>& windowHandle : windowHandles) {
         if (ignoreDragWindow && haveSameToken(windowHandle, mDragState->dragWindow)) {
             continue;
         }
-        const InputWindowInfo* windowInfo = windowHandle->getInfo();
+        const WindowInfo* windowInfo = windowHandle->getInfo();
         if (windowInfo->displayId == displayId) {
             auto flags = windowInfo->flags;
 
             if (windowInfo->visible) {
-                if (!flags.test(InputWindowInfo::Flag::NOT_TOUCHABLE)) {
-                    bool isTouchModal = !flags.test(InputWindowInfo::Flag::NOT_FOCUSABLE) &&
-                            !flags.test(InputWindowInfo::Flag::NOT_TOUCH_MODAL);
+                if (!flags.test(WindowInfo::Flag::NOT_TOUCHABLE)) {
+                    bool isTouchModal = !flags.test(WindowInfo::Flag::NOT_FOCUSABLE) &&
+                            !flags.test(WindowInfo::Flag::NOT_TOUCH_MODAL);
                     if (isTouchModal || windowInfo->touchableRegionContainsPoint(x, y)) {
-                        int32_t portalToDisplayId = windowInfo->portalToDisplayId;
-                        if (portalToDisplayId != ADISPLAY_ID_NONE &&
-                            portalToDisplayId != displayId) {
-                            if (addPortalWindows) {
-                                // For the monitoring channels of the display.
-                                touchState->addPortalWindow(windowHandle);
-                            }
-                            return findTouchedWindowAtLocked(portalToDisplayId, x, y, touchState,
-                                                             addOutsideTargets, addPortalWindows);
-                        }
                         // Found window.
                         return windowHandle;
                     }
                 }
 
-                if (addOutsideTargets && flags.test(InputWindowInfo::Flag::WATCH_OUTSIDE_TOUCH)) {
+                if (addOutsideTargets && flags.test(WindowInfo::Flag::WATCH_OUTSIDE_TOUCH)) {
                     touchState->addOrUpdateWindow(windowHandle,
                                                   InputTarget::FLAG_DISPATCH_AS_OUTSIDE,
                                                   BitSet32(0));
@@ -1043,17 +1033,11 @@
 }
 
 std::vector<TouchedMonitor> InputDispatcher::findTouchedGestureMonitorsLocked(
-        int32_t displayId, const std::vector<sp<InputWindowHandle>>& portalWindows) const {
+        int32_t displayId) const {
     std::vector<TouchedMonitor> touchedMonitors;
 
     std::vector<Monitor> monitors = getValueByKey(mGestureMonitorsByDisplay, displayId);
     addGestureMonitors(monitors, touchedMonitors);
-    for (const sp<InputWindowHandle>& portalWindow : portalWindows) {
-        const InputWindowInfo* windowInfo = portalWindow->getInfo();
-        monitors = getValueByKey(mGestureMonitorsByDisplay, windowInfo->portalToDisplayId);
-        addGestureMonitors(monitors, touchedMonitors, -windowInfo->frameLeft,
-                           -windowInfo->frameTop);
-    }
     return touchedMonitors;
 }
 
@@ -1589,23 +1573,6 @@
     // Add monitor channels from event's or focused display.
     addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(*entry));
 
-    if (isPointerEvent) {
-        std::unordered_map<int32_t, TouchState>::iterator it =
-                mTouchStatesByDisplay.find(entry->displayId);
-        if (it != mTouchStatesByDisplay.end()) {
-            const TouchState& state = it->second;
-            if (!state.portalWindows.empty()) {
-                // The event has gone through these portal windows, so we add monitoring targets of
-                // the corresponding displays as well.
-                for (size_t i = 0; i < state.portalWindows.size(); i++) {
-                    const InputWindowInfo* windowInfo = state.portalWindows[i]->getInfo();
-                    addGlobalMonitoringTargetsLocked(inputTargets, windowInfo->portalToDisplayId,
-                                                     -windowInfo->frameLeft, -windowInfo->frameTop);
-                }
-            }
-        }
-    }
-
     // Dispatch the motion.
     if (conflictingPointerActions) {
         CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
@@ -1616,7 +1583,7 @@
     return true;
 }
 
-void InputDispatcher::enqueueDragEventLocked(const sp<InputWindowHandle>& windowHandle,
+void InputDispatcher::enqueueDragEventLocked(const sp<WindowInfoHandle>& windowHandle,
                                              bool isExiting, const MotionEntry& motionEntry) {
     // If the window needs enqueue a drag event, the pointerCount should be 1 and the action should
     // be AMOTION_EVENT_ACTION_MOVE, that could guarantee the first pointer is always valid.
@@ -1796,7 +1763,7 @@
     std::string reason;
 
     int32_t displayId = getTargetDisplayId(entry);
-    sp<InputWindowHandle> focusedWindowHandle = getFocusedWindowHandleLocked(displayId);
+    sp<WindowInfoHandle> focusedWindowHandle = getFocusedWindowHandleLocked(displayId);
     std::shared_ptr<InputApplicationHandle> focusedApplicationHandle =
             getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
 
@@ -1923,8 +1890,8 @@
     // Update the touch state as needed based on the properties of the touch event.
     InputEventInjectionResult injectionResult = InputEventInjectionResult::PENDING;
     InjectionPermission injectionPermission = INJECTION_PERMISSION_UNKNOWN;
-    sp<InputWindowHandle> newHoverWindowHandle(mLastHoverWindowHandle);
-    sp<InputWindowHandle> newTouchedWindowHandle;
+    sp<WindowInfoHandle> newHoverWindowHandle(mLastHoverWindowHandle);
+    sp<WindowInfoHandle> newTouchedWindowHandle;
 
     // Copy current touch state into tempTouchState.
     // This state will be used to update mTouchStatesByDisplay at the end of this function.
@@ -1993,12 +1960,11 @@
             y = int32_t(entry.pointerCoords[pointerIndex].getAxisValue(AMOTION_EVENT_AXIS_Y));
         }
         bool isDown = maskedAction == AMOTION_EVENT_ACTION_DOWN;
-        newTouchedWindowHandle =
-                findTouchedWindowAtLocked(displayId, x, y, &tempTouchState,
-                                          isDown /*addOutsideTargets*/, true /*addPortalWindows*/);
+        newTouchedWindowHandle = findTouchedWindowAtLocked(displayId, x, y, &tempTouchState,
+                                                           isDown /*addOutsideTargets*/);
 
         std::vector<TouchedMonitor> newGestureMonitors = isDown
-                ? findTouchedGestureMonitorsLocked(displayId, tempTouchState.portalWindows)
+                ? findTouchedGestureMonitorsLocked(displayId)
                 : std::vector<TouchedMonitor>{};
 
         // Figure out whether splitting will be allowed for this window.
@@ -2117,7 +2083,7 @@
             int32_t x = int32_t(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
             int32_t y = int32_t(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
 
-            sp<InputWindowHandle> oldTouchedWindowHandle =
+            sp<WindowInfoHandle> oldTouchedWindowHandle =
                     tempTouchState.getFirstForegroundWindowHandle();
             newTouchedWindowHandle = findTouchedWindowAtLocked(displayId, x, y, &tempTouchState);
             if (oldTouchedWindowHandle != newTouchedWindowHandle &&
@@ -2216,15 +2182,15 @@
     // Check whether windows listening for outside touches are owned by the same UID. If it is
     // set the policy flag that we will not reveal coordinate information to this window.
     if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
-        sp<InputWindowHandle> foregroundWindowHandle =
+        sp<WindowInfoHandle> foregroundWindowHandle =
                 tempTouchState.getFirstForegroundWindowHandle();
         if (foregroundWindowHandle) {
             const int32_t foregroundWindowUid = foregroundWindowHandle->getInfo()->ownerUid;
             for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
                 if (touchedWindow.targetFlags & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
-                    sp<InputWindowHandle> inputWindowHandle = touchedWindow.windowHandle;
-                    if (inputWindowHandle->getInfo()->ownerUid != foregroundWindowUid) {
-                        tempTouchState.addOrUpdateWindow(inputWindowHandle,
+                    sp<WindowInfoHandle> windowInfoHandle = touchedWindow.windowHandle;
+                    if (windowInfoHandle->getInfo()->ownerUid != foregroundWindowUid) {
+                        tempTouchState.addOrUpdateWindow(windowInfoHandle,
                                                          InputTarget::FLAG_ZERO_COORDS,
                                                          BitSet32(0));
                     }
@@ -2240,15 +2206,15 @@
     // engine only supports touch events.  We would need to add a mechanism similar
     // to View.onGenericMotionEvent to enable wallpapers to handle these events.
     if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
-        sp<InputWindowHandle> foregroundWindowHandle =
+        sp<WindowInfoHandle> foregroundWindowHandle =
                 tempTouchState.getFirstForegroundWindowHandle();
         if (foregroundWindowHandle && foregroundWindowHandle->getInfo()->hasWallpaper) {
-            const std::vector<sp<InputWindowHandle>>& windowHandles =
+            const std::vector<sp<WindowInfoHandle>>& windowHandles =
                     getWindowHandlesLocked(displayId);
-            for (const sp<InputWindowHandle>& windowHandle : windowHandles) {
-                const InputWindowInfo* info = windowHandle->getInfo();
+            for (const sp<WindowInfoHandle>& windowHandle : windowHandles) {
+                const WindowInfo* info = windowHandle->getInfo();
                 if (info->displayId == displayId &&
-                    windowHandle->getInfo()->type == InputWindowInfo::Type::WALLPAPER) {
+                    windowHandle->getInfo()->type == WindowInfo::Type::WALLPAPER) {
                     tempTouchState
                             .addOrUpdateWindow(windowHandle,
                                                InputTarget::FLAG_WINDOW_IS_OBSCURED |
@@ -2367,10 +2333,9 @@
 }
 
 void InputDispatcher::finishDragAndDrop(int32_t displayId, float x, float y) {
-    const sp<InputWindowHandle> dropWindow =
+    const sp<WindowInfoHandle> dropWindow =
             findTouchedWindowAtLocked(displayId, x, y, nullptr /*touchState*/,
-                                      false /*addOutsideTargets*/, false /*addPortalWindows*/,
-                                      true /*ignoreDragWindow*/);
+                                      false /*addOutsideTargets*/, true /*ignoreDragWindow*/);
     if (dropWindow) {
         vec2 local = dropWindow->getInfo()->transform.transform(x, y);
         notifyDropWindowLocked(dropWindow->getToken(), local.x, local.y);
@@ -2402,10 +2367,9 @@
             return;
         }
 
-        const sp<InputWindowHandle> hoverWindowHandle =
+        const sp<WindowInfoHandle> hoverWindowHandle =
                 findTouchedWindowAtLocked(entry.displayId, x, y, nullptr /*touchState*/,
-                                          false /*addOutsideTargets*/, false /*addPortalWindows*/,
-                                          true /*ignoreDragWindow*/);
+                                          false /*addOutsideTargets*/, true /*ignoreDragWindow*/);
         // enqueue drag exit if needed.
         if (hoverWindowHandle != mDragState->dragHoverWindowHandle &&
             !haveSameToken(hoverWindowHandle, mDragState->dragHoverWindowHandle)) {
@@ -2427,7 +2391,7 @@
     }
 }
 
-void InputDispatcher::addWindowTargetLocked(const sp<InputWindowHandle>& windowHandle,
+void InputDispatcher::addWindowTargetLocked(const sp<WindowInfoHandle>& windowHandle,
                                             int32_t targetFlags, BitSet32 pointerIds,
                                             std::vector<InputTarget>& inputTargets) {
     std::vector<InputTarget>::iterator it =
@@ -2437,7 +2401,7 @@
                                      windowHandle->getToken();
                          });
 
-    const InputWindowInfo* windowInfo = windowHandle->getInfo();
+    const WindowInfo* windowInfo = windowHandle->getInfo();
 
     if (it == inputTargets.end()) {
         InputTarget inputTarget;
@@ -2488,7 +2452,7 @@
     inputTargets.push_back(target);
 }
 
-bool InputDispatcher::checkInjectionPermission(const sp<InputWindowHandle>& windowHandle,
+bool InputDispatcher::checkInjectionPermission(const sp<WindowInfoHandle>& windowHandle,
                                                const InjectionState* injectionState) {
     if (injectionState &&
         (windowHandle == nullptr ||
@@ -2513,8 +2477,8 @@
  * another window handle. We only check a few preconditions. Actually
  * checking the bounds is left to the caller.
  */
-static bool canBeObscuredBy(const sp<InputWindowHandle>& windowHandle,
-                            const sp<InputWindowHandle>& otherHandle) {
+static bool canBeObscuredBy(const sp<WindowInfoHandle>& windowHandle,
+                            const sp<WindowInfoHandle>& otherHandle) {
     // Compare by token so cloned layers aren't counted
     if (haveSameToken(windowHandle, otherHandle)) {
         return false;
@@ -2523,8 +2487,7 @@
     auto otherInfo = otherHandle->getInfo();
     if (!otherInfo->visible) {
         return false;
-    } else if (otherInfo->alpha == 0 &&
-               otherInfo->flags.test(InputWindowInfo::Flag::NOT_TOUCHABLE)) {
+    } else if (otherInfo->alpha == 0 && otherInfo->flags.test(WindowInfo::Flag::NOT_TOUCHABLE)) {
         // Those act as if they were invisible, so we don't need to flag them.
         // We do want to potentially flag touchable windows even if they have 0
         // opacity, since they can consume touches and alter the effects of the
@@ -2562,20 +2525,20 @@
  * If neither of those is true, then it means the touch can be allowed.
  */
 InputDispatcher::TouchOcclusionInfo InputDispatcher::computeTouchOcclusionInfoLocked(
-        const sp<InputWindowHandle>& windowHandle, int32_t x, int32_t y) const {
-    const InputWindowInfo* windowInfo = windowHandle->getInfo();
+        const sp<WindowInfoHandle>& windowHandle, int32_t x, int32_t y) const {
+    const WindowInfo* windowInfo = windowHandle->getInfo();
     int32_t displayId = windowInfo->displayId;
-    const std::vector<sp<InputWindowHandle>>& windowHandles = getWindowHandlesLocked(displayId);
+    const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
     TouchOcclusionInfo info;
     info.hasBlockingOcclusion = false;
     info.obscuringOpacity = 0;
     info.obscuringUid = -1;
     std::map<int32_t, float> opacityByUid;
-    for (const sp<InputWindowHandle>& otherHandle : windowHandles) {
+    for (const sp<WindowInfoHandle>& otherHandle : windowHandles) {
         if (windowHandle == otherHandle) {
             break; // All future windows are below us. Exit early.
         }
-        const InputWindowInfo* otherInfo = otherHandle->getInfo();
+        const WindowInfo* otherInfo = otherHandle->getInfo();
         if (canBeObscuredBy(windowHandle, otherHandle) && otherInfo->frameContainsPoint(x, y) &&
             !haveSameApplicationToken(windowInfo, otherInfo)) {
             if (DEBUG_TOUCH_OCCLUSION) {
@@ -2614,7 +2577,7 @@
     return info;
 }
 
-std::string InputDispatcher::dumpWindowForTouchOcclusion(const InputWindowInfo* info,
+std::string InputDispatcher::dumpWindowForTouchOcclusion(const WindowInfo* info,
                                                          bool isTouchedWindow) const {
     return StringPrintf(INDENT2
                         "* %stype=%s, package=%s/%" PRId32 ", id=%" PRId32 ", mode=%s, alpha=%.2f, "
@@ -2648,15 +2611,15 @@
     return true;
 }
 
-bool InputDispatcher::isWindowObscuredAtPointLocked(const sp<InputWindowHandle>& windowHandle,
+bool InputDispatcher::isWindowObscuredAtPointLocked(const sp<WindowInfoHandle>& windowHandle,
                                                     int32_t x, int32_t y) const {
     int32_t displayId = windowHandle->getInfo()->displayId;
-    const std::vector<sp<InputWindowHandle>>& windowHandles = getWindowHandlesLocked(displayId);
-    for (const sp<InputWindowHandle>& otherHandle : windowHandles) {
+    const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
+    for (const sp<WindowInfoHandle>& otherHandle : windowHandles) {
         if (windowHandle == otherHandle) {
             break; // All future windows are below us. Exit early.
         }
-        const InputWindowInfo* otherInfo = otherHandle->getInfo();
+        const WindowInfo* otherInfo = otherHandle->getInfo();
         if (canBeObscuredBy(windowHandle, otherHandle) &&
             otherInfo->frameContainsPoint(x, y)) {
             return true;
@@ -2665,15 +2628,15 @@
     return false;
 }
 
-bool InputDispatcher::isWindowObscuredLocked(const sp<InputWindowHandle>& windowHandle) const {
+bool InputDispatcher::isWindowObscuredLocked(const sp<WindowInfoHandle>& windowHandle) const {
     int32_t displayId = windowHandle->getInfo()->displayId;
-    const std::vector<sp<InputWindowHandle>>& windowHandles = getWindowHandlesLocked(displayId);
-    const InputWindowInfo* windowInfo = windowHandle->getInfo();
-    for (const sp<InputWindowHandle>& otherHandle : windowHandles) {
+    const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
+    const WindowInfo* windowInfo = windowHandle->getInfo();
+    for (const sp<WindowInfoHandle>& otherHandle : windowHandles) {
         if (windowHandle == otherHandle) {
             break; // All future windows are below us. Exit early.
         }
-        const InputWindowInfo* otherInfo = otherHandle->getInfo();
+        const WindowInfo* otherInfo = otherHandle->getInfo();
         if (canBeObscuredBy(windowHandle, otherHandle) &&
             otherInfo->overlaps(windowInfo)) {
             return true;
@@ -2683,8 +2646,7 @@
 }
 
 std::string InputDispatcher::getApplicationWindowLabel(
-        const InputApplicationHandle* applicationHandle,
-        const sp<InputWindowHandle>& windowHandle) {
+        const InputApplicationHandle* applicationHandle, const sp<WindowInfoHandle>& windowHandle) {
     if (applicationHandle != nullptr) {
         if (windowHandle != nullptr) {
             return applicationHandle->getName() + " - " + windowHandle->getName();
@@ -2707,10 +2669,10 @@
         return;
     }
     int32_t displayId = getTargetDisplayId(eventEntry);
-    sp<InputWindowHandle> focusedWindowHandle = getFocusedWindowHandleLocked(displayId);
+    sp<WindowInfoHandle> focusedWindowHandle = getFocusedWindowHandleLocked(displayId);
     if (focusedWindowHandle != nullptr) {
-        const InputWindowInfo* info = focusedWindowHandle->getInfo();
-        if (info->inputFeatures.test(InputWindowInfo::Feature::DISABLE_USER_ACTIVITY)) {
+        const WindowInfo* info = focusedWindowHandle->getInfo();
+        if (info->inputFeatures.test(WindowInfo::Feature::DISABLE_USER_ACTIVITY)) {
 #if DEBUG_DISPATCH_CYCLE
             ALOGD("Not poking user activity: disabled by window '%s'.", info->name.c_str());
 #endif
@@ -3481,10 +3443,10 @@
 #endif
 
     InputTarget target;
-    sp<InputWindowHandle> windowHandle =
+    sp<WindowInfoHandle> windowHandle =
             getWindowHandleLocked(connection->inputChannel->getConnectionToken());
     if (windowHandle != nullptr) {
-        const InputWindowInfo* windowInfo = windowHandle->getInfo();
+        const WindowInfo* windowInfo = windowHandle->getInfo();
         target.setDefaultPointerTransform(windowInfo->transform);
         target.globalScaleFactor = windowInfo->globalScaleFactor;
     }
@@ -3548,10 +3510,10 @@
 #endif
 
     InputTarget target;
-    sp<InputWindowHandle> windowHandle =
+    sp<WindowInfoHandle> windowHandle =
             getWindowHandleLocked(connection->inputChannel->getConnectionToken());
     if (windowHandle != nullptr) {
-        const InputWindowInfo* windowInfo = windowHandle->getInfo();
+        const WindowInfo* windowInfo = windowHandle->getInfo();
         target.setDefaultPointerTransform(windowInfo->transform);
         target.globalScaleFactor = windowInfo->globalScaleFactor;
     }
@@ -3877,9 +3839,9 @@
                              args->action, args->actionButton, args->flags, args->edgeFlags,
                              args->metaState, args->buttonState, args->classification, transform,
                              args->xPrecision, args->yPrecision, args->xCursorPosition,
-                             args->yCursorPosition, AMOTION_EVENT_INVALID_DISPLAY_SIZE,
-                             AMOTION_EVENT_INVALID_DISPLAY_SIZE, args->downTime, args->eventTime,
-                             args->pointerCount, args->pointerProperties, args->pointerCoords);
+                             args->yCursorPosition, INVALID_DISPLAY_SIZE, INVALID_DISPLAY_SIZE,
+                             args->downTime, args->eventTime, args->pointerCount,
+                             args->pointerProperties, args->pointerCoords);
 
             policyFlags |= POLICY_FLAG_FILTERED;
             if (!mPolicy->filterInputEvent(&event, policyFlags)) {
@@ -4317,22 +4279,22 @@
     }
 }
 
-const std::vector<sp<InputWindowHandle>>& InputDispatcher::getWindowHandlesLocked(
+const std::vector<sp<WindowInfoHandle>>& InputDispatcher::getWindowHandlesLocked(
         int32_t displayId) const {
-    static const std::vector<sp<InputWindowHandle>> EMPTY_WINDOW_HANDLES;
+    static const std::vector<sp<WindowInfoHandle>> EMPTY_WINDOW_HANDLES;
     auto it = mWindowHandlesByDisplay.find(displayId);
     return it != mWindowHandlesByDisplay.end() ? it->second : EMPTY_WINDOW_HANDLES;
 }
 
-sp<InputWindowHandle> InputDispatcher::getWindowHandleLocked(
+sp<WindowInfoHandle> InputDispatcher::getWindowHandleLocked(
         const sp<IBinder>& windowHandleToken) const {
     if (windowHandleToken == nullptr) {
         return nullptr;
     }
 
     for (auto& it : mWindowHandlesByDisplay) {
-        const std::vector<sp<InputWindowHandle>>& windowHandles = it.second;
-        for (const sp<InputWindowHandle>& windowHandle : windowHandles) {
+        const std::vector<sp<WindowInfoHandle>>& windowHandles = it.second;
+        for (const sp<WindowInfoHandle>& windowHandle : windowHandles) {
             if (windowHandle->getToken() == windowHandleToken) {
                 return windowHandle;
             }
@@ -4341,13 +4303,13 @@
     return nullptr;
 }
 
-sp<InputWindowHandle> InputDispatcher::getWindowHandleLocked(const sp<IBinder>& windowHandleToken,
-                                                             int displayId) const {
+sp<WindowInfoHandle> InputDispatcher::getWindowHandleLocked(const sp<IBinder>& windowHandleToken,
+                                                            int displayId) const {
     if (windowHandleToken == nullptr) {
         return nullptr;
     }
 
-    for (const sp<InputWindowHandle>& windowHandle : getWindowHandlesLocked(displayId)) {
+    for (const sp<WindowInfoHandle>& windowHandle : getWindowHandlesLocked(displayId)) {
         if (windowHandle->getToken() == windowHandleToken) {
             return windowHandle;
         }
@@ -4355,11 +4317,11 @@
     return nullptr;
 }
 
-sp<InputWindowHandle> InputDispatcher::getWindowHandleLocked(
-        const sp<InputWindowHandle>& windowHandle) const {
+sp<WindowInfoHandle> InputDispatcher::getWindowHandleLocked(
+        const sp<WindowInfoHandle>& windowHandle) const {
     for (auto& it : mWindowHandlesByDisplay) {
-        const std::vector<sp<InputWindowHandle>>& windowHandles = it.second;
-        for (const sp<InputWindowHandle>& handle : windowHandles) {
+        const std::vector<sp<WindowInfoHandle>>& windowHandles = it.second;
+        for (const sp<WindowInfoHandle>& handle : windowHandles) {
             if (handle->getId() == windowHandle->getId() &&
                 handle->getToken() == windowHandle->getToken()) {
                 if (windowHandle->getInfo()->displayId != it.first) {
@@ -4375,15 +4337,15 @@
     return nullptr;
 }
 
-sp<InputWindowHandle> InputDispatcher::getFocusedWindowHandleLocked(int displayId) const {
+sp<WindowInfoHandle> InputDispatcher::getFocusedWindowHandleLocked(int displayId) const {
     sp<IBinder> focusedToken = mFocusResolver.getFocusedWindowToken(displayId);
     return getWindowHandleLocked(focusedToken, displayId);
 }
 
-bool InputDispatcher::hasResponsiveConnectionLocked(InputWindowHandle& windowHandle) const {
+bool InputDispatcher::hasResponsiveConnectionLocked(WindowInfoHandle& windowHandle) const {
     sp<Connection> connection = getConnectionLocked(windowHandle.getToken());
     const bool noInputChannel =
-            windowHandle.getInfo()->inputFeatures.test(InputWindowInfo::Feature::NO_INPUT_CHANNEL);
+            windowHandle.getInfo()->inputFeatures.test(WindowInfo::Feature::NO_INPUT_CHANNEL);
     if (connection != nullptr && noInputChannel) {
         ALOGW("%s has feature NO_INPUT_CHANNEL, but it matched to connection %s",
               windowHandle.getName().c_str(), connection->inputChannel->getName().c_str());
@@ -4413,8 +4375,8 @@
 }
 
 void InputDispatcher::updateWindowHandlesForDisplayLocked(
-        const std::vector<sp<InputWindowHandle>>& inputWindowHandles, int32_t displayId) {
-    if (inputWindowHandles.empty()) {
+        const std::vector<sp<WindowInfoHandle>>& windowInfoHandles, int32_t displayId) {
+    if (windowInfoHandles.empty()) {
         // Remove all handles on a display if there are no windows left.
         mWindowHandlesByDisplay.erase(displayId);
         return;
@@ -4422,26 +4384,25 @@
 
     // Since we compare the pointer of input window handles across window updates, we need
     // to make sure the handle object for the same window stays unchanged across updates.
-    const std::vector<sp<InputWindowHandle>>& oldHandles = getWindowHandlesLocked(displayId);
-    std::unordered_map<int32_t /*id*/, sp<InputWindowHandle>> oldHandlesById;
-    for (const sp<InputWindowHandle>& handle : oldHandles) {
+    const std::vector<sp<WindowInfoHandle>>& oldHandles = getWindowHandlesLocked(displayId);
+    std::unordered_map<int32_t /*id*/, sp<WindowInfoHandle>> oldHandlesById;
+    for (const sp<WindowInfoHandle>& handle : oldHandles) {
         oldHandlesById[handle->getId()] = handle;
     }
 
-    std::vector<sp<InputWindowHandle>> newHandles;
-    for (const sp<InputWindowHandle>& handle : inputWindowHandles) {
+    std::vector<sp<WindowInfoHandle>> newHandles;
+    for (const sp<WindowInfoHandle>& handle : windowInfoHandles) {
         if (!handle->updateInfo()) {
             // handle no longer valid
             continue;
         }
 
-        const InputWindowInfo* info = handle->getInfo();
-        if ((getInputChannelLocked(handle->getToken()) == nullptr &&
-             info->portalToDisplayId == ADISPLAY_ID_NONE)) {
+        const WindowInfo* info = handle->getInfo();
+        if (getInputChannelLocked(handle->getToken()) == nullptr) {
             const bool noInputChannel =
-                    info->inputFeatures.test(InputWindowInfo::Feature::NO_INPUT_CHANNEL);
-            const bool canReceiveInput = !info->flags.test(InputWindowInfo::Flag::NOT_TOUCHABLE) ||
-                    !info->flags.test(InputWindowInfo::Flag::NOT_FOCUSABLE);
+                    info->inputFeatures.test(WindowInfo::Feature::NO_INPUT_CHANNEL);
+            const bool canReceiveInput = !info->flags.test(WindowInfo::Flag::NOT_TOUCHABLE) ||
+                    !info->flags.test(WindowInfo::Flag::NOT_FOCUSABLE);
             if (canReceiveInput && !noInputChannel) {
                 ALOGV("Window handle %s has no registered input channel",
                       handle->getName().c_str());
@@ -4457,7 +4418,7 @@
 
         if ((oldHandlesById.find(handle->getId()) != oldHandlesById.end()) &&
                 (oldHandlesById.at(handle->getId())->getToken() == handle->getToken())) {
-            const sp<InputWindowHandle>& oldHandle = oldHandlesById.at(handle->getId());
+            const sp<WindowInfoHandle>& oldHandle = oldHandlesById.at(handle->getId());
             oldHandle->updateFrom(handle);
             newHandles.push_back(oldHandle);
         } else {
@@ -4470,7 +4431,7 @@
 }
 
 void InputDispatcher::setInputWindows(
-        const std::unordered_map<int32_t, std::vector<sp<InputWindowHandle>>>& handlesPerDisplay) {
+        const std::unordered_map<int32_t, std::vector<sp<WindowInfoHandle>>>& handlesPerDisplay) {
     { // acquire lock
         std::scoped_lock _l(mLock);
         for (const auto& [displayId, handles] : handlesPerDisplay) {
@@ -4489,19 +4450,19 @@
  * For removed handle, check if need to send a cancel event if already in touch.
  */
 void InputDispatcher::setInputWindowsLocked(
-        const std::vector<sp<InputWindowHandle>>& inputWindowHandles, int32_t displayId) {
+        const std::vector<sp<WindowInfoHandle>>& windowInfoHandles, int32_t displayId) {
     if (DEBUG_FOCUS) {
         std::string windowList;
-        for (const sp<InputWindowHandle>& iwh : inputWindowHandles) {
+        for (const sp<WindowInfoHandle>& iwh : windowInfoHandles) {
             windowList += iwh->getName() + " ";
         }
         ALOGD("setInputWindows displayId=%" PRId32 " %s", displayId, windowList.c_str());
     }
 
     // Ensure all tokens are null if the window has feature NO_INPUT_CHANNEL
-    for (const sp<InputWindowHandle>& window : inputWindowHandles) {
+    for (const sp<WindowInfoHandle>& window : windowInfoHandles) {
         const bool noInputWindow =
-                window->getInfo()->inputFeatures.test(InputWindowInfo::Feature::NO_INPUT_CHANNEL);
+                window->getInfo()->inputFeatures.test(WindowInfo::Feature::NO_INPUT_CHANNEL);
         if (noInputWindow && window->getToken() != nullptr) {
             ALOGE("%s has feature NO_INPUT_WINDOW, but a non-null token. Clearing",
                   window->getName().c_str());
@@ -4510,18 +4471,18 @@
     }
 
     // Copy old handles for release if they are no longer present.
-    const std::vector<sp<InputWindowHandle>> oldWindowHandles = getWindowHandlesLocked(displayId);
+    const std::vector<sp<WindowInfoHandle>> oldWindowHandles = getWindowHandlesLocked(displayId);
 
     // Save the old windows' orientation by ID before it gets updated.
     std::unordered_map<int32_t, uint32_t> oldWindowOrientations;
-    for (const sp<InputWindowHandle>& handle : oldWindowHandles) {
+    for (const sp<WindowInfoHandle>& handle : oldWindowHandles) {
         oldWindowOrientations.emplace(handle->getId(),
                                       handle->getInfo()->transform.getOrientation());
     }
 
-    updateWindowHandlesForDisplayLocked(inputWindowHandles, displayId);
+    updateWindowHandlesForDisplayLocked(windowInfoHandles, displayId);
 
-    const std::vector<sp<InputWindowHandle>>& windowHandles = getWindowHandlesLocked(displayId);
+    const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
     if (mLastHoverWindowHandle &&
         std::find(windowHandles.begin(), windowHandles.end(), mLastHoverWindowHandle) ==
                 windowHandles.end()) {
@@ -4570,8 +4531,8 @@
     if (isPerWindowInputRotationEnabled()) {
         // Determine if the orientation of any of the input windows have changed, and cancel all
         // pointer events if necessary.
-        for (const sp<InputWindowHandle>& oldWindowHandle : oldWindowHandles) {
-            const sp<InputWindowHandle> newWindowHandle = getWindowHandleLocked(oldWindowHandle);
+        for (const sp<WindowInfoHandle>& oldWindowHandle : oldWindowHandles) {
+            const sp<WindowInfoHandle> newWindowHandle = getWindowHandleLocked(oldWindowHandle);
             if (newWindowHandle != nullptr &&
                 newWindowHandle->getInfo()->transform.getOrientation() !=
                         oldWindowOrientations[oldWindowHandle->getId()]) {
@@ -4590,7 +4551,7 @@
     // This ensures that unused input channels are released promptly.
     // Otherwise, they might stick around until the window handle is destroyed
     // which might not happen until the next GC.
-    for (const sp<InputWindowHandle>& oldWindowHandle : oldWindowHandles) {
+    for (const sp<WindowInfoHandle>& oldWindowHandle : oldWindowHandles) {
         if (getWindowHandleLocked(oldWindowHandle) == nullptr) {
             if (DEBUG_FOCUS) {
                 ALOGD("Window went away: %s", oldWindowHandle->getName().c_str());
@@ -4600,7 +4561,7 @@
             // check for window flags when windows are going away.
             // TODO(b/157929241) : delete this. This is only needed temporarily
             // in order to gather some data about the flag usage
-            if (oldWindowHandle->getInfo()->flags.test(InputWindowInfo::Flag::SLIPPERY)) {
+            if (oldWindowHandle->getInfo()->flags.test(WindowInfo::Flag::SLIPPERY)) {
                 ALOGW("%s has FLAG_SLIPPERY. Please report this in b/157929241",
                       oldWindowHandle->getName().c_str());
                 if (mCompatService != nullptr) {
@@ -4790,8 +4751,8 @@
     { // acquire lock
         std::scoped_lock _l(mLock);
 
-        sp<InputWindowHandle> fromWindowHandle = getWindowHandleLocked(fromToken);
-        sp<InputWindowHandle> toWindowHandle = getWindowHandleLocked(toToken);
+        sp<WindowInfoHandle> fromWindowHandle = getWindowHandleLocked(fromToken);
+        sp<WindowInfoHandle> toWindowHandle = getWindowHandleLocked(toToken);
         if (fromWindowHandle == nullptr || toWindowHandle == nullptr) {
             ALOGW("Cannot transfer focus because from or to window not found.");
             return false;
@@ -4869,7 +4830,7 @@
     { // acquire lock
         std::scoped_lock _l(mLock);
 
-        sp<InputWindowHandle> toWindowHandle = getWindowHandleLocked(destChannelToken);
+        sp<WindowInfoHandle> toWindowHandle = getWindowHandleLocked(destChannelToken);
         if (toWindowHandle == nullptr) {
             ALOGW("Could not find window associated with token=%p", destChannelToken.get());
             return false;
@@ -4936,7 +4897,7 @@
 
     std::string windowName = "None";
     if (mWindowTokenWithPointerCapture) {
-        const sp<InputWindowHandle> captureWindowHandle =
+        const sp<WindowInfoHandle> captureWindowHandle =
                 getWindowHandleLocked(mWindowTokenWithPointerCapture);
         windowName = captureWindowHandle ? captureWindowHandle->getName().c_str()
                                          : "token has capture without window";
@@ -4989,14 +4950,6 @@
             } else {
                 dump += INDENT3 "Windows: <none>\n";
             }
-            if (!state.portalWindows.empty()) {
-                dump += INDENT3 "Portal windows:\n";
-                for (size_t i = 0; i < state.portalWindows.size(); i++) {
-                    const sp<InputWindowHandle> portalWindowHandle = state.portalWindows[i];
-                    dump += StringPrintf(INDENT4 "%zu: name='%s'\n", i,
-                                         portalWindowHandle->getName().c_str());
-                }
-            }
         }
     } else {
         dump += INDENT "TouchStates: <no displays touched>\n";
@@ -5009,16 +4962,16 @@
 
     if (!mWindowHandlesByDisplay.empty()) {
         for (auto& it : mWindowHandlesByDisplay) {
-            const std::vector<sp<InputWindowHandle>> windowHandles = it.second;
+            const std::vector<sp<WindowInfoHandle>> windowHandles = it.second;
             dump += StringPrintf(INDENT "Display: %" PRId32 "\n", it.first);
             if (!windowHandles.empty()) {
                 dump += INDENT2 "Windows:\n";
                 for (size_t i = 0; i < windowHandles.size(); i++) {
-                    const sp<InputWindowHandle>& windowHandle = windowHandles[i];
-                    const InputWindowInfo* windowInfo = windowHandle->getInfo();
+                    const sp<WindowInfoHandle>& windowHandle = windowHandles[i];
+                    const WindowInfo* windowInfo = windowHandle->getInfo();
 
                     dump += StringPrintf(INDENT3 "%zu: name='%s', id=%" PRId32 ", displayId=%d, "
-                                                 "portalToDisplayId=%d, paused=%s, focusable=%s, "
+                                                 "paused=%s, focusable=%s, "
                                                  "hasWallpaper=%s, visible=%s, alpha=%.2f, "
                                                  "flags=%s, type=%s, "
                                                  "frame=[%d,%d][%d,%d], globalScale=%f, "
@@ -5026,8 +4979,7 @@
                                                  "applicationInfo.token=%s, "
                                                  "touchableRegion=",
                                          i, windowInfo->name.c_str(), windowInfo->id,
-                                         windowInfo->displayId, windowInfo->portalToDisplayId,
-                                         toString(windowInfo->paused),
+                                         windowInfo->displayId, toString(windowInfo->paused),
                                          toString(windowInfo->focusable),
                                          toString(windowInfo->hasWallpaper),
                                          toString(windowInfo->visible), windowInfo->alpha,
@@ -5396,7 +5348,7 @@
     { // acquire lock
         std::scoped_lock _l(mLock);
         if (DEBUG_FOCUS) {
-            const sp<InputWindowHandle> windowHandle = getWindowHandleLocked(windowToken);
+            const sp<WindowInfoHandle> windowHandle = getWindowHandleLocked(windowToken);
             ALOGI("Request to %s Pointer Capture from: %s.", enabled ? "enable" : "disable",
                   windowHandle != nullptr ? windowHandle->getName().c_str()
                                           : "token without window");
@@ -5567,7 +5519,7 @@
     postCommandLocked(std::move(commandEntry));
 }
 
-void InputDispatcher::updateLastAnrStateLocked(const sp<InputWindowHandle>& window,
+void InputDispatcher::updateLastAnrStateLocked(const sp<WindowInfoHandle>& window,
                                                const std::string& reason) {
     const std::string windowLabel = getApplicationWindowLabel(nullptr, window);
     updateLastAnrStateLocked(windowLabel, reason);
diff --git a/services/inputflinger/dispatcher/InputDispatcher.h b/services/inputflinger/dispatcher/InputDispatcher.h
index 9edf41c..32a467e 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.h
+++ b/services/inputflinger/dispatcher/InputDispatcher.h
@@ -37,10 +37,10 @@
 
 #include <attestation/HmacKeyManager.h>
 #include <com/android/internal/compat/IPlatformCompatNative.h>
+#include <gui/InputApplication.h>
+#include <gui/WindowInfo.h>
 #include <input/Input.h>
-#include <input/InputApplication.h>
 #include <input/InputTransport.h>
-#include <input/InputWindow.h>
 #include <limits.h>
 #include <stddef.h>
 #include <ui/Region.h>
@@ -109,8 +109,9 @@
 
     std::unique_ptr<VerifiedInputEvent> verifyInputEvent(const InputEvent& event) override;
 
-    void setInputWindows(const std::unordered_map<int32_t, std::vector<sp<InputWindowHandle>>>&
-                                 handlesPerDisplay) override;
+    void setInputWindows(
+            const std::unordered_map<int32_t, std::vector<sp<android::gui::WindowInfoHandle>>>&
+                    handlesPerDisplay) override;
     void setFocusedApplication(
             int32_t displayId,
             const std::shared_ptr<InputApplicationHandle>& inputApplicationHandle) override;
@@ -127,7 +128,7 @@
 
     base::Result<std::unique_ptr<InputChannel>> createInputChannel(
             const std::string& name) override;
-    void setFocusedWindow(const FocusRequest&) override;
+    void setFocusedWindow(const android::gui::FocusRequest&) override;
     base::Result<std::unique_ptr<InputChannel>> createInputMonitor(int32_t displayId,
                                                                    bool isGestureMonitor,
                                                                    const std::string& name,
@@ -190,8 +191,8 @@
     void enqueueFocusEventLocked(const sp<IBinder>& windowToken, bool hasFocus,
                                  const std::string& reason) REQUIRES(mLock);
     // Enqueues a drag event.
-    void enqueueDragEventLocked(const sp<InputWindowHandle>& windowToken, bool isExiting,
-                                const MotionEntry& motionEntry) REQUIRES(mLock);
+    void enqueueDragEventLocked(const sp<android::gui::WindowInfoHandle>& windowToken,
+                                bool isExiting, const MotionEntry& motionEntry) REQUIRES(mLock);
 
     // Adds an event to a queue of recent events for debugging purposes.
     void addRecentEventLocked(std::shared_ptr<EventEntry> entry) REQUIRES(mLock);
@@ -208,11 +209,11 @@
     // to transfer focus to a new application.
     std::shared_ptr<EventEntry> mNextUnblockedEvent GUARDED_BY(mLock);
 
-    sp<InputWindowHandle> findTouchedWindowAtLocked(int32_t displayId, int32_t x, int32_t y,
-                                                    TouchState* touchState,
-                                                    bool addOutsideTargets = false,
-                                                    bool addPortalWindows = false,
-                                                    bool ignoreDragWindow = false) REQUIRES(mLock);
+    sp<android::gui::WindowInfoHandle> findTouchedWindowAtLocked(int32_t displayId, int32_t x,
+                                                                 int32_t y, TouchState* touchState,
+                                                                 bool addOutsideTargets = false,
+                                                                 bool ignoreDragWindow = false)
+            REQUIRES(mLock);
 
     sp<Connection> getConnectionLocked(const sp<IBinder>& inputConnectionToken) const
             REQUIRES(mLock);
@@ -314,33 +315,36 @@
     float mMaximumObscuringOpacityForTouch GUARDED_BY(mLock);
     android::os::BlockUntrustedTouchesMode mBlockUntrustedTouchesMode GUARDED_BY(mLock);
 
-    std::unordered_map<int32_t, std::vector<sp<InputWindowHandle>>> mWindowHandlesByDisplay
-            GUARDED_BY(mLock);
-    void setInputWindowsLocked(const std::vector<sp<InputWindowHandle>>& inputWindowHandles,
-                               int32_t displayId) REQUIRES(mLock);
+    std::unordered_map<int32_t, std::vector<sp<android::gui::WindowInfoHandle>>>
+            mWindowHandlesByDisplay GUARDED_BY(mLock);
+    void setInputWindowsLocked(
+            const std::vector<sp<android::gui::WindowInfoHandle>>& inputWindowHandles,
+            int32_t displayId) REQUIRES(mLock);
     // Get a reference to window handles by display, return an empty vector if not found.
-    const std::vector<sp<InputWindowHandle>>& getWindowHandlesLocked(int32_t displayId) const
-            REQUIRES(mLock);
-    sp<InputWindowHandle> getWindowHandleLocked(const sp<IBinder>& windowHandleToken) const
-            REQUIRES(mLock);
+    const std::vector<sp<android::gui::WindowInfoHandle>>& getWindowHandlesLocked(
+            int32_t displayId) const REQUIRES(mLock);
+    sp<android::gui::WindowInfoHandle> getWindowHandleLocked(
+            const sp<IBinder>& windowHandleToken) const REQUIRES(mLock);
 
     // Same function as above, but faster. Since displayId is provided, this avoids the need
     // to loop through all displays.
-    sp<InputWindowHandle> getWindowHandleLocked(const sp<IBinder>& windowHandleToken,
-                                                int displayId) const REQUIRES(mLock);
-    sp<InputWindowHandle> getWindowHandleLocked(const sp<InputWindowHandle>& windowHandle) const
-            REQUIRES(mLock);
+    sp<android::gui::WindowInfoHandle> getWindowHandleLocked(const sp<IBinder>& windowHandleToken,
+                                                             int displayId) const REQUIRES(mLock);
+    sp<android::gui::WindowInfoHandle> getWindowHandleLocked(
+            const sp<android::gui::WindowInfoHandle>& windowHandle) const REQUIRES(mLock);
     std::shared_ptr<InputChannel> getInputChannelLocked(const sp<IBinder>& windowToken) const
             REQUIRES(mLock);
-    sp<InputWindowHandle> getFocusedWindowHandleLocked(int displayId) const REQUIRES(mLock);
-    bool hasResponsiveConnectionLocked(InputWindowHandle& windowHandle) const REQUIRES(mLock);
+    sp<android::gui::WindowInfoHandle> getFocusedWindowHandleLocked(int displayId) const
+            REQUIRES(mLock);
+    bool hasResponsiveConnectionLocked(android::gui::WindowInfoHandle& windowHandle) const
+            REQUIRES(mLock);
 
     /*
      * Validate and update InputWindowHandles for a given display.
      */
     void updateWindowHandlesForDisplayLocked(
-            const std::vector<sp<InputWindowHandle>>& inputWindowHandles, int32_t displayId)
-            REQUIRES(mLock);
+            const std::vector<sp<android::gui::WindowInfoHandle>>& inputWindowHandles,
+            int32_t displayId) REQUIRES(mLock);
 
     std::unordered_map<int32_t, TouchState> mTouchStatesByDisplay GUARDED_BY(mLock);
     std::unique_ptr<DragState> mDragState GUARDED_BY(mLock);
@@ -471,7 +475,7 @@
     AnrTracker mAnrTracker GUARDED_BY(mLock);
 
     // Contains the last window which received a hover event.
-    sp<InputWindowHandle> mLastHoverWindowHandle GUARDED_BY(mLock);
+    sp<android::gui::WindowInfoHandle> mLastHoverWindowHandle GUARDED_BY(mLock);
 
     void cancelEventsForAnrLocked(const sp<Connection>& connection) REQUIRES(mLock);
     nsecs_t getTimeSpentWaitingForApplicationLocked(nsecs_t currentTime) REQUIRES(mLock);
@@ -489,21 +493,20 @@
     android::os::InputEventInjectionResult findTouchedWindowTargetsLocked(
             nsecs_t currentTime, const MotionEntry& entry, std::vector<InputTarget>& inputTargets,
             nsecs_t* nextWakeupTime, bool* outConflictingPointerActions) REQUIRES(mLock);
-    std::vector<TouchedMonitor> findTouchedGestureMonitorsLocked(
-            int32_t displayId, const std::vector<sp<InputWindowHandle>>& portalWindows) const
+    std::vector<TouchedMonitor> findTouchedGestureMonitorsLocked(int32_t displayId) const
             REQUIRES(mLock);
     std::vector<TouchedMonitor> selectResponsiveMonitorsLocked(
             const std::vector<TouchedMonitor>& gestureMonitors) const REQUIRES(mLock);
 
-    void addWindowTargetLocked(const sp<InputWindowHandle>& windowHandle, int32_t targetFlags,
-                               BitSet32 pointerIds, std::vector<InputTarget>& inputTargets)
-            REQUIRES(mLock);
+    void addWindowTargetLocked(const sp<android::gui::WindowInfoHandle>& windowHandle,
+                               int32_t targetFlags, BitSet32 pointerIds,
+                               std::vector<InputTarget>& inputTargets) REQUIRES(mLock);
     void addMonitoringTargetLocked(const Monitor& monitor, float xOffset, float yOffset,
                                    std::vector<InputTarget>& inputTargets) REQUIRES(mLock);
     void addGlobalMonitoringTargetsLocked(std::vector<InputTarget>& inputTargets, int32_t displayId,
                                           float xOffset = 0, float yOffset = 0) REQUIRES(mLock);
     void pokeUserActivityLocked(const EventEntry& eventEntry) REQUIRES(mLock);
-    bool checkInjectionPermission(const sp<InputWindowHandle>& windowHandle,
+    bool checkInjectionPermission(const sp<android::gui::WindowInfoHandle>& windowHandle,
                                   const InjectionState* injectionState);
     // Enqueue a drag event if needed, and update the touch state.
     // Uses findTouchedWindowTargetsLocked to make the decision
@@ -518,15 +521,18 @@
         std::vector<std::string> debugInfo;
     };
 
-    TouchOcclusionInfo computeTouchOcclusionInfoLocked(const sp<InputWindowHandle>& windowHandle,
-                                                       int32_t x, int32_t y) const REQUIRES(mLock);
+    TouchOcclusionInfo computeTouchOcclusionInfoLocked(
+            const sp<android::gui::WindowInfoHandle>& windowHandle, int32_t x, int32_t y) const
+            REQUIRES(mLock);
     bool isTouchTrustedLocked(const TouchOcclusionInfo& occlusionInfo) const REQUIRES(mLock);
-    bool isWindowObscuredAtPointLocked(const sp<InputWindowHandle>& windowHandle, int32_t x,
-                                       int32_t y) const REQUIRES(mLock);
-    bool isWindowObscuredLocked(const sp<InputWindowHandle>& windowHandle) const REQUIRES(mLock);
-    std::string dumpWindowForTouchOcclusion(const InputWindowInfo* info, bool isTouchWindow) const;
+    bool isWindowObscuredAtPointLocked(const sp<android::gui::WindowInfoHandle>& windowHandle,
+                                       int32_t x, int32_t y) const REQUIRES(mLock);
+    bool isWindowObscuredLocked(const sp<android::gui::WindowInfoHandle>& windowHandle) const
+            REQUIRES(mLock);
+    std::string dumpWindowForTouchOcclusion(const android::gui::WindowInfo* info,
+                                            bool isTouchWindow) const;
     std::string getApplicationWindowLabel(const InputApplicationHandle* applicationHandle,
-                                          const sp<InputWindowHandle>& windowHandle);
+                                          const sp<android::gui::WindowInfoHandle>& windowHandle);
 
     // Manage the dispatch cycle for a single connection.
     // These methods are deliberately not Interruptible because doing all of the work
@@ -605,8 +611,8 @@
     void onAnrLocked(const sp<Connection>& connection) REQUIRES(mLock);
     void onAnrLocked(std::shared_ptr<InputApplicationHandle> application) REQUIRES(mLock);
     void onUntrustedTouchLocked(const std::string& obscuringPackage) REQUIRES(mLock);
-    void updateLastAnrStateLocked(const sp<InputWindowHandle>& window, const std::string& reason)
-            REQUIRES(mLock);
+    void updateLastAnrStateLocked(const sp<android::gui::WindowInfoHandle>& window,
+                                  const std::string& reason) REQUIRES(mLock);
     void updateLastAnrStateLocked(const InputApplicationHandle& application,
                                   const std::string& reason) REQUIRES(mLock);
     void updateLastAnrStateLocked(const std::string& windowLabel, const std::string& reason)
diff --git a/services/inputflinger/dispatcher/InputTarget.h b/services/inputflinger/dispatcher/InputTarget.h
index 1c4980b..9c62b7e 100644
--- a/services/inputflinger/dispatcher/InputTarget.h
+++ b/services/inputflinger/dispatcher/InputTarget.h
@@ -17,6 +17,7 @@
 #ifndef _UI_INPUT_INPUTDISPATCHER_INPUTTARGET_H
 #define _UI_INPUT_INPUTDISPATCHER_INPUTTARGET_H
 
+#include <gui/constants.h>
 #include <input/InputTransport.h>
 #include <ui/Transform.h>
 #include <utils/BitSet.h>
@@ -101,7 +102,7 @@
     float globalScaleFactor = 1.0f;
 
     // Display-size in its natural rotation. Used for compatibility transform of raw coordinates.
-    int2 displaySize = {AMOTION_EVENT_INVALID_DISPLAY_SIZE, AMOTION_EVENT_INVALID_DISPLAY_SIZE};
+    int2 displaySize = {INVALID_DISPLAY_SIZE, INVALID_DISPLAY_SIZE};
 
     // The subset of pointer ids to include in motion events dispatched to this input target
     // if FLAG_SPLIT is set.
diff --git a/services/inputflinger/dispatcher/TouchState.cpp b/services/inputflinger/dispatcher/TouchState.cpp
index 81b3cf0..b7ed658 100644
--- a/services/inputflinger/dispatcher/TouchState.cpp
+++ b/services/inputflinger/dispatcher/TouchState.cpp
@@ -14,13 +14,14 @@
  * limitations under the License.
  */
 
-#include <input/InputWindow.h>
+#include <gui/WindowInfo.h>
 
 #include "InputTarget.h"
 
 #include "TouchState.h"
 
-using android::InputWindowHandle;
+using android::gui::WindowInfo;
+using android::gui::WindowInfoHandle;
 
 namespace android::inputdispatcher {
 
@@ -36,7 +37,6 @@
     source = 0;
     displayId = ADISPLAY_ID_NONE;
     windows.clear();
-    portalWindows.clear();
     gestureMonitors.clear();
 }
 
@@ -47,11 +47,10 @@
     source = other.source;
     displayId = other.displayId;
     windows = other.windows;
-    portalWindows = other.portalWindows;
     gestureMonitors = other.gestureMonitors;
 }
 
-void TouchState::addOrUpdateWindow(const sp<InputWindowHandle>& windowHandle, int32_t targetFlags,
+void TouchState::addOrUpdateWindow(const sp<WindowInfoHandle>& windowHandle, int32_t targetFlags,
                                    BitSet32 pointerIds) {
     if (targetFlags & InputTarget::FLAG_SPLIT) {
         split = true;
@@ -76,16 +75,6 @@
     windows.push_back(touchedWindow);
 }
 
-void TouchState::addPortalWindow(const sp<InputWindowHandle>& windowHandle) {
-    size_t numWindows = portalWindows.size();
-    for (size_t i = 0; i < numWindows; i++) {
-        if (portalWindows[i] == windowHandle) {
-            return;
-        }
-    }
-    portalWindows.push_back(windowHandle);
-}
-
 void TouchState::addGestureMonitors(const std::vector<TouchedMonitor>& newMonitors) {
     const size_t newSize = gestureMonitors.size() + newMonitors.size();
     gestureMonitors.reserve(newSize);
@@ -118,10 +107,9 @@
 
 void TouchState::filterNonMonitors() {
     windows.clear();
-    portalWindows.clear();
 }
 
-sp<InputWindowHandle> TouchState::getFirstForegroundWindowHandle() const {
+sp<WindowInfoHandle> TouchState::getFirstForegroundWindowHandle() const {
     for (size_t i = 0; i < windows.size(); i++) {
         const TouchedWindow& window = windows[i];
         if (window.targetFlags & InputTarget::FLAG_FOREGROUND) {
@@ -137,7 +125,7 @@
     for (const TouchedWindow& window : windows) {
         if (window.targetFlags & InputTarget::FLAG_FOREGROUND) {
             if (haveSlipperyForegroundWindow ||
-                !window.windowHandle->getInfo()->flags.test(InputWindowInfo::Flag::SLIPPERY)) {
+                !window.windowHandle->getInfo()->flags.test(WindowInfo::Flag::SLIPPERY)) {
                 return false;
             }
             haveSlipperyForegroundWindow = true;
diff --git a/services/inputflinger/dispatcher/TouchState.h b/services/inputflinger/dispatcher/TouchState.h
index 623c6a8..579b868 100644
--- a/services/inputflinger/dispatcher/TouchState.h
+++ b/services/inputflinger/dispatcher/TouchState.h
@@ -22,7 +22,9 @@
 
 namespace android {
 
-class InputWindowHandle;
+namespace gui {
+class WindowInfoHandle;
+}
 
 namespace inputdispatcher {
 
@@ -34,25 +36,20 @@
     int32_t displayId; // id to the display that currently has a touch, others are rejected
     std::vector<TouchedWindow> windows;
 
-    // This collects the portal windows that the touch has gone through. Each portal window
-    // targets a display (embedded display for most cases). With this info, we can add the
-    // monitoring channels of the displays touched.
-    std::vector<sp<android::InputWindowHandle>> portalWindows;
-
     std::vector<TouchedMonitor> gestureMonitors;
 
     TouchState();
     ~TouchState();
     void reset();
     void copyFrom(const TouchState& other);
-    void addOrUpdateWindow(const sp<android::InputWindowHandle>& windowHandle, int32_t targetFlags,
-                           BitSet32 pointerIds);
-    void addPortalWindow(const sp<android::InputWindowHandle>& windowHandle);
+    void addOrUpdateWindow(const sp<android::gui::WindowInfoHandle>& windowHandle,
+                           int32_t targetFlags, BitSet32 pointerIds);
+    void addPortalWindow(const sp<android::gui::WindowInfoHandle>& windowHandle);
     void addGestureMonitors(const std::vector<TouchedMonitor>& monitors);
     void removeWindowByToken(const sp<IBinder>& token);
     void filterNonAsIsTouchWindows();
     void filterNonMonitors();
-    sp<InputWindowHandle> getFirstForegroundWindowHandle() const;
+    sp<android::gui::WindowInfoHandle> getFirstForegroundWindowHandle() const;
     bool isSlippery() const;
 };
 
diff --git a/services/inputflinger/dispatcher/TouchedWindow.h b/services/inputflinger/dispatcher/TouchedWindow.h
index 8713aa3..4c31ec3 100644
--- a/services/inputflinger/dispatcher/TouchedWindow.h
+++ b/services/inputflinger/dispatcher/TouchedWindow.h
@@ -19,13 +19,15 @@
 
 namespace android {
 
-class InputWindowHandle;
+namespace gui {
+class WindowInfoHandle;
+}
 
 namespace inputdispatcher {
 
 // Focus tracking for touch.
 struct TouchedWindow {
-    sp<android::InputWindowHandle> windowHandle;
+    sp<gui::WindowInfoHandle> windowHandle;
     int32_t targetFlags;
     BitSet32 pointerIds; // zero unless target flag FLAG_SPLIT is set
 };
diff --git a/services/inputflinger/dispatcher/include/InputDispatcherInterface.h b/services/inputflinger/dispatcher/include/InputDispatcherInterface.h
index 43428a0..80db035 100644
--- a/services/inputflinger/dispatcher/include/InputDispatcherInterface.h
+++ b/services/inputflinger/dispatcher/include/InputDispatcherInterface.h
@@ -19,18 +19,17 @@
 
 #include <InputListener.h>
 #include <android-base/result.h>
-#include <android/FocusRequest.h>
+#include <android/gui/FocusRequest.h>
 #include <android/os/BlockUntrustedTouchesMode.h>
 #include <android/os/ISetInputWindowsListener.h>
 #include <android/os/InputEventInjectionResult.h>
 #include <android/os/InputEventInjectionSync.h>
-#include <input/InputApplication.h>
+#include <gui/InputApplication.h>
+#include <gui/WindowInfo.h>
 #include <input/InputDevice.h>
 #include <input/InputTransport.h>
-#include <input/InputWindow.h>
 #include <unordered_map>
 
-
 namespace android {
 
 /* Notifies the system about input events generated by the input reader.
@@ -91,7 +90,7 @@
      * This method may be called on any thread (usually by the input manager).
      */
     virtual void setInputWindows(
-            const std::unordered_map<int32_t, std::vector<sp<InputWindowHandle>>>&
+            const std::unordered_map<int32_t, std::vector<sp<gui::WindowInfoHandle>>>&
                     handlesPerDisplay) = 0;
 
     /* Sets the focused application on the given display.
@@ -162,7 +161,7 @@
     /**
      * Sets focus on the specified window.
      */
-    virtual void setFocusedWindow(const FocusRequest&) = 0;
+    virtual void setFocusedWindow(const gui::FocusRequest&) = 0;
 
     /**
      * Creates an input channel that may be used as targets for input events.
diff --git a/services/inputflinger/dispatcher/include/InputDispatcherPolicyInterface.h b/services/inputflinger/dispatcher/include/InputDispatcherPolicyInterface.h
index 219f45a..ebfcbe1 100644
--- a/services/inputflinger/dispatcher/include/InputDispatcherPolicyInterface.h
+++ b/services/inputflinger/dispatcher/include/InputDispatcherPolicyInterface.h
@@ -20,8 +20,8 @@
 #include "InputDispatcherConfiguration.h"
 
 #include <binder/IBinder.h>
+#include <gui/InputApplication.h>
 #include <input/Input.h>
-#include <input/InputApplication.h>
 #include <utils/RefBase.h>
 
 namespace android {
diff --git a/services/inputflinger/host/InputFlinger.h b/services/inputflinger/host/InputFlinger.h
index 8112038..c05ff39 100644
--- a/services/inputflinger/host/InputFlinger.h
+++ b/services/inputflinger/host/InputFlinger.h
@@ -30,6 +30,8 @@
 #include <utils/String8.h>
 #include <utils/StrongPointer.h>
 
+using android::gui::FocusRequest;
+using android::gui::WindowInfo;
 using android::os::BnInputFlinger;
 using android::os::ISetInputWindowsListener;
 
@@ -44,7 +46,7 @@
     InputFlinger() ANDROID_API;
 
     status_t dump(int fd, const Vector<String16>& args) override;
-    binder::Status setInputWindows(const std::vector<InputWindowInfo>&,
+    binder::Status setInputWindows(const std::vector<WindowInfo>&,
                                    const sp<ISetInputWindowsListener>&) override {
         return binder::Status::ok();
     }
diff --git a/services/inputflinger/reader/InputDevice.cpp b/services/inputflinger/reader/InputDevice.cpp
index 7af014c..1e9ec54 100644
--- a/services/inputflinger/reader/InputDevice.cpp
+++ b/services/inputflinger/reader/InputDevice.cpp
@@ -18,7 +18,7 @@
 
 #include "InputDevice.h"
 
-#include <input/Flags.h>
+#include <ftl/Flags.h>
 #include <algorithm>
 
 #include "CursorInputMapper.h"
diff --git a/services/inputflinger/reader/controller/PeripheralController.cpp b/services/inputflinger/reader/controller/PeripheralController.cpp
index 16251ee..9c8a29a 100644
--- a/services/inputflinger/reader/controller/PeripheralController.cpp
+++ b/services/inputflinger/reader/controller/PeripheralController.cpp
@@ -19,8 +19,8 @@
 
 #include "../Macros.h"
 
+#include <ftl/NamedEnum.h>
 #include "PeripheralController.h"
-#include "input/NamedEnum.h"
 
 // Log detailed debug messages about input device lights.
 static constexpr bool DEBUG_LIGHT_DETAILS = false;
diff --git a/services/inputflinger/reader/include/EventHub.h b/services/inputflinger/reader/include/EventHub.h
index 410a706..1016a2c 100644
--- a/services/inputflinger/reader/include/EventHub.h
+++ b/services/inputflinger/reader/include/EventHub.h
@@ -22,7 +22,7 @@
 #include <unordered_map>
 #include <vector>
 
-#include <input/Flags.h>
+#include <ftl/Flags.h>
 #include <filesystem>
 
 #include <batteryservice/BatteryService.h>
diff --git a/services/inputflinger/reader/include/InputDevice.h b/services/inputflinger/reader/include/InputDevice.h
index 2f2eba7..f32472d 100644
--- a/services/inputflinger/reader/include/InputDevice.h
+++ b/services/inputflinger/reader/include/InputDevice.h
@@ -17,8 +17,8 @@
 #ifndef _UI_INPUTREADER_INPUT_DEVICE_H
 #define _UI_INPUTREADER_INPUT_DEVICE_H
 
+#include <ftl/Flags.h>
 #include <input/DisplayViewport.h>
-#include <input/Flags.h>
 #include <input/InputDevice.h>
 #include <input/PropertyMap.h>
 #include <stdint.h>
diff --git a/services/inputflinger/reader/mapper/TouchInputMapper.cpp b/services/inputflinger/reader/mapper/TouchInputMapper.cpp
index 6050238..fbb4db0 100644
--- a/services/inputflinger/reader/mapper/TouchInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/TouchInputMapper.cpp
@@ -18,7 +18,7 @@
 #include "../Macros.h"
 // clang-format on
 
-#include <input/NamedEnum.h>
+#include <ftl/NamedEnum.h>
 #include "TouchInputMapper.h"
 
 #include "CursorButtonAccumulator.h"
diff --git a/services/inputflinger/tests/Android.bp b/services/inputflinger/tests/Android.bp
index 918e1be..e686924 100644
--- a/services/inputflinger/tests/Android.bp
+++ b/services/inputflinger/tests/Android.bp
@@ -52,6 +52,7 @@
     ],
     aidl: {
         include_dirs: [
+            "frameworks/native/libs/gui",
             "frameworks/native/libs/input",
         ],
     },
diff --git a/services/inputflinger/tests/FocusResolver_test.cpp b/services/inputflinger/tests/FocusResolver_test.cpp
index 9051ff1..8c0edca 100644
--- a/services/inputflinger/tests/FocusResolver_test.cpp
+++ b/services/inputflinger/tests/FocusResolver_test.cpp
@@ -26,9 +26,12 @@
 
 // atest inputflinger_tests:FocusResolverTest
 
+using android::gui::FocusRequest;
+using android::gui::WindowInfoHandle;
+
 namespace android::inputdispatcher {
 
-class FakeWindowHandle : public InputWindowHandle {
+class FakeWindowHandle : public WindowInfoHandle {
 public:
     FakeWindowHandle(const std::string& name, const sp<IBinder>& token, bool focusable,
                      bool visible) {
@@ -47,7 +50,7 @@
     sp<IBinder> focusableWindowToken = new BBinder();
     sp<IBinder> invisibleWindowToken = new BBinder();
     sp<IBinder> unfocusableWindowToken = new BBinder();
-    std::vector<sp<InputWindowHandle>> windows;
+    std::vector<sp<WindowInfoHandle>> windows;
     windows.push_back(new FakeWindowHandle("Focusable", focusableWindowToken, true /* focusable */,
                                            true /* visible */));
     windows.push_back(new FakeWindowHandle("Invisible", invisibleWindowToken, true /* focusable */,
@@ -82,7 +85,7 @@
     sp<IBinder> focusableWindowToken = new BBinder();
     sp<IBinder> invisibleWindowToken = new BBinder();
     sp<IBinder> unfocusableWindowToken = new BBinder();
-    std::vector<sp<InputWindowHandle>> windows;
+    std::vector<sp<WindowInfoHandle>> windows;
     windows.push_back(new FakeWindowHandle("Mirror1", focusableWindowToken, true /* focusable */,
                                            true /* visible */));
     windows.push_back(new FakeWindowHandle("Mirror1", focusableWindowToken, true /* focusable */,
@@ -120,7 +123,7 @@
 
 TEST(FocusResolverTest, SetInputWindows) {
     sp<IBinder> focusableWindowToken = new BBinder();
-    std::vector<sp<InputWindowHandle>> windows;
+    std::vector<sp<WindowInfoHandle>> windows;
     sp<FakeWindowHandle> window = new FakeWindowHandle("Focusable", focusableWindowToken,
                                                        true /* focusable */, true /* visible */);
     windows.push_back(window);
@@ -142,7 +145,7 @@
 
 TEST(FocusResolverTest, FocusRequestsCanBePending) {
     sp<IBinder> invisibleWindowToken = new BBinder();
-    std::vector<sp<InputWindowHandle>> windows;
+    std::vector<sp<WindowInfoHandle>> windows;
 
     sp<FakeWindowHandle> invisibleWindow =
             new FakeWindowHandle("Invisible", invisibleWindowToken, true /* focusable */,
@@ -166,7 +169,7 @@
 
 TEST(FocusResolverTest, FocusRequestsArePersistent) {
     sp<IBinder> windowToken = new BBinder();
-    std::vector<sp<InputWindowHandle>> windows;
+    std::vector<sp<WindowInfoHandle>> windows;
 
     sp<FakeWindowHandle> window = new FakeWindowHandle("Test Window", windowToken,
                                                        false /* focusable */, true /* visible */);
@@ -207,7 +210,7 @@
 
 TEST(FocusResolverTest, ConditionalFocusRequestsAreNotPersistent) {
     sp<IBinder> hostWindowToken = new BBinder();
-    std::vector<sp<InputWindowHandle>> windows;
+    std::vector<sp<WindowInfoHandle>> windows;
 
     sp<FakeWindowHandle> hostWindow =
             new FakeWindowHandle("Host Window", hostWindowToken, true /* focusable */,
@@ -258,7 +261,7 @@
 }
 TEST(FocusResolverTest, FocusRequestsAreClearedWhenWindowIsRemoved) {
     sp<IBinder> windowToken = new BBinder();
-    std::vector<sp<InputWindowHandle>> windows;
+    std::vector<sp<WindowInfoHandle>> windows;
 
     sp<FakeWindowHandle> window = new FakeWindowHandle("Test Window", windowToken,
                                                        true /* focusable */, true /* visible */);
diff --git a/services/inputflinger/tests/IInputFlingerQuery.aidl b/services/inputflinger/tests/IInputFlingerQuery.aidl
index 5c8a8da..aff03bf 100644
--- a/services/inputflinger/tests/IInputFlingerQuery.aidl
+++ b/services/inputflinger/tests/IInputFlingerQuery.aidl
@@ -14,16 +14,16 @@
  * limitations under the License.
  */
 
-import android.FocusRequest;
 import android.InputChannel;
-import android.InputWindowInfo;
+import android.gui.FocusRequest;
+import android.gui.WindowInfo;
 import android.os.ISetInputWindowsListener;
 
 /** @hide */
 interface IInputFlingerQuery
 {
     /* Test interfaces */
-    void getInputWindows(out InputWindowInfo[] inputHandles);
+    void getInputWindows(out WindowInfo[] inputHandles);
     void getInputChannels(out InputChannel[] channels);
     void getLastFocusRequest(out FocusRequest request);
     void resetInputManager();
diff --git a/services/inputflinger/tests/InputClassifierConverter_test.cpp b/services/inputflinger/tests/InputClassifierConverter_test.cpp
index c0ada9d..f626d56 100644
--- a/services/inputflinger/tests/InputClassifierConverter_test.cpp
+++ b/services/inputflinger/tests/InputClassifierConverter_test.cpp
@@ -17,9 +17,9 @@
 #include "../InputClassifierConverter.h"
 
 #include <gtest/gtest.h>
+#include <gui/constants.h>
 #include <utils/BitSet.h>
 
-
 using namespace android::hardware::input;
 
 namespace android {
diff --git a/services/inputflinger/tests/InputClassifier_test.cpp b/services/inputflinger/tests/InputClassifier_test.cpp
index a72df01..3a9994e 100644
--- a/services/inputflinger/tests/InputClassifier_test.cpp
+++ b/services/inputflinger/tests/InputClassifier_test.cpp
@@ -16,6 +16,7 @@
 
 #include "../InputClassifier.h"
 #include <gtest/gtest.h>
+#include <gui/constants.h>
 
 #include "TestInputListener.h"
 
diff --git a/services/inputflinger/tests/InputDispatcher_test.cpp b/services/inputflinger/tests/InputDispatcher_test.cpp
index cb876c9..e268843 100644
--- a/services/inputflinger/tests/InputDispatcher_test.cpp
+++ b/services/inputflinger/tests/InputDispatcher_test.cpp
@@ -29,9 +29,12 @@
 #include <vector>
 
 using android::base::StringPrintf;
+using android::gui::FocusRequest;
+using android::gui::TouchOcclusionMode;
+using android::gui::WindowInfo;
+using android::gui::WindowInfoHandle;
 using android::os::InputEventInjectionResult;
 using android::os::InputEventInjectionSync;
-using android::os::TouchOcclusionMode;
 using namespace android::flag_operators;
 
 namespace android::inputdispatcher {
@@ -469,8 +472,8 @@
         }
     }
 
-    void setFocusedWindow(const sp<InputWindowHandle>& window,
-                          const sp<InputWindowHandle>& focusedWindow = nullptr) {
+    void setFocusedWindow(const sp<WindowInfoHandle>& window,
+                          const sp<WindowInfoHandle>& focusedWindow = nullptr) {
         FocusRequest request;
         request.token = window->getToken();
         request.windowName = window->getName();
@@ -527,8 +530,8 @@
     event.initialize(InputEvent::nextId(), DEVICE_ID, source, DISPLAY_ID, INVALID_HMAC,
                      /*action*/ -1, 0, 0, edgeFlags, metaState, 0, classification,
                      identityTransform, 0, 0, AMOTION_EVENT_INVALID_CURSOR_POSITION,
-                     AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_DISPLAY_SIZE,
-                     AMOTION_EVENT_INVALID_DISPLAY_SIZE, ARBITRARY_TIME, ARBITRARY_TIME,
+                     AMOTION_EVENT_INVALID_CURSOR_POSITION, INVALID_DISPLAY_SIZE,
+                     INVALID_DISPLAY_SIZE, ARBITRARY_TIME, ARBITRARY_TIME,
                      /*pointerCount*/ 1, pointerProperties, pointerCoords);
     ASSERT_EQ(InputEventInjectionResult::FAILED,
               mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
@@ -541,9 +544,8 @@
                              (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
                      0, 0, edgeFlags, metaState, 0, classification, identityTransform, 0, 0,
                      AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
-                     AMOTION_EVENT_INVALID_DISPLAY_SIZE, AMOTION_EVENT_INVALID_DISPLAY_SIZE,
-                     ARBITRARY_TIME, ARBITRARY_TIME, /*pointerCount*/ 1, pointerProperties,
-                     pointerCoords);
+                     INVALID_DISPLAY_SIZE, INVALID_DISPLAY_SIZE, ARBITRARY_TIME, ARBITRARY_TIME,
+                     /*pointerCount*/ 1, pointerProperties, pointerCoords);
     ASSERT_EQ(InputEventInjectionResult::FAILED,
               mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
                                             InputEventInjectionSync::NONE, 0ms, 0))
@@ -554,9 +556,8 @@
                              (~0U << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
                      0, 0, edgeFlags, metaState, 0, classification, identityTransform, 0, 0,
                      AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
-                     AMOTION_EVENT_INVALID_DISPLAY_SIZE, AMOTION_EVENT_INVALID_DISPLAY_SIZE,
-                     ARBITRARY_TIME, ARBITRARY_TIME, /*pointerCount*/ 1, pointerProperties,
-                     pointerCoords);
+                     INVALID_DISPLAY_SIZE, INVALID_DISPLAY_SIZE, ARBITRARY_TIME, ARBITRARY_TIME,
+                     /*pointerCount*/ 1, pointerProperties, pointerCoords);
     ASSERT_EQ(InputEventInjectionResult::FAILED,
               mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
                                             InputEventInjectionSync::NONE, 0ms, 0))
@@ -568,9 +569,8 @@
                              (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
                      0, 0, edgeFlags, metaState, 0, classification, identityTransform, 0, 0,
                      AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
-                     AMOTION_EVENT_INVALID_DISPLAY_SIZE, AMOTION_EVENT_INVALID_DISPLAY_SIZE,
-                     ARBITRARY_TIME, ARBITRARY_TIME, /*pointerCount*/ 1, pointerProperties,
-                     pointerCoords);
+                     INVALID_DISPLAY_SIZE, INVALID_DISPLAY_SIZE, ARBITRARY_TIME, ARBITRARY_TIME,
+                     /*pointerCount*/ 1, pointerProperties, pointerCoords);
     ASSERT_EQ(InputEventInjectionResult::FAILED,
               mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
                                             InputEventInjectionSync::NONE, 0ms, 0))
@@ -581,9 +581,8 @@
                              (~0U << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
                      0, 0, edgeFlags, metaState, 0, classification, identityTransform, 0, 0,
                      AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
-                     AMOTION_EVENT_INVALID_DISPLAY_SIZE, AMOTION_EVENT_INVALID_DISPLAY_SIZE,
-                     ARBITRARY_TIME, ARBITRARY_TIME, /*pointerCount*/ 1, pointerProperties,
-                     pointerCoords);
+                     INVALID_DISPLAY_SIZE, INVALID_DISPLAY_SIZE, ARBITRARY_TIME, ARBITRARY_TIME,
+                     /*pointerCount*/ 1, pointerProperties, pointerCoords);
     ASSERT_EQ(InputEventInjectionResult::FAILED,
               mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
                                             InputEventInjectionSync::NONE, 0ms, 0))
@@ -593,8 +592,8 @@
     event.initialize(InputEvent::nextId(), DEVICE_ID, source, DISPLAY_ID, INVALID_HMAC,
                      AMOTION_EVENT_ACTION_DOWN, 0, 0, edgeFlags, metaState, 0, classification,
                      identityTransform, 0, 0, AMOTION_EVENT_INVALID_CURSOR_POSITION,
-                     AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_DISPLAY_SIZE,
-                     AMOTION_EVENT_INVALID_DISPLAY_SIZE, ARBITRARY_TIME, ARBITRARY_TIME,
+                     AMOTION_EVENT_INVALID_CURSOR_POSITION, INVALID_DISPLAY_SIZE,
+                     INVALID_DISPLAY_SIZE, ARBITRARY_TIME, ARBITRARY_TIME,
                      /*pointerCount*/ 0, pointerProperties, pointerCoords);
     ASSERT_EQ(InputEventInjectionResult::FAILED,
               mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
@@ -604,8 +603,8 @@
     event.initialize(InputEvent::nextId(), DEVICE_ID, source, DISPLAY_ID, INVALID_HMAC,
                      AMOTION_EVENT_ACTION_DOWN, 0, 0, edgeFlags, metaState, 0, classification,
                      identityTransform, 0, 0, AMOTION_EVENT_INVALID_CURSOR_POSITION,
-                     AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_DISPLAY_SIZE,
-                     AMOTION_EVENT_INVALID_DISPLAY_SIZE, ARBITRARY_TIME, ARBITRARY_TIME,
+                     AMOTION_EVENT_INVALID_CURSOR_POSITION, INVALID_DISPLAY_SIZE,
+                     INVALID_DISPLAY_SIZE, ARBITRARY_TIME, ARBITRARY_TIME,
                      /*pointerCount*/ MAX_POINTERS + 1, pointerProperties, pointerCoords);
     ASSERT_EQ(InputEventInjectionResult::FAILED,
               mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
@@ -617,8 +616,8 @@
     event.initialize(InputEvent::nextId(), DEVICE_ID, source, DISPLAY_ID, INVALID_HMAC,
                      AMOTION_EVENT_ACTION_DOWN, 0, 0, edgeFlags, metaState, 0, classification,
                      identityTransform, 0, 0, AMOTION_EVENT_INVALID_CURSOR_POSITION,
-                     AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_DISPLAY_SIZE,
-                     AMOTION_EVENT_INVALID_DISPLAY_SIZE, ARBITRARY_TIME, ARBITRARY_TIME,
+                     AMOTION_EVENT_INVALID_CURSOR_POSITION, INVALID_DISPLAY_SIZE,
+                     INVALID_DISPLAY_SIZE, ARBITRARY_TIME, ARBITRARY_TIME,
                      /*pointerCount*/ 1, pointerProperties, pointerCoords);
     ASSERT_EQ(InputEventInjectionResult::FAILED,
               mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
@@ -629,8 +628,8 @@
     event.initialize(InputEvent::nextId(), DEVICE_ID, source, DISPLAY_ID, INVALID_HMAC,
                      AMOTION_EVENT_ACTION_DOWN, 0, 0, edgeFlags, metaState, 0, classification,
                      identityTransform, 0, 0, AMOTION_EVENT_INVALID_CURSOR_POSITION,
-                     AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_DISPLAY_SIZE,
-                     AMOTION_EVENT_INVALID_DISPLAY_SIZE, ARBITRARY_TIME, ARBITRARY_TIME,
+                     AMOTION_EVENT_INVALID_CURSOR_POSITION, INVALID_DISPLAY_SIZE,
+                     INVALID_DISPLAY_SIZE, ARBITRARY_TIME, ARBITRARY_TIME,
                      /*pointerCount*/ 1, pointerProperties, pointerCoords);
     ASSERT_EQ(InputEventInjectionResult::FAILED,
               mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
@@ -643,8 +642,8 @@
     event.initialize(InputEvent::nextId(), DEVICE_ID, source, DISPLAY_ID, INVALID_HMAC,
                      AMOTION_EVENT_ACTION_DOWN, 0, 0, edgeFlags, metaState, 0, classification,
                      identityTransform, 0, 0, AMOTION_EVENT_INVALID_CURSOR_POSITION,
-                     AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_DISPLAY_SIZE,
-                     AMOTION_EVENT_INVALID_DISPLAY_SIZE, ARBITRARY_TIME, ARBITRARY_TIME,
+                     AMOTION_EVENT_INVALID_CURSOR_POSITION, INVALID_DISPLAY_SIZE,
+                     INVALID_DISPLAY_SIZE, ARBITRARY_TIME, ARBITRARY_TIME,
                      /*pointerCount*/ 2, pointerProperties, pointerCoords);
     ASSERT_EQ(InputEventInjectionResult::FAILED,
               mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
@@ -892,7 +891,7 @@
     std::string mName;
 };
 
-class FakeWindowHandle : public InputWindowHandle {
+class FakeWindowHandle : public WindowInfoHandle {
 public:
     static const int32_t WIDTH = 600;
     static const int32_t HEIGHT = 800;
@@ -914,7 +913,7 @@
         mInfo.token = *token;
         mInfo.id = sId++;
         mInfo.name = name;
-        mInfo.type = InputWindowInfo::Type::APPLICATION;
+        mInfo.type = WindowInfo::Type::APPLICATION;
         mInfo.dispatchingTimeout = DISPATCHING_TIMEOUT;
         mInfo.alpha = 1.0;
         mInfo.frameLeft = 0;
@@ -948,9 +947,7 @@
 
     void setAlpha(float alpha) { mInfo.alpha = alpha; }
 
-    void setTouchOcclusionMode(android::os::TouchOcclusionMode mode) {
-        mInfo.touchOcclusionMode = mode;
-    }
+    void setTouchOcclusionMode(TouchOcclusionMode mode) { mInfo.touchOcclusionMode = mode; }
 
     void setApplicationToken(sp<IBinder> token) { mInfo.applicationInfo.token = token; }
 
@@ -964,11 +961,11 @@
         mInfo.addTouchableRegion(frame);
     }
 
-    void addFlags(Flags<InputWindowInfo::Flag> flags) { mInfo.flags |= flags; }
+    void addFlags(Flags<WindowInfo::Flag> flags) { mInfo.flags |= flags; }
 
-    void setFlags(Flags<InputWindowInfo::Flag> flags) { mInfo.flags = flags; }
+    void setFlags(Flags<WindowInfo::Flag> flags) { mInfo.flags = flags; }
 
-    void setInputFeatures(InputWindowInfo::Feature features) { mInfo.inputFeatures = features; }
+    void setInputFeatures(WindowInfo::Feature features) { mInfo.inputFeatures = features; }
 
     void setWindowTransform(float dsdx, float dtdx, float dtdy, float dsdy) {
         mInfo.transform.set(dsdx, dtdx, dtdy, dsdy);
@@ -1102,7 +1099,7 @@
 
     void assertNoEvents() {
         if (mInputReceiver == nullptr &&
-            mInfo.inputFeatures.test(InputWindowInfo::Feature::NO_INPUT_CHANNEL)) {
+            mInfo.inputFeatures.test(WindowInfo::Feature::NO_INPUT_CHANNEL)) {
             return; // Can't receive events if the window does not have input channel
         }
         ASSERT_NE(nullptr, mInputReceiver)
@@ -1283,8 +1280,8 @@
     int32_t mFlags{0};
     float mRawXCursorPosition{AMOTION_EVENT_INVALID_CURSOR_POSITION};
     float mRawYCursorPosition{AMOTION_EVENT_INVALID_CURSOR_POSITION};
-    int32_t mDisplayWidth{AMOTION_EVENT_INVALID_DISPLAY_SIZE};
-    int32_t mDisplayHeight{AMOTION_EVENT_INVALID_DISPLAY_SIZE};
+    int32_t mDisplayWidth{INVALID_DISPLAY_SIZE};
+    int32_t mDisplayHeight{INVALID_DISPLAY_SIZE};
 
     std::vector<PointerBuilder> mPointers;
 };
@@ -1410,7 +1407,7 @@
     sp<FakeWindowHandle> window =
             new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
     window->setFrame(Rect(0, 0, 100, 100));
-    window->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL);
+    window->setFlags(WindowInfo::Flag::NOT_TOUCH_MODAL);
 
     mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
     ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
@@ -1433,7 +1430,7 @@
     sp<FakeWindowHandle> window =
             new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
     window->setFrame(Rect(0, 0, 100, 100));
-    window->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL);
+    window->setFlags(WindowInfo::Flag::NOT_TOUCH_MODAL);
 
     mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
     mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
@@ -1469,11 +1466,11 @@
     sp<FakeWindowHandle> windowLeft =
             new FakeWindowHandle(application, mDispatcher, "Left", ADISPLAY_ID_DEFAULT);
     windowLeft->setFrame(Rect(0, 0, 600, 800));
-    windowLeft->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL);
+    windowLeft->setFlags(WindowInfo::Flag::NOT_TOUCH_MODAL);
     sp<FakeWindowHandle> windowRight =
             new FakeWindowHandle(application, mDispatcher, "Right", ADISPLAY_ID_DEFAULT);
     windowRight->setFrame(Rect(600, 0, 1200, 800));
-    windowRight->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL);
+    windowRight->setFlags(WindowInfo::Flag::NOT_TOUCH_MODAL);
 
     mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
 
@@ -1580,7 +1577,7 @@
     sp<FakeWindowHandle> window =
             new FakeWindowHandle(application, mDispatcher, "Window", ADISPLAY_ID_DEFAULT);
     window->setFrame(Rect(0, 0, 1200, 800));
-    window->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL);
+    window->setFlags(WindowInfo::Flag::NOT_TOUCH_MODAL);
 
     mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
 
@@ -1662,11 +1659,11 @@
     sp<FakeWindowHandle> windowLeft =
             new FakeWindowHandle(application, mDispatcher, "Left", ADISPLAY_ID_DEFAULT);
     windowLeft->setFrame(Rect(0, 0, 600, 800));
-    windowLeft->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL);
+    windowLeft->setFlags(WindowInfo::Flag::NOT_TOUCH_MODAL);
     sp<FakeWindowHandle> windowRight =
             new FakeWindowHandle(application, mDispatcher, "Right", ADISPLAY_ID_DEFAULT);
     windowRight->setFrame(Rect(600, 0, 1200, 800));
-    windowRight->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL);
+    windowRight->setFlags(WindowInfo::Flag::NOT_TOUCH_MODAL);
 
     mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
 
@@ -1860,15 +1857,13 @@
     sp<FakeWindowHandle> firstWindow =
             new FakeWindowHandle(application, mDispatcher, "First Window", ADISPLAY_ID_DEFAULT);
     firstWindow->setFrame(Rect(0, 0, 600, 400));
-    firstWindow->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL |
-                          InputWindowInfo::Flag::SPLIT_TOUCH);
+    firstWindow->setFlags(WindowInfo::Flag::NOT_TOUCH_MODAL | WindowInfo::Flag::SPLIT_TOUCH);
 
     // Create a non touch modal window that supports split touch
     sp<FakeWindowHandle> secondWindow =
             new FakeWindowHandle(application, mDispatcher, "Second Window", ADISPLAY_ID_DEFAULT);
     secondWindow->setFrame(Rect(0, 400, 600, 800));
-    secondWindow->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL |
-                           InputWindowInfo::Flag::SPLIT_TOUCH);
+    secondWindow->setFlags(WindowInfo::Flag::NOT_TOUCH_MODAL | WindowInfo::Flag::SPLIT_TOUCH);
 
     // Add the windows to the dispatcher
     mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {firstWindow, secondWindow}}});
@@ -1934,15 +1929,13 @@
     sp<FakeWindowHandle> firstWindow =
             new FakeWindowHandle(application, mDispatcher, "First Window", ADISPLAY_ID_DEFAULT);
     firstWindow->setFrame(Rect(0, 0, 600, 400));
-    firstWindow->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL |
-                          InputWindowInfo::Flag::SPLIT_TOUCH);
+    firstWindow->setFlags(WindowInfo::Flag::NOT_TOUCH_MODAL | WindowInfo::Flag::SPLIT_TOUCH);
 
     // Create a non touch modal window that supports split touch
     sp<FakeWindowHandle> secondWindow =
             new FakeWindowHandle(application, mDispatcher, "Second Window", ADISPLAY_ID_DEFAULT);
     secondWindow->setFrame(Rect(0, 400, 600, 800));
-    secondWindow->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL |
-                           InputWindowInfo::Flag::SPLIT_TOUCH);
+    secondWindow->setFlags(WindowInfo::Flag::NOT_TOUCH_MODAL | WindowInfo::Flag::SPLIT_TOUCH);
 
     // Add the windows to the dispatcher
     mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {firstWindow, secondWindow}}});
@@ -2060,15 +2053,13 @@
     sp<FakeWindowHandle> firstWindow =
             new FakeWindowHandle(application, mDispatcher, "First Window", ADISPLAY_ID_DEFAULT);
     firstWindow->setFrame(Rect(0, 0, 600, 400));
-    firstWindow->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL |
-                          InputWindowInfo::Flag::SPLIT_TOUCH);
+    firstWindow->setFlags(WindowInfo::Flag::NOT_TOUCH_MODAL | WindowInfo::Flag::SPLIT_TOUCH);
 
     // Create second non touch modal window that supports split touch
     sp<FakeWindowHandle> secondWindow =
             new FakeWindowHandle(application, mDispatcher, "Second Window", ADISPLAY_ID_DEFAULT);
     secondWindow->setFrame(Rect(0, 400, 600, 800));
-    secondWindow->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL |
-                           InputWindowInfo::Flag::SPLIT_TOUCH);
+    secondWindow->setFlags(WindowInfo::Flag::NOT_TOUCH_MODAL | WindowInfo::Flag::SPLIT_TOUCH);
 
     // Add the windows to the dispatcher
     mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {firstWindow, secondWindow}}});
@@ -2736,8 +2727,7 @@
 
     sp<FakeWindowHandle> slipperyExitWindow =
             new FakeWindowHandle(application, mDispatcher, "Top", ADISPLAY_ID_DEFAULT);
-    slipperyExitWindow->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL |
-                                 InputWindowInfo::Flag::SLIPPERY);
+    slipperyExitWindow->setFlags(WindowInfo::Flag::NOT_TOUCH_MODAL | WindowInfo::Flag::SLIPPERY);
     // Make sure this one overlaps the bottom window
     slipperyExitWindow->setFrame(Rect(25, 25, 75, 75));
     // Change the owner uid/pid of the window so that it is considered to be occluding the bottom
@@ -3231,12 +3221,12 @@
         mUnfocusedWindow->setFrame(Rect(0, 0, 30, 30));
         // Adding FLAG_NOT_TOUCH_MODAL to ensure taps outside this window are not sent to this
         // window.
-        mUnfocusedWindow->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL);
+        mUnfocusedWindow->setFlags(WindowInfo::Flag::NOT_TOUCH_MODAL);
 
         mFocusedWindow =
                 new FakeWindowHandle(application, mDispatcher, "Second", ADISPLAY_ID_DEFAULT);
         mFocusedWindow->setFrame(Rect(50, 50, 100, 100));
-        mFocusedWindow->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL);
+        mFocusedWindow->setFlags(WindowInfo::Flag::NOT_TOUCH_MODAL);
 
         // Set focused application.
         mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
@@ -3345,14 +3335,12 @@
                                         ADISPLAY_ID_DEFAULT);
         // Adding FLAG_NOT_TOUCH_MODAL otherwise all taps will go to the top most window.
         // We also need FLAG_SPLIT_TOUCH or we won't be able to get touches for both windows.
-        mWindow1->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL |
-                           InputWindowInfo::Flag::SPLIT_TOUCH);
+        mWindow1->setFlags(WindowInfo::Flag::NOT_TOUCH_MODAL | WindowInfo::Flag::SPLIT_TOUCH);
         mWindow1->setFrame(Rect(0, 0, 100, 100));
 
         mWindow2 = new FakeWindowHandle(application, mDispatcher, "Fake Window 2",
                                         ADISPLAY_ID_DEFAULT, mWindow1->getToken());
-        mWindow2->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL |
-                           InputWindowInfo::Flag::SPLIT_TOUCH);
+        mWindow2->setFlags(WindowInfo::Flag::NOT_TOUCH_MODAL | WindowInfo::Flag::SPLIT_TOUCH);
         mWindow2->setFrame(Rect(100, 100, 200, 200));
 
         mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mWindow1, mWindow2}}});
@@ -3363,7 +3351,7 @@
     sp<FakeWindowHandle> mWindow2;
 
     // Helper function to convert the point from screen coordinates into the window's space
-    static PointF getPointInWindow(const InputWindowInfo* windowInfo, const PointF& point) {
+    static PointF getPointInWindow(const WindowInfo* windowInfo, const PointF& point) {
         vec2 vals = windowInfo->transform.transform(point.x, point.y);
         return {vals.x, vals.y};
     }
@@ -3551,7 +3539,7 @@
         mWindow->setFocusable(true);
         // Adding FLAG_NOT_TOUCH_MODAL to ensure taps outside this window are not sent to this
         // window.
-        mWindow->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL);
+        mWindow->setFlags(WindowInfo::Flag::NOT_TOUCH_MODAL);
 
         // Set focused application.
         mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, mApplication);
@@ -3952,16 +3940,15 @@
         // Adding FLAG_NOT_TOUCH_MODAL to ensure taps outside this window are not sent to this
         // window.
         // Adding FLAG_WATCH_OUTSIDE_TOUCH to receive ACTION_OUTSIDE when another window is tapped
-        mUnfocusedWindow->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL |
-                                   InputWindowInfo::Flag::WATCH_OUTSIDE_TOUCH |
-                                   InputWindowInfo::Flag::SPLIT_TOUCH);
+        mUnfocusedWindow->setFlags(WindowInfo::Flag::NOT_TOUCH_MODAL |
+                                   WindowInfo::Flag::WATCH_OUTSIDE_TOUCH |
+                                   WindowInfo::Flag::SPLIT_TOUCH);
 
         mFocusedWindow =
                 new FakeWindowHandle(mApplication, mDispatcher, "Focused", ADISPLAY_ID_DEFAULT);
         mFocusedWindow->setDispatchingTimeout(30ms);
         mFocusedWindow->setFrame(Rect(50, 50, 100, 100));
-        mFocusedWindow->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL |
-                                 InputWindowInfo::Flag::SPLIT_TOUCH);
+        mFocusedWindow->setFlags(WindowInfo::Flag::NOT_TOUCH_MODAL | WindowInfo::Flag::SPLIT_TOUCH);
 
         // Set focused application.
         mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, mApplication);
@@ -4329,7 +4316,7 @@
                                               "Window without input channel", ADISPLAY_ID_DEFAULT,
                                               std::make_optional<sp<IBinder>>(nullptr) /*token*/);
 
-        mNoInputWindow->setInputFeatures(InputWindowInfo::Feature::NO_INPUT_CHANNEL);
+        mNoInputWindow->setInputFeatures(WindowInfo::Feature::NO_INPUT_CHANNEL);
         mNoInputWindow->setFrame(Rect(0, 0, 100, 100));
         // It's perfectly valid for this window to not have an associated input channel
 
@@ -4371,7 +4358,7 @@
                                           "Window with input channel and NO_INPUT_CHANNEL",
                                           ADISPLAY_ID_DEFAULT);
 
-    mNoInputWindow->setInputFeatures(InputWindowInfo::Feature::NO_INPUT_CHANNEL);
+    mNoInputWindow->setInputFeatures(WindowInfo::Feature::NO_INPUT_CHANNEL);
     mNoInputWindow->setFrame(Rect(0, 0, 100, 100));
     mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mNoInputWindow, mBottomWindow}}});
 
@@ -4671,10 +4658,10 @@
         mTouchWindow.clear();
     }
 
-    sp<FakeWindowHandle> getOccludingWindow(int32_t uid, std::string name,
-                                            os::TouchOcclusionMode mode, float alpha = 1.0f) {
+    sp<FakeWindowHandle> getOccludingWindow(int32_t uid, std::string name, TouchOcclusionMode mode,
+                                            float alpha = 1.0f) {
         sp<FakeWindowHandle> window = getWindow(uid, name);
-        window->setFlags(InputWindowInfo::Flag::NOT_TOUCHABLE);
+        window->setFlags(WindowInfo::Flag::NOT_TOUCHABLE);
         window->setTouchOcclusionMode(mode);
         window->setAlpha(alpha);
         return window;
@@ -4788,7 +4775,7 @@
        WindowWithZeroOpacityAndWatchOutside_ReceivesOutsideEvent) {
     const sp<FakeWindowHandle>& w =
             getOccludingWindow(APP_B_UID, "B", TouchOcclusionMode::BLOCK_UNTRUSTED, 0.0f);
-    w->addFlags(InputWindowInfo::Flag::WATCH_OUTSIDE_TOUCH);
+    w->addFlags(WindowInfo::Flag::WATCH_OUTSIDE_TOUCH);
     mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {w, mTouchWindow}}});
 
     touch();
@@ -4799,7 +4786,7 @@
 TEST_F(InputDispatcherUntrustedTouchesTest, OutsideEvent_HasZeroCoordinates) {
     const sp<FakeWindowHandle>& w =
             getOccludingWindow(APP_B_UID, "B", TouchOcclusionMode::BLOCK_UNTRUSTED, 0.0f);
-    w->addFlags(InputWindowInfo::Flag::WATCH_OUTSIDE_TOUCH);
+    w->addFlags(WindowInfo::Flag::WATCH_OUTSIDE_TOUCH);
     mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {w, mTouchWindow}}});
 
     touch();
@@ -5053,11 +5040,11 @@
         mApp = std::make_shared<FakeApplicationHandle>();
         mWindow = new FakeWindowHandle(mApp, mDispatcher, "TestWindow", ADISPLAY_ID_DEFAULT);
         mWindow->setFrame(Rect(0, 0, 100, 100));
-        mWindow->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL);
+        mWindow->setFlags(WindowInfo::Flag::NOT_TOUCH_MODAL);
 
         mSecondWindow = new FakeWindowHandle(mApp, mDispatcher, "TestWindow2", ADISPLAY_ID_DEFAULT);
         mSecondWindow->setFrame(Rect(100, 0, 200, 100));
-        mSecondWindow->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL);
+        mSecondWindow->setFlags(WindowInfo::Flag::NOT_TOUCH_MODAL);
 
         mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, mApp);
         mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mWindow, mSecondWindow}}});
diff --git a/services/inputflinger/tests/InputFlingerService_test.cpp b/services/inputflinger/tests/InputFlingerService_test.cpp
index c368e79..d2a98df 100644
--- a/services/inputflinger/tests/InputFlingerService_test.cpp
+++ b/services/inputflinger/tests/InputFlingerService_test.cpp
@@ -28,9 +28,9 @@
 #include <binder/Parcel.h>
 #include <binder/ProcessState.h>
 
+#include <gui/WindowInfo.h>
 #include <input/Input.h>
 #include <input/InputTransport.h>
-#include <input/InputWindow.h>
 
 #include <gtest/gtest.h>
 #include <inttypes.h>
@@ -44,6 +44,9 @@
 
 #define TAG "InputFlingerServiceTest"
 
+using android::gui::FocusRequest;
+using android::gui::WindowInfo;
+using android::gui::WindowInfoHandle;
 using android::os::BnInputFlinger;
 using android::os::BnSetInputWindowsListener;
 using android::os::IInputFlinger;
@@ -58,8 +61,8 @@
 static const sp<IBinder> FocusedTestInfoToken = new BBinder();
 static constexpr int32_t TestInfoId = 1;
 static const std::string TestInfoName = "InputFlingerServiceTestInputWindowInfo";
-static constexpr Flags<InputWindowInfo::Flag> TestInfoFlags = InputWindowInfo::Flag::NOT_FOCUSABLE;
-static constexpr InputWindowInfo::Type TestInfoType = InputWindowInfo::Type::INPUT_METHOD;
+static constexpr Flags<WindowInfo::Flag> TestInfoFlags = WindowInfo::Flag::NOT_FOCUSABLE;
+static constexpr WindowInfo::Type TestInfoType = WindowInfo::Type::INPUT_METHOD;
 static constexpr std::chrono::duration TestInfoDispatchingTimeout = 2532ms;
 static constexpr int32_t TestInfoFrameLeft = 93;
 static constexpr int32_t TestInfoFrameTop = 34;
@@ -79,8 +82,7 @@
 static constexpr bool TestInfoPaused = false;
 static constexpr int32_t TestInfoOwnerPid = 19;
 static constexpr int32_t TestInfoOwnerUid = 24;
-static constexpr InputWindowInfo::Feature TestInfoInputFeatures =
-        InputWindowInfo::Feature::NO_INPUT_CHANNEL;
+static constexpr WindowInfo::Feature TestInfoInputFeatures = WindowInfo::Feature::NO_INPUT_CHANNEL;
 static constexpr int32_t TestInfoDisplayId = 34;
 static constexpr int32_t TestInfoPortalToDisplayId = 2;
 static constexpr bool TestInfoReplaceTouchableRegionWithCrop = true;
@@ -102,13 +104,13 @@
 
 protected:
     void InitializeInputFlinger();
-    void setInputWindowsByInfos(const std::vector<InputWindowInfo>& infos);
+    void setInputWindowsByInfos(const std::vector<WindowInfo>& infos);
     void setFocusedWindow(const sp<IBinder> token, const sp<IBinder> focusedToken,
                           nsecs_t timestampNanos);
 
     void setInputWindowsFinished();
-    void verifyInputWindowInfo(const InputWindowInfo& info) const;
-    InputWindowInfo& getInfo() const { return const_cast<InputWindowInfo&>(mInfo); }
+    void verifyInputWindowInfo(const WindowInfo& info) const;
+    WindowInfo& getInfo() const { return const_cast<WindowInfo&>(mInfo); }
 
     sp<IInputFlinger> mService;
     sp<IInputFlingerQuery> mQuery;
@@ -116,7 +118,7 @@
 private:
     sp<SetInputWindowsListener> mSetInputWindowsListener;
     std::unique_ptr<InputChannel> mServerChannel, mClientChannel;
-    InputWindowInfo mInfo;
+    WindowInfo mInfo;
     std::mutex mLock;
     std::condition_variable mSetInputWindowsFinishedCondition;
 };
@@ -136,14 +138,14 @@
 public:
     TestInputManager(){};
 
-    binder::Status getInputWindows(std::vector<::android::InputWindowInfo>* inputHandles);
+    binder::Status getInputWindows(std::vector<WindowInfo>* inputHandles);
     binder::Status getInputChannels(std::vector<::android::InputChannel>* channels);
     binder::Status getLastFocusRequest(FocusRequest*);
 
     status_t dump(int fd, const Vector<String16>& args) override;
 
     binder::Status setInputWindows(
-            const std::vector<InputWindowInfo>& handles,
+            const std::vector<WindowInfo>& handles,
             const sp<ISetInputWindowsListener>& setInputWindowsListener) override;
 
     binder::Status createInputChannel(const std::string& name, InputChannel* outChannel) override;
@@ -154,7 +156,7 @@
 
 private:
     mutable Mutex mLock;
-    std::unordered_map<int32_t, std::vector<sp<InputWindowHandle>>> mHandlesPerDisplay;
+    std::unordered_map<int32_t, std::vector<sp<WindowInfoHandle>>> mHandlesPerDisplay;
     std::vector<std::shared_ptr<InputChannel>> mInputChannels;
     FocusRequest mFocusRequest;
 };
@@ -162,7 +164,7 @@
 class TestInputQuery : public BnInputFlingerQuery {
 public:
     TestInputQuery(sp<android::TestInputManager> manager) : mManager(manager){};
-    binder::Status getInputWindows(std::vector<::android::InputWindowInfo>* inputHandles) override;
+    binder::Status getInputWindows(std::vector<WindowInfo>* inputHandles) override;
     binder::Status getInputChannels(std::vector<::android::InputChannel>* channels) override;
     binder::Status getLastFocusRequest(FocusRequest*) override;
     binder::Status resetInputManager() override;
@@ -171,8 +173,7 @@
     sp<android::TestInputManager> mManager;
 };
 
-binder::Status TestInputQuery::getInputWindows(
-        std::vector<::android::InputWindowInfo>* inputHandles) {
+binder::Status TestInputQuery::getInputWindows(std::vector<WindowInfo>* inputHandles) {
     return mManager->getInputWindows(inputHandles);
 }
 
@@ -197,13 +198,13 @@
 }
 
 binder::Status TestInputManager::setInputWindows(
-        const std::vector<InputWindowInfo>& infos,
+        const std::vector<WindowInfo>& infos,
         const sp<ISetInputWindowsListener>& setInputWindowsListener) {
     AutoMutex _l(mLock);
 
     for (const auto& info : infos) {
-        mHandlesPerDisplay.emplace(info.displayId, std::vector<sp<InputWindowHandle>>());
-        mHandlesPerDisplay[info.displayId].push_back(new InputWindowHandle(info));
+        mHandlesPerDisplay.emplace(info.displayId, std::vector<sp<WindowInfoHandle>>());
+        mHandlesPerDisplay[info.displayId].push_back(new WindowInfoHandle(info));
     }
     if (setInputWindowsListener) {
         setInputWindowsListener->onSetInputWindowsFinished();
@@ -248,8 +249,7 @@
     return NO_ERROR;
 }
 
-binder::Status TestInputManager::getInputWindows(
-        std::vector<::android::InputWindowInfo>* inputInfos) {
+binder::Status TestInputManager::getInputWindows(std::vector<WindowInfo>* inputInfos) {
     for (auto& [displayId, inputHandles] : mHandlesPerDisplay) {
         for (auto& inputHandle : inputHandles) {
             inputInfos->push_back(*inputHandle->getInfo());
@@ -331,7 +331,7 @@
     mQuery->resetInputManager();
 }
 
-void InputFlingerServiceTest::verifyInputWindowInfo(const InputWindowInfo& info) const {
+void InputFlingerServiceTest::verifyInputWindowInfo(const WindowInfo& info) const {
     EXPECT_EQ(mInfo, info);
 }
 
@@ -345,7 +345,7 @@
     mQuery = interface_cast<IInputFlingerQuery>(input);
 }
 
-void InputFlingerServiceTest::setInputWindowsByInfos(const std::vector<InputWindowInfo>& infos) {
+void InputFlingerServiceTest::setInputWindowsByInfos(const std::vector<WindowInfo>& infos) {
     std::unique_lock<std::mutex> lock(mLock);
     mService->setInputWindows(infos, mSetInputWindowsListener);
     // Verify listener call
@@ -361,20 +361,20 @@
     request.timestamp = timestampNanos;
     mService->setFocusedWindow(request);
     // call set input windows and wait for the callback to drain the queue.
-    setInputWindowsByInfos(std::vector<InputWindowInfo>());
+    setInputWindowsByInfos(std::vector<WindowInfo>());
 }
 
 /**
  *  Test InputFlinger service interface SetInputWindows
  */
 TEST_F(InputFlingerServiceTest, InputWindow_SetInputWindows) {
-    std::vector<InputWindowInfo> infos = {getInfo()};
+    std::vector<WindowInfo> infos = {getInfo()};
     setInputWindowsByInfos(infos);
 
     // Verify input windows from service
-    std::vector<::android::InputWindowInfo> windowInfos;
+    std::vector<WindowInfo> windowInfos;
     mQuery->getInputWindows(&windowInfos);
-    for (const ::android::InputWindowInfo& windowInfo : windowInfos) {
+    for (const WindowInfo& windowInfo : windowInfos) {
         verifyInputWindowInfo(windowInfo);
     }
 }
diff --git a/services/inputflinger/tests/InputReader_test.cpp b/services/inputflinger/tests/InputReader_test.cpp
index 73198bc..02423c4 100644
--- a/services/inputflinger/tests/InputReader_test.cpp
+++ b/services/inputflinger/tests/InputReader_test.cpp
@@ -32,6 +32,7 @@
 #include <VibratorInputMapper.h>
 #include <android-base/thread_annotations.h>
 #include <gtest/gtest.h>
+#include <gui/constants.h>
 #include <inttypes.h>
 #include <math.h>
 
diff --git a/services/surfaceflinger/Android.bp b/services/surfaceflinger/Android.bp
index e669e45..63f7efc 100644
--- a/services/surfaceflinger/Android.bp
+++ b/services/surfaceflinger/Android.bp
@@ -211,7 +211,6 @@
         "libcutils",
         "libdisplayservicehidl",
         "libhidlbase",
-        "libinput",
         "liblayers_proto",
         "liblog",
         "libprocessgroup",
diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp
index 23779be..3cb7e9c 100644
--- a/services/surfaceflinger/BufferLayer.cpp
+++ b/services/surfaceflinger/BufferLayer.cpp
@@ -58,6 +58,8 @@
 
 namespace android {
 
+using gui::WindowInfo;
+
 static constexpr float defaultMaxLuminance = 1000.0;
 
 BufferLayer::BufferLayer(const LayerCreationArgs& args)
@@ -825,7 +827,7 @@
     wp<Layer> tmpZOrderRelativeOf = mDrawingState.zOrderRelativeOf;
     SortedVector<wp<Layer>> tmpZOrderRelatives = mDrawingState.zOrderRelatives;
     wp<Layer> tmpTouchableRegionCrop = mDrawingState.touchableRegionCrop;
-    InputWindowInfo tmpInputInfo = mDrawingState.inputInfo;
+    WindowInfo tmpInputInfo = mDrawingState.inputInfo;
 
     mDrawingState = clonedFrom->mDrawingState;
 
diff --git a/services/surfaceflinger/BufferQueueLayer.cpp b/services/surfaceflinger/BufferQueueLayer.cpp
index c64371b..b236fd2 100644
--- a/services/surfaceflinger/BufferQueueLayer.cpp
+++ b/services/surfaceflinger/BufferQueueLayer.cpp
@@ -125,11 +125,11 @@
 // -----------------------------------------------------------------------
 
 bool BufferQueueLayer::fenceHasSignaled() const {
+    Mutex::Autolock lock(mQueueItemLock);
     if (!hasFrameUpdate()) {
         return true;
     }
 
-    Mutex::Autolock lock(mQueueItemLock);
     if (mQueueItems[0].item.mIsDroppable) {
         // Even though this buffer's fence may not have signaled yet, it could
         // be replaced by another buffer before it has a chance to, which means
@@ -148,11 +148,12 @@
 }
 
 bool BufferQueueLayer::framePresentTimeIsCurrent(nsecs_t expectedPresentTime) const {
+    Mutex::Autolock lock(mQueueItemLock);
+
     if (!hasFrameUpdate() || isRemovedFromCurrentState()) {
         return true;
     }
 
-    Mutex::Autolock lock(mQueueItemLock);
     return mQueueItems[0].item.mTimestamp <= expectedPresentTime;
 }
 
@@ -264,13 +265,15 @@
         // and return early
         if (queuedBuffer) {
             Mutex::Autolock lock(mQueueItemLock);
-            mConsumer->mergeSurfaceDamage(mQueueItems[0].item.mSurfaceDamage);
-            mFlinger->mTimeStats->removeTimeRecord(layerId, mQueueItems[0].item.mFrameNumber);
-            if (mQueueItems[0].surfaceFrame) {
-                addSurfaceFrameDroppedForBuffer(mQueueItems[0].surfaceFrame);
+            if (mQueuedFrames > 0) {
+                mConsumer->mergeSurfaceDamage(mQueueItems[0].item.mSurfaceDamage);
+                mFlinger->mTimeStats->removeTimeRecord(layerId, mQueueItems[0].item.mFrameNumber);
+                if (mQueueItems[0].surfaceFrame) {
+                    addSurfaceFrameDroppedForBuffer(mQueueItems[0].surfaceFrame);
+                }
+                mQueueItems.erase(mQueueItems.begin());
+                mQueuedFrames--;
             }
-            mQueueItems.erase(mQueueItems.begin());
-            mQueuedFrames--;
         }
         return BAD_VALUE;
     } else if (updateResult != NO_ERROR || mUpdateTexImageFailed) {
@@ -300,6 +303,7 @@
         return BAD_VALUE;
     }
 
+    bool more_frames_pending = false;
     if (queuedBuffer) {
         // Autolock scope
         auto currentFrameNumber = mConsumer->getFrameNumber();
@@ -308,7 +312,7 @@
 
         // Remove any stale buffers that have been dropped during
         // updateTexImage
-        while (mQueueItems[0].item.mFrameNumber != currentFrameNumber) {
+        while (mQueuedFrames > 0 && mQueueItems[0].item.mFrameNumber != currentFrameNumber) {
             mConsumer->mergeSurfaceDamage(mQueueItems[0].item.mSurfaceDamage);
             mFlinger->mTimeStats->removeTimeRecord(layerId, mQueueItems[0].item.mFrameNumber);
             if (mQueueItems[0].surfaceFrame) {
@@ -329,11 +333,12 @@
                                               latchTime);
         }
         mQueueItems.erase(mQueueItems.begin());
+        more_frames_pending = (mQueuedFrames.fetch_sub(1) > 1);
     }
 
     // Decrement the queued-frames count.  Signal another event if we
     // have more frames pending.
-    if ((queuedBuffer && mQueuedFrames.fetch_sub(1) > 1) || mAutoRefresh) {
+    if ((queuedBuffer && more_frames_pending) || mAutoRefresh) {
         mFlinger->signalLayerUpdate();
     }
 
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/DisplayCreationArgs.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/DisplayCreationArgs.h
index 14eddb1..526e7da 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/DisplayCreationArgs.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/DisplayCreationArgs.h
@@ -40,7 +40,7 @@
     std::optional<ui::DisplayConnectionType> connectionType;
 
     // Size of the display in pixels
-    ui::Size pixels = ui::Size::INVALID;
+    ui::Size pixels = ui::kInvalidSize;
 
     // True if this display should be considered secure
     bool isSecure = false;
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/LayerState.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/LayerState.h
index bce438f..5237527 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/LayerState.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/LayerState.h
@@ -21,7 +21,7 @@
 #include <compositionengine/LayerFECompositionState.h>
 #include <compositionengine/OutputLayer.h>
 #include <compositionengine/impl/OutputLayerCompositionState.h>
-#include <input/Flags.h>
+#include <ftl/Flags.h>
 
 #include <string>
 
diff --git a/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp b/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp
index db9437b..f4a5835 100644
--- a/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp
@@ -60,7 +60,7 @@
 constexpr HalVirtualDisplayId HAL_VIRTUAL_DISPLAY_ID{456u};
 constexpr GpuVirtualDisplayId GPU_VIRTUAL_DISPLAY_ID{789u};
 
-const ui::Size DEFAULT_RESOLUTION{1920, 1080};
+constexpr ui::Size DEFAULT_RESOLUTION{1920, 1080};
 constexpr uint32_t DEFAULT_LAYER_STACK = 42;
 
 struct Layer {
diff --git a/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h b/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h
index 64cbea9..72de0b1 100644
--- a/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h
+++ b/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h
@@ -51,6 +51,7 @@
                  bool(HalVirtualDisplayId, ui::Size, ui::PixelFormat*,
                       std::optional<PhysicalDisplayId>));
     MOCK_METHOD2(allocatePhysicalDisplay, void(hal::HWDisplayId, PhysicalDisplayId));
+
     MOCK_METHOD1(createLayer, std::shared_ptr<HWC2::Layer>(HalDisplayId));
     MOCK_METHOD4(getDeviceCompositionChanges,
                  status_t(HalDisplayId, bool, std::chrono::steady_clock::time_point,
diff --git a/services/surfaceflinger/CompositionEngine/tests/RenderSurfaceTest.cpp b/services/surfaceflinger/CompositionEngine/tests/RenderSurfaceTest.cpp
index 5090bb2..431cc93 100644
--- a/services/surfaceflinger/CompositionEngine/tests/RenderSurfaceTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/RenderSurfaceTest.cpp
@@ -35,7 +35,7 @@
 
 constexpr int32_t DEFAULT_DISPLAY_WIDTH = 1920;
 constexpr int32_t DEFAULT_DISPLAY_HEIGHT = 1080;
-constexpr DisplayId DEFAULT_DISPLAY_ID = PhysicalDisplayId(123u);
+constexpr DisplayId DEFAULT_DISPLAY_ID = PhysicalDisplayId::fromPort(123u);
 const std::string DEFAULT_DISPLAY_NAME = "Mock Display";
 
 using testing::_;
diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h
index 70dcc1e..b068daf 100644
--- a/services/surfaceflinger/DisplayDevice.h
+++ b/services/surfaceflinger/DisplayDevice.h
@@ -297,16 +297,4 @@
     DisplayModes supportedModes;
 };
 
-// Predicates for display lookup.
-
-struct WithLayerStack {
-    explicit WithLayerStack(ui::LayerStack layerStack) : layerStack(layerStack) {}
-
-    bool operator()(const DisplayDevice& display) const {
-        return display.getLayerStack() == layerStack;
-    }
-
-    ui::LayerStack layerStack;
-};
-
 } // namespace android
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index ad31b3f..f1bfebc 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -71,7 +71,6 @@
 #include "SurfaceFlinger.h"
 #include "TimeStats/TimeStats.h"
 #include "TunnelModeEnabledReporter.h"
-#include "input/InputWindow.h"
 
 #define DEBUG_RESIZE 0
 
@@ -83,6 +82,7 @@
 using base::StringAppendF;
 using namespace android::flag_operators;
 using PresentState = frametimeline::SurfaceFrame::PresentState;
+using gui::WindowInfo;
 
 std::atomic<int32_t> Layer::sSequence{1};
 
@@ -90,8 +90,8 @@
       : mFlinger(args.flinger),
         mName(args.name),
         mClientRef(args.client),
-        mWindowType(static_cast<InputWindowInfo::Type>(
-                args.metadata.getInt32(METADATA_WINDOW_TYPE, 0))) {
+        mWindowType(
+                static_cast<WindowInfo::Type>(args.metadata.getInt32(METADATA_WINDOW_TYPE, 0))) {
     uint32_t layerFlags = 0;
     if (args.flags & ISurfaceComposerClient::eHidden) layerFlags |= layer_state_t::eLayerHidden;
     if (args.flags & ISurfaceComposerClient::eOpaque) layerFlags |= layer_state_t::eLayerOpaque;
@@ -1986,7 +1986,7 @@
     return handle->owner;
 }
 
-void Layer::setInputInfo(const InputWindowInfo& info) {
+void Layer::setInputInfo(const WindowInfo& info) {
     mDrawingState.inputInfo = info;
     mDrawingState.touchableRegionCrop = extractLayerFromBinder(info.touchableRegionCropHandle);
     mDrawingState.modified = true;
@@ -2136,7 +2136,7 @@
     }
 
     if (traceFlags & SurfaceTracing::TRACE_INPUT) {
-        InputWindowInfo info;
+        WindowInfo info;
         if (useDrawing) {
             info = fillInputInfo({nullptr});
         } else {
@@ -2167,7 +2167,7 @@
     return getCroppedBufferSize(getDrawingState());
 }
 
-void Layer::fillInputFrameInfo(InputWindowInfo& info, const ui::Transform& toPhysicalDisplay) {
+void Layer::fillInputFrameInfo(WindowInfo& info, const ui::Transform& toPhysicalDisplay) {
     // Transform layer size to screen space and inset it by surface insets.
     // If this is a portal window, set the touchableRegion to the layerBounds.
     Rect layerBounds = info.portalToDisplayId == ADISPLAY_ID_NONE
@@ -2262,7 +2262,7 @@
     info.touchableRegion = inputTransform.transform(info.touchableRegion);
 }
 
-void Layer::fillTouchOcclusionMode(InputWindowInfo& info) {
+void Layer::fillTouchOcclusionMode(WindowInfo& info) {
     sp<Layer> p = this;
     while (p != nullptr && !p->hasInputInfo()) {
         p = p->mDrawingParent.promote();
@@ -2272,17 +2272,17 @@
     }
 }
 
-InputWindowInfo Layer::fillInputInfo(const sp<DisplayDevice>& display) {
+WindowInfo Layer::fillInputInfo(const sp<DisplayDevice>& display) {
     if (!hasInputInfo()) {
         mDrawingState.inputInfo.name = getName();
         mDrawingState.inputInfo.ownerUid = mOwnerUid;
         mDrawingState.inputInfo.ownerPid = mOwnerPid;
-        mDrawingState.inputInfo.inputFeatures = InputWindowInfo::Feature::NO_INPUT_CHANNEL;
-        mDrawingState.inputInfo.flags = InputWindowInfo::Flag::NOT_TOUCH_MODAL;
+        mDrawingState.inputInfo.inputFeatures = WindowInfo::Feature::NO_INPUT_CHANNEL;
+        mDrawingState.inputInfo.flags = WindowInfo::Flag::NOT_TOUCH_MODAL;
         mDrawingState.inputInfo.displayId = getLayerStack();
     }
 
-    InputWindowInfo info = mDrawingState.inputInfo;
+    WindowInfo info = mDrawingState.inputInfo;
     info.id = sequence;
 
     if (info.displayId == ADISPLAY_ID_NONE) {
@@ -2456,7 +2456,7 @@
     }
     // Cloned layers shouldn't handle watch outside since their z order is not determined by
     // WM or the client.
-    mDrawingState.inputInfo.flags &= ~InputWindowInfo::Flag::WATCH_OUTSIDE_TOUCH;
+    mDrawingState.inputInfo.flags &= ~WindowInfo::Flag::WATCH_OUTSIDE_TOUCH;
 }
 
 void Layer::updateClonedRelatives(const std::map<sp<Layer>, sp<Layer>>& clonedLayersMap) {
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index ec9bb7c..82d0fc3 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -21,7 +21,7 @@
 #include <gui/BufferQueue.h>
 #include <gui/ISurfaceComposerClient.h>
 #include <gui/LayerState.h>
-#include <input/InputWindow.h>
+#include <gui/WindowInfo.h>
 #include <layerproto/LayerProtoHeader.h>
 #include <math/vec4.h>
 #include <renderengine/Mesh.h>
@@ -186,7 +186,7 @@
         float cornerRadius;
         int backgroundBlurRadius;
 
-        InputWindowInfo inputInfo;
+        gui::WindowInfo inputInfo;
         wp<Layer> touchableRegionCrop;
 
         // dataspace is only used by BufferStateLayer and EffectLayer
@@ -686,7 +686,7 @@
     void writeToProtoCommonState(LayerProto* layerInfo, LayerVector::StateSet,
                                  uint32_t traceFlags = SurfaceTracing::TRACE_ALL);
 
-    InputWindowInfo::Type getWindowType() const { return mWindowType; }
+    gui::WindowInfo::Type getWindowType() const { return mWindowType; }
 
     bool getPrimaryDisplayOnly() const;
 
@@ -838,9 +838,9 @@
     sp<IBinder> getHandle();
     const std::string& getName() const { return mName; }
     bool getPremultipledAlpha() const;
-    void setInputInfo(const InputWindowInfo& info);
+    void setInputInfo(const gui::WindowInfo& info);
 
-    InputWindowInfo fillInputInfo(const sp<DisplayDevice>& display);
+    gui::WindowInfo fillInputInfo(const sp<DisplayDevice>& display);
     /**
      * Returns whether this layer has an explicitly set input-info.
      */
@@ -1003,7 +1003,7 @@
     wp<Layer> mDrawingParent;
 
     // Window types from WindowManager.LayoutParams
-    const InputWindowInfo::Type mWindowType;
+    const gui::WindowInfo::Type mWindowType;
 
     // The owner of the layer. If created from a non system process, it will be the calling uid.
     // If created from a system process, the value can be passed in.
@@ -1054,10 +1054,10 @@
 
     // Fills in the touch occlusion mode of the first parent (including this layer) that
     // hasInputInfo() or no-op if no such parent is found.
-    void fillTouchOcclusionMode(InputWindowInfo& info);
+    void fillTouchOcclusionMode(gui::WindowInfo& info);
 
-    // Fills in the frame and transform info for the InputWindowInfo
-    void fillInputFrameInfo(InputWindowInfo& info, const ui::Transform& toPhysicalDisplay);
+    // Fills in the frame and transform info for the gui::WindowInfo
+    void fillInputFrameInfo(gui::WindowInfo& info, const ui::Transform& toPhysicalDisplay);
 
     bool updateFrameRateForLayerTree(bool treeHasFrameRateVote);
 
diff --git a/services/surfaceflinger/LayerProtoHelper.cpp b/services/surfaceflinger/LayerProtoHelper.cpp
index b1db6d3..79f7b1f 100644
--- a/services/surfaceflinger/LayerProtoHelper.cpp
+++ b/services/surfaceflinger/LayerProtoHelper.cpp
@@ -22,6 +22,9 @@
 #include "LayerProtoHelper.h"
 
 namespace android {
+
+using gui::WindowInfo;
+
 namespace surfaceflinger {
 
 void LayerProtoHelper::writePositionToProto(const float x, const float y,
@@ -125,7 +128,7 @@
 }
 
 void LayerProtoHelper::writeToProto(
-        const InputWindowInfo& inputInfo, const wp<Layer>& touchableRegionBounds,
+        const WindowInfo& inputInfo, const wp<Layer>& touchableRegionBounds,
         std::function<InputWindowInfoProto*()> getInputWindowInfoProto) {
     if (inputInfo.token == nullptr) {
         return;
@@ -133,7 +136,7 @@
 
     InputWindowInfoProto* proto = getInputWindowInfoProto();
     proto->set_layout_params_flags(inputInfo.flags.get());
-    using U = std::underlying_type_t<InputWindowInfo::Type>;
+    using U = std::underlying_type_t<WindowInfo::Type>;
     // TODO(b/129481165): This static assert can be safely removed once conversion warnings
     // are re-enabled.
     static_assert(std::is_same_v<U, int32_t>);
diff --git a/services/surfaceflinger/LayerProtoHelper.h b/services/surfaceflinger/LayerProtoHelper.h
index 502238d..187ce3d 100644
--- a/services/surfaceflinger/LayerProtoHelper.h
+++ b/services/surfaceflinger/LayerProtoHelper.h
@@ -17,7 +17,7 @@
 #include <layerproto/LayerProtoHeader.h>
 
 #include <Layer.h>
-#include <input/InputWindow.h>
+#include <gui/WindowInfo.h>
 #include <math/vec4.h>
 #include <ui/GraphicBuffer.h>
 #include <ui/Rect.h>
@@ -40,7 +40,7 @@
     static void writeToProto(const ui::Transform& transform, TransformProto* transformProto);
     static void writeToProto(const sp<GraphicBuffer>& buffer,
                              std::function<ActiveBufferProto*()> getActiveBufferProto);
-    static void writeToProto(const InputWindowInfo& inputInfo,
+    static void writeToProto(const gui::WindowInfo& inputInfo,
                              const wp<Layer>& touchableRegionBounds,
                              std::function<InputWindowInfoProto*()> getInputWindowInfoProto);
     static void writeToProto(const mat4 matrix, ColorTransformProto* colorTransformProto);
diff --git a/services/surfaceflinger/RefreshRateOverlay.cpp b/services/surfaceflinger/RefreshRateOverlay.cpp
index 663e62a..5c85bf0 100644
--- a/services/surfaceflinger/RefreshRateOverlay.cpp
+++ b/services/surfaceflinger/RefreshRateOverlay.cpp
@@ -25,6 +25,10 @@
 #include "Client.h"
 #include "Layer.h"
 
+#include <SkBlendMode.h>
+#include <SkPaint.h>
+#include <SkRect.h>
+#include <SkSurface.h>
 #include <gui/IProducerListener.h>
 
 #undef LOG_TAG
@@ -32,85 +36,64 @@
 
 namespace android {
 
-void RefreshRateOverlay::SevenSegmentDrawer::drawRect(const Rect& r, const half4& color,
-                                                      const sp<GraphicBuffer>& buffer,
-                                                      uint8_t* pixels) {
-    for (int32_t j = r.top; j < r.bottom; j++) {
-        if (j >= buffer->getHeight()) {
-            break;
-        }
-
-        for (int32_t i = r.left; i < r.right; i++) {
-            if (i >= buffer->getWidth()) {
-                break;
-            }
-
-            uint8_t* iter = pixels + 4 * (i + (buffer->getStride() * j));
-            iter[0] = uint8_t(color.r * 255);
-            iter[1] = uint8_t(color.g * 255);
-            iter[2] = uint8_t(color.b * 255);
-            iter[3] = uint8_t(color.a * 255);
-        }
-    }
-}
-
-void RefreshRateOverlay::SevenSegmentDrawer::drawSegment(Segment segment, int left,
-                                                         const half4& color,
-                                                         const sp<GraphicBuffer>& buffer,
-                                                         uint8_t* pixels) {
-    const Rect rect = [&]() {
+void RefreshRateOverlay::SevenSegmentDrawer::drawSegment(Segment segment, int left, SkColor& color,
+                                                         SkCanvas& canvas) {
+    const SkRect rect = [&]() {
         switch (segment) {
             case Segment::Upper:
-                return Rect(left, 0, left + DIGIT_WIDTH, DIGIT_SPACE);
+                return SkRect::MakeLTRB(left, 0, left + DIGIT_WIDTH, DIGIT_SPACE);
             case Segment::UpperLeft:
-                return Rect(left, 0, left + DIGIT_SPACE, DIGIT_HEIGHT / 2);
+                return SkRect::MakeLTRB(left, 0, left + DIGIT_SPACE, DIGIT_HEIGHT / 2);
             case Segment::UpperRight:
-                return Rect(left + DIGIT_WIDTH - DIGIT_SPACE, 0, left + DIGIT_WIDTH,
-                            DIGIT_HEIGHT / 2);
+                return SkRect::MakeLTRB(left + DIGIT_WIDTH - DIGIT_SPACE, 0, left + DIGIT_WIDTH,
+                                        DIGIT_HEIGHT / 2);
             case Segment::Middle:
-                return Rect(left, DIGIT_HEIGHT / 2 - DIGIT_SPACE / 2, left + DIGIT_WIDTH,
-                            DIGIT_HEIGHT / 2 + DIGIT_SPACE / 2);
+                return SkRect::MakeLTRB(left, DIGIT_HEIGHT / 2 - DIGIT_SPACE / 2,
+                                        left + DIGIT_WIDTH, DIGIT_HEIGHT / 2 + DIGIT_SPACE / 2);
             case Segment::LowerLeft:
-                return Rect(left, DIGIT_HEIGHT / 2, left + DIGIT_SPACE, DIGIT_HEIGHT);
+                return SkRect::MakeLTRB(left, DIGIT_HEIGHT / 2, left + DIGIT_SPACE, DIGIT_HEIGHT);
             case Segment::LowerRight:
-                return Rect(left + DIGIT_WIDTH - DIGIT_SPACE, DIGIT_HEIGHT / 2, left + DIGIT_WIDTH,
-                            DIGIT_HEIGHT);
-            case Segment::Buttom:
-                return Rect(left, DIGIT_HEIGHT - DIGIT_SPACE, left + DIGIT_WIDTH, DIGIT_HEIGHT);
+                return SkRect::MakeLTRB(left + DIGIT_WIDTH - DIGIT_SPACE, DIGIT_HEIGHT / 2,
+                                        left + DIGIT_WIDTH, DIGIT_HEIGHT);
+            case Segment::Bottom:
+                return SkRect::MakeLTRB(left, DIGIT_HEIGHT - DIGIT_SPACE, left + DIGIT_WIDTH,
+                                        DIGIT_HEIGHT);
         }
     }();
 
-    drawRect(rect, color, buffer, pixels);
+    SkPaint paint;
+    paint.setColor(color);
+    paint.setBlendMode(SkBlendMode::kSrc);
+    canvas.drawRect(rect, paint);
 }
 
-void RefreshRateOverlay::SevenSegmentDrawer::drawDigit(int digit, int left, const half4& color,
-                                                       const sp<GraphicBuffer>& buffer,
-                                                       uint8_t* pixels) {
+void RefreshRateOverlay::SevenSegmentDrawer::drawDigit(int digit, int left, SkColor& color,
+                                                       SkCanvas& canvas) {
     if (digit < 0 || digit > 9) return;
 
     if (digit == 0 || digit == 2 || digit == 3 || digit == 5 || digit == 6 || digit == 7 ||
         digit == 8 || digit == 9)
-        drawSegment(Segment::Upper, left, color, buffer, pixels);
+        drawSegment(Segment::Upper, left, color, canvas);
     if (digit == 0 || digit == 4 || digit == 5 || digit == 6 || digit == 8 || digit == 9)
-        drawSegment(Segment::UpperLeft, left, color, buffer, pixels);
+        drawSegment(Segment::UpperLeft, left, color, canvas);
     if (digit == 0 || digit == 1 || digit == 2 || digit == 3 || digit == 4 || digit == 7 ||
         digit == 8 || digit == 9)
-        drawSegment(Segment::UpperRight, left, color, buffer, pixels);
+        drawSegment(Segment::UpperRight, left, color, canvas);
     if (digit == 2 || digit == 3 || digit == 4 || digit == 5 || digit == 6 || digit == 8 ||
         digit == 9)
-        drawSegment(Segment::Middle, left, color, buffer, pixels);
+        drawSegment(Segment::Middle, left, color, canvas);
     if (digit == 0 || digit == 2 || digit == 6 || digit == 8)
-        drawSegment(Segment::LowerLeft, left, color, buffer, pixels);
+        drawSegment(Segment::LowerLeft, left, color, canvas);
     if (digit == 0 || digit == 1 || digit == 3 || digit == 4 || digit == 5 || digit == 6 ||
         digit == 7 || digit == 8 || digit == 9)
-        drawSegment(Segment::LowerRight, left, color, buffer, pixels);
+        drawSegment(Segment::LowerRight, left, color, canvas);
     if (digit == 0 || digit == 2 || digit == 3 || digit == 5 || digit == 6 || digit == 8 ||
         digit == 9)
-        drawSegment(Segment::Buttom, left, color, buffer, pixels);
+        drawSegment(Segment::Bottom, left, color, canvas);
 }
 
-std::vector<sp<GraphicBuffer>> RefreshRateOverlay::SevenSegmentDrawer::drawNumber(
-        int number, const half4& color, bool showSpinner) {
+std::vector<sp<GraphicBuffer>> RefreshRateOverlay::SevenSegmentDrawer::draw(
+        int number, SkColor& color, ui::Transform::RotationFlags rotation, bool showSpinner) {
     if (number < 0 || number > 1000) return {};
 
     const auto hundreds = number / 100;
@@ -120,55 +103,76 @@
     std::vector<sp<GraphicBuffer>> buffers;
     const auto loopCount = showSpinner ? 6 : 1;
     for (int i = 0; i < loopCount; i++) {
+        // Pre-rotate the buffer before it reaches SurfaceFlinger.
+        SkMatrix canvasTransform = SkMatrix();
+        auto [bufferWidth, bufferHeight] = [&] {
+            switch (rotation) {
+                case ui::Transform::ROT_90:
+                    canvasTransform.setTranslate(BUFFER_HEIGHT, 0);
+                    canvasTransform.preRotate(90);
+                    return std::make_tuple(BUFFER_HEIGHT, BUFFER_WIDTH);
+                case ui::Transform::ROT_270:
+                    canvasTransform.setRotate(270, BUFFER_WIDTH / 2.0, BUFFER_WIDTH / 2.0);
+                    return std::make_tuple(BUFFER_HEIGHT, BUFFER_WIDTH);
+                default:
+                    return std::make_tuple(BUFFER_WIDTH, BUFFER_HEIGHT);
+            }
+        }();
         sp<GraphicBuffer> buffer =
-                new GraphicBuffer(BUFFER_WIDTH, BUFFER_HEIGHT, HAL_PIXEL_FORMAT_RGBA_8888, 1,
+                new GraphicBuffer(bufferWidth, bufferHeight, HAL_PIXEL_FORMAT_RGBA_8888, 1,
                                   GRALLOC_USAGE_SW_WRITE_RARELY | GRALLOC_USAGE_HW_COMPOSER |
                                           GRALLOC_USAGE_HW_TEXTURE,
                                   "RefreshRateOverlayBuffer");
         const status_t bufferStatus = buffer->initCheck();
         LOG_ALWAYS_FATAL_IF(bufferStatus != OK, "RefreshRateOverlay: Buffer failed to allocate: %d",
                             bufferStatus);
-        uint8_t* pixels;
-        buffer->lock(GRALLOC_USAGE_SW_WRITE_RARELY, reinterpret_cast<void**>(&pixels));
-        // Clear buffer content
-        drawRect(Rect(BUFFER_WIDTH, BUFFER_HEIGHT), half4(0), buffer, pixels);
+
+        sk_sp<SkSurface> surface = SkSurface::MakeRasterN32Premul(bufferWidth, bufferHeight);
+        SkCanvas* canvas = surface->getCanvas();
+        canvas->setMatrix(canvasTransform);
+
         int left = 0;
         if (hundreds != 0) {
-            drawDigit(hundreds, left, color, buffer, pixels);
+            drawDigit(hundreds, left, color, *canvas);
         }
         left += DIGIT_WIDTH + DIGIT_SPACE;
 
         if (tens != 0) {
-            drawDigit(tens, left, color, buffer, pixels);
+            drawDigit(tens, left, color, *canvas);
         }
         left += DIGIT_WIDTH + DIGIT_SPACE;
 
-        drawDigit(ones, left, color, buffer, pixels);
+        drawDigit(ones, left, color, *canvas);
         left += DIGIT_WIDTH + DIGIT_SPACE;
 
         if (showSpinner) {
             switch (i) {
                 case 0:
-                    drawSegment(Segment::Upper, left, color, buffer, pixels);
+                    drawSegment(Segment::Upper, left, color, *canvas);
                     break;
                 case 1:
-                    drawSegment(Segment::UpperRight, left, color, buffer, pixels);
+                    drawSegment(Segment::UpperRight, left, color, *canvas);
                     break;
                 case 2:
-                    drawSegment(Segment::LowerRight, left, color, buffer, pixels);
+                    drawSegment(Segment::LowerRight, left, color, *canvas);
                     break;
                 case 3:
-                    drawSegment(Segment::Buttom, left, color, buffer, pixels);
+                    drawSegment(Segment::Bottom, left, color, *canvas);
                     break;
                 case 4:
-                    drawSegment(Segment::LowerLeft, left, color, buffer, pixels);
+                    drawSegment(Segment::LowerLeft, left, color, *canvas);
                     break;
                 case 5:
-                    drawSegment(Segment::UpperLeft, left, color, buffer, pixels);
+                    drawSegment(Segment::UpperLeft, left, color, *canvas);
                     break;
             }
         }
 
+        void* pixels = nullptr;
+        buffer->lock(GRALLOC_USAGE_SW_WRITE_RARELY, reinterpret_cast<void**>(&pixels));
+        const SkImageInfo& imageInfo = surface->imageInfo();
+        size_t dstRowBytes = buffer->getStride() * imageInfo.bytesPerPixel();
+        canvas->readPixels(imageInfo, pixels, dstRowBytes, 0, 0);
         buffer->unlock();
         buffers.emplace_back(buffer);
     }
@@ -210,7 +214,22 @@
 
 const std::vector<std::shared_ptr<renderengine::ExternalTexture>>&
 RefreshRateOverlay::getOrCreateBuffers(uint32_t fps) {
-    if (mBufferCache.find(fps) == mBufferCache.end()) {
+    ui::Transform::RotationFlags transformHint = mLayer->getTransformHint();
+    // Tell SurfaceFlinger about the pre-rotation on the buffer.
+    const auto transform = [&] {
+        switch (transformHint) {
+            case ui::Transform::ROT_90:
+                return ui::Transform::ROT_270;
+            case ui::Transform::ROT_270:
+                return ui::Transform::ROT_90;
+            default:
+                return ui::Transform::ROT_0;
+        }
+    }();
+    mLayer->setTransform(transform);
+
+    if (mBufferCache.find(transformHint) == mBufferCache.end() ||
+        mBufferCache.at(transformHint).find(fps) == mBufferCache.at(transformHint).end()) {
         // Ensure the range is > 0, so we don't divide by 0.
         const auto rangeLength = std::max(1u, mHighFps - mLowFps);
         // Clip values outside the range [mLowFps, mHighFps]. The current fps may be outside
@@ -218,12 +237,14 @@
         fps = std::max(fps, mLowFps);
         fps = std::min(fps, mHighFps);
         const auto fpsScale = static_cast<float>(fps - mLowFps) / rangeLength;
-        half4 color;
-        color.r = HIGH_FPS_COLOR.r * fpsScale + LOW_FPS_COLOR.r * (1 - fpsScale);
-        color.g = HIGH_FPS_COLOR.g * fpsScale + LOW_FPS_COLOR.g * (1 - fpsScale);
-        color.b = HIGH_FPS_COLOR.b * fpsScale + LOW_FPS_COLOR.b * (1 - fpsScale);
-        color.a = ALPHA;
-        auto buffers = SevenSegmentDrawer::drawNumber(fps, color, mShowSpinner);
+        SkColor4f colorBase = SkColor4f::FromColor(HIGH_FPS_COLOR) * fpsScale;
+        SkColor4f lowFpsColor = SkColor4f::FromColor(LOW_FPS_COLOR) * (1 - fpsScale);
+        colorBase.fR = colorBase.fR + lowFpsColor.fR;
+        colorBase.fG = colorBase.fG + lowFpsColor.fG;
+        colorBase.fB = colorBase.fB + lowFpsColor.fB;
+        colorBase.fA = ALPHA;
+        SkColor color = colorBase.toSkColor();
+        auto buffers = SevenSegmentDrawer::draw(fps, color, transformHint, mShowSpinner);
         std::vector<std::shared_ptr<renderengine::ExternalTexture>> textures;
         std::transform(buffers.begin(), buffers.end(), std::back_inserter(textures),
                        [&](const auto& buffer) -> std::shared_ptr<renderengine::ExternalTexture> {
@@ -233,10 +254,10 @@
                                                                   renderengine::ExternalTexture::
                                                                           Usage::READABLE);
                        });
-        mBufferCache.emplace(fps, textures);
+        mBufferCache[transformHint].emplace(fps, textures);
     }
 
-    return mBufferCache[fps];
+    return mBufferCache[transformHint][fps];
 }
 
 void RefreshRateOverlay::setViewport(ui::Size viewport) {
diff --git a/services/surfaceflinger/RefreshRateOverlay.h b/services/surfaceflinger/RefreshRateOverlay.h
index aa8329c..cb8b227 100644
--- a/services/surfaceflinger/RefreshRateOverlay.h
+++ b/services/surfaceflinger/RefreshRateOverlay.h
@@ -22,6 +22,8 @@
 #include <ui/Size.h>
 #include <utils/StrongPointer.h>
 
+#include <SkCanvas.h>
+#include <SkColor.h>
 #include <unordered_map>
 
 #include "Fps.h"
@@ -47,20 +49,16 @@
 private:
     class SevenSegmentDrawer {
     public:
-        static std::vector<sp<GraphicBuffer>> drawNumber(int number, const half4& color,
-                                                         bool showSpinner);
+        static std::vector<sp<GraphicBuffer>> draw(int number, SkColor& color,
+                                                   ui::Transform::RotationFlags, bool showSpinner);
         static uint32_t getHeight() { return BUFFER_HEIGHT; }
         static uint32_t getWidth() { return BUFFER_WIDTH; }
 
     private:
-        enum class Segment { Upper, UpperLeft, UpperRight, Middle, LowerLeft, LowerRight, Buttom };
+        enum class Segment { Upper, UpperLeft, UpperRight, Middle, LowerLeft, LowerRight, Bottom };
 
-        static void drawRect(const Rect& r, const half4& color, const sp<GraphicBuffer>& buffer,
-                             uint8_t* pixels);
-        static void drawSegment(Segment segment, int left, const half4& color,
-                                const sp<GraphicBuffer>& buffer, uint8_t* pixels);
-        static void drawDigit(int digit, int left, const half4& color,
-                              const sp<GraphicBuffer>& buffer, uint8_t* pixels);
+        static void drawSegment(Segment segment, int left, SkColor& color, SkCanvas& canvas);
+        static void drawDigit(int digit, int left, SkColor& color, SkCanvas& canvas);
 
         static constexpr uint32_t DIGIT_HEIGHT = 100;
         static constexpr uint32_t DIGIT_WIDTH = 64;
@@ -80,13 +78,15 @@
     sp<IBinder> mIBinder;
     sp<IGraphicBufferProducer> mGbp;
 
-    std::unordered_map<int, std::vector<std::shared_ptr<renderengine::ExternalTexture>>>
+    std::unordered_map<
+            ui::Transform::RotationFlags,
+            std::unordered_map<int, std::vector<std::shared_ptr<renderengine::ExternalTexture>>>>
             mBufferCache;
     std::optional<int> mCurrentFps;
     int mFrame = 0;
     static constexpr float ALPHA = 0.8f;
-    const half3 LOW_FPS_COLOR = half3(1.0f, 0.0f, 0.0f);
-    const half3 HIGH_FPS_COLOR = half3(0.0f, 1.0f, 0.0f);
+    const SkColor LOW_FPS_COLOR = SK_ColorRED;
+    const SkColor HIGH_FPS_COLOR = SK_ColorGREEN;
 
     const bool mShowSpinner;
 
diff --git a/services/surfaceflinger/Scheduler/Scheduler.cpp b/services/surfaceflinger/Scheduler/Scheduler.cpp
index e0b3640..6d6e3c2 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.cpp
+++ b/services/surfaceflinger/Scheduler/Scheduler.cpp
@@ -25,7 +25,7 @@
 #include <android/hardware/configstore/1.0/ISurfaceFlingerConfigs.h>
 #include <android/hardware/configstore/1.1/ISurfaceFlingerConfigs.h>
 #include <configstore/Utils.h>
-#include <input/InputWindow.h>
+#include <gui/WindowInfo.h>
 #include <system/window.h>
 #include <ui/DisplayStatInfo.h>
 #include <utils/Timers.h>
@@ -64,6 +64,8 @@
 
 namespace android {
 
+using gui::WindowInfo;
+
 namespace {
 
 std::unique_ptr<scheduler::VSyncTracker> createVSyncTracker() {
@@ -579,10 +581,9 @@
 void Scheduler::registerLayer(Layer* layer) {
     scheduler::LayerHistory::LayerVoteType voteType;
 
-    if (!mOptions.useContentDetection ||
-        layer->getWindowType() == InputWindowInfo::Type::STATUS_BAR) {
+    if (!mOptions.useContentDetection || layer->getWindowType() == WindowInfo::Type::STATUS_BAR) {
         voteType = scheduler::LayerHistory::LayerVoteType::NoVote;
-    } else if (layer->getWindowType() == InputWindowInfo::Type::WALLPAPER) {
+    } else if (layer->getWindowType() == WindowInfo::Type::WALLPAPER) {
         // Running Wallpaper at Min is considered as part of content detection.
         voteType = scheduler::LayerHistory::LayerVoteType::Min;
     } else {
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 84c0c7e..27f0038 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -159,6 +159,7 @@
 
 using android::hardware::power::Boost;
 using base::StringAppendF;
+using gui::WindowInfo;
 using ui::ColorMode;
 using ui::Dataspace;
 using ui::DisplayPrimaries;
@@ -3058,7 +3059,7 @@
 }
 
 void SurfaceFlinger::updateInputWindowInfo() {
-    std::vector<InputWindowInfo> inputInfos;
+    std::vector<WindowInfo> inputInfos;
 
     mDrawingState.traverseInReverseZOrder([&](Layer* layer) {
         if (!layer->needsInputInfo()) return;
@@ -4085,10 +4086,10 @@
     }
     if (what & layer_state_t::eInputInfoChanged) {
         if (privileged) {
-            layer->setInputInfo(*s.inputHandle->getInfo());
+            layer->setInputInfo(*s.windowInfoHandle->getInfo());
             flags |= eTraversalNeeded;
         } else {
-            ALOGE("Attempt to update InputWindowInfo without permission ACCESS_SURFACE_FLINGER");
+            ALOGE("Attempt to update WindowInfo without permission ACCESS_SURFACE_FLINGER");
         }
     }
     std::optional<nsecs_t> dequeueBufferTimestamp;
@@ -5649,37 +5650,24 @@
             }
             case 1035: {
                 const int modeId = data.readInt32();
-                mDebugDisplayModeSetByBackdoor = false;
 
-                const auto displayId = [&]() -> std::optional<PhysicalDisplayId> {
-                    uint64_t inputDisplayId = 0;
-                    if (data.readUint64(&inputDisplayId) == NO_ERROR) {
-                        const auto token = getPhysicalDisplayToken(
-                                static_cast<PhysicalDisplayId>(inputDisplayId));
-                        if (!token) {
-                            ALOGE("No display with id: %" PRIu64, inputDisplayId);
-                            return std::nullopt;
-                        }
-
-                        return std::make_optional<PhysicalDisplayId>(inputDisplayId);
+                const auto display = [&]() -> sp<IBinder> {
+                    uint64_t value;
+                    if (data.readUint64(&value) != NO_ERROR) {
+                        return getInternalDisplayToken();
                     }
 
-                    return getInternalDisplayId();
+                    if (const auto id = DisplayId::fromValue<PhysicalDisplayId>(value)) {
+                        return getPhysicalDisplayToken(*id);
+                    }
+
+                    ALOGE("Invalid physical display ID");
+                    return nullptr;
                 }();
 
-                if (!displayId) {
-                    ALOGE("No display found");
-                    return NO_ERROR;
-                }
-
-                status_t result = setActiveMode(getPhysicalDisplayToken(*displayId), modeId);
-                if (result != NO_ERROR) {
-                    return result;
-                }
-
-                mDebugDisplayModeSetByBackdoor = true;
-
-                return NO_ERROR;
+                const status_t result = setActiveMode(display, modeId);
+                mDebugDisplayModeSetByBackdoor = result == NO_ERROR;
+                return result;
             }
             case 1036: {
                 if (data.readInt32() > 0) {
@@ -5742,14 +5730,11 @@
                             std::optional<PhysicalDisplayId> inputId = std::nullopt;
                             if (uint64_t inputDisplayId;
                                 data.readUint64(&inputDisplayId) == NO_ERROR) {
-                                const auto token = getPhysicalDisplayToken(
-                                        static_cast<PhysicalDisplayId>(inputDisplayId));
-                                if (!token) {
+                                inputId = DisplayId::fromValue<PhysicalDisplayId>(inputDisplayId);
+                                if (!inputId || getPhysicalDisplayToken(*inputId)) {
                                     ALOGE("No display with id: %" PRIu64, inputDisplayId);
                                     return NAME_NOT_FOUND;
                                 }
-
-                                inputId = std::make_optional<PhysicalDisplayId>(inputDisplayId);
                             }
                             {
                                 Mutex::Autolock lock(mStateLock);
@@ -5999,7 +5984,7 @@
                                captureListener);
 }
 
-status_t SurfaceFlinger::captureDisplay(uint64_t displayIdOrLayerStack,
+status_t SurfaceFlinger::captureDisplay(DisplayId displayId,
                                         const sp<IScreenCaptureListener>& captureListener) {
     ui::LayerStack layerStack;
     wp<const DisplayDevice> displayWeak;
@@ -6007,21 +5992,14 @@
     ui::Dataspace dataspace;
     {
         Mutex::Autolock lock(mStateLock);
-        auto display = getDisplayDeviceLocked(PhysicalDisplayId{displayIdOrLayerStack});
 
-        // Fall back to first display whose layer stack matches.
-        if (!display) {
-            const auto layerStack = static_cast<ui::LayerStack>(displayIdOrLayerStack);
-            display = findDisplay(WithLayerStack(layerStack));
-        }
-
+        const auto display = getDisplayDeviceLocked(displayId);
         if (!display) {
             return NAME_NOT_FOUND;
         }
 
-        layerStack = display->getLayerStack();
         displayWeak = display;
-
+        layerStack = display->getLayerStack();
         size = display->getLayerStackSpaceRect().getSize();
 
         dataspace =
@@ -6106,7 +6084,11 @@
             }
         }
 
-        const auto display = findDisplay(WithLayerStack(parent->getLayerStack()));
+        const auto display =
+                findDisplay([layerStack = parent->getLayerStack()](const auto& display) {
+                    return display.getLayerStack() == layerStack;
+                });
+
         if (!display) {
             return NAME_NOT_FOUND;
         }
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index ecb6907..1d6f016 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -621,12 +621,10 @@
     sp<IDisplayEventConnection> createDisplayEventConnection(
             ISurfaceComposer::VsyncSource vsyncSource = eVsyncSourceApp,
             ISurfaceComposer::EventRegistrationFlags eventRegistration = {}) override;
-    status_t captureDisplay(const DisplayCaptureArgs& args,
-                            const sp<IScreenCaptureListener>& captureListener) override;
-    status_t captureDisplay(uint64_t displayOrLayerStack,
-                            const sp<IScreenCaptureListener>& captureListener) override;
-    status_t captureLayers(const LayerCaptureArgs& args,
-                           const sp<IScreenCaptureListener>& captureListener) override;
+
+    status_t captureDisplay(const DisplayCaptureArgs&, const sp<IScreenCaptureListener>&) override;
+    status_t captureDisplay(DisplayId, const sp<IScreenCaptureListener>&) override;
+    status_t captureLayers(const LayerCaptureArgs&, const sp<IScreenCaptureListener>&) override;
 
     status_t getDisplayStats(const sp<IBinder>& displayToken, DisplayStatInfo* stats) override;
     status_t getDisplayState(const sp<IBinder>& displayToken, ui::DisplayState*)
@@ -942,14 +940,6 @@
         return it == mDisplays.end() ? nullptr : it->second;
     }
 
-    sp<const DisplayDevice> getDisplayDeviceLocked(PhysicalDisplayId id) const
-            REQUIRES(mStateLock) {
-        if (const auto token = getPhysicalDisplayTokenLocked(id)) {
-            return getDisplayDeviceLocked(token);
-        }
-        return nullptr;
-    }
-
     sp<const DisplayDevice> getDefaultDisplayDeviceLocked() const REQUIRES(mStateLock) {
         return const_cast<SurfaceFlinger*>(this)->getDefaultDisplayDeviceLocked();
     }
diff --git a/services/surfaceflinger/tests/RefreshRateOverlay_test.cpp b/services/surfaceflinger/tests/RefreshRateOverlay_test.cpp
index 05858bf..fb4458a 100644
--- a/services/surfaceflinger/tests/RefreshRateOverlay_test.cpp
+++ b/services/surfaceflinger/tests/RefreshRateOverlay_test.cpp
@@ -20,6 +20,10 @@
 
 #include <gui/SurfaceComposerClient.h>
 #include <private/gui/ComposerService.h>
+#include <chrono>
+
+using ::std::literals::chrono_literals::operator""ms;
+using ::std::literals::chrono_literals::operator""s;
 
 static constexpr int kRefreshRateOverlayCode = 1034;
 static constexpr int kRefreshRateOverlayEnable = 1;
diff --git a/services/surfaceflinger/tests/fakehwc/SFFakeHwc_test.cpp b/services/surfaceflinger/tests/fakehwc/SFFakeHwc_test.cpp
index 162711d..a9e935d 100644
--- a/services/surfaceflinger/tests/fakehwc/SFFakeHwc_test.cpp
+++ b/services/surfaceflinger/tests/fakehwc/SFFakeHwc_test.cpp
@@ -279,7 +279,7 @@
     }
 
     bool waitForHotplugEvent(Display displayId, bool connected) {
-        return waitForHotplugEvent(PhysicalDisplayId(displayId), connected);
+        return waitForHotplugEvent(physicalIdFromHwcDisplayId(displayId), connected);
     }
 
     bool waitForHotplugEvent(PhysicalDisplayId displayId, bool connected) {
@@ -305,7 +305,7 @@
     }
 
     bool waitForModeChangedEvent(Display display, int32_t modeId) {
-        PhysicalDisplayId displayId(display);
+        PhysicalDisplayId displayId = physicalIdFromHwcDisplayId(display);
         int waitCount = 20;
         while (waitCount--) {
             while (!mReceivedDisplayEvents.empty()) {
diff --git a/services/surfaceflinger/tests/unittests/Android.bp b/services/surfaceflinger/tests/unittests/Android.bp
index b5086fa..bd6fe1d 100644
--- a/services/surfaceflinger/tests/unittests/Android.bp
+++ b/services/surfaceflinger/tests/unittests/Android.bp
@@ -23,7 +23,10 @@
 
 cc_test {
     name: "libsurfaceflinger_unittest",
-    defaults: ["surfaceflinger_defaults"],
+    defaults: [
+        "skia_renderengine_deps",
+        "surfaceflinger_defaults",
+    ],
     test_suites: ["device-tests"],
     sanitize: {
         // Using the address sanitizer not only helps uncover issues in the code
diff --git a/services/surfaceflinger/tests/unittests/CompositionTest.cpp b/services/surfaceflinger/tests/unittests/CompositionTest.cpp
index 560f139..fca3bfc 100644
--- a/services/surfaceflinger/tests/unittests/CompositionTest.cpp
+++ b/services/surfaceflinger/tests/unittests/CompositionTest.cpp
@@ -77,7 +77,7 @@
 constexpr hal::HWLayerId HWC_LAYER = 5000;
 constexpr Transform DEFAULT_TRANSFORM = static_cast<Transform>(0);
 
-constexpr PhysicalDisplayId DEFAULT_DISPLAY_ID(42);
+constexpr PhysicalDisplayId DEFAULT_DISPLAY_ID = PhysicalDisplayId::fromPort(42u);
 constexpr int DEFAULT_DISPLAY_WIDTH = 1920;
 constexpr int DEFAULT_DISPLAY_HEIGHT = 1024;
 
diff --git a/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp b/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
index cc24323..60b0f53 100644
--- a/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
+++ b/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
@@ -122,7 +122,7 @@
 
 sp<DisplayDevice> DisplayTransactionTest::injectDefaultInternalDisplay(
         std::function<void(FakeDisplayDeviceInjector&)> injectExtra) {
-    constexpr PhysicalDisplayId DEFAULT_DISPLAY_ID(777);
+    constexpr PhysicalDisplayId DEFAULT_DISPLAY_ID = PhysicalDisplayId::fromPort(255u);
     constexpr int DEFAULT_DISPLAY_WIDTH = 1080;
     constexpr int DEFAULT_DISPLAY_HEIGHT = 1920;
     constexpr HWDisplayId DEFAULT_DISPLAY_HWC_DISPLAY_ID = 0;
diff --git a/services/surfaceflinger/tests/unittests/EventThreadTest.cpp b/services/surfaceflinger/tests/unittests/EventThreadTest.cpp
index b4a1481..62acc6b 100644
--- a/services/surfaceflinger/tests/unittests/EventThreadTest.cpp
+++ b/services/surfaceflinger/tests/unittests/EventThreadTest.cpp
@@ -41,10 +41,13 @@
 
 namespace {
 
-constexpr PhysicalDisplayId INTERNAL_DISPLAY_ID(111);
-constexpr PhysicalDisplayId EXTERNAL_DISPLAY_ID(222);
-constexpr PhysicalDisplayId DISPLAY_ID_64BIT(0xabcd12349876fedcULL);
+constexpr PhysicalDisplayId INTERNAL_DISPLAY_ID = PhysicalDisplayId::fromPort(111u);
+constexpr PhysicalDisplayId EXTERNAL_DISPLAY_ID = PhysicalDisplayId::fromPort(222u);
+constexpr PhysicalDisplayId DISPLAY_ID_64BIT =
+        PhysicalDisplayId::fromEdid(0xffu, 0xffffu, 0xffff'ffffu);
+
 constexpr std::chrono::duration VSYNC_PERIOD(16ms);
+
 class MockVSyncSource : public VSyncSource {
 public:
     const char* getName() const override { return "test"; }
diff --git a/services/surfaceflinger/tests/unittests/OneShotTimerTest.cpp b/services/surfaceflinger/tests/unittests/OneShotTimerTest.cpp
index 6916764..597e5e7 100644
--- a/services/surfaceflinger/tests/unittests/OneShotTimerTest.cpp
+++ b/services/surfaceflinger/tests/unittests/OneShotTimerTest.cpp
@@ -72,7 +72,8 @@
     mIdleTimer->stop();
 }
 
-TEST_F(OneShotTimerTest, resetTest) {
+// TODO(b/186417847) This test is flaky. Reenable once fixed.
+TEST_F(OneShotTimerTest, DISABLED_resetTest) {
     fake::FakeClock* clock = new fake::FakeClock();
     mIdleTimer = std::make_unique<scheduler::OneShotTimer>("TestTimer", 1ms,
                                                            mResetTimerCallback.getInvocable(),
@@ -94,7 +95,8 @@
     EXPECT_FALSE(mResetTimerCallback.waitForUnexpectedCall().has_value());
 }
 
-TEST_F(OneShotTimerTest, resetBackToBackTest) {
+// TODO(b/186417847) This test is flaky. Reenable once fixed.
+TEST_F(OneShotTimerTest, DISABLED_resetBackToBackTest) {
     fake::FakeClock* clock = new fake::FakeClock();
     mIdleTimer = std::make_unique<scheduler::OneShotTimer>("TestTimer", 1ms,
                                                            mResetTimerCallback.getInvocable(),
@@ -144,7 +146,8 @@
     EXPECT_FALSE(mResetTimerCallback.waitForUnexpectedCall().has_value());
 }
 
-TEST_F(OneShotTimerTest, idleTimerIdlesTest) {
+// TODO(b/186417847) This test is flaky. Reenable once fixed.
+TEST_F(OneShotTimerTest, DISABLED_idleTimerIdlesTest) {
     fake::FakeClock* clock = new fake::FakeClock();
     mIdleTimer = std::make_unique<scheduler::OneShotTimer>("TestTimer", 1ms,
                                                            mResetTimerCallback.getInvocable(),
@@ -169,7 +172,8 @@
     EXPECT_FALSE(mResetTimerCallback.waitForUnexpectedCall().has_value());
 }
 
-TEST_F(OneShotTimerTest, timeoutCallbackExecutionTest) {
+// TODO(b/186417847) This test is flaky. Reenable once fixed.
+TEST_F(OneShotTimerTest, DISABLED_timeoutCallbackExecutionTest) {
     fake::FakeClock* clock = new fake::FakeClock();
     mIdleTimer = std::make_unique<scheduler::OneShotTimer>("TestTimer", 1ms,
                                                            mResetTimerCallback.getInvocable(),
diff --git a/services/surfaceflinger/tests/unittests/SchedulerTest.cpp b/services/surfaceflinger/tests/unittests/SchedulerTest.cpp
index f680d80..0023aa0 100644
--- a/services/surfaceflinger/tests/unittests/SchedulerTest.cpp
+++ b/services/surfaceflinger/tests/unittests/SchedulerTest.cpp
@@ -34,7 +34,7 @@
 namespace android {
 namespace {
 
-constexpr PhysicalDisplayId PHYSICAL_DISPLAY_ID(999);
+constexpr PhysicalDisplayId PHYSICAL_DISPLAY_ID = PhysicalDisplayId::fromPort(255u);
 
 class SchedulerTest : public testing::Test {
 protected:
diff --git a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.cpp b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.cpp
index 7de1872..20d41e6 100644
--- a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.cpp
+++ b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.cpp
@@ -18,6 +18,7 @@
 #pragma clang diagnostic push
 #pragma clang diagnostic ignored "-Wconversion"
 
+#undef LOG_TAG
 #define LOG_TAG "MockComposer"
 #include "mock/DisplayHardware/MockComposer.h"
 
diff --git a/services/surfaceflinger/tests/utils/CallbackUtils.h b/services/surfaceflinger/tests/utils/CallbackUtils.h
index 459b35c..f4a3425 100644
--- a/services/surfaceflinger/tests/utils/CallbackUtils.h
+++ b/services/surfaceflinger/tests/utils/CallbackUtils.h
@@ -20,8 +20,12 @@
 #include <gui/SurfaceControl.h>
 #include <ui/Fence.h>
 #include <utils/Timers.h>
+#include <chrono>
 #include <thread>
 
+using ::std::literals::chrono_literals::operator""ms;
+using ::std::literals::chrono_literals::operator""s;
+
 namespace android {
 
 namespace {