Load resources.pak earlier in content_main_runner

Reland "Load resources.pak earlier in service manager main"

This is a reland of 13dfb3270d72c4b826e4f03b8178b22dd81a158f

Original change's description:
> Load resources.pak earlier in service manager main
>
> We need to use the content in resources.pak in service manager, but at
> that time resource bundle has not been initialized. Create data pack to
> load resources.pak and append the data pack to resource bundle during the
> initialization.
>
> Move path FILE_RESOURCES_PACK from chrome_paths.h to ui_base_paths.cc.
>
> Bug: 729596, 815230
> Change-Id: Iec3a9409cbd9c10775afb72944e66e26650f1181
> Reviewed-on: https://chromium-review.googlesource.com/962679
> Reviewed-by: Yaron Friedman <yfriedman@chromium.org>
> Reviewed-by: Ken Rockot <rockot@chromium.org>
> Reviewed-by: Scott Violet <sky@chromium.org>
> Reviewed-by: Xi Han <hanxi@chromium.org>
> Commit-Queue: Ran Ji <ranj@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#554500}

Bug: 729596, 815230
Change-Id: Id963d1e64c70a22a29e94d8186ea0d4bcb1455fd

TBR=sky@chromium.org, yfriedman@chromium.org, rockot@chromium.org

Change-Id: Id963d1e64c70a22a29e94d8186ea0d4bcb1455fd
Reviewed-on: https://chromium-review.googlesource.com/1034133
Commit-Queue: Xi Han <hanxi@chromium.org>
Reviewed-by: Xi Han <hanxi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#555443}
diff --git a/chrome/app/chrome_main_delegate.cc b/chrome/app/chrome_main_delegate.cc
index 72edb9c..8f08d3ff 100644
--- a/chrome/app/chrome_main_delegate.cc
+++ b/chrome/app/chrome_main_delegate.cc
@@ -11,6 +11,7 @@
 #include "base/command_line.h"
 #include "base/cpu.h"
 #include "base/files/file_path.h"
+#include "base/files/file_util.h"
 #include "base/i18n/rtl.h"
 #include "base/lazy_instance.h"
 #include "base/macros.h"
@@ -113,6 +114,7 @@
 #include "base/android/java_exception_reporter.h"
 #include "chrome/browser/android/crash/pure_java_exception_handler.h"
 #include "chrome/common/descriptors_android.h"
+#include "ui/base/resource/resource_bundle_android.h"
 #else
 // Diagnostics is only available on non-android platforms.
 #include "chrome/browser/diagnostics/diagnostics_controller.h"
@@ -164,11 +166,6 @@
     g_chrome_content_utility_client = LAZY_INSTANCE_INITIALIZER;
 #endif
 
-#if !defined(CHROME_MULTIPLE_DLL_CHILD)
-base::LazyInstance<ChromeContentBrowserClient>::DestructorAtExit
-    g_chrome_content_browser_client = LAZY_INSTANCE_INITIALIZER;
-#endif
-
 #if defined(OS_POSIX)
 base::LazyInstance<ChromeCrashReporterClient>::Leaky g_chrome_crash_client =
     LAZY_INSTANCE_INITIALIZER;
@@ -1054,7 +1051,13 @@
 #if defined(CHROME_MULTIPLE_DLL_CHILD)
   return NULL;
 #else
-  return g_chrome_content_browser_client.Pointer();
+  if (chrome_content_browser_client_ == nullptr) {
+    DCHECK(service_manifest_data_pack_);
+    chrome_content_browser_client_ =
+        std::make_unique<ChromeContentBrowserClient>(
+            std::move(service_manifest_data_pack_));
+  }
+  return chrome_content_browser_client_.get();
 #endif
 }
 
@@ -1084,6 +1087,33 @@
 #endif
 }
 
