blob: 5d066025cba04cab9b8e5792f6cfe2c36e0cf25b [file] [log] [blame]
Avi Drissman4e1b7bc32022-09-15 14:03:501// Copyright 2013 The Chromium Authors
[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
Tom Sepez8726d30e2025-01-29 02:11:085#ifdef UNSAFE_BUFFERS_BUILD
6// TODO(crbug.com/390223051): Remove C-library calls to fix the errors.
7#pragma allow_unsafe_libc_calls
8#endif
9
[email protected]de7d61ff2013-08-20 11:30:4110#include "content/shell/browser/shell.h"
[email protected]9fbd3f862011-09-20 23:31:3411
avi66a07722015-12-25 23:38:1212#include <stddef.h>
13
Lukasz Anforowicz52b93722018-06-20 16:11:3914#include <map>
Peter Boströmdd7e40ec2021-04-05 20:40:1015#include <memory>
Lukasz Anforowicz52b93722018-06-20 16:11:3916#include <string>
17#include <utility>
18
[email protected]efb5f572012-01-29 10:57:3319#include "base/command_line.h"
Avi Drissmanadac21992023-01-11 23:46:3920#include "base/functional/callback_helpers.h"
skyostil95082a62015-06-05 19:53:0721#include "base/location.h"
Wez9a58a152018-06-07 18:59:3322#include "base/no_destructor.h"
fdoray896bea12016-06-10 15:52:0123#include "base/run_loop.h"
[email protected]21aa99682013-06-11 07:17:0124#include "base/strings/string_number_conversions.h"
25#include "base/strings/string_util.h"
[email protected]74ebfb12013-06-07 20:48:0026#include "base/strings/utf_string_conversions.h"
avi66a07722015-12-25 23:38:1227#include "build/build_config.h"
Javier Fernández García-Boente13150a042022-04-04 21:08:2228#include "components/custom_handlers/protocol_handler.h"
29#include "components/custom_handlers/protocol_handler_registry.h"
30#include "components/custom_handlers/simple_protocol_handler_registry_factory.h"
31#include "content/public/browser/browser_context.h"
Julie Jeongeun Kim88ce9ec2023-07-28 02:25:4032#include "content/public/browser/color_chooser.h"
[email protected]b50452f2014-08-18 12:31:4433#include "content/public/browser/devtools_agent_host.h"
Tommy Steimel71f154462024-05-22 19:05:0734#include "content/public/browser/document_picture_in_picture_window_controller.h"
Julie Jeongeun Kimec508272023-03-17 04:17:1235#include "content/public/browser/file_select_listener.h"
[email protected]0b659b32012-03-26 21:29:3236#include "content/public/browser/navigation_controller.h"
[email protected]b7c504c2013-05-07 14:42:1237#include "content/public/browser/navigation_entry.h"
Becca Hughes112832e2019-06-11 17:19:0238#include "content/public/browser/picture_in_picture_window_controller.h"
arthursonzognib93a4472020-04-10 07:38:0039#include "content/public/browser/presentation_receiver_flags.h"
Yutaka Hirano2109e582018-02-14 07:24:4640#include "content/public/browser/render_process_host.h"
[email protected]0b659b32012-03-26 21:29:3241#include "content/public/browser/render_view_host.h"
avif9ab5d942015-10-15 14:05:4442#include "content/public/browser/render_widget_host.h"
Xianzhu Wang6be66b012020-05-06 17:17:2543#include "content/public/browser/renderer_preferences_util.h"
[email protected]0b659b32012-03-26 21:29:3244#include "content/public/browser/web_contents.h"
guoweis8efb6d892015-10-12 18:26:1745#include "content/public/common/content_switches.h"
danakjde3e2a02020-05-12 16:51:2046#include "content/shell/app/resource.h"
[email protected]de7d61ff2013-08-20 11:30:4147#include "content/shell/browser/shell_content_browser_client.h"
48#include "content/shell/browser/shell_devtools_frontend.h"
49#include "content/shell/browser/shell_javascript_dialog_manager.h"
[email protected]b7c504c2013-05-07 14:42:1250#include "content/shell/common/shell_switches.h"
Scott Violeta35f9a42018-03-22 22:00:4451#include "media/media_buildflags.h"
Antonio Gomesb5bf548f2019-09-12 17:40:1552#include "third_party/blink/public/common/peerconnection/webrtc_ip_handling_policy.h"
Mario Sanchez Prada0bd8b8c2020-10-21 17:49:2353#include "third_party/blink/public/common/renderer_preferences/renderer_preferences.h"
Julie Jeongeun Kimec508272023-03-17 04:17:1254#include "third_party/blink/public/mojom/choosers/file_chooser.mojom-forward.h"
Brad Triebwasser767c27a2022-08-25 22:56:0555#include "third_party/blink/public/mojom/window_features/window_features.mojom.h"
[email protected]9fbd3f862011-09-20 23:31:3456
[email protected]9fbd3f862011-09-20 23:31:3457namespace content {
58
arthursonzogni75ede192021-07-06 14:45:4659namespace {
Wezcbf4a042018-06-13 16:29:1260// Null until/unless the default main message loop is running.
Lei Zhangebdd085d2022-10-25 17:24:2661base::OnceClosure& GetMainMessageLoopQuitClosure() {
62 static base::NoDestructor<base::OnceClosure> closure;
63 return *closure;
64}
Wez9a58a152018-06-07 18:59:3365
Lei Zhangebdd085d2022-10-25 17:24:2666constexpr int kDefaultTestWindowWidthDip = 800;
67constexpr int kDefaultTestWindowHeightDip = 600;
[email protected]1e57cab2013-05-28 04:26:1168
arthursonzogni75ede192021-07-06 14:45:4669// Owning pointer. We can not use unique_ptr as a global. That introduces a
70// static constructor/destructor.
71// Acquired in Shell::Init(), released in Shell::Shutdown().
72ShellPlatformDelegate* g_platform;
73} // namespace
74
[email protected]e99ca5112011-09-26 17:22:5475std::vector<Shell*> Shell::windows_;
danakja9fe91c2019-05-01 19:02:2976base::OnceCallback<void(Shell*)> Shell::shell_created_callback_;
[email protected]9fbd3f862011-09-20 23:31:3477
Bo Liu300c6052018-06-12 04:46:0778Shell::Shell(std::unique_ptr<WebContents> web_contents,
79 bool should_set_delegate)
erikchenbee5c9622018-04-27 19:30:2580 : WebContentsObserver(web_contents.get()),
danakjde3e2a02020-05-12 16:51:2081 web_contents_(std::move(web_contents)) {
Bo Liu300c6052018-06-12 04:46:0782 if (should_set_delegate)
83 web_contents_->SetDelegate(this);
arthursonzognifdd49912017-08-31 08:55:2684
danakjd4b48df52020-07-02 18:16:4885 if (!switches::IsRunWebTestsSwitchPresent()) {
Xianzhu Wang6be66b012020-05-06 17:17:2586 UpdateFontRendererPreferencesFromSystemSettings(
87 web_contents_->GetMutableRendererPrefs());
Francois Doraye6161152018-03-27 22:05:3788 }
Pavel Feldmanc7cd063c2017-10-06 20:04:2889
[email protected]9e00e6352012-07-30 17:05:1890 windows_.push_back(this);
91
danakja9fe91c2019-05-01 19:02:2992 if (shell_created_callback_)
93 std::move(shell_created_callback_).Run(this);
[email protected]9fbd3f862011-09-20 23:31:3494}
95
96Shell::~Shell() {
danakjde3e2a02020-05-12 16:51:2097 g_platform->CleanUp(this);
[email protected]e99ca5112011-09-26 17:22:5498
99 for (size_t i = 0; i < windows_.size(); ++i) {
100 if (windows_[i] == this) {
101 windows_.erase(windows_.begin() + i);
102 break;
103 }
104 }
[email protected]11a65b692012-03-30 11:29:16105
Sergey Ulanovf0875d12019-01-03 20:33:23106 web_contents_->SetDelegate(nullptr);
107 web_contents_.reset();
Arthur Sonzogni9e72df3f2021-07-02 14:32:17108
arthursonzogni75ede192021-07-06 14:45:46109 if (windows().empty())
110 g_platform->DidCloseLastWindow();
[email protected]9fbd3f862011-09-20 23:31:34111}
112
erikchenbee5c9622018-04-27 19:30:25113Shell* Shell::CreateShell(std::unique_ptr<WebContents> web_contents,
Bo Liu300c6052018-06-12 04:46:07114 const gfx::Size& initial_size,
115 bool should_set_delegate) {
erikchenbee5c9622018-04-27 19:30:25116 WebContents* raw_web_contents = web_contents.get();
Bo Liu300c6052018-06-12 04:46:07117 Shell* shell = new Shell(std::move(web_contents), should_set_delegate);
danakjde3e2a02020-05-12 16:51:20118 g_platform->CreatePlatformWindow(shell, initial_size);
[email protected]1596efb2013-01-17 22:13:01119
creisb6561df2016-02-11 20:20:54120 // Note: Do not make RenderFrameHost or RenderViewHost specific state changes
121 // here, because they will be forgotten after a cross-process navigation. Use
122 // RenderFrameCreated or RenderViewCreated instead.
Kent Tamuracd3ebc42018-05-16 06:44:22123 if (switches::IsRunWebTestsSwitchPresent()) {
erikchenbee5c9622018-04-27 19:30:25124 raw_web_contents->GetMutableRendererPrefs()->use_custom_colors = false;
Bruce Long1e3e1f542019-10-16 17:56:28125 raw_web_contents->SyncRendererPrefs();
[email protected]1596efb2013-01-17 22:13:01126 }
127
lukasza381b0492016-03-10 16:48:43128 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
guoweis4ee48592015-12-02 06:37:07129 if (command_line->HasSwitch(switches::kForceWebRtcIPHandlingPolicy)) {
erikchenbee5c9622018-04-27 19:30:25130 raw_web_contents->GetMutableRendererPrefs()->webrtc_ip_handling_policy =
Guido Urdanetad8bfc6f92024-12-11 14:01:22131 blink::ToWebRTCIPHandlingPolicy(command_line->GetSwitchValueASCII(
132 switches::kForceWebRtcIPHandlingPolicy));
guoweis8efb6d892015-10-12 18:26:17133 }
guoweis8efb6d892015-10-12 18:26:17134
danakj8de3b7492020-07-02 22:41:42135 g_platform->SetContents(shell);
136 g_platform->DidCreateOrAttachWebContents(shell, raw_web_contents);
danakj3dd7a6102020-12-30 19:58:39137 // If the RenderFrame was created during WebContents construction (as happens
138 // for windows opened from the renderer) then the Shell won't hear about the
139 // main frame being created as a WebContentsObservers. This gives the delegate
140 // a chance to act on the main frame accordingly.
Dave Tapuska327c06c92022-06-13 20:31:51141 if (raw_web_contents->GetPrimaryMainFrame()->IsRenderFrameLive())
danakj3dd7a6102020-12-30 19:58:39142 g_platform->MainFrameCreated(shell);
danakj7da833932020-06-23 21:49:40143
[email protected]3fd84032012-01-12 18:20:17144 return shell;
145}
146
arthursonzogni75ede192021-07-06 14:45:46147// static
Wezcbf4a042018-06-13 16:29:12148void Shell::SetMainMessageLoopQuitClosure(base::OnceClosure quit_closure) {
Lei Zhangebdd085d2022-10-25 17:24:26149 GetMainMessageLoopQuitClosure() = std::move(quit_closure);
Wezcbf4a042018-06-13 16:29:12150}
151
arthursonzogni75ede192021-07-06 14:45:46152// static
Wez7d3eb012018-06-20 22:51:28153void Shell::QuitMainMessageLoopForTesting() {
Lei Zhangebdd085d2022-10-25 17:24:26154 auto& quit_loop = GetMainMessageLoopQuitClosure();
155 if (quit_loop)
156 std::move(quit_loop).Run();
Wez7d3eb012018-06-20 22:51:28157}
158
arthursonzogni75ede192021-07-06 14:45:46159// static
[email protected]9e00e6352012-07-30 17:05:18160void Shell::SetShellCreatedCallback(
danakja9fe91c2019-05-01 19:02:29161 base::OnceCallback<void(Shell*)> shell_created_callback) {
162 DCHECK(!shell_created_callback_);
Tommy Nyquist4b749d02018-03-20 21:46:29163 shell_created_callback_ = std::move(shell_created_callback);
[email protected]9e00e6352012-07-30 17:05:18164}
165
danakjde3e2a02020-05-12 16:51:20166// static
167bool Shell::ShouldHideToolbar() {
168 return base::CommandLine::ForCurrentProcess()->HasSwitch(
169 switches::kContentShellHideToolbar);
170}
171
arthursonzogni75ede192021-07-06 14:45:46172// static
David Benjaminf62c6662019-03-21 20:25:04173Shell* Shell::FromWebContents(WebContents* web_contents) {
174 for (Shell* window : windows_) {
175 if (window->web_contents() && window->web_contents() == web_contents) {
176 return window;
[email protected]74830f02012-01-30 22:27:04177 }
178 }
Ivan Kotenkov2c0d2bb32017-11-01 15:41:28179 return nullptr;
[email protected]74830f02012-01-30 22:27:04180}
181
arthursonzogni75ede192021-07-06 14:45:46182// static
danakjde3e2a02020-05-12 16:51:20183void Shell::Initialize(std::unique_ptr<ShellPlatformDelegate> platform) {
arthursonzogni75ede192021-07-06 14:45:46184 DCHECK(!g_platform);
danakjde3e2a02020-05-12 16:51:20185 g_platform = platform.release();
186 g_platform->Initialize(GetShellDefaultSize());
[email protected]6153b272013-01-25 22:29:23187}
188
arthursonzogni75ede192021-07-06 14:45:46189// static
190void Shell::Shutdown() {
191 if (!g_platform) // Shutdown has already been called.
192 return;
193
194 DevToolsAgentHost::DetachAllClients();
195
196 while (!Shell::windows().empty())
197 Shell::windows().back()->Close();
198
199 delete g_platform;
200 g_platform = nullptr;
201
202 for (auto it = RenderProcessHost::AllHostsIterator(); !it.IsAtEnd();
203 it.Advance()) {
W. James MacLean94cc84962021-09-07 21:51:40204 it.GetCurrentValue()->DisableRefCounts();
arthursonzogni75ede192021-07-06 14:45:46205 }
Lei Zhangebdd085d2022-10-25 17:24:26206 auto& quit_loop = GetMainMessageLoopQuitClosure();
207 if (quit_loop)
208 std::move(quit_loop).Run();
arthursonzogni75ede192021-07-06 14:45:46209
Victor Hugo Vianna Silvad9412fe72025-06-17 14:58:46210 // Pump the message loop to allow window teardown tasks to run. On iOS the
211 // run loop is controlled differently and cannot be pumped.
212#if !BUILDFLAG(IS_IOS)
arthursonzogni75ede192021-07-06 14:45:46213 base::RunLoop().RunUntilIdle();
Victor Hugo Vianna Silvad9412fe72025-06-17 14:58:46214#endif // !BUILDFLAG(IS_IOS)
arthursonzogni75ede192021-07-06 14:45:46215}
216
[email protected]a2904092013-10-15 04:53:59217gfx::Size Shell::AdjustWindowSize(const gfx::Size& initial_size) {
218 if (!initial_size.IsEmpty())
219 return initial_size;
pdrcab84ee2015-03-13 21:47:04220 return GetShellDefaultSize();
[email protected]a2904092013-10-15 04:53:59221}
222
arthursonzogni75ede192021-07-06 14:45:46223// static
[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)) {
Johann5a6cf012023-01-17 20:24:13231 create_params.starting_sandbox_flags = kPresentationReceiverSandboxFlags;
mark a. foltzef394fce2017-10-21 09:11:02232 }
erikchenbee5c9622018-04-27 19:30:25233 std::unique_ptr<WebContents> web_contents =
Erik Chenbb8e738e2018-04-28 14:10:43234 WebContents::Create(create_params);
erikchenbee5c9622018-04-27 19:30:25235 Shell* shell =
danakjfc5184932019-09-12 18:08:32236 CreateShell(std::move(web_contents), AdjustWindowSize(initial_size),
Bo Liu300c6052018-06-12 04:46:07237 true /* should_set_delegate */);
danakj7da833932020-06-23 21:49:40238
[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
danakj3dd7a6102020-12-30 19:58:39244void Shell::RenderFrameCreated(RenderFrameHost* frame_host) {
Dave Tapuska327c06c92022-06-13 20:31:51245 if (frame_host == web_contents_->GetPrimaryMainFrame())
danakj3dd7a6102020-12-30 19:58:39246 g_platform->MainFrameCreated(this);
danakj24577b12020-05-13 22:38:18247}
248
[email protected]9fbd3f862011-09-20 23:31:34249void Shell::LoadURL(const GURL& url) {
Alex Moshchuk7e26eca2018-03-03 01:34:29250 LoadURLForFrame(
251 url, std::string(),
252 ui::PageTransitionFromInt(ui::PAGE_TRANSITION_TYPED |
253 ui::PAGE_TRANSITION_FROM_ADDRESS_BAR));
[email protected]d2494ff2013-02-20 08:22:37254}
255
Alex Moshchuk7e26eca2018-03-03 01:34:29256void Shell::LoadURLForFrame(const GURL& url,
257 const std::string& frame_name,
258 ui::PageTransition transition_type) {
[email protected]d2494ff2013-02-20 08:22:37259 NavigationController::LoadURLParams params(url);
[email protected]d2494ff2013-02-20 08:22:37260 params.frame_name = frame_name;
Alex Moshchuk7e26eca2018-03-03 01:34:29261 params.transition_type = transition_type;
[email protected]d2494ff2013-02-20 08:22:37262 web_contents_->GetController().LoadURLWithParams(params);
[email protected]9fbd3f862011-09-20 23:31:34263}
264
arthursonzogni75ede192021-07-06 14:45:46265void Shell::LoadDataWithBaseURL(const GURL& url,
266 const std::string& data,
267 const GURL& base_url) {
boliuec93ea92016-02-17 22:23:07268 bool load_as_string = false;
269 LoadDataWithBaseURLInternal(url, data, base_url, load_as_string);
270}
271
Xiaohan Wangbd084422022-01-15 18:47:51272#if BUILDFLAG(IS_ANDROID)
boliuec93ea92016-02-17 22:23:07273void Shell::LoadDataAsStringWithBaseURL(const GURL& url,
274 const std::string& data,
275 const GURL& base_url) {
276 bool load_as_string = true;
277 LoadDataWithBaseURLInternal(url, data, base_url, load_as_string);
278}
279#endif
280
281void Shell::LoadDataWithBaseURLInternal(const GURL& url,
282 const std::string& data,
283 const GURL& base_url,
284 bool load_as_string) {
Xiaohan Wangbd084422022-01-15 18:47:51285#if !BUILDFLAG(IS_ANDROID)
boliuec93ea92016-02-17 22:23:07286 DCHECK(!load_as_string); // Only supported on Android.
287#endif
288
Peter Kasting8104ba82024-01-31 15:23:40289 NavigationController::LoadURLParams params{GURL()};
boliuec93ea92016-02-17 22:23:07290 const std::string data_url_header = "data:text/html;charset=utf-8,";
291 if (load_as_string) {
292 params.url = GURL(data_url_header);
293 std::string data_url_as_string = data_url_header + data;
Xiaohan Wangbd084422022-01-15 18:47:51294#if BUILDFLAG(IS_ANDROID)
Jongmok Kimc5491082022-10-19 09:17:59295 params.data_url_as_string = base::MakeRefCounted<base::RefCountedString>(
296 std::move(data_url_as_string));
boliuec93ea92016-02-17 22:23:07297#endif
298 } else {
299 params.url = GURL(data_url_header + data);
300 }
301
[email protected]76bdecb2014-04-16 17:58:08302 params.load_type = NavigationController::LOAD_TYPE_DATA;
303 params.base_url_for_data_url = base_url;
Shu Yang112ad492024-07-25 17:11:54304 params.virtual_url_for_special_cases = url;
[email protected]76bdecb2014-04-16 17:58:08305 params.override_user_agent = NavigationController::UA_OVERRIDE_FALSE;
306 web_contents_->GetController().LoadURLWithParams(params);
[email protected]76bdecb2014-04-16 17:58:08307}
308
Dibyajyoti Pal3de66ad2024-08-23 23:34:03309WebContents* Shell::AddNewContents(
310 WebContents* source,
311 std::unique_ptr<WebContents> new_contents,
312 const GURL& target_url,
313 WindowOpenDisposition disposition,
314 const blink::mojom::WindowFeatures& window_features,
315 bool user_gesture,
316 bool* was_blocked) {
Tommy Steimel71f154462024-05-22 19:05:07317#if !BUILDFLAG(IS_ANDROID)
318 // If the shell is opening a document picture-in-picture window, it needs to
319 // inform the DocumentPictureInPictureWindowController.
320 if (disposition == WindowOpenDisposition::NEW_PICTURE_IN_PICTURE) {
321 DocumentPictureInPictureWindowController* controller =
322 PictureInPictureWindowController::
323 GetOrCreateDocumentPictureInPictureController(source);
324 controller->SetChildWebContents(new_contents.get());
325 controller->Show();
326 }
327#endif // !BUILDFLAG(IS_ANDROID)
328
Stefan Zager6f6e57c2025-03-19 22:03:45329 WebContents* result = new_contents.get();
Bo Liu300c6052018-06-12 04:46:07330 CreateShell(
Brad Triebwasser767c27a2022-08-25 22:56:05331 std::move(new_contents), AdjustWindowSize(window_features.bounds.size()),
Bo Liu300c6052018-06-12 04:46:07332 !delay_popup_contents_delegate_for_testing_ /* should_set_delegate */);
Stefan Zager6f6e57c2025-03-19 22:03:45333 return result;
[email protected]a2904092013-10-15 04:53:59334}
335
[email protected]9fbd3f862011-09-20 23:31:34336void Shell::GoBackOrForward(int offset) {
[email protected]0b659b32012-03-26 21:29:32337 web_contents_->GetController().GoToOffset(offset);
[email protected]9fbd3f862011-09-20 23:31:34338}
339
340void Shell::Reload() {
toyoshim6142d96f2016-12-19 09:07:25341 web_contents_->GetController().Reload(ReloadType::NORMAL, false);
[email protected]9fbd3f862011-09-20 23:31:34342}
343
toyoshime5aaf6a2016-05-18 08:07:48344void Shell::ReloadBypassingCache() {
toyoshim6142d96f2016-12-19 09:07:25345 web_contents_->GetController().Reload(ReloadType::BYPASSING_CACHE, false);
toyoshime5aaf6a2016-05-18 08:07:48346}
347
[email protected]9fbd3f862011-09-20 23:31:34348void Shell::Stop() {
[email protected]0b659b32012-03-26 21:29:32349 web_contents_->Stop();
[email protected]9fbd3f862011-09-20 23:31:34350}
351
Nate Chapin9aabf5f2021-11-12 00:31:19352void Shell::UpdateNavigationControls(bool should_show_loading_ui) {
[email protected]0b659b32012-03-26 21:29:32353 int current_index = web_contents_->GetController().GetCurrentEntryIndex();
354 int max_index = web_contents_->GetController().GetEntryCount() - 1;
[email protected]9fbd3f862011-09-20 23:31:34355
danakjde3e2a02020-05-12 16:51:20356 g_platform->EnableUIControl(this, ShellPlatformDelegate::BACK_BUTTON,
357 current_index > 0);
358 g_platform->EnableUIControl(this, ShellPlatformDelegate::FORWARD_BUTTON,
359 current_index < max_index);
360 g_platform->EnableUIControl(
361 this, ShellPlatformDelegate::STOP_BUTTON,
Nate Chapin9aabf5f2021-11-12 00:31:19362 should_show_loading_ui && web_contents_->IsLoading());
[email protected]9fbd3f862011-09-20 23:31:34363}
364
[email protected]7c17b6992012-08-09 16:16:30365void Shell::ShowDevTools() {
mohsen6eb57fb2016-07-22 03:14:08366 if (!devtools_frontend_) {
Dave Tapuska5198f0e2021-11-18 15:41:11367 auto* devtools_frontend = ShellDevToolsFrontend::Show(web_contents());
368 devtools_frontend_ = devtools_frontend->GetWeakPtr();
mohsen6eb57fb2016-07-22 03:14:08369 }
[email protected]3142e5d2014-02-07 00:54:46370
mohsen6eb57fb2016-07-22 03:14:08371 devtools_frontend_->Activate();
[email protected]7c17b6992012-08-09 16:16:30372}
373
[email protected]001841c92012-12-11 17:00:13374void Shell::CloseDevTools() {
[email protected]0773e0c2013-01-25 15:57:57375 if (!devtools_frontend_)
[email protected]001841c92012-12-11 17:00:13376 return;
[email protected]0773e0c2013-01-25 15:57:57377 devtools_frontend_->Close();
Ivan Kotenkov2c0d2bb32017-11-01 15:41:28378 devtools_frontend_ = nullptr;
[email protected]001841c92012-12-11 17:00:13379}
380
danakjde3e2a02020-05-12 16:51:20381void Shell::ResizeWebContentForTests(const gfx::Size& content_size) {
382 g_platform->ResizeWebContent(this, content_size);
383}
danakjde3e2a02020-05-12 16:51:20384
[email protected]9fbd3f862011-09-20 23:31:34385gfx::NativeView Shell::GetContentView() {
[email protected]59383c782013-04-17 16:43:27386 if (!web_contents_)
Avi Drissmandad01b0e2023-06-16 22:55:46387 return gfx::NativeView();
[email protected]fc2b46b2014-05-03 16:33:45388 return web_contents_->GetNativeView();
[email protected]9fbd3f862011-09-20 23:31:34389}
390
Xiaohan Wangbd084422022-01-15 18:47:51391#if !BUILDFLAG(IS_ANDROID)
danakjde3e2a02020-05-12 16:51:20392gfx::NativeWindow Shell::window() {
393 return g_platform->GetNativeWindow(this);
394}
395#endif
396
Xiaohan Wangbd084422022-01-15 18:47:51397#if BUILDFLAG(IS_MAC)
danakjde3e2a02020-05-12 16:51:20398void Shell::ActionPerformed(int control) {
399 switch (control) {
400 case IDC_NAV_BACK:
401 GoBackOrForward(-1);
402 break;
403 case IDC_NAV_FORWARD:
404 GoBackOrForward(1);
405 break;
406 case IDC_NAV_RELOAD:
407 Reload();
408 break;
409 case IDC_NAV_STOP:
410 Stop();
411 break;
412 }
413}
414
415void Shell::URLEntered(const std::string& url_string) {
416 if (!url_string.empty()) {
417 GURL url(url_string);
418 if (!url.has_scheme())
419 url = GURL("http://" + url_string);
420 LoadURL(url);
421 }
422}
423#endif
424
HuanPo Lin0d795c62024-03-28 03:54:05425WebContents* Shell::OpenURLFromTab(
426 WebContents* source,
427 const OpenURLParams& params,
428 base::OnceCallback<void(content::NavigationHandle&)>
429 navigation_handle_callback) {
lukasza04130152016-10-21 20:26:32430 WebContents* target = nullptr;
431 switch (params.disposition) {
432 case WindowOpenDisposition::CURRENT_TAB:
433 target = source;
434 break;
435
436 // Normally, the difference between NEW_POPUP and NEW_WINDOW is that a popup
437 // should have no toolbar, no status bar, no menu bar, no scrollbars and be
438 // not resizable. For simplicity and to enable new testing scenarios in
Kent Tamura21d1de62018-12-10 04:45:20439 // content shell and web tests, popups don't get special treatment below
lukasza04130152016-10-21 20:26:32440 // (i.e. they will have a toolbar and other things described here).
441 case WindowOpenDisposition::NEW_POPUP:
lukaszabe2f0da2017-04-25 00:43:00442 case WindowOpenDisposition::NEW_WINDOW:
Kent Tamura21d1de62018-12-10 04:45:20443 // content_shell doesn't really support tabs, but some web tests use
lukaszabe2f0da2017-04-25 00:43:00444 // middle click (which translates into kNavigationPolicyNewBackgroundTab),
445 // so we treat the cases below just like a NEW_WINDOW disposition.
446 case WindowOpenDisposition::NEW_BACKGROUND_TAB:
447 case WindowOpenDisposition::NEW_FOREGROUND_TAB: {
lukasza04130152016-10-21 20:26:32448 Shell* new_window =
449 Shell::CreateNewWindow(source->GetBrowserContext(),
450 GURL(), // Don't load anything just yet.
451 params.source_site_instance,
452 gfx::Size()); // Use default size.
453 target = new_window->web_contents();
lukasza04130152016-10-21 20:26:32454 break;
455 }
456
457 // No tabs in content_shell:
458 case WindowOpenDisposition::SINGLETON_TAB:
lukasza04130152016-10-21 20:26:32459 // No incognito mode in content_shell:
460 case WindowOpenDisposition::OFF_THE_RECORD:
Kent Tamura21d1de62018-12-10 04:45:20461 // TODO(lukasza): Investigate if some web tests might need support for
lukasza04130152016-10-21 20:26:32462 // SAVE_TO_DISK disposition. This would probably require that
Gyuyoung Kim26c7bc92020-04-29 00:53:00463 // WebTestControlHost always sets up and cleans up a temporary directory
lukasza04130152016-10-21 20:26:32464 // as the default downloads destinations for the duration of a test.
465 case WindowOpenDisposition::SAVE_TO_DISK:
466 // Ignoring requests with disposition == IGNORE_ACTION...
467 case WindowOpenDisposition::IGNORE_ACTION:
468 default:
469 return nullptr;
470 }
alexmos5a98a052016-01-06 00:15:02471
HuanPo Lin0d795c62024-03-28 03:54:05472 base::WeakPtr<NavigationHandle> navigation_handle =
473 target->GetController().LoadURLWithParams(
474 NavigationController::LoadURLParams(params));
475
476 if (navigation_handle_callback && navigation_handle) {
477 std::move(navigation_handle_callback).Run(*navigation_handle);
478 }
479
lukasza04130152016-10-21 20:26:32480 return target;
alexmos5a98a052016-01-06 00:15:02481}
482
[email protected]e3b10d12014-03-28 16:06:09483void Shell::LoadingStateChanged(WebContents* source,
Nate Chapin9aabf5f2021-11-12 00:31:19484 bool should_show_loading_ui) {
485 UpdateNavigationControls(should_show_loading_ui);
danakjde3e2a02020-05-12 16:51:20486 g_platform->SetIsLoading(this, source->IsLoading());
[email protected]e99ca5112011-09-26 17:22:54487}
488
Xiaohan Wangbd084422022-01-15 18:47:51489#if BUILDFLAG(IS_ANDROID)
danakjde3e2a02020-05-12 16:51:20490void Shell::SetOverlayMode(bool use_overlay_mode) {
491 g_platform->SetOverlayMode(this, use_overlay_mode);
492}
493#endif
494
Dave Tapuskaa4189512019-10-15 20:27:34495void Shell::EnterFullscreenModeForTab(
Mike Wasserman4ca09792020-05-29 17:44:43496 RenderFrameHost* requesting_frame,
Dave Tapuskaa4189512019-10-15 20:27:34497 const blink::mojom::FullscreenOptions& options) {
Mike Wasserman4ca09792020-05-29 17:44:43498 ToggleFullscreenModeForTab(WebContents::FromRenderFrameHost(requesting_frame),
499 true);
mlamouri7a78d6fd2015-01-17 13:23:53500}
501
502void Shell::ExitFullscreenModeForTab(WebContents* web_contents) {
503 ToggleFullscreenModeForTab(web_contents, false);
504}
505
[email protected]99c014c2012-11-27 12:03:42506void Shell::ToggleFullscreenModeForTab(WebContents* web_contents,
507 bool enter_fullscreen) {
Dave Tapuska1efc3012023-02-23 17:27:17508#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_IOS)
danakjde3e2a02020-05-12 16:51:20509 g_platform->ToggleFullscreenModeForTab(this, web_contents, enter_fullscreen);
[email protected]99c014c2012-11-27 12:03:42510#endif
[email protected]99c014c2012-11-27 12:03:42511 if (is_fullscreen_ != enter_fullscreen) {
512 is_fullscreen_ = enter_fullscreen;
Dave Tapuska327c06c92022-06-13 20:31:51513 web_contents->GetPrimaryMainFrame()
Lucas Furukawa Gadanie7649422021-02-03 03:04:32514 ->GetRenderViewHost()
Fady Samuel0b911822018-04-25 13:22:16515 ->GetWidget()
516 ->SynchronizeVisualProperties();
[email protected]99c014c2012-11-27 12:03:42517 }
518}
519
Lucas Furukawa Gadani4909f3c2019-06-18 22:36:52520bool Shell::IsFullscreenForTabOrPending(const WebContents* web_contents) {
Dave Tapuska1efc3012023-02-23 17:27:17521#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_IOS)
danakjde3e2a02020-05-12 16:51:20522 return g_platform->IsFullscreenForTabOrPending(this, web_contents);
[email protected]99c014c2012-11-27 12:03:42523#else
524 return is_fullscreen_;
525#endif
526}
527
Eric Willigers052f0432019-10-04 04:06:57528blink::mojom::DisplayMode Shell::GetDisplayMode(
529 const WebContents* web_contents) {
530 // TODO: should return blink::mojom::DisplayModeFullscreen wherever user puts
Lukasz Anforowicz52b93722018-06-20 16:11:39531 // a browser window into fullscreen (not only in case of renderer-initiated
532 // fullscreen mode): crbug.com/476874.
533 return IsFullscreenForTabOrPending(web_contents)
Eric Willigers052f0432019-10-04 04:06:57534 ? blink::mojom::DisplayMode::kFullscreen
535 : blink::mojom::DisplayMode::kBrowser;
mikhail.pozdnyakovc0e251b2015-04-15 06:51:12536}
537
Javier Fernández García-Boente13150a042022-04-04 21:08:22538#if !BUILDFLAG(IS_ANDROID)
539void Shell::RegisterProtocolHandler(RenderFrameHost* requesting_frame,
540 const std::string& protocol,
541 const GURL& url,
542 bool user_gesture) {
Johann5a6cf012023-01-17 20:24:13543 BrowserContext* context = requesting_frame->GetBrowserContext();
Javier Fernández García-Boente13150a042022-04-04 21:08:22544 if (context->IsOffTheRecord())
545 return;
546
547 custom_handlers::ProtocolHandler handler =
548 custom_handlers::ProtocolHandler::CreateProtocolHandler(
549 protocol, url, GetProtocolHandlerSecurityLevel(requesting_frame));
550
551 // The parameters's normalization process defined in the spec has been already
552 // applied in the WebContentImpl class, so at this point it shouldn't be
553 // possible to create an invalid handler.
554 // https://html.spec.whatwg.org/multipage/system-state.html#normalize-protocol-handler-parameters
555 DCHECK(handler.IsValid());
556
557 custom_handlers::ProtocolHandlerRegistry* registry = custom_handlers::
558 SimpleProtocolHandlerRegistryFactory::GetForBrowserContext(context, true);
559 DCHECK(registry);
560 if (registry->SilentlyHandleRegisterHandlerRequest(handler))
561 return;
562
Javier Fernández García-Boentea2b1f18b2022-04-11 22:05:53563 if (!user_gesture && !windows_.empty()) {
564 // TODO(jfernandez): This is not strictly needed, but we need a way to
565 // inform the observers in browser tests that the request has been
566 // cancelled, to avoid timeouts. Chrome just holds the handler as pending in
567 // the PageContentSettingsDelegate, but we don't have such thing in the
568 // Content Shell.
569 registry->OnDenyRegisterProtocolHandler(handler);
570 return;
571 }
572
Javier Fernández García-Boente13150a042022-04-04 21:08:22573 // FencedFrames can not register to handle any protocols.
574 if (requesting_frame->IsNestedWithinFencedFrame()) {
575 registry->OnIgnoreRegisterProtocolHandler(handler);
576 return;
577 }
578
579 // TODO(jfernandez): Are we interested at all on using the
580 // PermissionRequestManager in the ContentShell ?
Javier Fernández García-Boentec0e70552023-02-03 09:41:13581 if (registry->registration_mode() ==
582 custom_handlers::RphRegistrationMode::kAutoAccept) {
583 registry->OnAcceptRegisterProtocolHandler(handler);
584 }
Javier Fernández García-Boente13150a042022-04-04 21:08:22585}
David Risneyda4fd3a2025-03-18 18:34:49586
587void Shell::UnregisterProtocolHandler(RenderFrameHost* requesting_frame,
588 const std::string& protocol,
589 const GURL& url,
590 bool user_gesture) {
591 BrowserContext* context = requesting_frame->GetBrowserContext();
592 if (context->IsOffTheRecord()) {
593 return;
594 }
595
596 custom_handlers::ProtocolHandler handler =
597 custom_handlers::ProtocolHandler::CreateProtocolHandler(
598 protocol, url, GetProtocolHandlerSecurityLevel(requesting_frame));
599 custom_handlers::ProtocolHandlerRegistry* registry = custom_handlers::
600 SimpleProtocolHandlerRegistryFactory::GetForBrowserContext(context, true);
601 CHECK(registry);
602
603 registry->RemoveHandler(handler);
604}
Javier Fernández García-Boente13150a042022-04-04 21:08:22605#endif
606
Takumi Fujimoto4661871d2024-01-25 02:04:18607void Shell::RequestPointerLock(WebContents* web_contents,
[email protected]f78439002012-11-28 14:45:59608 bool user_gesture,
609 bool last_unlocked_by_target) {
Dave Tapuskab4998782020-10-08 17:22:47610 // Give the platform a chance to handle the lock request, if it doesn't
611 // indicate it handled it, allow the request.
Takumi Fujimoto4661871d2024-01-25 02:04:18612 if (!g_platform->HandlePointerLockRequest(this, web_contents, user_gesture,
Dave Tapuskab4998782020-10-08 17:22:47613 last_unlocked_by_target)) {
Takumi Fujimoto4661871d2024-01-25 02:04:18614 web_contents->GotResponseToPointerLockRequest(
Dave Tapuskab4998782020-10-08 17:22:47615 blink::mojom::PointerLockResult::kSuccess);
616 }
[email protected]f78439002012-11-28 14:45:59617}
618
danakjde3e2a02020-05-12 16:51:20619void Shell::Close() {
620 // Shell is "self-owned" and destroys itself. The ShellPlatformDelegate
621 // has the chance to co-opt this and do its own destruction.
622 if (!g_platform->DestroyShell(this))
623 delete this;
624}
625
[email protected]9e00e6352012-07-30 17:05:18626void Shell::CloseContents(WebContents* source) {
627 Close();
628}
629
Lucas Furukawa Gadani4909f3c2019-06-18 22:36:52630bool Shell::CanOverscrollContent() {
[email protected]067310262012-11-22 14:30:41631#if defined(USE_AURA)
632 return true;
633#else
634 return false;
635#endif
636}
637
Mugdha Lakhani5f8de7cc2020-03-10 20:43:36638void Shell::NavigationStateChanged(WebContents* source,
639 InvalidateTypes changed_flags) {
640 if (changed_flags & INVALIDATE_TYPE_URL)
danakjde3e2a02020-05-12 16:51:20641 g_platform->SetAddressBarURL(this, source->GetVisibleURL());
[email protected]e99ca5112011-09-26 17:22:54642}
643
mathiash72a5e462014-11-19 08:18:50644JavaScriptDialogManager* Shell::GetJavaScriptDialogManager(
645 WebContents* source) {
danakj8de3b7492020-07-02 22:41:42646 if (!dialog_manager_)
647 dialog_manager_ = g_platform->CreateJavaScriptDialogManager(this);
648 if (!dialog_manager_)
649 dialog_manager_ = std::make_unique<ShellJavaScriptDialogManager>();
[email protected]71a88bb2013-02-01 22:05:15650 return dialog_manager_.get();
[email protected]f2210022012-03-29 00:36:08651}
652
Xiaohan Wangbd084422022-01-15 18:47:51653#if BUILDFLAG(IS_MAC)
Johann5a6cf012023-01-17 20:24:13654void Shell::PrimaryPageChanged(Page& page) {
Julie Jeongeun Kimc37853f2022-12-16 11:00:32655 g_platform->DidNavigatePrimaryMainFramePostCommit(
Johann5a6cf012023-01-17 20:24:13656 this, WebContents::FromRenderFrameHost(&page.GetMainDocument()));
Xianzhu Wang0f021a82020-07-03 01:29:47657}
658
danakjde3e2a02020-05-12 16:51:20659bool Shell::HandleKeyboardEvent(WebContents* source,
Kartar Singh5c8e0b22024-05-30 10:32:14660 const input::NativeWebKeyboardEvent& event) {
danakjde3e2a02020-05-12 16:51:20661 return g_platform->HandleKeyboardEvent(this, source, event);
662}
663#endif
664
avia90ae4e2016-11-11 20:49:33665bool Shell::DidAddMessageToConsole(WebContents* source,
Lowell Manners1de5242e2019-04-25 10:18:46666 blink::mojom::ConsoleMessageLevel log_level,
Jan Wilken Dörrieaace0cfef2021-03-11 22:01:58667 const std::u16string& message,
avia90ae4e2016-11-11 20:49:33668 int32_t line_no,
Jan Wilken Dörrieaace0cfef2021-03-11 22:01:58669 const std::u16string& source_id) {
Kent Tamuracd3ebc42018-05-16 06:44:22670 return switches::IsRunWebTestsSwitchPresent();
[email protected]efb5f572012-01-29 10:57:33671}
672
Lukasz Anforowicz52b93722018-06-20 16:11:39673void Shell::RendererUnresponsive(
674 WebContents* source,
675 RenderWidgetHost* render_widget_host,
676 base::RepeatingClosure hang_monitor_restarter) {
danakj245441f2020-07-03 15:18:41677 LOG(WARNING) << "renderer unresponsive";
[email protected]5bf68f22012-08-31 07:38:10678}
679
[email protected]233567d2013-02-27 20:22:02680void Shell::ActivateContents(WebContents* contents) {
Xiaohan Wangbd084422022-01-15 18:47:51681#if !BUILDFLAG(IS_MAC)
danakjd4b48df52020-07-02 18:16:48682 // TODO(danakj): Move this to ShellPlatformDelegate.
danakj674bf1c02020-05-01 18:37:51683 contents->Focus();
684#else
685 // Mac headless mode is quite different than other platforms. Normally
686 // focusing the WebContents would cause the OS to focus the window. Because
687 // headless mac doesn't actually have system windows, we can't go down the
688 // normal path and have to fake it out in the browser process.
danakjde3e2a02020-05-12 16:51:20689 g_platform->ActivateContents(this, contents);
danakj674bf1c02020-05-01 18:37:51690#endif
[email protected]233567d2013-02-27 20:22:02691}
692
Tom Burginf0e48622024-05-16 15:06:12693#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_IOS)
Julie Jeongeun Kim88ce9ec2023-07-28 02:25:40694std::unique_ptr<ColorChooser> Shell::OpenColorChooser(
695 WebContents* web_contents,
696 SkColor color,
697 const std::vector<blink::mojom::ColorSuggestionPtr>& suggestions) {
698 return g_platform->OpenColorChooser(web_contents, color, suggestions);
699}
700#endif
701
Julie Jeongeun Kimec508272023-03-17 04:17:12702void Shell::RunFileChooser(RenderFrameHost* render_frame_host,
703 scoped_refptr<FileSelectListener> listener,
704 const blink::mojom::FileChooserParams& params) {
Bo Liu3afe2582023-08-11 23:02:56705 run_file_chooser_count_++;
706 if (hold_file_chooser_) {
707 held_file_chooser_listener_ = std::move(listener);
708 } else {
709 g_platform->RunFileChooser(render_frame_host, std::move(listener), params);
710 }
711}
712
713void Shell::EnumerateDirectory(WebContents* web_contents,
714 scoped_refptr<FileSelectListener> listener,
715 const base::FilePath& path) {
716 run_file_chooser_count_++;
717 if (hold_file_chooser_) {
718 held_file_chooser_listener_ = std::move(listener);
719 } else {
720 listener->FileSelectionCanceled();
721 }
Julie Jeongeun Kimec508272023-03-17 04:17:12722}
723
Jiacheng Guo3168d132024-05-31 04:31:06724bool Shell::IsBackForwardCacheSupported(WebContents& web_contents) {
Dave Tapuskadfff7382021-04-23 19:46:41725 return true;
726}
727
Hiroki Nakagawa662e7cc2024-12-16 05:15:36728PreloadingEligibility Shell::IsPrerender2Supported(
729 WebContents& web_contents,
730 PreloadingTriggerType trigger_type) {
Johanna0b3e9b2023-01-19 23:23:35731 return PreloadingEligibility::kEligible;
Lingqi Chi8159aec2021-06-15 01:46:03732}
733
Adithya Srinivasanb7204c82020-08-17 14:26:33734namespace {
735class PendingCallback : public base::RefCounted<PendingCallback> {
736 public:
737 explicit PendingCallback(base::OnceCallback<void()> cb)
738 : callback_(std::move(cb)) {}
739
740 private:
741 friend class base::RefCounted<PendingCallback>;
742 ~PendingCallback() { std::move(callback_).Run(); }
743 base::OnceCallback<void()> callback_;
744};
745} // namespace
746
Lukasz Anforowicz82a5ca92019-10-24 18:45:37747bool Shell::ShouldAllowRunningInsecureContent(WebContents* web_contents,
748 bool allowed_per_prefs,
749 const url::Origin& origin,
750 const GURL& resource_url) {
danakj8de3b7492020-07-02 22:41:42751 if (allowed_per_prefs)
752 return true;
carloskd9d97942017-02-16 08:58:09753
danakj8de3b7492020-07-02 22:41:42754 return g_platform->ShouldAllowRunningInsecureContent(this);
carloskd9d97942017-02-16 08:58:09755}
756
François Beaufort1388f2892022-01-29 08:22:47757PictureInPictureResult Shell::EnterPictureInPicture(WebContents* web_contents) {
Becca Hughes112832e2019-06-11 17:19:02758 // During tests, returning success to pretend the window was created and allow
759 // tests to run accordingly.
760 if (!switches::IsRunWebTestsSwitchPresent())
761 return PictureInPictureResult::kNotSupported;
Becca Hughes112832e2019-06-11 17:19:02762 return PictureInPictureResult::kSuccess;
Mounir Lamouri11e9ef432018-05-22 03:10:16763}
764
Bo Liu300c6052018-06-12 04:46:07765bool Shell::ShouldResumeRequestsForCreatedWindow() {
766 return !delay_popup_contents_delegate_for_testing_;
767}
768
danakjee2390a82020-06-10 16:53:37769void Shell::SetContentsBounds(WebContents* source, const gfx::Rect& bounds) {
770 DCHECK(source == web_contents()); // There's only one WebContents per Shell.
771
772 if (switches::IsRunWebTestsSwitchPresent()) {
773 // Note that chrome drops these requests on normal windows.
774 // TODO(danakj): The position is dropped here but we use the size. Web tests
775 // can't move the window in headless mode anyways, but maybe we should be
776 // letting them pretend?
777 g_platform->ResizeWebContent(this, bounds.size());
778 }
779}
780
pdrcab84ee2015-03-13 21:47:04781gfx::Size Shell::GetShellDefaultSize() {
danakj6c16fe92020-09-18 23:51:32782 static gfx::Size default_shell_size; // Only go through this method once.
783
pdrcab84ee2015-03-13 21:47:04784 if (!default_shell_size.IsEmpty())
785 return default_shell_size;
danakj6c16fe92020-09-18 23:51:32786
pdrcab84ee2015-03-13 21:47:04787 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
788 if (command_line->HasSwitch(switches::kContentShellHostWindowSize)) {
789 const std::string size_str = command_line->GetSwitchValueASCII(
arthursonzogni75ede192021-07-06 14:45:46790 switches::kContentShellHostWindowSize);
pdrcab84ee2015-03-13 21:47:04791 int width, height;
danakj6c16fe92020-09-18 23:51:32792 if (sscanf(size_str.c_str(), "%dx%d", &width, &height) == 2) {
793 default_shell_size = gfx::Size(width, height);
794 } else {
795 LOG(ERROR) << "Invalid size \"" << size_str << "\" given to --"
796 << switches::kContentShellHostWindowSize;
797 }
798 }
799
800 if (default_shell_size.IsEmpty()) {
arthursonzogni75ede192021-07-06 14:45:46801 default_shell_size =
802 gfx::Size(kDefaultTestWindowWidthDip, kDefaultTestWindowHeightDip);
pdrcab84ee2015-03-13 21:47:04803 }
danakj6c16fe92020-09-18 23:51:32804
pdrcab84ee2015-03-13 21:47:04805 return default_shell_size;
806}
807
Xiaohan Wangbd084422022-01-15 18:47:51808#if BUILDFLAG(IS_ANDROID)
danakjde3e2a02020-05-12 16:51:20809void Shell::LoadProgressChanged(double progress) {
810 g_platform->LoadProgressChanged(this, progress);
811}
812#endif
813
Avi Drissman93002212017-09-27 03:20:52814void Shell::TitleWasSet(NavigationEntry* entry) {
[email protected]1ef02d242013-10-07 16:18:53815 if (entry)
danakjde3e2a02020-05-12 16:51:20816 g_platform->SetTitle(this, entry->GetTitle());
[email protected]aecc085b2012-06-01 18:15:53817}
818
[email protected]9fbd3f862011-09-20 23:31:34819} // namespace content