blob: b4898b0681590fdc5ee5ca897baf338246f3d95b [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
avi66a07722015-12-25 23:38:127#include <stddef.h>
8
Lukasz Anforowicz52b93722018-06-20 16:11:399#include <map>
10#include <string>
11#include <utility>
12
[email protected]efb5f572012-01-29 10:57:3313#include "base/command_line.h"
skyostil95082a62015-06-05 19:53:0714#include "base/location.h"
avi66a07722015-12-25 23:38:1215#include "base/macros.h"
Wez9a58a152018-06-07 18:59:3316#include "base/no_destructor.h"
fdoray896bea12016-06-10 15:52:0117#include "base/run_loop.h"
skyostil95082a62015-06-05 19:53:0718#include "base/single_thread_task_runner.h"
[email protected]21aa99682013-06-11 07:17:0119#include "base/strings/string_number_conversions.h"
20#include "base/strings/string_util.h"
21#include "base/strings/stringprintf.h"
[email protected]74ebfb12013-06-07 20:48:0022#include "base/strings/utf_string_conversions.h"
gab30f26df2016-05-11 19:37:5523#include "base/threading/thread_task_runner_handle.h"
avi66a07722015-12-25 23:38:1224#include "build/build_config.h"
[email protected]b50452f2014-08-18 12:31:4425#include "content/public/browser/devtools_agent_host.h"
[email protected]0b659b32012-03-26 21:29:3226#include "content/public/browser/navigation_controller.h"
[email protected]b7c504c2013-05-07 14:42:1227#include "content/public/browser/navigation_entry.h"
Yutaka Hirano2109e582018-02-14 07:24:4628#include "content/public/browser/render_process_host.h"
[email protected]0b659b32012-03-26 21:29:3229#include "content/public/browser/render_view_host.h"
avif9ab5d942015-10-15 14:05:4430#include "content/public/browser/render_widget_host.h"
[email protected]0b659b32012-03-26 21:29:3231#include "content/public/browser/web_contents.h"
guoweis8efb6d892015-10-12 18:26:1732#include "content/public/common/content_switches.h"
[email protected]1596efb2013-01-17 22:13:0133#include "content/public/common/renderer_preferences.h"
guoweisc537ba22015-11-06 21:20:3134#include "content/public/common/webrtc_ip_handling_policy.h"
jochen5ce1af92016-02-17 20:39:4535#include "content/shell/browser/layout_test/blink_test_controller.h"
jyasskin8057c002015-09-10 19:09:5336#include "content/shell/browser/layout_test/layout_test_bluetooth_chooser_factory.h"
chenwilliamfed5bda2017-03-24 02:01:0637#include "content/shell/browser/layout_test/layout_test_devtools_bindings.h"
mkwst6efe7f2e62014-10-08 15:09:0138#include "content/shell/browser/layout_test/layout_test_javascript_dialog_manager.h"
lukasza8e550a02016-04-18 18:34:1739#include "content/shell/browser/layout_test/secondary_test_window_observer.h"
[email protected]de7d61ff2013-08-20 11:30:4140#include "content/shell/browser/shell_browser_main_parts.h"
41#include "content/shell/browser/shell_content_browser_client.h"
42#include "content/shell/browser/shell_devtools_frontend.h"
43#include "content/shell/browser/shell_javascript_dialog_manager.h"
carloskd9d97942017-02-16 08:58:0944#include "content/shell/common/layout_test/layout_test_switches.h"
[email protected]b7c504c2013-05-07 14:42:1245#include "content/shell/common/shell_messages.h"
46#include "content/shell/common/shell_switches.h"
Scott Violeta35f9a42018-03-22 22:00:4447#include "media/media_buildflags.h"
Blink Reformata30d4232018-04-07 15:31:0648#include "third_party/blink/public/web/web_presentation_receiver_flags.h"
[email protected]9fbd3f862011-09-20 23:31:3449
[email protected]9fbd3f862011-09-20 23:31:3450namespace content {
51
Wezcbf4a042018-06-13 16:29:1252// Null until/unless the default main message loop is running.
53base::NoDestructor<base::OnceClosure> g_quit_main_message_loop;
Wez9a58a152018-06-07 18:59:3354
pdrcab84ee2015-03-13 21:47:0455const int kDefaultTestWindowWidthDip = 800;
56const int kDefaultTestWindowHeightDip = 600;
[email protected]1e57cab2013-05-28 04:26:1157
[email protected]e99ca5112011-09-26 17:22:5458std::vector<Shell*> Shell::windows_;
[email protected]9e00e6352012-07-30 17:05:1859base::Callback<void(Shell*)> Shell::shell_created_callback_;
[email protected]9fbd3f862011-09-20 23:31:3460
[email protected]7fff43e2013-05-21 20:21:1061class Shell::DevToolsWebContentsObserver : public WebContentsObserver {
62 public:
63 DevToolsWebContentsObserver(Shell* shell, WebContents* web_contents)
64 : WebContentsObserver(web_contents),
65 shell_(shell) {
66 }
67
68 // WebContentsObserver
dchenge933b3e2014-10-21 11:44:0969 void WebContentsDestroyed() override {
[email protected]7fff43e2013-05-21 20:21:1070 shell_->OnDevToolsWebContentsDestroyed();
71 }
72
73 private:
74 Shell* shell_;
75
76 DISALLOW_COPY_AND_ASSIGN(DevToolsWebContentsObserver);
77};
78
Bo Liu300c6052018-06-12 04:46:0779Shell::Shell(std::unique_ptr<WebContents> web_contents,
80 bool should_set_delegate)
erikchenbee5c9622018-04-27 19:30:2581 : WebContentsObserver(web_contents.get()),
82 web_contents_(std::move(web_contents)),
Ivan Kotenkov2c0d2bb32017-11-01 15:41:2883 devtools_frontend_(nullptr),
[email protected]001841c92012-12-11 17:00:1384 is_fullscreen_(false),
Ivan Kotenkov2c0d2bb32017-11-01 15:41:2885 window_(nullptr),
sadrul8b11d262015-11-12 18:41:3386#if defined(OS_MACOSX)
[email protected]86b36e672012-12-21 00:09:5187 url_edit_view_(NULL),
sadrul8b11d262015-11-12 18:41:3388#endif
Pavel Feldmanc7cd063c2017-10-06 20:04:2889 headless_(false),
90 hide_toolbar_(false) {
Bo Liu300c6052018-06-12 04:46:0791 if (should_set_delegate)
92 web_contents_->SetDelegate(this);
arthursonzognifdd49912017-08-31 08:55:2693
Kent Tamuracd3ebc42018-05-16 06:44:2294 if (switches::IsRunWebTestsSwitchPresent()) {
[email protected]86b36e672012-12-21 00:09:5195 headless_ = true;
Francois Doraye6161152018-03-27 22:05:3796 // In a headless shell, disable occlusion tracking. Otherwise, WebContents
97 // would always behave as if they were occluded, i.e. would not render
98 // frames and would not receive input events.
99 base::CommandLine::ForCurrentProcess()->AppendSwitch(
100 switches::kDisableBackgroundingOccludedWindowsForTesting);
101 }
Pavel Feldmanc7cd063c2017-10-06 20:04:28102
103 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
104 switches::kContentShellHideToolbar))
105 hide_toolbar_ = true;
106
[email protected]9e00e6352012-07-30 17:05:18107 windows_.push_back(this);
108
109 if (!shell_created_callback_.is_null()) {
110 shell_created_callback_.Run(this);
111 shell_created_callback_.Reset();
112 }
[email protected]9fbd3f862011-09-20 23:31:34113}
114
115Shell::~Shell() {
116 PlatformCleanUp();
[email protected]e99ca5112011-09-26 17:22:54117
118 for (size_t i = 0; i < windows_.size(); ++i) {
119 if (windows_[i] == this) {
120 windows_.erase(windows_.begin() + i);
121 break;
122 }
123 }
[email protected]11a65b692012-03-30 11:29:16124
Wez9a58a152018-06-07 18:59:33125 if (windows_.empty()) {
[email protected]b53adf452014-02-07 12:55:08126 if (headless_)
127 PlatformExit();
Yutaka Hirano2109e582018-02-14 07:24:46128 for (auto it = RenderProcessHost::AllHostsIterator(); !it.IsAtEnd();
129 it.Advance()) {
130 it.GetCurrentValue()->DisableKeepAliveRefCount();
131 }
Wezcbf4a042018-06-13 16:29:12132 if (*g_quit_main_message_loop)
133 std::move(*g_quit_main_message_loop).Run();
[email protected]b53adf452014-02-07 12:55:08134 }
arthursonzognifdd49912017-08-31 08:55:26135
136 web_contents_->SetDelegate(nullptr);
[email protected]9fbd3f862011-09-20 23:31:34137}
138
erikchenbee5c9622018-04-27 19:30:25139Shell* Shell::CreateShell(std::unique_ptr<WebContents> web_contents,
Bo Liu300c6052018-06-12 04:46:07140 const gfx::Size& initial_size,
141 bool should_set_delegate) {
erikchenbee5c9622018-04-27 19:30:25142 WebContents* raw_web_contents = web_contents.get();
Bo Liu300c6052018-06-12 04:46:07143 Shell* shell = new Shell(std::move(web_contents), should_set_delegate);
[email protected]c0d036d2013-05-07 12:50:50144 shell->PlatformCreateWindow(initial_size.width(), initial_size.height());
[email protected]3fd84032012-01-12 18:20:17145
[email protected]5cba3bf2012-01-14 02:40:35146 shell->PlatformSetContents();
[email protected]3fd84032012-01-12 18:20:17147
148 shell->PlatformResizeSubViews();
[email protected]1596efb2013-01-17 22:13:01149
creisb6561df2016-02-11 20:20:54150 // Note: Do not make RenderFrameHost or RenderViewHost specific state changes
151 // here, because they will be forgotten after a cross-process navigation. Use
152 // RenderFrameCreated or RenderViewCreated instead.
Kent Tamuracd3ebc42018-05-16 06:44:22153 if (switches::IsRunWebTestsSwitchPresent()) {
erikchenbee5c9622018-04-27 19:30:25154 raw_web_contents->GetMutableRendererPrefs()->use_custom_colors = false;
155 raw_web_contents->GetRenderViewHost()->SyncRendererPrefs();
[email protected]1596efb2013-01-17 22:13:01156 }
157
lukasza381b0492016-03-10 16:48:43158 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
guoweis4ee48592015-12-02 06:37:07159 if (command_line->HasSwitch(switches::kForceWebRtcIPHandlingPolicy)) {
erikchenbee5c9622018-04-27 19:30:25160 raw_web_contents->GetMutableRendererPrefs()->webrtc_ip_handling_policy =
guoweis4ee48592015-12-02 06:37:07161 command_line->GetSwitchValueASCII(
162 switches::kForceWebRtcIPHandlingPolicy);
guoweis8efb6d892015-10-12 18:26:17163 }
guoweis8efb6d892015-10-12 18:26:17164
[email protected]3fd84032012-01-12 18:20:17165 return shell;
166}
167
[email protected]11a65b692012-03-30 11:29:16168void Shell::CloseAllWindows() {
[email protected]b50452f2014-08-18 12:31:44169 DevToolsAgentHost::DetachAllClients();
[email protected]11a65b692012-03-30 11:29:16170 std::vector<Shell*> open_windows(windows_);
Wezcbf4a042018-06-13 16:29:12171 for (size_t i = 0; i < open_windows.size(); ++i)
172 open_windows[i]->Close();
173
174 // Pump the message loop to allow window teardown tasks to run.
175 base::RunLoop().RunUntilIdle();
176
Wez7d3eb012018-06-20 22:51:28177 // If there were no windows open then the message loop quit closure will
178 // not have been run.
179 if (*g_quit_main_message_loop)
180 std::move(*g_quit_main_message_loop).Run();
181
dmazzoni948fbc72015-05-17 07:57:33182 PlatformExit();
[email protected]11a65b692012-03-30 11:29:16183}
184
Wezcbf4a042018-06-13 16:29:12185void Shell::SetMainMessageLoopQuitClosure(base::OnceClosure quit_closure) {
186 *g_quit_main_message_loop = std::move(quit_closure);
187}
188
Wez7d3eb012018-06-20 22:51:28189void Shell::QuitMainMessageLoopForTesting() {
John Budorick7732d4d02018-07-30 19:02:54190 DCHECK(*g_quit_main_message_loop);
Wez7d3eb012018-06-20 22:51:28191 std::move(*g_quit_main_message_loop).Run();
192}
193
[email protected]9e00e6352012-07-30 17:05:18194void Shell::SetShellCreatedCallback(
195 base::Callback<void(Shell*)> shell_created_callback) {
196 DCHECK(shell_created_callback_.is_null());
Tommy Nyquist4b749d02018-03-20 21:46:29197 shell_created_callback_ = std::move(shell_created_callback);
[email protected]9e00e6352012-07-30 17:05:18198}
199
[email protected]74830f02012-01-30 22:27:04200Shell* Shell::FromRenderViewHost(RenderViewHost* rvh) {
201 for (size_t i = 0; i < windows_.size(); ++i) {
[email protected]0b659b32012-03-26 21:29:32202 if (windows_[i]->web_contents() &&
203 windows_[i]->web_contents()->GetRenderViewHost() == rvh) {
[email protected]74830f02012-01-30 22:27:04204 return windows_[i];
205 }
206 }
Ivan Kotenkov2c0d2bb32017-11-01 15:41:28207 return nullptr;
[email protected]74830f02012-01-30 22:27:04208}
209
[email protected]6153b272013-01-25 22:29:23210void Shell::Initialize() {
pdrcab84ee2015-03-13 21:47:04211 PlatformInitialize(GetShellDefaultSize());
[email protected]6153b272013-01-25 22:29:23212}
213
[email protected]a2904092013-10-15 04:53:59214gfx::Size Shell::AdjustWindowSize(const gfx::Size& initial_size) {
215 if (!initial_size.IsEmpty())
216 return initial_size;
pdrcab84ee2015-03-13 21:47:04217 return GetShellDefaultSize();
[email protected]a2904092013-10-15 04:53:59218}
219
[email protected]bdcf9152012-07-19 17:43:21220Shell* Shell::CreateNewWindow(BrowserContext* browser_context,
[email protected]e99ca5112011-09-26 17:22:54221 const GURL& url,
lukasza04130152016-10-21 20:26:32222 const scoped_refptr<SiteInstance>& site_instance,
[email protected]cdb806722013-01-10 14:18:23223 const gfx::Size& initial_size) {
[email protected]54944cde2012-12-09 09:24:59224 WebContents::CreateParams create_params(browser_context, site_instance);
mark a. foltzef394fce2017-10-21 09:11:02225 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
226 switches::kForcePresentationReceiverForTesting)) {
227 create_params.starting_sandbox_flags =
228 blink::kPresentationReceiverSandboxFlags;
229 }
[email protected]a2904092013-10-15 04:53:59230 create_params.initial_size = AdjustWindowSize(initial_size);
erikchenbee5c9622018-04-27 19:30:25231 std::unique_ptr<WebContents> web_contents =
Erik Chenbb8e738e2018-04-28 14:10:43232 WebContents::Create(create_params);
erikchenbee5c9622018-04-27 19:30:25233 Shell* shell =
Bo Liu300c6052018-06-12 04:46:07234 CreateShell(std::move(web_contents), create_params.initial_size,
235 true /* should_set_delegate */);
[email protected]e99ca5112011-09-26 17:22:54236 if (!url.is_empty())
237 shell->LoadURL(url);
[email protected]9fbd3f862011-09-20 23:31:34238 return shell;
239}
240
Daniel Murphy16ed0782018-05-26 00:15:13241Shell* Shell::CreateNewWindowWithSessionStorageNamespace(
242 BrowserContext* browser_context,
243 const GURL& url,
244 const scoped_refptr<SiteInstance>& site_instance,
245 const gfx::Size& initial_size,
246 scoped_refptr<SessionStorageNamespace> session_storage_namespace) {
247 WebContents::CreateParams create_params(browser_context, site_instance);
248 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
249 switches::kForcePresentationReceiverForTesting)) {
250 create_params.starting_sandbox_flags =
251 blink::kPresentationReceiverSandboxFlags;
252 }
253 create_params.initial_size = AdjustWindowSize(initial_size);
254 std::map<std::string, scoped_refptr<SessionStorageNamespace>>
255 session_storages;
256 session_storages[""] = session_storage_namespace;
257 std::unique_ptr<WebContents> web_contents =
258 WebContents::CreateWithSessionStorage(create_params, session_storages);
259 Shell* shell =
Bo Liu300c6052018-06-12 04:46:07260 CreateShell(std::move(web_contents), create_params.initial_size,
261 true /* should_set_delegate */);
Daniel Murphy16ed0782018-05-26 00:15:13262 if (!url.is_empty())
263 shell->LoadURL(url);
264 return shell;
265}
266
[email protected]9fbd3f862011-09-20 23:31:34267void Shell::LoadURL(const GURL& url) {
Alex Moshchuk7e26eca2018-03-03 01:34:29268 LoadURLForFrame(
269 url, std::string(),
270 ui::PageTransitionFromInt(ui::PAGE_TRANSITION_TYPED |
271 ui::PAGE_TRANSITION_FROM_ADDRESS_BAR));
[email protected]d2494ff2013-02-20 08:22:37272}
273
Alex Moshchuk7e26eca2018-03-03 01:34:29274void Shell::LoadURLForFrame(const GURL& url,
275 const std::string& frame_name,
276 ui::PageTransition transition_type) {
[email protected]d2494ff2013-02-20 08:22:37277 NavigationController::LoadURLParams params(url);
[email protected]d2494ff2013-02-20 08:22:37278 params.frame_name = frame_name;
Alex Moshchuk7e26eca2018-03-03 01:34:29279 params.transition_type = transition_type;
[email protected]d2494ff2013-02-20 08:22:37280 web_contents_->GetController().LoadURLWithParams(params);
[email protected]fc2b46b2014-05-03 16:33:45281 web_contents_->Focus();
[email protected]9fbd3f862011-09-20 23:31:34282}
283
[email protected]76bdecb2014-04-16 17:58:08284void Shell::LoadDataWithBaseURL(const GURL& url, const std::string& data,
285 const GURL& base_url) {
boliuec93ea92016-02-17 22:23:07286 bool load_as_string = false;
287 LoadDataWithBaseURLInternal(url, data, base_url, load_as_string);
288}
289
290#if defined(OS_ANDROID)
291void Shell::LoadDataAsStringWithBaseURL(const GURL& url,
292 const std::string& data,
293 const GURL& base_url) {
294 bool load_as_string = true;
295 LoadDataWithBaseURLInternal(url, data, base_url, load_as_string);
296}
297#endif
298
299void Shell::LoadDataWithBaseURLInternal(const GURL& url,
300 const std::string& data,
301 const GURL& base_url,
302 bool load_as_string) {
303#if !defined(OS_ANDROID)
304 DCHECK(!load_as_string); // Only supported on Android.
305#endif
306
307 NavigationController::LoadURLParams params(GURL::EmptyGURL());
308 const std::string data_url_header = "data:text/html;charset=utf-8,";
309 if (load_as_string) {
310 params.url = GURL(data_url_header);
311 std::string data_url_as_string = data_url_header + data;
312#if defined(OS_ANDROID)
313 params.data_url_as_string =
314 base::RefCountedString::TakeString(&data_url_as_string);
315#endif
316 } else {
317 params.url = GURL(data_url_header + data);
318 }
319
[email protected]76bdecb2014-04-16 17:58:08320 params.load_type = NavigationController::LOAD_TYPE_DATA;
321 params.base_url_for_data_url = base_url;
322 params.virtual_url_for_data_url = url;
323 params.override_user_agent = NavigationController::UA_OVERRIDE_FALSE;
324 web_contents_->GetController().LoadURLWithParams(params);
[email protected]fc2b46b2014-05-03 16:33:45325 web_contents_->Focus();
[email protected]76bdecb2014-04-16 17:58:08326}
327
[email protected]a2904092013-10-15 04:53:59328void Shell::AddNewContents(WebContents* source,
erikchenbee5c9622018-04-27 19:30:25329 std::unique_ptr<WebContents> new_contents,
[email protected]a2904092013-10-15 04:53:59330 WindowOpenDisposition disposition,
bokan107a47f2015-02-03 23:23:39331 const gfx::Rect& initial_rect,
[email protected]a2904092013-10-15 04:53:59332 bool user_gesture,
333 bool* was_blocked) {
erikchenbee5c9622018-04-27 19:30:25334 WebContents* raw_new_contents = new_contents.get();
Bo Liu300c6052018-06-12 04:46:07335 CreateShell(
336 std::move(new_contents), AdjustWindowSize(initial_rect.size()),
337 !delay_popup_contents_delegate_for_testing_ /* should_set_delegate */);
Kent Tamuracd3ebc42018-05-16 06:44:22338 if (switches::IsRunWebTestsSwitchPresent())
erikchenbee5c9622018-04-27 19:30:25339 SecondaryTestWindowObserver::CreateForWebContents(raw_new_contents);
[email protected]a2904092013-10-15 04:53:59340}
341
[email protected]9fbd3f862011-09-20 23:31:34342void Shell::GoBackOrForward(int offset) {
[email protected]0b659b32012-03-26 21:29:32343 web_contents_->GetController().GoToOffset(offset);
[email protected]fc2b46b2014-05-03 16:33:45344 web_contents_->Focus();
[email protected]9fbd3f862011-09-20 23:31:34345}
346
347void Shell::Reload() {
toyoshim6142d96f2016-12-19 09:07:25348 web_contents_->GetController().Reload(ReloadType::NORMAL, false);
[email protected]fc2b46b2014-05-03 16:33:45349 web_contents_->Focus();
[email protected]9fbd3f862011-09-20 23:31:34350}
351
toyoshime5aaf6a2016-05-18 08:07:48352void Shell::ReloadBypassingCache() {
toyoshim6142d96f2016-12-19 09:07:25353 web_contents_->GetController().Reload(ReloadType::BYPASSING_CACHE, false);
toyoshime5aaf6a2016-05-18 08:07:48354 web_contents_->Focus();
355}
356
[email protected]9fbd3f862011-09-20 23:31:34357void Shell::Stop() {
[email protected]0b659b32012-03-26 21:29:32358 web_contents_->Stop();
[email protected]fc2b46b2014-05-03 16:33:45359 web_contents_->Focus();
[email protected]9fbd3f862011-09-20 23:31:34360}
361
[email protected]e3b10d12014-03-28 16:06:09362void Shell::UpdateNavigationControls(bool to_different_document) {
[email protected]0b659b32012-03-26 21:29:32363 int current_index = web_contents_->GetController().GetCurrentEntryIndex();
364 int max_index = web_contents_->GetController().GetEntryCount() - 1;
[email protected]9fbd3f862011-09-20 23:31:34365
366 PlatformEnableUIControl(BACK_BUTTON, current_index > 0);
367 PlatformEnableUIControl(FORWARD_BUTTON, current_index < max_index);
[email protected]e3b10d12014-03-28 16:06:09368 PlatformEnableUIControl(STOP_BUTTON,
369 to_different_document && web_contents_->IsLoading());
[email protected]9fbd3f862011-09-20 23:31:34370}
371
[email protected]7c17b6992012-08-09 16:16:30372void Shell::ShowDevTools() {
mohsen6eb57fb2016-07-22 03:14:08373 if (!devtools_frontend_) {
374 devtools_frontend_ = ShellDevToolsFrontend::Show(web_contents());
375 devtools_observer_.reset(new DevToolsWebContentsObserver(
376 this, devtools_frontend_->frontend_shell()->web_contents()));
377 }
[email protected]3142e5d2014-02-07 00:54:46378
mohsen6eb57fb2016-07-22 03:14:08379 devtools_frontend_->Activate();
380 devtools_frontend_->Focus();
[email protected]7c17b6992012-08-09 16:16:30381}
382
[email protected]001841c92012-12-11 17:00:13383void Shell::CloseDevTools() {
[email protected]0773e0c2013-01-25 15:57:57384 if (!devtools_frontend_)
[email protected]001841c92012-12-11 17:00:13385 return;
[email protected]7fff43e2013-05-21 20:21:10386 devtools_observer_.reset();
[email protected]0773e0c2013-01-25 15:57:57387 devtools_frontend_->Close();
Ivan Kotenkov2c0d2bb32017-11-01 15:41:28388 devtools_frontend_ = nullptr;
[email protected]001841c92012-12-11 17:00:13389}
390
[email protected]9fbd3f862011-09-20 23:31:34391gfx::NativeView Shell::GetContentView() {
[email protected]59383c782013-04-17 16:43:27392 if (!web_contents_)
Ivan Kotenkov2c0d2bb32017-11-01 15:41:28393 return nullptr;
[email protected]fc2b46b2014-05-03 16:33:45394 return web_contents_->GetNativeView();
[email protected]9fbd3f862011-09-20 23:31:34395}
396
alexmos5a98a052016-01-06 00:15:02397WebContents* Shell::OpenURLFromTab(WebContents* source,
398 const OpenURLParams& params) {
lukasza04130152016-10-21 20:26:32399 WebContents* target = nullptr;
400 switch (params.disposition) {
401 case WindowOpenDisposition::CURRENT_TAB:
402 target = source;
403 break;
404
405 // Normally, the difference between NEW_POPUP and NEW_WINDOW is that a popup
406 // should have no toolbar, no status bar, no menu bar, no scrollbars and be
407 // not resizable. For simplicity and to enable new testing scenarios in
408 // content shell and layout tests, popups don't get special treatment below
409 // (i.e. they will have a toolbar and other things described here).
410 case WindowOpenDisposition::NEW_POPUP:
lukaszabe2f0da2017-04-25 00:43:00411 case WindowOpenDisposition::NEW_WINDOW:
412 // content_shell doesn't really support tabs, but some layout tests use
413 // middle click (which translates into kNavigationPolicyNewBackgroundTab),
414 // so we treat the cases below just like a NEW_WINDOW disposition.
415 case WindowOpenDisposition::NEW_BACKGROUND_TAB:
416 case WindowOpenDisposition::NEW_FOREGROUND_TAB: {
lukasza04130152016-10-21 20:26:32417 Shell* new_window =
418 Shell::CreateNewWindow(source->GetBrowserContext(),
419 GURL(), // Don't load anything just yet.
420 params.source_site_instance,
421 gfx::Size()); // Use default size.
422 target = new_window->web_contents();
Kent Tamuracd3ebc42018-05-16 06:44:22423 if (switches::IsRunWebTestsSwitchPresent())
lukasza04130152016-10-21 20:26:32424 SecondaryTestWindowObserver::CreateForWebContents(target);
425 break;
426 }
427
428 // No tabs in content_shell:
429 case WindowOpenDisposition::SINGLETON_TAB:
lukasza04130152016-10-21 20:26:32430 // No incognito mode in content_shell:
431 case WindowOpenDisposition::OFF_THE_RECORD:
432 // TODO(lukasza): Investigate if some layout tests might need support for
433 // SAVE_TO_DISK disposition. This would probably require that
434 // BlinkTestController always sets up and cleans up a temporary directory
435 // as the default downloads destinations for the duration of a test.
436 case WindowOpenDisposition::SAVE_TO_DISK:
437 // Ignoring requests with disposition == IGNORE_ACTION...
438 case WindowOpenDisposition::IGNORE_ACTION:
439 default:
440 return nullptr;
441 }
alexmos5a98a052016-01-06 00:15:02442
443 NavigationController::LoadURLParams load_url_params(params.url);
444 load_url_params.source_site_instance = params.source_site_instance;
445 load_url_params.transition_type = params.transition;
446 load_url_params.frame_tree_node_id = params.frame_tree_node_id;
447 load_url_params.referrer = params.referrer;
448 load_url_params.redirect_chain = params.redirect_chain;
449 load_url_params.extra_headers = params.extra_headers;
450 load_url_params.is_renderer_initiated = params.is_renderer_initiated;
alexmos5a98a052016-01-06 00:15:02451 load_url_params.should_replace_current_entry =
452 params.should_replace_current_entry;
Marijn Kruisselbrink7a0d5e182018-05-24 22:55:09453 load_url_params.blob_url_loader_factory = params.blob_url_loader_factory;
alexmos5a98a052016-01-06 00:15:02454
lukasza477a5a22016-06-16 18:28:43455 if (params.uses_post) {
456 load_url_params.load_type = NavigationController::LOAD_TYPE_HTTP_POST;
457 load_url_params.post_data = params.post_data;
alexmos5a98a052016-01-06 00:15:02458 }
459
lukasza04130152016-10-21 20:26:32460 target->GetController().LoadURLWithParams(load_url_params);
461 return target;
alexmos5a98a052016-01-06 00:15:02462}
463
[email protected]e3b10d12014-03-28 16:06:09464void Shell::LoadingStateChanged(WebContents* source,
465 bool to_different_document) {
466 UpdateNavigationControls(to_different_document);
[email protected]15aea412012-01-19 03:18:50467 PlatformSetIsLoading(source->IsLoading());
[email protected]e99ca5112011-09-26 17:22:54468}
469
Dave Tapuska3ed44192018-05-01 18:53:30470void Shell::EnterFullscreenModeForTab(
471 WebContents* web_contents,
472 const GURL& origin,
473 const blink::WebFullscreenOptions& options) {
mlamouri7a78d6fd2015-01-17 13:23:53474 ToggleFullscreenModeForTab(web_contents, true);
475}
476
477void Shell::ExitFullscreenModeForTab(WebContents* web_contents) {
478 ToggleFullscreenModeForTab(web_contents, false);
479}
480
[email protected]99c014c2012-11-27 12:03:42481void Shell::ToggleFullscreenModeForTab(WebContents* web_contents,
482 bool enter_fullscreen) {
483#if defined(OS_ANDROID)
484 PlatformToggleFullscreenModeForTab(web_contents, enter_fullscreen);
485#endif
Kent Tamuracd3ebc42018-05-16 06:44:22486 if (!switches::IsRunWebTestsSwitchPresent())
[email protected]99c014c2012-11-27 12:03:42487 return;
488 if (is_fullscreen_ != enter_fullscreen) {
489 is_fullscreen_ = enter_fullscreen;
Fady Samuel0b911822018-04-25 13:22:16490 web_contents->GetRenderViewHost()
491 ->GetWidget()
492 ->SynchronizeVisualProperties();
[email protected]99c014c2012-11-27 12:03:42493 }
494}
495
496bool Shell::IsFullscreenForTabOrPending(const WebContents* web_contents) const {
497#if defined(OS_ANDROID)
498 return PlatformIsFullscreenForTabOrPending(web_contents);
499#else
500 return is_fullscreen_;
501#endif
502}
503
mikhail.pozdnyakovc0e251b2015-04-15 06:51:12504blink::WebDisplayMode Shell::GetDisplayMode(
505 const WebContents* web_contents) const {
Lukasz Anforowicz52b93722018-06-20 16:11:39506 // TODO: should return blink::WebDisplayModeFullscreen wherever user puts
507 // a browser window into fullscreen (not only in case of renderer-initiated
508 // fullscreen mode): crbug.com/476874.
509 return IsFullscreenForTabOrPending(web_contents)
510 ? blink::kWebDisplayModeFullscreen
511 : blink::kWebDisplayModeBrowser;
mikhail.pozdnyakovc0e251b2015-04-15 06:51:12512}
513
[email protected]f78439002012-11-28 14:45:59514void Shell::RequestToLockMouse(WebContents* web_contents,
515 bool user_gesture,
516 bool last_unlocked_by_target) {
517 web_contents->GotResponseToLockMouseRequest(true);
518}
519
[email protected]9e00e6352012-07-30 17:05:18520void Shell::CloseContents(WebContents* source) {
521 Close();
522}
523
[email protected]067310262012-11-22 14:30:41524bool Shell::CanOverscrollContent() const {
525#if defined(USE_AURA)
526 return true;
527#else
528 return false;
529#endif
530}
531
[email protected]3bbacc5b2012-04-17 17:46:15532void Shell::DidNavigateMainFramePostCommit(WebContents* web_contents) {
[email protected]4e3c7522013-08-13 11:53:18533 PlatformSetAddressBarURL(web_contents->GetLastCommittedURL());
[email protected]e99ca5112011-09-26 17:22:54534}
535
mathiash72a5e462014-11-19 08:18:50536JavaScriptDialogManager* Shell::GetJavaScriptDialogManager(
537 WebContents* source) {
mkwst6efe7f2e62014-10-08 15:09:01538 if (!dialog_manager_) {
Kent Tamuracd3ebc42018-05-16 06:44:22539 dialog_manager_.reset(switches::IsRunWebTestsSwitchPresent()
lukasza381b0492016-03-10 16:48:43540 ? new LayoutTestJavaScriptDialogManager
541 : new ShellJavaScriptDialogManager);
mkwst6efe7f2e62014-10-08 15:09:01542 }
[email protected]71a88bb2013-02-01 22:05:15543 return dialog_manager_.get();
[email protected]f2210022012-03-29 00:36:08544}
545
dcheng6003e0b2016-04-09 18:42:34546std::unique_ptr<BluetoothChooser> Shell::RunBluetoothChooser(
jyasskin93649a52016-02-17 19:57:02547 RenderFrameHost* frame,
548 const BluetoothChooser::EventHandler& event_handler) {
Lukasz Anforowiczf227b4912017-12-22 23:08:59549 BlinkTestController* blink_test_controller = BlinkTestController::Get();
Kent Tamuracd3ebc42018-05-16 06:44:22550 if (blink_test_controller && switches::IsRunWebTestsSwitchPresent())
Lukasz Anforowiczf227b4912017-12-22 23:08:59551 return blink_test_controller->RunBluetoothChooser(frame, event_handler);
jyasskin8057c002015-09-10 19:09:53552 return nullptr;
553}
554
avia90ae4e2016-11-11 20:49:33555bool Shell::DidAddMessageToConsole(WebContents* source,
556 int32_t level,
557 const base::string16& message,
558 int32_t line_no,
559 const base::string16& source_id) {
Kent Tamuracd3ebc42018-05-16 06:44:22560 return switches::IsRunWebTestsSwitchPresent();
[email protected]efb5f572012-01-29 10:57:33561}
562
Lukasz Anforowicz52b93722018-06-20 16:11:39563void Shell::RendererUnresponsive(
564 WebContents* source,
565 RenderWidgetHost* render_widget_host,
566 base::RepeatingClosure hang_monitor_restarter) {
Lukasz Anforowiczf227b4912017-12-22 23:08:59567 BlinkTestController* blink_test_controller = BlinkTestController::Get();
Kent Tamuracd3ebc42018-05-16 06:44:22568 if (blink_test_controller && switches::IsRunWebTestsSwitchPresent())
Lukasz Anforowiczf227b4912017-12-22 23:08:59569 blink_test_controller->RendererUnresponsive();
[email protected]5bf68f22012-08-31 07:38:10570}
571
[email protected]233567d2013-02-27 20:22:02572void Shell::ActivateContents(WebContents* contents) {
avif9ab5d942015-10-15 14:05:44573 contents->GetRenderViewHost()->GetWidget()->Focus();
[email protected]233567d2013-02-27 20:22:02574}
575
Lucas Furukawa Gadanic5c0cd02018-10-04 20:32:33576std::unique_ptr<WebContents> Shell::SwapWebContents(
577 WebContents* old_contents,
578 std::unique_ptr<WebContents> new_contents,
579 bool did_start_load,
580 bool did_finish_load) {
581 DCHECK_EQ(old_contents, web_contents_.get());
582 new_contents->SetDelegate(this);
583 web_contents_->SetDelegate(nullptr);
584 std::swap(web_contents_, new_contents);
585 PlatformSetContents();
586 PlatformSetAddressBarURL(web_contents_->GetLastCommittedURL());
587 LoadingStateChanged(web_contents_.get(), true);
588 return new_contents;
589}
590
carloskd9d97942017-02-16 08:58:09591bool Shell::ShouldAllowRunningInsecureContent(
592 content::WebContents* web_contents,
593 bool allowed_per_prefs,
594 const url::Origin& origin,
595 const GURL& resource_url) {
596 bool allowed_by_test = false;
Lukasz Anforowiczf227b4912017-12-22 23:08:59597 BlinkTestController* blink_test_controller = BlinkTestController::Get();
Kent Tamuracd3ebc42018-05-16 06:44:22598 if (blink_test_controller && switches::IsRunWebTestsSwitchPresent()) {
carloskd9d97942017-02-16 08:58:09599 const base::DictionaryValue& test_flags =
Lukasz Anforowiczf227b4912017-12-22 23:08:59600 blink_test_controller->accumulated_layout_test_runtime_flags_changes();
carloskd9d97942017-02-16 08:58:09601 test_flags.GetBoolean("running_insecure_content_allowed", &allowed_by_test);
602 }
603
604 return allowed_per_prefs || allowed_by_test;
605}
606
Mounir Lamouri11e9ef432018-05-22 03:10:16607gfx::Size Shell::EnterPictureInPicture(const viz::SurfaceId& surface_id,
608 const gfx::Size& natural_size) {
François Beaufort480ee2d2018-10-24 14:05:17609 // During tests, returning a fake window size (same aspect ratio) to pretend
610 // the window was created and allow tests to run accordingly.
611 return switches::IsRunWebTestsSwitchPresent() ? natural_size
Mounir Lamouri11e9ef432018-05-22 03:10:16612 : gfx::Size(0, 0);
613}
614
Bo Liu300c6052018-06-12 04:46:07615bool Shell::ShouldResumeRequestsForCreatedWindow() {
616 return !delay_popup_contents_delegate_for_testing_;
617}
618
pdrcab84ee2015-03-13 21:47:04619gfx::Size Shell::GetShellDefaultSize() {
620 static gfx::Size default_shell_size;
621 if (!default_shell_size.IsEmpty())
622 return default_shell_size;
623 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
624 if (command_line->HasSwitch(switches::kContentShellHostWindowSize)) {
625 const std::string size_str = command_line->GetSwitchValueASCII(
626 switches::kContentShellHostWindowSize);
627 int width, height;
628 CHECK_EQ(2, sscanf(size_str.c_str(), "%dx%d", &width, &height));
629 default_shell_size = gfx::Size(width, height);
630 } else {
631 default_shell_size = gfx::Size(
632 kDefaultTestWindowWidthDip, kDefaultTestWindowHeightDip);
633 }
634 return default_shell_size;
635}
636
Avi Drissman93002212017-09-27 03:20:52637void Shell::TitleWasSet(NavigationEntry* entry) {
[email protected]1ef02d242013-10-07 16:18:53638 if (entry)
639 PlatformSetTitle(entry->GetTitle());
[email protected]aecc085b2012-06-01 18:15:53640}
641
[email protected]7fff43e2013-05-21 20:21:10642void Shell::OnDevToolsWebContentsDestroyed() {
643 devtools_observer_.reset();
Ivan Kotenkov2c0d2bb32017-11-01 15:41:28644 devtools_frontend_ = nullptr;
[email protected]7fff43e2013-05-21 20:21:10645}
646
[email protected]9fbd3f862011-09-20 23:31:34647} // namespace content