Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / apps / shell / browser / shell_browser_main_parts.cc
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.
4
5 #include "apps/shell/browser/shell_browser_main_parts.h"
6
7 #include "apps/shell/browser/shell_browser_context.h"
8 #include "apps/shell/browser/shell_extension_system.h"
9 #include "apps/shell/browser/shell_extension_system_factory.h"
10 #include "apps/shell/browser/shell_extensions_browser_client.h"
11 #include "apps/shell/browser/web_view_window.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/browser_context_keyed_service/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/extension_system.h"
22 #include "extensions/browser/renderer_startup_helper.h"
23 #include "ui/aura/env.h"
24 #include "ui/aura/root_window.h"
25 #include "ui/aura/test/test_screen.h"
26 #include "ui/base/ime/input_method_initializer.h"
27 #include "ui/base/resource/resource_bundle.h"
28 #include "ui/gfx/screen.h"
29 #include "ui/views/test/test_views_delegate.h"
30 #include "ui/views/views_delegate.h"
31 #include "ui/views/widget/widget.h"
32 #include "ui/wm/test/wm_test_helper.h"
33
34 using content::BrowserContext;
35 using extensions::Extension;
36 using extensions::ExtensionSystem;
37 using extensions::ShellExtensionSystem;
38
39 namespace apps {
40 namespace {
41
42 // Register additional BrowserContextKeyedService factories here. See
43 // ChromeBrowserMainExtraPartsProfiles for details.
44 void EnsureBrowserContextKeyedServiceFactoriesBuilt() {
45   extensions::RendererStartupHelperFactory::GetInstance();
46   extensions::ShellExtensionSystemFactory::GetInstance();
47 }
48
49 // A ViewsDelegate to attach new unparented windows to app_shell's root window.
50 class ShellViewsDelegate : public views::TestViewsDelegate {
51  public:
52   explicit ShellViewsDelegate(aura::Window* root_window)
53       : root_window_(root_window) {}
54   virtual ~ShellViewsDelegate() {}
55
56   // views::ViewsDelegate implementation.
57   virtual void OnBeforeWidgetInit(
58       views::Widget::InitParams* params,
59       views::internal::NativeWidgetDelegate* delegate) OVERRIDE {
60     if (!params->parent)
61       params->parent = root_window_;
62   }
63
64  private:
65   aura::Window* root_window_;
66
67   DISALLOW_COPY_AND_ASSIGN(ShellViewsDelegate);
68 };
69
70 }  // namespace
71
72 ShellBrowserMainParts::ShellBrowserMainParts(
73     const content::MainFunctionParams& parameters)
74     : extension_system_(NULL) {
75 }
76
77 ShellBrowserMainParts::~ShellBrowserMainParts() {
78 }
79
80 void ShellBrowserMainParts::PreMainMessageLoopStart() {
81   // TODO(jamescook): Initialize touch here?
82 }
83
84 void ShellBrowserMainParts::PostMainMessageLoopStart() {
85 }
86
87 void ShellBrowserMainParts::PreEarlyInitialization() {
88 }
89
90 int ShellBrowserMainParts::PreCreateThreads() {
91   // TODO(jamescook): Initialize chromeos::CrosSettings here?
92
93   // Return no error.
94   return 0;
95 }
96
97 void ShellBrowserMainParts::PreMainMessageLoopRun() {
98   // NOTE: Much of this is culled from chrome/test/base/chrome_test_suite.cc
99
100   // TODO(jamescook): Initialize chromeos::UserManager.
101
102   net_log_.reset(new content::ShellNetLog("app_shell"));
103
104   // Initialize our "profile" equivalent.
105   browser_context_.reset(new ShellBrowserContext);
106
107   extensions_client_.reset(new ShellExtensionsClient());
108   extensions::ExtensionsClient::Set(extensions_client_.get());
109
110   extensions_browser_client_.reset(
111       new extensions::ShellExtensionsBrowserClient(browser_context_.get()));
112   extensions::ExtensionsBrowserClient::Set(extensions_browser_client_.get());
113
114   // Create our custom ExtensionSystem first because other
115   // BrowserContextKeyedServices depend on it.
116   // TODO(yoz): Move this after EnsureBrowserContextKeyedServiceFactoriesBuilt.
117   CreateExtensionSystem();
118
119   EnsureBrowserContextKeyedServiceFactoriesBuilt();
120   BrowserContextDependencyManager::GetInstance()->CreateBrowserContextServices(
121       browser_context_.get());
122
123   devtools_delegate_.reset(
124       new content::ShellDevToolsDelegate(browser_context_.get()));
125
126   CreateRootWindow();
127   CreateViewsDelegate();
128
129   const std::string kAppSwitch = "app";
130   CommandLine* command_line = CommandLine::ForCurrentProcess();
131   if (command_line->HasSwitch(kAppSwitch)) {
132     base::FilePath app_dir(command_line->GetSwitchValueNative(kAppSwitch));
133     base::FilePath app_absolute_dir = base::MakeAbsoluteFilePath(app_dir);
134     extension_system_->LoadAndLaunchApp(app_absolute_dir);
135   } else {
136     // TODO(jamescook): For demo purposes create a window with a WebView just
137     // to ensure that the content module is properly initialized.
138     webview_window_.reset(CreateWebViewWindow(browser_context_.get(),
139         wm_test_helper_->root_window()->window()));
140     webview_window_->Show();
141   }
142 }
143
144 bool ShellBrowserMainParts::MainMessageLoopRun(int* result_code)  {
145   base::RunLoop run_loop;
146   run_loop.Run();
147   *result_code = content::RESULT_CODE_NORMAL_EXIT;
148   return true;
149 }
150
151 void ShellBrowserMainParts::PostMainMessageLoopRun() {
152   devtools_delegate_->Stop();
153   DestroyViewsDelegate();
154   DestroyRootWindow();
155   BrowserContextDependencyManager::GetInstance()->DestroyBrowserContextServices(
156       browser_context_.get());
157   extension_system_ = NULL;
158   extensions::ExtensionsBrowserClient::Set(NULL);
159   extensions_browser_client_.reset();
160   browser_context_.reset();
161   aura::Env::DeleteInstance();
162 }
163
164 void ShellBrowserMainParts::OnWindowTreeHostCloseRequested(
165     const aura::RootWindow* root) {
166   base::MessageLoop::current()->PostTask(FROM_HERE,
167                                          base::MessageLoop::QuitClosure());
168 }
169
170 void ShellBrowserMainParts::CreateRootWindow() {
171   test_screen_.reset(aura::TestScreen::Create());
172   // TODO(jamescook): Replace this with a real Screen implementation.
173   gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_NATIVE, test_screen_.get());
174   // TODO(jamescook): Initialize a real input method.
175   ui::InitializeInputMethodForTesting();
176   // Set up basic pieces of views::corewm.
177   wm_test_helper_.reset(new wm::WMTestHelper(gfx::Size(800, 600)));
178   // Ensure the X window gets mapped.
179   wm_test_helper_->root_window()->host()->Show();
180   // Watch for the user clicking the close box.
181   wm_test_helper_->root_window()->AddRootWindowObserver(this);
182 }
183
184 void ShellBrowserMainParts::DestroyRootWindow() {
185   // We should close widget before destroying root window.
186   webview_window_.reset();
187   wm_test_helper_->root_window()->RemoveRootWindowObserver(this);
188   wm_test_helper_->root_window()->PrepareForShutdown();
189   wm_test_helper_.reset();
190   ui::ShutdownInputMethodForTesting();
191 }
192
193 void ShellBrowserMainParts::CreateViewsDelegate() {
194   DCHECK(!views::ViewsDelegate::views_delegate);
195   views::ViewsDelegate::views_delegate =
196       new ShellViewsDelegate(wm_test_helper_->root_window()->window());
197 }
198
199 void ShellBrowserMainParts::DestroyViewsDelegate() {
200   delete views::ViewsDelegate::views_delegate;
201   views::ViewsDelegate::views_delegate = NULL;
202 }
203
204 void ShellBrowserMainParts::CreateExtensionSystem() {
205   DCHECK(browser_context_);
206   extension_system_ = static_cast<ShellExtensionSystem*>(
207       ExtensionSystem::Get(browser_context_.get()));
208   extension_system_->InitForRegularProfile(true);
209 }
210
211 }  // namespace apps