+ui::DataPack* ChromeMainDelegate::LoadServiceManifestDataPack() {
+  DCHECK(!service_manifest_data_pack_ && !chrome_content_browser_client_);
+  const base::CommandLine& command_line =
+      *base::CommandLine::ForCurrentProcess();
+  std::string process_type =
+      command_line.GetSwitchValueASCII(switches::kProcessType);
+  DCHECK(process_type.empty());
+
+#if defined(OS_MACOSX)
+  SetUpBundleOverrides();
+#endif
+
+  base::FilePath resources_pack_path;
+  PathService::Get(chrome::FILE_RESOURCES_PACK, &resources_pack_path);
+
+#if defined(OS_ANDROID)
+  service_manifest_data_pack_ =
+      ui::GetDataPackFromPackFile("assets/resources.pak", resources_pack_path);
+#else
+  if (base::PathExists(resources_pack_path)) {
+    service_manifest_data_pack_.reset(new ui::DataPack(ui::SCALE_FACTOR_NONE));
+    service_manifest_data_pack_->LoadFromPath(resources_pack_path);
+  }
+#endif  // defined(OS_ANDROID)
+  return service_manifest_data_pack_.get();
+}
+
 bool ChromeMainDelegate::ShouldEnableProfilerRecording() {
   switch (chrome::GetChannel()) {
     case version_info::Channel::UNKNOWN:
diff --git a/chrome/app/chrome_main_delegate.h b/chrome/app/chrome_main_delegate.h
index b957cf7..1105b5fe 100644
--- a/chrome/app/chrome_main_delegate.h
+++ b/chrome/app/chrome_main_delegate.h
@@ -13,11 +13,14 @@
 #include "build/build_config.h"
 #include "chrome/common/chrome_content_client.h"
 #include "content/public/app/content_main_delegate.h"
+#include "ui/base/resource/data_pack.h"
 
 namespace base {
 class CommandLine;
 }
 
+class ChromeContentBrowserClient;
+
 // Chrome implementation of ContentMainDelegate.
 class ChromeMainDelegate : public content::ContentMainDelegate {
  public:
@@ -57,6 +60,7 @@
   content::ContentGpuClient* CreateContentGpuClient() override;
   content::ContentRendererClient* CreateContentRendererClient() override;
   content::ContentUtilityClient* CreateContentUtilityClient() override;
+  ui::DataPack* LoadServiceManifestDataPack() override;
 
 #if defined(OS_MACOSX)
   void InitMacCrashReporter(const base::CommandLine& command_line,
@@ -66,6 +70,12 @@
 
   ChromeContentClient chrome_content_client_;
 
+  std::unique_ptr<ChromeContentBrowserClient> chrome_content_browser_client_;
+
+  // This field is loaded by LoadServiceManifestDataPack() and passed to
+  // ContentBrowserClient in CreateContentBrowserClient()
+  std::unique_ptr<ui::DataPack> service_manifest_data_pack_;
+
   DISALLOW_COPY_AND_ASSIGN(ChromeMainDelegate);
 };
 
diff --git a/chrome/browser/chrome_browser_main.cc b/chrome/browser/chrome_browser_main.cc
index e95ac3b..c5fe52b6 100644
--- a/chrome/browser/chrome_browser_main.cc
+++ b/chrome/browser/chrome_browser_main.cc
@@ -187,6 +187,7 @@
 #include "net/url_request/url_request.h"
 #include "printing/buildflags/buildflags.h"
 #include "rlz/buildflags/buildflags.h"
+#include "services/service_manager/embedder/main_delegate.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/layout.h"
 #include "ui/base/material_design/material_design_controller.h"
@@ -675,7 +676,8 @@
 // Initializes the shared instance of ResourceBundle and returns the locale. An
 // empty string return value indicates failure.
 std::string InitResourceBundleAndDetermineLocale(
-    const content::MainFunctionParams& params) {
+    const content::MainFunctionParams& params,
+    std::unique_ptr<ui::DataPack> data_pack) {
 #if defined(OS_MACOSX)
   // TODO(markusheintz): Read preference pref::kApplicationLocale in order
   // to enforce the application locale.
@@ -692,23 +694,8 @@
   // method InitSharedInstance is ignored.
   locale = ui::ResourceBundle::InitSharedInstanceWithLocale(
       locale, nullptr, ui::ResourceBundle::LOAD_COMMON_RESOURCES);
-  if (locale.empty())
-    return locale;
 
-  // First run prefs needs data from the ResourceBundle, so load it now.
-  {
-    TRACE_EVENT0("startup",
-                 "ChromeBrowserMainParts::InitResourceBundleAndDetermineLocale:"
-                 ":AddDataPack");
-    base::FilePath resources_pack_path;
-    PathService::Get(chrome::FILE_RESOURCES_PACK, &resources_pack_path);
-#if defined(OS_ANDROID)
-    ui::LoadMainAndroidPackFile("assets/resources.pak", resources_pack_path);
-#else
-    ui::ResourceBundle::GetSharedInstance().AddDataPackFromPath(
-        resources_pack_path, ui::SCALE_FACTOR_NONE);
-#endif  // defined(OS_ANDROID)
-  }
+  ui::ResourceBundle::GetSharedInstance().AddDataPack(std::move(data_pack));
 
   return locale;
 }
@@ -861,7 +848,8 @@
 // BrowserMainParts ------------------------------------------------------------
 
 ChromeBrowserMainParts::ChromeBrowserMainParts(
-    const content::MainFunctionParams& parameters)
+    const content::MainFunctionParams& parameters,
+    std::unique_ptr<ui::DataPack> data_pack)
     : parameters_(parameters),
       parsed_command_line_(parameters.command_line),
       result_code_(content::RESULT_CODE_NORMAL_EXIT),
@@ -871,7 +859,8 @@
       should_call_pre_main_loop_start_startup_on_variations_service_(
           !parameters.ui_task),
       profile_(NULL),
-      run_message_loop_(true) {
+      run_message_loop_(true),
+      service_manifest_data_pack_(std::move(data_pack)) {
   // If we're running tests (ui_task is non-null).
   if (parameters.ui_task)
     browser_defaults::enable_help_app = false;
@@ -1183,7 +1172,9 @@
 
   // First run prefs may use the ResourceBundle (and get data from it), so this
   // needs to be before ApplyFirstRunPrefs().
-  std::string locale = InitResourceBundleAndDetermineLocale(parameters());
+  std::string locale = InitResourceBundleAndDetermineLocale(
+      parameters(), std::move(service_manifest_data_pack_));
+
   if (locale.empty()) {
     *failed_to_load_resource_bundle = true;
     return chrome::RESULT_CODE_MISSING_DATA;
diff --git a/chrome/browser/chrome_browser_main.h b/chrome/browser/chrome_browser_main.h
index a1e253e0..8c745da 100644
--- a/chrome/browser/chrome_browser_main.h
+++ b/chrome/browser/chrome_browser_main.h
@@ -6,10 +6,8 @@
 #define CHROME_BROWSER_CHROME_BROWSER_MAIN_H_
 
 #include <memory>
-#include <vector>
 
 #include "base/macros.h"
-#include "build/build_config.h"
 #include "chrome/browser/chrome_browser_field_trials.h"
 #include "chrome/browser/chrome_process_singleton.h"
 #include "chrome/browser/first_run/first_run.h"
@@ -18,6 +16,7 @@
 #include "chrome/common/thread_profiler.h"
 #include "content/public/browser/browser_main_parts.h"
 #include "content/public/common/main_function_params.h"
+#include "ui/base/resource/data_pack.h"
 
 class BrowserProcessImpl;
 class ChromeBrowserMainExtraParts;
@@ -56,8 +55,8 @@
   class DeferringTaskRunner;
 #endif
 
-  explicit ChromeBrowserMainParts(
-      const content::MainFunctionParams& parameters);
+  explicit ChromeBrowserMainParts(const content::MainFunctionParams& parameters,
+                                  std::unique_ptr<ui::DataPack> data_pack);
 
   // content::BrowserMainParts overrides.
   bool ShouldContentCreateFeatureList() override;
@@ -211,6 +210,10 @@
   scoped_refptr<DeferringTaskRunner> initial_task_runner_;
 #endif
 
+  // This is used to store the ui data pack. The data pack is moved when
+  // resource bundle gets created.
+  std::unique_ptr<ui::DataPack> service_manifest_data_pack_;
+
   DISALLOW_COPY_AND_ASSIGN(ChromeBrowserMainParts);
 };
 
diff --git a/chrome/browser/chrome_browser_main_android.cc b/chrome/browser/chrome_browser_main_android.cc
index 773d8419..db13c4df 100644
--- a/chrome/browser/chrome_browser_main_android.cc
+++ b/chrome/browser/chrome_browser_main_android.cc
@@ -34,9 +34,9 @@
 #include "ui/base/ui_base_paths.h"
 
 ChromeBrowserMainPartsAndroid::ChromeBrowserMainPartsAndroid(
-    const content::MainFunctionParams& parameters)
-    : ChromeBrowserMainParts(parameters) {
-}
+    const content::MainFunctionParams& parameters,
+    std::unique_ptr<ui::DataPack> data_pack)
+    : ChromeBrowserMainParts(parameters, std::move(data_pack)) {}
 
 ChromeBrowserMainPartsAndroid::~ChromeBrowserMainPartsAndroid() {
 }
diff --git a/chrome/browser/chrome_browser_main_android.h b/chrome/browser/chrome_browser_main_android.h
index 63ae1e2..7cf7c8cb 100644
--- a/chrome/browser/chrome_browser_main_android.h
+++ b/chrome/browser/chrome_browser_main_android.h
@@ -12,7 +12,8 @@
 class ChromeBrowserMainPartsAndroid : public ChromeBrowserMainParts {
  public:
   explicit ChromeBrowserMainPartsAndroid(
-      const content::MainFunctionParams& parameters);
+      const content::MainFunctionParams& parameters,
+      std::unique_ptr<ui::DataPack> data_pack);
   ~ChromeBrowserMainPartsAndroid() override;
 
   // content::BrowserMainParts overrides.
diff --git a/chrome/browser/chrome_browser_main_linux.cc b/chrome/browser/chrome_browser_main_linux.cc
index f41c5a6..be63d8b 100644
--- a/chrome/browser/chrome_browser_main_linux.cc
+++ b/chrome/browser/chrome_browser_main_linux.cc
@@ -34,9 +34,9 @@
 #endif
 
 ChromeBrowserMainPartsLinux::ChromeBrowserMainPartsLinux(
-    const content::MainFunctionParams& parameters)
-    : ChromeBrowserMainPartsPosix(parameters) {
-}
+    const content::MainFunctionParams& parameters,
+    std::unique_ptr<ui::DataPack> data_pack)
+    : ChromeBrowserMainPartsPosix(parameters, std::move(data_pack)) {}
 
 ChromeBrowserMainPartsLinux::~ChromeBrowserMainPartsLinux() {
 }
diff --git a/chrome/browser/chrome_browser_main_linux.h b/chrome/browser/chrome_browser_main_linux.h
index 0aea1165..cfbdda6 100644
--- a/chrome/browser/chrome_browser_main_linux.h
+++ b/chrome/browser/chrome_browser_main_linux.h
@@ -14,7 +14,8 @@
 class ChromeBrowserMainPartsLinux : public ChromeBrowserMainPartsPosix {
  public:
   explicit ChromeBrowserMainPartsLinux(
-      const content::MainFunctionParams& parameters);
+      const content::MainFunctionParams& parameters,
+      std::unique_ptr<ui::DataPack> data_pack);
   ~ChromeBrowserMainPartsLinux() override;
 
   // ChromeBrowserMainParts overrides.
diff --git a/chrome/browser/chrome_browser_main_mac.h b/chrome/browser/chrome_browser_main_mac.h
index 2f36120..5cd8d8e 100644
--- a/chrome/browser/chrome_browser_main_mac.h
+++ b/chrome/browser/chrome_browser_main_mac.h
@@ -11,7 +11,8 @@
 class ChromeBrowserMainPartsMac : public ChromeBrowserMainPartsPosix {
  public:
   explicit ChromeBrowserMainPartsMac(
-      const content::MainFunctionParams& parameters);
+      const content::MainFunctionParams& parameters,
+      std::unique_ptr<ui::DataPack> data_pack);
   ~ChromeBrowserMainPartsMac() override;
 
   // BrowserParts overrides.
diff --git a/chrome/browser/chrome_browser_main_mac.mm b/chrome/browser/chrome_browser_main_mac.mm
index 8e87b52a7..d59e1ab8 100644
--- a/chrome/browser/chrome_browser_main_mac.mm
+++ b/chrome/browser/chrome_browser_main_mac.mm
@@ -66,9 +66,9 @@
 // ChromeBrowserMainPartsMac ---------------------------------------------------
 
 ChromeBrowserMainPartsMac::ChromeBrowserMainPartsMac(
-    const content::MainFunctionParams& parameters)
-    : ChromeBrowserMainPartsPosix(parameters) {
-}
+    const content::MainFunctionParams& parameters,
+    std::unique_ptr<ui::DataPack> data_pack)
+    : ChromeBrowserMainPartsPosix(parameters, std::move(data_pack)) {}
 
 ChromeBrowserMainPartsMac::~ChromeBrowserMainPartsMac() {
 }
diff --git a/chrome/browser/chrome_browser_main_posix.cc b/chrome/browser/chrome_browser_main_posix.cc
index c9195fb..47b29d5 100644
--- a/chrome/browser/chrome_browser_main_posix.cc
+++ b/chrome/browser/chrome_browser_main_posix.cc
@@ -108,9 +108,9 @@
 // ChromeBrowserMainPartsPosix -------------------------------------------------
 
 ChromeBrowserMainPartsPosix::ChromeBrowserMainPartsPosix(
-    const content::MainFunctionParams& parameters)
-    : ChromeBrowserMainParts(parameters) {
-}
+    const content::MainFunctionParams& parameters,
+    std::unique_ptr<ui::DataPack> data_pack)
+    : ChromeBrowserMainParts(parameters, std::move(data_pack)) {}
 
 int ChromeBrowserMainPartsPosix::PreEarlyInitialization() {
   const int result = ChromeBrowserMainParts::PreEarlyInitialization();
diff --git a/chrome/browser/chrome_browser_main_posix.h b/chrome/browser/chrome_browser_main_posix.h
index 265c4c29..334a2fc 100644
--- a/chrome/browser/chrome_browser_main_posix.h
+++ b/chrome/browser/chrome_browser_main_posix.h
@@ -11,7 +11,8 @@
 class ChromeBrowserMainPartsPosix : public ChromeBrowserMainParts {
  public:
   explicit ChromeBrowserMainPartsPosix(
-      const content::MainFunctionParams& parameters);
+      const content::MainFunctionParams& parameters,
+      std::unique_ptr<ui::DataPack> data_pack);
 
   // content::BrowserMainParts overrides.
   int PreEarlyInitialization() override;
diff --git a/chrome/browser/chrome_browser_main_win.cc b/chrome/browser/chrome_browser_main_win.cc
index 73c416d..940e72e 100644
--- a/chrome/browser/chrome_browser_main_win.cc
+++ b/chrome/browser/chrome_browser_main_win.cc
@@ -452,9 +452,9 @@
 // ChromeBrowserMainPartsWin ---------------------------------------------------
 
 ChromeBrowserMainPartsWin::ChromeBrowserMainPartsWin(
-    const content::MainFunctionParams& parameters)
-    : ChromeBrowserMainParts(parameters) {
-}
+    const content::MainFunctionParams& parameters,
+    std::unique_ptr<ui::DataPack> data_pack)
+    : ChromeBrowserMainParts(parameters, std::move(data_pack)) {}
 
 ChromeBrowserMainPartsWin::~ChromeBrowserMainPartsWin() {
 }
