Guard against UIManagerHelper.getUIManager returning null

Summary:
Because the `mCatalystInstance` of the ReactContext can be null during teardown, there are technicaly cases where `UIManagerHelper.getUIManager` can return null. In those cases we check for a CatalystInstance and raise a SoftException, and return null. We must then guard in every case where we call `getUIManager` to prevent NullPointerExceptions.

See T56103679.

Currently crashes are coming from `PropsAnimatedNode.restoreDefaultValues` calling `UIManagerModule.synchronouslyUpdateViewOnUIThread` on teardown/at the end of an animation as RN is being torn down.

This can happen in both Paper and Fabric.

In dev this will still crash because the SoftException will trigger a crash. It will be a noop with logged warnings in production builds.

Changelog: [Internal]

Reviewed By: yungsters

Differential Revision: D18165576

fbshipit-source-id: 7059e04ca339208dd64a0a08a375b565cb8cda02
This commit is contained in:
Joshua Gross
2019-10-27 23:13:33 -07:00
committed by Facebook Github Bot
parent bdaab3c2e5
commit aa27645cf0
2 changed files with 31 additions and 9 deletions
@@ -10,9 +10,11 @@ package com.facebook.react.uimanager;
import static com.facebook.react.uimanager.common.UIManagerType.FABRIC;
import static com.facebook.react.uimanager.common.ViewUtil.getUIManagerType;
import androidx.annotation.Nullable;
import com.facebook.react.bridge.CatalystInstance;
import com.facebook.react.bridge.JSIModuleType;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReactSoftException;
import com.facebook.react.bridge.UIManager;
import com.facebook.react.uimanager.common.UIManagerType;
@@ -20,12 +22,20 @@ import com.facebook.react.uimanager.common.UIManagerType;
public class UIManagerHelper {
/** @return a {@link UIManager} that can handle the react tag received by parameter. */
@Nullable
public static UIManager getUIManagerForReactTag(ReactContext context, int reactTag) {
return getUIManager(context, getUIManagerType(reactTag));
}
/** @return a {@link UIManager} that can handle the react tag received by parameter. */
@Nullable
public static UIManager getUIManager(ReactContext context, @UIManagerType int uiManagerType) {
if (!context.hasActiveCatalystInstance()) {
ReactSoftException.logSoftException(
"UIManagerHelper",
new RuntimeException("Cannot get UIManager: no active Catalyst instance"));
return null;
}
CatalystInstance catalystInstance = context.getCatalystInstance();
return uiManagerType == FABRIC
? (UIManager) catalystInstance.getJSIModule(JSIModuleType.UIManager)