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 "content/shell/browser/shell_browser_main_parts.h"
6
7#include "base/base_switches.h"
8#include "base/bind.h"
9#include "base/command_line.h"
10#include "base/files/file_path.h"
11#include "base/message_loop/message_loop.h"
12#include "base/threading/thread.h"
13#include "base/threading/thread_restrictions.h"
14#include "content/public/browser/browser_thread.h"
15#include "content/public/browser/storage_partition.h"
16#include "content/public/common/content_switches.h"
17#include "content/public/common/main_function_params.h"
18#include "content/public/common/url_constants.h"
19#include "content/shell/browser/shell.h"
20#include "content/shell/browser/shell_browser_context.h"
21#include "content/shell/browser/shell_devtools_delegate.h"
22#include "content/shell/browser/shell_net_log.h"
23#include "content/shell/common/shell_switches.h"
24#include "net/base/filename_util.h"
25#include "net/base/net_module.h"
26#include "net/grit/net_resources.h"
27#include "storage/browser/quota/quota_manager.h"
28#include "ui/base/resource/resource_bundle.h"
29#include "url/gurl.h"
30
31#if defined(ENABLE_PLUGINS)
32#include "content/public/browser/plugin_service.h"
33#include "content/shell/browser/shell_plugin_service_filter.h"
34#endif
35
36#if defined(OS_ANDROID)
37#include "components/crash/browser/crash_dump_manager_android.h"
38#include "net/android/network_change_notifier_factory_android.h"
39#include "net/base/network_change_notifier.h"
40#endif
41
42#if defined(USE_AURA) && defined(USE_X11)
43#include "ui/events/x/touch_factory_x11.h"
44#endif
45#if !defined(OS_CHROMEOS) && defined(USE_AURA) && defined(OS_LINUX)
46#include "ui/base/ime/input_method_initializer.h"
47#endif
48
49namespace content {
50
51namespace {
52
53// Default quota for each origin is 5MB.
54const int kDefaultLayoutTestQuotaBytes = 5 * 1024 * 1024;
55
56GURL GetStartupURL() {
57  CommandLine* command_line = CommandLine::ForCurrentProcess();
58  if (command_line->HasSwitch(switches::kContentBrowserTest))
59    return GURL();
60  const CommandLine::StringVector& args = command_line->GetArgs();
61
62#if defined(OS_ANDROID)
63  // Delay renderer creation on Android until surface is ready.
64  return GURL();
65#endif
66
67  if (args.empty())
68    return GURL("http://www.google.com/");
69
70  GURL url(args[0]);
71  if (url.is_valid() && url.has_scheme())
72    return url;
73
74  return net::FilePathToFileURL(base::FilePath(args[0]));
75}
76
77base::StringPiece PlatformResourceProvider(int key) {
78  if (key == IDR_DIR_HEADER_HTML) {
79    base::StringPiece html_data =
80        ui::ResourceBundle::GetSharedInstance().GetRawDataResource(
81            IDR_DIR_HEADER_HTML);
82    return html_data;
83  }
84  return base::StringPiece();
85}
86
87}  // namespace
88
89ShellBrowserMainParts::ShellBrowserMainParts(
90    const MainFunctionParams& parameters)
91    : BrowserMainParts(), parameters_(parameters), run_message_loop_(true) {}
92
93ShellBrowserMainParts::~ShellBrowserMainParts() {
94}
95
96#if !defined(OS_MACOSX)
97void ShellBrowserMainParts::PreMainMessageLoopStart() {
98#if defined(USE_AURA) && defined(USE_X11)
99  ui::TouchFactory::SetTouchDeviceListFromCommandLine();
100#endif
101}
102#endif
103
104void ShellBrowserMainParts::PostMainMessageLoopStart() {
105#if defined(OS_ANDROID)
106  base::MessageLoopForUI::current()->Start();
107#endif
108}
109
110void ShellBrowserMainParts::PreEarlyInitialization() {
111#if !defined(OS_CHROMEOS) && defined(USE_AURA) && defined(OS_LINUX)
112  ui::InitializeInputMethodForTesting();
113#endif
114#if defined(OS_ANDROID)
115  net::NetworkChangeNotifier::SetFactory(
116      new net::NetworkChangeNotifierFactoryAndroid());
117#endif
118}
119
120void ShellBrowserMainParts::PreMainMessageLoopRun() {
121#if defined(OS_ANDROID)
122  if (CommandLine::ForCurrentProcess()->HasSwitch(
123          switches::kEnableCrashReporter)) {
124    base::FilePath crash_dumps_dir =
125        CommandLine::ForCurrentProcess()->GetSwitchValuePath(
126            switches::kCrashDumpsDir);
127    crash_dump_manager_.reset(new breakpad::CrashDumpManager(crash_dumps_dir));
128  }
129#endif
130  net_log_.reset(new ShellNetLog("content_shell"));
131  browser_context_.reset(new ShellBrowserContext(false, net_log_.get()));
132  off_the_record_browser_context_.reset(
133      new ShellBrowserContext(true, net_log_.get()));
134
135  Shell::Initialize();
136  net::NetModule::SetResourceProvider(PlatformResourceProvider);
137
138  devtools_delegate_.reset(new ShellDevToolsDelegate(browser_context_.get()));
139
140  if (!CommandLine::ForCurrentProcess()->HasSwitch(switches::kDumpRenderTree)) {
141    Shell::CreateNewWindow(browser_context_.get(),
142                           GetStartupURL(),
143                           NULL,
144                           MSG_ROUTING_NONE,
145                           gfx::Size());
146  }
147
148  if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kDumpRenderTree)) {
149    storage::QuotaManager* quota_manager =
150        BrowserContext::GetDefaultStoragePartition(browser_context())
151            ->GetQuotaManager();
152    BrowserThread::PostTask(
153        BrowserThread::IO,
154        FROM_HERE,
155        base::Bind(&storage::QuotaManager::SetTemporaryGlobalOverrideQuota,
156                   quota_manager,
157                   kDefaultLayoutTestQuotaBytes *
158                       storage::QuotaManager::kPerHostTemporaryPortion,
159                   storage::QuotaCallback()));
160#if defined(ENABLE_PLUGINS)
161    PluginService* plugin_service = PluginService::GetInstance();
162    plugin_service_filter_.reset(new ShellPluginServiceFilter);
163    plugin_service->SetFilter(plugin_service_filter_.get());
164#endif
165  }
166
167  if (parameters_.ui_task) {
168    parameters_.ui_task->Run();
169    delete parameters_.ui_task;
170    run_message_loop_ = false;
171  }
172}
173
174bool ShellBrowserMainParts::MainMessageLoopRun(int* result_code)  {
175  return !run_message_loop_;
176}
177
178void ShellBrowserMainParts::PostMainMessageLoopRun() {
179  if (devtools_delegate_)
180    devtools_delegate_->Stop();
181  browser_context_.reset();
182  off_the_record_browser_context_.reset();
183}
184
185}  // namespace
186