Fix a crash caused by transaction
A native transaction passed from webview is sent back to native side, so java side does not manage the life cycle of the transaction.
Bug: 191414767
Test: Play a video, switch to another app, wait for 10 seconds
Change-Id: I013052c202b445438d6cb6497f5f9a2fc22a2b85
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index 4e66ceb..c03db6d 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -2610,16 +2610,6 @@
= sRegistry.registerNativeAllocation(this, mNativeObject);
}
- /**
- * Create a transaction object that wraps a native peer.
- * @hide
- */
- Transaction(long nativeObject) {
- mNativeObject = nativeObject;
- mFreeNativeResources =
- sRegistry.registerNativeAllocation(this, mNativeObject);
- }
-
private Transaction(Parcel in) {
readFromParcel(in);
}
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 210f10c..5a248af 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -1371,8 +1371,12 @@
HardwareRenderer.ASurfaceTransactionCallback callback = (nativeTransactionObj,
nativeSurfaceControlObj,
frameNr) -> {
- Transaction t = new Transaction(nativeTransactionObj);
- mergeWithNextTransaction(t, frameNr);
+ if (mBlastBufferQueue == null) {
+ return false;
+ } else {
+ mBlastBufferQueue.mergeWithNextTransaction(nativeTransactionObj, frameNr);
+ return true;
+ }
};
mAttachInfo.mThreadedRenderer.setASurfaceTransactionCallback(callback);
}
diff --git a/graphics/java/android/graphics/BLASTBufferQueue.java b/graphics/java/android/graphics/BLASTBufferQueue.java
index 4534d36..6c1c2ee 100644
--- a/graphics/java/android/graphics/BLASTBufferQueue.java
+++ b/graphics/java/android/graphics/BLASTBufferQueue.java
@@ -131,4 +131,12 @@
nativeMergeWithNextTransaction(mNativeObject, t.mNativeObject, frameNumber);
}
+ /**
+ * Merge the transaction passed in to the next transaction in BlastBufferQueue.
+ * @param nativeTransaction native handle passed from native c/c++ code.
+ */
+ public void mergeWithNextTransaction(long nativeTransaction, long frameNumber) {
+ nativeMergeWithNextTransaction(mNativeObject, nativeTransaction, frameNumber);
+ }
+
}
diff --git a/graphics/java/android/graphics/HardwareRenderer.java b/graphics/java/android/graphics/HardwareRenderer.java
index e141d51..30d1e0f 100644
--- a/graphics/java/android/graphics/HardwareRenderer.java
+++ b/graphics/java/android/graphics/HardwareRenderer.java
@@ -912,7 +912,7 @@
* @param aSurfaceControlNativeObj ASurfaceControl native object handle
* @param frame The id of the frame being drawn.
*/
- void onMergeTransaction(long aSurfaceTranactionNativeObj,
+ boolean onMergeTransaction(long aSurfaceTranactionNativeObj,
long aSurfaceControlNativeObj, long frame);
}
diff --git a/libs/hwui/jni/android_graphics_HardwareRenderer.cpp b/libs/hwui/jni/android_graphics_HardwareRenderer.cpp
index 9ff2f46..4d31cd9 100644
--- a/libs/hwui/jni/android_graphics_HardwareRenderer.cpp
+++ b/libs/hwui/jni/android_graphics_HardwareRenderer.cpp
@@ -662,16 +662,18 @@
auto globalCallbackRef =
std::make_shared<JWeakGlobalRefHolder>(vm, aSurfaceTransactionCallback);
proxy->setASurfaceTransactionCallback(
- [globalCallbackRef](int64_t transObj, int64_t scObj, int64_t frameNr) {
+ [globalCallbackRef](int64_t transObj, int64_t scObj, int64_t frameNr) -> bool {
JNIEnv* env = getenv(globalCallbackRef->vm());
jobject localref = env->NewLocalRef(globalCallbackRef->ref());
if (CC_UNLIKELY(!localref)) {
- return;
+ return false;
}
- env->CallVoidMethod(localref, gASurfaceTransactionCallback.onMergeTransaction,
- static_cast<jlong>(transObj), static_cast<jlong>(scObj),
- static_cast<jlong>(frameNr));
+ jboolean ret = env->CallBooleanMethod(
+ localref, gASurfaceTransactionCallback.onMergeTransaction,
+ static_cast<jlong>(transObj), static_cast<jlong>(scObj),
+ static_cast<jlong>(frameNr));
env->DeleteLocalRef(localref);
+ return ret;
});
}
}
@@ -1064,7 +1066,7 @@
jclass aSurfaceTransactionCallbackClass =
FindClassOrDie(env, "android/graphics/HardwareRenderer$ASurfaceTransactionCallback");
gASurfaceTransactionCallback.onMergeTransaction =
- GetMethodIDOrDie(env, aSurfaceTransactionCallbackClass, "onMergeTransaction", "(JJJ)V");
+ GetMethodIDOrDie(env, aSurfaceTransactionCallbackClass, "onMergeTransaction", "(JJJ)Z");
jclass prepareSurfaceControlForWebviewCallbackClass = FindClassOrDie(
env, "android/graphics/HardwareRenderer$PrepareSurfaceControlForWebviewCallback");
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index 44d0038..0c9711b 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -910,9 +910,8 @@
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;
+ return std::invoke(mASurfaceTransactionCallback, reinterpret_cast<int64_t>(transaction),
+ reinterpret_cast<int64_t>(control), getFrameNumber());
}
void CanvasContext::prepareSurfaceControlForWebview() {
diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h
index a61c2bf..3279ccb 100644
--- a/libs/hwui/renderthread/CanvasContext.h
+++ b/libs/hwui/renderthread/CanvasContext.h
@@ -206,7 +206,7 @@
ASurfaceControlStats* stats);
void setASurfaceTransactionCallback(
- const std::function<void(int64_t, int64_t, int64_t)>& callback) {
+ const std::function<bool(int64_t, int64_t, int64_t)>& callback) {
mASurfaceTransactionCallback = callback;
}
@@ -317,7 +317,7 @@
// If set to true, we expect that callbacks into onSurfaceStatsAvailable
bool mExpectSurfaceStats = false;
- std::function<void(int64_t, int64_t, int64_t)> mASurfaceTransactionCallback;
+ std::function<bool(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 c47050c..a77b5b5 100644
--- a/libs/hwui/renderthread/RenderProxy.cpp
+++ b/libs/hwui/renderthread/RenderProxy.cpp
@@ -314,7 +314,7 @@
}
void RenderProxy::setASurfaceTransactionCallback(
- const std::function<void(int64_t, int64_t, int64_t)>& callback) {
+ const std::function<bool(int64_t, int64_t, int64_t)>& callback) {
mRenderThread.queue().post(
[this, cb = callback]() { mContext->setASurfaceTransactionCallback(cb); });
}
diff --git a/libs/hwui/renderthread/RenderProxy.h b/libs/hwui/renderthread/RenderProxy.h
index d575aa7..1b0f22e 100644
--- a/libs/hwui/renderthread/RenderProxy.h
+++ b/libs/hwui/renderthread/RenderProxy.h
@@ -123,7 +123,7 @@
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);
+ const std::function<bool(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);