Do not execute MountItems if their associated Surface has been stopped

Summary:
Introduce SurfaceId to the BatchMountItem. Do not execute it if the associated Surface has gone away.

Changelog: [Internal]

Reviewed By: mdvacca

Differential Revision: D21895452

fbshipit-source-id: 5df56720ce9b4293693884ebe105bda1dc87700e
This commit is contained in:
Joshua Gross
2020-06-05 17:13:35 -07:00
committed by Facebook GitHub Bot
parent b6fedfe179
commit 8b47e69477
3 changed files with 32 additions and 5 deletions
@@ -431,8 +431,9 @@ public class FabricUIManager implements UIManager, LifecycleEventListener {
@SuppressWarnings("unused")
@AnyThread
@ThreadConfined(ANY)
private MountItem createBatchMountItem(MountItem[] items, int size, int commitNumber) {
return new BatchMountItem(items, size, commitNumber);
private MountItem createBatchMountItem(
int rootTag, MountItem[] items, int size, int commitNumber) {
return new BatchMountItem(rootTag, items, size, commitNumber);
}
@DoNotStrip
@@ -786,6 +787,22 @@ public class FabricUIManager implements UIManager, LifecycleEventListener {
}
}
// Make sure surface associated with this MountItem has been started, and not stopped.
// TODO T68118357: clean up this logic and simplify this method overall
if (mountItem instanceof BatchMountItem) {
BatchMountItem batchMountItem = (BatchMountItem) mountItem;
int rootTag = batchMountItem.getRootTag();
if (mReactContextForRootTag.get(rootTag) == null) {
ReactSoftException.logSoftException(
TAG,
new ReactNoCrashSoftException(
"dispatchMountItems: skipping batched item: surface not available ["
+ rootTag
+ "]"));
continue;
}
}
// TODO: if early ViewCommand dispatch ships 100% as a feature, this can be removed.
// This try/catch catches Retryable errors that can only be thrown by ViewCommands, which
// won't be executed here in Early Dispatch mode.
@@ -841,11 +841,15 @@ void Binding::schedulerDidFinishTransaction(
static auto createMountItemsBatchContainer =
jni::findClassStatic(UIManagerJavaDescriptor)
->getMethod<alias_ref<JMountItem>(
jtypeArray<JMountItem::javaobject>, jint, jint)>(
jint, jtypeArray<JMountItem::javaobject>, jint, jint)>(
"createBatchMountItem");
auto batch = createMountItemsBatchContainer(
localJavaUIManager, mountItemsArray.get(), position, commitNumber);
localJavaUIManager,
surfaceId,
mountItemsArray.get(),
position,
commitNumber);
static auto scheduleMountItem = jni::findClassStatic(UIManagerJavaDescriptor)
->getMethod<void(
@@ -26,13 +26,14 @@ import com.facebook.systrace.Systrace;
@DoNotStrip
public class BatchMountItem implements MountItem {
private final int mRootTag;
@NonNull private final MountItem[] mMountItems;
private final int mSize;
private final int mCommitNumber;
public BatchMountItem(MountItem[] items, int size, int commitNumber) {
public BatchMountItem(int rootTag, MountItem[] items, int size, int commitNumber) {
if (items == null) {
throw new NullPointerException();
}
@@ -40,6 +41,7 @@ public class BatchMountItem implements MountItem {
throw new IllegalArgumentException(
"Invalid size received by parameter size: " + size + " items.size = " + items.length);
}
mRootTag = rootTag;
mMountItems = items;
mSize = size;
mCommitNumber = commitNumber;
@@ -68,6 +70,10 @@ public class BatchMountItem implements MountItem {
Systrace.endSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE);
}
public int getRootTag() {
return mRootTag;
}
@Override
public String toString() {
StringBuilder s = new StringBuilder();