1// Copyright 2014 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "extensions/shell/browser/shell_browser_main_parts.h"
6
7#include "base/command_line.h"
8#include "base/run_loop.h"
9#include "components/keyed_service/content/browser_context_dependency_manager.h"
10#include "components/omaha_query_params/omaha_query_params.h"
11#include "content/public/browser/child_process_security_policy.h"
12#include "content/public/browser/context_factory.h"
13#include "content/public/common/result_codes.h"
14#include "content/shell/browser/shell_devtools_delegate.h"
15#include "content/shell/browser/shell_net_log.h"
16#include "extensions/browser/app_window/app_window_client.h"
17#include "extensions/browser/browser_context_keyed_service_factories.h"
18#include "extensions/browser/extension_system.h"
19#include "extensions/common/constants.cc"
20#include "extensions/shell/browser/shell_browser_context.h"
21#include "extensions/shell/browser/shell_browser_main_delegate.h"
22#include "extensions/shell/browser/shell_desktop_controller.h"
23#include "extensions/shell/browser/shell_device_client.h"
24#include "extensions/shell/browser/shell_extension_system.h"
25#include "extensions/shell/browser/shell_extension_system_factory.h"
26#include "extensions/shell/browser/shell_extensions_browser_client.h"
27#include "extensions/shell/browser/shell_omaha_query_params_delegate.h"
28#include "extensions/shell/common/shell_extensions_client.h"
29#include "extensions/shell/common/switches.h"
30#include "ui/aura/env.h"
31#include "ui/aura/window_tree_host.h"
32#include "ui/base/ime/input_method_initializer.h"
33#include "ui/base/resource/resource_bundle.h"
34
35#if !defined(OS_ANDROID) && !defined(OS_IOS)
36#include "components/storage_monitor/storage_monitor.h"
37#endif
38
39#if defined(OS_CHROMEOS)
40#include "chromeos/audio/cras_audio_handler.h"
41#include "chromeos/dbus/dbus_thread_manager.h"
42#include "chromeos/network/network_handler.h"
43#include "extensions/shell/browser/shell_audio_controller_chromeos.h"
44#include "extensions/shell/browser/shell_network_controller_chromeos.h"
45#endif
46
47#if !defined(DISABLE_NACL)
48#include "components/nacl/browser/nacl_browser.h"
49#include "components/nacl/browser/nacl_process_host.h"
50#include "content/public/browser/browser_thread.h"
51#include "extensions/shell/browser/shell_nacl_browser_delegate.h"
52#endif
53
54using content::BrowserContext;
55
56namespace extensions {
57
58ShellBrowserMainParts::ShellBrowserMainParts(
59    const content::MainFunctionParams& parameters,
60    ShellBrowserMainDelegate* browser_main_delegate)
61    : extension_system_(NULL),
62      parameters_(parameters),
63      run_message_loop_(true),
64      browser_main_delegate_(browser_main_delegate) {
65}
66
67ShellBrowserMainParts::~ShellBrowserMainParts() {
68}
69
70void ShellBrowserMainParts::PreMainMessageLoopStart() {
71  // TODO(jamescook): Initialize touch here?
72}
73
74void ShellBrowserMainParts::PostMainMessageLoopStart() {
75#if defined(OS_CHROMEOS)
76  // Perform initialization of D-Bus objects here rather than in the below
77  // helper classes so those classes' tests can initialize stub versions of the
78  // D-Bus objects.
79  chromeos::DBusThreadManager::Initialize();
80
81  chromeos::NetworkHandler::Initialize();
82  network_controller_.reset(new ShellNetworkController(
83      base::CommandLine::ForCurrentProcess()->GetSwitchValueNative(
84          switches::kAppShellPreferredNetwork)));
85
86  chromeos::CrasAudioHandler::Initialize(
87      new ShellAudioController::PrefHandler());
88  audio_controller_.reset(new ShellAudioController());
89#else
90  // Non-Chrome OS platforms are for developer convenience, so use a test IME.
91  ui::InitializeInputMethodForTesting();
92#endif
93}
94
95void ShellBrowserMainParts::PreEarlyInitialization() {
96}
97
98int ShellBrowserMainParts::PreCreateThreads() {
99  // TODO(jamescook): Initialize chromeos::CrosSettings here?
100
101  content::ChildProcessSecurityPolicy::GetInstance()->RegisterWebSafeScheme(
102      kExtensionScheme);
103  content::ChildProcessSecurityPolicy::GetInstance()->RegisterWebSafeScheme(
104      kExtensionResourceScheme);
105
106  // Return no error.
107  return 0;
108}
109
110void ShellBrowserMainParts::PreMainMessageLoopRun() {
111  // Initialize our "profile" equivalent.
112  browser_context_.reset(new ShellBrowserContext);
113
114  aura::Env::GetInstance()->set_context_factory(content::GetContextFactory());
115
116#if !defined(OS_ANDROID) && !defined(OS_IOS)
117  storage_monitor::StorageMonitor::Create();
118#endif
119
120  desktop_controller_.reset(browser_main_delegate_->CreateDesktopController());
121
122  // NOTE: Much of this is culled from chrome/test/base/chrome_test_suite.cc
123  // TODO(jamescook): Initialize user_manager::UserManager.
124  net_log_.reset(new content::ShellNetLog("app_shell"));
125
126  device_client_.reset(new ShellDeviceClient);
127
128  extensions_client_.reset(new ShellExtensionsClient());
129  ExtensionsClient::Set(extensions_client_.get());
130
131  extensions_browser_client_.reset(
132      new ShellExtensionsBrowserClient(browser_context_.get()));
133  ExtensionsBrowserClient::Set(extensions_browser_client_.get());
134
135  omaha_query_params_delegate_.reset(new ShellOmahaQueryParamsDelegate);
136  omaha_query_params::OmahaQueryParams::SetDelegate(
137      omaha_query_params_delegate_.get());
138
139  // Create our custom ExtensionSystem first because other
140  // KeyedServices depend on it.
141  // TODO(yoz): Move this after EnsureBrowserContextKeyedServiceFactoriesBuilt.
142  CreateExtensionSystem();
143
144  // Register additional KeyedService factories here. See
145  // ChromeBrowserMainExtraPartsProfiles for details.
146  EnsureBrowserContextKeyedServiceFactoriesBuilt();
147  ShellExtensionSystemFactory::GetInstance();
148
149  BrowserContextDependencyManager::GetInstance()->CreateBrowserContextServices(
150      browser_context_.get());
151
152#if !defined(DISABLE_NACL)
153  // Takes ownership.
154  nacl::NaClBrowser::SetDelegate(
155      new ShellNaClBrowserDelegate(browser_context_.get()));
156  content::BrowserThread::PostTask(
157      content::BrowserThread::IO,
158      FROM_HERE,
159      base::Bind(nacl::NaClProcessHost::EarlyStartup));
160#endif
161
162  devtools_delegate_.reset(
163      new content::ShellDevToolsDelegate(browser_context_.get()));
164  if (parameters_.ui_task) {
165    // For running browser tests.
166    parameters_.ui_task->Run();
167    delete parameters_.ui_task;
168    run_message_loop_ = false;
169  } else {
170    browser_main_delegate_->Start(browser_context_.get());
171  }
172}
173
174bool ShellBrowserMainParts::MainMessageLoopRun(int* result_code) {
175  if (!run_message_loop_)
176    return true;
177  // TODO(yoz): just return false here?
178  base::RunLoop run_loop;
179  run_loop.Run();
180  *result_code = content::RESULT_CODE_NORMAL_EXIT;
181  return true;
182}
183
184void ShellBrowserMainParts::PostMainMessageLoopRun() {
185  browser_main_delegate_->Shutdown();
186
187  BrowserContextDependencyManager::GetInstance()->DestroyBrowserContextServices(
188      browser_context_.get());
189  extension_system_ = NULL;
190  ExtensionsBrowserClient::Set(NULL);
191  extensions_browser_client_.reset();
192  browser_context_.reset();
193
194  desktop_controller_.reset();
195
196#if !defined(OS_ANDROID) && !defined(OS_IOS)
197  storage_monitor::StorageMonitor::Destroy();
198#endif
199}
200
201void ShellBrowserMainParts::PostDestroyThreads() {
202#if defined(OS_CHROMEOS)
203  audio_controller_.reset();
204  chromeos::CrasAudioHandler::Shutdown();
205  network_controller_.reset();
206  chromeos::NetworkHandler::Shutdown();
207  chromeos::DBusThreadManager::Shutdown();
208#endif
209}
210
211void ShellBrowserMainParts::CreateExtensionSystem() {
212  DCHECK(browser_context_);
213  extension_system_ = static_cast<ShellExtensionSystem*>(
214      ExtensionSystem::Get(browser_context_.get()));
215  extension_system_->InitForRegularProfile(true);
216}
217
218}  // namespace extensions
219