diff --git a/chrome/browser/chrome_browser_main_win.h b/chrome/browser/chrome_browser_main_win.h
index 2e8ac43..4dc9464d 100644
--- a/chrome/browser/chrome_browser_main_win.h
+++ b/chrome/browser/chrome_browser_main_win.h
@@ -27,7 +27,8 @@
 class ChromeBrowserMainPartsWin : public ChromeBrowserMainParts {
  public:
   explicit ChromeBrowserMainPartsWin(
-      const content::MainFunctionParams& parameters);
+      const content::MainFunctionParams& parameters,
+      std::unique_ptr<ui::DataPack> data_pack);
 
   ~ChromeBrowserMainPartsWin() override;
 
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc
index 5c105b4..1af3f61 100644
--- a/chrome/browser/chrome_content_browser_client.cc
+++ b/chrome/browser/chrome_content_browser_client.cc
@@ -940,7 +940,8 @@
 
 }  // namespace
 
-ChromeContentBrowserClient::ChromeContentBrowserClient()
+ChromeContentBrowserClient::ChromeContentBrowserClient(
+    std::unique_ptr<ui::DataPack> data_pack)
     : weak_factory_(this) {
 #if BUILDFLAG(ENABLE_PLUGINS)
   for (size_t i = 0; i < arraysize(kPredefinedAllowedDevChannelOrigins); ++i)
@@ -969,6 +970,8 @@
   gpu_binder_registry_.AddInterface(
       base::Bind(&metrics::CallStackProfileCollector::Create,
                  metrics::CallStackProfileParams::GPU_PROCESS));
+
+  service_manifest_data_pack_ = std::move(data_pack);
 }
 
 ChromeContentBrowserClient::~ChromeContentBrowserClient() {
@@ -1028,20 +1031,27 @@
   ChromeBrowserMainParts* main_parts;
   // Construct the Main browser parts based on the OS type.
 #if defined(OS_WIN)
-  main_parts = new ChromeBrowserMainPartsWin(parameters);
+  main_parts = new ChromeBrowserMainPartsWin(
+      parameters, std::move(service_manifest_data_pack_));
 #elif defined(OS_MACOSX)
-  main_parts = new ChromeBrowserMainPartsMac(parameters);
+  main_parts = new ChromeBrowserMainPartsMac(
+      parameters, std::move(service_manifest_data_pack_));
 #elif defined(OS_CHROMEOS)
-  main_parts = new chromeos::ChromeBrowserMainPartsChromeos(parameters);
+  main_parts = new chromeos::ChromeBrowserMainPartsChromeos(
+      parameters, std::move(service_manifest_data_pack_));
 #elif defined(OS_LINUX)
-  main_parts = new ChromeBrowserMainPartsLinux(parameters);
+  main_parts = new ChromeBrowserMainPartsLinux(
+      parameters, std::move(service_manifest_data_pack_));
 #elif defined(OS_ANDROID)
-  main_parts = new ChromeBrowserMainPartsAndroid(parameters);
+  main_parts = new ChromeBrowserMainPartsAndroid(
+      parameters, std::move(service_manifest_data_pack_));
 #elif defined(OS_POSIX)
-  main_parts = new ChromeBrowserMainPartsPosix(parameters);
+  main_parts = new ChromeBrowserMainPartsPosix(
+      parameters, std::move(service_manifest_data_pack_));
 #else
   NOTREACHED();
-  main_parts = new ChromeBrowserMainParts(parameters);
+  main_parts = new ChromeBrowserMainParts(
+      parameters, std::move(service_manifest_data_pack_));
 #endif
 
   chrome::AddProfilesExtraParts(main_parts);
diff --git a/chrome/browser/chrome_content_browser_client.h b/chrome/browser/chrome_content_browser_client.h
index 6be76751a..4de5fcd 100644
--- a/chrome/browser/chrome_content_browser_client.h
+++ b/chrome/browser/chrome_content_browser_client.h
@@ -26,6 +26,7 @@
 #include "ppapi/buildflags/buildflags.h"
 #include "services/network/public/mojom/network_service.mojom.h"
 #include "services/service_manager/public/cpp/binder_registry.h"
+#include "ui/base/resource/data_pack.h"
 
 class ChromeContentBrowserClientParts;
 class PrefRegistrySimple;
@@ -64,7 +65,8 @@
 
 class ChromeContentBrowserClient : public content::ContentBrowserClient {
  public:
-  ChromeContentBrowserClient();
+  explicit ChromeContentBrowserClient(
+      std::unique_ptr<ui::DataPack> data_pack = nullptr);
   ~ChromeContentBrowserClient() override;
 
   // TODO(https://crbug.com/787567): This file is about calls from content/ out
@@ -515,6 +517,8 @@
                                               const url::Origin&>>
       worker_interfaces_parameterized_;
 
+  std::unique_ptr<ui::DataPack> service_manifest_data_pack_;
+
   base::WeakPtrFactory<ChromeContentBrowserClient> weak_factory_;
 
   DISALLOW_COPY_AND_ASSIGN(ChromeContentBrowserClient);
diff --git a/chrome/browser/chromeos/chrome_browser_main_chromeos.cc b/chrome/browser/chromeos/chrome_browser_main_chromeos.cc
index f5824986..6818a6c 100644
--- a/chrome/browser/chromeos/chrome_browser_main_chromeos.cc
+++ b/chrome/browser/chromeos/chrome_browser_main_chromeos.cc
@@ -599,8 +599,9 @@
 // ChromeBrowserMainPartsChromeos ----------------------------------------------
 
 ChromeBrowserMainPartsChromeos::ChromeBrowserMainPartsChromeos(
-    const content::MainFunctionParams& parameters)
-    : ChromeBrowserMainPartsLinux(parameters) {}
+    const content::MainFunctionParams& parameters,
+    std::unique_ptr<ui::DataPack> data_pack)
+    : ChromeBrowserMainPartsLinux(parameters, std::move(data_pack)) {}
 
 ChromeBrowserMainPartsChromeos::~ChromeBrowserMainPartsChromeos() {
   // To be precise, logout (browser shutdown) is not yet done, but the
diff --git a/chrome/browser/chromeos/chrome_browser_main_chromeos.h b/chrome/browser/chromeos/chrome_browser_main_chromeos.h
index 1fc598c..cbf8b08 100644
--- a/chrome/browser/chromeos/chrome_browser_main_chromeos.h
+++ b/chrome/browser/chromeos/chrome_browser_main_chromeos.h
@@ -69,7 +69,8 @@
 class ChromeBrowserMainPartsChromeos : public ChromeBrowserMainPartsLinux {
  public:
   explicit ChromeBrowserMainPartsChromeos(
-      const content::MainFunctionParams& parameters);
+      const content::MainFunctionParams& parameters,
+      std::unique_ptr<ui::DataPack> data_pack);
   ~ChromeBrowserMainPartsChromeos() override;
 
   // ChromeBrowserMainParts overrides.
diff --git a/content/app/content_main_runner.cc b/content/app/content_main_runner.cc
index 7f0fc3d..23bf9a09 100644
--- a/content/app/content_main_runner.cc
+++ b/content/app/content_main_runner.cc
@@ -436,6 +436,12 @@
 
 #endif  // OS_LINUX
 
+bool IsRootProcess() {
+  const base::CommandLine& command_line =
+      *base::CommandLine::ForCurrentProcess();
+  return command_line.GetSwitchValueASCII(switches::kProcessType).empty();
+}
+
 }  // namespace
 
 #if !defined(CHROME_MULTIPLE_DLL_CHILD)
@@ -729,9 +735,16 @@
     int exit_code = 0;
     if (delegate_ && delegate_->BasicStartupComplete(&exit_code))
       return exit_code;
-
     completed_basic_startup_ = true;
 
+    // We will need to use data from resources.pak in later cl, so load the file
+    // now.
+    if (IsRootProcess()) {
+      ui::DataPack* data_pack = delegate_->LoadServiceManifestDataPack();
+      // TODO(ranj): Read manifest from this data pack.
+      ignore_result(data_pack);
+    }
+
     const base::CommandLine& command_line =
         *base::CommandLine::ForCurrentProcess();
     std::string process_type =
diff --git a/content/public/app/content_main_delegate.cc b/content/public/app/content_main_delegate.cc
index 5f2631c..20dc0c9 100644
--- a/content/public/app/content_main_delegate.cc
+++ b/content/public/app/content_main_delegate.cc
@@ -26,6 +26,10 @@
   return -1;
 }
 
