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