diff --git a/ReactAndroid/src/main/java/com/facebook/react/cxxbridge/UnpackingJSBundleLoader.java b/ReactAndroid/src/main/java/com/facebook/react/cxxbridge/UnpackingJSBundleLoader.java index 19086bdb7..9465c4b4c 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/cxxbridge/UnpackingJSBundleLoader.java +++ b/ReactAndroid/src/main/java/com/facebook/react/cxxbridge/UnpackingJSBundleLoader.java @@ -66,6 +66,7 @@ public class UnpackingJSBundleLoader extends JSBundleLoader { private final String mSourceURL; private final Context mContext; private final int mLoadFlags; + private final @Nullable Runnable mOnUnpackedCallback; /** * Description of what needs to be unpacked. @@ -78,6 +79,7 @@ public class UnpackingJSBundleLoader extends JSBundleLoader { mSourceURL = Assertions.assertNotNull(builder.sourceURL); mUnpackers = builder.unpackers.toArray(new Unpacker[builder.unpackers.size()]); mLoadFlags = builder.loadFlags; + mOnUnpackedCallback = builder.callback; } /** @@ -85,18 +87,24 @@ public class UnpackingJSBundleLoader extends JSBundleLoader { * directory and unpacks everything again. */ /* package */ void prepare() { + boolean unpacked = false; + final File lockFilePath = new File(mContext.getFilesDir(), LOCK_FILE); Systrace.beginSection(TRACE_TAG_REACT_JAVA_BRIDGE, "UnpackingJSBundleLoader.prepare"); try (FileLocker lock = FileLocker.lock(lockFilePath)) { - prepareLocked(); + unpacked = prepareLocked(); } catch (IOException ioe) { throw new RuntimeException(ioe); } finally { Systrace.endSection(TRACE_TAG_REACT_JAVA_BRIDGE); } + + if (unpacked && mOnUnpackedCallback != null) { + mOnUnpackedCallback.run(); + } } - private void prepareLocked() throws IOException { + private boolean prepareLocked() throws IOException { final File dotFinishedFilePath = new File(mDirectoryPath, DOT_UNPACKED_FILE); boolean shouldReconstruct = !mDirectoryPath.exists() || !dotFinishedFilePath.exists(); @@ -106,7 +114,7 @@ public class UnpackingJSBundleLoader extends JSBundleLoader { } if (!shouldReconstruct) { - return; + return false; } boolean succeeded = false; @@ -138,6 +146,8 @@ public class UnpackingJSBundleLoader extends JSBundleLoader { SysUtil.dumbDeleteRecursive(mDirectoryPath); } } + + return true; } @Override @@ -201,6 +211,7 @@ public class UnpackingJSBundleLoader extends JSBundleLoader { private @Nullable String sourceURL; private final ArrayList unpackers; private int loadFlags; + private @Nullable Runnable callback; public Builder() { this.unpackers = new ArrayList(); @@ -208,6 +219,7 @@ public class UnpackingJSBundleLoader extends JSBundleLoader { destinationPath = null; sourceURL = null; loadFlags = 0; + callback = null; } public Builder setContext(Context context) { @@ -257,6 +269,11 @@ public class UnpackingJSBundleLoader extends JSBundleLoader { return this; } + public Builder setOnUnpackedCallback(Runnable callback) { + this.callback = callback; + return this; + } + public UnpackingJSBundleLoader build() { Assertions.assertNotNull(destinationPath); for (int i = 0; i < unpackers.size(); ++i) { diff --git a/ReactAndroid/src/test/java/com/facebook/react/cxxbridge/UnpackingJSBundleLoaderTest.java b/ReactAndroid/src/test/java/com/facebook/react/cxxbridge/UnpackingJSBundleLoaderTest.java index acbaf4808..d7145409d 100644 --- a/ReactAndroid/src/test/java/com/facebook/react/cxxbridge/UnpackingJSBundleLoaderTest.java +++ b/ReactAndroid/src/test/java/com/facebook/react/cxxbridge/UnpackingJSBundleLoaderTest.java @@ -56,6 +56,8 @@ public class UnpackingJSBundleLoaderTest { private CatalystInstanceImpl mCatalystInstanceImpl; private UnpackingJSBundleLoader.Unpacker[] mMockUnpackers; + private Runnable mCallback; + @Before public void setUp() throws IOException { mDestinationPath = folder.newFolder("destination"); @@ -75,6 +77,8 @@ public class UnpackingJSBundleLoaderTest { for (int i = 0; i < mMockUnpackers.length; ++i) { mMockUnpackers[i] = mock(UnpackingJSBundleLoader.Unpacker.class); } + + mCallback = mock(Runnable.class); } private void addUnpackers() { @@ -193,4 +197,17 @@ public class UnpackingJSBundleLoaderTest { assertFalse(mDestinationPath.exists()); } } + + @Test + public void testCallbackIsCalledAfterUnpack() { + mBuilder.setOnUnpackedCallback(mCallback).build().prepare(); + verify(mCallback).run(); + } + + @Test + public void testCallbackIsNotCalledIfNothingIsUnpacked() { + mBuilder.build().prepare(); + mBuilder.setOnUnpackedCallback(mCallback).build().prepare(); + verifyNoMoreInteractions(mCallback); + } }