From c7210b099a4385e4b2cfa2ab6a09e2d5937983e0 Mon Sep 17 00:00:00 2001 From: Sergei Dryganets Date: Fri, 29 Dec 2017 12:34:28 -0800 Subject: [PATCH] Android dialog module has a race condition as result it crashes see this issue: https://github.com/facebook/react-native/issues/6228. The mIsInForeground flag is set on UI thread but was used from the ReactMethod thread. I added asserts to make sure that FragmentManagerHelper wouldn't be used incorrectly. Make sure that dialogs work after this change. It will be nearly impossible to reproduce the issue manually but automatic regression tests should be able to catch this. At least our tests are crashing on some dialog scenarios from time to time. [ANDROID] [MINOR] [BUGFIX] - Race condition fix for Dialogs module. --- .../react/modules/dialog/DialogModule.java | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/ReactAndroid/src/main/java/com/facebook/react/modules/dialog/DialogModule.java b/ReactAndroid/src/main/java/com/facebook/react/modules/dialog/DialogModule.java index d543b6cf083c5c..6c2f39d180d691 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/modules/dialog/DialogModule.java +++ b/ReactAndroid/src/main/java/com/facebook/react/modules/dialog/DialogModule.java @@ -28,6 +28,7 @@ import com.facebook.react.bridge.ReactMethod; import com.facebook.react.bridge.ReadableArray; import com.facebook.react.bridge.ReadableMap; +import com.facebook.react.bridge.UiThreadUtil; import com.facebook.react.common.MapBuilder; import com.facebook.react.module.annotations.ReactModule; @@ -95,6 +96,7 @@ public FragmentManagerHelper(android.app.FragmentManager fragmentManager) { } public void showPendingAlert() { + UiThreadUtil.assertOnUiThread(); if (mFragmentToShow == null) { return; } @@ -123,6 +125,8 @@ private void dismissExisting() { } public void showNewAlert(boolean isInForeground, Bundle arguments, Callback actionCallback) { + UiThreadUtil.assertOnUiThread(); + dismissExisting(); AlertFragmentListener actionListener = @@ -218,8 +222,8 @@ public void onHostResume() { public void showAlert( ReadableMap options, Callback errorCallback, - Callback actionCallback) { - FragmentManagerHelper fragmentManagerHelper = getFragmentManagerHelper(); + final Callback actionCallback) { + final FragmentManagerHelper fragmentManagerHelper = getFragmentManagerHelper(); if (fragmentManagerHelper == null) { errorCallback.invoke("Tried to show an alert while not attached to an Activity"); return; @@ -253,7 +257,13 @@ public void showAlert( args.putBoolean(KEY_CANCELABLE, options.getBoolean(KEY_CANCELABLE)); } - fragmentManagerHelper.showNewAlert(mIsInForeground, args, actionCallback); + UiThreadUtil.runOnUiThread(new Runnable() { + @Override + public void run() { + fragmentManagerHelper.showNewAlert(mIsInForeground, args, actionCallback); + } + }); + } /**