blob: cb39064dff4cea4dd31bc8acd72dafca0728e8bf [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"
Becca Hughes112832e2019-06-11 17:19:0228#include "content/public/browser/picture_in_picture_window_controller.h"
Yutaka Hirano2109e582018-02-14 07:24:4629#include "content/public/browser/render_process_host.h"
[email protected]0b659b32012-03-26 21:29:3230#include "content/public/browser/render_view_host.h"
avif9ab5d942015-10-15 14:05:4431#include "content/public/browser/render_widget_host.h"
[email protected]0b659b32012-03-26 21:29:3232#include "content/public/browser/web_contents.h"
guoweis8efb6d892015-10-12 18:26:1733#include "content/public/common/content_switches.h"
[email protected]de7d61ff2013-08-20 11:30:4134#include "content/shell/browser/shell_browser_main_parts.h"
35#include "content/shell/browser/shell_content_browser_client.h"
36#include "content/shell/browser/shell_devtools_frontend.h"
37#include "content/shell/browser/shell_javascript_dialog_manager.h"
Kent Tamuraf92649d882018-12-03 09:07:4738#include "content/shell/browser/web_test/blink_test_controller.h"
Jun Cai149002e2019-05-09 23:13:0739#include "content/shell/browser/web_test/fake_bluetooth_scanning_prompt.h"
Kent Tamuraf92649d882018-12-03 09:07:4740#include "content/shell/browser/web_test/secondary_test_window_observer.h"
41#include "content/shell/browser/web_test/web_test_bluetooth_chooser_factory.h"
42#include "content/shell/browser/web_test/web_test_devtools_bindings.h"
43#include "content/shell/browser/web_test/web_test_javascript_dialog_manager.h"
[email protected]b7c504c2013-05-07 14:42:1244#include "content/shell/common/shell_switches.h"
Kent Tamurade503112018-12-04 08:57:4045#include "content/shell/common/web_test/web_test_switches.h"
Scott Violeta35f9a42018-03-22 22:00:4446#include "media/media_buildflags.h"
Antonio Gomesb5bf548f2019-09-12 17:40:1547#include "third_party/blink/public/common/peerconnection/webrtc_ip_handling_policy.h"
Sergio Villar Senincfa9cb662019-10-12 11:41:4348#include "third_party/blink/public/common/presentation/presentation_receiver_flags.h"
Leon Hanc819dc62019-01-28 04:30:1949#include "third_party/blink/public/mojom/renderer_preferences.mojom.h"
[email protected]9fbd3f862011-09-20 23:31:3450
[email protected]9fbd3f862011-09-20 23:31:3451namespace content {
52
Wezcbf4a042018-06-13 16:29:1253// Null until/unless the default main message loop is running.
54base::NoDestructor<base::OnceClosure> g_quit_main_message_loop;
Wez9a58a152018-06-07 18:59:3355
pdrcab84ee2015-03-13 21:47:0456const int kDefaultTestWindowWidthDip = 800;
57const int kDefaultTestWindowHeightDip = 600;
[email protected]1e57cab2013-05-28 04:26:1158
[email protected]e99ca5112011-09-26 17:22:5459std::vector<Shell*> Shell::windows_;
danakja9fe91c2019-05-01 19:02:2960base::OnceCallback<void(Shell*)> Shell::shell_created_callback_;
[email protected]9fbd3f862011-09-20 23:31:3461
[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
Bo Liu300c6052018-06-12 04:46:0780Shell::Shell(std::unique_ptr<WebContents> web_contents,
81 bool should_set_delegate)
erikchenbee5c9622018-04-27 19:30:2582 : WebContentsObserver(web_contents.get()),
83 web_contents_(std::move(web_contents)),
Ivan Kotenkov2c0d2bb32017-11-01 15:41:2884 devtools_frontend_(nullptr),
[email protected]001841c92012-12-11 17:00:1385 is_fullscreen_(false),
Ivan Kotenkov2c0d2bb32017-11-01 15:41:2886 window_(nullptr),
sadrul8b11d262015-11-12 18:41:3387#if defined(OS_MACOSX)
[email protected]86b36e672012-12-21 00:09:5188 url_edit_view_(NULL),
sadrul8b11d262015-11-12 18:41:3389#endif
Pavel Feldmanc7cd063c2017-10-06 20:04:2890 headless_(false),
91 hide_toolbar_(false) {
Bo Liu300c6052018-06-12 04:46:0792 if (should_set_delegate)
93 web_contents_->SetDelegate(this);
arthursonzognifdd49912017-08-31 08:55:2694
Kent Tamuracd3ebc42018-05-16 06:44:2295 if (switches::IsRunWebTestsSwitchPresent()) {
jonross26185702019-04-08 18:54:1096 headless_ = !base::CommandLine::ForCurrentProcess()->HasSwitch(
97 switches::kDisableHeadlessMode);
98 // Disable occlusion tracking. In a headless shell WebContents would always
99 // behave as if they were occluded, i.e. would not render frames and would
100 // not receive input events. For non-headless mode we do not want tests
101 // running in parallel to trigger occlusion tracking.
Francois Doraye6161152018-03-27 22:05:37102 base::CommandLine::ForCurrentProcess()->AppendSwitch(
103 switches::kDisableBackgroundingOccludedWindowsForTesting);
104 }
Pavel Feldmanc7cd063c2017-10-06 20:04:28105
106 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
107 switches::kContentShellHideToolbar))
108 hide_toolbar_ = true;
109
[email protected]9e00e6352012-07-30 17:05:18110 windows_.push_back(this);
111
danakja9fe91c2019-05-01 19:02:29112 if (shell_created_callback_)
113 std::move(shell_created_callback_).Run(this);
[email protected]9fbd3f862011-09-20 23:31:34114}
115
116Shell::~Shell() {
117 PlatformCleanUp();
[email protected]e99ca5112011-09-26 17:22:54118
119 for (size_t i = 0; i < windows_.size(); ++i) {
120 if (windows_[i] == this) {
121 windows_.erase(windows_.begin() + i);
122 break;
123 }
124 }
[email protected]11a65b692012-03-30 11:29:16125
Sergey Ulanovf0875d12019-01-03 20:33:23126 // Always destroy WebContents before calling PlatformExit(). WebContents
127 // destruction sequence may depend on the resources destroyed in
128 // PlatformExit() (e.g. the display::Screen singleton).
129 web_contents_->SetDelegate(nullptr);
130 web_contents_.reset();
131
Wez9a58a152018-06-07 18:59:33132 if (windows_.empty()) {
[email protected]b53adf452014-02-07 12:55:08133 if (headless_)
134 PlatformExit();
Yutaka Hirano2109e582018-02-14 07:24:46135 for (auto it = RenderProcessHost::AllHostsIterator(); !it.IsAtEnd();
136 it.Advance()) {
137 it.GetCurrentValue()->DisableKeepAliveRefCount();
138 }
Wezcbf4a042018-06-13 16:29:12139 if (*g_quit_main_message_loop)
140 std::move(*g_quit_main_message_loop).Run();
[email protected]b53adf452014-02-07 12:55:08141 }
[email protected]9fbd3f862011-09-20 23:31:34142}
143
erikchenbee5c9622018-04-27 19:30:25144Shell* Shell::CreateShell(std::unique_ptr<WebContents> web_contents,
Bo Liu300c6052018-06-12 04:46:07145 const gfx::Size& initial_size,
146 bool should_set_delegate) {
erikchenbee5c9622018-04-27 19:30:25147 WebContents* raw_web_contents = web_contents.get();
Bo Liu300c6052018-06-12 04:46:07148 Shell* shell = new Shell(std::move(web_contents), should_set_delegate);
[email protected]c0d036d2013-05-07 12:50:50149 shell->PlatformCreateWindow(initial_size.width(), initial_size.height());
[email protected]3fd84032012-01-12 18:20:17150
[email protected]5cba3bf2012-01-14 02:40:35151 shell->PlatformSetContents();
[email protected]3fd84032012-01-12 18:20:17152
153 shell->PlatformResizeSubViews();
[email protected]1596efb2013-01-17 22:13:01154
creisb6561df2016-02-11 20:20:54155 // Note: Do not make RenderFrameHost or RenderViewHost specific state changes
156 // here, because they will be forgotten after a cross-process navigation. Use
157 // RenderFrameCreated or RenderViewCreated instead.
Kent Tamuracd3ebc42018-05-16 06:44:22158 if (switches::IsRunWebTestsSwitchPresent()) {
erikchenbee5c9622018-04-27 19:30:25159 raw_web_contents->GetMutableRendererPrefs()->use_custom_colors = false;
Bruce Long1e3e1f542019-10-16 17:56:28160 raw_web_contents->SyncRendererPrefs();
[email protected]1596efb2013-01-17 22:13:01161 }
162
lukasza381b0492016-03-10 16:48:43163 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
guoweis4ee48592015-12-02 06:37:07164 if (command_line->HasSwitch(switches::kForceWebRtcIPHandlingPolicy)) {
erikchenbee5c9622018-04-27 19:30:25165 raw_web_contents->GetMutableRendererPrefs()->webrtc_ip_handling_policy =
guoweis4ee48592015-12-02 06:37:07166 command_line->GetSwitchValueASCII(
167 switches::kForceWebRtcIPHandlingPolicy);
guoweis8efb6d892015-10-12 18:26:17168 }
guoweis8efb6d892015-10-12 18:26:17169
[email protected]3fd84032012-01-12 18:20:17170 return shell;
171}
172
[email protected]11a65b692012-03-30 11:29:16173void Shell::CloseAllWindows() {
[email protected]b50452f2014-08-18 12:31:44174 DevToolsAgentHost::DetachAllClients();
[email protected]11a65b692012-03-30 11:29:16175 std::vector<Shell*> open_windows(windows_);
Wezcbf4a042018-06-13 16:29:12176 for (size_t i = 0; i < open_windows.size(); ++i)
177 open_windows[i]->Close();
178
179 // Pump the message loop to allow window teardown tasks to run.
180 base::RunLoop().RunUntilIdle();
181
Wez7d3eb012018-06-20 22:51:28182 // If there were no windows open then the message loop quit closure will
183 // not have been run.
184 if (*g_quit_main_message_loop)
185 std::move(*g_quit_main_message_loop).Run();
186
dmazzoni948fbc72015-05-17 07:57:33187 PlatformExit();
[email protected]11a65b692012-03-30 11:29:16188}
189
Wezcbf4a042018-06-13 16:29:12190void Shell::SetMainMessageLoopQuitClosure(base::OnceClosure quit_closure) {
191 *g_quit_main_message_loop = std::move(quit_closure);
192}
193
Wez7d3eb012018-06-20 22:51:28194void Shell::QuitMainMessageLoopForTesting() {
Wezc93f15a92020-02-25 21:57:44195 if (*g_quit_main_message_loop)
196 std::move(*g_quit_main_message_loop).Run();
Wez7d3eb012018-06-20 22:51:28197}
198
[email protected]9e00e6352012-07-30 17:05:18199void Shell::SetShellCreatedCallback(
danakja9fe91c2019-05-01 19:02:29200 base::OnceCallback<void(Shell*)> shell_created_callback) {
201 DCHECK(!shell_created_callback_);
Tommy Nyquist4b749d02018-03-20 21:46:29202 shell_created_callback_ = std::move(shell_created_callback);
[email protected]9e00e6352012-07-30 17:05:18203}
204
David Benjaminf62c6662019-03-21 20:25:04205Shell* Shell::FromWebContents(WebContents* web_contents) {
206 for (Shell* window : windows_) {
207 if (window->web_contents() && window->web_contents() == web_contents) {
208 return window;
[email protected]74830f02012-01-30 22:27:04209 }
210 }
Ivan Kotenkov2c0d2bb32017-11-01 15:41:28211 return nullptr;
[email protected]74830f02012-01-30 22:27:04212}
213
[email protected]6153b272013-01-25 22:29:23214void Shell::Initialize() {
pdrcab84ee2015-03-13 21:47:04215 PlatformInitialize(GetShellDefaultSize());
[email protected]6153b272013-01-25 22:29:23216}
217
[email protected]a2904092013-10-15 04:53:59218gfx::Size Shell::AdjustWindowSize(const gfx::Size& initial_size) {
219 if (!initial_size.IsEmpty())
220 return initial_size;
pdrcab84ee2015-03-13 21:47:04221 return GetShellDefaultSize();
[email protected]a2904092013-10-15 04:53:59222}
223
[email protected]bdcf9152012-07-19 17:43:21224Shell* Shell::CreateNewWindow(BrowserContext* browser_context,
[email protected]e99ca5112011-09-26 17:22:54225 const GURL& url,
lukasza04130152016-10-21 20:26:32226 const scoped_refptr<SiteInstance>& site_instance,
[email protected]cdb806722013-01-10 14:18:23227 const gfx::Size& initial_size) {
[email protected]54944cde2012-12-09 09:24:59228 WebContents::CreateParams create_params(browser_context, site_instance);
mark a. foltzef394fce2017-10-21 09:11:02229 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
230 switches::kForcePresentationReceiverForTesting)) {
231 create_params.starting_sandbox_flags =
232 blink::kPresentationReceiverSandboxFlags;
233 }
erikchenbee5c9622018-04-27 19:30:25234 std::unique_ptr<WebContents> web_contents =
Erik Chenbb8e738e2018-04-28 14:10:43235 WebContents::Create(create_params);
erikchenbee5c9622018-04-27 19:30:25236 Shell* shell =
danakjfc5184932019-09-12 18:08:32237 CreateShell(std::move(web_contents), AdjustWindowSize(initial_size),
Bo Liu300c6052018-06-12 04:46:07238 true /* should_set_delegate */);
[email protected]e99ca5112011-09-26 17:22:54239 if (!url.is_empty())
240 shell->LoadURL(url);
[email protected]9fbd3f862011-09-20 23:31:34241 return shell;
242}
243
Daniel Murphy16ed0782018-05-26 00:15:13244Shell* Shell::CreateNewWindowWithSessionStorageNamespace(
245 BrowserContext* browser_context,
246 const GURL& url,
247 const scoped_refptr<SiteInstance>& site_instance,
248 const gfx::Size& initial_size,
249 scoped_refptr<SessionStorageNamespace> session_storage_namespace) {
250 WebContents::CreateParams create_params(browser_context, site_instance);
251 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
252 switches::kForcePresentationReceiverForTesting)) {
253 create_params.starting_sandbox_flags =
254 blink::kPresentationReceiverSandboxFlags;
255 }
Daniel Murphy16ed0782018-05-26 00:15:13256 std::map<std::string, scoped_refptr<SessionStorageNamespace>>
257 session_storages;
258 session_storages[""] = session_storage_namespace;
259 std::unique_ptr<WebContents> web_contents =
260 WebContents::CreateWithSessionStorage(create_params, session_storages);
261 Shell* shell =
danakjfc5184932019-09-12 18:08:32262 CreateShell(std::move(web_contents), AdjustWindowSize(initial_size),
Bo Liu300c6052018-06-12 04:46:07263 true /* should_set_delegate */);
Daniel Murphy16ed0782018-05-26 00:15:13264 if (!url.is_empty())
265 shell->LoadURL(url);
266 return shell;
267}
268
[email protected]9fbd3f862011-09-20 23:31:34269void Shell::LoadURL(const GURL& url) {
Alex Moshchuk7e26eca2018-03-03 01:34:29270 LoadURLForFrame(
271 url, std::string(),
272 ui::PageTransitionFromInt(ui::PAGE_TRANSITION_TYPED |
273 ui::PAGE_TRANSITION_FROM_ADDRESS_BAR));
[email protected]d2494ff2013-02-20 08:22:37274}
275
Alex Moshchuk7e26eca2018-03-03 01:34:29276void Shell::LoadURLForFrame(const GURL& url,
277 const std::string& frame_name,
278 ui::PageTransition transition_type) {
[email protected]d2494ff2013-02-20 08:22:37279 NavigationController::LoadURLParams params(url);
[email protected]d2494ff2013-02-20 08:22:37280 params.frame_name = frame_name;
Alex Moshchuk7e26eca2018-03-03 01:34:29281 params.transition_type = transition_type;
[email protected]d2494ff2013-02-20 08:22:37282 web_contents_->GetController().LoadURLWithParams(params);
[email protected]fc2b46b2014-05-03 16:33:45283 web_contents_->Focus();
[email protected]9fbd3f862011-09-20 23:31:34284}
285
[email protected]76bdecb2014-04-16 17:58:08286void Shell::LoadDataWithBaseURL(const GURL& url, const std::string& data,
287 const GURL& base_url) {
boliuec93ea92016-02-17 22:23:07288 bool load_as_string = false;
289 LoadDataWithBaseURLInternal(url, data, base_url, load_as_string);
290}
291
292#if defined(OS_ANDROID)
293void Shell::LoadDataAsStringWithBaseURL(const GURL& url,
294 const std::string& data,
295 const GURL& base_url) {
296 bool load_as_string = true;
297 LoadDataWithBaseURLInternal(url, data, base_url, load_as_string);
298}
299#endif
300
301void Shell::LoadDataWithBaseURLInternal(const GURL& url,
302 const std::string& data,
303 const GURL& base_url,
304 bool load_as_string) {
305#if !defined(OS_ANDROID)
306 DCHECK(!load_as_string); // Only supported on Android.
307#endif
308
309 NavigationController::LoadURLParams params(GURL::EmptyGURL());
310 const std::string data_url_header = "data:text/html;charset=utf-8,";
311 if (load_as_string) {
312 params.url = GURL(data_url_header);
313 std::string data_url_as_string = data_url_header + data;
314#if defined(OS_ANDROID)
315 params.data_url_as_string =
316 base::RefCountedString::TakeString(&data_url_as_string);
317#endif
318 } else {
319 params.url = GURL(data_url_header + data);
320 }
321
[email protected]76bdecb2014-04-16 17:58:08322 params.load_type = NavigationController::LOAD_TYPE_DATA;
323 params.base_url_for_data_url = base_url;
324 params.virtual_url_for_data_url = url;
325 params.override_user_agent = NavigationController::UA_OVERRIDE_FALSE;
326 web_contents_->GetController().LoadURLWithParams(params);
[email protected]fc2b46b2014-05-03 16:33:45327 web_contents_->Focus();
[email protected]76bdecb2014-04-16 17:58:08328}
329
[email protected]a2904092013-10-15 04:53:59330void Shell::AddNewContents(WebContents* source,
erikchenbee5c9622018-04-27 19:30:25331 std::unique_ptr<WebContents> new_contents,
[email protected]a2904092013-10-15 04:53:59332 WindowOpenDisposition disposition,
bokan107a47f2015-02-03 23:23:39333 const gfx::Rect& initial_rect,
[email protected]a2904092013-10-15 04:53:59334 bool user_gesture,
335 bool* was_blocked) {
erikchenbee5c9622018-04-27 19:30:25336 WebContents* raw_new_contents = new_contents.get();
Bo Liu300c6052018-06-12 04:46:07337 CreateShell(
338 std::move(new_contents), AdjustWindowSize(initial_rect.size()),
339 !delay_popup_contents_delegate_for_testing_ /* should_set_delegate */);
Kent Tamuracd3ebc42018-05-16 06:44:22340 if (switches::IsRunWebTestsSwitchPresent())
erikchenbee5c9622018-04-27 19:30:25341 SecondaryTestWindowObserver::CreateForWebContents(raw_new_contents);
[email protected]a2904092013-10-15 04:53:59342}
343
[email protected]9fbd3f862011-09-20 23:31:34344void Shell::GoBackOrForward(int offset) {
[email protected]0b659b32012-03-26 21:29:32345 web_contents_->GetController().GoToOffset(offset);
[email protected]fc2b46b2014-05-03 16:33:45346 web_contents_->Focus();
[email protected]9fbd3f862011-09-20 23:31:34347}
348
349void Shell::Reload() {
toyoshim6142d96f2016-12-19 09:07:25350 web_contents_->GetController().Reload(ReloadType::NORMAL, false);
[email protected]fc2b46b2014-05-03 16:33:45351 web_contents_->Focus();
[email protected]9fbd3f862011-09-20 23:31:34352}
353
toyoshime5aaf6a2016-05-18 08:07:48354void Shell::ReloadBypassingCache() {
toyoshim6142d96f2016-12-19 09:07:25355 web_contents_->GetController().Reload(ReloadType::BYPASSING_CACHE, false);
toyoshime5aaf6a2016-05-18 08:07:48356 web_contents_->Focus();
357}
358
[email protected]9fbd3f862011-09-20 23:31:34359void Shell::Stop() {
[email protected]0b659b32012-03-26 21:29:32360 web_contents_->Stop();
[email protected]fc2b46b2014-05-03 16:33:45361 web_contents_->Focus();
[email protected]9fbd3f862011-09-20 23:31:34362}
363
[email protected]e3b10d12014-03-28 16:06:09364void Shell::UpdateNavigationControls(bool to_different_document) {
[email protected]0b659b32012-03-26 21:29:32365 int current_index = web_contents_->GetController().GetCurrentEntryIndex();
366 int max_index = web_contents_->GetController().GetEntryCount() - 1;
[email protected]9fbd3f862011-09-20 23:31:34367
368 PlatformEnableUIControl(BACK_BUTTON, current_index > 0);
369 PlatformEnableUIControl(FORWARD_BUTTON, current_index < max_index);
[email protected]e3b10d12014-03-28 16:06:09370 PlatformEnableUIControl(STOP_BUTTON,
371 to_different_document && web_contents_->IsLoading());
[email protected]9fbd3f862011-09-20 23:31:34372}
373
[email protected]7c17b6992012-08-09 16:16:30374void Shell::ShowDevTools() {
mohsen6eb57fb2016-07-22 03:14:08375 if (!devtools_frontend_) {
376 devtools_frontend_ = ShellDevToolsFrontend::Show(web_contents());
377 devtools_observer_.reset(new DevToolsWebContentsObserver(
378 this, devtools_frontend_->frontend_shell()->web_contents()));
379 }
[email protected]3142e5d2014-02-07 00:54:46380
mohsen6eb57fb2016-07-22 03:14:08381 devtools_frontend_->Activate();
382 devtools_frontend_->Focus();
[email protected]7c17b6992012-08-09 16:16:30383}
384
[email protected]001841c92012-12-11 17:00:13385void Shell::CloseDevTools() {
[email protected]0773e0c2013-01-25 15:57:57386 if (!devtools_frontend_)
[email protected]001841c92012-12-11 17:00:13387 return;
[email protected]7fff43e2013-05-21 20:21:10388 devtools_observer_.reset();
[email protected]0773e0c2013-01-25 15:57:57389 devtools_frontend_->Close();
Ivan Kotenkov2c0d2bb32017-11-01 15:41:28390 devtools_frontend_ = nullptr;
[email protected]001841c92012-12-11 17:00:13391}
392
[email protected]9fbd3f862011-09-20 23:31:34393gfx::NativeView Shell::GetContentView() {
[email protected]59383c782013-04-17 16:43:27394 if (!web_contents_)
Ivan Kotenkov2c0d2bb32017-11-01 15:41:28395 return nullptr;
[email protected]fc2b46b2014-05-03 16:33:45396 return web_contents_->GetNativeView();
[email protected]9fbd3f862011-09-20 23:31:34397}
398
alexmos5a98a052016-01-06 00:15:02399WebContents* Shell::OpenURLFromTab(WebContents* source,
400 const OpenURLParams& params) {
lukasza04130152016-10-21 20:26:32401 WebContents* target = nullptr;
402 switch (params.disposition) {
403 case WindowOpenDisposition::CURRENT_TAB:
404 target = source;
405 break;
406
407 // Normally, the difference between NEW_POPUP and NEW_WINDOW is that a popup
408 // should have no toolbar, no status bar, no menu bar, no scrollbars and be
409 // not resizable. For simplicity and to enable new testing scenarios in
Kent Tamura21d1de62018-12-10 04:45:20410 // content shell and web tests, popups don't get special treatment below
lukasza04130152016-10-21 20:26:32411 // (i.e. they will have a toolbar and other things described here).
412 case WindowOpenDisposition::NEW_POPUP:
lukaszabe2f0da2017-04-25 00:43:00413 case WindowOpenDisposition::NEW_WINDOW:
Kent Tamura21d1de62018-12-10 04:45:20414 // content_shell doesn't really support tabs, but some web tests use
lukaszabe2f0da2017-04-25 00:43:00415 // middle click (which translates into kNavigationPolicyNewBackgroundTab),
416 // so we treat the cases below just like a NEW_WINDOW disposition.
417 case WindowOpenDisposition::NEW_BACKGROUND_TAB:
418 case WindowOpenDisposition::NEW_FOREGROUND_TAB: {
lukasza04130152016-10-21 20:26:32419 Shell* new_window =
420 Shell::CreateNewWindow(source->GetBrowserContext(),
421 GURL(), // Don't load anything just yet.
422 params.source_site_instance,
423 gfx::Size()); // Use default size.
424 target = new_window->web_contents();
Kent Tamuracd3ebc42018-05-16 06:44:22425 if (switches::IsRunWebTestsSwitchPresent())
lukasza04130152016-10-21 20:26:32426 SecondaryTestWindowObserver::CreateForWebContents(target);
427 break;
428 }
429
430 // No tabs in content_shell:
431 case WindowOpenDisposition::SINGLETON_TAB:
lukasza04130152016-10-21 20:26:32432 // No incognito mode in content_shell:
433 case WindowOpenDisposition::OFF_THE_RECORD:
Kent Tamura21d1de62018-12-10 04:45:20434 // TODO(lukasza): Investigate if some web tests might need support for
lukasza04130152016-10-21 20:26:32435 // SAVE_TO_DISK disposition. This would probably require that
436 // BlinkTestController always sets up and cleans up a temporary directory
437 // as the default downloads destinations for the duration of a test.
438 case WindowOpenDisposition::SAVE_TO_DISK:
439 // Ignoring requests with disposition == IGNORE_ACTION...
440 case WindowOpenDisposition::IGNORE_ACTION:
441 default:
442 return nullptr;
443 }
alexmos5a98a052016-01-06 00:15:02444
Lukasz Anforowicz82a5ca92019-10-24 18:45:37445 target->GetController().LoadURLWithParams(
446 NavigationController::LoadURLParams(params));
lukasza04130152016-10-21 20:26:32447 return target;
alexmos5a98a052016-01-06 00:15:02448}
449
[email protected]e3b10d12014-03-28 16:06:09450void Shell::LoadingStateChanged(WebContents* source,
451 bool to_different_document) {
452 UpdateNavigationControls(to_different_document);
[email protected]15aea412012-01-19 03:18:50453 PlatformSetIsLoading(source->IsLoading());
[email protected]e99ca5112011-09-26 17:22:54454}
455
Dave Tapuskaa4189512019-10-15 20:27:34456void Shell::EnterFullscreenModeForTab(
457 WebContents* web_contents,
458 const GURL& origin,
459 const blink::mojom::FullscreenOptions& options) {
mlamouri7a78d6fd2015-01-17 13:23:53460 ToggleFullscreenModeForTab(web_contents, true);
461}
462
463void Shell::ExitFullscreenModeForTab(WebContents* web_contents) {
464 ToggleFullscreenModeForTab(web_contents, false);
465}
466
[email protected]99c014c2012-11-27 12:03:42467void Shell::ToggleFullscreenModeForTab(WebContents* web_contents,
468 bool enter_fullscreen) {
469#if defined(OS_ANDROID)
470 PlatformToggleFullscreenModeForTab(web_contents, enter_fullscreen);
471#endif
[email protected]99c014c2012-11-27 12:03:42472 if (is_fullscreen_ != enter_fullscreen) {
473 is_fullscreen_ = enter_fullscreen;
Fady Samuel0b911822018-04-25 13:22:16474 web_contents->GetRenderViewHost()
475 ->GetWidget()
476 ->SynchronizeVisualProperties();
[email protected]99c014c2012-11-27 12:03:42477 }
478}
479
Lucas Furukawa Gadani4909f3c2019-06-18 22:36:52480bool Shell::IsFullscreenForTabOrPending(const WebContents* web_contents) {
[email protected]99c014c2012-11-27 12:03:42481#if defined(OS_ANDROID)
482 return PlatformIsFullscreenForTabOrPending(web_contents);
483#else
484 return is_fullscreen_;
485#endif
486}
487
Eric Willigers052f0432019-10-04 04:06:57488blink::mojom::DisplayMode Shell::GetDisplayMode(
489 const WebContents* web_contents) {
490 // TODO: should return blink::mojom::DisplayModeFullscreen wherever user puts
Lukasz Anforowicz52b93722018-06-20 16:11:39491 // a browser window into fullscreen (not only in case of renderer-initiated
492 // fullscreen mode): crbug.com/476874.
493 return IsFullscreenForTabOrPending(web_contents)
Eric Willigers052f0432019-10-04 04:06:57494 ? blink::mojom::DisplayMode::kFullscreen
495 : blink::mojom::DisplayMode::kBrowser;
mikhail.pozdnyakovc0e251b2015-04-15 06:51:12496}
497
[email protected]f78439002012-11-28 14:45:59498void Shell::RequestToLockMouse(WebContents* web_contents,
499 bool user_gesture,
500 bool last_unlocked_by_target) {
501 web_contents->GotResponseToLockMouseRequest(true);
502}
503
[email protected]9e00e6352012-07-30 17:05:18504void Shell::CloseContents(WebContents* source) {
505 Close();
506}
507
Lucas Furukawa Gadani4909f3c2019-06-18 22:36:52508bool Shell::CanOverscrollContent() {
[email protected]067310262012-11-22 14:30:41509#if defined(USE_AURA)
510 return true;
511#else
512 return false;
513#endif
514}
515
[email protected]3bbacc5b2012-04-17 17:46:15516void Shell::DidNavigateMainFramePostCommit(WebContents* web_contents) {
John Abd-El-Malek13462f0b2019-08-28 00:45:42517 PlatformSetAddressBarURL(web_contents->GetVisibleURL());
[email protected]e99ca5112011-09-26 17:22:54518}
519
mathiash72a5e462014-11-19 08:18:50520JavaScriptDialogManager* Shell::GetJavaScriptDialogManager(
521 WebContents* source) {
mkwst6efe7f2e62014-10-08 15:09:01522 if (!dialog_manager_) {
Kent Tamuracd3ebc42018-05-16 06:44:22523 dialog_manager_.reset(switches::IsRunWebTestsSwitchPresent()
Kent Tamuraf92649d882018-12-03 09:07:47524 ? new WebTestJavaScriptDialogManager
lukasza381b0492016-03-10 16:48:43525 : new ShellJavaScriptDialogManager);
mkwst6efe7f2e62014-10-08 15:09:01526 }
[email protected]71a88bb2013-02-01 22:05:15527 return dialog_manager_.get();
[email protected]f2210022012-03-29 00:36:08528}
529
dcheng6003e0b2016-04-09 18:42:34530std::unique_ptr<BluetoothChooser> Shell::RunBluetoothChooser(
jyasskin93649a52016-02-17 19:57:02531 RenderFrameHost* frame,
532 const BluetoothChooser::EventHandler& event_handler) {
Lukasz Anforowiczf227b4912017-12-22 23:08:59533 BlinkTestController* blink_test_controller = BlinkTestController::Get();
Kent Tamuracd3ebc42018-05-16 06:44:22534 if (blink_test_controller && switches::IsRunWebTestsSwitchPresent())
Lukasz Anforowiczf227b4912017-12-22 23:08:59535 return blink_test_controller->RunBluetoothChooser(frame, event_handler);
jyasskin8057c002015-09-10 19:09:53536 return nullptr;
537}
538
Jun Cai149002e2019-05-09 23:13:07539std::unique_ptr<BluetoothScanningPrompt> Shell::ShowBluetoothScanningPrompt(
540 RenderFrameHost* frame,
541 const BluetoothScanningPrompt::EventHandler& event_handler) {
542 return std::make_unique<FakeBluetoothScanningPrompt>(event_handler);
543}
544
avia90ae4e2016-11-11 20:49:33545bool Shell::DidAddMessageToConsole(WebContents* source,
Lowell Manners1de5242e2019-04-25 10:18:46546 blink::mojom::ConsoleMessageLevel log_level,
avia90ae4e2016-11-11 20:49:33547 const base::string16& message,
548 int32_t line_no,
549 const base::string16& source_id) {
Kent Tamuracd3ebc42018-05-16 06:44:22550 return switches::IsRunWebTestsSwitchPresent();
[email protected]efb5f572012-01-29 10:57:33551}
552
Lucas Furukawa Gadani06548fb2019-01-15 05:01:25553void Shell::PortalWebContentsCreated(WebContents* portal_web_contents) {
554 if (switches::IsRunWebTestsSwitchPresent())
555 SecondaryTestWindowObserver::CreateForWebContents(portal_web_contents);
556}
557
Lukasz Anforowicz52b93722018-06-20 16:11:39558void Shell::RendererUnresponsive(
559 WebContents* source,
560 RenderWidgetHost* render_widget_host,
561 base::RepeatingClosure hang_monitor_restarter) {
Lukasz Anforowiczf227b4912017-12-22 23:08:59562 BlinkTestController* blink_test_controller = BlinkTestController::Get();
Kent Tamuracd3ebc42018-05-16 06:44:22563 if (blink_test_controller && switches::IsRunWebTestsSwitchPresent())
Lukasz Anforowiczf227b4912017-12-22 23:08:59564 blink_test_controller->RendererUnresponsive();
[email protected]5bf68f22012-08-31 07:38:10565}
566
[email protected]233567d2013-02-27 20:22:02567void Shell::ActivateContents(WebContents* contents) {
avif9ab5d942015-10-15 14:05:44568 contents->GetRenderViewHost()->GetWidget()->Focus();
[email protected]233567d2013-02-27 20:22:02569}
570
Kevin McNee7422bc42020-02-20 18:49:55571std::unique_ptr<WebContents> Shell::ActivatePortalWebContents(
572 WebContents* predecessor_contents,
573 std::unique_ptr<WebContents> portal_contents) {
574 DCHECK_EQ(predecessor_contents, web_contents_.get());
575 portal_contents->SetDelegate(this);
Lucas Furukawa Gadanic5c0cd02018-10-04 20:32:33576 web_contents_->SetDelegate(nullptr);
Adithya Srinivasan5d50d1e2019-10-09 00:27:48577 for (auto* shell_devtools_bindings :
Kevin McNee7422bc42020-02-20 18:49:55578 ShellDevToolsBindings::GetInstancesForWebContents(
579 predecessor_contents)) {
580 shell_devtools_bindings->UpdateInspectedWebContents(portal_contents.get());
Adithya Srinivasan5d50d1e2019-10-09 00:27:48581 }
Kevin McNee7422bc42020-02-20 18:49:55582 std::swap(web_contents_, portal_contents);
Lucas Furukawa Gadanic5c0cd02018-10-04 20:32:33583 PlatformSetContents();
John Abd-El-Malek13462f0b2019-08-28 00:45:42584 PlatformSetAddressBarURL(web_contents_->GetVisibleURL());
Lucas Furukawa Gadanic5c0cd02018-10-04 20:32:33585 LoadingStateChanged(web_contents_.get(), true);
Kevin McNee7422bc42020-02-20 18:49:55586 return portal_contents;
Lucas Furukawa Gadanic5c0cd02018-10-04 20:32:33587}
588
Lukasz Anforowicz82a5ca92019-10-24 18:45:37589bool Shell::ShouldAllowRunningInsecureContent(WebContents* web_contents,
590 bool allowed_per_prefs,
591 const url::Origin& origin,
592 const GURL& resource_url) {
carloskd9d97942017-02-16 08:58:09593 bool allowed_by_test = false;
Lukasz Anforowiczf227b4912017-12-22 23:08:59594 BlinkTestController* blink_test_controller = BlinkTestController::Get();
Kent Tamuracd3ebc42018-05-16 06:44:22595 if (blink_test_controller && switches::IsRunWebTestsSwitchPresent()) {
carloskd9d97942017-02-16 08:58:09596 const base::DictionaryValue& test_flags =
Kent Tamura679c7c42018-12-05 03:21:10597 blink_test_controller->accumulated_web_test_runtime_flags_changes();
carloskd9d97942017-02-16 08:58:09598 test_flags.GetBoolean("running_insecure_content_allowed", &allowed_by_test);
599 }
600
601 return allowed_per_prefs || allowed_by_test;
602}
603
Becca Hughes112832e2019-06-11 17:19:02604PictureInPictureResult Shell::EnterPictureInPicture(
Lukasz Anforowicz82a5ca92019-10-24 18:45:37605 WebContents* web_contents,
Becca Hughes112832e2019-06-11 17:19:02606 const viz::SurfaceId& surface_id,
607 const gfx::Size& natural_size) {
608 // During tests, returning success to pretend the window was created and allow
609 // tests to run accordingly.
610 if (!switches::IsRunWebTestsSwitchPresent())
611 return PictureInPictureResult::kNotSupported;
Becca Hughes112832e2019-06-11 17:19:02612 return PictureInPictureResult::kSuccess;
Mounir Lamouri11e9ef432018-05-22 03:10:16613}
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