From 0bde5302deaa6d25bdc2aa39eed3d69a15d298bf Mon Sep 17 00:00:00 2001 From: garyqian Date: Fri, 12 Mar 2021 14:30:13 -0800 Subject: [PATCH 1/4] Handle base module loading units --- .../PlayStoreDeferredComponentManager.java | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/shell/platform/android/io/flutter/embedding/engine/deferredcomponents/PlayStoreDeferredComponentManager.java b/shell/platform/android/io/flutter/embedding/engine/deferredcomponents/PlayStoreDeferredComponentManager.java index 6a3f2147afa09..78e54af2d8dc0 100644 --- a/shell/platform/android/io/flutter/embedding/engine/deferredcomponents/PlayStoreDeferredComponentManager.java +++ b/shell/platform/android/io/flutter/embedding/engine/deferredcomponents/PlayStoreDeferredComponentManager.java @@ -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(); @@ -269,7 +271,7 @@ private void initLoadingUnitMappingToComponentNames() { + "' is defined in the base module's AndroidManifest."); } else { for (String entry : rawMappingString.split(",")) { - String[] splitEntry = entry.split(":"); + String[] splitEntry = entry.split(":", -1); int loadingUnitId = Integer.parseInt(splitEntry[0]); loadingUnitIdToComponentNames.put(loadingUnitId, splitEntry[1]); if (splitEntry.length > 2) { @@ -290,6 +292,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(); From ac9e2ece46a2b06b3cabb570bae88e65f1aeb9f4 Mon Sep 17 00:00:00 2001 From: garyqian Date: Fri, 12 Mar 2021 15:13:13 -0800 Subject: [PATCH 2/4] Tests --- ...PlayStoreDeferredComponentManagerTest.java | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/shell/platform/android/test/io/flutter/embedding/engine/deferredcomponents/PlayStoreDeferredComponentManagerTest.java b/shell/platform/android/test/io/flutter/embedding/engine/deferredcomponents/PlayStoreDeferredComponentManagerTest.java index f6347dad1c698..913e521fce76c 100644 --- a/shell/platform/android/test/io/flutter/embedding/engine/deferredcomponents/PlayStoreDeferredComponentManagerTest.java +++ b/shell/platform/android/test/io/flutter/embedding/engine/deferredcomponents/PlayStoreDeferredComponentManagerTest.java @@ -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(); + TestPlayStoreDeferredComponentManager playStoreManager = + new TestPlayStoreDeferredComponentManager(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(); From eea24323b8d4a8716a3d65922440b04f2407e319 Mon Sep 17 00:00:00 2001 From: garyqian Date: Mon, 15 Mar 2021 12:50:22 -0700 Subject: [PATCH 3/4] Comments, formatting --- .../PlayStoreDeferredComponentManager.java | 1 + .../PlayStoreDeferredComponentManagerTest.java | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/shell/platform/android/io/flutter/embedding/engine/deferredcomponents/PlayStoreDeferredComponentManager.java b/shell/platform/android/io/flutter/embedding/engine/deferredcomponents/PlayStoreDeferredComponentManager.java index 78e54af2d8dc0..c5c7939930aa4 100644 --- a/shell/platform/android/io/flutter/embedding/engine/deferredcomponents/PlayStoreDeferredComponentManager.java +++ b/shell/platform/android/io/flutter/embedding/engine/deferredcomponents/PlayStoreDeferredComponentManager.java @@ -271,6 +271,7 @@ private void initLoadingUnitMappingToComponentNames() { + "' is defined in the base module's AndroidManifest."); } else { for (String entry : rawMappingString.split(",")) { + // Split with -1 param to include empty string following trailing ":" String[] splitEntry = entry.split(":", -1); int loadingUnitId = Integer.parseInt(splitEntry[0]); loadingUnitIdToComponentNames.put(loadingUnitId, splitEntry[1]); diff --git a/shell/platform/android/test/io/flutter/embedding/engine/deferredcomponents/PlayStoreDeferredComponentManagerTest.java b/shell/platform/android/test/io/flutter/embedding/engine/deferredcomponents/PlayStoreDeferredComponentManagerTest.java index 913e521fce76c..8e754770a1a18 100644 --- a/shell/platform/android/test/io/flutter/embedding/engine/deferredcomponents/PlayStoreDeferredComponentManagerTest.java +++ b/shell/platform/android/test/io/flutter/embedding/engine/deferredcomponents/PlayStoreDeferredComponentManagerTest.java @@ -185,12 +185,12 @@ public void downloadCallsJNIFunctionsWithSharedLibraryNameFromManifest() } @Test - public void manifestMappingHandlesBaseModuleEmptyString() - throws NameNotFoundException { + 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( + PlayStoreDeferredComponentManager.MAPPING_KEY, "123:module:custom_name.so,3:,4:"); bundle.putString(ApplicationInfoLoader.PUBLIC_FLUTTER_ASSETS_DIR_KEY, "custom_assets"); Context spyContext = createSpyContext(bundle); From 6139d0271c6255a90803d074382bc80fadd0c489 Mon Sep 17 00:00:00 2001 From: garyqian Date: Mon, 15 Mar 2021 13:45:17 -0700 Subject: [PATCH 4/4] Fix test --- .../PlayStoreDeferredComponentManagerTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/shell/platform/android/test/io/flutter/embedding/engine/deferredcomponents/PlayStoreDeferredComponentManagerTest.java b/shell/platform/android/test/io/flutter/embedding/engine/deferredcomponents/PlayStoreDeferredComponentManagerTest.java index 8e754770a1a18..10355120919f9 100644 --- a/shell/platform/android/test/io/flutter/embedding/engine/deferredcomponents/PlayStoreDeferredComponentManagerTest.java +++ b/shell/platform/android/test/io/flutter/embedding/engine/deferredcomponents/PlayStoreDeferredComponentManagerTest.java @@ -199,8 +199,8 @@ public void manifestMappingHandlesBaseModuleEmptyString() throws NameNotFoundExc String soTestFilename = "libapp.so-3.part.so"; String soTestPath = "test/path/" + soTestFilename; doReturn(new File(soTestPath)).when(spyContext).getFilesDir(); - TestPlayStoreDeferredComponentManager playStoreManager = - new TestPlayStoreDeferredComponentManager(spyContext, jni); + PlayStoreDeferredComponentManager playStoreManager = + new PlayStoreDeferredComponentManager(spyContext, jni); jni.setDeferredComponentManager(playStoreManager); assertEquals(jni.loadingUnitId, 0);