未验证 提交 9f50dae3 编写于 作者: J Jason Simmons 提交者: GitHub

Look up ICU symbols based on the path to libflutter.so as a fallback (#8139)

The ICU data is packaged within libflutter.so, and the engine uses
dlsym(RTLD_DEFAULT) to look up the ICU data symbols in the libraries
loaded by the process.

This approach apparently fails on some Xiaomi devices.  If RTLD_DEFAULT
can not find the symbols, then the platform will pass the path to the
libflutter.so library so the engine can use that to resolve the symbols.

Fixes https://github.com/flutter/flutter/issues/28208
上级 59715b71
......@@ -123,13 +123,29 @@ static bool GetSwitchValue(const fml::CommandLine& command_line,
return false;
}
std::unique_ptr<fml::Mapping> GetSymbolMapping(std::string symbol_prefix) {
fml::RefPtr<fml::NativeLibrary> proc_library =
std::unique_ptr<fml::Mapping> GetSymbolMapping(std::string symbol_prefix,
std::string native_lib_path) {
const uint8_t* mapping;
intptr_t size;
auto lookup_symbol = [&mapping, &size, symbol_prefix](
const fml::RefPtr<fml::NativeLibrary>& library) {
mapping = library->ResolveSymbol((symbol_prefix + "_start").c_str());
size = reinterpret_cast<intptr_t>(
library->ResolveSymbol((symbol_prefix + "_size").c_str()));
};
fml::RefPtr<fml::NativeLibrary> library =
fml::NativeLibrary::CreateForCurrentProcess();
const uint8_t* mapping =
proc_library->ResolveSymbol((symbol_prefix + "_start").c_str());
const intptr_t size = reinterpret_cast<intptr_t>(
proc_library->ResolveSymbol((symbol_prefix + "_size").c_str()));
lookup_symbol(library);
if (!(mapping && size)) {
// Symbol lookup for the current process fails on some devices. As a
// fallback, try doing the lookup based on the path to the Flutter library.
library = fml::NativeLibrary::Create(native_lib_path.c_str());
lookup_symbol(library);
}
FML_CHECK(mapping && size) << "Unable to resolve symbols: " << symbol_prefix;
return std::make_unique<fml::NonOwnedMapping>(mapping, size);
}
......@@ -228,11 +244,13 @@ blink::Settings SettingsFromCommandLine(const fml::CommandLine& command_line) {
command_line.GetOptionValue(FlagForSwitch(Switch::ICUDataFilePath),
&settings.icu_data_path);
if (command_line.HasOption(FlagForSwitch(Switch::ICUSymbolPrefix))) {
std::string icu_symbol_prefix;
std::string icu_symbol_prefix, native_lib_path;
command_line.GetOptionValue(FlagForSwitch(Switch::ICUSymbolPrefix),
&icu_symbol_prefix);
settings.icu_mapper = [icu_symbol_prefix] {
return GetSymbolMapping(icu_symbol_prefix);
command_line.GetOptionValue(FlagForSwitch(Switch::ICUNativeLibPath),
&native_lib_path);
settings.icu_mapper = [icu_symbol_prefix, native_lib_path] {
return GetSymbolMapping(icu_symbol_prefix, native_lib_path);
};
}
}
......
......@@ -52,6 +52,9 @@ DEF_SWITCH(ICUSymbolPrefix,
"icu-symbol-prefix",
"Prefix for the symbols representing ICU data linked into the "
"Flutter library.")
DEF_SWITCH(ICUNativeLibPath,
"icu-native-lib-path",
"Path to the library file that exports the ICU data.")
DEF_SWITCH(DartFlags,
"dart-flags",
"Flags passed directly to the Dart VM without being interpreted "
......
......@@ -6,6 +6,7 @@ package io.flutter.view;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.res.AssetManager;
import android.app.AlarmManager;
......@@ -195,7 +196,12 @@ public class FlutterMain {
sResourceExtractor.waitForCompletion();
List<String> shellArgs = new ArrayList<>();
shellArgs.add("--icu-symbol-prefix=_binary_icudtl_dat");
ApplicationInfo applicationInfo = applicationContext.getPackageManager().getApplicationInfo(
applicationContext.getPackageName(), PackageManager.GET_META_DATA);
shellArgs.add("--icu-native-lib-path=" + applicationInfo.nativeLibraryDir + File.separator + DEFAULT_LIBRARY);
if (args != null) {
Collections.addAll(shellArgs, args);
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册