Skip to content

Commit

Permalink
Enable flutter engine to also work with .*so files on android (flutte…
Browse files Browse the repository at this point in the history
…r#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)
  • Loading branch information
mkustermann authored Nov 21, 2017
1 parent 32270c7 commit 5c6ebf7
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 18 deletions.
1 change: 1 addition & 0 deletions common/settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
46 changes: 33 additions & 13 deletions shell/common/engine.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 3 additions & 0 deletions shell/common/shell.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
1 change: 1 addition & 0 deletions shell/common/switches.h
Original file line number Diff line number Diff line change
Expand Up @@ -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", "")
Expand Down
31 changes: 26 additions & 5 deletions shell/platform/android/io/flutter/view/FlutterMain.java
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand All @@ -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 =
Expand All @@ -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";
Expand All @@ -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;
Expand All @@ -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> {
Expand Down Expand Up @@ -141,9 +147,9 @@ public static void startInitialization(Context applicationContext, Settings sett

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.
Expand Down Expand Up @@ -179,6 +185,9 @@ public static void ensureInitializationComplete(Context applicationContext, Stri
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));
Expand Down Expand Up @@ -211,6 +220,7 @@ private static void initConfig(Context applicationContext) {
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);
Expand All @@ -228,13 +238,19 @@ private static void initResources(Context applicationContext) {
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();
}

/**
Expand All @@ -261,10 +277,15 @@ private static void initAot(Context applicationContext) {
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) {
Expand Down

0 comments on commit 5c6ebf7

Please sign in to comment.