Disable Webview Overlay when invisible

Remove Webview overlays when Webview node is set to invisible

Bug: 187292989
Test: play a video in a Webview, toggle visibility for the view, check
existence of a surface control named as "Webview Overlay
SurfaceControl#0"

Change-Id: If47a78a8ae1f7b65b9e7ab983ec72f580d78191a
diff --git a/libs/hwui/DisplayList.h b/libs/hwui/DisplayList.h
index 894b479..eb5878d 100644
--- a/libs/hwui/DisplayList.h
+++ b/libs/hwui/DisplayList.h
@@ -133,6 +133,12 @@
         }
     }
 
+    void onRemovedFromTree() {
+        if (mImpl) {
+            mImpl->onRemovedFromTree();
+        }
+    }
+
     [[nodiscard]] bool hasText() const {
         return mImpl && mImpl->hasText();
     }
@@ -172,6 +178,7 @@
             return false;
         }
         void syncContents(const WebViewSyncData& data) { }
+        void onRemovedFromTree() { }
         void applyColorTransform(ColorTransform transform) { }
     };
 
@@ -298,6 +305,10 @@
         apply([&](auto& it) { it.syncContents(data); });
     }
 
+    void onRemovedFromTree() {
+        apply([&](auto& it) { it.onRemovedFromTree(); });
+    }
+
     [[nodiscard]] bool hasText() const {
         return apply([](const auto& it) -> auto { return it.hasText(); });
     }
diff --git a/libs/hwui/RenderNode.cpp b/libs/hwui/RenderNode.cpp
index 44c335f..0c422df 100644
--- a/libs/hwui/RenderNode.cpp
+++ b/libs/hwui/RenderNode.cpp
@@ -18,6 +18,7 @@
 
 #include "DamageAccumulator.h"
 #include "Debug.h"
+#include "Properties.h"
 #include "TreeInfo.h"
 #include "VectorDrawable.h"
 #include "private/hwui/WebViewFunctor.h"
@@ -473,6 +474,9 @@
 }
 
 void RenderNode::onRemovedFromTree(TreeInfo* info) {
+    if (Properties::enableWebViewOverlays && mDisplayList) {
+        mDisplayList.onRemovedFromTree();
+    }
     destroyHardwareResources(info);
 }
 
diff --git a/libs/hwui/WebViewFunctorManager.cpp b/libs/hwui/WebViewFunctorManager.cpp
index 93f2f42..df41011 100644
--- a/libs/hwui/WebViewFunctorManager.cpp
+++ b/libs/hwui/WebViewFunctorManager.cpp
@@ -108,6 +108,13 @@
     mCallbacks.onSync(mFunctor, mData, syncData);
 }
 
