DialogModule crash fixes. (#19332)

Summary:
I'm trying to fix DialogModule crashes we have in production: #6228

In this PR I'm fixing the following problem:

The fragment manager methods should be called only from the foreground. Now dismissExisting is protected by the mIsForeground variable as well as showNewAlert method.

[ANDROID] [Fixed] DialogModule - Race condition in dialog module fixed.

Pull Request resolved: https://github.com/facebook/react-native/pull/19332

Reviewed By: mdvacca

Differential Revision: D13804542

Pulled By: hramos

fbshipit-source-id: 9d59c8eaad49e2d3f141e255467627d411ae8797
This commit is contained in:
Sergei Dryganets
2019-02-12 12:29:15 -08:00
committed by Facebook Github Bot
parent 0a07161084
commit 9df892cfcb

View File

@@ -21,6 +21,7 @@ import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.SoftAssertions;
import com.facebook.react.bridge.UiThreadUtil;
import com.facebook.react.common.MapBuilder;
import com.facebook.react.module.annotations.ReactModule;
@@ -92,9 +93,12 @@ public class DialogModule extends ReactContextBaseJavaModule implements Lifecycl
public void showPendingAlert() {
UiThreadUtil.assertOnUiThread();
SoftAssertions.assertCondition(mIsInForeground, "showPendingAlert() called in background");
if (mFragmentToShow == null) {
return;
}
dismissExisting();
if (isUsingSupportLibrary()) {
((SupportAlertFragment) mFragmentToShow).show(mSupportFragmentManager, FRAGMENT_TAG);
} else {
@@ -104,6 +108,9 @@ public class DialogModule extends ReactContextBaseJavaModule implements Lifecycl
}
private void dismissExisting() {
if (!mIsInForeground) {
return;
}
if (isUsingSupportLibrary()) {
SupportAlertFragment oldFragment =
(SupportAlertFragment) mSupportFragmentManager.findFragmentByTag(FRAGMENT_TAG);
@@ -119,7 +126,7 @@ public class DialogModule extends ReactContextBaseJavaModule implements Lifecycl
}
}
public void showNewAlert(boolean isInForeground, Bundle arguments, Callback actionCallback) {
public void showNewAlert(Bundle arguments, Callback actionCallback) {
UiThreadUtil.assertOnUiThread();
dismissExisting();
@@ -129,7 +136,7 @@ public class DialogModule extends ReactContextBaseJavaModule implements Lifecycl
if (isUsingSupportLibrary()) {
SupportAlertFragment alertFragment = new SupportAlertFragment(actionListener, arguments);
if (isInForeground && !mSupportFragmentManager.isStateSaved()) {
if (mIsInForeground && !mSupportFragmentManager.isStateSaved()) {
if (arguments.containsKey(KEY_CANCELABLE)) {
alertFragment.setCancelable(arguments.getBoolean(KEY_CANCELABLE));
}
@@ -139,7 +146,7 @@ public class DialogModule extends ReactContextBaseJavaModule implements Lifecycl
}
} else {
AlertFragment alertFragment = new AlertFragment(actionListener, arguments);
if (isInForeground) {
if (mIsInForeground) {
if (arguments.containsKey(KEY_CANCELABLE)) {
alertFragment.setCancelable(arguments.getBoolean(KEY_CANCELABLE));
}
@@ -255,7 +262,7 @@ public class DialogModule extends ReactContextBaseJavaModule implements Lifecycl
UiThreadUtil.runOnUiThread(new Runnable() {
@Override
public void run() {
fragmentManagerHelper.showNewAlert(mIsInForeground, args, actionCallback);
fragmentManagerHelper.showNewAlert(args, actionCallback);
}
});