Webview overlay support

The basic idea is to create a child surface control from the root surface control passed from ViewRootImpl to the render thread.

Transactions are sent back to the java layer to get merged.

In case of offscreen layers, SurfaceControl must be disabled.

This new feature is disabled for Vulkan at the moment, a new CL will be used to enable the support.

Bug: 173671170
Test: manual, webview apks
Change-Id: I119405d13eca3c59fd3ec78e50dc7739f78411d4
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index 2482188..bba2207 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -56,6 +56,22 @@
 namespace uirenderer {
 namespace renderthread {
 
+namespace {
+class ScopedActiveContext {
+public:
+    ScopedActiveContext(CanvasContext* context) { sActiveContext = context; }
+
+    ~ScopedActiveContext() { sActiveContext = nullptr; }
+
+    static CanvasContext* getActiveContext() { return sActiveContext; }
+
+private:
+    static CanvasContext* sActiveContext;
+};
+
+CanvasContext* ScopedActiveContext::sActiveContext = nullptr;
+} /* namespace */
+
 CanvasContext* CanvasContext::create(RenderThread& thread, bool translucent,
                                      RenderNode* rootRenderNode, IContextFactory* contextFactory) {
     auto renderType = Properties::getRenderPipelineType();
@@ -473,6 +489,7 @@
         return;
     }
 
+    ScopedActiveContext activeContext(this);
     mCurrentFrameInfo->set(FrameInfoIndex::FrameInterval) =
             mRenderThread.timeLord().frameIntervalNanos();
 
@@ -880,6 +897,17 @@
     return windowDirty;
 }
 
+CanvasContext* CanvasContext::getActiveContext() {
+    return ScopedActiveContext::getActiveContext();
+}
+
+bool CanvasContext::mergeTransaction(ASurfaceTransaction* transaction, ASurfaceControl* control) {
+    if (!mASurfaceTransactionCallback) return false;
+    std::invoke(mASurfaceTransactionCallback, reinterpret_cast<int64_t>(transaction),
+                reinterpret_cast<int64_t>(control), getFrameNumber());
+    return true;
+}
+
 } /* namespace renderthread */
 } /* namespace uirenderer */
 } /* namespace android */
diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h
index 74f426e..af1ebb2 100644
--- a/libs/hwui/renderthread/CanvasContext.h
+++ b/libs/hwui/renderthread/CanvasContext.h
@@ -109,6 +109,8 @@
      */
     GrDirectContext* getGrContext() const { return mRenderThread.getGrContext(); }
 
+    ASurfaceControl* getSurfaceControl() const { return mSurfaceControl; }
+
     // Won't take effect until next EGLSurface creation
     void setSwapBehavior(SwapBehavior swapBehavior);
 
@@ -201,6 +203,15 @@
     static void onSurfaceStatsAvailable(void* context, ASurfaceControl* control,
             ASurfaceControlStats* stats);
 
+    void setASurfaceTransactionCallback(
+            const std::function<void(int64_t, int64_t, int64_t)>& callback) {
+        mASurfaceTransactionCallback = callback;
+    }
+
+    bool mergeTransaction(ASurfaceTransaction* transaction, ASurfaceControl* control);
+
+    static CanvasContext* getActiveContext();
+
 private:
     CanvasContext(RenderThread& thread, bool translucent, RenderNode* rootRenderNode,
                   IContextFactory* contextFactory, std::unique_ptr<IRenderPipeline> renderPipeline);
@@ -296,6 +307,8 @@
 
     // If set to true, we expect that callbacks into onSurfaceStatsAvailable
     bool mExpectSurfaceStats = false;
+
+    std::function<void(int64_t, int64_t, int64_t)> mASurfaceTransactionCallback;
 };
 
 } /* namespace renderthread */
diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp
index 9361abd..1b4b4b9 100644
--- a/libs/hwui/renderthread/RenderProxy.cpp
+++ b/libs/hwui/renderthread/RenderProxy.cpp
@@ -295,6 +295,12 @@
             [this, cb = callback]() { mContext->setPictureCapturedCallback(cb); });
 }
 
+void RenderProxy::setASurfaceTransactionCallback(
+        const std::function<void(int64_t, int64_t, int64_t)>& callback) {
+    mRenderThread.queue().post(
+            [this, cb = callback]() { mContext->setASurfaceTransactionCallback(cb); });
+}
+
 void RenderProxy::setFrameCallback(std::function<void(int64_t)>&& callback) {
     mDrawFrameTask.setFrameCallback(std::move(callback));
 }
diff --git a/libs/hwui/renderthread/RenderProxy.h b/libs/hwui/renderthread/RenderProxy.h
index 8d55d3c..288f555 100644
--- a/libs/hwui/renderthread/RenderProxy.h
+++ b/libs/hwui/renderthread/RenderProxy.h
@@ -120,6 +120,8 @@
     void drawRenderNode(RenderNode* node);
     void setContentDrawBounds(int left, int top, int right, int bottom);
     void setPictureCapturedCallback(const std::function<void(sk_sp<SkPicture>&&)>& callback);
