Allow UnpackingJSBundleLoader's client to queue action to perform after unpacking

Reviewed By: tadeuzagallo

Differential Revision: D3735948

fbshipit-source-id: 5971a5367eb4b5a90e0f23b9279759e9f4060222
This commit is contained in:
Michał Gregorczyk 2016-09-06 19:39:30 -07:00 committed by Facebook Github Bot 8
parent d3238569bf
commit 2618ba2d60
2 changed files with 37 additions and 3 deletions

View File

@ -66,6 +66,7 @@ public class UnpackingJSBundleLoader extends JSBundleLoader {
private final String mSourceURL; private final String mSourceURL;
private final Context mContext; private final Context mContext;
private final int mLoadFlags; private final int mLoadFlags;
private final @Nullable Runnable mOnUnpackedCallback;
/** /**
* Description of what needs to be unpacked. * Description of what needs to be unpacked.
@ -78,6 +79,7 @@ public class UnpackingJSBundleLoader extends JSBundleLoader {
mSourceURL = Assertions.assertNotNull(builder.sourceURL); mSourceURL = Assertions.assertNotNull(builder.sourceURL);
mUnpackers = builder.unpackers.toArray(new Unpacker[builder.unpackers.size()]); mUnpackers = builder.unpackers.toArray(new Unpacker[builder.unpackers.size()]);
mLoadFlags = builder.loadFlags; mLoadFlags = builder.loadFlags;
mOnUnpackedCallback = builder.callback;
} }
/** /**
@ -85,18 +87,24 @@ public class UnpackingJSBundleLoader extends JSBundleLoader {
* directory and unpacks everything again. * directory and unpacks everything again.
*/ */
/* package */ void prepare() { /* package */ void prepare() {
boolean unpacked = false;
final File lockFilePath = new File(mContext.getFilesDir(), LOCK_FILE); final File lockFilePath = new File(mContext.getFilesDir(), LOCK_FILE);
Systrace.beginSection(TRACE_TAG_REACT_JAVA_BRIDGE, "UnpackingJSBundleLoader.prepare"); Systrace.beginSection(TRACE_TAG_REACT_JAVA_BRIDGE, "UnpackingJSBundleLoader.prepare");
try (FileLocker lock = FileLocker.lock(lockFilePath)) { try (FileLocker lock = FileLocker.lock(lockFilePath)) {
prepareLocked(); unpacked = prepareLocked();
} catch (IOException ioe) { } catch (IOException ioe) {
throw new RuntimeException(ioe); throw new RuntimeException(ioe);
} finally { } finally {
Systrace.endSection(TRACE_TAG_REACT_JAVA_BRIDGE); 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); final File dotFinishedFilePath = new File(mDirectoryPath, DOT_UNPACKED_FILE);
boolean shouldReconstruct = !mDirectoryPath.exists() || !dotFinishedFilePath.exists(); boolean shouldReconstruct = !mDirectoryPath.exists() || !dotFinishedFilePath.exists();
@ -106,7 +114,7 @@ public class UnpackingJSBundleLoader extends JSBundleLoader {
} }
if (!shouldReconstruct) { if (!shouldReconstruct) {
return; return false;
} }
boolean succeeded = false; boolean succeeded = false;
@ -138,6 +146,8 @@ public class UnpackingJSBundleLoader extends JSBundleLoader {
SysUtil.dumbDeleteRecursive(mDirectoryPath); SysUtil.dumbDeleteRecursive(mDirectoryPath);
} }
} }
return true;
} }
@Override @Override
@ -201,6 +211,7 @@ public class UnpackingJSBundleLoader extends JSBundleLoader {
private @Nullable String sourceURL; private @Nullable String sourceURL;
private final ArrayList<Unpacker> unpackers; private final ArrayList<Unpacker> unpackers;
private int loadFlags; private int loadFlags;
private @Nullable Runnable callback;
public Builder() { public Builder() {
this.unpackers = new ArrayList<Unpacker>(); this.unpackers = new ArrayList<Unpacker>();
@ -208,6 +219,7 @@ public class UnpackingJSBundleLoader extends JSBundleLoader {
destinationPath = null; destinationPath = null;
sourceURL = null; sourceURL = null;
loadFlags = 0; loadFlags = 0;
callback = null;
} }
public Builder setContext(Context context) { public Builder setContext(Context context) {
@ -257,6 +269,11 @@ public class UnpackingJSBundleLoader extends JSBundleLoader {
return this; return this;
} }
public Builder setOnUnpackedCallback(Runnable callback) {
this.callback = callback;
return this;
}
public UnpackingJSBundleLoader build() { public UnpackingJSBundleLoader build() {
Assertions.assertNotNull(destinationPath); Assertions.assertNotNull(destinationPath);
for (int i = 0; i < unpackers.size(); ++i) { for (int i = 0; i < unpackers.size(); ++i) {

View File

@ -56,6 +56,8 @@ public class UnpackingJSBundleLoaderTest {
private CatalystInstanceImpl mCatalystInstanceImpl; private CatalystInstanceImpl mCatalystInstanceImpl;
private UnpackingJSBundleLoader.Unpacker[] mMockUnpackers; private UnpackingJSBundleLoader.Unpacker[] mMockUnpackers;
private Runnable mCallback;
@Before @Before
public void setUp() throws IOException { public void setUp() throws IOException {
mDestinationPath = folder.newFolder("destination"); mDestinationPath = folder.newFolder("destination");
@ -75,6 +77,8 @@ public class UnpackingJSBundleLoaderTest {
for (int i = 0; i < mMockUnpackers.length; ++i) { for (int i = 0; i < mMockUnpackers.length; ++i) {
mMockUnpackers[i] = mock(UnpackingJSBundleLoader.Unpacker.class); mMockUnpackers[i] = mock(UnpackingJSBundleLoader.Unpacker.class);
} }
mCallback = mock(Runnable.class);
} }
private void addUnpackers() { private void addUnpackers() {
@ -193,4 +197,17 @@ public class UnpackingJSBundleLoaderTest {
assertFalse(mDestinationPath.exists()); 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);
}
} }