summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorerg <erg@chromium.org>2015-11-12 10:51:56 -0800
committerCommit bot <commit-bot@chromium.org>2015-11-12 18:53:20 +0000
commit140735acbef15c56d9ddaadd2bc58b5e26692a48 (patch)
tree2626c072f5b40f065fd0a2e6f394220f1122d578
parent203833423f5a1febbdb90bdd8166a8335521e3e4 (diff)
downloadchromium_src-140735acbef15c56d9ddaadd2bc58b5e26692a48.zip
chromium_src-140735acbef15c56d9ddaadd2bc58b5e26692a48.tar.gz
chromium_src-140735acbef15c56d9ddaadd2bc58b5e26692a48.tar.bz2
mandoline: Reland "Fix ICU initialization".
We need to complete the initialization of ICU before we raise the sandbox. That means we can't pass a file descriptor to the ICU data file across mojo pipes. Due to how Android handles resources files, we also can't pass a file descriptor around inside the same process. So pass a raw pointer to a memory mapped file during the sandbox warm-up phase, and make a new option to initialize ICU from this raw pointer. But that just uncovers a bigger issue: we don't always call what was the sandbox warming code. If it's general initialization that needs to be called before we run MojoMain(), we need to include initialization code in most all main.cc implementations. This bakes a base initialize call into the mojo application library. This fixes a crash in the page cycler set, which happens when a page tries to do date operations, which fail because of missing locale data. This fixes several crashes in local runs. [[This reland disables the sandbox on the page cycler bots because they don't have a new enough kernel to be sandboxed(!). It also includes the icu data in the mojo runner unittests.]] BUG=546644 First Review URL: https://codereview.chromium.org/1425853003 TBR=jam@chromium.org,sky@chromium.org R=yzshen@chromium.org Review URL: https://codereview.chromium.org/1431133003 Cr-Commit-Position: refs/heads/master@{#359349}
-rw-r--r--base/i18n/icu_util.cc24
-rw-r--r--base/i18n/icu_util.h25
-rw-r--r--components/html_viewer/BUILD.gn2
-rw-r--r--components/html_viewer/global_state.cc10
-rw-r--r--components/html_viewer/html_viewer_main.cc26
-rw-r--r--components/resource_provider/BUILD.gn6
-rw-r--r--components/resource_provider/public/cpp/resource_loader.cc13
-rw-r--r--components/resource_provider/public/cpp/resource_loader.h3
-rw-r--r--components/resource_provider/public/interfaces/resource_provider.mojom3
-rw-r--r--components/resource_provider/resource_provider_impl.cc10
-rw-r--r--components/resource_provider/resource_provider_impl.h1
-rw-r--r--mandoline/app/desktop/launcher_process.cc2
-rw-r--r--mandoline/services/core_services/BUILD.gn5
-rw-r--r--mandoline/services/core_services/main.cc26
-rw-r--r--mojo/application/public/cpp/BUILD.gn2
-rw-r--r--mojo/application/public/cpp/initialize_base_and_icu.cc43
-rw-r--r--mojo/runner/BUILD.gn6
-rw-r--r--mojo/runner/context.cc5
-rw-r--r--mojo/runner/host/BUILD.gn1
-rw-r--r--mojo/runner/host/child_process.cc15
-rw-r--r--mojo/runner/host/in_process_native_runner.cc2
-rw-r--r--mojo/runner/init.cc19
-rw-r--r--mojo/runner/init.h6
-rw-r--r--tools/telemetry/telemetry/internal/backends/mandoline/mandoline_browser_backend.py4
-rw-r--r--ui/views/mus/aura_init.cc4
25 files changed, 143 insertions, 120 deletions
diff --git a/base/i18n/icu_util.cc b/base/i18n/icu_util.cc
index 1dd54cd..e3afc04 100644
--- a/base/i18n/icu_util.cc
+++ b/base/i18n/icu_util.cc
@@ -143,6 +143,7 @@ bool InitializeICUWithFileDescriptorInternal(
return true;
}
if (data_fd == kInvalidPlatformFile) {
+ LOG(ERROR) << "Invalid file descriptor to ICU data received.";
return false;
}
@@ -164,6 +165,7 @@ bool InitializeICUWithFileDescriptorInternal(
#if !defined(OS_NACL)
#if ICU_UTIL_DATA_IMPL == ICU_UTIL_DATA_FILE
+#if defined(OS_ANDROID)
bool InitializeICUWithFileDescriptor(
PlatformFile data_fd,
const MemoryMappedFile::Region& data_region) {
@@ -179,6 +181,28 @@ PlatformFile GetIcuDataFileHandle(MemoryMappedFile::Region* out_region) {
*out_region = g_icudtl_region;
return g_icudtl_pf;
}
+#endif
+
+const uint8* GetRawIcuMemory() {
+ CHECK(g_icudtl_mapped_file);
+ return g_icudtl_mapped_file->data();
+}
+
+bool InitializeICUFromRawMemory(const uint8* raw_memory) {
+#if !defined(COMPONENT_BUILD)
+#if !defined(NDEBUG)
+ DCHECK(!g_check_called_once || !g_called_once);
+ g_called_once = true;
+#endif
+
+ UErrorCode err = U_ZERO_ERROR;
+ udata_setCommonData(const_cast<uint8*>(raw_memory), &err);
+ return err == U_ZERO_ERROR;
+#else
+ return true;
+#endif
+}
+
#endif // ICU_UTIL_DATA_IMPL == ICU_UTIL_DATA_FILE
bool InitializeICU() {
diff --git a/base/i18n/icu_util.h b/base/i18n/icu_util.h
index d62f8bac..ec24426 100644
--- a/base/i18n/icu_util.h
+++ b/base/i18n/icu_util.h
@@ -18,16 +18,37 @@ namespace i18n {
BASE_I18N_EXPORT bool InitializeICU();
#if ICU_UTIL_DATA_IMPL == ICU_UTIL_DATA_FILE
+#if defined(OS_ANDROID)
// Returns the PlatformFile and Region that was initialized by InitializeICU().
// Use with InitializeICUWithFileDescriptor().
BASE_I18N_EXPORT PlatformFile GetIcuDataFileHandle(
MemoryMappedFile::Region* out_region);
-// Android and html_viewer use a file descriptor passed by browser process to
-// initialize ICU in render processes.
+// Android uses a file descriptor passed by browser process to initialize ICU
+// in render processes.
BASE_I18N_EXPORT bool InitializeICUWithFileDescriptor(
PlatformFile data_fd,
const MemoryMappedFile::Region& data_region);
+#endif
+
+// Returns a void pointer to the memory mapped ICU data file.
+//
+// There are cases on Android where we would be unsafely reusing a file
+// descriptor within the same process when initializing two copies of ICU from
+// different binaries in the same address space. This returns an unowned
+// pointer to the memory mapped icu data file; consumers copies of base must
+// not outlive the copy of base that owns the memory mapped file.
+BASE_I18N_EXPORT const uint8* GetRawIcuMemory();
+
+// Initializes ICU memory
+//
+// This does nothing in component builds; this initialization should only be
+// done in cases where there could be two copies of base in a single process in
+// non-component builds. (The big example is mojo: the shell will have a copy
+// of base linked in, and the majority of mojo applications will have base
+// linked in but in non-component builds, these will be separate copies of
+// base.)
+BASE_I18N_EXPORT bool InitializeICUFromRawMemory(const uint8* raw_memory);
#endif // ICU_UTIL_DATA_IMPL == ICU_UTIL_DATA_FILE
#endif // !defined(OS_NACL)
diff --git a/components/html_viewer/BUILD.gn b/components/html_viewer/BUILD.gn
index dc5b228..876a79d 100644
--- a/components/html_viewer/BUILD.gn
+++ b/components/html_viewer/BUILD.gn
@@ -298,12 +298,10 @@ if (is_android) {
deps = [
":pak",
"//gin",
- "//third_party/icu:icudata",
]
dest = html_viewer_unittests_assets
sources = [
"$root_build_dir/html_viewer.pak",
- "$root_build_dir/icudtl.dat",
]
renaming_sources = v8_external_startup_data_renaming_sources
renaming_destinations = v8_external_startup_data_renaming_destinations
diff --git a/components/html_viewer/global_state.cc b/components/html_viewer/global_state.cc
index a0bb8be..9d7f46b 100644
--- a/components/html_viewer/global_state.cc
+++ b/components/html_viewer/global_state.cc
@@ -8,7 +8,6 @@
#include "base/bind.h"
#include "base/command_line.h"
-#include "base/i18n/icu_util.h"
#include "base/logging.h"
#include "components/html_viewer/blink_platform_impl.h"
#include "components/html_viewer/blink_settings_impl.h"
@@ -146,15 +145,12 @@ void GlobalState::InitIfNecessary(const gfx::Size& screen_size_in_pixels,
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
base::File pak_file = resource_loader_.ReleaseFile(kResourceResourcesPak);
- bool initialize_icu_and_ui = true;
+ bool initialize_ui = true;
#if defined(COMPONENT_BUILD)
if (command_line->HasSwitch("single-process"))
- initialize_icu_and_ui = false;
+ initialize_ui = false;
#endif
- if (initialize_icu_and_ui) {
- base::i18n::InitializeICUWithFileDescriptor(
- resource_loader_.GetICUFile().TakePlatformFile(),
- base::MemoryMappedFile::Region::kWholeFile);
+ if (initialize_ui) {
ui::RegisterPathProvider();
base::File pak_file_2 = pak_file.Duplicate();
ui::ResourceBundle::InitSharedInstanceWithPakFileRegion(
diff --git a/components/html_viewer/html_viewer_main.cc b/components/html_viewer/html_viewer_main.cc
index 79349639..9afd58d 100644
--- a/components/html_viewer/html_viewer_main.cc
+++ b/components/html_viewer/html_viewer_main.cc
@@ -6,32 +6,6 @@
#include "mojo/application/public/cpp/application_runner.h"
#include "third_party/mojo/src/mojo/public/c/system/main.h"
-// TODO(erg): Much of this will be the same between mojo applications. Maybe we
-// could centralize this code?
-#if defined(OS_LINUX) && !defined(OS_ANDROID)
-#include "base/rand_util.h"
-#include "base/sys_info.h"
-#include "third_party/icu/source/i18n/unicode/timezone.h"
-
-// TODO(erg): Much of this was coppied from zygote_main_linux.cc
-extern "C" {
-void __attribute__((visibility("default"))) MojoSandboxWarm() {
- base::RandUint64();
- base::SysInfo::AmountOfPhysicalMemory();
- base::SysInfo::MaxSharedMemorySize();
- base::SysInfo::NumberOfProcessors();
-
- // ICU DateFormat class (used in base/time_format.cc) needs to get the
- // Olson timezone ID by accessing the zoneinfo files on disk. After
- // TimeZone::createDefault is called once here, the timezone ID is
- // cached and there's no more need to access the file system.
- scoped_ptr<icu::TimeZone> zone(icu::TimeZone::createDefault());
-
- // TODO(erg): Perform OpenSSL warmup; it wants access to /dev/urandom.
-}
-}
-#endif // defined(OS_LINUX) && !defined(OS_ANDROID)
-
MojoResult MojoMain(MojoHandle shell_handle) {
mojo::ApplicationRunner runner(new html_viewer::HTMLViewer);
return runner.Run(shell_handle);
diff --git a/components/resource_provider/BUILD.gn b/components/resource_provider/BUILD.gn
index 5d26584..9a9ecb0 100644
--- a/components/resource_provider/BUILD.gn
+++ b/components/resource_provider/BUILD.gn
@@ -17,10 +17,7 @@ if (is_android) {
deps = [
":java_library",
":resource_provider_lib",
- "//third_party/icu:icudata",
]
-
- resources = [ "$root_out_dir/icudtl.dat" ]
}
shared_library("resource_provider_lib") {
@@ -75,11 +72,8 @@ if (is_android) {
"//base",
"//components/resource_provider/public/interfaces",
"//mojo/environment:chromium",
- "//third_party/icu:icudata",
"//url",
]
-
- resources = [ "$root_out_dir/icudtl.dat" ]
}
}
diff --git a/components/resource_provider/public/cpp/resource_loader.cc b/components/resource_provider/public/cpp/resource_loader.cc
index 8b1c116..5dd763f 100644
--- a/components/resource_provider/public/cpp/resource_loader.cc
+++ b/components/resource_provider/public/cpp/resource_loader.cc
@@ -56,15 +56,6 @@ base::File ResourceLoader::ReleaseFile(const std::string& path) {
return file_wrapper->Pass();
}
-base::File ResourceLoader::GetICUFile() {
- base::File rv;
- resource_provider_->GetICUHandle(
- base::Bind(&ResourceLoader::OnGotICU, base::Unretained(this), &rv));
- resource_provider_.WaitForIncomingResponse();
- CHECK(rv.IsValid());
- return rv.Pass();
-}
-
void ResourceLoader::OnGotResources(const std::vector<std::string>& paths,
mojo::Array<mojo::ScopedHandle> resources) {
@@ -77,8 +68,4 @@ void ResourceLoader::OnGotResources(const std::vector<std::string>& paths,
loaded_ = true;
}
-void ResourceLoader::OnGotICU(base::File* file, mojo::ScopedHandle handle) {
- *file = GetFileFromHandle(handle.Pass());
-}
-
} // namespace resource_provider
diff --git a/components/resource_provider/public/cpp/resource_loader.h b/components/resource_provider/public/cpp/resource_loader.h
index 2b055aa..69b5094 100644
--- a/components/resource_provider/public/cpp/resource_loader.h
+++ b/components/resource_provider/public/cpp/resource_loader.h
@@ -46,8 +46,6 @@ class ResourceLoader {
// Releases and returns the file wrapping the handle.
base::File ReleaseFile(const std::string& path);
- base::File GetICUFile();
-
bool loaded() const { return loaded_; }
private:
@@ -56,7 +54,6 @@ class ResourceLoader {
// Callback when resources have loaded.
void OnGotResources(const std::vector<std::string>& paths,
mojo::Array<mojo::ScopedHandle> resources);
- void OnGotICU(base::File* file, mojo::ScopedHandle handle);
ResourceProviderPtr resource_provider_;
diff --git a/components/resource_provider/public/interfaces/resource_provider.mojom b/components/resource_provider/public/interfaces/resource_provider.mojom
index 01c6b99..15af0d1 100644
--- a/components/resource_provider/public/interfaces/resource_provider.mojom
+++ b/components/resource_provider/public/interfaces/resource_provider.mojom
@@ -15,7 +15,4 @@ interface ResourceProvider {
// The result is an array of platform handles for each of the requested paths.
// TODO(sky): this should really be map<string,handle>, but that doesn't work.
GetResources(array<string> paths) => (array<handle> resource_handles);
-
- // Fetch a handle to the shared version of ICU table.
- GetICUHandle() => (handle resource_handle);
};
diff --git a/components/resource_provider/resource_provider_impl.cc b/components/resource_provider/resource_provider_impl.cc
index 3f14e76..628c16a 100644
--- a/components/resource_provider/resource_provider_impl.cc
+++ b/components/resource_provider/resource_provider_impl.cc
@@ -17,8 +17,6 @@ using mojo::ScopedHandle;
namespace resource_provider {
namespace {
-const char kResourceIcudtl[] = "icudtl.dat";
-
ScopedHandle GetHandleForPath(const base::FilePath& path) {
if (path.empty())
return ScopedHandle();
@@ -68,12 +66,4 @@ void ResourceProviderImpl::GetResources(mojo::Array<mojo::String> paths,
callback.Run(handles.Pass());
}
-void ResourceProviderImpl::GetICUHandle(const GetICUHandleCallback& callback) {
- const base::FilePath resource_app_path(
- GetPathForApplicationUrl(resource_provider_app_url_));
- mojo::ScopedHandle handle = GetHandleForPath(
- GetPathForResourceNamed(resource_app_path, kResourceIcudtl));
- callback.Run(handle.Pass());
-}
-
} // namespace resource_provider
diff --git a/components/resource_provider/resource_provider_impl.h b/components/resource_provider/resource_provider_impl.h
index b805cf7..8884a5b 100644
--- a/components/resource_provider/resource_provider_impl.h
+++ b/components/resource_provider/resource_provider_impl.h
@@ -21,7 +21,6 @@ class ResourceProviderImpl : public resource_provider::ResourceProvider {
// ResourceProvider:
void GetResources(mojo::Array<mojo::String> paths,
const GetResourcesCallback& callback) override;
- void GetICUHandle(const GetICUHandleCallback& callback) override;
const base::FilePath application_path_;
const std::string resource_provider_app_url_;
diff --git a/mandoline/app/desktop/launcher_process.cc b/mandoline/app/desktop/launcher_process.cc
index 5a94a32..60f5e32 100644
--- a/mandoline/app/desktop/launcher_process.cc
+++ b/mandoline/app/desktop/launcher_process.cc
@@ -32,8 +32,6 @@ int LauncherProcessMain(int argc, char** argv) {
if (!command_line->HasSwitch(switches::kMojoSingleProcess))
command_line->AppendSwitch(switches::kEnableMultiprocess);
command_line->AppendSwitch("use-new-edk");
- // http://crbug.com/546644
- command_line->AppendSwitch(switches::kMojoNoSandbox);
bool trace_startup = command_line->HasSwitch(switches::kTraceStartup);
if (trace_startup) {
diff --git a/mandoline/services/core_services/BUILD.gn b/mandoline/services/core_services/BUILD.gn
index f3b6ed7..8e093f8 100644
--- a/mandoline/services/core_services/BUILD.gn
+++ b/mandoline/services/core_services/BUILD.gn
@@ -27,11 +27,6 @@ mojo_native_application("core_services") {
}
deps += [ ":copy_files" ]
}
-
- if (!is_android) {
- deps += [ "//third_party/icu:icudata" ]
- resources = [ "$root_out_dir/icudtl.dat" ]
- }
}
source_set("sources") {
diff --git a/mandoline/services/core_services/main.cc b/mandoline/services/core_services/main.cc
index e9d36ba..ef8c847 100644
--- a/mandoline/services/core_services/main.cc
+++ b/mandoline/services/core_services/main.cc
@@ -6,32 +6,6 @@
#include "mojo/application/public/cpp/application_runner.h"
#include "third_party/mojo/src/mojo/public/c/system/main.h"
-// TODO(erg): Much of this will be the same between mojo applications. Maybe we
-// could centralize this code?
-#if defined(OS_LINUX) && !defined(OS_ANDROID)
-#include "base/rand_util.h"
-#include "base/sys_info.h"
-#include "third_party/icu/source/i18n/unicode/timezone.h"
-
-// TODO(erg): Much of this was coppied from zygote_main_linux.cc
-extern "C" {
-void __attribute__((visibility("default"))) MojoSandboxWarm() {
- base::RandUint64();
- base::SysInfo::AmountOfPhysicalMemory();
- base::SysInfo::MaxSharedMemorySize();
- base::SysInfo::NumberOfProcessors();
-
- // ICU DateFormat class (used in base/time_format.cc) needs to get the
- // Olson timezone ID by accessing the zoneinfo files on disk. After
- // TimeZone::createDefault is called once here, the timezone ID is
- // cached and there's no more need to access the file system.
- scoped_ptr<icu::TimeZone> zone(icu::TimeZone::createDefault());
-
- // TODO(erg): Perform OpenSSL warmup; it wants access to /dev/urandom.
-}
-}
-#endif // defined(OS_LINUX) && !defined(OS_ANDROID)
-
MojoResult MojoMain(MojoHandle shell_handle) {
mojo::ApplicationRunner runner(
new core_services::CoreServicesApplicationDelegate);
diff --git a/mojo/application/public/cpp/BUILD.gn b/mojo/application/public/cpp/BUILD.gn
index 12b0e51..578463f 100644
--- a/mojo/application/public/cpp/BUILD.gn
+++ b/mojo/application/public/cpp/BUILD.gn
@@ -26,6 +26,7 @@ source_set("sources") {
"application_impl.h",
"application_runner.h",
"connect.h",
+ "initialize_base_and_icu.cc",
"interface_factory.h",
"interface_factory_impl.h",
"lib/app_lifetime_helper.cc",
@@ -44,6 +45,7 @@ source_set("sources") {
deps = [
"//base",
+ "//base:i18n",
"//mojo/application/public/interfaces",
"//mojo/common",
"//mojo/environment:chromium",
diff --git a/mojo/application/public/cpp/initialize_base_and_icu.cc b/mojo/application/public/cpp/initialize_base_and_icu.cc
new file mode 100644
index 0000000..4635d49
--- /dev/null
+++ b/mojo/application/public/cpp/initialize_base_and_icu.cc
@@ -0,0 +1,43 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// This file declares a raw symbol and should be included only once in a
+// certain binary target. This needs to be run before we raise the sandbox,
+// which means that it can't use mojo. Our runners will dig around in the
+// symbol table and run this before the mojo system is initialized.
+
+#include "base/files/file.h"
+#include "base/i18n/icu_util.h"
+#include "base/rand_util.h"
+#include "base/sys_info.h"
+#include "third_party/icu/source/i18n/unicode/timezone.h"
+#include "third_party/mojo/src/mojo/public/c/system/types.h"
+
+extern "C" {
+#if defined(WIN32)
+__declspec(dllexport) void __cdecl
+#else
+void __attribute__((visibility("default")))
+#endif
+InitializeBase(const uint8* icu_data) {
+ base::RandUint64();
+ base::SysInfo::AmountOfPhysicalMemory();
+ base::SysInfo::NumberOfProcessors();
+#if defined(OS_POSIX) && !defined(OS_MACOSX)
+ base::SysInfo::MaxSharedMemorySize();
+#endif
+
+ // Initialize core ICU. We must perform the full initialization before we
+ // initialize icu::TimeZone subsystem because otherwise ICU gets in a state
+ // where the timezone data is disconnected from the locale data which can
+ // cause crashes.
+ CHECK(base::i18n::InitializeICUFromRawMemory(icu_data));
+
+ // ICU DateFormat class (used in base/time_format.cc) needs to get the
+ // Olson timezone ID by accessing the zoneinfo files on disk. After
+ // TimeZone::createDefault is called once here, the timezone ID is
+ // cached and there's no more need to access the file system.
+ scoped_ptr<icu::TimeZone> zone(icu::TimeZone::createDefault());
+}
+}
diff --git a/mojo/runner/BUILD.gn b/mojo/runner/BUILD.gn
index 803b4ff..84bc12b 100644
--- a/mojo/runner/BUILD.gn
+++ b/mojo/runner/BUILD.gn
@@ -52,7 +52,7 @@ source_set("mojo_runner_lib") {
]
deps += [
"//components/tracing:startup_tracing",
- "//mojo/shell",
+ "//third_party/icu:icudata",
]
} else {
sources += [
@@ -106,6 +106,7 @@ source_set("init") {
deps = [
"//mojo/runner/host:switches",
"//base",
+ "//base:i18n",
]
}
@@ -147,6 +148,7 @@ source_set("lib") {
public_deps = [
":init",
":switches",
+ "//mojo/shell",
]
if (!is_component_build) {
@@ -327,10 +329,12 @@ if (is_android) {
deps = [
"//mojo/services/test_service:test_app",
"//mojo/services/test_service:test_request_tracker_app",
+ "//third_party/icu:icudata",
]
# Directories can't be specified as sources so pass manually to the script.
args = [
+ "--files=" + rebase_path("$root_out_dir/icudtl.dat", root_build_dir),
"--files=" + rebase_path("$root_out_dir/test_app", root_build_dir),
"--files=" +
rebase_path("$root_out_dir/test_request_tracker_app", root_build_dir),
diff --git a/mojo/runner/context.cc b/mojo/runner/context.cc
index eeba581..850cb5a 100644
--- a/mojo/runner/context.cc
+++ b/mojo/runner/context.cc
@@ -9,6 +9,7 @@
#include "base/bind.h"
#include "base/command_line.h"
#include "base/files/file_path.h"
+#include "base/i18n/icu_util.h"
#include "base/lazy_instance.h"
#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
@@ -198,6 +199,10 @@ bool Context::Init(const base::FilePath& shell_file_root) {
"mojo_runner.trace");
}
+ // ICU data is a thing every part of the system needs. This here warms
+ // up the copy of ICU in the mojo runner.
+ CHECK(base::i18n::InitializeICU());
+
EnsureEmbedderIsInitialized();
task_runners_.reset(
new TaskRunners(base::MessageLoop::current()->task_runner()));
diff --git a/mojo/runner/host/BUILD.gn b/mojo/runner/host/BUILD.gn
index b534287..4227baa 100644
--- a/mojo/runner/host/BUILD.gn
+++ b/mojo/runner/host/BUILD.gn
@@ -62,6 +62,7 @@ source_set("lib") {
":switches",
"//base",
"//base:base_static",
+ "//base:i18n",
"//mojo/gles2",
"//mojo/message_pump",
"//mojo/platform_handle:platform_handle_impl",
diff --git a/mojo/runner/host/child_process.cc b/mojo/runner/host/child_process.cc
index d90358f..fac23ec 100644
--- a/mojo/runner/host/child_process.cc
+++ b/mojo/runner/host/child_process.cc
@@ -9,6 +9,7 @@
#include "base/callback_helpers.h"
#include "base/command_line.h"
#include "base/files/file_path.h"
+#include "base/i18n/icu_util.h"
#include "base/location.h"
#include "base/logging.h"
#include "base/macros.h"
@@ -24,6 +25,7 @@
#include "mojo/runner/child/child_controller.mojom.h"
#include "mojo/runner/host/native_application_support.h"
#include "mojo/runner/host/switches.h"
+#include "mojo/runner/init.h"
#include "third_party/mojo/src/mojo/edk/embedder/embedder.h"
#include "third_party/mojo/src/mojo/edk/embedder/platform_channel_pair.h"
#include "third_party/mojo/src/mojo/edk/embedder/process_delegate.h"
@@ -293,22 +295,17 @@ int ChildProcessMain() {
app_library = mojo::runner::LoadNativeApplication(
command_line.GetSwitchValuePath(switches::kChildProcess));
+ base::i18n::InitializeICU();
+ CallLibraryEarlyInitialization(app_library);
+
#if defined(OS_LINUX) && !defined(OS_ANDROID)
if (command_line.HasSwitch(switches::kEnableSandbox)) {
- // Warm parts of base.
+ // Warm parts of base in the copy of base in the mojo runner.
base::RandUint64();
base::SysInfo::AmountOfPhysicalMemory();
base::SysInfo::MaxSharedMemorySize();
base::SysInfo::NumberOfProcessors();
- // Do whatever warming that the mojo application wants.
- typedef void (*SandboxWarmFunction)();
- SandboxWarmFunction sandbox_warm = reinterpret_cast<SandboxWarmFunction>(
- base::GetFunctionPointerFromNativeLibrary(app_library,
- "MojoSandboxWarm"));
- if (sandbox_warm)
- sandbox_warm();
-
// TODO(erg,jln): Allowing access to all of /dev/shm/ makes it easy to
// spy on other shared memory using processes. This is a temporary hack
// so that we have some sandbox until we have proper shared memory
diff --git a/mojo/runner/host/in_process_native_runner.cc b/mojo/runner/host/in_process_native_runner.cc
index 19cc88c..ee5e9e3 100644
--- a/mojo/runner/host/in_process_native_runner.cc
+++ b/mojo/runner/host/in_process_native_runner.cc
@@ -12,6 +12,7 @@
#include "base/threading/platform_thread.h"
#include "mojo/runner/host/native_application_support.h"
#include "mojo/runner/host/out_of_process_native_runner.h"
+#include "mojo/runner/init.h"
namespace mojo {
namespace runner {
@@ -57,6 +58,7 @@ void InProcessNativeRunner::Run() {
// TODO(vtl): ScopedNativeLibrary doesn't have a .get() method!
base::NativeLibrary app_library = LoadNativeApplication(app_path_);
app_library_.Reset(app_library);
+ CallLibraryEarlyInitialization(app_library);
RunNativeApplication(app_library, application_request_.Pass());
app_completed_callback_runner_.Run();
app_completed_callback_runner_.Reset();
diff --git a/mojo/runner/init.cc b/mojo/runner/init.cc
index a5cc9e1..b76dfc6 100644
--- a/mojo/runner/init.cc
+++ b/mojo/runner/init.cc
@@ -8,6 +8,7 @@
#include "base/command_line.h"
#include "base/debug/debugger.h"
#include "base/files/file_path.h"
+#include "base/i18n/icu_util.h"
#include "base/logging.h"
#include "base/stl_util.h"
#include "base/strings/string_split.h"
@@ -60,5 +61,23 @@ void WaitForDebuggerIfNecessary() {
}
}
+void CallLibraryEarlyInitialization(base::NativeLibrary app_library) {
+ // Do whatever warming that the mojo application wants.
+ typedef void (*LibraryEarlyInitFunction)(const uint8*);
+ LibraryEarlyInitFunction init_function =
+ reinterpret_cast<LibraryEarlyInitFunction>(
+ base::GetFunctionPointerFromNativeLibrary(app_library,
+ "InitializeBase"));
+ if (init_function) {
+ // Get the ICU data that we prewarmed in the runner and then pass it to
+ // the copy of icu in the mojo binary that we're running.
+ const uint8* icu_data = base::i18n::GetRawIcuMemory();
+ init_function(icu_data);
+ }
+
+ // TODO(erg): All chromium binaries load base. We might want to make a
+ // general system for other people.
+}
+
} // namespace runner
} // namespace mojo
diff --git a/mojo/runner/init.h b/mojo/runner/init.h
index c4e8abd..879886c 100644
--- a/mojo/runner/init.h
+++ b/mojo/runner/init.h
@@ -5,6 +5,8 @@
#ifndef MOJO_RUNNER_INIT_H_
#define MOJO_RUNNER_INIT_H_
+#include "base/native_library.h"
+
namespace mojo {
namespace runner {
@@ -13,6 +15,10 @@ void InitializeLogging();
void WaitForDebuggerIfNecessary();
+// Calls "LibraryEarlyInitialization" in |app_library| if it exists. We do
+// common initialization there now.
+void CallLibraryEarlyInitialization(base::NativeLibrary app_library);
+
} // namespace runner
} // namespace mojo
diff --git a/tools/telemetry/telemetry/internal/backends/mandoline/mandoline_browser_backend.py b/tools/telemetry/telemetry/internal/backends/mandoline/mandoline_browser_backend.py
index 99971ad..5f1fa76 100644
--- a/tools/telemetry/telemetry/internal/backends/mandoline/mandoline_browser_backend.py
+++ b/tools/telemetry/telemetry/internal/backends/mandoline/mandoline_browser_backend.py
@@ -50,6 +50,10 @@ class MandolineBrowserBackend(browser_backend.BrowserBackend):
args = []
args.extend(self.browser_options.extra_browser_args)
args.extend(self.GetReplayBrowserStartupArgs())
+ # Currently the bots that run mojo perf tests use such an old kernel that
+ # it doesn't support the namespace sandboxing primitives. Disable it until
+ # infra fixes it.
+ args.extend('--no-sandbox')
return args
def _UseHostResolverRules(self):
diff --git a/ui/views/mus/aura_init.cc b/ui/views/mus/aura_init.cc
index 653c9c3..e3e4d80 100644
--- a/ui/views/mus/aura_init.cc
+++ b/ui/views/mus/aura_init.cc
@@ -4,7 +4,6 @@
#include "ui/views/mus/aura_init.h"
-#include "base/i18n/icu_util.h"
#include "base/lazy_instance.h"
#include "base/path_service.h"
#include "components/resource_provider/public/cpp/resource_loader.h"
@@ -77,9 +76,6 @@ void AuraInit::InitializeResources(mojo::ApplicationImpl* app) {
if (!resource_loader.BlockUntilLoaded())
return;
CHECK(resource_loader.loaded());
- base::i18n::InitializeICUWithFileDescriptor(
- resource_loader.GetICUFile().TakePlatformFile(),
- base::MemoryMappedFile::Region::kWholeFile);
ui::RegisterPathProvider();
base::File pak_file = resource_loader.ReleaseFile(resource_file_);
base::File pak_file_2 = pak_file.Duplicate();