Add API to WebView functor to support overlays

This CL adds api that exposes SurfaceControl to allow webview to
submit ASurfaceTransaction synchronously with hwui draw.

Test: just new API stubs, nothing to test.
Change-Id: I3a70ad12d04e5a1655887faf3782426a9131a999
diff --git a/libs/hwui/WebViewFunctorManager.cpp b/libs/hwui/WebViewFunctorManager.cpp
index 68541b4..671c66f 100644
--- a/libs/hwui/WebViewFunctorManager.cpp
+++ b/libs/hwui/WebViewFunctorManager.cpp
@@ -26,6 +26,35 @@
 
 namespace android::uirenderer {
 
+namespace {
+class ScopedCurrentFunctor {
+public:
+    ScopedCurrentFunctor(WebViewFunctor* functor) {
+        ALOG_ASSERT(!sCurrentFunctor);
+        ALOG_ASSERT(functor);
+        sCurrentFunctor = functor;
+    }
+    ~ScopedCurrentFunctor() {
+        ALOG_ASSERT(sCurrentFunctor);
+        sCurrentFunctor = nullptr;
+    }
+
+    static ASurfaceControl* getSurfaceControl() {
+        ALOG_ASSERT(sCurrentFunctor);
+        return sCurrentFunctor->getSurfaceControl();
+    }
+    static void mergeTransaction(ASurfaceTransaction* transaction) {
+        ALOG_ASSERT(sCurrentFunctor);
+        sCurrentFunctor->mergeTransaction(transaction);
+    }
+
+private:
+    static WebViewFunctor* sCurrentFunctor;
+};
+
+WebViewFunctor* ScopedCurrentFunctor::sCurrentFunctor = nullptr;
+}  // namespace
+
 RenderMode WebViewFunctor_queryPlatformRenderMode() {
     auto pipelineType = Properties::getRenderPipelineType();
     switch (pipelineType) {
@@ -83,7 +112,15 @@
     if (!mHasContext) {
         mHasContext = true;
     }
-    mCallbacks.gles.draw(mFunctor, mData, drawInfo);
+    ScopedCurrentFunctor currentFunctor(this);
+
+    WebViewOverlayData overlayParams = {
+            // TODO:
+            .overlaysMode = OverlaysMode::Disabled,
+            .getSurfaceControl = currentFunctor.getSurfaceControl,
+            .mergeTransaction = currentFunctor.mergeTransaction,
+    };
+    mCallbacks.gles.draw(mFunctor, mData, drawInfo, overlayParams);
 }
 
 void WebViewFunctor::initVk(const VkFunctorInitParams& params) {
@@ -98,7 +135,15 @@
 
 void WebViewFunctor::drawVk(const VkFunctorDrawParams& params) {
     ATRACE_NAME("WebViewFunctor::drawVk");
-    mCallbacks.vk.draw(mFunctor, mData, params);
+    ScopedCurrentFunctor currentFunctor(this);
+
+    WebViewOverlayData overlayParams = {
+            // TODO
+            .overlaysMode = OverlaysMode::Disabled,
+            .getSurfaceControl = currentFunctor.getSurfaceControl,
+            .mergeTransaction = currentFunctor.mergeTransaction,
+    };
+    mCallbacks.vk.draw(mFunctor, mData, params, overlayParams);
 }
 
 void WebViewFunctor::postDrawVk() {
@@ -118,6 +163,20 @@
     }
 }
 
+void WebViewFunctor::removeOverlays() {
+    ScopedCurrentFunctor currentFunctor(this);
+    mCallbacks.removeOverlays(mFunctor, mData, currentFunctor.mergeTransaction);
+}
+
+ASurfaceControl* WebViewFunctor::getSurfaceControl() {
+    // TODO
+    return nullptr;
+}
+
+void WebViewFunctor::mergeTransaction(ASurfaceTransaction* transaction) {
+    // TODO
+}
+
 WebViewFunctorManager& WebViewFunctorManager::instance() {
     static WebViewFunctorManager sInstance;
     return sInstance;
diff --git a/libs/hwui/WebViewFunctorManager.h b/libs/hwui/WebViewFunctorManager.h
index 675b738..737d605 100644
--- a/libs/hwui/WebViewFunctorManager.h
+++ b/libs/hwui/WebViewFunctorManager.h
@@ -56,6 +56,8 @@
 
         void postDrawVk() { mReference.postDrawVk(); }
 
+        void removeOverlays() { mReference.removeOverlays(); }
+
     private:
         friend class WebViewFunctor;
 
@@ -71,6 +73,10 @@
     void drawVk(const VkFunctorDrawParams& params);
     void postDrawVk();
     void destroyContext();
+    void removeOverlays();
+
+    ASurfaceControl* getSurfaceControl();
+    void mergeTransaction(ASurfaceTransaction* transaction);
 
     sp<Handle> createHandle() {
         LOG_ALWAYS_FATAL_IF(mCreatedHandle);
diff --git a/libs/hwui/private/hwui/WebViewFunctor.h b/libs/hwui/private/hwui/WebViewFunctor.h
index 96da947..22ae59e 100644
--- a/libs/hwui/private/hwui/WebViewFunctor.h
+++ b/libs/hwui/private/hwui/WebViewFunctor.h
@@ -17,6 +17,15 @@
 #ifndef FRAMEWORKS_BASE_WEBVIEWFUNCTOR_H
 #define FRAMEWORKS_BASE_WEBVIEWFUNCTOR_H
 
+#ifdef __ANDROID__  // Layoutlib does not support surface control
+#include <android/surface_control.h>
+#else
+// To avoid ifdefs around overlay implementation all over the place we typedef these to void *. They
+// won't be used.
+typedef void* ASurfaceControl;
+typedef void* ASurfaceTransaction;
+#endif
+
 #include <cutils/compiler.h>
 #include <private/hwui/DrawGlInfo.h>
 #include <private/hwui/DrawVkInfo.h>
@@ -28,6 +37,14 @@
     Vulkan,
 };
 
+enum class OverlaysMode {
+    // Indicated that webview should not promote anything to overlays this draw
+    // and remove all visible overlays.
+    Disabled,
+    // Indicates that webview can use overlays.
+    Enabled
+};
+
 // Static for the lifetime of the process
 ANDROID_API RenderMode WebViewFunctor_queryPlatformRenderMode();
 
@@ -35,6 +52,23 @@
     bool applyForceDark;
 };
 
+struct WebViewOverlayData {
+    // Desired overlay mode for this draw.
+    OverlaysMode overlaysMode;
+
+    // Returns parent ASurfaceControl for WebView overlays. It will be have same
+    // geometry as the surface we draw into and positioned below it (underlay).
+    // This does not pass ownership to webview, but guaranteed to be alive until
+    // transaction from next removeOverlays call or functor destruction will be
+    // finished.
+    ASurfaceControl* (*getSurfaceControl)();
+
+    // Merges WebView transaction to be applied synchronously with current draw.
+    // This doesn't pass ownership of the transaction, changes will be copied and
+    // webview can free transaction right after the call.
+    void (*mergeTransaction)(ASurfaceTransaction*);
+};
+
 struct WebViewFunctorCallbacks {
     // kModeSync, called on RenderThread
     void (*onSync)(int functor, void* data, const WebViewSyncData& syncData);
@@ -48,16 +82,23 @@
     // this functor had ever been drawn.
     void (*onDestroyed)(int functor, void* data);
 
+    // Called on render thread to force webview hide all overlays and stop updating them.
+    // Should happen during hwui draw (e.g can be called instead of draw if webview
+    // isn't visible and won't receive draw) and support MergeTransaction call.
+    void (*removeOverlays)(int functor, void* data, void (*mergeTransaction)(ASurfaceTransaction*));
+
     union {
         struct {
             // Called on RenderThread. initialize is guaranteed to happen before this call
-            void (*draw)(int functor, void* data, const DrawGlInfo& params);
+            void (*draw)(int functor, void* data, const DrawGlInfo& params,
+                         const WebViewOverlayData& overlayParams);
         } gles;
         struct {
             // Called either the first time the functor is used or the first time it's used after
             // a call to onContextDestroyed.
             void (*initialize)(int functor, void* data, const VkFunctorInitParams& params);
-            void (*draw)(int functor, void* data, const VkFunctorDrawParams& params);
+            void (*draw)(int functor, void* data, const VkFunctorDrawParams& params,
+                         const WebViewOverlayData& overlayParams);
             void (*postDraw)(int functor, void*);
         } vk;
     };
diff --git a/libs/hwui/tests/common/TestUtils.h b/libs/hwui/tests/common/TestUtils.h
index 36c5a8c1..c1d8b76 100644
--- a/libs/hwui/tests/common/TestUtils.h
+++ b/libs/hwui/tests/common/TestUtils.h
@@ -323,7 +323,8 @@
         };
         switch (mode) {
             case RenderMode::OpenGL_ES:
-                callbacks.gles.draw = [](int functor, void* client_data, const DrawGlInfo& params) {
+                callbacks.gles.draw = [](int functor, void* client_data, const DrawGlInfo& params,
+                                         const WebViewOverlayData& overlay_params) {
                     expectOnRenderThread("draw");
                     sMockFunctorCounts[functor].glesDraw++;
                 };
diff --git a/native/webview/plat_support/draw_fn.h b/native/webview/plat_support/draw_fn.h
index 42cad43..44fe56f 100644
--- a/native/webview/plat_support/draw_fn.h
+++ b/native/webview/plat_support/draw_fn.h
@@ -10,6 +10,7 @@
 #ifndef ANDROID_WEBVIEW_PUBLIC_BROWSER_DRAW_FN_H_
 #define ANDROID_WEBVIEW_PUBLIC_BROWSER_DRAW_FN_H_
 
+#include <android/surface_control.h>
 #include <vulkan/vulkan.h>
 
 #ifdef __cplusplus
@@ -21,7 +22,31 @@
 //
 // 1 is Android Q. This matches kAwDrawGLInfoVersion version 3.
 // 2 Adds transfer_function_* and color_space_toXYZD50 to AwDrawFn_DrawGLParams.
-static const int kAwDrawFnVersion = 2;
+// 3 Adds SurfaceControl related functions.
+static const int kAwDrawFnVersion = 3;
+
+// Returns parent ASurfaceControl for WebView overlays. It will be have same
+// geometry as the surface we draw into and positioned below it (underlay).
+// This does not pass ownership to webview, but guaranteed to be alive until
+// transaction from next removeOverlays call or functor destruction will be
+// finished.
+typedef ASurfaceControl* AwDrawFn_GetSurfaceControl();
+
+// Merges WebView transaction to be applied synchronously with current draw.
+// This doesn't pass ownership of the transaction, changes will be copied and
+// webview can free transaction right after the call.
+typedef void AwDrawFn_MergeTransaction(ASurfaceTransaction* transaction);
+
+enum AwDrawFnOverlaysMode {
+  // Indicated that webview should not promote anything to overlays this draw
+  // and remove all visible overlays.
+  // Added in version 3.
+  AW_DRAW_FN_OVERLAYS_MODE_DISABLED = 0,
+
+  // Indicates that webview can use overlays.
+  // Added in version 3.
+  AW_DRAW_FN_OVERLAYS_MODE_ENABLED = 1,
+};
 
 struct AwDrawFn_OnSyncParams {
   int version;
@@ -60,6 +85,19 @@
   float transfer_function_e;
   float transfer_function_f;
   float color_space_toXYZD50[9];
+
+  // Input: Indicates how webview should use overlays for this draw.
+  // Added in version 3.
+  AwDrawFnOverlaysMode overlays_mode;
+
+  // Input: WebView can call it to obtain parent surface control for overlays.
+  // Added in version 3.
+  AwDrawFn_GetSurfaceControl* get_surface_control;
+
+  // Input: WebView call this to apply ASurfaceTransaction synchronously with
+  // the draw.
+  // Added in version 3.
+  AwDrawFn_MergeTransaction* merge_transaction;
 };
 
 struct AwDrawFn_InitVkParams {
@@ -122,12 +160,33 @@
   int clip_top;
   int clip_right;
   int clip_bottom;
+
+  // Input: Indicates how webview should use overlays for this draw.
+  // Added in version 3.
+  AwDrawFnOverlaysMode overlays_mode;
+
+  // Input: WebView can call it to obtain parent surface control for overlays.
+  // Added in version 3.
+  AwDrawFn_GetSurfaceControl* get_surface_control;
+
+  // Input: WebView call this to apply ASurfaceTransaction synchronously with
+  // the draw.
+  // Added in version 3.
+  AwDrawFn_MergeTransaction* merge_transaction;
 };
 
 struct AwDrawFn_PostDrawVkParams {
   int version;
 };
 
+struct AwDrawFn_RemoveOverlaysParams {
+  int version;
+  // Input: WebView call this to apply ASurfaceTransaction synchronously with
+  // the draw.
+  // Added in version 3.
+  AwDrawFn_MergeTransaction* merge_transaction;
+};
+
 // Called on render thread while UI thread is blocked. Called for both GL and
 // VK.
 typedef void AwDrawFn_OnSync(int functor,
@@ -166,8 +225,15 @@
                                  void* data,
                                  AwDrawFn_PostDrawVkParams* params);
 
+// Can be called to make webview hide all overlays and stop updating them until
+// next draw. WebView must obtain new ASurfaceControl after this call to use as
+// parent for the overlays on next draw.
+typedef void AwDrawFn_RemoveOverlays(int functor,
+                                     void* data,
+                                     AwDrawFn_RemoveOverlaysParams* params);
+
 struct AwDrawFnFunctorCallbacks {
-  // No version here since this is passed from chromium to android.
+  // version is passed in CreateFunctor call.
   AwDrawFn_OnSync* on_sync;
   AwDrawFn_OnContextDestroyed* on_context_destroyed;
   AwDrawFn_OnDestroyed* on_destroyed;
@@ -175,6 +241,8 @@
   AwDrawFn_InitVk* init_vk;
   AwDrawFn_DrawVk* draw_vk;
   AwDrawFn_PostDrawVk* post_draw_vk;
+  // Added in version 3.
+  AwDrawFn_RemoveOverlays* remove_overlays;
 };
 
 enum AwDrawFnRenderMode {
@@ -185,10 +253,16 @@
 // Get the render mode. Result is static for the process.
 typedef AwDrawFnRenderMode AwDrawFn_QueryRenderMode(void);
 
-// Create a functor. |functor_callbacks| should be valid until OnDestroyed.
+// This available up to version 3, use the one below.
 typedef int AwDrawFn_CreateFunctor(void* data,
                                    AwDrawFnFunctorCallbacks* functor_callbacks);
 
+// Create a functor. |functor_callbacks| should be valid until OnDestroyed.
+typedef int AwDrawFn_CreateFunctor_v3(
+    void* data,
+    int version,
+    AwDrawFnFunctorCallbacks* functor_callbacks);
+
 // May be called on any thread to signal that the functor should be destroyed.
 // The functor will receive an onDestroyed when the last usage of it is
 // released, and it should be considered alive & active until that point.
@@ -197,8 +271,11 @@
 struct AwDrawFnFunctionTable {
   int version;
   AwDrawFn_QueryRenderMode* query_render_mode;
+  // Available up to version 3.
   AwDrawFn_CreateFunctor* create_functor;
   AwDrawFn_ReleaseFunctor* release_functor;
+  // Added in version 3.
+  AwDrawFn_CreateFunctor_v3* create_functor_v3;
 };
 
 #ifdef __cplusplus
diff --git a/native/webview/plat_support/draw_functor.cpp b/native/webview/plat_support/draw_functor.cpp
index 7cce61b..ea57ea0 100644
--- a/native/webview/plat_support/draw_functor.cpp
+++ b/native/webview/plat_support/draw_functor.cpp
@@ -32,6 +32,15 @@
   AwDrawFnFunctorCallbacks callbacks;
 };
 
+AwDrawFnOverlaysMode GetOverlaysMode(uirenderer::OverlaysMode overlays_mode) {
+  switch (overlays_mode) {
+    case uirenderer::OverlaysMode::Disabled:
+      return AW_DRAW_FN_OVERLAYS_MODE_DISABLED;
+    case uirenderer::OverlaysMode::Enabled:
+      return AW_DRAW_FN_OVERLAYS_MODE_ENABLED;
+  }
+}
+
 void onSync(int functor, void* data,
             const uirenderer::WebViewSyncData& syncData) {
   AwDrawFn_OnSyncParams params = {
@@ -53,8 +62,20 @@
   delete support;
 }
 
+void removeOverlays(int functor, void* data,
+                    AwDrawFn_MergeTransaction merge_transaction) {
+  AwDrawFn_RemoveOverlaysParams params = {
+      .version = kAwDrawFnVersion,
+      .merge_transaction = merge_transaction
+  };
+  SupportData* support = static_cast<SupportData*>(data);
+  if (support->callbacks.remove_overlays)
+    support->callbacks.remove_overlays(functor, support->data, &params);
+}
+
 void draw_gl(int functor, void* data,
-             const uirenderer::DrawGlInfo& draw_gl_params) {
+             const uirenderer::DrawGlInfo& draw_gl_params,
+             const uirenderer::WebViewOverlayData& overlay_params) {
   float gabcdef[7];
   draw_gl_params.color_space_ptr->transferFn(gabcdef);
   AwDrawFn_DrawGLParams params = {
@@ -73,6 +94,9 @@
       .transfer_function_d = gabcdef[4],
       .transfer_function_e = gabcdef[5],
       .transfer_function_f = gabcdef[6],
+      .overlays_mode = GetOverlaysMode(overlay_params.overlaysMode),
+      .get_surface_control = overlay_params.getSurfaceControl,
+      .merge_transaction = overlay_params.mergeTransaction
   };
   COMPILE_ASSERT(NELEM(params.transform) == NELEM(draw_gl_params.transform),
                  mismatched_transform_matrix_sizes);
@@ -118,7 +142,9 @@
   support->callbacks.init_vk(functor, support->data, &params);
 }
 
-void drawVk(int functor, void* data, const uirenderer::VkFunctorDrawParams& draw_vk_params) {
+void drawVk(int functor, void* data,
+            const uirenderer::VkFunctorDrawParams& draw_vk_params,
+            const uirenderer::WebViewOverlayData& overlay_params) {
   SupportData* support = static_cast<SupportData*>(data);
   float gabcdef[7];
   draw_vk_params.color_space_ptr->transferFn(gabcdef);
@@ -142,6 +168,9 @@
       .clip_top = draw_vk_params.clip_top,
       .clip_right = draw_vk_params.clip_right,
       .clip_bottom = draw_vk_params.clip_bottom,
+      .overlays_mode = GetOverlaysMode(overlay_params.overlaysMode),
+      .get_surface_control = overlay_params.getSurfaceControl,
+      .merge_transaction = overlay_params.mergeTransaction
   };
   COMPILE_ASSERT(sizeof(params.color_space_toXYZD50) == sizeof(skcms_Matrix3x3),
                  gamut_transform_size_mismatch);
@@ -161,12 +190,14 @@
   support->callbacks.post_draw_vk(functor, support->data, &params);
 }
 
-int CreateFunctor(void* data, AwDrawFnFunctorCallbacks* functor_callbacks) {
+int CreateFunctor_v3(void* data, int version,
+                     AwDrawFnFunctorCallbacks* functor_callbacks) {
   static bool callbacks_initialized = false;
   static uirenderer::WebViewFunctorCallbacks webview_functor_callbacks = {
       .onSync = &onSync,
       .onContextDestroyed = &onContextDestroyed,
       .onDestroyed = &onDestroyed,
+      .removeOverlays = &removeOverlays,
   };
   if (!callbacks_initialized) {
     switch (uirenderer::WebViewFunctor_queryPlatformRenderMode()) {
@@ -183,8 +214,23 @@
   }
   SupportData* support = new SupportData{
       .data = data,
-      .callbacks = *functor_callbacks,
   };
+
+  // These callbacks are available on all versions.
+  support->callbacks = {
+      .on_sync = functor_callbacks->on_sync,
+      .on_context_destroyed = functor_callbacks->on_context_destroyed,
+      .on_destroyed = functor_callbacks->on_destroyed,
+      .draw_gl = functor_callbacks->draw_gl,
+      .init_vk = functor_callbacks->init_vk,
+      .draw_vk = functor_callbacks->draw_vk,
+      .post_draw_vk = functor_callbacks->post_draw_vk,
+  };
+
+  if (version >= 3) {
+    support->callbacks.remove_overlays = functor_callbacks->remove_overlays;
+  }
+
   int functor = uirenderer::WebViewFunctor_create(
       support, webview_functor_callbacks,
       uirenderer::WebViewFunctor_queryPlatformRenderMode());
@@ -192,6 +238,12 @@
   return functor;
 }
 
+int CreateFunctor(void* data, AwDrawFnFunctorCallbacks* functor_callbacks) {
+  const int kVersionForDeprecatedCreateFunctor = 2;
+  return CreateFunctor_v3(data, kVersionForDeprecatedCreateFunctor,
+                          functor_callbacks);
+}
+
 void ReleaseFunctor(int functor) {
   uirenderer::WebViewFunctor_release(functor);
 }
@@ -211,6 +263,7 @@
     .query_render_mode = &QueryRenderMode,
     .create_functor = &CreateFunctor,
     .release_functor = &ReleaseFunctor,
+    .create_functor_v3 = &CreateFunctor_v3,
   };
   return reinterpret_cast<intptr_t>(&function_table);
 }