Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -248,12 +248,14 @@ private ApplicationInfo getApplicationInfo() {

// Obtain and parses the metadata string. An example encoded string is:
//
// "2:component2,3:component3,4:component1:libcomponent4.so"
// "2:component2,3:component3,4:component1:libcomponent4.so,5:"
//
// Where loading unit 2 is included in component2, loading unit 3 is
// included in component3, and loading unit 4 is included in component1.
// An optional third parameter can be added to indicate the name of
// the shared library of the loading unit.
// the shared library of the loading unit. Loading unit 5 maps to an empty
// string, indicating it is included in the base module and no dynamic
// feature modules need to be downloaded.
private void initLoadingUnitMappingToComponentNames() {
String mappingKey = DeferredComponentManager.class.getName() + ".loadingUnitMapping";
ApplicationInfo applicationInfo = getApplicationInfo();
Expand All @@ -269,7 +271,8 @@ private void initLoadingUnitMappingToComponentNames() {
+ "' is defined in the base module's AndroidManifest.");
} else {
for (String entry : rawMappingString.split(",")) {
String[] splitEntry = entry.split(":");
// Split with -1 param to include empty string following trailing ":"
String[] splitEntry = entry.split(":", -1);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add a code comment

int loadingUnitId = Integer.parseInt(splitEntry[0]);
loadingUnitIdToComponentNames.put(loadingUnitId, splitEntry[1]);
if (splitEntry.length > 2) {
Expand All @@ -290,6 +293,13 @@ public void installDeferredComponent(int loadingUnitId, String componentName) {
return;
}

// Handle a loading unit that is included in the base module that does not need download.
if (resolvedComponentName.equals("") && loadingUnitId > 0) {
// No need to load assets as base assets are already loaded.
loadDartLibrary(loadingUnitId, resolvedComponentName);
return;
}

SplitInstallRequest request =
SplitInstallRequest.newBuilder().addModule(resolvedComponentName).build();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,37 @@ public void downloadCallsJNIFunctionsWithSharedLibraryNameFromManifest()
assertEquals(jni.assetBundlePath, "custom_assets");
}

@Test
public void manifestMappingHandlesBaseModuleEmptyString() throws NameNotFoundException {
TestFlutterJNI jni = new TestFlutterJNI();

Bundle bundle = new Bundle();
bundle.putString(
PlayStoreDeferredComponentManager.MAPPING_KEY, "123:module:custom_name.so,3:,4:");
bundle.putString(ApplicationInfoLoader.PUBLIC_FLUTTER_ASSETS_DIR_KEY, "custom_assets");

Context spyContext = createSpyContext(bundle);
doReturn(null).when(spyContext).getAssets();

String soTestFilename = "libapp.so-3.part.so";
String soTestPath = "test/path/" + soTestFilename;
doReturn(new File(soTestPath)).when(spyContext).getFilesDir();
PlayStoreDeferredComponentManager playStoreManager =
new PlayStoreDeferredComponentManager(spyContext, jni);
jni.setDeferredComponentManager(playStoreManager);
assertEquals(jni.loadingUnitId, 0);

playStoreManager.installDeferredComponent(3, null);
assertEquals(jni.loadDartDeferredLibraryCalled, 1);
assertEquals(jni.updateAssetManagerCalled, 0); // no assets to load for base
assertEquals(jni.deferredComponentInstallFailureCalled, 0);

assertEquals(jni.searchPaths[0], soTestFilename);
assertTrue(jni.searchPaths[1].endsWith(soTestPath));
assertEquals(jni.searchPaths.length, 2);
assertEquals(jni.loadingUnitId, 3);
}

@Test
public void searchPathsAddsApks() throws NameNotFoundException {
TestFlutterJNI jni = new TestFlutterJNI();
Expand Down