Merge "SF: Pass the correct layer creation args when mirroring"
diff --git a/cmds/servicemanager/servicemanager.microdroid.rc b/cmds/servicemanager/servicemanager.microdroid.rc
index c516043..8819e1e 100644
--- a/cmds/servicemanager/servicemanager.microdroid.rc
+++ b/cmds/servicemanager/servicemanager.microdroid.rc
@@ -5,5 +5,4 @@
     critical
     onrestart setprop servicemanager.ready false
     onrestart restart apexd
-    task_profiles ServiceCapacityLow
     shutdown critical
diff --git a/include/ftl/concat.h b/include/ftl/concat.h
index ded48f7..e0774d3 100644
--- a/include/ftl/concat.h
+++ b/include/ftl/concat.h
@@ -20,7 +20,9 @@
 
 namespace android::ftl {
 
-// Lightweight (not allocating nor sprintf-based) concatenation.
+// Lightweight (not allocating nor sprintf-based) concatenation. The variadic arguments can be
+// values of integral type (including bool and char), string literals, or strings whose length
+// is constrained:
 //
 //   std::string_view name = "Volume";
 //   ftl::Concat string(ftl::truncated<3>(name), ": ", -3, " dB");
diff --git a/include/ftl/details/concat.h b/include/ftl/details/concat.h
index 8ce949e..726ba02 100644
--- a/include/ftl/details/concat.h
+++ b/include/ftl/details/concat.h
@@ -19,6 +19,7 @@
 #include <functional>
 #include <string_view>
 
+#include <ftl/details/type_traits.h>
 #include <ftl/string.h>
 
 namespace android::ftl::details {
@@ -26,16 +27,42 @@
 template <typename T, typename = void>
 struct StaticString;
 
+// Booleans.
 template <typename T>
-struct StaticString<T, std::enable_if_t<std::is_integral_v<T>>> {
-  static constexpr std::size_t N = to_chars_length_v<T>;
+struct StaticString<T, std::enable_if_t<is_bool_v<T>>> {
+  static constexpr std::size_t N = 5;  // Length of "false".
 
-  explicit StaticString(T v) : view(to_chars(buffer, v)) {}
+  explicit constexpr StaticString(bool b) : view(b ? "true" : "false") {}
 
-  to_chars_buffer_t<T> buffer;
   const std::string_view view;
 };
 
+// Characters.
+template <typename T>
+struct StaticString<T, std::enable_if_t<is_char_v<T>>> {
+  static constexpr std::size_t N = 1;
+
+  explicit constexpr StaticString(char c) : character(c) {}
+
+  const char character;
+  const std::string_view view{&character, 1u};
+};
+
+// Integers, including the integer value of other character types like char32_t.
+template <typename T>
+struct StaticString<
+    T, std::enable_if_t<std::is_integral_v<remove_cvref_t<T>> && !is_bool_v<T> && !is_char_v<T>>> {
+  using U = remove_cvref_t<T>;
+  static constexpr std::size_t N = to_chars_length_v<U>;
+
+  // TODO: Mark this and to_chars as `constexpr` in C++23.
+  explicit StaticString(U v) : view(to_chars(buffer, v)) {}
+
+  to_chars_buffer_t<U> buffer;
+  const std::string_view view;
+};
+
+// Character arrays.
 template <std::size_t M>
 struct StaticString<const char (&)[M], void> {
   static constexpr std::size_t N = M - 1;
@@ -50,6 +77,7 @@
   std::string_view view;
 };
 
+// Strings with constrained length.
 template <std::size_t M>
 struct StaticString<Truncated<M>, void> {
   static constexpr std::size_t N = M;
diff --git a/include/ftl/details/type_traits.h b/include/ftl/details/type_traits.h
index 7092ec5..47bebc5 100644
--- a/include/ftl/details/type_traits.h
+++ b/include/ftl/details/type_traits.h
@@ -24,4 +24,10 @@
 template <typename U>
 using remove_cvref_t = std::remove_cv_t<std::remove_reference_t<U>>;
 
+template <typename T>
+constexpr bool is_bool_v = std::is_same_v<remove_cvref_t<T>, bool>;
+
+template <typename T>
+constexpr bool is_char_v = std::is_same_v<remove_cvref_t<T>, char>;
+
 }  // namespace android::ftl::details
diff --git a/libs/binder/Android.bp b/libs/binder/Android.bp
index c4bb6d0..83c2c13 100644
--- a/libs/binder/Android.bp
+++ b/libs/binder/Android.bp
@@ -484,9 +484,6 @@
         java: {
             enabled: false,
         },
-        cpp: {
-            gen_trace: false,
-        },
     },
 }
 
diff --git a/libs/binder/ndk/include_platform/android/binder_manager.h b/libs/binder/ndk/include_platform/android/binder_manager.h
index dfa8ea2..c234270 100644
--- a/libs/binder/ndk/include_platform/android/binder_manager.h
+++ b/libs/binder/ndk/include_platform/android/binder_manager.h
@@ -143,6 +143,17 @@
 bool AServiceManager_isUpdatableViaApex(const char* instance) __INTRODUCED_IN(31);
 
 /**
+ * Returns the APEX name if a service is declared as updatable via an APEX module.
+ *
+ * \param instance identifier of the service
+ * \param context to pass to callback
+ * \param callback taking the APEX name (e.g. 'com.android.foo') and context
+ */
+void AServiceManager_getUpdatableApexName(const char* instance, void* context,
+                                          void (*callback)(const char*, void*))
+        __INTRODUCED_IN(__ANDROID_API_U__);
+
+/**
  * Prevent lazy services without client from shutting down their process
  *
  * This should only be used if it is every eventually set to false. If a
diff --git a/libs/binder/ndk/libbinder_ndk.map.txt b/libs/binder/ndk/libbinder_ndk.map.txt
index 259a736..32ca564 100644
--- a/libs/binder/ndk/libbinder_ndk.map.txt
+++ b/libs/binder/ndk/libbinder_ndk.map.txt
@@ -152,6 +152,11 @@
     AParcel_unmarshal;
 };
 
+LIBBINDER_NDK34 { # introduced=UpsideDownCake
+  global:
+    AServiceManager_getUpdatableApexName; # systemapi
+};
+
 LIBBINDER_NDK_PLATFORM {
   global:
     AParcel_getAllowFds;
diff --git a/libs/binder/ndk/service_manager.cpp b/libs/binder/ndk/service_manager.cpp
index 7649a26..a12d0e9 100644
--- a/libs/binder/ndk/service_manager.cpp
+++ b/libs/binder/ndk/service_manager.cpp
@@ -113,6 +113,18 @@
     sp<IServiceManager> sm = defaultServiceManager();
     return sm->updatableViaApex(String16(instance)) != std::nullopt;
 }
+void AServiceManager_getUpdatableApexName(const char* instance, void* context,
+                                          void (*callback)(const char*, void*)) {
+    CHECK_NE(instance, nullptr);
+    // context may be nullptr
+    CHECK_NE(callback, nullptr);
+
+    sp<IServiceManager> sm = defaultServiceManager();
+    std::optional<String16> updatableViaApex = sm->updatableViaApex(String16(instance));
+    if (updatableViaApex.has_value()) {
+        callback(String8(updatableViaApex.value()).c_str(), context);
+    }
+}
 void AServiceManager_forceLazyServicesPersist(bool persist) {
     auto serviceRegistrar = android::binder::LazyServiceRegistrar::getInstance();
     serviceRegistrar.forcePersist(persist);
diff --git a/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp b/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp
index 01b9472..e221e4c 100644
--- a/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp
+++ b/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp
@@ -33,13 +33,15 @@
 #include <binder/IResultReceiver.h>
 #include <binder/IServiceManager.h>
 #include <binder/IShellCallback.h>
-
 #include <sys/prctl.h>
+
 #include <chrono>
 #include <condition_variable>
 #include <iostream>
 #include <mutex>
+#include <optional>
 #include <thread>
+
 #include "android/binder_ibinder.h"
 
 using namespace android;
@@ -337,6 +339,16 @@
     EXPECT_EQ(isUpdatable, false);
 }
 
+TEST(NdkBinder, GetUpdatableViaApex) {
+    std::optional<std::string> updatableViaApex;
+    AServiceManager_getUpdatableApexName(
+            "android.hardware.light.ILights/default", &updatableViaApex,
+            [](const char* apexName, void* context) {
+                *static_cast<std::optional<std::string>*>(context) = apexName;
+            });
+    EXPECT_EQ(updatableViaApex, std::nullopt) << *updatableViaApex;
+}
+
 // This is too slow
 TEST(NdkBinder, CheckLazyServiceShutDown) {
     ndk::SpAIBinder binder(AServiceManager_waitForService(kLazyBinderNdkUnitTestService));
diff --git a/libs/ftl/concat_test.cpp b/libs/ftl/concat_test.cpp
index 8ecb1b2..771f054 100644
--- a/libs/ftl/concat_test.cpp
+++ b/libs/ftl/concat_test.cpp
@@ -28,8 +28,25 @@
   EXPECT_EQ(string.c_str()[string.size()], '\0');
 }
 
+TEST(Concat, Characters) {
+  EXPECT_EQ(ftl::Concat(u'a', ' ', U'b').str(), "97 98");
+}
+
+TEST(Concat, References) {
+  int i[] = {-1, 2};
+  unsigned u = 3;
+  EXPECT_EQ(ftl::Concat(i[0], std::as_const(i[1]), u).str(), "-123");
+
+  const bool b = false;
+  const char c = 'o';
+  EXPECT_EQ(ftl::Concat(b, "tt", c).str(), "falsetto");
+}
+
 namespace {
 
+static_assert(ftl::Concat{true, false, true}.str() == "truefalsetrue");
+static_assert(ftl::Concat{':', '-', ')'}.str() == ":-)");
+
 static_assert(ftl::Concat{"foo"}.str() == "foo");
 static_assert(ftl::Concat{ftl::truncated<3>("foobar")}.str() == "foo");
 
diff --git a/libs/jpegrecoverymap/Android.bp b/libs/jpegrecoverymap/Android.bp
index 285f8d5..b52c4c7 100644
--- a/libs/jpegrecoverymap/Android.bp
+++ b/libs/jpegrecoverymap/Android.bp
@@ -31,4 +31,8 @@
     srcs: [
         "recoverymap.cpp",
     ],
+
+    shared_libs: [
+        "libutils",
+    ],
 }
\ No newline at end of file
diff --git a/libs/jpegrecoverymap/include/jpegrecoverymap/recoverymap.h b/libs/jpegrecoverymap/include/jpegrecoverymap/recoverymap.h
index 6949f85..15eca1e 100644
--- a/libs/jpegrecoverymap/include/jpegrecoverymap/recoverymap.h
+++ b/libs/jpegrecoverymap/include/jpegrecoverymap/recoverymap.h
@@ -14,12 +14,14 @@
  * limitations under the License.
  */
 
+ #include <utils/Errors.h>
+
 namespace android::recoverymap {
 
 /*
  * Holds information for uncompressed image or recovery map.
  */
-struct jpeg_r_uncompressed_struct {
+struct jpegr_uncompressed_struct {
     // Pointer to the data location.
     void* data;
     // Width of the recovery map or image in pixels.
@@ -31,37 +33,90 @@
 /*
  * Holds information for compressed image or recovery map.
  */
-struct jpeg_r_compressed_struct {
+struct jpegr_compressed_struct {
     // Pointer to the data location.
     void* data;
     // Data length;
     int length;
 };
 
-typedef struct jpeg_r_uncompressed_struct* j_r_uncompressed_ptr;
-typedef struct jpeg_r_compressed_struct* j_r_compressed_ptr;
+typedef struct jpegr_uncompressed_struct* jr_uncompressed_ptr;
+typedef struct jpegr_compressed_struct* jr_compressed_ptr;
 
 class RecoveryMap {
 public:
     /*
+     * Compress JPEGR image from 10-bit HDR YUV and 8-bit SDR YUV.
+     *
+     * Generate recovery map from the HDR and SDR inputs, compress SDR YUV to 8-bit JPEG and append
+     * the recovery map to the end of the compressed JPEG.
+     * @param uncompressed_p010_image uncompressed HDR image in P010 color format
+     * @param uncompressed_yuv_420_image uncompressed SDR image in YUV_420 color format
+     * @param dest destination of the compressed JPEGR image
+     * @return NO_ERROR if encoding succeeds, error code if error occurs.
+     */
+    status_t encodeJPEGR(jr_uncompressed_ptr uncompressed_p010_image,
+                         jr_uncompressed_ptr uncompressed_yuv_420_image,
+                         void* dest);
+
+    /*
+     * Compress JPEGR image from 10-bit HDR YUV and 8-bit SDR YUV.
+     *
+     * Generate recovery map from the HDR and SDR inputs, append the recovery map to the end of the
+     * compressed JPEG.
+     * @param uncompressed_p010_image uncompressed HDR image in P010 color format
+     * @param uncompressed_yuv_420_image uncompressed SDR image in YUV_420 color format
+     * @param compressed_jpeg_image compressed 8-bit JPEG image
+     * @param dest destination of the compressed JPEGR image
+     * @return NO_ERROR if encoding succeeds, error code if error occurs.
+     */
+    status_t encodeJPEGR(jr_uncompressed_ptr uncompressed_p010_image,
+                         jr_uncompressed_ptr uncompressed_yuv_420_image,
+                         void* compressed_jpeg_image,
+                         void* dest);
+
+    /*
+     * Compress JPEGR image from 10-bit HDR YUV and 8-bit SDR YUV.
+     *
+     * Decode the compressed 8-bit JPEG image to YUV SDR, generate recovery map from the HDR input
+     * and the decoded SDR result, append the recovery map to the end of the compressed JPEG.
+     * @param uncompressed_p010_image uncompressed HDR image in P010 color format
+     * @param compressed_jpeg_image compressed 8-bit JPEG image
+     * @param dest destination of the compressed JPEGR image
+     * @return NO_ERROR if encoding succeeds, error code if error occurs.
+     */
+    status_t encodeJPEGR(jr_uncompressed_ptr uncompressed_p010_image,
+                         void* compressed_jpeg_image,
+                         void* dest);
+
+    /*
+     * Decompress JPEGR image.
+     *
+     * @param compressed_jpegr_image compressed JPEGR image
+     * @param dest destination of the uncompressed JPEGR image
+     * @return NO_ERROR if decoding succeeds, error code if error occurs.
+     */
+    status_t decodeJPEGR(void* compressed_jpegr_image, jr_uncompressed_ptr dest);
+private:
+    /*
      * This method is called in the decoding pipeline. It will decode the recovery map.
      *
      * @param compressed_recovery_map compressed recovery map
      * @param dest decoded recover map
-     * @return true if decoding succeeds
+     * @return NO_ERROR if decoding succeeds, error code if error occurs.
      */
-    bool decodeRecoveryMap(j_r_compressed_ptr compressed_recovery_map,
-                           j_r_uncompressed_ptr dest);
+    status_t decodeRecoveryMap(jr_compressed_ptr compressed_recovery_map,
+                               jr_uncompressed_ptr dest);
 
     /*
      * This method is called in the encoding pipeline. It will encode the recovery map.
      *
      * @param uncompressed_recovery_map uncompressed recovery map
      * @param dest encoded recover map
-     * @return true if encoding succeeds
+     * @return NO_ERROR if encoding succeeds, error code if error occurs.
      */
-    bool encodeRecoveryMap(j_r_uncompressed_ptr uncompressed_recovery_map,
-                           j_r_compressed_ptr dest);
+    status_t encodeRecoveryMap(jr_uncompressed_ptr uncompressed_recovery_map,
+                               jr_compressed_ptr dest);
 
     /*
      * This method is called in the encoding pipeline. It will take the uncompressed 8-bit and
@@ -70,11 +125,11 @@
      * @param uncompressed_yuv_420_image uncompressed SDR image in YUV_420 color format
      * @param uncompressed_p010_image uncompressed HDR image in P010 color format
      * @param dest recover map
-     * @return true if calculation succeeds
+     * @return NO_ERROR if calculation succeeds, error code if error occurs.
      */
-    bool generateRecoveryMap(j_r_uncompressed_ptr uncompressed_yuv_420_image,
-                             j_r_uncompressed_ptr uncompressed_p010_image,
-                             j_r_uncompressed_ptr dest);
+    status_t generateRecoveryMap(jr_uncompressed_ptr uncompressed_yuv_420_image,
+                                 jr_uncompressed_ptr uncompressed_p010_image,
+                                 jr_uncompressed_ptr dest);
 
     /*
      * This method is called in the decoding pipeline. It will take the uncompressed (decoded)
@@ -84,20 +139,21 @@
      * @param uncompressed_yuv_420_image uncompressed SDR image in YUV_420 color format
      * @param uncompressed_recovery_map uncompressed recovery map
      * @param dest reconstructed HDR image
-     * @return true if calculation succeeds
+     * @return NO_ERROR if calculation succeeds, error code if error occurs.
      */
-    bool applyRecoveryMap(j_r_uncompressed_ptr uncompressed_yuv_420_image,
-                          j_r_uncompressed_ptr uncompressed_recovery_map,
-                          j_r_uncompressed_ptr dest);
+    status_t applyRecoveryMap(jr_uncompressed_ptr uncompressed_yuv_420_image,
+                              jr_uncompressed_ptr uncompressed_recovery_map,
+                              jr_uncompressed_ptr dest);
 
     /*
      * This method is called in the decoding pipeline. It will read XMP metadata to find the start
      * position of the compressed recovery map, and will extract the compressed recovery map.
      *
-     * @param compressed_jpeg_r_image compressed JPEG_R image
-     * @return compressed recovery map
+     * @param compressed_jpegr_image compressed JPEGR image
+     * @param dest destination of compressed recovery map
+     * @return NO_ERROR if calculation succeeds, error code if error occurs.
      */
-    j_r_compressed_ptr extractRecoveryMap(void* compressed_jpeg_r_image);
+    status_t extractRecoveryMap(void* compressed_jpegr_image, jr_compressed_ptr dest);
 
     /*
      * This method is called in the encoding pipeline. It will take the standard 8-bit JPEG image
@@ -106,10 +162,12 @@
      *
      * @param compressed_jpeg_image compressed 8-bit JPEG image
      * @param compress_recovery_map compressed recover map
-     * @return compressed JPEG_R image
+     * @param dest compressed JPEGR image
+     * @return NO_ERROR if calculation succeeds, error code if error occurs.
      */
-    void* appendRecoveryMap(void* compressed_jpeg_image,
-                            j_r_compressed_ptr compressed_recovery_map);
+    status_t appendRecoveryMap(void* compressed_jpeg_image,
+                               jr_compressed_ptr compressed_recovery_map,
+                               void* dest);
 };
 
 } // namespace android::recoverymap
diff --git a/libs/jpegrecoverymap/recoverymap.cpp b/libs/jpegrecoverymap/recoverymap.cpp
index bd92652..5d25722 100644
--- a/libs/jpegrecoverymap/recoverymap.cpp
+++ b/libs/jpegrecoverymap/recoverymap.cpp
@@ -18,69 +18,123 @@
 
 namespace android::recoverymap {
 
-bool RecoveryMap::decodeRecoveryMap(j_r_compressed_ptr compressed_recovery_map,
-                                    j_r_uncompressed_ptr dest) {
+status_t RecoveryMap::encodeJPEGR(jr_uncompressed_ptr uncompressed_p010_image,
+                                  jr_uncompressed_ptr uncompressed_yuv_420_image,
+                                  void* dest) {
+  if (uncompressed_p010_image == nullptr
+   || uncompressed_yuv_420_image == nullptr
+   || dest == nullptr) {
+    return BAD_VALUE;
+  }
+
+  // TBD
+  return NO_ERROR;
+}
+
+status_t RecoveryMap::encodeJPEGR(jr_uncompressed_ptr uncompressed_p010_image,
+                                  jr_uncompressed_ptr uncompressed_yuv_420_image,
+                                  void* compressed_jpeg_image,
+                                  void* dest) {
+
+  if (uncompressed_p010_image == nullptr
+   || uncompressed_yuv_420_image == nullptr
+   || compressed_jpeg_image == nullptr
+   || dest == nullptr) {
+    return BAD_VALUE;
+  }
+
+  // TBD
+  return NO_ERROR;
+}
+
+status_t RecoveryMap::encodeJPEGR(jr_uncompressed_ptr uncompressed_p010_image,
+                                  void* compressed_jpeg_image,
+                                  void* dest) {
+  if (uncompressed_p010_image == nullptr
+   || compressed_jpeg_image == nullptr
+   || dest == nullptr) {
+    return BAD_VALUE;
+  }
+
+  // TBD
+  return NO_ERROR;
+}
+
+status_t RecoveryMap::decodeJPEGR(void* compressed_jpegr_image, jr_uncompressed_ptr dest) {
+  if (compressed_jpegr_image == nullptr || dest == nullptr) {
+    return BAD_VALUE;
+  }
+
+  // TBD
+  return NO_ERROR;
+}
+
+status_t RecoveryMap::decodeRecoveryMap(jr_compressed_ptr compressed_recovery_map,
+                                        jr_uncompressed_ptr dest) {
   if (compressed_recovery_map == nullptr || dest == nullptr) {
-    return false;
+    return BAD_VALUE;
   }
 
   // TBD
-  return true;
+  return NO_ERROR;
 }
 
-bool RecoveryMap::encodeRecoveryMap(j_r_uncompressed_ptr uncompressed_recovery_map,
-                                    j_r_compressed_ptr dest) {
+status_t RecoveryMap::encodeRecoveryMap(jr_uncompressed_ptr uncompressed_recovery_map,
+                                        jr_compressed_ptr dest) {
   if (uncompressed_recovery_map == nullptr || dest == nullptr) {
-    return false;
+    return BAD_VALUE;
   }
 
   // TBD
-  return true;
+  return NO_ERROR;
 }
 
-bool RecoveryMap::generateRecoveryMap(j_r_uncompressed_ptr uncompressed_yuv_420_image,
-                                      j_r_uncompressed_ptr uncompressed_p010_image,
-                                      j_r_uncompressed_ptr dest) {
+status_t RecoveryMap::generateRecoveryMap(jr_uncompressed_ptr uncompressed_yuv_420_image,
+                                          jr_uncompressed_ptr uncompressed_p010_image,
+                                          jr_uncompressed_ptr dest) {
   if (uncompressed_yuv_420_image == nullptr
    || uncompressed_p010_image == nullptr
    || dest == nullptr) {
-    return false;
+    return BAD_VALUE;
   }
 
   // TBD
-  return true;
+  return NO_ERROR;
 }
 
-bool RecoveryMap::applyRecoveryMap(j_r_uncompressed_ptr uncompressed_yuv_420_image,
-                                   j_r_uncompressed_ptr uncompressed_recovery_map,
-                                   j_r_uncompressed_ptr dest) {
+status_t RecoveryMap::applyRecoveryMap(jr_uncompressed_ptr uncompressed_yuv_420_image,
+                                       jr_uncompressed_ptr uncompressed_recovery_map,
+                                       jr_uncompressed_ptr dest) {
   if (uncompressed_yuv_420_image == nullptr
    || uncompressed_recovery_map == nullptr
    || dest == nullptr) {
-    return false;
+    return BAD_VALUE;
   }
 
   // TBD
-  return true;
+  return NO_ERROR;
 }
 
-j_r_compressed_ptr RecoveryMap::extractRecoveryMap(void* compressed_jpeg_r_image) {
-  if (compressed_jpeg_r_image == nullptr) {
-    return nullptr;
+status_t RecoveryMap::extractRecoveryMap(void* compressed_jpegr_image, jr_compressed_ptr dest) {
+  if (compressed_jpegr_image == nullptr || dest == nullptr) {
+    return BAD_VALUE;
   }
 
   // TBD
-  return nullptr;
+  return NO_ERROR;
 }
 
-void* RecoveryMap::appendRecoveryMap(void* compressed_jpeg_image,
-                                     j_r_compressed_ptr compressed_recovery_map) {
-  if (compressed_jpeg_image == nullptr || compressed_recovery_map == nullptr) {
-    return nullptr;
+status_t RecoveryMap::appendRecoveryMap(void* compressed_jpeg_image,
+                                     jr_compressed_ptr compressed_recovery_map,
+                                     void* dest) {
+  if (compressed_jpeg_image == nullptr
+   || compressed_recovery_map == nullptr
+   || dest == nullptr) {
+    return BAD_VALUE;
   }
 
   // TBD
-  return nullptr;
+  return NO_ERROR;
 }
 
 } // namespace android::recoverymap
diff --git a/opengl/libs/EGL/getProcAddress.cpp b/opengl/libs/EGL/getProcAddress.cpp
index b3d6f74..e0ba946 100644
--- a/opengl/libs/EGL/getProcAddress.cpp
+++ b/opengl/libs/EGL/getProcAddress.cpp
@@ -118,70 +118,27 @@
             : "rax", "cc"                                       \
             );
 
-#elif defined(__mips64)
+#elif defined(__riscv)
+    #define API_ENTRY(_api) __attribute__((noinline)) _api
 
-        #define API_ENTRY(_api) __attribute__((noinline)) _api
-
-        #define CALL_GL_EXTENSION_API(_api, ...)                    \
-            register unsigned int _t0 asm("$12");                   \
-            register unsigned int _fn asm("$25");                   \
-            register unsigned int _tls asm("$3");                   \
-            asm volatile(                                           \
-                ".set  push\n\t"                                    \
-                ".set  noreorder\n\t"                               \
-                "rdhwr %[tls], $29\n\t"                             \
-                "ld    %[t0], %[OPENGL_API](%[tls])\n\t"            \
-                "beqz  %[t0], 1f\n\t"                               \
-                " move %[fn], $ra\n\t"                              \
-                "ld    %[t0], %[API](%[t0])\n\t"                    \
-                "beqz  %[t0], 1f\n\t"                               \
-                " nop\n\t"                                          \
-                "move  %[fn], %[t0]\n\t"                            \
-                "1:\n\t"                                            \
-                "jalr  $0, %[fn]\n\t"                               \
-                " nop\n\t"                                          \
-                ".set  pop\n\t"                                     \
-                : [fn] "=c"(_fn),                                   \
-                  [tls] "=&r"(_tls),                                \
-                  [t0] "=&r"(_t0)                                   \
-                : [OPENGL_API] "I"(TLS_SLOT_OPENGL_API*4),          \
-                  [API] "I"(__builtin_offsetof(gl_hooks_t,          \
-                                          ext.extensions[_api]))    \
-                :                                                   \
-            );
-
-#elif defined(__mips__)
-
-        #define API_ENTRY(_api) __attribute__((noinline)) _api
-
-        #define CALL_GL_EXTENSION_API(_api, ...)                    \
-            register unsigned int _t0 asm("$8");                    \
-            register unsigned int _fn asm("$25");                    \
-            register unsigned int _tls asm("$3");                   \
-            asm volatile(                                           \
-                ".set  push\n\t"                                    \
-                ".set  noreorder\n\t"                               \
-                ".set  mips32r2\n\t"                                \
-                "rdhwr %[tls], $29\n\t"                             \
-                "lw    %[t0], %[OPENGL_API](%[tls])\n\t"            \
-                "beqz  %[t0], 1f\n\t"                               \
-                " move %[fn], $ra\n\t"                              \
-                "lw    %[t0], %[API](%[t0])\n\t"                    \
-                "beqz  %[t0], 1f\n\t"                               \
-                " nop\n\t"                                          \
-                "move  %[fn], %[t0]\n\t"                            \
-                "1:\n\t"                                            \
-                "jalr  $0, %[fn]\n\t"                               \
-                " nop\n\t"                                          \
-                ".set  pop\n\t"                                     \
-                : [fn] "=c"(_fn),                                   \
-                  [tls] "=&r"(_tls),                                \
-                  [t0] "=&r"(_t0)                                   \
-                : [OPENGL_API] "I"(TLS_SLOT_OPENGL_API*4),          \
-                  [API] "I"(__builtin_offsetof(gl_hooks_t,          \
-                                          ext.extensions[_api]))    \
-                :                                                   \
-            );
+    #define CALL_GL_EXTENSION_API(_api)                             \
+        asm volatile(                                               \
+            "mv t0, tp\n"                                           \
+            "li t1, %[tls]\n"                                       \
+            "add t0, t0, t1\n"                                      \
+            "ld t0, 0(t0)\n"                                        \
+            "beqz t0, 1f\n"                                         \
+            "li t1, %[api]\n"                                       \
+            "add t0, t0, t1\n"                                      \
+            "ld t0, 0(t0)\n"                                        \
+            "jalr x0, t0\n"                                         \
+            "1: ret\n"                                              \
+            :                                                       \
+            : [tls] "i" (TLS_SLOT_OPENGL_API * sizeof(void*)),      \
+              [api] "i" (__builtin_offsetof(gl_hooks_t,             \
+                                        ext.extensions[_api]))      \
+            : "t0", "t1"                                            \
+        );
 
 #endif
 
diff --git a/opengl/libs/GLES2/gl2.cpp b/opengl/libs/GLES2/gl2.cpp
index 65f50f5..5bd5c14 100644
--- a/opengl/libs/GLES2/gl2.cpp
+++ b/opengl/libs/GLES2/gl2.cpp
@@ -191,73 +191,44 @@
             :                              \
         );
 
-#elif defined(__mips64)
+#elif defined(__riscv)
 
     #define API_ENTRY(_api) __attribute__((naked,noinline)) _api
 
-    // t0:  $12
-    // fn:  $25
-    // tls: $3
-    // v0:  $2
-    #define CALL_GL_API_INTERNAL_CALL(_api, ...)                  \
-        asm volatile(                                             \
-            ".set  push\n\t"                                      \
-            ".set  noreorder\n\t"                                 \
-            "rdhwr $3, $29\n\t"                                   \
-            "ld    $12, %[OPENGL_API]($3)\n\t"                    \
-            "beqz  $12, 1f\n\t"                                   \
-            " move $25, $ra\n\t"                                  \
-            "ld    $12, %[API]($12)\n\t"                          \
-            "beqz  $12, 1f\n\t"                                   \
-            " nop\n\t"                                            \
-            "move  $25, $12\n\t"                                  \
-            "1:\n\t"                                              \
-            "jalr  $0, $25\n\t"                                   \
-            " move $2, $0\n\t"                                    \
-            ".set  pop\n\t"                                       \
-            :                                                     \
-            : [OPENGL_API] "I"(TLS_SLOT_OPENGL_API*sizeof(void*)),\
-              [API] "I"(__builtin_offsetof(gl_hooks_t, gl._api))  \
-            : "$2", "$3", "$4", "$5", "$6", "$7", "$8", "$9",     \
-              "$10", "$11", "$12", "$25"                          \
-        );
-
-    #define CALL_GL_API_INTERNAL_SET_RETURN_VALUE
-    #define CALL_GL_API_INTERNAL_DO_RETURN
-
-#elif defined(__mips__)
-
-    #define API_ENTRY(_api) __attribute__((naked,noinline)) _api
-
-    // t0:  $8
-    // fn:  $25
-    // tls: $3
-    // v0:  $2
     #define CALL_GL_API_INTERNAL_CALL(_api, ...)                 \
         asm volatile(                                            \
-            ".set  push\n\t"                                     \
-            ".set  noreorder\n\t"                                \
-            ".set  mips32r2\n\t"                                 \
-            "rdhwr $3, $29\n\t"                                  \
-            "lw    $3, %[OPENGL_API]($3)\n\t"                    \
-            "beqz  $3, 1f\n\t"                                   \
-            " move $25,$ra\n\t"                                  \
-            "lw    $3, %[API]($3)\n\t"                           \
-            "beqz  $3, 1f\n\t"                                   \
-            " nop\n\t"                                           \
-            "move  $25, $3\n\t"                                  \
-            "1:\n\t"                                             \
-            "jalr  $0, $25\n\t"                                  \
-            " move $2, $0\n\t"                                   \
-            ".set  pop\n\t"                                      \
+            "mv t0, tp\n"                                        \
+            "li t1, %[tls]\n"                                    \
+            "add t0, t0, t1\n"                                   \
+            "ld t0, 0(t0)\n"                                     \
+            "beqz t0, 1f\n"                                      \
+            "li t1, %[api]\n"                                    \
+            "add t0, t0, t1\n"                                   \
+            "ld t0, 0(t0)\n"                                     \
+            "jalr x0, t0\n"                                      \
+            "1:\n"                                               \
             :                                                    \
-            : [OPENGL_API] "I"(TLS_SLOT_OPENGL_API*4),           \
-              [API] "I"(__builtin_offsetof(gl_hooks_t, gl._api)) \
-            : "$2", "$3", "$4", "$5", "$6", "$7", "$8", "$25"    \
+            : [tls] "i"(TLS_SLOT_OPENGL_API*sizeof(void *)),     \
+              [api] "i"(__builtin_offsetof(gl_hooks_t, gl._api)) \
+            : "t0", "t1", "t2", "a0", "a1", "a2", "a3", "a4",    \
+              "a5", "t6", "t3", "t4", "t5", "t6"                 \
         );
 
-    #define CALL_GL_API_INTERNAL_SET_RETURN_VALUE
-    #define CALL_GL_API_INTERNAL_DO_RETURN
+    #define CALL_GL_API_INTERNAL_SET_RETURN_VALUE \
+        asm volatile(                             \
+            "li a0, 0\n"                          \
+            :                                     \
+            :                                     \
+            : "a0"                                \
+        );
+
+    #define CALL_GL_API_INTERNAL_DO_RETURN \
+        asm volatile(                      \
+            "ret\n"                        \
+            :                              \
+            :                              \
+            :                              \
+        );
 
 #endif
 
diff --git a/opengl/libs/GLES_CM/gl.cpp b/opengl/libs/GLES_CM/gl.cpp
index bacd4b4..64c0f97 100644
--- a/opengl/libs/GLES_CM/gl.cpp
+++ b/opengl/libs/GLES_CM/gl.cpp
@@ -247,73 +247,44 @@
             :                              \
         );
 
-#elif defined(__mips64)
+#elif defined(__riscv)
 
     #define API_ENTRY(_api) __attribute__((naked,noinline)) _api
 
-    // t0:  $12
-    // fn:  $25
-    // tls: $3
-    // v0:  $2
-    #define CALL_GL_API_INTERNAL_CALL(_api, ...)                  \
-        asm volatile(                                             \
-            ".set  push\n\t"                                      \
-            ".set  noreorder\n\t"                                 \
-            "rdhwr $3, $29\n\t"                                   \
-            "ld    $12, %[OPENGL_API]($3)\n\t"                    \
-            "beqz  $12, 1f\n\t"                                   \
-            " move $25, $ra\n\t"                                  \
-            "ld    $12, %[API]($12)\n\t"                          \
-            "beqz  $12, 1f\n\t"                                   \
-            " nop\n\t"                                            \
-            "move  $25, $12\n\t"                                  \
-            "1:\n\t"                                              \
-            "jalr  $0, $25\n\t"                                   \
-            " move $2, $0\n\t"                                    \
-            ".set  pop\n\t"                                       \
-            :                                                     \
-            : [OPENGL_API] "I"(TLS_SLOT_OPENGL_API*sizeof(void*)),\
-              [API] "I"(__builtin_offsetof(gl_hooks_t, gl._api))  \
-            : "$2", "$3", "$4", "$5", "$6", "$7", "$8", "$9",     \
-              "$10", "$11", "$12", "$25"                          \
-        );
-
-    #define CALL_GL_API_INTERNAL_SET_RETURN_VALUE
-    #define CALL_GL_API_INTERNAL_DO_RETURN
-
-#elif defined(__mips__)
-
-    #define API_ENTRY(_api) __attribute__((naked,noinline)) _api
-
-    // t0:  $8
-    // fn:  $25
-    // tls: $3
-    // v0:  $2
     #define CALL_GL_API_INTERNAL_CALL(_api, ...)                 \
         asm volatile(                                            \
-            ".set  push\n\t"                                     \
-            ".set  noreorder\n\t"                                \
-            ".set  mips32r2\n\t"                                 \
-            "rdhwr $3, $29\n\t"                                  \
-            "lw    $3, %[OPENGL_API]($3)\n\t"                    \
-            "beqz  $3, 1f\n\t"                                   \
-            " move $25,$ra\n\t"                                  \
-            "lw    $3, %[API]($3)\n\t"                           \
-            "beqz  $3, 1f\n\t"                                   \
-            " nop\n\t"                                           \
-            "move  $25, $3\n\t"                                  \
-            "1:\n\t"                                             \
-            "jalr  $0, $25\n\t"                                  \
-            " move $2, $0\n\t"                                   \
-            ".set  pop\n\t"                                      \
+            "mv t0, tp\n"                                        \
+            "li t1, %[tls]\n"                                    \
+            "add t0, t0, t1\n"                                   \
+            "ld t0, 0(t0)\n"                                     \
+            "beqz t0, 1f\n"                                      \
+            "li t1, %[api]\n"                                    \
+            "add t0, t0, t1\n"                                   \
+            "ld t0, 0(t0)\n"                                     \
+            "jalr x0, t0\n"                                      \
+            "1:\n"                                               \
             :                                                    \
-            : [OPENGL_API] "I"(TLS_SLOT_OPENGL_API*4),           \
-              [API] "I"(__builtin_offsetof(gl_hooks_t, gl._api)) \
-            : "$2", "$3", "$4", "$5", "$6", "$7", "$8", "$25"    \
+            : [tls] "i"(TLS_SLOT_OPENGL_API*sizeof(void *)),     \
+              [api] "i"(__builtin_offsetof(gl_hooks_t, gl._api)) \
+            : "t0", "t1", "t2", "a0", "a1", "a2", "a3", "a4",    \
+              "a5", "t6", "t3", "t4", "t5", "t6"                 \
         );
 
-    #define CALL_GL_API_INTERNAL_SET_RETURN_VALUE
-    #define CALL_GL_API_INTERNAL_DO_RETURN
+    #define CALL_GL_API_INTERNAL_SET_RETURN_VALUE \
+        asm volatile(                             \
+            "li a0, 0\n"                          \
+            :                                     \
+            :                                     \
+            : "a0"                                \
+        );
+
+    #define CALL_GL_API_INTERNAL_DO_RETURN \
+        asm volatile(                      \
+            "ret\n"                        \
+            :                              \
+            :                              \
+            :                              \
+        );
 
 #endif
 
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp
index 2ecd7bc..acd3d75 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.cpp
+++ b/services/inputflinger/dispatcher/InputDispatcher.cpp
@@ -1071,7 +1071,7 @@
                                                                 int32_t y, TouchState* touchState,
                                                                 bool isStylus,
                                                                 bool addOutsideTargets,
-                                                                bool ignoreDragWindow) {
+                                                                bool ignoreDragWindow) const {
     if (addOutsideTargets && touchState == nullptr) {
         LOG_ALWAYS_FATAL("Must provide a valid touch state if adding outside targets");
     }
@@ -3984,13 +3984,14 @@
     if (DEBUG_INBOUND_EVENT_DETAILS) {
         ALOGD("notifyMotion - id=%" PRIx32 " eventTime=%" PRId64 ", deviceId=%d, source=0x%x, "
               "displayId=%" PRId32 ", policyFlags=0x%x, "
-              "action=0x%x, actionButton=0x%x, flags=0x%x, metaState=0x%x, buttonState=0x%x, "
+              "action=%s, actionButton=0x%x, flags=0x%x, metaState=0x%x, buttonState=0x%x, "
               "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, xCursorPosition=%f, "
               "yCursorPosition=%f, downTime=%" PRId64,
               args->id, args->eventTime, args->deviceId, args->source, args->displayId,
-              args->policyFlags, args->action, args->actionButton, args->flags, args->metaState,
-              args->buttonState, args->edgeFlags, args->xPrecision, args->yPrecision,
-              args->xCursorPosition, args->yCursorPosition, args->downTime);
+              args->policyFlags, MotionEvent::actionToString(args->action).c_str(),
+              args->actionButton, args->flags, args->metaState, args->buttonState, args->edgeFlags,
+              args->xPrecision, args->yPrecision, args->xCursorPosition, args->yCursorPosition,
+              args->downTime);
         for (uint32_t i = 0; i < args->pointerCount; i++) {
             ALOGD("  Pointer %d: id=%d, toolType=%d, "
                   "x=%f, y=%f, pressure=%f, size=%f, "
diff --git a/services/inputflinger/dispatcher/InputDispatcher.h b/services/inputflinger/dispatcher/InputDispatcher.h
index 14b046a..b20a548 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.h
+++ b/services/inputflinger/dispatcher/InputDispatcher.h
@@ -239,7 +239,7 @@
 
     sp<android::gui::WindowInfoHandle> findTouchedWindowAtLocked(
             int32_t displayId, int32_t x, int32_t y, TouchState* touchState, bool isStylus = false,
-            bool addOutsideTargets = false, bool ignoreDragWindow = false) REQUIRES(mLock);
+            bool addOutsideTargets = false, bool ignoreDragWindow = false) const REQUIRES(mLock);
 
     std::vector<sp<android::gui::WindowInfoHandle>> findTouchedSpyWindowsAtLocked(
             int32_t displayId, int32_t x, int32_t y, bool isStylus) const REQUIRES(mLock);