From bfbb2e67fc0bb26b4ecf78f5f2b5d597f1f26588 Mon Sep 17 00:00:00 2001 From: Chingjun Lau Date: Tue, 29 Sep 2020 17:19:51 -0700 Subject: [PATCH 1/3] Initialize the AssetManager from the application context so that assets from dynamic feature modules can be loaded. --- .../io/flutter/embedding/engine/FlutterEngine.java | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/shell/platform/android/io/flutter/embedding/engine/FlutterEngine.java b/shell/platform/android/io/flutter/embedding/engine/FlutterEngine.java index 71730e4668a85..2e001e7a73965 100644 --- a/shell/platform/android/io/flutter/embedding/engine/FlutterEngine.java +++ b/shell/platform/android/io/flutter/embedding/engine/FlutterEngine.java @@ -5,6 +5,8 @@ package io.flutter.embedding.engine; import android.content.Context; +import android.content.pm.PackageManager.NameNotFoundException; +import android.content.res.AssetManager; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import io.flutter.FlutterInjector; @@ -264,7 +266,13 @@ public FlutterEngine( @Nullable String[] dartVmArgs, boolean automaticallyRegisterPlugins, boolean waitForRestorationData) { - this.dartExecutor = new DartExecutor(flutterJNI, context.getAssets()); + AssetManager assetManager; + try { + assetManager = context.createPackageContext(context.getPackageName(), 0).getAssets(); + } catch (NameNotFoundException e) { + assetManager = context.getAssets(); + } + this.dartExecutor = new DartExecutor(flutterJNI, assetManager); this.dartExecutor.onAttachedToJNI(); accessibilityChannel = new AccessibilityChannel(dartExecutor, flutterJNI); From 9996fd77b98b3c6f3140d6bd9a8615a694355736 Mon Sep 17 00:00:00 2001 From: Chingjun Lau Date: Fri, 9 Oct 2020 13:54:08 -0700 Subject: [PATCH 2/3] Fix tests, and added test for getAssets --- .../embedding/engine/FlutterEngineTest.java | 28 +++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/shell/platform/android/test/io/flutter/embedding/engine/FlutterEngineTest.java b/shell/platform/android/test/io/flutter/embedding/engine/FlutterEngineTest.java index 6f141fa1aa192..033fc1ef3943f 100644 --- a/shell/platform/android/test/io/flutter/embedding/engine/FlutterEngineTest.java +++ b/shell/platform/android/test/io/flutter/embedding/engine/FlutterEngineTest.java @@ -4,6 +4,7 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.any; +import static org.mockito.Mockito.anyInt; import static org.mockito.Mockito.atLeast; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; @@ -11,6 +12,7 @@ import static org.mockito.Mockito.when; import android.content.Context; +import android.content.pm.PackageManager.NameNotFoundException; import io.flutter.FlutterInjector; import io.flutter.embedding.engine.FlutterEngine; import io.flutter.embedding.engine.FlutterJNI; @@ -127,8 +129,11 @@ public void itNotifiesPlatformViewsControllerAboutJNILifecycle() { } @Test - public void itUsesApplicationContext() { + public void itUsesApplicationContext() throws NameNotFoundException { Context context = mock(Context.class); + Context packageContext = mock(Context.class); + + when(context.createPackageContext(any(), anyInt())).thenReturn(packageContext); new FlutterEngine( context, @@ -141,12 +146,31 @@ public void itUsesApplicationContext() { } @Test - public void itCanUseFlutterLoaderInjectionViaFlutterInjector() { + public void itUsesPackageContextForAssetManager() throws NameNotFoundException { + Context context = mock(Context.class); + Context packageContext = mock(Context.class); + when(context.createPackageContext(any(), anyInt())).thenReturn(packageContext); + + new FlutterEngine( + context, + mock(FlutterLoader.class), + flutterJNI, + /*dartVmArgs=*/ new String[] {}, + /*automaticallyRegisterPlugins=*/ false); + + verify(packageContext, atLeast(1)).getAssets(); + } + + @Test + public void itCanUseFlutterLoaderInjectionViaFlutterInjector() throws NameNotFoundException { FlutterInjector.reset(); FlutterLoader mockFlutterLoader = mock(FlutterLoader.class); FlutterInjector.setInstance( new FlutterInjector.Builder().setFlutterLoader(mockFlutterLoader).build()); Context mockContext = mock(Context.class); + Context packageContext = mock(Context.class); + + when(mockContext.createPackageContext(any(), anyInt())).thenReturn(packageContext); new FlutterEngine(mockContext, null, flutterJNI); From bda5c393c89a7d91c7e854d06e2fa4723f8d4a5e Mon Sep 17 00:00:00 2001 From: Chingjun Lau Date: Fri, 9 Oct 2020 14:00:06 -0700 Subject: [PATCH 3/3] Add test that it never uses original context to get asset manager --- .../test/io/flutter/embedding/engine/FlutterEngineTest.java | 1 + 1 file changed, 1 insertion(+) diff --git a/shell/platform/android/test/io/flutter/embedding/engine/FlutterEngineTest.java b/shell/platform/android/test/io/flutter/embedding/engine/FlutterEngineTest.java index 033fc1ef3943f..be9057d97ed8e 100644 --- a/shell/platform/android/test/io/flutter/embedding/engine/FlutterEngineTest.java +++ b/shell/platform/android/test/io/flutter/embedding/engine/FlutterEngineTest.java @@ -159,6 +159,7 @@ public void itUsesPackageContextForAssetManager() throws NameNotFoundException { /*automaticallyRegisterPlugins=*/ false); verify(packageContext, atLeast(1)).getAssets(); + verify(context, times(0)).getAssets(); } @Test