Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / extensions / shell / browser / shell_browser_main_parts.cc
blob073dacb5afde651afdf34b57b2d87dbd2d9bed89
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.
5 #include "extensions/shell/browser/shell_browser_main_parts.h"
7 #include <string>
9 #include "base/command_line.h"
10 #include "base/prefs/pref_service.h"
11 #include "base/run_loop.h"
12 #include "components/devtools_http_handler/devtools_http_handler.h"
13 #include "components/keyed_service/content/browser_context_dependency_manager.h"
14 #include "components/storage_monitor/storage_monitor.h"
15 #include "components/update_client/update_query_params.h"
16 #include "content/public/browser/child_process_security_policy.h"
17 #include "content/public/browser/context_factory.h"
18 #include "content/public/common/result_codes.h"
19 #include "content/shell/browser/shell_devtools_manager_delegate.h"
20 #include "extensions/browser/app_window/app_window_client.h"
21 #include "extensions/browser/browser_context_keyed_service_factories.h"
22 #include "extensions/browser/extension_system.h"
23 #include "extensions/browser/updater/update_service.h"
24 #include "extensions/common/constants.h"
25 #include "extensions/common/switches.h"
26 #include "extensions/shell/browser/shell_browser_context.h"
27 #include "extensions/shell/browser/shell_browser_context_keyed_service_factories.h"
28 #include "extensions/shell/browser/shell_browser_main_delegate.h"
29 #include "extensions/shell/browser/shell_desktop_controller_aura.h"
30 #include "extensions/shell/browser/shell_device_client.h"
31 #include "extensions/shell/browser/shell_extension_system.h"
32 #include "extensions/shell/browser/shell_extension_system_factory.h"
33 #include "extensions/shell/browser/shell_extensions_browser_client.h"
34 #include "extensions/shell/browser/shell_oauth2_token_service.h"
35 #include "extensions/shell/browser/shell_prefs.h"
36 #include "extensions/shell/browser/shell_update_query_params_delegate.h"
37 #include "extensions/shell/common/shell_extensions_client.h"
38 #include "extensions/shell/common/switches.h"
39 #include "ui/base/ime/input_method_initializer.h"
40 #include "ui/base/resource/resource_bundle.h"
42 #if defined(USE_AURA)
43 #include "ui/aura/env.h"
44 #endif
46 #if defined(OS_CHROMEOS)
47 #include "chromeos/audio/audio_devices_pref_handler_impl.h"
48 #include "chromeos/audio/cras_audio_handler.h"
49 #include "chromeos/dbus/dbus_thread_manager.h"
50 #include "chromeos/disks/disk_mount_manager.h"
51 #include "chromeos/network/network_handler.h"
52 #include "extensions/shell/browser/shell_audio_controller_chromeos.h"
53 #include "extensions/shell/browser/shell_network_controller_chromeos.h"
54 #endif
56 #if defined(OS_MACOSX)
57 #include "extensions/shell/browser/shell_browser_main_parts_mac.h"
58 #endif
60 #if !defined(DISABLE_NACL)
61 #include "components/nacl/browser/nacl_browser.h"
62 #include "components/nacl/browser/nacl_process_host.h"
63 #include "content/public/browser/browser_thread.h"
64 #include "extensions/shell/browser/shell_nacl_browser_delegate.h"
65 #endif
67 using base::CommandLine;
68 using content::BrowserContext;
70 #if !defined(DISABLE_NACL)
71 using content::BrowserThread;
72 #endif
74 namespace extensions {
76 namespace {
78 void CrxInstallComplete(bool success) {
79 VLOG(1) << "CRX download complete. Success: " << success;
83 ShellBrowserMainParts::ShellBrowserMainParts(
84 const content::MainFunctionParams& parameters,
85 ShellBrowserMainDelegate* browser_main_delegate)
86 : devtools_http_handler_(nullptr),
87 extension_system_(nullptr),
88 parameters_(parameters),
89 run_message_loop_(true),
90 browser_main_delegate_(browser_main_delegate) {
93 ShellBrowserMainParts::~ShellBrowserMainParts() {
94 DCHECK(!devtools_http_handler_);
97 void ShellBrowserMainParts::PreMainMessageLoopStart() {
98 // TODO(jamescook): Initialize touch here?
99 #if defined(OS_MACOSX)
100 MainPartsPreMainMessageLoopStartMac();
101 #endif
104 void ShellBrowserMainParts::PostMainMessageLoopStart() {
105 #if defined(OS_CHROMEOS)
106 // Perform initialization of D-Bus objects here rather than in the below
107 // helper classes so those classes' tests can initialize stub versions of the
108 // D-Bus objects.
109 chromeos::DBusThreadManager::Initialize();
110 chromeos::disks::DiskMountManager::Initialize();
112 chromeos::NetworkHandler::Initialize();
113 network_controller_.reset(new ShellNetworkController(
114 base::CommandLine::ForCurrentProcess()->GetSwitchValueNative(
115 switches::kAppShellPreferredNetwork)));
117 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
118 switches::kAppShellAllowRoaming)) {
119 network_controller_->SetCellularAllowRoaming(true);
122 #else
123 // Non-Chrome OS platforms are for developer convenience, so use a test IME.
124 ui::InitializeInputMethodForTesting();
125 #endif
128 void ShellBrowserMainParts::PreEarlyInitialization() {
131 int ShellBrowserMainParts::PreCreateThreads() {
132 // TODO(jamescook): Initialize chromeos::CrosSettings here?
134 content::ChildProcessSecurityPolicy::GetInstance()->RegisterWebSafeScheme(
135 kExtensionScheme);
136 content::ChildProcessSecurityPolicy::GetInstance()->RegisterWebSafeScheme(
137 kExtensionResourceScheme);
139 // Return no error.
140 return 0;
143 void ShellBrowserMainParts::PreMainMessageLoopRun() {
144 // Initialize our "profile" equivalent.
145 browser_context_.reset(new ShellBrowserContext);
147 // app_shell only supports a single user, so all preferences live in the user
148 // data directory, including the device-wide local state.
149 local_state_ = shell_prefs::CreateLocalState(browser_context_->GetPath());
150 user_pref_service_ =
151 shell_prefs::CreateUserPrefService(browser_context_.get());
153 #if defined(OS_CHROMEOS)
154 chromeos::CrasAudioHandler::Initialize(
155 new chromeos::AudioDevicesPrefHandlerImpl(local_state_.get()));
156 audio_controller_.reset(new ShellAudioController());
157 #endif
159 #if defined(USE_AURA)
160 aura::Env::GetInstance()->set_context_factory(content::GetContextFactory());
161 #endif
163 storage_monitor::StorageMonitor::Create();
165 desktop_controller_.reset(browser_main_delegate_->CreateDesktopController());
167 // TODO(jamescook): Initialize user_manager::UserManager.
169 device_client_.reset(new ShellDeviceClient);
171 extensions_client_.reset(CreateExtensionsClient());
172 ExtensionsClient::Set(extensions_client_.get());
174 extensions_browser_client_.reset(CreateExtensionsBrowserClient(
175 browser_context_.get(), user_pref_service_.get()));
176 ExtensionsBrowserClient::Set(extensions_browser_client_.get());
178 update_query_params_delegate_.reset(new ShellUpdateQueryParamsDelegate);
179 update_client::UpdateQueryParams::SetDelegate(
180 update_query_params_delegate_.get());
182 // Create our custom ExtensionSystem first because other
183 // KeyedServices depend on it.
184 // TODO(yoz): Move this after EnsureBrowserContextKeyedServiceFactoriesBuilt.
185 CreateExtensionSystem();
187 // Register additional KeyedService factories here. See
188 // ChromeBrowserMainExtraPartsProfiles for details.
189 EnsureBrowserContextKeyedServiceFactoriesBuilt();
190 ShellExtensionSystemFactory::GetInstance();
192 BrowserContextDependencyManager::GetInstance()->CreateBrowserContextServices(
193 browser_context_.get());
195 // Initialize OAuth2 support from command line.
196 base::CommandLine* cmd = base::CommandLine::ForCurrentProcess();
197 oauth2_token_service_.reset(new ShellOAuth2TokenService(
198 browser_context_.get(),
199 cmd->GetSwitchValueASCII(switches::kAppShellUser),
200 cmd->GetSwitchValueASCII(switches::kAppShellRefreshToken)));
202 #if !defined(DISABLE_NACL)
203 // Takes ownership.
204 nacl::NaClBrowser::SetDelegate(
205 new ShellNaClBrowserDelegate(browser_context_.get()));
206 // Track the task so it can be canceled if app_shell shuts down very quickly,
207 // such as in browser tests.
208 task_tracker_.PostTask(
209 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO).get(),
210 FROM_HERE,
211 base::Bind(nacl::NaClProcessHost::EarlyStartup));
212 #endif
214 // TODO(rockot): Remove this temporary hack test.
215 std::string install_crx_id =
216 cmd->GetSwitchValueASCII(switches::kAppShellInstallCrx);
217 if (install_crx_id.size() != 0) {
218 CHECK(install_crx_id.size() == 32)
219 << "Extension ID must be exactly 32 characters long.";
220 UpdateService* update_service = UpdateService::Get(browser_context_.get());
221 update_service->DownloadAndInstall(install_crx_id,
222 base::Bind(CrxInstallComplete));
225 devtools_http_handler_.reset(
226 content::ShellDevToolsManagerDelegate::CreateHttpHandler(
227 browser_context_.get()));
228 if (parameters_.ui_task) {
229 // For running browser tests.
230 parameters_.ui_task->Run();
231 delete parameters_.ui_task;
232 run_message_loop_ = false;
233 } else {
234 browser_main_delegate_->Start(browser_context_.get());
238 bool ShellBrowserMainParts::MainMessageLoopRun(int* result_code) {
239 if (!run_message_loop_)
240 return true;
241 // TODO(yoz): just return false here?
242 base::RunLoop run_loop;
243 run_loop.Run();
244 *result_code = content::RESULT_CODE_NORMAL_EXIT;
245 return true;
248 void ShellBrowserMainParts::PostMainMessageLoopRun() {
249 // NOTE: Please destroy objects in the reverse order of their creation.
250 browser_main_delegate_->Shutdown();
251 devtools_http_handler_.reset();
253 #if !defined(DISABLE_NACL)
254 task_tracker_.TryCancelAll();
255 nacl::NaClBrowser::SetDelegate(nullptr);
256 #endif
258 oauth2_token_service_.reset();
259 BrowserContextDependencyManager::GetInstance()->DestroyBrowserContextServices(
260 browser_context_.get());
261 extension_system_ = NULL;
262 ExtensionsBrowserClient::Set(NULL);
263 extensions_browser_client_.reset();
265 desktop_controller_.reset();
267 storage_monitor::StorageMonitor::Destroy();
269 #if defined(OS_CHROMEOS)
270 audio_controller_.reset();
271 chromeos::CrasAudioHandler::Shutdown();
272 #endif
274 user_pref_service_->CommitPendingWrite();
275 user_pref_service_.reset();
276 local_state_->CommitPendingWrite();
277 local_state_.reset();
279 browser_context_.reset();
282 void ShellBrowserMainParts::PostDestroyThreads() {
283 #if defined(OS_CHROMEOS)
284 network_controller_.reset();
285 chromeos::NetworkHandler::Shutdown();
286 chromeos::disks::DiskMountManager::Shutdown();
287 chromeos::DBusThreadManager::Shutdown();
288 #endif
291 ExtensionsClient* ShellBrowserMainParts::CreateExtensionsClient() {
292 return new ShellExtensionsClient();
295 ExtensionsBrowserClient* ShellBrowserMainParts::CreateExtensionsBrowserClient(
296 content::BrowserContext* context,
297 PrefService* service) {
298 return new ShellExtensionsBrowserClient(context, service);
301 void ShellBrowserMainParts::CreateExtensionSystem() {
302 DCHECK(browser_context_);
303 extension_system_ = static_cast<ShellExtensionSystem*>(
304 ExtensionSystem::Get(browser_context_.get()));
305 extension_system_->InitForRegularProfile(true);
308 } // namespace extensions