mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Fix deferred components startup threading and improve .so search algorithm. (flutter/engine#26429)
This commit is contained in:
parent
fa0b88fcb2
commit
d3de3f1f24
@ -1313,8 +1313,15 @@ void Shell::LoadDartDeferredLibrary(
|
||||
intptr_t loading_unit_id,
|
||||
std::unique_ptr<const fml::Mapping> snapshot_data,
|
||||
std::unique_ptr<const fml::Mapping> snapshot_instructions) {
|
||||
engine_->LoadDartDeferredLibrary(loading_unit_id, std::move(snapshot_data),
|
||||
std::move(snapshot_instructions));
|
||||
task_runners_.GetUITaskRunner()->PostTask(fml::MakeCopyable(
|
||||
[engine = engine_->GetWeakPtr(), loading_unit_id,
|
||||
data = std::move(snapshot_data),
|
||||
instructions = std::move(snapshot_instructions)]() mutable {
|
||||
if (engine) {
|
||||
engine->LoadDartDeferredLibrary(loading_unit_id, std::move(data),
|
||||
std::move(instructions));
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
void Shell::LoadDartDeferredLibraryError(intptr_t loading_unit_id,
|
||||
|
||||
@ -425,18 +425,34 @@ public class PlayStoreDeferredComponentManager implements DeferredComponentManag
|
||||
List<String> apkPaths = new ArrayList<>();
|
||||
// If not found in APKs, we check in extracted native libs for the lib directly.
|
||||
List<String> soPaths = new ArrayList<>();
|
||||
|
||||
Queue<File> searchFiles = new LinkedList<>();
|
||||
// Downloaded modules are stored here
|
||||
searchFiles.add(context.getFilesDir());
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
// The initial installed apks are provided by `sourceDirs` in ApplicationInfo.
|
||||
// The jniLibs we want are in the splits not the baseDir. These
|
||||
// APKs are only searched as a fallback, as base libs generally do not need
|
||||
// to be fully path referenced.
|
||||
for (String path : context.getApplicationInfo().splitSourceDirs) {
|
||||
searchFiles.add(new File(path));
|
||||
}
|
||||
}
|
||||
|
||||
while (!searchFiles.isEmpty()) {
|
||||
File file = searchFiles.remove();
|
||||
if (file != null && file.isDirectory()) {
|
||||
if (file != null && file.isDirectory() && file.listFiles() != null) {
|
||||
for (File f : file.listFiles()) {
|
||||
searchFiles.add(f);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
String name = file.getName();
|
||||
if (name.endsWith(".apk") && name.startsWith(componentName) && name.contains(pathAbi)) {
|
||||
// Special case for "split_config" since android base module non-master apks are
|
||||
// initially installed with the "split_config" prefix/name.
|
||||
if (name.endsWith(".apk")
|
||||
&& (name.startsWith(componentName) || name.startsWith("split_config"))
|
||||
&& name.contains(pathAbi)) {
|
||||
apkPaths.add(file.getAbsolutePath());
|
||||
continue;
|
||||
}
|
||||
@ -459,7 +475,7 @@ public class PlayStoreDeferredComponentManager implements DeferredComponentManag
|
||||
}
|
||||
|
||||
flutterJNI.loadDartDeferredLibrary(
|
||||
loadingUnitId, searchPaths.toArray(new String[apkPaths.size()]));
|
||||
loadingUnitId, searchPaths.toArray(new String[searchPaths.size()]));
|
||||
}
|
||||
|
||||
public boolean uninstallDeferredComponent(int loadingUnitId, String componentName) {
|
||||
|
||||
@ -14,6 +14,7 @@ import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.content.Context;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
@ -32,6 +33,7 @@ import org.robolectric.annotation.Config;
|
||||
|
||||
@Config(manifest = Config.NONE)
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
@TargetApi(21)
|
||||
public class PlayStoreDeferredComponentManagerTest {
|
||||
private class TestFlutterJNI extends FlutterJNI {
|
||||
public int loadDartDeferredLibraryCalled = 0;
|
||||
@ -90,9 +92,12 @@ public class PlayStoreDeferredComponentManagerTest {
|
||||
PackageManager packageManager = mock(PackageManager.class);
|
||||
ApplicationInfo applicationInfo = mock(ApplicationInfo.class);
|
||||
applicationInfo.metaData = metadata;
|
||||
applicationInfo.splitSourceDirs = new String[1];
|
||||
applicationInfo.splitSourceDirs[0] = "some.invalid.apk";
|
||||
when(packageManager.getApplicationInfo(any(String.class), any(int.class)))
|
||||
.thenReturn(applicationInfo);
|
||||
doReturn(packageManager).when(spyContext).getPackageManager();
|
||||
doReturn(applicationInfo).when(spyContext).getApplicationInfo();
|
||||
return spyContext;
|
||||
}
|
||||
|
||||
@ -239,6 +244,30 @@ public class PlayStoreDeferredComponentManagerTest {
|
||||
assertEquals(jni.loadingUnitId, 123);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void searchPathsSearchesSplitConfig() throws NameNotFoundException {
|
||||
TestFlutterJNI jni = new TestFlutterJNI();
|
||||
Context spyContext = createSpyContext(null);
|
||||
doReturn(null).when(spyContext).getAssets();
|
||||
String apkTestPath = "test/path/split_config.armeabi_v7a.apk";
|
||||
doReturn(new File(apkTestPath)).when(spyContext).getFilesDir();
|
||||
TestPlayStoreDeferredComponentManager playStoreManager =
|
||||
new TestPlayStoreDeferredComponentManager(spyContext, jni);
|
||||
jni.setDeferredComponentManager(playStoreManager);
|
||||
|
||||
assertEquals(jni.loadingUnitId, 0);
|
||||
|
||||
playStoreManager.installDeferredComponent(123, "TestModuleName");
|
||||
assertEquals(jni.loadDartDeferredLibraryCalled, 1);
|
||||
assertEquals(jni.updateAssetManagerCalled, 1);
|
||||
assertEquals(jni.deferredComponentInstallFailureCalled, 0);
|
||||
|
||||
assertEquals(jni.searchPaths[0], "libapp.so-123.part.so");
|
||||
assertTrue(jni.searchPaths[1].endsWith(apkTestPath + "!lib/armeabi-v7a/libapp.so-123.part.so"));
|
||||
assertEquals(jni.searchPaths.length, 2);
|
||||
assertEquals(jni.loadingUnitId, 123);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void invalidSearchPathsAreIgnored() throws NameNotFoundException {
|
||||
TestFlutterJNI jni = new TestFlutterJNI();
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user