blob: 0c8f7e246ba3fe6789eb7449dbe144c6b22156af [file] [log] [blame]
[email protected]de7d61ff2013-08-20 11:30:411// Copyright 2013 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
[email protected]de7d61ff2013-08-20 11:30:415#include "content/shell/browser/shell.h"
[email protected]9fbd3f862011-09-20 23:31:346
[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]21aa99682013-06-11 07:17:0110#include "base/strings/string_number_conversions.h"
11#include "base/strings/string_util.h"
12#include "base/strings/stringprintf.h"
[email protected]74ebfb12013-06-07 20:48:0013#include "base/strings/utf_string_conversions.h"
[email protected]b50452f2014-08-18 12:31:4414#include "content/public/browser/devtools_agent_host.h"
[email protected]0b659b32012-03-26 21:29:3215#include "content/public/browser/navigation_controller.h"
[email protected]b7c504c2013-05-07 14:42:1216#include "content/public/browser/navigation_entry.h"
[email protected]0b659b32012-03-26 21:29:3217#include "content/public/browser/render_view_host.h"
18#include "content/public/browser/web_contents.h"
[email protected]7fff43e2013-05-21 20:21:1019#include "content/public/browser/web_contents_observer.h"
[email protected]1596efb2013-01-17 22:13:0120#include "content/public/common/renderer_preferences.h"
mkwst30d20d52014-10-09 13:33:1421#include "content/shell/browser/layout_test/layout_test_devtools_frontend.h"
mkwst6efe7f2e62014-10-08 15:09:0122#include "content/shell/browser/layout_test/layout_test_javascript_dialog_manager.h"
[email protected]de7d61ff2013-08-20 11:30:4123#include "content/shell/browser/notify_done_forwarder.h"
24#include "content/shell/browser/shell_browser_main_parts.h"
25#include "content/shell/browser/shell_content_browser_client.h"
26#include "content/shell/browser/shell_devtools_frontend.h"
27#include "content/shell/browser/shell_javascript_dialog_manager.h"
28#include "content/shell/browser/webkit_test_controller.h"
[email protected]b7c504c2013-05-07 14:42:1229#include "content/shell/common/shell_messages.h"
30#include "content/shell/common/shell_switches.h"
[email protected]9fbd3f862011-09-20 23:31:3431
[email protected]9fbd3f862011-09-20 23:31:3432namespace content {
33
[email protected]1e57cab2013-05-28 04:26:1134const int Shell::kDefaultTestWindowWidthDip = 800;
35const int Shell::kDefaultTestWindowHeightDip = 600;
36
[email protected]e99ca5112011-09-26 17:22:5437std::vector<Shell*> Shell::windows_;
[email protected]9e00e6352012-07-30 17:05:1838base::Callback<void(Shell*)> Shell::shell_created_callback_;
[email protected]9fbd3f862011-09-20 23:31:3439
[email protected]11a65b692012-03-30 11:29:1640bool Shell::quit_message_loop_ = true;
41
arurajku168b0ac2014-12-15 19:36:2842namespace {
43gfx::Size ShellDefaultSize() {
44 static gfx::Size default_shell_size;
45 if (!default_shell_size.IsEmpty())
46 return default_shell_size;
47 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
48 if (command_line->HasSwitch(switches::kContentShellHostWindowSize)) {
49 const std::string size_str = command_line->GetSwitchValueASCII(
50 switches::kContentShellHostWindowSize);
51 int width, height;
52 CHECK_EQ(2, sscanf(size_str.c_str(), "%dx%d", &width, &height));
53 default_shell_size = gfx::Size(width, height);
54 } else {
55 default_shell_size = gfx::Size(
56 Shell::kDefaultTestWindowWidthDip, Shell::kDefaultTestWindowHeightDip);
57 }
58 return default_shell_size;
59}
60} // namespace
61
[email protected]7fff43e2013-05-21 20:21:1062class Shell::DevToolsWebContentsObserver : public WebContentsObserver {
63 public:
64 DevToolsWebContentsObserver(Shell* shell, WebContents* web_contents)
65 : WebContentsObserver(web_contents),
66 shell_(shell) {
67 }
68
69 // WebContentsObserver
dchenge933b3e2014-10-21 11:44:0970 void WebContentsDestroyed() override {
[email protected]7fff43e2013-05-21 20:21:1071 shell_->OnDevToolsWebContentsDestroyed();
72 }
73
74 private:
75 Shell* shell_;
76
77 DISALLOW_COPY_AND_ASSIGN(DevToolsWebContentsObserver);
78};
79
[email protected]0b659b32012-03-26 21:29:3280Shell::Shell(WebContents* web_contents)
[email protected]1ef02d242013-10-07 16:18:5381 : WebContentsObserver(web_contents),
82 devtools_frontend_(NULL),
[email protected]001841c92012-12-11 17:00:1383 is_fullscreen_(false),
[email protected]99c014c2012-11-27 12:03:4284 window_(NULL),
[email protected]86b36e672012-12-21 00:09:5185 url_edit_view_(NULL),
[email protected]86b36e672012-12-21 00:09:5186 headless_(false) {
87 const CommandLine& command_line = *CommandLine::ForCurrentProcess();
[email protected]28cc78e2013-06-13 09:05:4688 if (command_line.HasSwitch(switches::kDumpRenderTree))
[email protected]86b36e672012-12-21 00:09:5189 headless_ = true;
[email protected]9e00e6352012-07-30 17:05:1890 windows_.push_back(this);
91
92 if (!shell_created_callback_.is_null()) {
93 shell_created_callback_.Run(this);
94 shell_created_callback_.Reset();
95 }
[email protected]9fbd3f862011-09-20 23:31:3496}
97
98Shell::~Shell() {
99 PlatformCleanUp();
[email protected]e99ca5112011-09-26 17:22:54100
101 for (size_t i = 0; i < windows_.size(); ++i) {
102 if (windows_[i] == this) {
103 windows_.erase(windows_.begin() + i);
104 break;
105 }
106 }
[email protected]11a65b692012-03-30 11:29:16107
[email protected]b53adf452014-02-07 12:55:08108 if (windows_.empty() && quit_message_loop_) {
109 if (headless_)
110 PlatformExit();
[email protected]dd32b1272013-05-04 14:17:11111 base::MessageLoop::current()->PostTask(FROM_HERE,
112 base::MessageLoop::QuitClosure());
[email protected]b53adf452014-02-07 12:55:08113 }
[email protected]9fbd3f862011-09-20 23:31:34114}
115
[email protected]c0d036d2013-05-07 12:50:50116Shell* Shell::CreateShell(WebContents* web_contents,
117 const gfx::Size& initial_size) {
[email protected]0b659b32012-03-26 21:29:32118 Shell* shell = new Shell(web_contents);
[email protected]c0d036d2013-05-07 12:50:50119 shell->PlatformCreateWindow(initial_size.width(), initial_size.height());
[email protected]3fd84032012-01-12 18:20:17120
[email protected]0b659b32012-03-26 21:29:32121 shell->web_contents_.reset(web_contents);
122 web_contents->SetDelegate(shell);
[email protected]3fd84032012-01-12 18:20:17123
[email protected]5cba3bf2012-01-14 02:40:35124 shell->PlatformSetContents();
[email protected]3fd84032012-01-12 18:20:17125
126 shell->PlatformResizeSubViews();
[email protected]1596efb2013-01-17 22:13:01127
128 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kDumpRenderTree)) {
129 web_contents->GetMutableRendererPrefs()->use_custom_colors = false;
130 web_contents->GetRenderViewHost()->SyncRendererPrefs();
131 }
132
[email protected]3fd84032012-01-12 18:20:17133 return shell;
134}
135
[email protected]11a65b692012-03-30 11:29:16136void Shell::CloseAllWindows() {
[email protected]997ec9f2012-11-21 04:44:14137 base::AutoReset<bool> auto_reset(&quit_message_loop_, false);
[email protected]b50452f2014-08-18 12:31:44138 DevToolsAgentHost::DetachAllClients();
[email protected]11a65b692012-03-30 11:29:16139 std::vector<Shell*> open_windows(windows_);
140 for (size_t i = 0; i < open_windows.size(); ++i)
141 open_windows[i]->Close();
[email protected]4249a422013-11-27 19:04:04142 PlatformExit();
[email protected]dd32b1272013-05-04 14:17:11143 base::MessageLoop::current()->RunUntilIdle();
[email protected]11a65b692012-03-30 11:29:16144}
145
[email protected]9e00e6352012-07-30 17:05:18146void Shell::SetShellCreatedCallback(
147 base::Callback<void(Shell*)> shell_created_callback) {
148 DCHECK(shell_created_callback_.is_null());
149 shell_created_callback_ = shell_created_callback;
150}
151
[email protected]74830f02012-01-30 22:27:04152Shell* Shell::FromRenderViewHost(RenderViewHost* rvh) {
153 for (size_t i = 0; i < windows_.size(); ++i) {
[email protected]0b659b32012-03-26 21:29:32154 if (windows_[i]->web_contents() &&
155 windows_[i]->web_contents()->GetRenderViewHost() == rvh) {
[email protected]74830f02012-01-30 22:27:04156 return windows_[i];
157 }
158 }
159 return NULL;
160}
161
[email protected]6153b272013-01-25 22:29:23162// static
163void Shell::Initialize() {
arurajku168b0ac2014-12-15 19:36:28164 PlatformInitialize(ShellDefaultSize());
[email protected]6153b272013-01-25 22:29:23165}
166
[email protected]a2904092013-10-15 04:53:59167gfx::Size Shell::AdjustWindowSize(const gfx::Size& initial_size) {
168 if (!initial_size.IsEmpty())
169 return initial_size;
arurajku168b0ac2014-12-15 19:36:28170 return ShellDefaultSize();
[email protected]a2904092013-10-15 04:53:59171}
172
[email protected]bdcf9152012-07-19 17:43:21173Shell* Shell::CreateNewWindow(BrowserContext* browser_context,
[email protected]e99ca5112011-09-26 17:22:54174 const GURL& url,
175 SiteInstance* site_instance,
[email protected]cdb806722013-01-10 14:18:23176 const gfx::Size& initial_size) {
[email protected]54944cde2012-12-09 09:24:59177 WebContents::CreateParams create_params(browser_context, site_instance);
[email protected]a2904092013-10-15 04:53:59178 create_params.initial_size = AdjustWindowSize(initial_size);
[email protected]54944cde2012-12-09 09:24:59179 WebContents* web_contents = WebContents::Create(create_params);
[email protected]c0d036d2013-05-07 12:50:50180 Shell* shell = CreateShell(web_contents, create_params.initial_size);
[email protected]e99ca5112011-09-26 17:22:54181 if (!url.is_empty())
182 shell->LoadURL(url);
[email protected]9fbd3f862011-09-20 23:31:34183 return shell;
184}
185
186void Shell::LoadURL(const GURL& url) {
[email protected]d2494ff2013-02-20 08:22:37187 LoadURLForFrame(url, std::string());
188}
189
190void Shell::LoadURLForFrame(const GURL& url, const std::string& frame_name) {
191 NavigationController::LoadURLParams params(url);
Sylvain Defresnec6ccc77d2014-09-19 10:19:35192 params.transition_type = ui::PageTransitionFromInt(
193 ui::PAGE_TRANSITION_TYPED | ui::PAGE_TRANSITION_FROM_ADDRESS_BAR);
[email protected]d2494ff2013-02-20 08:22:37194 params.frame_name = frame_name;
195 web_contents_->GetController().LoadURLWithParams(params);
[email protected]fc2b46b2014-05-03 16:33:45196 web_contents_->Focus();
[email protected]9fbd3f862011-09-20 23:31:34197}
198
[email protected]76bdecb2014-04-16 17:58:08199void Shell::LoadDataWithBaseURL(const GURL& url, const std::string& data,
200 const GURL& base_url) {
201 const GURL data_url = GURL("data:text/html;charset=utf-8," + data);
202 NavigationController::LoadURLParams params(data_url);
203 params.load_type = NavigationController::LOAD_TYPE_DATA;
204 params.base_url_for_data_url = base_url;
205 params.virtual_url_for_data_url = url;
206 params.override_user_agent = NavigationController::UA_OVERRIDE_FALSE;
207 web_contents_->GetController().LoadURLWithParams(params);
[email protected]fc2b46b2014-05-03 16:33:45208 web_contents_->Focus();
[email protected]76bdecb2014-04-16 17:58:08209}
210
[email protected]a2904092013-10-15 04:53:59211void Shell::AddNewContents(WebContents* source,
212 WebContents* new_contents,
213 WindowOpenDisposition disposition,
214 const gfx::Rect& initial_pos,
215 bool user_gesture,
216 bool* was_blocked) {
217 CreateShell(new_contents, AdjustWindowSize(initial_pos.size()));
218 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kDumpRenderTree))
219 NotifyDoneForwarder::CreateForWebContents(new_contents);
220}
221
[email protected]9fbd3f862011-09-20 23:31:34222void Shell::GoBackOrForward(int offset) {
[email protected]0b659b32012-03-26 21:29:32223 web_contents_->GetController().GoToOffset(offset);
[email protected]fc2b46b2014-05-03 16:33:45224 web_contents_->Focus();
[email protected]9fbd3f862011-09-20 23:31:34225}
226
227void Shell::Reload() {
[email protected]0b659b32012-03-26 21:29:32228 web_contents_->GetController().Reload(false);
[email protected]fc2b46b2014-05-03 16:33:45229 web_contents_->Focus();
[email protected]9fbd3f862011-09-20 23:31:34230}
231
232void Shell::Stop() {
[email protected]0b659b32012-03-26 21:29:32233 web_contents_->Stop();
[email protected]fc2b46b2014-05-03 16:33:45234 web_contents_->Focus();
[email protected]9fbd3f862011-09-20 23:31:34235}
236
[email protected]e3b10d12014-03-28 16:06:09237void Shell::UpdateNavigationControls(bool to_different_document) {
[email protected]0b659b32012-03-26 21:29:32238 int current_index = web_contents_->GetController().GetCurrentEntryIndex();
239 int max_index = web_contents_->GetController().GetEntryCount() - 1;
[email protected]9fbd3f862011-09-20 23:31:34240
241 PlatformEnableUIControl(BACK_BUTTON, current_index > 0);
242 PlatformEnableUIControl(FORWARD_BUTTON, current_index < max_index);
[email protected]e3b10d12014-03-28 16:06:09243 PlatformEnableUIControl(STOP_BUTTON,
244 to_different_document && web_contents_->IsLoading());
[email protected]9fbd3f862011-09-20 23:31:34245}
246
[email protected]7c17b6992012-08-09 16:16:30247void Shell::ShowDevTools() {
[email protected]06c253012014-04-16 18:35:33248 InnerShowDevTools("", "");
[email protected]3142e5d2014-02-07 00:54:46249}
250
251void Shell::ShowDevToolsForElementAt(int x, int y) {
[email protected]06c253012014-04-16 18:35:33252 InnerShowDevTools("", "");
[email protected]2317fcd2014-02-10 14:36:48253 devtools_frontend_->InspectElementAt(x, y);
[email protected]7c17b6992012-08-09 16:16:30254}
255
[email protected]06c253012014-04-16 18:35:33256void Shell::ShowDevToolsForTest(const std::string& settings,
257 const std::string& frontend_url) {
258 InnerShowDevTools(settings, frontend_url);
[email protected]fee9eca02014-02-14 19:24:40259}
260
[email protected]001841c92012-12-11 17:00:13261void Shell::CloseDevTools() {
[email protected]0773e0c2013-01-25 15:57:57262 if (!devtools_frontend_)
[email protected]001841c92012-12-11 17:00:13263 return;
[email protected]7fff43e2013-05-21 20:21:10264 devtools_observer_.reset();
[email protected]0773e0c2013-01-25 15:57:57265 devtools_frontend_->Close();
266 devtools_frontend_ = NULL;
[email protected]001841c92012-12-11 17:00:13267}
268
[email protected]9fbd3f862011-09-20 23:31:34269gfx::NativeView Shell::GetContentView() {
[email protected]59383c782013-04-17 16:43:27270 if (!web_contents_)
[email protected]9fbd3f862011-09-20 23:31:34271 return NULL;
[email protected]fc2b46b2014-05-03 16:33:45272 return web_contents_->GetNativeView();
[email protected]9fbd3f862011-09-20 23:31:34273}
274
[email protected]9e00e6352012-07-30 17:05:18275WebContents* Shell::OpenURLFromTab(WebContents* source,
276 const OpenURLParams& params) {
[email protected]7cf38302013-08-29 12:23:46277 // CURRENT_TAB is the only one we implement for now.
278 if (params.disposition != CURRENT_TAB)
279 return NULL;
[email protected]fbaccee2013-08-12 23:24:02280 NavigationController::LoadURLParams load_url_params(params.url);
lfg9ef7d2d2014-12-15 22:32:30281 load_url_params.source_site_instance = params.source_site_instance;
[email protected]fbaccee2013-08-12 23:24:02282 load_url_params.referrer = params.referrer;
[email protected]c80297782013-11-21 07:10:16283 load_url_params.frame_tree_node_id = params.frame_tree_node_id;
[email protected]fbaccee2013-08-12 23:24:02284 load_url_params.transition_type = params.transition;
285 load_url_params.extra_headers = params.extra_headers;
286 load_url_params.should_replace_current_entry =
287 params.should_replace_current_entry;
288
289 if (params.transferred_global_request_id != GlobalRequestID()) {
290 load_url_params.is_renderer_initiated = params.is_renderer_initiated;
291 load_url_params.transferred_global_request_id =
292 params.transferred_global_request_id;
293 } else if (params.is_renderer_initiated) {
294 load_url_params.is_renderer_initiated = true;
295 }
296
297 source->GetController().LoadURLWithParams(load_url_params);
[email protected]9e00e6352012-07-30 17:05:18298 return source;
299}
300
[email protected]e3b10d12014-03-28 16:06:09301void Shell::LoadingStateChanged(WebContents* source,
302 bool to_different_document) {
303 UpdateNavigationControls(to_different_document);
[email protected]15aea412012-01-19 03:18:50304 PlatformSetIsLoading(source->IsLoading());
[email protected]e99ca5112011-09-26 17:22:54305}
306
[email protected]99c014c2012-11-27 12:03:42307void Shell::ToggleFullscreenModeForTab(WebContents* web_contents,
308 bool enter_fullscreen) {
309#if defined(OS_ANDROID)
310 PlatformToggleFullscreenModeForTab(web_contents, enter_fullscreen);
311#endif
312 if (!CommandLine::ForCurrentProcess()->HasSwitch(switches::kDumpRenderTree))
313 return;
314 if (is_fullscreen_ != enter_fullscreen) {
315 is_fullscreen_ = enter_fullscreen;
316 web_contents->GetRenderViewHost()->WasResized();
317 }
318}
319
320bool Shell::IsFullscreenForTabOrPending(const WebContents* web_contents) const {
321#if defined(OS_ANDROID)
322 return PlatformIsFullscreenForTabOrPending(web_contents);
323#else
324 return is_fullscreen_;
325#endif
326}
327
[email protected]f78439002012-11-28 14:45:59328void Shell::RequestToLockMouse(WebContents* web_contents,
329 bool user_gesture,
330 bool last_unlocked_by_target) {
331 web_contents->GotResponseToLockMouseRequest(true);
332}
333
[email protected]9e00e6352012-07-30 17:05:18334void Shell::CloseContents(WebContents* source) {
335 Close();
336}
337
[email protected]067310262012-11-22 14:30:41338bool Shell::CanOverscrollContent() const {
339#if defined(USE_AURA)
340 return true;
341#else
342 return false;
343#endif
344}
345
[email protected]3bbacc5b2012-04-17 17:46:15346void Shell::DidNavigateMainFramePostCommit(WebContents* web_contents) {
[email protected]4e3c7522013-08-13 11:53:18347 PlatformSetAddressBarURL(web_contents->GetLastCommittedURL());
[email protected]e99ca5112011-09-26 17:22:54348}
349
mathiash72a5e462014-11-19 08:18:50350JavaScriptDialogManager* Shell::GetJavaScriptDialogManager(
351 WebContents* source) {
mkwst6efe7f2e62014-10-08 15:09:01352 if (!dialog_manager_) {
353 const CommandLine& command_line = *CommandLine::ForCurrentProcess();
354 dialog_manager_.reset(command_line.HasSwitch(switches::kDumpRenderTree)
355 ? new LayoutTestJavaScriptDialogManager
356 : new ShellJavaScriptDialogManager);
357 }
[email protected]71a88bb2013-02-01 22:05:15358 return dialog_manager_.get();
[email protected]f2210022012-03-29 00:36:08359}
360
[email protected]c272c5b2012-06-06 09:01:06361bool Shell::AddMessageToConsole(WebContents* source,
362 int32 level,
[email protected]fcf75d42013-12-03 20:11:26363 const base::string16& message,
[email protected]c272c5b2012-06-06 09:01:06364 int32 line_no,
[email protected]fcf75d42013-12-03 20:11:26365 const base::string16& source_id) {
[email protected]55a5cd12013-01-28 15:24:23366 return CommandLine::ForCurrentProcess()->HasSwitch(switches::kDumpRenderTree);
[email protected]efb5f572012-01-29 10:57:33367}
368
[email protected]5bf68f22012-08-31 07:38:10369void Shell::RendererUnresponsive(WebContents* source) {
370 if (!CommandLine::ForCurrentProcess()->HasSwitch(switches::kDumpRenderTree))
371 return;
372 WebKitTestController::Get()->RendererUnresponsive();
373}
374
[email protected]233567d2013-02-27 20:22:02375void Shell::ActivateContents(WebContents* contents) {
376 contents->GetRenderViewHost()->Focus();
377}
378
379void Shell::DeactivateContents(WebContents* contents) {
380 contents->GetRenderViewHost()->Blur();
381}
382
[email protected]3eeacfa62013-07-23 09:23:15383void Shell::WorkerCrashed(WebContents* source) {
384 if (!CommandLine::ForCurrentProcess()->HasSwitch(switches::kDumpRenderTree))
385 return;
386 WebKitTestController::Get()->WorkerCrashed();
387}
388
[email protected]3142e5d2014-02-07 00:54:46389bool Shell::HandleContextMenu(const content::ContextMenuParams& params) {
390 return PlatformHandleContextMenu(params);
391}
392
[email protected]d0bb9952014-02-10 20:58:26393void Shell::WebContentsFocused(WebContents* contents) {
394#if defined(TOOLKIT_VIEWS)
395 PlatformWebContentsFocused(contents);
396#endif
397}
398
[email protected]1ef02d242013-10-07 16:18:53399void Shell::TitleWasSet(NavigationEntry* entry, bool explicit_set) {
400 if (entry)
401 PlatformSetTitle(entry->GetTitle());
[email protected]aecc085b2012-06-01 18:15:53402}
403
[email protected]06c253012014-04-16 18:35:33404void Shell::InnerShowDevTools(const std::string& settings,
405 const std::string& frontend_url) {
[email protected]fee9eca02014-02-14 19:24:40406 if (!devtools_frontend_) {
mkwst30d20d52014-10-09 13:33:14407 if (CommandLine::ForCurrentProcess()->HasSwitch(
408 switches::kDumpRenderTree)) {
409 devtools_frontend_ = LayoutTestDevToolsFrontend::Show(
410 web_contents(), settings, frontend_url);
411 } else {
412 devtools_frontend_ = ShellDevToolsFrontend::Show(web_contents());
413 }
[email protected]fee9eca02014-02-14 19:24:40414 devtools_observer_.reset(new DevToolsWebContentsObserver(
415 this, devtools_frontend_->frontend_shell()->web_contents()));
416 }
417
418 devtools_frontend_->Activate();
419 devtools_frontend_->Focus();
420}
421
[email protected]7fff43e2013-05-21 20:21:10422void Shell::OnDevToolsWebContentsDestroyed() {
423 devtools_observer_.reset();
424 devtools_frontend_ = NULL;
425}
426
[email protected]9fbd3f862011-09-20 23:31:34427} // namespace content