blob: 5a0c8c503648d9173a883c4481a6894e34fb3f21 [file] [log] [blame]
Avi Drissman4e1b7bc32022-09-15 14:03:501// Copyright 2012 The Chromium Authors
license.botbf09a502008-08-24 00:55:552// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
initial.commit09911bf2008-07-26 23:55:294
[email protected]93ddb3c2012-04-11 21:44:295#include "content/browser/web_contents/web_contents_impl.h"
[email protected]39526562011-02-05 03:41:516
avib7348942015-12-25 20:57:107#include <stddef.h>
8
w.shackleton49bcd392016-01-06 17:38:229#include <cmath>
Alexander Timin5fdeff22020-09-08 09:20:3710#include <memory>
Jan Wilken Dörriead587c32021-03-11 14:09:2711#include <string>
[email protected]2bb171882012-03-07 02:09:4612#include <utility>
rkaplowe56a52032017-02-07 00:14:5413#include <vector>
[email protected]b75b8292010-10-01 07:28:2514
Bartek Nowierskid5d1984a2022-12-18 12:13:1515#include "base/allocator/partition_allocator/partition_alloc_buildflags.h"
K. Moon97def7d2022-02-01 15:56:0216#include "base/check_op.h"
[email protected]36fb2c7c2011-04-04 15:49:0817#include "base/command_line.h"
Lei Zhangd4f2c7ad2021-05-13 20:10:1218#include "base/containers/contains.h"
Lei Zhang7375aec2021-06-30 16:54:5319#include "base/containers/cxx20_erase.h"
Avi Drissman33972942020-06-19 14:16:0120#include "base/containers/flat_set.h"
zqzhang181047e62016-07-01 13:37:1721#include "base/feature_list.h"
Marijn Kruisselbrink46fa4bd2019-07-11 18:15:4722#include "base/files/file_path.h"
Avi Drissmanadac21992023-01-11 23:46:3923#include "base/functional/bind.h"
[email protected]cbb1ef592013-06-05 19:49:4624#include "base/lazy_instance.h"
skyostil95082a62015-06-05 19:53:0725#include "base/location.h"
[email protected]6d636e62013-07-31 03:15:5626#include "base/logging.h"
fdorayba121422016-12-23 19:51:4827#include "base/memory/ptr_util.h"
Keishi Hattori0e45c022021-11-27 09:25:5228#include "base/memory/raw_ptr.h"
dmazzonid95ae842016-04-12 21:17:3929#include "base/memory/ref_counted.h"
Rakina Zata Amni4029b6d2020-07-28 02:36:2030#include "base/metrics/field_trial.h"
Joe Mason7dabc6f2021-12-06 17:29:0331#include "base/metrics/histogram_functions.h"
asvitkine8d51e9d2016-09-02 23:55:4332#include "base/metrics/histogram_macros.h"
bratell0a7406f2017-03-28 07:46:3733#include "base/metrics/user_metrics.h"
Avi Drissman4891b852018-09-25 18:12:5834#include "base/no_destructor.h"
David Sandersd4bf5eb2022-03-17 07:12:0535#include "base/observer_list.h"
[email protected]04cbd3d2013-12-04 04:58:2036#include "base/process/process.h"
Peter Kastingd5685942022-09-02 17:52:1737#include "base/ranges/algorithm.h"
Avi Drissman4891b852018-09-25 18:12:5838#include "base/strings/string_split.h"
[email protected]348fbaac2013-06-11 06:31:5139#include "base/strings/string_util.h"
Lei Zhange02299a2021-04-26 23:12:2440#include "base/strings/stringprintf.h"
Rakina Zata Amni4029b6d2020-07-28 02:36:2041#include "base/system/sys_info.h"
Patrick Monette643cdf62021-10-15 19:13:4242#include "base/task/single_thread_task_runner.h"
[email protected]a43858f2013-06-28 15:18:3743#include "base/time/time.h"
Alexander Timin5fdeff22020-09-08 09:20:3744#include "base/trace_event/optional_trace_event.h"
ssid3e765612015-01-28 04:03:4245#include "base/trace_event/trace_event.h"
avib7348942015-12-25 20:57:1046#include "build/build_config.h"
Hidehiko Abe7c68f582020-09-03 15:47:2547#include "build/chromeos_buildflags.h"
Min Qinda0ed2062018-02-23 22:00:5348#include "components/download/public/common/download_stats.h"
Eric Secklerab20ea22021-02-08 11:39:2649#include "components/power_scheduler/power_mode.h"
50#include "components/power_scheduler/power_mode_arbiter.h"
51#include "components/power_scheduler/power_mode_voter.h"
rsleevi24f64dc22015-08-07 21:39:2152#include "components/url_formatter/url_formatter.h"
Alexander Surkovfb6cb382020-12-01 14:46:2353#include "content/browser/accessibility/browser_accessibility.h"
Steve Kobes6615df92021-03-15 18:02:2054#include "content/browser/accessibility/browser_accessibility_state_impl.h"
Andrew Paseltiner7cbb6172021-10-06 21:22:5155#include "content/browser/attribution_reporting/attribution_host.h"
jamescookda2505812015-03-20 18:01:1856#include "content/browser/bad_message.h"
Max Morinddebb972018-09-20 10:04:1457#include "content/browser/browser_main_loop.h"
[email protected]7a846df2012-09-20 19:17:3958#include "content/browser/browser_plugin/browser_plugin_embedder.h"
59#include "content/browser/browser_plugin/browser_plugin_guest.h"
[email protected]b9535422012-02-09 01:47:5960#include "content/browser/child_process_security_policy_impl.h"
Pavel Feldman3c1842b2017-08-02 05:00:1661#include "content/browser/devtools/protocol/page_handler.h"
dgozmanf00c4f72016-10-19 17:45:1562#include "content/browser/devtools/render_frame_devtools_agent_host.h"
Becca Hughes3b5a43482018-07-17 22:31:5563#include "content/browser/display_cutout/display_cutout_host_impl.h"
[email protected]5f2aa722013-08-07 16:59:4164#include "content/browser/dom_storage/dom_storage_context_wrapper.h"
[email protected]1ea3c792012-04-17 01:25:0465#include "content/browser/dom_storage/session_storage_namespace_impl.h"
[email protected]aa4f3972012-03-01 18:12:1266#include "content/browser/download/mhtml_generation_manager.h"
[email protected]a53209b2012-01-20 16:48:1667#include "content/browser/download/save_package.h"
Dave Tapuska54c76a032021-10-27 22:10:4268#include "content/browser/fenced_frame/fenced_frame.h"
paulmeyerc0b762b2016-04-13 11:55:1769#include "content/browser/find_request_manager.h"
Kenneth Russell954ed9ce2018-04-12 23:07:0170#include "content/browser/gpu/gpu_data_manager_impl.h"
Mark Schillaci1363e4a2021-10-04 19:10:0971#include "content/browser/host_zoom_map_impl.h"
dalecurtisbc6572e12014-09-12 19:22:3072#include "content/browser/media/audio_stream_monitor.h"
dalecurtis88c240072015-12-09 02:11:1873#include "content/browser/media/media_web_contents_observer.h"
Mike Wassermandabad612020-08-13 04:26:2774#include "content/browser/permissions/permission_controller_impl.h"
Illia Klimovb648dbd2021-07-08 08:08:4975#include "content/browser/permissions/permission_util.h"
Kevin McNee94ea52f52020-06-23 17:42:0676#include "content/browser/portal/portal.h"
Yoshiki Tanioka49b4cfb2022-10-20 09:25:3177#include "content/browser/preloading/prerender/prerender_final_status.h"
Sreeja Kamishettyc227f7a2022-07-08 22:33:1578#include "content/browser/preloading/prerender/prerender_host_registry.h"
Lingqi Chi8e192ba2022-11-22 04:34:2579#include "content/browser/preloading/prerender/prerender_metrics.h"
Hiroki Nakagawa3e2527042022-11-24 06:46:4280#include "content/browser/preloading/prerender/prerender_new_tab_handle.h"
Tal Pressman5dcd2382020-08-26 07:13:0581#include "content/browser/renderer_host/agent_scheduling_group_host.h"
danakje34636e2020-09-15 22:15:0082#include "content/browser/renderer_host/cross_process_frame_connector.h"
David Black9cca3592019-11-06 23:02:2283#include "content/browser/renderer_host/frame_token_message_queue.h"
danakje34636e2020-09-15 22:15:0084#include "content/browser/renderer_host/frame_tree_node.h"
85#include "content/browser/renderer_host/navigation_entry_impl.h"
86#include "content/browser/renderer_host/navigation_request.h"
Julie Jeongeun Kim9e204512021-06-24 07:28:5487#include "content/browser/renderer_host/page_impl.h"
danakje34636e2020-09-15 22:15:0088#include "content/browser/renderer_host/render_frame_host_impl.h"
89#include "content/browser/renderer_host/render_frame_proxy_host.h"
[email protected]21161032014-05-05 16:56:5090#include "content/browser/renderer_host/render_view_host_delegate_view.h"
[email protected]b3c41c0b2012-03-06 15:48:3291#include "content/browser/renderer_host/render_view_host_impl.h"
[email protected]bafe6cd2012-05-23 23:09:5092#include "content/browser/renderer_host/render_widget_host_impl.h"
kenrb2a565f82015-09-02 20:24:5993#include "content/browser/renderer_host/render_widget_host_input_event_router.h"
[email protected]cfd80b02014-05-01 17:46:4894#include "content/browser/renderer_host/render_widget_host_view_base.h"
Ken Buchanandaef006b2017-08-17 18:32:1595#include "content/browser/renderer_host/render_widget_host_view_child_frame.h"
ekaramadadd882292016-06-08 15:22:5696#include "content/browser/renderer_host/text_input_manager.h"
Joe Mason7ae0e2b2021-11-01 12:30:3697#include "content/browser/renderer_host/visible_time_request_trigger.h"
Mike Wasserman8edbf2c2023-01-05 19:53:0698#include "content/browser/screen_details/screen_change_monitor.h"
leon.han552e9de2017-02-09 14:37:3099#include "content/browser/screen_orientation/screen_orientation_provider.h"
Yao Xiao1ac702d2022-06-08 17:20:49100#include "content/browser/shared_storage/shared_storage_budget_charger.h"
[email protected]b6583592012-01-25 19:52:33101#include "content/browser/site_instance_impl.h"
Lei Zhang2764bca2021-07-15 02:00:07102#include "content/browser/wake_lock/wake_lock_context_host.h"
David Bokan1bdb3701f2021-04-30 22:02:35103#include "content/browser/web_contents/java_script_dialog_commit_deferring_condition.h"
Avi Drissman0d0908ded2022-04-28 05:39:39104#include "content/browser/web_contents/web_contents_view.h"
lfgc740d4b22016-04-15 16:45:33105#include "content/browser/web_contents/web_contents_view_child_frame.h"
[email protected]86a0a6e2013-01-28 06:33:03106#include "content/browser/webui/web_ui_controller_factory_registry.h"
[email protected]d2353452012-01-19 19:53:56107#include "content/browser/webui/web_ui_impl.h"
David Bienvenu1cdcf092020-11-04 18:47:56108#include "content/browser/xr/service/xr_runtime_manager_impl.h"
Rakina Zata Amni4029b6d2020-07-28 02:36:20109#include "content/common/content_switches_internal.h"
Alexander Surkov3b8d2252020-11-30 21:13:14110#include "content/public/browser/ax_inspect_factory.h"
[email protected]ccb797302011-12-15 16:55:11111#include "content/public/browser/browser_context.h"
Kevin McNee5f594382021-05-06 23:18:23112#include "content/public/browser/browser_plugin_guest_manager.h"
Gabriel Charette790754c2018-03-16 21:32:59113#include "content/public/browser/browser_thread.h"
Lei Zhang2764bca2021-07-15 02:00:07114#include "content/public/browser/color_chooser.h"
[email protected]87f3c082011-10-19 18:07:44115#include "content/public/browser/content_browser_client.h"
Lukasz Anforowicz8c4446dc2020-03-11 22:16:42116#include "content/public/browser/context_menu_params.h"
Ken Rockotce010f02019-12-12 23:32:32117#include "content/public/browser/device_service.h"
Fergal Daly1336ac642021-09-14 15:13:11118#include "content/public/browser/disallow_activation_reason.h"
[email protected]e582fdd2011-12-20 16:48:17119#include "content/public/browser/download_manager.h"
Kent Tamura512a27e2018-10-04 00:49:32120#include "content/public/browser/file_select_listener.h"
ekaramada110f642016-12-21 19:47:28121#include "content/public/browser/focused_node_details.h"
Sreeja Kamishetty15f9944a22022-03-10 10:16:08122#include "content/public/browser/frame_type.h"
Danyao Wanga78f3dd22020-03-05 05:31:27123#include "content/public/browser/global_routing_id.h"
[email protected]d9083482012-01-06 00:38:46124#include "content/public/browser/invalidate_type.h"
[email protected]71a88bb2013-02-01 22:05:15125#include "content/public/browser/javascript_dialog_manager.h"
skyf65d9bb2017-03-24 02:26:39126#include "content/public/browser/keyboard_event_processing_result.h"
[email protected]09d31d52012-03-11 22:30:27127#include "content/public/browser/load_notification_details.h"
[email protected]5b96836f2011-12-22 07:39:00128#include "content/public/browser/navigation_details.h"
[email protected]375fa1b2012-05-22 22:05:37129#include "content/public/browser/notification_details.h"
[email protected]be2510c02012-05-28 14:52:14130#include "content/public/browser/notification_service.h"
scottmg011d96e32016-06-29 19:15:08131#include "content/public/browser/notification_types.h"
[email protected]95640212014-07-26 18:14:30132#include "content/public/browser/render_widget_host_iterator.h"
Avi Drissman783c1232021-02-05 01:27:05133#include "content/public/browser/render_widget_host_observer.h"
Lukasz Anforowicze1b954d92017-10-30 21:28:06134#include "content/public/browser/restore_type.h"
Alex Moshchuk134690e2022-05-21 01:50:09135#include "content/public/browser/site_isolation_policy.h"
falken52a56e32016-12-08 05:02:40136#include "content/public/browser/ssl_status.h"
[email protected]4c3a23582012-08-18 08:54:34137#include "content/public/browser/storage_partition.h"
[email protected]674bc592011-12-20 23:00:42138#include "content/public/browser/web_contents_delegate.h"
Avi Drissman0d0908ded2022-04-28 05:39:39139#include "content/public/browser/web_contents_view_delegate.h"
Lei Zhangee3b63ad2018-06-06 23:25:31140#include "content/public/browser/web_ui_controller.h"
Hans Wennborg5ffd1392019-10-16 11:00:02141#include "content/public/common/content_client.h"
Francois Doray3f2afbd2018-04-06 19:18:18142#include "content/public/common/content_features.h"
[email protected]64d69de42012-02-06 00:19:54143#include "content/public/common/content_switches.h"
Leon Han963dc182018-11-06 05:41:48144#include "content/public/common/referrer_type_converters.h"
David Sanders7d4623d2022-04-21 07:00:18145#include "content/public/common/url_constants.h"
Rakina Zata Amni4029b6d2020-07-28 02:36:20146#include "media/base/media_switches.h"
Max Morinddebb972018-09-20 10:04:14147#include "media/base/user_input_monitor.h"
wjmaclean64951902016-04-29 20:59:12148#include "net/base/url_util.h"
David Van Clevef99881632020-07-16 19:41:13149#include "net/http/http_util.h"
rhalavati0fbaeef32017-06-01 15:56:30150#include "net/traffic_annotation/network_traffic_annotation.h"
Scott Violet02e38b92018-03-27 23:42:14151#include "ppapi/buildflags/buildflags.h"
Dale Curtisc496a7762021-02-24 01:15:44152#include "services/device/public/mojom/wake_lock.mojom.h"
arthursonzognib93a4472020-04-10 07:38:00153#include "services/network/public/cpp/web_sandbox_flags.h"
Lei Zhang2764bca2021-07-15 02:00:07154#include "services/network/public/mojom/network_context.mojom.h"
Anton Bikineevf62d1bf2021-05-15 17:56:07155#include "third_party/abseil-cpp/absl/types/optional.h"
Javier Fernández García-Boente0bda5d22022-03-17 23:25:27156#include "third_party/blink/public/common/custom_handlers/protocol_handler_utils.h"
Takashi Toyoshima58a780012021-04-08 03:19:37157#include "third_party/blink/public/common/features.h"
shivanigithubc688ced2020-11-04 19:46:15158#include "third_party/blink/public/common/loader/resource_type_util.h"
Blink Reformata30d4232018-04-07 15:31:06159#include "third_party/blink/public/common/mime_util/mime_util.h"
danakj938b37a62019-09-24 18:35:54160#include "third_party/blink/public/common/page/page_zoom.h"
Miyoung Shin5d77f72072020-10-09 15:14:20161#include "third_party/blink/public/common/page_state/page_state.h"
Andy Paicua6d6d852022-04-28 18:08:36162#include "third_party/blink/public/common/permissions/permission_utils.h"
Frédéric Wangb79fece2020-10-28 18:13:07163#include "third_party/blink/public/common/security/protocol_handler_security_level.h"
David Bokan7950a3f2020-10-27 21:53:31164#include "third_party/blink/public/common/switches.h"
Gyuyoung Kim1ac4ca782020-09-11 03:32:51165#include "third_party/blink/public/common/web_preferences/web_preferences.h"
Abhijeet Kandalkarde7348e2020-01-13 06:06:54166#include "third_party/blink/public/mojom/frame/frame.mojom.h"
Dave Tapuskaa4189512019-10-15 20:27:34167#include "third_party/blink/public/mojom/frame/fullscreen.mojom.h"
Mikel Astiz034ba14e2021-04-30 07:23:49168#include "third_party/blink/public/mojom/image_downloader/image_downloader.mojom.h"
Antonio Gomes0d42960a2019-06-05 12:35:51169#include "third_party/blink/public/mojom/mediastream/media_stream.mojom-shared.h"
Simon Hangl574cecf2022-05-05 06:19:46170#include "third_party/blink/public/mojom/mediastream/media_stream.mojom.h"
Brad Triebwasser767c27a2022-08-25 22:56:05171#include "third_party/blink/public/mojom/window_features/window_features.mojom.h"
halton.huoca2eabd2015-07-06 08:17:40172#include "third_party/skia/include/core/SkBitmap.h"
dmazzonid95ae842016-04-12 21:17:39173#include "ui/accessibility/ax_tree_combiner.h"
David Bokan7ec5ac922022-11-29 03:31:31174#include "ui/base/ime/mojom/virtual_keyboard_types.mojom.h"
Gyuyoung Kimc527ec32020-11-21 03:31:43175#include "ui/base/pointer/pointer_device.h"
Lei Zhang2764bca2021-07-15 02:00:07176#include "ui/base/window_open_disposition.h"
tom855c4bf32021-09-30 00:27:26177#include "ui/color/color_provider_manager.h"
Rakina Zata Amni4029b6d2020-07-28 02:36:20178#include "ui/display/screen.h"
Brad Triebwasser9d34d252022-07-26 20:44:42179#include "ui/display/types/display_constants.h"
Daniel Cheng90196c82018-04-25 21:49:14180#include "ui/events/base_event_utils.h"
Rakina Zata Amni4029b6d2020-07-28 02:36:20181#include "ui/gfx/animation/animation.h"
[email protected]3c733bde2010-12-21 19:56:31182
Xiaohan Wang24ec9342022-01-15 17:34:22183#if BUILDFLAG(IS_WIN)
Peter Kvitek965f3cd2022-01-06 22:33:41184#include "base/threading/thread_restrictions.h"
ekaramada110f642016-12-21 19:47:28185#include "content/browser/renderer_host/dip_util.h"
186#include "ui/gfx/geometry/dip_util.h"
187#endif
188
Xiaohan Wang24ec9342022-01-15 17:34:22189#if BUILDFLAG(IS_ANDROID)
mfomitchev2b8b066a2016-01-28 19:23:15190#include "content/browser/android/date_time_chooser_android.h"
sammcf5f1b0f2016-09-20 23:05:11191#include "content/browser/android/java_interfaces_impl.h"
Leon Hanccb985f2019-08-26 02:43:24192#include "content/browser/android/nfc_host.h"
[email protected]155c7f22013-12-09 17:07:18193#include "content/browser/web_contents/web_contents_android.h"
Ke He31d0bb02018-02-24 07:16:24194#include "services/device/public/mojom/nfc.mojom.h"
Lei Zhang2764bca2021-07-15 02:00:07195#include "services/service_manager/public/cpp/interface_provider.h"
Mugdha Lakhani0a0d7862020-07-29 09:58:45196#include "ui/android/view_android.h"
Lei Zhang2764bca2021-07-15 02:00:07197#include "ui/base/device_form_factor.h"
Xiaohan Wang24ec9342022-01-15 17:34:22198#endif // BUILDFLAG(IS_ANDROID)
[email protected]583418cc2013-01-17 14:01:10199
K. Moon9ae6ef2c2022-08-18 01:30:06200#if BUILDFLAG(ENABLE_PPAPI)
zqzhang181047e62016-07-01 13:37:17201#include "content/browser/media/session/pepper_playback_observer.h"
Lei Zhangebcc6302018-01-12 19:46:45202#endif
zqzhang181047e62016-07-01 13:37:17203
Lei Zhang2764bca2021-07-15 02:00:07204#if defined(USE_AURA)
205#include "ui/aura/window.h"
206#endif
207
Bartek Nowierskibc01b7112023-02-01 14:11:42208#if BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC) && BUILDFLAG(USE_STARSCAN)
209#include "base/allocator/partition_allocator/starscan/pcscan.h"
210#include "content/browser/starscan_load_observer.h"
211#endif
212
[email protected]8ff00d72012-10-23 19:12:21213namespace content {
Abigail Kleinaa898742019-11-01 02:31:25214
[email protected]420ae012009-04-24 05:16:32215namespace {
216
Dave Tapuskae1a08aaf2021-03-05 18:31:59217// The window which we dobounce load info updates in.
Peter Kastinge5a38ed2021-10-02 03:06:35218constexpr auto kUpdateLoadStatesInterval = base::Milliseconds(250);
Dave Tapuskae1a08aaf2021-03-05 18:31:59219
Sreeja Kamishetty2771b7d2021-04-07 06:34:18220using LifecycleState = RenderFrameHost::LifecycleState;
Takashi Toyoshimadaf538e2021-04-13 05:47:29221using LifecycleStateImpl = RenderFrameHostImpl::LifecycleStateImpl;
Sreeja Kamishettybe0ccd6b2020-06-09 11:52:50222
Elly Fong-Jones564de6262022-07-28 21:11:16223base::LazyInstance<base::RepeatingCallbackList<void(WebContents*)>>::
224 DestructorAtExit g_created_callbacks = LAZY_INSTANCE_INITIALIZER;
[email protected]cbb1ef592013-06-05 19:49:46225
Miyoung Shin7d8077a2022-03-25 07:13:14226bool HasMatchingWidgetHost(FrameTree* tree, RenderWidgetHostImpl* host) {
kenrb19221852016-04-29 17:21:40227 // This method scans the frame tree rather than checking whether
228 // host->delegate() == this, which allows it to return false when the host
229 // for a frame that is pending or pending deletion.
230 if (!host)
231 return false;
232
Miyoung Shin7d8077a2022-03-25 07:13:14233 for (FrameTreeNode* node : tree->NodesIncludingInnerTreeNodes()) {
234 // We might cross a WebContents boundary here, but it's fine as we are only
235 // comparing the RWHI with the given `host`, which is always guaranteed to
236 // belong to the same WebContents as `tree`.
237 if (node->current_frame_host()->GetRenderWidgetHost() == host) {
238 DCHECK_EQ(WebContentsImpl::FromFrameTreeNode(node),
239 WebContentsImpl::FromRenderWidgetHostImpl(host));
kenrb19221852016-04-29 17:21:40240 return true;
Miyoung Shin7d8077a2022-03-25 07:13:14241 }
kenrb19221852016-04-29 17:21:40242 }
243 return false;
244}
245
Ian Clelland5cbaaf82017-11-27 22:00:03246RenderFrameHostImpl* FindOpenerRFH(const WebContents::CreateParams& params) {
247 RenderFrameHostImpl* opener_rfh = nullptr;
alexmose201c7cd2015-06-10 17:14:21248 if (params.opener_render_frame_id != MSG_ROUTING_NONE) {
Ian Clelland5cbaaf82017-11-27 22:00:03249 opener_rfh = RenderFrameHostImpl::FromID(params.opener_render_process_id,
250 params.opener_render_frame_id);
alexmose201c7cd2015-06-10 17:14:21251 }
Ian Clelland5cbaaf82017-11-27 22:00:03252 return opener_rfh;
lukasza6f8ac622017-06-06 03:10:20253}
254
Dominick Ng37a15052018-07-17 23:56:35255// Returns |true| if |type| is the kind of user input that should trigger the
256// user interaction observers.
257bool IsUserInteractionInputType(blink::WebInputEvent::Type type) {
Mustaq Ahmed3a40f9f22022-10-11 19:16:17258 // TODO(mustaq): This list should be based off the HTML spec:
259 // https://html.spec.whatwg.org/multipage/interaction.html#tracking-user-activation,
260 // and kGestureScrollBegin is a clear outlier.
Dave Tapuska347d60a2020-04-21 23:55:47261 return type == blink::WebInputEvent::Type::kMouseDown ||
262 type == blink::WebInputEvent::Type::kGestureScrollBegin ||
263 type == blink::WebInputEvent::Type::kTouchStart ||
264 type == blink::WebInputEvent::Type::kRawKeyDown;
Dominick Ng37a15052018-07-17 23:56:35265}
266
Pavel Feldman3c1842b2017-08-02 05:00:16267// Ensures that OnDialogClosed is only called once.
268class CloseDialogCallbackWrapper
269 : public base::RefCountedThreadSafe<CloseDialogCallbackWrapper> {
270 public:
Avi Drissmane04d3992017-10-05 15:11:36271 using CloseCallback =
Jan Wilken Dörrieaace0cfef2021-03-11 22:01:58272 base::OnceCallback<void(bool, bool, const std::u16string&)>;
Avi Drissmane04d3992017-10-05 15:11:36273
274 explicit CloseDialogCallbackWrapper(CloseCallback callback)
275 : callback_(std::move(callback)) {}
Pavel Feldman3c1842b2017-08-02 05:00:16276
277 void Run(bool dialog_was_suppressed,
278 bool success,
Jan Wilken Dörrieaace0cfef2021-03-11 22:01:58279 const std::u16string& user_input) {
Avi Drissmane04d3992017-10-05 15:11:36280 if (callback_.is_null())
Pavel Feldman3c1842b2017-08-02 05:00:16281 return;
Avi Drissmane04d3992017-10-05 15:11:36282 std::move(callback_).Run(dialog_was_suppressed, success, user_input);
Pavel Feldman3c1842b2017-08-02 05:00:16283 }
284
285 private:
286 friend class base::RefCountedThreadSafe<CloseDialogCallbackWrapper>;
Fergal Daly55b6d722020-09-11 07:56:33287 ~CloseDialogCallbackWrapper() = default;
Avi Drissmane04d3992017-10-05 15:11:36288
289 CloseCallback callback_;
Pavel Feldman3c1842b2017-08-02 05:00:16290};
291
Arthur Sonzogni929d29f2018-09-17 14:19:44292bool FrameCompareDepth(RenderFrameHostImpl* a, RenderFrameHostImpl* b) {
Harkiran Bolaria2e3c0b772021-09-01 16:01:40293 return a->GetFrameDepth() < b->GetFrameDepth();
Arthur Sonzogni929d29f2018-09-17 14:19:44294}
295
Frédéric Wangb79fece2020-10-28 18:13:07296bool AreValidRegisterProtocolHandlerArguments(
297 const std::string& protocol,
298 const GURL& url,
299 const url::Origin& origin,
300 blink::ProtocolHandlerSecurityLevel security_level) {
Raymes Khoury58373df2019-08-06 06:29:20301 ChildProcessSecurityPolicyImpl* policy =
302 ChildProcessSecurityPolicyImpl::GetInstance();
303 if (policy->IsPseudoScheme(protocol))
304 return false;
305
Javier Fernández García-Boente0bda5d22022-03-17 23:25:27306 // Implementation of the protocol handler arguments normalization steps defined
307 // in the spec.
308 // https://html.spec.whatwg.org/multipage/system-state.html#normalize-protocol-handler-parameters
309 //
310 // Verify custom handler schemes for errors as described in steps 1 and 2
311 if (!blink::IsValidCustomHandlerScheme(protocol, security_level))
312 return false;
313
Javier Fernández García-Boentef8a578f2022-06-29 23:36:23314 blink::URLSyntaxErrorCode code =
315 blink::IsValidCustomHandlerURLSyntax(url, url.spec());
316 if (code != blink::URLSyntaxErrorCode::kNoError)
317 return false;
Javier Fernández García-Boente0bda5d22022-03-17 23:25:27318
319 // Verify custom handler URL security as described in steps 6 and 7
320 if (!blink::IsAllowedCustomHandlerURL(url, security_level))
321 return false;
Raymes Khoury58373df2019-08-06 06:29:20322 url::Origin url_origin = url::Origin::Create(url);
323 if (url_origin.opaque())
324 return false;
Frédéric Wangb79fece2020-10-28 18:13:07325 if (security_level < blink::ProtocolHandlerSecurityLevel::kUntrustedOrigins &&
Lukasz Anforowiczd00c1ed2022-01-13 05:25:10326 !origin.IsSameOriginWith(url))
Raymes Khoury58373df2019-08-06 06:29:20327 return false;
328
329 return true;
330}
331
yilkal796e89e2019-10-02 23:58:28332void RecordMaxFrameCountUMA(size_t max_frame_count) {
333 UMA_HISTOGRAM_COUNTS_10000("Navigation.MainFrame.MaxFrameCount",
334 max_frame_count);
335}
336
Avi Drissman33972942020-06-19 14:16:01337// Returns the set of all WebContentses that are reachable from |web_contents|
Rakina Zata Amni3a48ae42022-05-05 03:39:56338// by applying some combination of
339// WebContents::GetFirstWebContentsInLiveOriginalOpenerChain() and
Avi Drissman33972942020-06-19 14:16:01340// WebContents::GetOuterWebContents(). The |web_contents| parameter will be
341// included in the returned set.
342base::flat_set<WebContentsImpl*> GetAllOpeningWebContents(
343 WebContentsImpl* web_contents) {
344 base::flat_set<WebContentsImpl*> result;
345 base::flat_set<WebContentsImpl*> current;
346
347 current.insert(web_contents);
348
349 while (!current.empty()) {
350 WebContentsImpl* current_contents = *current.begin();
351 current.erase(current.begin());
352 auto insert_result = result.insert(current_contents);
353
354 if (insert_result.second) {
Rakina Zata Amni3a48ae42022-05-05 03:39:56355 if (WebContents* opener_contents =
356 current_contents
357 ->GetFirstWebContentsInLiveOriginalOpenerChain()) {
358 current.insert(static_cast<WebContentsImpl*>(opener_contents));
Avi Drissman33972942020-06-19 14:16:01359 }
360
361 WebContentsImpl* outer_contents = current_contents->GetOuterWebContents();
362 if (outer_contents)
363 current.insert(outer_contents);
364 }
365 }
366
367 return result;
368}
369
Xiaohan Wang24ec9342022-01-15 17:34:22370#if BUILDFLAG(IS_ANDROID)
Rakina Zata Amni4029b6d2020-07-28 02:36:20371float GetDeviceScaleAdjustment(int min_width) {
372 static const float kMinFSM = 1.05f;
373 static const int kWidthForMinFSM = 320;
374 static const float kMaxFSM = 1.3f;
375 static const int kWidthForMaxFSM = 800;
376
377 if (min_width <= kWidthForMinFSM)
378 return kMinFSM;
379 if (min_width >= kWidthForMaxFSM)
380 return kMaxFSM;
381
382 // The font scale multiplier varies linearly between kMinFSM and kMaxFSM.
383 float ratio = static_cast<float>(min_width - kWidthForMinFSM) /
384 (kWidthForMaxFSM - kWidthForMinFSM);
385 return ratio * (kMaxFSM - kMinFSM) + kMinFSM;
386}
387#endif
388
Avi Drissman33972942020-06-19 14:16:01389// Used to attach the "set of fullscreen contents" to a browser context. Storing
390// sets of WebContents on their browser context is done for two reasons. One,
391// related WebContentses must necessarily share a browser context, so this saves
392// lookup time by restricting to one specific browser context. Two, separating
393// by browser context is preemptive paranoia about keeping things separate.
394class FullscreenContentsHolder : public base::SupportsUserData::Data {
395 public:
396 FullscreenContentsHolder() = default;
397 ~FullscreenContentsHolder() override = default;
398
399 FullscreenContentsHolder(const FullscreenContentsHolder&) = delete;
400 FullscreenContentsHolder& operator=(const FullscreenContentsHolder&) = delete;
401
402 base::flat_set<WebContentsImpl*>* set() { return &set_; }
403
404 private:
405 base::flat_set<WebContentsImpl*> set_;
406};
407
408const char kFullscreenContentsSet[] = "fullscreen-contents";
409
410base::flat_set<WebContentsImpl*>* FullscreenContentsSet(
411 BrowserContext* browser_context) {
412 auto* set_holder = static_cast<FullscreenContentsHolder*>(
413 browser_context->GetUserData(kFullscreenContentsSet));
414 if (!set_holder) {
415 auto new_holder = std::make_unique<FullscreenContentsHolder>();
416 set_holder = new_holder.get();
417 browser_context->SetUserData(kFullscreenContentsSet, std::move(new_holder));
418 }
419
420 return set_holder->set();
421}
422
Brad Triebwasser5eb94a92022-10-13 22:34:28423// Returns true if `host` has the Window Management permission granted.
424bool IsWindowManagementGranted(RenderFrameHost* host) {
Illia Klimov4a2cb192022-03-15 06:31:35425 content::PermissionController* permission_controller =
426 host->GetBrowserContext()->GetPermissionController();
427 DCHECK(permission_controller);
Mike Wasserman909aa2c2021-06-02 02:36:59428
Illia Klimov4a2cb192022-03-15 06:31:35429 return permission_controller->GetPermissionStatusForCurrentDocument(
Brad Triebwasser334d00e2022-10-17 18:47:57430 blink::PermissionType::WINDOW_MANAGEMENT, host) ==
Illia Klimov4a2cb192022-03-15 06:31:35431 blink::mojom::PermissionStatus::GRANTED;
Mike Wasserman5b7d3bf2020-08-21 21:52:26432}
433
Mike Wassermanb6bc0152020-08-25 22:46:20434// Adjust the requested |bounds| for opening or placing a window and return the
435// id of the display where the window will be placed. The bounds may not extend
436// outside a single screen's work area, and the |host| requires permission to
437// specify bounds on a screen other than its current screen.
Mike Wassermandabad612020-08-13 04:26:27438// TODO(crbug.com/897300): These adjustments are inaccurate for window.open(),
439// which specifies the inner content size, and for window.moveTo, resizeTo, etc.
440// calls on newly created windows, which may pass empty sizes or positions to
441// indicate uninitialized placement information in the renderer. Constraints
442// enforced later should resolve most inaccuracies, but this early enforcement
443// is needed to ensure bounds indicate the appropriate display.
Mike Wassermanb6bc0152020-08-25 22:46:20444int64_t AdjustRequestedWindowBounds(gfx::Rect* bounds, RenderFrameHost* host) {
Mike Wassermandabad612020-08-13 04:26:27445 auto* screen = display::Screen::GetScreen();
Mike Wassermanb6bc0152020-08-25 22:46:20446 auto display = screen->GetDisplayMatching(*bounds);
Mike Wassermandabad612020-08-13 04:26:27447
448 // Check, but do not prompt, for permission to place windows on other screens.
449 // Sites generally need permission to get such bounds in the first place.
450 // Also clamp offscreen bounds to the window's current screen.
Brad Triebwasser5eb94a92022-10-13 22:34:28451 if (!bounds->Intersects(display.bounds()) || !IsWindowManagementGranted(host))
Mike Wassermandabad612020-08-13 04:26:27452 display = screen->GetDisplayNearestView(host->GetNativeView());
Mike Wassermandabad612020-08-13 04:26:27453
Mike Wassermanb6bc0152020-08-25 22:46:20454 bounds->AdjustToFit(display.work_area());
455 return display.id();
Mike Wassermandabad612020-08-13 04:26:27456}
457
tom083fe8992021-10-21 17:48:45458// A ColorProviderSource used when one has not been explicitly set. This source
459// only reflects theme information present in the web NativeTheme singleton.
460// Keep this an implementation detail of WebContentsImpl as we should not be
461// exposing a default ColorProviderSource generally.
462class DefaultColorProviderSource : public ui::ColorProviderSource,
463 public ui::NativeThemeObserver {
464 public:
465 DefaultColorProviderSource() {
466 native_theme_observation_.Observe(ui::NativeTheme::GetInstanceForWeb());
467 }
468 DefaultColorProviderSource(const DefaultColorProviderSource&) = delete;
469 DefaultColorProviderSource& operator=(const DefaultColorProviderSource&) =
470 delete;
471 ~DefaultColorProviderSource() override = default;
472
473 static DefaultColorProviderSource* GetInstance() {
474 static base::NoDestructor<DefaultColorProviderSource> instance;
475 return instance.get();
476 }
477
478 // ui::ColorProviderSource:
479 const ui::ColorProvider* GetColorProvider() const override {
480 return ui::ColorProviderManager::Get().GetColorProviderFor(
Allen Bauerec3e8e152022-03-17 17:47:38481 GetColorProviderKey());
tom083fe8992021-10-21 17:48:45482 }
483
484 // ui::NativeThemeObserver:
485 void OnNativeThemeUpdated(ui::NativeTheme* observed_theme) override {
486 DCHECK(native_theme_observation_.IsObservingSource(observed_theme));
487 NotifyColorProviderChanged();
488 }
489
Allen Bauerec3e8e152022-03-17 17:47:38490 protected:
491 // ui::ColorProviderSource:
492 ui::ColorProviderManager::Key GetColorProviderKey() const override {
493 return ui::NativeTheme::GetInstanceForWeb()->GetColorProviderKey(nullptr);
494 }
495
tom083fe8992021-10-21 17:48:45496 private:
497 base::ScopedObservation<ui::NativeTheme, ui::NativeThemeObserver>
498 native_theme_observation_{this};
499};
tom855c4bf32021-09-30 00:27:26500
Dave Tapuska21e9da02021-12-15 20:58:20501size_t GetFrameTreeSize(FrameTree* frame_tree) {
502 size_t tree_size = 0;
503 FrameTree::NodeRange node_range = frame_tree->NodesIncludingInnerTreeNodes();
504 FrameTree::NodeIterator node_iter = node_range.begin();
505 while (node_iter != node_range.end()) {
506 // Skip over collapsed frame trees.
507 if ((*node_iter)->is_collapsed()) {
508 node_iter.AdvanceSkippingChildren();
509 } else {
510 ++tree_size;
511 ++node_iter;
512 }
513 }
514 return tree_size;
515}
516
lukasza6f8ac622017-06-06 03:10:20517} // namespace
518
Bruno Pitrus2b0fb8b2022-10-17 15:56:10519// This is a small helper class created while a JavaScript dialog is showing
520// and destroyed when it's dismissed. Clients can register callbacks to receive
521// a notification when the dialog is dismissed.
522class JavaScriptDialogDismissNotifier {
523 public:
524 JavaScriptDialogDismissNotifier() = default;
525
526 JavaScriptDialogDismissNotifier(const JavaScriptDialogDismissNotifier&) =
527 delete;
528 JavaScriptDialogDismissNotifier& operator=(
529 const JavaScriptDialogDismissNotifier&) = delete;
530
531 ~JavaScriptDialogDismissNotifier() {
532 for (auto& callback : callbacks_) {
533 std::move(callback).Run();
534 }
535 }
536
537 void NotifyOnDismiss(base::OnceClosure callback) {
538 callbacks_.push_back(std::move(callback));
539 }
540
541 private:
542 std::vector<base::OnceClosure> callbacks_;
543};
544
Joel Hockey8c2011b22020-04-30 05:07:19545CreatedWindow::CreatedWindow() = default;
546CreatedWindow::CreatedWindow(std::unique_ptr<WebContentsImpl> contents,
547 GURL target_url)
548 : contents(std::move(contents)), target_url(std::move(target_url)) {}
549CreatedWindow::~CreatedWindow() = default;
550CreatedWindow::CreatedWindow(CreatedWindow&&) = default;
551CreatedWindow& CreatedWindow::operator=(CreatedWindow&&) = default;
552
Erik Chenbb8e738e2018-04-28 14:10:43553std::unique_ptr<WebContents> WebContents::Create(
554 const WebContents::CreateParams& params) {
Albert J. Wong65fe64d2019-09-20 02:48:14555 return WebContentsImpl::Create(params);
556}
557
558std::unique_ptr<WebContentsImpl> WebContentsImpl::Create(
559 const CreateParams& params) {
560 return CreateWithOpener(params, FindOpenerRFH(params));
[email protected]d1198fd2012-08-13 22:50:19561}
562
erikchenade1fef2018-05-02 22:07:57563std::unique_ptr<WebContents> WebContents::CreateWithSessionStorage(
[email protected]54944cde2012-12-09 09:24:59564 const WebContents::CreateParams& params,
[email protected]fdac6ade2013-07-20 01:06:30565 const SessionStorageNamespaceMap& session_storage_namespace_map) {
Alexander Timin5fdeff22020-09-08 09:20:37566 OPTIONAL_TRACE_EVENT0("content", "WebContents::CreateWithSessionStorage");
erikchenade1fef2018-05-02 22:07:57567 std::unique_ptr<WebContentsImpl> new_contents(
568 new WebContentsImpl(params.browser_context));
Ian Clelland5cbaaf82017-11-27 22:00:03569 RenderFrameHostImpl* opener_rfh = FindOpenerRFH(params);
570 FrameTreeNode* opener = nullptr;
571 if (opener_rfh)
572 opener = opener_rfh->frame_tree_node();
573 new_contents->SetOpenerForNewContents(opener, params.opener_suppressed);
[email protected]fdac6ade2013-07-20 01:06:30574
Fergal Daly55b6d722020-09-11 07:56:33575 for (const auto& it : session_storage_namespace_map) {
576 new_contents->GetController().SetSessionStorageNamespace(it.first,
577 it.second.get());
[email protected]fdac6ade2013-07-20 01:06:30578 }
579
Sean Toppingbbc4a2bd2019-01-30 02:16:14580 WebContentsImpl* outer_web_contents = nullptr;
Sam McNally69a33772018-06-27 16:54:12581 if (params.guest_delegate) {
582 // This makes |new_contents| act as a guest.
583 // For more info, see comment above class BrowserPluginGuest.
Albert J. Wongc55cc64d2018-10-12 02:50:04584 BrowserPluginGuest::CreateInWebContents(new_contents.get(),
585 params.guest_delegate);
Sean Toppingbbc4a2bd2019-01-30 02:16:14586 outer_web_contents = static_cast<WebContentsImpl*>(
587 params.guest_delegate->GetOwnerWebContents());
Sam McNally69a33772018-06-27 16:54:12588 }
589
Harkiran Bolaria5ce27632022-01-20 15:05:05590 new_contents->Init(params, blink::FramePolicy());
Sean Toppingbbc4a2bd2019-01-30 02:16:14591 if (outer_web_contents)
592 outer_web_contents->InnerWebContentsCreated(new_contents.get());
[email protected]d1198fd2012-08-13 22:50:19593 return new_contents;
[email protected]a81343d232011-12-27 07:39:20594}
[email protected]746d3052012-05-22 15:15:47595
Elly Fong-Jones564de6262022-07-28 21:11:16596base::CallbackListSubscription
597WebContentsImpl::FriendWrapper::AddCreatedCallbackForTesting(
nickf9acfbe2014-12-23 19:12:37598 const CreatedCallback& callback) {
Elly Fong-Jones564de6262022-07-28 21:11:16599 return g_created_callbacks.Get().Add(callback);
[email protected]cbb1ef592013-06-05 19:49:46600}
601
avidf38c952015-10-27 13:45:13602WebContents* WebContents::FromRenderViewHost(RenderViewHost* rvh) {
Alexander Timin5fdeff22020-09-08 09:20:37603 OPTIONAL_TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("content.verbose"),
604 "WebContents::FromRenderViewHost", "render_view_host",
Alexander Timinf785f342021-03-18 00:00:56605 rvh);
avidf38c952015-10-27 13:45:13606 if (!rvh)
607 return nullptr;
Kevin McNee2c3ceca2021-09-17 22:52:48608 return static_cast<WebContentsImpl*>(
609 static_cast<RenderViewHostImpl*>(rvh)->GetDelegate());
[email protected]746d3052012-05-22 15:15:47610}
611
[email protected]a86c0e962013-12-17 17:10:39612WebContents* WebContents::FromRenderFrameHost(RenderFrameHost* rfh) {
Alexander Timin5fdeff22020-09-08 09:20:37613 OPTIONAL_TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("content.verbose"),
614 "WebContents::FromRenderFrameHost", "render_frame_host",
Alexander Timinf785f342021-03-18 00:00:56615 rfh);
Fergal Daly5b64d472021-10-14 04:31:29616 return WebContentsImpl::FromRenderFrameHostImpl(
617 static_cast<RenderFrameHostImpl*>(rfh));
618}
619
620WebContentsImpl* WebContentsImpl::FromRenderFrameHostImpl(
621 RenderFrameHostImpl* rfh) {
622 OPTIONAL_TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("content.verbose"),
623 "WebContentsImpl::FromRenderFrameHostImpl",
624 "render_frame_host", rfh);
avidf38c952015-10-27 13:45:13625 if (!rfh)
626 return nullptr;
Fergal Daly5b64d472021-10-14 04:31:29627 return static_cast<WebContentsImpl*>(rfh->delegate());
[email protected]a86c0e962013-12-17 17:10:39628}
629
ananta4b7467a52016-09-23 01:42:38630WebContents* WebContents::FromFrameTreeNodeId(int frame_tree_node_id) {
Alexander Timin5fdeff22020-09-08 09:20:37631 OPTIONAL_TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("content.verbose"),
632 "WebContents::FromFrameTreeNodeId",
633 "frame_tree_node_id", frame_tree_node_id);
ananta4b7467a52016-09-23 01:42:38634 FrameTreeNode* frame_tree_node =
635 FrameTreeNode::GloballyFindByID(frame_tree_node_id);
anantab8cfa3b2016-10-14 22:43:19636 if (!frame_tree_node)
637 return nullptr;
jam8c4edd02017-05-06 18:50:33638 return WebContentsImpl::FromFrameTreeNode(frame_tree_node);
ananta4b7467a52016-09-23 01:42:38639}
640
Matt Falkenhagen888db592021-09-07 20:20:25641WebContentsImpl* WebContentsImpl::FromRenderWidgetHostImpl(
642 RenderWidgetHostImpl* rwh) {
643 if (!rwh)
644 return nullptr;
645 return static_cast<WebContentsImpl*>(rwh->delegate());
646}
647
leon.han552e9de2017-02-09 14:37:30648void WebContents::SetScreenOrientationDelegate(
649 ScreenOrientationDelegate* delegate) {
650 ScreenOrientationProvider::SetDelegate(delegate);
651}
652
Avi Drissman783c1232021-02-05 01:27:05653// WebContentsImpl::RenderWidgetHostDestructionObserver -----------------------
[email protected]7fff43e2013-05-21 20:21:10654
Avi Drissman783c1232021-02-05 01:27:05655class WebContentsImpl::RenderWidgetHostDestructionObserver
656 : public RenderWidgetHostObserver {
[email protected]7fff43e2013-05-21 20:21:10657 public:
Avi Drissman783c1232021-02-05 01:27:05658 RenderWidgetHostDestructionObserver(WebContentsImpl* owner,
659 RenderWidgetHost* watched_host)
660 : owner_(owner), watched_host_(watched_host) {
661 watched_host_->AddObserver(this);
662 }
663
Peter Boström828b9022021-09-21 02:28:43664 RenderWidgetHostDestructionObserver(
665 const RenderWidgetHostDestructionObserver&) = delete;
666 RenderWidgetHostDestructionObserver& operator=(
667 const RenderWidgetHostDestructionObserver&) = delete;
668
Avi Drissman783c1232021-02-05 01:27:05669 ~RenderWidgetHostDestructionObserver() override {
670 watched_host_->RemoveObserver(this);
671 }
672
673 // RenderWidgetHostObserver:
674 void RenderWidgetHostDestroyed(RenderWidgetHost* widget_host) override {
675 owner_->OnRenderWidgetHostDestroyed(widget_host);
676 }
677
678 private:
Keishi Hattori0e45c022021-11-27 09:25:52679 raw_ptr<WebContentsImpl> owner_;
680 raw_ptr<RenderWidgetHost> watched_host_;
Avi Drissman783c1232021-02-05 01:27:05681};
682
683// WebContentsImpl::WebContentsDestructionObserver ----------------------------
684
685class WebContentsImpl::WebContentsDestructionObserver
686 : public WebContentsObserver {
687 public:
688 WebContentsDestructionObserver(WebContentsImpl* owner,
689 WebContents* watched_contents)
Fergal Daly09d6c762020-05-29 02:05:18690 : WebContentsObserver(watched_contents), owner_(owner) {}
[email protected]7fff43e2013-05-21 20:21:10691
Peter Boström9b036532021-10-28 23:37:28692 WebContentsDestructionObserver(const WebContentsDestructionObserver&) =
693 delete;
694 WebContentsDestructionObserver& operator=(
695 const WebContentsDestructionObserver&) = delete;
696
[email protected]7fff43e2013-05-21 20:21:10697 // WebContentsObserver:
dchengc2282aa2014-10-21 12:07:58698 void WebContentsDestroyed() override {
[email protected]12a46832014-05-09 13:35:58699 owner_->OnWebContentsDestroyed(
700 static_cast<WebContentsImpl*>(web_contents()));
[email protected]7fff43e2013-05-21 20:21:10701 }
702
703 private:
Keishi Hattori0e45c022021-11-27 09:25:52704 raw_ptr<WebContentsImpl> owner_;
[email protected]7fff43e2013-05-21 20:21:10705};
706
Tom Burgin732656d32022-02-07 18:33:26707#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_MAC)
Bo Liu2bceebc2021-06-03 15:06:33708// TODO(sreejakshetty): Make |WebContentsImpl::ColorChooserHolder| per-frame
709// instead of WebContents-owned.
710// WebContentsImpl::ColorChooserHolder -----------------------------------------
711class WebContentsImpl::ColorChooserHolder : public blink::mojom::ColorChooser {
Joel Hockey85b379d2017-12-11 10:42:13712 public:
Bo Liu2bceebc2021-06-03 15:06:33713 ColorChooserHolder(
714 mojo::PendingReceiver<blink::mojom::ColorChooser> receiver,
715 mojo::PendingRemote<blink::mojom::ColorChooserClient> client)
Bo Liuab8f9972021-04-08 22:44:36716 : receiver_(this, std::move(receiver)), client_(std::move(client)) {}
717
Bo Liu2bceebc2021-06-03 15:06:33718 ~ColorChooserHolder() override {
Bo Liuab8f9972021-04-08 22:44:36719 if (chooser_)
720 chooser_->End();
Joel Hockey85b379d2017-12-11 10:42:13721 }
[email protected]8ed16472014-04-11 19:02:48722
Bo Liuab8f9972021-04-08 22:44:36723 void SetChooser(std::unique_ptr<content::ColorChooser> chooser) {
724 chooser_ = std::move(chooser);
725 if (chooser_) {
726 receiver_.set_disconnect_handler(
727 base::BindOnce([](content::ColorChooser* chooser) { chooser->End(); },
728 base::Unretained(chooser_.get())));
729 }
730 }
[email protected]8ed16472014-04-11 19:02:48731
Joel Hockey85b379d2017-12-11 10:42:13732 void SetSelectedColor(SkColor color) override {
Bo Liu2bceebc2021-06-03 15:06:33733 OPTIONAL_TRACE_EVENT0(
734 "content", "WebContentsImpl::ColorChooserHolder::SetSelectedColor");
Bo Liuab8f9972021-04-08 22:44:36735 if (chooser_)
736 chooser_->SetSelectedColor(color);
Joel Hockey85b379d2017-12-11 10:42:13737 }
738
739 void DidChooseColorInColorChooser(SkColor color) {
Alexander Timin5fdeff22020-09-08 09:20:37740 OPTIONAL_TRACE_EVENT0(
741 "content",
Bo Liu2bceebc2021-06-03 15:06:33742 "WebContentsImpl::ColorChooserHolder::DidChooseColorInColorChooser");
Joel Hockey85b379d2017-12-11 10:42:13743 client_->DidChooseColor(color);
744 }
745
746 private:
747 // Color chooser that was opened by this tab.
748 std::unique_ptr<content::ColorChooser> chooser_;
749
Julie Jeongeun Kim8e2879e2019-08-06 23:55:20750 // mojo receiver.
751 mojo::Receiver<blink::mojom::ColorChooser> receiver_;
Joel Hockey85b379d2017-12-11 10:42:13752
753 // mojo renderer client.
Julie Jeongeun Kim8e2879e2019-08-06 23:55:20754 mojo::Remote<blink::mojom::ColorChooserClient> client_;
Joel Hockey85b379d2017-12-11 10:42:13755};
Tom Burgin732656d32022-02-07 18:33:26756#endif // BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_MAC)
nicka0ac8382016-12-15 23:59:23757
lazyboy6ec48b2a2015-06-29 15:18:14758// WebContentsImpl::WebContentsTreeNode ----------------------------------------
lfg601233692017-03-06 22:45:44759WebContentsImpl::WebContentsTreeNode::WebContentsTreeNode(
760 WebContentsImpl* current_web_contents)
761 : current_web_contents_(current_web_contents),
762 outer_web_contents_(nullptr),
lazyboy6ec48b2a2015-06-29 15:18:14763 outer_contents_frame_tree_node_id_(
avallee0206f782016-07-28 18:55:33764 FrameTreeNode::kFrameTreeNodeInvalidId),
Carlos Caballero6a99dac2021-11-03 10:41:17765 focused_frame_tree_(
766 current_web_contents->GetPrimaryFrameTree().GetSafeRef()) {}
lazyboy6ec48b2a2015-06-29 15:18:14767
Fergal Daly55b6d722020-09-11 07:56:33768WebContentsImpl::WebContentsTreeNode::~WebContentsTreeNode() = default;
lazyboy6ec48b2a2015-06-29 15:18:14769
Lucas Furukawa Gadani99125822019-01-03 15:41:49770std::unique_ptr<WebContents>
771WebContentsImpl::WebContentsTreeNode::DisconnectFromOuterWebContents() {
Alexander Timin5fdeff22020-09-08 09:20:37772 OPTIONAL_TRACE_EVENT0("content",
773 "WebContentsTreeNode::DisconnectFromOuterWebContents");
Lucas Furukawa Gadani99125822019-01-03 15:41:49774 std::unique_ptr<WebContents> inner_contents =
775 outer_web_contents_->node_.DetachInnerWebContents(current_web_contents_);
776 OuterContentsFrameTreeNode()->RemoveObserver(this);
777 outer_contents_frame_tree_node_id_ = FrameTreeNode::kFrameTreeNodeInvalidId;
778 outer_web_contents_ = nullptr;
779 return inner_contents;
780}
781
paulmeyerfeafc2d2017-04-25 21:46:40782void WebContentsImpl::WebContentsTreeNode::AttachInnerWebContents(
Lucas Furukawa Gadani6e5b4f32019-03-02 04:18:50783 std::unique_ptr<WebContents> inner_web_contents,
784 RenderFrameHostImpl* render_frame_host) {
Alexander Timin5fdeff22020-09-08 09:20:37785 OPTIONAL_TRACE_EVENT0("content",
786 "WebContentsTreeNode::AttachInnerWebContents");
Lucas Furukawa Gadani6e5b4f32019-03-02 04:18:50787 WebContentsImpl* inner_web_contents_impl =
788 static_cast<WebContentsImpl*>(inner_web_contents.get());
789 WebContentsTreeNode& inner_web_contents_node = inner_web_contents_impl->node_;
790
Lucas Furukawa Gadani6e5b4f32019-03-02 04:18:50791 inner_web_contents_node.outer_web_contents_ = current_web_contents_;
792 inner_web_contents_node.outer_contents_frame_tree_node_id_ =
793 render_frame_host->frame_tree_node()->frame_tree_node_id();
794
Lucas Furukawa Gadani3d38ec152018-10-26 20:55:18795 inner_web_contents_.push_back(std::move(inner_web_contents));
Lucas Furukawa Gadani6e5b4f32019-03-02 04:18:50796
797 render_frame_host->frame_tree_node()->AddObserver(&inner_web_contents_node);
Jeremy Roman03ce13ce2020-05-29 22:16:57798 current_web_contents_->InnerWebContentsAttached(inner_web_contents_impl);
paulmeyerfeafc2d2017-04-25 21:46:40799}
800
Lucas Furukawa Gadani3d38ec152018-10-26 20:55:18801std::unique_ptr<WebContents>
802WebContentsImpl::WebContentsTreeNode::DetachInnerWebContents(
paulmeyerfeafc2d2017-04-25 21:46:40803 WebContentsImpl* inner_web_contents) {
Alexander Timin5fdeff22020-09-08 09:20:37804 OPTIONAL_TRACE_EVENT0(
805 "content",
806 "WebContentsImpl::WebContentsTreeNode::DetachInnerWebContents");
Lucas Furukawa Gadani3d38ec152018-10-26 20:55:18807 std::unique_ptr<WebContents> detached_contents;
808 for (std::unique_ptr<WebContents>& web_contents : inner_web_contents_) {
809 if (web_contents.get() == inner_web_contents) {
810 detached_contents = std::move(web_contents);
811 std::swap(web_contents, inner_web_contents_.back());
812 inner_web_contents_.pop_back();
Jeremy Roman03ce13ce2020-05-29 22:16:57813 current_web_contents_->InnerWebContentsDetached(inner_web_contents);
Lucas Furukawa Gadani3d38ec152018-10-26 20:55:18814 return detached_contents;
815 }
816 }
817
818 NOTREACHED();
819 return nullptr;
paulmeyerfeafc2d2017-04-25 21:46:40820}
821
lfga3e2bdc2017-03-07 20:44:01822FrameTreeNode*
823WebContentsImpl::WebContentsTreeNode::OuterContentsFrameTreeNode() const {
824 return FrameTreeNode::GloballyFindByID(outer_contents_frame_tree_node_id_);
lfg601233692017-03-06 22:45:44825}
826
lfga3e2bdc2017-03-07 20:44:01827void WebContentsImpl::WebContentsTreeNode::OnFrameTreeNodeDestroyed(
828 FrameTreeNode* node) {
Alexander Timin5fdeff22020-09-08 09:20:37829 OPTIONAL_TRACE_EVENT0("content",
830 "WebContentsTreeNode::OnFrameTreeNodeDestroyed");
lfga3e2bdc2017-03-07 20:44:01831 DCHECK_EQ(outer_contents_frame_tree_node_id_, node->frame_tree_node_id())
832 << "WebContentsTreeNode should only receive notifications for the "
833 "FrameTreeNode in its outer WebContents that hosts it.";
Lucas Furukawa Gadani3d38ec152018-10-26 20:55:18834
Paul Semela6d423722022-09-28 18:17:28835 node->RemoveObserver(this);
Lucas Furukawa Gadani3d38ec152018-10-26 20:55:18836 // Deletes |this| too.
837 outer_web_contents_->node_.DetachInnerWebContents(current_web_contents_);
lazyboy6ec48b2a2015-06-29 15:18:14838}
839
Dave Tapuskad8b0530f2021-10-19 15:12:31840void WebContentsImpl::WebContentsTreeNode::SetFocusedFrameTree(
841 FrameTree* frame_tree) {
842 OPTIONAL_TRACE_EVENT0("content", "WebContentsTreeNode::SetFocusedFrameTree");
avallee0206f782016-07-28 18:55:33843 DCHECK(!outer_web_contents())
844 << "Only the outermost WebContents tracks focus.";
Dave Tapuskad8b0530f2021-10-19 15:12:31845 focused_frame_tree_ = frame_tree->GetSafeRef();
avallee0206f782016-07-28 18:55:33846}
847
paulmeyerfeafc2d2017-04-25 21:46:40848WebContentsImpl*
849WebContentsImpl::WebContentsTreeNode::GetInnerWebContentsInFrame(
850 const FrameTreeNode* frame) {
851 auto ftn_id = frame->frame_tree_node_id();
Lucas Furukawa Gadani3d38ec152018-10-26 20:55:18852 for (auto& contents : inner_web_contents_) {
853 WebContentsImpl* impl = static_cast<WebContentsImpl*>(contents.get());
854 if (impl->node_.outer_contents_frame_tree_node_id() == ftn_id) {
855 return impl;
paulmeyerfeafc2d2017-04-25 21:46:40856 }
857 }
858 return nullptr;
859}
860
Lucas Furukawa Gadani3d38ec152018-10-26 20:55:18861std::vector<WebContentsImpl*>
862WebContentsImpl::WebContentsTreeNode::GetInnerWebContents() const {
863 std::vector<WebContentsImpl*> inner_web_contents;
864 for (auto& contents : inner_web_contents_)
865 inner_web_contents.push_back(static_cast<WebContentsImpl*>(contents.get()));
866
867 return inner_web_contents;
paulmeyerfeafc2d2017-04-25 21:46:40868}
869
Alexander Timin90c20c32020-08-12 15:28:32870// WebContentsObserverList -----------------------------------------------------
871WebContentsImpl::WebContentsObserverList::WebContentsObserverList() = default;
872WebContentsImpl::WebContentsObserverList::~WebContentsObserverList() = default;
873
874void WebContentsImpl::WebContentsObserverList::AddObserver(
875 WebContentsObserver* observer) {
876 observers_.AddObserver(observer);
877}
878
879void WebContentsImpl::WebContentsObserverList::RemoveObserver(
880 WebContentsObserver* observer) {
881 observers_.RemoveObserver(observer);
882}
883
[email protected]b172aee2012-04-10 17:05:26884// WebContentsImpl -------------------------------------------------------------
[email protected]420ae012009-04-24 05:16:32885
Lukasz Anforowicz7a0381c2022-12-07 20:23:08886namespace {
887
888// A helper for ensuring that WebContents are closed (or otherwise destroyed)
889// *before* their BrowserContext is destroyed.
890class WebContentsOfBrowserContext : public base::SupportsUserData::Data {
891 public:
892 static void Attach(WebContentsImpl& web_contents) {
893 WebContentsOfBrowserContext* self =
894 GetOrCreate(*web_contents.GetBrowserContext());
895 self->web_contents_set_.insert(&web_contents);
896 }
897
898 static void Detach(WebContentsImpl& web_contents) {
899 WebContentsOfBrowserContext* self =
900 GetOrCreate(*web_contents.GetBrowserContext());
901 self->web_contents_set_.erase(&web_contents);
902 }
903
904 ~WebContentsOfBrowserContext() override {
905 // The ~WebContentsOfBrowserContext destructor is called when the
906 // BrowserContext (and its UserData) gets destroyed. At this point
907 // in time all the WebContents of this BrowserContext should have been
908 // already closed (i.e. we expect the `web_contents_set_` set to be empty at
909 // this point - emptied by calls to the `Detach` method above).
910 if (web_contents_set_.empty())
911 return; // Everything is okay - nothing to warn about.
912
Nicolas Ouellet-Payeur177a6c42023-01-25 20:25:07913#if BUILDFLAG(IS_ANDROID)
914 JNIEnv* env = base::android::AttachCurrentThread();
915#endif // BUILDFLAG(IS_ANDROID)
916
Lukasz Anforowicz7a0381c2022-12-07 20:23:08917 // Any remaining WebContents contain dangling pointers to the
918 // BrowserContext being destroyed. Such WebContents (and their
919 // RenderFrameHosts, SiteInstances, etc.) risk causing
920 // use-after-free bugs. For more discussion about managing the
921 // lifetime of WebContents please see https://crbug.com/1376879#c44.
922 for (WebContents* web_contents_with_dangling_ptr_to_browser_context :
923 web_contents_set_) {
924 std::string creator = web_contents_with_dangling_ptr_to_browser_context
925 ->GetCreatorLocation()
926 .ToString();
927 SCOPED_CRASH_KEY_STRING256("shutdown", "web_contents/creator", creator);
Nicolas Ouellet-Payeur177a6c42023-01-25 20:25:07928
929#if BUILDFLAG(IS_ANDROID)
930 // On Android, also report the Java stack trace from WebContents's
931 // creation.
932 WebContentsAndroid::ReportDanglingPtrToBrowserContext(
933 env, web_contents_with_dangling_ptr_to_browser_context);
934#endif // BUILDFLAG(IS_ANDROID)
935
Lukasz Anforowicz7a0381c2022-12-07 20:23:08936 NOTREACHED()
937 << "BrowserContext is getting destroyed without first closing all "
Lukasz Anforowicz1746d872023-01-03 23:53:26938 << "WebContents (for more info see https://crbug.com/1376879#c44); "
939 << "creator = " << creator;
Lukasz Anforowicz7a0381c2022-12-07 20:23:08940 base::debug::DumpWithoutCrashing();
941 }
942 }
943
944 std::unique_ptr<Data> Clone() override {
945 // Indicate to `SupportsUserData` / `BrowserContext` that cloning is not
946 // supported.
947 return nullptr;
948 }
949
950 private:
951 WebContentsOfBrowserContext() = default;
952
953 // Gets WebContentsOfBrowserContext associated with the given
954 // `browser_context` (creating a new WebContentsOfBrowserContext if
955 // necessary - if one hasn't been created yet).
956 static WebContentsOfBrowserContext* GetOrCreate(
957 BrowserContext& browser_context) {
958 static const char* kUserDataKey = "WebContentsOfBrowserContext/UserDataKey";
959 WebContentsOfBrowserContext* result =
960 static_cast<WebContentsOfBrowserContext*>(
961 browser_context.GetUserData(kUserDataKey));
962 if (!result) {
963 result = new WebContentsOfBrowserContext();
964 browser_context.SetUserData(kUserDataKey, base::WrapUnique(result));
965 }
966 return result;
967 }
968
969 // Set of all `WebContents` within the tracked `BrowserContext`.
970 //
971 // Usage of `raw_ptr` below is okay (i.e. it shouldn't dangle), because
972 // when `WebContentsImpl`'s destructor runs, then it removes the set entry
973 // (by calling `Detach`).
974 std::set<raw_ptr<WebContents>> web_contents_set_;
975};
976
977} // namespace
978
alexmose201c7cd2015-06-10 17:14:21979WebContentsImpl::WebContentsImpl(BrowserContext* browser_context)
Ivan Kotenkov2c0d2bb32017-11-01 15:41:28980 : delegate_(nullptr),
Ivan Kotenkov2c0d2bb32017-11-01 15:41:28981 render_view_host_delegate_view_(nullptr),
Rakina Zata Amnic7ffea882021-08-16 10:04:28982 opened_by_another_window_(false),
Carlos Caballerob65b6e3a2021-11-15 10:09:00983 primary_frame_tree_(browser_context,
984 this,
985 this,
986 this,
987 this,
988 this,
989 this,
990 this,
991 this,
Danil Somsikov259aa65f2022-11-11 20:49:44992 FrameTree::Type::kPrimary),
Dave Tapuskad8b0530f2021-10-19 15:12:31993 node_(this),
Khushalc5eaf222021-06-30 20:15:48994 primary_main_frame_process_status_(
995 base::TERMINATION_STATUS_STILL_RUNNING),
996 primary_main_frame_process_error_code_(0),
Jan Wilken Dörrieaace0cfef2021-03-11 22:01:58997 load_state_(net::LOAD_STATE_IDLE, std::u16string()),
[email protected]094e5b22009-09-25 04:23:56998 upload_size_(0),
999 upload_position_(0),
dfalcantarae6b7b46752015-07-10 18:14:161000 is_resume_pending_(false),
[email protected]fdd61c62009-04-22 19:22:571001 notify_disconnection_(false),
Ivan Kotenkov2c0d2bb32017-11-01 15:41:281002 dialog_manager_(nullptr),
[email protected]7ab1e7d62009-10-14 23:32:011003 is_showing_before_unload_dialog_(false),
gab0dccfef2015-05-20 18:43:391004 last_active_time_(base::TimeTicks::Now()),
[email protected]ebf40a72010-07-22 01:46:381005 closed_by_user_gesture_(false),
danakj938b37a62019-09-24 18:35:541006 minimum_zoom_percent_(
1007 static_cast<int>(blink::kMinimumPageZoomFactor * 100)),
1008 maximum_zoom_percent_(
1009 static_cast<int>(blink::kMaximumPageZoomFactor * 100)),
w.shackleton49bcd392016-01-06 17:38:221010 zoom_scroll_remainder_(0),
[email protected]34ff1cfc2014-08-20 06:16:051011 force_disable_overscroll_content_(false),
[email protected]95640212014-07-26 18:14:301012 last_dialog_suppressed_(false),
waffles1c12bf402016-02-10 17:45:481013 accessibility_mode_(
Dominic Mazzoni21fb0282019-02-13 18:32:471014 GetContentClient()->browser()->GetAXModeForBrowserContext(
1015 browser_context)),
avayvodcc85bbd2015-08-28 19:11:151016 audio_stream_monitor_(this),
Thomas Guilbert882c4cec2019-02-14 05:55:451017 media_web_contents_observer_(
1018 std::make_unique<MediaWebContentsObserver>(this)),
qinmin72e8bd02016-10-21 19:35:371019 is_overlay_content_(false),
ekaramadf6750aa2017-06-06 18:29:421020 showing_context_menu_(false),
Johann344e1c72022-11-22 07:22:301021 prerender_host_registry_(std::make_unique<PrerenderHostRegistry>(*this)),
Eric Secklerab20ea22021-02-08 11:39:261022 audible_power_mode_voter_(
1023 power_scheduler::PowerModeArbiter::GetInstance()->NewVoter(
1024 "PowerModeVoter.Audible")) {
Alexander Timin5fdeff22020-09-08 09:20:371025 TRACE_EVENT0("content", "WebContentsImpl::WebContentsImpl");
Lukasz Anforowicz7a0381c2022-12-07 20:23:081026 WebContentsOfBrowserContext::Attach(*this);
K. Moon9ae6ef2c2022-08-18 01:30:061027#if BUILDFLAG(ENABLE_PPAPI)
Fergal Daly55b6d722020-09-11 07:56:331028 pepper_playback_observer_ = std::make_unique<PepperPlaybackObserver>(this);
zqzhang181047e62016-07-01 13:37:171029#endif
blundelle75a8f92017-03-27 08:11:171030
Xiaohan Wang24ec9342022-01-15 17:34:221031#if BUILDFLAG(IS_ANDROID)
Elly Fong-Jonescdd7ae82019-02-20 23:26:331032 display_cutout_host_impl_ = std::make_unique<DisplayCutoutHostImpl>(this);
Becca Hughes86334622018-07-09 21:29:381033#endif
John Delaney732721e92020-02-07 23:11:271034
tom083fe8992021-10-21 17:48:451035 // WebContents can exist independently of a ColorProviderSource and is still
1036 // expected to be able to render its content and be inserted into a
1037 // gfx::NativeView hierarchy. Whilst most WebContents clients should be
1038 // setting a ColorProviderSource we must accommodate for cases where this is
1039 // not currently being done. For these cases fallback to the default source.
1040 SetColorProviderSource(DefaultColorProviderSource::GetInstance());
1041
Alison Maher7f366dc62020-03-03 19:46:001042 ui::NativeTheme* native_theme = ui::NativeTheme::GetInstanceForWeb();
Sigurdur Asgeirsson103e2fb2020-11-10 00:50:161043 native_theme_observation_.Observe(native_theme);
Alison Maher7f366dc62020-03-03 19:46:001044 using_dark_colors_ = native_theme->ShouldUseDarkColors();
1045 preferred_color_scheme_ = native_theme->GetPreferredColorScheme();
Alison Maher3b11e942020-10-27 17:17:501046 preferred_contrast_ = native_theme->GetPreferredContrast();
Alison Maher7f366dc62020-03-03 19:46:001047
Mike Wassermanb213b9352020-04-16 00:32:341048 screen_change_monitor_ =
1049 std::make_unique<ScreenChangeMonitor>(base::BindRepeating(
1050 &WebContentsImpl::OnScreensChange, base::Unretained(this)));
1051
Yao Xiao1ac702d2022-06-08 17:20:491052 if (base::FeatureList::IsEnabled(blink::features::kSharedStorageAPI)) {
1053 SharedStorageBudgetCharger::CreateForWebContents(this);
1054 }
1055
Bartek Nowierskibc01b7112023-02-01 14:11:421056#if BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC) && BUILDFLAG(USE_STARSCAN)
Anton Bikineev99a00522021-08-25 08:57:591057 // TODO(1231679): Remove or move to another place after finishing the PCScan
1058 // experiment.
Kalvin Lee9833bf92022-06-30 02:12:051059 if (partition_alloc::internal::PCScan::IsInitialized()) {
Anton Bikineev99a00522021-08-25 08:57:591060 star_scan_load_observer_ = std::make_unique<StarScanLoadObserver>(this);
1061 }
Bartek Nowierskibc01b7112023-02-01 14:11:421062#endif // BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC) && BUILDFLAG(USE_STARSCAN)
[email protected]332af7732009-03-11 13:21:351063}
initial.commit09911bf2008-07-26 23:55:291064
[email protected]b172aee2012-04-10 17:05:261065WebContentsImpl::~WebContentsImpl() {
Alexander Timin5fdeff22020-09-08 09:20:371066 TRACE_EVENT0("content", "WebContentsImpl::~WebContentsImpl");
Lukasz Anforowicz7a0381c2022-12-07 20:23:081067 WebContentsOfBrowserContext::Detach(*this);
Alexander Timin5fdeff22020-09-08 09:20:371068
creisba91ba82017-05-12 22:56:191069 // Imperfect sanity check against double free, given some crashes unexpectedly
1070 // observed in the wild.
Takashi Toyoshimaea534ef22021-07-21 03:27:591071 CHECK(!IsBeingDestroyed());
creisba91ba82017-05-12 22:56:191072
1073 // We generally keep track of is_being_destroyed_ to let other features know
1074 // to avoid certain actions during destruction.
[email protected]420ae012009-04-24 05:16:321075 is_being_destroyed_ = true;
1076
creis97867aa2017-02-17 18:39:451077 // A WebContents should never be deleted while it is notifying observers,
creisba91ba82017-05-12 22:56:191078 // since this will lead to a use-after-free as it continues to notify later
creis97867aa2017-02-17 18:39:451079 // observers.
Alexander Timin90c20c32020-08-12 15:28:321080 CHECK(!observers_.is_notifying_observers());
danakje6aa9bb2021-03-02 20:28:071081 // This is used to watch for one-off observers (i.e. non-WebContentsObservers)
1082 // destroying WebContents, which they should not do.
1083 CHECK(!prevent_destruction_);
creis97867aa2017-02-17 18:39:451084
Takashi Toyoshima5e351c92021-04-27 06:29:021085 // We usually record `max_loaded_frame_count_` in `DidFinishNavigation()`
1086 // for pages the user navigated away from other than the last one. We record
1087 // it for the last page here.
Khushal97d31e82021-06-23 21:07:541088 if (first_primary_navigation_completed_)
Takashi Toyoshima5e351c92021-04-27 06:29:021089 RecordMaxFrameCountUMA(max_loaded_frame_count_);
1090
Avi Drissman33972942020-06-19 14:16:011091 FullscreenContentsSet(GetBrowserContext())->erase(this);
1092
kenrb2a565f82015-09-02 20:24:591093 rwh_input_event_router_.reset();
1094
avallee0206f782016-07-28 18:55:331095 WebContentsImpl* outermost = GetOutermostWebContents();
avallee9993fca2016-11-17 06:16:501096 if (this != outermost && ContainsOrIsFocusedWebContents()) {
avallee0206f782016-07-28 18:55:331097 // If the current WebContents is in focus, unset it.
avallee9993fca2016-11-17 06:16:501098 outermost->SetAsFocusedWebContentsIfNecessary();
avallee0206f782016-07-28 18:55:331099 }
1100
Alex Moshchuk83805532022-08-12 15:15:231101 if (mouse_lock_widget_) {
James Hollyerd5c9de462020-03-10 19:02:451102 mouse_lock_widget_->RejectMouseLockOrUnlockIfNecessary(
1103 blink::mojom::PointerLockResult::kElementDestroyed);
Nick Carterd73635b2018-03-13 18:31:411104
Alex Moshchuk83805532022-08-12 15:15:231105 // Normally, the call above clears mouse_lock_widget_ pointers on the
1106 // entire WebContents chain, since it results in calling LostMouseLock()
1107 // when the mouse lock is already active. However, this doesn't work for
1108 // <webview> guests if the mouse lock request is still pending while the
1109 // <webview> is destroyed. Hence, ensure that all mouse lock widget
1110 // pointers are cleared. See https://crbug.com/1346245.
1111 for (WebContentsImpl* current = this; current;
1112 current = current->GetOuterWebContents()) {
1113 current->mouse_lock_widget_ = nullptr;
1114 }
1115 }
1116
dcheng57e39e22016-01-21 00:25:381117 for (RenderWidgetHostImpl* widget : created_widgets_)
1118 widget->DetachDelegate();
[email protected]b24b68a2012-09-24 21:57:261119 created_widgets_.clear();
1120
[email protected]3ab9cb82011-06-03 18:02:071121 // Clear out any JavaScript state.
avi5d3b8692016-10-12 22:00:461122 if (dialog_manager_) {
avi6879fcf2017-01-21 05:27:531123 dialog_manager_->CancelDialogs(this, /*reset_state=*/true);
avi5d3b8692016-10-12 22:00:461124 }
[email protected]3ab9cb82011-06-03 18:02:071125
Tom Burgin732656d32022-02-07 18:33:261126#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_MAC)
Bo Liu2bceebc2021-06-03 15:06:331127 color_chooser_holder_.reset();
Tom Burgin732656d32022-02-07 18:33:261128#endif // BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_MAC)
Rakina Zata Amni16196122018-11-14 02:14:001129 find_request_manager_.reset();
[email protected]da8543762012-03-20 08:52:201130
Takashi Toyoshima58a780012021-04-08 03:19:371131 // Shutdown the primary FrameTree.
Carlos Caballerob65b6e3a2021-11-15 10:09:001132 primary_frame_tree_.Shutdown();
[email protected]f273ee52013-10-18 16:05:271133
Hiroki Nakagawa9bc09f22021-04-23 09:48:551134 // Shutdown the non-primary FrameTrees.
1135 //
Takashi Toyoshima58a780012021-04-08 03:19:371136 // Do this here rather than relying on the owner of the FrameTree to shutdown
1137 // on WebContentsDestroyed(), so that all the FrameTrees are shutdown at the
1138 // same time for consistency. Also, destroying a FrameTree results in other
1139 // observer functions like RenderFrameDeleted() being called, which are not
1140 // expected to be called after WebContentsDestroyed().
Hiroki Nakagawa9bc09f22021-04-23 09:48:551141 //
1142 // Currently the only instances of the non-primary FrameTrees are for
1143 // prerendering. Shutdown them by destructing PrerenderHostRegistry.
Hiroki Nakagawa5b82ee442021-09-20 17:17:201144 prerender_host_registry_.reset();
Takashi Toyoshima58a780012021-04-08 03:19:371145
K. Moon9ae6ef2c2022-08-18 01:30:061146#if BUILDFLAG(ENABLE_PPAPI)
zqzhang181047e62016-07-01 13:37:171147 // Call this before WebContentsDestroyed() is broadcasted since
1148 // AudioFocusManager will be destroyed after that.
1149 pepper_playback_observer_.reset();
1150#endif // defined(ENABLED_PLUGINS)
1151
Chris Hamiltondf0d72cd2018-05-29 16:23:531152 // If audio is playing then notify external observers of the audio stream
1153 // disappearing.
1154 if (is_currently_audible_) {
1155 is_currently_audible_ = false;
Andrew Grievee19cd93e2021-01-22 05:43:061156 observers_.NotifyObservers(&WebContentsObserver::OnAudioStateChanged,
1157 false);
Chris Hamiltondf0d72cd2018-05-29 16:23:531158 if (GetOuterWebContents())
1159 GetOuterWebContents()->OnAudioStateChanged();
1160 }
1161
Xiaohan Wang24ec9342022-01-15 17:34:221162#if BUILDFLAG(IS_ANDROID)
Kevin McNee576bb5d82019-05-29 16:47:511163 // For simplicity, destroy the Java WebContents before we notify of the
1164 // destruction of the WebContents.
1165 ClearWebContentsAndroid();
1166#endif
1167
Dave Tapuska765a2f62021-07-07 20:52:231168 // |save_package_| is refcounted so make sure we clear the page before
1169 // we toss out our reference.
1170 if (save_package_)
1171 save_package_->ClearPage();
1172
Andrew Grievee19cd93e2021-01-22 05:43:061173 observers_.NotifyObservers(&WebContentsObserver::WebContentsDestroyed);
Andrew Grievee19cd93e2021-01-22 05:43:061174 observers_.NotifyObservers(&WebContentsObserver::ResetWebContents);
Ivan Kotenkov2c0d2bb32017-11-01 15:41:281175 SetDelegate(nullptr);
[email protected]b5a1d11c2011-02-17 03:09:421176}
1177
erikchen50735fd2018-05-05 15:08:331178std::unique_ptr<WebContentsImpl> WebContentsImpl::CreateWithOpener(
[email protected]54944cde2012-12-09 09:24:591179 const WebContents::CreateParams& params,
Ian Clelland5cbaaf82017-11-27 22:00:031180 RenderFrameHostImpl* opener_rfh) {
Alexander Timin5fdeff22020-09-08 09:20:371181 OPTIONAL_TRACE_EVENT1("browser", "WebContentsImpl::CreateWithOpener",
Alexander Timinf785f342021-03-18 00:00:561182 "opener", opener_rfh);
Ian Clelland5cbaaf82017-11-27 22:00:031183 FrameTreeNode* opener = nullptr;
1184 if (opener_rfh)
1185 opener = opener_rfh->frame_tree_node();
erikchen50735fd2018-05-05 15:08:331186 std::unique_ptr<WebContentsImpl> new_contents(
1187 new WebContentsImpl(params.browser_context));
lukasza6f8ac622017-06-06 03:10:201188 new_contents->SetOpenerForNewContents(opener, params.opener_suppressed);
alexmose201c7cd2015-06-10 17:14:211189
alexmosaedfc6f2016-01-21 23:57:381190 // If the opener is sandboxed, a new popup must inherit the opener's sandbox
1191 // flags, and these flags take effect immediately. An exception is if the
1192 // opener's sandbox flags lack the PropagatesToAuxiliaryBrowsingContexts
1193 // bit (which is controlled by the "allow-popups-to-escape-sandbox" token).
Arthur Sonzogni73a39802022-01-31 14:50:221194 // See https://html.spec.whatwg.org/C/#attr-iframe-sandbox.
Carlos Caballero6a99dac2021-11-03 10:41:171195 FrameTreeNode* new_root = new_contents->GetPrimaryFrameTree().root();
alexmosaedfc6f2016-01-21 23:57:381196 if (opener) {
arthursonzognib93a4472020-04-10 07:38:001197 network::mojom::WebSandboxFlags opener_flags =
Antonio Gomes7096ac02020-02-14 14:29:541198 opener_rfh->active_sandbox_flags();
Ian Clelland942f73a2020-12-07 18:20:261199 if (opener_rfh->IsSandboxed(network::mojom::WebSandboxFlags::
1200 kPropagatesToAuxiliaryBrowsingContexts)) {
Charlie Hue1b77ac2019-12-13 21:30:171201 new_root->SetPendingFramePolicy({opener_flags,
1202 {} /* container_policy */,
1203 {} /* required_document_policy */});
alexmosaedfc6f2016-01-21 23:57:381204 }
arthursonzogni034bb9c2020-10-01 08:29:561205 new_root->SetInitialPopupURL(params.initial_popup_url);
1206 new_root->SetPopupCreatorOrigin(opener_rfh->GetLastCommittedOrigin());
alexmosaedfc6f2016-01-21 23:57:381207 }
1208
mark a. foltzef394fce2017-10-21 09:11:021209 // Apply starting sandbox flags.
Luna Luc3fdacdf2017-11-08 04:48:531210 blink::FramePolicy frame_policy(new_root->pending_frame_policy());
mark a. foltzef394fce2017-10-21 09:11:021211 frame_policy.sandbox_flags |= params.starting_sandbox_flags;
1212 new_root->SetPendingFramePolicy(frame_policy);
mark a. foltzef394fce2017-10-21 09:11:021213
alexmose201c7cd2015-06-10 17:14:211214 // This may be true even when opener is null, such as when opening blocked
1215 // popups.
Rakina Zata Amnic7ffea882021-08-16 10:04:281216 if (params.opened_by_another_window)
1217 new_contents->opened_by_another_window_ = true;
alexmos090fae8e2015-05-28 17:09:281218
Sean Toppingbbc4a2bd2019-01-30 02:16:141219 WebContentsImpl* outer_web_contents = nullptr;
[email protected]4858e432014-06-23 18:14:171220 if (params.guest_delegate) {
[email protected]83100cd2014-05-10 11:50:061221 // This makes |new_contents| act as a guest.
1222 // For more info, see comment above class BrowserPluginGuest.
Albert J. Wongc55cc64d2018-10-12 02:50:041223 BrowserPluginGuest::CreateInWebContents(new_contents.get(),
1224 params.guest_delegate);
Sean Toppingbbc4a2bd2019-01-30 02:16:141225 outer_web_contents = static_cast<WebContentsImpl*>(
1226 params.guest_delegate->GetOwnerWebContents());
[email protected]83100cd2014-05-10 11:50:061227 }
mark a. foltzef394fce2017-10-21 09:11:021228
Harkiran Bolaria5ce27632022-01-20 15:05:051229 new_contents->Init(params, frame_policy);
Sean Toppingbbc4a2bd2019-01-30 02:16:141230 if (outer_web_contents)
1231 outer_web_contents->InnerWebContentsCreated(new_contents.get());
[email protected]d1198fd2012-08-13 22:50:191232 return new_contents;
1233}
1234
[email protected]95640212014-07-26 18:14:301235// static
1236std::vector<WebContentsImpl*> WebContentsImpl::GetAllWebContents() {
Alexander Timin5fdeff22020-09-08 09:20:371237 OPTIONAL_TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("content.verbose"),
1238 "WebContentsImpl::GetAllWebContents");
[email protected]95640212014-07-26 18:14:301239 std::vector<WebContentsImpl*> result;
dcheng59716272016-04-09 05:19:081240 std::unique_ptr<RenderWidgetHostIterator> widgets(
[email protected]95640212014-07-26 18:14:301241 RenderWidgetHostImpl::GetRenderWidgetHosts());
[email protected]95640212014-07-26 18:14:301242 while (RenderWidgetHost* rwh = widgets->GetNextHost()) {
[email protected]95640212014-07-26 18:14:301243 RenderViewHost* rvh = RenderViewHost::From(rwh);
1244 if (!rvh)
1245 continue;
1246 WebContents* web_contents = WebContents::FromRenderViewHost(rvh);
1247 if (!web_contents)
1248 continue;
Dave Tapuska327c06c92022-06-13 20:31:511249 if (web_contents->GetPrimaryMainFrame()->GetRenderViewHost() != rvh)
avidf38c952015-10-27 13:45:131250 continue;
1251 // Because a WebContents can only have one current RVH at a time, there will
1252 // be no duplicate WebContents here.
1253 result.push_back(static_cast<WebContentsImpl*>(web_contents));
[email protected]95640212014-07-26 18:14:301254 }
1255 return result;
1256}
1257
clamya16aa8172015-05-26 13:07:251258// static
1259WebContentsImpl* WebContentsImpl::FromFrameTreeNode(
paulmeyerfeafc2d2017-04-25 21:46:401260 const FrameTreeNode* frame_tree_node) {
Alexander Timin5fdeff22020-09-08 09:20:371261 OPTIONAL_TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("content.verbose"),
1262 "WebContentsImpl::FromFrameTreeNode", "frame_tree_node",
Alexander Timinfb70a2d2021-02-08 03:19:071263 static_cast<const void*>(frame_tree_node));
clamya16aa8172015-05-26 13:07:251264 return static_cast<WebContentsImpl*>(
1265 WebContents::FromRenderFrameHost(frame_tree_node->current_frame_host()));
1266}
1267
clamy0d32d6d2015-11-24 11:16:261268// static
Patrick Monette275a6f92b2020-01-09 21:05:041269WebContents* WebContentsImpl::FromRenderFrameHostID(
Alexander Timin8690530c2021-06-19 00:34:321270 GlobalRenderFrameHostId render_frame_host_id) {
Alexander Timin5fdeff22020-09-08 09:20:371271 OPTIONAL_TRACE_EVENT2(TRACE_DISABLED_BY_DEFAULT("content.verbose"),
1272 "WebContentsImpl::FromRenderFrameHostID", "process_id",
1273 render_frame_host_id.child_id, "frame_id",
1274 render_frame_host_id.frame_routing_id);
Patrick Monette275a6f92b2020-01-09 21:05:041275 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI) ||
1276 !BrowserThread::IsThreadInitialized(BrowserThread::UI));
Patrick Monette7364e6972020-01-09 22:56:021277 RenderFrameHost* render_frame_host =
1278 RenderFrameHost::FromID(render_frame_host_id);
1279 if (!render_frame_host)
1280 return nullptr;
1281
1282 return WebContents::FromRenderFrameHost(render_frame_host);
Patrick Monette275a6f92b2020-01-09 21:05:041283}
1284
1285// static
clamy0d32d6d2015-11-24 11:16:261286WebContents* WebContentsImpl::FromRenderFrameHostID(int render_process_host_id,
1287 int render_frame_host_id) {
Patrick Monette7364e6972020-01-09 22:56:021288 return FromRenderFrameHostID(
Alexander Timin8690530c2021-06-19 00:34:321289 GlobalRenderFrameHostId(render_process_host_id, render_frame_host_id));
clamy0d32d6d2015-11-24 11:16:261290}
1291
paulmeyerfeafc2d2017-04-25 21:46:401292// static
1293WebContentsImpl* WebContentsImpl::FromOuterFrameTreeNode(
1294 const FrameTreeNode* frame_tree_node) {
Alexander Timin5fdeff22020-09-08 09:20:371295 OPTIONAL_TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("content.verbose"),
1296 "WebContentsImpl::FromOuterFrameTreeNode",
Alexander Timinfb70a2d2021-02-08 03:19:071297 "frame_tree_node",
1298 static_cast<const void*>(frame_tree_node));
paulmeyerfeafc2d2017-04-25 21:46:401299 return WebContentsImpl::FromFrameTreeNode(frame_tree_node)
1300 ->node_.GetInnerWebContentsInFrame(frame_tree_node);
1301}
1302
nicka0ac8382016-12-15 23:59:231303bool WebContentsImpl::OnMessageReceived(RenderFrameHostImpl* render_frame_host,
1304 const IPC::Message& message) {
Alexander Timin5fdeff22020-09-08 09:20:371305 OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::OnMessageReceived",
Alexander Timinf785f342021-03-18 00:00:561306 "render_frame_host", render_frame_host);
Alexander Timin5fdeff22020-09-08 09:20:371307
Alexander Timin90c20c32020-08-12 15:28:321308 for (auto& observer : observers_.observer_list()) {
nicka0ac8382016-12-15 23:59:231309 if (observer.OnMessageReceived(message, render_frame_host))
1310 return true;
1311 }
1312
Dave Tapuskaef8be1612021-01-11 17:53:141313 return false;
[email protected]724159a2010-12-30 01:11:181314}
1315
Kuznetsov Alexey1a516bd2021-08-04 23:49:051316std::string WebContentsImpl::GetTitleForMediaControls() {
1317 OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::GetTitleForMediaControls");
1318
1319 if (!delegate_)
1320 return std::string();
1321 return delegate_->GetTitleForMediaControls(this);
1322}
1323
Brad Triebwasser9d34d252022-07-26 20:44:421324bool WebContentsImpl::IsFullscreenOnDisplay(int64_t display_id) const {
1325 if (!delegate_)
1326 return false;
1327 DCHECK_NE(display_id, display::kInvalidDisplayId);
1328 int64_t fullscreen_display = display::kInvalidDisplayId;
1329 if (!delegate_->IsFullscreenForTabOrPending(this, &fullscreen_display))
1330 return false;
1331 return fullscreen_display == display_id;
1332}
1333
Carlos Caballero40b0efd2021-01-26 11:55:001334// Returns the NavigationController for the primary FrameTree, i.e. the one
1335// whose URL is shown in the omnibox. With MPArch we can have multiple
1336// FrameTrees in one WebContents and each has its own NavigationController.
1337// TODO(https://crbug.com/1170273): Make sure callers are aware of this.
[email protected]d1198fd2012-08-13 22:50:191338NavigationControllerImpl& WebContentsImpl::GetController() {
Carlos Caballerob65b6e3a2021-11-15 10:09:001339 return primary_frame_tree_.controller();
[email protected]f5fa20e2011-12-21 22:35:561340}
1341
Lucas Furukawa Gadanie1c5dfda2018-11-29 17:57:411342BrowserContext* WebContentsImpl::GetBrowserContext() {
Carlos Caballero40b0efd2021-01-26 11:55:001343 return GetController().GetBrowserContext();
[email protected]627e0512011-12-21 22:55:301344}
1345
Claudio DeSouza2be02d42021-08-12 23:23:401346base::WeakPtr<WebContents> WebContentsImpl::GetWeakPtr() {
1347 return weak_factory_.GetWeakPtr();
1348}
1349
Lucas Furukawa Gadanie1c5dfda2018-11-29 17:57:411350const GURL& WebContentsImpl::GetURL() {
Peter Boström101d7672018-12-15 00:43:591351 return GetVisibleURL();
[email protected]be1f56ab2011-12-22 06:55:311352}
1353
Lucas Furukawa Gadanie1c5dfda2018-11-29 17:57:411354const GURL& WebContentsImpl::GetVisibleURL() {
[email protected]c854a7e2013-05-21 16:42:241355 // We may not have a navigation entry yet.
Carlos Caballero40b0efd2021-01-26 11:55:001356 NavigationEntry* entry = GetController().GetVisibleEntry();
[email protected]c854a7e2013-05-21 16:42:241357 return entry ? entry->GetVirtualURL() : GURL::EmptyGURL();
1358}
1359
Lucas Furukawa Gadanie1c5dfda2018-11-29 17:57:411360const GURL& WebContentsImpl::GetLastCommittedURL() {
[email protected]c854a7e2013-05-21 16:42:241361 // We may not have a navigation entry yet.
Carlos Caballero40b0efd2021-01-26 11:55:001362 NavigationEntry* entry = GetController().GetLastCommittedEntry();
[email protected]c854a7e2013-05-21 16:42:241363 return entry ? entry->GetVirtualURL() : GURL::EmptyGURL();
1364}
1365
[email protected]8ff00d72012-10-23 19:12:211366WebContentsDelegate* WebContentsImpl::GetDelegate() {
[email protected]be1f56ab2011-12-22 06:55:311367 return delegate_;
1368}
1369
[email protected]8ff00d72012-10-23 19:12:211370void WebContentsImpl::SetDelegate(WebContentsDelegate* delegate) {
Alexander Timin5fdeff22020-09-08 09:20:371371 OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::SetDelegate", "delegate",
Alexander Timinfb70a2d2021-02-08 03:19:071372 static_cast<void*>(delegate));
[email protected]be1f56ab2011-12-22 06:55:311373 // TODO(cbentzel): remove this debugging code?
1374 if (delegate == delegate_)
1375 return;
1376 if (delegate_)
1377 delegate_->Detach(this);
1378 delegate_ = delegate;
[email protected]a6b73c62013-02-11 23:05:081379 if (delegate_) {
[email protected]be1f56ab2011-12-22 06:55:311380 delegate_->Attach(this);
Wolfgang Beyera21c8a0d2021-05-26 07:22:051381 // RenderFrameDevToolsAgentHost should not be told about the WebContents
1382 // until there is a `delegate_`.
1383 RenderFrameDevToolsAgentHost::AttachToWebContents(this);
[email protected]a6b73c62013-02-11 23:05:081384 }
danakj5f22bcc2021-02-12 18:09:011385
1386 // Re-read values from the new delegate and apply them.
1387 if (view_)
1388 view_->SetOverscrollControllerEnabled(CanOverscrollContent());
[email protected]be1f56ab2011-12-22 06:55:311389}
1390
Dave Tapuska1d5e5772022-06-02 17:26:011391RenderFrameHostImpl* WebContentsImpl::GetPrimaryMainFrame() {
Carlos Caballerob65b6e3a2021-11-15 10:09:001392 return primary_frame_tree_.root()->current_frame_host();
[email protected]60eca4eb2013-12-06 00:02:161393}
1394
Sreeja Kamishetty3dde6312021-06-22 14:05:291395PageImpl& WebContentsImpl::GetPrimaryPage() {
1396 // We should not be accessing Page during the destruction of this WebContents,
1397 // as the Page has already been cleared.
1398 //
1399 // Please note that IsBeingDestroyed() should be checked to ensure that we
1400 // don't access Page related data that is going to be destroyed.
Carlos Caballerob65b6e3a2021-11-15 10:09:001401 CHECK(primary_frame_tree_.root()->current_frame_host());
1402 return primary_frame_tree_.root()->current_frame_host()->GetPage();
Sreeja Kamishetty3dde6312021-06-22 14:05:291403}
1404
nick53d5cbf2015-04-23 22:50:141405RenderFrameHostImpl* WebContentsImpl::GetFocusedFrame() {
Kevin McNee61927b32022-07-05 16:35:381406 // If this method is called on an inner WebContents, don't return frames from
1407 // outside of the inner WebContents's subtree.
1408 if (GetOuterWebContents() && !ContainsOrIsFocusedWebContents()) {
nick53d5cbf2015-04-23 22:50:141409 return nullptr;
Kevin McNee61927b32022-07-05 16:35:381410 }
1411
1412 FrameTreeNode* focused_node = GetFocusedFrameTree()->GetFocusedFrame();
1413 if (!focused_node) {
1414 return nullptr;
1415 }
1416
1417 // If an inner frame tree has focus, we should return a RenderFrameHost from
1418 // the inner frame tree and not the placeholder RenderFrameHost.
1419 DCHECK_EQ(
1420 focused_node->current_frame_host()->inner_tree_main_frame_tree_node_id(),
1421 FrameTreeNode::kFrameTreeNodeInvalidId);
1422
nick53d5cbf2015-04-23 22:50:141423 return focused_node->current_frame_host();
[email protected]9c9343b2014-03-08 02:56:071424}
1425
Kevin McNee07c67ec92021-08-11 16:18:331426bool WebContentsImpl::IsPrerenderedFrame(int frame_tree_node_id) {
Kevin McNee07c67ec92021-08-11 16:18:331427 if (frame_tree_node_id == RenderFrameHost::kNoFrameTreeNodeId)
1428 return false;
1429
1430 FrameTreeNode* frame_tree_node =
1431 FrameTreeNode::GloballyFindByID(frame_tree_node_id);
1432 if (!frame_tree_node)
1433 return false;
1434
Kevin McNeeab98c4a52022-01-28 16:53:061435 // In the case of inner frame trees in a prerender, the inner frame tree's
1436 // type, would not be FrameTree::Type::kPrerender. So if this is not the
1437 // outermost frame, we use the lifecycle state of the document that owns this.
1438 // TODO(1196715, 1232528): This relies on the LifecycleState being correct
1439 // in the case of inner frame trees.
1440 if (frame_tree_node->GetParentOrOuterDocumentOrEmbedder()) {
1441 return frame_tree_node->GetParentOrOuterDocumentOrEmbedder()
1442 ->lifecycle_state() ==
1443 RenderFrameHostImpl::LifecycleStateImpl::kPrerendering;
1444 }
Abhijeet Kandalkar497904e22023-01-12 07:59:301445 return frame_tree_node->GetFrameType() == FrameType::kPrerenderMainFrame;
Kevin McNee07c67ec92021-08-11 16:18:331446}
1447
creisf71a2632017-05-04 19:03:501448RenderFrameHostImpl* WebContentsImpl::UnsafeFindFrameByFrameTreeNodeId(
rob3e2a0732016-01-06 21:22:091449 int frame_tree_node_id) {
Alexander Timin5fdeff22020-09-08 09:20:371450 OPTIONAL_TRACE_EVENT1("content",
1451 "WebContentsImpl::UnsafeFindFrameByFrameTreeNodeId",
1452 "frame_tree_node_id", frame_tree_node_id);
creisf71a2632017-05-04 19:03:501453 // Beware using this! The RenderFrameHost may have changed since the caller
1454 // obtained frame_tree_node_id.
Kunihiko Sakamoto1c5a09e2021-08-10 02:40:391455 FrameTreeNode* ftn = FrameTreeNode::GloballyFindByID(frame_tree_node_id);
1456 if (!ftn)
1457 return nullptr;
1458 if (this != WebContents::FromRenderFrameHost(ftn->current_frame_host()))
1459 return nullptr;
1460 return ftn->current_frame_host();
rob3e2a0732016-01-06 21:22:091461}
1462
Daniel Cheng982f2b22022-08-25 23:46:161463void WebContentsImpl::ForEachRenderFrameHostWithAction(
1464 base::FunctionRef<FrameIterationAction(RenderFrameHost*)> on_frame) {
1465 ForEachRenderFrameHostWithAction(
1466 [on_frame](RenderFrameHostImpl* rfh) { return on_frame(rfh); });
Kevin McNeec9d0fda2021-05-19 15:55:171467}
1468
1469void WebContentsImpl::ForEachRenderFrameHost(
Daniel Cheng982f2b22022-08-25 23:46:161470 base::FunctionRef<void(RenderFrameHost*)> on_frame) {
1471 ForEachRenderFrameHost(
1472 [on_frame](RenderFrameHostImpl* rfh) { on_frame(rfh); });
Kevin McNeec9d0fda2021-05-19 15:55:171473}
1474
Daniel Cheng982f2b22022-08-25 23:46:161475void WebContentsImpl::ForEachRenderFrameHostWithAction(
1476 base::FunctionRef<FrameIterationAction(RenderFrameHostImpl*)> on_frame) {
Kevin McNeec9d0fda2021-05-19 15:55:171477 ForEachRenderFrameHostImpl(on_frame, /* include_speculative */ false);
1478}
1479
1480void WebContentsImpl::ForEachRenderFrameHost(
Daniel Cheng982f2b22022-08-25 23:46:161481 base::FunctionRef<void(RenderFrameHostImpl*)> on_frame) {
1482 ForEachRenderFrameHostWithAction([on_frame](RenderFrameHostImpl* rfh) {
1483 on_frame(rfh);
1484 return FrameIterationAction::kContinue;
1485 });
Kevin McNeec9d0fda2021-05-19 15:55:171486}
1487
Daniel Cheng982f2b22022-08-25 23:46:161488void WebContentsImpl::ForEachRenderFrameHostIncludingSpeculativeWithAction(
1489 base::FunctionRef<FrameIterationAction(RenderFrameHostImpl*)> on_frame) {
Kevin McNeec9d0fda2021-05-19 15:55:171490 ForEachRenderFrameHostImpl(on_frame, /* include_speculative */ true);
1491}
1492
1493void WebContentsImpl::ForEachRenderFrameHostIncludingSpeculative(
Daniel Cheng982f2b22022-08-25 23:46:161494 base::FunctionRef<void(RenderFrameHostImpl*)> on_frame) {
1495 ForEachRenderFrameHostIncludingSpeculativeWithAction(
1496 [on_frame](RenderFrameHostImpl* rfh) {
1497 on_frame(rfh);
1498 return FrameIterationAction::kContinue;
1499 });
Kevin McNeec9d0fda2021-05-19 15:55:171500}
1501
1502void WebContentsImpl::ForEachRenderFrameHostImpl(
Daniel Cheng982f2b22022-08-25 23:46:161503 base::FunctionRef<FrameIterationAction(RenderFrameHostImpl*)> on_frame,
Kevin McNeec9d0fda2021-05-19 15:55:171504 bool include_speculative) {
1505 // Since |RenderFrameHostImpl::ForEachRenderFrameHost| will reach the
1506 // RenderFrameHosts descending from a specified root, it is enough to start
1507 // iteration from each of the outermost main frames to reach everything in
1508 // this WebContents. However, if iteration stops early in
1509 // |RenderFrameHostImpl::ForEachRenderFrameHost|, we also need to stop early
1510 // by not iterating over additional outermost main frames.
1511 bool iteration_stopped = false;
Daniel Cheng982f2b22022-08-25 23:46:161512 auto on_frame_with_termination =
1513 [on_frame, &iteration_stopped](RenderFrameHostImpl* rfh) {
1514 const auto action = on_frame(rfh);
1515 if (action == FrameIterationAction::kStop) {
1516 iteration_stopped = true;
1517 }
1518 return action;
1519 };
Kevin McNeec9d0fda2021-05-19 15:55:171520
1521 for (auto* rfh : GetOutermostMainFrames()) {
1522 if (include_speculative) {
Daniel Cheng982f2b22022-08-25 23:46:161523 rfh->ForEachRenderFrameHostIncludingSpeculativeWithAction(
Kevin McNeec9d0fda2021-05-19 15:55:171524 on_frame_with_termination);
1525 } else {
Daniel Cheng982f2b22022-08-25 23:46:161526 rfh->ForEachRenderFrameHostWithAction(on_frame_with_termination);
Kevin McNeec9d0fda2021-05-19 15:55:171527 }
1528
1529 if (iteration_stopped) {
1530 return;
1531 }
1532 }
1533}
1534
Takashi Toyoshimadc3f7472021-07-21 08:02:321535void WebContentsImpl::ForEachFrameTree(
1536 FrameTreeIterationCallback on_frame_tree) {
Kevin McNee53f0b2d2021-11-02 18:00:451537 // Consider all outermost frame trees, and for each, iterate through their
1538 // FrameTreeNodes to find any inner frame trees.
1539 for (FrameTree* outermost_frame_tree : GetOutermostFrameTrees()) {
1540 FrameTree::NodeRange node_range =
1541 outermost_frame_tree->NodesIncludingInnerTreeNodes();
1542 FrameTree::NodeIterator node_iter = node_range.begin();
1543 while (node_iter != node_range.end()) {
1544 FrameTreeNode* node = *node_iter;
1545 if (FromFrameTreeNode(node) != this) {
1546 // Exclude any inner frame trees based on multi-WebContents
1547 // architecture.
1548 node_iter.AdvanceSkippingChildren();
1549 } else {
1550 if (node->IsMainFrame()) {
1551 on_frame_tree.Run(node->frame_tree());
1552 }
1553 ++node_iter;
1554 }
1555 }
1556 }
1557}
Takashi Toyoshimadc3f7472021-07-21 08:02:321558
Kevin McNee53f0b2d2021-11-02 18:00:451559std::vector<FrameTree*> WebContentsImpl::GetOutermostFrameTrees() {
Sarah Murphy3bccae62022-02-15 20:22:451560 // If the WebContentsImpl is being destroyed, then we should not
1561 // perform the tree traversal.
1562 if (IsBeingDestroyed())
1563 return {};
1564
Kevin McNee53f0b2d2021-11-02 18:00:451565 std::vector<FrameTree*> result;
Carlos Caballero1a261f82021-11-04 15:54:031566 result.push_back(&GetPrimaryFrameTree());
Kevin McNee53f0b2d2021-11-02 18:00:451567
Johann344e1c72022-11-22 07:22:301568 const std::vector<FrameTree*> prerender_frame_trees =
1569 GetPrerenderHostRegistry()->GetPrerenderFrameTrees();
1570 result.insert(result.end(), prerender_frame_trees.begin(),
1571 prerender_frame_trees.end());
Fergal Daly80da12492022-02-10 06:10:511572
Kevin McNee53f0b2d2021-11-02 18:00:451573 return result;
Takashi Toyoshimadc3f7472021-07-21 08:02:321574}
1575
Kevin McNeec9d0fda2021-05-19 15:55:171576std::vector<RenderFrameHostImpl*> WebContentsImpl::GetOutermostMainFrames() {
Kevin McNeed7fc6d052022-02-08 21:21:501577 // Do nothing if the WebContents is currently being initialized or destroyed.
Dave Tapuska327c06c92022-06-13 20:31:511578 if (!GetPrimaryMainFrame())
Kevin McNeed7fc6d052022-02-08 21:21:501579 return {};
1580
Kevin McNeec9d0fda2021-05-19 15:55:171581 std::vector<RenderFrameHostImpl*> result;
Kevin McNee53f0b2d2021-11-02 18:00:451582
1583 for (FrameTree* outermost_frame_tree : GetOutermostFrameTrees()) {
Kevin McNeed7fc6d052022-02-08 21:21:501584 DCHECK(outermost_frame_tree->GetMainFrame());
Kevin McNee53f0b2d2021-11-02 18:00:451585 result.push_back(outermost_frame_tree->GetMainFrame());
1586 }
Kevin McNeec9d0fda2021-05-19 15:55:171587
1588 for (const auto& entry : GetController().GetBackForwardCache().GetEntries()) {
Yuzu Saijo68390b992021-07-27 06:17:201589 result.push_back(entry->render_frame_host());
Kevin McNeec9d0fda2021-05-19 15:55:171590 }
1591
Kevin McNeec9d0fda2021-05-19 15:55:171592 // In the case of inner WebContents, we still allow this method to be called,
1593 // but the semantics of the values being returned are "outermost
1594 // within this WebContents" as opposed to truly outermost. We would not expect
1595 // any other outermost pages besides the primary page in the case of inner
1596 // WebContents.
1597 DCHECK(!GetOuterWebContents() || (result.size() == 1));
1598
1599 return result;
1600}
1601
Gyuyoung Kim877e86d2020-07-21 04:01:021602void WebContentsImpl::ExecutePageBroadcastMethod(
1603 PageBroadcastMethodCallback callback) {
Alexander Timin5fdeff22020-09-08 09:20:371604 OPTIONAL_TRACE_EVENT0("content",
1605 "WebContentsImpl::ExecutePageBroadcastMethod");
Carlos Caballerob65b6e3a2021-11-15 10:09:001606 primary_frame_tree_.root()->render_manager()->ExecutePageBroadcastMethod(
1607 callback);
Gyuyoung Kim877e86d2020-07-21 04:01:021608}
1609
Takashi Toyoshimadf3f4e312021-11-19 03:51:481610void WebContentsImpl::ExecutePageBroadcastMethodForAllPages(
1611 PageBroadcastMethodCallback callback) {
1612 OPTIONAL_TRACE_EVENT0(
1613 "content", "WebContentsImpl::ExecutePageBroadcastMethodForAllPages");
1614 ForEachFrameTree(base::BindRepeating(
Arthur Sonzognif6785ec2022-12-05 10:11:501615 [](PageBroadcastMethodCallback* callback, FrameTree& frame_tree) {
1616 frame_tree.root()->render_manager()->ExecutePageBroadcastMethod(
Takashi Toyoshimadf3f4e312021-11-19 03:51:481617 *callback);
1618 },
1619 &callback));
1620}
1621
Lucas Furukawa Gadanie1c5dfda2018-11-29 17:57:411622RenderViewHostImpl* WebContentsImpl::GetRenderViewHost() {
Alex Moshchuk2e470ea2021-02-03 06:46:341623 return GetRenderManager()->current_frame_host()->render_view_host();
[email protected]be1f56ab2011-12-22 06:55:311624}
1625
creis89a0f782015-05-27 16:13:171626void WebContentsImpl::CancelActiveAndPendingDialogs() {
Alexander Timin5fdeff22020-09-08 09:20:371627 OPTIONAL_TRACE_EVENT0("content",
1628 "WebContentsImpl::CancelActiveAndPendingDialogs");
Evan Stade753fc202020-07-13 18:09:541629 if (dialog_manager_) {
avi6879fcf2017-01-21 05:27:531630 dialog_manager_->CancelDialogs(this, /*reset_state=*/false);
Evan Stade753fc202020-07-13 18:09:541631 }
creis89a0f782015-05-27 16:13:171632 if (browser_plugin_embedder_)
1633 browser_plugin_embedder_->CancelGuestDialogs();
1634}
1635
naskoc0fceff2015-04-30 15:53:521636void WebContentsImpl::ClosePage() {
Alexander Timin5fdeff22020-09-08 09:20:371637 OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::ClosePage");
Alex Moshchuke558aba2023-01-13 07:42:021638 GetPrimaryMainFrame()->ClosePage();
naskoc0fceff2015-04-30 15:53:521639}
1640
Lucas Furukawa Gadanie1c5dfda2018-11-29 17:57:411641RenderWidgetHostView* WebContentsImpl::GetRenderWidgetHostView() {
[email protected]fa944cb82013-11-15 17:51:211642 return GetRenderManager()->GetRenderWidgetHostView();
[email protected]be1f56ab2011-12-22 06:55:311643}
1644
lfg265a2672016-04-23 03:11:021645RenderWidgetHostView* WebContentsImpl::GetTopLevelRenderWidgetHostView() {
1646 if (GetOuterWebContents())
1647 return GetOuterWebContents()->GetTopLevelRenderWidgetHostView();
1648 return GetRenderManager()->GetRenderWidgetHostView();
1649}
1650
[email protected]8ff00d72012-10-23 19:12:211651WebContentsView* WebContentsImpl::GetView() const {
[email protected]be1f56ab2011-12-22 06:55:311652 return view_.get();
1653}
1654
Mike Wasserman5a3cc61d2020-08-27 21:12:031655void WebContentsImpl::OnScreensChange(bool is_multi_screen_changed) {
Alexander Timin5fdeff22020-09-08 09:20:371656 OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::OnScreensChange",
1657 "is_multi_screen_changed", is_multi_screen_changed);
Mike Wassermandb8f4f02020-10-06 01:18:371658 // Allow fullscreen requests shortly after user-generated screens changes.
Mike Wasserman11554ff92021-05-16 00:46:261659 // TODO(crbug.com/1169291): Mac should not activate this on local process
1660 // display::Screen signals, but via RenderWidgetHostViewMac screen updates.
Mike Wassermandb8f4f02020-10-06 01:18:371661 transient_allow_fullscreen_.Activate();
Mike Wasserman11554ff92021-05-16 00:46:261662
1663 // Mac display info may originate from a remote process hosting the NSWindow;
1664 // this local process display::Screen signal should not trigger updates.
1665 // TODO(crbug.com/1169291): Unify screen info plumbing, caching, etc.
Xiaohan Wang24ec9342022-01-15 17:34:221666#if !BUILDFLAG(IS_MAC)
Mike Wasserman9545ebc2021-01-28 03:32:141667 // This updates Screen attributes and fires Screen.change events as needed,
1668 // propagating to all widgets through the VisualProperties update waterfall.
1669 // This is triggered by system changes, not renderer IPC, so explicitly check
1670 // that the RenderWidgetHostView is valid before sending an update.
1671 if (RenderWidgetHostViewBase* view =
1672 GetRenderViewHost()->GetWidget()->GetView()) {
Adrienne Walker39dcdcf2021-10-06 19:30:351673 // Only update top-level views, as child frames will have their ScreenInfos
1674 // updated by the visual property flow.
1675 if (!view->IsRenderWidgetHostViewChildFrame())
1676 view->UpdateScreenInfo();
Mike Wasserman9545ebc2021-01-28 03:32:141677 }
Xiaohan Wang24ec9342022-01-15 17:34:221678#endif // !BUILDFLAG(IS_MAC)
Mike Wassermanb213b9352020-04-16 00:32:341679}
1680
leon.han552e9de2017-02-09 14:37:301681void WebContentsImpl::OnScreenOrientationChange() {
Alexander Timin5fdeff22020-09-08 09:20:371682 OPTIONAL_TRACE_EVENT0("content",
1683 "WebContentsImpl::OnScreenOrientationChange");
leon.han552e9de2017-02-09 14:37:301684 DCHECK(screen_orientation_provider_);
Lan Weif81c6e7c2020-02-12 16:46:091685 DidChangeScreenOrientation();
Becca Hughese9e27952018-06-25 17:08:271686 screen_orientation_provider_->OnOrientationChange();
leon.hane4db177a2017-02-07 14:19:161687}
1688
Anton Bikineevf62d1bf2021-05-15 17:56:071689absl::optional<SkColor> WebContentsImpl::GetThemeColor() {
Jeremy Roman2d8dfe132021-07-06 20:51:261690 return GetPrimaryPage().theme_color();
yusufod41c5f92015-03-06 00:14:281691}
1692
Anton Bikineevf62d1bf2021-05-15 17:56:071693absl::optional<SkColor> WebContentsImpl::GetBackgroundColor() {
Jeremy Roman2d8dfe132021-07-06 20:51:261694 return GetPrimaryPage().background_color();
Alan Cutterd73a15d92020-08-21 07:12:451695}
1696
Bo Liub5e79d92021-06-12 01:40:411697void WebContentsImpl::SetPageBaseBackgroundColor(
1698 absl::optional<SkColor> color) {
1699 if (page_base_background_color_ == color)
1700 return;
1701 page_base_background_color_ = color;
1702 ExecutePageBroadcastMethod(base::BindRepeating(
1703 [](absl::optional<SkColor> color, RenderViewHostImpl* rvh) {
1704 // Null `broadcast` can happen before view is created on the renderer
1705 // side, in which case this color will be sent in CreateView.
1706 if (auto& broadcast = rvh->GetAssociatedPageBroadcast())
1707 broadcast->SetPageBaseBackgroundColor(color);
1708 },
1709 page_base_background_color_));
1710}
1711
tom855c4bf32021-09-30 00:27:261712void WebContentsImpl::SetColorProviderSource(ui::ColorProviderSource* source) {
1713 ColorProviderSourceObserver::Observe(source);
1714}
1715
Doug Turner63f3c7b2017-07-29 05:10:011716void WebContentsImpl::SetAccessibilityMode(ui::AXMode mode) {
Alexander Timin5fdeff22020-09-08 09:20:371717 OPTIONAL_TRACE_EVENT2("content", "WebContentsImpl::SetAccessibilityMode",
1718 "mode", mode.ToString(), "previous_mode",
1719 accessibility_mode_.ToString());
1720
[email protected]95640212014-07-26 18:14:301721 if (mode == accessibility_mode_)
1722 return;
1723
dmazzonif8a31042016-12-03 00:52:131724 // Don't allow accessibility to be enabled for WebContents that are never
danakj77eb7e82020-01-09 19:38:461725 // user-visible, like background pages.
1726 if (IsNeverComposited())
dmazzonif8a31042016-12-03 00:52:131727 return;
1728
[email protected]95640212014-07-26 18:14:301729 accessibility_mode_ = mode;
Ian Vollickffdc0542021-05-14 02:12:301730 // Update state for all frames in this tree and inner trees. Should also
1731 // include speculative frame hosts.
Dave Tapuska327c06c92022-06-13 20:31:511732 GetPrimaryMainFrame()->ForEachRenderFrameHostIncludingSpeculative(
Daniel Cheng982f2b22022-08-25 23:46:161733 &RenderFrameHostImpl::UpdateAccessibilityMode);
[email protected]95640212014-07-26 18:14:301734}
1735
Doug Turner63f3c7b2017-07-29 05:10:011736void WebContentsImpl::AddAccessibilityMode(ui::AXMode mode) {
1737 ui::AXMode new_mode(accessibility_mode_);
dougtcd3dad732017-03-14 03:26:231738 new_mode |= mode;
1739 SetAccessibilityMode(new_mode);
[email protected]95640212014-07-26 18:14:301740}
1741
Avi Drissman1e620f32018-03-16 13:57:291742// Helper class used by WebContentsImpl::RequestAXTreeSnapshot.
1743// Handles the callbacks from parallel snapshot requests to each frame,
1744// and feeds the results to an AXTreeCombiner, which converts them into a
1745// single combined accessibility tree.
Dave Tapuskac05b0172021-09-09 20:27:191746class AXTreeSnapshotCombiner : public base::RefCounted<AXTreeSnapshotCombiner> {
Avi Drissman1e620f32018-03-16 13:57:291747 public:
Dave Tapuskac05b0172021-09-09 20:27:191748 AXTreeSnapshotCombiner(WebContents::AXTreeSnapshotCallback callback,
1749 mojom::SnapshotAccessibilityTreeParamsPtr params)
1750 : callback_(std::move(callback)), params_(std::move(params)) {}
Avi Drissman1e620f32018-03-16 13:57:291751
Dave Tapuskac05b0172021-09-09 20:27:191752 WebContents::AXTreeSnapshotCallback AddFrame(bool is_root) {
Avi Drissman1e620f32018-03-16 13:57:291753 // Adds a reference to |this|.
1754 return base::BindOnce(&AXTreeSnapshotCombiner::ReceiveSnapshot, this,
1755 is_root);
1756 }
1757
1758 void ReceiveSnapshot(bool is_root, const ui::AXTreeUpdate& snapshot) {
1759 combiner_.AddTree(snapshot, is_root);
1760 }
1761
Dave Tapuskac05b0172021-09-09 20:27:191762 void AXTreeSnapshotOnFrame(RenderFrameHostImpl* rfhi) {
1763 OPTIONAL_TRACE_EVENT0("content",
1764 "AXTreeSnapshotCombiner::AXTreeSnapshotOnFrame");
Dave Tapuska5dd5f9822021-09-10 20:57:151765 bool is_root = !rfhi->GetParentOrOuterDocumentOrEmbedder();
Dave Tapuskac05b0172021-09-09 20:27:191766 rfhi->RequestAXTreeSnapshot(AddFrame(is_root), params_.Clone());
1767 }
1768
Avi Drissman1e620f32018-03-16 13:57:291769 private:
1770 friend class base::RefCounted<AXTreeSnapshotCombiner>;
1771
1772 // This is called automatically after the last call to ReceiveSnapshot
1773 // when there are no more references to this object.
1774 ~AXTreeSnapshotCombiner() {
1775 combiner_.Combine();
1776 std::move(callback_).Run(combiner_.combined());
1777 }
1778
1779 ui::AXTreeCombiner combiner_;
Dave Tapuskac05b0172021-09-09 20:27:191780 WebContents::AXTreeSnapshotCallback callback_;
1781 mojom::SnapshotAccessibilityTreeParamsPtr params_;
Avi Drissman1e620f32018-03-16 13:57:291782};
1783
1784void WebContentsImpl::RequestAXTreeSnapshot(AXTreeSnapshotCallback callback,
Dominic Mazzoni77d0aba2021-01-14 09:42:161785 ui::AXMode ax_mode,
1786 bool exclude_offscreen,
1787 size_t max_nodes,
1788 base::TimeDelta timeout) {
Alexander Timin5fdeff22020-09-08 09:20:371789 OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::RequestAXTreeSnapshot",
1790 "mode", ax_mode.ToString());
dmazzonid95ae842016-04-12 21:17:391791 // Send a request to each of the frames in parallel. Each one will return
1792 // an accessibility tree snapshot, and AXTreeSnapshotCombiner will combine
1793 // them into a single tree and call |callback| with that result, then
1794 // delete |combiner|.
Dominic Mazzoni77d0aba2021-01-14 09:42:161795 auto params = mojom::SnapshotAccessibilityTreeParams::New();
Amanda Lin Dietze54912e2022-11-22 20:25:571796 params->ax_mode = ax_mode.flags();
Dominic Mazzoni77d0aba2021-01-14 09:42:161797 params->exclude_offscreen = exclude_offscreen;
1798 params->max_nodes = max_nodes;
1799 params->timeout = timeout;
Avi Drissman1e620f32018-03-16 13:57:291800
Dave Tapuskac05b0172021-09-09 20:27:191801 auto combiner = base::MakeRefCounted<AXTreeSnapshotCombiner>(
1802 std::move(callback), std::move(params));
Daniel Cheng982f2b22022-08-25 23:46:161803 GetPrimaryMainFrame()->ForEachRenderFrameHost(
1804 [&combiner](RenderFrameHostImpl* rfh) {
1805 combiner->AXTreeSnapshotOnFrame(rfh);
1806 });
dmazzoni83ba5c82015-04-14 07:11:511807}
1808
Becca Hughes3b5a43482018-07-17 22:31:551809void WebContentsImpl::NotifyViewportFitChanged(
1810 blink::mojom::ViewportFit value) {
Alexander Timin5fdeff22020-09-08 09:20:371811 OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::NotifyViewportFitChanged",
1812 "value", static_cast<int>(value));
Andrew Grievee19cd93e2021-01-22 05:43:061813 observers_.NotifyObservers(&WebContentsObserver::ViewportFitChanged, value);
Becca Hughes3b5a43482018-07-17 22:31:551814}
1815
Lucas Furukawa Gadanie1c5dfda2018-11-29 17:57:411816FindRequestManager* WebContentsImpl::GetFindRequestManagerForTesting() {
Miyoung Shinbf4c40c2021-10-21 11:00:231817 return GetOrCreateFindRequestManager();
Ehsan Karamad6beb2ea2018-11-25 18:15:131818}
1819
akabac6bd1212018-06-25 20:10:481820void WebContentsImpl::UpdateZoom() {
Alexander Timin5fdeff22020-09-08 09:20:371821 OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::UpdateZoom");
akabac6bd1212018-06-25 20:10:481822 RenderWidgetHostImpl* rwh = GetRenderViewHost()->GetWidget();
1823 if (rwh->GetView())
1824 rwh->SynchronizeVisualProperties();
wjmaclean64951902016-04-29 20:59:121825}
1826
wjmaclean64951902016-04-29 20:59:121827void WebContentsImpl::UpdateZoomIfNecessary(const std::string& scheme,
akabac6bd1212018-06-25 20:10:481828 const std::string& host) {
Alexander Timin5fdeff22020-09-08 09:20:371829 OPTIONAL_TRACE_EVENT2("content", "WebContentsImpl::UpdateZoomIfNecessary",
1830 "scheme", scheme, "host", host);
wjmaclean64951902016-04-29 20:59:121831 NavigationEntry* entry = GetController().GetLastCommittedEntry();
1832 if (!entry)
1833 return;
1834
1835 GURL url = HostZoomMap::GetURLFromEntry(entry);
1836 if (host != net::GetHostOrSpecFromURL(url) ||
1837 (!scheme.empty() && !url.SchemeIs(scheme))) {
1838 return;
1839 }
1840
akabac6bd1212018-06-25 20:10:481841 UpdateZoom();
wjmaclean64951902016-04-29 20:59:121842}
1843
paulmeyerfeafc2d2017-04-25 21:46:401844std::vector<WebContentsImpl*> WebContentsImpl::GetWebContentsAndAllInner() {
1845 std::vector<WebContentsImpl*> all_contents(1, this);
1846
1847 for (size_t i = 0; i != all_contents.size(); ++i) {
1848 for (auto* inner_contents : all_contents[i]->GetInnerWebContents()) {
Lucas Furukawa Gadani2ec00c82018-12-14 15:53:161849 all_contents.push_back(static_cast<WebContentsImpl*>(inner_contents));
paulmeyerfeafc2d2017-04-25 21:46:401850 }
1851 }
1852
1853 return all_contents;
1854}
1855
Sreeja Kamishettycfb4b862022-03-29 16:59:391856void WebContentsImpl::OnManifestUrlChanged(PageImpl& page) {
Julie Jeongeun Kim9e204512021-06-24 07:28:541857 absl::optional<GURL> manifest_url = page.GetManifestUrl();
Julie Jeongeun Kimd74c1e7f2021-06-18 04:06:181858 if (!manifest_url.has_value())
1859 return;
1860
Sreeja Kamishettycfb4b862022-03-29 16:59:391861 if (!page.IsPrimary())
1862 return;
1863
Alexander Timin5fdeff22020-09-08 09:20:371864 OPTIONAL_TRACE_EVENT2("content", "WebContentsImpl::NotifyManifestUrlChanged",
Sreeja Kamishetty1b5c1432021-06-25 11:32:591865 "render_frame_host", &page.GetMainDocument(),
Julie Jeongeun Kim9e204512021-06-24 07:28:541866 "manifest_url", manifest_url);
1867 observers_.NotifyObservers(&WebContentsObserver::DidUpdateWebManifestURL,
Sreeja Kamishetty1b5c1432021-06-25 11:32:591868 &page.GetMainDocument(), *manifest_url);
Sam McNally145fb172017-05-10 00:13:231869}
1870
Lucas Furukawa Gadanie1c5dfda2018-11-29 17:57:411871WebUI* WebContentsImpl::GetWebUI() {
Carlos Caballerob65b6e3a2021-11-15 10:09:001872 return primary_frame_tree_.root()->current_frame_host()->web_ui();
[email protected]d5f942ba2008-09-26 19:30:341873}
1874
Maks Orlovich73f374d2020-04-02 12:46:131875void WebContentsImpl::SetUserAgentOverride(
1876 const blink::UserAgentOverride& ua_override,
1877 bool override_in_new_tabs) {
Alexander Timin5fdeff22020-09-08 09:20:371878 OPTIONAL_TRACE_EVENT2("content", "WebContentsImpl::SetUserAgentOverride",
1879 "ua_override", ua_override.ua_string_override,
1880 "override_in_new_tabs", override_in_new_tabs);
Maks Orlovich73f374d2020-04-02 12:46:131881 DCHECK(!ua_override.ua_metadata_override.has_value() ||
1882 !ua_override.ua_string_override.empty());
1883
1884 if (GetUserAgentOverride() == ua_override)
[email protected]bf70edce2012-06-20 22:32:221885 return;
1886
David Van Clevede398a52020-12-28 21:33:031887 if (!ua_override.ua_string_override.empty() &&
1888 !net::HttpUtil::IsValidHeaderValue(ua_override.ua_string_override)) {
1889 return;
1890 }
1891
Changwan Ryuc1134a82018-03-07 02:10:141892 should_override_user_agent_in_new_tabs_ = override_in_new_tabs;
1893
Maks Orlovich73f374d2020-04-02 12:46:131894 renderer_preferences_.user_agent_override = ua_override;
[email protected]bf70edce2012-06-20 22:32:221895
Bruce Long1e3e1f542019-10-16 17:56:281896 // Send the new override string to all renderers in the current page.
1897 SyncRendererPrefs();
[email protected]bf70edce2012-06-20 22:32:221898
1899 // Reload the page if a load is currently in progress to avoid having
1900 // different parts of the page loaded using different user agents.
Scott Violete1d58cc2020-04-28 23:07:171901 // No need to reload if the current entry matches that of the
1902 // NavigationRequest supplied to DidStartNavigation() as NavigationRequest
1903 // handles it.
Arthur Sonzognif6785ec2022-12-05 10:11:501904 ForEachFrameTree(base::BindRepeating([](FrameTree& frame_tree) {
Takashi Toyoshimac8d26342021-08-06 07:22:281905 // For prerendering, we don't want to activate a prerendered page loaded
1906 // with a stale UA and will handle it even if it finishes loading.
Arthur Sonzognif6785ec2022-12-05 10:11:501907 if (!frame_tree.IsLoadingIncludingInnerFrameTrees() &&
1908 !frame_tree.is_prerendering()) {
Takashi Toyoshimafa9a910e2021-08-05 04:03:001909 return;
Yu Gaoc8c18552022-06-22 14:38:451910 }
Takashi Toyoshimac8d26342021-08-06 07:22:281911
Arthur Sonzognif6785ec2022-12-05 10:11:501912 NavigationEntry* entry = frame_tree.controller().GetVisibleEntry();
Takashi Toyoshimafa9a910e2021-08-05 04:03:001913 if (!entry || !entry->GetIsOverridingUserAgent())
1914 return;
Arthur Sonzognif6785ec2022-12-05 10:11:501915 if (frame_tree.root()->navigation_request() &&
1916 !frame_tree.root()->navigation_request()->ua_change_requires_reload()) {
Takashi Toyoshimafa9a910e2021-08-05 04:03:001917 return;
1918 }
Arthur Sonzognif6785ec2022-12-05 10:11:501919 if (frame_tree.is_prerendering()) {
Takashi Toyoshimafa9a910e2021-08-05 04:03:001920 // Just cancel if the FrameTree is for prerendering, as prerendered
1921 // page may not allow another navigation including a reload, depending
1922 // on conditions.
Arthur Sonzognif6785ec2022-12-05 10:11:501923 frame_tree.GetMainFrame()->CancelPrerendering(PrerenderCancellationReason(
1924 PrerenderFinalStatus::kUaChangeRequiresReload));
Takashi Toyoshimafa9a910e2021-08-05 04:03:001925 } else {
Arthur Sonzognif6785ec2022-12-05 10:11:501926 frame_tree.controller().Reload(ReloadType::BYPASSING_CACHE, true);
Takashi Toyoshimafa9a910e2021-08-05 04:03:001927 }
1928 }));
[email protected]8d0f3312012-08-18 01:47:531929
Andrew Grievee19cd93e2021-01-22 05:43:061930 observers_.NotifyObservers(&WebContentsObserver::UserAgentOverrideSet,
1931 ua_override);
[email protected]86ef6a392012-05-11 22:03:111932}
1933
Scott Violet2a6c5bff2020-04-29 23:59:061934void WebContentsImpl::SetRendererInitiatedUserAgentOverrideOption(
1935 NavigationController::UserAgentOverrideOption option) {
Alexander Timin5fdeff22020-09-08 09:20:371936 OPTIONAL_TRACE_EVENT0(
1937 "content",
1938 "WebContentsImpl::SetRendererInitiatedUserAgentOverrideOption");
Scott Violet2a6c5bff2020-04-29 23:59:061939 renderer_initiated_user_agent_override_option_ = option;
1940}
1941
Maks Orlovich73f374d2020-04-02 12:46:131942const blink::UserAgentOverride& WebContentsImpl::GetUserAgentOverride() {
[email protected]bf70edce2012-06-20 22:32:221943 return renderer_preferences_.user_agent_override;
[email protected]86ef6a392012-05-11 22:03:111944}
1945
Scott Violet2a6c5bff2020-04-29 23:59:061946bool WebContentsImpl::ShouldOverrideUserAgentForRendererInitiatedNavigation() {
Carlos Caballero40b0efd2021-01-26 11:55:001947 NavigationEntryImpl* current_entry = GetController().GetLastCommittedEntry();
Rakina Zata Amni2322f4f82022-01-24 13:24:241948 if (!current_entry || current_entry->IsInitialEntry())
Scott Violet2a6c5bff2020-04-29 23:59:061949 return should_override_user_agent_in_new_tabs_;
1950
1951 switch (renderer_initiated_user_agent_override_option_) {
1952 case NavigationController::UA_OVERRIDE_INHERIT:
1953 return current_entry->GetIsOverridingUserAgent();
1954 case NavigationController::UA_OVERRIDE_TRUE:
1955 return true;
1956 case NavigationController::UA_OVERRIDE_FALSE:
1957 return false;
1958 default:
1959 break;
1960 }
1961 return false;
Changwan Ryuc1134a82018-03-07 02:10:141962}
1963
dmazzonidd3d51a72016-12-14 18:41:011964void WebContentsImpl::EnableWebContentsOnlyAccessibilityMode() {
Alexander Timin5fdeff22020-09-08 09:20:371965 OPTIONAL_TRACE_EVENT0(
1966 "content", "WebContentsImpl::EnableWebContentsOnlyAccessibilityMode");
Dominic Mazzonid9fda172019-03-07 17:12:071967 // If accessibility is already enabled, we'll need to force a reset
1968 // in order to ensure new observers of accessibility events get the
1969 // full accessibility tree from scratch.
1970 bool need_reset = GetAccessibilityMode().has_mode(ui::AXMode::kWebContents);
1971
1972 ui::AXMode desired_mode =
1973 GetContentClient()->browser()->GetAXModeForBrowserContext(
1974 GetBrowserContext());
1975 desired_mode |= ui::kAXModeWebContentsOnly;
1976 AddAccessibilityMode(desired_mode);
1977
Ian Vollickffdc0542021-05-14 02:12:301978 // Accessibility mode updates include speculative RFH's as well as any inner
1979 // trees. Iterate across these as we do for SetAccessibilityMode (which is
1980 // called indirectly above via AddAccessibilityMode).
Dominic Mazzonid9fda172019-03-07 17:12:071981 if (need_reset) {
Dave Tapuska327c06c92022-06-13 20:31:511982 GetPrimaryMainFrame()->ForEachRenderFrameHostIncludingSpeculative(
Daniel Cheng982f2b22022-08-25 23:46:161983 &RenderFrameHostImpl::AccessibilityReset);
dchengafb53e22016-02-04 08:11:081984 }
[email protected]95640212014-07-26 18:14:301985}
1986
Lucas Furukawa Gadanie1c5dfda2018-11-29 17:57:411987bool WebContentsImpl::IsWebContentsOnlyAccessibilityModeForTesting() {
Doug Turner63f3c7b2017-07-29 05:10:011988 return accessibility_mode_ == ui::kAXModeWebContentsOnly;
[email protected]95640212014-07-26 18:14:301989}
1990
Lucas Furukawa Gadanie1c5dfda2018-11-29 17:57:411991bool WebContentsImpl::IsFullAccessibilityModeForTesting() {
Doug Turner63f3c7b2017-07-29 05:10:011992 return accessibility_mode_ == ui::kAXModeComplete;
[email protected]95640212014-07-26 18:14:301993}
1994
Xiaohan Wang24ec9342022-01-15 17:34:221995#if BUILDFLAG(IS_ANDROID)
Becca Hughes6daf5662018-06-27 16:50:541996
1997void WebContentsImpl::SetDisplayCutoutSafeArea(gfx::Insets insets) {
Alexander Timin5fdeff22020-09-08 09:20:371998 OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::SetDisplayCutoutSafeArea");
Becca Hughes86334622018-07-09 21:29:381999 if (display_cutout_host_impl_)
2000 display_cutout_host_impl_->SetDisplayCutoutSafeArea(insets);
Becca Hughes6daf5662018-06-27 16:50:542001}
2002
2003#endif
2004
Jan Wilken Dörrieaace0cfef2021-03-11 22:01:582005const std::u16string& WebContentsImpl::GetTitle() {
Nasko Oskov2f7d2112019-10-29 03:26:572006 WebUI* our_web_ui =
2007 GetRenderManager()->speculative_frame_host()
2008 ? GetRenderManager()->speculative_frame_host()->web_ui()
2009 : GetRenderManager()->current_frame_host()->web_ui();
[email protected]7ade2732011-02-10 00:13:582010 if (our_web_ui) {
[email protected]96d185d2009-04-24 03:28:542011 // Don't override the title in view source mode.
Carlos Caballero40b0efd2021-01-26 11:55:002012 NavigationEntry* entry = GetController().GetVisibleEntry();
[email protected]96d185d2009-04-24 03:28:542013 if (!(entry && entry->IsViewSourceMode())) {
[email protected]e0112912011-02-02 22:54:352014 // Give the Web UI the chance to override our title.
Jan Wilken Dörrieaace0cfef2021-03-11 22:01:582015 const std::u16string& title = our_web_ui->GetOverriddenTitle();
[email protected]96d185d2009-04-24 03:28:542016 if (!title.empty())
2017 return title;
2018 }
2019 }
2020
Rakina Zata Amni46087a12022-11-11 08:28:382021 return GetNavigationEntryForTitle()->GetTitleForDisplay();
[email protected]96d185d2009-04-24 03:28:542022}
2023
Lucas Furukawa Gadanie1c5dfda2018-11-29 17:57:412024SiteInstanceImpl* WebContentsImpl::GetSiteInstance() {
Aaron Colwellc4bd7d62021-01-29 04:23:132025 return GetRenderManager()->current_frame_host()->GetSiteInstance();
[email protected]96d185d2009-04-24 03:28:542026}
2027
Lucas Furukawa Gadanie1c5dfda2018-11-29 17:57:412028bool WebContentsImpl::IsLoading() {
Yu Gaoc8c18552022-06-22 14:38:452029 return primary_frame_tree_.IsLoadingIncludingInnerFrameTrees();
[email protected]3c9e1872010-11-18 16:17:492030}
2031
Lucas Furukawa Gadanie1c5dfda2018-11-29 17:57:412032double WebContentsImpl::GetLoadProgress() {
Sreeja Kamishetty0be3b1b2021-08-12 17:04:152033 // TODO(crbug.com/1199682): Make this MPArch friendly considering primary
2034 // frame tree and its descendants.
Carlos Caballerob65b6e3a2021-11-15 10:09:002035 return primary_frame_tree_.GetLoadProgress();
Peter Boström18a40fa2018-10-31 19:03:502036}
2037
Nate Chapin9aabf5f2021-11-12 00:31:192038bool WebContentsImpl::ShouldShowLoadingUI() {
2039 return IsLoading() && should_show_loading_ui_;
[email protected]6dfed692014-05-22 04:18:032040}
2041
Sreeja Kamishetty81347582022-01-06 12:46:332042bool WebContentsImpl::IsDocumentOnLoadCompletedInPrimaryMainFrame() {
Jeremy Roman1ed2346b2021-06-25 15:26:352043 // TODO(mparch): This should be moved to Page, and callers should use it
2044 // directly.
2045 return GetPrimaryPage().is_on_load_completed_in_main_document();
Alexander Timindd0fa0c52019-11-06 13:03:372046}
2047
Lucas Furukawa Gadanie1c5dfda2018-11-29 17:57:412048bool WebContentsImpl::IsWaitingForResponse() {
Peter Boströma9a27f6e2018-11-21 13:12:192049 NavigationRequest* ongoing_navigation_request =
Carlos Caballerob65b6e3a2021-11-15 10:09:002050 primary_frame_tree_.root()->navigation_request();
Peter Boströma9a27f6e2018-11-21 13:12:192051
2052 // An ongoing navigation request means we're waiting for a response.
2053 return ongoing_navigation_request != nullptr;
[email protected]be1f56ab2011-12-22 06:55:312054}
2055
Lucas Furukawa Gadanie1c5dfda2018-11-29 17:57:412056const net::LoadStateWithParam& WebContentsImpl::GetLoadState() {
[email protected]be1f56ab2011-12-22 06:55:312057 return load_state_;
2058}
2059
Jan Wilken Dörrieaace0cfef2021-03-11 22:01:582060const std::u16string& WebContentsImpl::GetLoadStateHost() {
[email protected]be1f56ab2011-12-22 06:55:312061 return load_state_host_;
2062}
2063
Lucas Furukawa Gadanie1c5dfda2018-11-29 17:57:412064uint64_t WebContentsImpl::GetUploadSize() {
[email protected]be1f56ab2011-12-22 06:55:312065 return upload_size_;
2066}
2067
Lucas Furukawa Gadanie1c5dfda2018-11-29 17:57:412068uint64_t WebContentsImpl::GetUploadPosition() {
[email protected]be1f56ab2011-12-22 06:55:312069 return upload_position_;
2070}
2071
Lucas Furukawa Gadanie1c5dfda2018-11-29 17:57:412072const std::string& WebContentsImpl::GetEncoding() {
Dominic Farolino5c606c12021-12-18 09:40:142073 return GetPrimaryPage().GetEncoding();
[email protected]be1f56ab2011-12-22 06:55:312074}
2075
Charles Zhaod72f99d2018-09-17 14:18:272076bool WebContentsImpl::WasDiscarded() {
Carlos Caballero6a99dac2021-11-03 10:41:172077 return GetPrimaryFrameTree().root()->was_discarded();
Charles Zhaod72f99d2018-09-17 14:18:272078}
2079
Shubhie Panickerddf2a4e2018-03-06 00:09:062080void WebContentsImpl::SetWasDiscarded(bool was_discarded) {
Julie Jeongeun Kimc2e892f2023-01-11 10:22:092081 // It's set based on a tab and the setting value is started from a primary
2082 // tree and propagated to all children nodes including a fenced frame node.
Carlos Caballero6a99dac2021-11-03 10:41:172083 GetPrimaryFrameTree().root()->set_was_discarded();
Shubhie Panickerddf2a4e2018-03-06 00:09:062084}
2085
Dale Curtis7030f252021-04-07 14:05:312086base::ScopedClosureRunner WebContentsImpl::IncrementCapturerCount(
2087 const gfx::Size& capture_size,
2088 bool stay_hidden,
Elad Alon0feb6602021-10-14 09:26:362089 bool stay_awake,
2090 bool is_activity) {
Alexander Timin5fdeff22020-09-08 09:20:372091 OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::IncrementCapturerCount");
Takashi Toyoshimaea534ef22021-07-21 03:27:592092 DCHECK(!IsBeingDestroyed());
Xianzhu Wang724e08f2020-09-01 21:35:072093 if (stay_hidden) {
2094 // A hidden capture should not have side effect on the web contents, so it
2095 // should not pass a non-empty |capture_size| which will cause side effect.
2096 DCHECK(capture_size.IsEmpty());
Collin Bakerc5259962019-11-14 17:51:582097 ++hidden_capturer_count_;
Xianzhu Wang724e08f2020-09-01 21:35:072098 } else {
Collin Bakerc5259962019-11-14 17:51:582099 ++visible_capturer_count_;
Xianzhu Wang724e08f2020-09-01 21:35:072100 }
[email protected]222f5822014-02-05 23:40:492101
Dale Curtis7030f252021-04-07 14:05:312102 if (stay_awake)
2103 ++stay_awake_capturer_count_;
2104
Scott Violet7f0b5c32021-11-04 03:06:222105 view_->OnCapturerCountChanged();
2106
[email protected]222f5822014-02-05 23:40:492107 // Note: This provides a hint to upstream code to size the views optimally
2108 // for quality (e.g., to avoid scaling).
2109 if (!capture_size.IsEmpty() && preferred_size_for_capture_.IsEmpty()) {
2110 preferred_size_for_capture_ = capture_size;
2111 OnPreferredSizeChanged(preferred_size_);
2112 }
ccameron8807c38f2015-01-17 00:29:192113
Dale Curtis7030f252021-04-07 14:05:312114 if (!capture_wake_lock_ && stay_awake_capturer_count_) {
Dale Curtisc496a7762021-02-24 01:15:442115 if (auto* wake_lock_context = GetWakeLockContext()) {
2116 auto receiver = capture_wake_lock_.BindNewPipeAndPassReceiver();
2117 wake_lock_context->GetWakeLock(
2118 device::mojom::WakeLockType::kPreventDisplaySleepAllowDimming,
2119 device::mojom::WakeLockReason::kOther, "Capturing",
2120 std::move(receiver));
2121 }
2122 }
2123
2124 if (capture_wake_lock_)
2125 capture_wake_lock_->RequestWakeLock();
2126
Elad Alon0feb6602021-10-14 09:26:362127 UpdateVisibilityAndNotifyPageAndView(GetVisibility(), is_activity);
[email protected]54597982013-02-06 01:59:552128
Elad Alon0feb6602021-10-14 09:26:362129 return base::ScopedClosureRunner(base::BindOnce(
2130 &WebContentsImpl::DecrementCapturerCount, weak_factory_.GetWeakPtr(),
2131 stay_hidden, stay_awake, is_activity));
[email protected]be1f56ab2011-12-22 06:55:312132}
2133
Elad Alonf156eb62021-05-17 22:02:372134const blink::mojom::CaptureHandleConfig&
2135WebContentsImpl::GetCaptureHandleConfig() {
2136 DCHECK_CURRENTLY_ON(BrowserThread::UI);
2137 return capture_handle_config_;
2138}
2139
Lucas Furukawa Gadanie1c5dfda2018-11-29 17:57:412140bool WebContentsImpl::IsBeingCaptured() {
Collin Bakerc5259962019-11-14 17:51:582141 return visible_capturer_count_ + hidden_capturer_count_ > 0;
[email protected]f2bd40812013-07-20 04:30:442142}
2143
Xianzhu Wangc61434c2020-08-21 19:17:302144bool WebContentsImpl::IsBeingVisiblyCaptured() {
2145 return visible_capturer_count_ > 0;
2146}
2147
Lucas Furukawa Gadanie1c5dfda2018-11-29 17:57:412148bool WebContentsImpl::IsAudioMuted() {
Guido Urdanetaf8372942019-11-15 09:47:212149 return audio_stream_factory_ && audio_stream_factory_->IsMuted();
miu50f97892014-09-22 22:49:522150}
2151
2152void WebContentsImpl::SetAudioMuted(bool mute) {
Alexander Timin5fdeff22020-09-08 09:20:372153 OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::SetAudioMuted", "mute",
2154 mute);
miu50f97892014-09-22 22:49:522155 DVLOG(1) << "SetAudioMuted(mute=" << mute << "), was " << IsAudioMuted()
2156 << " for WebContentsImpl@" << this;
2157
2158 if (mute == IsAudioMuted())
2159 return;
2160
Guido Urdanetaf8372942019-11-15 09:47:212161 GetAudioStreamFactory()->SetMuted(mute);
miu50f97892014-09-22 22:49:522162
Andrew Grievee19cd93e2021-01-22 05:43:062163 observers_.NotifyObservers(&WebContentsObserver::DidUpdateAudioMutingState,
2164 mute);
Jan Rucka442c83f2017-08-08 13:27:542165 // Notification for UI updates in response to the changed muting state.
Collin Bakeraf540cf2019-09-20 20:54:162166 NotifyNavigationStateChanged(INVALIDATE_TYPE_AUDIO);
Jan Rucka442c83f2017-08-08 13:27:542167}
2168
2169bool WebContentsImpl::IsCurrentlyAudible() {
Chris Hamiltondf0d72cd2018-05-29 16:23:532170 return is_currently_audible_;
miu50f97892014-09-22 22:49:522171}
2172
Lucas Furukawa Gadanie1c5dfda2018-11-29 17:57:412173bool WebContentsImpl::IsConnectedToBluetoothDevice() {
ortunodf4d7982016-04-08 02:33:352174 return bluetooth_connected_device_count_ > 0;
ortuno32e7db3c2016-03-29 16:14:202175}
2176
Ovidio Henriquez76696f62020-07-08 03:06:592177bool WebContentsImpl::IsScanningForBluetoothDevices() {
2178 return bluetooth_scanning_sessions_count_ > 0;
2179}
2180
Lucas Furukawa Gadani4b4eed02019-06-04 23:12:042181bool WebContentsImpl::IsConnectedToSerialPort() {
Reilly Grant5e7c79b22019-04-09 17:26:202182 return serial_active_frame_count_ > 0;
2183}
2184
Matt Reynoldse8c6c1f2019-11-02 09:53:532185bool WebContentsImpl::IsConnectedToHidDevice() {
2186 return hid_active_frame_count_ > 0;
2187}
2188
Matt Reynoldsed00ca7e72022-08-18 20:56:202189bool WebContentsImpl::IsConnectedToUsbDevice() {
2190 return usb_active_frame_count_ > 0;
2191}
2192
Austin Sullivanafefb722021-01-14 01:26:392193bool WebContentsImpl::HasFileSystemAccessHandles() {
2194 return file_system_access_handle_count_ > 0;
Marijn Kruisselbrink29051042019-08-06 22:56:552195}
Marijn Kruisselbrinkf1714aa22019-07-02 03:45:332196
Lucas Furukawa Gadanie1c5dfda2018-11-29 17:57:412197bool WebContentsImpl::HasPictureInPictureVideo() {
sawtellea7333a82018-05-31 02:36:362198 return has_picture_in_picture_video_;
2199}
2200
Klaus Weidnerd8219432022-02-08 21:50:592201bool WebContentsImpl::HasPictureInPictureDocument() {
2202 return has_picture_in_picture_document_;
2203}
2204
2205void WebContentsImpl::SetHasPictureInPictureCommon(
2206 bool has_picture_in_picture) {
2207 NotifyNavigationStateChanged(INVALIDATE_TYPE_TAB);
2208 observers_.NotifyObservers(&WebContentsObserver::MediaPictureInPictureChanged,
2209 has_picture_in_picture);
Fred Shiheb7d2ff2023-01-18 02:31:462210 if (has_picture_in_picture) {
2211 pip_capture_handle_ = IncrementCapturerCount({}, true, false);
2212 } else {
2213 pip_capture_handle_.RunAndReset();
2214 }
Klaus Weidnerd8219432022-02-08 21:50:592215
2216 // Picture-in-picture state can affect how we notify visibility for non-
2217 // visible pages.
2218 if (visibility_ != Visibility::VISIBLE)
2219 UpdateVisibilityAndNotifyPageAndView(visibility_);
2220}
2221
sawtellea7333a82018-05-31 02:36:362222void WebContentsImpl::SetHasPictureInPictureVideo(
2223 bool has_picture_in_picture_video) {
Alexander Timin5fdeff22020-09-08 09:20:372224 OPTIONAL_TRACE_EVENT1("content",
2225 "WebContentsImpl::SetHasPictureInPictureVideo",
2226 "has_pip_video", has_picture_in_picture_video);
sawtellea7333a82018-05-31 02:36:362227 // If status of |this| is already accurate, there is no need to update.
2228 if (has_picture_in_picture_video == has_picture_in_picture_video_)
2229 return;
2230 has_picture_in_picture_video_ = has_picture_in_picture_video;
Klaus Weidnerd8219432022-02-08 21:50:592231 SetHasPictureInPictureCommon(has_picture_in_picture_video);
2232}
Frank Liberatoe5ae7142021-10-06 15:49:402233
Klaus Weidnerd8219432022-02-08 21:50:592234void WebContentsImpl::SetHasPictureInPictureDocument(
2235 bool has_picture_in_picture_document) {
2236 OPTIONAL_TRACE_EVENT1("content",
2237 "WebContentsImpl::SetHasPictureInPictureDocument",
2238 "has_pip_document", has_picture_in_picture_document);
2239 // If status of |this| is already accurate, there is no need to update.
2240 if (has_picture_in_picture_document == has_picture_in_picture_document_)
2241 return;
2242 has_picture_in_picture_document_ = has_picture_in_picture_document;
2243 SetHasPictureInPictureCommon(has_picture_in_picture_document);
sawtellea7333a82018-05-31 02:36:362244}
2245
Lucas Furukawa Gadanie1c5dfda2018-11-29 17:57:412246bool WebContentsImpl::IsCrashed() {
Khushalc5eaf222021-06-30 20:15:482247 switch (primary_main_frame_process_status_) {
Dominic Mazzoni73a48322018-05-25 18:14:072248 case base::TERMINATION_STATUS_PROCESS_CRASHED:
2249 case base::TERMINATION_STATUS_ABNORMAL_TERMINATION:
2250 case base::TERMINATION_STATUS_PROCESS_WAS_KILLED:
2251 case base::TERMINATION_STATUS_OOM:
2252 case base::TERMINATION_STATUS_LAUNCH_FAILED:
Xiaohan Wang24ec9342022-01-15 17:34:222253#if BUILDFLAG(IS_CHROMEOS)
Dominic Mazzoni73a48322018-05-25 18:14:072254 case base::TERMINATION_STATUS_PROCESS_WAS_KILLED_BY_OOM:
oshima620225722015-06-04 19:45:272255#endif
Xiaohan Wang24ec9342022-01-15 17:34:222256#if BUILDFLAG(IS_ANDROID)
Dominic Mazzoni73a48322018-05-25 18:14:072257 case base::TERMINATION_STATUS_OOM_PROTECTED:
2258#endif
Xiaohan Wang24ec9342022-01-15 17:34:222259#if BUILDFLAG(IS_WIN)
Will Harris07925d12019-10-31 03:03:052260 case base::TERMINATION_STATUS_INTEGRITY_FAILURE:
2261#endif
Dominic Mazzoni73a48322018-05-25 18:14:072262 return true;
2263 case base::TERMINATION_STATUS_NORMAL_TERMINATION:
2264 case base::TERMINATION_STATUS_STILL_RUNNING:
2265 return false;
2266 case base::TERMINATION_STATUS_MAX_ENUM:
2267 NOTREACHED();
2268 return false;
2269 }
2270
2271 NOTREACHED();
2272 return false;
[email protected]3c9e1872010-11-18 16:17:492273}
2274
Khushalc5eaf222021-06-30 20:15:482275void WebContentsImpl::SetPrimaryMainFrameProcessStatus(
2276 base::TerminationStatus status,
2277 int error_code) {
2278 OPTIONAL_TRACE_EVENT2("content",
2279 "WebContentsImpl::SetPrimaryMainFrameProcessStatus",
danakjcdab6ed52021-02-10 23:44:132280 "status", static_cast<int>(status), "old_status",
Khushalc5eaf222021-06-30 20:15:482281 static_cast<int>(primary_main_frame_process_status_));
2282 if (status == primary_main_frame_process_status_)
[email protected]d5f942ba2008-09-26 19:30:342283 return;
2284
Khushalc5eaf222021-06-30 20:15:482285 primary_main_frame_process_status_ = status;
2286 primary_main_frame_process_error_code_ = error_code;
[email protected]8ff00d72012-10-23 19:12:212287 NotifyNavigationStateChanged(INVALIDATE_TYPE_TAB);
[email protected]d5f942ba2008-09-26 19:30:342288}
2289
Lucas Furukawa Gadanie1c5dfda2018-11-29 17:57:412290base::TerminationStatus WebContentsImpl::GetCrashedStatus() {
Khushalc5eaf222021-06-30 20:15:482291 return primary_main_frame_process_status_;
[email protected]be1f56ab2011-12-22 06:55:312292}
2293
Lucas Furukawa Gadanie1c5dfda2018-11-29 17:57:412294int WebContentsImpl::GetCrashedErrorCode() {
Khushalc5eaf222021-06-30 20:15:482295 return primary_main_frame_process_error_code_;
afakhry98241832016-03-11 19:27:472296}
2297
Lucas Furukawa Gadanie1c5dfda2018-11-29 17:57:412298bool WebContentsImpl::IsBeingDestroyed() {
[email protected]be1f56ab2011-12-22 06:55:312299 return is_being_destroyed_;
2300}
2301
[email protected]7f924832014-08-09 05:57:222302void WebContentsImpl::NotifyNavigationStateChanged(
2303 InvalidateTypes changed_flags) {
Alexander Timin5fdeff22020-09-08 09:20:372304 TRACE_EVENT1("content,navigation",
2305 "WebContentsImpl::NotifyNavigationStateChanged", "changed_flags",
2306 static_cast<int>(changed_flags));
dalecurtis88c240072015-12-09 02:11:182307 // Notify the media observer of potential audibility changes.
Collin Bakeraf540cf2019-09-20 20:54:162308 if (changed_flags & INVALIDATE_TYPE_AUDIO) {
mlamouri44e4ef42016-01-20 18:42:272309 media_web_contents_observer_->MaybeUpdateAudibleState();
dalecurtisbc6572e12014-09-12 19:22:302310 }
2311
[email protected]d5f942ba2008-09-26 19:30:342312 if (delegate_)
2313 delegate_->NavigationStateChanged(this, changed_flags);
wjmaclean1dabf3e32016-05-13 23:34:442314
2315 if (GetOuterWebContents())
2316 GetOuterWebContents()->NotifyNavigationStateChanged(changed_flags);
[email protected]d5f942ba2008-09-26 19:30:342317}
2318
David Black9cca3592019-11-06 23:02:222319void WebContentsImpl::OnVerticalScrollDirectionChanged(
2320 viz::VerticalScrollDirection scroll_direction) {
Alexander Timin5fdeff22020-09-08 09:20:372321 OPTIONAL_TRACE_EVENT1("content",
2322 "WebContentsImpl::OnVerticalScrollDirectionChanged",
2323 "scroll_direction", static_cast<int>(scroll_direction));
Andrew Grievee19cd93e2021-01-22 05:43:062324 observers_.NotifyObservers(
2325 &WebContentsObserver::DidChangeVerticalScrollDirection, scroll_direction);
David Black9cca3592019-11-06 23:02:222326}
2327
David Bokan7ec5ac922022-11-29 03:31:312328int WebContentsImpl::GetVirtualKeyboardResizeHeight() {
2329 // Only consider a web contents to be insetted by the virtual keyboard if it
2330 // is in the currently active tab.
2331 if (GetVisibility() != Visibility::VISIBLE)
2332 return 0;
2333
2334 // The only mode where the virtual keyboard causes the web contents to be
2335 // resized is kResizesContent.
2336 if (GetPrimaryPage().virtual_keyboard_mode() !=
2337 ui::mojom::VirtualKeyboardMode::kResizesContent) {
2338 return 0;
2339 }
2340
2341 // The virtual keyboard never resizes content when fullscreened.
2342 if (IsFullscreen())
2343 return 0;
2344
2345 return GetDelegate() ? GetDelegate()->GetVirtualKeyboardHeight(this) : 0;
2346}
2347
Chris Hamiltondf0d72cd2018-05-29 16:23:532348void WebContentsImpl::OnAudioStateChanged() {
2349 // This notification can come from any embedded contents or from this
2350 // WebContents' stream monitor. Aggregate these signals to get the actual
2351 // state.
Jeremy Roman03ce13ce2020-05-29 22:16:572352 //
2353 // Note that guests may not be attached as inner contents, and so may need to
Peter Kastingd5685942022-09-02 17:52:172354 // be checked separately. This intentionally does not do a recursive search,
2355 // since the state is aggregated in each inner WebContents and reflects that
2356 // whole subtree.
Chris Hamiltondf0d72cd2018-05-29 16:23:532357 bool is_currently_audible =
2358 audio_stream_monitor_.IsCurrentlyAudible() ||
2359 (browser_plugin_embedder_ &&
Jeremy Roman03ce13ce2020-05-29 22:16:572360 browser_plugin_embedder_->AreAnyGuestsCurrentlyAudible()) ||
Peter Kastingd5685942022-09-02 17:52:172361 base::ranges::any_of(GetInnerWebContents(),
2362 [](WebContents* inner_contents) {
2363 return inner_contents->IsCurrentlyAudible();
2364 });
Alexander Timin5fdeff22020-09-08 09:20:372365 OPTIONAL_TRACE_EVENT2("content", "WebContentsImpl::OnAudioStateChanged",
2366 "is_currently_audible", is_currently_audible,
2367 "was_audible", is_currently_audible_);
Chris Hamiltondf0d72cd2018-05-29 16:23:532368 if (is_currently_audible == is_currently_audible_)
2369 return;
2370
2371 // Update internal state.
2372 is_currently_audible_ = is_currently_audible;
2373 was_ever_audible_ = was_ever_audible_ || is_currently_audible_;
2374
Eric Secklerab20ea22021-02-08 11:39:262375 audible_power_mode_voter_->VoteFor(is_currently_audible_
2376 ? power_scheduler::PowerMode::kAudible
2377 : power_scheduler::PowerMode::kIdle);
2378
Gyuyoung Kim877e86d2020-07-21 04:01:022379 ExecutePageBroadcastMethod(base::BindRepeating(
2380 [](bool is_currently_audible, RenderViewHostImpl* rvh) {
2381 if (auto& broadcast = rvh->GetAssociatedPageBroadcast())
2382 broadcast->AudioStateChanged(is_currently_audible);
2383 },
2384 is_currently_audible_));
altimind8bd26c2016-11-04 11:44:542385
altiminec87fd1f2016-11-17 20:22:492386 // Notification for UI updates in response to the changed audio state.
Collin Bakeraf540cf2019-09-20 20:54:162387 NotifyNavigationStateChanged(INVALIDATE_TYPE_AUDIO);
Jan Rucka442c83f2017-08-08 13:27:542388
Chris Hamiltondf0d72cd2018-05-29 16:23:532389 // Ensure that audio state changes propagate from innermost to outermost
2390 // WebContents.
2391 if (GetOuterWebContents())
2392 GetOuterWebContents()->OnAudioStateChanged();
Tommy Steimel18360512017-11-01 00:38:192393
Andrew Grievee19cd93e2021-01-22 05:43:062394 observers_.NotifyObservers(&WebContentsObserver::OnAudioStateChanged,
2395 is_currently_audible_);
altimind8bd26c2016-11-04 11:44:542396}
2397
Lucas Furukawa Gadanie1c5dfda2018-11-29 17:57:412398base::TimeTicks WebContentsImpl::GetLastActiveTime() {
[email protected]9a890452014-02-13 22:21:022399 return last_active_time_;
[email protected]3e324142012-06-25 18:26:332400}
2401
[email protected]9e2e4632012-07-27 16:38:412402void WebContentsImpl::WasShown() {
Alexander Timin5fdeff22020-09-08 09:20:372403 TRACE_EVENT0("content", "WebContentsImpl::WasShown");
Collin Baker989e0882019-11-01 01:27:172404 UpdateVisibilityAndNotifyPageAndView(Visibility::VISIBLE);
[email protected]be1f56ab2011-12-22 06:55:312405}
2406
[email protected]b172aee2012-04-10 17:05:262407void WebContentsImpl::WasHidden() {
Alexander Timin5fdeff22020-09-08 09:20:372408 TRACE_EVENT0("content", "WebContentsImpl::WasHidden");
Collin Baker989e0882019-11-01 01:27:172409 UpdateVisibilityAndNotifyPageAndView(Visibility::HIDDEN);
[email protected]375fa1b2012-05-22 22:05:372410}
2411
Evan Stade6decc972022-10-24 19:42:182412bool WebContentsImpl::HasRecentInteraction() {
2413 if (last_interaction_time_.is_null())
2414 return false;
2415
Peter Kastinge5a38ed2021-10-02 03:06:352416 static constexpr base::TimeDelta kMaxInterval = base::Seconds(5);
Evan Stade6decc972022-10-24 19:42:182417 base::TimeDelta delta = ui::EventTimeForNow() - last_interaction_time_;
Daniel Cheng90196c82018-04-25 21:49:142418 // Note: the expectation is that the caller is typically expecting an input
2419 // event, e.g. validating that a WebUI message that requires a gesture is
Daniel Chenge81030b32019-07-17 20:20:232420 // actually attached to a gesture.
Daniel Cheng90196c82018-04-25 21:49:142421 return delta <= kMaxInterval;
2422}
2423
Avi Drissman738ea192018-08-29 20:24:162424void WebContentsImpl::SetIgnoreInputEvents(bool ignore_input_events) {
Alexander Timin5fdeff22020-09-08 09:20:372425 OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::SetIgnoreInputEvents",
2426 "ignore_input_events", ignore_input_events);
Avi Drissman738ea192018-08-29 20:24:162427 ignore_input_events_ = ignore_input_events;
2428}
2429
Sebastien Marchandc38e5ae2021-02-18 20:28:132430bool WebContentsImpl::HasActiveEffectivelyFullscreenVideo() {
2431 return IsFullscreen() &&
2432 media_web_contents_observer_->HasActiveEffectivelyFullscreenVideo();
2433}
2434
Alexander Timinbebb2002021-04-20 15:42:242435void WebContentsImpl::WriteIntoTrace(perfetto::TracedValue context) {
Alexander Timine9f413e82021-03-12 14:06:442436 auto dict = std::move(context).WriteDictionary();
Carlos Caballerob65b6e3a2021-11-15 10:09:002437 dict.Add("root_frame_tree_node_id",
2438 primary_frame_tree_.root()->frame_tree_node_id());
Alexander Timine9f413e82021-03-12 14:06:442439}
2440
Lukasz Anforowicz2c1573a2021-09-21 18:58:182441const base::Location& WebContentsImpl::GetCreatorLocation() {
2442 return creator_location_;
2443}
2444
Tommy Steimel57eafde2023-01-27 17:33:242445const absl::optional<blink::mojom::PictureInPictureWindowOptions>&
2446WebContentsImpl::GetPictureInPictureOptions() const {
2447 return picture_in_picture_options_;
Tommy Steimel991916c42022-06-24 20:59:572448}
2449
Xiaohan Wang24ec9342022-01-15 17:34:222450#if BUILDFLAG(IS_ANDROID)
Khushalb8aabcf42021-06-22 11:55:032451void WebContentsImpl::SetPrimaryMainFrameImportance(
Bo Liu16dd7b8322018-05-02 21:19:502452 ChildProcessImportance importance) {
Alexander Timin5fdeff22020-09-08 09:20:372453 OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::SetMainFrameImportance",
2454 "importance", static_cast<int>(importance));
Dave Tapuska327c06c92022-06-13 20:31:512455 GetPrimaryMainFrame()->GetRenderWidgetHost()->SetImportance(importance);
Bo Liu7c6779e92017-08-16 02:02:282456}
Bo Liu168c8642017-08-28 18:26:022457#endif
Bo Liu7c6779e92017-08-16 02:02:282458
ccameron8807c38f2015-01-17 00:29:192459void WebContentsImpl::WasOccluded() {
Alexander Timin5fdeff22020-09-08 09:20:372460 TRACE_EVENT0("content", "WebContentsImpl::WasOccluded");
Collin Baker989e0882019-11-01 01:27:172461 UpdateVisibilityAndNotifyPageAndView(Visibility::OCCLUDED);
ccameron8807c38f2015-01-17 00:29:192462}
2463
Lucas Furukawa Gadanie1c5dfda2018-11-29 17:57:412464Visibility WebContentsImpl::GetVisibility() {
Francois Doraye6161152018-03-27 22:05:372465 return visibility_;
Francois Dorayfe4a1772018-02-17 04:17:092466}
2467
Rakina Zata Amni26e8d8a2020-08-05 06:06:062468bool WebContentsImpl::NeedToFireBeforeUnloadOrUnloadEvents() {
Alexander Timinc7bee322020-05-19 17:54:342469 if (!notify_disconnection_)
Alex Moshchuk6fcaca752018-07-14 02:13:592470 return false;
2471
Alex Moshchuke558aba2023-01-13 07:42:022472 // Don't fire if the main frame indicates that beforeunload and unload have
2473 // already executed (e.g., after receiving a ClosePage ACK) or should be
2474 // ignored.
2475 if (GetPrimaryMainFrame()->IsPageReadyToBeClosed()) {
Alex Moshchuk6fcaca752018-07-14 02:13:592476 return false;
Alex Moshchuke558aba2023-01-13 07:42:022477 }
Alex Moshchuk6fcaca752018-07-14 02:13:592478
Alex Moshchukc78dbc722019-10-31 20:00:502479 // Check whether any frame in the frame tree needs to run beforeunload or
Rakina Zata Amni26e8d8a2020-08-05 06:06:062480 // unload-time event handlers.
Carlos Caballerob65b6e3a2021-11-15 10:09:002481 for (FrameTreeNode* node : primary_frame_tree_.Nodes()) {
Alex Moshchukc78dbc722019-10-31 20:00:502482 RenderFrameHostImpl* rfh = node->current_frame_host();
2483
Rakina Zata Amni26e8d8a2020-08-05 06:06:062484 // No need to run beforeunload/unload-time events if the RenderFrame isn't
2485 // live.
Alex Moshchukc78dbc722019-10-31 20:00:502486 if (!rfh->IsRenderFrameLive())
2487 continue;
Rakina Zata Amni26e8d8a2020-08-05 06:06:062488 bool should_run_before_unload_handler =
Dave Tapuska97d22ab2019-12-03 17:56:362489 rfh->GetSuddenTerminationDisablerState(
Rakina Zata Amni26e8d8a2020-08-05 06:06:062490 blink::mojom::SuddenTerminationDisablerType::kBeforeUnloadHandler);
2491 bool should_run_unload_handler = rfh->GetSuddenTerminationDisablerState(
2492 blink::mojom::SuddenTerminationDisablerType::kUnloadHandler);
2493 bool should_run_page_hide_handler = rfh->GetSuddenTerminationDisablerState(
2494 blink::mojom::SuddenTerminationDisablerType::kPageHideHandler);
2495 auto* rvh = static_cast<RenderViewHostImpl*>(rfh->GetRenderViewHost());
2496 // If the tab is already hidden, we should not run visibilitychange
2497 // handlers.
2498 bool is_page_visible = rvh->GetPageLifecycleStateManager()
2499 ->CalculatePageLifecycleState()
2500 ->visibility == PageVisibilityState::kVisible;
2501
2502 bool should_run_visibility_change_handler =
2503 is_page_visible && rfh->GetSuddenTerminationDisablerState(
2504 blink::mojom::SuddenTerminationDisablerType::
2505 kVisibilityChangeHandler);
2506 if (should_run_before_unload_handler || should_run_unload_handler ||
2507 should_run_page_hide_handler || should_run_visibility_change_handler) {
Alex Moshchukc78dbc722019-10-31 20:00:502508 return true;
2509 }
Aditya Keerthi34f37e62019-03-08 15:54:532510 }
Alex Moshchuk6fcaca752018-07-14 02:13:592511
Alex Moshchukc78dbc722019-10-31 20:00:502512 return false;
[email protected]be1f56ab2011-12-22 06:55:312513}
2514
Chris Hamilton3b3e315d2018-09-19 13:16:212515void WebContentsImpl::DispatchBeforeUnload(bool auto_cancel) {
Alexander Timin5fdeff22020-09-08 09:20:372516 OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::DispatchBeforeUnload",
2517 "auto_cancel", auto_cancel);
Chris Hamilton3b3e315d2018-09-19 13:16:212518 auto before_unload_type =
2519 auto_cancel ? RenderFrameHostImpl::BeforeUnloadType::DISCARD
2520 : RenderFrameHostImpl::BeforeUnloadType::TAB_CLOSE;
Dave Tapuska327c06c92022-06-13 20:31:512521 GetPrimaryMainFrame()->DispatchBeforeUnload(before_unload_type, false);
[email protected]1c3f80bd2014-04-08 23:02:062522}
2523
W. James MacLean2539adb32019-12-13 00:40:442524bool WebContentsImpl::IsInnerWebContentsForGuest() {
Charlie Reis3d189602021-04-27 21:24:472525 return IsGuest();
W. James MacLean2539adb32019-12-13 00:40:442526}
2527
Lucas Furukawa Gadani6e5b4f32019-03-02 04:18:502528void WebContentsImpl::AttachInnerWebContents(
2529 std::unique_ptr<WebContents> inner_web_contents,
W. James MacLean62883982019-11-12 20:39:002530 RenderFrameHost* render_frame_host,
Dave Tapuska82b54012022-07-15 23:26:102531 mojo::PendingAssociatedRemote<blink::mojom::RemoteFrame> remote_frame,
2532 mojo::PendingAssociatedReceiver<blink::mojom::RemoteFrameHost>
2533 remote_frame_host_receiver,
W. James MacLean62883982019-11-12 20:39:002534 bool is_full_page) {
Alexander Timin5fdeff22020-09-08 09:20:372535 OPTIONAL_TRACE_EVENT2("content", "WebContentsImpl::AttachInnerWebContents",
Alexander Timinfb70a2d2021-02-08 03:19:072536 "inner_web_contents",
2537 static_cast<void*>(inner_web_contents.get()),
Alexander Timin5fdeff22020-09-08 09:20:372538 "is_full_page", is_full_page);
Lucas Furukawa Gadani6e5b4f32019-03-02 04:18:502539 WebContentsImpl* inner_web_contents_impl =
2540 static_cast<WebContentsImpl*>(inner_web_contents.get());
2541 DCHECK(!inner_web_contents_impl->node_.outer_web_contents());
2542 auto* render_frame_host_impl =
2543 static_cast<RenderFrameHostImpl*>(render_frame_host);
Matt Falkenhagen7b71b9f12021-08-12 01:32:432544 DCHECK_EQ(this, WebContents::FromRenderFrameHost(render_frame_host_impl));
Kevin McNee490c04be2021-06-04 22:52:552545 DCHECK(render_frame_host_impl->GetParent());
Lucas Furukawa Gadani105de1e812018-05-31 19:38:392546
Lucas Furukawa Gadani6e5b4f32019-03-02 04:18:502547 RenderFrameHostManager* inner_render_manager =
2548 inner_web_contents_impl->GetRenderManager();
2549 RenderFrameHostImpl* inner_main_frame =
2550 inner_render_manager->current_frame_host();
2551 RenderViewHostImpl* inner_render_view_host =
Alex Moshchuk2e470ea2021-02-03 06:46:342552 inner_main_frame->render_view_host();
Lucas Furukawa Gadani6e5b4f32019-03-02 04:18:502553 auto* outer_render_manager =
2554 render_frame_host_impl->frame_tree_node()->render_manager();
lfg91a79e12016-04-01 23:52:192555
Dominic Farolino377edb302021-07-29 05:57:182556 // Make |render_frame_host_impl| an outer delegate frame.
2557 render_frame_host_impl->set_inner_tree_main_frame_tree_node_id(
2558 inner_main_frame->frame_tree_node()->frame_tree_node_id());
2559
Lucas Furukawa Gadani105de1e812018-05-31 19:38:392560 // When attaching a WebContents as an inner WebContents, we need to replace
2561 // the Webcontents' view with a WebContentsViewChildFrame.
Fergal Daly55b6d722020-09-11 07:56:332562 inner_web_contents_impl->view_ = std::make_unique<WebContentsViewChildFrame>(
Lucas Furukawa Gadani6e5b4f32019-03-02 04:18:502563 inner_web_contents_impl,
2564 GetContentClient()->browser()->GetWebContentsViewDelegate(
2565 inner_web_contents_impl),
Fergal Daly55b6d722020-09-11 07:56:332566 &inner_web_contents_impl->render_view_host_delegate_view_);
Kevin McNee490c04be2021-06-04 22:52:552567 // On platforms where destroying the WebContents' view does not also destroy
2568 // the platform RenderWidgetHostView, we need to destroy it if it exists.
2569 // TODO(mcnee): Should all platforms' WebContentsView destroy the platform
2570 // RWHV?
2571 if (RenderWidgetHostViewBase* prev_rwhv =
2572 inner_render_manager->GetRenderWidgetHostView()) {
2573 if (!prev_rwhv->IsRenderWidgetHostViewChildFrame()) {
2574 prev_rwhv->Destroy();
2575 }
2576 }
Lucas Furukawa Gadani105de1e812018-05-31 19:38:392577
lfg91a79e12016-04-01 23:52:192578 // When the WebContents being initialized has an opener, the browser side
2579 // Render{View,Frame}Host must be initialized and the RenderWidgetHostView
2580 // created. This is needed because the usual initialization happens during
2581 // the first navigation, but when attaching a new window we don't navigate
2582 // before attaching. If the browser side is already initialized, the calls
2583 // below will just early return.
Sharon Yang65e78f2d2022-02-24 19:58:362584 inner_render_manager->InitRenderView(
2585 inner_main_frame->GetSiteInstance()->group(), inner_render_view_host,
2586 nullptr);
Lucas Furukawa Gadani6e5b4f32019-03-02 04:18:502587 if (!inner_render_manager->GetRenderWidgetHostView()) {
2588 inner_web_contents_impl->CreateRenderWidgetHostViewForRenderManager(
2589 inner_render_view_host);
2590 }
lfg91a79e12016-04-01 23:52:192591
K. Moon97def7d2022-02-01 15:56:022592 inner_web_contents_impl->RecursivelyUnregisterRenderWidgetHostViews();
Adithya Srinivasane6e7f842019-12-16 18:41:362593
lazyboy6ec48b2a2015-06-29 15:18:142594 // Create a link to our outer WebContents.
Lucas Furukawa Gadani6e5b4f32019-03-02 04:18:502595 node_.AttachInnerWebContents(std::move(inner_web_contents),
2596 render_frame_host_impl);
lazyboy6ec48b2a2015-06-29 15:18:142597
lazyboy6ec48b2a2015-06-29 15:18:142598 // Create a proxy in top-level RenderFrameHostManager, pointing to the
2599 // SiteInstance of the outer WebContents. The proxy will be used to send
2600 // postMessage to the inner WebContents.
Harkiran Bolariae45272d2022-04-12 08:05:012601 auto* proxy =
2602 inner_main_frame->browsing_context_state()->CreateOuterDelegateProxy(
2603 render_frame_host_impl->GetSiteInstance(),
Dave Tapuska144570102022-08-02 19:28:272604 inner_main_frame->frame_tree_node(), blink::RemoteFrameToken());
Dave Tapuska82b54012022-07-15 23:26:102605 if (remote_frame && remote_frame_host_receiver) {
2606 proxy->BindRemoteFrameInterfaces(std::move(remote_frame),
2607 std::move(remote_frame_host_receiver));
2608 }
lazyboy6ec48b2a2015-06-29 15:18:142609
Lucas Furukawa Gadani99125822019-01-03 15:41:492610 // When attaching a GuestView as an inner WebContents, there should already be
2611 // a live RenderFrame, which has to be swapped. When attaching a portal, there
2612 // will not be a live RenderFrame before creating the proxy.
Lucas Furukawa Gadani6e5b4f32019-03-02 04:18:502613 if (render_frame_host_impl->IsRenderFrameLive()) {
2614 inner_render_manager->SwapOuterDelegateFrame(render_frame_host_impl, proxy);
Lucas Furukawa Gadani99125822019-01-03 15:41:492615
Lucas Furukawa Gadani6e5b4f32019-03-02 04:18:502616 inner_web_contents_impl->ReattachToOuterWebContentsFrame();
Lucas Furukawa Gadani99125822019-01-03 15:41:492617 }
ekaramadadd882292016-06-08 15:22:562618
Carlos Caballerob65b6e3a2021-11-15 10:09:002619 if (primary_frame_tree_.GetFocusedFrame() ==
Lucas Furukawa Gadani6e5b4f32019-03-02 04:18:502620 render_frame_host_impl->frame_tree_node()) {
2621 inner_web_contents_impl->SetFocusedFrame(
Carlos Caballerob65b6e3a2021-11-15 10:09:002622 inner_web_contents_impl->primary_frame_tree_.root(),
Sharon Yangefe52632022-03-08 23:06:062623 render_frame_host_impl->GetSiteInstance()->group());
avallee7529b2a2017-04-26 11:37:512624 }
Lucas Furukawa Gadani6e5b4f32019-03-02 04:18:502625 outer_render_manager->set_attach_complete();
W. James MacLean62883982019-11-12 20:39:002626
2627 // If the inner WebContents is full frame, give it focus.
2628 if (is_full_page) {
2629 // There should only ever be one inner WebContents when |is_full_page| is
2630 // true, and it is the one we just attached.
2631 DCHECK_EQ(1u, node_.GetInnerWebContents().size());
2632 inner_web_contents_impl->SetAsFocusedWebContentsIfNecessary();
2633 }
Chris Hamilton16b5d1d2020-06-04 00:08:122634
Andrew Grievee19cd93e2021-01-22 05:43:062635 observers_.NotifyObservers(&WebContentsObserver::InnerWebContentsAttached,
2636 inner_web_contents_impl, render_frame_host,
2637 is_full_page);
Mario Sanchez Prada989aeb7a2020-10-13 09:42:562638
2639 // Make sure that the inner web contents and its outer delegate get properly
2640 // linked via the embedding token now that inner web contents are attached.
2641 inner_main_frame->PropagateEmbeddingTokenToParentFrame();
lazyboy6ec48b2a2015-06-29 15:18:142642}
2643
Lucas Furukawa Gadani99125822019-01-03 15:41:492644std::unique_ptr<WebContents> WebContentsImpl::DetachFromOuterWebContents() {
Alexander Timin5fdeff22020-09-08 09:20:372645 OPTIONAL_TRACE_EVENT0("content",
2646 "WebContentsImpl::DetachFromOuterWebContents");
Chris Hamilton16b5d1d2020-06-04 00:08:122647 auto* outer_web_contents = GetOuterWebContents();
2648 DCHECK(outer_web_contents);
Dave Tapuska327c06c92022-06-13 20:31:512649 GetPrimaryMainFrame()
Dave Tapuska5dd5f9822021-09-10 20:57:152650 ->GetParentOrOuterDocumentOrEmbedder()
Dominic Farolino377edb302021-07-29 05:57:182651 ->set_inner_tree_main_frame_tree_node_id(
2652 FrameTreeNode::kFrameTreeNodeInvalidId);
Chris Hamilton16b5d1d2020-06-04 00:08:122653
K. Moon97def7d2022-02-01 15:56:022654 RecursivelyUnregisterRenderWidgetHostViews();
Lucas Gadanid29952582020-06-09 21:24:002655
2656 // Each RenderViewHost has a RenderWidgetHost which can have a
2657 // RenderWidgetHostView, and it needs to be re-created with the appropriate
2658 // platform view. It is important to re-create all child views, not only the
2659 // current one, since the view can be swapped due to a cross-origin
2660 // navigation.
2661 std::set<RenderViewHostImpl*> render_view_hosts;
Sharon Yanged884542023-02-02 17:33:442662 primary_frame_tree_.ForEachRenderViewHost([&render_view_hosts](
2663 RenderViewHostImpl* rvh) {
2664 if (rvh->GetWidget() && rvh->GetWidget()->GetView()) {
2665 DCHECK(rvh->GetWidget()->GetView()->IsRenderWidgetHostViewChildFrame());
2666 render_view_hosts.insert(rvh);
Kevin McNee6471a702020-01-27 18:23:072667 }
Sharon Yanged884542023-02-02 17:33:442668 });
Lucas Gadanid29952582020-06-09 21:24:002669
2670 for (auto* render_view_host : render_view_hosts)
2671 render_view_host->GetWidget()->GetView()->Destroy();
2672
Harkiran Bolariae45272d2022-04-12 08:05:012673 GetRenderManager()
2674 ->current_frame_host()
2675 ->browsing_context_state()
2676 ->DeleteOuterDelegateProxy(node_.OuterContentsFrameTreeNode()
2677 ->current_frame_host()
2678 ->GetSiteInstance()
2679 ->group());
Avi Drissman0d0908ded2022-04-28 05:39:392680 view_ = CreateWebContentsView(
Lucas Furukawa Gadani99125822019-01-03 15:41:492681 this, GetContentClient()->browser()->GetWebContentsViewDelegate(this),
Avi Drissman0d0908ded2022-04-28 05:39:392682 &render_view_host_delegate_view_);
danakjfc5184932019-09-12 18:08:322683 view_->CreateView(nullptr);
Lucas Furukawa Gadani99125822019-01-03 15:41:492684 std::unique_ptr<WebContents> web_contents =
2685 node_.DisconnectFromOuterWebContents();
2686 DCHECK_EQ(web_contents.get(), this);
Carlos Caballero6a99dac2021-11-03 10:41:172687 node_.SetFocusedFrameTree(&GetPrimaryFrameTree());
Lucas Gadanid29952582020-06-09 21:24:002688
2689 for (auto* render_view_host : render_view_hosts)
2690 CreateRenderWidgetHostViewForRenderManager(render_view_host);
2691
K. Moon97def7d2022-02-01 15:56:022692 RecursivelyRegisterRenderWidgetHostViews();
Dave Tapuska327c06c92022-06-13 20:31:512693 GetPrimaryMainFrame()->UpdateAXTreeData();
Chris Hamilton16b5d1d2020-06-04 00:08:122694
2695 // Invoke on the *outer* web contents observers for symmetry.
Andrew Grievee19cd93e2021-01-22 05:43:062696 outer_web_contents->observers_.NotifyObservers(
2697 &WebContentsObserver::InnerWebContentsDetached, this);
Chris Hamilton16b5d1d2020-06-04 00:08:122698
Lucas Furukawa Gadani99125822019-01-03 15:41:492699 return web_contents;
2700}
2701
K. Moon97def7d2022-02-01 15:56:022702void WebContentsImpl::RecursivelyRegisterRenderWidgetHostViews() {
2703 OPTIONAL_TRACE_EVENT0(
2704 "content", "WebContentsImpl::RecursivelyRegisterRenderWidgetHostViews");
2705
2706 auto* text_input_manager = GetTextInputManager();
Adithya Srinivasane6e7f842019-12-16 18:41:362707 for (auto* view : GetRenderWidgetHostViewsInWebContentsTree()) {
K. Moon97def7d2022-02-01 15:56:022708 if (text_input_manager) {
2709 // Use RenderWidgetHostView::GetTextInputManager() for its side effects,
2710 // rather than registering the view directly; the view caches the
2711 // TextInputManager.
2712 //
2713 // TODO(crbug.com/1292036): This probably could be made more symmetrical
2714 // with unregistration. Getting rid of lazy registration might also allow
2715 // eliminating some special cases in TextInputManager.
2716 auto* text_input_manager_for_view = view->GetTextInputManager();
2717 DCHECK_EQ(text_input_manager, text_input_manager_for_view);
2718 }
2719
Kevin McNeeef1e9362021-06-08 21:31:522720 if (view->IsRenderWidgetHostViewChildFrame())
Adithya Srinivasane6e7f842019-12-16 18:41:362721 static_cast<RenderWidgetHostViewChildFrame*>(view)->RegisterFrameSinkId();
2722 }
2723}
W. James MacLean2dc75ed42019-03-06 14:31:092724
K. Moon97def7d2022-02-01 15:56:022725void WebContentsImpl::RecursivelyUnregisterRenderWidgetHostViews() {
2726 OPTIONAL_TRACE_EVENT0(
2727 "content", "WebContentsImpl::RecursivelyUnregisterRenderWidgetHostViews");
2728
2729 auto* text_input_manager = GetTextInputManager();
Adithya Srinivasane6e7f842019-12-16 18:41:362730 for (auto* view : GetRenderWidgetHostViewsInWebContentsTree()) {
K. Moon97def7d2022-02-01 15:56:022731 if (text_input_manager) {
2732 // The RenderWidgetHostView will drop the cached TextInputManager itself.
2733 text_input_manager->Unregister(view);
2734 }
2735
Kevin McNeeef1e9362021-06-08 21:31:522736 if (view->IsRenderWidgetHostViewChildFrame()) {
Adithya Srinivasane6e7f842019-12-16 18:41:362737 static_cast<RenderWidgetHostViewChildFrame*>(view)
2738 ->UnregisterFrameSinkId();
2739 }
W. James MacLean2dc75ed42019-03-06 14:31:092740 }
2741}
2742
Lucas Furukawa Gadaniaed1fed2017-10-13 17:34:142743void WebContentsImpl::ReattachToOuterWebContentsFrame() {
Alexander Timin5fdeff22020-09-08 09:20:372744 OPTIONAL_TRACE_EVENT0("content",
2745 "WebContentsImpl::ReattachToOuterWebContentsFrame");
Lucas Furukawa Gadaniaed1fed2017-10-13 17:34:142746 DCHECK(node_.outer_web_contents());
2747 auto* render_manager = GetRenderManager();
Kevin McNee490c04be2021-06-04 22:52:552748 auto* child_rwhv = render_manager->GetRenderWidgetHostView();
2749 DCHECK(child_rwhv);
2750 DCHECK(child_rwhv->IsRenderWidgetHostViewChildFrame());
Dave Tapuskaefc4936a2021-10-05 20:47:102751 render_manager->SetRWHViewForInnerFrameTree(
Kevin McNee490c04be2021-06-04 22:52:552752 static_cast<RenderWidgetHostViewChildFrame*>(child_rwhv));
Lucas Furukawa Gadaniaed1fed2017-10-13 17:34:142753
K. Moon97def7d2022-02-01 15:56:022754 RecursivelyRegisterRenderWidgetHostViews();
Dave Tapuska327c06c92022-06-13 20:31:512755 GetPrimaryMainFrame()->UpdateAXTreeData();
Lucas Furukawa Gadaniaed1fed2017-10-13 17:34:142756}
2757
Lucas Gadani972985622020-05-28 20:52:512758void WebContentsImpl::DidActivatePortal(
2759 WebContentsImpl* predecessor_web_contents,
2760 base::TimeTicks activation_time) {
Alexander Timin5fdeff22020-09-08 09:20:372761 TRACE_EVENT2("content", "WebContentsImpl::DidActivatePortal", "predecessor",
Alexander Timinfb70a2d2021-02-08 03:19:072762 static_cast<void*>(predecessor_web_contents), "activation_time",
2763 activation_time);
Lucas Gadani972985622020-05-28 20:52:512764 DCHECK(predecessor_web_contents);
Kevin McNeef8eb64c2020-04-21 21:36:062765 NotifyInsidePortal(false);
Andrew Grievee19cd93e2021-01-22 05:43:062766 observers_.NotifyObservers(&WebContentsObserver::DidActivatePortal,
2767 predecessor_web_contents, activation_time);
Lucas Gadani972985622020-05-28 20:52:512768 GetDelegate()->WebContentsBecamePortal(predecessor_web_contents);
Kevin McNeef8eb64c2020-04-21 21:36:062769}
2770
Adithya Srinivasan11af2c52019-12-16 22:52:552771void WebContentsImpl::NotifyInsidePortal(bool inside_portal) {
Alexander Timin5fdeff22020-09-08 09:20:372772 OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::NotifyInsidePortal",
2773 "inside_portal", inside_portal);
Gyuyoung Kim1c029712020-07-22 09:21:062774 ExecutePageBroadcastMethod(base::BindRepeating(
2775 [](bool inside_portal, RenderViewHostImpl* rvh) {
2776 if (auto& broadcast = rvh->GetAssociatedPageBroadcast())
2777 broadcast->SetInsidePortal(inside_portal);
2778 },
2779 inside_portal));
Adithya Srinivasan11af2c52019-12-16 22:52:552780}
2781
dalecurtis6c58ed02016-10-28 23:02:372782void WebContentsImpl::DidChangeVisibleSecurityState() {
Alexander Timin5fdeff22020-09-08 09:20:372783 OPTIONAL_TRACE_EVENT0("content",
2784 "WebContentsImpl::DidChangeVisibleSecurityState");
Emily Starkc663b0242019-04-26 19:34:452785 if (delegate_)
dalecurtis6c58ed02016-10-28 23:02:372786 delegate_->VisibleSecurityStateChanged(this);
Clark DuVall22aaff32021-03-18 17:17:472787
2788 SCOPED_UMA_HISTOGRAM_TIMER(
2789 "WebContentsObserver.DidChangeVisibleSecurityState");
Andrew Grievee19cd93e2021-01-22 05:43:062790 observers_.NotifyObservers(
2791 &WebContentsObserver::DidChangeVisibleSecurityState);
dalecurtis6c58ed02016-10-28 23:02:372792}
2793
Gyuyoung Kim1ac4ca782020-09-11 03:32:512794const blink::web_pref::WebPreferences WebContentsImpl::ComputeWebPreferences() {
Alexander Timin5fdeff22020-09-08 09:20:372795 OPTIONAL_TRACE_EVENT0("browser", "WebContentsImpl::ComputeWebPreferences");
2796
Gyuyoung Kim1ac4ca782020-09-11 03:32:512797 blink::web_pref::WebPreferences prefs;
Rakina Zata Amni4029b6d2020-07-28 02:36:202798
2799 const base::CommandLine& command_line =
2800 *base::CommandLine::ForCurrentProcess();
2801
2802 SetSlowWebPreferences(command_line, &prefs);
2803
2804 prefs.web_security_enabled =
2805 !command_line.HasSwitch(switches::kDisableWebSecurity);
2806
2807 prefs.remote_fonts_enabled =
2808 !command_line.HasSwitch(switches::kDisableRemoteFonts);
Rakina Zata Amni4029b6d2020-07-28 02:36:202809 prefs.local_storage_enabled =
2810 !command_line.HasSwitch(switches::kDisableLocalStorage);
2811 prefs.databases_enabled =
2812 !command_line.HasSwitch(switches::kDisableDatabases);
2813
2814 prefs.webgl1_enabled = !command_line.HasSwitch(switches::kDisable3DAPIs) &&
2815 !command_line.HasSwitch(switches::kDisableWebGL);
2816 prefs.webgl2_enabled = !command_line.HasSwitch(switches::kDisable3DAPIs) &&
2817 !command_line.HasSwitch(switches::kDisableWebGL) &&
2818 !command_line.HasSwitch(switches::kDisableWebGL2);
2819
2820 prefs.pepper_3d_enabled = !command_line.HasSwitch(switches::kDisablePepper3d);
2821
Rakina Zata Amni4029b6d2020-07-28 02:36:202822 prefs.allow_file_access_from_file_urls =
2823 command_line.HasSwitch(switches::kAllowFileAccessFromFiles);
2824
2825 prefs.accelerated_2d_canvas_enabled =
2826 !command_line.HasSwitch(switches::kDisableAccelerated2dCanvas);
Alisa Lin79251142021-06-15 20:22:122827 prefs.canvas_2d_layers_enabled =
2828 command_line.HasSwitch(switches::kEnableCanvas2DLayers) ||
2829 base::FeatureList::IsEnabled(features::kEnableCanvas2DLayers);
Rakina Zata Amni4029b6d2020-07-28 02:36:202830 prefs.antialiased_2d_canvas_disabled =
2831 command_line.HasSwitch(switches::kDisable2dCanvasAntialiasing);
2832 prefs.antialiased_clips_2d_canvas_enabled =
2833 !command_line.HasSwitch(switches::kDisable2dCanvasClipAntialiasing);
2834
2835 prefs.disable_ipc_flooding_protection =
2836 command_line.HasSwitch(switches::kDisableIpcFloodingProtection) ||
2837 command_line.HasSwitch(switches::kDisablePushStateThrottle);
2838
2839 prefs.accelerated_video_decode_enabled =
2840 !command_line.HasSwitch(switches::kDisableAcceleratedVideoDecode);
2841
2842 std::string autoplay_policy = media::GetEffectiveAutoplayPolicy(command_line);
2843 if (autoplay_policy == switches::autoplay::kNoUserGestureRequiredPolicy) {
Gyuyoung Kim1ac4ca782020-09-11 03:32:512844 prefs.autoplay_policy =
Gyuyoung Kimf6c02a262020-10-13 01:36:132845 blink::mojom::AutoplayPolicy::kNoUserGestureRequired;
Rakina Zata Amni4029b6d2020-07-28 02:36:202846 } else if (autoplay_policy ==
2847 switches::autoplay::kUserGestureRequiredPolicy) {
Gyuyoung Kimf6c02a262020-10-13 01:36:132848 prefs.autoplay_policy = blink::mojom::AutoplayPolicy::kUserGestureRequired;
Rakina Zata Amni4029b6d2020-07-28 02:36:202849 } else if (autoplay_policy ==
2850 switches::autoplay::kDocumentUserActivationRequiredPolicy) {
Gyuyoung Kim1ac4ca782020-09-11 03:32:512851 prefs.autoplay_policy =
Gyuyoung Kimf6c02a262020-10-13 01:36:132852 blink::mojom::AutoplayPolicy::kDocumentUserActivationRequired;
Rakina Zata Amni4029b6d2020-07-28 02:36:202853 } else {
2854 NOTREACHED();
2855 }
2856
2857 prefs.dont_send_key_events_to_javascript =
2858 base::FeatureList::IsEnabled(features::kDontSendKeyEventsToJavascript);
2859
2860// TODO(dtapuska): Enable barrel button selection drag support on Android.
2861// crbug.com/758042
Xiaohan Wang24ec9342022-01-15 17:34:222862#if BUILDFLAG(IS_WIN)
Elly Fong-Jones081a4cc32021-06-02 22:59:192863 prefs.barrel_button_for_drag_enabled = true;
Xiaohan Wang24ec9342022-01-15 17:34:222864#endif // BUILDFLAG(IS_WIN)
Rakina Zata Amni4029b6d2020-07-28 02:36:202865
Rakina Zata Amni4029b6d2020-07-28 02:36:202866 prefs.enable_scroll_animator =
2867 command_line.HasSwitch(switches::kEnableSmoothScrolling) ||
2868 (!command_line.HasSwitch(switches::kDisableSmoothScrolling) &&
2869 gfx::Animation::ScrollAnimationsEnabledBySystem());
2870
2871 prefs.prefers_reduced_motion = gfx::Animation::PrefersReducedMotion();
2872
2873 if (ChildProcessSecurityPolicyImpl::GetInstance()->HasWebUIBindings(
2874 GetRenderViewHost()->GetProcess()->GetID())) {
2875 prefs.loads_images_automatically = true;
2876 prefs.javascript_enabled = true;
2877 }
2878
2879 prefs.viewport_enabled = command_line.HasSwitch(switches::kEnableViewport);
2880
David Bokan7950a3f2020-10-27 21:53:312881 prefs.threaded_scrolling_enabled =
2882 !command_line.HasSwitch(blink::switches::kDisableThreadedScrolling);
2883
John Abd-El-Malek74f0b95c2021-04-05 06:24:022884 if (GetController().GetVisibleEntry() &&
2885 GetController().GetVisibleEntry()->GetIsOverridingUserAgent()) {
Xiaohan Wang24ec9342022-01-15 17:34:222886#if BUILDFLAG(IS_ANDROID)
John Abd-El-Malek267d9ed12021-03-24 21:29:132887 // Only ignore viewport meta tag when Request Desktop Site is used, but not
2888 // in other situations where embedder changes to arbitrary mobile UA string.
2889 if (renderer_preferences_.user_agent_override.ua_metadata_override &&
2890 !renderer_preferences_.user_agent_override.ua_metadata_override->mobile)
2891#endif
2892 prefs.viewport_meta_enabled = false;
2893 }
Rakina Zata Amni4029b6d2020-07-28 02:36:202894
Rakina Zata Amni4029b6d2020-07-28 02:36:202895 prefs.spatial_navigation_enabled =
2896 command_line.HasSwitch(switches::kEnableSpatialNavigation);
2897
John Abd-El-Malek74f0b95c2021-04-05 06:24:022898 if (is_spatial_navigation_disabled_)
Rakina Zata Amni4029b6d2020-07-28 02:36:202899 prefs.spatial_navigation_enabled = false;
2900
Mahesh Machavolu6cb80182022-07-22 08:09:312901 prefs.stylus_handwriting_enabled = stylus_handwriting_enabled_;
2902
Rakina Zata Amni4029b6d2020-07-28 02:36:202903 prefs.disable_reading_from_canvas =
2904 command_line.HasSwitch(switches::kDisableReadingFromCanvas);
2905
2906 prefs.strict_mixed_content_checking =
2907 command_line.HasSwitch(switches::kEnableStrictMixedContentChecking);
2908
2909 prefs.strict_powerful_feature_restrictions = command_line.HasSwitch(
2910 switches::kEnableStrictPowerfulFeatureRestrictions);
2911
Justin Novosad967ad8f02021-03-31 20:40:352912 prefs.fake_no_alloc_direct_call_for_testing_enabled =
2913 command_line.HasSwitch(switches::kEnableFakeNoAllocDirectCallForTesting);
2914
Rakina Zata Amni4029b6d2020-07-28 02:36:202915 const std::string blockable_mixed_content_group =
2916 base::FieldTrialList::FindFullName("BlockableMixedContent");
2917 prefs.strictly_block_blockable_mixed_content =
2918 blockable_mixed_content_group == "StrictlyBlockBlockableMixedContent";
2919
2920 const std::string plugin_mixed_content_status =
2921 base::FieldTrialList::FindFullName("PluginMixedContentStatus");
2922 prefs.block_mixed_plugin_content =
2923 plugin_mixed_content_status == "BlockableMixedContent";
2924
2925 prefs.v8_cache_options = GetV8CacheOptions();
2926
2927 prefs.user_gesture_required_for_presentation = !command_line.HasSwitch(
2928 switches::kDisableGestureRequirementForPresentation);
2929
John Abd-El-Malek74f0b95c2021-04-05 06:24:022930 if (is_overlay_content_)
Rakina Zata Amni4029b6d2020-07-28 02:36:202931 prefs.hide_download_ui = true;
2932
2933 // `media_controls_enabled` is `true` by default.
John Abd-El-Malek74f0b95c2021-04-05 06:24:022934 if (has_persistent_video_)
Rakina Zata Amni4029b6d2020-07-28 02:36:202935 prefs.media_controls_enabled = false;
2936
Xiaohan Wang24ec9342022-01-15 17:34:222937#if BUILDFLAG(IS_ANDROID)
Rakina Zata Amni4029b6d2020-07-28 02:36:202938 display::Display display = display::Screen::GetScreen()->GetPrimaryDisplay();
2939 gfx::Size size = display.GetSizeInPixel();
2940 int min_width = size.width() < size.height() ? size.width() : size.height();
2941 prefs.device_scale_adjustment = GetDeviceScaleAdjustment(
2942 static_cast<int>(min_width / display.device_scale_factor()));
Xiaohan Wang24ec9342022-01-15 17:34:222943#endif // BUILDFLAG(IS_ANDROID)
Rakina Zata Amni4029b6d2020-07-28 02:36:202944
Dave Tapuska52678d1362022-07-22 19:37:162945 // GuestViews in the same StoragePartition need to find each other's frames.
2946 prefs.renderer_wide_named_frame_lookup = IsGuest();
2947
David Bokan7ec5ac922022-11-29 03:31:312948 if (command_line.HasSwitch(switches::kHideScrollbars))
2949 prefs.hide_scrollbars = true;
2950
Aaron Colwellbd02c6c2021-01-16 00:34:292951 GetContentClient()->browser()->OverrideWebkitPrefs(this, &prefs);
Rakina Zata Amni4029b6d2020-07-28 02:36:202952 return prefs;
2953}
2954
2955void WebContentsImpl::SetSlowWebPreferences(
2956 const base::CommandLine& command_line,
Gyuyoung Kim1ac4ca782020-09-11 03:32:512957 blink::web_pref::WebPreferences* prefs) {
Alexander Timin5fdeff22020-09-08 09:20:372958 OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::SetSlowWebPreferences");
2959
Rakina Zata Amni4029b6d2020-07-28 02:36:202960 if (web_preferences_.get()) {
2961#define SET_FROM_CACHE(prefs, field) prefs->field = web_preferences_->field
2962
2963 SET_FROM_CACHE(prefs, touch_event_feature_detection_enabled);
2964 SET_FROM_CACHE(prefs, available_pointer_types);
2965 SET_FROM_CACHE(prefs, available_hover_types);
2966 SET_FROM_CACHE(prefs, primary_pointer_type);
2967 SET_FROM_CACHE(prefs, primary_hover_type);
2968 SET_FROM_CACHE(prefs, pointer_events_max_touch_points);
2969 SET_FROM_CACHE(prefs, number_of_cpu_cores);
2970
Xiaohan Wang24ec9342022-01-15 17:34:222971#if BUILDFLAG(IS_ANDROID)
Rakina Zata Amni4029b6d2020-07-28 02:36:202972 SET_FROM_CACHE(prefs, video_fullscreen_orientation_lock_enabled);
2973 SET_FROM_CACHE(prefs, video_rotate_to_fullscreen_enabled);
2974#endif
2975
2976#undef SET_FROM_CACHE
2977 } else {
2978 // Every prefs->field modified below should have a SET_FROM_CACHE entry
2979 // above.
2980
2981 // On Android, Touch event feature detection is enabled by default,
2982 // Otherwise default is disabled.
2983 std::string touch_enabled_default_switch =
2984 switches::kTouchEventFeatureDetectionDisabled;
Xiaohan Wang24ec9342022-01-15 17:34:222985#if BUILDFLAG(IS_ANDROID)
Rakina Zata Amni4029b6d2020-07-28 02:36:202986 touch_enabled_default_switch = switches::kTouchEventFeatureDetectionEnabled;
Xiaohan Wang24ec9342022-01-15 17:34:222987#endif // BUILDFLAG(IS_ANDROID)
Rakina Zata Amni4029b6d2020-07-28 02:36:202988 const std::string touch_enabled_switch =
2989 command_line.HasSwitch(switches::kTouchEventFeatureDetection)
2990 ? command_line.GetSwitchValueASCII(
2991 switches::kTouchEventFeatureDetection)
2992 : touch_enabled_default_switch;
2993
2994 prefs->touch_event_feature_detection_enabled =
2995 (touch_enabled_switch == switches::kTouchEventFeatureDetectionAuto)
2996 ? (ui::GetTouchScreensAvailability() ==
2997 ui::TouchScreensAvailability::ENABLED)
2998 : (touch_enabled_switch.empty() ||
2999 touch_enabled_switch ==
3000 switches::kTouchEventFeatureDetectionEnabled);
3001
3002 std::tie(prefs->available_pointer_types, prefs->available_hover_types) =
Peter Kvitek965f3cd2022-01-06 22:33:413003 GetAvailablePointerAndHoverTypes();
Gyuyoung Kimd50ce7f2020-11-20 19:16:303004 prefs->primary_pointer_type = static_cast<blink::mojom::PointerType>(
3005 ui::GetPrimaryPointerType(prefs->available_pointer_types));
Gyuyoung Kimc527ec32020-11-21 03:31:433006 prefs->primary_hover_type = static_cast<blink::mojom::HoverType>(
3007 ui::GetPrimaryHoverType(prefs->available_hover_types));
Rakina Zata Amni4029b6d2020-07-28 02:36:203008
3009 prefs->pointer_events_max_touch_points = ui::MaxTouchPoints();
3010
3011 prefs->number_of_cpu_cores = base::SysInfo::NumberOfProcessors();
3012
Xiaohan Wang24ec9342022-01-15 17:34:223013#if BUILDFLAG(IS_ANDROID)
Rakina Zata Amni4029b6d2020-07-28 02:36:203014 const bool device_is_phone =
3015 ui::GetDeviceFormFactor() == ui::DEVICE_FORM_FACTOR_PHONE;
3016 prefs->video_fullscreen_orientation_lock_enabled = device_is_phone;
3017 prefs->video_rotate_to_fullscreen_enabled = device_is_phone;
3018#endif
3019 }
3020}
3021
3022void WebContentsImpl::OnWebPreferencesChanged() {
Alexander Timin5fdeff22020-09-08 09:20:373023 OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::OnWebPreferencesChanged");
3024
Rakina Zata Amni4029b6d2020-07-28 02:36:203025 // This is defensive code to avoid infinite loops due to code run inside
3026 // SetWebPreferences() accidentally updating more preferences and thus
3027 // calling back into this code. See crbug.com/398751 for one past example.
3028 if (updating_web_preferences_)
3029 return;
3030 updating_web_preferences_ = true;
3031 SetWebPreferences(ComputeWebPreferences());
Xiaohan Wang24ec9342022-01-15 17:34:223032#if BUILDFLAG(IS_ANDROID)
Carlos Caballerob65b6e3a2021-11-15 10:09:003033 for (FrameTreeNode* node : primary_frame_tree_.Nodes()) {
Rakina Zata Amni4029b6d2020-07-28 02:36:203034 RenderFrameHostImpl* rfh = node->current_frame_host();
3035 if (rfh->is_local_root()) {
3036 if (auto* rwh = rfh->GetRenderWidgetHost())
3037 rwh->SetForceEnableZoom(web_preferences_->force_enable_zoom);
3038 }
3039 }
3040#endif
3041 updating_web_preferences_ = false;
3042}
3043
Ahmed Fakhryd70bf37b2018-04-04 17:07:243044void WebContentsImpl::NotifyPreferencesChanged() {
Alexander Timin5fdeff22020-09-08 09:20:373045 OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::NotifyPreferencesChanged");
3046
Rakina Zata Amni347b70902020-07-22 10:49:043047 // Recompute the WebPreferences based on the current state of the WebContents,
Rakina Zata Amni4029b6d2020-07-28 02:36:203048 // etc. Note that OnWebPreferencesChanged will also call SetWebPreferences and
3049 // send the updated WebPreferences to all RenderViews for this WebContents.
3050 OnWebPreferencesChanged();
Ahmed Fakhryd70bf37b2018-04-04 17:07:243051}
3052
Bruce Long1e3e1f542019-10-16 17:56:283053void WebContentsImpl::SyncRendererPrefs() {
Alexander Timin5fdeff22020-09-08 09:20:373054 OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::SyncRendererPrefs");
3055
Mario Sanchez Prada0bd8b8c2020-10-21 17:49:233056 blink::RendererPreferences renderer_preferences = GetRendererPrefs();
Bruce Long1e3e1f542019-10-16 17:56:283057 RenderViewHostImpl::GetPlatformSpecificPrefs(&renderer_preferences);
Takashi Toyoshimadf3f4e312021-11-19 03:51:483058 ExecutePageBroadcastMethodForAllPages(base::BindRepeating(
Mario Sanchez Pradac3eb9c82020-10-23 19:12:503059 [](const blink::RendererPreferences& preferences,
3060 RenderViewHostImpl* rvh) {
3061 rvh->SendRendererPreferencesToRenderer(preferences);
3062 },
3063 renderer_preferences));
Bruce Long1e3e1f542019-10-16 17:56:283064}
3065
Alexander Timin1cc31f42020-05-12 16:26:013066void WebContentsImpl::OnCookiesAccessed(NavigationHandle* navigation,
3067 const CookieAccessDetails& details) {
Alexander Timin5fdeff22020-09-08 09:20:373068 OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::OnCookiesAccessed",
Alexander Timinf785f342021-03-18 00:00:563069 "navigation_handle", navigation);
Andrew Grievee19cd93e2021-01-22 05:43:063070 // Use a variable to select between overloads.
3071 void (WebContentsObserver::*func)(NavigationHandle*,
3072 const CookieAccessDetails&) =
3073 &WebContentsObserver::OnCookiesAccessed;
3074 observers_.NotifyObservers(func, navigation, details);
Alexander Timin1cc31f42020-05-12 16:26:013075}
3076
3077void WebContentsImpl::OnCookiesAccessed(RenderFrameHostImpl* rfh,
3078 const CookieAccessDetails& details) {
Alexander Timin5fdeff22020-09-08 09:20:373079 OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::OnCookiesAccessed",
Alexander Timinf785f342021-03-18 00:00:563080 "render_frame_host", rfh);
Andrew Grievee19cd93e2021-01-22 05:43:063081 // Use a variable to select between overloads.
3082 void (WebContentsObserver::*func)(RenderFrameHost*,
3083 const CookieAccessDetails&) =
3084 &WebContentsObserver::OnCookiesAccessed;
3085 observers_.NotifyObservers(func, rfh, details);
Josh Karlindaba39322019-07-17 23:24:333086}
3087
[email protected]b172aee2012-04-10 17:05:263088void WebContentsImpl::Stop() {
Alexander Timin5fdeff22020-09-08 09:20:373089 TRACE_EVENT0("content", "WebContentsImpl::Stop");
Takashi Toyoshimadc3f7472021-07-21 08:02:323090 ForEachFrameTree(base::BindRepeating(
Arthur Sonzognif6785ec2022-12-05 10:11:503091 [](FrameTree& frame_tree) { frame_tree.StopLoading(); }));
Johann344e1c72022-11-22 07:22:303092 GetPrerenderHostRegistry()->CancelAllHosts(PrerenderFinalStatus::kStop);
Andrew Grievee19cd93e2021-01-22 05:43:063093 observers_.NotifyObservers(&WebContentsObserver::NavigationStopped);
[email protected]0bfbf882011-12-22 18:19:273094}
3095
Francois Doray47f759d2018-06-11 18:13:513096void WebContentsImpl::SetPageFrozen(bool frozen) {
Alexander Timin5fdeff22020-09-08 09:20:373097 TRACE_EVENT1("content", "WebContentsImpl::SetPageFrozen", "frozen", frozen);
3098
Francois Doray47f759d2018-06-11 18:13:513099 // A visible page is never frozen.
3100 DCHECK_NE(Visibility::VISIBLE, GetVisibility());
3101
Sharon Yanged884542023-02-02 17:33:443102 primary_frame_tree_.ForEachRenderViewHost(
3103 [&frozen](RenderViewHostImpl* rvh) { rvh->SetIsFrozen(frozen); });
Fadi Meawada6573e02018-03-10 00:52:113104}
3105
erikchen6c7df7f7a2018-05-03 18:13:593106std::unique_ptr<WebContents> WebContentsImpl::Clone() {
Alexander Timin5fdeff22020-09-08 09:20:373107 TRACE_EVENT0("content", "WebContentsImpl::Clone");
3108
[email protected]14392a52012-05-02 20:28:443109 // We use our current SiteInstance since the cloned entry will use it anyway.
alexmose201c7cd2015-06-10 17:14:213110 // We pass our own opener so that the cloned page can access it if it was set
[email protected]ed245db2012-12-18 08:00:453111 // before.
[email protected]54944cde2012-12-09 09:24:593112 CreateParams create_params(GetBrowserContext(), GetSiteInstance());
Carlos Caballerob65b6e3a2021-11-15 10:09:003113 FrameTreeNode* opener = primary_frame_tree_.root()->opener();
Ian Clelland5cbaaf82017-11-27 22:00:033114 RenderFrameHostImpl* opener_rfh = nullptr;
3115 if (opener)
3116 opener_rfh = opener->current_frame_host();
erikchen6c7df7f7a2018-05-03 18:13:593117 std::unique_ptr<WebContentsImpl> tc =
erikchen50735fd2018-05-05 15:08:333118 CreateWithOpener(create_params, opener_rfh);
Carlos Caballerob65b6e3a2021-11-15 10:09:003119 tc->GetController().CopyStateFrom(&primary_frame_tree_.controller(), true);
Andrew Grievee19cd93e2021-01-22 05:43:063120 observers_.NotifyObservers(&WebContentsObserver::DidCloneToNewWebContents,
3121 this, tc.get());
[email protected]0bfbf882011-12-22 18:19:273122 return tc;
3123}
3124
Matt Falkenhagen548ed1562021-07-06 01:38:263125WebContents* WebContentsImpl::DeprecatedGetWebContents() {
[email protected]ec6c05f2013-10-23 18:41:573126 return this;
3127}
3128
Harkiran Bolaria5ce27632022-01-20 15:05:053129void WebContentsImpl::Init(const WebContents::CreateParams& params,
3130 blink::FramePolicy primary_main_frame_policy) {
Alexander Timin5fdeff22020-09-08 09:20:373131 TRACE_EVENT0("content", "WebContentsImpl::Init");
3132
Lukasz Anforowicz2c1573a2021-09-21 18:58:183133 creator_location_ = params.creator_location;
Nicolas Ouellet-Payeur177a6c42023-01-25 20:25:073134#if BUILDFLAG(IS_ANDROID)
3135 java_creator_location_ = params.java_creator_location;
3136#endif // BUILDFLAG(IS_ANDROID)
Lukasz Anforowicz2c1573a2021-09-21 18:58:183137
Tommy Steimel57eafde2023-01-27 17:33:243138 if (params.picture_in_picture_options.has_value()) {
3139 picture_in_picture_options_ = params.picture_in_picture_options;
3140 }
Tommy Steimel991916c42022-06-24 20:59:573141
[email protected]fa944cb82013-11-15 17:51:213142 // This is set before initializing the render manager since
[email protected]b0936d22013-11-28 06:47:363143 // RenderFrameHostManager::Init calls back into us via its delegate to ask if
[email protected]fa944cb82013-11-15 17:51:213144 // it should be hidden.
Francois Doraye6161152018-03-27 22:05:373145 visibility_ =
3146 params.initially_hidden ? Visibility::HIDDEN : Visibility::VISIBLE;
[email protected]d6fa88f2013-10-18 16:00:433147
Thoren Paulsond344c0a2021-10-14 19:20:313148 enable_wake_locks_ = params.enable_wake_locks;
3149
Sebastien Marchand28cf23182018-06-20 02:39:353150 if (!params.last_active_time.is_null())
3151 last_active_time_ = params.last_active_time;
3152
Charlie Reis37be2682023-01-10 17:04:473153 scoped_refptr<SiteInstanceImpl> site_instance =
3154 static_cast<SiteInstanceImpl*>(params.site_instance.get());
dcheng3ce04b62015-10-26 23:30:553155 if (!site_instance)
Charlie Reis37be2682023-01-10 17:04:473156 site_instance = SiteInstanceImpl::Create(params.browser_context);
Lukasz Anforowicz3caa8372018-06-05 17:22:073157 if (params.desired_renderer_state == CreateParams::kNoRendererProcess) {
Charlie Reis37be2682023-01-10 17:04:473158 site_instance->PreventAssociationWithSpareProcess();
Lukasz Anforowicz3caa8372018-06-05 17:22:073159 }
dcheng3ce04b62015-10-26 23:30:553160
Rakina Zata Amni4eb716e2022-04-05 21:32:463161 // Iniitalize the primary FrameTree.
3162 // Note that GetOpener() is used here to get the opener for origin
3163 // inheritance, instead of other similar functions:
3164 // - GetOriginalOpener(), which would always return the main frame of the
3165 // opener, which might be different from the actual opener.
3166 // - FindOpenerRFH(), which will still return the opener frame if the
3167 // opener is suppressed (e.g. due to 'noopener'). The opener should not
3168 // be used for origin inheritance purposes in those cases, so this should
3169 // not pass the opener for those cases.
Harkiran Bolaria5ce27632022-01-20 15:05:053170 primary_frame_tree_.Init(
3171 site_instance.get(), params.renderer_initiated_creation,
Danil Somsikov259aa65f2022-11-11 20:49:443172 params.main_frame_name, GetOpener(), primary_main_frame_policy,
3173 base::UnguessableToken::Create());
[email protected]d1198fd2012-08-13 22:50:193174
Avi Drissman0d0908ded2022-04-28 05:39:393175 std::unique_ptr<WebContentsViewDelegate> delegate =
[email protected]fc2b46b2014-05-03 16:33:453176 GetContentClient()->browser()->GetWebContentsViewDelegate(this);
3177
W. James MacLean2539adb32019-12-13 00:40:443178 if (browser_plugin_guest_) {
Fergal Daly55b6d722020-09-11 07:56:333179 view_ = std::make_unique<WebContentsViewChildFrame>(
Avi Drissman0d0908ded2022-04-28 05:39:393180 this, std::move(delegate), &render_view_host_delegate_view_);
sky52a39e342016-12-17 17:23:223181 } else {
Avi Drissman0d0908ded2022-04-28 05:39:393182 view_ = CreateWebContentsView(this, std::move(delegate),
3183 &render_view_host_delegate_view_);
[email protected]d1198fd2012-08-13 22:50:193184 }
[email protected]fc2b46b2014-05-03 16:33:453185 CHECK(render_view_host_delegate_view_);
[email protected]d1198fd2012-08-13 22:50:193186 CHECK(view_.get());
3187
danakjfc5184932019-09-12 18:08:323188 view_->CreateView(params.context);
[email protected]d1198fd2012-08-13 22:50:193189
Fergal Daly55b6d722020-09-11 07:56:333190 screen_orientation_provider_ =
3191 std::make_unique<ScreenOrientationProvider>(this);
[email protected]01f83f92014-06-17 14:41:543192
Xiaohan Wang24ec9342022-01-15 17:34:223193#if BUILDFLAG(IS_ANDROID)
Oksana Zhuravlova0b634332019-10-28 23:04:223194 DateTimeChooserAndroid::CreateForWebContents(this);
[email protected]583418cc2013-01-17 14:01:103195#endif
fsamuel7310a4262014-12-05 05:06:443196
Nan Lin5a491532022-11-11 18:03:283197 // AttributionHost must be created after `view_->CreateView()` is called as it
3198 // may invoke `WebContentsAndroid::AddObserver()`.
3199 if (base::FeatureList::IsEnabled(blink::features::kConversionMeasurement)) {
3200 AttributionHost::CreateForWebContents(this);
3201 }
3202
fsamuel7310a4262014-12-05 05:06:443203 // BrowserPluginGuest::Init needs to be called after this WebContents has
W. James MacLean6e78da342019-12-13 15:13:233204 // a RenderWidgetHostViewChildFrame. That is, |view_->CreateView| above.
fsamuel7310a4262014-12-05 05:06:443205 if (browser_plugin_guest_)
3206 browser_plugin_guest_->Init();
nickf9acfbe2014-12-23 19:12:373207
Elly Fong-Jones564de6262022-07-28 21:11:163208 g_created_callbacks.Get().Notify(this);
naskob21fe4872015-02-24 14:15:563209
lof84501da082016-05-23 21:22:543210 // Create the renderer process in advance if requested.
Lukasz Anforowicz3caa8372018-06-05 17:22:073211 if (params.desired_renderer_state ==
3212 CreateParams::kInitializeAndWarmupRendererProcess) {
lof84501da082016-05-23 21:22:543213 if (!GetRenderManager()->current_frame_host()->IsRenderFrameLive()) {
Charlie Reis37be2682023-01-10 17:04:473214 GetRenderManager()->InitRenderView(site_instance->group(),
3215 GetRenderViewHost(), nullptr);
lof84501da082016-05-23 21:22:543216 }
3217 }
3218
Lukasz Anforowicz18302902021-11-16 19:45:053219 // Let the embedder know about the newly created and initialized WebContents.
3220 GetContentClient()->browser()->OnWebContentsCreated(this);
3221
naskof5940b9f2015-03-02 23:04:053222 // Ensure that observers are notified of the creation of this WebContents's
3223 // main RenderFrameHost. It must be done here for main frames, since the
3224 // NotifySwappedFromRenderManager expects view_ to already be created and that
3225 // happens after RenderFrameHostManager::Init.
Dave Tapuskae45d6fd2021-09-29 17:03:593226 NotifySwappedFromRenderManager(nullptr,
3227 GetRenderManager()->current_frame_host());
[email protected]d1198fd2012-08-13 22:50:193228}
3229
[email protected]7fff43e2013-05-21 20:21:103230void WebContentsImpl::OnWebContentsDestroyed(WebContentsImpl* web_contents) {
Alexander Timin5fdeff22020-09-08 09:20:373231 OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::OnWebContentsDestroyed");
3232
Avi Drissman783c1232021-02-05 01:27:053233 RemoveWebContentsDestructionObserver(web_contents);
[email protected]7fff43e2013-05-21 20:21:103234
[email protected]ceee8cd2013-03-08 04:59:513235 // Clear a pending contents that has been closed before being shown.
alexmosc2a8cec2016-05-23 22:19:533236 for (auto iter = pending_contents_.begin(); iter != pending_contents_.end();
[email protected]ceee8cd2013-03-08 04:59:513237 ++iter) {
Joel Hockey8c2011b22020-04-30 05:07:193238 if (iter->second.contents.get() != web_contents)
[email protected]ceee8cd2013-03-08 04:59:513239 continue;
erikchenbee5c9622018-04-27 19:30:253240
3241 // Someone else has deleted the WebContents. That should never happen!
3242 // TODO(erikchen): Fix semantics here. https://crbug.com/832879.
Joel Hockey8c2011b22020-04-30 05:07:193243 iter->second.contents.release();
[email protected]ceee8cd2013-03-08 04:59:513244 pending_contents_.erase(iter);
[email protected]ceee8cd2013-03-08 04:59:513245 return;
3246 }
3247 NOTREACHED();
[email protected]14392a52012-05-02 20:28:443248}
3249
Avi Drissman783c1232021-02-05 01:27:053250void WebContentsImpl::OnRenderWidgetHostDestroyed(
3251 RenderWidgetHost* render_widget_host) {
3252 OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::OnWebContentsDestroyed");
Alexander Timin5fdeff22020-09-08 09:20:373253
Avi Drissman783c1232021-02-05 01:27:053254 RemoveRenderWidgetHostDestructionObserver(render_widget_host);
3255
3256 // Clear a pending widget that has been closed before being shown.
3257 size_t num_erased =
3258 base::EraseIf(pending_widgets_, [render_widget_host](const auto& pair) {
3259 return pair.second == render_widget_host;
3260 });
3261 DCHECK_EQ(1u, num_erased);
3262}
3263
3264void WebContentsImpl::AddWebContentsDestructionObserver(
3265 WebContentsImpl* web_contents) {
3266 OPTIONAL_TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("content.verbose"),
3267 "WebContentsImpl::AddWebContentsDestructionObserver");
3268
3269 if (!base::Contains(web_contents_destruction_observers_, web_contents)) {
3270 web_contents_destruction_observers_[web_contents] =
3271 std::make_unique<WebContentsDestructionObserver>(this, web_contents);
[email protected]7fff43e2013-05-21 20:21:103272 }
3273}
3274
Avi Drissman783c1232021-02-05 01:27:053275void WebContentsImpl::RemoveWebContentsDestructionObserver(
3276 WebContentsImpl* web_contents) {
3277 OPTIONAL_TRACE_EVENT0(
3278 TRACE_DISABLED_BY_DEFAULT("content.verbose"),
3279 "WebContentsImpl::RemoveWebContentsDestructionObserver");
3280 web_contents_destruction_observers_.erase(web_contents);
3281}
3282
3283void WebContentsImpl::AddRenderWidgetHostDestructionObserver(
3284 RenderWidgetHost* render_widget_host) {
3285 OPTIONAL_TRACE_EVENT0(
3286 TRACE_DISABLED_BY_DEFAULT("content.verbose"),
3287 "WebContentsImpl::AddRenderWidgetHostDestructionObserver");
3288
3289 if (!base::Contains(render_widget_host_destruction_observers_,
3290 render_widget_host)) {
3291 render_widget_host_destruction_observers_[render_widget_host] =
3292 std::make_unique<RenderWidgetHostDestructionObserver>(
3293 this, render_widget_host);
3294 }
3295}
3296
3297void WebContentsImpl::RemoveRenderWidgetHostDestructionObserver(
3298 RenderWidgetHost* render_widget_host) {
3299 OPTIONAL_TRACE_EVENT0(
3300 TRACE_DISABLED_BY_DEFAULT("content.verbose"),
3301 "WebContentsImpl::RemoveRenderWidgetHostDestructionObserver");
3302 render_widget_host_destruction_observers_.erase(render_widget_host);
[email protected]7fff43e2013-05-21 20:21:103303}
3304
[email protected]b172aee2012-04-10 17:05:263305void WebContentsImpl::AddObserver(WebContentsObserver* observer) {
Alexander Timin5fdeff22020-09-08 09:20:373306 OPTIONAL_TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("content.verbose"),
3307 "WebContentsImpl::AddObserver");
[email protected]be1f56ab2011-12-22 06:55:313308 observers_.AddObserver(observer);
3309}
3310
[email protected]b172aee2012-04-10 17:05:263311void WebContentsImpl::RemoveObserver(WebContentsObserver* observer) {
Alexander Timin5fdeff22020-09-08 09:20:373312 OPTIONAL_TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("content.verbose"),
3313 "WebContentsImpl::RemoveObserver");
[email protected]be1f56ab2011-12-22 06:55:313314 observers_.RemoveObserver(observer);
3315}
3316
Kevin McNeeef1e9362021-06-08 21:31:523317std::set<RenderWidgetHostViewBase*>
Adithya Srinivasane6e7f842019-12-16 18:41:363318WebContentsImpl::GetRenderWidgetHostViewsInWebContentsTree() {
Kevin McNeeef1e9362021-06-08 21:31:523319 std::set<RenderWidgetHostViewBase*> result;
Daniel Cheng982f2b22022-08-25 23:46:163320 GetPrimaryMainFrame()->ForEachRenderFrameHost(
3321 [&result](RenderFrameHostImpl* rfh) {
Kevin McNeeef1e9362021-06-08 21:31:523322 if (auto* view =
3323 static_cast<RenderWidgetHostViewBase*>(rfh->GetView())) {
3324 result.insert(view);
3325 }
Daniel Cheng982f2b22022-08-25 23:46:163326 });
Adithya Srinivasane6e7f842019-12-16 18:41:363327 return result;
3328}
3329
[email protected]b172aee2012-04-10 17:05:263330void WebContentsImpl::Activate() {
Alexander Timin5fdeff22020-09-08 09:20:373331 OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::Activate");
[email protected]d5f942ba2008-09-26 19:30:343332 if (delegate_)
3333 delegate_->ActivateContents(this);
3334}
3335
Ahmed Fakhryfaa32d22018-10-05 15:56:163336void WebContentsImpl::SetTopControlsShownRatio(
3337 RenderWidgetHostImpl* render_widget_host,
3338 float ratio) {
Alexander Timin5fdeff22020-09-08 09:20:373339 OPTIONAL_TRACE_EVENT2("content", "WebContentsImpl::SetTopControlsShownRatio",
Alexander Timinf785f342021-03-18 00:00:563340 "render_widget_host", render_widget_host, "ratio",
3341 ratio);
Ahmed Fakhryfaa32d22018-10-05 15:56:163342 if (!delegate_)
3343 return;
3344
Dave Tapuska327c06c92022-06-13 20:31:513345 RenderFrameHostImpl* rfh = GetPrimaryMainFrame();
Ahmed Fakhryfaa32d22018-10-05 15:56:163346 if (!rfh || render_widget_host != rfh->GetRenderWidgetHost())
3347 return;
3348
3349 delegate_->SetTopControlsShownRatio(this, ratio);
Ahmed Fakhry58e6ef542018-09-04 18:05:383350}
3351
Ahmed Fakhry58e6ef542018-09-04 18:05:383352void WebContentsImpl::SetTopControlsGestureScrollInProgress(bool in_progress) {
Alexander Timin5fdeff22020-09-08 09:20:373353 OPTIONAL_TRACE_EVENT1(
3354 "content", "WebContentsImpl::SetTopControlsGestureScrollInProgress",
3355 "in_progress", in_progress);
Ahmed Fakhry58e6ef542018-09-04 18:05:383356 if (delegate_)
3357 delegate_->SetTopControlsGestureScrollInProgress(in_progress);
3358}
3359
lazyboy63f5b312015-11-23 20:19:523360void WebContentsImpl::RenderWidgetCreated(
3361 RenderWidgetHostImpl* render_widget_host) {
Alexander Timin5fdeff22020-09-08 09:20:373362 OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::RenderWidgetCreated",
Alexander Timinf785f342021-03-18 00:00:563363 "render_widget_host", render_widget_host);
lazyboy63f5b312015-11-23 20:19:523364 created_widgets_.insert(render_widget_host);
3365}
3366
[email protected]b24b68a2012-09-24 21:57:263367void WebContentsImpl::RenderWidgetDeleted(
3368 RenderWidgetHostImpl* render_widget_host) {
Alexander Timin5fdeff22020-09-08 09:20:373369 OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::RenderWidgetDeleted",
Alexander Timinf785f342021-03-18 00:00:563370 "render_widget_host", render_widget_host);
Takashi Toyoshimaea534ef22021-07-21 03:27:593371 // Note that IsBeingDestroyed() can return true at this point as
lazyboy63f5b312015-11-23 20:19:523372 // ~WebContentsImpl() calls RFHM::ClearRFHsPendingShutdown(), which might lead
3373 // us here.
3374 created_widgets_.erase(render_widget_host);
[email protected]b24b68a2012-09-24 21:57:263375
Takashi Toyoshimaea534ef22021-07-21 03:27:593376 if (IsBeingDestroyed())
lazyboy63f5b312015-11-23 20:19:523377 return;
[email protected]44470a22013-01-24 01:21:543378
lfg7d4caad2017-03-22 09:01:453379 if (render_widget_host == mouse_lock_widget_)
lfgff8dfc8d2016-10-21 17:42:323380 LostMouseLock(mouse_lock_widget_);
Joe Downing192998b22018-03-22 15:51:363381
Joe Downingc1a57efe2018-05-09 18:23:543382 CancelKeyboardLock(render_widget_host);
[email protected]b24b68a2012-09-24 21:57:263383}
3384
estaded0a0c992015-01-21 14:12:063385void WebContentsImpl::RenderWidgetWasResized(
rouslan2f5993f2015-01-29 00:18:313386 RenderWidgetHostImpl* render_widget_host,
3387 bool width_changed) {
Alexander Timin5fdeff22020-09-08 09:20:373388 OPTIONAL_TRACE_EVENT2("content", "WebContentsImpl::RenderWidgetWasResized",
Alexander Timinf785f342021-03-18 00:00:563389 "render_widget_host", render_widget_host,
3390 "width_changed", width_changed);
Dave Tapuska327c06c92022-06-13 20:31:513391 RenderFrameHostImpl* rfh = GetPrimaryMainFrame();
estadece344ec02015-01-23 00:12:293392 if (!rfh || render_widget_host != rfh->GetRenderWidgetHost())
estaded0a0c992015-01-21 14:12:063393 return;
estaded0a0c992015-01-21 14:12:063394
Dave Tapuska1ca6d5f2021-10-13 22:40:033395 observers_.NotifyObservers(&WebContentsObserver::PrimaryMainFrameWasResized,
Andrew Grievee19cd93e2021-01-22 05:43:063396 width_changed);
estaded0a0c992015-01-21 14:12:063397}
3398
skyf65d9bb2017-03-24 02:26:393399KeyboardEventProcessingResult WebContentsImpl::PreHandleKeyboardEvent(
3400 const NativeWebKeyboardEvent& event) {
Alexander Timin5fdeff22020-09-08 09:20:373401 OPTIONAL_TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("content.verbose"),
3402 "WebContentsImpl::PreHandleKeyboardEvent");
W. James MacLeane1187272019-11-12 03:42:483403 auto* outermost_contents = GetOutermostWebContents();
3404 // TODO(wjmaclean): Generalize this to forward all key events to the outermost
3405 // delegate's handler.
Avi Drissman97aef042020-06-30 21:04:483406 if (outermost_contents != this && IsFullscreen() &&
W. James MacLeane1187272019-11-12 03:42:483407 event.windows_key_code == ui::VKEY_ESCAPE) {
3408 // When an inner WebContents has focus and is fullscreen, redirect <esc>
3409 // key events to the outermost WebContents so it can be handled by that
3410 // WebContents' delegate.
3411 if (outermost_contents->PreHandleKeyboardEvent(event) ==
3412 KeyboardEventProcessingResult::HANDLED) {
3413 return KeyboardEventProcessingResult::HANDLED;
3414 }
3415 }
skyf65d9bb2017-03-24 02:26:393416 return delegate_ ? delegate_->PreHandleKeyboardEvent(this, event)
3417 : KeyboardEventProcessingResult::NOT_HANDLED;
[email protected]63954792011-07-11 04:17:483418}
3419
Dave Tapuska344399e2019-09-09 15:18:263420bool WebContentsImpl::HandleMouseEvent(const blink::WebMouseEvent& event) {
Alexander Timin5fdeff22020-09-08 09:20:373421 OPTIONAL_TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("content.verbose"),
3422 "WebContentsImpl::HandleMouseEvent");
Dave Tapuska344399e2019-09-09 15:18:263423 // Handle mouse button back/forward in the browser process after the render
3424 // process is done with the event. This ensures all renderer-initiated history
3425 // navigations can be treated consistently.
3426 if (event.GetType() == blink::WebInputEvent::Type::kMouseUp) {
3427 WebContentsImpl* outermost = GetOutermostWebContents();
3428 if (event.button == blink::WebPointerProperties::Button::kBack &&
Carlos Caballero40b0efd2021-01-26 11:55:003429 outermost->GetController().CanGoBack()) {
3430 outermost->GetController().GoBack();
Dave Tapuska344399e2019-09-09 15:18:263431 return true;
3432 } else if (event.button == blink::WebPointerProperties::Button::kForward &&
Carlos Caballero40b0efd2021-01-26 11:55:003433 outermost->GetController().CanGoForward()) {
3434 outermost->GetController().GoForward();
Dave Tapuska344399e2019-09-09 15:18:263435 return true;
3436 }
3437 }
3438 return false;
3439}
3440
Scott Violetd5caa872018-10-16 22:00:513441bool WebContentsImpl::HandleKeyboardEvent(const NativeWebKeyboardEvent& event) {
Alexander Timin5fdeff22020-09-08 09:20:373442 OPTIONAL_TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("content.verbose"),
3443 "WebContentsImpl::HandleKeyboardEvent");
[email protected]0b094002014-08-20 18:28:103444 if (browser_plugin_embedder_ &&
3445 browser_plugin_embedder_->HandleKeyboardEvent(event)) {
Scott Violetd5caa872018-10-16 22:00:513446 return true;
[email protected]0b094002014-08-20 18:28:103447 }
Scott Violetd5caa872018-10-16 22:00:513448 return delegate_ && delegate_->HandleKeyboardEvent(this, event);
[email protected]63954792011-07-11 04:17:483449}
3450
Alexander Timin5fdeff22020-09-08 09:20:373451bool WebContentsImpl::HandleWheelEvent(const blink::WebMouseWheelEvent& event) {
3452 OPTIONAL_TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("content.verbose"),
3453 "WebContentsImpl::HandleWheelEvent");
Xiaohan Wang24ec9342022-01-15 17:34:223454#if !BUILDFLAG(IS_MAC)
lanweia93644f2015-01-21 22:00:333455 // On platforms other than Mac, control+mousewheel may change zoom. On Mac,
3456 // this isn't done for two reasons:
[email protected]bccc4472013-04-18 16:37:193457 // -the OS already has a gesture to do this through pinch-zoom
3458 // -if a user starts an inertial scroll, let's go, and presses control
3459 // (i.e. control+tab) then the OS's buffered scroll events will come in
3460 // with control key set which isn't what the user wants
Blink Reformat1c4d759e2017-04-09 16:34:543461 if (delegate_ && event.wheel_ticks_y &&
Ehsan Karamad0f83cb112018-09-06 22:07:363462 event.event_action == blink::WebMouseWheelEvent::EventAction::kPageZoom) {
w.shackleton49bcd392016-01-06 17:38:223463 // Count only integer cumulative scrolls as zoom events; this handles
3464 // smooth scroll and regular scroll device behavior.
Blink Reformat1c4d759e2017-04-09 16:34:543465 zoom_scroll_remainder_ += event.wheel_ticks_y;
w.shackleton49bcd392016-01-06 17:38:223466 int whole_zoom_scroll_remainder_ = std::lround(zoom_scroll_remainder_);
3467 zoom_scroll_remainder_ -= whole_zoom_scroll_remainder_;
3468 if (whole_zoom_scroll_remainder_ != 0) {
3469 delegate_->ContentsZoomChange(whole_zoom_scroll_remainder_ > 0);
3470 }
[email protected]fb3f066e2013-02-12 19:12:523471 return true;
3472 }
[email protected]bccc4472013-04-18 16:37:193473#endif
[email protected]fb3f066e2013-02-12 19:12:523474 return false;
3475}
3476
[email protected]04bce562014-01-30 05:34:543477bool WebContentsImpl::PreHandleGestureEvent(
3478 const blink::WebGestureEvent& event) {
Alexander Timin5fdeff22020-09-08 09:20:373479 OPTIONAL_TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("content.verbose"),
3480 "WebContentsImpl::PreHandleGestureEvent");
[email protected]28042d32014-02-03 14:10:033481 return delegate_ && delegate_->PreHandleGestureEvent(this, event);
[email protected]04bce562014-01-30 05:34:543482}
3483
kenrb2a565f82015-09-02 20:24:593484RenderWidgetHostInputEventRouter* WebContentsImpl::GetInputEventRouter() {
Takashi Toyoshimaea534ef22021-07-21 03:27:593485 if (!IsBeingDestroyed()) {
3486 if (GetOuterWebContents())
3487 return GetOuterWebContents()->GetInputEventRouter();
wjmacleane31234f2015-12-14 17:20:453488
Takashi Toyoshimaea534ef22021-07-21 03:27:593489 if (!rwh_input_event_router_.get()) {
3490 rwh_input_event_router_ =
3491 std::make_unique<RenderWidgetHostInputEventRouter>();
3492 }
3493 }
kenrb2a565f82015-09-02 20:24:593494 return rwh_input_event_router_.get();
3495}
3496
alexmosc4cbacb2015-11-21 01:29:223497RenderWidgetHostImpl* WebContentsImpl::GetFocusedRenderWidgetHost(
3498 RenderWidgetHostImpl* receiving_widget) {
alexmosc4cbacb2015-11-21 01:29:223499 // Events for widgets other than the main frame (e.g., popup menus) should be
3500 // forwarded directly to the widget they arrived on.
Dave Tapuska327c06c92022-06-13 20:31:513501 if (receiving_widget != GetPrimaryMainFrame()->GetRenderWidgetHost())
alexmosc4cbacb2015-11-21 01:29:223502 return receiving_widget;
alexmosc4d183e2015-11-06 00:46:523503
paulmeyerfeafc2d2017-04-25 21:46:403504 // If the focused WebContents is a guest WebContents, then get the focused
3505 // frame in the embedder WebContents instead.
Dave Tapuskad8b0530f2021-10-19 15:12:313506 FrameTreeNode* focused_frame = GetFocusedFrameTree()->GetFocusedFrame();
lfg1453e412017-04-11 00:48:503507
alexmosc4d183e2015-11-06 00:46:523508 if (!focused_frame)
alexmosc4cbacb2015-11-21 01:29:223509 return receiving_widget;
alexmosc4d183e2015-11-06 00:46:523510
alexmos732ca3a2015-12-08 02:01:023511 // The view may be null if a subframe's renderer process has crashed while
3512 // the subframe has focus. Drop the event in that case. Do not give
3513 // it to the main frame, so that the user doesn't unexpectedly type into the
3514 // wrong frame if a focused subframe renderer crashes while they type.
3515 RenderWidgetHostView* view = focused_frame->current_frame_host()->GetView();
3516 if (!view)
3517 return nullptr;
3518
3519 return RenderWidgetHostImpl::From(view->GetRenderWidgetHost());
alexmosc4d183e2015-11-06 00:46:523520}
3521
avallee9993fca2016-11-17 06:16:503522RenderWidgetHostImpl* WebContentsImpl::GetRenderWidgetHostWithPageFocus() {
Dave Tapuska54c76a032021-10-27 22:10:423523 FrameTree* focused_frame_tree = GetFocusedFrameTree();
3524 return focused_frame_tree->root()
3525 ->current_frame_host()
3526 ->GetRenderWidgetHost();
avallee9993fca2016-11-17 06:16:503527}
3528
Koji Ishii640cff722021-12-03 19:16:553529bool WebContentsImpl::CanEnterFullscreenMode(
3530 RenderFrameHostImpl* requesting_frame,
3531 const blink::mojom::FullscreenOptions& options) {
Avi Drissman33972942020-06-19 14:16:013532 // It's possible that this WebContents was spawned while blocking UI was on
3533 // the screen, or that it was downstream from a WebContents when UI was
3534 // blocked. Therefore, disqualify it from fullscreen if it or any upstream
3535 // WebContents has an active blocker.
Peter Kastingd5685942022-09-02 17:52:173536 return base::ranges::all_of(GetAllOpeningWebContents(this),
3537 [](auto* opener) {
3538 return opener->fullscreen_blocker_count_ == 0;
3539 }) &&
Koji Ishii640cff722021-12-03 19:16:553540 delegate_->CanEnterFullscreenModeForTab(requesting_frame, options);
Avi Drissmand1d25652020-03-06 21:28:583541}
3542
Dave Tapuska3ed44192018-05-01 18:53:303543void WebContentsImpl::EnterFullscreenMode(
Kevin McNeefb86fcf2021-02-26 23:20:573544 RenderFrameHostImpl* requesting_frame,
Dave Tapuskaa4189512019-10-15 20:27:343545 const blink::mojom::FullscreenOptions& options) {
Alexander Timin5fdeff22020-09-08 09:20:373546 OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::EnterFullscreenMode");
Koji Ishii640cff722021-12-03 19:16:553547 DCHECK(CanEnterFullscreenMode(requesting_frame, options));
Miyoung Shin6db578702021-09-11 02:38:333548 DCHECK(requesting_frame->IsActive());
Mike Wassermandbf43d92022-05-20 00:32:533549 DCHECK(ContainsOrIsFocusedWebContents());
Avi Drissmand1d25652020-03-06 21:28:583550
Jonathan Rossc1d5cc72022-11-03 22:09:393551 // When WebView is the `delegate_` we can end up with VisualProperties changes
3552 // synchronously. Notify the view ahead so it can handle the transition.
3553 if (auto* view = GetRenderWidgetHostView())
3554 static_cast<RenderWidgetHostViewBase*>(view)->EnterFullscreenMode(options);
3555
Joe Downing13dd76b2018-04-09 18:32:153556 if (delegate_) {
Mike Wasserman4ca09792020-05-29 17:44:433557 delegate_->EnterFullscreenModeForTab(requesting_frame, options);
mlamouri7a78d6fd2015-01-17 13:23:533558
Joe Downing13dd76b2018-04-09 18:32:153559 if (keyboard_lock_widget_)
3560 delegate_->RequestKeyboardLock(this, esc_key_locked_);
3561 }
3562
Andrew Grievee19cd93e2021-01-22 05:43:063563 observers_.NotifyObservers(
3564 &WebContentsObserver::DidToggleFullscreenModeForTab, IsFullscreen(),
3565 false);
Avi Drissman33972942020-06-19 14:16:013566 FullscreenContentsSet(GetBrowserContext())->insert(this);
mlamouri7a78d6fd2015-01-17 13:23:533567}
3568
bokanece34a82016-01-28 19:49:463569void WebContentsImpl::ExitFullscreenMode(bool will_cause_resize) {
Alexander Timin5fdeff22020-09-08 09:20:373570 OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::ExitFullscreenMode",
3571 "will_cause_resize", will_cause_resize);
Jonathan Rossc1d5cc72022-11-03 22:09:393572 // When WebView is the `delegate_` we can end up with VisualProperties changes
3573 // synchronously. Notify the view ahead so it can handle the transition.
3574 if (auto* view = GetRenderWidgetHostView())
3575 static_cast<RenderWidgetHostViewBase*>(view)->ExitFullscreenMode();
3576
Joe Downing13dd76b2018-04-09 18:32:153577 if (delegate_) {
mlamouri7a78d6fd2015-01-17 13:23:533578 delegate_->ExitFullscreenModeForTab(this);
[email protected]657c8e02014-03-19 19:18:373579
Joe Downing13dd76b2018-04-09 18:32:153580 if (keyboard_lock_widget_)
3581 delegate_->CancelKeyboardLockRequest(this);
3582 }
3583
bokanece34a82016-01-28 19:49:463584 // The fullscreen state is communicated to the renderer through a resize
3585 // message. If the change in fullscreen state doesn't cause a view resize
3586 // then we must ensure web contents exit the fullscreen state by explicitly
3587 // sending a resize message. This is required for the situation of the browser
3588 // moving the view into a "browser fullscreen" state and then the contents
3589 // entering "tab fullscreen". Exiting the contents "tab fullscreen" then won't
3590 // have the side effect of the view resizing, hence the explicit call here is
3591 // required.
3592 if (!will_cause_resize) {
3593 if (RenderWidgetHostView* rwhv = GetRenderWidgetHostView()) {
Ian Vollick6d75ac32021-05-05 17:45:093594 if (RenderWidgetHost* render_widget_host = rwhv->GetRenderWidgetHost())
3595 render_widget_host->SynchronizeVisualProperties();
bokanece34a82016-01-28 19:49:463596 }
scheib3dcb6c932015-02-23 10:55:583597 }
3598
Arthur Sonzogni929d29f2018-09-17 14:19:443599 current_fullscreen_frame_ = nullptr;
Becca Hughese9e27952018-06-25 17:08:273600
Andrew Grievee19cd93e2021-01-22 05:43:063601 observers_.NotifyObservers(
3602 &WebContentsObserver::DidToggleFullscreenModeForTab, IsFullscreen(),
3603 will_cause_resize);
Becca Hughesd11d6502018-07-31 17:01:283604
3605 if (display_cutout_host_impl_)
3606 display_cutout_host_impl_->DidExitFullscreen();
Avi Drissman33972942020-06-19 14:16:013607
3608 FullscreenContentsSet(GetBrowserContext())->erase(this);
[email protected]8a5e0ca2011-08-25 06:30:473609}
3610
Batalov Vladislave9a5f3822020-12-02 07:31:113611void WebContentsImpl::FullscreenStateChanged(
Kevin McNeefb86fcf2021-02-26 23:20:573612 RenderFrameHostImpl* rfh,
Batalov Vladislave9a5f3822020-12-02 07:31:113613 bool is_fullscreen,
3614 blink::mojom::FullscreenOptionsPtr options) {
Alexander Timin5fdeff22020-09-08 09:20:373615 OPTIONAL_TRACE_EVENT2("content", "WebContentsImpl::FullscreenStateChanged",
Alexander Timinf785f342021-03-18 00:00:563616 "render_frame_host", rfh, "is_fullscreen",
3617 is_fullscreen);
Becca Hughesfd5d8f892018-06-14 18:23:363618
Jinsuk Kim726a04522022-08-25 18:25:373619 GetView()->FullscreenStateChanged(is_fullscreen);
3620
Becca Hughesfd5d8f892018-06-14 18:23:363621 if (is_fullscreen) {
Batalov Vladislave9a5f3822020-12-02 07:31:113622 if (options.is_null()) {
3623 ReceivedBadMessage(rfh->GetProcess(),
3624 bad_message::WCI_INVALID_FULLSCREEN_OPTIONS);
3625 return;
3626 }
3627
3628 if (delegate_)
Kevin McNeefb86fcf2021-02-26 23:20:573629 delegate_->FullscreenStateChangedForTab(rfh, *options);
Batalov Vladislave9a5f3822020-12-02 07:31:113630
Kevin McNeefb86fcf2021-02-26 23:20:573631 if (!base::Contains(fullscreen_frames_, rfh)) {
3632 fullscreen_frames_.insert(rfh);
Arthur Sonzogni929d29f2018-09-17 14:19:443633 FullscreenFrameSetUpdated();
Becca Hughesfd5d8f892018-06-14 18:23:363634 }
Arthur Sonzogni929d29f2018-09-17 14:19:443635 return;
3636 }
Becca Hughesfd5d8f892018-06-14 18:23:363637
Kevin McNeefb86fcf2021-02-26 23:20:573638 // If |rfh| is no longer in fullscreen, remove it and any descendants.
Arthur Sonzogni929d29f2018-09-17 14:19:443639 // See https://fullscreen.spec.whatwg.org.
Arthur Sonzogni969a794e2018-10-11 08:56:093640 size_t size_before_deletion = fullscreen_frames_.size();
3641 base::EraseIf(fullscreen_frames_, [&](RenderFrameHostImpl* current) {
Dave Tapuska8c4c83762021-09-15 21:31:523642 while (current) {
3643 if (current == rfh)
3644 return true;
3645 // We only look for direct parents. fencedframes and portals will not
3646 // enter fullscreen.
3647 current = current->GetParent();
3648 }
3649 return false;
Arthur Sonzogni929d29f2018-09-17 14:19:443650 });
3651
Arthur Sonzogni969a794e2018-10-11 08:56:093652 if (size_before_deletion != fullscreen_frames_.size())
Arthur Sonzogni929d29f2018-09-17 14:19:443653 FullscreenFrameSetUpdated();
3654}
3655
3656void WebContentsImpl::FullscreenFrameSetUpdated() {
Alexander Timin5fdeff22020-09-08 09:20:373657 OPTIONAL_TRACE_EVENT0("content",
3658 "WebContentsImpl::FullscreenFrameSetUpdated");
Arthur Sonzogni929d29f2018-09-17 14:19:443659 if (fullscreen_frames_.empty()) {
3660 current_fullscreen_frame_ = nullptr;
3661 return;
Becca Hughesfd5d8f892018-06-14 18:23:363662 }
3663
Arthur Sonzogni929d29f2018-09-17 14:19:443664 // Find the current fullscreen frame and call the observers.
3665 // If frame A is fullscreen, then frame B goes into inner fullscreen, then B
3666 // exits fullscreen - that will result in A being fullscreen.
3667 RenderFrameHostImpl* new_fullscreen_frame = *std::max_element(
3668 fullscreen_frames_.begin(), fullscreen_frames_.end(), FrameCompareDepth);
Becca Hughesfd5d8f892018-06-14 18:23:363669
Arthur Sonzogni929d29f2018-09-17 14:19:443670 // If we have already notified observers about this frame then we should not
3671 // fire the observers again.
3672 if (new_fullscreen_frame == current_fullscreen_frame_)
3673 return;
3674 current_fullscreen_frame_ = new_fullscreen_frame;
Becca Hughesfd5d8f892018-06-14 18:23:363675
Andrew Grievee19cd93e2021-01-22 05:43:063676 observers_.NotifyObservers(&WebContentsObserver::DidAcquireFullscreen,
3677 new_fullscreen_frame);
Arthur Sonzogni929d29f2018-09-17 14:19:443678 if (display_cutout_host_impl_)
3679 display_cutout_host_impl_->DidAcquireFullscreen(new_fullscreen_frame);
Becca Hughesfd5d8f892018-06-14 18:23:363680}
3681
Tsuyoshi Horocd828462021-04-21 04:59:583682PageVisibilityState WebContentsImpl::CalculatePageVisibilityState(
3683 Visibility visibility) const {
Collin Baker989e0882019-11-01 01:27:173684 // Only hide the page if there are no entities capturing screenshots
David Bienvenu1cdcf092020-11-04 18:47:563685 // or video (e.g. mirroring or WebXR). If there are, apply the correct state
3686 // of kHidden or kHiddenButPainting.
3687 bool web_contents_visible_in_vr = false;
3688#if BUILDFLAG(ENABLE_VR)
3689 web_contents_visible_in_vr =
3690 XRRuntimeManagerImpl::GetImmersiveSessionWebContents() == this;
3691#endif
3692
Frank Liberato9c28010b2021-11-05 21:18:323693 // If there are entities in Picture-in-Picture mode, don't activate the
3694 // "disable rendering" optimization, since it still needs to drive the video,
3695 // and possibly other elements on the page like canvas, to keep the picture in
3696 // picture window up to date.
Tsuyoshi Horocd828462021-04-21 04:59:583697 if (visibility == Visibility::VISIBLE || visible_capturer_count_ > 0 ||
David Bienvenu1cdcf092020-11-04 18:47:563698 web_contents_visible_in_vr) {
Tsuyoshi Horocd828462021-04-21 04:59:583699 return PageVisibilityState::kVisible;
Fred Shiheb7d2ff2023-01-18 02:31:463700 } else if (hidden_capturer_count_ > 0) {
Tsuyoshi Horocd828462021-04-21 04:59:583701 return PageVisibilityState::kHiddenButPainting;
David Bienvenu1cdcf092020-11-04 18:47:563702 }
Tsuyoshi Horocd828462021-04-21 04:59:583703 return PageVisibilityState::kHidden;
3704}
3705
3706PageVisibilityState WebContentsImpl::GetPageVisibilityState() const {
3707 return CalculatePageVisibilityState(visibility_);
3708}
3709
3710void WebContentsImpl::UpdateVisibilityAndNotifyPageAndView(
Elad Alon0feb6602021-10-14 09:26:363711 Visibility new_visibility,
3712 bool is_activity) {
Kevin McNeed7fc6d052022-02-08 21:21:503713 DCHECK(!IsBeingDestroyed());
3714
Tsuyoshi Horocd828462021-04-21 04:59:583715 PageVisibilityState page_visibility =
3716 CalculatePageVisibilityState(new_visibility);
3717
Frank Liberato9c28010b2021-11-05 21:18:323718 // A crashed frame might be covered by a sad tab. See docs on SadTabHelper
3719 // exactly when it is or isn't. Either way, don't make it visible.
David Bienvenu1cdcf092020-11-04 18:47:563720 bool view_is_visible =
Frank Liberato9c28010b2021-11-05 21:18:323721 !IsCrashed() && page_visibility != PageVisibilityState::kHidden;
Collin Baker989e0882019-11-01 01:27:173722
Dave Tapuska05fcfb62021-10-18 17:09:033723 // Prerendering relies on overriding FrameTree::Delegate::IsHidden,
3724 // while for other frame trees FrameTree::Delegate::IsHidden
3725 // resolves to WebContents' visibility, so we avoid Prerender RennderViewHosts
3726 // here.
3727 ForEachRenderViewHostTypes view_mask =
3728 static_cast<ForEachRenderViewHostTypes>(
3729 ForEachRenderViewHostTypes::kBackForwardCacheViews |
3730 ForEachRenderViewHostTypes::kActiveViews);
3731
3732 RenderViewHostIterationCallback update_frame_tree_visibility =
3733 base::BindRepeating(
3734 [](PageVisibilityState page_visibility,
3735 RenderViewHostImpl* render_view_host) {
3736 render_view_host->SetFrameTreeVisibility(page_visibility);
3737 },
3738 page_visibility);
Collin Bakerc5259962019-11-14 17:51:583739 if (page_visibility != PageVisibilityState::kHidden) {
Dana Friedcf3bc8e2019-11-13 20:00:243740 // We cannot show a page or capture video unless there is a valid renderer
3741 // associated with this web contents. The navigation controller for this
3742 // page must be set to active (allowing navigation to complete, a renderer
3743 // and its associated views to be created, etc.) if any of these conditions
3744 // holds.
3745 //
3746 // Previously, it was possible for browser-side code to try to capture video
3747 // from a restored tab (for a variety of reasons, including the browser
3748 // creating preview thumbnails) and the tab would never actually load. By
Collin Bakerc5259962019-11-14 17:51:583749 // keying this behavior off of |page_visibility| instead of just
Dana Friedcf3bc8e2019-11-13 20:00:243750 // |new_visibility| we avoid this case. See crbug.com/1020782 for more
3751 // context.
Carlos Caballero40b0efd2021-01-26 11:55:003752 GetController().SetActive(true);
Dana Friedcf3bc8e2019-11-13 20:00:243753
3754 // This shows the Page before showing the individual RenderWidgets, as
3755 // RenderWidgets will work to produce compositor frames and handle input
3756 // as soon as they are shown. But the Page and other classes do not expect
3757 // to be producing frames when the Page is hidden. So we make sure the Page
3758 // is shown first.
Dave Tapuska05fcfb62021-10-18 17:09:033759 ForEachRenderViewHost(view_mask, update_frame_tree_visibility);
Collin Baker98457b52019-11-06 21:34:293760 }
Collin Baker989e0882019-11-01 01:27:173761
3762 // |GetRenderWidgetHostView()| can be null if the user middle clicks a link to
3763 // open a tab in the background, then closes the tab before selecting it.
3764 // This is because closing the tab calls WebContentsImpl::Destroy(), which
3765 // removes the |GetRenderViewHost()|; then when we actually destroy the
3766 // window, OnWindowPosChanged() notices and calls WasHidden() (which
3767 // calls us).
3768 if (auto* view = GetRenderWidgetHostView()) {
3769 if (view_is_visible) {
David Bienvenuc40de892021-01-28 00:12:143770 static_cast<RenderWidgetHostViewBase*>(view)->ShowWithVisibility(
Joe Mason3f70f472021-11-05 15:26:503771 page_visibility);
Collin Baker989e0882019-11-01 01:27:173772 } else if (new_visibility == Visibility::HIDDEN) {
3773 view->Hide();
3774 } else {
3775 view->WasOccluded();
3776 }
3777 }
3778
Carlos IL07f282f2020-05-15 22:58:293779 SetVisibilityForChildViews(view_is_visible);
Collin Baker989e0882019-11-01 01:27:173780
3781 // Make sure to call SetVisibilityAndNotifyObservers(VISIBLE) before notifying
3782 // the CrossProcessFrameConnector.
3783 if (new_visibility == Visibility::VISIBLE) {
Elad Alon0feb6602021-10-14 09:26:363784 if (is_activity) {
3785 last_active_time_ = base::TimeTicks::Now();
3786 }
Collin Baker989e0882019-11-01 01:27:173787 SetVisibilityAndNotifyObservers(new_visibility);
3788 }
3789
Collin Bakerc5259962019-11-14 17:51:583790 if (page_visibility == PageVisibilityState::kHidden) {
Collin Baker989e0882019-11-01 01:27:173791 // Similar to when showing the page, we only hide the page after
3792 // hiding the individual RenderWidgets.
Dave Tapuska05fcfb62021-10-18 17:09:033793 ForEachRenderViewHost(view_mask, update_frame_tree_visibility);
Collin Baker989e0882019-11-01 01:27:173794 } else {
Dave Tapuska05fcfb62021-10-18 17:09:033795 for (FrameTreeNode* node :
Dave Tapuska327c06c92022-06-13 20:31:513796 FrameTree::SubtreeAndInnerTreeNodes(GetPrimaryMainFrame())) {
Dave Tapuska05fcfb62021-10-18 17:09:033797 RenderFrameProxyHost* proxy_to_parent_or_outer_delegate =
3798 node->render_manager()->GetProxyToParentOrOuterDelegate();
3799 if (!proxy_to_parent_or_outer_delegate)
Collin Baker989e0882019-11-01 01:27:173800 continue;
3801
Dave Tapuska05fcfb62021-10-18 17:09:033802 // DelegateWasShown keeps track of crash metrics. This is safe to
3803 // call for GuestViews, and inner frame trees.
3804 proxy_to_parent_or_outer_delegate->cross_process_frame_connector()
3805 ->DelegateWasShown();
Collin Baker989e0882019-11-01 01:27:173806 }
3807 }
3808
3809 if (new_visibility != Visibility::VISIBLE)
3810 SetVisibilityAndNotifyObservers(new_visibility);
3811}
3812
Michael Thiessene5663522022-05-25 21:23:283813#if BUILDFLAG(IS_ANDROID)
3814void WebContentsImpl::UpdateUserGestureCarryoverInfo() {
3815 OPTIONAL_TRACE_EVENT0("content",
3816 "WebContentsImpl::UpdateUserGestureCarryoverInfo");
3817 if (delegate_)
3818 delegate_->UpdateUserGestureCarryoverInfo(this);
3819}
3820#endif
3821
Avi Drissman97aef042020-06-30 21:04:483822bool WebContentsImpl::IsFullscreen() {
[email protected]199bba6e2012-04-04 16:19:383823 return delegate_ ? delegate_->IsFullscreenForTabOrPending(this) : false;
[email protected]5d5f7af2011-10-01 01:38:123824}
3825
Malay Keshav87c42c02019-01-15 08:37:473826bool WebContentsImpl::ShouldShowStaleContentOnEviction() {
3827 return GetDelegate() && GetDelegate()->ShouldShowStaleContentOnEviction(this);
3828}
3829
danakj45d42452020-04-08 17:24:183830blink::mojom::DisplayMode WebContentsImpl::GetDisplayMode() const {
mikhail.pozdnyakovc0e251b2015-04-15 06:51:123831 return delegate_ ? delegate_->GetDisplayMode(this)
Eric Willigers052f0432019-10-04 04:06:573832 : blink::mojom::DisplayMode::kBrowser;
mikhail.pozdnyakovc0e251b2015-04-15 06:51:123833}
3834
avic3aa8422015-11-09 20:57:223835void WebContentsImpl::RequestToLockMouse(
3836 RenderWidgetHostImpl* render_widget_host,
3837 bool user_gesture,
lfgad8244352016-07-13 16:55:513838 bool last_unlocked_by_target,
3839 bool privileged) {
Alexander Timinf785f342021-03-18 00:00:563840 OPTIONAL_TRACE_EVENT2("content", "WebContentsImpl::RequestToLockMouse",
3841 "render_widget_host", render_widget_host, "privileged",
3842 privileged);
Tsuyoshi Horo0c9728f2021-12-03 16:50:043843 if (render_widget_host->frame_tree()->type() ==
3844 FrameTree::Type::kFencedFrame) {
3845 // The renderer should have checked and disallowed the request for fenced
3846 // frames in PointerLockController and dispatched pointerlockerror. Ignore
3847 // the request and mark it as bad if it didn't happen for some reason.
3848 ReceivedBadMessage(render_widget_host->GetProcess(),
3849 bad_message::WCI_REQUEST_LOCK_MOUSE_FENCED_FRAME);
3850 return;
3851 }
lfgf0cd46e2017-01-04 00:05:233852 for (WebContentsImpl* current = this; current;
3853 current = current->GetOuterWebContents()) {
3854 if (current->mouse_lock_widget_) {
James Hollyerd5c9de462020-03-10 19:02:453855 render_widget_host->GotResponseToLockMouseRequest(
3856 blink::mojom::PointerLockResult::kAlreadyLocked);
lfgf0cd46e2017-01-04 00:05:233857 return;
3858 }
[email protected]e9621112011-10-17 05:38:373859 }
avic3aa8422015-11-09 20:57:223860
lfgad8244352016-07-13 16:55:513861 if (privileged) {
lfgf0cd46e2017-01-04 00:05:233862 DCHECK(!GetOuterWebContents());
lfgad8244352016-07-13 16:55:513863 mouse_lock_widget_ = render_widget_host;
James Hollyerd5c9de462020-03-10 19:02:453864 render_widget_host->GotResponseToLockMouseRequest(
3865 blink::mojom::PointerLockResult::kSuccess);
lfgad8244352016-07-13 16:55:513866 return;
3867 }
3868
lfgbee1e0a2016-06-08 21:24:213869 bool widget_in_frame_tree = false;
Carlos Caballerob65b6e3a2021-11-15 10:09:003870 for (FrameTreeNode* node : primary_frame_tree_.Nodes()) {
lfgbee1e0a2016-06-08 21:24:213871 if (node->current_frame_host()->GetRenderWidgetHost() ==
3872 render_widget_host) {
3873 widget_in_frame_tree = true;
3874 break;
3875 }
3876 }
3877
3878 if (widget_in_frame_tree && delegate_) {
lfgf0cd46e2017-01-04 00:05:233879 for (WebContentsImpl* current = this; current;
3880 current = current->GetOuterWebContents()) {
3881 current->mouse_lock_widget_ = render_widget_host;
3882 }
3883
avic3aa8422015-11-09 20:57:223884 delegate_->RequestToLockMouse(this, user_gesture, last_unlocked_by_target);
lfgbee1e0a2016-06-08 21:24:213885 } else {
James Hollyerd5c9de462020-03-10 19:02:453886 render_widget_host->GotResponseToLockMouseRequest(
3887 blink::mojom::PointerLockResult::kWrongDocument);
lfgbee1e0a2016-06-08 21:24:213888 }
[email protected]e9621112011-10-17 05:38:373889}
3890
avi3e4b8512015-11-11 01:55:493891void WebContentsImpl::LostMouseLock(RenderWidgetHostImpl* render_widget_host) {
Alexander Timin5fdeff22020-09-08 09:20:373892 OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::LostMouseLock",
Alexander Timinf785f342021-03-18 00:00:563893 "render_widget_host", render_widget_host);
lfgbee1e0a2016-06-08 21:24:213894 CHECK(mouse_lock_widget_);
lfgf0cd46e2017-01-04 00:05:233895
Matt Falkenhagen888db592021-09-07 20:20:253896 if (WebContentsImpl::FromRenderWidgetHostImpl(mouse_lock_widget_) != this)
lfgf0cd46e2017-01-04 00:05:233897 return mouse_lock_widget_->delegate()->LostMouseLock(render_widget_host);
3898
lfgbee1e0a2016-06-08 21:24:213899 mouse_lock_widget_->SendMouseLockLost();
lfgf0cd46e2017-01-04 00:05:233900 for (WebContentsImpl* current = this; current;
3901 current = current->GetOuterWebContents()) {
3902 current->mouse_lock_widget_ = nullptr;
3903 }
avi3e4b8512015-11-11 01:55:493904
[email protected]e9621112011-10-17 05:38:373905 if (delegate_)
3906 delegate_->LostMouseLock();
3907}
3908
lfgad8244352016-07-13 16:55:513909bool WebContentsImpl::HasMouseLock(RenderWidgetHostImpl* render_widget_host) {
3910 // To verify if the mouse is locked, the mouse_lock_widget_ needs to be
3911 // assigned to the widget that requested the mouse lock, and the top-level
3912 // platform RenderWidgetHostView needs to hold the mouse lock from the OS.
Lucas Gadania0ea0172018-09-20 18:31:373913 auto* widget_host = GetTopLevelRenderWidgetHostView();
3914 return mouse_lock_widget_ == render_widget_host && widget_host &&
3915 widget_host->IsMouseLocked();
lfgad8244352016-07-13 16:55:513916}
3917
lfg84763c92017-02-16 18:55:153918RenderWidgetHostImpl* WebContentsImpl::GetMouseLockWidget() {
Lucas Gadania0ea0172018-09-20 18:31:373919 auto* widget_host = GetTopLevelRenderWidgetHostView();
Dave Tapuska406647a2020-10-21 00:55:573920 if (widget_host && widget_host->IsMouseLocked()) {
lfg84763c92017-02-16 18:55:153921 return mouse_lock_widget_;
Lucas Gadania0ea0172018-09-20 18:31:373922 }
lfg84763c92017-02-16 18:55:153923
3924 return nullptr;
3925}
3926
Joe Downing192998b22018-03-22 15:51:363927bool WebContentsImpl::RequestKeyboardLock(
Joe Downing13dd76b2018-04-09 18:32:153928 RenderWidgetHostImpl* render_widget_host,
3929 bool esc_key_locked) {
Alexander Timinf785f342021-03-18 00:00:563930 OPTIONAL_TRACE_EVENT2("content", "WebContentsImpl::RequestKeyboardLock",
3931 "render_widget_host", render_widget_host,
3932 "esc_key_locked", esc_key_locked);
Joe Downing192998b22018-03-22 15:51:363933 DCHECK(render_widget_host);
Matt Falkenhagen888db592021-09-07 20:20:253934 if (WebContentsImpl::FromRenderWidgetHostImpl(render_widget_host) != this) {
Joe Downing192998b22018-03-22 15:51:363935 NOTREACHED();
3936 return false;
3937 }
3938
3939 // KeyboardLock is only supported when called by the top-level browsing
3940 // context and is not supported in embedded content scenarios.
3941 if (GetOuterWebContents())
3942 return false;
3943
Joe Downing13dd76b2018-04-09 18:32:153944 esc_key_locked_ = esc_key_locked;
Joe Downing192998b22018-03-22 15:51:363945 keyboard_lock_widget_ = render_widget_host;
3946
Joe Downing13dd76b2018-04-09 18:32:153947 if (delegate_)
3948 delegate_->RequestKeyboardLock(this, esc_key_locked_);
Joe Downing192998b22018-03-22 15:51:363949 return true;
3950}
3951
3952void WebContentsImpl::CancelKeyboardLock(
3953 RenderWidgetHostImpl* render_widget_host) {
Alexander Timin5fdeff22020-09-08 09:20:373954 OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::CancelKeyboardLockRequest",
Alexander Timinf785f342021-03-18 00:00:563955 "render_widget_host", render_widget_host);
Joe Downing192998b22018-03-22 15:51:363956 if (!keyboard_lock_widget_ || render_widget_host != keyboard_lock_widget_)
3957 return;
3958
3959 RenderWidgetHostImpl* old_keyboard_lock_widget = keyboard_lock_widget_;
3960 keyboard_lock_widget_ = nullptr;
3961
Joe Downing13dd76b2018-04-09 18:32:153962 if (delegate_)
3963 delegate_->CancelKeyboardLockRequest(this);
3964
Joe Downing192998b22018-03-22 15:51:363965 old_keyboard_lock_widget->CancelKeyboardLock();
3966}
3967
3968RenderWidgetHostImpl* WebContentsImpl::GetKeyboardLockWidget() {
3969 return keyboard_lock_widget_;
3970}
3971
Dave Tapuskae1c62952021-11-02 23:14:063972bool WebContentsImpl::OnRenderFrameProxyVisibilityChanged(
3973 RenderFrameProxyHost* render_frame_proxy_host,
Dave Tapuskac3344362019-02-20 17:54:283974 blink::mojom::FrameVisibility visibility) {
Alexander Timin5fdeff22020-09-08 09:20:373975 OPTIONAL_TRACE_EVENT1("content",
3976 "WebContentsImpl::OnRenderFrameProxyVisibilityChanged",
3977 "visibility", static_cast<int>(visibility));
Dave Tapuskae1c62952021-11-02 23:14:063978
3979 // Check that we are responsible for the RenderFrameProxyHost by checking that
Carlos Caballerob65b6e3a2021-11-15 10:09:003980 // its FrameTreeNode matches our `primary_frame_tree_` root. Otherwise this is
3981 // not a visibility change that affects all frames in an inner WebContents.
3982 if (render_frame_proxy_host->frame_tree_node() != primary_frame_tree_.root())
Dave Tapuskae1c62952021-11-02 23:14:063983 return false;
3984
3985 DCHECK(GetOuterWebContents());
3986
Dave Tapuskac3344362019-02-20 17:54:283987 switch (visibility) {
3988 case blink::mojom::FrameVisibility::kRenderedInViewport:
3989 WasShown();
3990 break;
3991 case blink::mojom::FrameVisibility::kNotRendered:
3992 WasHidden();
3993 break;
3994 case blink::mojom::FrameVisibility::kRenderedOutOfViewport:
3995 WasOccluded();
3996 break;
3997 }
Dave Tapuskae1c62952021-11-02 23:14:063998 return true;
ekaramada4f42692016-02-11 19:48:373999}
4000
Alexander Timin9666d502021-06-19 01:34:504001FrameTree* WebContentsImpl::CreateNewWindow(
Kevin McNeefb86fcf2021-02-26 23:20:574002 RenderFrameHostImpl* opener,
rockot5c478a72016-09-28 23:14:184003 const mojom::CreateNewWindowParams& params,
Albert J. Wong65fe64d2019-09-20 02:48:144004 bool is_new_browsing_instance,
Sergey Kuznetsov32257a22019-02-11 20:26:504005 bool has_user_gesture,
[email protected]97714c82012-06-06 10:15:134006 SessionStorageNamespace* session_storage_namespace) {
Alexander Timin5fdeff22020-09-08 09:20:374007 TRACE_EVENT2("browser,content,navigation", "WebContentsImpl::CreateNewWindow",
Alexander Timinf785f342021-03-18 00:00:564008 "opener", opener, "params", params);
csharrison95f01e922017-04-24 18:52:354009 DCHECK(opener);
nick5ae4d2d2017-01-06 01:18:354010
Georg Neis736ad4c2022-06-10 05:58:324011 // Give the content browser client a chance to intercept the request and open
4012 // the URL with an external handler.
4013 if (GetContentClient()->browser()->OpenExternally(opener, params.target_url,
4014 params.disposition))
4015 return nullptr;
4016
csharrison95f01e922017-04-24 18:52:354017 int render_process_id = opener->GetProcess()->GetID();
Charlie Reis37be2682023-01-10 17:04:474018 SiteInstanceImpl* source_site_instance = opener->GetSiteInstance();
Alex Moshchuk8015afcf2022-01-31 22:59:254019 const auto& partition_config =
4020 source_site_instance->GetStoragePartitionConfig();
Aaron Colwell78b4bde2021-03-16 16:16:094021
Aaron Colwelleb219982020-01-16 02:17:274022 {
Lukasz Anforowiczb9a969a2021-04-29 15:26:254023 StoragePartition* partition =
4024 GetBrowserContext()->GetStoragePartition(source_site_instance);
Aaron Colwelleb219982020-01-16 02:17:274025 DOMStorageContextWrapper* dom_storage_context =
4026 static_cast<DOMStorageContextWrapper*>(
4027 partition->GetDOMStorageContext());
4028 SessionStorageNamespaceImpl* session_storage_namespace_impl =
4029 static_cast<SessionStorageNamespaceImpl*>(session_storage_namespace);
4030 CHECK(session_storage_namespace_impl->IsFromContext(dom_storage_context));
4031 }
[email protected]dd6730412013-08-14 15:03:374032
Albert J. Wong1ceccef92019-10-08 08:25:204033 if (delegate_ && delegate_->IsWebContentsCreationOverridden(
4034 source_site_instance, params.window_container_type,
4035 opener->GetLastCommittedURL(), params.frame_name,
4036 params.target_url)) {
Alexander Timin9666d502021-06-19 01:34:504037 auto* web_contents_impl =
4038 static_cast<WebContentsImpl*>(delegate_->CreateCustomWebContents(
4039 opener, source_site_instance, is_new_browsing_instance,
4040 opener->GetLastCommittedURL(), params.frame_name, params.target_url,
Alex Moshchuk8015afcf2022-01-31 22:59:254041 partition_config, session_storage_namespace));
Alexander Timin9666d502021-06-19 01:34:504042 if (!web_contents_impl)
4043 return nullptr;
Carlos Caballero6a99dac2021-11-03 10:41:174044 return &web_contents_impl->GetPrimaryFrameTree();
[email protected]dd6730412013-08-14 15:03:374045 }
4046
danakj22b4e8b2019-08-01 23:14:394047 bool renderer_started_hidden =
4048 params.disposition == WindowOpenDisposition::NEW_BACKGROUND_TAB;
4049
Alex Moshchuk134690e2022-05-21 01:50:094050 bool is_guest = IsGuest();
4051
Aaron Colwelleb219982020-01-16 02:17:274052 // We usually create the new window in the same BrowsingInstance (group of
4053 // script-related windows), by passing in the current SiteInstance. However,
Alex Moshchuk134690e2022-05-21 01:50:094054 // if the opener is being suppressed, we need to ensure that the new
4055 // SiteInstance is created in a new BrowsingInstance.
4056 scoped_refptr<SiteInstance> site_instance;
4057 if (params.opener_suppressed) {
4058 if (is_guest) {
4059 // For site-isolated guests, noopener windows can be created in a new
4060 // BrowsingInstance as long as they preserve the guest's StoragePartition.
4061 // For non-isolated guests, we preserve the legacy behavior of keeping the
4062 // new window in the old SiteInstance and BrowsingInstance.
4063 site_instance = SiteIsolationPolicy::IsSiteIsolationForGuestsEnabled()
4064 ? SiteInstance::CreateForGuest(GetBrowserContext(),
4065 partition_config)
4066 : source_site_instance;
4067 } else {
4068 site_instance = SiteInstance::Create(GetBrowserContext());
4069 }
4070 } else {
4071 site_instance = source_site_instance;
4072 }
Aaron Colwelleb219982020-01-16 02:17:274073
[email protected]dd6730412013-08-14 15:03:374074 // Create the new web contents. This will automatically create the new
4075 // WebContentsView. In the future, we may want to create the view separately.
[email protected]fc72bb12013-06-02 21:13:464076 CreateParams create_params(GetBrowserContext(), site_instance.get());
nasko48321ca32015-07-02 20:44:124077 create_params.main_frame_name = params.frame_name;
alexmos4cf2aa32015-07-15 23:40:434078 create_params.opener_render_process_id = render_process_id;
csharrison95f01e922017-04-24 18:52:354079 create_params.opener_render_frame_id = opener->GetRoutingID();
[email protected]50d326e2014-05-20 17:59:064080 create_params.opener_suppressed = params.opener_suppressed;
danakj22b4e8b2019-08-01 23:14:394081 create_params.initially_hidden = renderer_started_hidden;
arthursonzogni034bb9c2020-10-01 08:29:564082 create_params.initial_popup_url = params.target_url;
[email protected]50d326e2014-05-20 17:59:064083
Albert J. Wong65fe64d2019-09-20 02:48:144084 // Even though all codepaths leading here are in response to a renderer
Arthur Hemeryf6218ed2022-10-01 14:39:254085 // trying to open a new window, if the new window ends up in a different
Albert J. Wong65fe64d2019-09-20 02:48:144086 // browsing instance, then the RenderViewHost, RenderWidgetHost,
4087 // RenderFrameHost constellation is effectively browser initiated
4088 // the opener's process will not given the routing IDs for the new
4089 // objects.
4090 create_params.renderer_initiated_creation = !is_new_browsing_instance;
Albert J. Wong1ceccef92019-10-08 08:25:204091
Tommy Steimel991916c42022-06-24 20:59:574092 if (params.pip_options) {
Tommy Steimel57eafde2023-01-27 17:33:244093 create_params.picture_in_picture_options = *(params.pip_options);
Tommy Steimel991916c42022-06-24 20:59:574094 }
4095
Hiroki Nakagawa3e2527042022-11-24 06:46:424096 // Check whether there is an available prerendered page for this navigation if
4097 // this is not for guest. If it exists, take WebContents pre-created for
4098 // hosting the prerendered page instead of creating new WebContents.
4099 // TODO(crbug.com/1350676): Instead of filtering out the guest case here,
4100 // check it and drop prerender requests before starting prerendering.
Albert J. Wong65fe64d2019-09-20 02:48:144101 std::unique_ptr<WebContentsImpl> new_contents;
Hiroki Nakagawa3e2527042022-11-24 06:46:424102 if (base::FeatureList::IsEnabled(blink::features::kPrerender2InNewTab) &&
4103 !is_guest) {
4104 new_contents =
4105 GetPrerenderHostRegistry()->TakePreCreatedWebContentsForNewTabIfExists(
4106 params, create_params);
4107 if (new_contents) {
4108 // The SiteInstance of the pre-created WebContents should be in a
4109 // different BrowsingInstance from the source SiteInstance, while they
4110 // should be in the same StoragePartition.
4111 SiteInstanceImpl* new_site_instance = new_contents->GetSiteInstance();
4112 DCHECK(!new_site_instance->IsRelatedSiteInstance(source_site_instance));
4113 DCHECK_EQ(new_site_instance->GetStoragePartitionConfig(),
4114 source_site_instance->GetStoragePartitionConfig());
4115 }
[email protected]c4538072013-03-18 02:17:554116 }
danakje6c01622018-10-05 19:39:264117
Hiroki Nakagawa3e2527042022-11-24 06:46:424118 if (!new_contents) {
4119 if (!is_guest) {
4120 create_params.context = view_->GetNativeView();
4121 new_contents = WebContentsImpl::Create(create_params);
4122 } else {
4123 new_contents =
4124 GetBrowserPluginGuest()->CreateNewGuestWindow(create_params);
4125 }
4126 new_contents->GetController().SetSessionStorageNamespace(
4127 partition_config, session_storage_namespace);
4128 }
4129
4130 auto* new_contents_impl = new_contents.get();
[email protected]d1198fd2012-08-13 22:50:194131
alexmos646fec02015-07-25 00:11:494132 // If the new frame has a name, make sure any SiteInstances that can find
4133 // this named frame have proxies for it. Must be called after
4134 // SetSessionStorageNamespace, since this calls CreateRenderView, which uses
4135 // GetSessionStorageNamespace.
Harkiran Bolaria2912a6b32022-02-22 16:43:454136 if (!params.frame_name.empty()) {
4137 new_contents_impl->GetRenderManager()->CreateProxiesForNewNamedFrame(
Dave Tapuska327c06c92022-06-13 20:31:514138 new_contents_impl->GetPrimaryMainFrame()->browsing_context_state());
Harkiran Bolaria2912a6b32022-02-22 16:43:454139 }
alexmos646fec02015-07-25 00:11:494140
[email protected]c4538072013-03-18 02:17:554141 // Save the window for later if we're not suppressing the opener (since it
[email protected]d70bea92013-04-05 04:23:344142 // will be shown immediately).
4143 if (!params.opener_suppressed) {
4144 if (!is_guest) {
danakje6c01622018-10-05 19:39:264145 WebContentsView* new_view = new_contents_impl->view_.get();
[email protected]bafe6cd2012-05-23 23:09:504146
[email protected]d70bea92013-04-05 04:23:344147 // TODO(brettw): It seems bogus that we have to call this function on the
4148 // newly created object and give it one of its own member variables.
danakj22b4e8b2019-08-01 23:14:394149 RenderWidgetHostView* widget_view = new_view->CreateViewForWidget(
W. James MacLean13d834d2019-12-04 16:06:454150 new_contents_impl->GetRenderViewHost()->GetWidget());
danakj5f22bcc2021-02-12 18:09:014151 view_->SetOverscrollControllerEnabled(CanOverscrollContent());
danakj22b4e8b2019-08-01 23:14:394152 if (!renderer_started_hidden) {
4153 // RenderWidgets for frames always initialize as hidden. If the renderer
4154 // created this window as visible, then we show it here.
4155 widget_view->Show();
4156 }
[email protected]d70bea92013-04-05 04:23:344157 }
[email protected]bafe6cd2012-05-23 23:09:504158 // Save the created window associated with the route so we can show it
4159 // later.
Albert J. Wongcb004632018-07-10 22:58:254160 //
4161 // TODO(ajwong): This should be keyed off the RenderFrame routing id or the
4162 // FrameTreeNode id instead of the routing id of the Widget for the main
4163 // frame. https://crbug.com/545684
Dave Tapuska327c06c92022-06-13 20:31:514164 int32_t main_frame_routing_id = new_contents_impl->GetPrimaryMainFrame()
Fergal Daly052873a82020-03-11 14:45:494165 ->GetRenderWidgetHost()
4166 ->GetRoutingID();
4167 GlobalRoutingID id(render_process_id, main_frame_routing_id);
Joel Hockey8c2011b22020-04-30 05:07:194168 pending_contents_[id] =
4169 CreatedWindow(std::move(new_contents), params.target_url);
Avi Drissman783c1232021-02-05 01:27:054170 AddWebContentsDestructionObserver(new_contents_impl);
[email protected]bafe6cd2012-05-23 23:09:504171 }
4172
4173 if (delegate_) {
Bryan McQuaded2b93c02017-07-14 22:26:314174 delegate_->WebContentsCreated(this, render_process_id,
4175 opener->GetRoutingID(), params.frame_name,
danakje6c01622018-10-05 19:39:264176 params.target_url, new_contents_impl);
[email protected]bafe6cd2012-05-23 23:09:504177 }
4178
Andrew Grievee19cd93e2021-01-22 05:43:064179 observers_.NotifyObservers(&WebContentsObserver::DidOpenRequestedURL,
4180 new_contents_impl, opener, params.target_url,
4181 params.referrer.To<Referrer>(), params.disposition,
4182 ui::PAGE_TRANSITION_LINK,
4183 false, // started_from_context_menu
4184 true); // renderer_initiated
pnolandaae574e2017-03-06 21:04:214185
[email protected]bafe6cd2012-05-23 23:09:504186 if (params.opener_suppressed) {
4187 // When the opener is suppressed, the original renderer cannot access the
4188 // new window. As a result, we need to show and navigate the window here.
[email protected]eda238a12012-09-07 23:44:004189 bool was_blocked = false;
erikchenbee5c9622018-04-27 19:30:254190
[email protected]eda238a12012-09-07 23:44:004191 if (delegate_) {
danakje6c01622018-10-05 19:39:264192 base::WeakPtr<WebContentsImpl> weak_new_contents =
4193 new_contents_impl->weak_factory_.GetWeakPtr();
nick0d558482017-02-13 22:27:224194
Brad Triebwasser767c27a2022-08-25 22:56:054195 delegate_->AddNewContents(
4196 this, std::move(new_contents), params.target_url, params.disposition,
4197 *params.features, has_user_gesture, &was_blocked);
danakje6c01622018-10-05 19:39:264198 // The delegate may delete |new_contents_impl| during AddNewContents().
nick0d558482017-02-13 22:27:224199 if (!weak_new_contents)
Albert J. Wong65fe64d2019-09-20 02:48:144200 return nullptr;
[email protected]eda238a12012-09-07 23:44:004201 }
erikchenbee5c9622018-04-27 19:30:254202
[email protected]eda238a12012-09-07 23:44:004203 if (!was_blocked) {
Nasko Oskov83a8cf92018-10-19 14:58:564204 std::unique_ptr<NavigationController::LoadURLParams> load_params =
4205 std::make_unique<NavigationController::LoadURLParams>(
4206 params.target_url);
Nasko Oskov93e7c55c2018-12-19 01:59:294207 load_params->initiator_origin = opener->GetLastCommittedOrigin();
John Delaney23bf1a242021-02-26 19:41:294208 load_params->initiator_process_id = opener->GetProcess()->GetID();
John Delaney8623c642021-01-06 17:37:074209 load_params->initiator_frame_token = opener->GetFrameToken();
Lukasz Anforowiczd2629b42020-08-11 16:07:314210 // Avoiding setting |load_params->source_site_instance| when
4211 // |opener_suppressed| is true, because in that case we do not want to use
4212 // the old SiteInstance and/or BrowsingInstance. See also the test here:
4213 // NewPopupCOOP_SameOriginPolicyAndCrossOriginIframeSetsNoopener.
Leon Han963dc182018-11-06 05:41:484214 load_params->referrer = params.referrer.To<Referrer>();
Nasko Oskov83a8cf92018-10-19 14:58:564215 load_params->transition_type = ui::PAGE_TRANSITION_LINK;
4216 load_params->is_renderer_initiated = true;
John Delaney8623c642021-01-06 17:37:074217 load_params->was_opener_suppressed = true;
Sergey Kuznetsov32257a22019-02-11 20:26:504218 load_params->has_user_gesture = has_user_gesture;
jongdeok.kim5de823b32022-06-14 04:37:504219 load_params->is_form_submission = params.is_form_submission;
4220 if (params.form_submission_post_data) {
4221 load_params->load_type = NavigationController::LOAD_TYPE_HTTP_POST;
4222 load_params->post_data = params.form_submission_post_data;
4223 load_params->post_content_type =
4224 params.form_submission_post_content_type;
4225 }
John Delaney8623c642021-01-06 17:37:074226 load_params->impression = params.impression;
Gang Wub14b3022021-03-25 22:53:484227 load_params->override_user_agent =
4228 new_contents_impl->should_override_user_agent_in_new_tabs_
4229 ? NavigationController::UA_OVERRIDE_TRUE
4230 : NavigationController::UA_OVERRIDE_FALSE;
Antonio Sartori6984c742021-08-26 08:03:414231 load_params->download_policy = params.download_policy;
Yao Xiao720ef9d62022-12-09 05:18:294232 load_params->initiator_activation_and_ad_status =
4233 params.initiator_activation_and_ad_status;
mariakhomenkoa4971c12015-07-21 19:04:374234
4235 if (delegate_ && !is_guest &&
4236 !delegate_->ShouldResumeRequestsForCreatedWindow()) {
Nasko Oskov83a8cf92018-10-19 14:58:564237 // We are in asynchronous add new contents path, delay navigation.
4238 DCHECK(!new_contents_impl->delayed_open_url_params_);
4239 new_contents_impl->delayed_load_url_params_ = std::move(load_params);
mariakhomenkoa4971c12015-07-21 19:04:374240 } else {
Carlos Caballero40b0efd2021-01-26 11:55:004241 new_contents_impl->GetController().LoadURLWithParams(
4242 *load_params.get());
Nasko Oskov28ebd5b2018-12-07 22:29:334243 if (!is_guest)
4244 new_contents_impl->Focus();
mariakhomenkoa4971c12015-07-21 19:04:374245 }
[email protected]eda238a12012-09-07 23:44:004246 }
[email protected]bafe6cd2012-05-23 23:09:504247 }
Carlos Caballero6a99dac2021-11-03 10:41:174248 return &new_contents_impl->GetPrimaryFrameTree();
[email protected]bafe6cd2012-05-23 23:09:504249}
4250
Dave Tapuska42f9b902020-10-23 21:57:064251RenderWidgetHostImpl* WebContentsImpl::CreateNewPopupWidget(
Dave Tapuska80fb72522022-03-18 21:34:234252 base::SafeRef<SiteInstanceGroup> site_instance_group,
Tal Pressman5dcd2382020-08-26 07:13:054253 int32_t route_id,
Dave Tapuska04ccda062020-10-21 21:58:124254 mojo::PendingAssociatedReceiver<blink::mojom::PopupWidgetHost>
4255 blink_popup_widget_host,
Dave Tapuska8499eec2020-03-16 17:54:304256 mojo::PendingAssociatedReceiver<blink::mojom::WidgetHost> blink_widget_host,
4257 mojo::PendingAssociatedRemote<blink::mojom::Widget> blink_widget) {
Alexander Timinf785f342021-03-18 00:00:564258 OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::CreateNewPopupWidget",
4259 "route_id", route_id);
arthursonzogni4fe2e31d2020-12-04 15:51:014260 RenderWidgetHostImpl* widget_host = RenderWidgetHostImpl::CreateSelfOwned(
Dave Tapuska80fb72522022-03-18 21:34:234261 &primary_frame_tree_, this, site_instance_group, route_id, IsHidden(),
Tal Pressman5dcd2382020-08-26 07:13:054262 std::make_unique<FrameTokenMessageQueue>());
Dave Tapuska8499eec2020-03-16 17:54:304263
4264 widget_host->BindWidgetInterfaces(std::move(blink_widget_host),
4265 std::move(blink_widget));
Dave Tapuska04ccda062020-10-21 21:58:124266 widget_host->BindPopupWidgetInterface(std::move(blink_popup_widget_host));
[email protected]cfd80b02014-05-01 17:46:484267 RenderWidgetHostViewBase* widget_view =
4268 static_cast<RenderWidgetHostViewBase*>(
danakj0b246942018-09-17 21:30:274269 view_->CreateViewForChildWidget(widget_host));
[email protected]83918ec2013-01-10 15:37:194270 if (!widget_view)
Dave Tapuska42f9b902020-10-23 21:57:064271 return nullptr;
Dave Tapuska04b305f92020-10-19 18:20:284272 widget_view->SetWidgetType(WidgetType::kPopup);
Avi Drissman783c1232021-02-05 01:27:054273
[email protected]bafe6cd2012-05-23 23:09:504274 // Save the created widget associated with the route so we can show it later.
Dave Tapuska80fb72522022-03-18 21:34:234275 pending_widgets_[GlobalRoutingID(site_instance_group->process()->GetID(),
4276 route_id)] = widget_host;
Avi Drissman783c1232021-02-05 01:27:054277 AddRenderWidgetHostDestructionObserver(widget_host);
4278
Dave Tapuska42f9b902020-10-23 21:57:064279 return widget_host;
[email protected]bafe6cd2012-05-23 23:09:504280}
4281
Brad Triebwasser767c27a2022-08-25 22:56:054282void WebContentsImpl::ShowCreatedWindow(
4283 RenderFrameHostImpl* opener,
4284 int main_frame_widget_route_id,
4285 WindowOpenDisposition disposition,
4286 const blink::mojom::WindowFeatures& window_features,
4287 bool user_gesture) {
Alexander Timin5fdeff22020-09-08 09:20:374288 OPTIONAL_TRACE_EVENT2("content", "WebContentsImpl::ShowCreatedWindow",
Alexander Timinf785f342021-03-18 00:00:564289 "opener", opener, "main_frame_widget_route_id",
Alexander Timin5fdeff22020-09-08 09:20:374290 main_frame_widget_route_id);
danakje6c01622018-10-05 19:39:264291 // This method is the renderer requesting an existing top level window to
4292 // show a new top level window that the renderer created. Each top level
4293 // window is associated with a WebContents. In this case it was created
4294 // earlier but showing it was deferred until the renderer requested for it
4295 // to be shown. We find that previously created WebContents here.
4296 // TODO(danakj): Why do we defer this show step until the renderer asks for it
4297 // when it will always do so. What needs to happen in the renderer before we
4298 // reach here?
Anton Bikineevf62d1bf2021-05-15 17:56:074299 absl::optional<CreatedWindow> owned_created = GetCreatedWindow(
Mike Wassermandabad612020-08-13 04:26:274300 opener->GetProcess()->GetID(), main_frame_widget_route_id);
Joel Hockey8c2011b22020-04-30 05:07:194301
danakje6c01622018-10-05 19:39:264302 // The browser may have rejected the request to make a new window, or the
Dave Tapuska437e5d92020-10-26 17:59:364303 // renderer could be requesting to show a previously shown window (occurs when
4304 // mojom::CreateNewWindowStatus::kReuse is used). Ignore the request then.
Joel Hockey8c2011b22020-04-30 05:07:194305 if (!owned_created || !owned_created->contents)
danakje6c01622018-10-05 19:39:264306 return;
mariakhomenko44bdc4732015-04-29 01:55:384307
Joel Hockey8c2011b22020-04-30 05:07:194308 WebContentsImpl* created = owned_created->contents.get();
4309
danakje6c01622018-10-05 19:39:264310 // This uses the delegate for the WebContents where the window was created
4311 // from, to control how to show the newly created window.
4312 WebContentsDelegate* delegate = GetDelegate();
nick5ae4d2d2017-01-06 01:18:354313
Brad Triebwasser767c27a2022-08-25 22:56:054314 // Individual members of |window_features.bounds| may be 0 to indicate that
4315 // the window.open() feature string did not specify a value. This code does
4316 // not distinguish between an unspecified value and 0.
Mike Wassermanb6bc0152020-08-25 22:46:204317 // Assume that if any single value is non-zero, all values should be used.
Brad Triebwasser767c27a2022-08-25 22:56:054318 // TODO(crbug.com/897300): Utilize window_features.has_x and others.
4319 blink::mojom::WindowFeatures adjusted_features = window_features;
Mike Wassermanb6bc0152020-08-25 22:46:204320 int64_t display_id = display::kInvalidDisplayId;
Brad Triebwasser767c27a2022-08-25 22:56:054321 if (adjusted_features.bounds != gfx::Rect())
4322 display_id = AdjustRequestedWindowBounds(&adjusted_features.bounds, opener);
Mike Wassermanb6bc0152020-08-25 22:46:204323
4324 // Drop fullscreen when opening a WebContents to prohibit deceptive behavior.
4325 // Only drop fullscreen on the specific destination display, if it is known.
Brad Triebwasser5eb94a92022-10-13 22:34:284326 // This supports sites using cross-screen window management capabilities to
Mike Wassermanb6bc0152020-08-25 22:46:204327 // retain fullscreen and open a window on another screen.
4328 ForSecurityDropFullscreen(display_id).RunAndReset();
4329
danakje6c01622018-10-05 19:39:264330 // The delegate can be null in tests, so we must check for it :(.
4331 if (delegate) {
4332 // Mark the web contents as pending resume, then immediately do
4333 // the resume if the delegate wants it.
4334 created->is_resume_pending_ = true;
4335 if (delegate->ShouldResumeRequestsForCreatedWindow())
4336 created->ResumeLoadingCreatedWebContents();
4337
Joel Hockey8c2011b22020-04-30 05:07:194338 delegate->AddNewContents(this, std::move(owned_created->contents),
Joel Hockey891e88062020-04-30 05:38:444339 std::move(owned_created->target_url), disposition,
Brad Triebwasser767c27a2022-08-25 22:56:054340 adjusted_features, user_gesture, nullptr);
[email protected]eda238a12012-09-07 23:44:004341 }
[email protected]bafe6cd2012-05-23 23:09:504342}
4343
alexmosc2a8cec2016-05-23 22:19:534344void WebContentsImpl::ShowCreatedWidget(int process_id,
Albert J. Wongf6e13ed2018-09-18 15:25:474345 int widget_route_id,
Maksim Sisov113ea342021-08-26 16:19:314346 const gfx::Rect& initial_rect,
4347 const gfx::Rect& initial_anchor_rect) {
Alexander Timin5fdeff22020-09-08 09:20:374348 OPTIONAL_TRACE_EVENT2("content", "WebContentsImpl::ShowCreatedWidget",
4349 "process_id", process_id, "widget_route_id",
4350 widget_route_id);
[email protected]cfd80b02014-05-01 17:46:484351 RenderWidgetHostViewBase* widget_host_view =
alexmosc2a8cec2016-05-23 22:19:534352 static_cast<RenderWidgetHostViewBase*>(
Dave Tapuska22cafa32020-10-06 11:56:054353 GetCreatedWidget(process_id, widget_route_id));
[email protected]bafe6cd2012-05-23 23:09:504354 if (!widget_host_view)
4355 return;
[email protected]cfd80b02014-05-01 17:46:484356
W. James MacLeanec4125c2019-09-27 18:56:004357 // GetOutermostWebContents() returns |this| if there are no outer WebContents.
W. James MacLean3c5f50462019-10-28 16:24:214358 auto* outer_web_contents = GetOuterWebContents();
4359 auto* outermost_web_contents = GetOutermostWebContents();
W. James MacLeanec4125c2019-09-27 18:56:004360 RenderWidgetHostView* view =
W. James MacLean3c5f50462019-10-28 16:24:214361 outermost_web_contents->GetRenderWidgetHostView();
4362 // It's not entirely obvious why we need the transform only in the case where
4363 // the outer webcontents is not the same as the outermost webcontents. It may
4364 // be due to the fact that oopifs that are children of the mainframe get
4365 // correct values for their screenrects, but deeper cross-process frames do
4366 // not. Hopefully this can be resolved with https://crbug.com/928825.
4367 // Handling these cases separately is needed for http://crbug.com/1015298.
4368 bool needs_transform = this != outermost_web_contents &&
4369 outermost_web_contents != outer_web_contents;
W. James MacLeanec4125c2019-09-27 18:56:004370
4371 gfx::Rect transformed_rect(initial_rect);
Maksim Sisov113ea342021-08-26 16:19:314372 gfx::Rect transformed_anchor_rect(initial_anchor_rect);
W. James MacLeanec4125c2019-09-27 18:56:004373 RenderWidgetHostView* this_view = GetRenderWidgetHostView();
W. James MacLean3c5f50462019-10-28 16:24:214374 if (needs_transform) {
W. James MacLeanec4125c2019-09-27 18:56:004375 // We need to transform the coordinates of initial_rect.
4376 gfx::Point origin =
4377 this_view->TransformPointToRootCoordSpace(initial_rect.origin());
4378 gfx::Point bottom_right =
4379 this_view->TransformPointToRootCoordSpace(initial_rect.bottom_right());
4380 transformed_rect =
4381 gfx::Rect(origin.x(), origin.y(), bottom_right.x() - origin.x(),
4382 bottom_right.y() - origin.y());
Maksim Sisov113ea342021-08-26 16:19:314383
4384 origin =
4385 this_view->TransformPointToRootCoordSpace(initial_anchor_rect.origin());
4386 bottom_right = this_view->TransformPointToRootCoordSpace(
4387 initial_anchor_rect.bottom_right());
4388 transformed_anchor_rect =
4389 gfx::Rect(origin.x(), origin.y(), bottom_right.x() - origin.x(),
4390 bottom_right.y() - origin.y());
[email protected]cfd80b02014-05-01 17:46:484391 }
4392
Maksim Sisov113ea342021-08-26 16:19:314393 widget_host_view->InitAsPopup(view, transformed_rect,
4394 transformed_anchor_rect);
[email protected]89054502012-06-03 10:29:244395
yiyixcb1fbc4f2018-03-16 19:54:084396 RenderWidgetHostImpl* render_widget_host_impl = widget_host_view->host();
danakj08eb51d2020-12-30 20:15:234397 // Renderer-owned popup widgets wait for the renderer to request for them
4398 // to be shown. We signal that this condition is satisfied by calling Init().
[email protected]89054502012-06-03 10:29:244399 render_widget_host_impl->Init();
[email protected]bafe6cd2012-05-23 23:09:504400}
4401
Anton Bikineevf62d1bf2021-05-15 17:56:074402absl::optional<CreatedWindow> WebContentsImpl::GetCreatedWindow(
nick5ae4d2d2017-01-06 01:18:354403 int process_id,
4404 int main_frame_widget_route_id) {
Alexander Timin5fdeff22020-09-08 09:20:374405 OPTIONAL_TRACE_EVENT2("content", "WebContentsImpl::GetCreatedWindow",
4406 "process_id", process_id, "main_frame_widget_route_id",
4407 main_frame_widget_route_id);
4408
Lukasz Anforowicz09060bdf72018-08-23 15:53:174409 auto key = GlobalRoutingID(process_id, main_frame_widget_route_id);
nick5ae4d2d2017-01-06 01:18:354410 auto iter = pending_contents_.find(key);
[email protected]bafe6cd2012-05-23 23:09:504411
4412 // Certain systems can block the creation of new windows. If we didn't succeed
4413 // in creating one, just return NULL.
alexmosc2a8cec2016-05-23 22:19:534414 if (iter == pending_contents_.end())
Anton Bikineevf62d1bf2021-05-15 17:56:074415 return absl::nullopt;
[email protected]bafe6cd2012-05-23 23:09:504416
Joel Hockey8c2011b22020-04-30 05:07:194417 CreatedWindow result = std::move(iter->second);
4418 WebContentsImpl* new_contents = result.contents.get();
nick5ae4d2d2017-01-06 01:18:354419 pending_contents_.erase(key);
Avi Drissman783c1232021-02-05 01:27:054420 RemoveWebContentsDestructionObserver(new_contents);
[email protected]bafe6cd2012-05-23 23:09:504421
[email protected]d70bea92013-04-05 04:23:344422 // Don't initialize the guest WebContents immediately.
Charlie Reis3d189602021-04-27 21:24:474423 if (new_contents->IsGuest())
Joel Hockey8c2011b22020-04-30 05:07:194424 return result;
[email protected]d70bea92013-04-05 04:23:344425
Dave Tapuska327c06c92022-06-13 20:31:514426 if (!new_contents->GetPrimaryMainFrame()
4427 ->GetProcess()
4428 ->IsInitializedAndNotDead() ||
4429 !new_contents->GetPrimaryMainFrame()->GetView()) {
Anton Bikineevf62d1bf2021-05-15 17:56:074430 return absl::nullopt;
nick5ae4d2d2017-01-06 01:18:354431 }
[email protected]bafe6cd2012-05-23 23:09:504432
Joel Hockey8c2011b22020-04-30 05:07:194433 return result;
[email protected]bafe6cd2012-05-23 23:09:504434}
4435
alexmosc2a8cec2016-05-23 22:19:534436RenderWidgetHostView* WebContentsImpl::GetCreatedWidget(int process_id,
4437 int route_id) {
Alexander Timin5fdeff22020-09-08 09:20:374438 OPTIONAL_TRACE_EVENT2("content", "WebContentsImpl::GetCreatedWidget",
4439 "process_id", process_id, "route_id", route_id);
4440
Avi Drissman783c1232021-02-05 01:27:054441 auto iter = pending_widgets_.find(GlobalRoutingID(process_id, route_id));
4442 if (iter == pending_widgets_.end()) {
[email protected]bafe6cd2012-05-23 23:09:504443 DCHECK(false);
alexmosc2a8cec2016-05-23 22:19:534444 return nullptr;
[email protected]bafe6cd2012-05-23 23:09:504445 }
4446
Avi Drissman783c1232021-02-05 01:27:054447 RenderWidgetHost* widget_host = iter->second;
4448 pending_widgets_.erase(GlobalRoutingID(process_id, route_id));
4449 RemoveRenderWidgetHostDestructionObserver(widget_host);
[email protected]bafe6cd2012-05-23 23:09:504450
Lukasz Anforowicz5510ed652018-06-06 16:16:194451 if (!widget_host->GetProcess()->IsInitializedAndNotDead()) {
[email protected]bafe6cd2012-05-23 23:09:504452 // The view has gone away or the renderer crashed. Nothing to do.
alexmosc2a8cec2016-05-23 22:19:534453 return nullptr;
[email protected]bafe6cd2012-05-23 23:09:504454 }
4455
Avi Drissman783c1232021-02-05 01:27:054456 return widget_host->GetView();
[email protected]bafe6cd2012-05-23 23:09:504457}
4458
Mario Sanchez Pradaf68d98272020-12-09 18:47:524459void WebContentsImpl::CreateMediaPlayerHostForRenderFrameHost(
Kevin McNeefb86fcf2021-02-26 23:20:574460 RenderFrameHostImpl* frame_host,
Miyoung Shin040d8342021-02-23 15:12:314461 mojo::PendingAssociatedReceiver<media::mojom::MediaPlayerHost> receiver) {
Alexander Timin8690530c2021-06-19 00:34:324462 media_web_contents_observer()->BindMediaPlayerHost(frame_host->GetGlobalId(),
4463 std::move(receiver));
Mario Sanchez Pradaf68d98272020-12-09 18:47:524464}
4465
[email protected]f13b4202012-06-12 23:53:234466void WebContentsImpl::RequestMediaAccessPermission(
[email protected]33662e52013-01-07 21:31:094467 const MediaStreamRequest& request,
Mark Pilgrim57499082018-06-12 12:38:304468 MediaResponseCallback callback) {
Alexander Timin5fdeff22020-09-08 09:20:374469 OPTIONAL_TRACE_EVENT2("content",
4470 "WebContentsImpl::RequestMediaAccessPermission",
4471 "render_process_id", request.render_process_id,
4472 "render_frame_id", request.render_frame_id);
4473
[email protected]d19b84b2014-03-14 11:52:374474 if (delegate_) {
Mark Pilgrim57499082018-06-12 12:38:304475 delegate_->RequestMediaAccessPermission(this, request, std::move(callback));
[email protected]d19b84b2014-03-14 11:52:374476 } else {
Antonio Gomes0d42960a2019-06-05 12:35:514477 std::move(callback).Run(
Simon Hanglfd5379972022-06-09 09:36:544478 blink::mojom::StreamDevicesSet(),
Antonio Gomes0d42960a2019-06-05 12:35:514479 blink::mojom::MediaStreamRequestResult::FAILED_DUE_TO_SHUTDOWN,
4480 std::unique_ptr<MediaStreamUI>());
[email protected]d19b84b2014-03-14 11:52:374481 }
[email protected]f13b4202012-06-12 23:53:234482}
4483
Chandan Padhia4b8bcb72017-09-12 16:41:044484bool WebContentsImpl::CheckMediaAccessPermission(
Kevin McNeefb86fcf2021-02-26 23:20:574485 RenderFrameHostImpl* render_frame_host,
Chandan Padhia4b8bcb72017-09-12 16:41:044486 const url::Origin& security_origin,
Antonio Gomesc8b734b2019-06-05 18:22:164487 blink::mojom::MediaStreamType type) {
Alexander Timinf785f342021-03-18 00:00:564488 OPTIONAL_TRACE_EVENT2("content",
4489 "WebContentsImpl::CheckMediaAccessPermission",
4490 "render_frame_host", render_frame_host,
4491 "security_origin", security_origin);
Alexander Timin5fdeff22020-09-08 09:20:374492
Antonio Gomesc8b734b2019-06-05 18:22:164493 DCHECK(type == blink::mojom::MediaStreamType::DEVICE_AUDIO_CAPTURE ||
4494 type == blink::mojom::MediaStreamType::DEVICE_VIDEO_CAPTURE);
Chandan Padhia4b8bcb72017-09-12 16:41:044495 return delegate_ && delegate_->CheckMediaAccessPermission(
Raymes Khouryad7c24a12018-03-05 23:22:584496 render_frame_host, security_origin.GetURL(), type);
grunell657d4d82014-09-18 00:09:434497}
4498
Guido Urdaneta73fa6632019-01-14 18:46:264499std::string WebContentsImpl::GetDefaultMediaDeviceID(
Antonio Gomesc8b734b2019-06-05 18:22:164500 blink::mojom::MediaStreamType type) {
Alexander Timin5fdeff22020-09-08 09:20:374501 OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::GetDefaultMediaDeviceID",
4502 "type", static_cast<int>(type));
4503
guidou8a440b842017-01-30 13:58:434504 if (!delegate_)
4505 return std::string();
4506 return delegate_->GetDefaultMediaDeviceID(this, type);
4507}
4508
Elad Alonf156eb62021-05-17 22:02:374509void WebContentsImpl::SetCaptureHandleConfig(
4510 blink::mojom::CaptureHandleConfigPtr config) {
4511 DCHECK_CURRENTLY_ON(BrowserThread::UI);
4512
4513 if (capture_handle_config_ == *config) {
4514 return; // Avoid unnecessary notifications.
4515 }
4516
4517 capture_handle_config_ = std::move(*config);
4518
4519 // Propagates the capture-handle-config inside of the browser process.
4520 // Only render processes which are eligible based on |permittedOrigins|
4521 // will get this.
4522 observers_.NotifyObservers(&WebContentsObserver::OnCaptureHandleConfigUpdate,
4523 capture_handle_config_);
4524}
4525
avi85ee8362016-10-08 02:09:084526bool WebContentsImpl::IsJavaScriptDialogShowing() const {
4527 return is_showing_javascript_dialog_;
4528}
4529
avic031d392017-03-03 03:09:424530bool WebContentsImpl::ShouldIgnoreUnresponsiveRenderer() {
Minoru Chikamune562598cd2020-12-28 01:42:314531 // Suppress unresponsive renderers if the command line asks for it.
4532 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
4533 switches::kDisableHangMonitor))
4534 return true;
4535
Kevin McNeed7fc6d052022-02-08 21:21:504536 if (IsBeingDestroyed())
4537 return true;
4538
Dominique Fauteux-Chapleau99244382020-07-08 20:37:004539 if (suppress_unresponsive_renderer_count_ > 0)
4540 return true;
4541
avic031d392017-03-03 03:09:424542 // Ignore unresponsive renderers if the debugger is attached to them since the
4543 // unresponsiveness might be a result of the renderer sitting on a breakpoint.
4544 //
Xiaohan Wang00d05a02022-01-21 22:47:184545#if BUILDFLAG(IS_WIN)
David Bienvenu525f8a02019-02-15 02:02:424546 // Check if a windows debugger is attached to the renderer process.
4547 base::ProcessHandle process_handle =
Dave Tapuska327c06c92022-06-13 20:31:514548 GetPrimaryMainFrame()->GetProcess()->GetProcess().Handle();
David Bienvenu525f8a02019-02-15 02:02:424549 BOOL debugger_present = FALSE;
4550 if (CheckRemoteDebuggerPresent(process_handle, &debugger_present) &&
4551 debugger_present)
4552 return true;
Xiaohan Wang24ec9342022-01-15 17:34:224553#endif // BUILDFLAG(IS_WIN)
David Bienvenu525f8a02019-02-15 02:02:424554
avic031d392017-03-03 03:09:424555 // TODO(pfeldman): Fix this to only return true if the renderer is *actually*
4556 // sitting on a breakpoint. https://crbug.com/684202
4557 return DevToolsAgentHost::IsDebuggerAttached(this);
4558}
4559
Lucas Furukawa Gadanie1c5dfda2018-11-29 17:57:414560ui::AXMode WebContentsImpl::GetAccessibilityMode() {
[email protected]95640212014-07-26 18:14:304561 return accessibility_mode_;
4562}
4563
Mario Sanchez Prada5d7f1ac2020-07-16 17:18:404564void WebContentsImpl::AXTreeIDForMainFrameHasChanged() {
Alexander Timin5fdeff22020-09-08 09:20:374565 OPTIONAL_TRACE_EVENT0("content",
4566 "WebContentsImpl::AXTreeIDForMainFrameHasChanged");
4567
Mario Sanchez Prada5d7f1ac2020-07-16 17:18:404568 RenderWidgetHostViewBase* rwhv =
4569 static_cast<RenderWidgetHostViewBase*>(GetRenderWidgetHostView());
4570 if (rwhv)
Dave Tapuska327c06c92022-06-13 20:31:514571 rwhv->SetMainFrameAXTreeID(GetPrimaryMainFrame()->GetAXTreeID());
Mario Sanchez Prada5d7f1ac2020-07-16 17:18:404572
Andrew Grievee19cd93e2021-01-22 05:43:064573 observers_.NotifyObservers(
4574 &WebContentsObserver::AXTreeIDForMainFrameHasChanged);
Mario Sanchez Prada5d7f1ac2020-07-16 17:18:404575}
4576
Dominic Mazzonia7b0edb22017-08-09 16:32:514577void WebContentsImpl::AccessibilityEventReceived(
Dominic Mazzoniccbaa9b2018-06-06 07:44:234578 const AXEventNotificationDetails& details) {
Alexander Timin5fdeff22020-09-08 09:20:374579 OPTIONAL_TRACE_EVENT0("content",
4580 "WebContentsImpl::AccessibilityEventReceived");
Andrew Grievee19cd93e2021-01-22 05:43:064581 observers_.NotifyObservers(&WebContentsObserver::AccessibilityEventReceived,
4582 details);
[email protected]31a71eaf2014-03-13 01:47:364583}
4584
dmazzoni2400c462016-08-23 15:07:134585void WebContentsImpl::AccessibilityLocationChangesReceived(
4586 const std::vector<AXLocationChangeNotificationDetails>& details) {
Alexander Timin5fdeff22020-09-08 09:20:374587 OPTIONAL_TRACE_EVENT0(
4588 "content", "WebContentsImpl::AccessibilityLocationChangesReceived");
Andrew Grievee19cd93e2021-01-22 05:43:064589 observers_.NotifyObservers(
4590 &WebContentsObserver::AccessibilityLocationChangesReceived, details);
dmazzoni2400c462016-08-23 15:07:134591}
4592
Alexander Surkov2ab51622020-09-02 12:01:424593std::string WebContentsImpl::DumpAccessibilityTree(
Abigail Kleinabb428332019-09-13 18:26:214594 bool internal,
Alexander Surkov90482882020-10-12 16:30:384595 std::vector<ui::AXPropertyFilter> property_filters) {
Alexander Timin5fdeff22020-09-08 09:20:374596 OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::DumpAccessibilityTree");
James Wallace-Leeeafc94cb92018-07-23 21:35:094597 auto* ax_mgr = GetOrCreateRootBrowserAccessibilityManager();
Javier Contreras Tenorioaa5f70c52023-02-06 12:34:044598 // Since for Web Content we get the AXTree updates through the renderer at a
4599 // point after the manager is created, there are cases where at this point in
4600 // the lifecycle the AXTree associated with `ax_mgr` does not have a valid
4601 // tree ID. As such, if this is the case we return an empty string early. If
4602 // we don't have this check, there will be a scenario where we then try to get
4603 // the manager using the ID (which at this point is invalid) which leads to a
4604 // crash. See https://crbug.com/1405036.
Javier Contreras Tenorio4908f712023-02-08 21:42:044605 if (!ax_mgr || !ax_mgr->HasValidTreeID())
Javier Contreras Tenorioaa5f70c52023-02-06 12:34:044606 return "-";
4607
Javier Contreras Tenorio4908f712023-02-08 21:42:044608 // Developer mode: crash immediately on any accessibility fatal error.
4609 // This only runs during integration tests, or if a developer is
4610 // using an inspection tool, e.g. chrome://accessibility.
4611 BrowserAccessibilityManager::AlwaysFailFast();
4612
Alexander Surkovfb6cb382020-12-01 14:46:234613 std::unique_ptr<ui::AXTreeFormatter> formatter =
4614 internal ? AXInspectFactory::CreateBlinkFormatter()
4615 : AXInspectFactory::CreatePlatformFormatter();
4616
4617 formatter->SetPropertyFilters(property_filters);
Javier Contrerasa0039cbf2022-08-31 19:35:024618 return formatter->Format(ax_mgr->GetBrowserAccessibilityRoot());
James Wallace-Leeeafc94cb92018-07-23 21:35:094619}
4620
Abigail Kleinaa898742019-11-01 02:31:254621void WebContentsImpl::RecordAccessibilityEvents(
Abigail Kleinbb8304bd2020-05-18 21:44:184622 bool start_recording,
Anton Bikineevf62d1bf2021-05-15 17:56:074623 absl::optional<ui::AXEventCallback> callback) {
Alexander Timin5fdeff22020-09-08 09:20:374624 OPTIONAL_TRACE_EVENT0("content",
4625 "WebContentsImpl::RecordAccessibilityEvents");
Aaron Leventhal96df51a92021-12-02 23:39:014626
Abigail Kleinbb8304bd2020-05-18 21:44:184627 // Only pass a callback to RecordAccessibilityEvents when starting to record.
4628 DCHECK_EQ(start_recording, callback.has_value());
4629 if (start_recording) {
Aaron Leventhaldadb9bf2022-09-14 22:08:184630 BrowserAccessibilityStateImpl::GetInstance()->AddAccessibilityModeFlags(
Amanda Lin Dietze54912e2022-11-22 20:25:574631 ui::kAXModeBasic.flags());
Abigail Kleinaa898742019-11-01 02:31:254632 auto* ax_mgr = GetOrCreateRootBrowserAccessibilityManager();
Aaron Leventhaldadb9bf2022-09-14 22:08:184633 CHECK(ax_mgr);
Abigail Kleinaa898742019-11-01 02:31:254634 base::ProcessId pid = base::Process::Current().Pid();
Alexander Surkovf83fa6cd2022-02-11 14:01:514635 gfx::AcceleratedWidget widget =
Javier Contrerasa0039cbf2022-08-31 19:35:024636 ax_mgr->GetBrowserAccessibilityRoot()
4637 ->GetTargetForNativeAccessibilityEvent();
Alexander Surkovf83fa6cd2022-02-11 14:01:514638 event_recorder_ = content::AXInspectFactory::CreatePlatformRecorder(
Alexander Surkov34080bf2022-08-23 21:26:234639 ax_mgr, pid, ui::AXTreeSelector(widget));
Abigail Kleinbb8304bd2020-05-18 21:44:184640 event_recorder_->ListenToEvents(*callback);
Abigail Kleinaa898742019-11-01 02:31:254641 } else {
Abigail Kleinbb8304bd2020-05-18 21:44:184642 if (event_recorder_) {
Adam Ettenbergere1a5a182021-06-04 17:49:424643 event_recorder_->WaitForDoneRecording();
Abigail Kleinbb8304bd2020-05-18 21:44:184644 event_recorder_.reset(nullptr);
4645 }
Abigail Kleinaa898742019-11-01 02:31:254646 }
4647}
4648
Ke He7319dbe2017-11-09 05:54:444649device::mojom::GeolocationContext* WebContentsImpl::GetGeolocationContext() {
Alexander Timin5fdeff22020-09-08 09:20:374650 OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::GetGeolocationContext");
Ella Ge3e375b702020-06-05 15:57:164651 if (delegate_) {
4652 auto* installed_webapp_context =
4653 delegate_->GetInstalledWebappGeolocationContext();
4654 if (installed_webapp_context)
4655 return installed_webapp_context;
4656 }
4657
Ken Rockotce010f02019-12-12 23:32:324658 if (!geolocation_context_) {
4659 GetDeviceService().BindGeolocationContext(
4660 geolocation_context_.BindNewPipeAndPassReceiver());
4661 }
Conley Owens6894c4f2017-07-10 19:29:134662 return geolocation_context_.get();
blundellc57b93f2014-10-29 13:19:574663}
4664
ke.he98b761e2017-05-09 05:59:174665device::mojom::WakeLockContext* WebContentsImpl::GetWakeLockContext() {
Thoren Paulsond344c0a2021-10-14 19:20:314666 if (!enable_wake_locks_)
4667 return nullptr;
blundelld8cd72b2017-03-28 07:18:384668 if (!wake_lock_context_host_)
Fergal Daly55b6d722020-09-11 07:56:334669 wake_lock_context_host_ = std::make_unique<WakeLockContextHost>(this);
blundelle75a8f92017-03-27 08:11:174670 return wake_lock_context_host_->GetWakeLockContext();
alogvinovf50445a2015-10-30 13:00:124671}
4672
Xiaohan Wang24ec9342022-01-15 17:34:224673#if BUILDFLAG(IS_ANDROID)
Miyoung Shin59f39ff2019-09-17 07:23:204674void WebContentsImpl::GetNFC(
Reilly Grantafbe2242020-02-20 21:14:554675 RenderFrameHost* render_frame_host,
Miyoung Shin59f39ff2019-09-17 07:23:204676 mojo::PendingReceiver<device::mojom::NFC> receiver) {
Reilly Grantafbe2242020-02-20 21:14:554677 if (!nfc_host_)
4678 nfc_host_ = std::make_unique<NFCHost>(this);
4679 nfc_host_->GetNFC(render_frame_host, std::move(receiver));
blundellf5316fc2017-05-15 11:49:034680}
4681#endif
4682
lfgbb9c28a2016-03-01 03:19:494683void WebContentsImpl::SendScreenRects() {
Alexander Timin5fdeff22020-09-08 09:20:374684 OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::SendScreenRects");
Kevin McNeed7fc6d052022-02-08 21:21:504685
4686 DCHECK(!IsBeingDestroyed());
4687
Dave Tapuska327c06c92022-06-13 20:31:514688 GetPrimaryMainFrame()->ForEachRenderFrameHost(
Daniel Cheng982f2b22022-08-25 23:46:164689 [](RenderFrameHostImpl* render_frame_host) {
Dave Tapuska41fbb6e2021-12-07 01:11:414690 if (render_frame_host->is_local_root()) {
4691 render_frame_host->GetRenderWidgetHost()->SendScreenRects();
4692 }
Daniel Cheng982f2b22022-08-25 23:46:164693 });
[email protected]32deec62013-05-15 23:55:044694}
4695
Dave Tapuska3450d0b2022-04-08 21:27:534696void WebContentsImpl::SendActiveState(bool active) {
4697 DCHECK(!IsBeingDestroyed());
4698
4699 // Replicate the active state to all LocalRoots.
Daniel Cheng982f2b22022-08-25 23:46:164700 GetPrimaryMainFrame()->ForEachRenderFrameHost(
4701 [active](RenderFrameHostImpl* render_frame_host) {
Dave Tapuska3450d0b2022-04-08 21:27:534702 if (render_frame_host->is_local_root()) {
4703 render_frame_host->GetRenderWidgetHost()->SetActive(active);
4704 }
Daniel Cheng982f2b22022-08-25 23:46:164705 });
Dave Tapuska3450d0b2022-04-08 21:27:534706}
4707
ekaramadadd882292016-06-08 15:22:564708TextInputManager* WebContentsImpl::GetTextInputManager() {
David Bokane86aa032022-05-08 18:21:244709 if (suppress_ime_events_for_testing_)
4710 return nullptr;
4711
ekaramadadd882292016-06-08 15:22:564712 if (GetOuterWebContents())
4713 return GetOuterWebContents()->GetTextInputManager();
4714
Ehsan Karamadc179dc02018-12-15 03:09:294715 if (!text_input_manager_ && !browser_plugin_guest_) {
Fergal Daly55b6d722020-09-11 07:56:334716 text_input_manager_ = std::make_unique<TextInputManager>(
Darren Shenca53d5f2018-05-15 04:56:014717 GetBrowserContext() &&
Fergal Daly55b6d722020-09-11 07:56:334718 !GetBrowserContext()->IsOffTheRecord() /* should_do_learning */);
Darren Shenca53d5f2018-05-15 04:56:014719 }
ekaramadadd882292016-06-08 15:22:564720
4721 return text_input_manager_.get();
4722}
4723
Dave Tapuska1d72e332021-10-13 19:24:384724bool WebContentsImpl::IsWidgetForPrimaryMainFrame(
kenrb11f213a2017-03-24 18:12:064725 RenderWidgetHostImpl* render_widget_host) {
Dave Tapuska327c06c92022-06-13 20:31:514726 return render_widget_host == GetPrimaryMainFrame()->GetRenderWidgetHost();
kenrb11f213a2017-03-24 18:12:064727}
4728
[email protected]95640212014-07-26 18:14:304729BrowserAccessibilityManager*
Alexander Timin5fdeff22020-09-08 09:20:374730WebContentsImpl::GetRootBrowserAccessibilityManager() {
Dave Tapuska327c06c92022-06-13 20:31:514731 RenderFrameHostImpl* rfh =
4732 static_cast<RenderFrameHostImpl*>(GetPrimaryMainFrame());
creisc014b402015-04-23 16:41:454733 return rfh ? rfh->browser_accessibility_manager() : nullptr;
[email protected]95640212014-07-26 18:14:304734}
4735
4736BrowserAccessibilityManager*
Alexander Timin5fdeff22020-09-08 09:20:374737WebContentsImpl::GetOrCreateRootBrowserAccessibilityManager() {
Dave Tapuska327c06c92022-06-13 20:31:514738 RenderFrameHostImpl* rfh =
4739 static_cast<RenderFrameHostImpl*>(GetPrimaryMainFrame());
creisc014b402015-04-23 16:41:454740 return rfh ? rfh->GetOrCreateBrowserAccessibilityManager() : nullptr;
[email protected]95640212014-07-26 18:14:304741}
4742
Dave Tapuskab336b922017-07-06 19:24:054743void WebContentsImpl::ExecuteEditCommand(
4744 const std::string& command,
Anton Bikineevf62d1bf2021-05-15 17:56:074745 const absl::optional<std::u16string>& value) {
Alexander Timin5fdeff22020-09-08 09:20:374746 OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::ExecuteEditCommand");
Dave Tapuska58a099e2020-06-08 21:48:404747 auto* input_handler = GetFocusedFrameWidgetInputHandler();
Dave Tapuskae782bea2019-07-09 16:21:514748 if (!input_handler)
Dave Tapuskab336b922017-07-06 19:24:054749 return;
4750
Dave Tapuskae782bea2019-07-09 16:21:514751 input_handler->ExecuteEditCommand(command, value);
Dave Tapuskab336b922017-07-06 19:24:054752}
4753
mohsen7ab1ec16ec2015-07-02 18:26:234754void WebContentsImpl::MoveRangeSelectionExtent(const gfx::Point& extent) {
Alexander Timin5fdeff22020-09-08 09:20:374755 OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::MoveRangeSelectionExtent");
Dave Tapuska58a099e2020-06-08 21:48:404756 auto* input_handler = GetFocusedFrameWidgetInputHandler();
Dave Tapuskae782bea2019-07-09 16:21:514757 if (!input_handler)
mohsen7ab1ec16ec2015-07-02 18:26:234758 return;
4759
Dave Tapuskae782bea2019-07-09 16:21:514760 input_handler->MoveRangeSelectionExtent(extent);
mohsen7ab1ec16ec2015-07-02 18:26:234761}
4762
4763void WebContentsImpl::SelectRange(const gfx::Point& base,
4764 const gfx::Point& extent) {
Alexander Timin5fdeff22020-09-08 09:20:374765 OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::SelectRange");
Dave Tapuska58a099e2020-06-08 21:48:404766 auto* input_handler = GetFocusedFrameWidgetInputHandler();
Dave Tapuskae782bea2019-07-09 16:21:514767 if (!input_handler)
mohsen7ab1ec16ec2015-07-02 18:26:234768 return;
4769
Dave Tapuskae782bea2019-07-09 16:21:514770 input_handler->SelectRange(base, extent);
mohsen7ab1ec16ec2015-07-02 18:26:234771}
4772
Dave Tapuskab336b922017-07-06 19:24:054773void WebContentsImpl::MoveCaret(const gfx::Point& extent) {
Alexander Timin5fdeff22020-09-08 09:20:374774 OPTIONAL_TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("content.verbose"),
4775 "WebContentsImpl::MoveCaret");
Dave Tapuska58a099e2020-06-08 21:48:404776 auto* input_handler = GetFocusedFrameWidgetInputHandler();
Dave Tapuskae782bea2019-07-09 16:21:514777 if (!input_handler)
Dave Tapuskab336b922017-07-06 19:24:054778 return;
4779
Dave Tapuskae782bea2019-07-09 16:21:514780 input_handler->MoveCaret(extent);
Dave Tapuskab336b922017-07-06 19:24:054781}
4782
Shimi Zhang37deeb22017-09-28 00:59:014783void WebContentsImpl::AdjustSelectionByCharacterOffset(
4784 int start_adjust,
4785 int end_adjust,
4786 bool show_selection_menu) {
Alexander Timin5fdeff22020-09-08 09:20:374787 OPTIONAL_TRACE_EVENT0("content",
4788 "WebContentsImpl::AdjustSelectionByCharacterOffset");
Dave Tapuska58a099e2020-06-08 21:48:404789 auto* input_handler = GetFocusedFrameWidgetInputHandler();
Dave Tapuskae782bea2019-07-09 16:21:514790 if (!input_handler)
aurimasab0319022015-07-10 21:57:384791 return;
4792
Shimi Zhang37deeb22017-09-28 00:59:014793 using blink::mojom::SelectionMenuBehavior;
Dave Tapuskae782bea2019-07-09 16:21:514794 input_handler->AdjustSelectionByCharacterOffset(
Shimi Zhang37deeb22017-09-28 00:59:014795 start_adjust, end_adjust,
4796 show_selection_menu ? SelectionMenuBehavior::kShow
4797 : SelectionMenuBehavior::kHide);
aurimasab0319022015-07-10 21:57:384798}
4799
avic3aa8422015-11-09 20:57:224800void WebContentsImpl::ResizeDueToAutoResize(
4801 RenderWidgetHostImpl* render_widget_host,
Fady Samuel97947112018-05-05 16:24:544802 const gfx::Size& new_size) {
Alexander Timin5fdeff22020-09-08 09:20:374803 OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::ResizeDueToAutoResize",
Alexander Timinf785f342021-03-18 00:00:564804 "render_widget_host", render_widget_host);
avic3aa8422015-11-09 20:57:224805 if (render_widget_host != GetRenderViewHost()->GetWidget())
4806 return;
4807
[email protected]61e2b3cc2012-03-02 16:13:344808 if (delegate_)
4809 delegate_->ResizeDueToAutoResize(this, new_size);
4810}
4811
[email protected]b172aee2012-04-10 17:05:264812WebContents* WebContentsImpl::OpenURL(const OpenURLParams& params) {
Alexander Timinf785f342021-03-18 00:00:564813 TRACE_EVENT1("content", "WebContentsImpl::OpenURL", "url", params.url);
Aaron Colwell9dab1652019-12-09 18:29:494814#if DCHECK_IS_ON()
4815 DCHECK(params.Valid());
4816#endif
4817
Bo Liu300c6052018-06-12 04:46:074818 if (!delegate_) {
4819 // Embedder can delay setting a delegate on new WebContents with
4820 // WebContentsDelegate::ShouldResumeRequestsForCreatedWindow. In the mean
4821 // time, navigations, including the initial one, that goes through OpenURL
4822 // should be delayed until embedder is ready to resume loading.
4823 delayed_open_url_params_ = std::make_unique<OpenURLParams>(params);
Nasko Oskov83a8cf92018-10-19 14:58:564824
4825 // If there was a navigation deferred when creating the window through
4826 // CreateNewWindow, drop it in favor of this navigation.
4827 delayed_load_url_params_.reset();
4828
Ivan Kotenkov2c0d2bb32017-11-01 15:41:284829 return nullptr;
Bo Liu300c6052018-06-12 04:46:074830 }
[email protected]00c37fc2011-08-02 00:22:504831
pnoland488944652017-02-22 18:58:544832 RenderFrameHost* source_render_frame_host = RenderFrameHost::FromID(
4833 params.source_render_process_id, params.source_render_frame_id);
4834
David Bokan8cb28a522021-05-26 18:50:594835 // Prevent frames that are not active (e.g. a prerendering page) from opening
4836 // new windows, tabs, popups, etc.
Ian Vollickf6725a2e2021-05-20 14:21:304837 if (params.disposition != WindowOpenDisposition::CURRENT_TAB &&
Sreeja Kamishettye49854f82021-06-02 00:52:034838 source_render_frame_host && !source_render_frame_host->IsActive()) {
Ian Vollickf6725a2e2021-05-20 14:21:304839 return nullptr;
4840 }
4841
David Bokan534f1f42021-05-21 18:55:414842 if (params.frame_tree_node_id != FrameTreeNode::kFrameTreeNodeInvalidId) {
4843 if (auto* frame_tree_node =
4844 FrameTreeNode::GloballyFindByID(params.frame_tree_node_id)) {
4845 // If a frame tree node ID is specified and it exists, ensure it is for a
4846 // node within this WebContents. Note: this WebContents could be hosting
4847 // multiple frame trees (e.g. prerendering) so it's not enough to check
Carlos Caballerob65b6e3a2021-11-15 10:09:004848 // against this->primary_frame_tree_. Check against page_delegate(), which
4849 // is always a WebContentsImpl, while delegate() may be implemented by
Matt Falkenhagen7b37cf492021-09-30 08:32:164850 // something else such as for prerendered frame trees.
Arthur Sonzognif6785ec2022-12-05 10:11:504851 FrameTree& frame_tree = frame_tree_node->frame_tree();
4852 CHECK_EQ(frame_tree.page_delegate(), this);
David Bokan8cb28a522021-05-26 18:50:594853
Dave Tapuska42dc0310e2022-03-16 20:40:574854 // Prerendering and fenced frame navigations are hidden from embedders.
4855 // If the navigation is targeting a frame in a prerendering or fenced
4856 // frame tree, we shouldn't run that navigation through the embedder
4857 // delegate. Embedder implementations of
4858 // `WebContentsDelegate::OpenURLFromTab` assume that the primary
4859 // frame tree Navigation controller should be used for navigating.
4860 // Instead, we just navigate directly on the relevant frame
4861 // tree.
Arthur Sonzognif6785ec2022-12-05 10:11:504862 if (frame_tree.type() == FrameTree::Type::kPrerender ||
Abhijeet Kandalkar749b8bf12022-12-14 16:41:484863 frame_tree_node->IsInFencedFrameTree()) {
Hiroki Nakagawa5b82ee442021-09-20 17:17:204864 DCHECK_EQ(params.disposition, WindowOpenDisposition::CURRENT_TAB);
Arthur Sonzognif6785ec2022-12-05 10:11:504865 frame_tree.controller().LoadURLWithParams(
Hiroki Nakagawa5b82ee442021-09-20 17:17:204866 NavigationController::LoadURLParams(params));
4867 return this;
David Bokan8cb28a522021-05-26 18:50:594868 }
David Bokan534f1f42021-05-21 18:55:414869 } else {
4870 // If the node doesn't exist it was probably removed from its frame tree.
4871 // In that case, abort since continuing would navigate the root frame.
4872 return nullptr;
4873 }
4874 }
4875
Ian Vollickf6725a2e2021-05-20 14:21:304876 WebContents* new_contents = delegate_->OpenURLFromTab(this, params);
4877
pnoland488944652017-02-22 18:58:544878 if (source_render_frame_host && params.source_site_instance) {
4879 CHECK_EQ(source_render_frame_host->GetSiteInstance(),
4880 params.source_site_instance.get());
4881 }
4882
4883 if (new_contents && source_render_frame_host && new_contents != this) {
Andrew Grievee19cd93e2021-01-22 05:43:064884 observers_.NotifyObservers(
4885 &WebContentsObserver::DidOpenRequestedURL, new_contents,
4886 source_render_frame_host, params.url, params.referrer,
4887 params.disposition, params.transition, params.started_from_context_menu,
4888 params.is_renderer_initiated);
pnoland488944652017-02-22 18:58:544889 }
4890
[email protected]e5d549d2011-12-28 01:29:204891 return new_contents;
[email protected]d5f942ba2008-09-26 19:30:344892}
4893
avi2b177592014-12-10 02:08:024894void WebContentsImpl::SetHistoryOffsetAndLengthForView(
4895 RenderViewHost* render_view_host,
4896 int history_offset,
4897 int history_length) {
Alexander Timin5fdeff22020-09-08 09:20:374898 OPTIONAL_TRACE_EVENT2(
4899 "content", "WebContentsImpl::SetHistoryOffsetAndLengthForView",
4900 "history_offset", history_offset, "history_length", history_length);
Dave Tapuskac0888292020-10-30 22:50:104901 if (auto& broadcast = static_cast<RenderViewHostImpl*>(render_view_host)
4902 ->GetAssociatedPageBroadcast())
4903 broadcast->SetHistoryOffsetAndLength(history_offset, history_length);
[email protected]796931a92011-08-10 01:32:144904}
4905
arthursonzogni818c2642019-09-27 12:18:104906void WebContentsImpl::ReloadFocusedFrame() {
Alexander Timin5fdeff22020-09-08 09:20:374907 OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::ReloadFocusedFrame");
[email protected]1f3fc1d2014-04-03 14:50:174908 RenderFrameHost* focused_frame = GetFocusedFrame();
4909 if (!focused_frame)
4910 return;
4911
yilkal921048bd2019-10-09 23:51:044912 focused_frame->Reload();
[email protected]959be4c2014-04-08 15:01:334913}
4914
4915void WebContentsImpl::Undo() {
Alexander Timin5fdeff22020-09-08 09:20:374916 OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::Undo");
Dave Tapuska58a099e2020-06-08 21:48:404917 auto* input_handler = GetFocusedFrameWidgetInputHandler();
Dave Tapuskae782bea2019-07-09 16:21:514918 if (!input_handler)
[email protected]959be4c2014-04-08 15:01:334919 return;
4920
Evan Stade6decc972022-10-24 19:42:184921 last_interaction_time_ = ui::EventTimeForNow();
Dave Tapuskae782bea2019-07-09 16:21:514922 input_handler->Undo();
[email protected]959be4c2014-04-08 15:01:334923 RecordAction(base::UserMetricsAction("Undo"));
4924}
4925
4926void WebContentsImpl::Redo() {
Alexander Timin5fdeff22020-09-08 09:20:374927 OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::Redo");
Dave Tapuska58a099e2020-06-08 21:48:404928 auto* input_handler = GetFocusedFrameWidgetInputHandler();
Dave Tapuskae782bea2019-07-09 16:21:514929 if (!input_handler)
[email protected]959be4c2014-04-08 15:01:334930 return;
Dave Tapuskae782bea2019-07-09 16:21:514931
Evan Stade6decc972022-10-24 19:42:184932 last_interaction_time_ = ui::EventTimeForNow();
Dave Tapuskae782bea2019-07-09 16:21:514933 input_handler->Redo();
[email protected]959be4c2014-04-08 15:01:334934 RecordAction(base::UserMetricsAction("Redo"));
4935}
4936
4937void WebContentsImpl::Cut() {
Alexander Timin5fdeff22020-09-08 09:20:374938 OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::Cut");
Dave Tapuska58a099e2020-06-08 21:48:404939 auto* input_handler = GetFocusedFrameWidgetInputHandler();
Dave Tapuskae782bea2019-07-09 16:21:514940 if (!input_handler)
[email protected]959be4c2014-04-08 15:01:334941 return;
4942
Evan Stade6decc972022-10-24 19:42:184943 last_interaction_time_ = ui::EventTimeForNow();
Dave Tapuskae782bea2019-07-09 16:21:514944 input_handler->Cut();
[email protected]959be4c2014-04-08 15:01:334945 RecordAction(base::UserMetricsAction("Cut"));
4946}
4947
4948void WebContentsImpl::Copy() {
Alexander Timin5fdeff22020-09-08 09:20:374949 OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::Copy");
Dave Tapuska58a099e2020-06-08 21:48:404950 auto* input_handler = GetFocusedFrameWidgetInputHandler();
Dave Tapuskae782bea2019-07-09 16:21:514951 if (!input_handler)
[email protected]959be4c2014-04-08 15:01:334952 return;
4953
Evan Stade6decc972022-10-24 19:42:184954 last_interaction_time_ = ui::EventTimeForNow();
Dave Tapuskae782bea2019-07-09 16:21:514955 input_handler->Copy();
[email protected]959be4c2014-04-08 15:01:334956 RecordAction(base::UserMetricsAction("Copy"));
4957}
4958
4959void WebContentsImpl::CopyToFindPboard() {
Alexander Timin5fdeff22020-09-08 09:20:374960 OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::CopyToFindPboard");
Xiaohan Wang24ec9342022-01-15 17:34:224961#if BUILDFLAG(IS_MAC)
Dave Tapuska58a099e2020-06-08 21:48:404962 auto* input_handler = GetFocusedFrameWidgetInputHandler();
Dave Tapuskae782bea2019-07-09 16:21:514963 if (!input_handler)
[email protected]959be4c2014-04-08 15:01:334964 return;
4965
Evan Stade6decc972022-10-24 19:42:184966 last_interaction_time_ = ui::EventTimeForNow();
[email protected]959be4c2014-04-08 15:01:334967 // Windows/Linux don't have the concept of a find pasteboard.
Dave Tapuskae782bea2019-07-09 16:21:514968 input_handler->CopyToFindPboard();
[email protected]959be4c2014-04-08 15:01:334969 RecordAction(base::UserMetricsAction("CopyToFindPboard"));
4970#endif
4971}
4972
4973void WebContentsImpl::Paste() {
Alexander Timin5fdeff22020-09-08 09:20:374974 OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::Paste");
Dave Tapuska58a099e2020-06-08 21:48:404975 auto* input_handler = GetFocusedFrameWidgetInputHandler();
Dave Tapuskae782bea2019-07-09 16:21:514976 if (!input_handler)
[email protected]959be4c2014-04-08 15:01:334977 return;
4978
Evan Stade6decc972022-10-24 19:42:184979 last_interaction_time_ = ui::EventTimeForNow();
Dave Tapuskae782bea2019-07-09 16:21:514980 input_handler->Paste();
Andrew Grievee19cd93e2021-01-22 05:43:064981 observers_.NotifyObservers(&WebContentsObserver::OnPaste);
[email protected]959be4c2014-04-08 15:01:334982 RecordAction(base::UserMetricsAction("Paste"));
4983}
4984
4985void WebContentsImpl::PasteAndMatchStyle() {
Alexander Timin5fdeff22020-09-08 09:20:374986 OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::PasteAndMatchStyle");
Dave Tapuska58a099e2020-06-08 21:48:404987 auto* input_handler = GetFocusedFrameWidgetInputHandler();
Dave Tapuskae782bea2019-07-09 16:21:514988 if (!input_handler)
[email protected]959be4c2014-04-08 15:01:334989 return;
4990
Evan Stade6decc972022-10-24 19:42:184991 last_interaction_time_ = ui::EventTimeForNow();
Dave Tapuskae782bea2019-07-09 16:21:514992 input_handler->PasteAndMatchStyle();
Andrew Grievee19cd93e2021-01-22 05:43:064993 observers_.NotifyObservers(&WebContentsObserver::OnPaste);
[email protected]959be4c2014-04-08 15:01:334994 RecordAction(base::UserMetricsAction("PasteAndMatchStyle"));
4995}
4996
4997void WebContentsImpl::Delete() {
Alexander Timin5fdeff22020-09-08 09:20:374998 OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::Delete");
Dave Tapuska58a099e2020-06-08 21:48:404999 auto* input_handler = GetFocusedFrameWidgetInputHandler();
Dave Tapuskae782bea2019-07-09 16:21:515000 if (!input_handler)
[email protected]959be4c2014-04-08 15:01:335001 return;
5002
Evan Stade6decc972022-10-24 19:42:185003 last_interaction_time_ = ui::EventTimeForNow();
Dave Tapuskae782bea2019-07-09 16:21:515004 input_handler->Delete();
[email protected]959be4c2014-04-08 15:01:335005 RecordAction(base::UserMetricsAction("DeleteSelection"));
5006}
5007
5008void WebContentsImpl::SelectAll() {
Alexander Timin5fdeff22020-09-08 09:20:375009 OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::SelectAll");
Dave Tapuska58a099e2020-06-08 21:48:405010 auto* input_handler = GetFocusedFrameWidgetInputHandler();
Dave Tapuskae782bea2019-07-09 16:21:515011 if (!input_handler)
[email protected]959be4c2014-04-08 15:01:335012 return;
5013
Evan Stade6decc972022-10-24 19:42:185014 last_interaction_time_ = ui::EventTimeForNow();
Dave Tapuskae782bea2019-07-09 16:21:515015 input_handler->SelectAll();
[email protected]959be4c2014-04-08 15:01:335016 RecordAction(base::UserMetricsAction("SelectAll"));
5017}
5018
yabinh351e7ec2017-03-10 02:43:245019void WebContentsImpl::CollapseSelection() {
Alexander Timin5fdeff22020-09-08 09:20:375020 OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::CollapseSelection");
Dave Tapuska58a099e2020-06-08 21:48:405021 auto* input_handler = GetFocusedFrameWidgetInputHandler();
Dave Tapuskae782bea2019-07-09 16:21:515022 if (!input_handler)
[email protected]959be4c2014-04-08 15:01:335023 return;
5024
Evan Stade6decc972022-10-24 19:42:185025 last_interaction_time_ = ui::EventTimeForNow();
Dave Tapuskae782bea2019-07-09 16:21:515026 input_handler->CollapseSelection();
[email protected]1f3fc1d2014-04-03 14:50:175027}
5028
Leonard Greyf378e7d2021-03-25 20:53:505029void WebContentsImpl::ScrollToTopOfDocument() {
Anton Bikineevf62d1bf2021-05-15 17:56:075030 ExecuteEditCommand("ScrollToBeginningOfDocument", absl::nullopt);
Leonard Greyf378e7d2021-03-25 20:53:505031}
5032
5033void WebContentsImpl::ScrollToBottomOfDocument() {
Anton Bikineevf62d1bf2021-05-15 17:56:075034 ExecuteEditCommand("ScrollToEndOfDocument", absl::nullopt);
Leonard Greyf378e7d2021-03-25 20:53:505035}
5036
Jan Wilken Dörrieaace0cfef2021-03-11 22:01:585037void WebContentsImpl::Replace(const std::u16string& word) {
Alexander Timin5fdeff22020-09-08 09:20:375038 OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::Replace");
Dave Tapuska58a099e2020-06-08 21:48:405039 auto* input_handler = GetFocusedFrameWidgetInputHandler();
Dave Tapuskae782bea2019-07-09 16:21:515040 if (!input_handler)
[email protected]1f3fc1d2014-04-03 14:50:175041 return;
5042
Evan Stade6decc972022-10-24 19:42:185043 last_interaction_time_ = ui::EventTimeForNow();
Dave Tapuskae782bea2019-07-09 16:21:515044 input_handler->Replace(word);
[email protected]1f3fc1d2014-04-03 14:50:175045}
5046
Jan Wilken Dörrieaace0cfef2021-03-11 22:01:585047void WebContentsImpl::ReplaceMisspelling(const std::u16string& word) {
Alexander Timin5fdeff22020-09-08 09:20:375048 OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::ReplaceMisspelling");
Dave Tapuska58a099e2020-06-08 21:48:405049 auto* input_handler = GetFocusedFrameWidgetInputHandler();
Dave Tapuskae782bea2019-07-09 16:21:515050 if (!input_handler)
[email protected]1f3fc1d2014-04-03 14:50:175051 return;
5052
Evan Stade6decc972022-10-24 19:42:185053 last_interaction_time_ = ui::EventTimeForNow();
Dave Tapuskae782bea2019-07-09 16:21:515054 input_handler->ReplaceMisspelling(word);
[email protected]959be4c2014-04-08 15:01:335055}
5056
Gyuyoung Kim1bc1ba82021-02-08 23:32:445057void WebContentsImpl::NotifyContextMenuClosed(const GURL& link_followed) {
Alexander Timin5fdeff22020-09-08 09:20:375058 OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::NotifyContextMenuClosed");
[email protected]959be4c2014-04-08 15:01:335059 RenderFrameHost* focused_frame = GetFocusedFrame();
5060 if (!focused_frame)
5061 return;
5062
Gyuyoung Kim1bc1ba82021-02-08 23:32:445063 if (context_menu_client_)
5064 context_menu_client_->ContextMenuClosed(link_followed);
5065
5066 context_menu_client_.reset();
[email protected]959be4c2014-04-08 15:01:335067}
5068
5069void WebContentsImpl::ExecuteCustomContextMenuCommand(
Gyuyoung Kim49b81f92021-01-23 10:20:585070 int action,
Gyuyoung Kim1bc1ba82021-02-08 23:32:445071 const GURL& link_followed) {
Alexander Timin5fdeff22020-09-08 09:20:375072 OPTIONAL_TRACE_EVENT1("content",
5073 "WebContentsImpl::ExecuteCustomContextMenuCommand",
5074 "action", action);
[email protected]959be4c2014-04-08 15:01:335075 RenderFrameHost* focused_frame = GetFocusedFrame();
5076 if (!focused_frame)
5077 return;
5078
Gyuyoung Kim1bc1ba82021-02-08 23:32:445079 if (context_menu_client_)
5080 context_menu_client_->CustomContextMenuAction(action);
[email protected]4fed3702014-04-01 09:08:005081}
5082
[email protected]fc2b46b2014-05-03 16:33:455083gfx::NativeView WebContentsImpl::GetNativeView() {
5084 return view_->GetNativeView();
5085}
5086
5087gfx::NativeView WebContentsImpl::GetContentNativeView() {
5088 return view_->GetContentNativeView();
5089}
5090
5091gfx::NativeWindow WebContentsImpl::GetTopLevelNativeWindow() {
5092 return view_->GetTopLevelNativeWindow();
5093}
5094
5095gfx::Rect WebContentsImpl::GetViewBounds() {
5096 return view_->GetViewBounds();
5097}
5098
5099gfx::Rect WebContentsImpl::GetContainerBounds() {
Jeremy Roman352239c2020-05-21 16:31:325100 return view_->GetContainerBounds();
[email protected]fc2b46b2014-05-03 16:33:455101}
5102
5103DropData* WebContentsImpl::GetDropData() {
5104 return view_->GetDropData();
5105}
5106
5107void WebContentsImpl::Focus() {
Alexander Timin5fdeff22020-09-08 09:20:375108 OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::Focus");
miu9e14e492014-10-25 02:39:045109 view_->Focus();
[email protected]fc2b46b2014-05-03 16:33:455110}
5111
5112void WebContentsImpl::SetInitialFocus() {
Alexander Timin5fdeff22020-09-08 09:20:375113 OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::SetInitialFocus");
miu9e14e492014-10-25 02:39:045114 view_->SetInitialFocus();
[email protected]fc2b46b2014-05-03 16:33:455115}
5116
5117void WebContentsImpl::StoreFocus() {
Alexander Timin5fdeff22020-09-08 09:20:375118 OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::StoreFocus");
miu9e14e492014-10-25 02:39:045119 view_->StoreFocus();
[email protected]fc2b46b2014-05-03 16:33:455120}
5121
5122void WebContentsImpl::RestoreFocus() {
Alexander Timin5fdeff22020-09-08 09:20:375123 OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::RestoreFocus");
miu9e14e492014-10-25 02:39:045124 view_->RestoreFocus();
[email protected]fc2b46b2014-05-03 16:33:455125}
5126
[email protected]b172aee2012-04-10 17:05:265127void WebContentsImpl::FocusThroughTabTraversal(bool reverse) {
Alexander Timin5fdeff22020-09-08 09:20:375128 OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::FocusThroughTabTraversal",
5129 "reverse", reverse);
Maxim Podgorodskiya926c4ff2017-11-20 02:06:395130 view_->FocusThroughTabTraversal(reverse);
[email protected]96d185d2009-04-24 03:28:545131}
5132
[email protected]b172aee2012-04-10 17:05:265133bool WebContentsImpl::IsSavable() {
[email protected]a53209b2012-01-20 16:48:165134 // WebKit creates Document object when MIME type is application/xhtml+xml,
5135 // so we also support this MIME type.
Yuzu Saijoc23e9b72020-06-25 07:21:275136 std::string mime_type = GetContentsMimeType();
5137 return mime_type == "text/html" || mime_type == "text/xml" ||
5138 mime_type == "application/xhtml+xml" || mime_type == "text/plain" ||
5139 mime_type == "text/css" ||
5140 blink::IsSupportedJavascriptMimeType(mime_type);
[email protected]a53209b2012-01-20 16:48:165141}
5142
[email protected]b172aee2012-04-10 17:05:265143void WebContentsImpl::OnSavePage() {
Alexander Timin5fdeff22020-09-08 09:20:375144 OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::OnSavePage");
[email protected]c7dd2f62011-07-18 15:57:595145 // If we can not save the page, try to download it.
[email protected]a53209b2012-01-20 16:48:165146 if (!IsSavable()) {
Min Qinda0ed2062018-02-23 22:00:535147 download::RecordSavePackageEvent(
5148 download::SAVE_PACKAGE_DOWNLOAD_ON_NON_HTML);
Dave Tapuska327c06c92022-06-13 20:31:515149 SaveFrame(GetLastCommittedURL(), Referrer(), GetPrimaryMainFrame());
[email protected]27678b2a2012-02-04 22:09:145150 return;
[email protected]c7dd2f62011-07-18 15:57:595151 }
5152
5153 Stop();
5154
5155 // Create the save package and possibly prompt the user for the name to save
5156 // the page as. The user prompt is an asynchronous operation that runs on
5157 // another thread.
Dave Tapuska765a2f62021-07-07 20:52:235158 save_package_ = new SavePackage(GetPrimaryPage());
[email protected]c7dd2f62011-07-18 15:57:595159 save_package_->GetSaveInfo();
5160}
5161
5162// Used in automated testing to bypass prompting the user for file names.
5163// Instead, the names and paths are hard coded rather than running them through
5164// file name sanitation and extension / mime checking.
[email protected]2dec8ec2013-02-07 19:20:345165bool WebContentsImpl::SavePage(const base::FilePath& main_file,
5166 const base::FilePath& dir_path,
[email protected]8ff00d72012-10-23 19:12:215167 SavePageType save_type) {
Alexander Timin5fdeff22020-09-08 09:20:375168 OPTIONAL_TRACE_EVENT2("content", "WebContentsImpl::SavePage", "main_file",
Alexander Timinf785f342021-03-18 00:00:565169 main_file, "dir_path", dir_path);
[email protected]c7dd2f62011-07-18 15:57:595170 // Stop the page from navigating.
5171 Stop();
5172
Dave Tapuska765a2f62021-07-07 20:52:235173 save_package_ =
5174 new SavePackage(GetPrimaryPage(), save_type, main_file, dir_path);
[email protected]8ff00d72012-10-23 19:12:215175 return save_package_->Init(SavePackageDownloadCreatedCallback());
[email protected]c7dd2f62011-07-18 15:57:595176}
5177
Yao Xiaoe5007042021-02-26 02:32:095178void WebContentsImpl::SaveFrame(const GURL& url,
5179 const Referrer& referrer,
5180 RenderFrameHost* rfh) {
Alexander Timin5fdeff22020-09-08 09:20:375181 OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::SaveFrame");
Jan Wilken Dörrieaace0cfef2021-03-11 22:01:585182 SaveFrameWithHeaders(url, referrer, std::string(), std::u16string(), rfh);
kundaji6c7f9692015-03-09 18:00:375183}
5184
Xing Liu10329bf2018-03-20 19:22:145185void WebContentsImpl::SaveFrameWithHeaders(
5186 const GURL& url,
5187 const Referrer& referrer,
5188 const std::string& headers,
Jan Wilken Dörrieaace0cfef2021-03-11 22:01:585189 const std::u16string& suggested_filename,
Yao Xiaoe5007042021-02-26 02:32:095190 RenderFrameHost* rfh) {
5191 DCHECK(rfh);
Jeremy Romancfa82c652021-07-06 21:43:275192 auto& rfhi = *static_cast<RenderFrameHostImpl*>(rfh);
Yao Xiaoe5007042021-02-26 02:32:095193
Alexander Timin5fdeff22020-09-08 09:20:375194 OPTIONAL_TRACE_EVENT2("content", "WebContentsImpl::SaveFrameWithHeaders",
Alexander Timinf785f342021-03-18 00:00:565195 "url", url, "headers", headers);
Lei Zhang13a42e42019-02-19 23:28:115196 // Check and see if the guest can handle this.
5197 if (delegate_) {
5198 WebContents* guest_web_contents = nullptr;
5199 if (browser_plugin_embedder_) {
5200 BrowserPluginGuest* guest = browser_plugin_embedder_->GetFullPageGuest();
5201 if (guest)
5202 guest_web_contents = guest->GetWebContents();
5203 } else if (browser_plugin_guest_) {
5204 guest_web_contents = this;
5205 }
5206
5207 if (guest_web_contents && delegate_->GuestSaveFrame(guest_web_contents))
5208 return;
5209 }
5210
nasko89ad7742015-03-05 22:14:195211 if (!GetLastCommittedURL().is_valid())
[email protected]3c71576ce2013-07-23 02:00:015212 return;
Yao Xiaoe5007042021-02-26 02:32:095213 if (delegate_ && delegate_->SaveFrame(url, referrer, rfh))
sammc92af61552014-11-19 23:27:405214 return;
5215
avib7348942015-12-25 20:57:105216 int64_t post_id = -1;
Jeremy Romancfa82c652021-07-06 21:43:275217 if (rfhi.is_main_frame()) {
5218 NavigationEntry* entry =
5219 rfhi.frame_tree()->controller().GetLastCommittedEntry();
[email protected]3c71576ce2013-07-23 02:00:015220 if (entry)
5221 post_id = entry->GetPostID();
5222 }
Ramin Halavati24e21012017-07-10 12:56:065223 net::NetworkTrafficAnnotationTag traffic_annotation =
5224 net::DefineNetworkTrafficAnnotation("download_web_contents_frame", R"(
5225 semantics {
5226 sender: "Save Page Action"
5227 description:
5228 "Saves the given frame's URL to the local file system."
5229 trigger:
5230 "The user has triggered a save operation on the frame through a "
5231 "context menu or other mechanism."
5232 data: "None."
5233 destination: WEBSITE
5234 }
5235 policy {
Ramin Halavati3b979782017-07-21 11:40:265236 cookies_allowed: YES
Ramin Halavati24e21012017-07-10 12:56:065237 cookies_store: "user"
5238 setting:
5239 "This feature cannot be disabled by settings, but it's is only "
5240 "triggered by user request."
5241 policy_exception_justification: "Not implemented."
5242 })");
Min Qina904f3302018-02-13 23:33:345243 auto params = std::make_unique<download::DownloadUrlParameters>(
Jeremy Romancfa82c652021-07-06 21:43:275244 url, rfh->GetProcess()->GetID(), rfh->GetRoutingID(), traffic_annotation);
Min Qina904f3302018-02-13 23:33:345245 params->set_referrer(referrer.url);
5246 params->set_referrer_policy(
5247 Referrer::ReferrerPolicyForUrlRequest(referrer.policy));
[email protected]3c71576ce2013-07-23 02:00:015248 params->set_post_id(post_id);
[email protected]3c71576ce2013-07-23 02:00:015249 if (post_id >= 0)
5250 params->set_method("POST");
5251 params->set_prompt(true);
kundaji6c7f9692015-03-09 18:00:375252
Min Qin7e82cc72021-12-28 19:20:495253 if (!headers.empty()) {
Min Qina904f3302018-02-13 23:33:345254 for (download::DownloadUrlParameters::RequestHeadersNameValuePair
5255 key_value : ParseDownloadHeaders(headers)) {
Megan Jablonski2f6a4c52017-07-10 23:01:255256 params->add_request_header(key_value.first, key_value.second);
kundaji6c7f9692015-03-09 18:00:375257 }
5258 }
Min Qin7e82cc72021-12-28 19:20:495259 params->set_prefer_cache(true);
Xing Liu10329bf2018-03-20 19:22:145260 params->set_suggested_name(suggested_filename);
Min Qin0ca8e1ee2018-01-31 00:49:355261 params->set_download_source(download::DownloadSource::WEB_CONTENTS_API);
Jeremy Romancfa82c652021-07-06 21:43:275262 params->set_isolation_info(rfhi.ComputeIsolationInfoForNavigation(url));
Yao Xiaoe5007042021-02-26 02:32:095263
Lukasz Anforowicz48d83452021-05-12 02:58:205264 GetBrowserContext()->GetDownloadManager()->DownloadUrl(std::move(params));
[email protected]3c71576ce2013-07-23 02:00:015265}
5266
[email protected]b172aee2012-04-10 17:05:265267void WebContentsImpl::GenerateMHTML(
dewittj6dc5747a2016-05-17 01:48:475268 const MHTMLGenerationParams& params,
Avi Drissman149b7832018-03-23 14:31:495269 base::OnceCallback<void(int64_t)> callback) {
Alexander Timin5fdeff22020-09-08 09:20:375270 OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::GenerateMHTML");
Angel Alvarez902496682019-08-27 22:58:425271 base::OnceCallback<void(const MHTMLGenerationResult&)> wrapper_callback =
5272 base::BindOnce(
5273 [](base::OnceCallback<void(int64_t)> size_callback,
5274 const MHTMLGenerationResult& result) {
5275 std::move(size_callback).Run(result.file_size);
5276 },
5277 std::move(callback));
5278 MHTMLGenerationManager::GetInstance()->SaveMHTML(this, params,
5279 std::move(wrapper_callback));
5280}
5281
5282void WebContentsImpl::GenerateMHTMLWithResult(
5283 const MHTMLGenerationParams& params,
5284 MHTMLGenerationResult::GenerateMHTMLCallback callback) {
Alexander Timin5fdeff22020-09-08 09:20:375285 OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::GenerateMHTMLWithResult");
Avi Drissman149b7832018-03-23 14:31:495286 MHTMLGenerationManager::GetInstance()->SaveMHTML(this, params,
5287 std::move(callback));
[email protected]aa4f3972012-03-01 18:12:125288}
5289
Lucas Furukawa Gadanie1c5dfda2018-11-29 17:57:415290const std::string& WebContentsImpl::GetContentsMimeType() {
Jeremy Roman2d8dfe132021-07-06 20:51:265291 return GetPrimaryPage().contents_mime_type();
[email protected]0bfbf882011-12-22 18:19:275292}
5293
Mario Sanchez Prada0bd8b8c2020-10-21 17:49:235294blink::RendererPreferences* WebContentsImpl::GetMutableRendererPrefs() {
[email protected]0bfbf882011-12-22 18:19:275295 return &renderer_preferences_;
5296}
5297
Ella Ge80a52dce2017-11-15 18:01:525298void WebContentsImpl::DragSourceEndedAt(float client_x,
5299 float client_y,
5300 float screen_x,
5301 float screen_y,
Henrique Ferreiro299008ec2020-12-29 14:36:285302 ui::mojom::DragOperation operation,
Paul Meyer0c58c3712016-11-17 22:59:515303 RenderWidgetHost* source_rwh) {
Alexander Timin5fdeff22020-09-08 09:20:375304 OPTIONAL_TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("content.verbose"),
5305 "WebContentsImpl::DragSourceEndedAt");
Paul Meyer0c58c3712016-11-17 22:59:515306 if (source_rwh) {
Ella Ge80a52dce2017-11-15 18:01:525307 source_rwh->DragSourceEndedAt(gfx::PointF(client_x, client_y),
Joel Einbinder64dd12442021-04-06 06:09:275308 gfx::PointF(screen_x, screen_y), operation,
5309 base::DoNothing());
Paul Meyer0c58c3712016-11-17 22:59:515310 }
[email protected]cf200a562013-05-03 16:24:295311}
5312
Dave Tapuskae1a08aaf2021-03-05 18:31:595313void WebContentsImpl::LoadStateChanged(network::mojom::LoadInfoPtr load_info) {
Alexander Timin5fdeff22020-09-08 09:20:375314 OPTIONAL_TRACE_EVENT2("content", "WebContentsImpl::LoadStateChanged", "host",
Dave Tapuskae1a08aaf2021-03-05 18:31:595315 load_info->host, "load_state", load_info->load_state);
5316
5317 // If the new load state isn't progressed as far as the current loading state
5318 // or both are sending an upload and the upload is smaller, return early
5319 // discarding the new load state.
5320 if (load_info_timestamp_ + kUpdateLoadStatesInterval > load_info->timestamp &&
5321 (load_state_.state > load_info->load_state ||
5322 (load_state_.state == load_info->load_state &&
5323 load_state_.state == net::LOAD_STATE_SENDING_REQUEST &&
5324 upload_size_ > load_info->upload_size))) {
Elly Fong-Jonescad9c3d12018-01-31 17:26:105325 return;
5326 }
Dave Tapuskae1a08aaf2021-03-05 18:31:595327
5328 load_info_timestamp_ = load_info->timestamp;
Jan Wilken Dörrieaace0cfef2021-03-11 22:01:585329 std::u16string host16 = url_formatter::IDNToUnicode(load_info->host);
Dave Tapuskae1a08aaf2021-03-05 18:31:595330 // Drop no-op updates.
5331 if (load_state_.state == load_info->load_state &&
5332 load_state_.param == load_info->state_param &&
5333 upload_position_ == load_info->upload_position &&
5334 upload_size_ == load_info->upload_size && load_state_host_ == host16) {
5335 return;
5336 }
5337 load_state_ = net::LoadStateWithParam(
5338 static_cast<net::LoadState>(load_info->load_state),
5339 load_info->state_param);
Charles Harrison911fa062018-03-06 21:01:465340 load_state_host_ = host16;
jam73f892642016-09-11 06:04:065341}
5342
Collin Baker989e0882019-11-01 01:27:175343void WebContentsImpl::SetVisibilityAndNotifyObservers(Visibility visibility) {
Alexander Timin5fdeff22020-09-08 09:20:375344 OPTIONAL_TRACE_EVENT1("content",
5345 "WebContentsImpl::SetVisibilityAndNotifyObservers",
5346 "visibility", static_cast<int>(visibility));
Francois Doraye6161152018-03-27 22:05:375347 const Visibility previous_visibility = visibility_;
5348 visibility_ = visibility;
5349
Francois Dorayfe4a1772018-02-17 04:17:095350 // Notify observers if the visibility changed or if WasShown() is being called
5351 // for the first time.
Francois Dorayfe4a1772018-02-17 04:17:095352 if (visibility != previous_visibility ||
5353 (visibility == Visibility::VISIBLE && !did_first_set_visible_)) {
Clark DuVall22aaff32021-03-18 17:17:475354 SCOPED_UMA_HISTOGRAM_TIMER("WebContentsObserver.OnVisibilityChanged");
Andrew Grievee19cd93e2021-01-22 05:43:065355 observers_.NotifyObservers(&WebContentsObserver::OnVisibilityChanged,
5356 visibility);
Francois Dorayfe4a1772018-02-17 04:17:095357 }
5358}
5359
Michael Thiessen896405db2017-07-20 17:52:325360void WebContentsImpl::NotifyWebContentsFocused(
5361 RenderWidgetHost* render_widget_host) {
Alexander Timin5fdeff22020-09-08 09:20:375362 OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::NotifyWebContentsFocused",
Alexander Timinf785f342021-03-18 00:00:565363 "render_widget_host", render_widget_host);
Andrew Grievee19cd93e2021-01-22 05:43:065364 observers_.NotifyObservers(&WebContentsObserver::OnWebContentsFocused,
5365 render_widget_host);
calamity7fe55ce2015-04-10 03:59:375366}
5367
Michael Thiessen896405db2017-07-20 17:52:325368void WebContentsImpl::NotifyWebContentsLostFocus(
5369 RenderWidgetHost* render_widget_host) {
Alexander Timinf785f342021-03-18 00:00:565370 OPTIONAL_TRACE_EVENT1("content",
5371 "WebContentsImpl::NotifyWebContentsLostFocus",
5372 "render_widget_host", render_widget_host);
Andrew Grievee19cd93e2021-01-22 05:43:065373 observers_.NotifyObservers(&WebContentsObserver::OnWebContentsLostFocus,
5374 render_widget_host);
zijiehe3bee08e22017-05-17 04:14:465375}
5376
Paul Meyer0c58c3712016-11-17 22:59:515377void WebContentsImpl::SystemDragEnded(RenderWidgetHost* source_rwh) {
Alexander Timin5fdeff22020-09-08 09:20:375378 OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::SystemDragEnded",
Alexander Timinf785f342021-03-18 00:00:565379 "render_widget_host", source_rwh);
Paul Meyer0c58c3712016-11-17 22:59:515380 if (source_rwh)
5381 source_rwh->DragSourceSystemDragEnded();
[email protected]7813bd72011-02-05 02:19:345382}
5383
[email protected]b172aee2012-04-10 17:05:265384void WebContentsImpl::SetClosedByUserGesture(bool value) {
Alexander Timin5fdeff22020-09-08 09:20:375385 OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::SetClosedByUserGesture",
5386 "value", value);
[email protected]0bfbf882011-12-22 18:19:275387 closed_by_user_gesture_ = value;
5388}
5389
Lucas Furukawa Gadanie1c5dfda2018-11-29 17:57:415390bool WebContentsImpl::GetClosedByUserGesture() {
[email protected]0bfbf882011-12-22 18:19:275391 return closed_by_user_gesture_;
5392}
5393
Lucas Furukawa Gadanie1c5dfda2018-11-29 17:57:415394int WebContentsImpl::GetMinimumZoomPercent() {
[email protected]0bfbf882011-12-22 18:19:275395 return minimum_zoom_percent_;
5396}
5397
Lucas Furukawa Gadanie1c5dfda2018-11-29 17:57:415398int WebContentsImpl::GetMaximumZoomPercent() {
[email protected]0bfbf882011-12-22 18:19:275399 return maximum_zoom_percent_;
5400}
5401
Dave Tapuska8f7c3872020-02-07 01:16:385402void WebContentsImpl::SetPageScale(float scale_factor) {
Alexander Timin5fdeff22020-09-08 09:20:375403 OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::SetPageScale",
5404 "scale_factor", scale_factor);
Dave Tapuska327c06c92022-06-13 20:31:515405 GetPrimaryMainFrame()->GetAssociatedLocalMainFrame()->SetScaleFactor(
5406 scale_factor);
ccameronb7c1d6c2015-03-09 17:08:245407}
5408
Lucas Furukawa Gadanie1c5dfda2018-11-29 17:57:415409gfx::Size WebContentsImpl::GetPreferredSize() {
Francois Doray24fc62c2017-12-11 17:27:335410 return IsBeingCaptured() ? preferred_size_for_capture_ : preferred_size_;
[email protected]bcd2815602012-01-14 18:17:235411}
5412
James Hollyerd5c9de462020-03-10 19:02:455413bool WebContentsImpl::GotResponseToLockMouseRequest(
5414 blink::mojom::PointerLockResult result) {
Alexander Timin5fdeff22020-09-08 09:20:375415 OPTIONAL_TRACE_EVENT0("content",
5416 "WebContentsImpl::GotResponseToLockMouseRequest");
lfgf0cd46e2017-01-04 00:05:235417 if (mouse_lock_widget_) {
Matt Falkenhagen888db592021-09-07 20:20:255418 auto* web_contents =
5419 WebContentsImpl::FromRenderWidgetHostImpl(mouse_lock_widget_);
5420 if (web_contents != this)
5421 return web_contents->GotResponseToLockMouseRequest(result);
lfgad8244352016-07-13 16:55:515422
James Hollyerd5c9de462020-03-10 19:02:455423 if (mouse_lock_widget_->GotResponseToLockMouseRequest(result))
lfgf0cd46e2017-01-04 00:05:235424 return true;
5425 }
5426
5427 for (WebContentsImpl* current = this; current;
5428 current = current->GetOuterWebContents()) {
5429 current->mouse_lock_widget_ = nullptr;
5430 }
5431
lfgbee1e0a2016-06-08 21:24:215432 return false;
[email protected]0bfbf882011-12-22 18:19:275433}
5434
James Hollyerd5c9de462020-03-10 19:02:455435void WebContentsImpl::GotLockMousePermissionResponse(bool allowed) {
5436 GotResponseToLockMouseRequest(
5437 allowed ? blink::mojom::PointerLockResult::kSuccess
5438 : blink::mojom::PointerLockResult::kPermissionDenied);
5439}
5440
Dave Tapuskab4998782020-10-08 17:22:475441void WebContentsImpl::DropMouseLockForTesting() {
5442 if (mouse_lock_widget_) {
5443 mouse_lock_widget_->RejectMouseLockOrUnlockIfNecessary(
5444 blink::mojom::PointerLockResult::kUnknownError);
5445 for (WebContentsImpl* current = this; current;
5446 current = current->GetOuterWebContents()) {
5447 current->mouse_lock_widget_ = nullptr;
5448 }
5449 }
5450}
5451
Joe Downing13dd76b2018-04-09 18:32:155452bool WebContentsImpl::GotResponseToKeyboardLockRequest(bool allowed) {
Alexander Timin5fdeff22020-09-08 09:20:375453 OPTIONAL_TRACE_EVENT1("content",
5454 "WebContentsImpl::GotResponseToKeyboardLockRequest",
5455 "allowed", allowed);
5456
Joe Downing13dd76b2018-04-09 18:32:155457 if (!keyboard_lock_widget_)
5458 return false;
5459
Matt Falkenhagen888db592021-09-07 20:20:255460 if (WebContentsImpl::FromRenderWidgetHostImpl(keyboard_lock_widget_) !=
5461 this) {
Joe Downing13dd76b2018-04-09 18:32:155462 NOTREACHED();
5463 return false;
5464 }
5465
5466 // KeyboardLock is only supported when called by the top-level browsing
5467 // context and is not supported in embedded content scenarios.
5468 if (GetOuterWebContents())
5469 return false;
5470
5471 keyboard_lock_widget_->GotResponseToKeyboardLockRequest(allowed);
5472 return true;
5473}
5474
Lucas Furukawa Gadanie1c5dfda2018-11-29 17:57:415475bool WebContentsImpl::HasOpener() {
Ivan Kotenkov2c0d2bb32017-11-01 15:41:285476 return GetOpener() != nullptr;
[email protected]a0358d72012-03-09 14:06:505477}
5478
Lucas Furukawa Gadanie1c5dfda2018-11-29 17:57:415479RenderFrameHostImpl* WebContentsImpl::GetOpener() {
Carlos Caballerob65b6e3a2021-11-15 10:09:005480 FrameTreeNode* opener_ftn = primary_frame_tree_.root()->opener();
lukasza6f8ac622017-06-06 03:10:205481 return opener_ftn ? opener_ftn->current_frame_host() : nullptr;
jochen55ff3502014-12-18 20:52:575482}
5483
Rakina Zata Amni3a48ae42022-05-05 03:39:565484bool WebContentsImpl::HasLiveOriginalOpenerChain() {
5485 return GetFirstWebContentsInLiveOriginalOpenerChain() != nullptr;
jochen6004a362017-02-04 00:11:405486}
5487
Rakina Zata Amni3a48ae42022-05-05 03:39:565488WebContents* WebContentsImpl::GetFirstWebContentsInLiveOriginalOpenerChain() {
5489 FrameTreeNode* opener_ftn =
5490 primary_frame_tree_.root()
5491 ->first_live_main_frame_in_original_opener_chain();
5492 return opener_ftn ? WebContents::FromRenderFrameHost(
5493 opener_ftn->current_frame_host())
5494 : nullptr;
jochen6004a362017-02-04 00:11:405495}
5496
Tom Burgin732656d32022-02-07 18:33:265497#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_MAC)
[email protected]cb805452013-05-22 15:16:215498void WebContentsImpl::DidChooseColorInColorChooser(SkColor color) {
Alexander Timin5fdeff22020-09-08 09:20:375499 OPTIONAL_TRACE_EVENT1("content",
5500 "WebContentsImpl::DidChooseColorInColorChooser",
5501 "color", color);
Bo Liu2bceebc2021-06-03 15:06:335502 if (color_chooser_holder_)
5503 color_chooser_holder_->DidChooseColorInColorChooser(color);
[email protected]da8543762012-03-20 08:52:205504}
5505
[email protected]cb805452013-05-22 15:16:215506void WebContentsImpl::DidEndColorChooser() {
Alexander Timin5fdeff22020-09-08 09:20:375507 OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::DidEndColorChooser");
Bo Liu2bceebc2021-06-03 15:06:335508 color_chooser_holder_.reset();
[email protected]da8543762012-03-20 08:52:205509}
Tom Burgin732656d32022-02-07 18:33:265510#endif // BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_MAC)
[email protected]da8543762012-03-20 08:52:205511
halton.huoca2eabd2015-07-06 08:17:405512int WebContentsImpl::DownloadImage(
5513 const GURL& url,
5514 bool is_favicon,
Rouslan Solomakhindb19343e2021-09-15 15:34:555515 const gfx::Size& preferred_size,
halton.huoca2eabd2015-07-06 08:17:405516 uint32_t max_bitmap_size,
5517 bool bypass_cache,
Avi Drissmana5a52dd2018-03-27 03:39:025518 WebContents::ImageDownloadCallback callback) {
Alexander Timin5fdeff22020-09-08 09:20:375519 OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::DownloadImage", "url",
Alexander Timinf785f342021-03-18 00:00:565520 url);
Alexander Timin8690530c2021-06-19 00:34:325521 return DownloadImageInFrame(GlobalRenderFrameHostId(), url, is_favicon,
Danyao Wanga78f3dd22020-03-05 05:31:275522 preferred_size, max_bitmap_size, bypass_cache,
5523 std::move(callback));
5524}
5525
5526int WebContentsImpl::DownloadImageInFrame(
Alexander Timin8690530c2021-06-19 00:34:325527 const GlobalRenderFrameHostId& initiator_frame_routing_id,
Danyao Wanga78f3dd22020-03-05 05:31:275528 const GURL& url,
5529 bool is_favicon,
Rouslan Solomakhindb19343e2021-09-15 15:34:555530 const gfx::Size& preferred_size,
Danyao Wanga78f3dd22020-03-05 05:31:275531 uint32_t max_bitmap_size,
5532 bool bypass_cache,
5533 WebContents::ImageDownloadCallback callback) {
Alexander Timin5fdeff22020-09-08 09:20:375534 OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::DownloadImageInFrame");
amistry9f01b772015-07-29 01:54:555535 DCHECK_CURRENTLY_ON(BrowserThread::UI);
halton.huoca2eabd2015-07-06 08:17:405536 static int next_image_download_id = 0;
danakj34c8ac02021-02-25 19:16:095537 const int download_id = ++next_image_download_id;
Danyao Wanga78f3dd22020-03-05 05:31:275538
5539 RenderFrameHostImpl* initiator_frame =
5540 initiator_frame_routing_id.child_id
5541 ? RenderFrameHostImpl::FromID(initiator_frame_routing_id)
Dave Tapuska327c06c92022-06-13 20:31:515542 : GetPrimaryMainFrame();
danakj34c8ac02021-02-25 19:16:095543 if (!initiator_frame->IsRenderFrameLive()) {
amistry9f01b772015-07-29 01:54:555544 // If the renderer process is dead (i.e. crash, or memory pressure on
5545 // Android), the downloader service will be invalid. Pre-Mojo, this would
Avi Drissmana5a52dd2018-03-27 03:39:025546 // hang the callback indefinitely since the IPC would be dropped. Now,
amistry9f01b772015-07-29 01:54:555547 // respond with a 400 HTTP error code to indicate that something went wrong.
Gabriel Charettee7cdc5cd2020-05-27 23:35:055548 GetUIThreadTaskRunner({})->PostTask(
5549 FROM_HERE,
Mikel Astiz034ba14e2021-04-30 07:23:495550 base::BindOnce(
5551 &WebContentsImpl::OnDidDownloadImage, weak_factory_.GetWeakPtr(),
5552 initiator_frame->GetWeakPtr(), std::move(callback), download_id,
5553 url, 400, std::vector<SkBitmap>(), std::vector<gfx::Size>()));
amistry9f01b772015-07-29 01:54:555554 return download_id;
5555 }
5556
danakj34c8ac02021-02-25 19:16:095557 initiator_frame->GetMojoImageDownloader()->DownloadImage(
Fredrik Söderquistb2b39eb92019-11-18 16:16:505558 url, is_favicon, preferred_size, max_bitmap_size, bypass_cache,
tzike2aca992017-09-05 08:50:545559 base::BindOnce(&WebContentsImpl::OnDidDownloadImage,
Mikel Astiz034ba14e2021-04-30 07:23:495560 weak_factory_.GetWeakPtr(), initiator_frame->GetWeakPtr(),
5561 std::move(callback), download_id, url));
amistry9f01b772015-07-29 01:54:555562 return download_id;
[email protected]795c28972012-12-06 06:13:395563}
5564
[email protected]36ec24f2014-01-09 00:32:085565void WebContentsImpl::Find(int request_id,
Jan Wilken Dörrieaace0cfef2021-03-11 22:01:585566 const std::u16string& search_text,
Joey Arharcac45bf2022-01-07 21:59:315567 blink::mojom::FindOptionsPtr options,
5568 bool skip_delay) {
Alexander Timin5fdeff22020-09-08 09:20:375569 OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::Find");
thestig6057a6b22015-11-12 23:01:335570 // Cowardly refuse to search for no text.
5571 if (search_text.empty()) {
5572 NOTREACHED();
5573 return;
5574 }
5575
Rakina Zata Amni3f77dff2018-09-08 16:19:435576 GetOrCreateFindRequestManager()->Find(request_id, search_text,
Joey Arharcac45bf2022-01-07 21:59:315577 std::move(options), skip_delay);
[email protected]36ec24f2014-01-09 00:32:085578}
5579
5580void WebContentsImpl::StopFinding(StopFindAction action) {
Alexander Timin5fdeff22020-09-08 09:20:375581 OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::StopFinding");
paulmeyerfeafc2d2017-04-25 21:46:405582 if (FindRequestManager* manager = GetFindRequestManager())
5583 manager->StopFinding(action);
[email protected]36ec24f2014-01-09 00:32:085584}
5585
Tommy Steimel18360512017-11-01 00:38:195586bool WebContentsImpl::WasEverAudible() {
5587 return was_ever_audible_;
5588}
5589
bokanece34a82016-01-28 19:49:465590void WebContentsImpl::ExitFullscreen(bool will_cause_resize) {
Alexander Timin5fdeff22020-09-08 09:20:375591 OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::ExitFullscreen");
mlamouri7a78d6fd2015-01-17 13:23:535592 // Clean up related state and initiate the fullscreen exit.
James Hollyerd5c9de462020-03-10 19:02:455593 GetRenderViewHost()->GetWidget()->RejectMouseLockOrUnlockIfNecessary(
5594 blink::mojom::PointerLockResult::kUserRejected);
bokanece34a82016-01-28 19:49:465595 ExitFullscreenMode(will_cause_resize);
mlamouri7a78d6fd2015-01-17 13:23:535596}
5597
Mike Wassermanb6bc0152020-08-25 22:46:205598base::ScopedClosureRunner WebContentsImpl::ForSecurityDropFullscreen(
5599 int64_t display_id) {
Alexander Timin5fdeff22020-09-08 09:20:375600 OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::ForSecurityDropFullscreen",
5601 "display_id", display_id);
Avi Drissman33972942020-06-19 14:16:015602 // Kick WebContentses that are "related" to this WebContents out of
5603 // fullscreen. This needs to be done with two passes, because it is simple to
5604 // walk _up_ the chain of openers and outer contents, but it not simple to
5605 // walk _down_ the chain.
5606
5607 // First, determine if any WebContents that is in fullscreen has this
5608 // WebContents as an upstream contents. Drop that WebContents out of
5609 // fullscreen if it does. This is theoretically quadratic-ish (fullscreen
5610 // contentses x each one's opener length) but neither of those is expected to
5611 // ever be a large number.
Avi Drissman33972942020-06-19 14:16:015612 auto fullscreen_set_copy = *FullscreenContentsSet(GetBrowserContext());
5613 for (auto* fullscreen_contents : fullscreen_set_copy) {
Avi Drissman97aef042020-06-30 21:04:485614 // Checking IsFullscreen() for tabs in the fullscreen set may seem
5615 // redundant, but teeeeechnically fullscreen is run by the delegate, and
5616 // it's possible that the delegate's notion of fullscreen may have changed
5617 // outside of WebContents's notice.
Mike Wassermanb6bc0152020-08-25 22:46:205618 if (fullscreen_contents->IsFullscreen() &&
Brad Triebwasser9d34d252022-07-26 20:44:425619 (display_id == display::kInvalidDisplayId ||
5620 fullscreen_contents->IsFullscreenOnDisplay(display_id))) {
Avi Drissman33972942020-06-19 14:16:015621 auto opener_contentses = GetAllOpeningWebContents(fullscreen_contents);
5622 if (opener_contentses.count(this))
5623 fullscreen_contents->ExitFullscreen(true);
5624 }
5625 }
5626
5627 // Second, walk upstream from this WebContents, and drop the fullscreen of
5628 // all WebContentses that are in fullscreen. Block all the WebContentses in
5629 // the chain from entering fullscreen while the returned closure runner is
5630 // alive. It's OK that this set doesn't contain downstream WebContentses, as
5631 // any request to enter fullscreen will have the upstream of the WebContents
5632 // checked. (See CanEnterFullscreenMode().)
Avi Drissmanced52b62019-08-14 21:25:465633
Avi Drissman1a55a9d62020-03-10 18:56:455634 std::vector<base::WeakPtr<WebContentsImpl>> blocked_contentses;
5635
Avi Drissman33972942020-06-19 14:16:015636 for (auto* opener : GetAllOpeningWebContents(this)) {
Avi Drissman1a55a9d62020-03-10 18:56:455637 // Drop fullscreen if the WebContents is in it, and...
Brad Triebwasser9d34d252022-07-26 20:44:425638 if (opener->IsFullscreen() && (display_id == display::kInvalidDisplayId ||
5639 opener->IsFullscreenOnDisplay(display_id)))
Avi Drissman33972942020-06-19 14:16:015640 opener->ExitFullscreen(true);
Avi Drissmanced52b62019-08-14 21:25:465641
Avi Drissman1a55a9d62020-03-10 18:56:455642 // ...block the WebContents from entering fullscreen until further notice.
Avi Drissman33972942020-06-19 14:16:015643 ++opener->fullscreen_blocker_count_;
5644 blocked_contentses.push_back(opener->weak_factory_.GetWeakPtr());
Avi Drissmanced52b62019-08-14 21:25:465645 }
Avi Drissman1a55a9d62020-03-10 18:56:455646
5647 return base::ScopedClosureRunner(base::BindOnce(
5648 [](std::vector<base::WeakPtr<WebContentsImpl>> blocked_contentses) {
5649 for (base::WeakPtr<WebContentsImpl>& web_contents :
5650 blocked_contentses) {
5651 if (web_contents) {
5652 DCHECK_GT(web_contents->fullscreen_blocker_count_, 0);
5653 --web_contents->fullscreen_blocker_count_;
5654 }
5655 }
5656 },
5657 std::move(blocked_contentses)));
Avi Drissmanced52b62019-08-14 21:25:465658}
5659
mariakhomenko44bdc4732015-04-29 01:55:385660void WebContentsImpl::ResumeLoadingCreatedWebContents() {
Alexander Timin5fdeff22020-09-08 09:20:375661 OPTIONAL_TRACE_EVENT0("content",
5662 "WebContentsImpl::ResumeLoadingCreatedWebContents");
Nasko Oskov83a8cf92018-10-19 14:58:565663 if (delayed_load_url_params_.get()) {
5664 DCHECK(!delayed_open_url_params_);
Carlos Caballero40b0efd2021-01-26 11:55:005665 GetController().LoadURLWithParams(*delayed_load_url_params_.get());
Nasko Oskov83a8cf92018-10-19 14:58:565666 delayed_load_url_params_.reset(nullptr);
5667 return;
5668 }
5669
mariakhomenkoa4971c12015-07-21 19:04:375670 if (delayed_open_url_params_.get()) {
5671 OpenURL(*delayed_open_url_params_.get());
5672 delayed_open_url_params_.reset(nullptr);
5673 return;
5674 }
5675
danakj08eb51d2020-12-30 20:15:235676 // Renderer-created main frames wait for the renderer to request for them to
5677 // perform navigations and to be shown. We signal that this condition is
5678 // satisfied by calling Init().
dfalcantarae6b7b46752015-07-10 18:14:165679 if (is_resume_pending_) {
5680 is_resume_pending_ = false;
Dave Tapuska327c06c92022-06-13 20:31:515681 GetPrimaryMainFrame()->Init();
dfalcantarae6b7b46752015-07-10 18:14:165682 }
mariakhomenko44bdc4732015-04-29 01:55:385683}
5684
[email protected]b172aee2012-04-10 17:05:265685bool WebContentsImpl::FocusLocationBarByDefault() {
Alexander Timin5fdeff22020-09-08 09:20:375686 OPTIONAL_TRACE_EVENT0("content",
5687 "WebContentsImpl::FocusLocationBarByDefault");
Xiyuan Xia2a66b112018-12-06 15:52:165688 if (should_focus_location_bar_by_default_)
[email protected]0c9406632013-02-08 01:13:335689 return true;
Xiyuan Xia2a66b112018-12-06 15:52:165690
[email protected]0c9406632013-02-08 01:13:335691 return delegate_ && delegate_->ShouldFocusLocationBarByDefault(this);
[email protected]0bfbf882011-12-22 18:19:275692}
5693
clamy0e119882015-07-31 16:12:335694void WebContentsImpl::DidStartNavigation(NavigationHandle* navigation_handle) {
Charles Harrison53096ba2017-12-15 15:39:485695 TRACE_EVENT1("navigation", "WebContentsImpl::DidStartNavigation",
Alexander Timinf785f342021-03-18 00:00:565696 "navigation_handle", navigation_handle);
Clark DuVall22aaff32021-03-18 17:17:475697 {
5698 SCOPED_UMA_HISTOGRAM_TIMER("WebContentsObserver.DidStartNavigation");
5699 observers_.NotifyObservers(&WebContentsObserver::DidStartNavigation,
5700 navigation_handle);
5701 }
Khushal7548ad102021-06-25 23:23:375702 if (navigation_handle->IsInPrimaryMainFrame()) {
Xiyuan Xia2a66b112018-12-06 15:52:165703 // When the browser is started with about:blank as the startup URL, focus
5704 // the location bar (which will also select its contents) so people can
5705 // simply begin typing to navigate elsewhere.
5706 //
5707 // We need to be careful not to trigger this for anything other than the
5708 // startup navigation. In particular, if we allow an attacker to open a
5709 // popup to about:blank, then navigate, focusing the Omnibox will cause the
5710 // end of the new URL to be scrolled into view instead of the start,
5711 // allowing the attacker to spoof other URLs. The conditions checked here
5712 // are all aimed at ensuring no such attacker-controlled navigation can
5713 // trigger this.
5714 should_focus_location_bar_by_default_ =
Carlos Caballero40b0efd2021-01-26 11:55:005715 GetController().IsInitialNavigation() &&
Xiyuan Xia2a66b112018-12-06 15:52:165716 !navigation_handle->IsRendererInitiated() &&
5717 navigation_handle->GetURL() == url::kAboutBlankURL;
5718 }
clamy0e119882015-07-31 16:12:335719}
5720
5721void WebContentsImpl::DidRedirectNavigation(
5722 NavigationHandle* navigation_handle) {
Charles Harrison53096ba2017-12-15 15:39:485723 TRACE_EVENT1("navigation", "WebContentsImpl::DidRedirectNavigation",
Alexander Timinf785f342021-03-18 00:00:565724 "navigation_handle", navigation_handle);
Clark DuVall22aaff32021-03-18 17:17:475725 {
5726 SCOPED_UMA_HISTOGRAM_TIMER("WebContentsObserver.DidRedirectNavigation");
5727 observers_.NotifyObservers(&WebContentsObserver::DidRedirectNavigation,
5728 navigation_handle);
5729 }
jam5f358e52017-02-13 16:37:035730 // Notify accessibility if this is a reload. This has to called on the
5731 // BrowserAccessibilityManager associated with the old RFHI.
5732 if (navigation_handle->GetReloadType() != ReloadType::NONE) {
Mohamed Abdelhalim95794962019-09-20 11:16:495733 NavigationRequest* request = NavigationRequest::From(navigation_handle);
jam5f358e52017-02-13 16:37:035734 BrowserAccessibilityManager* manager =
Mohamed Abdelhalim95794962019-09-20 11:16:495735 request->frame_tree_node()
jam5f358e52017-02-13 16:37:035736 ->current_frame_host()
5737 ->browser_accessibility_manager();
5738 if (manager)
5739 manager->UserIsReloading();
5740 }
clamy0e119882015-07-31 16:12:335741}
5742
clamyefca29e2015-09-17 00:22:115743void WebContentsImpl::ReadyToCommitNavigation(
5744 NavigationHandle* navigation_handle) {
Charles Harrison53096ba2017-12-15 15:39:485745 TRACE_EVENT1("navigation", "WebContentsImpl::ReadyToCommitNavigation",
Alexander Timinf785f342021-03-18 00:00:565746 "navigation_handle", navigation_handle);
Elad Alonf156eb62021-05-17 22:02:375747
5748 // Cross-document navigation of the top-level frame resets the capture
Khushal918195b2021-08-20 19:28:415749 // handle config. Using IsInPrimaryMainFrame is valid here since the browser
5750 // caches this state for the active main frame only.
Elad Alonf156eb62021-05-17 22:02:375751 if (!navigation_handle->IsSameDocument() &&
Kevin McNee19b0d0f32021-06-30 17:35:525752 navigation_handle->IsInPrimaryMainFrame()) {
Elad Alonf156eb62021-05-17 22:02:375753 SetCaptureHandleConfig(blink::mojom::CaptureHandleConfig::New());
5754 }
5755
Andrew Grievee19cd93e2021-01-22 05:43:065756 observers_.NotifyObservers(&WebContentsObserver::ReadyToCommitNavigation,
5757 navigation_handle);
Elad Alonf156eb62021-05-17 22:02:375758
Kenneth Russell954ed9ce2018-04-12 23:07:015759 // If any domains are blocked from accessing 3D APIs because they may
5760 // have caused the GPU to reset recently, unblock them here if the user
5761 // initiated this navigation. This implies that the user was involved in
5762 // the decision to navigate, so there's no concern about
5763 // denial-of-service issues. Want to do this as early as
5764 // possible to avoid race conditions with pages attempting to access
5765 // WebGL early on.
5766 //
5767 // TODO(crbug.com/617904): currently navigations initiated by the browser
5768 // (reload button, reload menu option, pressing return in the Omnibox)
5769 // return false from HasUserGesture(). If or when that is addressed,
5770 // remove the check for IsRendererInitiated() below.
5771 //
5772 // TODO(crbug.com/832180): HasUserGesture comes from the renderer
5773 // process and isn't validated. Until it is, don't trust it.
5774 if (!navigation_handle->IsRendererInitiated()) {
5775 GpuDataManagerImpl::GetInstance()->UnblockDomainFrom3DAPIs(
5776 navigation_handle->GetURL());
5777 }
5778
John Abd-El-Malekfde08e6da2017-12-05 04:06:245779 if (navigation_handle->IsSameDocument())
5780 return;
5781
Livvie Lin139bf442018-08-10 00:18:545782 // SSLInfo is not needed on subframe navigations since the main-frame
5783 // certificate is the only one that can be inspected (using the info
5784 // bubble) without refreshing the page with DevTools open.
Carlos ILaed1e7b2019-03-12 19:27:215785 // We don't call DidStartResourceResponse on net errors, since that results on
5786 // existing cert exceptions being revoked, which leads to weird behavior with
5787 // committed interstitials or while offline. We only need the error check for
Julie Jeongeun Kimf6732dc412021-11-16 07:33:065788 // the main frame case.
Carlos ILaed1e7b2019-03-12 19:27:215789 if (navigation_handle->IsInMainFrame() &&
5790 navigation_handle->GetNetErrorCode() == net::OK) {
Carlos Caballeroede6f8c2021-01-28 11:01:505791 static_cast<NavigationRequest*>(navigation_handle)
5792 ->frame_tree_node()
5793 ->frame_tree()
Arthur Sonzognif6785ec2022-12-05 10:11:505794 .controller()
Carlos Caballeroede6f8c2021-01-28 11:01:505795 .ssl_manager()
5796 ->DidStartResourceResponse(
Yoshisato Yanagisawa66845bf2022-05-12 04:04:025797 url::SchemeHostPort(navigation_handle->GetURL()),
Carlos Caballeroede6f8c2021-01-28 11:01:505798 navigation_handle->GetSSLInfo().has_value()
5799 ? net::IsCertStatusError(
5800 navigation_handle->GetSSLInfo()->cert_status)
5801 : false);
Camille Lamy62b826012019-02-26 09:15:475802 }
clamyefca29e2015-09-17 00:22:115803}
5804
clamy0e119882015-07-31 16:12:335805void WebContentsImpl::DidFinishNavigation(NavigationHandle* navigation_handle) {
Charles Harrison53096ba2017-12-15 15:39:485806 TRACE_EVENT1("navigation", "WebContentsImpl::DidFinishNavigation",
Alexander Timinf785f342021-03-18 00:00:565807 "navigation_handle", navigation_handle);
Steven Holte38041342018-06-22 22:00:575808
Clark DuVall22aaff32021-03-18 17:17:475809 {
5810 SCOPED_UMA_HISTOGRAM_TIMER("WebContentsObserver.DidFinishNavigation");
5811 observers_.NotifyObservers(&WebContentsObserver::DidFinishNavigation,
5812 navigation_handle);
5813 }
Becca Hughesd11d6502018-07-31 17:01:285814 if (display_cutout_host_impl_)
5815 display_cutout_host_impl_->DidFinishNavigation(navigation_handle);
5816
jam5f358e52017-02-13 16:37:035817 if (navigation_handle->HasCommitted()) {
Ian Prestcdd843d2020-01-28 18:59:585818 // TODO(domfarolino, dmazzoni): Do this using WebContentsObserver. See
5819 // https://crbug.com/981271.
5820 BrowserAccessibilityManager* manager =
5821 static_cast<RenderFrameHostImpl*>(
5822 navigation_handle->GetRenderFrameHost())
5823 ->browser_accessibility_manager();
5824 if (manager) {
5825 if (navigation_handle->IsErrorPage()) {
5826 manager->NavigationFailed();
5827 } else {
5828 manager->NavigationSucceeded();
5829 }
5830 }
5831
Khushalafff1d22021-06-25 16:00:345832 // TODO(crbug.com/1223113) : Move this tracking to PageImpl.
5833 if (navigation_handle->IsInPrimaryMainFrame() &&
Khushal6fca53762021-06-25 04:42:185834 !navigation_handle->IsSameDocument()) {
5835 was_ever_audible_ = false;
Tommy Steimel18360512017-11-01 00:38:195836 }
Lan Weif81c6e7c2020-02-12 16:46:095837
Robert Lina662a472022-09-01 01:00:255838 // Clear the stored prerender activation result if this is not a prerender
5839 // activation. If this is another prerender activation, it will override
5840 // the old result in DevTools.
5841 if (!navigation_handle->IsPrerenderedPageActivation() &&
5842 !navigation_handle->IsSameDocument() &&
5843 navigation_handle->IsInPrimaryMainFrame()) {
5844 last_navigation_was_prerender_activation_for_devtools_ = false;
5845 }
5846
Lan Weif81c6e7c2020-02-12 16:46:095847 if (!navigation_handle->IsSameDocument())
5848 last_screen_orientation_change_time_ = base::TimeTicks();
dmazzonibf8cec42015-02-08 08:28:085849 }
Xiyuan Xia2a66b112018-12-06 15:52:165850
5851 // If we didn't end up on about:blank after setting this in DidStartNavigation
5852 // then don't focus the location bar.
5853 if (should_focus_location_bar_by_default_ &&
5854 navigation_handle->GetURL() != url::kAboutBlankURL) {
5855 should_focus_location_bar_by_default_ = false;
5856 }
yilkal796e89e2019-10-02 23:58:285857
Khushal97d31e82021-06-23 21:07:545858 if (navigation_handle->IsInPrimaryMainFrame() &&
5859 first_primary_navigation_completed_) {
yilkal172da772019-11-06 22:49:075860 RecordMaxFrameCountUMA(max_loaded_frame_count_);
Khushal97d31e82021-06-23 21:07:545861 }
yilkal796e89e2019-10-02 23:58:285862
yilkal172da772019-11-06 22:49:075863 // If navigation has successfully finished in the main frame, set
Khushal97d31e82021-06-23 21:07:545864 // |first_primary_navigation_completed_| to true so that we will record
yilkal172da772019-11-06 22:49:075865 // |max_loaded_frame_count_| above when future main frame navigations finish.
Khushal97d31e82021-06-23 21:07:545866 if (navigation_handle->IsInPrimaryMainFrame() &&
5867 !navigation_handle->IsErrorPage()) {
5868 first_primary_navigation_completed_ = true;
yilkal172da772019-11-06 22:49:075869
5870 // Navigation has completed in main frame. Reset |max_loaded_frame_count_|.
5871 // |max_loaded_frame_count_| is not necessarily 1 if the navigation was
5872 // served from BackForwardCache.
Dave Tapuska21e9da02021-12-15 20:58:205873 max_loaded_frame_count_ = GetFrameTreeSize(&primary_frame_tree_);
yilkal796e89e2019-10-02 23:58:285874 }
Rakina Zata Amni347b70902020-07-22 10:49:045875
5876 if (web_preferences_) {
5877 // Update the WebPreferences for this WebContents that depends on changes
5878 // that might occur during navigation. This will only update the preferences
5879 // that needs to be updated (and won't cause an update/overwrite preferences
5880 // that needs to stay the same after navigations).
5881 bool value_changed_due_to_override =
5882 GetContentClient()->browser()->OverrideWebPreferencesAfterNavigation(
5883 this, web_preferences_.get());
5884 // We need to update the WebPreferences value on the renderer if the value
5885 // is changed due to the override above, or if the navigation is served from
5886 // the back-forward cache, because the WebPreferences value stored in the
5887 // renderer might be stale (because we don't send WebPreferences updates to
Takashi Toyoshima9c01ce442021-06-11 04:55:575888 // bfcached renderers). Same for prerendering.
Rakina Zata Amni347b70902020-07-22 10:49:045889 // TODO(rakina): Maybe handle the back-forward cache case in
5890 // ReadyToCommitNavigation instead?
Rakina Zata Amni2c46e88b2021-04-02 05:22:335891 // TODO(https://crbug.com/1194880): Maybe sync RendererPreferences as well?
Rakina Zata Amni347b70902020-07-22 10:49:045892 if (value_changed_due_to_override ||
Takashi Toyoshima1c1f02cd2021-06-18 21:39:165893 NavigationRequest::From(navigation_handle)->IsPageActivation()) {
Rakina Zata Amni347b70902020-07-22 10:49:045894 SetWebPreferences(*web_preferences_.get());
5895 }
5896 }
Ian Vollick6d75ac32021-05-05 17:45:095897
5898 if (navigation_handle->HasCommitted() &&
5899 navigation_handle->IsPrerenderedPageActivation()) {
Julie Jeongeun Kimd74c1e7f2021-06-18 04:06:185900 // We defer favicon and manifest URL updates while prerendering. Upon
5901 // activation, we must inform interested parties about our candidate favicon
5902 // URLs and the manifest URL.
Julie Jeongeun Kim0a594bb2021-10-21 05:30:535903 DCHECK(navigation_handle->IsInPrimaryMainFrame());
Ian Vollick6d75ac32021-05-05 17:45:095904 auto* rfhi = static_cast<RenderFrameHostImpl*>(
5905 navigation_handle->GetRenderFrameHost());
Julie Jeongeun Kim0a594bb2021-10-21 05:30:535906 UpdateFaviconURL(rfhi, rfhi->FaviconURLs());
5907 OnManifestUrlChanged(rfhi->GetPage());
Adithya Srinivasan9b0c99c2021-08-10 15:19:455908
5909 // The page might have set its title while prerendering, and if it was, we
5910 // skipped notifying observers then, and we need to notify them now after
5911 // the page is activated.
5912 DCHECK(navigation_handle->IsInPrimaryMainFrame());
5913 NavigationEntryImpl* entry = GetController().GetLastCommittedEntry();
5914 DCHECK(entry);
5915 if (!entry->GetTitle().empty()) {
5916 NotifyTitleUpdateForEntry(entry);
5917 }
Ian Vollick6d75ac32021-05-05 17:45:095918 }
[email protected]400992b2012-06-14 00:03:545919}
5920
[email protected]b80624c2014-02-09 02:46:555921void WebContentsImpl::DidFailLoadWithError(
5922 RenderFrameHostImpl* render_frame_host,
[email protected]b80624c2014-02-09 02:46:555923 const GURL& url,
Dave Tapuska924ef3c2020-01-22 18:20:595924 int error_code) {
Alexander Timin5fdeff22020-09-08 09:20:375925 TRACE_EVENT2("content,navigation", "WebContentsImpl::DidFailLoadWithError",
Alexander Timinf785f342021-03-18 00:00:565926 "render_frame_host", render_frame_host, "url", url);
Andrew Grievee19cd93e2021-01-22 05:43:065927 observers_.NotifyObservers(&WebContentsObserver::DidFailLoad,
5928 render_frame_host, url, error_code);
[email protected]b80624c2014-02-09 02:46:555929}
5930
[email protected]52913802013-12-10 05:52:185931void WebContentsImpl::NotifyChangedNavigationState(
5932 InvalidateTypes changed_flags) {
5933 NotifyNavigationStateChanged(changed_flags);
5934}
5935
Alexander Timina0ef6df2021-06-24 13:34:465936bool WebContentsImpl::ShouldAllowRendererInitiatedCrossProcessNavigation(
Ian Vollick1c6dd3e2022-04-13 02:06:265937 bool is_outermost_main_frame_navigation) {
Alexander Timina0ef6df2021-06-24 13:34:465938 OPTIONAL_TRACE_EVENT1(
5939 "content",
5940 "WebContentsImpl::ShouldAllowRendererInitiatedCrossProcessNavigation",
Ian Vollick1c6dd3e2022-04-13 02:06:265941 "is_outermost_main_frame_navigation", is_outermost_main_frame_navigation);
creis29460272015-12-16 04:38:225942 if (!delegate_)
5943 return true;
Alexander Timina0ef6df2021-06-24 13:34:465944 return delegate_->ShouldAllowRendererInitiatedCrossProcessNavigation(
Ian Vollick1c6dd3e2022-04-13 02:06:265945 is_outermost_main_frame_navigation);
creis29460272015-12-16 04:38:225946}
5947
[email protected]aa62afd2014-04-22 19:22:465948bool WebContentsImpl::ShouldPreserveAbortedURLs() {
Alexander Timin5fdeff22020-09-08 09:20:375949 OPTIONAL_TRACE_EVENT0("content",
5950 "WebContentsImpl::ShouldPreserveAbortedURLs");
[email protected]aa62afd2014-04-22 19:22:465951 if (!delegate_)
5952 return false;
5953 return delegate_->ShouldPreserveAbortedURLs(this);
5954}
5955
Abhijeet Kandalkar3dc6e602022-11-09 05:08:375956void WebContentsImpl::NotifyNavigationStateChangedFromController(
5957 InvalidateTypes changed_flags) {
5958 NotifyNavigationStateChanged(changed_flags);
5959}
5960
[email protected]0d0f4c492014-04-02 06:42:575961void WebContentsImpl::DidNavigateMainFramePreCommit(
Liviu Tinta235581962021-07-14 20:37:075962 FrameTreeNode* frame_tree_node,
[email protected]5cfbddc2014-06-23 23:52:235963 bool navigation_is_within_page) {
Kevin McNee9f3ef7c2021-09-29 18:43:415964 // The `frame_tree_node` is always a main frame.
Liviu Tinta235581962021-07-14 20:37:075965 DCHECK(frame_tree_node->IsMainFrame());
Alexander Timin5fdeff22020-09-08 09:20:375966 TRACE_EVENT1("content,navigation",
5967 "WebContentsImpl::DidNavigateMainFramePreCommit",
5968 "navigation_is_within_page", navigation_is_within_page);
Abhijeet Kandalkarc2e075e2022-12-16 12:55:525969 const bool is_primary_mainframe =
5970 frame_tree_node->GetFrameType() == FrameType::kPrimaryMainFrame;
Liviu Tinta235581962021-07-14 20:37:075971 // If running for a non-primary main frame, early out.
Abhijeet Kandalkarc2e075e2022-12-16 12:55:525972 if (!is_primary_mainframe)
Liviu Tinta235581962021-07-14 20:37:075973 return;
5974
[email protected]0d0f4c492014-04-02 06:42:575975 // Ensure fullscreen mode is exited before committing the navigation to a
5976 // different page. The next page will not start out assuming it is in
5977 // fullscreen mode.
[email protected]5cfbddc2014-06-23 23:52:235978 if (navigation_is_within_page) {
[email protected]dfc39cb2014-04-09 22:58:195979 // No page change? Then, the renderer and browser can remain in fullscreen.
[email protected]0d0f4c492014-04-02 06:42:575980 return;
5981 }
Liviu Tinta235581962021-07-14 20:37:075982
Avi Drissman97aef042020-06-30 21:04:485983 if (IsFullscreen())
bokanece34a82016-01-28 19:49:465984 ExitFullscreen(false);
Avi Drissman97aef042020-06-30 21:04:485985 DCHECK(!IsFullscreen());
Joe Downingc1a57efe2018-05-09 18:23:545986
5987 // Clean up keyboard lock state when navigating.
5988 CancelKeyboardLock(keyboard_lock_widget_);
[email protected]0d0f4c492014-04-02 06:42:575989}
5990
[email protected]37567b432014-02-12 01:12:225991void WebContentsImpl::DidNavigateMainFramePostCommit(
sky8b00392d2015-01-10 00:30:285992 RenderFrameHostImpl* render_frame_host,
Rakina Zata Amniff10975d2021-10-08 06:04:245993 const LoadCommittedDetails& details) {
Liviu Tinta40904052021-07-20 15:12:525994 // The render_frame_host is always a main frame.
5995 DCHECK(render_frame_host->is_main_frame());
Alexander Timinf785f342021-03-18 00:00:565996 OPTIONAL_TRACE_EVENT1("content,navigation",
5997 "WebContentsImpl::DidNavigateMainFramePostCommit",
5998 "render_frame_host", render_frame_host);
Kevin McNee9f3ef7c2021-09-29 18:43:415999 const bool is_primary_main_frame = render_frame_host->IsInPrimaryMainFrame();
Liviu Tinta40904052021-07-20 15:12:526000
[email protected]37567b432014-02-12 01:12:226001 if (details.is_navigation_to_different_page()) {
Liviu Tinta40904052021-07-20 15:12:526002 if (is_primary_main_frame) {
6003 // Clear the status bubble. This is a workaround for a bug where WebKit
6004 // doesn't let us know that the cursor left an element during a
6005 // transition (this is also why the mouse cursor remains as a hand after
6006 // clicking on a link); see bugs 1184641 and 980803. We don't want to
6007 // clear the bubble when a user navigates to a named anchor in the same
6008 // page.
6009 ClearTargetURL();
6010 }
lanwei9d343ad22015-02-11 01:46:006011
Carlos Caballero179e1992021-04-08 14:31:086012 RenderWidgetHostViewBase* rwhvb = static_cast<RenderWidgetHostViewBase*>(
6013 render_frame_host->GetMainFrame()->GetView());
lanwei9d343ad22015-02-11 01:46:006014 if (rwhvb)
6015 rwhvb->OnDidNavigateMainFrameToNewPage();
[email protected]37567b432014-02-12 01:12:226016 }
6017
Jeremy Roman2d8dfe132021-07-06 20:51:266018 PageImpl& page = render_frame_host->GetPage();
6019 if (page.IsPrimary()) {
6020 // The following events will not fire again if the this is a back-forward
6021 // cache restore or prerendering activation. Fire them ourselves if needed.
6022 if (details.is_navigation_to_different_page() &&
6023 page.did_first_visually_non_empty_paint()) {
6024 OnFirstVisuallyNonEmptyPaint(page);
6025 }
6026 OnThemeColorChanged(page);
6027 OnBackgroundColorChanged(page);
Michael Bai19f17a302021-12-08 04:08:336028 DidInferColorScheme(page);
Tal Pressmancbca7e22021-08-06 01:28:496029 AXTreeIDForMainFrameHasChanged();
Carlos Caballero91fffb22019-10-29 15:24:306030 }
[email protected]37567b432014-02-12 01:12:226031}
6032
6033void WebContentsImpl::DidNavigateAnyFramePostCommit(
6034 RenderFrameHostImpl* render_frame_host,
Rakina Zata Amniff10975d2021-10-08 06:04:246035 const LoadCommittedDetails& details) {
Alexander Timinf785f342021-03-18 00:00:566036 OPTIONAL_TRACE_EVENT1("content,navigation",
6037 "WebContentsImpl::DidNavigateAnyFramePostCommit",
6038 "render_frame_host", render_frame_host);
[email protected]b4c84012014-04-28 19:51:106039
Yoshisato Yanagisawa84141482021-11-24 23:46:426040 // This function can be called by prerendered frames or other inactive frames,
6041 // we want to guard the dialog cancellations below.
6042 const bool is_active = render_frame_host->IsActive();
6043
Yoshisato Yanagisawa4289e8d2022-03-01 05:55:386044 // If we navigate off the active non-fenced frame page, close all JavaScript
6045 // dialogs. We do not cancel the dialogs for fenced frames because it can be
6046 // used as a communication channel. Please see also:
6047 // RenderFrameHostManager::UnloadOldFrame in
6048 // content/browser/renderer_host/render_frame_host_manager.cc
6049 //
6050 // TODO(crbug.com/1299379): Note that fenced frames cannot open modal dialogs
6051 // so this only affects dialogs outside the fenced frame tree. If this is ever
6052 // changed then the navigation should be deferred till the dialog from within
6053 // the fenced frame is open.
6054 if (is_active && !render_frame_host->IsNestedWithinFencedFrame() &&
6055 !details.is_same_document) {
creis89a0f782015-05-27 16:13:176056 CancelActiveAndPendingDialogs();
Yoshisato Yanagisawa4289e8d2022-03-01 05:55:386057 }
[email protected]37567b432014-02-12 01:12:226058
avid53461d2016-02-25 17:15:046059 // If this is a user-initiated navigation, start allowing JavaScript dialogs
6060 // again.
Yao Xiaod553b702022-12-08 02:20:476061 //
6062 // TODO(https://crbug.com/1399296): Consider using the actual value of
6063 // "whether a navigation started with user activation or not" instead of
6064 // has_user_gesture, which might get filtered out when navigating from
6065 // proxies. If so, we can remove tracking of
6066 // `last_committed_common_params_has_user_gesture` entirely.
6067 if (render_frame_host->last_committed_common_params_has_user_gesture() &&
Rakina Zata Amniff10975d2021-10-08 06:04:246068 dialog_manager_) {
Yoshisato Yanagisawa84141482021-11-24 23:46:426069 DCHECK(is_active);
avi6879fcf2017-01-21 05:27:536070 dialog_manager_->CancelDialogs(this, /*reset_state=*/true);
avi5d3b8692016-10-12 22:00:466071 }
[email protected]37567b432014-02-12 01:12:226072}
6073
[email protected]277857a2014-06-03 10:38:016074bool WebContentsImpl::CanOverscrollContent() const {
Alexander Timin5fdeff22020-09-08 09:20:376075 OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::CanOverscrollContent");
[email protected]e85165c642014-06-10 14:34:316076 // Disable overscroll when touch emulation is on. See crbug.com/369938.
[email protected]34ff1cfc2014-08-20 06:16:056077 if (force_disable_overscroll_content_)
[email protected]e85165c642014-06-10 14:34:316078 return false;
danakj5f22bcc2021-02-12 18:09:016079 return delegate_ && delegate_->CanOverscrollContent();
[email protected]37567b432014-02-12 01:12:226080}
6081
Jeremy Roman2d8dfe132021-07-06 20:51:266082void WebContentsImpl::OnThemeColorChanged(PageImpl& page) {
Alexander Timin5fdeff22020-09-08 09:20:376083 OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::OnThemeColorChanged",
Jeremy Roman2d8dfe132021-07-06 20:51:266084 "page", page);
6085 if (!page.IsPrimary())
6086 return;
6087
6088 if (page.did_first_visually_non_empty_paint() &&
6089 last_sent_theme_color_ != page.theme_color()) {
Andrew Grievee19cd93e2021-01-22 05:43:066090 observers_.NotifyObservers(&WebContentsObserver::DidChangeThemeColor);
Jeremy Roman2d8dfe132021-07-06 20:51:266091 last_sent_theme_color_ = page.theme_color();
peter90afaba2015-06-01 12:05:296092 }
[email protected]e7104762014-06-20 19:17:256093}
6094
Jeremy Roman2d8dfe132021-07-06 20:51:266095void WebContentsImpl::OnBackgroundColorChanged(PageImpl& page) {
6096 if (!page.IsPrimary())
6097 return;
6098
6099 if (page.did_first_visually_non_empty_paint() &&
6100 last_sent_background_color_ != page.background_color()) {
Andrew Grievee19cd93e2021-01-22 05:43:066101 observers_.NotifyObservers(&WebContentsObserver::OnBackgroundColorChanged);
Jeremy Roman2d8dfe132021-07-06 20:51:266102 last_sent_background_color_ = page.background_color();
Hassan Talatf8f48442021-06-11 00:46:566103 return;
6104 }
6105
Jeremy Roman2d8dfe132021-07-06 20:51:266106 if (page.background_color().has_value()) {
Hassan Talatf8f48442021-06-11 00:46:566107 if (auto* view = GetRenderWidgetHostView()) {
6108 static_cast<RenderWidgetHostViewBase*>(view)->SetContentBackgroundColor(
Jeremy Roman2d8dfe132021-07-06 20:51:266109 page.background_color().value());
Hassan Talatf8f48442021-06-11 00:46:566110 }
Alan Cutterd73a15d92020-08-21 07:12:456111 }
6112}
6113
Michael Bai19f17a302021-12-08 04:08:336114void WebContentsImpl::DidInferColorScheme(PageImpl& page) {
6115 // If the page is primary, notify embedders that the current inferred color
6116 // scheme for this WebContents has changed.
6117 if (page.IsPrimary()) {
6118 observers_.NotifyObservers(&WebContentsObserver::InferredColorSchemeUpdated,
6119 page.inferred_color_scheme());
Michael Bai93d372bd2022-03-28 23:05:546120 if (page.inferred_color_scheme().has_value()) {
6121 bool dark = page.inferred_color_scheme().value() ==
6122 blink::mojom::PreferredColorScheme::kDark;
6123 base::UmaHistogramBoolean("Power.DarkMode.InferredDarkPageColorScheme",
6124 dark);
Michael Baie0fc428f2022-04-01 02:48:056125 if (web_preferences_->preferred_color_scheme ==
6126 blink::mojom::PreferredColorScheme::kDark) {
Michael Bai93d372bd2022-03-28 23:05:546127 base::UmaHistogramBoolean(
6128 "Power.DarkMode.DarkColorScheme.InferredDarkPageColorScheme", dark);
6129 }
6130 }
Michael Bai19f17a302021-12-08 04:08:336131 }
6132}
6133
David Bokand6e44055b2022-09-21 03:58:086134void WebContentsImpl::OnVirtualKeyboardModeChanged(PageImpl& page) {
6135 if (!page.IsPrimary())
6136 return;
6137
6138 observers_.NotifyObservers(&WebContentsObserver::VirtualKeyboardModeChanged,
6139 page.virtual_keyboard_mode());
6140}
6141
Gyuyoung Kim1905f7c2020-05-02 00:00:246142void WebContentsImpl::DidLoadResourceFromMemoryCache(
nicka0ac8382016-12-15 23:59:236143 RenderFrameHostImpl* source,
[email protected]724159a2010-12-30 01:11:186144 const GURL& url,
[email protected]70435962011-08-02 20:13:286145 const std::string& http_method,
[email protected]6d6cfb3a2012-05-23 22:53:186146 const std::string& mime_type,
Arthur Sonzogni54013f22021-09-03 14:57:126147 network::mojom::RequestDestination request_destination,
6148 bool include_credentials) {
Alexander Timinf785f342021-03-18 00:00:566149 OPTIONAL_TRACE_EVENT2("content",
6150 "WebContentsImpl::DidLoadResourceFromMemoryCache",
6151 "render_frame_host", source, "url", url);
Andrew Grievee19cd93e2021-01-22 05:43:066152 observers_.NotifyObservers(
Lucas Furukawa Gadani07b45e152021-04-14 00:56:446153 &WebContentsObserver::DidLoadResourceFromMemoryCache, source, url,
6154 mime_type, request_destination);
[email protected]b0f724c2013-09-05 04:21:136155
Arthur Sonzogni54013f22021-09-03 14:57:126156 if (!url.is_valid() || !url.SchemeIsHTTPOrHTTPS())
6157 return;
shivanigithubc688ced2020-11-04 19:46:156158
Arthur Sonzogni54013f22021-09-03 14:57:126159 StoragePartition* partition = source->GetProcess()->GetStoragePartition();
6160
6161 DCHECK(!blink::IsRequestDestinationFrame(request_destination));
6162 partition->GetNetworkContext()->NotifyExternalCacheHit(
6163 url, http_method, source->GetNetworkIsolationKey(),
6164 /*is_subframe_document_resource=*/false,
6165 /*include_credentials=*/include_credentials);
[email protected]724159a2010-12-30 01:11:186166}
6167
Sreeja Kamishetty49783302022-01-28 17:52:256168void WebContentsImpl::PrimaryMainDocumentElementAvailable() {
Alexander Timin5fdeff22020-09-08 09:20:376169 OPTIONAL_TRACE_EVENT0("content",
Sreeja Kamishetty49783302022-01-28 17:52:256170 "WebContentsImpl::PrimaryMainDocumentElementAvailable");
Clark DuVall22aaff32021-03-18 17:17:476171 SCOPED_UMA_HISTOGRAM_TIMER(
Sreeja Kamishetty49783302022-01-28 17:52:256172 "WebContentsObserver.PrimaryMainDocumentElementAvailable");
6173 observers_.NotifyObservers(
6174 &WebContentsObserver::PrimaryMainDocumentElementAvailable);
Julie Jeongeun Kim0b103492020-01-29 05:30:516175}
6176
carloskd9d97942017-02-16 08:58:096177void WebContentsImpl::PassiveInsecureContentFound(const GURL& resource_url) {
Alexander Timinf785f342021-03-18 00:00:566178 OPTIONAL_TRACE_EVENT1("content",
6179 "WebContentsImpl::PassiveInsecureContentFound",
6180 "resource_url", resource_url);
Sergey Kuznetsov3ebc01b2018-02-01 04:57:366181 if (delegate_) {
6182 delegate_->PassiveInsecureContentFound(resource_url);
6183 }
carloskd9d97942017-02-16 08:58:096184}
6185
6186bool WebContentsImpl::ShouldAllowRunningInsecureContent(
carloskd9d97942017-02-16 08:58:096187 bool allowed_per_prefs,
6188 const url::Origin& origin,
6189 const GURL& resource_url) {
Alexander Timin5fdeff22020-09-08 09:20:376190 OPTIONAL_TRACE_EVENT0("content",
6191 "WebContentsImpl::ShouldAllowRunningInsecureContent");
Sergey Kuznetsov3ebc01b2018-02-01 04:57:366192 if (delegate_) {
Carlos IL29294a62020-05-15 00:21:166193 return delegate_->ShouldAllowRunningInsecureContent(this, allowed_per_prefs,
6194 origin, resource_url);
Sergey Kuznetsov3ebc01b2018-02-01 04:57:366195 }
6196
6197 return allowed_per_prefs;
carloskd9d97942017-02-16 08:58:096198}
6199
Lukasz Anforowicze1b954d92017-10-30 21:28:066200void WebContentsImpl::ViewSource(RenderFrameHostImpl* frame) {
Alexander Timin5fdeff22020-09-08 09:20:376201 OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::ViewSource",
Alexander Timinf785f342021-03-18 00:00:566202 "render_frame_host", frame);
Lukasz Anforowicze1b954d92017-10-30 21:28:066203 DCHECK_EQ(this, WebContents::FromRenderFrameHost(frame));
6204
6205 // Don't do anything if there is no |delegate_| that could accept and show the
6206 // new WebContents containing the view-source.
6207 if (!delegate_)
6208 return;
6209
6210 // Use the last committed entry, since the pending entry hasn't loaded yet and
6211 // won't be copied into the cloned tab.
6212 NavigationEntryImpl* last_committed_entry =
Jeremy Romanb26f7d12021-06-16 22:12:056213 frame->frame_tree()->controller().GetLastCommittedEntry();
Lukasz Anforowicze1b954d92017-10-30 21:28:066214 if (!last_committed_entry)
6215 return;
6216
6217 FrameNavigationEntry* frame_entry =
6218 last_committed_entry->GetFrameEntry(frame->frame_tree_node());
6219 if (!frame_entry)
6220 return;
6221
6222 // Any new WebContents opened while this WebContents is in fullscreen can be
6223 // used to confuse the user, so drop fullscreen.
Avi Drissman1a55a9d62020-03-10 18:56:456224 base::ScopedClosureRunner fullscreen_block = ForSecurityDropFullscreen();
6225 // The new view source contents will be independent of this contents, so
6226 // release the fullscreen block.
6227 fullscreen_block.RunAndReset();
Lukasz Anforowicze1b954d92017-10-30 21:28:066228
6229 // We intentionally don't share the SiteInstance with the original frame so
6230 // that view source has a consistent process model and always ends up in a new
6231 // process (https://crbug.com/699493).
Lei Zhangd40a27472021-04-15 19:04:426232 scoped_refptr<SiteInstanceImpl> site_instance_for_view_source;
Lukasz Anforowicz435bcb582019-07-12 20:50:066233 // Referrer and initiator are not important, because view-source should not
6234 // hit the network, but should be served from the cache instead.
Lukasz Anforowicze1b954d92017-10-30 21:28:066235 Referrer referrer_for_view_source;
Anton Bikineevf62d1bf2021-05-15 17:56:076236 absl::optional<url::Origin> initiator_for_view_source = absl::nullopt;
W. James MacLean23e90a12022-12-21 04:38:216237 absl::optional<GURL> initiator_base_url_for_view_source = absl::nullopt;
Lukasz Anforowicze1b954d92017-10-30 21:28:066238 // Do not restore title, derive it from the url.
Jan Wilken Dörrieaace0cfef2021-03-11 22:01:586239 std::u16string title_for_view_source;
Lukasz Anforowicze1b954d92017-10-30 21:28:066240 auto navigation_entry = std::make_unique<NavigationEntryImpl>(
6241 site_instance_for_view_source, frame_entry->url(),
Lukasz Anforowicz435bcb582019-07-12 20:50:066242 referrer_for_view_source, initiator_for_view_source,
W. James MacLean23e90a12022-12-21 04:38:216243 initiator_base_url_for_view_source, title_for_view_source,
6244 ui::PAGE_TRANSITION_LINK,
Marijn Kruisselbrink7a0d5e182018-05-24 22:55:096245 /* is_renderer_initiated = */ false,
Rakina Zata Amniafd3c6582021-11-30 06:19:176246 /* blob_url_loader_factory = */ nullptr, /* is_initial_entry = */ false);
Joel Hockey891e88062020-04-30 05:38:446247 const GURL url(content::kViewSourceScheme + std::string(":") +
6248 frame_entry->url().spec());
6249 navigation_entry->SetVirtualURL(url);
shivanigithubc688ced2020-11-04 19:46:156250
Matt Menkef5ee9782021-02-09 05:17:486251 // View source opens the URL in a new tab as a top-level navigation. A
6252 // top-level navigation may have a different IsolationInfo than the source
6253 // iframe, so preserve the IsolationInfo from the origin frame, to use the
6254 // same network shard and increase chances of a cache hit.
6255 navigation_entry->set_isolation_info(
6256 frame->ComputeIsolationInfoForNavigation(navigation_entry->GetURL()));
Yao Xiaof68f57d2019-10-03 04:20:056257
Lukasz Anforowicze1b954d92017-10-30 21:28:066258 // Do not restore scroller position.
6259 // TODO(creis, lukasza, arthursonzogni): Do not reuse the original PageState,
6260 // but start from a new one and only copy the needed data.
Miyoung Shin5d77f72072020-10-09 15:14:206261 const blink::PageState& new_page_state =
Lukasz Anforowicze1b954d92017-10-30 21:28:066262 frame_entry->page_state().RemoveScrollOffset();
6263
6264 scoped_refptr<FrameNavigationEntry> new_frame_entry =
6265 navigation_entry->root_node()->frame_entry;
6266 new_frame_entry->set_method(frame_entry->method());
6267 new_frame_entry->SetPageState(new_page_state);
6268
6269 // Create a new WebContents, which is used to display the source code.
erikchenbee5c9622018-04-27 19:30:256270 std::unique_ptr<WebContents> view_source_contents =
Erik Chenbb8e738e2018-04-28 14:10:436271 Create(CreateParams(GetBrowserContext()));
Lukasz Anforowicze1b954d92017-10-30 21:28:066272
6273 // Restore the previously created NavigationEntry.
6274 std::vector<std::unique_ptr<NavigationEntry>> navigation_entries;
6275 navigation_entries.push_back(std::move(navigation_entry));
Lukasz Anforowicz0de0f452020-12-02 19:57:156276 view_source_contents->GetController().Restore(0, RestoreType::kRestored,
Lukasz Anforowicze1b954d92017-10-30 21:28:066277 &navigation_entries);
6278
6279 // Add |view_source_contents| as a new tab.
Lukasz Anforowicze1b954d92017-10-30 21:28:066280 constexpr bool kUserGesture = true;
6281 bool ignored_was_blocked;
Joel Hockey891e88062020-04-30 05:38:446282 delegate_->AddNewContents(this, std::move(view_source_contents), url,
Lukasz Anforowicze1b954d92017-10-30 21:28:066283 WindowOpenDisposition::NEW_FOREGROUND_TAB,
Brad Triebwasser767c27a2022-08-25 22:56:056284 blink::mojom::WindowFeatures(), kUserGesture,
6285 &ignored_was_blocked);
Lukasz Anforowicze1b954d92017-10-30 21:28:066286 // Note that the |delegate_| could have deleted |view_source_contents| during
6287 // AddNewContents method call.
6288}
6289
Jay Civelli116683f2018-03-27 19:56:236290void WebContentsImpl::ResourceLoadComplete(
Kevin McNeefb86fcf2021-02-26 23:20:576291 RenderFrameHostImpl* render_frame_host,
Clark DuVall36164bd2018-08-09 22:49:086292 const GlobalRequestID& request_id,
Minggang Wangee5af392020-02-05 02:55:286293 blink::mojom::ResourceLoadInfoPtr resource_load_info) {
Alexander Timinf785f342021-03-18 00:00:566294 OPTIONAL_TRACE_EVENT2("content", "WebContentsImpl::ResourceLoadComplete",
6295 "render_frame_host", render_frame_host, "request_id",
6296 request_id);
Andrew Grievee19cd93e2021-01-22 05:43:066297 const blink::mojom::ResourceLoadInfo& resource_load_info_ref =
6298 *resource_load_info;
6299 observers_.NotifyObservers(&WebContentsObserver::ResourceLoadComplete,
6300 render_frame_host, request_id,
6301 resource_load_info_ref);
John Abd-El-Malekd4882642017-12-04 21:45:196302}
6303
Gyuyoung Kim1ac4ca782020-09-11 03:32:516304const blink::web_pref::WebPreferences&
6305WebContentsImpl::GetOrCreateWebPreferences() {
Alexander Timin5fdeff22020-09-08 09:20:376306 OPTIONAL_TRACE_EVENT0("content",
6307 "WebContentsImpl::GetOrCreateWebPreferences");
Rakina Zata Amni347b70902020-07-22 10:49:046308 // Compute WebPreferences based on the current state if it's null.
6309 if (!web_preferences_)
Rakina Zata Amni4029b6d2020-07-28 02:36:206310 OnWebPreferencesChanged();
Rakina Zata Amni347b70902020-07-22 10:49:046311 return *web_preferences_.get();
6312}
6313
Gyuyoung Kim1ac4ca782020-09-11 03:32:516314void WebContentsImpl::SetWebPreferences(
6315 const blink::web_pref::WebPreferences& prefs) {
Alexander Timin5fdeff22020-09-08 09:20:376316 OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::SetWebPreferences");
Gyuyoung Kim1ac4ca782020-09-11 03:32:516317 web_preferences_ = std::make_unique<blink::web_pref::WebPreferences>(prefs);
Rakina Zata Amni347b70902020-07-22 10:49:046318 // Get all the RenderViewHosts (except the ones for currently back-forward
6319 // cached pages), and make them send the current WebPreferences
6320 // to the renderer. WebPreferences updates for back-forward cached pages will
6321 // be sent when we restore those pages from the back-forward cache.
Sharon Yanged884542023-02-02 17:33:446322 primary_frame_tree_.ForEachRenderViewHost(
6323 [](RenderViewHostImpl* rvh) { rvh->SendWebPreferencesToRenderer(); });
Rakina Zata Amni347b70902020-07-22 10:49:046324}
6325
6326void WebContentsImpl::RecomputeWebPreferencesSlow() {
Alexander Timin5fdeff22020-09-08 09:20:376327 OPTIONAL_TRACE_EVENT0("content",
6328 "WebContentsImpl::RecomputeWebPreferencesSlow");
Rakina Zata Amni4029b6d2020-07-28 02:36:206329 // OnWebPreferencesChanged is a no-op when this is true.
6330 if (updating_web_preferences_)
6331 return;
Rakina Zata Amni347b70902020-07-22 10:49:046332 // Resets |web_preferences_| so that we won't have any cached value for slow
6333 // attributes (which won't get recomputed if we have pre-existing values for
6334 // them).
6335 web_preferences_.reset();
Rakina Zata Amni4029b6d2020-07-28 02:36:206336 OnWebPreferencesChanged();
Rakina Zata Amni347b70902020-07-22 10:49:046337}
6338
Bo Liub5e79d92021-06-12 01:40:416339absl::optional<SkColor> WebContentsImpl::GetBaseBackgroundColor() {
6340 return page_base_background_color_;
6341}
6342
Wei Li5bb659742018-02-14 03:07:586343void WebContentsImpl::PrintCrossProcessSubframe(
6344 const gfx::Rect& rect,
6345 int document_cookie,
Kevin McNeefb86fcf2021-02-26 23:20:576346 RenderFrameHostImpl* subframe_host) {
Alexander Timin5fdeff22020-09-08 09:20:376347 OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::PrintCrossProcessSubframe",
Alexander Timinf785f342021-03-18 00:00:566348 "subframe", subframe_host);
Wei Li5c0b4d12018-03-22 15:05:226349 auto* outer_contents = GetOuterWebContents();
6350 if (outer_contents) {
6351 // When an extension or app page is printed, the content should be
6352 // composited with outer content, so the outer contents should handle the
6353 // print request.
6354 outer_contents->PrintCrossProcessSubframe(rect, document_cookie,
6355 subframe_host);
6356 return;
6357 }
6358
Wei Li5bb659742018-02-14 03:07:586359 // If there is no delegate such as in tests or during deletion, do nothing.
6360 if (!delegate_)
6361 return;
6362
6363 delegate_->PrintCrossProcessSubframe(this, rect, document_cookie,
6364 subframe_host);
6365}
6366
ckitagawa8695799b2020-02-05 16:08:496367void WebContentsImpl::CapturePaintPreviewOfCrossProcessSubframe(
6368 const gfx::Rect& rect,
6369 const base::UnguessableToken& guid,
Kevin McNeefb86fcf2021-02-26 23:20:576370 RenderFrameHostImpl* render_frame_host) {
Alexander Timin5fdeff22020-09-08 09:20:376371 OPTIONAL_TRACE_EVENT1(
6372 "content", "WebContentsImpl::CapturePaintPreviewOfCrossProcessSubframe",
Alexander Timinf785f342021-03-18 00:00:566373 "render_frame_host", render_frame_host);
ckitagawa8695799b2020-02-05 16:08:496374 if (!delegate_)
6375 return;
ckitagawac43ac982020-07-07 17:41:176376 delegate_->CapturePaintPreviewOfSubframe(this, rect, guid, render_frame_host);
ckitagawa8695799b2020-02-05 16:08:496377}
6378
Xiaohan Wang24ec9342022-01-15 17:34:226379#if BUILDFLAG(IS_ANDROID)
rob.buis300b0872017-03-10 20:43:586380base::android::ScopedJavaLocalRef<jobject>
6381WebContentsImpl::GetJavaRenderFrameHostDelegate() {
6382 return GetJavaWebContents();
6383}
6384#endif
6385
Kevin McNeefb86fcf2021-02-26 23:20:576386void WebContentsImpl::DOMContentLoaded(RenderFrameHostImpl* render_frame_host) {
Alexander Timin5fdeff22020-09-08 09:20:376387 OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::DOMContentLoaded",
Alexander Timinf785f342021-03-18 00:00:566388 "render_frame_host", render_frame_host);
Clark DuVall22aaff32021-03-18 17:17:476389 SCOPED_UMA_HISTOGRAM_TIMER("WebContentsObserver.DOMContentLoaded");
Andrew Grievee19cd93e2021-01-22 05:43:066390 observers_.NotifyObservers(&WebContentsObserver::DOMContentLoaded,
6391 render_frame_host);
[email protected]724159a2010-12-30 01:11:186392}
6393
Kevin McNeefb86fcf2021-02-26 23:20:576394void WebContentsImpl::OnDidFinishLoad(RenderFrameHostImpl* render_frame_host,
nicka0ac8382016-12-15 23:59:236395 const GURL& url) {
Alexander Timin5fdeff22020-09-08 09:20:376396 OPTIONAL_TRACE_EVENT2("content", "WebContentsImpl::OnDidFinishLoad",
Alexander Timinf785f342021-03-18 00:00:566397 "render_frame_host", render_frame_host, "url", url);
[email protected]8b3af1e2014-01-24 13:29:126398 GURL validated_url(url);
Gyuyoung Kim525e0c5d2020-03-09 15:04:196399 render_frame_host->GetProcess()->FilterURL(false, &validated_url);
[email protected]028053d42014-03-05 22:20:376400
Clark DuVall22aaff32021-03-18 17:17:476401 {
6402 SCOPED_UMA_HISTOGRAM_TIMER("WebContentsObserver.DidFinishLoad");
6403 observers_.NotifyObservers(&WebContentsObserver::DidFinishLoad,
6404 render_frame_host, validated_url);
6405 }
Dave Tapuska21e9da02021-12-15 20:58:206406 size_t tree_size = GetFrameTreeSize(&primary_frame_tree_);
yilkal172da772019-11-06 22:49:076407 if (max_loaded_frame_count_ < tree_size)
6408 max_loaded_frame_count_ = tree_size;
6409
Dave Tapuska21e9da02021-12-15 20:58:206410 if (!render_frame_host->GetParentOrOuterDocument())
yilkal172da772019-11-06 22:49:076411 UMA_HISTOGRAM_COUNTS_1000("Navigation.MainFrame.FrameCount", tree_size);
[email protected]1a55c5be2011-11-29 11:36:316412}
6413
Carlos Caballeroede6f8c2021-01-28 11:01:506414bool WebContentsImpl::IsAllowedToGoToEntryAtOffset(int32_t offset) {
6415 // TODO(https://crbug.com/1170277): This should probably be renamed to
6416 // WebContentsDelegate::IsAllowedToGoToEntryAtOffset or
6417 // ShouldGoToEntryAtOffset
6418 return !delegate_ || delegate_->OnGoToEntryOffset(offset);
[email protected]216813952011-05-19 22:21:266419}
6420
Kevin McNee3183a7792021-11-09 21:03:366421void WebContentsImpl::OnPageScaleFactorChanged(PageImpl& source) {
6422 OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::OnPageScaleFactorChanged",
6423 "source", source);
mcnee432e47d2015-11-09 19:37:466424
Kevin McNee3183a7792021-11-09 21:03:366425 if (source.IsPrimary()) {
6426 observers_.NotifyObservers(&WebContentsObserver::OnPageScaleFactorChanged,
Kevin McNeec4325ba2022-04-08 23:18:236427 source.GetPageScaleFactor());
mcnee432e47d2015-11-09 19:37:466428 }
mcnee432e47d2015-11-09 19:37:466429}
6430
Kent Tamura8c9e0562018-11-06 07:02:196431void WebContentsImpl::EnumerateDirectory(
6432 RenderFrameHost* render_frame_host,
Kent Tamura3abb32d2020-07-02 00:23:016433 scoped_refptr<FileChooserImpl::FileSelectListenerImpl> listener,
Kent Tamura8c9e0562018-11-06 07:02:196434 const base::FilePath& directory_path) {
Alexander Timinf785f342021-03-18 00:00:566435 OPTIONAL_TRACE_EVENT2("content", "WebContentsImpl::EnumerateDirectory",
6436 "render_frame_host", render_frame_host,
6437 "directory_path", directory_path);
Avi Drissman1a55a9d62020-03-10 18:56:456438 // Any explicit focusing of another window while this WebContents is in
6439 // fullscreen can be used to confuse the user, so drop fullscreen.
6440 base::ScopedClosureRunner fullscreen_block = ForSecurityDropFullscreen();
6441 listener->SetFullscreenBlock(std::move(fullscreen_block));
6442
Kent Tamura8c9e0562018-11-06 07:02:196443 if (delegate_)
6444 delegate_->EnumerateDirectory(this, std::move(listener), directory_path);
6445 else
6446 listener->FileSelectionCanceled();
[email protected]3a29a6e2011-08-24 18:26:216447}
6448
Dave Tapuskaf9fc3122019-10-18 19:42:556449void WebContentsImpl::RegisterProtocolHandler(RenderFrameHostImpl* source,
6450 const std::string& protocol,
6451 const GURL& url,
Dave Tapuskaf9fc3122019-10-18 19:42:556452 bool user_gesture) {
Alexander Timin5fdeff22020-09-08 09:20:376453 OPTIONAL_TRACE_EVENT2("content", "WebContentsImpl::RegisterProtocolHandler",
Alexander Timinf785f342021-03-18 00:00:566454 "render_frame_host", source, "protocol", protocol);
nicka0ac8382016-12-15 23:59:236455 // TODO(nick): Do we need to apply FilterURL to |url|?
[email protected]e5f2de02012-07-20 22:15:436456 if (!delegate_)
6457 return;
6458
Frédéric Wangb79fece2020-10-28 18:13:076459 blink::ProtocolHandlerSecurityLevel security_level =
6460 delegate_->GetProtocolHandlerSecurityLevel(source);
6461
Javier Fernández García-Boente0bda5d22022-03-17 23:25:276462 // Run the protocol handler arguments normalization process defined in the
6463 // spec.
6464 // https://html.spec.whatwg.org/multipage/system-state.html#normalize-protocol-handler-parameters
Raymes Khoury58373df2019-08-06 06:29:206465 if (!AreValidRegisterProtocolHandlerArguments(
Frédéric Wangb79fece2020-10-28 18:13:076466 protocol, url, source->GetLastCommittedOrigin(), security_level)) {
Raymes Khoury58373df2019-08-06 06:29:206467 ReceivedBadMessage(source->GetProcess(),
6468 bad_message::REGISTER_PROTOCOL_HANDLER_INVALID_URL);
[email protected]b9535422012-02-09 01:47:596469 return;
Raymes Khoury58373df2019-08-06 06:29:206470 }
[email protected]8f810632013-06-06 22:33:326471
Carlos Caballero8a6c6b72020-07-20 16:56:226472 delegate_->RegisterProtocolHandler(source, protocol, url, user_gesture);
[email protected]7d189022011-08-25 22:54:206473}
6474
Dave Tapuskaf9fc3122019-10-18 19:42:556475void WebContentsImpl::UnregisterProtocolHandler(RenderFrameHostImpl* source,
6476 const std::string& protocol,
6477 const GURL& url,
6478 bool user_gesture) {
Alexander Timin5fdeff22020-09-08 09:20:376479 OPTIONAL_TRACE_EVENT2("content", "WebContentsImpl::UnregisterProtocolHandler",
Alexander Timinf785f342021-03-18 00:00:566480 "render_frame_host", source, "protocol", protocol);
nicka0ac8382016-12-15 23:59:236481 // TODO(nick): Do we need to apply FilterURL to |url|?
[email protected]f5273e52014-07-14 16:30:206482 if (!delegate_)
6483 return;
6484
Frédéric Wangb79fece2020-10-28 18:13:076485 blink::ProtocolHandlerSecurityLevel security_level =
6486 delegate_->GetProtocolHandlerSecurityLevel(source);
6487
Raymes Khoury58373df2019-08-06 06:29:206488 if (!AreValidRegisterProtocolHandlerArguments(
Frédéric Wangb79fece2020-10-28 18:13:076489 protocol, url, source->GetLastCommittedOrigin(), security_level)) {
Raymes Khoury58373df2019-08-06 06:29:206490 ReceivedBadMessage(source->GetProcess(),
6491 bad_message::REGISTER_PROTOCOL_HANDLER_INVALID_URL);
[email protected]f5273e52014-07-14 16:30:206492 return;
Raymes Khoury58373df2019-08-06 06:29:206493 }
[email protected]f5273e52014-07-14 16:30:206494
Carlos Caballero8a6c6b72020-07-20 16:56:226495 delegate_->UnregisterProtocolHandler(source, protocol, url, user_gesture);
[email protected]f5273e52014-07-14 16:30:206496}
6497
Ewelina Baraned2df8ad2021-12-22 10:05:376498void WebContentsImpl::DomOperationResponse(RenderFrameHost* render_frame_host,
6499 const std::string& json_string) {
6500 OPTIONAL_TRACE_EVENT2("content", "WebContentsImpl::DomOperationResponse",
6501 "render_frame_host", render_frame_host, "json_string",
6502 json_string);
Alexander Timin5fdeff22020-09-08 09:20:376503
Ewelina Baraned2df8ad2021-12-22 10:05:376504 observers_.NotifyObservers(&WebContentsObserver::DomOperationResponse,
6505 render_frame_host, json_string);
Gyuyoung Kimc5f4ac12020-05-08 10:59:396506}
6507
Gyuyoung Kim4c50517842020-06-04 17:50:446508void WebContentsImpl::SavableResourceLinksResponse(
6509 RenderFrameHostImpl* source,
6510 const std::vector<GURL>& resources_list,
6511 blink::mojom::ReferrerPtr referrer,
6512 const std::vector<blink::mojom::SavableSubframePtr>& subframes) {
Alexander Timinf785f342021-03-18 00:00:566513 OPTIONAL_TRACE_EVENT1("content",
6514 "WebContentsImpl::SavableResourceLinksResponse",
6515 "render_frame_host", source);
Dave Tapuskaa7cad8f492021-08-04 16:55:306516 if (save_package_) {
6517 save_package_->SavableResourceLinksResponse(source, resources_list,
6518 std::move(referrer), subframes);
6519 }
Gyuyoung Kim4c50517842020-06-04 17:50:446520}
6521
6522void WebContentsImpl::SavableResourceLinksError(RenderFrameHostImpl* source) {
Alexander Timin5fdeff22020-09-08 09:20:376523 OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::SavableResourceLinksError",
Alexander Timinf785f342021-03-18 00:00:566524 "render_frame_host", source);
Dave Tapuskaa7cad8f492021-08-04 16:55:306525 if (save_package_) {
6526 save_package_->SavableResourceLinksError(source);
6527 }
Gyuyoung Kim4c50517842020-06-04 17:50:446528}
6529
Alexander Timin17edc742020-04-23 18:22:186530void WebContentsImpl::OnServiceWorkerAccessed(
6531 RenderFrameHost* render_frame_host,
6532 const GURL& scope,
6533 AllowServiceWorkerResult allowed) {
Alexander Timin5fdeff22020-09-08 09:20:376534 OPTIONAL_TRACE_EVENT2("content", "WebContentsImpl::OnServiceWorkerAccessed",
Alexander Timinf785f342021-03-18 00:00:566535 "render_frame_host", render_frame_host, "scope", scope);
Andrew Grievee19cd93e2021-01-22 05:43:066536 // Use a variable to select between overloads.
6537 void (WebContentsObserver::*func)(RenderFrameHost*, const GURL&,
6538 AllowServiceWorkerResult) =
6539 &WebContentsObserver::OnServiceWorkerAccessed;
6540 observers_.NotifyObservers(func, render_frame_host, scope, allowed);
Alexander Timin17edc742020-04-23 18:22:186541}
6542
6543void WebContentsImpl::OnServiceWorkerAccessed(
6544 NavigationHandle* navigation,
6545 const GURL& scope,
6546 AllowServiceWorkerResult allowed) {
Alexander Timin5fdeff22020-09-08 09:20:376547 OPTIONAL_TRACE_EVENT2("content", "WebContentsImpl::OnServiceWorkerAccessed",
Alexander Timinf785f342021-03-18 00:00:566548 "navigation_handle", navigation, "scope", scope);
Andrew Grievee19cd93e2021-01-22 05:43:066549 // Use a variable to select between overloads.
6550 void (WebContentsObserver::*func)(NavigationHandle*, const GURL&,
6551 AllowServiceWorkerResult) =
6552 &WebContentsObserver::OnServiceWorkerAccessed;
6553 observers_.NotifyObservers(func, navigation, scope, allowed);
Alexander Timin17edc742020-04-23 18:22:186554}
6555
Miyoung Shincb6475a2019-11-09 10:49:456556void WebContentsImpl::OnColorChooserFactoryReceiver(
Julie Jeongeun Kim8e2879e2019-08-06 23:55:206557 mojo::PendingReceiver<blink::mojom::ColorChooserFactory> receiver) {
Alexander Timin5fdeff22020-09-08 09:20:376558 OPTIONAL_TRACE_EVENT0("content",
6559 "WebContentsImpl::OnColorChooserFactoryReceiver");
Julie Jeongeun Kim8e2879e2019-08-06 23:55:206560 color_chooser_factory_receivers_.Add(this, std::move(receiver));
Joel Hockey85b379d2017-12-11 10:42:136561}
6562
Tom Burgin732656d32022-02-07 18:33:266563#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_MAC)
Joel Hockey85b379d2017-12-11 10:42:136564void WebContentsImpl::OpenColorChooser(
Julie Jeongeun Kim8e2879e2019-08-06 23:55:206565 mojo::PendingReceiver<blink::mojom::ColorChooser> chooser_receiver,
6566 mojo::PendingRemote<blink::mojom::ColorChooserClient> client,
[email protected]8ed16472014-04-11 19:02:486567 SkColor color,
Joel Hockey163835a2017-12-20 11:51:576568 std::vector<blink::mojom::ColorSuggestionPtr> suggestions) {
Alexander Timin5fdeff22020-09-08 09:20:376569 OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::OpenColorChooser");
Bo Liu2bceebc2021-06-03 15:06:336570 // Create `color_chooser_holder_` before calling OpenColorChooser since
Bo Liuab8f9972021-04-08 22:44:366571 // OpenColorChooser may callback with results.
Bo Liu2bceebc2021-06-03 15:06:336572 color_chooser_holder_.reset();
6573 color_chooser_holder_ = std::make_unique<ColorChooserHolder>(
6574 std::move(chooser_receiver), std::move(client));
Elly Fong-Jones77f78d42021-01-29 23:56:556575
Bo Liu2bceebc2021-06-03 15:06:336576 auto new_color_chooser =
Ivan Kotenkov2c0d2bb32017-11-01 15:41:286577 delegate_ ? delegate_->OpenColorChooser(this, color, suggestions)
Bo Liu2bceebc2021-06-03 15:06:336578 : nullptr;
6579 if (color_chooser_holder_ && new_color_chooser) {
6580 color_chooser_holder_->SetChooser(std::move(new_color_chooser));
Bo Liu5f4bf412021-06-01 20:09:336581 } else if (new_color_chooser) {
6582 // OpenColorChooser synchronously called back to DidEndColorChooser.
Bo Liu2bceebc2021-06-03 15:06:336583 DCHECK(!color_chooser_holder_);
Bo Liu5f4bf412021-06-01 20:09:336584 new_color_chooser->End();
Bo Liu2bceebc2021-06-03 15:06:336585 } else if (color_chooser_holder_) {
Bo Liu5f4bf412021-06-01 20:09:336586 DCHECK(!new_color_chooser);
Bo Liu2bceebc2021-06-03 15:06:336587 color_chooser_holder_.reset();
Bo Liu5f4bf412021-06-01 20:09:336588 }
[email protected]da8543762012-03-20 08:52:206589}
Tom Burgin732656d32022-02-07 18:33:266590#endif // BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_MAC)
[email protected]da8543762012-03-20 08:52:206591
K. Moon9ae6ef2c2022-08-18 01:30:066592#if BUILDFLAG(ENABLE_PPAPI)
nicka0ac8382016-12-15 23:59:236593void WebContentsImpl::OnPepperInstanceCreated(RenderFrameHostImpl* source,
6594 int32_t pp_instance) {
Alexander Timin5fdeff22020-09-08 09:20:376595 OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::OnPepperInstanceCreated",
Alexander Timinf785f342021-03-18 00:00:566596 "render_frame_host", source);
Andrew Grievee19cd93e2021-01-22 05:43:066597 observers_.NotifyObservers(&WebContentsObserver::PepperInstanceCreated);
nicka0ac8382016-12-15 23:59:236598 pepper_playback_observer_->PepperInstanceCreated(source, pp_instance);
emaxxe70f5e12015-05-29 11:26:006599}
6600
nicka0ac8382016-12-15 23:59:236601void WebContentsImpl::OnPepperInstanceDeleted(RenderFrameHostImpl* source,
6602 int32_t pp_instance) {
Alexander Timin5fdeff22020-09-08 09:20:376603 OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::OnPepperInstanceDeleted",
Alexander Timinf785f342021-03-18 00:00:566604 "render_frame_host", source);
Andrew Grievee19cd93e2021-01-22 05:43:066605 observers_.NotifyObservers(&WebContentsObserver::PepperInstanceDeleted);
nicka0ac8382016-12-15 23:59:236606 pepper_playback_observer_->PepperInstanceDeleted(source, pp_instance);
emaxxe70f5e12015-05-29 11:26:006607}
6608
nicka0ac8382016-12-15 23:59:236609void WebContentsImpl::OnPepperPluginHung(RenderFrameHostImpl* source,
6610 int plugin_child_id,
tommyclie6633ca72014-10-31 00:40:426611 const base::FilePath& path,
6612 bool is_hung) {
Alexander Timin5fdeff22020-09-08 09:20:376613 OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::OnPepperPluginHung",
Alexander Timinf785f342021-03-18 00:00:566614 "render_frame_host", source);
Steven Holte95922222018-09-14 20:06:236615 UMA_HISTOGRAM_COUNTS_1M("Pepper.PluginHung", 1);
tommyclie6633ca72014-10-31 00:40:426616
Andrew Grievee19cd93e2021-01-22 05:43:066617 observers_.NotifyObservers(&WebContentsObserver::PluginHungStatusChanged,
6618 plugin_child_id, path, is_hung);
tommyclie6633ca72014-10-31 00:40:426619}
6620
nicka0ac8382016-12-15 23:59:236621void WebContentsImpl::OnPepperStartsPlayback(RenderFrameHostImpl* source,
6622 int32_t pp_instance) {
Alexander Timin5fdeff22020-09-08 09:20:376623 OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::OnPepperStartsPlayback",
Alexander Timinf785f342021-03-18 00:00:566624 "render_frame_host", source);
nicka0ac8382016-12-15 23:59:236625 pepper_playback_observer_->PepperStartsPlayback(source, pp_instance);
zqzhang181047e62016-07-01 13:37:176626}
6627
nicka0ac8382016-12-15 23:59:236628void WebContentsImpl::OnPepperStopsPlayback(RenderFrameHostImpl* source,
6629 int32_t pp_instance) {
Alexander Timin5fdeff22020-09-08 09:20:376630 OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::OnPepperStopsPlayback",
Alexander Timinf785f342021-03-18 00:00:566631 "render_frame_host", source);
nicka0ac8382016-12-15 23:59:236632 pepper_playback_observer_->PepperStopsPlayback(source, pp_instance);
zqzhang181047e62016-07-01 13:37:176633}
6634
Dave Tapuska993dae352021-01-08 17:40:596635void WebContentsImpl::OnPepperPluginCrashed(RenderFrameHostImpl* source,
6636 const base::FilePath& plugin_path,
6637 base::ProcessId plugin_pid) {
6638 OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::OnPepperPluginCrashed",
Alexander Timinf785f342021-03-18 00:00:566639 "render_frame_host", source);
nicka0ac8382016-12-15 23:59:236640 // TODO(nick): Eliminate the |plugin_pid| parameter, which can't be trusted,
Gyuyoung Kim26c7bc92020-04-29 00:53:006641 // and is only used by WebTestControlHost.
Andrew Grievee19cd93e2021-01-22 05:43:066642 observers_.NotifyObservers(&WebContentsObserver::PluginCrashed, plugin_path,
6643 plugin_pid);
tommyclie6633ca72014-10-31 00:40:426644}
6645
K. Moon9ae6ef2c2022-08-18 01:30:066646#endif // BUILDFLAG(ENABLE_PPAPI)
[email protected]19be7a62012-10-01 23:03:376647
Miyoung Shin5709ab02020-02-19 06:50:416648void WebContentsImpl::UpdateFaviconURL(
Kevin McNeefb86fcf2021-02-26 23:20:576649 RenderFrameHostImpl* source,
Ian Vollick6d75ac32021-05-05 17:45:096650 const std::vector<blink::mojom::FaviconURLPtr>& candidates) {
Alexander Timin5fdeff22020-09-08 09:20:376651 OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::UpdateFaviconURL",
Alexander Timinf785f342021-03-18 00:00:566652 "render_frame_host", source);
pkotwiczf9bc20592015-04-21 18:57:066653 // We get updated favicon URLs after the page stops loading. If a cross-site
6654 // navigation occurs while a page is still loading, the initial page
6655 // may stop loading and send us updated favicon URLs after the navigation
6656 // for the new page has committed.
Julie Jeongeun Kim0a594bb2021-10-21 05:30:536657 if (!source->IsInPrimaryMainFrame())
pkotwiczf9bc20592015-04-21 18:57:066658 return;
6659
Andrew Grievee19cd93e2021-01-22 05:43:066660 observers_.NotifyObservers(&WebContentsObserver::DidUpdateFaviconURL, source,
Ian Vollick6d75ac32021-05-05 17:45:096661 candidates);
[email protected]795c28972012-12-06 06:13:396662}
6663
qinmin72e8bd02016-10-21 19:35:376664void WebContentsImpl::SetIsOverlayContent(bool is_overlay_content) {
Alexander Timin5fdeff22020-09-08 09:20:376665 OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::SetIsOverlayContent",
6666 "is_overlay_content", is_overlay_content);
qinmin72e8bd02016-10-21 19:35:376667 is_overlay_content_ = is_overlay_content;
6668}
6669
Jeremy Roman2d8dfe132021-07-06 20:51:266670void WebContentsImpl::OnFirstVisuallyNonEmptyPaint(PageImpl& page) {
6671 OPTIONAL_TRACE_EVENT1(
6672 "content", "WebContentsImpl::OnFirstVisuallyNonEmptyPaint", "page", page);
6673 if (!page.IsPrimary())
6674 return;
6675
Clark DuVall22aaff32021-03-18 17:17:476676 {
6677 SCOPED_UMA_HISTOGRAM_TIMER(
6678 "WebContentsObserver.DidFirstVisuallyNonEmptyPaint");
6679 observers_.NotifyObservers(
6680 &WebContentsObserver::DidFirstVisuallyNonEmptyPaint);
6681 }
Jeremy Roman2d8dfe132021-07-06 20:51:266682 if (page.theme_color() != last_sent_theme_color_) {
yusufod41c5f92015-03-06 00:14:286683 // Theme color should have updated by now if there was one.
Andrew Grievee19cd93e2021-01-22 05:43:066684 observers_.NotifyObservers(&WebContentsObserver::DidChangeThemeColor);
Jeremy Roman2d8dfe132021-07-06 20:51:266685 last_sent_theme_color_ = GetPrimaryPage().theme_color();
yusufod41c5f92015-03-06 00:14:286686 }
Alan Cutterd73a15d92020-08-21 07:12:456687
Jeremy Roman2d8dfe132021-07-06 20:51:266688 if (page.background_color() != last_sent_background_color_) {
Alan Cutterd73a15d92020-08-21 07:12:456689 // Background color should have updated by now if there was one.
Andrew Grievee19cd93e2021-01-22 05:43:066690 observers_.NotifyObservers(&WebContentsObserver::OnBackgroundColorChanged);
Jeremy Roman2d8dfe132021-07-06 20:51:266691 last_sent_background_color_ = page.background_color();
Alan Cutterd73a15d92020-08-21 07:12:456692 }
[email protected]9f268072013-11-07 00:02:156693}
[email protected]d9030b82013-07-19 08:26:066694
Charlie Reis3d189602021-04-27 21:24:476695bool WebContentsImpl::IsGuest() {
6696 return !!browser_plugin_guest_;
6697}
6698
Kevin McNee068c3eb2020-04-03 18:24:196699bool WebContentsImpl::IsPortal() {
Adithya Srinivasan46b8a792019-02-01 14:47:236700 return portal();
6701}
6702
Kevin McNee94ea52f52020-06-23 17:42:066703WebContentsImpl* WebContentsImpl::GetPortalHostWebContents() {
6704 return portal() ? portal()->GetPortalHostContents() : nullptr;
6705}
6706
[email protected]17e286e2013-03-01 23:29:396707void WebContentsImpl::NotifyBeforeFormRepostWarningShow() {
Alexander Timin5fdeff22020-09-08 09:20:376708 OPTIONAL_TRACE_EVENT0("content",
6709 "WebContentsImpl::NotifyBeforeFormRepostWarningShow");
Andrew Grievee19cd93e2021-01-22 05:43:066710 observers_.NotifyObservers(&WebContentsObserver::BeforeFormRepostWarningShow);
[email protected]17e286e2013-03-01 23:29:396711}
6712
[email protected]ec6c05f2013-10-23 18:41:576713void WebContentsImpl::ActivateAndShowRepostFormWarningDialog() {
Alexander Timin5fdeff22020-09-08 09:20:376714 OPTIONAL_TRACE_EVENT0(
6715 "content", "WebContentsImpl::ActivateAndShowRepostFormWarningDialog");
[email protected]ec6c05f2013-10-23 18:41:576716 Activate();
6717 if (delegate_)
6718 delegate_->ShowRepostFormWarningDialog(this);
6719}
6720
[email protected]b4c84012014-04-28 19:51:106721bool WebContentsImpl::HasAccessedInitialDocument() {
Carlos Caballero6a99dac2021-11-03 10:41:176722 return GetPrimaryFrameTree().has_accessed_initial_main_document();
[email protected]b4c84012014-04-28 19:51:106723}
6724
afakhry6f0c1ec22016-07-14 13:55:136725void WebContentsImpl::UpdateTitleForEntry(NavigationEntry* entry,
Jan Wilken Dörrieaace0cfef2021-03-11 22:01:586726 const std::u16string& title) {
Alexander Timin5fdeff22020-09-08 09:20:376727 OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::UpdateTitleForEntry",
Alexander Timinf785f342021-03-18 00:00:566728 "title", title);
Adithya Srinivasan9b0c99c2021-08-10 15:19:456729 NavigationEntryImpl* entry_impl =
6730 NavigationEntryImpl::FromNavigationEntry(entry);
6731 bool title_changed = UpdateTitleForEntryImpl(entry_impl, title);
6732 if (title_changed)
6733 NotifyTitleUpdateForEntry(entry_impl);
6734}
6735
6736bool WebContentsImpl::UpdateTitleForEntryImpl(NavigationEntryImpl* entry,
6737 const std::u16string& title) {
Rakina Zata Amni46087a12022-11-11 08:28:386738 DCHECK(entry);
Jan Wilken Dörrieaace0cfef2021-03-11 22:01:586739 std::u16string final_title;
Avi Drissman93002212017-09-27 03:20:526740 base::TrimWhitespace(title, base::TRIM_ALL, &final_title);
[email protected]420ae012009-04-24 05:16:326741
Rakina Zata Amni46087a12022-11-11 08:28:386742 if (final_title == entry->GetTitle())
6743 return false; // Nothing changed, don't bother.
[email protected]420ae012009-04-24 05:16:326744
Rakina Zata Amni46087a12022-11-11 08:28:386745 entry->SetTitle(final_title);
6746 // The title for display may differ from the title just set; grab it.
6747 final_title = entry->GetTitleForDisplay();
Avi Drissman93002212017-09-27 03:20:526748
Adithya Srinivasan9b0c99c2021-08-10 15:19:456749 return true;
6750}
[email protected]420ae012009-04-24 05:16:326751
Adithya Srinivasan9b0c99c2021-08-10 15:19:456752void WebContentsImpl::NotifyTitleUpdateForEntry(NavigationEntryImpl* entry) {
Rakina Zata Amni46087a12022-11-11 08:28:386753 // |entry| must belong to the primary frame tree's NavigationController.
6754 DCHECK(GetController().GetEntryWithUniqueIDIncludingPending(
6755 entry->GetUniqueID()));
6756 std::u16string final_title = entry->GetTitleForDisplay();
Adithya Srinivasan9b0c99c2021-08-10 15:19:456757 bool did_web_contents_title_change = entry == GetNavigationEntryForTitle();
6758 if (did_web_contents_title_change)
6759 view_->SetPageTitle(final_title);
[email protected]420ae012009-04-24 05:16:326760
Clark DuVall22aaff32021-03-18 17:17:476761 {
6762 SCOPED_UMA_HISTOGRAM_TIMER("WebContentsObserver.TitleWasSet");
6763 observers_.NotifyObservers(&WebContentsObserver::TitleWasSet, entry);
6764 }
Adithya Srinivasan9b0c99c2021-08-10 15:19:456765
6766 if (did_web_contents_title_change)
afakhry6f0c1ec22016-07-14 13:55:136767 NotifyNavigationStateChanged(INVALIDATE_TYPE_TITLE);
[email protected]420ae012009-04-24 05:16:326768}
6769
Adithya Srinivasan9b0c99c2021-08-10 15:19:456770NavigationEntry* WebContentsImpl::GetNavigationEntryForTitle() {
6771 // We use the title for the last committed entry rather than a pending
6772 // navigation entry. For example, when the user types in a URL, we want to
6773 // keep the old page's title until the new load has committed and we get a new
6774 // title.
6775 NavigationEntry* entry = GetController().GetLastCommittedEntry();
6776
6777 // We make an exception for initial navigations. We only want to use the title
6778 // from the visible entry if:
6779 // 1. The pending entry has been explicitly assigned a title to display.
6780 // 2. The user is doing a history navigation in a new tab (e.g., Ctrl+Back),
6781 // which case there is a pending entry index other than -1.
6782 //
6783 // Otherwise, we want to stick with the last committed entry's title during
6784 // new navigations, which have pending entries at index -1 with no title.
6785 if (GetController().IsInitialNavigation() &&
6786 ((GetController().GetVisibleEntry() &&
6787 !GetController().GetVisibleEntry()->GetTitle().empty()) ||
6788 GetController().GetPendingEntryIndex() != -1)) {
6789 entry = GetController().GetVisibleEntry();
6790 }
6791
6792 return entry;
6793}
6794
fdegansa696e5112015-04-17 01:57:596795void WebContentsImpl::SendChangeLoadProgress() {
Alexander Timin5fdeff22020-09-08 09:20:376796 OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::SendChangeLoadProgress",
Sreeja Kamishetty0be3b1b2021-08-12 17:04:156797 "load_progress", GetLoadProgress());
[email protected]960b0372014-05-19 18:01:006798 loading_last_progress_update_ = base::TimeTicks::Now();
Clark DuVall22aaff32021-03-18 17:17:476799
6800 SCOPED_UMA_HISTOGRAM_TIMER("WebContentsObserver.LoadProgressChanged");
Andrew Grievee19cd93e2021-01-22 05:43:066801 observers_.NotifyObservers(&WebContentsObserver::LoadProgressChanged,
Sreeja Kamishetty0be3b1b2021-08-12 17:04:156802 GetLoadProgress());
[email protected]960b0372014-05-19 18:01:006803}
6804
6805void WebContentsImpl::ResetLoadProgressState() {
Alexander Timin5fdeff22020-09-08 09:20:376806 OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::ResetLoadProgressState");
Sreeja Kamishetty0be3b1b2021-08-12 17:04:156807 GetPrimaryPage().set_load_progress(0.0);
[email protected]960b0372014-05-19 18:01:006808 loading_weak_factory_.InvalidateWeakPtrs();
6809 loading_last_progress_update_ = base::TimeTicks();
6810}
6811
clamy44e84ce2016-02-22 15:38:256812// Notifies the RenderWidgetHost instance about the fact that the page is
6813// loading, or done loading.
Nate Chapin9aabf5f2021-11-12 00:31:196814void WebContentsImpl::LoadingStateChanged(bool should_show_loading_ui,
clamy44e84ce2016-02-22 15:38:256815 LoadNotificationDetails* details) {
Takashi Toyoshimaea534ef22021-07-21 03:27:596816 if (IsBeingDestroyed())
Nate Chapin22ea6592019-03-05 22:29:026817 return;
clamy44e84ce2016-02-22 15:38:256818
6819 bool is_loading = IsLoading();
6820
Alexander Timin5fdeff22020-09-08 09:20:376821 OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::LoadingStateChanged",
6822 "is_loading", is_loading);
6823
clamy44e84ce2016-02-22 15:38:256824 if (!is_loading) {
Jan Wilken Dörrieaace0cfef2021-03-11 22:01:586825 load_state_ =
6826 net::LoadStateWithParam(net::LOAD_STATE_IDLE, std::u16string());
clamy44e84ce2016-02-22 15:38:256827 load_state_host_.clear();
6828 upload_size_ = 0;
6829 upload_position_ = 0;
6830 }
6831
Nate Chapin9aabf5f2021-11-12 00:31:196832 should_show_loading_ui_ = should_show_loading_ui;
clamy44e84ce2016-02-22 15:38:256833
6834 if (delegate_)
Nate Chapin9aabf5f2021-11-12 00:31:196835 delegate_->LoadingStateChanged(this, should_show_loading_ui_);
clamy44e84ce2016-02-22 15:38:256836 NotifyNavigationStateChanged(INVALIDATE_TYPE_LOAD);
6837
6838 std::string url = (details ? details->url.possibly_invalid_spec() : "NULL");
6839 if (is_loading) {
Dan Elphick3fb6ca12020-10-26 18:15:486840 TRACE_EVENT_NESTABLE_ASYNC_BEGIN2(
6841 "browser,navigation", "WebContentsImpl Loading", this, "URL", url,
Carlos Caballero6a99dac2021-11-03 10:41:176842 "Primary Main FrameTreeNode id",
6843 GetPrimaryFrameTree().root()->frame_tree_node_id());
Clark DuVall22aaff32021-03-18 17:17:476844 SCOPED_UMA_HISTOGRAM_TIMER("WebContentsObserver.DidStartLoading");
Andrew Grievee19cd93e2021-01-22 05:43:066845 observers_.NotifyObservers(&WebContentsObserver::DidStartLoading);
clamy44e84ce2016-02-22 15:38:256846 } else {
Dan Elphick3fb6ca12020-10-26 18:15:486847 TRACE_EVENT_NESTABLE_ASYNC_END1(
6848 "browser,navigation", "WebContentsImpl Loading", this, "URL", url);
Clark DuVall22aaff32021-03-18 17:17:476849 SCOPED_UMA_HISTOGRAM_TIMER("WebContentsObserver.DidStopLoading");
Andrew Grievee19cd93e2021-01-22 05:43:066850 observers_.NotifyObservers(&WebContentsObserver::DidStopLoading);
clamy44e84ce2016-02-22 15:38:256851 }
6852
6853 // TODO(avi): Remove. http://crbug.com/170921
6854 int type = is_loading ? NOTIFICATION_LOAD_START : NOTIFICATION_LOAD_STOP;
6855 NotificationDetails det = NotificationService::NoDetails();
6856 if (details)
Ian Vollick6d75ac32021-05-05 17:45:096857 det = Details<LoadNotificationDetails>(details);
clamy44e84ce2016-02-22 15:38:256858 NotificationService::current()->Notify(
Carlos Caballero40b0efd2021-01-26 11:55:006859 type, Source<NavigationController>(&GetController()), det);
clamy44e84ce2016-02-22 15:38:256860}
6861
danakja0bce4c952020-05-12 20:40:286862void WebContentsImpl::NotifyViewSwapped(RenderViewHost* old_view,
6863 RenderViewHost* new_view) {
Alexander Timin5fdeff22020-09-08 09:20:376864 OPTIONAL_TRACE_EVENT2("content", "WebContentsImpl::NotifyViewSwapped",
Alexander Timinf785f342021-03-18 00:00:566865 "old_view", old_view, "new_view", new_view);
danakja0bce4c952020-05-12 20:40:286866 DCHECK_NE(old_view, new_view);
[email protected]420ae012009-04-24 05:16:326867 // After sending out a swap notification, we need to send a disconnect
6868 // notification so that clients that pick up a pointer to |this| can NULL the
6869 // pointer. See Bug 1230284.
6870 notify_disconnection_ = true;
Nasko Oskov82dbf012023-01-10 22:40:016871 observers_.NotifyObservers(&WebContentsObserver::RenderViewHostChanged,
6872 old_view, new_view);
danakja0bce4c952020-05-12 20:40:286873 view_->RenderViewHostChanged(old_view, new_view);
Jinsuk Kimdc5284c22018-07-11 02:22:066874
Lucas Furukawa Gadanif9ea4fc2018-08-03 23:57:136875 // If this is an inner WebContents that has swapped views, we need to reattach
6876 // it to its outer WebContents.
6877 if (node_.outer_web_contents())
6878 ReattachToOuterWebContentsFrame();
6879
[email protected]7a846df2012-09-20 19:17:396880 // Ensure that the associated embedder gets cleared after a RenderViewHost
6881 // gets swapped, so we don't reuse the same embedder next time a
6882 // RenderViewHost is attached to this WebContents.
6883 RemoveBrowserPluginEmbedder();
[email protected]420ae012009-04-24 05:16:326884}
6885
Kevin McNeefb86fcf2021-02-26 23:20:576886void WebContentsImpl::NotifyFrameSwapped(RenderFrameHostImpl* old_frame,
Dave Tapuskae45d6fd2021-09-29 17:03:596887 RenderFrameHostImpl* new_frame) {
Alexander Timin5fdeff22020-09-08 09:20:376888 TRACE_EVENT2("content", "WebContentsImpl::NotifyFrameSwapped", "old_frame",
Alexander Timinf785f342021-03-18 00:00:566889 old_frame, "new_frame", new_frame);
Xiaohan Wang24ec9342022-01-15 17:34:226890#if BUILDFLAG(IS_ANDROID)
danakja0bce4c952020-05-12 20:40:286891 // Copy importance from |old_frame| if |new_frame| is a main frame.
6892 if (old_frame && !new_frame->GetParent()) {
Kevin McNeefb86fcf2021-02-26 23:20:576893 RenderWidgetHostImpl* old_widget = old_frame->GetRenderWidgetHost();
6894 RenderWidgetHostImpl* new_widget = new_frame->GetRenderWidgetHost();
danakja0bce4c952020-05-12 20:40:286895 new_widget->SetImportance(old_widget->importance());
Bo Liu7c6779e92017-08-16 02:02:286896 }
Bo Liu168c8642017-08-28 18:26:026897#endif
Andrew Grievee19cd93e2021-01-22 05:43:066898 observers_.NotifyObservers(&WebContentsObserver::RenderFrameHostChanged,
6899 old_frame, new_frame);
[email protected]02d7b6e2014-06-24 21:01:506900}
6901
[email protected]cbb1ef592013-06-05 19:49:466902void WebContentsImpl::NotifyNavigationEntryCommitted(
6903 const LoadCommittedDetails& load_details) {
Alexander Timin5fdeff22020-09-08 09:20:376904 OPTIONAL_TRACE_EVENT0("content",
6905 "WebContentsImpl::NotifyNavigationEntryCommitted");
Clark DuVall22aaff32021-03-18 17:17:476906 SCOPED_UMA_HISTOGRAM_TIMER("WebContentsObserver.NavigationEntryCommitted");
Andrew Grievee19cd93e2021-01-22 05:43:066907 observers_.NotifyObservers(&WebContentsObserver::NavigationEntryCommitted,
6908 load_details);
[email protected]cbb1ef592013-06-05 19:49:466909}
6910
Sam McNally5c087a32017-08-25 01:46:146911void WebContentsImpl::NotifyNavigationEntryChanged(
6912 const EntryChangedDetails& change_details) {
Alexander Timin5fdeff22020-09-08 09:20:376913 OPTIONAL_TRACE_EVENT0("content",
6914 "WebContentsImpl::NotifyNavigationEntryChanged");
Clark DuVall22aaff32021-03-18 17:17:476915 SCOPED_UMA_HISTOGRAM_TIMER("WebContentsObserver.NavigationEntryChanged");
Andrew Grievee19cd93e2021-01-22 05:43:066916 observers_.NotifyObservers(&WebContentsObserver::NavigationEntryChanged,
6917 change_details);
Sam McNally5c087a32017-08-25 01:46:146918}
6919
6920void WebContentsImpl::NotifyNavigationListPruned(
6921 const PrunedDetails& pruned_details) {
Alexander Timin5fdeff22020-09-08 09:20:376922 OPTIONAL_TRACE_EVENT0("content",
6923 "WebContentsImpl::NotifyNavigationListPruned");
Andrew Grievee19cd93e2021-01-22 05:43:066924 observers_.NotifyObservers(&WebContentsObserver::NavigationListPruned,
6925 pruned_details);
Sam McNally5c087a32017-08-25 01:46:146926}
6927
Christian Dullweber1af31e62018-02-22 11:49:486928void WebContentsImpl::NotifyNavigationEntriesDeleted() {
Alexander Timin5fdeff22020-09-08 09:20:376929 OPTIONAL_TRACE_EVENT0("content",
6930 "WebContentsImpl::NotifyNavigationEntriesDeleted");
Clark DuVall22aaff32021-03-18 17:17:476931 SCOPED_UMA_HISTOGRAM_TIMER("WebContentsObserver.NavigationEntryDeleted");
Andrew Grievee19cd93e2021-01-22 05:43:066932 observers_.NotifyObservers(&WebContentsObserver::NavigationEntriesDeleted);
Christian Dullweber1af31e62018-02-22 11:49:486933}
6934
Varun Khaneja5da94302019-06-25 04:48:106935void WebContentsImpl::OnDidBlockNavigation(
6936 const GURL& blocked_url,
6937 const GURL& initiator_url,
Abhijeet Kandalkarde7348e2020-01-13 06:06:546938 blink::mojom::NavigationBlockedReason reason) {
Alexander Timinf785f342021-03-18 00:00:566939 OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::OnDidBlockNavigation",
6940 "details", [&](perfetto::TracedValue context) {
6941 // TODO(crbug.com/1183371): Replace this with passing
6942 // more parameters to TRACE_EVENT directly when
6943 // available.
6944 auto dict = std::move(context).WriteDictionary();
6945 dict.Add("blocked_url", blocked_url);
6946 dict.Add("initiator_url", initiator_url);
6947 dict.Add("reason", reason);
6948 });
Nicolas Dossou-gbetebcab2472017-09-09 12:28:406949 if (delegate_)
Varun Khaneja5da94302019-06-25 04:48:106950 delegate_->OnDidBlockNavigation(this, blocked_url, initiator_url, reason);
Nicolas Dossou-gbetebcab2472017-09-09 12:28:406951}
6952
Kevin McNeefb86fcf2021-02-26 23:20:576953void WebContentsImpl::RenderFrameCreated(
6954 RenderFrameHostImpl* render_frame_host) {
Alexander Timin5fdeff22020-09-08 09:20:376955 TRACE_EVENT1("content", "WebContentsImpl::RenderFrameCreated",
Alexander Timinf785f342021-03-18 00:00:566956 "render_frame_host", render_frame_host);
danakjcdab6ed52021-02-10 23:44:136957
Kevin McNee9f3ef7c2021-09-29 18:43:416958 if (render_frame_host->IsInPrimaryMainFrame()) {
Khushalc5eaf222021-06-30 20:15:486959 NotifyPrimaryMainFrameProcessIsAlive();
danakjcdab6ed52021-02-10 23:44:136960 }
6961
Clark DuVall22aaff32021-03-18 17:17:476962 {
6963 SCOPED_UMA_HISTOGRAM_TIMER("WebContentsObserver.RenderFrameCreated");
6964 observers_.NotifyObservers(&WebContentsObserver::RenderFrameCreated,
6965 render_frame_host);
6966 }
Kevin McNeefb86fcf2021-02-26 23:20:576967 render_frame_host->UpdateAccessibilityMode();
clamy91b7abf2016-03-24 15:17:456968
Becca Hughesd11d6502018-07-31 17:01:286969 if (display_cutout_host_impl_)
6970 display_cutout_host_impl_->RenderFrameCreated(render_frame_host);
[email protected]b849847b2013-12-10 21:57:586971}
6972
Kevin McNeefb86fcf2021-02-26 23:20:576973void WebContentsImpl::RenderFrameDeleted(
6974 RenderFrameHostImpl* render_frame_host) {
Alexander Timin5fdeff22020-09-08 09:20:376975 TRACE_EVENT1("content", "WebContentsImpl::RenderFrameDeleted",
Alexander Timinf785f342021-03-18 00:00:566976 "render_frame_host", render_frame_host);
Clark DuVall22aaff32021-03-18 17:17:476977 {
6978 SCOPED_UMA_HISTOGRAM_TIMER("WebContentsObserver.RenderFrameDeleted");
6979 observers_.NotifyObservers(&WebContentsObserver::RenderFrameDeleted,
6980 render_frame_host);
6981 }
K. Moon9ae6ef2c2022-08-18 01:30:066982#if BUILDFLAG(ENABLE_PPAPI)
zqzhang7b6f4f02016-12-07 22:10:226983 pepper_playback_observer_->RenderFrameDeleted(render_frame_host);
6984#endif
Becca Hughesfd5d8f892018-06-14 18:23:366985
Becca Hughesd11d6502018-07-31 17:01:286986 if (display_cutout_host_impl_)
6987 display_cutout_host_impl_->RenderFrameDeleted(render_frame_host);
6988
Becca Hughesfd5d8f892018-06-14 18:23:366989 // Remove any fullscreen state that the frame has stored.
Batalov Vladislave9a5f3822020-12-02 07:31:116990 FullscreenStateChanged(render_frame_host, false /* is_fullscreen */,
6991 blink::mojom::FullscreenOptionsPtr());
[email protected]b849847b2013-12-10 21:57:586992}
6993
Gyuyoung Kim1bc1ba82021-02-08 23:32:446994void WebContentsImpl::ShowContextMenu(
Lukasz Anforowicz49e30ea02021-10-28 20:31:566995 RenderFrameHost& render_frame_host,
Gyuyoung Kim1bc1ba82021-02-08 23:32:446996 mojo::PendingAssociatedRemote<blink::mojom::ContextMenuClient>
6997 context_menu_client,
6998 const ContextMenuParams& params) {
Alexander Timin5fdeff22020-09-08 09:20:376999 OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::ShowContextMenu",
Alexander Timinf785f342021-03-18 00:00:567000 "render_frame_host", render_frame_host);
avie9fd8722017-04-10 16:17:587001 // If a renderer fires off a second command to show a context menu before the
7002 // first context menu is closed, just ignore it. https://crbug.com/707534
ekaramadf6750aa2017-06-06 18:29:427003 if (showing_context_menu_)
avie9fd8722017-04-10 16:17:587004 return;
7005
Gyuyoung Kim1bc1ba82021-02-08 23:32:447006 if (context_menu_client) {
7007 context_menu_client_.reset();
7008 context_menu_client_.Bind(std::move(context_menu_client));
7009 }
7010
[email protected]077e704b2014-05-23 19:24:107011 ContextMenuParams context_menu_params(params);
[email protected]a09d53ce2014-01-31 00:46:427012 // Allow WebContentsDelegates to handle the context menu operation first.
Joel Klinghed0ea22ea2019-02-20 22:04:227013 if (delegate_ &&
7014 delegate_->HandleContextMenu(render_frame_host, context_menu_params))
[email protected]a09d53ce2014-01-31 00:46:427015 return;
7016
[email protected]077e704b2014-05-23 19:24:107017 render_view_host_delegate_view_->ShowContextMenu(render_frame_host,
7018 context_menu_params);
[email protected]a09d53ce2014-01-31 00:46:427019}
7020
Avi Drissman4891b852018-09-25 18:12:587021namespace {
7022// Normalizes the line endings: \r\n -> \n, lone \r -> \n.
Jan Wilken Dörrieaace0cfef2021-03-11 22:01:587023std::u16string NormalizeLineBreaks(const std::u16string& source) {
Jan Wilken Dörrie8aeb5742021-03-23 19:27:027024 static const base::NoDestructor<std::u16string> kReturnNewline(u"\r\n");
7025 static const base::NoDestructor<std::u16string> kReturn(u"\r");
7026 static const base::NoDestructor<std::u16string> kNewline(u"\n");
Avi Drissman4891b852018-09-25 18:12:587027
7028 std::vector<base::StringPiece16> pieces;
7029
7030 for (const auto& rn_line : base::SplitStringPieceUsingSubstr(
7031 source, *kReturnNewline, base::KEEP_WHITESPACE,
7032 base::SPLIT_WANT_ALL)) {
7033 auto r_lines = base::SplitStringPieceUsingSubstr(
7034 rn_line, *kReturn, base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL);
7035 std::move(std::begin(r_lines), std::end(r_lines),
7036 std::back_inserter(pieces));
7037 }
7038
7039 return base::JoinString(pieces, *kNewline);
7040}
7041} // namespace
7042
Dave Tapuskacdf545cc2020-01-23 18:38:527043void WebContentsImpl::RunJavaScriptDialog(
Kevin McNeefb86fcf2021-02-26 23:20:577044 RenderFrameHostImpl* render_frame_host,
Jan Wilken Dörrieaace0cfef2021-03-11 22:01:587045 const std::u16string& message,
7046 const std::u16string& default_prompt,
Dave Tapuskacdf545cc2020-01-23 18:38:527047 JavaScriptDialogType dialog_type,
Carlos IL5c669bc2021-05-26 21:16:247048 bool disable_third_party_subframe_suppresion,
Dave Tapuskacdf545cc2020-01-23 18:38:527049 JavaScriptDialogCallback response_callback) {
Alexander Timin5fdeff22020-09-08 09:20:377050 OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::RunJavaScriptDialog",
Alexander Timinf785f342021-03-18 00:00:567051 "render_frame_host", render_frame_host);
Adithya Srinivasan8c177fe82022-07-28 15:26:277052 DCHECK(render_frame_host->GetPage().IsPrimary() && !IsPortal());
Tal Pressmanf1cdc752021-10-25 05:03:497053
Avi Drissman2ccbb402018-03-20 21:11:367054 // Ensure that if showing a dialog is the first thing that a page does, that
7055 // the contents of the previous page aren't shown behind it. This is required
7056 // because showing a dialog freezes the renderer, so no frames will be coming
7057 // from it. https://crbug.com/823353
Kevin McNeefb86fcf2021-02-26 23:20:577058 auto* render_widget_host_impl = render_frame_host->GetRenderWidgetHost();
Avi Drissman2ccbb402018-03-20 21:11:367059 if (render_widget_host_impl)
7060 render_widget_host_impl->ForceFirstFrameAfterNavigationTimeout();
7061
avi0720b02e2017-06-13 03:22:137062 // Running a dialog causes an exit to webpage-initiated fullscreen.
7063 // http://crbug.com/728276
Avi Drissman1a55a9d62020-03-10 18:56:457064 base::ScopedClosureRunner fullscreen_block = ForSecurityDropFullscreen();
avi0720b02e2017-06-13 03:22:137065
Avi Drissman1a55a9d62020-03-10 18:56:457066 auto callback =
7067 base::BindOnce(&WebContentsImpl::OnDialogClosed, base::Unretained(this),
7068 render_frame_host->GetProcess()->GetID(),
7069 render_frame_host->GetRoutingID(),
7070 std::move(response_callback), std::move(fullscreen_block));
Pavel Feldman3c1842b2017-08-02 05:00:167071
Pavel Feldman3c1842b2017-08-02 05:00:167072 std::vector<protocol::PageHandler*> page_handlers =
7073 protocol::PageHandler::EnabledForWebContents(this);
7074
Pavel Feldmanfab3cb62017-10-05 01:02:017075 if (delegate_)
7076 dialog_manager_ = delegate_->GetJavaScriptDialogManager(this);
7077
Charlie Reis96077362019-07-04 00:34:047078 // While a JS message dialog is showing, defer commits in this WebContents.
David Bokan1bdb3701f2021-04-30 22:02:357079 javascript_dialog_dismiss_notifier_ =
7080 std::make_unique<JavaScriptDialogDismissNotifier>();
Charlie Reis96077362019-07-04 00:34:047081
Carlos IL07f282f2020-05-15 22:58:297082 // Suppress JavaScript dialogs when requested.
7083 bool should_suppress = delegate_ && delegate_->ShouldSuppressDialogs(this);
Pavel Feldman1c587bc52018-04-04 21:16:057084 bool has_non_devtools_handlers = delegate_ && dialog_manager_;
7085 bool has_handlers = page_handlers.size() || has_non_devtools_handlers;
Pavel Feldmanfab3cb62017-10-05 01:02:017086 bool suppress_this_message = should_suppress || !has_handlers;
7087
Carlos IL5c669bc2021-05-26 21:16:247088 if (!disable_third_party_subframe_suppresion &&
7089 GetContentClient()->browser()->SuppressDifferentOriginSubframeJSDialogs(
Carlos IL0806d682021-02-25 19:47:267090 GetBrowserContext())) {
Carlos IL6a2cd962021-03-23 19:13:467091 // We can't check for opaque origin cases, default to allowing them to
7092 // trigger dialogs.
7093 // TODO(carlosil): The main use case for opaque use cases are tests,
7094 // investigate if there are uses in the wild, otherwise adapt tests that
7095 // require dialogs so they commit an origin first, and remove this
7096 // conditional.
7097 if (!render_frame_host->GetLastCommittedOrigin().opaque()) {
7098 bool is_different_origin_subframe =
7099 render_frame_host->GetLastCommittedOrigin() !=
Lukasz Anforowiczd00c1ed2022-01-13 05:25:107100 render_frame_host->GetOutermostMainFrame()->GetLastCommittedOrigin();
Carlos IL6a2cd962021-03-23 19:13:467101 suppress_this_message |= is_different_origin_subframe;
Carlos IL7971a0792021-04-07 21:43:357102 if (is_different_origin_subframe) {
Dave Tapuska327c06c92022-06-13 20:31:517103 GetPrimaryMainFrame()->AddMessageToConsole(
Carlos IL7971a0792021-04-07 21:43:357104 blink::mojom::ConsoleMessageLevel::kWarning,
7105 base::StringPrintf(
7106 "A different origin subframe tried to create a JavaScript "
7107 "dialog. This is no longer allowed and was blocked. See "
7108 "https://www.chromestatus.com/feature/5148698084376576 for "
7109 "more details."));
7110 }
Carlos IL6a2cd962021-03-23 19:13:467111 }
Carlos IL0d9b7592021-02-08 22:23:167112 }
7113
Pavel Feldmanfab3cb62017-10-05 01:02:017114 if (suppress_this_message) {
Jan Wilken Dörrieaace0cfef2021-03-11 22:01:587115 std::move(callback).Run(true, false, std::u16string());
Pavel Feldman3c1842b2017-08-02 05:00:167116 return;
7117 }
7118
7119 scoped_refptr<CloseDialogCallbackWrapper> wrapper =
Avi Drissmane04d3992017-10-05 15:11:367120 new CloseDialogCallbackWrapper(std::move(callback));
Pavel Feldman3c1842b2017-08-02 05:00:167121
7122 is_showing_javascript_dialog_ = true;
7123
Jan Wilken Dörrieaace0cfef2021-03-11 22:01:587124 std::u16string normalized_message = NormalizeLineBreaks(message);
Avi Drissman4891b852018-09-25 18:12:587125
Pavel Feldman3c1842b2017-08-02 05:00:167126 for (auto* handler : page_handlers) {
Avi Drissmane04d3992017-10-05 15:11:367127 handler->DidRunJavaScriptDialog(
Avi Drissman4891b852018-09-25 18:12:587128 render_frame_host->GetLastCommittedURL(), normalized_message,
7129 default_prompt, dialog_type, has_non_devtools_handlers,
Avi Drissmane04d3992017-10-05 15:11:367130 base::BindOnce(&CloseDialogCallbackWrapper::Run, wrapper, false));
Pavel Feldman3c1842b2017-08-02 05:00:167131 }
7132
7133 if (dialog_manager_) {
[email protected]87de04b02014-04-08 22:14:497134 dialog_manager_->RunJavaScriptDialog(
Avi Drissman4891b852018-09-25 18:12:587135 this, render_frame_host, dialog_type, normalized_message,
7136 default_prompt,
Avi Drissmane04d3992017-10-05 15:11:367137 base::BindOnce(&CloseDialogCallbackWrapper::Run, wrapper, false),
7138 &suppress_this_message);
[email protected]87de04b02014-04-08 22:14:497139 }
7140
7141 if (suppress_this_message) {
7142 // If we are suppressing messages, just reply as if the user immediately
7143 // pressed "Cancel", passing true to |dialog_was_suppressed|.
Jan Wilken Dörrieaace0cfef2021-03-11 22:01:587144 wrapper->Run(true, false, std::u16string());
[email protected]87de04b02014-04-08 22:14:497145 }
[email protected]87de04b02014-04-08 22:14:497146}
7147
David Bokan1bdb3701f2021-04-30 22:02:357148void WebContentsImpl::NotifyOnJavaScriptDialogDismiss(
7149 base::OnceClosure callback) {
7150 DCHECK(javascript_dialog_dismiss_notifier_);
7151 javascript_dialog_dismiss_notifier_->NotifyOnDismiss(std::move(callback));
7152}
7153
[email protected]87de04b02014-04-08 22:14:497154void WebContentsImpl::RunBeforeUnloadConfirm(
Kevin McNeefb86fcf2021-02-26 23:20:577155 RenderFrameHostImpl* render_frame_host,
[email protected]87de04b02014-04-08 22:14:497156 bool is_reload,
Dave Tapuskacdf545cc2020-01-23 18:38:527157 JavaScriptDialogCallback response_callback) {
Alexander Timin5fdeff22020-09-08 09:20:377158 OPTIONAL_TRACE_EVENT2("content", "WebContentsImpl::RunBeforeUnloadConfirm",
Alexander Timinf785f342021-03-18 00:00:567159 "render_frame_host", render_frame_host, "is_reload",
7160 is_reload);
Adithya Srinivasan8c177fe82022-07-28 15:26:277161 DCHECK(render_frame_host->GetPage().IsPrimary() && !IsPortal());
Tal Pressmanf1cdc752021-10-25 05:03:497162
Avi Drissman2ccbb402018-03-20 21:11:367163 // Ensure that if showing a dialog is the first thing that a page does, that
7164 // the contents of the previous page aren't shown behind it. This is required
7165 // because showing a dialog freezes the renderer, so no frames will be coming
7166 // from it. https://crbug.com/823353
Kevin McNeefb86fcf2021-02-26 23:20:577167 auto* render_widget_host_impl = render_frame_host->GetRenderWidgetHost();
Avi Drissman2ccbb402018-03-20 21:11:367168 if (render_widget_host_impl)
7169 render_widget_host_impl->ForceFirstFrameAfterNavigationTimeout();
7170
avi0720b02e2017-06-13 03:22:137171 // Running a dialog causes an exit to webpage-initiated fullscreen.
7172 // http://crbug.com/728276
Avi Drissman1a55a9d62020-03-10 18:56:457173 base::ScopedClosureRunner fullscreen_block = ForSecurityDropFullscreen();
avi0720b02e2017-06-13 03:22:137174
Avi Drissman1a55a9d62020-03-10 18:56:457175 auto callback =
7176 base::BindOnce(&WebContentsImpl::OnDialogClosed, base::Unretained(this),
7177 render_frame_host->GetProcess()->GetID(),
7178 render_frame_host->GetRoutingID(),
7179 std::move(response_callback), std::move(fullscreen_block));
Pavel Feldman3c1842b2017-08-02 05:00:167180
Pavel Feldman3c1842b2017-08-02 05:00:167181 std::vector<protocol::PageHandler*> page_handlers =
7182 protocol::PageHandler::EnabledForWebContents(this);
7183
Pavel Feldmanfab3cb62017-10-05 01:02:017184 if (delegate_)
7185 dialog_manager_ = delegate_->GetJavaScriptDialogManager(this);
7186
Charlie Reis96077362019-07-04 00:34:047187 // While a JS beforeunload dialog is showing, defer commits in this
7188 // WebContents.
David Bokan1bdb3701f2021-04-30 22:02:357189 javascript_dialog_dismiss_notifier_ =
7190 std::make_unique<JavaScriptDialogDismissNotifier>();
Charlie Reis96077362019-07-04 00:34:047191
Dave Tapuska19578e92021-08-09 17:14:027192 bool should_suppress = delegate_ && delegate_->ShouldSuppressDialogs(this);
Pavel Feldman1c587bc52018-04-04 21:16:057193 bool has_non_devtools_handlers = delegate_ && dialog_manager_;
7194 bool has_handlers = page_handlers.size() || has_non_devtools_handlers;
Pavel Feldmanfab3cb62017-10-05 01:02:017195 if (should_suppress || !has_handlers) {
Jan Wilken Dörrieaace0cfef2021-03-11 22:01:587196 std::move(callback).Run(false, true, std::u16string());
[email protected]87de04b02014-04-08 22:14:497197 return;
7198 }
7199
7200 is_showing_before_unload_dialog_ = true;
Pavel Feldman3c1842b2017-08-02 05:00:167201
7202 scoped_refptr<CloseDialogCallbackWrapper> wrapper =
Avi Drissmane04d3992017-10-05 15:11:367203 new CloseDialogCallbackWrapper(std::move(callback));
Pavel Feldman3c1842b2017-08-02 05:00:167204
Kevin McNeefb86fcf2021-02-26 23:20:577205 GURL frame_url = render_frame_host->GetLastCommittedURL();
Pavel Feldman3c1842b2017-08-02 05:00:167206 for (auto* handler : page_handlers) {
Avi Drissmane04d3992017-10-05 15:11:367207 handler->DidRunBeforeUnloadConfirm(
Pavel Feldman1c587bc52018-04-04 21:16:057208 frame_url, has_non_devtools_handlers,
Avi Drissmane04d3992017-10-05 15:11:367209 base::BindOnce(&CloseDialogCallbackWrapper::Run, wrapper, false));
Pavel Feldman3c1842b2017-08-02 05:00:167210 }
7211
7212 if (dialog_manager_) {
Avi Drissmane04d3992017-10-05 15:11:367213 dialog_manager_->RunBeforeUnloadDialog(
Avi Drissmanff9ed752017-11-28 21:18:127214 this, render_frame_host, is_reload,
Avi Drissmane04d3992017-10-05 15:11:367215 base::BindOnce(&CloseDialogCallbackWrapper::Run, wrapper, false));
Pavel Feldman3c1842b2017-08-02 05:00:167216 }
[email protected]87de04b02014-04-08 22:14:497217}
7218
Kent Tamurac260c9a2018-09-14 09:10:567219void WebContentsImpl::RunFileChooser(
7220 RenderFrameHost* render_frame_host,
Kent Tamura3abb32d2020-07-02 00:23:017221 scoped_refptr<FileChooserImpl::FileSelectListenerImpl> listener,
Kent Tamurac260c9a2018-09-14 09:10:567222 const blink::mojom::FileChooserParams& params) {
Alexander Timin5fdeff22020-09-08 09:20:377223 OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::RunFileChooser",
Alexander Timinf785f342021-03-18 00:00:567224 "render_frame_host", render_frame_host);
Avi Drissman3d41e7712018-08-27 21:18:087225 // Any explicit focusing of another window while this WebContents is in
7226 // fullscreen can be used to confuse the user, so drop fullscreen.
Avi Drissman1a55a9d62020-03-10 18:56:457227 base::ScopedClosureRunner fullscreen_block = ForSecurityDropFullscreen();
7228 listener->SetFullscreenBlock(std::move(fullscreen_block));
Avi Drissman3d41e7712018-08-27 21:18:087229
naskoada75b22016-06-11 16:09:467230 if (delegate_)
Kent Tamura512a27e2018-10-04 00:49:327231 delegate_->RunFileChooser(render_frame_host, std::move(listener), params);
7232 else
7233 listener->FileSelectionCanceled();
naskoada75b22016-06-11 16:09:467234}
7235
Lucas Furukawa Gadanie1c5dfda2018-11-29 17:57:417236double WebContentsImpl::GetPendingPageZoomLevel() {
Xiaohan Wang24ec9342022-01-15 17:34:227237#if BUILDFLAG(IS_ANDROID)
Mark Schillaci1363e4a2021-10-04 19:10:097238 // On Android, use the default page zoom level when the AccessibilityPageZoom
Aishwarya Rajesh39ef1c62022-11-09 06:25:377239 // and RequestDesktopSiteZoom features are not enabled.
7240 if (!base::FeatureList::IsEnabled(features::kAccessibilityPageZoom) &&
7241 !base::FeatureList::IsEnabled(features::kRequestDesktopSiteZoom)) {
Mark Schillaci1363e4a2021-10-04 19:10:097242 return 0.0;
7243 }
7244#endif
wjmaclean64951902016-04-29 20:59:127245 NavigationEntry* pending_entry = GetController().GetPendingEntry();
7246 if (!pending_entry)
7247 return HostZoomMap::GetZoomLevel(this);
7248
7249 GURL url = pending_entry->GetURL();
7250 return HostZoomMap::GetForWebContents(this)->GetZoomLevelForHostAndScheme(
7251 url.scheme(), net::GetHostOrSpecFromURL(url));
7252}
7253
François Beaufortad6c5232018-02-26 11:00:447254bool WebContentsImpl::IsPictureInPictureAllowedForFullscreenVideo() const {
7255 return media_web_contents_observer_
7256 ->IsPictureInPictureAllowedForFullscreenVideo();
7257}
7258
ekaramada110f642016-12-21 19:47:287259bool WebContentsImpl::IsFocusedElementEditable() {
7260 RenderFrameHostImpl* frame = GetFocusedFrame();
7261 return frame && frame->has_focused_editable_element();
7262}
7263
Lucas Furukawa Gadanie1c5dfda2018-11-29 17:57:417264bool WebContentsImpl::IsShowingContextMenu() {
ekaramadf6750aa2017-06-06 18:29:427265 return showing_context_menu_;
7266}
7267
7268void WebContentsImpl::SetShowingContextMenu(bool showing) {
Alexander Timin5fdeff22020-09-08 09:20:377269 OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::SetShowingContextMenu",
7270 "showing", showing);
7271
ekaramadf6750aa2017-06-06 18:29:427272 DCHECK_NE(showing_context_menu_, showing);
7273 showing_context_menu_ = showing;
7274
7275 if (auto* view = GetRenderWidgetHostView()) {
7276 // Notify the main frame's RWHV to run the platform-specific code, if any.
7277 static_cast<RenderWidgetHostViewBase*>(view)->SetShowingContextMenu(
7278 showing);
7279 }
7280}
7281
ekaramada110f642016-12-21 19:47:287282void WebContentsImpl::ClearFocusedElement() {
Alexander Timin5fdeff22020-09-08 09:20:377283 OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::ClearFocusedElement");
ekaramada110f642016-12-21 19:47:287284 if (auto* frame = GetFocusedFrame())
7285 frame->ClearFocusedElement();
7286}
7287
danakj77eb7e82020-01-09 19:38:467288bool WebContentsImpl::IsNeverComposited() {
[email protected]7912e822014-04-16 02:37:037289 if (!delegate_)
7290 return false;
danakj77eb7e82020-01-09 19:38:467291 return delegate_->IsNeverComposited(this);
[email protected]7912e822014-04-16 02:37:037292}
7293
[email protected]5a3bdf52012-05-24 15:12:577294RenderViewHostDelegateView* WebContentsImpl::GetDelegateView() {
7295 return render_view_host_delegate_view_;
[email protected]420ae012009-04-24 05:16:327296}
7297
Mario Sanchez Prada0bd8b8c2020-10-21 17:49:237298const blink::RendererPreferences& WebContentsImpl::GetRendererPrefs() const {
[email protected]840b1512009-07-21 16:53:467299 return renderer_preferences_;
[email protected]80d96fa2009-06-10 22:34:517300}
7301
Lucas Furukawa Gadani2ec00c82018-12-14 15:53:167302RenderFrameHostImpl* WebContentsImpl::GetOuterWebContentsFrame() {
7303 if (GetOuterDelegateFrameTreeNodeId() ==
7304 FrameTreeNode::kFrameTreeNodeInvalidId) {
7305 return nullptr;
7306 }
7307
7308 FrameTreeNode* outer_node =
7309 FrameTreeNode::GloballyFindByID(GetOuterDelegateFrameTreeNodeId());
7310 // The outer node should be in the outer WebContents.
Arthur Sonzognif6785ec2022-12-05 10:11:507311 DCHECK_EQ(&outer_node->frame_tree(),
Carlos Caballero6a99dac2021-11-03 10:41:177312 &GetOuterWebContents()->GetPrimaryFrameTree());
Alexander Timin381e7e182020-04-28 19:04:037313 return outer_node->parent();
Lucas Furukawa Gadani2ec00c82018-12-14 15:53:167314}
7315
Lucas Furukawa Gadanie1c5dfda2018-11-29 17:57:417316WebContentsImpl* WebContentsImpl::GetOuterWebContents() {
Lucas Furukawa Gadani105de1e812018-05-31 19:38:397317 return node_.outer_web_contents();
avallee0206f782016-07-28 18:55:337318}
7319
Lucas Furukawa Gadani2ec00c82018-12-14 15:53:167320std::vector<WebContents*> WebContentsImpl::GetInnerWebContents() {
7321 std::vector<WebContents*> all_inner_contents;
Lucas Furukawa Gadani2ec00c82018-12-14 15:53:167322 const auto& inner_contents = node_.GetInnerWebContents();
7323 all_inner_contents.insert(all_inner_contents.end(), inner_contents.begin(),
7324 inner_contents.end());
7325 return all_inner_contents;
7326}
7327
Jeremy Roman7e70bf952020-01-07 23:23:587328WebContentsImpl* WebContentsImpl::GetResponsibleWebContents() {
7329 // Iteratively ask delegates which other contents is responsible until a fixed
7330 // point is found.
7331 WebContentsImpl* contents = this;
7332 while (WebContentsDelegate* delegate = contents->GetDelegate()) {
7333 auto* responsible_contents = static_cast<WebContentsImpl*>(
7334 delegate->GetResponsibleWebContents(contents));
7335 if (responsible_contents == contents)
7336 break;
7337 contents = responsible_contents;
7338 }
7339 return contents;
7340}
7341
avallee0206f782016-07-28 18:55:337342WebContentsImpl* WebContentsImpl::GetFocusedWebContents() {
Dave Tapuskad8b0530f2021-10-19 15:12:317343 return WebContentsImpl::FromFrameTreeNode(GetFocusedFrameTree()->root());
7344}
7345
7346FrameTree* WebContentsImpl::GetFocusedFrameTree() {
7347 return GetOutermostWebContents()->node_.focused_frame_tree();
avallee0206f782016-07-28 18:55:337348}
7349
Lukasz Anforowicz2cd231bf2020-10-02 19:13:207350void WebContentsImpl::SetFocusToLocationBar() {
7351 OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::SetFocusToLocationBar");
7352 if (delegate_)
7353 delegate_->SetFocusToLocationBar();
7354}
7355
avallee9993fca2016-11-17 06:16:507356bool WebContentsImpl::ContainsOrIsFocusedWebContents() {
7357 for (WebContentsImpl* focused_contents = GetFocusedWebContents();
7358 focused_contents;
7359 focused_contents = focused_contents->GetOuterWebContents()) {
7360 if (focused_contents == this)
7361 return true;
7362 }
7363
7364 return false;
7365}
7366
W. James MacLean9437b5bf2019-12-06 17:33:447367void WebContentsImpl::RemoveBrowserPluginEmbedder() {
Alexander Timin5fdeff22020-09-08 09:20:377368 OPTIONAL_TRACE_EVENT0("content",
7369 "WebContentsImpl::RemoveBrowserPluginEmbedder");
W. James MacLean9437b5bf2019-12-06 17:33:447370 browser_plugin_embedder_.reset();
7371}
7372
avallee0206f782016-07-28 18:55:337373WebContentsImpl* WebContentsImpl::GetOutermostWebContents() {
7374 WebContentsImpl* root = this;
7375 while (root->GetOuterWebContents())
7376 root = root->GetOuterWebContents();
7377 return root;
7378}
7379
Sean Toppingbbc4a2bd2019-01-30 02:16:147380void WebContentsImpl::InnerWebContentsCreated(WebContents* inner_web_contents) {
Alexander Timin5fdeff22020-09-08 09:20:377381 OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::InnerWebContentsCreated");
Andrew Grievee19cd93e2021-01-22 05:43:067382 observers_.NotifyObservers(&WebContentsObserver::InnerWebContentsCreated,
7383 inner_web_contents);
Sean Toppingbbc4a2bd2019-01-30 02:16:147384}
7385
Jeremy Roman03ce13ce2020-05-29 22:16:577386void WebContentsImpl::InnerWebContentsAttached(
7387 WebContents* inner_web_contents) {
Alexander Timin5fdeff22020-09-08 09:20:377388 OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::InnerWebContentsDetached");
Jeremy Roman03ce13ce2020-05-29 22:16:577389 if (inner_web_contents->IsCurrentlyAudible())
7390 OnAudioStateChanged();
7391}
7392
7393void WebContentsImpl::InnerWebContentsDetached(
7394 WebContents* inner_web_contents) {
Alexander Timin5fdeff22020-09-08 09:20:377395 OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::InnerWebContentsCreated");
Takashi Toyoshimaea534ef22021-07-21 03:27:597396 if (!IsBeingDestroyed())
Jeremy Roman03ce13ce2020-05-29 22:16:577397 OnAudioStateChanged();
7398}
7399
[email protected]b172aee2012-04-10 17:05:267400void WebContentsImpl::RenderViewReady(RenderViewHost* rvh) {
Alexander Timin5fdeff22020-09-08 09:20:377401 OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::RenderViewReady",
Alexander Timinf785f342021-03-18 00:00:567402 "render_view_host", rvh);
[email protected]151a63d2011-12-20 22:32:527403 if (rvh != GetRenderViewHost()) {
[email protected]420ae012009-04-24 05:16:327404 // Don't notify the world, since this came from a renderer in the
7405 // background.
7406 return;
7407 }
7408
dmazzoni62111452017-04-28 23:46:557409 RenderWidgetHostViewBase* rwhv =
7410 static_cast<RenderWidgetHostViewBase*>(GetRenderWidgetHostView());
7411 if (rwhv)
Dave Tapuska327c06c92022-06-13 20:31:517412 rwhv->SetMainFrameAXTreeID(GetPrimaryMainFrame()->GetAXTreeID());
dmazzoni62111452017-04-28 23:46:557413
[email protected]da7a7182013-09-06 08:11:117414 notify_disconnection_ = true;
[email protected]da7a7182013-09-06 08:11:117415
Clark DuVall22aaff32021-03-18 17:17:477416 {
7417 SCOPED_UMA_HISTOGRAM_TIMER("WebContentsObserver.RenderViewReady");
7418 observers_.NotifyObservers(&WebContentsObserver::RenderViewReady);
7419 }
Jinsuk Kim895b2c52018-07-03 06:49:167420 view_->RenderViewReady();
[email protected]420ae012009-04-24 05:16:327421}
7422
[email protected]ec6a7eb2013-04-22 17:34:227423void WebContentsImpl::RenderViewTerminated(RenderViewHost* rvh,
7424 base::TerminationStatus status,
7425 int error_code) {
Alexander Timin5fdeff22020-09-08 09:20:377426 OPTIONAL_TRACE_EVENT2("content", "WebContentsImpl::RenderViewTerminated",
Alexander Timinf785f342021-03-18 00:00:567427 "render_view_host", rvh, "status",
Alexander Timin5fdeff22020-09-08 09:20:377428 static_cast<int>(status));
Alex Moshchuk2e470ea2021-02-03 06:46:347429
7430 // It is possible to get here while the WebContentsImpl is being destroyed,
7431 // in particular when the destruction of the main frame's RenderFrameHost and
7432 // RenderViewHost triggers cleanup of the main frame's process, which in turn
7433 // dispatches RenderProcessExited observers, one of which calls in here. In
7434 // this state, we cannot check GetRenderViewHost() below, since
7435 // current_frame_host() for the root FrameTreeNode has already been cleared.
7436 // Since the WebContents is going away, none of the work here is needed, so
7437 // just return early.
Takashi Toyoshimaea534ef22021-07-21 03:27:597438 if (IsBeingDestroyed())
Alex Moshchuk2e470ea2021-02-03 06:46:347439 return;
7440
[email protected]151a63d2011-12-20 22:32:527441 if (rvh != GetRenderViewHost()) {
[email protected]420ae012009-04-24 05:16:327442 // The pending page's RenderViewHost is gone.
7443 return;
7444 }
Lingqi Chi641aeee2021-09-08 00:32:587445
7446 auto* rvh_impl = static_cast<RenderViewHostImpl*>(rvh);
Kevin McNee9f3ef7c2021-09-29 18:43:417447 DCHECK(rvh_impl->GetMainRenderFrameHost()->IsInPrimaryMainFrame())
Khushalc5eaf222021-06-30 20:15:487448 << "GetRenderViewHost() must belong to the primary frame tree";
7449
[email protected]2fcdcc32014-03-05 02:14:077450 // Ensure fullscreen mode is exited in the |delegate_| since a crashed
7451 // renderer may not have made a clean exit.
Avi Drissman97aef042020-06-30 21:04:487452 if (IsFullscreen())
bokanece34a82016-01-28 19:49:467453 ExitFullscreenMode(false);
[email protected]2fcdcc32014-03-05 02:14:077454
Klaus Weidnerd8219432022-02-08 21:50:597455 // Ensure any video or document in Picture-in-Picture is exited in the
7456 // |delegate_| since a crashed renderer may not have made a clean exit.
7457 if (HasPictureInPictureVideo() || HasPictureInPictureDocument())
Jennifer Apacibleb4b972a2018-06-07 04:41:027458 ExitPictureInPicture();
7459
[email protected]698191dc2014-02-25 01:06:137460 // Cancel any visible dialogs so they are not left dangling over the sad tab.
creis89a0f782015-05-27 16:13:177461 CancelActiveAndPendingDialogs();
[email protected]698191dc2014-02-25 01:06:137462
Lingqi Chi641aeee2021-09-08 00:32:587463 audio_stream_monitor_.RenderProcessGone(rvh_impl->GetProcess()->GetID());
dalecurtis3d1e1302017-02-20 22:33:257464
[email protected]960b0372014-05-19 18:01:007465 // Reset the loading progress. TODO(avi): What does it mean to have a
7466 // "renderer crash" when there is more than one renderer process serving a
7467 // webpage? Once this function is called at a more granular frame level, we
7468 // probably will need to more granularly reset the state here.
7469 ResetLoadProgressState();
Khushalc5eaf222021-06-30 20:15:487470
7471 SetPrimaryMainFrameProcessStatus(status, error_code);
[email protected]960b0372014-05-19 18:01:007472
Dave Tapuska7052b7c52021-10-18 17:30:537473 TRACE_EVENT0(
7474 "content",
7475 "Dispatching WebContentsObserver::PrimaryMainFrameRenderProcessGone");
7476 // Some observers might destroy WebContents in
7477 // PrimaryMainFrameRenderProcessGone.
Alexander Timin90c20c32020-08-12 15:28:327478 base::WeakPtr<WebContentsImpl> weak_ptr = weak_factory_.GetWeakPtr();
Alexander Timin90c20c32020-08-12 15:28:327479 for (auto& observer : observers_.observer_list()) {
Dave Tapuska7052b7c52021-10-18 17:30:537480 observer.PrimaryMainFrameRenderProcessGone(status);
Alexander Timin90c20c32020-08-12 15:28:327481 if (!weak_ptr)
7482 return;
7483 }
7484
7485 // |this| might have been deleted. Do not add code here.
[email protected]420ae012009-04-24 05:16:327486}
7487
[email protected]b172aee2012-04-10 17:05:267488void WebContentsImpl::RenderViewDeleted(RenderViewHost* rvh) {
Alexander Timin5fdeff22020-09-08 09:20:377489 OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::RenderViewDeleted",
Alexander Timinf785f342021-03-18 00:00:567490 "render_view_host", rvh);
Andrew Grievee19cd93e2021-01-22 05:43:067491 observers_.NotifyObservers(&WebContentsObserver::RenderViewDeleted, rvh);
[email protected]2e4633c2009-07-09 16:58:067492}
7493
Lukasz Anforowiczfd707142018-02-07 19:46:137494void WebContentsImpl::ClearTargetURL() {
Alexander Timin5fdeff22020-09-08 09:20:377495 OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::ClearTargetURL");
Mario Sanchez Pradadffbe66e2020-09-07 12:01:087496 frame_that_set_last_target_url_ = nullptr;
Lukasz Anforowiczfd707142018-02-07 19:46:137497 if (delegate_)
7498 delegate_->UpdateTargetURL(this, GURL());
7499}
7500
Alex Moshchuke558aba2023-01-13 07:42:027501void WebContentsImpl::Close() {
7502 OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::Close",
7503 "render_frame_host", GetPrimaryMainFrame());
Xiaohan Wang24ec9342022-01-15 17:34:227504#if BUILDFLAG(IS_MAC)
[email protected]07707302009-11-06 00:50:297505 // The UI may be in an event-tracking loop, such as between the
7506 // mouse-down and mouse-up in text selection or a button click.
7507 // Defer the close until after tracking is complete, so that we
7508 // don't free objects out from under the UI.
[email protected]07707302009-11-06 00:50:297509 // TODO(shess): This could get more fine-grained. For instance,
7510 // closing a tab in another window while selecting text in the
7511 // current window's Omnibox should be just fine.
Christopher Cameron9ae31e0d2019-03-01 20:01:197512 if (view_->CloseTabAfterEventTrackingIfNeeded())
[email protected]07707302009-11-06 00:50:297513 return;
[email protected]60780f412013-02-25 16:34:107514#endif
[email protected]07707302009-11-06 00:50:297515
Alex Moshchuke558aba2023-01-13 07:42:027516 if (delegate_) {
[email protected]6934a702011-12-20 00:04:517517 delegate_->CloseContents(this);
Alex Moshchuke558aba2023-01-13 07:42:027518 }
[email protected]420ae012009-04-24 05:16:327519}
7520
Dave Tapuska3f201fa2020-10-28 14:17:107521void WebContentsImpl::SetWindowRect(const gfx::Rect& new_bounds) {
7522 OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::SetWindowRect");
Mike Wassermandabad612020-08-13 04:26:277523 if (!delegate_)
7524 return;
7525
7526 // Members of |new_bounds| may be 0 to indicate uninitialized values for newly
7527 // opened windows, even if the |GetContainerBounds()| inner rect is correct.
7528 // TODO(crbug.com/897300): Plumb values as specified; fallback on outer rect.
7529 auto bounds = new_bounds;
7530 if (bounds.IsEmpty())
7531 bounds.set_size(GetContainerBounds().size());
7532
7533 // Only requests from the main frame, not subframes, should reach this code.
Dave Tapuska327c06c92022-06-13 20:31:517534 int64_t display_id =
7535 AdjustRequestedWindowBounds(&bounds, GetPrimaryMainFrame());
Mike Wassermanb6bc0152020-08-25 22:46:207536
7537 // Drop fullscreen when placing a WebContents to prohibit deceptive behavior.
7538 // Only drop fullscreen on the specific destination display, which is known.
Brad Triebwasser5eb94a92022-10-13 22:34:287539 // This supports sites using cross-screen window management capabilities to
Mike Wassermanb6bc0152020-08-25 22:46:207540 // retain fullscreen and place a window on another screen.
7541 ForSecurityDropFullscreen(display_id).RunAndReset();
7542
Mike Wassermandabad612020-08-13 04:26:277543 delegate_->SetContentsBounds(this, bounds);
[email protected]420ae012009-04-24 05:16:327544}
7545
Lingqi Chib2f442002021-07-29 01:53:547546void WebContentsImpl::UpdateWindowPreferredSize(const gfx::Size& pref_size) {
7547 OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::UpdatePreferredSize");
7548 const gfx::Size old_size = GetPreferredSize();
7549 preferred_size_ = pref_size;
7550 OnPreferredSizeChanged(old_size);
7551}
7552
Camille Lamy8766bd3e2020-11-26 11:36:327553std::vector<RenderFrameHostImpl*>
7554WebContentsImpl::GetActiveTopLevelDocumentsInBrowsingContextGroup(
7555 RenderFrameHostImpl* render_frame_host) {
7556 std::vector<RenderFrameHostImpl*> out;
7557 for (WebContentsImpl* web_contents : GetAllWebContents()) {
Dave Tapuska327c06c92022-06-13 20:31:517558 RenderFrameHostImpl* other_render_frame_host =
7559 web_contents->GetPrimaryMainFrame();
Camille Lamy8766bd3e2020-11-26 11:36:327560
7561 // Filters out inactive documents.
7562 if (other_render_frame_host->lifecycle_state() !=
Sreeja Kamishetty299329ad2021-03-25 14:06:017563 RenderFrameHostImpl::LifecycleStateImpl::kActive) {
Camille Lamy8766bd3e2020-11-26 11:36:327564 continue;
7565 }
7566
7567 // Filters out documents from a different browsing context group.
7568 if (!render_frame_host->GetSiteInstance()->IsRelatedSiteInstance(
7569 other_render_frame_host->GetSiteInstance())) {
7570 continue;
7571 }
7572
7573 out.push_back(other_render_frame_host);
7574 }
7575 return out;
7576}
7577
Hiroki Nakagawa1cb14552021-04-23 03:37:347578PrerenderHostRegistry* WebContentsImpl::GetPrerenderHostRegistry() {
Hiroki Nakagawa1cb14552021-04-23 03:37:347579 DCHECK(prerender_host_registry_);
7580 return prerender_host_registry_.get();
7581}
7582
fdegansa696e5112015-04-17 01:57:597583void WebContentsImpl::DidStartLoading(FrameTreeNode* frame_tree_node,
Nate Chapin9aabf5f2021-11-12 00:31:197584 bool should_show_loading_ui) {
Alexander Timin5fdeff22020-09-08 09:20:377585 OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::DidStartLoading",
Alexander Timinf785f342021-03-18 00:00:567586 "frame_tree_node", frame_tree_node);
Sreeja Kamishetty15f9944a22022-03-10 10:16:087587 LoadingStateChanged(
7588 frame_tree_node->GetFrameType() == FrameType::kPrimaryMainFrame &&
7589 should_show_loading_ui,
7590 nullptr);
dmazzonibf8cec42015-02-08 08:28:087591
Xiyuan Xia2a66b112018-12-06 15:52:167592 // Reset the focus state from DidStartNavigation to false if a new load starts
7593 // afterward, in case loading logic triggers a FocusLocationBarByDefault call.
7594 should_focus_location_bar_by_default_ = false;
Ian Prestcdd843d2020-01-28 18:59:587595
7596 // Notify accessibility that the user is navigating away from the
7597 // current document.
7598 // TODO(domfarolino, dmazzoni): Do this using WebContentsObserver. See
7599 // https://crbug.com/981271.
7600 BrowserAccessibilityManager* manager =
7601 frame_tree_node->current_frame_host()->browser_accessibility_manager();
7602 if (manager)
7603 manager->UserIsNavigatingAway();
[email protected]420ae012009-04-24 05:16:327604}
7605
fdegansc73eec22015-03-19 14:47:547606void WebContentsImpl::DidStopLoading() {
Alexander Timin5fdeff22020-09-08 09:20:377607 OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::DidStopLoading");
dcheng59716272016-04-09 05:19:087608 std::unique_ptr<LoadNotificationDetails> details;
[email protected]420ae012009-04-24 05:16:327609
[email protected]9595fd82013-04-19 21:28:497610 // Use the last committed entry rather than the active one, in case a
7611 // pending entry has been created.
Carlos Caballero40b0efd2021-01-26 11:55:007612 NavigationEntry* entry = GetController().GetLastCommittedEntry();
[email protected]9595fd82013-04-19 21:28:497613
[email protected]420ae012009-04-24 05:16:327614 // An entry may not exist for a stop when loading an initial blank page or
7615 // if an iframe injected by script into a blank page finishes loading.
7616 if (entry) {
Fergal Daly55b6d722020-09-11 07:56:337617 details = std::make_unique<LoadNotificationDetails>(
Carlos Caballero40b0efd2021-01-26 11:55:007618 entry->GetVirtualURL(), &GetController(),
7619 GetController().GetCurrentEntryIndex());
[email protected]420ae012009-04-24 05:16:327620 }
7621
Nate Chapin9aabf5f2021-11-12 00:31:197622 LoadingStateChanged(true /* should_show_loading_ui */, details.get());
[email protected]420ae012009-04-24 05:16:327623}
7624
Yeunjoo Choi8a64db302022-08-25 02:29:287625void WebContentsImpl::DidChangeLoadProgressForPrimaryMainFrame() {
Alexander Timin5fdeff22020-09-08 09:20:377626 OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::DidChangeLoadProgress");
Takashi Toyoshimaea534ef22021-07-21 03:27:597627 if (IsBeingDestroyed())
Nate Chapin22ea6592019-03-05 22:29:027628 return;
Sreeja Kamishetty0be3b1b2021-08-12 17:04:157629 double load_progress = GetLoadProgress();
fdegansa696e5112015-04-17 01:57:597630
7631 // The delegate is notified immediately for the first and last updates. Also,
7632 // since the message loop may be pretty busy when a page is loaded, it might
7633 // not execute a posted task in a timely manner so the progress report is sent
7634 // immediately if enough time has passed.
Sreeja Kamishetty0be3b1b2021-08-12 17:04:157635 base::TimeDelta min_delay = minimum_delay_between_loading_updates_ms_;
Ian Vollick6d75ac32021-05-05 17:45:097636 bool delay_elapsed =
7637 loading_last_progress_update_.is_null() ||
fdegansa696e5112015-04-17 01:57:597638 base::TimeTicks::Now() - loading_last_progress_update_ > min_delay;
7639
7640 if (load_progress == 0.0 || load_progress == 1.0 || delay_elapsed) {
7641 // If there is a pending task to send progress, it is now obsolete.
7642 loading_weak_factory_.InvalidateWeakPtrs();
7643
7644 // Notify the load progress change.
7645 SendChangeLoadProgress();
7646
7647 // Clean-up the states if needed.
7648 if (load_progress == 1.0)
7649 ResetLoadProgressState();
7650 return;
7651 }
7652
7653 if (loading_weak_factory_.HasWeakPtrs())
7654 return;
7655
Peter Kastinge5a38ed2021-10-02 03:06:357656 if (min_delay == base::Milliseconds(0)) {
Sreeja Kamishetty0be3b1b2021-08-12 17:04:157657 SendChangeLoadProgress();
7658 } else {
Sean Maher5b9af51f2022-11-21 15:32:477659 base::SingleThreadTaskRunner::GetCurrentDefault()->PostDelayedTask(
Sreeja Kamishetty0be3b1b2021-08-12 17:04:157660 FROM_HERE,
7661 base::BindOnce(&WebContentsImpl::SendChangeLoadProgress,
7662 loading_weak_factory_.GetWeakPtr()),
7663 min_delay);
7664 }
fdegansa696e5112015-04-17 01:57:597665}
7666
Tsuyoshi Horocd828462021-04-21 04:59:587667bool WebContentsImpl::IsHidden() {
7668 return GetPageVisibilityState() == PageVisibilityState::kHidden;
7669}
7670
avid6d88b912017-01-13 00:16:007671std::vector<std::unique_ptr<NavigationThrottle>>
7672WebContentsImpl::CreateThrottlesForNavigation(
clamycbf524d42016-09-27 12:48:357673 NavigationHandle* navigation_handle) {
Alexander Timin5fdeff22020-09-08 09:20:377674 OPTIONAL_TRACE_EVENT1("content",
7675 "WebContentsImpl::CreateThrottlesForNavigation",
Alexander Timinf785f342021-03-18 00:00:567676 "navigation", navigation_handle);
Charlie Reis96077362019-07-04 00:34:047677 auto throttles = GetContentClient()->browser()->CreateThrottlesForNavigation(
clamycbf524d42016-09-27 12:48:357678 navigation_handle);
Charlie Reis96077362019-07-04 00:34:047679
Charlie Reis96077362019-07-04 00:34:047680 return throttles;
clamycbf524d42016-09-27 12:48:357681}
7682
David Bokan1bdb3701f2021-04-30 22:02:357683std::vector<std::unique_ptr<CommitDeferringCondition>>
7684WebContentsImpl::CreateDeferringConditionsForNavigationCommit(
David Bokan51a6df832022-02-17 18:31:197685 NavigationHandle& navigation_handle,
7686 CommitDeferringCondition::NavigationType type) {
7687 OPTIONAL_TRACE_EVENT2(
7688 "content", "WebContentsImpl::CreateDeferringConditionsForNavigation",
7689 "navigation", navigation_handle, "NavigationType", type);
7690 std::vector<std::unique_ptr<CommitDeferringCondition>> conditions =
7691 GetContentClient()
7692 ->browser()
7693 ->CreateCommitDeferringConditionsForNavigation(&navigation_handle,
7694 type);
7695
David Bokan1bdb3701f2021-04-30 22:02:357696 if (auto condition = JavaScriptDialogCommitDeferringCondition::MaybeCreate(
7697 static_cast<NavigationRequest&>(navigation_handle)))
7698 conditions.push_back(std::move(condition));
7699 return conditions;
7700}
7701
clamy1e5574e92016-09-29 16:48:447702std::unique_ptr<NavigationUIData> WebContentsImpl::GetNavigationUIData(
7703 NavigationHandle* navigation_handle) {
Alexander Timin5fdeff22020-09-08 09:20:377704 OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::GetNavigationUIData");
clamy1e5574e92016-09-29 16:48:447705 return GetContentClient()->browser()->GetNavigationUIData(navigation_handle);
7706}
7707
W. James MacLeanc07dc41b2022-07-25 18:52:167708void WebContentsImpl::RegisterExistingOriginAsHavingDefaultIsolation(
W. James MacLeanb70fab82020-05-01 18:51:147709 const url::Origin& origin,
7710 NavigationRequest* navigation_request_to_exclude) {
Alexander Timin5fdeff22020-09-08 09:20:377711 OPTIONAL_TRACE_EVENT2(
7712 "content",
W. James MacLeanc07dc41b2022-07-25 18:52:167713 "WebContentsImpl::RegisterExistingOriginAsHavingDefaultIsolation",
Alexander Timinf785f342021-03-18 00:00:567714 "origin", origin, "navigation_request_to_exclude",
7715 navigation_request_to_exclude);
W. James MacLean1c40862c2020-04-27 21:05:577716 // Note: This function can be made static if we ever need call it without
7717 // a WebContentsImpl instance, in which case we can use a wrapper to
7718 // implement the override from NavigatorDelegate.
7719 for (WebContentsImpl* web_contents : GetAllWebContents()) {
W. James MacLean17cc71f2020-11-12 21:20:127720 // We only need to search entries in the same BrowserContext as us.
7721 if (web_contents->GetBrowserContext() != GetBrowserContext())
7722 continue;
Carlos Caballero40b0efd2021-01-26 11:55:007723
W. James MacLeanc6dc86c2021-08-12 13:58:377724 // Walk the frame trees to notify each one's NavigationController about the
W. James MacLeanc07dc41b2022-07-25 18:52:167725 // opting-in or opting-out `origin`, and also pick up any frames without
W. James MacLeanc6dc86c2021-08-12 13:58:377726 // FrameNavigationEntries.
W. James MacLeanb70fab82020-05-01 18:51:147727 // * Some frames won't have FrameNavigationEntries (Issues 524208, 608402).
7728 // * Some pending navigations won't have NavigationEntries.
W. James MacLeanc6dc86c2021-08-12 13:58:377729 web_contents->ForEachFrameTree(base::BindRepeating(
7730 [](const url::Origin& origin,
7731 NavigationRequest* navigation_request_to_exclude,
Arthur Sonzognif6785ec2022-12-05 10:11:507732 FrameTree& frame_tree) {
7733 frame_tree.RegisterExistingOriginAsHavingDefaultIsolation(
W. James MacLeanc6dc86c2021-08-12 13:58:377734 origin, navigation_request_to_exclude);
7735 },
7736 origin, navigation_request_to_exclude));
W. James MacLean1c40862c2020-04-27 21:05:577737 }
7738}
7739
Kevin McNeefb86fcf2021-02-26 23:20:577740void WebContentsImpl::DidChangeName(RenderFrameHostImpl* render_frame_host,
alexmosbe2f4c32015-03-10 02:30:237741 const std::string& name) {
Alexander Timinf785f342021-03-18 00:00:567742 OPTIONAL_TRACE_EVENT2("content", "WebContentsImpl::DidChangeName",
7743 "render_frame_host", render_frame_host, "name", name);
Andrew Grievee19cd93e2021-01-22 05:43:067744 observers_.NotifyObservers(&WebContentsObserver::FrameNameChanged,
7745 render_frame_host, name);
alexmosbe2f4c32015-03-10 02:30:237746}
7747
John Delaneyb625dca92021-04-14 17:00:347748void WebContentsImpl::DidReceiveUserActivation(
Kevin McNeefb86fcf2021-02-26 23:20:577749 RenderFrameHostImpl* render_frame_host) {
John Delaneyb625dca92021-04-14 17:00:347750 OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::DidReceiveUserActivation",
Alexander Timinf785f342021-03-18 00:00:567751 "render_frame_host", render_frame_host);
John Delaneyb625dca92021-04-14 17:00:347752 observers_.NotifyObservers(&WebContentsObserver::FrameReceivedUserActivation,
7753 render_frame_host);
John Delaneyedd8d6c2019-01-25 00:23:577754}
7755
Robert Sesekc4eeccbd2021-07-23 21:20:197756void WebContentsImpl::BindDisplayCutoutHost(
7757 RenderFrameHostImpl* render_frame_host,
7758 mojo::PendingAssociatedReceiver<blink::mojom::DisplayCutoutHost> receiver) {
7759 if (display_cutout_host_impl_) {
7760 display_cutout_host_impl_->BindReceiver(std::move(receiver),
7761 render_frame_host);
7762 }
7763}
7764
Kevin McNeefb86fcf2021-02-26 23:20:577765void WebContentsImpl::DidChangeDisplayState(
7766 RenderFrameHostImpl* render_frame_host,
7767 bool is_display_none) {
Alexander Timin5fdeff22020-09-08 09:20:377768 OPTIONAL_TRACE_EVENT2("content", "WebContentsImpl::DidChangeDisplayState",
Alexander Timinf785f342021-03-18 00:00:567769 "render_frame_host", render_frame_host,
Alexander Timin5fdeff22020-09-08 09:20:377770 "is_display_none", is_display_none);
Andrew Grievee19cd93e2021-01-22 05:43:067771 observers_.NotifyObservers(&WebContentsObserver::FrameDisplayStateChanged,
7772 render_frame_host, is_display_none);
John Delaney0146a742019-01-25 19:25:287773}
7774
Kevin McNeefb86fcf2021-02-26 23:20:577775void WebContentsImpl::FrameSizeChanged(RenderFrameHostImpl* render_frame_host,
John Delaney0146a742019-01-25 19:25:287776 const gfx::Size& frame_size) {
Alexander Timin5fdeff22020-09-08 09:20:377777 OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::FrameSizeChanged",
Alexander Timinf785f342021-03-18 00:00:567778 "render_frame_host", render_frame_host);
Andrew Grievee19cd93e2021-01-22 05:43:067779 observers_.NotifyObservers(&WebContentsObserver::FrameSizeChanged,
7780 render_frame_host, frame_size);
John Delaney0146a742019-01-25 19:25:287781}
7782
[email protected]39f2f9252014-05-03 00:54:017783void WebContentsImpl::DocumentOnLoadCompleted(
Kevin McNeefb86fcf2021-02-26 23:20:577784 RenderFrameHostImpl* render_frame_host) {
Alexander Timin5fdeff22020-09-08 09:20:377785 OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::DocumentOnLoadCompleted",
Alexander Timinf785f342021-03-18 00:00:567786 "render_frame_host", render_frame_host);
Sreeja Kamishetty6b55ecc2021-12-10 11:28:177787 DCHECK(render_frame_host->IsInPrimaryMainFrame());
Jeremy Romand597d3372021-07-09 23:36:567788 ShowInsecureLocalhostWarningIfNeeded(render_frame_host->GetPage());
falken52a56e32016-12-08 05:02:407789
Andrew Grievee19cd93e2021-01-22 05:43:067790 observers_.NotifyObservers(
Sreeja Kamishetty81347582022-01-06 12:46:337791 &WebContentsObserver::DocumentOnLoadCompletedInPrimaryMainFrame);
[email protected]25497492010-09-11 15:15:087792}
7793
Kevin McNeefb86fcf2021-02-26 23:20:577794void WebContentsImpl::UpdateTitle(RenderFrameHostImpl* render_frame_host,
Jan Wilken Dörrieaace0cfef2021-03-11 22:01:587795 const std::u16string& title,
[email protected]ef3adfc2014-05-11 00:04:547796 base::i18n::TextDirection title_direction) {
Alexander Timin5fdeff22020-09-08 09:20:377797 OPTIONAL_TRACE_EVENT2("content", "WebContentsImpl::UpdateTitle",
Alexander Timinf785f342021-03-18 00:00:567798 "render_frame_host", render_frame_host, "title", title);
[email protected]ef3adfc2014-05-11 00:04:547799 // Try to find the navigation entry, which might not be the current one.
Adithya Srinivasan9b0c99c2021-08-10 15:19:457800 // For example, it might be from a pending deletion RFH, or it might be from a
7801 // non-primary frame tree.
Carlos Caballeroede6f8c2021-01-28 11:01:507802 NavigationEntryImpl* entry =
Kevin McNeefb86fcf2021-02-26 23:20:577803 render_frame_host->frame_tree()->controller().GetEntryWithUniqueID(
7804 render_frame_host->nav_entry_id());
[email protected]ef3adfc2014-05-11 00:04:547805
Rakina Zata Amni46087a12022-11-11 08:28:387806 if (!entry) {
7807 // We can handle title updates with no matching NavigationEntry, but only if
7808 // the update is for the initial NavigationEntry. In that case the initial
7809 // empty document RFH wouldn't have a `nav_entry_id` set because it hasn't
7810 // committed any navigation. Note that if the title update came from the
7811 // initial empty document but the WebContents is doing a session restore,
7812 // we will ignore the title update (because GetLastCommittedEntry() would
7813 // return the non-initial restored entry), which avoids accidental
7814 // overwriting of the restored entry's title.
7815 if (render_frame_host->GetParent() || !render_frame_host->frame_tree()
7816 ->controller()
7817 .GetLastCommittedEntry()
7818 ->IsInitialEntry()) {
Rakina Zata Amni2322f4f82022-01-24 13:24:247819 return;
Rakina Zata Amni46087a12022-11-11 08:28:387820 }
7821 entry =
7822 render_frame_host->frame_tree()->controller().GetLastCommittedEntry();
Rakina Zata Amniafd3c6582021-11-30 06:19:177823 }
[email protected]ef3adfc2014-05-11 00:04:547824
7825 // TODO(evan): make use of title_direction.
7826 // http://code.google.com/p/chromium/issues/detail?id=27094
Adithya Srinivasan9b0c99c2021-08-10 15:19:457827 bool title_changed = UpdateTitleForEntryImpl(entry, title);
Dave Tapuska327c06c92022-06-13 20:31:517828 if (title_changed && render_frame_host == GetPrimaryMainFrame()) {
Adithya Srinivasan9b0c99c2021-08-10 15:19:457829 NotifyTitleUpdateForEntry(entry);
7830 }
[email protected]ef3adfc2014-05-11 00:04:547831}
7832
Kevin McNeefb86fcf2021-02-26 23:20:577833void WebContentsImpl::UpdateTargetURL(RenderFrameHostImpl* render_frame_host,
Mario Sanchez Pradadffbe66e2020-09-07 12:01:087834 const GURL& url) {
Alexander Timin5fdeff22020-09-08 09:20:377835 OPTIONAL_TRACE_EVENT2("content", "WebContentsImpl::UpdateTargetURL",
Alexander Timinf785f342021-03-18 00:00:567836 "render_frame_host", render_frame_host, "url", url);
Mario Sanchez Pradadffbe66e2020-09-07 12:01:087837 // In case of racey updates from multiple RenderViewHosts, the last URL should
7838 // be shown - see also some discussion in https://crbug.com/807776.
7839 if (!url.is_valid() && render_frame_host != frame_that_set_last_target_url_)
7840 return;
7841 frame_that_set_last_target_url_ =
7842 url.is_valid() ? render_frame_host : nullptr;
7843
7844 if (delegate_)
7845 delegate_->UpdateTargetURL(this, url);
7846}
7847
alexmose7da5a12015-04-09 02:22:167848bool WebContentsImpl::ShouldRouteMessageEvent(
Sharon Yang7298ae802022-02-25 03:50:157849 RenderFrameHostImpl* target_rfh) const {
7850 OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::ShouldRouteMessageEvent",
7851 "render_frame_host", target_rfh);
alexmose7da5a12015-04-09 02:22:167852 // Allow the message if this WebContents is dedicated to a browser plugin
7853 // guest.
[email protected]0eba810b2012-10-18 03:19:367854 // Note: This check means that an embedder could theoretically receive a
7855 // postMessage from anyone (not just its own guests). However, this is
7856 // probably not a risk for apps since other pages won't have references
7857 // to App windows.
alexmose7da5a12015-04-09 02:22:167858 return GetBrowserPluginGuest() || GetBrowserPluginEmbedder();
7859}
[email protected]f546640b2012-05-15 00:03:497860
Kevin McNeefb86fcf2021-02-26 23:20:577861void WebContentsImpl::EnsureOpenerProxiesExist(
7862 RenderFrameHostImpl* source_rfh) {
Alexander Timin5fdeff22020-09-08 09:20:377863 OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::EnsureOpenerProxiesExist",
Alexander Timinf785f342021-03-18 00:00:567864 "render_frame_host", source_rfh);
alexmose7da5a12015-04-09 02:22:167865 WebContentsImpl* source_web_contents = static_cast<WebContentsImpl*>(
7866 WebContents::FromRenderFrameHost(source_rfh));
[email protected]f546640b2012-05-15 00:03:497867
alexmose7da5a12015-04-09 02:22:167868 if (source_web_contents) {
lazyboy6ec48b2a2015-06-29 15:18:147869 // If this message is going to outer WebContents from inner WebContents,
7870 // then we should not create a RenderView. AttachToOuterWebContentsFrame()
7871 // already created a RenderFrameProxyHost for that purpose.
7872 if (GetBrowserPluginEmbedder() &&
W. James MacLean2539adb32019-12-13 00:40:447873 source_web_contents->browser_plugin_guest_) {
lazyboy6ec48b2a2015-06-29 15:18:147874 return;
W. James MacLean2539adb32019-12-13 00:40:447875 }
lazyboy6ec48b2a2015-06-29 15:18:147876
lfg812874d2016-02-09 22:26:137877 if (this != source_web_contents && GetBrowserPluginGuest()) {
naskob3041b98a42016-03-12 04:43:067878 // We create a RenderFrameProxyHost for the embedder in the guest's render
7879 // process but we intentionally do not expose the embedder's opener chain
7880 // to it.
7881 source_web_contents->GetRenderManager()->CreateRenderFrameProxy(
Harkiran Bolaria2912a6b32022-02-22 16:43:457882 GetSiteInstance(),
Dave Tapuska327c06c92022-06-13 20:31:517883 source_web_contents->GetPrimaryMainFrame()->browsing_context_state());
[email protected]f546640b2012-05-15 00:03:497884 } else {
Kevin McNeefb86fcf2021-02-26 23:20:577885 source_rfh->frame_tree_node()->render_manager()->CreateOpenerProxies(
Harkiran Bolaria2912a6b32022-02-22 16:43:457886 GetSiteInstance(), nullptr, source_rfh->browsing_context_state());
[email protected]f546640b2012-05-15 00:03:497887 }
7888 }
[email protected]f546640b2012-05-15 00:03:497889}
7890
avallee9993fca2016-11-17 06:16:507891void WebContentsImpl::SetAsFocusedWebContentsIfNecessary() {
Carlos Caballero1a261f82021-11-04 15:54:037892 SetFocusedFrameTree(&GetPrimaryFrameTree());
Dave Tapuska54c76a032021-10-27 22:10:427893}
7894
7895void WebContentsImpl::SetFocusedFrameTree(FrameTree* frame_tree_to_focus) {
7896 OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::SetFocusedFrameTree");
Adithya Srinivasan11c3d6ba02021-02-12 20:25:107897 DCHECK(!GetOuterWebContents() || !IsPortal());
Dave Tapuska54c76a032021-10-27 22:10:427898 DCHECK(frame_tree_to_focus);
7899
avallee9993fca2016-11-17 06:16:507900 // Only change focus if we are not currently focused.
Dave Tapuska54c76a032021-10-27 22:10:427901 FrameTree* old_focused_frame_tree = GetFocusedFrameTree();
7902 if (old_focused_frame_tree == frame_tree_to_focus)
avallee9993fca2016-11-17 06:16:507903 return;
7904
Dave Tapuska54c76a032021-10-27 22:10:427905 GetOutermostWebContents()->node_.SetFocusedFrameTree(frame_tree_to_focus);
paulmeyerfeafc2d2017-04-25 21:46:407906
Dave Tapuska54c76a032021-10-27 22:10:427907 // Send a page level blur to the `old_focused_frame_tree` so that it displays
7908 // inactive UI and focus `frame_tree_to_focus` to activate it.
7909 if (old_focused_frame_tree) {
7910 old_focused_frame_tree->root()
7911 ->current_frame_host()
7912 ->GetRenderWidgetHost()
7913 ->SetPageFocus(false);
7914 }
avalleec2ff1ef2017-01-21 00:12:307915
Dave Tapuska54c76a032021-10-27 22:10:427916 // Make sure the outer frame trees knows our frame is focused. Otherwise, the
avalleec2ff1ef2017-01-21 00:12:307917 // outer renderer could have the element before or after the frame element
7918 // focused which would return early without actually advancing focus.
Kevin McNee088a1b52022-07-13 23:15:377919 RenderFrameHostImpl::UpdateAXFocusDeferScope focus_defer_scope(
7920 *frame_tree_to_focus->root()
7921 ->current_frame_host()
7922 ->GetOutermostMainFrameOrEmbedder());
Dave Tapuska54c76a032021-10-27 22:10:427923 frame_tree_to_focus->FocusOuterFrameTrees();
avalleec2ff1ef2017-01-21 00:12:307924
Dave Tapuska54c76a032021-10-27 22:10:427925 frame_tree_to_focus->root()
7926 ->current_frame_host()
7927 ->GetRenderWidgetHost()
7928 ->SetPageFocus(true);
avallee9993fca2016-11-17 06:16:507929}
7930
avallee0206f782016-07-28 18:55:337931void WebContentsImpl::SetFocusedFrame(FrameTreeNode* node,
Sharon Yangefe52632022-03-08 23:06:067932 SiteInstanceGroup* source) {
Alexander Timin5fdeff22020-09-08 09:20:377933 OPTIONAL_TRACE_EVENT2("content", "WebContentsImpl::SetFocusedFrame",
Sharon Yangefe52632022-03-08 23:06:067934 "frame_tree_node", node, "source_site_instance_group",
Alexander Timinf785f342021-03-18 00:00:567935 source);
Kevin McNee088a1b52022-07-13 23:15:377936
7937 // Focus will not be in a consistent state until the focused frame tree is
7938 // also updated (if necessary).
7939 RenderFrameHostImpl::UpdateAXFocusDeferScope focus_defer_scope(
7940 *node->current_frame_host()->GetOutermostMainFrameOrEmbedder());
7941
Arthur Sonzognif6785ec2022-12-05 10:11:507942 node->frame_tree().SetFocusedFrame(node, source);
avalleed68cdd12017-06-21 22:07:277943
Dave Tapuska54c76a032021-10-27 22:10:427944 auto* inner_contents = node_.GetInnerWebContentsInFrame(node);
7945
7946 // We currently do not need to descend into inner frame trees that
7947 // are not an inner WebContents for focus. If `inner_contents` is null,
7948 // then the only supported inner frame tree type would be fenced frames.
7949 // An embedding frame focusing a fenced frame is not allowed since that would
7950 // be an information leak. If a renderer attempts to do that, that should be
7951 // blocked by `RenderFrameProxyHost::DidFocusFrame()`.
7952 DCHECK(inner_contents ||
7953 node->current_frame_host()->inner_tree_main_frame_tree_node_id() ==
7954 FrameTreeNode::kFrameTreeNodeInvalidId);
7955
7956 if (inner_contents) {
7957 // An inner WebContents is not created from Fenced Frames so we
7958 // shouldn't end up in this branch.
Abhijeet Kandalkar749b8bf12022-12-14 16:41:487959 DCHECK(!node->IsInFencedFrameTree());
Dave Tapuska54c76a032021-10-27 22:10:427960
Lucas Furukawa Gadaniabbfa342017-08-29 19:37:577961 // |this| is an outer WebContents and |node| represents an inner
7962 // WebContents. Transfer the focus to the inner contents if |this| is
7963 // focused.
Adithya Srinivasan11c3d6ba02021-02-12 20:25:107964 DCHECK(!inner_contents->IsPortal());
Lucas Furukawa Gadaniabbfa342017-08-29 19:37:577965 if (GetFocusedWebContents() == this)
7966 inner_contents->SetAsFocusedWebContentsIfNecessary();
7967 } else if (node_.OuterContentsFrameTreeNode() &&
7968 node_.OuterContentsFrameTreeNode()
7969 ->current_frame_host()
Sharon Yangefe52632022-03-08 23:06:067970 ->GetSiteInstance()
7971 ->group() == source) {
Dave Tapuska54c76a032021-10-27 22:10:427972 // A GuestView embedding a fenced frame will have an
7973 // OuterContentsFrameTreeNode. However, it will not have the same site
7974 // instance because a FencedFrame creates a new BrowsingInstance.
Abhijeet Kandalkar749b8bf12022-12-14 16:41:487975 DCHECK(!node->IsInFencedFrameTree());
Dave Tapuska54c76a032021-10-27 22:10:427976
Lucas Furukawa Gadaniabbfa342017-08-29 19:37:577977 // |this| is an inner WebContents, |node| is its main FrameTreeNode and
7978 // the outer WebContents FrameTreeNode is at |source|'s SiteInstance.
7979 // Transfer the focus to the inner WebContents if the outer WebContents is
7980 // focused. This branch is used when an inner WebContents is focused through
Lowell Mannersa9530382019-08-01 09:46:577981 // its RenderFrameProxyHost (via FrameFocused mojo call, used to
Lucas Furukawa Gadaniabbfa342017-08-29 19:37:577982 // implement the window.focus() API).
7983 if (GetFocusedWebContents() == GetOuterWebContents())
Arthur Sonzognif6785ec2022-12-05 10:11:507984 SetFocusedFrameTree(&node->frame_tree());
Dave Tapuska54c76a032021-10-27 22:10:427985 } else if (!GetOuterWebContents() || GetFocusedWebContents() == this) {
7986 // This is an outermost WebContents or we are currently focused so allow
7987 // the requested node's frame tree to be focused. The
7988 // (GetFocusedWebContents() == this) is needed when there are multiple
7989 // frame trees within an inner WebContents (ie. a GuestView with fenced
7990 // frames).
Arthur Sonzognif6785ec2022-12-05 10:11:507991 SetFocusedFrameTree(&node->frame_tree());
Lucas Furukawa Gadaniabbfa342017-08-29 19:37:577992 }
avalleed68cdd12017-06-21 22:07:277993}
7994
Avi Drissman36f801f2018-02-01 20:06:047995void WebContentsImpl::DidCallFocus() {
Alexander Timin5fdeff22020-09-08 09:20:377996 OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::DidCallFocus");
Avi Drissman36f801f2018-02-01 20:06:047997 // Any explicit focusing of another window while this WebContents is in
7998 // fullscreen can be used to confuse the user, so drop fullscreen.
Avi Drissman1a55a9d62020-03-10 18:56:457999 base::ScopedClosureRunner fullscreen_block = ForSecurityDropFullscreen();
8000 // The other contents is independent of this contents, so release the
8001 // fullscreen block.
8002 fullscreen_block.RunAndReset();
Avi Drissman36f801f2018-02-01 20:06:048003}
8004
Lucas Furukawa Gadaniabbfa342017-08-29 19:37:578005void WebContentsImpl::OnAdvanceFocus(RenderFrameHostImpl* source_rfh) {
Alexander Timin5fdeff22020-09-08 09:20:378006 OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::OnAdvanceFocus",
Alexander Timinf785f342021-03-18 00:00:568007 "render_frame_host", source_rfh);
Dave Tapuska2402595f2022-08-03 16:24:218008 // When a RenderFrame needs to advance focus to a `blink::RemoteFrame` (by
8009 // hitting TAB), the `blink::RemoteFrame` sends an IPC to
8010 // RenderFrameProxyHost. When this RenderFrameProxyHost represents an inner
8011 // WebContents, the outer WebContents needs to focus the inner WebContents.
Lucas Furukawa Gadaniabbfa342017-08-29 19:37:578012 if (GetOuterWebContents() &&
Matt Falkenhagen7b71b9f12021-08-12 01:32:438013 GetOuterWebContents() == WebContents::FromRenderFrameHost(source_rfh) &&
Lucas Furukawa Gadaniabbfa342017-08-29 19:37:578014 GetFocusedWebContents() == GetOuterWebContents()) {
8015 SetAsFocusedWebContentsIfNecessary();
8016 }
8017}
8018
ekaramada110f642016-12-21 19:47:288019void WebContentsImpl::OnFocusedElementChangedInFrame(
8020 RenderFrameHostImpl* frame,
Emily Stark023dbacc2020-08-27 22:31:408021 const gfx::Rect& bounds_in_root_view,
8022 blink::mojom::FocusType focus_type) {
Alexander Timinf785f342021-03-18 00:00:568023 OPTIONAL_TRACE_EVENT1("content",
8024 "WebContentsImpl::OnFocusedElementChangedInFrame",
8025 "render_frame_host", frame);
ekaramada110f642016-12-21 19:47:288026 RenderWidgetHostViewBase* root_view =
8027 static_cast<RenderWidgetHostViewBase*>(GetRenderWidgetHostView());
8028 if (!root_view || !frame->GetView())
8029 return;
Katie De013137a2020-07-09 23:03:108030 // Convert to screen coordinates from window coordinates by adding the
8031 // window's origin.
ekaramada110f642016-12-21 19:47:288032 gfx::Point origin = bounds_in_root_view.origin();
8033 origin += root_view->GetViewBounds().OffsetFromOrigin();
8034 gfx::Rect bounds_in_screen(origin, bounds_in_root_view.size());
8035
8036 root_view->FocusedNodeChanged(frame->has_focused_editable_element(),
8037 bounds_in_screen);
8038
8039 FocusedNodeDetails details = {frame->has_focused_editable_element(),
Emily Stark023dbacc2020-08-27 22:31:408040 bounds_in_screen, focus_type};
Steve Kobes6615df92021-03-15 18:02:208041 BrowserAccessibilityStateImpl::GetInstance()->OnFocusChangedInPage(details);
Andrew Grievee19cd93e2021-01-22 05:43:068042 observers_.NotifyObservers(&WebContentsObserver::OnFocusChangedInPage,
8043 &details);
ekaramada110f642016-12-21 19:47:288044}
8045
Lowell Manners1de5242e2019-04-25 10:18:468046bool WebContentsImpl::DidAddMessageToConsole(
Kevin McNeefb86fcf2021-02-26 23:20:578047 RenderFrameHostImpl* source_frame,
Lowell Manners1de5242e2019-04-25 10:18:468048 blink::mojom::ConsoleMessageLevel log_level,
Jan Wilken Dörrieaace0cfef2021-03-11 22:01:588049 const std::u16string& message,
Lowell Manners1de5242e2019-04-25 10:18:468050 int32_t line_no,
Jan Wilken Dörrieaace0cfef2021-03-11 22:01:588051 const std::u16string& source_id,
Anton Bikineevf62d1bf2021-05-15 17:56:078052 const absl::optional<std::u16string>& untrusted_stack_trace) {
Alexander Timin5fdeff22020-09-08 09:20:378053 OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::DidAddMessageToConsole",
Alexander Timinf785f342021-03-18 00:00:568054 "message", message);
Alexander Timin5fdeff22020-09-08 09:20:378055
Andrew Grievee19cd93e2021-01-22 05:43:068056 observers_.NotifyObservers(&WebContentsObserver::OnDidAddMessageToConsole,
8057 source_frame, log_level, message, line_no,
8058 source_id, untrusted_stack_trace);
Alexander Timin5fdeff22020-09-08 09:20:378059
[email protected]a796f202012-05-30 14:14:258060 if (!delegate_)
8061 return false;
Lowell Manners1de5242e2019-04-25 10:18:468062 return delegate_->DidAddMessageToConsole(this, log_level, message, line_no,
avia90ae4e2016-11-11 20:49:338063 source_id);
[email protected]a796f202012-05-30 14:14:258064}
8065
Daniel Cheng90196c82018-04-25 21:49:148066void WebContentsImpl::DidReceiveInputEvent(
dominickn9c7ceaa32016-02-27 01:52:538067 RenderWidgetHostImpl* render_widget_host,
Emily Starkc7bd40c42020-07-21 19:12:558068 const blink::WebInputEvent& event) {
Alexander Timin5fdeff22020-09-08 09:20:378069 OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::DidReceiveInputEvent",
Alexander Timinf785f342021-03-18 00:00:568070 "render_widget_host", render_widget_host);
Alexander Timin5fdeff22020-09-08 09:20:378071
Emily Starkc7bd40c42020-07-21 19:12:558072 if (!IsUserInteractionInputType(event.GetType()))
Daniel Cheng90196c82018-04-25 21:49:148073 return;
8074
kenrb19221852016-04-29 17:21:408075 // Ignore unless the widget is currently in the frame tree.
Carlos Caballerob65b6e3a2021-11-15 10:09:008076 if (!HasMatchingWidgetHost(&primary_frame_tree_, render_widget_host))
avic3aa8422015-11-09 20:57:228077 return;
8078
Emily Starkc7bd40c42020-07-21 19:12:558079 if (event.GetType() != blink::WebInputEvent::Type::kGestureScrollBegin)
Evan Stade6decc972022-10-24 19:42:188080 last_interaction_time_ = ui::EventTimeForNow();
dominickn9c7ceaa32016-02-27 01:52:538081
Andrew Grievee19cd93e2021-01-22 05:43:068082 observers_.NotifyObservers(&WebContentsObserver::DidGetUserInteraction,
8083 event);
dominickn2dd142dd2015-10-29 05:30:508084}
8085
Avi Drissman738ea192018-08-29 20:24:168086bool WebContentsImpl::ShouldIgnoreInputEvents() {
8087 WebContentsImpl* web_contents = this;
8088 while (web_contents) {
8089 if (web_contents->ignore_input_events_)
8090 return true;
8091 web_contents = web_contents->GetOuterWebContents();
8092 }
8093
8094 return false;
8095}
8096
avallee9993fca2016-11-17 06:16:508097void WebContentsImpl::FocusOwningWebContents(
8098 RenderWidgetHostImpl* render_widget_host) {
Alexander Timin5fdeff22020-09-08 09:20:378099 OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::FocusOwningWebContents",
Alexander Timinf785f342021-03-18 00:00:568100 "render_widget_host", render_widget_host);
Alex Moshchukc4f0a722019-11-19 22:41:288101 RenderWidgetHostImpl* main_frame_widget_host =
Dave Tapuska327c06c92022-06-13 20:31:518102 GetPrimaryMainFrame()->GetRenderWidgetHost();
avallee9993fca2016-11-17 06:16:508103 RenderWidgetHostImpl* focused_widget =
Alex Moshchukc4f0a722019-11-19 22:41:288104 GetFocusedRenderWidgetHost(main_frame_widget_host);
avallee9993fca2016-11-17 06:16:508105
8106 if (focused_widget != render_widget_host &&
avallee8e881592016-11-19 00:39:308107 (!focused_widget ||
8108 focused_widget->delegate() != render_widget_host->delegate())) {
avallee9993fca2016-11-17 06:16:508109 SetAsFocusedWebContentsIfNecessary();
8110 }
8111}
8112
[email protected]b172aee2012-04-10 17:05:268113void WebContentsImpl::OnIgnoredUIEvent() {
Alexander Timin5fdeff22020-09-08 09:20:378114 OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::OnIgnoredUIEvent");
[email protected]31145092011-09-30 01:49:448115 // Notify observers.
Andrew Grievee19cd93e2021-01-22 05:43:068116 observers_.NotifyObservers(&WebContentsObserver::DidGetIgnoredUIEvent);
[email protected]fa1cf0b82010-01-15 21:49:448117}
8118
avic3aa8422015-11-09 20:57:228119void WebContentsImpl::RendererUnresponsive(
Lukasz Anforowicz52b93722018-06-20 16:11:398120 RenderWidgetHostImpl* render_widget_host,
8121 base::RepeatingClosure hang_monitor_restarter) {
Alexander Timin5fdeff22020-09-08 09:20:378122 OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::RendererUnresponsive",
Alexander Timinf785f342021-03-18 00:00:568123 "render_widget_host", render_widget_host);
avic031d392017-03-03 03:09:428124 if (ShouldIgnoreUnresponsiveRenderer())
[email protected]e5fc1632011-08-08 07:51:538125 return;
8126
Lukasz Anforowicz4f0593d2018-09-21 18:33:548127 // Do not report hangs (to task manager, to hang renderer dialog, etc.) for
8128 // invisible tabs (like extension background page, background tabs). See
8129 // https://crbug.com/881812 for rationale and for choosing the visibility
8130 // (rather than process priority) as the signal here.
8131 if (GetVisibility() != Visibility::VISIBLE)
8132 return;
8133
Avi Drissman8920def2018-01-31 19:53:368134 if (!render_widget_host->renderer_initialized())
[email protected]55452902011-06-01 21:57:478135 return;
8136
Andrew Grievee19cd93e2021-01-22 05:43:068137 observers_.NotifyObservers(&WebContentsObserver::OnRendererUnresponsive,
8138 render_widget_host->GetProcess());
Dave Tapuskac6146c52017-12-20 22:48:158139 if (delegate_)
Lukasz Anforowicz52b93722018-06-20 16:11:398140 delegate_->RendererUnresponsive(this, render_widget_host,
8141 std::move(hang_monitor_restarter));
[email protected]420ae012009-04-24 05:16:328142}
8143
avic3aa8422015-11-09 20:57:228144void WebContentsImpl::RendererResponsive(
8145 RenderWidgetHostImpl* render_widget_host) {
Alexander Timin5fdeff22020-09-08 09:20:378146 OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::RenderResponsive",
Alexander Timinf785f342021-03-18 00:00:568147 "render_widget_host", render_widget_host);
Andrew Grievee19cd93e2021-01-22 05:43:068148 observers_.NotifyObservers(&WebContentsObserver::OnRendererResponsive,
8149 render_widget_host->GetProcess());
Alexander Timin5fdeff22020-09-08 09:20:378150
[email protected]6934a702011-12-20 00:04:518151 if (delegate_)
Avi Drissman1572e8c3c2018-02-02 19:06:368152 delegate_->RendererResponsive(this, render_widget_host);
[email protected]420ae012009-04-24 05:16:328153}
8154
[email protected]b172aee2012-04-10 17:05:268155void WebContentsImpl::BeforeUnloadFiredFromRenderManager(
Ian Vollick6d75ac32021-05-05 17:45:098156 bool proceed,
[email protected]420ae012009-04-24 05:16:328157 bool* proceed_to_fire_unload) {
Alexander Timin5fdeff22020-09-08 09:20:378158 OPTIONAL_TRACE_EVENT0("content",
8159 "WebContentsImpl::BeforeUnloadFiredFromRenderManager");
Arthur Sonzogni72be0c22023-02-10 10:19:048160 observers_.NotifyObservers(&WebContentsObserver::BeforeUnloadFired, proceed);
[email protected]6934a702011-12-20 00:04:518161 if (delegate_)
8162 delegate_->BeforeUnloadFired(this, proceed, proceed_to_fire_unload);
[email protected]e80af492013-06-24 21:52:098163 // Note: |this| might be deleted at this point.
[email protected]420ae012009-04-24 05:16:328164}
8165
[email protected]af905902013-10-01 21:38:518166void WebContentsImpl::CancelModalDialogsForRenderManager() {
Alexander Timin5fdeff22020-09-08 09:20:378167 OPTIONAL_TRACE_EVENT0("content",
8168 "WebContentsImpl::CancelModalDialogsForRenderManager");
[email protected]af905902013-10-01 21:38:518169 // We need to cancel modal dialogs when doing a process swap, since the load
avi2460c762015-04-17 15:21:548170 // deferrer would prevent us from swapping out. We also clear the state
8171 // because this is a cross-process navigation, which means that it's a new
8172 // site that should not have to pay for the sins of its predecessor.
creis89a0f782015-05-27 16:13:178173 //
Lei Zhang6410ec1a2019-01-31 21:38:588174 // Note that we don't bother telling |browser_plugin_embedder_| because the
creis89a0f782015-05-27 16:13:178175 // cross-process navigation will either destroy the browser plugins or not
8176 // require their dialogs to close.
avi5d3b8692016-10-12 22:00:468177 if (dialog_manager_) {
avi6879fcf2017-01-21 05:27:538178 dialog_manager_->CancelDialogs(this, /*reset_state=*/true);
avi5d3b8692016-10-12 22:00:468179 }
[email protected]af905902013-10-01 21:38:518180}
8181
Kevin McNeefb86fcf2021-02-26 23:20:578182void WebContentsImpl::NotifySwappedFromRenderManager(
8183 RenderFrameHostImpl* old_frame,
Dave Tapuskae45d6fd2021-09-29 17:03:598184 RenderFrameHostImpl* new_frame) {
Alexander Timinf785f342021-03-18 00:00:568185 TRACE_EVENT2("content", "WebContentsImpl::NotifySwappedFromRenderManager",
8186 "old_render_frame_host", old_frame, "new_render_frame_host",
8187 new_frame);
Khushalc5eaf222021-06-30 20:15:488188 DCHECK_NE(new_frame->lifecycle_state(),
8189 RenderFrameHostImpl::LifecycleStateImpl::kSpeculative);
Carlos Caballerod3644512021-02-11 15:59:538190
Nasko Oskov82dbf012023-01-10 22:40:018191 // Only fire RenderViewHostChanged if it is related to our FrameTree, as
8192 // observers can not deal with events coming from non-primary FrameTree.
8193 // TODO(https://crbug.com/1168562): Update observers to deal with the events,
8194 // and fire events for all frame trees.
Kevin McNee9f3ef7c2021-09-29 18:43:418195 if (new_frame->IsInPrimaryMainFrame()) {
danakja0bce4c952020-05-12 20:40:288196 // The |new_frame| and its various compadres are already swapped into place
8197 // for the WebContentsImpl when this method is called.
Carlos Caballerob65b6e3a2021-11-15 10:09:008198 DCHECK_EQ(
8199 primary_frame_tree_.root()->render_manager()->GetRenderWidgetHostView(),
8200 new_frame->GetView());
danakja0bce4c952020-05-12 20:40:288201
Fergal Daly6767b2e2020-02-04 03:15:168202 RenderViewHost* old_rvh =
danakja0bce4c952020-05-12 20:40:288203 old_frame ? old_frame->GetRenderViewHost() : nullptr;
8204 RenderViewHost* new_rvh = new_frame->GetRenderViewHost();
Fergal Daly6767b2e2020-02-04 03:15:168205 // |old_rvh| and |new_rvh| might be equal when navigating from a crashed
8206 // RenderFrameHost to a new same-site one. With RenderDocument, this will
8207 // happen for every same-site navigation.
8208 if (old_rvh != new_rvh)
8209 NotifyViewSwapped(old_rvh, new_rvh);
[email protected]a6b73c62013-02-11 23:05:088210
danakja0bce4c952020-05-12 20:40:288211 auto* rwhv = static_cast<RenderWidgetHostViewBase*>(new_frame->GetView());
8212 if (rwhv) {
8213 rwhv->SetMainFrameAXTreeID(new_frame->GetAXTreeID());
8214
8215 // The RenderWidgetHostView for the speculative RenderFrameHost is not
8216 // resized with the current RenderFrameHost while a navigation is
8217 // pending. So when we swap in the main frame, we need to update the
8218 // RenderWidgetHostView's size.
8219 //
8220 // Historically, this was done to fix b/1079768 for interstitials.
8221 rwhv->SetSize(GetSizeForMainFrame());
8222 }
Khushalc5eaf222021-06-30 20:15:488223
8224 NotifyPrimaryMainFrameProcessIsAlive();
[email protected]02d7b6e2014-06-24 21:01:508225 }
8226
Dave Tapuskae45d6fd2021-09-29 17:03:598227 NotifyFrameSwapped(old_frame, new_frame);
[email protected]3a3d47472010-07-15 21:03:548228}
8229
Jonathan Ross61ec65342021-12-14 23:01:408230void WebContentsImpl::NotifySwappedFromRenderManagerWithoutFallbackContent(
8231 RenderFrameHostImpl* new_frame) {
8232 auto* rwhv = static_cast<RenderWidgetHostViewBase*>(new_frame->GetView());
8233 if (rwhv)
8234 rwhv->ClearFallbackSurfaceForCommitPending();
8235}
8236
naskof5940b9f2015-03-02 23:04:058237void WebContentsImpl::NotifyMainFrameSwappedFromRenderManager(
Kevin McNeefb86fcf2021-02-26 23:20:578238 RenderFrameHostImpl* old_frame,
8239 RenderFrameHostImpl* new_frame) {
Nasko Oskov82dbf012023-01-10 22:40:018240 // Only fire RenderViewHostChanged if it is
8241 // related to our FrameTree, as observers cannot deal with events coming
8242 // from non-primary FrameTree.
8243 // TODO(https://crbug.com/1168562): Update observers to deal with the events,
8244 // and fire events for all frame trees.
Kevin McNee9f3ef7c2021-09-29 18:43:418245 if (!new_frame->IsInPrimaryMainFrame()) {
Carlos Caballerod3644512021-02-11 15:59:538246 return;
8247 }
danakja0bce4c952020-05-12 20:40:288248 NotifyViewSwapped(old_frame ? old_frame->GetRenderViewHost() : nullptr,
8249 new_frame->GetRenderViewHost());
naskof5940b9f2015-03-02 23:04:058250}
8251
dcheng59716272016-04-09 05:19:088252std::unique_ptr<WebUIImpl> WebContentsImpl::CreateWebUIForRenderFrameHost(
Ian Barkley-Yeungbda77fb2020-12-08 04:26:468253 RenderFrameHostImpl* frame_host,
Denis Kuznetsov [CET]2c6f0159f2020-05-18 14:18:168254 const GURL& url) {
Miyoung Shin072d4052020-07-13 07:52:448255 return CreateWebUI(frame_host, url);
[email protected]420ae012009-04-24 05:16:328256}
8257
lfgbede6392015-09-11 21:54:068258void WebContentsImpl::CreateRenderWidgetHostViewForRenderManager(
8259 RenderViewHost* render_view_host) {
Alexander Timin5fdeff22020-09-08 09:20:378260 OPTIONAL_TRACE_EVENT1(
8261 "content", "WebContentsImpl::CreateRenderWidgetHostViewForRenderManager",
Alexander Timinf785f342021-03-18 00:00:568262 "render_view_host", render_view_host);
Dave Tapuskaefc4936a2021-10-05 20:47:108263 // TODO(crbug.com/1254770): Fix this for portals.
8264 bool is_inner_frame_tree = static_cast<RenderViewHostImpl*>(render_view_host)
8265 ->frame_tree()
8266 ->type() == FrameTree::Type::kFencedFrame;
8267 if (is_inner_frame_tree) {
8268 WebContentsViewChildFrame::CreateRenderWidgetHostViewForInnerFrameTree(
8269 this, render_view_host->GetWidget());
8270 } else {
8271 RenderWidgetHostViewBase* rwh_view =
8272 view_->CreateViewForWidget(render_view_host->GetWidget());
8273 view_->SetOverscrollControllerEnabled(CanOverscrollContent());
8274 rwh_view->SetSize(GetSizeForMainFrame());
8275 }
lfgbede6392015-09-11 21:54:068276}
8277
Fergal Daly6de62f52020-10-14 01:56:448278void WebContentsImpl::ReattachOuterDelegateIfNeeded() {
8279 if (node_.outer_web_contents())
8280 ReattachToOuterWebContentsFrame();
8281}
8282
lfgbede6392015-09-11 21:54:068283bool WebContentsImpl::CreateRenderViewForRenderManager(
8284 RenderViewHost* render_view_host,
Anton Bikineevf62d1bf2021-05-15 17:56:078285 const absl::optional<blink::FrameToken>& opener_frame_token,
Aaron Colwell6fdff5e2021-01-27 22:42:018286 RenderFrameProxyHost* proxy_host) {
Alexander Timin5fdeff22020-09-08 09:20:378287 TRACE_EVENT1("browser,navigation",
8288 "WebContentsImpl::CreateRenderViewForRenderManager",
Alexander Timinf785f342021-03-18 00:00:568289 "render_view_host", render_view_host);
Carlos Caballero40b0efd2021-01-26 11:55:008290 auto* rvh_impl = static_cast<RenderViewHostImpl*>(render_view_host);
danakje6aa9bb2021-03-02 20:28:078291 // Observers should not destroy the WebContents here or we will crash as the
8292 // stack unwinds. See crbug.com/1181043.
8293 base::AutoReset<bool> scope(&prevent_destruction_, true);
Carlos Caballero40b0efd2021-01-26 11:55:008294
Aaron Colwell6fdff5e2021-01-27 22:42:018295 if (!proxy_host)
lfg9431efd2016-12-14 14:45:268296 CreateRenderWidgetHostViewForRenderManager(render_view_host);
lfg9431efd2016-12-14 14:45:268297
Aaron Colwell6fdff5e2021-01-27 22:42:018298 const auto proxy_routing_id =
8299 proxy_host ? proxy_host->GetRoutingID() : MSG_ROUTING_NONE;
Carlos Caballeroede6f8c2021-01-28 11:01:508300 // TODO(https://crbug.com/1171646): Given MPArch, should we pass
Rakina Zata Amnic7ffea882021-08-16 10:04:288301 // opened_by_another_window_ for non primary FrameTrees?
Carlos Caballero40b0efd2021-01-26 11:55:008302 if (!rvh_impl->CreateRenderView(opener_frame_token, proxy_routing_id,
Rakina Zata Amnic7ffea882021-08-16 10:04:288303 opened_by_another_window_)) {
[email protected]a4127722011-04-27 23:13:528304 return false;
[email protected]14392a52012-05-02 20:28:448305 }
Lingqi Chidcf722442021-09-02 01:47:198306
W. James MacLean62198672019-06-04 16:46:108307 // Set the TextAutosizer state from the main frame's renderer on the new view,
8308 // but only if it's not for the main frame. Main frame renderers should create
8309 // this state themselves from up-to-date values, so we shouldn't override it
8310 // with the cached values.
Lingqi Chi2f0e71232021-09-08 02:36:198311 if (!rvh_impl->GetMainRenderFrameHost() && proxy_host) {
Antonio Gomesda7e03d2020-08-05 15:03:088312 proxy_host->GetAssociatedRemoteMainFrame()->UpdateTextAutosizerPageInfo(
Lingqi Chidcf722442021-09-02 01:47:198313 proxy_host->frame_tree_node()
8314 ->current_frame_host()
8315 ->GetPage()
8316 .text_autosizer_page_info()
8317 .Clone());
W. James MacLean62198672019-06-04 16:46:108318 }
[email protected]a4127722011-04-27 23:13:528319
Alex Moshchuk7142d51a2022-04-01 16:30:268320 // If `render_view_host` is for an inner WebContents, ensure that its
8321 // RenderWidgetHostView is properly reattached to the outer WebContents. Note
8322 // that this should only be done when `render_view_host` is already the
8323 // current RenderViewHost in this WebContents. If it isn't, the reattachment
8324 // will happen later when `render_view_host` becomes current as part of
8325 // committing the speculative RenderFrameHost it's associated with.
8326 if (!proxy_host && render_view_host == GetRenderViewHost())
Fergal Daly6de62f52020-10-14 01:56:448327 ReattachOuterDelegateIfNeeded();
Lucas Furukawa Gadaniaed1fed2017-10-13 17:34:148328
Carlos Caballeroede6f8c2021-01-28 11:01:508329 SetHistoryOffsetAndLengthForView(
8330 render_view_host,
8331 rvh_impl->frame_tree()->controller().GetLastCommittedEntryIndex(),
8332 rvh_impl->frame_tree()->controller().GetEntryCount());
avi2b177592014-12-10 02:08:028333
Xiaohan Wang24ec9342022-01-15 17:34:228334#if BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_MAC) && !BUILDFLAG(IS_ANDROID)
[email protected]f8233cc2011-05-31 20:24:508335 // Force a ViewMsg_Resize to be sent, needed to make plugins show up on
8336 // linux. See crbug.com/83941.
avif9ab5d942015-10-15 14:05:448337 RenderWidgetHostView* rwh_view = render_view_host->GetWidget()->GetView();
[email protected]245f7d52011-11-28 15:36:448338 if (rwh_view) {
8339 if (RenderWidgetHost* render_widget_host = rwh_view->GetRenderWidgetHost())
Fady Samuel0b911822018-04-25 13:22:168340 render_widget_host->SynchronizeVisualProperties();
[email protected]245f7d52011-11-28 15:36:448341 }
[email protected]f8233cc2011-05-31 20:24:508342#endif
8343
[email protected]420ae012009-04-24 05:16:328344 return true;
8345}
8346
Xiaohan Wang24ec9342022-01-15 17:34:228347#if BUILDFLAG(IS_ANDROID)
[email protected]fc2b46b2014-05-03 16:33:458348
[email protected]155c7f22013-12-09 17:07:188349base::android::ScopedJavaLocalRef<jobject>
8350WebContentsImpl::GetJavaWebContents() {
mostynb042582e2015-03-16 22:13:408351 DCHECK_CURRENTLY_ON(BrowserThread::UI);
[email protected]0e813a52014-08-13 10:34:568352 return GetWebContentsAndroid()->GetJavaObject();
8353}
[email protected]155c7f22013-12-09 17:07:188354
Nicolas Ouellet-Payeur177a6c42023-01-25 20:25:078355base::android::ScopedJavaLocalRef<jthrowable>
8356WebContentsImpl::GetJavaCreatorLocation() {
8357 return base::android::ScopedJavaLocalRef<jthrowable>(java_creator_location_);
8358}
8359
[email protected]0e813a52014-08-13 10:34:568360WebContentsAndroid* WebContentsImpl::GetWebContentsAndroid() {
Kevin McNee576bb5d82019-05-29 16:47:518361 if (!web_contents_android_) {
8362 web_contents_android_ = std::make_unique<WebContentsAndroid>(this);
[email protected]155c7f22013-12-09 17:07:188363 }
Kevin McNee576bb5d82019-05-29 16:47:518364 return web_contents_android_.get();
8365}
8366
8367void WebContentsImpl::ClearWebContentsAndroid() {
8368 DCHECK_CURRENTLY_ON(BrowserThread::UI);
8369 web_contents_android_.reset();
[email protected]155c7f22013-12-09 17:07:188370}
8371
Ian Vollick6d75ac32021-05-05 17:45:098372void WebContentsImpl::ActivateNearestFindResult(float x, float y) {
Alexander Timin5fdeff22020-09-08 09:20:378373 OPTIONAL_TRACE_EVENT0("content",
8374 "WebContentsImpl::ActivateNearestFindResult");
paulmeyerc0b762b2016-04-13 11:55:178375 GetOrCreateFindRequestManager()->ActivateNearestFindResult(x, y);
8376}
8377
8378void WebContentsImpl::RequestFindMatchRects(int current_version) {
Alexander Timin5fdeff22020-09-08 09:20:378379 OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::RequestFindMatchRects");
paulmeyerc0b762b2016-04-13 11:55:178380 GetOrCreateFindRequestManager()->RequestFindMatchRects(current_version);
8381}
8382
rockot400ea35b2016-10-15 19:15:328383service_manager::InterfaceProvider* WebContentsImpl::GetJavaInterfaces() {
sammcf5f1b0f2016-09-20 23:05:118384 if (!java_interfaces_) {
Gyuyoung Kim6c9ce9022019-11-26 05:40:088385 mojo::PendingRemote<service_manager::mojom::InterfaceProvider> provider;
8386 BindInterfaceRegistryForWebContents(
8387 provider.InitWithNewPipeAndPassReceiver(), this);
Peter Boström08e7ed82021-04-19 17:49:598388 java_interfaces_ = std::make_unique<service_manager::InterfaceProvider>(
Sean Maher5b9af51f2022-11-21 15:32:478389 base::SingleThreadTaskRunner::GetCurrentDefault());
sammcf5f1b0f2016-09-20 23:05:118390 java_interfaces_->Bind(std::move(provider));
8391 }
8392 return java_interfaces_.get();
8393}
8394
Francois Doray6c26f3342018-08-24 17:17:228395#endif
8396
Lucas Furukawa Gadanie1c5dfda2018-11-29 17:57:418397bool WebContentsImpl::CompletedFirstVisuallyNonEmptyPaint() {
Jeremy Roman2d8dfe132021-07-06 20:51:268398 return GetPrimaryPage().did_first_visually_non_empty_paint();
spqchane72c3cb2017-06-30 23:02:108399}
8400
pkotwicz75ca8ffd2016-02-16 23:10:198401void WebContentsImpl::OnDidDownloadImage(
Mikel Astiz034ba14e2021-04-30 07:23:498402 base::WeakPtr<RenderFrameHostImpl> rfh,
Avi Drissmana5a52dd2018-03-27 03:39:028403 ImageDownloadCallback callback,
pkotwicz75ca8ffd2016-02-16 23:10:198404 int id,
8405 const GURL& image_url,
leon.hancbc4bc3c2016-02-26 07:08:528406 int32_t http_status_code,
danakjcd882fe2020-12-09 19:32:198407 const std::vector<SkBitmap>& images,
leon.hanc2228532016-08-16 05:59:188408 const std::vector<gfx::Size>& original_image_sizes) {
Alexander Timin5fdeff22020-09-08 09:20:378409 OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::OnDidDownloadImage",
Alexander Timinf785f342021-03-18 00:00:568410 "image_url", image_url);
Mikel Astiz034ba14e2021-04-30 07:23:498411
8412 // Guard against buggy or compromised renderers that could violate the API
8413 // contract that |images| and |original_image_sizes| must have the same
8414 // length.
8415 if (images.size() != original_image_sizes.size()) {
8416 if (rfh) {
8417 ReceivedBadMessage(rfh->GetProcess(),
8418 bad_message::WCI_INVALID_DOWNLOAD_IMAGE_RESULT);
8419 }
8420 // Respond with a 400 to indicate that something went wrong.
8421 std::move(callback).Run(id, 400, image_url, std::vector<SkBitmap>(),
8422 std::vector<gfx::Size>());
8423 return;
8424 }
8425
Avi Drissmana5a52dd2018-03-27 03:39:028426 std::move(callback).Run(id, http_status_code, image_url, images,
8427 original_image_sizes);
pkotwicz75ca8ffd2016-02-16 23:10:198428}
8429
[email protected]6fba26d2014-04-29 09:38:288430void WebContentsImpl::OnDialogClosed(int render_process_id,
8431 int render_frame_id,
Dave Tapuskacdf545cc2020-01-23 18:38:528432 JavaScriptDialogCallback response_callback,
Avi Drissman1a55a9d62020-03-10 18:56:458433 base::ScopedClosureRunner fullscreen_block,
[email protected]87de04b02014-04-08 22:14:498434 bool dialog_was_suppressed,
[email protected]b172aee2012-04-10 17:05:268435 bool success,
Jan Wilken Dörrieaace0cfef2021-03-11 22:01:588436 const std::u16string& user_input) {
Ian Vollick6d75ac32021-05-05 17:45:098437 RenderFrameHostImpl* rfh =
8438 RenderFrameHostImpl::FromID(render_process_id, render_frame_id);
Adithya Srinivasan2d948b22022-09-15 13:22:208439 DCHECK((!rfh || rfh->GetPage().IsPrimary()) && !IsPortal());
Alexander Timin5fdeff22020-09-08 09:20:378440 OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::OnDialogClosed",
Alexander Timinf785f342021-03-18 00:00:568441 "render_frame_host", rfh);
[email protected]87de04b02014-04-08 22:14:498442 last_dialog_suppressed_ = dialog_was_suppressed;
Avi Drissman1a55a9d62020-03-10 18:56:458443 fullscreen_block.RunAndReset();
[email protected]87de04b02014-04-08 22:14:498444
David Bokan1bdb3701f2021-04-30 22:02:358445 javascript_dialog_dismiss_notifier_.reset();
Charlie Reis96077362019-07-04 00:34:048446
[email protected]beb440c2009-11-06 04:08:548447 if (is_showing_before_unload_dialog_ && !success) {
clamybc6f4152016-04-01 20:14:238448 // It is possible for the current RenderFrameHost to have changed in the
8449 // meantime. Do not reset the navigation state in that case.
8450 if (rfh && rfh == rfh->frame_tree_node()->current_frame_host()) {
clamy44e84ce2016-02-22 15:38:258451 rfh->frame_tree_node()->BeforeUnloadCanceled();
Carlos Caballeroede6f8c2021-01-28 11:01:508452 rfh->frame_tree()->controller().DiscardNonCommittedEntries();
clamybc6f4152016-04-01 20:14:238453 }
[email protected]ec8e8b02013-06-19 04:57:108454
Charles Reis15d60b132017-11-03 17:43:478455 // Update the URL display either way, to avoid showing a stale URL.
8456 NotifyNavigationStateChanged(INVALIDATE_TYPE_URL);
8457
Andrew Grievee19cd93e2021-01-22 05:43:068458 observers_.NotifyObservers(
8459 &WebContentsObserver::BeforeUnloadDialogCancelled);
[email protected]beb440c2009-11-06 04:08:548460 }
[email protected]87de04b02014-04-08 22:14:498461
Dave Tapuskacdf545cc2020-01-23 18:38:528462 std::move(response_callback).Run(success, user_input);
Pavel Feldman3c1842b2017-08-02 05:00:168463
Dave Tapuskacdf545cc2020-01-23 18:38:528464 std::vector<protocol::PageHandler*> page_handlers =
8465 protocol::PageHandler::EnabledForWebContents(this);
8466 for (auto* handler : page_handlers)
8467 handler->DidCloseJavaScriptDialog(success, user_input);
avi1c51fb62017-02-27 20:43:038468
8469 is_showing_javascript_dialog_ = false;
8470 is_showing_before_unload_dialog_ = false;
[email protected]beb440c2009-11-06 04:08:548471}
8472
Paul Semel3e241042022-10-11 12:57:318473RenderFrameHostManager* WebContentsImpl::GetRenderManager() {
Carlos Caballerob65b6e3a2021-11-15 10:09:008474 return primary_frame_tree_.root()->render_manager();
[email protected]fa944cb82013-11-15 17:51:218475}
8476
[email protected]f8497342013-02-05 22:15:028477BrowserPluginGuest* WebContentsImpl::GetBrowserPluginGuest() const {
[email protected]7a846df2012-09-20 19:17:398478 return browser_plugin_guest_.get();
8479}
8480
Albert J. Wongc55cc64d2018-10-12 02:50:048481void WebContentsImpl::SetBrowserPluginGuest(
8482 std::unique_ptr<BrowserPluginGuest> guest) {
Alexander Timin5fdeff22020-09-08 09:20:378483 OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::SetBrowserPluginGuest");
Albert J. Wongc55cc64d2018-10-12 02:50:048484 DCHECK(!browser_plugin_guest_);
8485 DCHECK(guest);
8486 browser_plugin_guest_ = std::move(guest);
[email protected]738f57a2013-06-29 21:06:548487}
8488
Aidan Wolter52bcc12a2018-11-14 03:27:298489base::UnguessableToken WebContentsImpl::GetAudioGroupId() {
Aidan Wolter52bcc12a2018-11-14 03:27:298490 return GetAudioStreamFactory()->group_id();
8491}
8492
Miyoung Shin5709ab02020-02-19 06:50:418493const std::vector<blink::mojom::FaviconURLPtr>&
8494WebContentsImpl::GetFaviconURLs() {
Dave Tapuska327c06c92022-06-13 20:31:518495 return GetPrimaryMainFrame()->FaviconURLs();
Mounir Lamouri7b4a1f232019-12-23 16:32:108496}
8497
Mugdha Lakhani0a0d7862020-07-29 09:58:458498// The Mac implementation of the next two methods is in
8499// web_contents_impl_mac.mm
Xiaohan Wang24ec9342022-01-15 17:34:228500#if !BUILDFLAG(IS_MAC)
Mugdha Lakhani0a0d7862020-07-29 09:58:458501
8502void WebContentsImpl::Resize(const gfx::Rect& new_bounds) {
Alexander Timin5fdeff22020-09-08 09:20:378503 OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::Resize");
Mugdha Lakhani0a0d7862020-07-29 09:58:458504#if defined(USE_AURA)
8505 aura::Window* window = GetNativeView();
8506 window->SetBounds(gfx::Rect(window->bounds().origin(), new_bounds.size()));
Xiaohan Wang24ec9342022-01-15 17:34:228507#elif BUILDFLAG(IS_ANDROID)
Mugdha Lakhani0a0d7862020-07-29 09:58:458508 content::RenderWidgetHostView* view = GetRenderWidgetHostView();
8509 if (view)
8510 view->SetBounds(new_bounds);
8511#endif
8512}
8513
8514gfx::Size WebContentsImpl::GetSize() {
8515#if defined(USE_AURA)
8516 aura::Window* window = GetNativeView();
8517 return window->bounds().size();
Xiaohan Wang24ec9342022-01-15 17:34:228518#elif BUILDFLAG(IS_ANDROID)
Mugdha Lakhani0a0d7862020-07-29 09:58:458519 ui::ViewAndroid* view_android = GetNativeView();
8520 return view_android->bounds().size();
Dave Tapuskaa1cc3702023-02-03 20:43:248521#elif BUILDFLAG(IS_IOS)
8522 // TODO(crbug.com/1411704): Implement me.
8523 NOTREACHED();
8524 return gfx::Size();
Mugdha Lakhani0a0d7862020-07-29 09:58:458525#endif
8526}
8527
Xiaohan Wang24ec9342022-01-15 17:34:228528#endif // !BUILDFLAG(IS_MAC)
Mugdha Lakhani0a0d7862020-07-29 09:58:458529
Mike Jacksonf116a2e2021-06-09 16:48:308530gfx::Rect WebContentsImpl::GetWindowsControlsOverlayRect() const {
8531 return window_controls_overlay_rect_;
8532}
8533
Hassan Talatd96dbc02021-01-20 08:02:048534void WebContentsImpl::UpdateWindowControlsOverlay(
Amanda Baker228ec482021-03-24 19:50:088535 const gfx::Rect& bounding_rect) {
Mike Jacksonf116a2e2021-06-09 16:48:308536 if (window_controls_overlay_rect_ == bounding_rect)
8537 return;
8538
8539 window_controls_overlay_rect_ = bounding_rect;
8540
8541 // Updates to the |window_controls_overlay_rect_| are sent via
8542 // the VisualProperties message.
8543 if (RenderWidgetHost* render_widget_host =
Dave Tapuska327c06c92022-06-13 20:31:518544 GetPrimaryMainFrame()->GetRenderWidgetHost())
Mike Jacksonf116a2e2021-06-09 16:48:308545 render_widget_host->SynchronizeVisualProperties();
Marijn Kruisselbrink61cdd4d2023-01-26 02:47:488546
8547 view_->UpdateWindowControlsOverlay(bounding_rect);
Hassan Talatd96dbc02021-01-20 08:02:048548}
8549
[email protected]f8497342013-02-05 22:15:028550BrowserPluginEmbedder* WebContentsImpl::GetBrowserPluginEmbedder() const {
[email protected]7a846df2012-09-20 19:17:398551 return browser_plugin_embedder_.get();
8552}
[email protected]8ff00d72012-10-23 19:12:218553
fsamuel60b42282015-03-10 03:29:148554void WebContentsImpl::CreateBrowserPluginEmbedderIfNecessary() {
Alexander Timin5fdeff22020-09-08 09:20:378555 OPTIONAL_TRACE_EVENT0(
8556 "content", "WebContentsImpl::CreateBrowserPluginEmbedderIfNecessary");
fsamuel60b42282015-03-10 03:29:148557 if (browser_plugin_embedder_)
8558 return;
8559 browser_plugin_embedder_.reset(BrowserPluginEmbedder::Create(this));
8560}
8561
danakja0bce4c952020-05-12 20:40:288562gfx::Size WebContentsImpl::GetSizeForMainFrame() {
8563 if (delegate_) {
8564 // The delegate has a chance to specify a size independent of the UI.
8565 gfx::Size delegate_size = delegate_->GetSizeForNewRenderView(this);
8566 if (!delegate_size.IsEmpty())
8567 return delegate_size;
8568 }
8569
8570 // Device emulation, when enabled, can specify a size independent of the UI.
8571 if (!device_emulation_size_.IsEmpty())
8572 return device_emulation_size_;
8573
8574 return GetContainerBounds().size();
[email protected]dc0fd432013-08-27 15:29:218575}
8576
Carlos Caballero6ff6ace2021-02-05 16:53:008577void WebContentsImpl::OnFrameTreeNodeDestroyed(FrameTreeNode* node) {
Alexander Timinf785f342021-03-18 00:00:568578 OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::OnFrameTreeNodeDestroyed",
Carlos Caballerobf3624962021-04-02 01:26:028579 "node", node);
Dave Tapuska54c76a032021-10-27 22:10:428580 // If we are the focused frame tree and are destroying the root node
8581 // reassign the focused frame tree node.
Arthur Sonzognif6785ec2022-12-05 10:11:508582 if (!node->parent() && GetFocusedFrameTree() == &node->frame_tree() &&
8583 &node->frame_tree() != &primary_frame_tree_) {
Dave Tapuska54c76a032021-10-27 22:10:428584 FrameTreeNode* frame_in_embedder =
8585 node->render_manager()->GetOuterDelegateNode();
Arthur Sonzognif6785ec2022-12-05 10:11:508586 SetFocusedFrameTree(frame_in_embedder ? &frame_in_embedder->frame_tree()
Carlos Caballerob65b6e3a2021-11-15 10:09:008587 : &primary_frame_tree_);
Dave Tapuska54c76a032021-10-27 22:10:428588 }
8589
Andrew Grievee19cd93e2021-01-22 05:43:068590 observers_.NotifyObservers(&WebContentsObserver::FrameDeleted,
Carlos Caballerobf3624962021-04-02 01:26:028591 node->frame_tree_node_id());
[email protected]9b159a52013-10-03 17:24:558592}
8593
[email protected]222f5822014-02-05 23:40:498594void WebContentsImpl::OnPreferredSizeChanged(const gfx::Size& old_size) {
Alexander Timin5fdeff22020-09-08 09:20:378595 OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::OnPreferredSizeChanged");
[email protected]222f5822014-02-05 23:40:498596 if (!delegate_)
8597 return;
8598 const gfx::Size new_size = GetPreferredSize();
8599 if (new_size != old_size)
8600 delegate_->UpdatePreferredSize(this, new_size);
8601}
8602
Miyoung Shin072d4052020-07-13 07:52:448603std::unique_ptr<WebUIImpl> WebContentsImpl::CreateWebUI(
Ian Barkley-Yeungbda77fb2020-12-08 04:26:468604 RenderFrameHostImpl* frame_host,
Miyoung Shin072d4052020-07-13 07:52:448605 const GURL& url) {
Alexander Timin5fdeff22020-09-08 09:20:378606 TRACE_EVENT2("content", "WebContentsImpl::CreateWebUI", "frame_host",
Alexander Timinf785f342021-03-18 00:00:568607 frame_host, "url", url);
Miyoung Shin072d4052020-07-13 07:52:448608 std::unique_ptr<WebUIImpl> web_ui =
8609 std::make_unique<WebUIImpl>(this, frame_host);
Lei Zhangee3b63ad2018-06-06 23:25:318610 std::unique_ptr<WebUIController> controller(
avie865b1d2016-10-24 19:42:598611 WebUIControllerFactoryRegistry::GetInstance()
Lei Zhangee3b63ad2018-06-06 23:25:318612 ->CreateWebUIControllerForURL(web_ui.get(), url));
dbeama1b926a2015-08-31 23:17:518613 if (controller) {
Lei Zhangee3b63ad2018-06-06 23:25:318614 web_ui->SetController(std::move(controller));
dbeama1b926a2015-08-31 23:17:518615 return web_ui;
8616 }
8617
avie865b1d2016-10-24 19:42:598618 return nullptr;
dbeama1b926a2015-08-31 23:17:518619}
8620
Lucas Furukawa Gadanie1c5dfda2018-11-29 17:57:418621FindRequestManager* WebContentsImpl::GetFindRequestManager() {
8622 for (auto* contents = this; contents;
paulmeyerfeafc2d2017-04-25 21:46:408623 contents = contents->GetOuterWebContents()) {
8624 if (contents->find_request_manager_)
8625 return contents->find_request_manager_.get();
8626 }
8627
8628 return nullptr;
8629}
8630
paulmeyerc0b762b2016-04-13 11:55:178631FindRequestManager* WebContentsImpl::GetOrCreateFindRequestManager() {
paulmeyerfeafc2d2017-04-25 21:46:408632 if (FindRequestManager* manager = GetFindRequestManager())
8633 return manager;
8634
Ehsan Karamad6beb2ea2018-11-25 18:15:138635 DCHECK(!browser_plugin_guest_ || GetOuterWebContents());
8636
paulmeyerfeafc2d2017-04-25 21:46:408637 // No existing FindRequestManager found, so one must be created.
Fergal Daly55b6d722020-09-11 07:56:338638 find_request_manager_ = std::make_unique<FindRequestManager>(this);
paulmeyerfeafc2d2017-04-25 21:46:408639
8640 // Concurrent find sessions must not overlap, so destroy any existing
8641 // FindRequestManagers in any inner WebContentses.
Lucas Furukawa Gadani2ec00c82018-12-14 15:53:168642 for (WebContents* contents : GetWebContentsAndAllInner()) {
8643 auto* web_contents_impl = static_cast<WebContentsImpl*>(contents);
8644 if (web_contents_impl == this)
paulmeyerfeafc2d2017-04-25 21:46:408645 continue;
Lucas Furukawa Gadani2ec00c82018-12-14 15:53:168646 if (web_contents_impl->find_request_manager_) {
8647 web_contents_impl->find_request_manager_->StopFinding(
8648 STOP_FIND_ACTION_CLEAR_SELECTION);
8649 web_contents_impl->find_request_manager_.release();
paulmeyerfeafc2d2017-04-25 21:46:408650 }
8651 }
paulmeyerc0b762b2016-04-13 11:55:178652
8653 return find_request_manager_.get();
8654}
8655
8656void WebContentsImpl::NotifyFindReply(int request_id,
8657 int number_of_matches,
8658 const gfx::Rect& selection_rect,
8659 int active_match_ordinal,
8660 bool final_update) {
Alexander Timin5fdeff22020-09-08 09:20:378661 OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::NotifyFindReply");
Takashi Toyoshimaea534ef22021-07-21 03:27:598662 if (delegate_ && !IsBeingDestroyed() &&
Dave Tapuska327c06c92022-06-13 20:31:518663 !GetPrimaryMainFrame()->GetProcess()->FastShutdownStarted()) {
paulmeyerc0b762b2016-04-13 11:55:178664 delegate_->FindReply(this, request_id, number_of_matches, selection_rect,
8665 active_match_ordinal, final_update);
8666 }
8667}
8668
ortuno467e5792016-06-10 04:32:398669void WebContentsImpl::IncrementBluetoothConnectedDeviceCount() {
Alexander Timin5fdeff22020-09-08 09:20:378670 OPTIONAL_TRACE_EVENT0(
8671 "content", "WebContentsImpl::IncrementBluetoothConnectedDeviceCount");
ortuno467e5792016-06-10 04:32:398672 // Trying to invalidate the tab state while being destroyed could result in a
8673 // use after free.
8674 if (IsBeingDestroyed()) {
8675 return;
8676 }
8677 // Notify for UI updates if the state changes.
8678 bluetooth_connected_device_count_++;
8679 if (bluetooth_connected_device_count_ == 1) {
Francois Doray66766a572019-12-17 20:56:498680 OnIsConnectedToBluetoothDeviceChanged(true);
ortuno467e5792016-06-10 04:32:398681 }
8682}
8683
8684void WebContentsImpl::DecrementBluetoothConnectedDeviceCount() {
Alexander Timin5fdeff22020-09-08 09:20:378685 OPTIONAL_TRACE_EVENT0(
8686 "content", "WebContentsImpl::DecrementBluetoothConnectedDeviceCount");
ortuno467e5792016-06-10 04:32:398687 // Trying to invalidate the tab state while being destroyed could result in a
8688 // use after free.
8689 if (IsBeingDestroyed()) {
8690 return;
8691 }
8692 // Notify for UI updates if the state changes.
Lukasz Anforowicze9ae3722017-09-29 17:37:388693 DCHECK_NE(bluetooth_connected_device_count_, 0u);
ortuno467e5792016-06-10 04:32:398694 bluetooth_connected_device_count_--;
8695 if (bluetooth_connected_device_count_ == 0) {
Francois Doray66766a572019-12-17 20:56:498696 OnIsConnectedToBluetoothDeviceChanged(false);
8697 }
8698}
8699
8700void WebContentsImpl::OnIsConnectedToBluetoothDeviceChanged(
8701 bool is_connected_to_bluetooth_device) {
Alexander Timin5fdeff22020-09-08 09:20:378702 OPTIONAL_TRACE_EVENT0(
8703 "content", "WebContentsImpl::OnIsConnectedToBluetoothDeviceChanged");
Francois Doray66766a572019-12-17 20:56:498704 NotifyNavigationStateChanged(INVALIDATE_TYPE_TAB);
Andrew Grievee19cd93e2021-01-22 05:43:068705 observers_.NotifyObservers(
8706 &WebContentsObserver::OnIsConnectedToBluetoothDeviceChanged,
8707 is_connected_to_bluetooth_device);
ortuno467e5792016-06-10 04:32:398708}
8709
Ovidio Henriquez76696f62020-07-08 03:06:598710void WebContentsImpl::IncrementBluetoothScanningSessionsCount() {
Alexander Timin5fdeff22020-09-08 09:20:378711 OPTIONAL_TRACE_EVENT0(
8712 "content", "WebContentsImpl::IncrementBluetoothScanningSessionsCount");
Ovidio Henriquez76696f62020-07-08 03:06:598713 // Trying to invalidate the tab state while being destroyed could result in a
8714 // use after free.
8715 if (IsBeingDestroyed())
8716 return;
8717
8718 // Notify for UI updates if the state changes.
8719 bluetooth_scanning_sessions_count_++;
8720 if (bluetooth_scanning_sessions_count_ == 1)
8721 NotifyNavigationStateChanged(INVALIDATE_TYPE_TAB);
8722}
8723
8724void WebContentsImpl::DecrementBluetoothScanningSessionsCount() {
Alexander Timin5fdeff22020-09-08 09:20:378725 OPTIONAL_TRACE_EVENT0(
8726 "content", "WebContentsImpl::DecrementBluetoothScanningSessionsCount");
Ovidio Henriquez76696f62020-07-08 03:06:598727 // Trying to invalidate the tab state while being destroyed could result in a
8728 // use after free.
8729 if (IsBeingDestroyed())
8730 return;
8731
8732 DCHECK_NE(0u, bluetooth_scanning_sessions_count_);
8733 bluetooth_scanning_sessions_count_--;
8734 if (bluetooth_scanning_sessions_count_ == 0)
8735 NotifyNavigationStateChanged(INVALIDATE_TYPE_TAB);
8736}
8737
Reilly Grant5e7c79b22019-04-09 17:26:208738void WebContentsImpl::IncrementSerialActiveFrameCount() {
Alexander Timin5fdeff22020-09-08 09:20:378739 OPTIONAL_TRACE_EVENT0("content",
8740 "WebContentsImpl::IncrementSerialActiveFrameCount");
Reilly Grant5e7c79b22019-04-09 17:26:208741 // Trying to invalidate the tab state while being destroyed could result in a
8742 // use after free.
8743 if (IsBeingDestroyed())
8744 return;
8745
8746 // Notify for UI updates if the state changes.
8747 serial_active_frame_count_++;
8748 if (serial_active_frame_count_ == 1)
8749 NotifyNavigationStateChanged(INVALIDATE_TYPE_TAB);
8750}
8751
8752void WebContentsImpl::DecrementSerialActiveFrameCount() {
Alexander Timin5fdeff22020-09-08 09:20:378753 OPTIONAL_TRACE_EVENT0("content",
8754 "WebContentsImpl::DecrementSerialActiveFrameCount");
Reilly Grant5e7c79b22019-04-09 17:26:208755 // Trying to invalidate the tab state while being destroyed could result in a
8756 // use after free.
8757 if (IsBeingDestroyed())
8758 return;
8759
8760 // Notify for UI updates if the state changes.
8761 DCHECK_NE(0u, serial_active_frame_count_);
8762 serial_active_frame_count_--;
8763 if (serial_active_frame_count_ == 0)
8764 NotifyNavigationStateChanged(INVALIDATE_TYPE_TAB);
8765}
8766
Matt Reynoldse8c6c1f2019-11-02 09:53:538767void WebContentsImpl::IncrementHidActiveFrameCount() {
Alexander Timin5fdeff22020-09-08 09:20:378768 OPTIONAL_TRACE_EVENT0("content",
8769 "WebContentsImpl::IncrementHidActiveFrameCount");
Matt Reynoldse8c6c1f2019-11-02 09:53:538770 // Trying to invalidate the tab state while being destroyed could result in a
8771 // use after free.
8772 if (IsBeingDestroyed())
8773 return;
8774
8775 // Notify for UI updates if the active frame count transitions from zero to
8776 // non-zero.
8777 hid_active_frame_count_++;
8778 if (hid_active_frame_count_ == 1)
8779 NotifyNavigationStateChanged(INVALIDATE_TYPE_TAB);
8780}
8781
8782void WebContentsImpl::DecrementHidActiveFrameCount() {
Alexander Timin5fdeff22020-09-08 09:20:378783 OPTIONAL_TRACE_EVENT0("content",
8784 "WebContentsImpl::DecrementHidActiveFrameCount");
Matt Reynoldse8c6c1f2019-11-02 09:53:538785 // Trying to invalidate the tab state while being destroyed could result in a
8786 // use after free.
8787 if (IsBeingDestroyed())
8788 return;
8789
8790 // Notify for UI updates if the active frame count transitions from non-zero
8791 // to zero.
8792 DCHECK_NE(0u, hid_active_frame_count_);
8793 hid_active_frame_count_--;
8794 if (hid_active_frame_count_ == 0)
8795 NotifyNavigationStateChanged(INVALIDATE_TYPE_TAB);
8796}
8797
Matt Reynoldsed00ca7e72022-08-18 20:56:208798void WebContentsImpl::OnIsConnectedToUsbDeviceChanged(
8799 bool is_connected_to_usb_device) {
8800 OPTIONAL_TRACE_EVENT0("content",
8801 "WebContentsImpl::OnIsConnectedToUsbDeviceChanged");
8802 NotifyNavigationStateChanged(INVALIDATE_TYPE_TAB);
8803 observers_.NotifyObservers(
8804 &WebContentsObserver::OnIsConnectedToUsbDeviceChanged,
8805 is_connected_to_usb_device);
8806}
8807
8808void WebContentsImpl::IncrementUsbActiveFrameCount() {
8809 OPTIONAL_TRACE_EVENT0("content",
8810 "WebContentsImpl::IncrementUsbActiveFrameCount");
8811 // Trying to invalidate the tab state while being destroyed could result in a
8812 // use after free.
8813 if (IsBeingDestroyed())
8814 return;
8815
8816 // Notify for UI updates if the active frame count transitions from zero to
8817 // non-zero.
8818 usb_active_frame_count_++;
8819 if (usb_active_frame_count_ == 1)
8820 OnIsConnectedToUsbDeviceChanged(true);
8821}
8822
8823void WebContentsImpl::DecrementUsbActiveFrameCount() {
8824 OPTIONAL_TRACE_EVENT0("content",
8825 "WebContentsImpl::DecrementUsbActiveFrameCount");
8826 // Trying to invalidate the tab state while being destroyed could result in a
8827 // use after free.
8828 if (IsBeingDestroyed())
8829 return;
8830
8831 // Notify for UI updates if the active frame count transitions from non-zero
8832 // to zero.
8833 DCHECK_NE(0u, usb_active_frame_count_);
8834 usb_active_frame_count_--;
8835 if (usb_active_frame_count_ == 0)
8836 OnIsConnectedToUsbDeviceChanged(false);
8837}
8838
Austin Sullivanafefb722021-01-14 01:26:398839void WebContentsImpl::IncrementFileSystemAccessHandleCount() {
Alexander Timin5fdeff22020-09-08 09:20:378840 OPTIONAL_TRACE_EVENT0(
Austin Sullivanafefb722021-01-14 01:26:398841 "content", "WebContentsImpl::IncrementFileSystemAccessHandleCount");
Marijn Kruisselbrink29051042019-08-06 22:56:558842 // Trying to invalidate the tab state while being destroyed could result in a
8843 // use after free.
8844 if (IsBeingDestroyed())
8845 return;
8846
8847 // Notify for UI updates if the state changes. Need both TYPE_TAB and TYPE_URL
8848 // to update both the tab-level usage indicator and the usage indicator in the
8849 // omnibox.
Austin Sullivanafefb722021-01-14 01:26:398850 file_system_access_handle_count_++;
8851 if (file_system_access_handle_count_ == 1) {
Marijn Kruisselbrink29051042019-08-06 22:56:558852 NotifyNavigationStateChanged(static_cast<content::InvalidateTypes>(
8853 INVALIDATE_TYPE_TAB | INVALIDATE_TYPE_URL));
8854 }
8855}
8856
Austin Sullivanafefb722021-01-14 01:26:398857void WebContentsImpl::DecrementFileSystemAccessHandleCount() {
Alexander Timin5fdeff22020-09-08 09:20:378858 OPTIONAL_TRACE_EVENT0(
Austin Sullivanafefb722021-01-14 01:26:398859 "content", "WebContentsImpl::DecrementFileSystemAccessHandleCount");
Marijn Kruisselbrink29051042019-08-06 22:56:558860 // Trying to invalidate the tab state while being destroyed could result in a
8861 // use after free.
8862 if (IsBeingDestroyed())
8863 return;
8864
8865 // Notify for UI updates if the state changes. Need both TYPE_TAB and TYPE_URL
8866 // to update both the tab-level usage indicator and the usage indicator in the
8867 // omnibox.
Austin Sullivanafefb722021-01-14 01:26:398868 DCHECK_NE(0u, file_system_access_handle_count_);
8869 file_system_access_handle_count_--;
8870 if (file_system_access_handle_count_ == 0) {
Marijn Kruisselbrink29051042019-08-06 22:56:558871 NotifyNavigationStateChanged(static_cast<content::InvalidateTypes>(
8872 INVALIDATE_TYPE_TAB | INVALIDATE_TYPE_URL));
8873 }
8874}
8875
zqzhang8ac49002017-03-16 21:51:358876void WebContentsImpl::SetHasPersistentVideo(bool has_persistent_video) {
Alexander Timin5fdeff22020-09-08 09:20:378877 OPTIONAL_TRACE_EVENT2("content", "WebContentsImpl::SetHasPersistentVideo",
8878 "has_persistent_video", has_persistent_video,
8879 "had_persistent_value", has_persistent_video_);
zqzhang8ac49002017-03-16 21:51:358880 if (has_persistent_video_ == has_persistent_video)
mlamouri5cd9ae82017-02-18 11:05:098881 return;
8882
zqzhang8ac49002017-03-16 21:51:358883 has_persistent_video_ = has_persistent_video;
mlamouri5cd9ae82017-02-18 11:05:098884 NotifyPreferencesChanged();
zqzhang8ac49002017-03-16 21:51:358885 media_web_contents_observer()->RequestPersistentVideo(has_persistent_video);
Jonathan Rossc1d5cc72022-11-03 22:09:398886
8887 // This is Picture-in-Picture on Android S+.
8888 if (auto* view = GetRenderWidgetHostView()) {
8889 static_cast<RenderWidgetHostViewBase*>(view)->SetHasPersistentVideo(
8890 has_persistent_video);
8891 }
mlamouri5cd9ae82017-02-18 11:05:098892}
8893
Ian Vollick5d5c37f2019-06-19 22:50:578894void WebContentsImpl::SetSpatialNavigationDisabled(bool disabled) {
Alexander Timin5fdeff22020-09-08 09:20:378895 OPTIONAL_TRACE_EVENT2(
8896 "content", "WebContentsImpl::SetSpatialNavigationDisabled", "disabled",
8897 disabled, "was_disabled", is_spatial_navigation_disabled_);
Ian Vollick5d5c37f2019-06-19 22:50:578898 if (is_spatial_navigation_disabled_ == disabled)
8899 return;
8900
8901 is_spatial_navigation_disabled_ = disabled;
8902 NotifyPreferencesChanged();
8903}
8904
Mahesh Machavolu6cb80182022-07-22 08:09:318905void WebContentsImpl::SetStylusHandwritingEnabled(bool enabled) {
8906 if (stylus_handwriting_enabled_ == enabled)
8907 return;
8908 stylus_handwriting_enabled_ = enabled;
8909 NotifyPreferencesChanged();
8910}
8911
François Beaufort1388f2892022-01-29 08:22:478912PictureInPictureResult WebContentsImpl::EnterPictureInPicture() {
Alexander Timin5fdeff22020-09-08 09:20:378913 OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::EnterPictureInPicture");
François Beaufort1388f2892022-01-29 08:22:478914 return delegate_ ? delegate_->EnterPictureInPicture(this)
8915 : PictureInPictureResult::kNotSupported;
Mounir Lamouri11e9ef432018-05-22 03:10:168916}
8917
Mounir Lamouri6d759e12018-05-16 20:01:308918void WebContentsImpl::ExitPictureInPicture() {
Alexander Timin5fdeff22020-09-08 09:20:378919 OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::ExitPictureInPicture");
Mounir Lamouri6d759e12018-05-16 20:01:308920 if (delegate_)
8921 delegate_->ExitPictureInPicture();
8922}
8923
Alexander Cooper987d046cc2021-04-14 00:07:218924void WebContentsImpl::OnXrHasRenderTarget(
8925 const viz::FrameSinkId& frame_sink_id) {
8926 xr_render_target_ = frame_sink_id;
8927 observers_.NotifyObservers(&WebContentsObserver::CaptureTargetChanged);
8928}
8929
8930viz::FrameSinkId WebContentsImpl::GetCaptureFrameSinkId() {
8931 if (xr_render_target_.is_valid())
8932 return xr_render_target_;
8933
8934 RenderWidgetHostView* host_view = GetRenderWidgetHostView();
8935 if (!host_view) {
8936 return {};
8937 }
8938
8939 RenderWidgetHostViewBase* base_view =
8940 static_cast<RenderWidgetHostViewBase*>(host_view);
8941 return base_view->GetFrameSinkId();
8942}
8943
Xiaohan Wang24ec9342022-01-15 17:34:228944#if BUILDFLAG(IS_ANDROID)
paulmeyerc0b762b2016-04-13 11:55:178945void WebContentsImpl::NotifyFindMatchRectsReply(
8946 int version,
8947 const std::vector<gfx::RectF>& rects,
8948 const gfx::RectF& active_rect) {
Alexander Timin5fdeff22020-09-08 09:20:378949 OPTIONAL_TRACE_EVENT0("content",
8950 "WebContentsImpl::NotifyFindMatchRectsReply");
paulmeyerc0b762b2016-04-13 11:55:178951 if (delegate_)
8952 delegate_->FindMatchRectsReply(this, version, rects, active_rect);
8953}
8954#endif
8955
[email protected]34ff1cfc2014-08-20 06:16:058956void WebContentsImpl::SetForceDisableOverscrollContent(bool force_disable) {
Alexander Timin5fdeff22020-09-08 09:20:378957 OPTIONAL_TRACE_EVENT1("content",
8958 "WebContentsImpl::SetForceDisableOverscrollContent",
8959 "force_disable", force_disable);
[email protected]34ff1cfc2014-08-20 06:16:058960 force_disable_overscroll_content_ = force_disable;
8961 if (view_)
8962 view_->SetOverscrollControllerEnabled(CanOverscrollContent());
8963}
8964
Jianzhou Fengd8720c72018-01-18 03:06:308965bool WebContentsImpl::SetDeviceEmulationSize(const gfx::Size& new_size) {
Alexander Timin5fdeff22020-09-08 09:20:378966 OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::SetDeviceEmulationSize");
Jianzhou Fengd8720c72018-01-18 03:06:308967 device_emulation_size_ = new_size;
Dave Tapuska327c06c92022-06-13 20:31:518968 RenderWidgetHostView* rwhv = GetPrimaryMainFrame()->GetView();
Jianzhou Fengd8720c72018-01-18 03:06:308969
8970 const gfx::Size current_size = rwhv->GetViewBounds().size();
8971 if (view_size_before_emulation_.IsEmpty())
8972 view_size_before_emulation_ = current_size;
8973
8974 if (current_size != new_size)
8975 rwhv->SetSize(new_size);
8976
8977 return current_size != new_size;
8978}
8979
8980void WebContentsImpl::ClearDeviceEmulationSize() {
Alexander Timin5fdeff22020-09-08 09:20:378981 OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::ClearDeviceEmulationSize");
Dave Tapuska327c06c92022-06-13 20:31:518982 RenderWidgetHostView* rwhv = GetPrimaryMainFrame()->GetView();
Jianzhou Fengd8720c72018-01-18 03:06:308983 // WebContentsView could get resized during emulation, which also resizes
8984 // RWHV. If it happens, assume user would like to keep using the size after
8985 // emulation.
8986 // TODO(jzfeng): Prohibit resizing RWHV through any other means (at least when
8987 // WebContentsView size changes).
Dmitry Gozmanc63707182018-03-06 00:09:398988 if (!view_size_before_emulation_.IsEmpty() && rwhv &&
8989 rwhv->GetViewBounds().size() == device_emulation_size_) {
Jianzhou Fengd8720c72018-01-18 03:06:308990 rwhv->SetSize(view_size_before_emulation_);
Dmitry Gozmanc63707182018-03-06 00:09:398991 }
Jianzhou Fengd8720c72018-01-18 03:06:308992 device_emulation_size_ = gfx::Size();
8993 view_size_before_emulation_ = gfx::Size();
8994}
8995
Max Morin5bc74f52018-05-09 07:00:218996ForwardingAudioStreamFactory* WebContentsImpl::GetAudioStreamFactory() {
8997 if (!audio_stream_factory_) {
Sergey Ulanov52d396d2022-09-06 23:46:438998 std::unique_ptr<AudioStreamBrokerFactory> broker_factory;
8999 if (delegate_)
9000 broker_factory = delegate_->CreateAudioStreamBrokerFactory(this);
9001 if (!broker_factory)
9002 broker_factory = AudioStreamBrokerFactory::CreateImpl();
Max Morin5bc74f52018-05-09 07:00:219003 audio_stream_factory_.emplace(
9004 this,
Max Morinddebb972018-09-20 10:04:149005 // BrowserMainLoop::GetInstance() may be null in unit tests.
9006 BrowserMainLoop::GetInstance()
9007 ? static_cast<media::UserInputMonitorBase*>(
9008 BrowserMainLoop::GetInstance()->user_input_monitor())
9009 : nullptr,
Sergey Ulanov52d396d2022-09-06 23:46:439010 std::move(broker_factory));
Max Morin5bc74f52018-05-09 07:00:219011 }
9012
9013 return &*audio_stream_factory_;
9014}
9015
dalecurtis88c240072015-12-09 02:11:189016void WebContentsImpl::MediaStartedPlaying(
billorr21c005d2016-11-17 03:57:049017 const WebContentsObserver::MediaPlayerInfo& media_info,
Mounir Lamouri0f5bdf52019-04-04 16:32:359018 const MediaPlayerId& id) {
Alexander Timin5fdeff22020-09-08 09:20:379019 OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::MediaStartedPlaying");
billorr21c005d2016-11-17 03:57:049020 if (media_info.has_video)
9021 currently_playing_video_count_++;
9022
Andrew Grievee19cd93e2021-01-22 05:43:069023 observers_.NotifyObservers(&WebContentsObserver::MediaStartedPlaying,
9024 media_info, id);
dalecurtis88c240072015-12-09 02:11:189025}
9026
9027void WebContentsImpl::MediaStoppedPlaying(
billorr21c005d2016-11-17 03:57:049028 const WebContentsObserver::MediaPlayerInfo& media_info,
Mounir Lamouri0f5bdf52019-04-04 16:32:359029 const MediaPlayerId& id,
Becca Hughes220bfc102017-11-14 18:24:079030 WebContentsObserver::MediaStoppedReason reason) {
Alexander Timin5fdeff22020-09-08 09:20:379031 OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::MediaStoppedPlaying");
billorr21c005d2016-11-17 03:57:049032 if (media_info.has_video)
9033 currently_playing_video_count_--;
9034
Andrew Grievee19cd93e2021-01-22 05:43:069035 observers_.NotifyObservers(&WebContentsObserver::MediaStoppedPlaying,
9036 media_info, id, reason);
billorr21c005d2016-11-17 03:57:049037}
9038
Mounir Lamouri0f5bdf52019-04-04 16:32:359039void WebContentsImpl::MediaResized(const gfx::Size& size,
9040 const MediaPlayerId& id) {
Alexander Timin5fdeff22020-09-08 09:20:379041 OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::MediaResized");
peconn257951522017-06-09 18:24:599042 cached_video_sizes_[id] = size;
9043
Andrew Grievee19cd93e2021-01-22 05:43:069044 observers_.NotifyObservers(&WebContentsObserver::MediaResized, size, id);
peconn257951522017-06-09 18:24:599045}
9046
Chris Hamiltonc347e102020-11-18 23:10:219047void WebContentsImpl::MediaEffectivelyFullscreenChanged(bool is_fullscreen) {
9048 OPTIONAL_TRACE_EVENT1("content",
9049 "WebContentsImpl::MediaEffectivelyFullscreenChanged",
9050 "is_fullscreen", is_fullscreen);
Andrew Grievee19cd93e2021-01-22 05:43:069051 observers_.NotifyObservers(
9052 &WebContentsObserver::MediaEffectivelyFullscreenChanged, is_fullscreen);
Chris Hamiltonc347e102020-11-18 23:10:219053}
9054
Chris Hamiltonc347e102020-11-18 23:10:219055void WebContentsImpl::MediaDestroyed(const MediaPlayerId& id) {
9056 OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::MediaDestroyed");
Andrew Grievee19cd93e2021-01-22 05:43:069057 observers_.NotifyObservers(&WebContentsObserver::MediaDestroyed, id);
Chris Hamiltonc347e102020-11-18 23:10:219058}
9059
9060int WebContentsImpl::GetCurrentlyPlayingVideoCount() {
9061 return currently_playing_video_count_;
Peter E Conneccb34c22017-09-08 09:37:589062}
9063
Anton Bikineevf62d1bf2021-05-15 17:56:079064absl::optional<gfx::Size> WebContentsImpl::GetFullscreenVideoSize() {
9065 absl::optional<MediaPlayerId> id =
Peter Conn31c726a2017-08-17 11:07:349066 media_web_contents_observer_->GetFullscreenVideoMediaPlayerId();
Jan Wilken Dörrie531be7ca2019-06-07 10:05:579067 if (id && base::Contains(cached_video_sizes_, id.value()))
Anton Bikineevf62d1bf2021-05-15 17:56:079068 return absl::optional<gfx::Size>(cached_video_sizes_[id.value()]);
9069 return absl::nullopt;
peconn257951522017-06-09 18:24:599070}
9071
Kevin McNeefb86fcf2021-02-26 23:20:579072void WebContentsImpl::AudioContextPlaybackStarted(RenderFrameHostImpl* host,
Raymond Toye413650c2018-08-31 00:12:479073 int context_id) {
Alexander Timinf785f342021-03-18 00:00:569074 OPTIONAL_TRACE_EVENT1("content",
9075 "WebContentsImpl::AudioContextPlaybackStarted",
9076 "render_frame_host", host);
Raymond Toye413650c2018-08-31 00:12:479077 WebContentsObserver::AudioContextId audio_context_id(host, context_id);
Andrew Grievee19cd93e2021-01-22 05:43:069078 observers_.NotifyObservers(&WebContentsObserver::AudioContextPlaybackStarted,
9079 audio_context_id);
Raymond Toye413650c2018-08-31 00:12:479080}
9081
Kevin McNeefb86fcf2021-02-26 23:20:579082void WebContentsImpl::AudioContextPlaybackStopped(RenderFrameHostImpl* host,
Raymond Toye413650c2018-08-31 00:12:479083 int context_id) {
Alexander Timinf785f342021-03-18 00:00:569084 OPTIONAL_TRACE_EVENT1("content",
9085 "WebContentsImpl::AudioContextPlaybackStopped",
9086 "render_frame_host", host);
Raymond Toye413650c2018-08-31 00:12:479087 WebContentsObserver::AudioContextId audio_context_id(host, context_id);
Andrew Grievee19cd93e2021-01-22 05:43:069088 observers_.NotifyObservers(&WebContentsObserver::AudioContextPlaybackStopped,
9089 audio_context_id);
Raymond Toye413650c2018-08-31 00:12:479090}
9091
Kevin McNeefb86fcf2021-02-26 23:20:579092void WebContentsImpl::OnFrameAudioStateChanged(RenderFrameHostImpl* host,
Chris Hamilton16ca64a2020-05-14 23:13:179093 bool is_audible) {
Alexander Timin5fdeff22020-09-08 09:20:379094 OPTIONAL_TRACE_EVENT2("content", "WebContentsImpl::OnFrameAudioStateChanged",
Alexander Timinf785f342021-03-18 00:00:569095 "render_frame_host", host, "is_audible", is_audible);
Andrew Grievee19cd93e2021-01-22 05:43:069096 observers_.NotifyObservers(&WebContentsObserver::OnFrameAudioStateChanged,
9097 host, is_audible);
Chris Hamilton16ca64a2020-05-14 23:13:179098}
9099
evliu7f736f02019-11-07 17:43:509100media::MediaMetricsProvider::RecordAggregateWatchTimeCallback
Minoru Chikamunea602642f2021-08-20 04:39:139101WebContentsImpl::GetRecordAggregateWatchTimeCallback(
9102 const GURL& page_main_frame_last_committed_url) {
Alexander Timin5fdeff22020-09-08 09:20:379103 OPTIONAL_TRACE_EVENT0("content",
9104 "WebContentsImpl::RecordAggregateWatchTimeCallback");
Becca Hughes53652442020-03-17 15:35:429105 if (!delegate_ || !delegate_->GetDelegateWeakPtr())
9106 return base::DoNothing();
9107
evliu7f736f02019-11-07 17:43:509108 return base::BindRepeating(
Minoru Chikamunea602642f2021-08-20 04:39:139109 [](base::WeakPtr<WebContentsDelegate> delegate,
9110 GURL page_main_frame_last_committed_url,
Becca Hughes53652442020-03-17 15:35:429111 base::TimeDelta total_watch_time, base::TimeDelta time_stamp,
9112 bool has_video, bool has_audio) {
evliua283c9e2019-11-08 22:57:229113 content::MediaPlayerWatchTime watch_time(
Minoru Chikamunea602642f2021-08-20 04:39:139114 page_main_frame_last_committed_url,
Mike West800532c2021-10-14 09:26:529115 page_main_frame_last_committed_url.DeprecatedGetOriginAsURL(),
9116 total_watch_time, time_stamp, has_video, has_audio);
evliu7f736f02019-11-07 17:43:509117
9118 // Save the watch time if the delegate is still alive.
9119 if (delegate)
9120 delegate->MediaWatchTimeChanged(watch_time);
9121 },
Minoru Chikamunea602642f2021-08-20 04:39:139122 delegate_->GetDelegateWeakPtr(), page_main_frame_last_committed_url);
evliu7f736f02019-11-07 17:43:509123}
9124
Kevin McNee5f594382021-05-06 23:18:239125std::vector<FrameTreeNode*> WebContentsImpl::GetUnattachedOwnedNodes(
9126 RenderFrameHostImpl* owner) {
9127 std::vector<FrameTreeNode*> unattached_owned_nodes;
9128 BrowserPluginGuestManager* guest_manager =
9129 GetBrowserContext()->GetGuestManager();
Dave Tapuska327c06c92022-06-13 20:31:519130 if (owner == GetPrimaryMainFrame() && guest_manager) {
Kevin McNee5f594382021-05-06 23:18:239131 guest_manager->ForEachUnattachedGuest(
9132 this, base::BindRepeating(
9133 [](std::vector<FrameTreeNode*>& unattached_owned_nodes,
9134 WebContents* guest_contents) {
9135 unattached_owned_nodes.push_back(
9136 static_cast<WebContentsImpl*>(guest_contents)
Carlos Caballerob65b6e3a2021-11-15 10:09:009137 ->primary_frame_tree_.root());
Kevin McNee5f594382021-05-06 23:18:239138 },
9139 std::ref(unattached_owned_nodes)));
9140 }
9141 // TODO(mcnee): Also include orphaned portals here.
9142 // See https://crbug.com/1196715
9143 return unattached_owned_nodes;
9144}
9145
Darwin Huang6195d042021-02-12 22:36:009146void WebContentsImpl::IsClipboardPasteContentAllowed(
Roger Tawa03ffdbd2020-01-16 18:12:549147 const GURL& url,
9148 const ui::ClipboardFormatType& data_type,
9149 const std::string& data,
Darwin Huang6195d042021-02-12 22:36:009150 IsClipboardPasteContentAllowedCallback callback) {
Dominique Fauteux-Chapleau99244382020-07-08 20:37:009151 ++suppress_unresponsive_renderer_count_;
Darwin Huang6195d042021-02-12 22:36:009152 GetContentClient()->browser()->IsClipboardPasteContentAllowed(
Dominique Fauteux-Chapleau99244382020-07-08 20:37:009153 this, url, data_type, data,
Darwin Huang6195d042021-02-12 22:36:009154 base::BindOnce(
9155 &WebContentsImpl::IsClipboardPasteContentAllowedWrapperCallback,
9156 weak_factory_.GetWeakPtr(), std::move(callback)));
Dominique Fauteux-Chapleau99244382020-07-08 20:37:009157}
9158
Darwin Huang6195d042021-02-12 22:36:009159void WebContentsImpl::IsClipboardPasteContentAllowedWrapperCallback(
9160 IsClipboardPasteContentAllowedCallback callback,
Roger Tawac6170262022-10-28 23:48:529161 const absl::optional<std::string>& data) {
9162 std::move(callback).Run(data);
Dominique Fauteux-Chapleau99244382020-07-08 20:37:009163 --suppress_unresponsive_renderer_count_;
Roger Tawa03ffdbd2020-01-16 18:12:549164}
9165
Robert Sesek5047c412021-08-09 17:36:189166void WebContentsImpl::BindScreenOrientation(
9167 RenderFrameHost* rfh,
9168 mojo::PendingAssociatedReceiver<device::mojom::ScreenOrientation>
9169 receiver) {
9170 screen_orientation_provider_->BindScreenOrientation(rfh, std::move(receiver));
9171}
9172
Lan Weif81c6e7c2020-02-12 16:46:099173bool WebContentsImpl::HasSeenRecentScreenOrientationChange() {
Peter Kastinge5a38ed2021-10-02 03:06:359174 static constexpr base::TimeDelta kMaxInterval = base::Seconds(1);
Lan Weif81c6e7c2020-02-12 16:46:099175 base::TimeDelta delta =
9176 ui::EventTimeForNow() - last_screen_orientation_change_time_;
Mike Wassermandb8f4f02020-10-06 01:18:379177 // Return whether a screen orientation change happened in the last 1 second.
Lan Weif81c6e7c2020-02-12 16:46:099178 return delta <= kMaxInterval;
9179}
9180
Mike Wassermandb8f4f02020-10-06 01:18:379181bool WebContentsImpl::IsTransientAllowFullscreenActive() const {
9182 return transient_allow_fullscreen_.IsActive();
9183}
9184
Dave Tapuskadfff7382021-04-23 19:46:419185bool WebContentsImpl::IsBackForwardCacheSupported() {
9186 if (!GetDelegate())
9187 return false;
9188 return GetDelegate()->IsBackForwardCacheSupported();
9189}
9190
Sreeja Kamishettyd64b993d2022-02-14 12:04:429191FrameTree* WebContentsImpl::LoadingTree() {
9192 return &GetPrimaryFrameTree();
9193}
9194
Lan Weif81c6e7c2020-02-12 16:46:099195void WebContentsImpl::DidChangeScreenOrientation() {
9196 last_screen_orientation_change_time_ = ui::EventTimeForNow();
9197}
9198
William Liucc35b315f2022-11-17 20:42:049199bool WebContentsImpl::ShowPopupMenu(RenderFrameHostImpl* render_frame_host,
9200 const gfx::Rect& bounds) {
Alexander Timin5fdeff22020-09-08 09:20:379201 OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::ShowPopupMenu",
Alexander Timinf785f342021-03-18 00:00:569202 "render_frame_host", render_frame_host);
Lingqi Chif8d423e2021-08-12 08:00:189203 DCHECK(render_frame_host->IsActive());
John Abd-El-Malek5b1d7252021-03-05 21:03:089204 if (show_poup_menu_callback_) {
9205 std::move(show_poup_menu_callback_).Run(bounds);
9206 return true;
Miyoung Shin4d947d22020-04-24 04:48:339207 }
9208 return false;
9209}
9210
Francois Doraye6161152018-03-27 22:05:379211void WebContentsImpl::UpdateWebContentsVisibility(Visibility visibility) {
Alexander Timin5fdeff22020-09-08 09:20:379212 OPTIONAL_TRACE_EVENT1("content",
9213 "WebContentsImpl::UpdateWebContentsVisibility",
9214 "visibility", visibility);
Francois Doray1d3372a2020-12-17 19:00:119215 // Occlusion is disabled when
Francois Doray3f2afbd2018-04-06 19:18:189216 // |switches::kDisableBackgroundingOccludedWindowsForTesting| is specified on
9217 // the command line (to avoid flakiness in browser tests).
9218 const bool occlusion_is_disabled =
Francois Doraye6161152018-03-27 22:05:379219 base::CommandLine::ForCurrentProcess()->HasSwitch(
9220 switches::kDisableBackgroundingOccludedWindowsForTesting);
9221 if (occlusion_is_disabled && visibility == Visibility::OCCLUDED)
9222 visibility = Visibility::VISIBLE;
9223
tapted65ff2ea72016-03-01 23:39:009224 if (!did_first_set_visible_) {
Francois Doraye6161152018-03-27 22:05:379225 if (visibility == Visibility::VISIBLE) {
9226 // A WebContents created with CreateParams::initially_hidden = false
9227 // starts with GetVisibility() == Visibility::VISIBLE even though it is
9228 // not really visible. Call WasShown() when it becomes visible for real as
9229 // the page load mechanism and some WebContentsObserver rely on that.
tapted65ff2ea72016-03-01 23:39:009230 WasShown();
Francois Dorayfe4a1772018-02-17 04:17:099231 did_first_set_visible_ = true;
tapted65ff2ea72016-03-01 23:39:009232 }
Francois Doraye6161152018-03-27 22:05:379233
9234 // Trust the initial visibility of the WebContents and do not switch it to
9235 // HIDDEN or OCCLUDED before it becomes VISIBLE for real. Doing so would
9236 // result in destroying resources that would immediately be recreated (e.g.
9237 // UpdateWebContents(HIDDEN) can be called when a WebContents is added to a
9238 // hidden window that is about to be shown).
9239
tapted65ff2ea72016-03-01 23:39:009240 return;
9241 }
Francois Doraye6161152018-03-27 22:05:379242
9243 if (visibility == visibility_)
tapted65ff2ea72016-03-01 23:39:009244 return;
9245
Collin Baker989e0882019-11-01 01:27:179246 UpdateVisibilityAndNotifyPageAndView(visibility);
tapted65ff2ea72016-03-01 23:39:009247}
9248
aelias5252baa2016-04-10 01:18:029249void WebContentsImpl::UpdateOverridingUserAgent() {
Alexander Timin5fdeff22020-09-08 09:20:379250 OPTIONAL_TRACE_EVENT0("content",
9251 "WebContentsImpl::UpdateOverridingUserAgent");
mlamouri5cd9ae82017-02-18 11:05:099252 NotifyPreferencesChanged();
aelias5252baa2016-04-10 01:18:029253}
9254
avid53461d2016-02-25 17:15:049255void WebContentsImpl::SetJavaScriptDialogManagerForTesting(
9256 JavaScriptDialogManager* dialog_manager) {
Alexander Timin5fdeff22020-09-08 09:20:379257 OPTIONAL_TRACE_EVENT0(
9258 "content", "WebContentsImpl::SetJavaScriptDialogManagerForTesting");
avid53461d2016-02-25 17:15:049259 dialog_manager_ = dialog_manager;
9260}
9261
Jeremy Romand597d3372021-07-09 23:36:569262void WebContentsImpl::ShowInsecureLocalhostWarningIfNeeded(PageImpl& page) {
Alexander Timin5fdeff22020-09-08 09:20:379263 OPTIONAL_TRACE_EVENT0(
9264 "content", "WebContentsImpl::ShowInsecureLocalhostWarningIfNeeded");
Jeremy Romand597d3372021-07-09 23:36:569265
falken52a56e32016-12-08 05:02:409266 bool allow_localhost = base::CommandLine::ForCurrentProcess()->HasSwitch(
9267 switches::kAllowInsecureLocalhost);
9268 if (!allow_localhost)
9269 return;
9270
Jeremy Romand597d3372021-07-09 23:36:569271 RenderFrameHostImpl& frame = page.GetMainDocument();
9272 NavigationEntry* entry =
9273 frame.frame_tree()->controller().GetLastCommittedEntry();
Rob Wuf79b3ba2018-01-14 01:54:319274 if (!entry || !net::IsLocalhost(entry->GetURL()))
falken52a56e32016-12-08 05:02:409275 return;
9276
Jeremy Romand597d3372021-07-09 23:36:569277 SSLStatus ssl_status = entry->GetSSL();
Matt Mueller936511442019-09-03 18:15:129278 if (!net::IsCertStatusError(ssl_status.cert_status))
falken52a56e32016-12-08 05:02:409279 return;
9280
Jeremy Romand597d3372021-07-09 23:36:569281 frame.AddMessageToConsole(blink::mojom::ConsoleMessageLevel::kWarning,
9282 "This site does not have a valid SSL "
9283 "certificate! Without SSL, your site's and "
9284 "visitors' data is vulnerable to theft and "
9285 "tampering. Get a valid SSL certificate before "
9286 " releasing your website to the public.");
falken52a56e32016-12-08 05:02:409287}
9288
ekaramadf6750aa2017-06-06 18:29:429289bool WebContentsImpl::IsShowingContextMenuOnPage() const {
9290 return showing_context_menu_;
9291}
9292
Min Qina904f3302018-02-13 23:33:349293download::DownloadUrlParameters::RequestHeadersType
9294WebContentsImpl::ParseDownloadHeaders(const std::string& headers) {
Alexander Timin5fdeff22020-09-08 09:20:379295 OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::ParseDownloadHeaders",
9296 "headers", headers);
Min Qina904f3302018-02-13 23:33:349297 download::DownloadUrlParameters::RequestHeadersType request_headers;
Megan Jablonski2f6a4c52017-07-10 23:01:259298 for (const base::StringPiece& key_value : base::SplitStringPiece(
9299 headers, "\r\n", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY)) {
9300 std::vector<std::string> pair = base::SplitString(
9301 key_value, ":", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
9302 if (2ul == pair.size())
9303 request_headers.push_back(make_pair(pair[0], pair[1]));
9304 }
9305 return request_headers;
9306}
9307
lukasza6f8ac622017-06-06 03:10:209308void WebContentsImpl::SetOpenerForNewContents(FrameTreeNode* opener,
9309 bool opener_suppressed) {
Alexander Timin5fdeff22020-09-08 09:20:379310 OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::SetOpenerForNewContents");
lukasza6f8ac622017-06-06 03:10:209311 if (opener) {
Carlos Caballero6a99dac2021-11-03 10:41:179312 FrameTreeNode* new_root = GetPrimaryFrameTree().root();
lukasza6f8ac622017-06-06 03:10:209313
9314 // For the "original opener", track the opener's main frame instead, because
9315 // if the opener is a subframe, the opener tracking could be easily bypassed
9316 // by spawning from a subframe and deleting the subframe.
9317 // https://crbug.com/705316
Arthur Sonzognif6785ec2022-12-05 10:11:509318 new_root->SetOriginalOpener(opener->frame_tree().root());
Danil Somsikov259aa65f2022-11-11 20:49:449319 new_root->SetOpenerDevtoolsFrameToken(
9320 opener->current_frame_host()->devtools_frame_token());
Rakina Zata Amnic7ffea882021-08-16 10:04:289321 opened_by_another_window_ = true;
lukasza6f8ac622017-06-06 03:10:209322
9323 if (!opener_suppressed) {
9324 new_root->SetOpener(opener);
lukasza6f8ac622017-06-06 03:10:209325 }
9326 }
9327}
9328
Mounir Lamouri0f5bdf52019-04-04 16:32:359329void WebContentsImpl::MediaMutedStatusChanged(const MediaPlayerId& id,
9330 bool muted) {
Alexander Timin5fdeff22020-09-08 09:20:379331 OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::MediaMutedStatusChanged",
9332 "muted", muted);
Andrew Grievee19cd93e2021-01-22 05:43:069333 observers_.NotifyObservers(&WebContentsObserver::MediaMutedStatusChanged, id,
9334 muted);
Becca Hughes9f6fd4b82017-06-15 10:01:409335}
9336
EhsanK2075c7e2017-08-21 02:42:399337void WebContentsImpl::SetVisibilityForChildViews(bool visible) {
Alexander Timin5fdeff22020-09-08 09:20:379338 OPTIONAL_TRACE_EVENT1("content",
9339 "WebContentsImpl::SetVisibilityForChildViews",
9340 "visible", visible);
Dave Tapuska327c06c92022-06-13 20:31:519341 GetPrimaryMainFrame()->SetVisibilityForChildViews(visible);
EhsanK2075c7e2017-08-21 02:42:399342}
9343
Alison Maher7f366dc62020-03-03 19:46:009344void WebContentsImpl::OnNativeThemeUpdated(ui::NativeTheme* observed_theme) {
Alexander Timin5fdeff22020-09-08 09:20:379345 OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::OnNativeThemeUpdated");
Sigurdur Asgeirsson103e2fb2020-11-10 00:50:169346 DCHECK(native_theme_observation_.IsObservingSource(observed_theme));
Alison Maher7f366dc62020-03-03 19:46:009347
9348 bool using_dark_colors = observed_theme->ShouldUseDarkColors();
9349 ui::NativeTheme::PreferredColorScheme preferred_color_scheme =
9350 observed_theme->GetPreferredColorScheme();
Alison Maher3b11e942020-10-27 17:17:509351 ui::NativeTheme::PreferredContrast preferred_contrast =
9352 observed_theme->GetPreferredContrast();
Alison Maher7f366dc62020-03-03 19:46:009353 bool preferences_changed = false;
9354
9355 if (using_dark_colors_ != using_dark_colors) {
9356 using_dark_colors_ = using_dark_colors;
9357 preferences_changed = true;
9358 }
9359 if (preferred_color_scheme_ != preferred_color_scheme) {
9360 preferred_color_scheme_ = preferred_color_scheme;
9361 preferences_changed = true;
9362 }
Alison Maher3b11e942020-10-27 17:17:509363 if (preferred_contrast_ != preferred_contrast) {
9364 preferred_contrast_ = preferred_contrast;
9365 preferences_changed = true;
9366 }
Alison Maher7f366dc62020-03-03 19:46:009367
9368 if (preferences_changed)
9369 NotifyPreferencesChanged();
9370}
9371
Abigail Klein08cfe3f2021-04-01 02:09:319372void WebContentsImpl::OnCaptionStyleUpdated() {
9373 NotifyPreferencesChanged();
9374}
9375
tom855c4bf32021-09-30 00:27:269376void WebContentsImpl::OnColorProviderChanged() {
tom083fe8992021-10-21 17:48:459377 // TODO(tluk): Currently changes to theme related web prefs are being
9378 // propagated in OnNativeThemeUpdated(). This logic should be moved here since
9379 // there are instances where the system theme may not change but clients
9380 // manually change the ColorProviderSource currently being observed by this
9381 // WebContents.
9382
9383 // OnColorProviderChanged() might have been triggered as the result of the
9384 // observed source being reset. If this is the case fallback to the default
9385 // source.
9386 if (!GetColorProviderSource()) {
9387 SetColorProviderSource(DefaultColorProviderSource::GetInstance());
9388 return;
9389 }
Tom Lukaszewicz22b784a42021-11-29 22:56:499390 observers_.NotifyObservers(&WebContentsObserver::OnColorProviderChanged);
tom855c4bf32021-09-30 00:27:269391}
9392
Tom Lukaszewicz63b3da52022-01-26 01:37:579393const ui::ColorProvider& WebContentsImpl::GetColorProvider() const {
tom083fe8992021-10-21 17:48:459394 auto* source = GetColorProviderSource();
9395 DCHECK(source);
Tom Lukaszewicz63b3da52022-01-26 01:37:579396 auto* color_provider = source->GetColorProvider();
9397 DCHECK(color_provider);
9398 return *color_provider;
tom855c4bf32021-09-30 00:27:269399}
9400
Dave Tapuska58a099e2020-06-08 21:48:409401blink::mojom::FrameWidgetInputHandler*
9402WebContentsImpl::GetFocusedFrameWidgetInputHandler() {
9403 auto* focused_render_widget_host =
Dave Tapuska327c06c92022-06-13 20:31:519404 GetFocusedRenderWidgetHost(GetPrimaryMainFrame()->GetRenderWidgetHost());
Dave Tapuska58a099e2020-06-08 21:48:409405 if (!focused_render_widget_host)
Dave Tapuskae782bea2019-07-09 16:21:519406 return nullptr;
Dave Tapuska58a099e2020-06-08 21:48:409407 return focused_render_widget_host->GetFrameWidgetInputHandler();
Dave Tapuskae782bea2019-07-09 16:21:519408}
9409
Alexander Timine3ec4192020-04-20 16:39:409410ukm::SourceId WebContentsImpl::GetCurrentPageUkmSourceId() {
Dave Tapuska327c06c92022-06-13 20:31:519411 return GetPrimaryMainFrame()->GetPageUkmSourceId();
Alexander Timine3ec4192020-04-20 16:39:409412}
9413
Dave Tapuska05fcfb62021-10-18 17:09:039414void WebContentsImpl::ForEachRenderViewHost(
9415 ForEachRenderViewHostTypes view_mask,
9416 RenderViewHostIterationCallback on_render_view_host) {
Yuzu Saijo232076f2020-05-29 07:14:029417 std::set<RenderViewHostImpl*> render_view_hosts;
9418
Dave Tapuska05fcfb62021-10-18 17:09:039419 if ((view_mask & (ForEachRenderViewHostTypes::kPrerenderViews |
9420 ForEachRenderViewHostTypes::kActiveViews)) != 0) {
9421 ForEachFrameTree(base::BindRepeating(
9422 [](ForEachRenderViewHostTypes view_mask,
9423 std::set<RenderViewHostImpl*>& render_view_hosts,
Arthur Sonzognif6785ec2022-12-05 10:11:509424 FrameTree& frame_tree) {
Dave Tapuska05fcfb62021-10-18 17:09:039425 // Check the view masks.
Arthur Sonzognif6785ec2022-12-05 10:11:509426 if (frame_tree.is_prerendering()) {
Dave Tapuska05fcfb62021-10-18 17:09:039427 // We are in a prerendering page.
9428 if ((view_mask & ForEachRenderViewHostTypes::kPrerenderViews) == 0)
9429 return;
9430 } else {
9431 // We are in an active page.
9432 if ((view_mask & ForEachRenderViewHostTypes::kActiveViews) == 0)
9433 return;
9434 }
Sharon Yanged884542023-02-02 17:33:449435 frame_tree.ForEachRenderViewHost(
9436 [&render_view_hosts](RenderViewHostImpl* rvh) {
9437 render_view_hosts.insert(rvh);
9438 });
Dave Tapuska05fcfb62021-10-18 17:09:039439 },
9440 view_mask, std::ref(render_view_hosts)));
Yuzu Saijo232076f2020-05-29 07:14:029441 }
9442
Dave Tapuska05fcfb62021-10-18 17:09:039443 if ((view_mask & ForEachRenderViewHostTypes::kBackForwardCacheViews) != 0) {
9444 // Add RenderViewHostImpls in BackForwardCache.
9445 const auto& entries = GetController().GetBackForwardCache().GetEntries();
9446 for (const auto& entry : entries) {
Dave Tapuskac3e58352022-09-28 19:05:279447 for (const auto& render_view : entry->render_view_hosts()) {
9448 render_view_hosts.insert(&*render_view);
9449 }
Dave Tapuska05fcfb62021-10-18 17:09:039450 }
Yuzu Saijo232076f2020-05-29 07:14:029451 }
9452
Dave Tapuska05fcfb62021-10-18 17:09:039453 for (auto* render_view_host : render_view_hosts)
9454 on_render_view_host.Run(render_view_host);
Yuzu Saijo232076f2020-05-29 07:14:029455}
9456
Julie Jeongeun Kimd4597df12022-11-11 02:44:519457void WebContentsImpl::NotifyPageBecamePrimary(PageImpl& page) {
Sreeja Kamishettya21b4f62021-06-25 07:48:259458 OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::PrimaryPageChanged");
9459
Sreeja Kamishetty53468972021-07-13 11:53:329460 DCHECK_EQ(&page, &GetPrimaryPage());
9461
Dave Tapuska765a2f62021-07-07 20:52:239462 // Clear |save_package_| since the primary page changed.
9463 if (save_package_) {
9464 save_package_->ClearPage();
9465 save_package_.reset();
9466 }
Sreeja Kamishetty53468972021-07-13 11:53:329467 observers_.NotifyObservers(&WebContentsObserver::PrimaryPageChanged, page);
Sreeja Kamishettya21b4f62021-06-25 07:48:259468}
9469
Dominic Farolinoedf44ee2021-07-20 23:50:599470int WebContentsImpl::GetOuterDelegateFrameTreeNodeId() {
9471 return node_.outer_contents_frame_tree_node_id();
9472}
9473
Sreeja Kamishettybe0ccd6b2020-06-09 11:52:509474void WebContentsImpl::RenderFrameHostStateChanged(
Sreeja Kamishetty2771b7d2021-04-07 06:34:189475 RenderFrameHost* render_frame_host,
9476 LifecycleState old_state,
9477 LifecycleState new_state) {
9478 DCHECK_NE(old_state, new_state);
Alexander Timinf785f342021-03-18 00:00:569479 OPTIONAL_TRACE_EVENT2("content",
9480 "WebContentsImpl::RenderFrameHostStateChanged",
9481 "render_frame_host", render_frame_host, "states",
9482 [&](perfetto::TracedValue context) {
9483 // TODO(crbug.com/1183371): Replace this with passing
9484 // more parameters to TRACE_EVENT directly when
9485 // available.
9486 auto dict = std::move(context).WriteDictionary();
9487 dict.Add("old", old_state);
9488 dict.Add("new", new_state);
9489 });
Sreeja Kamishettybe0ccd6b2020-06-09 11:52:509490
Tom Burgin732656d32022-02-07 18:33:269491#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_MAC)
Kevin McNee0c88f7af2021-04-30 15:17:249492 if (old_state == LifecycleState::kActive && !render_frame_host->GetParent()) {
Bo Liu2bceebc2021-06-03 15:06:339493 // TODO(sreejakshetty): Remove this reset when ColorChooserHolder becomes
Sreeja Kamishettybe0ccd6b2020-06-09 11:52:509494 // per-frame.
9495 // Close the color chooser popup when RenderFrameHost changes state from
9496 // kActive.
Bo Liu2bceebc2021-06-03 15:06:339497 color_chooser_holder_.reset();
Sreeja Kamishettybe0ccd6b2020-06-09 11:52:509498 }
Tom Burgin732656d32022-02-07 18:33:269499#endif // BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_MAC)
Sreeja Kamishetty2771b7d2021-04-07 06:34:189500
9501 observers_.NotifyObservers(&WebContentsObserver::RenderFrameHostStateChanged,
9502 render_frame_host, old_state, new_state);
Sreeja Kamishettybe0ccd6b2020-06-09 11:52:509503}
9504
Dale Curtis7030f252021-04-07 14:05:319505void WebContentsImpl::DecrementCapturerCount(bool stay_hidden,
Elad Alon0feb6602021-10-14 09:26:369506 bool stay_awake,
9507 bool is_activity) {
Dale Curtis7030f252021-04-07 14:05:319508 OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::DecrementCapturerCount");
9509 if (stay_hidden)
9510 --hidden_capturer_count_;
9511 else
9512 --visible_capturer_count_;
9513 if (stay_awake)
9514 --stay_awake_capturer_count_;
9515 DCHECK_GE(hidden_capturer_count_, 0);
9516 DCHECK_GE(visible_capturer_count_, 0);
9517 DCHECK_GE(stay_awake_capturer_count_, 0);
9518
Takashi Toyoshimaea534ef22021-07-21 03:27:599519 if (IsBeingDestroyed())
Dale Curtis7030f252021-04-07 14:05:319520 return;
9521
Scott Violet7f0b5c32021-11-04 03:06:229522 view_->OnCapturerCountChanged();
9523
Dale Curtis7030f252021-04-07 14:05:319524 const bool is_being_captured = IsBeingCaptured();
9525 if (!is_being_captured) {
9526 const gfx::Size old_size = preferred_size_for_capture_;
9527 preferred_size_for_capture_ = gfx::Size();
9528 OnPreferredSizeChanged(old_size);
9529 }
9530
9531 if (capture_wake_lock_ && (!is_being_captured || !stay_awake_capturer_count_))
9532 capture_wake_lock_->CancelWakeLock();
9533
Elad Alon0feb6602021-10-14 09:26:369534 UpdateVisibilityAndNotifyPageAndView(GetVisibility(), is_activity);
Dale Curtis7030f252021-04-07 14:05:319535}
9536
Khushalc5eaf222021-06-30 20:15:489537void WebContentsImpl::NotifyPrimaryMainFrameProcessIsAlive() {
9538 // The WebContents tracks the process state for the primary main frame's
9539 // renderer.
Mahesh Machavolu3c4b3112021-10-06 16:20:139540 // Consider renderer as terminated when exited with any termination status.
9541 bool was_renderer_terminated = primary_main_frame_process_status_ !=
9542 base::TERMINATION_STATUS_STILL_RUNNING;
Khushalc5eaf222021-06-30 20:15:489543 SetPrimaryMainFrameProcessStatus(base::TERMINATION_STATUS_STILL_RUNNING, 0);
9544 // Restore the focus to the tab (otherwise the focus will be on the top
9545 // window).
Mahesh Machavolu3c4b3112021-10-06 16:20:139546 if (was_renderer_terminated && !FocusLocationBarByDefault()) {
Khushalc5eaf222021-06-30 20:15:489547 if (!delegate_ || delegate_->ShouldFocusPageAfterCrash()) {
9548 view_->Focus();
9549 }
9550 }
9551}
9552
Yoshisato Yanagisawa607a7cca2021-10-14 02:45:369553void WebContentsImpl::UpdateBrowserControlsState(
9554 cc::BrowserControlsState constraints,
9555 cc::BrowserControlsState current,
9556 bool animate) {
9557 // Browser controls should be synchronised with the scroll state. Therefore,
9558 // they are controlled from the renderer by the main RenderFrame(Host).
Yoshisato Yanagisawad016d62d32021-10-15 04:38:559559 GetPrimaryPage().UpdateBrowserControlsState(constraints, current, animate);
Yoshisato Yanagisawa607a7cca2021-10-14 02:45:369560}
9561
Joe Mason7ae0e2b2021-11-01 12:30:369562void WebContentsImpl::SetTabSwitchStartTime(base::TimeTicks start_time,
9563 bool destination_is_loaded) {
Joe Mason4dc51d42022-12-17 00:00:149564 GetVisibleTimeRequestTrigger().UpdateRequest(
9565 start_time, destination_is_loaded,
9566 /*show_reason_tab_switching=*/true,
9567 /*show_reason_bfcache_restore=*/false);
Joe Mason7ae0e2b2021-11-01 12:30:369568}
9569
Joe Mason4dc51d42022-12-17 00:00:149570VisibleTimeRequestTrigger& WebContentsImpl::GetVisibleTimeRequestTrigger() {
9571 return visible_time_request_trigger_;
Joe Mason7ae0e2b2021-11-01 12:30:369572}
9573
Robert Linc37fb582021-11-11 03:18:479574std::unique_ptr<PrerenderHandle> WebContentsImpl::StartPrerendering(
Asami Doicf0f1642021-11-25 05:00:269575 const GURL& prerendering_url,
9576 PrerenderTriggerType trigger_type,
Robert Lin125720c042022-01-21 01:14:589577 const std::string& embedder_histogram_suffix,
Lingqi Chi21d9feb2022-02-02 09:42:189578 ui::PageTransition page_transition,
Sreeja Kamishettyac12140e2022-07-14 22:16:519579 PreloadingAttempt* preloading_attempt,
Lingqi Chi21d9feb2022-02-02 09:42:189580 absl::optional<base::RepeatingCallback<bool(const GURL&)>>
9581 url_match_predicate) {
Robert Linc37fb582021-11-11 03:18:479582 PrerenderAttributes attributes(
Asami Doicf0f1642021-11-25 05:00:269583 prerendering_url, trigger_type, embedder_histogram_suffix,
9584 content::Referrer(), /*initiator_origin=*/absl::nullopt, prerendering_url,
Hiroki Nakagawab930733e2023-01-04 16:40:529585 content::ChildProcessHost::kInvalidUniqueID, GetWeakPtr(),
Robert Lin286e2eb92022-05-10 23:41:539586 /*initiator_frame_token=*/absl::nullopt,
9587 /*initiator_frame_tree_node_id=*/RenderFrameHost::kNoFrameTreeNodeId,
9588 ukm::kInvalidSourceId, page_transition, url_match_predicate);
Sreeja Kamishettyac12140e2022-07-14 22:16:519589 int frame_tree_node_id = GetPrerenderHostRegistry()->CreateAndStartHost(
Hiroki Nakagawaa000bb82022-11-29 06:01:029590 attributes, preloading_attempt);
Robert Linc37fb582021-11-11 03:18:479591
9592 if (frame_tree_node_id != FrameTreeNode::kFrameTreeNodeInvalidId) {
9593 return std::make_unique<PrerenderHandleImpl>(
Robert Lin624a0fe2021-12-08 22:58:309594 GetPrerenderHostRegistry()->GetWeakPtr(), frame_tree_node_id,
9595 prerendering_url);
Robert Linc37fb582021-11-11 03:18:479596 }
9597 return nullptr;
9598}
9599
Anthony Vallee-Duboisaa026522022-12-07 17:24:289600void WebContentsImpl::AboutToBeDiscarded(WebContents* new_contents) {
9601 observers_.NotifyObservers(&WebContentsObserver::AboutToBeDiscarded,
9602 new_contents);
9603}
9604
Yoshiki Tanioka49b4cfb2022-10-20 09:25:319605bool WebContentsImpl::CancelPrerendering(FrameTreeNode* frame_tree_node,
9606 PrerenderFinalStatus final_status) {
Kevin McNeeab98c4a52022-01-28 16:53:069607 if (!frame_tree_node)
9608 return false;
9609
9610 DCHECK_EQ(this, FromFrameTreeNode(frame_tree_node));
9611
9612 // A prerendered page is identified by its root FrameTreeNode id, so if the
9613 // given `frame_tree_node` is in any way embedded, we need to iterate up to
9614 // the prerender root.
9615 if (frame_tree_node->GetParentOrOuterDocumentOrEmbedder()) {
9616 return frame_tree_node->GetParentOrOuterDocumentOrEmbedder()
Lingqi Chi8e192ba2022-11-22 04:34:259617 ->CancelPrerendering(PrerenderCancellationReason(final_status));
Kevin McNeeab98c4a52022-01-28 16:53:069618 }
9619 return GetPrerenderHostRegistry()->CancelHost(
9620 frame_tree_node->frame_tree_node_id(), final_status);
9621}
9622
David Bokand6e44055b2022-09-21 03:58:089623ui::mojom::VirtualKeyboardMode WebContentsImpl::GetVirtualKeyboardMode() const {
9624 return primary_frame_tree_.root()
9625 ->current_frame_host()
9626 ->GetPage()
9627 .virtual_keyboard_mode();
9628}
9629
Peter Kvitek965f3cd2022-01-06 22:33:419630// static
9631std::pair<int, int> WebContentsImpl::GetAvailablePointerAndHoverTypes() {
9632 // On Windows we have to temporarily allow blocking calls since
9633 // ui::GetAvailablePointerAndHoverTypes needs to call some in order to
9634 // figure out tablet device details in base::win::IsDeviceUsedAsATablet,
9635 // see https://crbug.com/1262162.
Xiaohan Wang24ec9342022-01-15 17:34:229636#if BUILDFLAG(IS_WIN)
Peter Kvitek965f3cd2022-01-06 22:33:419637 base::ScopedAllowBlocking scoped_allow_blocking;
9638#endif
9639 return ui::GetAvailablePointerAndHoverTypes();
9640}
9641
[email protected]8ff00d72012-10-23 19:12:219642} // namespace content