+void WebViewFunctor::onRemovedFromTree() {
+    ATRACE_NAME("WebViewFunctor::onRemovedFromTree");
+    if (mSurfaceControl) {
+        removeOverlays();
+    }
+}
+
 void WebViewFunctor::drawGl(const DrawGlInfo& drawInfo) {
     ATRACE_NAME("WebViewFunctor::drawGl");
     if (!mHasContext) {
@@ -185,6 +192,7 @@
     ScopedCurrentFunctor currentFunctor(this);
     mCallbacks.removeOverlays(mFunctor, mData, currentFunctor.mergeTransaction);
     if (mSurfaceControl) {
+        reparentSurfaceControl(nullptr);
         auto funcs = renderthread::RenderThread::getInstance().getASurfaceControlFunctions();
         funcs.releaseFunc(mSurfaceControl);
         mSurfaceControl = nullptr;
@@ -217,9 +225,12 @@
 void WebViewFunctor::mergeTransaction(ASurfaceTransaction* transaction) {
     ATRACE_NAME("WebViewFunctor::mergeTransaction");
     if (transaction == nullptr) return;
+    bool done = false;
     renderthread::CanvasContext* activeContext = renderthread::CanvasContext::getActiveContext();
-    LOG_ALWAYS_FATAL_IF(activeContext == nullptr, "Null active canvas context!");
-    bool done = activeContext->mergeTransaction(transaction, mSurfaceControl);
+    // activeContext might be null when called from mCallbacks.removeOverlays()
+    if (activeContext != nullptr) {
+        done = activeContext->mergeTransaction(transaction, mSurfaceControl);
+    }
     if (!done) {
         auto funcs = renderthread::RenderThread::getInstance().getASurfaceControlFunctions();
         funcs.transactionApplyFunc(transaction);
diff --git a/libs/hwui/WebViewFunctorManager.h b/libs/hwui/WebViewFunctorManager.h
index 048d1fb..f28f310 100644
--- a/libs/hwui/WebViewFunctorManager.h
+++ b/libs/hwui/WebViewFunctorManager.h
@@ -58,6 +58,8 @@
 
         void removeOverlays() { mReference.removeOverlays(); }
 
+        void onRemovedFromTree() { mReference.onRemovedFromTree(); }
+
     private:
         friend class WebViewFunctor;
 
@@ -74,6 +76,7 @@
     void postDrawVk();
     void destroyContext();
     void removeOverlays();
+    void onRemovedFromTree();
 
     ASurfaceControl* getSurfaceControl();
     void mergeTransaction(ASurfaceTransaction* transaction);
diff --git a/libs/hwui/canvas/CanvasOpBuffer.cpp b/libs/hwui/canvas/CanvasOpBuffer.cpp
index 6089c572..336c5d8 100644
--- a/libs/hwui/canvas/CanvasOpBuffer.cpp
+++ b/libs/hwui/canvas/CanvasOpBuffer.cpp
@@ -46,6 +46,10 @@
     LOG_ALWAYS_FATAL("TODO");
 }
 
+void CanvasOpBuffer::onRemovedFromTree() {
+    LOG_ALWAYS_FATAL("TODO");
+}
+
 void CanvasOpBuffer::applyColorTransform(ColorTransform transform) {
     LOG_ALWAYS_FATAL("TODO");
 }
diff --git a/libs/hwui/canvas/CanvasOpBuffer.h b/libs/hwui/canvas/CanvasOpBuffer.h
index af797ca..529546d 100644
--- a/libs/hwui/canvas/CanvasOpBuffer.h
+++ b/libs/hwui/canvas/CanvasOpBuffer.h
@@ -100,6 +100,7 @@
             TreeObserver& observer, TreeInfo& info, bool functorsNeedLayer,
             std::function<void(RenderNode*, TreeObserver&, TreeInfo&, bool)> childFn);
     void syncContents(const WebViewSyncData& data);
+    void onRemovedFromTree();
     void applyColorTransform(ColorTransform transform);
 
     [[nodiscard]] bool isEmpty() const { return !mHas.content; }
diff --git a/libs/hwui/pipeline/skia/FunctorDrawable.h b/libs/hwui/pipeline/skia/FunctorDrawable.h
index 988a896..9bbd0a9 100644
--- a/libs/hwui/pipeline/skia/FunctorDrawable.h
+++ b/libs/hwui/pipeline/skia/FunctorDrawable.h
@@ -44,6 +44,10 @@
         mWebViewHandle->sync(data);
     }
 
+    virtual void onRemovedFromTree() {
+        mWebViewHandle->onRemovedFromTree();
+    }
+
 protected:
     virtual SkRect onGetBounds() override { return mBounds; }
 
diff --git a/libs/hwui/pipeline/skia/SkiaDisplayList.cpp b/libs/hwui/pipeline/skia/SkiaDisplayList.cpp
index 3498f71..fcfc4f8 100644
--- a/libs/hwui/pipeline/skia/SkiaDisplayList.cpp
+++ b/libs/hwui/pipeline/skia/SkiaDisplayList.cpp
@@ -47,6 +47,12 @@
     }
 }
 
+void SkiaDisplayList::onRemovedFromTree() {
+    for (auto& functor : mChildFunctors) {
+        functor->onRemovedFromTree();
+    }
+}
+
 bool SkiaDisplayList::reuseDisplayList(RenderNode* node) {
     reset();
     node->attachAvailableList(this);
diff --git a/libs/hwui/pipeline/skia/SkiaDisplayList.h b/libs/hwui/pipeline/skia/SkiaDisplayList.h
index 90e9bc6..2a67734 100644
--- a/libs/hwui/pipeline/skia/SkiaDisplayList.h
+++ b/libs/hwui/pipeline/skia/SkiaDisplayList.h
@@ -111,6 +111,13 @@
      */
     void syncContents(const WebViewSyncData& data);
 
+    /**
+     * ONLY to be called by RenderNode::onRemovedFromTree so that we can notify any
+     * contained VectorDrawables or GLFunctors.
+     *
+     */
+    void onRemovedFromTree();
+
     void applyColorTransform(ColorTransform transform) {
         mDisplayList.applyColorTransform(transform);
     }