diff options
author | 2021-05-03 14:47:36 -0700 | |
---|---|---|
committer | 2021-06-18 10:14:22 -0700 | |
commit | 34f42fdecdf380d82f2be32b3564517002cc2112 (patch) | |
tree | b399058237780bf95b6b6a688e48e3fd727544bc | |
parent | 1d88151a380c2a8f102c76b8413d17989215ccf8 (diff) |
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
-rw-r--r-- | core/java/android/view/ViewRootImpl.java | 31 | ||||
-rw-r--r-- | graphics/java/android/graphics/HardwareRenderer.java | 26 | ||||
-rw-r--r-- | libs/hwui/WebViewFunctorManager.cpp | 2 | ||||
-rw-r--r-- | libs/hwui/jni/android_graphics_HardwareRenderer.cpp | 34 | ||||
-rw-r--r-- | libs/hwui/renderthread/CanvasContext.cpp | 7 | ||||
-rw-r--r-- | libs/hwui/renderthread/CanvasContext.h | 8 | ||||
-rw-r--r-- | libs/hwui/renderthread/RenderProxy.cpp | 6 | ||||
-rw-r--r-- | libs/hwui/renderthread/RenderProxy.h | 1 | ||||
-rw-r--r-- | libs/hwui/renderthread/RenderThread.cpp | 4 | ||||
-rw-r--r-- | libs/hwui/renderthread/RenderThread.h | 3 |
10 files changed, 121 insertions, 1 deletions
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index d42e0c367763..cf8c746d6ecb 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -461,6 +461,9 @@ public final class ViewRootImpl implements ViewParent, protected final ViewFrameInfo mViewFrameInfo = new ViewFrameInfo(); private final InputEventAssigner mInputEventAssigner = new InputEventAssigner(); + // Set to true if mSurfaceControl is used for Webview Overlay + private boolean mIsForWebviewOverlay; + /** * Update the Choreographer's FrameInfo object with the timing information for the current * ViewRootImpl instance. Erase the data in the current ViewFrameInfo to prepare for the next @@ -1374,6 +1377,23 @@ public final class ViewRootImpl implements ViewParent, mAttachInfo.mThreadedRenderer.setASurfaceTransactionCallback(callback); } + /** + * Register a callback to be executed when Webview overlay needs a surface control. + * This callback will be executed on RenderThread worker thread, and released inside native code + * when CanvasContext is destroyed. + */ + private void addPrepareSurfaceControlForWebviewCallback() { + HardwareRenderer.PrepareSurfaceControlForWebviewCallback callback = () -> { + // make mSurfaceControl transparent, so child surface controls are visible + if (mIsForWebviewOverlay) return; + synchronized (ViewRootImpl.this) { + mIsForWebviewOverlay = true; + } + mTransaction.setOpaque(mSurfaceControl, false).apply(); + }; + mAttachInfo.mThreadedRenderer.setPrepareSurfaceControlForWebviewCallback(callback); + } + @UnsupportedAppUsage private void enableHardwareAcceleration(WindowManager.LayoutParams attrs) { mAttachInfo.mHardwareAccelerated = false; @@ -1418,6 +1438,7 @@ public final class ViewRootImpl implements ViewParent, if (mHardwareRendererObserver != null) { mAttachInfo.mThreadedRenderer.addObserver(mHardwareRendererObserver); } + addPrepareSurfaceControlForWebviewCallback(); addASurfaceTransactionCallback(); mAttachInfo.mThreadedRenderer.setSurfaceControl(mSurfaceControl); } @@ -7743,6 +7764,7 @@ public final class ViewRootImpl implements ViewParent, } } if (mAttachInfo.mThreadedRenderer != null) { + addPrepareSurfaceControlForWebviewCallback(); addASurfaceTransactionCallback(); mAttachInfo.mThreadedRenderer.setSurfaceControl(mSurfaceControl); } @@ -7790,7 +7812,14 @@ public final class ViewRootImpl implements ViewParent, return; } - mTransaction.setOpaque(mSurfaceControl, opaque).apply(); + synchronized (this) { + if (mIsForWebviewOverlay) { + mIsSurfaceOpaque = false; + return; + } + mTransaction.setOpaque(mSurfaceControl, opaque).apply(); + } + mIsSurfaceOpaque = opaque; } diff --git a/graphics/java/android/graphics/HardwareRenderer.java b/graphics/java/android/graphics/HardwareRenderer.java index 6aa74cb415f9..e141d5178570 100644 --- a/graphics/java/android/graphics/HardwareRenderer.java +++ b/graphics/java/android/graphics/HardwareRenderer.java @@ -762,6 +762,16 @@ public class HardwareRenderer { nSetASurfaceTransactionCallback(mNativeProxy, callback); } + private PrepareSurfaceControlForWebviewCallback mAPrepareSurfaceControlForWebviewCallback; + + /** @hide */ + public void setPrepareSurfaceControlForWebviewCallback( + PrepareSurfaceControlForWebviewCallback callback) { + // ensure callback is kept alive on the java side since weak ref is used in native code + mAPrepareSurfaceControlForWebviewCallback = callback; + nSetPrepareSurfaceControlForWebviewCallback(mNativeProxy, callback); + } + /** @hide */ public void setFrameCallback(FrameDrawingCallback callback) { nSetFrameCallback(mNativeProxy, callback); @@ -876,6 +886,19 @@ public class HardwareRenderer { session.close(); } + /** + * Interface used to receive callbacks when Webview requests a surface control. + * + * @hide + */ + public interface PrepareSurfaceControlForWebviewCallback { + /** + * Invoked when Webview calls to get a surface control. + * + */ + void prepare(); + } + /** * Interface used to receive callbacks when a transaction needs to be merged. * @@ -1374,6 +1397,9 @@ public class HardwareRenderer { private static native void nSetASurfaceTransactionCallback(long nativeProxy, ASurfaceTransactionCallback callback); + private static native void nSetPrepareSurfaceControlForWebviewCallback(long nativeProxy, + PrepareSurfaceControlForWebviewCallback callback); + private static native void nSetFrameCallback(long nativeProxy, FrameDrawingCallback callback); private static native void nSetFrameCompleteCallback(long nativeProxy, diff --git a/libs/hwui/WebViewFunctorManager.cpp b/libs/hwui/WebViewFunctorManager.cpp index d9b9e2456fff..92e20c477669 100644 --- a/libs/hwui/WebViewFunctorManager.cpp +++ b/libs/hwui/WebViewFunctorManager.cpp @@ -197,6 +197,8 @@ ASurfaceControl* WebViewFunctor::getSurfaceControl() { 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 819a34b21a05..9ff2f461d40d 100644 --- a/libs/hwui/jni/android_graphics_HardwareRenderer.cpp +++ b/libs/hwui/jni/android_graphics_HardwareRenderer.cpp @@ -71,6 +71,10 @@ struct { } gASurfaceTransactionCallback; struct { + jmethodID prepare; +} gPrepareSurfaceControlForWebviewCallback; + +struct { jmethodID onFrameDraw; } gFrameDrawingCallback; @@ -672,6 +676,28 @@ static void android_view_ThreadedRenderer_setASurfaceTransactionCallback( } } +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 @@ static const JNINativeMethod gMethods[] = { {"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 @@ int register_android_view_ThreadedRenderer(JNIEnv* env) { 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 8bfc2c14ad7c..77e64d5ddea4 100644 --- a/libs/hwui/renderthread/CanvasContext.cpp +++ b/libs/hwui/renderthread/CanvasContext.cpp @@ -197,6 +197,7 @@ void CanvasContext::setSurfaceControl(ASurfaceControl* surfaceControl) { if (surfaceControl == nullptr) { setASurfaceTransactionCallback(nullptr); + setPrepareSurfaceControlForWebviewCallback(nullptr); } if (mSurfaceControl != nullptr) { @@ -918,6 +919,12 @@ bool CanvasContext::mergeTransaction(ASurfaceTransaction* transaction, ASurfaceC 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 4bdc2514db8c..a61c2bfd5c01 100644 --- a/libs/hwui/renderthread/CanvasContext.h +++ b/libs/hwui/renderthread/CanvasContext.h @@ -212,6 +212,12 @@ public: 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 @@ private: 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 6fd644bfa28e..c47050c31e9a 100644 --- a/libs/hwui/renderthread/RenderProxy.cpp +++ b/libs/hwui/renderthread/RenderProxy.cpp @@ -319,6 +319,12 @@ void RenderProxy::setASurfaceTransactionCallback( [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 6d80949a4eba..d575aa77e4ab 100644 --- a/libs/hwui/renderthread/RenderProxy.h +++ b/libs/hwui/renderthread/RenderProxy.h @@ -124,6 +124,7 @@ public: 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 4ba774801bba..524407d2b9b0 100644 --- a/libs/hwui/renderthread/RenderThread.cpp +++ b/libs/hwui/renderthread/RenderThread.cpp @@ -102,6 +102,10 @@ ASurfaceControlFunctions::ASurfaceControlFunctions() { (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 dd060097ddf7..c5e3746587b8 100644 --- a/libs/hwui/renderthread/RenderThread.h +++ b/libs/hwui/renderthread/RenderThread.h @@ -96,6 +96,8 @@ typedef void (*AST_delete)(ASurfaceTransaction* transaction); 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 @@ struct ASurfaceControlFunctions { AST_delete transactionDeleteFunc; AST_apply transactionApplyFunc; AST_setVisibility transactionSetVisibilityFunc; + AST_setZOrder transactionSetZOrderFunc; }; class ChoreographerSource; |