1 // Copyright 2013 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 "apps/shell/browser/shell_browser_main_parts.h"
7 #include "apps/shell/browser/shell_browser_context.h"
8 #include "apps/shell/browser/shell_desktop_controller.h"
9 #include "apps/shell/browser/shell_extension_system.h"
10 #include "apps/shell/browser/shell_extension_system_factory.h"
11 #include "apps/shell/browser/shell_extensions_browser_client.h"
12 #include "apps/shell/common/shell_extensions_client.h"
13 #include "base/command_line.h"
14 #include "base/file_util.h"
15 #include "base/files/file_path.h"
16 #include "base/run_loop.h"
17 #include "components/keyed_service/content/browser_context_dependency_manager.h"
18 #include "content/public/common/result_codes.h"
19 #include "content/shell/browser/shell_devtools_delegate.h"
20 #include "content/shell/browser/shell_net_log.h"
21 #include "extensions/browser/browser_context_keyed_service_factories.h"
22 #include "extensions/browser/extension_system.h"
23 #include "ui/aura/window_tree_host.h"
24 #include "ui/base/resource/resource_bundle.h"
26 #if defined(OS_CHROMEOS)
27 #include "apps/shell/browser/shell_network_controller_chromeos.h"
28 #include "chromeos/dbus/dbus_thread_manager.h"
31 using content::BrowserContext;
32 using extensions::Extension;
33 using extensions::ExtensionSystem;
34 using extensions::ShellExtensionSystem;
38 // Register additional KeyedService factories here. See
39 // ChromeBrowserMainExtraPartsProfiles for details.
40 void EnsureBrowserContextKeyedServiceFactoriesBuilt() {
41 extensions::EnsureBrowserContextKeyedServiceFactoriesBuilt();
42 extensions::ShellExtensionSystemFactory::GetInstance();
49 ShellBrowserMainParts::ShellBrowserMainParts(
50 const content::MainFunctionParams& parameters)
51 : extension_system_(NULL),
52 parameters_(parameters),
53 run_message_loop_(true) {}
55 ShellBrowserMainParts::~ShellBrowserMainParts() {
58 void ShellBrowserMainParts::PreMainMessageLoopStart() {
59 // TODO(jamescook): Initialize touch here?
62 void ShellBrowserMainParts::PostMainMessageLoopStart() {
63 #if defined(OS_CHROMEOS)
64 chromeos::DBusThreadManager::Initialize();
65 network_controller_.reset(new ShellNetworkController);
69 void ShellBrowserMainParts::PreEarlyInitialization() {
72 int ShellBrowserMainParts::PreCreateThreads() {
73 // TODO(jamescook): Initialize chromeos::CrosSettings here?
79 void ShellBrowserMainParts::PreMainMessageLoopRun() {
80 // Initialize our "profile" equivalent.
81 browser_context_.reset(new ShellBrowserContext);
83 desktop_controller_.reset(new ShellDesktopController);
84 desktop_controller_->GetWindowTreeHost()->AddObserver(this);
86 // NOTE: Much of this is culled from chrome/test/base/chrome_test_suite.cc
87 // TODO(jamescook): Initialize chromeos::UserManager.
88 net_log_.reset(new content::ShellNetLog("app_shell"));
90 extensions_client_.reset(new ShellExtensionsClient());
91 extensions::ExtensionsClient::Set(extensions_client_.get());
93 extensions_browser_client_.reset(
94 new extensions::ShellExtensionsBrowserClient(browser_context_.get()));
95 extensions::ExtensionsBrowserClient::Set(extensions_browser_client_.get());
97 // Create our custom ExtensionSystem first because other
98 // KeyedServices depend on it.
99 // TODO(yoz): Move this after EnsureBrowserContextKeyedServiceFactoriesBuilt.
100 CreateExtensionSystem();
102 ::EnsureBrowserContextKeyedServiceFactoriesBuilt();
103 BrowserContextDependencyManager::GetInstance()->CreateBrowserContextServices(
104 browser_context_.get());
106 devtools_delegate_.reset(
107 new content::ShellDevToolsDelegate(browser_context_.get()));
109 const std::string kAppSwitch = "app";
110 CommandLine* command_line = CommandLine::ForCurrentProcess();
111 if (command_line->HasSwitch(kAppSwitch)) {
112 base::FilePath app_dir(command_line->GetSwitchValueNative(kAppSwitch));
113 base::FilePath app_absolute_dir = base::MakeAbsoluteFilePath(app_dir);
114 extension_system_->LoadAndLaunchApp(app_absolute_dir);
115 } else if (parameters_.ui_task) {
116 // For running browser tests.
117 parameters_.ui_task->Run();
118 delete parameters_.ui_task;
119 run_message_loop_ = false;
121 LOG(ERROR) << "--" << kAppSwitch << " unset; boredom is in your future";
125 bool ShellBrowserMainParts::MainMessageLoopRun(int* result_code) {
126 if (!run_message_loop_)
128 // TODO(yoz): just return false here?
129 base::RunLoop run_loop;
131 *result_code = content::RESULT_CODE_NORMAL_EXIT;
135 void ShellBrowserMainParts::PostMainMessageLoopRun() {
136 BrowserContextDependencyManager::GetInstance()->DestroyBrowserContextServices(
137 browser_context_.get());
138 extension_system_ = NULL;
139 extensions::ExtensionsBrowserClient::Set(NULL);
140 extensions_browser_client_.reset();
141 browser_context_.reset();
143 desktop_controller_->GetWindowTreeHost()->RemoveObserver(this);
144 desktop_controller_.reset();
147 void ShellBrowserMainParts::PostDestroyThreads() {
148 #if defined(OS_CHROMEOS)
149 network_controller_.reset();
150 chromeos::DBusThreadManager::Shutdown();
154 void ShellBrowserMainParts::OnHostCloseRequested(
155 const aura::WindowTreeHost* host) {
156 desktop_controller_->CloseAppWindow();
157 base::MessageLoop::current()->PostTask(FROM_HERE,
158 base::MessageLoop::QuitClosure());
161 void ShellBrowserMainParts::CreateExtensionSystem() {
162 DCHECK(browser_context_);
163 extension_system_ = static_cast<ShellExtensionSystem*>(
164 ExtensionSystem::Get(browser_context_.get()));
165 extension_system_->InitForRegularProfile(true);