+ui::DataPack* ContentMainDelegate::LoadServiceManifestDataPack() {
+  return nullptr;
+}
+
 #if defined(OS_MACOSX)
 
 bool ContentMainDelegate::ProcessRegistersWithSystemProcess(
diff --git a/content/public/app/content_main_delegate.h b/content/public/app/content_main_delegate.h
index a53d40b..c3f364e 100644
--- a/content/public/app/content_main_delegate.h
+++ b/content/public/app/content_main_delegate.h
@@ -23,6 +23,10 @@
 class Identity;
 }  // namespace service_manager
 
+namespace ui {
+class DataPack;
+}
+
 namespace content {
 
 class ContentBrowserClient;
@@ -59,6 +63,10 @@
   // Called right before the process exits.
   virtual void ProcessExiting(const std::string& process_type) {}
 
+  // This loads the service manifest datapack, takes its ownership and returns
+  // the pointer to it.
+  virtual ui::DataPack* LoadServiceManifestDataPack();
+
 #if defined(OS_MACOSX)
   // Returns true if the process registers with the system monitor, so that we
   // can allocate an IO port for it before the sandbox is initialized. Embedders
diff --git a/ui/base/resource/resource_bundle.cc b/ui/base/resource/resource_bundle.cc
index cc391df..2a00d4e8 100644
--- a/ui/base/resource/resource_bundle.cc
+++ b/ui/base/resource/resource_bundle.cc
@@ -247,6 +247,18 @@
 }
 #endif  // !defined(OS_ANDROID)
 
