未验证 提交 5c6ebf79 编写于 作者: M Martin Kustermann 提交者: GitHub

Enable flutter engine to also work with .*so files on android (#4298)

* Enable flutter engine to also work with .*so files on android

We would like to be able to use native tools (e.g. simpleperf, gdb) with
precompiled flutter apps.  The native tools work much better with *.so
files instead of the custom formats the Dart VM uses by default.

This CL adds support for being able to load the flutter app from an *.so
file on Android.

* Add sanity check to ensure we have either shared library or instruction snapshot (but not both)
上级 32270c78
......@@ -26,6 +26,7 @@ struct Settings {
bool dart_non_checked_mode = false;
bool enable_software_rendering = false;
bool using_blink = true;
std::string aot_shared_library_path;
std::string aot_snapshot_path;
std::string aot_vm_snapshot_data_filename;
std::string aot_vm_snapshot_instr_filename;
......
......@@ -163,20 +163,40 @@ void Engine::Init(const std::string& bundle_path) {
dlsym(library_handle, "kDartIsolateSnapshotInstructions"));
#elif OS(ANDROID)
const blink::Settings& settings = blink::Settings::Get();
const std::string& aot_shared_library_path = settings.aot_shared_library_path;
const std::string& aot_snapshot_path = settings.aot_snapshot_path;
FXL_CHECK(!aot_snapshot_path.empty());
vm_snapshot_data =
MemMapSnapshot(aot_snapshot_path, "vm_snapshot_data",
settings.aot_vm_snapshot_data_filename, false);
vm_snapshot_instr =
MemMapSnapshot(aot_snapshot_path, "vm_snapshot_instr",
settings.aot_vm_snapshot_instr_filename, true);
default_isolate_snapshot_data =
MemMapSnapshot(aot_snapshot_path, "isolate_snapshot_data",
settings.aot_isolate_snapshot_data_filename, false);
default_isolate_snapshot_instr =
MemMapSnapshot(aot_snapshot_path, "isolate_snapshot_instr",
settings.aot_isolate_snapshot_instr_filename, true);
if (!aot_shared_library_path.empty()) {
FXL_CHECK(aot_snapshot_path.empty());
dlerror(); // clear previous errors on thread
void* library_handle = dlopen(aot_shared_library_path.c_str(), RTLD_NOW);
const char* err = dlerror();
if (err != nullptr) {
FXL_LOG(FATAL) << "dlopen failed: " << err;
}
vm_snapshot_data = reinterpret_cast<const uint8_t*>(
dlsym(library_handle, "_kDartVmSnapshotData"));
vm_snapshot_instr = reinterpret_cast<const uint8_t*>(
dlsym(library_handle, "_kDartVmSnapshotInstructions"));
default_isolate_snapshot_data = reinterpret_cast<const uint8_t*>(
dlsym(library_handle, "_kDartIsolateSnapshotData"));
default_isolate_snapshot_instr = reinterpret_cast<const uint8_t*>(
dlsym(library_handle, "_kDartIsolateSnapshotInstructions"));
} else {
FXL_CHECK(!aot_snapshot_path.empty());
vm_snapshot_data =
MemMapSnapshot(aot_snapshot_path, "vm_snapshot_data",
settings.aot_vm_snapshot_data_filename, false);
vm_snapshot_instr =
MemMapSnapshot(aot_snapshot_path, "vm_snapshot_instr",
settings.aot_vm_snapshot_instr_filename, true);
default_isolate_snapshot_data =
MemMapSnapshot(aot_snapshot_path, "isolate_snapshot_data",
settings.aot_isolate_snapshot_data_filename, false);
default_isolate_snapshot_instr =
MemMapSnapshot(aot_snapshot_path, "isolate_snapshot_instr",
settings.aot_isolate_snapshot_instr_filename, true);
}
#else
#error Unknown OS
#endif
......
......@@ -139,6 +139,9 @@ void Shell::InitStandalone(fxl::CommandLine command_line,
command_line.GetOptionValue(FlagForSwitch(Switch::AotIsolateSnapshotData),
&settings.aot_isolate_snapshot_data_filename);
command_line.GetOptionValue(FlagForSwitch(Switch::AotSharedLibraryPath),
&settings.aot_shared_library_path);
command_line.GetOptionValue(
FlagForSwitch(Switch::AotIsolateSnapshotInstructions),
&settings.aot_isolate_snapshot_instr_filename);
......
......@@ -22,6 +22,7 @@ namespace shell {
// clang-format on
DEF_SWITCHES_START
DEF_SWITCH(AotSharedLibraryPath, "aot-shared-library-path", "Path to the *.so.")
DEF_SWITCH(AotSnapshotPath, "aot-snapshot-path", "Path to the AOT snapshot.")
DEF_SWITCH(AotVmSnapshotData, "vm-snapshot-data", "")
DEF_SWITCH(AotVmSnapshotInstructions, "vm-snapshot-instr", "")
......
......@@ -30,6 +30,7 @@ public class FlutterMain {
private static final String TAG = "FlutterMain";
// Must match values in sky::shell::switches
private static final String AOT_SHARED_LIBRARY_PATH = "aot-shared-library-path";
private static final String AOT_SNAPSHOT_PATH_KEY = "aot-snapshot-path";
private static final String AOT_VM_SNAPSHOT_DATA_KEY = "vm-snapshot-data";
private static final String AOT_VM_SNAPSHOT_INSTR_KEY = "vm-snapshot-instr";
......@@ -39,6 +40,8 @@ public class FlutterMain {
private static final String SNAPSHOT_BLOB_KEY = "snapshot-blob";
// XML Attribute keys supported in AndroidManifest.xml
public static final String PUBLIC_AOT_AOT_SHARED_LIBRARY_PATH =
FlutterMain.class.getName() + '.' + AOT_SHARED_LIBRARY_PATH;
public static final String PUBLIC_AOT_VM_SNAPSHOT_DATA_KEY =
FlutterMain.class.getName() + '.' + AOT_VM_SNAPSHOT_DATA_KEY;
public static final String PUBLIC_AOT_VM_SNAPSHOT_INSTR_KEY =
......@@ -53,6 +56,7 @@ public class FlutterMain {
FlutterMain.class.getName() + '.' + SNAPSHOT_BLOB_KEY;
// Resource names used for components of the precompiled snapshot.
private static final String DEFAULT_AOT_SHARED_LIBRARY_PATH= "app.so";
private static final String DEFAULT_AOT_VM_SNAPSHOT_DATA = "vm_snapshot_data";
private static final String DEFAULT_AOT_VM_SNAPSHOT_INSTR = "vm_snapshot_instr";
private static final String DEFAULT_AOT_ISOLATE_SNAPSHOT_DATA = "isolate_snapshot_data";
......@@ -68,6 +72,7 @@ public class FlutterMain {
.build();
// Mutable because default values can be overridden via config properties
private static String sAotSharedLibraryPath = DEFAULT_AOT_SHARED_LIBRARY_PATH;
private static String sAotVmSnapshotData = DEFAULT_AOT_VM_SNAPSHOT_DATA;
private static String sAotVmSnapshotInstr = DEFAULT_AOT_VM_SNAPSHOT_INSTR;
private static String sAotIsolateSnapshotData = DEFAULT_AOT_ISOLATE_SNAPSHOT_DATA;
......@@ -78,6 +83,7 @@ public class FlutterMain {
private static boolean sInitialized = false;
private static ResourceExtractor sResourceExtractor;
private static boolean sIsPrecompiled;
private static boolean sIsPrecompiledAsSharedLibrary;
private static Settings sSettings;
private static final class ImmutableSetBuilder<T> {
......@@ -141,9 +147,9 @@ public class FlutterMain {
long initStartTimestampMillis = SystemClock.uptimeMillis();
initConfig(applicationContext);
initAot(applicationContext);
initResources(applicationContext);
System.loadLibrary("flutter");
initAot(applicationContext);
// We record the initialization time using SystemClock because at the start of the
// initialization we have not yet loaded the native library to call into dart_tools_api.h.
......@@ -179,6 +185,9 @@ public class FlutterMain {
shellArgs.add("--" + AOT_VM_SNAPSHOT_INSTR_KEY + "=" + sAotVmSnapshotInstr);
shellArgs.add("--" + AOT_ISOLATE_SNAPSHOT_DATA_KEY + "=" + sAotIsolateSnapshotData);
shellArgs.add("--" + AOT_ISOLATE_SNAPSHOT_INSTR_KEY + "=" + sAotIsolateSnapshotInstr);
} else if (sIsPrecompiledAsSharedLibrary) {
shellArgs.add("--" + AOT_SHARED_LIBRARY_PATH + "=" +
new File(PathUtils.getDataDirectory(applicationContext), sAotSharedLibraryPath));
} else {
shellArgs.add("--cache-dir-path=" +
PathUtils.getCacheDirectory(applicationContext));
......@@ -211,6 +220,7 @@ public class FlutterMain {
Bundle metadata = applicationContext.getPackageManager().getApplicationInfo(
applicationContext.getPackageName(), PackageManager.GET_META_DATA).metaData;
if (metadata != null) {
sAotSharedLibraryPath = metadata.getString(PUBLIC_AOT_AOT_SHARED_LIBRARY_PATH, DEFAULT_AOT_SHARED_LIBRARY_PATH);
sAotVmSnapshotData = metadata.getString(PUBLIC_AOT_VM_SNAPSHOT_DATA_KEY, DEFAULT_AOT_VM_SNAPSHOT_DATA);
sAotVmSnapshotInstr = metadata.getString(PUBLIC_AOT_VM_SNAPSHOT_INSTR_KEY, DEFAULT_AOT_VM_SNAPSHOT_INSTR);
sAotIsolateSnapshotData = metadata.getString(PUBLIC_AOT_ISOLATE_SNAPSHOT_DATA_KEY, DEFAULT_AOT_ISOLATE_SNAPSHOT_DATA);
......@@ -228,13 +238,19 @@ public class FlutterMain {
new ResourceCleaner(context).start();
sResourceExtractor = new ResourceExtractor(context)
.addResources(SKY_RESOURCES)
.addResource(sFlx);
if (sIsPrecompiledAsSharedLibrary) {
sResourceExtractor
.addResource(sAotSharedLibraryPath);
} else {
sResourceExtractor
.addResource(sAotVmSnapshotData)
.addResource(sAotVmSnapshotInstr)
.addResource(sAotIsolateSnapshotData)
.addResource(sAotIsolateSnapshotInstr)
.addResource(sFlx)
.addResource(sSnapshotBlob)
.start();
.addResource(sSnapshotBlob);
}
sResourceExtractor.start();
}
/**
......@@ -261,10 +277,15 @@ public class FlutterMain {
sAotIsolateSnapshotData,
sAotIsolateSnapshotInstr
));
sIsPrecompiledAsSharedLibrary = assets.contains(sAotSharedLibraryPath);
if (sIsPrecompiled && sIsPrecompiledAsSharedLibrary) {
throw new RuntimeException(
"Found precompiled app as shared library and as Dart VM snapshots.");
}
}
public static boolean isRunningPrecompiledCode() {
return sIsPrecompiled;
return sIsPrecompiled || sIsPrecompiledAsSharedLibrary;
}
public static String findAppBundlePath(Context applicationContext) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册