+    void setASurfaceTransactionCallback(
+            const std::function<void(int64_t, int64_t, int64_t)>& callback);
     void setFrameCallback(std::function<void(int64_t)>&& callback);
     void setFrameCompleteCallback(std::function<void(int64_t)>&& callback);
 
diff --git a/libs/hwui/renderthread/RenderThread.cpp b/libs/hwui/renderthread/RenderThread.cpp
index 682baa6..04aa1cb 100644
--- a/libs/hwui/renderthread/RenderThread.cpp
+++ b/libs/hwui/renderthread/RenderThread.cpp
@@ -54,6 +54,10 @@
 
 ASurfaceControlFunctions::ASurfaceControlFunctions() {
     void* handle_ = dlopen("libandroid.so", RTLD_NOW | RTLD_NODELETE);
+    createFunc = (ASC_create)dlsym(handle_, "ASurfaceControl_create");
+    LOG_ALWAYS_FATAL_IF(createFunc == nullptr,
+                        "Failed to find required symbol ASurfaceControl_create!");
+
     acquireFunc = (ASC_acquire) dlsym(handle_, "ASurfaceControl_acquire");
     LOG_ALWAYS_FATAL_IF(acquireFunc == nullptr,
             "Failed to find required symbol ASurfaceControl_acquire!");
@@ -81,6 +85,23 @@
             "ASurfaceControlStats_getFrameNumber");
     LOG_ALWAYS_FATAL_IF(getFrameNumberFunc == nullptr,
             "Failed to find required symbol ASurfaceControlStats_getFrameNumber!");
+
+    transactionCreateFunc = (AST_create)dlsym(handle_, "ASurfaceTransaction_create");
+    LOG_ALWAYS_FATAL_IF(transactionCreateFunc == nullptr,
+                        "Failed to find required symbol ASurfaceTransaction_create!");
+
+    transactionDeleteFunc = (AST_delete)dlsym(handle_, "ASurfaceTransaction_delete");
+    LOG_ALWAYS_FATAL_IF(transactionDeleteFunc == nullptr,
+                        "Failed to find required symbol ASurfaceTransaction_delete!");
+
+    transactionApplyFunc = (AST_apply)dlsym(handle_, "ASurfaceTransaction_apply");
+    LOG_ALWAYS_FATAL_IF(transactionApplyFunc == nullptr,
+                        "Failed to find required symbol ASurfaceTransaction_apply!");
+
+    transactionSetVisibilityFunc =
+            (AST_setVisibility)dlsym(handle_, "ASurfaceTransaction_setVisibility");
+    LOG_ALWAYS_FATAL_IF(transactionSetVisibilityFunc == nullptr,
+                        "Failed to find required symbol ASurfaceTransaction_setVisibility!");
 }
 
 void RenderThread::frameCallback(int64_t frameTimeNanos, void* data) {
diff --git a/libs/hwui/renderthread/RenderThread.h b/libs/hwui/renderthread/RenderThread.h
index 9e5bce7..cd9b923 100644
--- a/libs/hwui/renderthread/RenderThread.h
+++ b/libs/hwui/renderthread/RenderThread.h
@@ -79,25 +79,39 @@
     virtual ~VsyncSource() {}
 };
 
+typedef ASurfaceControl* (*ASC_create)(ASurfaceControl* parent, const char* debug_name);
 typedef void (*ASC_acquire)(ASurfaceControl* control);
 typedef void (*ASC_release)(ASurfaceControl* control);
 
 typedef void (*ASC_registerSurfaceStatsListener)(ASurfaceControl* control, void* context,
         ASurfaceControl_SurfaceStatsListener func);
 typedef void (*ASC_unregisterSurfaceStatsListener)(void* context,
-                                       ASurfaceControl_SurfaceStatsListener func);
+                                                   ASurfaceControl_SurfaceStatsListener func);
 
 typedef int64_t (*ASCStats_getAcquireTime)(ASurfaceControlStats* stats);
 typedef uint64_t (*ASCStats_getFrameNumber)(ASurfaceControlStats* stats);
 
+typedef ASurfaceTransaction* (*AST_create)();
+typedef void (*AST_delete)(ASurfaceTransaction* transaction);
+typedef void (*AST_apply)(ASurfaceTransaction* transaction);
+typedef void (*AST_setVisibility)(ASurfaceTransaction* transaction,
+                                  ASurfaceControl* surface_control, int8_t visibility);
+
 struct ASurfaceControlFunctions {
     ASurfaceControlFunctions();
+
+    ASC_create createFunc;
     ASC_acquire acquireFunc;
     ASC_release releaseFunc;
     ASC_registerSurfaceStatsListener registerListenerFunc;
     ASC_unregisterSurfaceStatsListener unregisterListenerFunc;
     ASCStats_getAcquireTime getAcquireTimeFunc;
     ASCStats_getFrameNumber getFrameNumberFunc;
+
+    AST_create transactionCreateFunc;
+    AST_delete transactionDeleteFunc;
+    AST_apply transactionApplyFunc;
+    AST_setVisibility transactionSetVisibilityFunc;
 };
 
 class ChoreographerSource;