未验证 提交 e1204944 编写于 作者: G Gary Qian 提交者: GitHub

Fix deferred components startup threading and improve .so search algorithm. (#26429)

上级 a832502e
......@@ -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();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册