blob: 0175bfe04f63deda0da4258dac5dc08a3ee83bb1 [file] [log] [blame]
[email protected]5cba3bf2012-01-14 02:40:351// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]9fbd3f862011-09-20 23:31:342// 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.h"
6
[email protected]11a65b692012-03-30 11:29:167#include "base/auto_reset.h"
[email protected]efb5f572012-01-29 10:57:338#include "base/command_line.h"
[email protected]aaf68892013-07-18 00:11:309#include "base/message_loop/message_loop.h"
[email protected]9fbd3f862011-09-20 23:31:3410#include "base/path_service.h"
[email protected]21aa99682013-06-11 07:17:0111#include "base/strings/string_number_conversions.h"
12#include "base/strings/string_util.h"
13#include "base/strings/stringprintf.h"
[email protected]74ebfb12013-06-07 20:48:0014#include "base/strings/utf_string_conversions.h"
[email protected]e641ea692013-01-28 10:39:2315#include "content/public/browser/devtools_manager.h"
[email protected]0b659b32012-03-26 21:29:3216#include "content/public/browser/navigation_controller.h"
[email protected]b7c504c2013-05-07 14:42:1217#include "content/public/browser/navigation_entry.h"
[email protected]aecc085b2012-06-01 18:15:5318#include "content/public/browser/notification_details.h"
19#include "content/public/browser/notification_source.h"
20#include "content/public/browser/notification_types.h"
[email protected]0b659b32012-03-26 21:29:3221#include "content/public/browser/render_view_host.h"
22#include "content/public/browser/web_contents.h"
[email protected]7fff43e2013-05-21 20:21:1023#include "content/public/browser/web_contents_observer.h"
[email protected]ed245db2012-12-18 08:00:4524#include "content/public/browser/web_contents_view.h"
[email protected]1596efb2013-01-17 22:13:0125#include "content/public/common/renderer_preferences.h"
[email protected]b7c504c2013-05-07 14:42:1226#include "content/shell/common/shell_messages.h"
27#include "content/shell/common/shell_switches.h"
[email protected]1ca4fac2013-04-08 14:15:1128#include "content/shell/notify_done_forwarder.h"
[email protected]7c17b6992012-08-09 16:16:3029#include "content/shell/shell_browser_main_parts.h"
30#include "content/shell/shell_content_browser_client.h"
[email protected]0773e0c2013-01-25 15:57:5731#include "content/shell/shell_devtools_frontend.h"
[email protected]71a88bb2013-02-01 22:05:1532#include "content/shell/shell_javascript_dialog_manager.h"
[email protected]8dafad32012-12-10 14:11:4533#include "content/shell/webkit_test_controller.h"
[email protected]9fbd3f862011-09-20 23:31:3434
[email protected]9fbd3f862011-09-20 23:31:3435namespace content {
36
[email protected]1e57cab2013-05-28 04:26:1137const int Shell::kDefaultTestWindowWidthDip = 800;
38const int Shell::kDefaultTestWindowHeightDip = 600;
39
[email protected]e99ca5112011-09-26 17:22:5440std::vector<Shell*> Shell::windows_;
[email protected]9e00e6352012-07-30 17:05:1841base::Callback<void(Shell*)> Shell::shell_created_callback_;
[email protected]9fbd3f862011-09-20 23:31:3442
[email protected]11a65b692012-03-30 11:29:1643bool Shell::quit_message_loop_ = true;
44
[email protected]7fff43e2013-05-21 20:21:1045class Shell::DevToolsWebContentsObserver : public WebContentsObserver {
46 public:
47 DevToolsWebContentsObserver(Shell* shell, WebContents* web_contents)
48 : WebContentsObserver(web_contents),
49 shell_(shell) {
50 }
51
52 // WebContentsObserver
53 virtual void WebContentsDestroyed(WebContents* web_contents) OVERRIDE {
54 shell_->OnDevToolsWebContentsDestroyed();
55 }
56
57 private:
58 Shell* shell_;
59
60 DISALLOW_COPY_AND_ASSIGN(DevToolsWebContentsObserver);
61};
62
[email protected]0b659b32012-03-26 21:29:3263Shell::Shell(WebContents* web_contents)
[email protected]0773e0c2013-01-25 15:57:5764 : devtools_frontend_(NULL),
[email protected]001841c92012-12-11 17:00:1365 is_fullscreen_(false),
[email protected]99c014c2012-11-27 12:03:4266 window_(NULL),
[email protected]86b36e672012-12-21 00:09:5167 url_edit_view_(NULL),
[email protected]fa4a45832012-04-12 21:32:4868#if defined(OS_WIN) && !defined(USE_AURA)
[email protected]86b36e672012-12-21 00:09:5169 default_edit_wnd_proc_(0),
[email protected]9fbd3f862011-09-20 23:31:3470#endif
[email protected]86b36e672012-12-21 00:09:5171 headless_(false) {
72 const CommandLine& command_line = *CommandLine::ForCurrentProcess();
[email protected]28cc78e2013-06-13 09:05:4673 if (command_line.HasSwitch(switches::kDumpRenderTree))
[email protected]86b36e672012-12-21 00:09:5174 headless_ = true;
[email protected]9e00e6352012-07-30 17:05:1875 registrar_.Add(this, NOTIFICATION_WEB_CONTENTS_TITLE_UPDATED,
76 Source<WebContents>(web_contents));
77 windows_.push_back(this);
78
79 if (!shell_created_callback_.is_null()) {
80 shell_created_callback_.Run(this);
81 shell_created_callback_.Reset();
82 }
[email protected]9fbd3f862011-09-20 23:31:3483}
84
85Shell::~Shell() {
86 PlatformCleanUp();
[email protected]e99ca5112011-09-26 17:22:5487
88 for (size_t i = 0; i < windows_.size(); ++i) {
89 if (windows_[i] == this) {
90 windows_.erase(windows_.begin() + i);
91 break;
92 }
93 }
[email protected]11a65b692012-03-30 11:29:1694
95 if (windows_.empty() && quit_message_loop_)
[email protected]dd32b1272013-05-04 14:17:1196 base::MessageLoop::current()->PostTask(FROM_HERE,
97 base::MessageLoop::QuitClosure());
[email protected]9fbd3f862011-09-20 23:31:3498}
99
[email protected]c0d036d2013-05-07 12:50:50100Shell* Shell::CreateShell(WebContents* web_contents,
101 const gfx::Size& initial_size) {
[email protected]0b659b32012-03-26 21:29:32102 Shell* shell = new Shell(web_contents);
[email protected]c0d036d2013-05-07 12:50:50103 shell->PlatformCreateWindow(initial_size.width(), initial_size.height());
[email protected]3fd84032012-01-12 18:20:17104
[email protected]0b659b32012-03-26 21:29:32105 shell->web_contents_.reset(web_contents);
106 web_contents->SetDelegate(shell);
[email protected]3fd84032012-01-12 18:20:17107
[email protected]5cba3bf2012-01-14 02:40:35108 shell->PlatformSetContents();
[email protected]3fd84032012-01-12 18:20:17109
110 shell->PlatformResizeSubViews();
[email protected]1596efb2013-01-17 22:13:01111
112 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kDumpRenderTree)) {
113 web_contents->GetMutableRendererPrefs()->use_custom_colors = false;
114 web_contents->GetRenderViewHost()->SyncRendererPrefs();
115 }
116
[email protected]3fd84032012-01-12 18:20:17117 return shell;
118}
119
[email protected]11a65b692012-03-30 11:29:16120void Shell::CloseAllWindows() {
[email protected]997ec9f2012-11-21 04:44:14121 base::AutoReset<bool> auto_reset(&quit_message_loop_, false);
[email protected]e641ea692013-01-28 10:39:23122 DevToolsManager::GetInstance()->CloseAllClientHosts();
[email protected]11a65b692012-03-30 11:29:16123 std::vector<Shell*> open_windows(windows_);
124 for (size_t i = 0; i < open_windows.size(); ++i)
125 open_windows[i]->Close();
[email protected]dd32b1272013-05-04 14:17:11126 base::MessageLoop::current()->RunUntilIdle();
[email protected]11a65b692012-03-30 11:29:16127}
128
[email protected]9e00e6352012-07-30 17:05:18129void Shell::SetShellCreatedCallback(
130 base::Callback<void(Shell*)> shell_created_callback) {
131 DCHECK(shell_created_callback_.is_null());
132 shell_created_callback_ = shell_created_callback;
133}
134
[email protected]74830f02012-01-30 22:27:04135Shell* Shell::FromRenderViewHost(RenderViewHost* rvh) {
136 for (size_t i = 0; i < windows_.size(); ++i) {
[email protected]0b659b32012-03-26 21:29:32137 if (windows_[i]->web_contents() &&
138 windows_[i]->web_contents()->GetRenderViewHost() == rvh) {
[email protected]74830f02012-01-30 22:27:04139 return windows_[i];
140 }
141 }
142 return NULL;
143}
144
[email protected]6153b272013-01-25 22:29:23145// static
146void Shell::Initialize() {
[email protected]1e57cab2013-05-28 04:26:11147 PlatformInitialize(
148 gfx::Size(kDefaultTestWindowWidthDip, kDefaultTestWindowHeightDip));
[email protected]6153b272013-01-25 22:29:23149}
150
[email protected]bdcf9152012-07-19 17:43:21151Shell* Shell::CreateNewWindow(BrowserContext* browser_context,
[email protected]e99ca5112011-09-26 17:22:54152 const GURL& url,
153 SiteInstance* site_instance,
154 int routing_id,
[email protected]cdb806722013-01-10 14:18:23155 const gfx::Size& initial_size) {
[email protected]54944cde2012-12-09 09:24:59156 WebContents::CreateParams create_params(browser_context, site_instance);
157 create_params.routing_id = routing_id;
[email protected]cdb806722013-01-10 14:18:23158 if (!initial_size.IsEmpty())
159 create_params.initial_size = initial_size;
160 else
[email protected]1e57cab2013-05-28 04:26:11161 create_params.initial_size =
162 gfx::Size(kDefaultTestWindowWidthDip, kDefaultTestWindowHeightDip);
[email protected]54944cde2012-12-09 09:24:59163 WebContents* web_contents = WebContents::Create(create_params);
[email protected]c0d036d2013-05-07 12:50:50164 Shell* shell = CreateShell(web_contents, create_params.initial_size);
[email protected]e99ca5112011-09-26 17:22:54165 if (!url.is_empty())
166 shell->LoadURL(url);
[email protected]9fbd3f862011-09-20 23:31:34167 return shell;
168}
169
170void Shell::LoadURL(const GURL& url) {
[email protected]d2494ff2013-02-20 08:22:37171 LoadURLForFrame(url, std::string());
172}
173
174void Shell::LoadURLForFrame(const GURL& url, const std::string& frame_name) {
175 NavigationController::LoadURLParams params(url);
176 params.transition_type = PageTransitionFromInt(
177 PAGE_TRANSITION_TYPED | PAGE_TRANSITION_FROM_ADDRESS_BAR);
178 params.frame_name = frame_name;
179 web_contents_->GetController().LoadURLWithParams(params);
[email protected]f3615f02013-02-26 06:09:06180 web_contents_->GetView()->Focus();
[email protected]9fbd3f862011-09-20 23:31:34181}
182
183void Shell::GoBackOrForward(int offset) {
[email protected]0b659b32012-03-26 21:29:32184 web_contents_->GetController().GoToOffset(offset);
[email protected]f3615f02013-02-26 06:09:06185 web_contents_->GetView()->Focus();
[email protected]9fbd3f862011-09-20 23:31:34186}
187
188void Shell::Reload() {
[email protected]0b659b32012-03-26 21:29:32189 web_contents_->GetController().Reload(false);
[email protected]f3615f02013-02-26 06:09:06190 web_contents_->GetView()->Focus();
[email protected]9fbd3f862011-09-20 23:31:34191}
192
193void Shell::Stop() {
[email protected]0b659b32012-03-26 21:29:32194 web_contents_->Stop();
[email protected]f3615f02013-02-26 06:09:06195 web_contents_->GetView()->Focus();
[email protected]9fbd3f862011-09-20 23:31:34196}
197
198void Shell::UpdateNavigationControls() {
[email protected]0b659b32012-03-26 21:29:32199 int current_index = web_contents_->GetController().GetCurrentEntryIndex();
200 int max_index = web_contents_->GetController().GetEntryCount() - 1;
[email protected]9fbd3f862011-09-20 23:31:34201
202 PlatformEnableUIControl(BACK_BUTTON, current_index > 0);
203 PlatformEnableUIControl(FORWARD_BUTTON, current_index < max_index);
[email protected]0b659b32012-03-26 21:29:32204 PlatformEnableUIControl(STOP_BUTTON, web_contents_->IsLoading());
[email protected]9fbd3f862011-09-20 23:31:34205}
206
[email protected]7c17b6992012-08-09 16:16:30207void Shell::ShowDevTools() {
[email protected]0773e0c2013-01-25 15:57:57208 if (devtools_frontend_) {
209 devtools_frontend_->Focus();
[email protected]001841c92012-12-11 17:00:13210 return;
211 }
[email protected]0773e0c2013-01-25 15:57:57212 devtools_frontend_ = ShellDevToolsFrontend::Show(web_contents());
[email protected]7fff43e2013-05-21 20:21:10213 devtools_observer_.reset(new DevToolsWebContentsObserver(
214 this, devtools_frontend_->frontend_shell()->web_contents()));
[email protected]7c17b6992012-08-09 16:16:30215}
216
[email protected]001841c92012-12-11 17:00:13217void Shell::CloseDevTools() {
[email protected]0773e0c2013-01-25 15:57:57218 if (!devtools_frontend_)
[email protected]001841c92012-12-11 17:00:13219 return;
[email protected]7fff43e2013-05-21 20:21:10220 devtools_observer_.reset();
[email protected]0773e0c2013-01-25 15:57:57221 devtools_frontend_->Close();
222 devtools_frontend_ = NULL;
[email protected]001841c92012-12-11 17:00:13223}
224
[email protected]9fbd3f862011-09-20 23:31:34225gfx::NativeView Shell::GetContentView() {
[email protected]59383c782013-04-17 16:43:27226 if (!web_contents_)
[email protected]9fbd3f862011-09-20 23:31:34227 return NULL;
[email protected]f3615f02013-02-26 06:09:06228 return web_contents_->GetView()->GetNativeView();
[email protected]9fbd3f862011-09-20 23:31:34229}
230
[email protected]9e00e6352012-07-30 17:05:18231WebContents* Shell::OpenURLFromTab(WebContents* source,
232 const OpenURLParams& params) {
233 // The only one we implement for now.
234 DCHECK(params.disposition == CURRENT_TAB);
235 source->GetController().LoadURL(
236 params.url, params.referrer, params.transition, std::string());
237 return source;
238}
239
[email protected]2a6bc3e2011-12-28 23:51:33240void Shell::LoadingStateChanged(WebContents* source) {
[email protected]e99ca5112011-09-26 17:22:54241 UpdateNavigationControls();
[email protected]15aea412012-01-19 03:18:50242 PlatformSetIsLoading(source->IsLoading());
[email protected]e99ca5112011-09-26 17:22:54243}
244
[email protected]99c014c2012-11-27 12:03:42245void Shell::ToggleFullscreenModeForTab(WebContents* web_contents,
246 bool enter_fullscreen) {
247#if defined(OS_ANDROID)
248 PlatformToggleFullscreenModeForTab(web_contents, enter_fullscreen);
249#endif
250 if (!CommandLine::ForCurrentProcess()->HasSwitch(switches::kDumpRenderTree))
251 return;
252 if (is_fullscreen_ != enter_fullscreen) {
253 is_fullscreen_ = enter_fullscreen;
254 web_contents->GetRenderViewHost()->WasResized();
255 }
256}
257
258bool Shell::IsFullscreenForTabOrPending(const WebContents* web_contents) const {
259#if defined(OS_ANDROID)
260 return PlatformIsFullscreenForTabOrPending(web_contents);
261#else
262 return is_fullscreen_;
263#endif
264}
265
[email protected]f78439002012-11-28 14:45:59266void Shell::RequestToLockMouse(WebContents* web_contents,
267 bool user_gesture,
268 bool last_unlocked_by_target) {
269 web_contents->GotResponseToLockMouseRequest(true);
270}
271
[email protected]9e00e6352012-07-30 17:05:18272void Shell::CloseContents(WebContents* source) {
273 Close();
274}
275
[email protected]067310262012-11-22 14:30:41276bool Shell::CanOverscrollContent() const {
277#if defined(USE_AURA)
278 return true;
279#else
280 return false;
281#endif
282}
283
[email protected]3fd84032012-01-12 18:20:17284void Shell::WebContentsCreated(WebContents* source_contents,
285 int64 source_frame_id,
[email protected]50de3222013-03-20 15:36:13286 const string16& frame_name,
[email protected]3fd84032012-01-12 18:20:17287 const GURL& target_url,
288 WebContents* new_contents) {
[email protected]c0d036d2013-05-07 12:50:50289 CreateShell(new_contents, source_contents->GetView()->GetContainerSize());
[email protected]1ca4fac2013-04-08 14:15:11290 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kDumpRenderTree))
291 NotifyDoneForwarder::CreateForWebContents(new_contents);
[email protected]3fd84032012-01-12 18:20:17292}
293
[email protected]3bbacc5b2012-04-17 17:46:15294void Shell::DidNavigateMainFramePostCommit(WebContents* web_contents) {
295 PlatformSetAddressBarURL(web_contents->GetURL());
[email protected]e99ca5112011-09-26 17:22:54296}
297
[email protected]71a88bb2013-02-01 22:05:15298JavaScriptDialogManager* Shell::GetJavaScriptDialogManager() {
[email protected]59383c782013-04-17 16:43:27299 if (!dialog_manager_)
[email protected]71a88bb2013-02-01 22:05:15300 dialog_manager_.reset(new ShellJavaScriptDialogManager());
301 return dialog_manager_.get();
[email protected]f2210022012-03-29 00:36:08302}
303
[email protected]c272c5b2012-06-06 09:01:06304bool Shell::AddMessageToConsole(WebContents* source,
305 int32 level,
306 const string16& message,
307 int32 line_no,
308 const string16& source_id) {
[email protected]55a5cd12013-01-28 15:24:23309 return CommandLine::ForCurrentProcess()->HasSwitch(switches::kDumpRenderTree);
[email protected]efb5f572012-01-29 10:57:33310}
311
[email protected]5bf68f22012-08-31 07:38:10312void Shell::RendererUnresponsive(WebContents* source) {
313 if (!CommandLine::ForCurrentProcess()->HasSwitch(switches::kDumpRenderTree))
314 return;
315 WebKitTestController::Get()->RendererUnresponsive();
316}
317
[email protected]233567d2013-02-27 20:22:02318void Shell::ActivateContents(WebContents* contents) {
319 contents->GetRenderViewHost()->Focus();
320}
321
322void Shell::DeactivateContents(WebContents* contents) {
323 contents->GetRenderViewHost()->Blur();
324}
325
[email protected]3eeacfa62013-07-23 09:23:15326void Shell::WorkerCrashed(WebContents* source) {
327 if (!CommandLine::ForCurrentProcess()->HasSwitch(switches::kDumpRenderTree))
328 return;
329 WebKitTestController::Get()->WorkerCrashed();
330}
331
[email protected]aecc085b2012-06-01 18:15:53332void Shell::Observe(int type,
333 const NotificationSource& source,
334 const NotificationDetails& details) {
335 if (type == NOTIFICATION_WEB_CONTENTS_TITLE_UPDATED) {
336 std::pair<NavigationEntry*, bool>* title =
337 Details<std::pair<NavigationEntry*, bool> >(details).ptr();
338
339 if (title->first) {
340 string16 text = title->first->GetTitle();
341 PlatformSetTitle(text);
342 }
[email protected]d212efd2013-04-15 13:03:06343 } else {
344 NOTREACHED();
[email protected]aecc085b2012-06-01 18:15:53345 }
346}
347
[email protected]7fff43e2013-05-21 20:21:10348void Shell::OnDevToolsWebContentsDestroyed() {
349 devtools_observer_.reset();
350 devtools_frontend_ = NULL;
351}
352
[email protected]9fbd3f862011-09-20 23:31:34353} // namespace content