+void ResourceBundle::AddDataPack(std::unique_ptr<DataPack> data_pack) {
+#if DCHECK_IS_ON()
+  data_pack->CheckForDuplicateResources(data_packs_);
+#endif
+
+  if (GetScaleForScaleFactor(data_pack->GetScaleFactor()) >
+      GetScaleForScaleFactor(max_scale_factor_))
+    max_scale_factor_ = data_pack->GetScaleFactor();
+
+  data_packs_.push_back(std::move(data_pack));
+}
+
 void ResourceBundle::AddDataPackFromPath(const base::FilePath& path,
                                          ScaleFactor scale_factor) {
   AddDataPackFromPathInternal(path, scale_factor, false);
@@ -805,18 +817,6 @@
   }
 }
 
-void ResourceBundle::AddDataPack(std::unique_ptr<DataPack> data_pack) {
-#if DCHECK_IS_ON()
-  data_pack->CheckForDuplicateResources(data_packs_);
-#endif
-
-  if (GetScaleForScaleFactor(data_pack->GetScaleFactor()) >
-      GetScaleForScaleFactor(max_scale_factor_))
-    max_scale_factor_ = data_pack->GetScaleFactor();
-
-  data_packs_.push_back(std::move(data_pack));
-}
-
 void ResourceBundle::InitDefaultFontList() {
 #if defined(OS_CHROMEOS)
   std::string font_family = base::UTF16ToUTF8(
diff --git a/ui/base/resource/resource_bundle.h b/ui/base/resource/resource_bundle.h
index 413b61a..422d84b 100644
--- a/ui/base/resource/resource_bundle.h
+++ b/ui/base/resource/resource_bundle.h
@@ -158,6 +158,10 @@
   // Check if the .pak for the given locale exists.
   bool LocaleDataPakExists(const std::string& locale);
 
+  // Inserts |data_pack| to |data_pack_| and updates |max_scale_factor_|
+  // accordingly.
+  void AddDataPack(std::unique_ptr<DataPack> data_pack);
+
   // Registers additional data pack files with this ResourceBundle.  When
   // looking for a DataResource, we will search these files after searching the
   // main module. |path| should be the complete path to the pack file if known
@@ -337,10 +341,6 @@
                                    ScaleFactor scale_factor,
                                    bool optional);
 
-  // Inserts |data_pack| to |data_pack_| and updates |max_scale_factor_|
-  // accordingly.
-  void AddDataPack(std::unique_ptr<DataPack> data_pack);
-
   // Try to load the locale specific strings from an external data module.
   // Returns the locale that is loaded.
   std::string LoadLocaleResources(const std::string& pref_locale);
diff --git a/ui/base/resource/resource_bundle_android.cc b/ui/base/resource/resource_bundle_android.cc
index 16907b59..6ce54d1 100644
--- a/ui/base/resource/resource_bundle_android.cc
+++ b/ui/base/resource/resource_bundle_android.cc
@@ -11,7 +11,6 @@
 #include "base/path_service.h"
 #include "jni/ResourceBundle_jni.h"
 #include "ui/base/l10n/l10n_util.h"
-#include "ui/base/resource/data_pack.h"
 #include "ui/base/resource/resource_bundle.h"
 #include "ui/base/ui_base_paths.h"
 
@@ -176,6 +175,21 @@
   }
 }
 
