blob: d5f16617e55eb45ea26f2ed2653527fa8c0ccd49 [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]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]0b659b32012-03-26 21:29:3218#include "content/public/browser/render_view_host.h"
19#include "content/public/browser/web_contents.h"
[email protected]7fff43e2013-05-21 20:21:1020#include "content/public/browser/web_contents_observer.h"
[email protected]ed245db2012-12-18 08:00:4521#include "content/public/browser/web_contents_view.h"
[email protected]1596efb2013-01-17 22:13:0122#include "content/public/common/renderer_preferences.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
[email protected]7fff43e2013-05-21 20:21:1042class Shell::DevToolsWebContentsObserver : public WebContentsObserver {
43 public:
44 DevToolsWebContentsObserver(Shell* shell, WebContents* web_contents)
45 : WebContentsObserver(web_contents),
46 shell_(shell) {
47 }
48
49 // WebContentsObserver
50 virtual void WebContentsDestroyed(WebContents* web_contents) OVERRIDE {
51 shell_->OnDevToolsWebContentsDestroyed();
52 }
53
54 private:
55 Shell* shell_;
56
57 DISALLOW_COPY_AND_ASSIGN(DevToolsWebContentsObserver);
58};
59
[email protected]0b659b32012-03-26 21:29:3260Shell::Shell(WebContents* web_contents)
[email protected]1ef02d242013-10-07 16:18:5361 : WebContentsObserver(web_contents),
62 devtools_frontend_(NULL),
[email protected]001841c92012-12-11 17:00:1363 is_fullscreen_(false),
[email protected]99c014c2012-11-27 12:03:4264 window_(NULL),
[email protected]86b36e672012-12-21 00:09:5165 url_edit_view_(NULL),
[email protected]86b36e672012-12-21 00:09:5166 headless_(false) {
67 const CommandLine& command_line = *CommandLine::ForCurrentProcess();
[email protected]28cc78e2013-06-13 09:05:4668 if (command_line.HasSwitch(switches::kDumpRenderTree))
[email protected]86b36e672012-12-21 00:09:5169 headless_ = true;
[email protected]9e00e6352012-07-30 17:05:1870 windows_.push_back(this);
71
72 if (!shell_created_callback_.is_null()) {
73 shell_created_callback_.Run(this);
74 shell_created_callback_.Reset();
75 }
[email protected]9fbd3f862011-09-20 23:31:3476}
77
78Shell::~Shell() {
79 PlatformCleanUp();
[email protected]e99ca5112011-09-26 17:22:5480
81 for (size_t i = 0; i < windows_.size(); ++i) {
82 if (windows_[i] == this) {
83 windows_.erase(windows_.begin() + i);
84 break;
85 }
86 }
[email protected]11a65b692012-03-30 11:29:1687
[email protected]b53adf452014-02-07 12:55:0888 if (windows_.empty() && quit_message_loop_) {
89 if (headless_)
90 PlatformExit();
[email protected]dd32b1272013-05-04 14:17:1191 base::MessageLoop::current()->PostTask(FROM_HERE,
92 base::MessageLoop::QuitClosure());
[email protected]b53adf452014-02-07 12:55:0893 }
[email protected]9fbd3f862011-09-20 23:31:3494}
95
[email protected]c0d036d2013-05-07 12:50:5096Shell* Shell::CreateShell(WebContents* web_contents,
97 const gfx::Size& initial_size) {
[email protected]0b659b32012-03-26 21:29:3298 Shell* shell = new Shell(web_contents);
[email protected]c0d036d2013-05-07 12:50:5099 shell->PlatformCreateWindow(initial_size.width(), initial_size.height());
[email protected]3fd84032012-01-12 18:20:17100
[email protected]0b659b32012-03-26 21:29:32101 shell->web_contents_.reset(web_contents);
102 web_contents->SetDelegate(shell);
[email protected]3fd84032012-01-12 18:20:17103
[email protected]5cba3bf2012-01-14 02:40:35104 shell->PlatformSetContents();
[email protected]3fd84032012-01-12 18:20:17105
106 shell->PlatformResizeSubViews();
[email protected]1596efb2013-01-17 22:13:01107
108 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kDumpRenderTree)) {
109 web_contents->GetMutableRendererPrefs()->use_custom_colors = false;
110 web_contents->GetRenderViewHost()->SyncRendererPrefs();
111 }
112
[email protected]3fd84032012-01-12 18:20:17113 return shell;
114}
115
[email protected]11a65b692012-03-30 11:29:16116void Shell::CloseAllWindows() {
[email protected]997ec9f2012-11-21 04:44:14117 base::AutoReset<bool> auto_reset(&quit_message_loop_, false);
[email protected]e641ea692013-01-28 10:39:23118 DevToolsManager::GetInstance()->CloseAllClientHosts();
[email protected]11a65b692012-03-30 11:29:16119 std::vector<Shell*> open_windows(windows_);
120 for (size_t i = 0; i < open_windows.size(); ++i)
121 open_windows[i]->Close();
[email protected]4249a422013-11-27 19:04:04122 PlatformExit();
[email protected]dd32b1272013-05-04 14:17:11123 base::MessageLoop::current()->RunUntilIdle();
[email protected]11a65b692012-03-30 11:29:16124}
125
[email protected]9e00e6352012-07-30 17:05:18126void Shell::SetShellCreatedCallback(
127 base::Callback<void(Shell*)> shell_created_callback) {
128 DCHECK(shell_created_callback_.is_null());
129 shell_created_callback_ = shell_created_callback;
130}
131
[email protected]74830f02012-01-30 22:27:04132Shell* Shell::FromRenderViewHost(RenderViewHost* rvh) {
133 for (size_t i = 0; i < windows_.size(); ++i) {
[email protected]0b659b32012-03-26 21:29:32134 if (windows_[i]->web_contents() &&
135 windows_[i]->web_contents()->GetRenderViewHost() == rvh) {
[email protected]74830f02012-01-30 22:27:04136 return windows_[i];
137 }
138 }
139 return NULL;
140}
141
[email protected]6153b272013-01-25 22:29:23142// static
143void Shell::Initialize() {
[email protected]1e57cab2013-05-28 04:26:11144 PlatformInitialize(
145 gfx::Size(kDefaultTestWindowWidthDip, kDefaultTestWindowHeightDip));
[email protected]6153b272013-01-25 22:29:23146}
147
[email protected]a2904092013-10-15 04:53:59148gfx::Size Shell::AdjustWindowSize(const gfx::Size& initial_size) {
149 if (!initial_size.IsEmpty())
150 return initial_size;
151 return gfx::Size(kDefaultTestWindowWidthDip, kDefaultTestWindowHeightDip);
152}
153
[email protected]bdcf9152012-07-19 17:43:21154Shell* Shell::CreateNewWindow(BrowserContext* browser_context,
[email protected]e99ca5112011-09-26 17:22:54155 const GURL& url,
156 SiteInstance* site_instance,
157 int routing_id,
[email protected]cdb806722013-01-10 14:18:23158 const gfx::Size& initial_size) {
[email protected]54944cde2012-12-09 09:24:59159 WebContents::CreateParams create_params(browser_context, site_instance);
160 create_params.routing_id = routing_id;
[email protected]a2904092013-10-15 04:53:59161 create_params.initial_size = AdjustWindowSize(initial_size);
[email protected]54944cde2012-12-09 09:24:59162 WebContents* web_contents = WebContents::Create(create_params);
[email protected]c0d036d2013-05-07 12:50:50163 Shell* shell = CreateShell(web_contents, create_params.initial_size);
[email protected]e99ca5112011-09-26 17:22:54164 if (!url.is_empty())
165 shell->LoadURL(url);
[email protected]9fbd3f862011-09-20 23:31:34166 return shell;
167}
168
169void Shell::LoadURL(const GURL& url) {
[email protected]d2494ff2013-02-20 08:22:37170 LoadURLForFrame(url, std::string());
171}
172
173void Shell::LoadURLForFrame(const GURL& url, const std::string& frame_name) {
174 NavigationController::LoadURLParams params(url);
175 params.transition_type = PageTransitionFromInt(
176 PAGE_TRANSITION_TYPED | PAGE_TRANSITION_FROM_ADDRESS_BAR);
177 params.frame_name = frame_name;
178 web_contents_->GetController().LoadURLWithParams(params);
[email protected]f3615f02013-02-26 06:09:06179 web_contents_->GetView()->Focus();
[email protected]9fbd3f862011-09-20 23:31:34180}
181
[email protected]a2904092013-10-15 04:53:59182void Shell::AddNewContents(WebContents* source,
183 WebContents* new_contents,
184 WindowOpenDisposition disposition,
185 const gfx::Rect& initial_pos,
186 bool user_gesture,
187 bool* was_blocked) {
188 CreateShell(new_contents, AdjustWindowSize(initial_pos.size()));
189 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kDumpRenderTree))
190 NotifyDoneForwarder::CreateForWebContents(new_contents);
191}
192
[email protected]9fbd3f862011-09-20 23:31:34193void Shell::GoBackOrForward(int offset) {
[email protected]0b659b32012-03-26 21:29:32194 web_contents_->GetController().GoToOffset(offset);
[email protected]f3615f02013-02-26 06:09:06195 web_contents_->GetView()->Focus();
[email protected]9fbd3f862011-09-20 23:31:34196}
197
198void Shell::Reload() {
[email protected]0b659b32012-03-26 21:29:32199 web_contents_->GetController().Reload(false);
[email protected]f3615f02013-02-26 06:09:06200 web_contents_->GetView()->Focus();
[email protected]9fbd3f862011-09-20 23:31:34201}
202
203void Shell::Stop() {
[email protected]0b659b32012-03-26 21:29:32204 web_contents_->Stop();
[email protected]f3615f02013-02-26 06:09:06205 web_contents_->GetView()->Focus();
[email protected]9fbd3f862011-09-20 23:31:34206}
207
208void Shell::UpdateNavigationControls() {
[email protected]0b659b32012-03-26 21:29:32209 int current_index = web_contents_->GetController().GetCurrentEntryIndex();
210 int max_index = web_contents_->GetController().GetEntryCount() - 1;
[email protected]9fbd3f862011-09-20 23:31:34211
212 PlatformEnableUIControl(BACK_BUTTON, current_index > 0);
213 PlatformEnableUIControl(FORWARD_BUTTON, current_index < max_index);
[email protected]0b659b32012-03-26 21:29:32214 PlatformEnableUIControl(STOP_BUTTON, web_contents_->IsLoading());
[email protected]9fbd3f862011-09-20 23:31:34215}
216
[email protected]7c17b6992012-08-09 16:16:30217void Shell::ShowDevTools() {
[email protected]3142e5d2014-02-07 00:54:46218 ShowDevToolsForElementAt(-1, -1);
219}
220
221void Shell::ShowDevToolsForElementAt(int x, int y) {
[email protected]0773e0c2013-01-25 15:57:57222 if (devtools_frontend_) {
223 devtools_frontend_->Focus();
[email protected]001841c92012-12-11 17:00:13224 return;
225 }
[email protected]3142e5d2014-02-07 00:54:46226 devtools_frontend_ = ShellDevToolsFrontend::ShowForElementAt(
227 web_contents(), x, y);
[email protected]7fff43e2013-05-21 20:21:10228 devtools_observer_.reset(new DevToolsWebContentsObserver(
229 this, devtools_frontend_->frontend_shell()->web_contents()));
[email protected]7c17b6992012-08-09 16:16:30230}
231
[email protected]001841c92012-12-11 17:00:13232void Shell::CloseDevTools() {
[email protected]0773e0c2013-01-25 15:57:57233 if (!devtools_frontend_)
[email protected]001841c92012-12-11 17:00:13234 return;
[email protected]7fff43e2013-05-21 20:21:10235 devtools_observer_.reset();
[email protected]0773e0c2013-01-25 15:57:57236 devtools_frontend_->Close();
237 devtools_frontend_ = NULL;
[email protected]001841c92012-12-11 17:00:13238}
239
[email protected]9fbd3f862011-09-20 23:31:34240gfx::NativeView Shell::GetContentView() {
[email protected]59383c782013-04-17 16:43:27241 if (!web_contents_)
[email protected]9fbd3f862011-09-20 23:31:34242 return NULL;
[email protected]f3615f02013-02-26 06:09:06243 return web_contents_->GetView()->GetNativeView();
[email protected]9fbd3f862011-09-20 23:31:34244}
245
[email protected]9e00e6352012-07-30 17:05:18246WebContents* Shell::OpenURLFromTab(WebContents* source,
247 const OpenURLParams& params) {
[email protected]7cf38302013-08-29 12:23:46248 // CURRENT_TAB is the only one we implement for now.
249 if (params.disposition != CURRENT_TAB)
250 return NULL;
[email protected]fbaccee2013-08-12 23:24:02251 NavigationController::LoadURLParams load_url_params(params.url);
252 load_url_params.referrer = params.referrer;
[email protected]c80297782013-11-21 07:10:16253 load_url_params.frame_tree_node_id = params.frame_tree_node_id;
[email protected]fbaccee2013-08-12 23:24:02254 load_url_params.transition_type = params.transition;
255 load_url_params.extra_headers = params.extra_headers;
256 load_url_params.should_replace_current_entry =
257 params.should_replace_current_entry;
258
259 if (params.transferred_global_request_id != GlobalRequestID()) {
260 load_url_params.is_renderer_initiated = params.is_renderer_initiated;
261 load_url_params.transferred_global_request_id =
262 params.transferred_global_request_id;
263 } else if (params.is_renderer_initiated) {
264 load_url_params.is_renderer_initiated = true;
265 }
266
267 source->GetController().LoadURLWithParams(load_url_params);
[email protected]9e00e6352012-07-30 17:05:18268 return source;
269}
270
[email protected]2a6bc3e2011-12-28 23:51:33271void Shell::LoadingStateChanged(WebContents* source) {
[email protected]e99ca5112011-09-26 17:22:54272 UpdateNavigationControls();
[email protected]15aea412012-01-19 03:18:50273 PlatformSetIsLoading(source->IsLoading());
[email protected]e99ca5112011-09-26 17:22:54274}
275
[email protected]99c014c2012-11-27 12:03:42276void Shell::ToggleFullscreenModeForTab(WebContents* web_contents,
277 bool enter_fullscreen) {
278#if defined(OS_ANDROID)
279 PlatformToggleFullscreenModeForTab(web_contents, enter_fullscreen);
280#endif
281 if (!CommandLine::ForCurrentProcess()->HasSwitch(switches::kDumpRenderTree))
282 return;
283 if (is_fullscreen_ != enter_fullscreen) {
284 is_fullscreen_ = enter_fullscreen;
285 web_contents->GetRenderViewHost()->WasResized();
286 }
287}
288
289bool Shell::IsFullscreenForTabOrPending(const WebContents* web_contents) const {
290#if defined(OS_ANDROID)
291 return PlatformIsFullscreenForTabOrPending(web_contents);
292#else
293 return is_fullscreen_;
294#endif
295}
296
[email protected]f78439002012-11-28 14:45:59297void Shell::RequestToLockMouse(WebContents* web_contents,
298 bool user_gesture,
299 bool last_unlocked_by_target) {
300 web_contents->GotResponseToLockMouseRequest(true);
301}
302
[email protected]9e00e6352012-07-30 17:05:18303void Shell::CloseContents(WebContents* source) {
304 Close();
305}
306
[email protected]067310262012-11-22 14:30:41307bool Shell::CanOverscrollContent() const {
308#if defined(USE_AURA)
309 return true;
310#else
311 return false;
312#endif
313}
314
[email protected]3bbacc5b2012-04-17 17:46:15315void Shell::DidNavigateMainFramePostCommit(WebContents* web_contents) {
[email protected]4e3c7522013-08-13 11:53:18316 PlatformSetAddressBarURL(web_contents->GetLastCommittedURL());
[email protected]e99ca5112011-09-26 17:22:54317}
318
[email protected]71a88bb2013-02-01 22:05:15319JavaScriptDialogManager* Shell::GetJavaScriptDialogManager() {
[email protected]59383c782013-04-17 16:43:27320 if (!dialog_manager_)
[email protected]71a88bb2013-02-01 22:05:15321 dialog_manager_.reset(new ShellJavaScriptDialogManager());
322 return dialog_manager_.get();
[email protected]f2210022012-03-29 00:36:08323}
324
[email protected]c272c5b2012-06-06 09:01:06325bool Shell::AddMessageToConsole(WebContents* source,
326 int32 level,
[email protected]fcf75d42013-12-03 20:11:26327 const base::string16& message,
[email protected]c272c5b2012-06-06 09:01:06328 int32 line_no,
[email protected]fcf75d42013-12-03 20:11:26329 const base::string16& source_id) {
[email protected]55a5cd12013-01-28 15:24:23330 return CommandLine::ForCurrentProcess()->HasSwitch(switches::kDumpRenderTree);
[email protected]efb5f572012-01-29 10:57:33331}
332
[email protected]5bf68f22012-08-31 07:38:10333void Shell::RendererUnresponsive(WebContents* source) {
334 if (!CommandLine::ForCurrentProcess()->HasSwitch(switches::kDumpRenderTree))
335 return;
336 WebKitTestController::Get()->RendererUnresponsive();
337}
338
[email protected]233567d2013-02-27 20:22:02339void Shell::ActivateContents(WebContents* contents) {
340 contents->GetRenderViewHost()->Focus();
341}
342
343void Shell::DeactivateContents(WebContents* contents) {
344 contents->GetRenderViewHost()->Blur();
345}
346
[email protected]3eeacfa62013-07-23 09:23:15347void Shell::WorkerCrashed(WebContents* source) {
348 if (!CommandLine::ForCurrentProcess()->HasSwitch(switches::kDumpRenderTree))
349 return;
350 WebKitTestController::Get()->WorkerCrashed();
351}
352
[email protected]3142e5d2014-02-07 00:54:46353bool Shell::HandleContextMenu(const content::ContextMenuParams& params) {
354 return PlatformHandleContextMenu(params);
355}
356
[email protected]1ef02d242013-10-07 16:18:53357void Shell::TitleWasSet(NavigationEntry* entry, bool explicit_set) {
358 if (entry)
359 PlatformSetTitle(entry->GetTitle());
[email protected]aecc085b2012-06-01 18:15:53360}
361
[email protected]7fff43e2013-05-21 20:21:10362void Shell::OnDevToolsWebContentsDestroyed() {
363 devtools_observer_.reset();
364 devtools_frontend_ = NULL;
365}
366
[email protected]9fbd3f862011-09-20 23:31:34367} // namespace content