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
This commit is contained in:
Huihong Luo
2021-06-24 10:04:32 -07:00
parent ef1bb2c9fa
commit 4df4151bc0
9 changed files with 29 additions and 26 deletions

View File

@@ -2610,16 +2610,6 @@ public final class SurfaceControl implements Parcelable {
= 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);
}

View File

@@ -1371,8 +1371,12 @@ public final class ViewRootImpl implements ViewParent,
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);
}

View File

@@ -131,4 +131,12 @@ public final class BLASTBufferQueue {
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);
}
}

View File

@@ -912,7 +912,7 @@ public class HardwareRenderer {
* @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);
}

View File

@@ -662,16 +662,18 @@ static void android_view_ThreadedRenderer_setASurfaceTransactionCallback(
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 @@ int register_android_view_ThreadedRenderer(JNIEnv* env) {
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");

View File

@@ -910,9 +910,8 @@ CanvasContext* CanvasContext::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;
return std::invoke(mASurfaceTransactionCallback, reinterpret_cast<int64_t>(transaction),
reinterpret_cast<int64_t>(control), getFrameNumber());
}
void CanvasContext::prepareSurfaceControlForWebview() {

View File

@@ -206,7 +206,7 @@ public:
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 @@ private:
// 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();

View File

@@ -314,7 +314,7 @@ void RenderProxy::setPictureCapturedCallback(
}
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); });
}

View File

@@ -123,7 +123,7 @@ public:
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);