+std::unique_ptr<DataPack> GetDataPackFromPackFile(
+    const char* path_within_apk,
+    const base::FilePath& disk_file_path) {
+  if (LoadFromApkOrFile(path_within_apk, &disk_file_path, &g_resources_pack_fd,
+                        &g_resources_pack_region)) {
+    std::unique_ptr<DataPack> data_pack =
+        std::make_unique<DataPack>(SCALE_FACTOR_NONE);
+    if (data_pack->LoadFromFileRegion(base::File(g_resources_pack_fd),
+                                      g_resources_pack_region)) {
+      return data_pack;
+    }
+  }
+  return nullptr;
+}
+
 int GetMainAndroidPackFd(base::MemoryMappedFile::Region* out_region) {
   DCHECK_GE(g_resources_pack_fd, 0);
   *out_region = g_resources_pack_region;
diff --git a/ui/base/resource/resource_bundle_android.h b/ui/base/resource/resource_bundle_android.h
index 57059b0..2913731 100644
--- a/ui/base/resource/resource_bundle_android.h
+++ b/ui/base/resource/resource_bundle_android.h
@@ -9,6 +9,7 @@
 #include <string>
 
 #include "base/files/memory_mapped_file.h"
+#include "ui/base/resource/data_pack.h"
 #include "ui/base/ui_base_export.h"
 
 namespace ui {
@@ -19,6 +20,10 @@
     const char* path_within_apk,
     const base::FilePath& disk_file_path);
 
+UI_BASE_EXPORT std::unique_ptr<DataPack> GetDataPackFromPackFile(
+    const char* path_within_apk,
+    const base::FilePath& disk_file_path);
+
 // Returns the file descriptor and region for resources.pak.
 UI_BASE_EXPORT int GetMainAndroidPackFd(
     base::MemoryMappedFile::Region* out_region);