Fix z-order for webview surface control
Set the root surface control transparent, and set the z order of the newly created child surface control to -1.
A new callback is needed to update root surface control in sync from Java side.
Bug: 186750329
Test: use latest APKs from Webview team, play a video, mini toolbar should be visible
Change-Id: I0b37ee8f83fd2b41ff4f2856dbadd31ff6170baf
diff --git a/libs/hwui/WebViewFunctorManager.cpp b/libs/hwui/WebViewFunctorManager.cpp
index d9b9e24..92e20c4 100644
--- a/libs/hwui/WebViewFunctorManager.cpp
+++ b/libs/hwui/WebViewFunctorManager.cpp
@@ -197,6 +197,8 @@
auto funcs = renderthread::RenderThread::getInstance().getASurfaceControlFunctions();
mSurfaceControl = funcs.createFunc(rootSurfaceControl, "Webview Overlay SurfaceControl");
ASurfaceTransaction* transaction = funcs.transactionCreateFunc();
+ activeContext->prepareSurfaceControlForWebview();
+ funcs.transactionSetZOrderFunc(transaction, mSurfaceControl, -1);
funcs.transactionSetVisibilityFunc(transaction, mSurfaceControl,
ASURFACE_TRANSACTION_VISIBILITY_SHOW);
funcs.transactionApplyFunc(transaction);
diff --git a/libs/hwui/jni/android_graphics_HardwareRenderer.cpp b/libs/hwui/jni/android_graphics_HardwareRenderer.cpp
index 819a34b..9ff2f46 100644
--- a/libs/hwui/jni/android_graphics_HardwareRenderer.cpp
+++ b/libs/hwui/jni/android_graphics_HardwareRenderer.cpp
@@ -71,6 +71,10 @@
} gASurfaceTransactionCallback;
struct {
+ jmethodID prepare;
+} gPrepareSurfaceControlForWebviewCallback;
+
+struct {
jmethodID onFrameDraw;
} gFrameDrawingCallback;
@@ -672,6 +676,28 @@
}
}
+static void android_view_ThreadedRenderer_setPrepareSurfaceControlForWebviewCallback(
+ JNIEnv* env, jobject clazz, jlong proxyPtr, jobject callback) {
+ RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
+ if (!callback) {
+ proxy->setPrepareSurfaceControlForWebviewCallback(nullptr);
+ } else {
+ JavaVM* vm = nullptr;
+ LOG_ALWAYS_FATAL_IF(env->GetJavaVM(&vm) != JNI_OK, "Unable to get Java VM");
+ auto globalCallbackRef =
+ std::make_shared<JWeakGlobalRefHolder>(vm, callback);
+ proxy->setPrepareSurfaceControlForWebviewCallback([globalCallbackRef]() {
+ JNIEnv* env = getenv(globalCallbackRef->vm());
+ jobject localref = env->NewLocalRef(globalCallbackRef->ref());
+ if (CC_UNLIKELY(!localref)) {
+ return;
+ }
+ env->CallVoidMethod(localref, gPrepareSurfaceControlForWebviewCallback.prepare);
+ env->DeleteLocalRef(localref);
+ });
+ }
+}
+
static void android_view_ThreadedRenderer_setFrameCallback(JNIEnv* env,
jobject clazz, jlong proxyPtr, jobject frameCallback) {
RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
@@ -970,6 +996,9 @@
{"nSetASurfaceTransactionCallback",
"(JLandroid/graphics/HardwareRenderer$ASurfaceTransactionCallback;)V",
(void*)android_view_ThreadedRenderer_setASurfaceTransactionCallback},
+ {"nSetPrepareSurfaceControlForWebviewCallback",
+ "(JLandroid/graphics/HardwareRenderer$PrepareSurfaceControlForWebviewCallback;)V",
+ (void*)android_view_ThreadedRenderer_setPrepareSurfaceControlForWebviewCallback},
{"nSetFrameCallback", "(JLandroid/graphics/HardwareRenderer$FrameDrawingCallback;)V",
(void*)android_view_ThreadedRenderer_setFrameCallback},
{"nSetFrameCompleteCallback",
@@ -1037,6 +1066,11 @@
gASurfaceTransactionCallback.onMergeTransaction =
GetMethodIDOrDie(env, aSurfaceTransactionCallbackClass, "onMergeTransaction", "(JJJ)V");
+ jclass prepareSurfaceControlForWebviewCallbackClass = FindClassOrDie(
+ env, "android/graphics/HardwareRenderer$PrepareSurfaceControlForWebviewCallback");
+ gPrepareSurfaceControlForWebviewCallback.prepare =
+ GetMethodIDOrDie(env, prepareSurfaceControlForWebviewCallbackClass, "prepare", "()V");
+
jclass frameCallbackClass = FindClassOrDie(env,
"android/graphics/HardwareRenderer$FrameDrawingCallback");
gFrameDrawingCallback.onFrameDraw = GetMethodIDOrDie(env, frameCallbackClass,
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index 8bfc2c1..77e64d5 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -197,6 +197,7 @@
if (surfaceControl == nullptr) {
setASurfaceTransactionCallback(nullptr);
+ setPrepareSurfaceControlForWebviewCallback(nullptr);
}
if (mSurfaceControl != nullptr) {
@@ -918,6 +919,12 @@
return true;
}
+void CanvasContext::prepareSurfaceControlForWebview() {
+ if (mPrepareSurfaceControlForWebviewCallback) {
+ std::invoke(mPrepareSurfaceControlForWebviewCallback);
+ }
+}
+
} /* namespace renderthread */
} /* namespace uirenderer */
} /* namespace android */
diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h
index 4bdc251..a61c2bf 100644
--- a/libs/hwui/renderthread/CanvasContext.h
+++ b/libs/hwui/renderthread/CanvasContext.h
@@ -212,6 +212,12 @@
bool mergeTransaction(ASurfaceTransaction* transaction, ASurfaceControl* control);
+ void setPrepareSurfaceControlForWebviewCallback(const std::function<void()>& callback) {
+ mPrepareSurfaceControlForWebviewCallback = callback;
+ }
+
+ void prepareSurfaceControlForWebview();
+
static CanvasContext* getActiveContext();
private:
@@ -312,6 +318,8 @@
bool mExpectSurfaceStats = false;
std::function<void(int64_t, int64_t, int64_t)> mASurfaceTransactionCallback;
+ std::function<void()> mPrepareSurfaceControlForWebviewCallback;
+
void cleanupResources();
};
diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp
index 6fd644b..c47050c 100644
--- a/libs/hwui/renderthread/RenderProxy.cpp
+++ b/libs/hwui/renderthread/RenderProxy.cpp
@@ -319,6 +319,12 @@
[this, cb = callback]() { mContext->setASurfaceTransactionCallback(cb); });
}
+void RenderProxy::setPrepareSurfaceControlForWebviewCallback(
+ const std::function<void()>& callback) {
+ mRenderThread.queue().post(
+ [this, cb = callback]() { mContext->setPrepareSurfaceControlForWebviewCallback(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 6d80949..d575aa7 100644
--- a/libs/hwui/renderthread/RenderProxy.h
+++ b/libs/hwui/renderthread/RenderProxy.h
@@ -124,6 +124,7 @@
void setPictureCapturedCallback(const std::function<void(sk_sp<SkPicture>&&)>& callback);
void setASurfaceTransactionCallback(
const std::function<void(int64_t, int64_t, int64_t)>& callback);
+ void setPrepareSurfaceControlForWebviewCallback(const std::function<void()>& 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 4ba7748..524407d 100644
--- a/libs/hwui/renderthread/RenderThread.cpp
+++ b/libs/hwui/renderthread/RenderThread.cpp
@@ -102,6 +102,10 @@
(AST_setVisibility)dlsym(handle_, "ASurfaceTransaction_setVisibility");
LOG_ALWAYS_FATAL_IF(transactionSetVisibilityFunc == nullptr,
"Failed to find required symbol ASurfaceTransaction_setVisibility!");
+
+ transactionSetZOrderFunc = (AST_setZOrder)dlsym(handle_, "ASurfaceTransaction_setZOrder");
+ LOG_ALWAYS_FATAL_IF(transactionSetZOrderFunc == nullptr,
+ "Failed to find required symbol ASurfaceTransaction_setZOrder!");
}
void RenderThread::frameCallback(int64_t frameTimeNanos, void* data) {
diff --git a/libs/hwui/renderthread/RenderThread.h b/libs/hwui/renderthread/RenderThread.h
index dd06009..c5e3746 100644
--- a/libs/hwui/renderthread/RenderThread.h
+++ b/libs/hwui/renderthread/RenderThread.h
@@ -96,6 +96,8 @@
typedef void (*AST_apply)(ASurfaceTransaction* transaction);
typedef void (*AST_setVisibility)(ASurfaceTransaction* transaction,
ASurfaceControl* surface_control, int8_t visibility);
+typedef void (*AST_setZOrder)(ASurfaceTransaction* transaction, ASurfaceControl* surface_control,
+ int32_t z_order);
struct ASurfaceControlFunctions {
ASurfaceControlFunctions();
@@ -112,6 +114,7 @@
AST_delete transactionDeleteFunc;
AST_apply transactionApplyFunc;
AST_setVisibility transactionSetVisibilityFunc;
+ AST_setZOrder transactionSetZOrderFunc;
};
class ChoreographerSource;