#include "content/renderer/render_frame_impl.h"
#include <map>
#include <memory>
#include <string>
#include <utility>
#include <vector>
#include "base/auto_reset.h"
#include "base/command_line.h"
#include "base/containers/flat_map.h"
#include "base/debug/alias.h"
#include "base/debug/asan_invalid_access.h"
#include "base/debug/crash_logging.h"
#include "base/debug/dump_without_crashing.h"
#include "base/feature_list.h"
#include "base/files/file.h"
#include "base/functional/bind.h"
#include "base/functional/callback_helpers.h"
#include "base/json/json_reader.h"
#include "base/json/json_writer.h"
#include "base/logging.h"
#include "base/memory/ptr_util.h"
#include "base/memory/weak_ptr.h"
#include "base/metrics/field_trial.h"
#include "base/metrics/field_trial_params.h"
#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
#include "base/observer_list.h"
#include "base/process/process.h"
#include "base/ranges/algorithm.h"
#include "base/run_loop.h"
#include "base/strings/strcat.h"
#include "base/strings/string_piece.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/task/single_thread_task_runner.h"
#include "base/task/thread_pool.h"
#include "base/time/time.h"
#include "base/trace_event/base_tracing.h"
#include "base/trace_event/trace_event.h"
#include "base/types/optional_util.h"
#include "base/unguessable_token.h"
#include "base/values.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
#include "cc/base/switches.h"
#include "cc/trees/ukm_manager.h"
#include "content/common/associated_interfaces.mojom.h"
#include "content/common/content_navigation_policy.h"
#include "content/common/content_switches_internal.h"
#include "content/common/debug_utils.h"
#include "content/common/features.h"
#include "content/common/frame.mojom.h"
#include "content/common/frame_messages.mojom.h"
#include "content/common/main_frame_counter.h"
#include "content/common/navigation_client.mojom.h"
#include "content/common/navigation_gesture.h"
#include "content/common/navigation_params_utils.h"
#include "content/common/renderer_host.mojom.h"
#include "content/common/web_package/signed_exchange_utils.h"
#include "content/public/common/bindings_policy.h"
#include "content/public/common/content_constants.h"
#include "content/public/common/content_features.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/extra_mojo_js_features.mojom.h"
#include "content/public/common/isolated_world_ids.h"
#include "content/public/common/url_constants.h"
#include "content/public/common/url_utils.h"
#include "content/public/renderer/content_renderer_client.h"
#include "content/public/renderer/render_frame_observer.h"
#include "content/public/renderer/render_frame_visitor.h"
#include "content/public/renderer/render_thread.h"
#include "content/public/renderer/renderer_ppapi_host.h"
#include "content/public/renderer/window_features_converter.h"
#include "content/renderer/accessibility/aom_content_ax_tree.h"
#include "content/renderer/accessibility/ax_tree_snapshotter_impl.h"
#include "content/renderer/accessibility/render_accessibility_impl.h"
#include "content/renderer/accessibility/render_accessibility_manager.h"
#include "content/renderer/agent_scheduling_group.h"
#include "content/renderer/content_security_policy_util.h"
#include "content/renderer/document_state.h"
#include "content/renderer/dom_automation_controller.h"
#include "content/renderer/effective_connection_type_helper.h"
#include "content/renderer/frame_owner_properties_converter.h"
#include "content/renderer/gpu_benchmarking_extension.h"
#include "content/renderer/media/media_permission_dispatcher.h"
#include "content/renderer/mhtml_handle_writer.h"
#include "content/renderer/mojo/blink_interface_registry_impl.h"
#include "content/renderer/navigation_client.h"
#include "content/renderer/navigation_state.h"
#include "content/renderer/pepper/pepper_audio_controller.h"
#include "content/renderer/policy_container_util.h"
#include "content/renderer/render_process.h"
#include "content/renderer/render_thread_impl.h"
#include "content/renderer/renderer_blink_platform_impl.h"
#include "content/renderer/service_worker/service_worker_network_provider_for_frame.h"
#include "content/renderer/service_worker/web_service_worker_provider_impl.h"
#include "content/renderer/skia_benchmarking_extension.h"
#include "content/renderer/stats_collection_controller.h"
#include "content/renderer/v8_value_converter_impl.h"
#include "content/renderer/web_ui_extension.h"
#include "content/renderer/web_ui_extension_data.h"
#include "content/renderer/worker/dedicated_worker_host_factory_client.h"
#include "crypto/sha2.h"
#include "ipc/ipc_message.h"
#include "media/mojo/mojom/audio_processing.mojom.h"
#include "mojo/public/cpp/bindings/pending_associated_receiver.h"
#include "mojo/public/cpp/bindings/pending_associated_remote.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "mojo/public/cpp/bindings/receiver.h"
#include "mojo/public/cpp/bindings/self_owned_receiver.h"
#include "net/base/data_url.h"
#include "net/base/load_flags.h"
#include "net/base/net_errors.h"
#include "net/base/registry_controlled_domains/registry_controlled_domain.h"
#include "net/http/http_request_headers.h"
#include "net/http/http_util.h"
#include "ppapi/buildflags/buildflags.h"
#include "services/metrics/public/cpp/ukm_source_id.h"
#include "services/network/public/cpp/features.h"
#include "services/network/public/cpp/not_implemented_url_loader_factory.h"
#include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h"
#include "services/network/public/mojom/fetch_api.mojom.h"
#include "services/network/public/mojom/restricted_cookie_manager.mojom.h"
#include "services/network/public/mojom/url_loader.mojom.h"
#include "services/network/public/mojom/url_response_head.mojom.h"
#include "services/service_manager/public/mojom/interface_provider.mojom.h"
#include "services/viz/public/cpp/gpu/context_provider_command_buffer.h"
#include "third_party/abseil-cpp/absl/types/optional.h"
#include "third_party/blink/public/common/action_after_pagehide.h"
#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
#include "third_party/blink/public/common/chrome_debug_urls.h"
#include "third_party/blink/public/common/context_menu_data/context_menu_data.h"
#include "third_party/blink/public/common/context_menu_data/untrustworthy_context_menu_params.h"
#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/common/input/web_keyboard_event.h"
#include "third_party/blink/public/common/interest_group/ad_auction_constants.h"
#include "third_party/blink/public/common/loader/loader_constants.h"
#include "third_party/blink/public/common/loader/record_load_histograms.h"
#include "third_party/blink/public/common/loader/resource_type_util.h"
#include "third_party/blink/public/common/loader/url_loader_throttle.h"
#include "third_party/blink/public/common/navigation/impression.h"
#include "third_party/blink/public/common/navigation/navigation_params_mojom_traits.h"
#include "third_party/blink/public/common/navigation/navigation_policy.h"
#include "third_party/blink/public/common/page_state/page_state.h"
#include "third_party/blink/public/common/permissions_policy/permissions_policy.h"
#include "third_party/blink/public/common/thread_safe_browser_interface_broker_proxy.h"
#include "third_party/blink/public/mojom/blob/blob.mojom.h"
#include "third_party/blink/public/mojom/blob/blob_url_store.mojom.h"
#include "third_party/blink/public/mojom/choosers/file_chooser.mojom.h"
#include "third_party/blink/public/mojom/dom_storage/storage_area.mojom.h"
#include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom.h"
#include "third_party/blink/public/mojom/frame/frame.mojom.h"
#include "third_party/blink/public/mojom/frame/frame_owner_properties.mojom.h"
#include "third_party/blink/public/mojom/frame/user_activation_notification_type.mojom.h"
#include "third_party/blink/public/mojom/frame/user_activation_update_types.mojom.h"
#include "third_party/blink/public/mojom/frame/view_transition_state.mojom.h"
#include "third_party/blink/public/mojom/input/focus_type.mojom.h"
#include "third_party/blink/public/mojom/input/input_handler.mojom-shared.h"
#include "third_party/blink/public/mojom/loader/referrer.mojom.h"
#include "third_party/blink/public/mojom/loader/request_context_frame_type.mojom.h"
#include "third_party/blink/public/mojom/loader/resource_cache.mojom.h"
#include "third_party/blink/public/mojom/loader/resource_load_info.mojom.h"
#include "third_party/blink/public/mojom/navigation/navigation_params.mojom.h"
#include "third_party/blink/public/mojom/page/widget.mojom.h"
#include "third_party/blink/public/mojom/permissions/permission.mojom.h"
#include "third_party/blink/public/mojom/render_accessibility.mojom.h"
#include "third_party/blink/public/mojom/renderer_preference_watcher.mojom.h"
#include "third_party/blink/public/mojom/widget/platform_widget.mojom.h"
#include "third_party/blink/public/platform/file_path_conversion.h"
#include "third_party/blink/public/platform/modules/service_worker/web_service_worker_network_provider.h"
#include "third_party/blink/public/platform/resource_load_info_notifier_wrapper.h"
#include "third_party/blink/public/platform/scheduler/web_agent_group_scheduler.h"
#include "third_party/blink/public/platform/tracked_child_url_loader_factory_bundle.h"
#include "third_party/blink/public/platform/url_conversion.h"
#include "third_party/blink/public/platform/weak_wrapper_resource_load_info_notifier.h"
#include "third_party/blink/public/platform/web_data.h"
#include "third_party/blink/public/platform/web_dedicated_or_shared_worker_fetch_context.h"
#include "third_party/blink/public/platform/web_http_body.h"
#include "third_party/blink/public/platform/web_media_player.h"
#include "third_party/blink/public/platform/web_media_player_source.h"
#include "third_party/blink/public/platform/web_navigation_body_loader.h"
#include "third_party/blink/public/platform/web_runtime_features.h"
#include "third_party/blink/public/platform/web_string.h"
#include "third_party/blink/public/platform/web_url.h"
#include "third_party/blink/public/platform/web_url_error.h"
#include "third_party/blink/public/platform/web_url_request_extra_data.h"
#include "third_party/blink/public/platform/web_url_request_util.h"
#include "third_party/blink/public/platform/web_url_response.h"
#include "third_party/blink/public/platform/web_vector.h"
#include "third_party/blink/public/web/blink.h"
#include "third_party/blink/public/web/modules/media/audio/audio_device_factory.h"
#include "third_party/blink/public/web/modules/media/audio/audio_output_ipc_factory.h"
#include "third_party/blink/public/web/modules/media/webmediaplayer_util.h"
#include "third_party/blink/public/web/modules/mediastream/web_media_stream_device_observer.h"
#include "third_party/blink/public/web/web_autofill_client.h"
#include "third_party/blink/public/web/web_console_message.h"
#include "third_party/blink/public/web/web_document.h"
#include "third_party/blink/public/web/web_element_collection.h"
#include "third_party/blink/public/web/web_frame_owner_properties.h"
#include "third_party/blink/public/web/web_frame_serializer.h"
#include "third_party/blink/public/web/web_frame_widget.h"
#include "third_party/blink/public/web/web_input_method_controller.h"
#include "third_party/blink/public/web/web_local_frame.h"
#include "third_party/blink/public/web/web_navigation_control.h"
#include "third_party/blink/public/web/web_navigation_policy.h"
#include "third_party/blink/public/web/web_navigation_timings.h"
#include "third_party/blink/public/web/web_navigation_type.h"
#include "third_party/blink/public/web/web_performance_metrics_for_nested_contexts.h"
#include "third_party/blink/public/web/web_picture_in_picture_window_options.h"
#include "third_party/blink/public/web/web_plugin.h"
#include "third_party/blink/public/web/web_plugin_container.h"
#include "third_party/blink/public/web/web_plugin_document.h"
#include "third_party/blink/public/web/web_plugin_params.h"
#include "third_party/blink/public/web/web_range.h"
#include "third_party/blink/public/web/web_remote_frame.h"
#include "third_party/blink/public/web/web_savable_resources_test_support.h"
#include "third_party/blink/public/web/web_script_source.h"
#include "third_party/blink/public/web/web_searchable_form_data.h"
#include "third_party/blink/public/web/web_security_policy.h"
#include "third_party/blink/public/web/web_serialized_script_value.h"
#include "third_party/blink/public/web/web_settings.h"
#include "third_party/blink/public/web/web_v8_features.h"
#include "third_party/blink/public/web/web_view.h"
#include "third_party/blink/public/web/web_widget.h"
#include "third_party/blink/public/web/web_window_features.h"
#include "ui/accessibility/ax_tree_update.h"
#include "ui/events/base_event_utils.h"
#include "url/origin.h"
#include "url/url_constants.h"
#include "url/url_util.h"
#include "v8/include/v8-isolate.h"
#include "v8/include/v8-local-handle.h"
#include "v8/include/v8-microtask-queue.h"
#if BUILDFLAG(ENABLE_PPAPI)
#include "content/renderer/pepper/pepper_browser_connection.h"
#include "content/renderer/pepper/pepper_plugin_instance_impl.h"
#include "content/renderer/pepper/pepper_plugin_registry.h"
#include "content/renderer/pepper/pepper_webplugin_impl.h"
#include "content/renderer/pepper/plugin_module.h"
#endif
#if BUILDFLAG(IS_ANDROID)
#include <cpu-features.h>
#include "content/renderer/java/gin_java_bridge_dispatcher.h"
#endif
#if BUILDFLAG(IS_OHOS)
#include "cef/libcef/renderer/javascript/oh_gin_javascript_bridge_dispatcher.h"
#endif
#ifdef OHOS_LOGGER_REPORT
#include "base/base_switches.h"
#include "base/command_line.h"
#include "url/ohos/log_utils.h"
#endif
using base::Time;
using blink::ContextMenuData;
using blink::WebContentDecryptionModule;
using blink::WebData;
using blink::WebDocument;
using blink::WebDocumentLoader;
using blink::WebDOMMessageEvent;
using blink::WebElement;
using blink::WebElementCollection;
using blink::WebFrame;
using blink::WebFrameLoadType;
using blink::WebFrameSerializer;
using blink::WebFrameSerializerClient;
using blink::WebHistoryItem;
using blink::WebHTTPBody;
using blink::WebLocalFrame;
using blink::WebMediaPlayer;
using blink::WebMediaPlayerClient;
using blink::WebMediaPlayerEncryptedMediaClient;
using blink::WebNavigationParams;
using blink::WebNavigationPolicy;
using blink::WebNavigationType;
using blink::WebNode;
using blink::WebPluginDocument;
using blink::WebPluginParams;
using blink::WebRange;
using blink::WebScriptSource;
using blink::WebSearchableFormData;
using blink::WebSecurityOrigin;
using blink::WebSecurityPolicy;
using blink::WebSerializedScriptValue;
using blink::WebServiceWorkerProvider;
using blink::WebSettings;
using blink::WebString;
using blink::WebThreadSafeData;
using blink::WebURL;
using blink::WebURLError;
using blink::WebURLRequest;
using blink::WebURLResponse;
using blink::WebVector;
using blink::WebView;
using blink::mojom::SelectionMenuBehavior;
using network::mojom::ReferrerPolicy;
namespace content {
namespace {
const int kExtraCharsBeforeAndAfterSelection = 100;
const size_t kMaxURLLogChars = 1024;
constexpr base::TimeDelta kDelaySecondsForContentStateSyncHidden =
base::Seconds(5);
constexpr base::TimeDelta kDelaySecondsForContentStateSync = base::Seconds(1);
typedef std::map<int, RenderFrameImpl*> RoutingIDFrameMap;
static base::LazyInstance<RoutingIDFrameMap>::DestructorAtExit
g_routing_id_frame_map = LAZY_INSTANCE_INITIALIZER;
typedef std::map<blink::WebFrame*, RenderFrameImpl*> FrameMap;
base::LazyInstance<FrameMap>::DestructorAtExit g_frame_map =
LAZY_INSTANCE_INITIALIZER;
int64_t ExtractPostId(const WebHistoryItem& item) {
if (item.IsNull() || item.HttpBody().IsNull())
return -1;
return item.HttpBody().Identifier();
}
std::string TrimURL(const std::string& url) {
if (url.length() <= kMaxURLLogChars)
return url;
return url.substr(0, kMaxURLLogChars - 3) + "...";
}
ui::PageTransition GetTransitionType(ui::PageTransition default_transition,
bool replaces_current_item,
bool is_main_frame,
bool is_in_fenced_frame_tree,
WebNavigationType navigation_type) {
if (is_in_fenced_frame_tree) {
return ui::PAGE_TRANSITION_AUTO_SUBFRAME;
}
if (replaces_current_item && !is_main_frame) {
return ui::PAGE_TRANSITION_AUTO_SUBFRAME;
}
bool is_form_submit =
navigation_type == blink::kWebNavigationTypeFormSubmitted ||
navigation_type == blink::kWebNavigationTypeFormResubmittedBackForward ||
navigation_type == blink::kWebNavigationTypeFormResubmittedReload;
if (ui::PageTransitionCoreTypeIs(default_transition,
ui::PAGE_TRANSITION_LINK) &&
is_form_submit) {
return ui::PAGE_TRANSITION_FORM_SUBMIT;
}
return default_transition;
}
ui::PageTransition GetTransitionType(blink::WebDocumentLoader* document_loader,
bool is_main_frame,
bool is_in_fenced_frame_tree) {
NavigationState* navigation_state =
DocumentState::FromDocumentLoader(document_loader)->navigation_state();
ui::PageTransition default_transition =
navigation_state->IsForSynchronousCommit()
? ui::PAGE_TRANSITION_LINK
: ui::PageTransitionFromInt(
navigation_state->common_params().transition);
if (!is_in_fenced_frame_tree && navigation_state->WasWithinSameDocument())
return default_transition;
return GetTransitionType(default_transition,
document_loader->ReplacesCurrentHistoryItem(),
is_main_frame, is_in_fenced_frame_tree,
document_loader->GetNavigationType());
}
bool MaybeGetOverriddenURL(WebDocumentLoader* document_loader, GURL* output) {
DocumentState* document_state =
DocumentState::FromDocumentLoader(document_loader);
if (document_state->was_load_data_with_base_url_request()) {
*output = document_state->data_url();
return true;
}
if (document_loader->HasUnreachableURL()) {
*output = document_loader->UnreachableWebURL();
return true;
}
return false;
}
bool IsTopLevelNavigation(WebFrame* frame) {
return frame->Parent() == nullptr && !frame->View()->IsFencedFrameRoot();
}
void FillNavigationParamsRequest(
const blink::mojom::CommonNavigationParams& common_params,
const blink::mojom::CommitNavigationParams& commit_params,
blink::WebNavigationParams* navigation_params) {
navigation_params->url = !commit_params.original_url.is_empty()
? commit_params.original_url
: common_params.url;
navigation_params->http_method = WebString::FromASCII(
!commit_params.original_method.empty() ? commit_params.original_method
: common_params.method);
if (common_params.referrer->url.is_valid()) {
WebString referrer = WebSecurityPolicy::GenerateReferrerHeader(
common_params.referrer->policy, common_params.url,
WebString::FromUTF8(common_params.referrer->url.spec()));
navigation_params->referrer = referrer;
navigation_params->referrer_policy = common_params.referrer->policy;
}
if (common_params.referrer->policy !=
network::mojom::ReferrerPolicy::kDefault) {
navigation_params->referrer_policy = common_params.referrer->policy;
}
if (common_params.post_data) {
navigation_params->http_body =
blink::GetWebHTTPBodyForRequestBody(*common_params.post_data);
if (!commit_params.post_content_type.empty()) {
navigation_params->http_content_type =
WebString::FromASCII(commit_params.post_content_type);
}
}
if (common_params.initiator_origin) {
navigation_params->requestor_origin =
common_params.initiator_origin.value();
}
navigation_params->initiator_origin_trial_features = {
common_params.initiator_origin_trial_features.begin(),
common_params.initiator_origin_trial_features.end()};
navigation_params->was_discarded = commit_params.was_discarded;
navigation_params->document_ukm_source_id =
commit_params.document_ukm_source_id;
if (!commit_params.prefetched_signed_exchanges.empty()) {
navigation_params->prefetched_signed_exchanges = WebVector<std::unique_ptr<
blink::WebNavigationParams::PrefetchedSignedExchange>>();
for (const auto& exchange : commit_params.prefetched_signed_exchanges) {
blink::WebURLResponse web_response = blink::WebURLResponse::Create(
exchange->inner_url, *exchange->inner_response,
false , -1 );
navigation_params->prefetched_signed_exchanges.emplace_back(
std::make_unique<
blink::WebNavigationParams::PrefetchedSignedExchange>(
exchange->outer_url,
WebString::FromLatin1(
signed_exchange_utils::CreateHeaderIntegrityHashString(
exchange->header_integrity)),
exchange->inner_url, web_response,
std::move(exchange->loader_factory_handle)));
}
}
navigation_params->had_transient_user_activation =
common_params.has_user_gesture;
WebVector<WebString> web_origin_trials;
web_origin_trials.reserve(commit_params.force_enabled_origin_trials.size());
for (const auto& trial : commit_params.force_enabled_origin_trials)
web_origin_trials.emplace_back(WebString::FromASCII(trial));
navigation_params->force_enabled_origin_trials = web_origin_trials;
if (!commit_params.early_hints_preloaded_resources.empty()) {
navigation_params->early_hints_preloaded_resources = WebVector<WebURL>();
for (const auto& resource : commit_params.early_hints_preloaded_resources) {
navigation_params->early_hints_preloaded_resources.emplace_back(resource);
}
}
if (blink::features::IsNewBaseUrlInheritanceBehaviorEnabled() &&
common_params.initiator_base_url) {
if (!common_params.url.IsAboutSrcdoc() &&
!common_params.url.IsAboutBlank()) {
SCOPED_CRASH_KEY_BOOL("new_base_url", "rfi_base_url_is_empty",
common_params.initiator_base_url->is_empty());
base::debug::DumpWithoutCrashing();
navigation_params->fallback_base_url = WebURL();
} else {
navigation_params->fallback_base_url =
common_params.initiator_base_url.value();
}
} else {
navigation_params->fallback_base_url = WebURL();
}
}
blink::mojom::CommonNavigationParamsPtr MakeCommonNavigationParams(
const WebSecurityOrigin& current_origin,
std::unique_ptr<blink::WebNavigationInfo> info,
int load_flags,
bool has_download_sandbox_flag,
bool from_ad,
bool is_history_navigation_in_new_child_frame,
network::mojom::RequestDestination request_destination) {
DCHECK(!info->url_request.RequestorOrigin().IsNull());
blink::mojom::ReferrerPtr referrer = blink::mojom::Referrer::New(
blink::WebStringToGURL(info->url_request.ReferrerString()),
info->url_request.GetReferrerPolicy());
DCHECK(info->navigation_type != blink::kWebNavigationTypeBackForward);
blink::mojom::NavigationType navigation_type =
blink::mojom::NavigationType::DIFFERENT_DOCUMENT;
if (info->navigation_type == blink::kWebNavigationTypeReload) {
if (load_flags & net::LOAD_BYPASS_CACHE)
navigation_type = blink::mojom::NavigationType::RELOAD_BYPASSING_CACHE;
else
navigation_type = blink::mojom::NavigationType::RELOAD;
}
auto source_location = network::mojom::SourceLocation::New(
info->source_location.url.Latin1(), info->source_location.line_number,
info->source_location.column_number);
const blink::WebURLRequestExtraData* url_request_extra_data =
static_cast<blink::WebURLRequestExtraData*>(
info->url_request.GetURLRequestExtraData().get());
DCHECK(url_request_extra_data);
std::vector<int> initiator_origin_trial_features(
info->initiator_origin_trial_features.begin(),
info->initiator_origin_trial_features.end());
blink::NavigationDownloadPolicy download_policy;
download_policy.ApplyDownloadFramePolicy(
info->is_opener_navigation, info->url_request.HasUserGesture(),
info->url_request.RequestorOrigin().CanAccess(current_origin),
has_download_sandbox_flag, from_ad);
absl::optional<GURL> initiator_base_url;
if (info->requestor_base_url.IsValid()) {
initiator_base_url = info->requestor_base_url;
}
return blink::mojom::CommonNavigationParams::New(
info->url_request.Url(), info->url_request.RequestorOrigin(),
initiator_base_url, std::move(referrer),
url_request_extra_data->transition_type(), navigation_type,
download_policy,
info->frame_load_type == WebFrameLoadType::kReplaceCurrentItem, GURL(),
base::TimeTicks::Now(), info->url_request.HttpMethod().Latin1(),
blink::GetRequestBodyForWebURLRequest(info->url_request),
std::move(source_location), false ,
info->url_request.HasUserGesture(),
info->url_request.HasTextFragmentToken(),
info->should_check_main_world_content_security_policy,
initiator_origin_trial_features, info->href_translate.Latin1(),
is_history_navigation_in_new_child_frame, info->input_start,
request_destination);
}
WebFrameLoadType NavigationTypeToLoadType(
blink::mojom::NavigationType navigation_type,
bool should_replace_current_entry) {
switch (navigation_type) {
case blink::mojom::NavigationType::RELOAD:
case blink::mojom::NavigationType::RELOAD_ORIGINAL_REQUEST_URL:
return WebFrameLoadType::kReload;
case blink::mojom::NavigationType::RELOAD_BYPASSING_CACHE:
return WebFrameLoadType::kReloadBypassingCache;
case blink::mojom::NavigationType::HISTORY_SAME_DOCUMENT:
case blink::mojom::NavigationType::HISTORY_DIFFERENT_DOCUMENT:
case blink::mojom::NavigationType::RESTORE:
case blink::mojom::NavigationType::RESTORE_WITH_POST:
return WebFrameLoadType::kBackForward;
case blink::mojom::NavigationType::SAME_DOCUMENT:
case blink::mojom::NavigationType::DIFFERENT_DOCUMENT:
return should_replace_current_entry
? WebFrameLoadType::kReplaceCurrentItem
: WebFrameLoadType::kStandard;
default:
NOTREACHED();
return WebFrameLoadType::kStandard;
}
}
RenderFrameImpl::CreateRenderFrameImplFunction g_create_render_frame_impl =
nullptr;
WebString ConvertRelativePathToHtmlAttribute(const base::FilePath& path) {
DCHECK(!path.IsAbsolute());
return WebString::FromUTF8(
std::string("./") +
path.NormalizePathSeparatorsTo(FILE_PATH_LITERAL('/')).AsUTF8Unsafe());
}
class RenderFrameWebFrameSerializerClient
: public blink::WebFrameSerializerClient {
public:
explicit RenderFrameWebFrameSerializerClient(
mojo::PendingRemote<mojom::FrameHTMLSerializerHandler> handler_remote)
: handler_remote_(std::move(handler_remote)) {}
void DidSerializeDataForFrame(
const WebVector<char>& data,
WebFrameSerializerClient::FrameSerializationStatus status) override {
DCHECK(handler_remote_.is_bound());
handler_remote_->DidReceiveData(std::string(data.data(), data.size()));
if (status == WebFrameSerializerClient::kCurrentFrameIsFinished) {
handler_remote_->Done();
handler_remote_.reset();
}
}
private:
mojo::Remote<mojom::FrameHTMLSerializerHandler> handler_remote_;
};
class LinkRewritingDelegate : public WebFrameSerializer::LinkRewritingDelegate {
public:
LinkRewritingDelegate(
const base::flat_map<GURL, base::FilePath>& url_to_local_path,
const base::flat_map<blink::FrameToken, base::FilePath>&
frame_token_to_local_path)
: url_to_local_path_(url_to_local_path),
frame_token_to_local_path_(frame_token_to_local_path) {}
bool RewriteFrameSource(WebFrame* frame, WebString* rewritten_link) override {
const blink::FrameToken frame_token = frame->GetFrameToken();
auto it = frame_token_to_local_path_.find(frame_token);
if (it == frame_token_to_local_path_.end())
return false;
const base::FilePath& local_path = it->second;
*rewritten_link = ConvertRelativePathToHtmlAttribute(local_path);
return true;
}
bool RewriteLink(const WebURL& url, WebString* rewritten_link) override {
auto it = url_to_local_path_.find(GURL(url));
if (it == url_to_local_path_.end())
return false;
const base::FilePath& local_path = it->second;
*rewritten_link = ConvertRelativePathToHtmlAttribute(local_path);
return true;
}
private:
const base::flat_map<GURL, base::FilePath>& url_to_local_path_;
const base::flat_map<blink::FrameToken, base::FilePath>&
frame_token_to_local_path_;
};
class MHTMLPartsGenerationDelegate
: public WebFrameSerializer::MHTMLPartsGenerationDelegate {
public:
MHTMLPartsGenerationDelegate(
const mojom::SerializeAsMHTMLParams& params,
std::unordered_set<std::string>* serialized_resources_uri_digests)
: params_(params),
serialized_resources_uri_digests_(serialized_resources_uri_digests) {
DCHECK(serialized_resources_uri_digests_);
DCHECK(std::is_sorted(params_.digests_of_uris_to_skip.begin(),
params_.digests_of_uris_to_skip.end()));
DCHECK(base::ranges::adjacent_find(params_.digests_of_uris_to_skip) ==
params_.digests_of_uris_to_skip.end());
}
MHTMLPartsGenerationDelegate(const MHTMLPartsGenerationDelegate&) = delete;
MHTMLPartsGenerationDelegate& operator=(const MHTMLPartsGenerationDelegate&) =
delete;
bool ShouldSkipResource(const WebURL& url) override {
std::string digest =
crypto::SHA256HashString(params_.salt + GURL(url).spec());
if (std::binary_search(params_.digests_of_uris_to_skip.begin(),
params_.digests_of_uris_to_skip.end(), digest))
return true;
auto pair = serialized_resources_uri_digests_->insert(digest);
bool insertion_took_place = pair.second;
DCHECK(insertion_took_place);
return false;
}
bool UseBinaryEncoding() override { return params_.mhtml_binary_encoding; }
bool RemovePopupOverlay() override {
return params_.mhtml_popup_overlay_removal;
}
private:
const mojom::SerializeAsMHTMLParams& params_;
std::unordered_set<std::string>* serialized_resources_uri_digests_;
};
bool IsHttpPost(const blink::WebURLRequest& request) {
return request.HttpMethod().Utf8() == "POST";
}
class MHTMLHandleWriterDelegate {
public:
MHTMLHandleWriterDelegate(
const mojom::SerializeAsMHTMLParams& params,
MHTMLHandleWriter::MHTMLWriteCompleteCallback callback,
scoped_refptr<base::TaskRunner> main_thread_task_runner) {
DCHECK(params.output_handle);
if (params.output_handle->is_file_handle()) {
handle_ = new MHTMLFileHandleWriter(
std::move(main_thread_task_runner), std::move(callback),
std::move(params.output_handle->get_file_handle()));
} else {
handle_ = new MHTMLProducerHandleWriter(
std::move(main_thread_task_runner), std::move(callback),
std::move(params.output_handle->get_producer_handle()));
}
}
MHTMLHandleWriterDelegate(const MHTMLHandleWriterDelegate&) = delete;
MHTMLHandleWriterDelegate& operator=(const MHTMLHandleWriterDelegate&) =
delete;
void WriteContents(std::vector<WebThreadSafeData> mhtml_contents) {
base::ThreadPool::PostTask(
FROM_HERE, {base::MayBlock()},
base::BindOnce(&MHTMLHandleWriter::WriteContents,
base::Unretained(handle_), std::move(mhtml_contents)));
}
void Finish(mojom::MhtmlSaveStatus save_status) {
base::ThreadPool::PostTask(
FROM_HERE, {base::MayBlock()},
base::BindOnce(&MHTMLHandleWriter::Finish, base::Unretained(handle_),
save_status));
}
private:
MHTMLHandleWriter* handle_;
};
mojo::PendingRemote<blink::mojom::BlobURLToken> CloneBlobURLToken(
blink::CrossVariantMojoRemote<blink::mojom::BlobURLTokenInterfaceBase>&
blob_url_token) {
if (!blob_url_token)
return mojo::NullRemote();
mojo::PendingRemote<blink::mojom::BlobURLToken> cloned_token;
mojo::Remote<blink::mojom::BlobURLToken> token(std::move(blob_url_token));
token->Clone(cloned_token.InitWithNewPipeAndPassReceiver());
blob_url_token = token.Unbind();
return cloned_token;
}
std::unique_ptr<DocumentState> BuildDocumentState() {
std::unique_ptr<DocumentState> document_state =
std::make_unique<DocumentState>();
document_state->set_navigation_state(
NavigationState::CreateForSynchronousCommit());
return document_state;
}
std::unique_ptr<DocumentState> BuildDocumentStateFromParams(
const blink::mojom::CommonNavigationParams& common_params,
const blink::mojom::CommitNavigationParams& commit_params,
mojom::NavigationClient::CommitNavigationCallback commit_callback,
std::unique_ptr<NavigationClient> navigation_client,
int request_id,
bool was_initiated_in_this_frame) {
std::unique_ptr<DocumentState> document_state(new DocumentState());
DCHECK(!common_params.navigation_start.is_null());
DCHECK(!common_params.url.SchemeIs(url::kJavaScriptScheme));
document_state->set_is_overriding_user_agent(
commit_params.is_overriding_user_agent);
document_state->set_must_reset_scroll_and_scale_state(
common_params.navigation_type ==
blink::mojom::NavigationType::RELOAD_ORIGINAL_REQUEST_URL);
document_state->set_request_id(request_id);
document_state->set_was_load_data_with_base_url_request(
commit_params.is_load_data_with_base_url);
if (commit_params.is_load_data_with_base_url)
document_state->set_data_url(common_params.url);
document_state->set_navigation_state(
NavigationState::CreateForCrossDocumentCommit(
common_params.Clone(), commit_params.Clone(),
std::move(commit_callback), std::move(navigation_client),
was_initiated_in_this_frame));
return document_state;
}
void ApplyFilePathAlias(blink::WebURLRequest* request) {
const base::CommandLine::StringType file_url_path_alias =
base::CommandLine::ForCurrentProcess()->GetSwitchValueNative(
switches::kFileUrlPathAlias);
if (file_url_path_alias.empty())
return;
const auto alias_mapping =
base::SplitString(file_url_path_alias, FILE_PATH_LITERAL("="),
base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
if (alias_mapping.size() != 2) {
LOG(ERROR) << "Invalid file path alias format.";
return;
}
#if BUILDFLAG(IS_WIN)
std::wstring path = base::UTF16ToWide(request->Url().GetString().Utf16());
const std::wstring file_prefix =
base::ASCIIToWide(url::kFileScheme) +
base::ASCIIToWide(url::kStandardSchemeSeparator);
#else
std::string path = request->Url().GetString().Utf8();
const std::string file_prefix =
std::string(url::kFileScheme) + url::kStandardSchemeSeparator;
#endif
if (!base::StartsWith(path, file_prefix + alias_mapping[0],
base::CompareCase::SENSITIVE)) {
return;
}
base::ReplaceFirstSubstringAfterOffset(&path, 0, alias_mapping[0],
alias_mapping[1]);
#if BUILDFLAG(IS_WIN)
request->SetUrl(blink::WebURL(GURL(base::WideToUTF8(path))));
#else
request->SetUrl(blink::WebURL(GURL(path)));
#endif
}
blink::WebNavigationTimings BuildNavigationTimings(
base::TimeTicks navigation_start,
const blink::mojom::NavigationTiming& browser_navigation_timings,
base::TimeTicks input_start) {
blink::WebNavigationTimings renderer_navigation_timings;
DCHECK(!navigation_start.is_null());
renderer_navigation_timings.navigation_start =
std::min(navigation_start, base::TimeTicks::Now());
renderer_navigation_timings.redirect_start =
browser_navigation_timings.redirect_start;
renderer_navigation_timings.redirect_end =
browser_navigation_timings.redirect_end;
renderer_navigation_timings.fetch_start =
browser_navigation_timings.fetch_start;
renderer_navigation_timings.input_start = input_start;
renderer_navigation_timings.parent_resource_timing_access =
browser_navigation_timings.parent_resource_timing_access;
return renderer_navigation_timings;
}
WebHistoryItem NavigationApiHistoryEntryPtrToWebHistoryItem(
const blink::mojom::NavigationApiHistoryEntry& entry) {
return WebHistoryItem(
WebString::FromUTF16(entry.url), WebString::FromUTF16(entry.key),
WebString::FromUTF16(entry.id), entry.item_sequence_number,
entry.document_sequence_number, WebString::FromUTF16(entry.state));
}
void FillMiscNavigationParams(
const blink::mojom::CommonNavigationParams& common_params,
const blink::mojom::CommitNavigationParams& commit_params,
blink::WebNavigationParams* navigation_params) {
navigation_params->navigation_timings = BuildNavigationTimings(
common_params.navigation_start, *commit_params.navigation_timing,
common_params.input_start);
navigation_params->is_user_activated =
commit_params.was_activated == blink::mojom::WasActivatedOption::kYes;
navigation_params->has_text_fragment_token =
common_params.text_fragment_token;
navigation_params->is_browser_initiated = commit_params.is_browser_initiated;
navigation_params->is_cross_site_cross_browsing_context_group =
commit_params.is_cross_site_cross_browsing_context_group;
navigation_params->should_have_sticky_user_activation =
commit_params.should_have_sticky_user_activation;
#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_OHOS)
navigation_params->grant_load_local_resources =
commit_params.can_load_local_resources;
#else
DCHECK(!commit_params.can_load_local_resources);
#endif
if (commit_params.origin_to_commit) {
navigation_params->origin_to_commit =
commit_params.origin_to_commit.value();
}
navigation_params->storage_key = std::move(commit_params.storage_key);
navigation_params->session_storage_key =
std::move(commit_params.session_storage_key);
navigation_params->frame_policy = commit_params.frame_policy;
if (common_params.navigation_type == blink::mojom::NavigationType::RESTORE) {
navigation_params->force_fetch_cache_mode =
blink::mojom::FetchCacheMode::kDefault;
}
navigation_params->origin_agent_cluster = commit_params.origin_agent_cluster;
navigation_params->origin_agent_cluster_left_as_default =
commit_params.origin_agent_cluster_left_as_default;
navigation_params->reduced_accept_language =
WebString::FromASCII(commit_params.reduced_accept_language);
navigation_params->enabled_client_hints.reserve(
commit_params.enabled_client_hints.size());
for (auto enabled_hint : commit_params.enabled_client_hints)
navigation_params->enabled_client_hints.emplace_back(enabled_hint);
if (commit_params.http_response_code != -1)
navigation_params->http_status_code = commit_params.http_response_code;
navigation_params->modified_runtime_features =
commit_params.modified_runtime_features;
auto& entry_arrays = commit_params.navigation_api_history_entry_arrays;
navigation_params->navigation_api_back_entries.reserve(
entry_arrays->back_entries.size());
for (const auto& entry : entry_arrays->back_entries) {
navigation_params->navigation_api_back_entries.emplace_back(
NavigationApiHistoryEntryPtrToWebHistoryItem(*entry));
}
navigation_params->navigation_api_forward_entries.reserve(
entry_arrays->forward_entries.size());
for (const auto& entry : entry_arrays->forward_entries) {
navigation_params->navigation_api_forward_entries.emplace_back(
NavigationApiHistoryEntryPtrToWebHistoryItem(*entry));
}
if (commit_params.fenced_frame_properties) {
navigation_params->fenced_frame_properties =
commit_params.fenced_frame_properties;
if (commit_params.fenced_frame_properties->nested_urn_config_pairs() &&
commit_params.fenced_frame_properties->nested_urn_config_pairs()
->potentially_opaque_value.has_value()) {
const auto& nested_urn_config_pairs_value =
commit_params.fenced_frame_properties->nested_urn_config_pairs()
->potentially_opaque_value.value();
DCHECK_EQ(blink::kMaxAdAuctionAdComponents,
nested_urn_config_pairs_value.size());
navigation_params->ad_auction_components.emplace();
for (const auto& nested_urn_config_pair : nested_urn_config_pairs_value) {
const GURL& urn = nested_urn_config_pair.first;
DCHECK(urn.SchemeIs(url::kUrnScheme));
navigation_params->ad_auction_components->push_back(blink::WebURL(urn));
}
}
}
navigation_params->ancestor_or_self_has_cspee =
commit_params.ancestor_or_self_has_cspee;
}
std::string GetUniqueNameOfWebFrame(WebFrame* web_frame) {
if (web_frame->IsWebLocalFrame())
return RenderFrameImpl::FromWebFrame(web_frame)->unique_name();
return web_frame->ToWebRemoteFrame()->UniqueName().Utf8();
}
perfetto::protos::pbzero::FrameDeleteIntention FrameDeleteIntentionToProto(
mojom::FrameDeleteIntention intent) {
using ProtoLevel = perfetto::protos::pbzero::FrameDeleteIntention;
switch (intent) {
case mojom::FrameDeleteIntention::kNotMainFrame:
return ProtoLevel::FRAME_DELETE_INTENTION_NOT_MAIN_FRAME;
case mojom::FrameDeleteIntention::kSpeculativeMainFrameForShutdown:
return ProtoLevel::
FRAME_DELETE_INTENTION_SPECULATIVE_MAIN_FRAME_FOR_SHUTDOWN;
case mojom::FrameDeleteIntention::
kSpeculativeMainFrameForNavigationCancelled:
return ProtoLevel::
FRAME_DELETE_INTENTION_SPECULATIVE_MAIN_FRAME_FOR_NAVIGATION_CANCELLED;
}
NOTREACHED();
return ProtoLevel::FRAME_DELETE_INTENTION_NOT_MAIN_FRAME;
}
void PropagatePageZoomToNewlyAttachedFrame(blink::WebView* web_view,
float device_scale_factor) {
web_view->SetZoomFactorForDeviceScaleFactor(device_scale_factor);
}
void CallClientDeferMediaLoad(base::WeakPtr<RenderFrameImpl> frame,
bool has_played_media_before,
base::OnceClosure closure) {
if (!frame)
return;
GetContentClient()->renderer()->DeferMediaLoad(
frame.get(), has_played_media_before, std::move(closure));
}
void LogCommitHistograms(base::TimeTicks commit_sent, bool is_main_frame) {
if (!base::TimeTicks::IsConsistentAcrossProcesses())
return;
const char* frame_type = is_main_frame ? "MainFrame" : "Subframe";
auto now = base::TimeTicks::Now();
base::UmaHistogramTimes(
base::StrCat({"Navigation.RendererCommitDelay.", frame_type}),
now - commit_sent);
if (auto* task = base::TaskAnnotator::CurrentTaskForThread()) {
base::UmaHistogramTimes(
base::StrCat({"Navigation.RendererCommitQueueTime.", frame_type}),
now - task->queue_time);
}
if (!RenderThreadImpl::current())
return;
base::TimeTicks run_loop_start_time =
RenderThreadImpl::current()->run_loop_start_time();
if (commit_sent < run_loop_start_time) {
base::UmaHistogramTimes(
base::StrCat({"Navigation.RendererCommitProcessWaitTime.", frame_type}),
run_loop_start_time - commit_sent);
}
}
content::mojom::WindowContainerType WindowFeaturesToContainerType(
const blink::WebWindowFeatures& window_features) {
if (window_features.background) {
if (window_features.persistent)
return content::mojom::WindowContainerType::PERSISTENT;
else
return content::mojom::WindowContainerType::BACKGROUND;
} else {
return content::mojom::WindowContainerType::NORMAL;
}
}
WindowOpenDisposition NavigationPolicyToDisposition(
WebNavigationPolicy policy) {
switch (policy) {
case blink::kWebNavigationPolicyDownload:
return WindowOpenDisposition::SAVE_TO_DISK;
case blink::kWebNavigationPolicyCurrentTab:
return WindowOpenDisposition::CURRENT_TAB;
case blink::kWebNavigationPolicyNewBackgroundTab:
return WindowOpenDisposition::NEW_BACKGROUND_TAB;
case blink::kWebNavigationPolicyNewForegroundTab:
return WindowOpenDisposition::NEW_FOREGROUND_TAB;
case blink::kWebNavigationPolicyNewWindow:
return WindowOpenDisposition::NEW_WINDOW;
case blink::kWebNavigationPolicyNewPopup:
return WindowOpenDisposition::NEW_POPUP;
case blink::kWebNavigationPolicyPictureInPicture:
return WindowOpenDisposition::NEW_PICTURE_IN_PICTURE;
}
NOTREACHED() << "Unexpected WebNavigationPolicy";
return WindowOpenDisposition::IGNORE_ACTION;
}
}
RenderFrameImpl::AssertNavigationCommits::AssertNavigationCommits(
RenderFrameImpl* frame)
: AssertNavigationCommits(frame, false) {}
RenderFrameImpl::AssertNavigationCommits::AssertNavigationCommits(
RenderFrameImpl* frame,
MayReplaceInitialEmptyDocumentTag)
: AssertNavigationCommits(frame, true) {}
RenderFrameImpl::AssertNavigationCommits::~AssertNavigationCommits() {
if (frame_) {
CHECK_EQ(NavigationCommitState::kDidCommit,
frame_->navigation_commit_state_);
frame_->navigation_commit_state_ = NavigationCommitState::kNone;
}
}
RenderFrameImpl::AssertNavigationCommits::AssertNavigationCommits(
RenderFrameImpl* frame,
bool allow_transition_from_initial_empty_document)
: frame_(frame->weak_factory_.GetWeakPtr()) {
if (NavigationCommitState::kNone != frame->navigation_commit_state_) {
CHECK(allow_transition_from_initial_empty_document);
CHECK_EQ(NavigationCommitState::kInitialEmptyDocument,
frame->navigation_commit_state_);
}
frame->navigation_commit_state_ = NavigationCommitState::kWillCommit;
}
class RenderFrameImpl::MHTMLBodyLoaderClient
: public blink::WebNavigationBodyLoader::Client {
public:
MHTMLBodyLoaderClient(
RenderFrameImpl* frame,
std::unique_ptr<blink::WebNavigationParams> navigation_params,
base::OnceCallback<void(std::unique_ptr<blink::WebNavigationParams>)>
done_callback)
: frame_(frame),
navigation_params_(std::move(navigation_params)),
body_loader_(std::move(navigation_params_->body_loader)),
done_callback_(std::move(done_callback)) {
body_loader_->StartLoadingBody(this);
}
MHTMLBodyLoaderClient(const MHTMLBodyLoaderClient&) = delete;
MHTMLBodyLoaderClient& operator=(const MHTMLBodyLoaderClient&) = delete;
~MHTMLBodyLoaderClient() override {
CHECK(
committing_ ||
!frame_ ||
NavigationCommitState::kWillCommit == frame_->navigation_commit_state_);
}
void Detach() {
frame_ = nullptr;
}
void BodyDataReceived(base::span<const char> data) override {
data_.Append(data.data(), data.size());
}
void BodyLoadingFinished(base::TimeTicks completion_time,
int64_t total_encoded_data_length,
int64_t total_encoded_body_length,
int64_t total_decoded_body_length,
bool should_report_corb_blocking,
const absl::optional<WebURLError>& error) override {
committing_ = true;
AssertNavigationCommits assert_navigation_commits(frame_);
if (!error.has_value()) {
WebNavigationParams::FillBodyLoader(navigation_params_.get(), data_);
navigation_params_->is_static_data = false;
}
std::move(done_callback_).Run(std::move(navigation_params_));
}
private:
RenderFrameImpl* frame_;
bool committing_ = false;
WebData data_;
std::unique_ptr<blink::WebNavigationParams> navigation_params_;
std::unique_ptr<blink::WebNavigationBodyLoader> body_loader_;
base::OnceCallback<void(std::unique_ptr<blink::WebNavigationParams>)>
done_callback_;
};
RenderFrameImpl::UniqueNameFrameAdapter::UniqueNameFrameAdapter(
RenderFrameImpl* render_frame)
: render_frame_(render_frame) {}
RenderFrameImpl::UniqueNameFrameAdapter::~UniqueNameFrameAdapter() {}
bool RenderFrameImpl::UniqueNameFrameAdapter::IsMainFrame() const {
return render_frame_->IsMainFrame();
}
bool RenderFrameImpl::UniqueNameFrameAdapter::IsCandidateUnique(
base::StringPiece name) const {
DCHECK(!name.empty());
for (blink::WebFrame* frame = GetWebFrame()->Top(); frame;
frame = frame->TraverseNext()) {
if (GetUniqueNameOfWebFrame(frame) == name)
return false;
}
return true;
}
int RenderFrameImpl::UniqueNameFrameAdapter::GetSiblingCount() const {
int sibling_count = 0;
for (blink::WebFrame* frame = GetWebFrame()->Parent()->FirstChild(); frame;
frame = frame->NextSibling()) {
if (frame == GetWebFrame())
continue;
++sibling_count;
}
return sibling_count;
}
int RenderFrameImpl::UniqueNameFrameAdapter::GetChildCount() const {
int child_count = 0;
for (blink::WebFrame* frame = GetWebFrame()->FirstChild(); frame;
frame = frame->NextSibling()) {
++child_count;
}
return child_count;
}
std::vector<std::string>
RenderFrameImpl::UniqueNameFrameAdapter::CollectAncestorNames(
BeginPoint begin_point,
bool (*should_stop)(base::StringPiece)) const {
std::vector<std::string> result;
for (blink::WebFrame* frame = begin_point == BeginPoint::kParentFrame
? GetWebFrame()->Parent()
: GetWebFrame();
frame; frame = frame->Parent()) {
result.push_back(GetUniqueNameOfWebFrame(frame));
if (should_stop(result.back()))
break;
}
return result;
}
std::vector<int> RenderFrameImpl::UniqueNameFrameAdapter::GetFramePosition(
BeginPoint begin_point) const {
std::vector<int> result;
blink::WebFrame* parent = begin_point == BeginPoint::kParentFrame
? GetWebFrame()->Parent()
: GetWebFrame();
blink::WebFrame* child =
begin_point == BeginPoint::kParentFrame ? GetWebFrame() : nullptr;
while (parent) {
int position_in_parent = 0;
blink::WebFrame* sibling = parent->FirstChild();
while (sibling != child) {
sibling = sibling->NextSibling();
++position_in_parent;
}
result.push_back(position_in_parent);
child = parent;
parent = parent->Parent();
}
return result;
}
blink::WebLocalFrame* RenderFrameImpl::UniqueNameFrameAdapter::GetWebFrame()
const {
return render_frame_->frame_;
}
RenderFrameImpl* RenderFrameImpl::Create(
AgentSchedulingGroup& agent_scheduling_group,
int32_t routing_id,
mojo::PendingAssociatedReceiver<mojom::Frame> frame_receiver,
mojo::PendingRemote<blink::mojom::BrowserInterfaceBroker>
browser_interface_broker,
mojo::PendingAssociatedRemote<blink::mojom::AssociatedInterfaceProvider>
associated_interface_provider,
const base::UnguessableToken& devtools_frame_token) {
DCHECK(routing_id != MSG_ROUTING_NONE);
CreateParams params(
agent_scheduling_group, routing_id, std::move(frame_receiver),
std::move(browser_interface_broker),
std::move(associated_interface_provider), devtools_frame_token);
if (g_create_render_frame_impl)
return g_create_render_frame_impl(std::move(params));
else
return new RenderFrameImpl(std::move(params));
}
RenderFrame* RenderFrame::FromRoutingID(int routing_id) {
return RenderFrameImpl::FromRoutingID(routing_id);
}
RenderFrameImpl* RenderFrameImpl::FromRoutingID(int routing_id) {
DCHECK(RenderThread::IsMainThread());
auto iter = g_routing_id_frame_map.Get().find(routing_id);
if (iter != g_routing_id_frame_map.Get().end())
return iter->second;
return nullptr;
}
RenderFrameImpl* RenderFrameImpl::CreateMainFrame(
AgentSchedulingGroup& agent_scheduling_group,
blink::WebView* web_view,
blink::WebFrame* opener,
bool is_for_nested_main_frame,
bool is_for_scalable_page,
blink::mojom::FrameReplicationStatePtr replication_state,
const base::UnguessableToken& devtools_frame_token,
mojom::CreateLocalMainFrameParamsPtr params,
const blink::WebURL& base_url) {
DCHECK_NE(MSG_ROUTING_NONE, params->widget_params->routing_id);
RenderFrameImpl* render_frame = RenderFrameImpl::Create(
agent_scheduling_group, params->routing_id, std::move(params->frame),
std::move(params->interface_broker),
std::move(params->associated_interface_provider_remote),
devtools_frame_token);
WebLocalFrame* web_frame = WebLocalFrame::CreateMainFrame(
web_view, render_frame, render_frame->blink_interface_registry_.get(),
params->frame_token, params->document_token,
ToWebPolicyContainer(std::move(params->policy_container)), opener,
WebString::FromUTF8(replication_state->name),
replication_state->frame_policy.sandbox_flags, base_url);
if (!params->is_on_initial_empty_document)
render_frame->frame_->SetIsNotOnInitialEmptyDocument();
blink::WebFrameWidget* web_frame_widget = web_frame->InitializeFrameWidget(
std::move(params->widget_params->frame_widget_host),
std::move(params->widget_params->frame_widget),
std::move(params->widget_params->widget_host),
std::move(params->widget_params->widget),
viz::FrameSinkId(RenderThread::Get()->GetClientId(),
params->widget_params->routing_id),
is_for_nested_main_frame, is_for_scalable_page,
true);
web_frame_widget->InitializeCompositing(
params->widget_params->visual_properties.screen_infos,
nullptr);
render_frame->GetWebView()->DidAttachLocalMainFrame();
web_frame_widget->ApplyVisualProperties(
params->widget_params->visual_properties);
render_frame->in_frame_tree_ = true;
render_frame->Initialize(nullptr);
if (params->subresource_loader_factories
->IsTrackedChildPendingURLLoaderFactoryBundle()) {
render_frame->loader_factories_ =
base::MakeRefCounted<blink::TrackedChildURLLoaderFactoryBundle>(
base::WrapUnique(
static_cast<blink::TrackedChildPendingURLLoaderFactoryBundle*>(
params->subresource_loader_factories.release())));
} else {
render_frame->loader_factories_ = render_frame->CreateLoaderFactoryBundle(
std::move(params->subresource_loader_factories),
absl::nullopt,
mojo::NullRemote(),
mojo::NullRemote(),
mojo::NullRemote());
}
return render_frame;
}
void RenderFrameImpl::CreateFrame(
AgentSchedulingGroup& agent_scheduling_group,
const blink::LocalFrameToken& frame_token,
int routing_id,
mojo::PendingAssociatedReceiver<mojom::Frame> frame_receiver,
mojo::PendingRemote<blink::mojom::BrowserInterfaceBroker>
browser_interface_broker,
mojo::PendingAssociatedRemote<blink::mojom::AssociatedInterfaceProvider>
associated_interface_provider,
blink::WebView* web_view,
const absl::optional<blink::FrameToken>& previous_frame_token,
const absl::optional<blink::FrameToken>& opener_frame_token,
const absl::optional<blink::FrameToken>& parent_frame_token,
const absl::optional<blink::FrameToken>& previous_sibling_frame_token,
const base::UnguessableToken& devtools_frame_token,
blink::mojom::TreeScopeType tree_scope_type,
blink::mojom::FrameReplicationStatePtr replicated_state,
mojom::CreateFrameWidgetParamsPtr widget_params,
blink::mojom::FrameOwnerPropertiesPtr frame_owner_properties,
bool is_on_initial_empty_document,
const blink::DocumentToken& document_token,
blink::mojom::PolicyContainerPtr policy_container) {
RenderFrameImpl* render_frame = nullptr;
blink::WebLocalFrame* web_frame = nullptr;
if (!previous_frame_token) {
CHECK(parent_frame_token);
WebFrame* parent_web_frame =
WebFrame::FromFrameToken(parent_frame_token.value());
CHECK(parent_web_frame);
CHECK(parent_web_frame->IsWebRemoteFrame());
blink::WebFrame* previous_sibling_web_frame = nullptr;
if (previous_sibling_frame_token) {
previous_sibling_web_frame =
blink::WebFrame::FromFrameToken(previous_sibling_frame_token.value());
}
CHECK(!web_view);
web_view = parent_web_frame->View();
render_frame = RenderFrameImpl::Create(
agent_scheduling_group, routing_id, std::move(frame_receiver),
std::move(browser_interface_broker),
std::move(associated_interface_provider), devtools_frame_token);
render_frame->unique_name_helper_.set_propagated_name(
replicated_state->unique_name);
WebFrame* opener = nullptr;
if (opener_frame_token)
opener = WebFrame::FromFrameToken(opener_frame_token.value());
web_frame = parent_web_frame->ToWebRemoteFrame()->CreateLocalChild(
tree_scope_type, WebString::FromUTF8(replicated_state->name),
replicated_state->frame_policy, render_frame,
render_frame->blink_interface_registry_.get(),
previous_sibling_web_frame,
frame_owner_properties->To<blink::WebFrameOwnerProperties>(),
frame_token, opener, document_token,
ToWebPolicyContainer(std::move(policy_container)));
render_frame->in_frame_tree_ = true;
} else {
WebFrame* previous_web_frame =
WebFrame::FromFrameToken(previous_frame_token.value());
if (!previous_web_frame)
return;
if (web_view) {
CHECK(!previous_web_frame->Parent());
CHECK_NE(web_view, previous_web_frame->View());
} else {
web_view = previous_web_frame->View();
}
render_frame = RenderFrameImpl::Create(
agent_scheduling_group, routing_id, std::move(frame_receiver),
std::move(browser_interface_broker),
std::move(associated_interface_provider), devtools_frame_token);
web_frame = blink::WebLocalFrame::CreateProvisional(
render_frame, render_frame->blink_interface_registry_.get(),
frame_token, previous_web_frame, replicated_state->frame_policy,
WebString::FromUTF8(replicated_state->name), web_view);
DCHECK_EQ(!previous_web_frame->Parent(), !web_frame->Parent());
render_frame->unique_name_helper_.set_propagated_name(
GetUniqueNameOfWebFrame(previous_web_frame));
}
CHECK(web_view);
CHECK(render_frame);
CHECK(web_frame);
bool is_main_frame = !web_frame->Parent();
if (!is_main_frame)
DCHECK(parent_frame_token);
if (is_main_frame) {
DCHECK(widget_params);
DCHECK_NE(widget_params->routing_id, MSG_ROUTING_NONE);
bool is_for_nested_main_frame = web_view->IsFencedFrameRoot();
blink::WebFrameWidget* web_frame_widget = web_frame->InitializeFrameWidget(
std::move(widget_params->frame_widget_host),
std::move(widget_params->frame_widget),
std::move(widget_params->widget_host), std::move(widget_params->widget),
viz::FrameSinkId(RenderThread::Get()->GetClientId(),
widget_params->routing_id),
is_for_nested_main_frame,
!is_for_nested_main_frame,
true);
web_frame_widget->InitializeCompositing(
widget_params->visual_properties.screen_infos,
nullptr);
web_frame_widget->ApplyVisualProperties(widget_params->visual_properties);
} else if (widget_params) {
DCHECK(widget_params->routing_id != MSG_ROUTING_NONE);
blink::WebFrameWidget* web_frame_widget = web_frame->InitializeFrameWidget(
std::move(widget_params->frame_widget_host),
std::move(widget_params->frame_widget),
std::move(widget_params->widget_host), std::move(widget_params->widget),
viz::FrameSinkId(RenderThread::Get()->GetClientId(),
widget_params->routing_id),
false,
false,
true);
web_frame_widget->InitializeCompositing(
widget_params->visual_properties.screen_infos,
nullptr);
web_frame_widget->ApplyVisualProperties(widget_params->visual_properties);
}
if (!is_on_initial_empty_document)
render_frame->frame_->SetIsNotOnInitialEmptyDocument();
render_frame->Initialize(web_frame->Parent());
}
RenderFrame* RenderFrame::FromWebFrame(blink::WebLocalFrame* web_frame) {
return RenderFrameImpl::FromWebFrame(web_frame);
}
void RenderFrame::ForEach(RenderFrameVisitor* visitor) {
DCHECK(RenderThread::IsMainThread());
FrameMap* frames = g_frame_map.Pointer();
for (auto it = frames->begin(); it != frames->end(); ++it) {
if (!visitor->Visit(it->second))
return;
}
}
RenderFrameImpl* RenderFrameImpl::FromWebFrame(blink::WebFrame* web_frame) {
DCHECK(RenderThread::IsMainThread());
auto iter = g_frame_map.Get().find(web_frame);
if (iter != g_frame_map.Get().end())
return iter->second;
return nullptr;
}
void RenderFrameImpl::InstallCreateHook(
CreateRenderFrameImplFunction create_frame) {
DCHECK(!g_create_render_frame_impl);
g_create_render_frame_impl = create_frame;
}
blink::WebURL RenderFrameImpl::OverrideFlashEmbedWithHTML(
const blink::WebURL& url) {
return GetContentClient()->renderer()->OverrideFlashEmbedWithHTML(url);
}
RenderFrameImpl::CreateParams::CreateParams(
AgentSchedulingGroup& agent_scheduling_group,
int32_t routing_id,
mojo::PendingAssociatedReceiver<mojom::Frame> frame_receiver,
mojo::PendingRemote<blink::mojom::BrowserInterfaceBroker>
browser_interface_broker,
mojo::PendingAssociatedRemote<blink::mojom::AssociatedInterfaceProvider>
associated_interface_provider,
const base::UnguessableToken& devtools_frame_token)
: agent_scheduling_group(&agent_scheduling_group),
routing_id(routing_id),
frame_receiver(std::move(frame_receiver)),
browser_interface_broker(std::move(browser_interface_broker)),
associated_interface_provider(std::move(associated_interface_provider)),
devtools_frame_token(devtools_frame_token) {}
RenderFrameImpl::CreateParams::~CreateParams() = default;
RenderFrameImpl::CreateParams::CreateParams(CreateParams&&) = default;
RenderFrameImpl::CreateParams& RenderFrameImpl::CreateParams::operator=(
CreateParams&&) = default;
RenderFrameImpl::RenderFrameImpl(CreateParams params)
: agent_scheduling_group_(*params.agent_scheduling_group),
is_main_frame_(true),
unique_name_frame_adapter_(this),
unique_name_helper_(&unique_name_frame_adapter_),
in_frame_tree_(false),
routing_id_(params.routing_id),
selection_text_offset_(0),
selection_range_(gfx::Range::InvalidRange()),
render_accessibility_manager_(
std::make_unique<RenderAccessibilityManager>(this)),
weak_wrapper_resource_load_info_notifier_(
std::make_unique<blink::WeakWrapperResourceLoadInfoNotifier>(this)),
#if BUILDFLAG(ENABLE_PPAPI)
focused_pepper_plugin_(nullptr),
#endif
navigation_client_impl_(nullptr),
media_factory_(
this,
base::BindRepeating(&RenderFrameImpl::RequestOverlayRoutingToken,
base::Unretained(this))),
devtools_frame_token_(params.devtools_frame_token) {
DCHECK(RenderThread::IsMainThread());
blink_interface_registry_ = std::make_unique<BlinkInterfaceRegistryImpl>(
registry_.GetWeakPtr(), associated_interfaces_.GetWeakPtr());
DCHECK(params.frame_receiver.is_valid());
pending_frame_receiver_ = std::move(params.frame_receiver);
DCHECK(params.browser_interface_broker.is_valid());
browser_interface_broker_proxy_.Bind(
std::move(params.browser_interface_broker),
agent_scheduling_group_.agent_group_scheduler().DefaultTaskRunner());
DCHECK(params.associated_interface_provider.is_valid());
pending_associated_interface_provider_remote_ =
std::move(params.associated_interface_provider);
delayed_state_sync_timer_.SetTaskRunner(
agent_scheduling_group_.agent_group_scheduler().DefaultTaskRunner());
media_factory_.SetupMojo();
std::pair<RoutingIDFrameMap::iterator, bool> result =
g_routing_id_frame_map.Get().insert(std::make_pair(routing_id_, this));
CHECK(result.second) << "Inserting a duplicate item.";
#if BUILDFLAG(IS_ANDROID)
new GinJavaBridgeDispatcher(this);
#endif
#if BUILDFLAG(IS_OHOS)
new NWEB::OhGinJavascriptBridgeDispatcher(this);
#endif
}
mojom::FrameHost* RenderFrameImpl::GetFrameHost() {
if (!frame_host_remote_.is_bound())
GetRemoteAssociatedInterfaces()->GetInterface(&frame_host_remote_);
return frame_host_remote_.get();
}
RenderFrameImpl::~RenderFrameImpl() {
for (auto& observer : observers_)
observer.OnDestruct();
for (auto& observer : observers_)
observer.RenderFrameGone();
web_media_stream_device_observer_.reset();
if (initialized_ && is_main_frame_)
MainFrameCounter::DecrementCount();
base::trace_event::TraceLog::GetInstance()->RemoveProcessLabel(routing_id_);
g_routing_id_frame_map.Get().erase(routing_id_);
agent_scheduling_group_.RemoveRoute(routing_id_);
}
void RenderFrameImpl::Initialize(blink::WebFrame* parent) {
initialized_ = true;
is_main_frame_ = !parent;
if (is_main_frame_)
MainFrameCounter::IncrementCount();
TRACE_EVENT1("navigation,rail", "RenderFrameImpl::Initialize", "routing_id",
routing_id_);
#if BUILDFLAG(ENABLE_PPAPI)
new PepperBrowserConnection(this);
#endif
RegisterMojoInterfaces();
{
TRACE_EVENT("navigation", "ContentRendererClient::RenderFrameCreated");
GetContentClient()->renderer()->RenderFrameCreated(this);
}
auto& factory = blink::AudioOutputIPCFactory::GetInstance();
if (factory.io_task_runner()) {
factory.RegisterRemoteFactory(GetWebFrame()->GetLocalFrameToken(),
GetBrowserInterfaceBroker());
}
frame_request_blocker_ = blink::WebFrameRequestBlocker::Create();
frame_receiver_.Bind(
std::move(pending_frame_receiver_),
GetTaskRunner(blink::TaskType::kInternalNavigationAssociated));
agent_scheduling_group_.AddFrameRoute(
routing_id_, this,
GetTaskRunner(blink::TaskType::kInternalNavigationAssociated));
}
void RenderFrameImpl::GetInterface(
const std::string& interface_name,
mojo::ScopedMessagePipeHandle interface_pipe) {
if (registry_.TryBindInterface(interface_name, &interface_pipe))
return;
for (auto& observer : observers_) {
observer.OnInterfaceRequestForFrame(interface_name, &interface_pipe);
if (!interface_pipe.is_valid())
return;
}
}
blink::WebFrameWidget* RenderFrameImpl::GetLocalRootWebFrameWidget() {
return frame_->LocalRoot()->FrameWidget();
}
#if BUILDFLAG(ENABLE_PPAPI)
void RenderFrameImpl::PepperPluginCreated(RendererPpapiHost* host) {
for (auto& observer : observers_)
observer.DidCreatePepperPlugin(host);
}
void RenderFrameImpl::PepperTextInputTypeChanged(
PepperPluginInstanceImpl* instance) {
if (instance != focused_pepper_plugin_)
return;
GetLocalRootWebFrameWidget()->UpdateTextInputState();
}
void RenderFrameImpl::PepperCaretPositionChanged(
PepperPluginInstanceImpl* instance) {
if (instance != focused_pepper_plugin_)
return;
GetLocalRootWebFrameWidget()->UpdateSelectionBounds();
}
void RenderFrameImpl::PepperCancelComposition(
PepperPluginInstanceImpl* instance) {
if (instance != focused_pepper_plugin_)
return;
GetLocalRootWebFrameWidget()->CancelCompositionForPepper();
}
void RenderFrameImpl::PepperSelectionChanged(
PepperPluginInstanceImpl* instance) {
if (instance != focused_pepper_plugin_)
return;
SyncSelectionIfRequired(blink::SyncCondition::kNotForced);
}
#endif
void RenderFrameImpl::ScriptedPrint() {
bool user_initiated = GetLocalRootWebFrameWidget()->HandlingInputEvent();
for (auto& observer : observers_)
observer.ScriptedPrint(user_initiated);
}
bool RenderFrameImpl::Send(IPC::Message* message) {
return agent_scheduling_group_.Send(message);
}
bool RenderFrameImpl::OnMessageReceived(const IPC::Message& msg) {
if (!frame_)
return false;
DCHECK(!frame_->GetDocument().IsNull());
GetContentClient()->SetActiveURL(
frame_->GetDocument().Url(),
frame_->Top()->GetSecurityOrigin().ToString().Utf8());
for (auto& observer : observers_) {
if (observer.OnMessageReceived(msg))
return true;
}
return false;
}
void RenderFrameImpl::OnAssociatedInterfaceRequest(
const std::string& interface_name,
mojo::ScopedInterfaceEndpointHandle handle) {
if (!associated_interfaces_.TryBindInterface(interface_name, &handle)) {
for (auto& observer : observers_) {
if (observer.OnAssociatedInterfaceRequestForFrame(interface_name,
&handle)) {
return;
}
}
}
}
void RenderFrameImpl::SetUpSharedMemoryForSmoothness(
base::ReadOnlySharedMemoryRegion shared_memory) {
DCHECK(shared_memory.IsValid());
for (auto& observer : observers_) {
DCHECK(shared_memory.IsValid());
if (observer.SetUpSmoothnessReporting(shared_memory))
break;
}
}
void RenderFrameImpl::BindAutoplayConfiguration(
mojo::PendingAssociatedReceiver<blink::mojom::AutoplayConfigurationClient>
receiver) {
autoplay_configuration_receiver_.reset();
autoplay_configuration_receiver_.Bind(
std::move(receiver),
GetTaskRunner(blink::TaskType::kInternalNavigationAssociated));
}
void RenderFrameImpl::BindFrameBindingsControl(
mojo::PendingAssociatedReceiver<mojom::FrameBindingsControl> receiver) {
frame_bindings_control_receiver_.Bind(
std::move(receiver),
GetTaskRunner(blink::TaskType::kInternalNavigationAssociated));
}
void RenderFrameImpl::BindNavigationClient(
mojo::PendingAssociatedReceiver<mojom::NavigationClient> receiver) {
LOG(DEBUG) << "RenderFrameImpl::BindNavigationClient";
navigation_client_impl_ = std::make_unique<NavigationClient>(this);
navigation_client_impl_->Bind(std::move(receiver));
}
void RenderFrameImpl::Unload(
bool is_loading,
blink::mojom::FrameReplicationStatePtr replicated_frame_state,
const blink::RemoteFrameToken& proxy_frame_token,
blink::mojom::RemoteFrameInterfacesFromBrowserPtr remote_frame_interfaces,
blink::mojom::RemoteMainFrameInterfacesPtr remote_main_frame_interfaces) {
TRACE_EVENT1("navigation,rail", "RenderFrameImpl::UnloadFrame", "id",
routing_id_);
DCHECK(!base::RunLoop::IsNestedOnCurrentThread());
SendUpdateState();
auto& agent_scheduling_group = agent_scheduling_group_;
blink::LocalFrameToken frame_token = frame_->GetLocalFrameToken();
scoped_refptr<base::SingleThreadTaskRunner> task_runner =
GetTaskRunner(blink::TaskType::kInternalPostMessageForwarding);
if (!SwapOutAndDeleteThis(is_loading, std::move(replicated_frame_state),
proxy_frame_token,
std::move(remote_frame_interfaces),
std::move(remote_main_frame_interfaces))) {
return;
}
auto send_unload_ack = base::BindOnce(
[](AgentSchedulingGroup* agent_scheduling_group,
const blink::LocalFrameToken& frame_token) {
agent_scheduling_group->DidUnloadRenderFrame(frame_token);
},
&agent_scheduling_group, frame_token);
task_runner->PostTask(FROM_HERE, std::move(send_unload_ack));
}
void RenderFrameImpl::Delete(mojom::FrameDeleteIntention intent) {
TRACE_EVENT(
"navigation", "RenderFrameImpl::Delete", [&](perfetto::EventContext ctx) {
auto* event = ctx.event<perfetto::protos::pbzero::ChromeTrackEvent>();
auto* data = event->set_render_frame_impl_deletion();
data->set_intent(FrameDeleteIntentionToProto(intent));
});
switch (intent) {
case mojom::FrameDeleteIntention::kNotMainFrame:
DCHECK(!is_main_frame_);
break;
case mojom::FrameDeleteIntention::kSpeculativeMainFrameForShutdown:
DCHECK(is_main_frame_);
if (in_frame_tree_)
return;
break;
case mojom::FrameDeleteIntention::
kSpeculativeMainFrameForNavigationCancelled:
DCHECK(is_main_frame_);
#if !BUILDFLAG(IS_ANDROID)
CHECK(!in_frame_tree_);
#endif
break;
}
frame_->Detach();
}
void RenderFrameImpl::UndoCommitNavigation(
bool is_loading,
blink::mojom::FrameReplicationStatePtr replicated_frame_state,
const blink::RemoteFrameToken& proxy_frame_token,
blink::mojom::RemoteFrameInterfacesFromBrowserPtr remote_frame_interfaces,
blink::mojom::RemoteMainFrameInterfacesPtr remote_main_frame_interfaces) {
SwapOutAndDeleteThis(is_loading, std::move(replicated_frame_state),
proxy_frame_token, std::move(remote_frame_interfaces),
std::move(remote_main_frame_interfaces));
}
void RenderFrameImpl::SnapshotAccessibilityTree(
mojom::SnapshotAccessibilityTreeParamsPtr params,
SnapshotAccessibilityTreeCallback callback) {
ui::AXTreeUpdate response;
AXTreeSnapshotterImpl snapshotter(this, ui::AXMode(params->ax_mode));
snapshotter.Snapshot(params->max_nodes, params->timeout, &response);
std::move(callback).Run(response);
}
void RenderFrameImpl::GetSerializedHtmlWithLocalLinks(
const base::flat_map<GURL, base::FilePath>& url_map,
const base::flat_map<blink::FrameToken, base::FilePath>& frame_token_map,
bool save_with_empty_url,
mojo::PendingRemote<mojom::FrameHTMLSerializerHandler> handler_remote) {
LinkRewritingDelegate delegate(url_map, frame_token_map);
RenderFrameWebFrameSerializerClient client(std::move(handler_remote));
WebFrameSerializer::Serialize(GetWebFrame(), &client, &delegate,
save_with_empty_url);
}
void RenderFrameImpl::SetResourceCache(
mojo::PendingRemote<blink::mojom::ResourceCache> remote) {
CHECK(base::FeatureList::IsEnabled(blink::features::kRemoteResourceCache));
frame_->SetResourceCacheRemote(std::move(remote));
}
void RenderFrameImpl::SetWantErrorMessageStackTrace() {
want_error_message_stack_trace_ = true;
v8::Isolate::GetCurrent()->SetCaptureStackTraceForUncaughtExceptions(true);
}
void RenderFrameImpl::NotifyObserversOfFailedProvisionalLoad() {
for (auto& observer : observers_)
observer.DidFailProvisionalLoad();
}
void RenderFrameImpl::DidMeaningfulLayout(
blink::WebMeaningfulLayout layout_type) {
for (auto& observer : observers_)
observer.DidMeaningfulLayout(layout_type);
}
void RenderFrameImpl::DidCommitAndDrawCompositorFrame() {
#if BUILDFLAG(ENABLE_PPAPI)
PepperPluginSet plugins = active_pepper_instances_;
for (auto* plugin : plugins) {
if (active_pepper_instances_.find(plugin) != active_pepper_instances_.end())
plugin->ViewInitiatedPaint();
}
#endif
}
RenderFrame* RenderFrameImpl::GetMainRenderFrame() {
WebFrame* main_frame = GetWebView()->MainFrame();
DCHECK(main_frame);
if (!main_frame->IsWebLocalFrame())
return nullptr;
return RenderFrame::FromWebFrame(main_frame->ToWebLocalFrame());
}
RenderAccessibility* RenderFrameImpl::GetRenderAccessibility() {
return render_accessibility_manager_->GetRenderAccessibilityImpl();
}
std::unique_ptr<AXTreeSnapshotter> RenderFrameImpl::CreateAXTreeSnapshotter(
ui::AXMode ax_mode) {
return std::make_unique<AXTreeSnapshotterImpl>(this, ax_mode);
}
int RenderFrameImpl::GetRoutingID() {
return routing_id_;
}
blink::WebLocalFrame* RenderFrameImpl::GetWebFrame() {
DCHECK(frame_);
return frame_;
}
const blink::WebLocalFrame* RenderFrameImpl::GetWebFrame() const {
DCHECK(frame_);
return frame_;
}
blink::WebView* RenderFrameImpl::GetWebView() {
blink::WebView* web_view = GetWebFrame()->View();
DCHECK(web_view);
return web_view;
}
const blink::WebView* RenderFrameImpl::GetWebView() const {
const blink::WebView* web_view = GetWebFrame()->View();
DCHECK(web_view);
return web_view;
}
const blink::web_pref::WebPreferences& RenderFrameImpl::GetBlinkPreferences() {
return GetWebView()->GetWebPreferences();
}
const blink::RendererPreferences& RenderFrameImpl::GetRendererPreferences()
const {
return GetWebView()->GetRendererPreferences();
}
void RenderFrameImpl::ShowVirtualKeyboard() {
GetLocalRootWebFrameWidget()->ShowVirtualKeyboard();
}
blink::WebPlugin* RenderFrameImpl::CreatePlugin(
const WebPluginInfo& info,
const blink::WebPluginParams& params) {
#if BUILDFLAG(ENABLE_PPAPI)
absl::optional<url::Origin> origin_lock;
if (GetContentClient()->renderer()->IsOriginIsolatedPepperPlugin(info.path)) {
origin_lock = url::Origin::Create(GURL(params.url));
}
bool pepper_plugin_was_registered = false;
scoped_refptr<PluginModule> pepper_module(PluginModule::Create(
this, info, origin_lock, &pepper_plugin_was_registered,
GetTaskRunner(blink::TaskType::kNetworking)));
if (pepper_plugin_was_registered) {
if (pepper_module.get()) {
return new PepperWebPluginImpl(pepper_module.get(), params, this);
}
}
#if BUILDFLAG(IS_CHROMEOS_ASH)
LOG(WARNING) << "Pepper module/plugin creation failed.";
#endif
#endif
return nullptr;
}
void RenderFrameImpl::ExecuteJavaScript(const std::u16string& javascript) {
v8::HandleScope handle_scope(v8::Isolate::GetCurrent());
frame_->ExecuteScript(WebScriptSource(WebString::FromUTF16(javascript)));
}
void RenderFrameImpl::BindLocalInterface(
const std::string& interface_name,
mojo::ScopedMessagePipeHandle interface_pipe) {
GetInterface(interface_name, std::move(interface_pipe));
}
blink::AssociatedInterfaceRegistry*
RenderFrameImpl::GetAssociatedInterfaceRegistry() {
return &associated_interfaces_;
}
blink::AssociatedInterfaceProvider*
RenderFrameImpl::GetRemoteAssociatedInterfaces() {
if (!remote_associated_interfaces_) {
DCHECK(pending_associated_interface_provider_remote_);
remote_associated_interfaces_ =
std::make_unique<blink::AssociatedInterfaceProvider>(
std::move(pending_associated_interface_provider_remote_),
GetTaskRunner(blink::TaskType::kInternalNavigationAssociated));
}
return remote_associated_interfaces_.get();
}
void RenderFrameImpl::SetSelectedText(const std::u16string& selection_text,
size_t offset,
const gfx::Range& range) {
GetWebFrame()->TextSelectionChanged(WebString::FromUTF16(selection_text),
static_cast<uint32_t>(offset), range);
}
#if defined(OHOS_CLIPBOARD)
void RenderFrameImpl::MouseSelectMenuShow(bool show) {
if (GetFrameHost()) {
GetFrameHost()->MouseSelectMenuShow(show);
}
}
void RenderFrameImpl::ChangeVisibilityOfQuickMenu() {
if (GetFrameHost()) {
GetFrameHost()->ChangeVisibilityOfQuickMenu();
}
}
#endif
#ifdef OHOS_AI
void RenderFrameImpl::CloseImageOverlaySelection() {
if (GetFrameHost()) {
GetFrameHost()->CloseImageOverlaySelection();
}
}
#endif
void RenderFrameImpl::AddMessageToConsole(
blink::mojom::ConsoleMessageLevel level,
const std::string& message) {
AddMessageToConsoleImpl(level, message, false );
}
bool RenderFrameImpl::IsPasting() {
return GetLocalRootWebFrameWidget()->IsPasting();
}
void RenderFrameImpl::AddAutoplayFlags(const url::Origin& origin,
const int32_t flags) {
if (autoplay_flags_.first == origin) {
autoplay_flags_.second |= flags;
} else {
autoplay_flags_ = std::make_pair(origin, flags);
}
}
#if BUILDFLAG(IS_ANDROID)
void RenderFrameImpl::NotifyUpdateUserGestureCarryoverInfo() {
GetFrameHost()->UpdateUserGestureCarryoverInfo();
}
#endif
void RenderFrameImpl::NotifyResourceRedirectReceived(
const net::RedirectInfo& redirect_info,
network::mojom::URLResponseHeadPtr redirect_response) {}
void RenderFrameImpl::NotifyResourceResponseReceived(
int64_t request_id,
const url::SchemeHostPort& final_response_url,
network::mojom::URLResponseHeadPtr response_head,
network::mojom::RequestDestination request_destination) {
if (!blink::IsRequestDestinationFrame(request_destination)) {
GetFrameHost()->SubresourceResponseStarted(final_response_url,
response_head->cert_status);
}
DidStartResponse(final_response_url, request_id, std::move(response_head),
request_destination);
}
void RenderFrameImpl::NotifyResourceTransferSizeUpdated(
int64_t request_id,
int32_t transfer_size_diff) {
DidReceiveTransferSizeUpdate(request_id, transfer_size_diff);
}
void RenderFrameImpl::NotifyResourceLoadCompleted(
blink::mojom::ResourceLoadInfoPtr resource_load_info,
const network::URLLoaderCompletionStatus& status) {
DidCompleteResponse(resource_load_info->request_id, status);
GetFrameHost()->ResourceLoadComplete(std::move(resource_load_info));
}
void RenderFrameImpl::NotifyResourceLoadCanceled(int64_t request_id) {
DidCancelResponse(request_id);
}
void RenderFrameImpl::Clone(
mojo::PendingReceiver<blink::mojom::ResourceLoadInfoNotifier>
pending_resource_load_info_notifier) {
resource_load_info_notifier_receivers_.Add(
this, std::move(pending_resource_load_info_notifier),
agent_scheduling_group_.agent_group_scheduler().DefaultTaskRunner());
}
void RenderFrameImpl::GetInterfaceProvider(
mojo::PendingReceiver<service_manager::mojom::InterfaceProvider> receiver) {
auto task_runner = GetTaskRunner(blink::TaskType::kInternalDefault);
DCHECK(task_runner);
interface_provider_receivers_.Add(this, std::move(receiver), task_runner);
}
void RenderFrameImpl::BlockRequests() {
frame_request_blocker_->Block();
}
void RenderFrameImpl::ResumeBlockedRequests() {
frame_request_blocker_->Resume();
}
void RenderFrameImpl::AllowBindings(int32_t enabled_bindings_flags) {
enabled_bindings_ |= enabled_bindings_flags;
}
void RenderFrameImpl::EnableMojoJsBindings(
content::mojom::ExtraMojoJsFeaturesPtr features) {
enable_mojo_js_bindings_ = true;
mojo_js_features_ = std::move(features);
}
void RenderFrameImpl::EnableMojoJsBindingsWithBroker(
mojo::PendingRemote<blink::mojom::BrowserInterfaceBroker> broker) {
mojo_js_interface_broker_ = std::move(broker);
}
void RenderFrameImpl::BindWebUI(
mojo::PendingAssociatedReceiver<mojom::WebUI> receiver,
mojo::PendingAssociatedRemote<mojom::WebUIHost> remote) {
DCHECK(enabled_bindings_ & BINDINGS_POLICY_WEB_UI);
WebUIExtensionData::Create(this, std::move(receiver), std::move(remote));
}
void RenderFrameImpl::SetOldPageLifecycleStateFromNewPageCommitIfNeeded(
const blink::mojom::OldPageInfo* old_page_info,
const GURL& new_page_url) {
if (!old_page_info)
return;
RenderFrameImpl* old_main_render_frame = RenderFrameImpl::FromRoutingID(
old_page_info->routing_id_for_old_main_frame);
if (!old_main_render_frame) {
return;
}
if (!IsMainFrame() && !old_main_render_frame->IsMainFrame()) {
SCOPED_CRASH_KEY_BOOL("old_page_info", "new_is_main_frame", IsMainFrame());
SCOPED_CRASH_KEY_STRING256("old_page_info", "new_url", new_page_url.spec());
SCOPED_CRASH_KEY_BOOL("old_page_info", "old_is_main_frame",
old_main_render_frame->IsMainFrame());
SCOPED_CRASH_KEY_STRING256("old_page_info", "old_url",
old_main_render_frame->GetLoadingUrl().spec());
SCOPED_CRASH_KEY_NUMBER("old_page_info", "old_routing_id",
old_page_info->routing_id_for_old_main_frame);
SCOPED_CRASH_KEY_BOOL(
"old_page_info", "old_is_frozen",
old_page_info->new_lifecycle_state_for_old_page->is_frozen);
SCOPED_CRASH_KEY_BOOL("old_page_info", "old_is_in_bfcache",
old_page_info->new_lifecycle_state_for_old_page
->is_in_back_forward_cache);
SCOPED_CRASH_KEY_BOOL(
"old_page_info", "old_is_hidden",
old_page_info->new_lifecycle_state_for_old_page->visibility ==
blink::mojom::PageVisibilityState::kHidden);
SCOPED_CRASH_KEY_BOOL(
"old_page_info", "old_pagehide_dispatch",
old_page_info->new_lifecycle_state_for_old_page->pagehide_dispatch ==
blink::mojom::PagehideDispatch::kNotDispatched);
CaptureTraceForNavigationDebugScenario(
DebugScenario::kDebugNonMainFrameWithOldPageInfo);
return;
}
DCHECK_EQ(old_page_info->new_lifecycle_state_for_old_page->visibility,
blink::mojom::PageVisibilityState::kHidden);
DCHECK_NE(old_page_info->new_lifecycle_state_for_old_page->pagehide_dispatch,
blink::mojom::PagehideDispatch::kNotDispatched);
WebFrame* old_main_web_frame = old_main_render_frame->GetWebFrame();
old_main_web_frame->View()->SetPageLifecycleStateFromNewPageCommit(
old_page_info->new_lifecycle_state_for_old_page->visibility,
old_page_info->new_lifecycle_state_for_old_page->pagehide_dispatch);
}
void RenderFrameImpl::CommitNavigation(
blink::mojom::CommonNavigationParamsPtr common_params,
blink::mojom::CommitNavigationParamsPtr commit_params,
network::mojom::URLResponseHeadPtr response_head,
mojo::ScopedDataPipeConsumerHandle response_body,
network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints,
std::unique_ptr<blink::PendingURLLoaderFactoryBundle>
subresource_loader_factories,
absl::optional<std::vector<blink::mojom::TransferrableURLLoaderPtr>>
subresource_overrides,
blink::mojom::ControllerServiceWorkerInfoPtr controller_service_worker_info,
blink::mojom::ServiceWorkerContainerInfoForClientPtr container_info,
mojo::PendingRemote<network::mojom::URLLoaderFactory>
prefetch_loader_factory,
mojo::PendingRemote<network::mojom::URLLoaderFactory> topics_loader_factory,
mojo::PendingRemote<network::mojom::URLLoaderFactory>
keep_alive_loader_factory,
const blink::DocumentToken& document_token,
const base::UnguessableToken& devtools_navigation_token,
const absl::optional<blink::ParsedPermissionsPolicy>& permissions_policy,
blink::mojom::PolicyContainerPtr policy_container,
mojo::PendingRemote<blink::mojom::CodeCacheHost> code_cache_host,
mojo::PendingRemote<blink::mojom::ResourceCache> resource_cache,
mojom::CookieManagerInfoPtr cookie_manager_info,
mojom::StorageInfoPtr storage_info,
mojom::NavigationClient::CommitNavigationCallback commit_callback) {
LOG(INFO) << "RenderFrameImpl::CommitNavigation " << devtools_navigation_token.ToString();
DCHECK(navigation_client_impl_);
DCHECK(!blink::IsRendererDebugURL(common_params->url));
DCHECK(!NavigationTypeUtils::IsSameDocument(common_params->navigation_type));
CHECK(!commit_params->origin_to_commit);
LogCommitHistograms(commit_params->commit_sent, is_main_frame_);
AssertNavigationCommits assert_navigation_commits(
this, kMayReplaceInitialEmptyDocument);
SetOldPageLifecycleStateFromNewPageCommitIfNeeded(
commit_params->old_page_info.get(), common_params->url);
bool was_initiated_in_this_frame =
navigation_client_impl_ &&
navigation_client_impl_->was_initiated_in_this_frame();
DCHECK(common_params->url.SchemeIs(url::kJavaScriptScheme) ||
subresource_loader_factories);
int request_id = blink::GenerateRequestId();
std::unique_ptr<DocumentState> document_state = BuildDocumentStateFromParams(
*common_params, *commit_params, std::move(commit_callback),
std::move(navigation_client_impl_), request_id,
was_initiated_in_this_frame);
#if BUILDFLAG(IS_OHOS) && defined(OHOS_NWEB_EX)
const base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
if (command_line && command_line->HasSwitch(switches::kEnableNwebEx)) {
viewport_meta_enabled_=GetBlinkPreferences().viewport_meta_enabled;
}
#endif
bool is_client_redirect =
!!(common_params->transition & ui::PAGE_TRANSITION_CLIENT_REDIRECT);
auto navigation_params = std::make_unique<WebNavigationParams>(
document_token, devtools_navigation_token);
navigation_params->navigation_delivery_type =
commit_params->navigation_delivery_type;
navigation_params->is_client_redirect = is_client_redirect;
FillMiscNavigationParams(*common_params, *commit_params,
navigation_params.get());
navigation_params->policy_container =
ToWebPolicyContainer(std::move(policy_container));
navigation_params->view_transition_state =
std::move(commit_params->view_transition_state);
if (frame_->IsOutermostMainFrame() && permissions_policy) {
navigation_params->permissions_policy_override = permissions_policy;
}
auto commit_with_params = base::BindOnce(
&RenderFrameImpl::CommitNavigationWithParams, weak_factory_.GetWeakPtr(),
common_params.Clone(), commit_params.Clone(),
std::move(subresource_loader_factories), std::move(subresource_overrides),
std::move(controller_service_worker_info), std::move(container_info),
std::move(prefetch_loader_factory), std::move(topics_loader_factory),
std::move(keep_alive_loader_factory), std::move(code_cache_host),
std::move(resource_cache), std::move(cookie_manager_info),
std::move(storage_info), std::move(document_state));
bool should_handle_data_url_as_string = false;
#if BUILDFLAG(IS_ANDROID)
should_handle_data_url_as_string |=
is_main_frame_ && !commit_params->data_url_as_string.empty();
#endif
if (should_handle_data_url_as_string ||
commit_params->is_load_data_with_base_url) {
std::string mime_type, charset, data;
GURL base_url;
DecodeDataURL(*common_params, *commit_params, &mime_type, &charset, &data,
&base_url);
navigation_params->url = base_url;
WebNavigationParams::FillStaticResponse(navigation_params.get(),
WebString::FromUTF8(mime_type),
WebString::FromUTF8(charset), data);
std::move(commit_with_params).Run(std::move(navigation_params));
return;
}
FillNavigationParamsRequest(*common_params, *commit_params,
navigation_params.get());
if (!url_loader_client_endpoints &&
common_params->url.SchemeIs(url::kDataScheme)) {
std::string mime_type, charset, data;
if (!net::DataURL::Parse(common_params->url, &mime_type, &charset, &data)) {
CHECK(false) << "Invalid URL passed: "
<< common_params->url.possibly_invalid_spec();
return;
}
WebNavigationParams::FillStaticResponse(navigation_params.get(),
WebString::FromUTF8(mime_type),
WebString::FromUTF8(charset), data);
} else {
blink::WebNavigationBodyLoader::FillNavigationParamsResponseAndBodyLoader(
std::move(common_params), std::move(commit_params), request_id,
response_head.Clone(), std::move(response_body),
std::move(url_loader_client_endpoints),
GetTaskRunner(blink::TaskType::kInternalLoading),
CreateResourceLoadInfoNotifierWrapper(), !frame_->Parent(),
navigation_params.get());
}
bool is_mhtml_archive = base::EqualsCaseInsensitiveASCII(
response_head->mime_type, "multipart/related") ||
base::EqualsCaseInsensitiveASCII(
response_head->mime_type, "message/rfc822");
if (is_mhtml_archive && navigation_params->body_loader) {
mhtml_body_loader_client_ =
std::make_unique<RenderFrameImpl::MHTMLBodyLoaderClient>(
this, std::move(navigation_params), std::move(commit_with_params));
navigation_commit_state_ = NavigationCommitState::kDidCommit;
return;
}
std::move(commit_with_params).Run(std::move(navigation_params));
}
void RenderFrameImpl::CommitNavigationWithParams(
blink::mojom::CommonNavigationParamsPtr common_params,
blink::mojom::CommitNavigationParamsPtr commit_params,
std::unique_ptr<blink::PendingURLLoaderFactoryBundle>
subresource_loader_factories,
absl::optional<std::vector<blink::mojom::TransferrableURLLoaderPtr>>
subresource_overrides,
blink::mojom::ControllerServiceWorkerInfoPtr controller_service_worker_info,
blink::mojom::ServiceWorkerContainerInfoForClientPtr container_info,
mojo::PendingRemote<network::mojom::URLLoaderFactory>
prefetch_loader_factory,
mojo::PendingRemote<network::mojom::URLLoaderFactory> topics_loader_factory,
mojo::PendingRemote<network::mojom::URLLoaderFactory>
keep_alive_loader_factory,
mojo::PendingRemote<blink::mojom::CodeCacheHost> code_cache_host,
mojo::PendingRemote<blink::mojom::ResourceCache> resource_cache,
mojom::CookieManagerInfoPtr cookie_manager_info,
mojom::StorageInfoPtr storage_info,
std::unique_ptr<DocumentState> document_state,
std::unique_ptr<WebNavigationParams> navigation_params) {
#ifdef OHOS_ARKWEB_ADBLOCK
bool site_adblock_enabled = commit_params->site_adblock_enabled;
#endif
if (common_params->url.IsAboutSrcdoc()) {
WebNavigationParams::FillStaticResponse(navigation_params.get(),
"text/html", "UTF-8",
commit_params->srcdoc_value);
}
scoped_refptr<blink::ChildURLLoaderFactoryBundle> new_loader_factories =
CreateLoaderFactoryBundle(std::move(subresource_loader_factories),
std::move(subresource_overrides),
std::move(prefetch_loader_factory),
std::move(topics_loader_factory),
std::move(keep_alive_loader_factory));
DCHECK(new_loader_factories);
DCHECK(new_loader_factories->HasBoundDefaultFactory());
if (commit_params->is_view_source)
frame_->EnableViewSourceMode(true);
if (commit_params->not_restored_reasons) {
frame_->SetNotRestoredReasons(
std::move(commit_params->not_restored_reasons));
}
mhtml_body_loader_client_.reset();
PrepareFrameForCommit(common_params->url, *commit_params);
blink::WebFrameLoadType load_type =
NavigationTypeToLoadType(common_params->navigation_type,
common_params->should_replace_current_entry);
WebHistoryItem item_for_history_navigation;
blink::mojom::CommitResult commit_status = blink::mojom::CommitResult::Ok;
if (load_type == WebFrameLoadType::kBackForward) {
DCHECK_NE(0, commit_params->nav_entry_id);
commit_status = PrepareForHistoryNavigationCommit(
*common_params, *commit_params, &item_for_history_navigation,
&load_type);
}
if (commit_status != blink::mojom::CommitResult::Ok) {
if (frame_ && !frame_->IsLoading())
GetFrameHost()->DidStopLoading();
return;
}
navigation_params->frame_load_type = load_type;
navigation_params->history_item = item_for_history_navigation;
navigation_params->load_with_storage_access =
commit_params->load_with_storage_access;
if (!container_info) {
navigation_params->service_worker_network_provider =
ServiceWorkerNetworkProviderForFrame::CreateInvalidInstance();
} else {
navigation_params->service_worker_network_provider =
ServiceWorkerNetworkProviderForFrame::Create(
this, std::move(container_info),
std::move(controller_service_worker_info),
network::SharedURLLoaderFactory::Create(
new_loader_factories->Clone()));
}
DCHECK(!pending_loader_factories_);
pending_loader_factories_ = std::move(new_loader_factories);
pending_code_cache_host_ = std::move(code_cache_host);
pending_resource_cache_ = std::move(resource_cache);
pending_cookie_manager_info_ = std::move(cookie_manager_info);
pending_storage_info_ = std::move(storage_info);
original_storage_key_ = navigation_params->storage_key;
base::WeakPtr<RenderFrameImpl> weak_self = weak_factory_.GetWeakPtr();
frame_->CommitNavigation(std::move(navigation_params),
std::move(document_state));
if (!weak_self)
return;
#ifdef OHOS_ARKWEB_ADBLOCK
if (is_main_frame_) {
OnUpdateAdBlockEnabledToRender(site_adblock_enabled);
}
#endif
ResetMembersUsedForDurationOfCommit();
}
void RenderFrameImpl::CommitFailedNavigation(
blink::mojom::CommonNavigationParamsPtr common_params,
blink::mojom::CommitNavigationParamsPtr commit_params,
bool has_stale_copy_in_cache,
int error_code,
int extended_error_code,
net::ResolveErrorInfo resolve_error_info,
const absl::optional<std::string>& error_page_content,
std::unique_ptr<blink::PendingURLLoaderFactoryBundle>
subresource_loader_factories,
const blink::DocumentToken& document_token,
blink::mojom::PolicyContainerPtr policy_container,
mojom::AlternativeErrorPageOverrideInfoPtr alternative_error_page_info,
mojom::NavigationClient::CommitFailedNavigationCallback callback) {
TRACE_EVENT1("navigation,benchmark,rail",
"RenderFrameImpl::CommitFailedNavigation", "id", routing_id_);
DCHECK(navigation_client_impl_);
DCHECK(!NavigationTypeUtils::IsSameDocument(common_params->navigation_type));
CHECK(commit_params->origin_to_commit);
DCHECK(!common_params->initiator_base_url);
AssertNavigationCommits assert_navigation_commits(
this, kMayReplaceInitialEmptyDocument);
GetWebView()->SetHistoryListFromNavigation(
commit_params->current_history_list_offset,
commit_params->current_history_list_length);
mhtml_body_loader_client_.reset();
GetContentClient()->SetActiveURL(
common_params->url, frame_->Top()->GetSecurityOrigin().ToString().Utf8());
scoped_refptr<blink::ChildURLLoaderFactoryBundle> new_loader_factories =
CreateLoaderFactoryBundle(
std::move(subresource_loader_factories),
absl::nullopt ,
mojo::NullRemote() ,
mojo::NullRemote() ,
mojo::NullRemote() );
DCHECK(new_loader_factories->HasBoundDefaultFactory());
WebURLError error(
error_code, extended_error_code, resolve_error_info,
has_stale_copy_in_cache ? WebURLError::HasCopyInCache::kTrue
: WebURLError::HasCopyInCache::kFalse,
WebURLError::IsWebSecurityViolation::kFalse, common_params->url,
WebURLError::ShouldCollapseInitiator::kFalse);
auto navigation_params = std::make_unique<WebNavigationParams>(
document_token,
base::UnguessableToken::Create());
FillNavigationParamsRequest(*common_params, *commit_params,
navigation_params.get());
navigation_params->url = GURL(kUnreachableWebDataURL);
navigation_params->http_method = WebString::FromASCII(common_params->method);
navigation_params->error_code = error_code;
CHECK_NE(net::ERR_ABORTED, error_code);
if (commit_params->nav_entry_id == 0) {
NotifyObserversOfFailedProvisionalLoad();
}
std::string error_html;
std::string* error_html_ptr = &error_html;
if (error_code == net::ERR_HTTP_RESPONSE_CODE_FAILURE) {
DCHECK_NE(commit_params->http_response_code, -1);
GetContentClient()->renderer()->PrepareErrorPageForHttpStatusError(
this, error, navigation_params->http_method.Ascii(),
commit_params->http_response_code, nullptr, error_html_ptr);
} else {
if (error_page_content) {
error_html = error_page_content.value();
error_html_ptr = nullptr;
}
GetContentClient()->renderer()->PrepareErrorPage(
this, error, navigation_params->http_method.Ascii(),
std::move(alternative_error_page_info), error_html_ptr);
}
frame_->EnableViewSourceMode(false);
auto page_state =
blink::PageState::CreateFromEncodedData(commit_params->page_state);
if (page_state.IsValid())
navigation_params->history_item = WebHistoryItem(page_state);
if (!navigation_params->history_item.IsNull()) {
navigation_params->frame_load_type = WebFrameLoadType::kBackForward;
} else if (common_params->should_replace_current_entry) {
navigation_params->frame_load_type = WebFrameLoadType::kReplaceCurrentItem;
}
navigation_params->service_worker_network_provider =
ServiceWorkerNetworkProviderForFrame::CreateInvalidInstance();
FillMiscNavigationParams(*common_params, *commit_params,
navigation_params.get());
WebNavigationParams::FillStaticResponse(navigation_params.get(), "text/html",
"UTF-8", error_html);
navigation_params->unreachable_url = error.url();
if (commit_params->redirects.size()) {
navigation_params->pre_redirect_url_for_failed_navigations =
commit_params->redirects[0];
} else {
navigation_params->pre_redirect_url_for_failed_navigations = error.url();
}
navigation_params->policy_container =
ToWebPolicyContainer(std::move(policy_container));
navigation_params->view_transition_state =
std::move(commit_params->view_transition_state);
std::unique_ptr<DocumentState> document_state = BuildDocumentStateFromParams(
*common_params, *commit_params, std::move(callback),
std::move(navigation_client_impl_), blink::GenerateRequestId(),
false );
#if BUILDFLAG(IS_OHOS) && defined(OHOS_NWEB_EX)
const base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
if (command_line && command_line->HasSwitch(switches::kEnableNwebEx)) {
if (viewport_meta_enabled_ != GetBlinkPreferences().viewport_meta_enabled) {
document_state->set_must_reset_scroll_and_scale_state(true);
viewport_meta_enabled_ = GetBlinkPreferences().viewport_meta_enabled;
}
}
#endif
DCHECK(!pending_loader_factories_);
pending_loader_factories_ = std::move(new_loader_factories);
base::WeakPtr<RenderFrameImpl> weak_this = weak_factory_.GetWeakPtr();
frame_->CommitNavigation(std::move(navigation_params),
std::move(document_state));
if (!weak_this)
return;
ResetMembersUsedForDurationOfCommit();
}
void RenderFrameImpl::CommitSameDocumentNavigation(
blink::mojom::CommonNavigationParamsPtr common_params,
blink::mojom::CommitNavigationParamsPtr commit_params,
CommitSameDocumentNavigationCallback callback) {
DCHECK(!blink::IsRendererDebugURL(common_params->url));
DCHECK(!NavigationTypeUtils::IsReload(common_params->navigation_type));
DCHECK(!commit_params->is_view_source);
DCHECK(NavigationTypeUtils::IsSameDocument(common_params->navigation_type));
CHECK(in_frame_tree_);
if (mhtml_body_loader_client_) {
mhtml_body_loader_client_->Detach();
mhtml_body_loader_client_.reset();
}
PrepareFrameForCommit(common_params->url, *commit_params);
blink::WebFrameLoadType load_type =
NavigationTypeToLoadType(common_params->navigation_type,
common_params->should_replace_current_entry);
DocumentState* document_state =
DocumentState::FromDocumentLoader(frame_->GetDocumentLoader());
document_state->set_navigation_state(
NavigationState::CreateForSameDocumentCommitFromBrowser(
std::move(common_params), std::move(commit_params),
std::move(callback)));
NavigationState* navigation_state = document_state->navigation_state();
blink::mojom::CommitResult commit_status = blink::mojom::CommitResult::Ok;
WebHistoryItem item_for_history_navigation;
if (navigation_state->common_params().navigation_type ==
blink::mojom::NavigationType::HISTORY_SAME_DOCUMENT) {
DCHECK(blink::PageState::CreateFromEncodedData(
navigation_state->commit_params().page_state)
.IsValid());
DCHECK_NE(0, navigation_state->commit_params().nav_entry_id);
DCHECK(!navigation_state->common_params()
.is_history_navigation_in_new_child_frame);
commit_status = PrepareForHistoryNavigationCommit(
navigation_state->common_params(), navigation_state->commit_params(),
&item_for_history_navigation, &load_type);
}
if (commit_status == blink::mojom::CommitResult::Ok) {
base::WeakPtr<RenderFrameImpl> weak_this = weak_factory_.GetWeakPtr();
bool use_base_url_for_data_url =
!navigation_state->common_params().base_url_for_data_url.is_empty();
#if BUILDFLAG(IS_ANDROID)
use_base_url_for_data_url |=
!navigation_state->commit_params().data_url_as_string.empty();
#endif
GURL url;
if (is_main_frame_ && use_base_url_for_data_url) {
url = navigation_state->common_params().base_url_for_data_url;
} else {
url = navigation_state->common_params().url;
}
bool is_client_redirect = !!(navigation_state->common_params().transition &
ui::PAGE_TRANSITION_CLIENT_REDIRECT);
bool started_with_transient_activation =
navigation_state->common_params().has_user_gesture;
bool is_browser_initiated =
navigation_state->commit_params().is_browser_initiated;
absl::optional<blink::scheduler::TaskAttributionId>
soft_navigation_heuristics_task_id =
navigation_state->commit_params()
.soft_navigation_heuristics_task_id;
WebSecurityOrigin initiator_origin;
if (navigation_state->common_params().initiator_origin) {
initiator_origin =
navigation_state->common_params().initiator_origin.value();
}
commit_status = frame_->CommitSameDocumentNavigation(
url, load_type, item_for_history_navigation, is_client_redirect,
started_with_transient_activation, initiator_origin,
is_browser_initiated, soft_navigation_heuristics_task_id);
if (commit_status == blink::mojom::CommitResult::Ok) {
return;
}
if (!weak_this || document_state->navigation_state() != navigation_state) {
return;
}
}
DCHECK_NE(commit_status, blink::mojom::CommitResult::Ok);
navigation_state->RunCommitSameDocumentNavigationCallback(commit_status);
document_state->clear_navigation_state();
if (frame_ && !frame_->IsLoading()) {
GetFrameHost()->DidStopLoading();
}
}
void RenderFrameImpl::UpdateSubresourceLoaderFactories(
std::unique_ptr<blink::PendingURLLoaderFactoryBundle>
subresource_loader_factories) {
if (loader_factories_->IsHostChildURLLoaderFactoryBundle()) {
static_cast<blink::HostChildURLLoaderFactoryBundle*>(
loader_factories_.get())
->UpdateThisAndAllClones(std::move(subresource_loader_factories));
} else {
DCHECK(!subresource_loader_factories->pending_default_factory().is_valid());
DCHECK(!subresource_loader_factories->pending_isolated_world_factories()
.empty());
DCHECK_EQ(NavigationCommitState::kInitialEmptyDocument,
navigation_commit_state_);
auto partial_bundle =
base::MakeRefCounted<blink::ChildURLLoaderFactoryBundle>();
static_cast<blink::URLLoaderFactoryBundle*>(partial_bundle.get())
->Update(std::move(subresource_loader_factories));
loader_factories_->Update(partial_bundle->PassInterface());
}
}
blink::BrowserInterfaceBrokerProxy*
RenderFrameImpl::GetBrowserInterfaceBroker() {
return &browser_interface_broker_proxy_;
}
bool RenderFrameImpl::IsPluginHandledExternally(
const blink::WebElement& plugin_element,
const blink::WebURL& url,
const blink::WebString& suggested_mime_type) {
#if BUILDFLAG(ENABLE_PLUGINS)
return GetContentClient()->renderer()->IsPluginHandledExternally(
this, plugin_element, GURL(url), suggested_mime_type.Utf8());
#else
return false;
#endif
}
v8::Local<v8::Object> RenderFrameImpl::GetScriptableObject(
const blink::WebElement& plugin_element,
v8::Isolate* isolate) {
#if BUILDFLAG(ENABLE_PLUGINS)
return GetContentClient()->renderer()->GetScriptableObject(plugin_element,
isolate);
#else
return v8::Local<v8::Object>();
#endif
}
void RenderFrameImpl::UpdateSubresourceFactory(
std::unique_ptr<blink::PendingURLLoaderFactoryBundle> info) {
auto child_info = std::make_unique<blink::ChildPendingURLLoaderFactoryBundle>(
std::move(info));
GetLoaderFactoryBundle()->Update(std::move(child_info));
}
void RenderFrameImpl::BindToFrame(blink::WebNavigationControl* frame) {
DCHECK(!frame_);
std::pair<FrameMap::iterator, bool> result =
g_frame_map.Get().emplace(frame, this);
CHECK(result.second) << "Inserting a duplicate item.";
frame_ = frame;
}
blink::WebPlugin* RenderFrameImpl::CreatePlugin(
const blink::WebPluginParams& params) {
blink::WebPlugin* plugin = nullptr;
if (GetContentClient()->renderer()->OverrideCreatePlugin(this, params,
&plugin)) {
return plugin;
}
#if BUILDFLAG(ENABLE_PPAPI)
WebPluginInfo info;
std::string mime_type;
bool found = false;
GetPepperHost()->GetPluginInfo(params.url, params.mime_type.Utf8(), &found,
&info, &mime_type);
if (!found)
return nullptr;
WebPluginParams params_to_use = params;
params_to_use.mime_type = WebString::FromUTF8(mime_type);
return CreatePlugin(info, params_to_use);
#else
return nullptr;
#endif
}
blink::WebMediaPlayer* RenderFrameImpl::CreateMediaPlayer(
const blink::WebMediaPlayerSource& source,
WebMediaPlayerClient* client,
blink::MediaInspectorContext* inspector_context,
WebMediaPlayerEncryptedMediaClient* encrypted_client,
WebContentDecryptionModule* initial_cdm,
const blink::WebString& sink_id,
const cc::LayerTreeSettings* settings,
scoped_refptr<base::TaskRunner> compositor_worker_task_runner) {
DCHECK(settings);
return media_factory_.CreateMediaPlayer(
source, client, inspector_context, encrypted_client, initial_cdm, sink_id,
GetLocalRootWebFrameWidget()->GetFrameSinkId(), *settings,
agent_scheduling_group_.agent_group_scheduler().CompositorTaskRunner(),
std::move(compositor_worker_task_runner));
}
#if BUILDFLAG(IS_OHOS)
blink::WebNativeBridge* RenderFrameImpl::CreateWebNativeBridge(
blink::WebNativeClient* client) {
return media_factory_.CreateWebNativeBridge(client);
}
#endif
std::unique_ptr<blink::WebContentSettingsClient>
RenderFrameImpl::CreateWorkerContentSettingsClient() {
if (!frame_ || !frame_->View())
return nullptr;
return GetContentClient()->renderer()->CreateWorkerContentSettingsClient(
this);
}
#if !BUILDFLAG(IS_ANDROID)
std::unique_ptr<media::SpeechRecognitionClient>
RenderFrameImpl::CreateSpeechRecognitionClient(
media::SpeechRecognitionClient::OnReadyCallback callback) {
if (!frame_ || !frame_->View())
return nullptr;
return GetContentClient()->renderer()->CreateSpeechRecognitionClient(
this, std::move(callback));
}
#endif
scoped_refptr<blink::WebWorkerFetchContext>
RenderFrameImpl::CreateWorkerFetchContext() {
ServiceWorkerNetworkProviderForFrame* provider =
static_cast<ServiceWorkerNetworkProviderForFrame*>(
frame_->GetDocumentLoader()->GetServiceWorkerNetworkProvider());
DCHECK(provider);
mojo::PendingReceiver<blink::mojom::RendererPreferenceWatcher>
watcher_receiver;
GetWebView()->RegisterRendererPreferenceWatcher(
watcher_receiver.InitWithNewPipeAndPassRemote());
mojo::PendingRemote<blink::mojom::ResourceLoadInfoNotifier>
pending_resource_load_info_notifier;
resource_load_info_notifier_receivers_.Add(
this,
pending_resource_load_info_notifier.InitWithNewPipeAndPassReceiver(),
agent_scheduling_group_.agent_group_scheduler().DefaultTaskRunner());
std::vector<std::string> cors_exempt_header_list =
RenderThreadImpl::current()->cors_exempt_header_list();
blink::WebVector<blink::WebString> web_cors_exempt_header_list(
cors_exempt_header_list.size());
base::ranges::transform(
cors_exempt_header_list, web_cors_exempt_header_list.begin(),
[](const auto& header) { return blink::WebString::FromLatin1(header); });
scoped_refptr<blink::WebDedicatedOrSharedWorkerFetchContext>
web_dedicated_or_shared_worker_fetch_context =
blink::WebDedicatedOrSharedWorkerFetchContext::Create(
provider->context(), GetWebView()->GetRendererPreferences(),
std::move(watcher_receiver), GetLoaderFactoryBundle()->Clone(),
GetLoaderFactoryBundle()->Clone(),
mojo::NullReceiver(),
web_cors_exempt_header_list,
std::move(pending_resource_load_info_notifier));
web_dedicated_or_shared_worker_fetch_context->set_ancestor_frame_id(
routing_id_);
web_dedicated_or_shared_worker_fetch_context->set_frame_request_blocker(
frame_request_blocker_);
web_dedicated_or_shared_worker_fetch_context->set_site_for_cookies(
frame_->GetDocument().SiteForCookies());
web_dedicated_or_shared_worker_fetch_context->set_top_frame_origin(
frame_->GetDocument().TopFrameOrigin());
for (auto& observer : observers_) {
observer.WillCreateWorkerFetchContext(
web_dedicated_or_shared_worker_fetch_context.get());
}
return web_dedicated_or_shared_worker_fetch_context;
}
scoped_refptr<blink::WebWorkerFetchContext>
RenderFrameImpl::CreateWorkerFetchContextForPlzDedicatedWorker(
blink::WebDedicatedWorkerHostFactoryClient* factory_client) {
DCHECK(base::FeatureList::IsEnabled(blink::features::kPlzDedicatedWorker));
DCHECK(factory_client);
mojo::PendingReceiver<blink::mojom::RendererPreferenceWatcher>
watcher_receiver;
GetWebView()->RegisterRendererPreferenceWatcher(
watcher_receiver.InitWithNewPipeAndPassRemote());
mojo::PendingRemote<blink::mojom::ResourceLoadInfoNotifier>
pending_resource_load_info_notifier;
resource_load_info_notifier_receivers_.Add(
this,
pending_resource_load_info_notifier.InitWithNewPipeAndPassReceiver(),
agent_scheduling_group_.agent_group_scheduler().DefaultTaskRunner());
scoped_refptr<blink::WebDedicatedOrSharedWorkerFetchContext>
web_dedicated_or_shared_worker_fetch_context =
static_cast<DedicatedWorkerHostFactoryClient*>(factory_client)
->CreateWorkerFetchContext(
GetWebView()->GetRendererPreferences(),
std::move(watcher_receiver),
std::move(pending_resource_load_info_notifier));
web_dedicated_or_shared_worker_fetch_context->set_ancestor_frame_id(
routing_id_);
web_dedicated_or_shared_worker_fetch_context->set_frame_request_blocker(
frame_request_blocker_);
web_dedicated_or_shared_worker_fetch_context->set_site_for_cookies(
frame_->GetDocument().SiteForCookies());
web_dedicated_or_shared_worker_fetch_context->set_top_frame_origin(
frame_->GetDocument().TopFrameOrigin());
for (auto& observer : observers_) {
observer.WillCreateWorkerFetchContext(
web_dedicated_or_shared_worker_fetch_context.get());
}
return web_dedicated_or_shared_worker_fetch_context;
}
std::unique_ptr<blink::WebPrescientNetworking>
RenderFrameImpl::CreatePrescientNetworking() {
return GetContentClient()->renderer()->CreatePrescientNetworking(this);
}
std::unique_ptr<blink::ResourceLoadInfoNotifierWrapper>
RenderFrameImpl::CreateResourceLoadInfoNotifierWrapper() {
return std::make_unique<blink::ResourceLoadInfoNotifierWrapper>(
weak_wrapper_resource_load_info_notifier_->AsWeakPtr());
}
std::unique_ptr<blink::WebServiceWorkerProvider>
RenderFrameImpl::CreateServiceWorkerProvider() {
if (!frame_->GetDocumentLoader())
return nullptr;
if (!ChildThreadImpl::current())
return nullptr;
ServiceWorkerNetworkProviderForFrame* provider =
static_cast<ServiceWorkerNetworkProviderForFrame*>(
frame_->GetDocumentLoader()->GetServiceWorkerNetworkProvider());
if (!provider->context()) {
return nullptr;
}
return std::make_unique<WebServiceWorkerProviderImpl>(provider->context());
}
blink::AssociatedInterfaceProvider*
RenderFrameImpl::GetRemoteNavigationAssociatedInterfaces() {
return GetRemoteAssociatedInterfaces();
}
namespace {
struct CreateChildFrameTraceEvent {
explicit CreateChildFrameTraceEvent(int routing_id) {
TRACE_EVENT_BEGIN("navigation,rail", "RenderFrameImpl::createChildFrame",
"routing_id", routing_id);
}
~CreateChildFrameTraceEvent() {
TRACE_EVENT_END("navigation,rail", "child_routing_id", child_routing_id);
}
int child_routing_id = -1;
};
}
blink::WebLocalFrame* RenderFrameImpl::CreateChildFrame(
blink::mojom::TreeScopeType scope,
const blink::WebString& name,
const blink::WebString& fallback_name,
const blink::FramePolicy& frame_policy,
const blink::WebFrameOwnerProperties& frame_owner_properties,
blink::FrameOwnerElementType frame_owner_element_type,
blink::WebPolicyContainerBindParams policy_container_bind_params,
ukm::SourceId document_ukm_source_id,
FinishChildFrameCreationFn finish_creation) {
CreateChildFrameTraceEvent trace_event(routing_id_);
int child_routing_id;
blink::LocalFrameToken frame_token;
base::UnguessableToken devtools_frame_token;
blink::DocumentToken document_token;
if (!RenderThread::Get()->GenerateFrameRoutingID(
child_routing_id, frame_token, devtools_frame_token,
document_token)) {
return nullptr;
}
trace_event.child_routing_id = child_routing_id;
bool is_created_by_script =
v8::Isolate::GetCurrent() && v8::Isolate::GetCurrent()->InContext();
std::string frame_unique_name =
unique_name_helper_.GenerateNameForNewChildFrame(
name.IsEmpty() ? fallback_name.Utf8() : name.Utf8(),
is_created_by_script);
mojo::PendingAssociatedReceiver<mojom::Frame> pending_frame_receiver;
mojo::PendingRemote<blink::mojom::BrowserInterfaceBroker>
browser_interface_broker;
mojo::PendingAssociatedRemote<blink::mojom::AssociatedInterfaceProvider>
associated_interface_provider;
GetFrameHost()->CreateChildFrame(
child_routing_id,
pending_frame_receiver.InitWithNewEndpointAndPassRemote(),
browser_interface_broker.InitWithNewPipeAndPassReceiver(),
blink::mojom::PolicyContainerBindParams::New(
std::move(policy_container_bind_params.receiver)),
associated_interface_provider.InitWithNewEndpointAndPassReceiver(), scope,
name.Utf8(), frame_unique_name, is_created_by_script, frame_policy,
blink::mojom::FrameOwnerProperties::From(frame_owner_properties),
frame_owner_element_type, document_ukm_source_id);
RenderFrameImpl* child_render_frame = RenderFrameImpl::Create(
agent_scheduling_group_, child_routing_id,
std::move(pending_frame_receiver), std::move(browser_interface_broker),
std::move(associated_interface_provider), devtools_frame_token);
child_render_frame->loader_factories_ = CloneLoaderFactories();
child_render_frame->unique_name_helper_.set_propagated_name(
frame_unique_name);
if (is_created_by_script)
child_render_frame->unique_name_helper_.Freeze();
blink::WebLocalFrame* web_frame = frame_->CreateLocalChild(
scope, child_render_frame,
child_render_frame->blink_interface_registry_.get(), frame_token);
finish_creation(web_frame, document_token);
child_render_frame->in_frame_tree_ = true;
child_render_frame->Initialize(GetWebFrame());
return web_frame;
}
void RenderFrameImpl::DidCreateFencedFrame(
const blink::RemoteFrameToken& frame_token) {
for (auto& observer : observers_)
observer.DidCreateFencedFrame(frame_token);
}
blink::WebFrame* RenderFrameImpl::FindFrame(const blink::WebString& name) {
if (GetBlinkPreferences().renderer_wide_named_frame_lookup) {
for (const auto& it : g_routing_id_frame_map.Get()) {
WebLocalFrame* frame = it.second->GetWebFrame();
if (frame->AssignedName() == name)
return frame;
}
}
return GetContentClient()->renderer()->FindFrame(this->GetWebFrame(),
name.Utf8());
}
void RenderFrameImpl::WillSwap() {
if (navigation_client_impl_ &&
ShouldQueueNavigationsWhenPendingCommitRFHExists()) {
navigation_client_impl_->ResetWithoutCancelling();
}
}
void RenderFrameImpl::WillDetach() {
for (auto& observer : observers_)
observer.WillDetach();
auto& factory = blink::AudioOutputIPCFactory::GetInstance();
if (factory.io_task_runner())
factory.MaybeDeregisterRemoteFactory(GetWebFrame()->GetLocalFrameToken());
SendUpdateState();
}
void RenderFrameImpl::FrameDetached() {
auto it = g_frame_map.Get().find(frame_);
CHECK(it != g_frame_map.Get().end());
CHECK_EQ(it->second, this);
g_frame_map.Get().erase(it);
render_accessibility_manager_.reset();
frame_->Close();
frame_ = nullptr;
if (mhtml_body_loader_client_) {
mhtml_body_loader_client_->Detach();
mhtml_body_loader_client_.reset();
}
delete this;
}
void RenderFrameImpl::DidChangeName(const blink::WebString& name) {
if (GetWebFrame()->GetCurrentHistoryItem().IsNull()) {
unique_name_helper_.UpdateName(name.Utf8());
}
GetFrameHost()->DidChangeName(name.Utf8(), unique_name_helper_.value());
}
void RenderFrameImpl::DidMatchCSS(
const blink::WebVector<blink::WebString>& newly_matching_selectors,
const blink::WebVector<blink::WebString>& stopped_matching_selectors) {
for (auto& observer : observers_)
observer.DidMatchCSS(newly_matching_selectors, stopped_matching_selectors);
}
bool RenderFrameImpl::ShouldReportDetailedMessageForSourceAndSeverity(
blink::mojom::ConsoleMessageLevel log_level,
const blink::WebString& source) {
if (want_error_message_stack_trace_ &&
log_level == blink::mojom::ConsoleMessageLevel::kError) {
return true;
}
return GetContentClient()->renderer()->ShouldReportDetailedMessageForSource(
source.Utf16());
}
void RenderFrameImpl::DidAddMessageToConsole(
const blink::WebConsoleMessage& message,
const blink::WebString& source_name,
unsigned source_line,
const blink::WebString& stack_trace) {
if (ShouldReportDetailedMessageForSourceAndSeverity(message.level,
source_name)) {
for (auto& observer : observers_) {
observer.DetailedConsoleMessageAdded(
message.text.Utf16(), source_name.Utf16(), stack_trace.Utf16(),
source_line, message.level);
}
}
}
void RenderFrameImpl::DidCreateDocumentLoader(
blink::WebDocumentLoader* document_loader) {
DocumentState* document_state =
DocumentState::FromDocumentLoader(document_loader);
if (!document_state) {
document_loader->SetExtraData(BuildDocumentState());
document_loader->SetServiceWorkerNetworkProvider(
ServiceWorkerNetworkProviderForFrame::CreateInvalidInstance());
}
document_loader->SetCodeCacheHost(std::move(pending_code_cache_host_));
}
void RenderFrameImpl::DidCommitNavigation(
blink::WebHistoryCommitType commit_type,
bool should_reset_browser_interface_broker,
const blink::ParsedPermissionsPolicy& permissions_policy_header,
const blink::DocumentPolicyFeatureState& document_policy_header) {
CHECK_EQ(NavigationCommitState::kWillCommit, navigation_commit_state_);
navigation_commit_state_ = NavigationCommitState::kDidCommit;
WebDocumentLoader* document_loader = frame_->GetDocumentLoader();
DocumentState* document_state =
DocumentState::FromDocumentLoader(document_loader);
NavigationState* navigation_state = document_state->navigation_state();
DCHECK(!navigation_state->WasWithinSameDocument());
TRACE_EVENT2("navigation,benchmark,rail",
"RenderFrameImpl::didStartProvisionalLoad", "id", routing_id_,
"url", document_loader->GetUrl().GetString().Utf8());
if (pending_loader_factories_) {
loader_factories_ = std::move(pending_loader_factories_);
}
DCHECK(loader_factories_);
DCHECK(loader_factories_->HasBoundDefaultFactory());
if (!navigation_state->was_initiated_in_this_frame()) {
for (auto& observer : observers_)
observer.DidStartNavigation(document_loader->GetUrl(), absl::nullopt);
}
for (auto& observer : observers_)
observer.ReadyToCommitNavigation(document_loader);
for (auto& observer : observers_)
observer.DidCreateNewDocument();
DVLOG(1) << "Committed provisional load: "
<< TrimURL(GetLoadingUrl().possibly_invalid_spec());
TRACE_EVENT2("navigation,rail", "RenderFrameImpl::didCommitProvisionalLoad",
"id", routing_id_, "url",
GetLoadingUrl().possibly_invalid_spec());
if (base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kWaitForDebuggerOnNavigation)) {
std::string renderer =
base::StrCat({"Renderer url=\"",
TrimURL(GetLoadingUrl().possibly_invalid_spec()), "\""});
content::WaitForDebugger(renderer);
}
GetWebFrame()->SetEmbeddingToken(base::UnguessableToken::Create());
mojo::PendingReceiver<blink::mojom::BrowserInterfaceBroker>
browser_interface_broker_receiver;
if (should_reset_browser_interface_broker) {
browser_interface_broker_receiver = browser_interface_broker_proxy_.Reset(
agent_scheduling_group_.agent_group_scheduler().DefaultTaskRunner());
auto& factory = blink::AudioOutputIPCFactory::GetInstance();
if (factory.io_task_runner()) {
factory.MaybeDeregisterRemoteFactory(GetWebFrame()->GetLocalFrameToken());
factory.RegisterRemoteFactory(GetWebFrame()->GetLocalFrameToken(),
GetBrowserInterfaceBroker());
}
audio_input_stream_factory_.reset();
render_accessibility_manager_->CloseConnection();
}
if (media_permission_dispatcher_)
media_permission_dispatcher_->OnNavigation();
ui::PageTransition transition =
GetTransitionType(frame_->GetDocumentLoader(), IsMainFrame(),
GetWebView()->IsFencedFrameRoot());
if (pending_cookie_manager_info_ &&
pending_cookie_manager_info_->origin ==
url::Origin(frame_->GetDocument().GetSecurityOrigin())) {
frame_->GetDocument().SetCookieManager(
std::move(pending_cookie_manager_info_->cookie_manager));
}
if (pending_storage_info_ &&
original_storage_key_.origin() ==
url::Origin(frame_->GetDocument().GetSecurityOrigin())) {
if (pending_storage_info_->local_storage_area) {
frame_->SetLocalStorageArea(
std::move(pending_storage_info_->local_storage_area));
}
if (pending_storage_info_->session_storage_area) {
frame_->SetSessionStorageArea(
std::move(pending_storage_info_->session_storage_area));
}
}
if (pending_resource_cache_.is_valid()) {
CHECK(base::FeatureList::IsEnabled(blink::features::kRemoteResourceCache));
frame_->SetResourceCacheRemote(std::move(pending_resource_cache_));
}
DidCommitNavigationInternal(
commit_type, transition, permissions_policy_header,
document_policy_header,
should_reset_browser_interface_broker
? mojom::DidCommitProvisionalLoadInterfaceParams::New(
std::move(browser_interface_broker_receiver))
: nullptr,
nullptr , GetWebFrame()->GetEmbeddingToken());
navigation_state->set_transition_type(ui::PAGE_TRANSITION_LINK);
UpdateEncoding(frame_, frame_->View()->PageEncoding().Utf8());
NotifyObserversOfNavigationCommit(transition);
document_state->clear_navigation_state();
ResetMembersUsedForDurationOfCommit();
}
void RenderFrameImpl::DidCommitDocumentReplacementNavigation(
blink::WebDocumentLoader* document_loader) {
DocumentState::FromDocumentLoader(document_loader)
->set_navigation_state(NavigationState::CreateForSynchronousCommit());
for (auto& observer : observers_)
observer.DidStartNavigation(document_loader->GetUrl(), absl::nullopt);
for (auto& observer : observers_)
observer.ReadyToCommitNavigation(document_loader);
for (auto& observer : observers_)
observer.DidCreateNewDocument();
ui::PageTransition transition = GetTransitionType(
document_loader, IsMainFrame(), GetWebView()->IsFencedFrameRoot());
NotifyObserversOfNavigationCommit(transition);
}
void RenderFrameImpl::DidClearWindowObject() {
if (enabled_bindings_ & BINDINGS_POLICY_WEB_UI)
WebUIExtension::Install(frame_);
const base::CommandLine& command_line =
*base::CommandLine::ForCurrentProcess();
if (command_line.HasSwitch(switches::kDomAutomationController))
DomAutomationController::Install(this, frame_);
if (command_line.HasSwitch(switches::kStatsCollectionController))
StatsCollectionController::Install(frame_);
if (command_line.HasSwitch(cc::switches::kEnableGpuBenchmarking))
GpuBenchmarking::Install(weak_factory_.GetWeakPtr());
if (command_line.HasSwitch(switches::kEnableSkiaBenchmarking))
SkiaBenchmarking::Install(frame_);
for (auto& observer : observers_)
observer.DidClearWindowObject();
}
void RenderFrameImpl::DidCreateDocumentElement() {
for (auto& observer : observers_)
observer.DidCreateDocumentElement();
}
void RenderFrameImpl::RunScriptsAtDocumentElementAvailable() {
if (!initialized_)
return;
GetContentClient()->renderer()->RunScriptsAtDocumentStart(this);
}
#if defined(OHOS_JSPROXY)
void RenderFrameImpl::RunScriptsAtHeadReady() {
if (!initialized_) {
return;
}
if (GetContentClient() && GetContentClient()->renderer()) {
GetContentClient()->renderer()->RunScriptsAtHeadReady(this);
}
}
#endif
void RenderFrameImpl::DidReceiveTitle(const blink::WebString& title) {
if (!frame_->Parent() && !title.IsEmpty()) {
base::trace_event::TraceLog::GetInstance()->UpdateProcessLabel(
routing_id_, title.Utf8());
} else {
GURL loading_url = GetLoadingUrl();
if (!loading_url.host().empty() &&
loading_url.scheme() != url::kFileScheme) {
std::string frame_title;
if (frame_->Parent()) {
frame_title += "Subframe: ";
}
frame_title += loading_url.DeprecatedGetOriginAsURL().spec();
base::trace_event::TraceLog::GetInstance()->UpdateProcessLabel(
routing_id_, frame_title);
}
}
UpdateEncoding(frame_, frame_->View()->PageEncoding().Utf8());
}
void RenderFrameImpl::DidDispatchDOMContentLoadedEvent() {
TRACE_EVENT1("navigation,benchmark,rail",
"RenderFrameImpl::DidDispatchDOMContentLoadedEvent", "id",
routing_id_);
for (auto& observer : observers_)
observer.DidDispatchDOMContentLoadedEvent();
UpdateEncoding(frame_, frame_->View()->PageEncoding().Utf8());
}
void RenderFrameImpl::RunScriptsAtDocumentReady() {
DCHECK(initialized_);
GetContentClient()->renderer()->RunScriptsAtDocumentEnd(this);
}
void RenderFrameImpl::RunScriptsAtDocumentIdle() {
GetContentClient()->renderer()->RunScriptsAtDocumentIdle(this);
}
void RenderFrameImpl::DidHandleOnloadEvents() {
for (auto& observer : observers_)
observer.DidHandleOnloadEvents();
}
void RenderFrameImpl::DidFinishLoad() {
TRACE_EVENT1("navigation,benchmark,rail", "RenderFrameImpl::didFinishLoad",
"id", routing_id_);
if (!frame_->Parent()) {
TRACE_EVENT_INSTANT1("WebCore,benchmark,rail", "LoadFinished",
TRACE_EVENT_SCOPE_PROCESS, "isOutermostMainFrame",
frame_->IsOutermostMainFrame());
}
for (auto& observer : observers_) {
observer.DidFinishLoad();
}
}
void RenderFrameImpl::DidFinishLoadForPrinting() {
for (auto& observer : observers_)
observer.DidFinishLoadForPrinting();
}
#ifdef OHOS_ARKWEB_ADBLOCK
void RenderFrameImpl::DidSubresourceFiltered() {
TRACE_EVENT1("navigation, benchmark, rail",
"RenderFrameImpl::DidSubresourceFiltered", "id", routing_id_);
for (auto& observer : observers_){
observer.DidSubresourceFiltered();
}
}
bool RenderFrameImpl::GetGlobalAdblockEnabled() {
return GetRendererPreferences().is_global_adblock_enabled;
}
void RenderFrameImpl::OnUpdateAdBlockEnabledToRender(
bool site_adblock_enabled) {
if (GetWebView()) {
LOG(INFO) << "[Adblock] render frame update adblock:"
<< site_adblock_enabled;
GetWebView()->OnSetAdBlockEnable(site_adblock_enabled);
}
if (!frame_) {
return;
}
WebDocumentLoader* document_loader = frame_->GetDocumentLoader();
if (!document_loader) {
return;
}
blink::WebDocumentSubresourceFilter* filter =
document_loader->GetWebSubresourceFilter();
if (filter) {
filter->set_activation_state(site_adblock_enabled);
}
}
#endif
void RenderFrameImpl::DidFinishSameDocumentNavigation(
blink::WebHistoryCommitType commit_type,
bool is_synchronously_committed,
blink::mojom::SameDocumentNavigationType same_document_navigation_type,
bool is_client_redirect) {
TRACE_EVENT1("navigation,rail",
"RenderFrameImpl::didFinishSameDocumentNavigation", "id",
routing_id_);
WebDocumentLoader* document_loader = frame_->GetDocumentLoader();
DocumentState* document_state =
DocumentState::FromDocumentLoader(document_loader);
if (is_synchronously_committed) {
document_state->set_navigation_state(
NavigationState::CreateForSynchronousCommit());
}
document_state->navigation_state()->set_was_within_same_document(true);
ui::PageTransition transition = GetTransitionType(
document_loader, IsMainFrame(), GetWebView()->IsFencedFrameRoot());
auto same_document_params =
mojom::DidCommitSameDocumentNavigationParams::New();
same_document_params->same_document_navigation_type =
same_document_navigation_type;
same_document_params->is_client_redirect = is_client_redirect;
same_document_params->started_with_transient_activation =
document_loader->LastNavigationHadTransientUserActivation();
same_document_params->should_replace_current_entry =
document_loader->ReplacesCurrentHistoryItem();
DidCommitNavigationInternal(
commit_type, transition,
blink::ParsedPermissionsPolicy(),
blink::DocumentPolicyFeatureState(),
nullptr,
std::move(same_document_params),
absl::nullopt
);
document_state->navigation_state()->set_transition_type(
ui::PAGE_TRANSITION_LINK);
for (auto& observer : observers_)
observer.DidFinishSameDocumentNavigation();
document_state->clear_navigation_state();
}
void RenderFrameImpl::DidFailAsyncSameDocumentCommit() {
DocumentState* document_state =
DocumentState::FromDocumentLoader(frame_->GetDocumentLoader());
if (NavigationState* navigation_state = document_state->navigation_state()) {
navigation_state->RunCommitSameDocumentNavigationCallback(
blink::mojom::CommitResult::Aborted);
document_state->clear_navigation_state();
}
}
void RenderFrameImpl::WillFreezePage() {
SendUpdateState();
}
void RenderFrameImpl::DidOpenDocumentInputStream(const blink::WebURL& url) {
GetFrameHost()->DidOpenDocumentInputStream(url);
}
void RenderFrameImpl::DidSetPageLifecycleState() {
for (auto& observer : observers_)
observer.DidSetPageLifecycleState();
}
void RenderFrameImpl::NotifyCurrentHistoryItemChanged() {
SendUpdateState();
}
void RenderFrameImpl::DidUpdateCurrentHistoryItem() {
StartDelayedSyncTimer();
}
void RenderFrameImpl::StartDelayedSyncTimer() {
base::TimeDelta delay;
if (send_content_state_immediately_) {
SendUpdateState();
return;
} else if (GetWebView()->GetVisibilityState() !=
blink::mojom::PageVisibilityState::kVisible)
delay = kDelaySecondsForContentStateSyncHidden;
else
delay = kDelaySecondsForContentStateSync;
if (delayed_state_sync_timer_.IsRunning()) {
if (delayed_state_sync_timer_.GetCurrentDelay() == delay)
return;
delayed_state_sync_timer_.Stop();
}
delayed_state_sync_timer_.Start(FROM_HERE, delay, this,
&RenderFrameImpl::SendUpdateState);
}
bool RenderFrameImpl::SwapOutAndDeleteThis(
bool is_loading,
blink::mojom::FrameReplicationStatePtr replicated_frame_state,
const blink::RemoteFrameToken& proxy_frame_token,
blink::mojom::RemoteFrameInterfacesFromBrowserPtr remote_frame_interfaces,
blink::mojom::RemoteMainFrameInterfacesPtr remote_main_frame_interfaces) {
TRACE_EVENT1("navigation,rail", "RenderFrameImpl::SwapOutAndDeleteThis", "id",
routing_id_);
DCHECK(!base::RunLoop::IsNestedOnCurrentThread());
blink::WebRemoteFrame* remote_frame = blink::WebRemoteFrame::Create(
frame_->GetTreeScopeType(), proxy_frame_token);
blink::WebView* web_view = GetWebView();
bool is_main_frame = is_main_frame_;
bool success =
frame_->Swap(remote_frame, std::move(remote_frame_interfaces->frame_host),
std::move(remote_frame_interfaces->frame_receiver),
std::move(replicated_frame_state));
if (is_main_frame) {
DCHECK(success);
web_view->DidAttachRemoteMainFrame(
std::move(remote_main_frame_interfaces->main_frame_host),
std::move(remote_main_frame_interfaces->main_frame));
}
if (!success) {
remote_frame->Close();
return false;
}
if (is_loading)
remote_frame->DidStartLoading();
return true;
}
base::UnguessableToken RenderFrameImpl::GetDevToolsFrameToken() {
return devtools_frame_token_;
}
void RenderFrameImpl::AbortClientNavigation() {
CHECK(in_frame_tree_);
browser_side_navigation_pending_ = false;
if (mhtml_body_loader_client_) {
mhtml_body_loader_client_->Detach();
mhtml_body_loader_client_.reset();
}
NotifyObserversOfFailedProvisionalLoad();
navigation_client_impl_.reset();
}
void RenderFrameImpl::DidChangeSelection(bool is_empty_selection,
blink::SyncCondition force_sync) {
if (!GetLocalRootWebFrameWidget()->HandlingInputEvent() &&
!GetLocalRootWebFrameWidget()->HandlingSelectRange())
return;
if (is_empty_selection)
selection_text_.clear();
GetLocalRootWebFrameWidget()->UpdateTextInputState();
SyncSelectionIfRequired(force_sync);
}
void RenderFrameImpl::OnMainFrameIntersectionChanged(
const gfx::Rect& main_frame_intersection_rect) {
if (main_frame_intersection_rect != main_frame_intersection_rect_) {
main_frame_intersection_rect_ = main_frame_intersection_rect;
for (auto& observer : observers_) {
observer.OnMainFrameIntersectionChanged(main_frame_intersection_rect);
}
}
}
void RenderFrameImpl::OnMainFrameViewportRectangleChanged(
const gfx::Rect& main_frame_viewport_rect) {
if (main_frame_viewport_rect != main_frame_viewport_rect_) {
main_frame_viewport_rect_ = main_frame_viewport_rect;
for (auto& observer : observers_) {
observer.OnMainFrameViewportRectangleChanged(main_frame_viewport_rect);
}
}
}
void RenderFrameImpl::OnMainFrameImageAdRectangleChanged(
int element_id,
const gfx::Rect& image_ad_rect) {
for (auto& observer : observers_) {
observer.OnMainFrameImageAdRectangleChanged(element_id, image_ad_rect);
}
}
void RenderFrameImpl::OnOverlayPopupAdDetected() {
for (auto& observer : observers_) {
observer.OnOverlayPopupAdDetected();
}
}
void RenderFrameImpl::OnLargeStickyAdDetected() {
for (auto& observer : observers_) {
observer.OnLargeStickyAdDetected();
}
}
void RenderFrameImpl::WillSendRequest(blink::WebURLRequest& request,
ForRedirect for_redirect) {
WillSendRequestInternal(request, false,
ui::PAGE_TRANSITION_LINK, for_redirect);
for (auto& observer : observers_) {
observer.WillSendRequest(request);
}
}
void RenderFrameImpl::WillSendRequestInternal(
blink::WebURLRequest& request,
bool for_outermost_main_frame,
ui::PageTransition transition_type,
ForRedirect for_redirect) {
if (GetWebView()->GetRendererPreferences().enable_do_not_track) {
request.SetHttpHeaderField(
blink::WebString::FromUTF8(blink::kDoNotTrackHeader), "1");
}
ApplyFilePathAlias(&request);
GURL new_url;
absl::optional<url::Origin> initiator_origin =
request.RequestorOrigin().IsNull()
? absl::optional<url::Origin>()
: absl::optional<url::Origin>(request.RequestorOrigin());
GetContentClient()->renderer()->WillSendRequest(
frame_, transition_type, request.Url(), request.SiteForCookies(),
base::OptionalToPtr(initiator_origin), &new_url);
if (!new_url.is_empty())
request.SetUrl(WebURL(new_url));
WebString custom_user_agent;
if (request.GetURLRequestExtraData()) {
blink::WebURLRequestExtraData* old_request_extra_data =
static_cast<blink::WebURLRequestExtraData*>(
request.GetURLRequestExtraData().get());
custom_user_agent = old_request_extra_data->custom_user_agent();
if (!custom_user_agent.IsNull()) {
if (custom_user_agent.IsEmpty())
request.ClearHttpHeaderField("User-Agent");
else
request.SetHttpHeaderField("User-Agent", custom_user_agent);
}
}
if (!request.GetURLRequestExtraData()) {
request.SetURLRequestExtraData(
base::MakeRefCounted<blink::WebURLRequestExtraData>());
}
auto* url_request_extra_data = static_cast<blink::WebURLRequestExtraData*>(
request.GetURLRequestExtraData().get());
url_request_extra_data->set_custom_user_agent(custom_user_agent);
url_request_extra_data->set_is_outermost_main_frame(IsMainFrame() &&
!IsInFencedFrameTree());
url_request_extra_data->set_transition_type(transition_type);
bool is_for_no_state_prefetch =
GetContentClient()->renderer()->IsPrefetchOnly(this);
url_request_extra_data->set_is_for_no_state_prefetch(
is_for_no_state_prefetch);
url_request_extra_data->set_frame_request_blocker(frame_request_blocker_);
url_request_extra_data->set_allow_cross_origin_auth_prompt(
GetWebView()->GetRendererPreferences().allow_cross_origin_auth_prompt);
url_request_extra_data->set_top_frame_origin(GetSecurityOriginOfTopFrame());
request.SetDownloadToNetworkCacheOnly(is_for_no_state_prefetch &&
!for_outermost_main_frame);
RenderThreadImpl* render_thread = RenderThreadImpl::current();
if (!for_redirect && render_thread &&
render_thread->url_loader_throttle_provider()) {
url_request_extra_data->set_url_loader_throttles(
render_thread->url_loader_throttle_provider()->CreateThrottles(
routing_id_, request));
}
request.SetHasUserGesture(frame_->HasTransientUserActivation());
if (!GetWebView()->GetRendererPreferences().enable_referrers) {
request.SetReferrerString(WebString());
request.SetReferrerPolicy(network::mojom::ReferrerPolicy::kNever);
}
}
void RenderFrameImpl::DidLoadResourceFromMemoryCache(
const blink::WebURLRequest& request,
const blink::WebURLResponse& response) {
for (auto& observer : observers_) {
observer.DidLoadResourceFromMemoryCache(
request.Url(), response.RequestId(), response.EncodedBodyLength(),
response.MimeType().Utf8(), response.FromArchive());
}
}
void RenderFrameImpl::DidStartResponse(
const url::SchemeHostPort& final_response_url,
int request_id,
network::mojom::URLResponseHeadPtr response_head,
network::mojom::RequestDestination request_destination) {
for (auto& observer : observers_) {
observer.DidStartResponse(final_response_url, request_id, *response_head,
request_destination);
}
}
void RenderFrameImpl::DidCompleteResponse(
int request_id,
const network::URLLoaderCompletionStatus& status) {
for (auto& observer : observers_)
observer.DidCompleteResponse(request_id, status);
}
void RenderFrameImpl::DidCancelResponse(int request_id) {
for (auto& observer : observers_)
observer.DidCancelResponse(request_id);
}
void RenderFrameImpl::DidReceiveTransferSizeUpdate(int resource_id,
int received_data_length) {
for (auto& observer : observers_) {
observer.DidReceiveTransferSizeUpdate(resource_id, received_data_length);
}
}
void RenderFrameImpl::DidChangePerformanceTiming() {
for (auto& observer : observers_)
observer.DidChangePerformanceTiming();
}
void RenderFrameImpl::DidObserveInputDelay(base::TimeDelta input_delay) {
for (auto& observer : observers_)
observer.DidObserveInputDelay(input_delay);
}
void RenderFrameImpl::DidObserveUserInteraction(
base::TimeDelta max_event_duration,
blink::UserInteractionType interaction_type) {
for (auto& observer : observers_)
observer.DidObserveUserInteraction(max_event_duration, interaction_type);
}
void RenderFrameImpl::DidChangeCpuTiming(base::TimeDelta time) {
for (auto& observer : observers_)
observer.DidChangeCpuTiming(time);
}
void RenderFrameImpl::DidObserveLoadingBehavior(
blink::LoadingBehaviorFlag behavior) {
for (auto& observer : observers_)
observer.DidObserveLoadingBehavior(behavior);
}
void RenderFrameImpl::DidObserveSubresourceLoad(
const blink::SubresourceLoadMetrics& subresource_load_metrics) {
for (auto& observer : observers_)
observer.DidObserveSubresourceLoad(subresource_load_metrics);
}
void RenderFrameImpl::DidObserveNewFeatureUsage(
const blink::UseCounterFeature& feature) {
for (auto& observer : observers_)
observer.DidObserveNewFeatureUsage(feature);
}
void RenderFrameImpl::DidObserveSoftNavigation(uint32_t count) {
for (auto& observer : observers_) {
observer.DidObserveSoftNavigation(count);
}
}
void RenderFrameImpl::DidObserveLayoutShift(double score,
bool after_input_or_scroll) {
for (auto& observer : observers_)
observer.DidObserveLayoutShift(score, after_input_or_scroll);
}
void RenderFrameImpl::DidCreateScriptContext(v8::Local<v8::Context> context,
int world_id) {
v8::MicrotasksScope microtasks(blink::MainThreadIsolate(),
context->GetMicrotaskQueue(),
v8::MicrotasksScope::kDoNotRunMicrotasks);
if (((enabled_bindings_ & BINDINGS_POLICY_MOJO_WEB_UI) ||
enable_mojo_js_bindings_) &&
IsMainFrame() && world_id == ISOLATED_WORLD_ID_GLOBAL) {
#if BUILDFLAG(IS_OHOS)
LOG(WARNING) << "MojoJS ability is disabled for security reasons.";
#else
blink::WebV8Features::EnableMojoJS(context, true);
#endif
if (mojo_js_features_) {
if (mojo_js_features_->file_system_access)
blink::WebV8Features::EnableMojoJSFileSystemAccessHelper(context, true);
}
}
#if BUILDFLAG(IS_OHOS)
else {
LOG(WARNING) << "For security reasons MojoJS is forcibly disabled.";
}
#endif
if (world_id == ISOLATED_WORLD_ID_GLOBAL &&
mojo_js_interface_broker_.is_valid()) {
blink::WebV8Features::EnableMojoJSAndUseBroker(
context, std::move(mojo_js_interface_broker_));
}
for (auto& observer : observers_)
observer.DidCreateScriptContext(context, world_id);
}
void RenderFrameImpl::WillReleaseScriptContext(v8::Local<v8::Context> context,
int world_id) {
for (auto& observer : observers_)
observer.WillReleaseScriptContext(context, world_id);
}
void RenderFrameImpl::DidChangeScrollOffset() {
StartDelayedSyncTimer();
for (auto& observer : observers_)
observer.DidChangeScrollOffset();
}
void RenderFrameImpl::PreloadSubresourceOptimizationsForOrigins(
const std::vector<blink::WebSecurityOrigin>& origins) {
for (auto& observer : observers_)
observer.PreloadSubresourceOptimizationsForOrigins(origins);
}
blink::WebMediaStreamDeviceObserver*
RenderFrameImpl::MediaStreamDeviceObserver() {
if (!web_media_stream_device_observer_)
InitializeMediaStreamDeviceObserver();
return web_media_stream_device_observer_.get();
}
blink::WebEncryptedMediaClient* RenderFrameImpl::EncryptedMediaClient() {
return media_factory_.EncryptedMediaClient();
}
blink::WebString RenderFrameImpl::UserAgentOverride() {
if (ShouldUseUserAgentOverride()) {
return WebString::FromUTF8(GetWebView()
->GetRendererPreferences()
.user_agent_override.ua_string_override);
}
return blink::WebString();
}
absl::optional<blink::UserAgentMetadata>
RenderFrameImpl::UserAgentMetadataOverride() {
if (ShouldUseUserAgentOverride()) {
return GetWebView()
->GetRendererPreferences()
.user_agent_override.ua_metadata_override;
}
return absl::nullopt;
}
bool RenderFrameImpl::ShouldUseUserAgentOverride() const {
auto* web_view = GetWebView();
if (web_view->MainFrame()->IsWebRemoteFrame())
return false;
const WebLocalFrame* main_frame = web_view->MainFrame()->ToWebLocalFrame();
WebDocumentLoader* document_loader = main_frame->GetDocumentLoader();
DocumentState* document_state =
document_loader ? DocumentState::FromDocumentLoader(document_loader)
: nullptr;
return document_state && document_state->is_overriding_user_agent();
}
blink::mojom::RendererAudioInputStreamFactory*
RenderFrameImpl::GetAudioInputStreamFactory() {
if (!audio_input_stream_factory_)
GetBrowserInterfaceBroker()->GetInterface(
audio_input_stream_factory_.BindNewPipeAndPassReceiver(
agent_scheduling_group_.agent_group_scheduler()
.DefaultTaskRunner()));
return audio_input_stream_factory_.get();
}
bool RenderFrameImpl::AllowContentInitiatedDataUrlNavigations(
const blink::WebURL& url) {
return url.GetString() == kUnreachableWebDataURL;
}
void RenderFrameImpl::PostAccessibilityEvent(const ui::AXEvent& event) {
if (!IsAccessibilityEnabled())
return;
render_accessibility_manager_->GetRenderAccessibilityImpl()->HandleAXEvent(
event);
}
void RenderFrameImpl::NotifyWebAXObjectMarkedDirty(
const blink::WebAXObject& obj) {
if (!IsAccessibilityEnabled())
return;
render_accessibility_manager_->GetRenderAccessibilityImpl()
->NotifyWebAXObjectMarkedDirty(obj);
}
void RenderFrameImpl::AXReadyCallback() {
if (!IsAccessibilityEnabled())
return;
render_accessibility_manager_->GetRenderAccessibilityImpl()
->AXReadyCallback();
}
void RenderFrameImpl::AddObserver(RenderFrameObserver* observer) {
observers_.AddObserver(observer);
}
void RenderFrameImpl::RemoveObserver(RenderFrameObserver* observer) {
observer->RenderFrameGone();
observers_.RemoveObserver(observer);
}
void RenderFrameImpl::OnDroppedNavigation() {
browser_side_navigation_pending_ = false;
frame_->DidDropNavigation();
}
void RenderFrameImpl::WasHidden() {
frame_->WasHidden();
for (auto& observer : observers_)
observer.WasHidden();
#if BUILDFLAG(ENABLE_PPAPI)
for (auto* plugin : active_pepper_instances_)
plugin->PageVisibilityChanged(false);
#endif
}
void RenderFrameImpl::WasShown() {
frame_->WasShown();
for (auto& observer : observers_)
observer.WasShown();
#if BUILDFLAG(ENABLE_PPAPI)
for (auto* plugin : active_pepper_instances_)
plugin->PageVisibilityChanged(true);
#endif
}
bool RenderFrameImpl::IsMainFrame() {
return is_main_frame_;
}
bool RenderFrameImpl::IsInFencedFrameTree() const {
return GetWebFrame()->IsInFencedFrameTree();
}
bool RenderFrameImpl::IsHidden() {
return GetLocalRootWebFrameWidget()->IsHidden();
}
bool RenderFrameImpl::IsLocalRoot() const {
return !(frame_->Parent() && frame_->Parent()->IsWebLocalFrame());
}
const RenderFrameImpl* RenderFrameImpl::GetLocalRoot() const {
return IsLocalRoot() ? this
: RenderFrameImpl::FromWebFrame(frame_->LocalRoot());
}
mojom::DidCommitProvisionalLoadParamsPtr
RenderFrameImpl::MakeDidCommitProvisionalLoadParams(
blink::WebHistoryCommitType commit_type,
ui::PageTransition transition,
const blink::ParsedPermissionsPolicy& permissions_policy_header,
const blink::DocumentPolicyFeatureState& document_policy_header,
const absl::optional<base::UnguessableToken>& embedding_token) {
WebDocumentLoader* document_loader = frame_->GetDocumentLoader();
const WebURLResponse& response = document_loader->GetWebResponse();
DocumentState* document_state =
DocumentState::FromDocumentLoader(frame_->GetDocumentLoader());
NavigationState* navigation_state = document_state->navigation_state();
auto params = mojom::DidCommitProvisionalLoadParams::New();
params->http_status_code = response.HttpStatusCode();
params->url_is_unreachable = document_loader->HasUnreachableURL();
params->method = "GET";
params->post_id = -1;
params->embedding_token = embedding_token;
params->origin_calculation_debug_info =
document_loader->OriginCalculationDebugInfo().Utf8();
params->navigation_token = navigation_state->commit_params().navigation_token;
if (params->navigation_token.is_empty())
params->navigation_token = base::UnguessableToken::Create();
params->did_create_new_entry =
(commit_type == blink::kWebStandardCommit) ||
(commit_type == blink::kWebHistoryInertCommit && !frame_->Parent() &&
document_loader->ReplacesCurrentHistoryItem() &&
!navigation_state->WasWithinSameDocument());
WebDocument frame_document = frame_->GetDocument();
WebSecurityOrigin frame_origin = frame_document.GetSecurityOrigin();
params->origin = frame_origin;
params->permissions_policy_header = permissions_policy_header;
params->document_policy_header = document_policy_header;
params->insecure_request_policy = frame_->GetInsecureRequestPolicy();
params->insecure_navigations_set =
frame_->GetInsecureRequestToUpgrade().ReleaseVector();
params->has_potentially_trustworthy_unique_origin =
frame_origin.IsOpaque() && frame_origin.IsPotentiallyTrustworthy();
params->url = GetLoadingUrl();
if (blink::features::IsNewBaseUrlInheritanceBehaviorEnabled() &&
(params->url.IsAboutBlank() || params->url.IsAboutSrcdoc())) {
params->initiator_base_url = frame_document.BaseURL();
}
params->should_update_history =
!document_loader->HasUnreachableURL() && response.HttpStatusCode() != 404;
const WebHistoryItem& item = GetWebFrame()->GetCurrentHistoryItem();
params->page_state = GetWebFrame()->CurrentHistoryItemToPageState();
params->method = document_loader->HttpMethod().Latin1();
if (params->method == "POST")
params->post_id = ExtractPostId(item);
params->item_sequence_number = item.ItemSequenceNumber();
params->document_sequence_number = item.DocumentSequenceNumber();
params->navigation_api_key = item.GetNavigationApiKey().Utf8();
params->referrer = blink::mojom::Referrer::New(
blink::WebStringToGURL(document_loader->Referrer()),
network::mojom::ReferrerPolicy::kDefault);
if (!frame_->Parent()) {
params->contents_mime_type =
document_loader->GetWebResponse().MimeType().Utf8();
params->transition = transition;
if (GetWebView()->IsFencedFrameRoot()) {
DCHECK(ui::PageTransitionCoreTypeIs(params->transition,
ui::PAGE_TRANSITION_AUTO_SUBFRAME));
} else {
DCHECK(ui::PageTransitionIsMainFrame(params->transition));
}
if (document_loader->IsClientRedirect()) {
params->transition = ui::PageTransitionFromInt(
params->transition | ui::PAGE_TRANSITION_CLIENT_REDIRECT);
}
params->is_overriding_user_agent =
document_state->is_overriding_user_agent();
params->history_list_was_cleared =
navigation_state->commit_params().should_clear_history_list;
} else {
if (commit_type == blink::kWebStandardCommit)
params->transition = ui::PAGE_TRANSITION_MANUAL_SUBFRAME;
else
params->transition = ui::PAGE_TRANSITION_AUTO_SUBFRAME;
DCHECK(!navigation_state->commit_params().should_clear_history_list);
params->history_list_was_cleared = false;
}
bool requires_universal_access = false;
const bool file_scheme_with_universal_access =
params->origin.scheme() == url::kFileScheme &&
GetBlinkPreferences().allow_universal_access_from_file_urls;
if (!params->origin.opaque() && params->url.IsStandard() &&
GetBlinkPreferences().web_security_enabled) {
if (!params->origin.IsSameOriginWith(params->url)) {
if (!file_scheme_with_universal_access) {
SCOPED_CRASH_KEY_STRING256("MakeDCPLParams", "mismatched_url",
params->url.possibly_invalid_spec());
SCOPED_CRASH_KEY_STRING256("MakeDCPLParams", "mismatched_origin",
params->origin.GetDebugString());
CHECK(false) << " url:" << params->url << " origin:" << params->origin;
} else {
requires_universal_access = true;
}
}
if (file_scheme_with_universal_access) {
base::UmaHistogramBoolean(
"Android.WebView.UniversalAccess.OriginUrlMismatchInRenderFrame",
requires_universal_access);
}
}
params->request_id = document_state->request_id();
params->unload_start =
GetWebFrame()->PerformanceMetricsForNestedContexts().UnloadStart();
params->unload_end =
GetWebFrame()->PerformanceMetricsForNestedContexts().UnloadEnd();
params->commit_navigation_end = GetWebFrame()
->PerformanceMetricsForNestedContexts()
.CommitNavigationEnd();
return params;
}
void RenderFrameImpl::UpdateNavigationHistory(
blink::WebHistoryCommitType commit_type) {
NavigationState* navigation_state =
DocumentState::FromDocumentLoader(frame_->GetDocumentLoader())
->navigation_state();
const blink::mojom::CommitNavigationParams& commit_params =
navigation_state->commit_params();
GetWebFrame()->UpdateCurrentHistoryItem();
GetWebFrame()->SetTargetToCurrentHistoryItem(
blink::WebString::FromUTF8(unique_name_helper_.value()));
bool is_new_navigation = commit_type == blink::kWebStandardCommit;
blink::WebView* webview = GetWebView();
if (commit_params.should_clear_history_list) {
webview->SetHistoryListFromNavigation( 0,
1);
} else if (is_new_navigation) {
DCHECK(!navigation_state->common_params().should_replace_current_entry ||
(webview->HistoryBackListCount() +
webview->HistoryForwardListCount() + 1) > 0);
if (!navigation_state->common_params().should_replace_current_entry)
webview->IncreaseHistoryListFromNavigation();
} else if (commit_params.nav_entry_id != 0 &&
!commit_params.intended_as_new_entry) {
webview->SetHistoryListFromNavigation(
navigation_state->commit_params().pending_history_list_offset, {});
}
}
void RenderFrameImpl::NotifyObserversOfNavigationCommit(
ui::PageTransition transition) {
for (auto& observer : observers_)
observer.DidCommitProvisionalLoad(transition);
}
void RenderFrameImpl::UpdateStateForCommit(
blink::WebHistoryCommitType commit_type,
ui::PageTransition transition) {
DocumentState* document_state =
DocumentState::FromDocumentLoader(frame_->GetDocumentLoader());
NavigationState* navigation_state = document_state->navigation_state();
SendUpdateState();
UpdateNavigationHistory(commit_type);
if (document_state->must_reset_scroll_and_scale_state()) {
GetWebView()->ResetScrollAndScaleState();
document_state->set_must_reset_scroll_and_scale_state(false);
}
if (!frame_->Parent()) {
RenderThreadImpl* render_thread_impl = RenderThreadImpl::current();
if (render_thread_impl) {
render_thread_impl->histogram_customizer()->RenderViewNavigatedToHost(
GetLoadingUrl().host(), blink::WebView::GetWebViewCount());
}
}
if (IsLocalRoot()) {
PropagatePageZoomToNewlyAttachedFrame(
GetWebView(),
GetLocalRootWebFrameWidget()->GetScreenInfo().device_scale_factor);
}
if (!frame_->Parent() && !navigation_state->WasWithinSameDocument()) {
GetWebView()->ClearAutoplayFlags();
}
if (url::Origin(frame_->GetSecurityOrigin()) == autoplay_flags_.first) {
GetWebView()->AddAutoplayFlags(autoplay_flags_.second);
autoplay_flags_.first = url::Origin();
}
}
void RenderFrameImpl::DidCommitNavigationInternal(
blink::WebHistoryCommitType commit_type,
ui::PageTransition transition,
const blink::ParsedPermissionsPolicy& permissions_policy_header,
const blink::DocumentPolicyFeatureState& document_policy_header,
mojom::DidCommitProvisionalLoadInterfaceParamsPtr interface_params,
mojom::DidCommitSameDocumentNavigationParamsPtr same_document_params,
const absl::optional<base::UnguessableToken>& embedding_token) {
DCHECK(!(same_document_params && interface_params));
UpdateStateForCommit(commit_type, transition);
if (GetBlinkPreferences().renderer_wide_named_frame_lookup)
GetWebFrame()->SetAllowsCrossBrowsingInstanceFrameLookup();
auto params = MakeDidCommitProvisionalLoadParams(
commit_type, transition, permissions_policy_header,
document_policy_header, embedding_token);
NavigationState* navigation_state =
DocumentState::FromDocumentLoader(frame_->GetDocumentLoader())
->navigation_state();
if (same_document_params) {
GetFrameHost()->DidCommitSameDocumentNavigation(
std::move(params), std::move(same_document_params));
navigation_state->RunCommitSameDocumentNavigationCallback(
blink::mojom::CommitResult::Ok);
} else {
if (navigation_state->has_navigation_client()) {
navigation_state->RunCommitNavigationCallback(
std::move(params), std::move(interface_params));
} else {
GetFrameHost()->DidCommitProvisionalLoad(std::move(params),
std::move(interface_params));
}
}
if (IsMainFrame()) {
main_frame_intersection_rect_.reset();
main_frame_viewport_rect_.reset();
}
}
void RenderFrameImpl::PrepareFrameForCommit(
const GURL& url,
const blink::mojom::CommitNavigationParams& commit_params) {
browser_side_navigation_pending_ = false;
GetContentClient()->SetActiveURL(
url, frame_->Top()->GetSecurityOrigin().ToString().Utf8());
GetWebView()->SetHistoryListFromNavigation(
commit_params.current_history_list_offset,
commit_params.current_history_list_length);
}
blink::mojom::CommitResult RenderFrameImpl::PrepareForHistoryNavigationCommit(
const blink::mojom::CommonNavigationParams& common_params,
const blink::mojom::CommitNavigationParams& commit_params,
WebHistoryItem* item_for_history_navigation,
blink::WebFrameLoadType* load_type) {
blink::mojom::NavigationType navigation_type = common_params.navigation_type;
DCHECK(navigation_type ==
blink::mojom::NavigationType::HISTORY_SAME_DOCUMENT ||
navigation_type ==
blink::mojom::NavigationType::HISTORY_DIFFERENT_DOCUMENT ||
navigation_type == blink::mojom::NavigationType::RESTORE ||
navigation_type == blink::mojom::NavigationType::RESTORE_WITH_POST);
*item_for_history_navigation = WebHistoryItem(
blink::PageState::CreateFromEncodedData(commit_params.page_state));
if (item_for_history_navigation->IsNull())
return blink::mojom::CommitResult::Aborted;
*load_type = blink::WebFrameLoadType::kBackForward;
history_subframe_unique_names_ = commit_params.subframe_unique_names;
if (navigation_type == blink::mojom::NavigationType::HISTORY_SAME_DOCUMENT) {
CHECK(!GetWebFrame()->GetCurrentHistoryItem().IsNull());
DCHECK_EQ(GetWebFrame()->GetCurrentHistoryItem().DocumentSequenceNumber(),
item_for_history_navigation->DocumentSequenceNumber());
if (GetWebFrame()->GetCurrentHistoryItem().DocumentSequenceNumber() !=
item_for_history_navigation->DocumentSequenceNumber()) {
SCOPED_CRASH_KEY_NUMBER(
"history_bad_seq", "browser_doc_seq_num",
item_for_history_navigation->DocumentSequenceNumber());
SCOPED_CRASH_KEY_NUMBER(
"history_bad_seq", "renderer_doc_seq_num",
GetWebFrame()->GetCurrentHistoryItem().DocumentSequenceNumber());
base::debug::DumpWithoutCrashing();
return blink::mojom::CommitResult::RestartCrossDocument;
}
}
return blink::mojom::CommitResult::Ok;
}
bool RenderFrameImpl::SwapIn(WebFrame* previous_web_frame) {
CHECK(!in_frame_tree_);
unique_name_helper_.set_propagated_name(
GetUniqueNameOfWebFrame(previous_web_frame));
bool is_main_frame = is_main_frame_;
if (!previous_web_frame->Swap(frame_)) {
DCHECK(!is_main_frame);
return false;
}
in_frame_tree_ = true;
if (is_main_frame_) {
GetWebView()->DidAttachLocalMainFrame();
}
return true;
}
void RenderFrameImpl::DidStartLoading() {
TRACE_EVENT1("navigation,rail", "RenderFrameImpl::didStartLoading", "id",
routing_id_);
}
void RenderFrameImpl::DidStopLoading() {
TRACE_EVENT1("navigation,rail", "RenderFrameImpl::didStopLoading", "id",
routing_id_);
history_subframe_unique_names_.clear();
GetFrameHost()->DidStopLoading();
}
void RenderFrameImpl::NotifyAccessibilityModeChange(ui::AXMode new_mode) {
for (auto& observer : observers_)
observer.AccessibilityModeChanged(new_mode);
}
void RenderFrameImpl::FocusedElementChanged(const blink::WebElement& element) {
for (auto& observer : observers_)
observer.FocusedElementChanged(element);
}
void RenderFrameImpl::BeginNavigation(
std::unique_ptr<blink::WebNavigationInfo> info) {
CHECK(in_frame_tree_);
const bool first_navigation_in_render_frame = !had_started_any_navigation_;
had_started_any_navigation_ = true;
const GURL& url = info->url_request.Url();
TRACE_EVENT2("navigation", "RenderFrameImpl::BeginNavigation", "url",
url.possibly_invalid_spec(), "navigation_type",
static_cast<int>(info->navigation_type));
if (GetWebFrame() && GetWebFrame()->DispatchedPagehideAndStillHidden()) {
UMA_HISTOGRAM_ENUMERATION("BackForwardCache.SameSite.ActionAfterPagehide2",
blink::ActionAfterPagehide::kNavigation);
}
bool use_archive = (info->archive_status ==
blink::WebNavigationInfo::ArchiveStatus::Present) &&
!url.SchemeIs(url::kDataScheme);
DCHECK(!(use_archive && IsMainFrame()));
#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_OHOS)
if (!url.is_empty() && !use_archive && !IsURLHandledByNetworkStack(url) &&
GetContentClient()->renderer()->HandleNavigation(
this, frame_, info->url_request, info->navigation_type,
info->navigation_policy, false )) {
return;
}
#endif
if (info->is_unfenced_top_navigation) {
OpenURL(std::move(info));
return;
}
if (IsTopLevelNavigation(frame_) &&
GetWebView()
->GetRendererPreferences()
.browser_handles_all_top_level_requests) {
OpenURL(std::move(info));
return;
}
bool is_history_navigation_in_new_child_frame = false;
if (info->is_history_navigation_in_new_child_frame && frame_->Parent() &&
!use_archive) {
RenderFrameImpl* parent = RenderFrameImpl::FromWebFrame(frame_->Parent());
auto iter = parent->history_subframe_unique_names_.find(
unique_name_helper_.value());
if (iter != parent->history_subframe_unique_names_.end()) {
bool history_item_is_about_blank = iter->second;
is_history_navigation_in_new_child_frame =
!history_item_is_about_blank || url != url::kAboutBlankURL;
parent->history_subframe_unique_names_.erase(iter);
}
}
if (is_history_navigation_in_new_child_frame) {
if (info->is_client_redirect) {
is_history_navigation_in_new_child_frame = false;
GetFrameHost()->CancelInitialHistoryLoad();
}
}
GURL old_url(frame_->GetDocumentLoader()->GetUrl());
if (IsTopLevelNavigation(frame_) && !url.SchemeIs(url::kAboutScheme) &&
!url.is_empty()) {
bool should_fork = HasWebUIScheme(url) || HasWebUIScheme(old_url) ||
(enabled_bindings_ & kWebUIBindingsPolicyMask);
if (should_fork) {
OpenURL(std::move(info));
return;
}
}
if (frame_->IsOutermostMainFrame() && url.is_valid() &&
url.SchemeIsHTTPOrHTTPS() &&
base::FeatureList::IsEnabled(kSpeculativeServiceWorkerStartup)) {
frame_->MaybeStartOutermostMainFrameNavigation(WebVector<WebURL>({url}));
}
if (info->navigation_policy == blink::kWebNavigationPolicyDownload) {
mojo::PendingRemote<blink::mojom::BlobURLToken> blob_url_token =
CloneBlobURLToken(info->blob_url_token);
frame_->DownloadURL(info->url_request,
network::mojom::RedirectMode::kFollow,
std::move(blob_url_token));
return;
}
if (info->navigation_policy != blink::kWebNavigationPolicyCurrentTab) {
OpenURL(std::move(info));
return;
}
base::WeakPtr<RenderFrameImpl> weak_self = weak_factory_.GetWeakPtr();
base::TimeTicks renderer_before_unload_start = base::TimeTicks::Now();
if (!frame_->DispatchBeforeUnloadEvent(info->navigation_type ==
blink::kWebNavigationTypeReload) ||
!weak_self) {
return;
}
base::TimeTicks renderer_before_unload_end = base::TimeTicks::Now();
if (!info->form.IsNull()) {
for (auto& observer : observers_)
observer.WillSubmitForm(info->form);
}
if (mhtml_body_loader_client_) {
mhtml_body_loader_client_->Detach();
mhtml_body_loader_client_.reset();
}
bool should_do_synchronous_about_blank_navigation =
WebDocumentLoader::WillLoadUrlAsEmpty(url) &&
info->url_request.HttpMethod().Equals("GET") &&
frame_->IsOnInitialEmptyDocument() && first_navigation_in_render_frame &&
!is_history_navigation_in_new_child_frame &&
!info->is_fullscreen_requested;
if (should_do_synchronous_about_blank_navigation) {
for (auto& observer : observers_)
observer.DidStartNavigation(url, info->navigation_type);
SynchronouslyCommitAboutBlankForBug778318(std::move(info));
return;
}
#ifdef OHOS_LOGGER_REPORT
if (IsMainFrame()) {
LOG_FEEDBACK(INFO) << "Begin navigation routing_id: " << routing_id_;
}
#endif
BeginNavigationInternal(
std::move(info), is_history_navigation_in_new_child_frame,
renderer_before_unload_start, renderer_before_unload_end);
}
void RenderFrameImpl::SynchronouslyCommitAboutBlankForBug778318(
std::unique_ptr<blink::WebNavigationInfo> info) {
CHECK_EQ(NavigationCommitState::kInitialEmptyDocument,
navigation_commit_state_);
navigation_commit_state_ = NavigationCommitState::kNone;
AssertNavigationCommits assert_navigation_commits(this);
auto navigation_params = WebNavigationParams::CreateFromInfo(*info);
navigation_params->document_token = frame_->GetDocument().Token();
navigation_params->is_synchronous_commit_for_bug_778318 = true;
navigation_params->service_worker_network_provider =
ServiceWorkerNetworkProviderForFrame::CreateInvalidInstance();
DCHECK(IsMainFrame() || navigation_params->frame_load_type ==
WebFrameLoadType::kReplaceCurrentItem);
if (info->initiator_frame_token.has_value() &&
WebFrame::FromFrameToken(info->initiator_frame_token.value())) {
WebFrame* initiator =
WebFrame::FromFrameToken(info->initiator_frame_token.value());
DCHECK(initiator->IsWebLocalFrame());
navigation_params->referrer =
initiator->ToWebLocalFrame()->GetDocument().Url().GetString();
}
frame_->CommitNavigation(std::move(navigation_params), BuildDocumentState());
}
void RenderFrameImpl::SerializeAsMHTML(mojom::SerializeAsMHTMLParamsPtr params,
SerializeAsMHTMLCallback callback) {
TRACE_EVENT0("page-serialization", "RenderFrameImpl::SerializeAsMHTML");
base::TimeTicks start_time = base::TimeTicks::Now();
const WebString mhtml_boundary =
WebString::FromUTF8(params->mhtml_boundary_marker);
DCHECK(!mhtml_boundary.IsEmpty());
std::vector<WebThreadSafeData> mhtml_contents;
std::unordered_set<std::string> serialized_resources_uri_digests;
MHTMLPartsGenerationDelegate delegate(*params,
&serialized_resources_uri_digests);
mojom::MhtmlSaveStatus save_status = mojom::MhtmlSaveStatus::kSuccess;
bool has_some_data = false;
if (IsMainFrame()) {
TRACE_EVENT0("page-serialization",
"RenderFrameImpl::SerializeAsMHTML header");
mhtml_contents.emplace_back(WebFrameSerializer::GenerateMHTMLHeader(
mhtml_boundary, GetWebFrame(), &delegate));
has_some_data = true;
}
if (save_status == mojom::MhtmlSaveStatus::kSuccess) {
TRACE_EVENT0("page-serialization",
"RenderFrameImpl::SerializeAsMHTML parts serialization");
mhtml_contents.emplace_back(WebFrameSerializer::GenerateMHTMLParts(
mhtml_boundary, GetWebFrame(), &delegate));
has_some_data |= !mhtml_contents.back().IsEmpty();
}
base::TimeDelta main_thread_use_time = base::TimeTicks::Now() - start_time;
UMA_HISTOGRAM_TIMES(
"PageSerialization.MhtmlGeneration.RendererMainThreadTime.SingleFrame",
main_thread_use_time);
MHTMLHandleWriterDelegate handle_delegate(
*params,
base::BindOnce(&RenderFrameImpl::OnWriteMHTMLComplete,
weak_factory_.GetWeakPtr(), std::move(callback),
std::move(serialized_resources_uri_digests)),
GetTaskRunner(blink::TaskType::kInternalDefault));
if (save_status == mojom::MhtmlSaveStatus::kSuccess && has_some_data) {
handle_delegate.WriteContents(mhtml_contents);
} else {
handle_delegate.Finish(save_status);
}
}
void RenderFrameImpl::OnWriteMHTMLComplete(
SerializeAsMHTMLCallback callback,
std::unordered_set<std::string> serialized_resources_uri_digests,
mojom::MhtmlSaveStatus save_status) {
TRACE_EVENT1("page-serialization", "RenderFrameImpl::OnWriteMHTMLComplete",
"frame save status", save_status);
DCHECK(RenderThread::IsMainThread())
<< "Must run in the main renderer thread";
std::vector<std::string> digests_of_new_parts(
std::make_move_iterator(serialized_resources_uri_digests.begin()),
std::make_move_iterator(serialized_resources_uri_digests.end()));
std::move(callback).Run(save_status, std::move(digests_of_new_parts));
}
#ifndef STATIC_ASSERT_ENUM
#define STATIC_ASSERT_ENUM(a, b) \
static_assert(static_cast<int>(a) == static_cast<int>(b), \
"mismatching enums: " #a)
#undef STATIC_ASSERT_ENUM
#endif
void RenderFrameImpl::RequestOverlayRoutingToken(
media::RoutingTokenCallback callback) {
std::move(callback).Run(GetWebFrame()->GetFrameToken().value());
}
void RenderFrameImpl::OpenURL(std::unique_ptr<blink::WebNavigationInfo> info) {
DCHECK(!info->url_request.RequestorOrigin().IsNull());
WebNavigationPolicy policy = info->navigation_policy;
auto params = blink::mojom::OpenURLParams::New();
params->url = info->url_request.Url();
params->initiator_origin = info->url_request.RequestorOrigin();
if (info->requestor_base_url.IsValid()) {
params->initiator_base_url = info->requestor_base_url;
}
params->post_body = blink::GetRequestBodyForWebURLRequest(info->url_request);
DCHECK_EQ(!!params->post_body, IsHttpPost(info->url_request));
params->extra_headers =
blink::GetWebURLRequestHeadersAsString(info->url_request).Latin1();
params->referrer = blink::mojom::Referrer::New(
blink::WebStringToGURL(info->url_request.ReferrerString()),
info->url_request.GetReferrerPolicy());
params->disposition = NavigationPolicyToDisposition(policy);
params->triggering_event_info = info->triggering_event_info;
params->blob_url_token = CloneBlobURLToken(info->blob_url_token);
params->should_replace_current_entry =
info->frame_load_type == WebFrameLoadType::kReplaceCurrentItem &&
GetWebView()->HistoryBackListCount() +
GetWebView()->HistoryForwardListCount() + 1;
params->user_gesture = info->has_transient_user_activation;
params->is_unfenced_top_navigation = info->is_unfenced_top_navigation;
params->initiator_policy_container_keep_alive_handle =
std::move(info->initiator_policy_container_keep_alive_handle);
params->initiator_frame_token = info->initiator_frame_token;
params->source_location = network::mojom::SourceLocation::New();
params->impression = info->impression;
if (GetContentClient()->renderer()->AllowPopup())
params->user_gesture = true;
DCHECK(!is_main_frame_ || !frame_->HasTransientUserActivation());
if (!is_main_frame_ &&
(policy == blink::kWebNavigationPolicyNewBackgroundTab ||
policy == blink::kWebNavigationPolicyNewForegroundTab ||
policy == blink::kWebNavigationPolicyNewWindow ||
policy == blink::kWebNavigationPolicyNewPopup ||
policy == blink::kWebNavigationPolicyPictureInPicture)) {
frame_->ConsumeTransientUserActivation();
}
params->href_translate = info->href_translate.Latin1();
bool current_frame_has_download_sandbox_flag = !frame_->IsAllowedToDownload();
bool has_download_sandbox_flag =
info->initiator_frame_has_download_sandbox_flag ||
current_frame_has_download_sandbox_flag;
bool from_ad = info->initiator_frame_is_ad || frame_->IsAdFrame();
params->download_policy.ApplyDownloadFramePolicy(
info->is_opener_navigation, info->url_request.HasUserGesture(),
info->url_request.RequestorOrigin().CanAccess(
frame_->GetSecurityOrigin()),
has_download_sandbox_flag, from_ad);
params->initiator_activation_and_ad_status =
blink::GetNavigationInitiatorActivationAndAdStatus(
info->url_request.HasUserGesture(), info->is_ad_script_in_stack);
GetFrameHost()->OpenURL(std::move(params));
}
blink::ChildURLLoaderFactoryBundle* RenderFrameImpl::GetLoaderFactoryBundle() {
DCHECK(loader_factories_);
return loader_factories_.get();
}
scoped_refptr<blink::ChildURLLoaderFactoryBundle>
RenderFrameImpl::CreateLoaderFactoryBundle(
std::unique_ptr<blink::PendingURLLoaderFactoryBundle> info,
absl::optional<std::vector<blink::mojom::TransferrableURLLoaderPtr>>
subresource_overrides,
mojo::PendingRemote<network::mojom::URLLoaderFactory>
prefetch_loader_factory,
mojo::PendingRemote<network::mojom::URLLoaderFactory> topics_loader_factory,
mojo::PendingRemote<network::mojom::URLLoaderFactory>
keep_alive_loader_factory) {
DCHECK(info);
auto loader_factories =
base::MakeRefCounted<blink::HostChildURLLoaderFactoryBundle>(
GetTaskRunner(blink::TaskType::kInternalLoading));
loader_factories->Update(
std::make_unique<blink::ChildPendingURLLoaderFactoryBundle>(
std::move(info)));
if (subresource_overrides) {
loader_factories->UpdateSubresourceOverrides(&*subresource_overrides);
}
if (prefetch_loader_factory) {
loader_factories->SetPrefetchLoaderFactory(
std::move(prefetch_loader_factory));
}
if (topics_loader_factory) {
loader_factories->SetTopicsLoaderFactory(std::move(topics_loader_factory));
}
if (keep_alive_loader_factory) {
loader_factories->SetKeepAliveLoaderFactory(
std::move(keep_alive_loader_factory));
}
return loader_factories;
}
void RenderFrameImpl::UpdateEncoding(WebFrame* frame,
const std::string& encoding_name) {
if (!frame->Parent()) {
GetFrameHost()->UpdateEncoding(encoding_name);
}
}
void RenderFrameImpl::SyncSelectionIfRequired(blink::SyncCondition force_sync) {
std::u16string text;
size_t offset;
gfx::Range range;
#if BUILDFLAG(ENABLE_PPAPI)
if (focused_pepper_plugin_) {
focused_pepper_plugin_->GetSurroundingText(&text, &range);
offset = 0;
} else
#endif
{
WebRange selection =
frame_->GetInputMethodController()->GetSelectionOffsets();
if (selection.IsNull())
return;
range = gfx::Range(selection.StartOffset(), selection.EndOffset());
if (frame_->GetInputMethodController()->TextInputType() !=
blink::kWebTextInputTypeNone) {
if (selection.StartOffset() > kExtraCharsBeforeAndAfterSelection)
offset = selection.StartOffset() - kExtraCharsBeforeAndAfterSelection;
else
offset = 0;
size_t length =
selection.EndOffset() - offset + kExtraCharsBeforeAndAfterSelection;
text = frame_->RangeAsText(WebRange(offset, length)).Utf16();
} else {
offset = selection.StartOffset();
text = frame_->SelectionAsText().Utf16();
range.set_end(range.start() + text.length());
}
}
if (force_sync == blink::SyncCondition::kForced ||
selection_text_offset_ != offset || selection_range_ != range ||
selection_text_ != text) {
selection_text_ = text;
selection_text_offset_ = offset;
selection_range_ = range;
SetSelectedText(text, offset, range);
}
GetLocalRootWebFrameWidget()->UpdateSelectionBounds();
}
void RenderFrameImpl::CreateAudioInputStream(
blink::CrossVariantMojoRemote<
blink::mojom::RendererAudioInputStreamFactoryClientInterfaceBase>
client,
const base::UnguessableToken& session_id,
const media::AudioParameters& params,
bool automatic_gain_control,
uint32_t shared_memory_count,
blink::CrossVariantMojoReceiver<
media::mojom::AudioProcessorControlsInterfaceBase> controls_receiver,
const media::AudioProcessingSettings* settings) {
DCHECK_EQ(!!settings, !!controls_receiver);
media::mojom::AudioProcessingConfigPtr processing_config;
if (controls_receiver) {
DCHECK(settings);
processing_config = media::mojom::AudioProcessingConfig::New(
std::move(controls_receiver), *settings);
}
GetAudioInputStreamFactory()->CreateStream(
std::move(client), session_id, params, automatic_gain_control,
shared_memory_count, std::move(processing_config));
}
void RenderFrameImpl::AssociateInputAndOutputForAec(
const base::UnguessableToken& input_stream_id,
const std::string& output_device_id) {
GetAudioInputStreamFactory()->AssociateInputAndOutputForAec(input_stream_id,
output_device_id);
}
void RenderFrameImpl::InitializeMediaStreamDeviceObserver() {
RenderThreadImpl* render_thread = RenderThreadImpl::current();
if (!render_thread)
return;
DCHECK(!web_media_stream_device_observer_);
web_media_stream_device_observer_ =
std::make_unique<blink::WebMediaStreamDeviceObserver>(GetWebFrame());
}
void RenderFrameImpl::BeginNavigationInternal(
std::unique_ptr<blink::WebNavigationInfo> info,
bool is_history_navigation_in_new_child_frame,
base::TimeTicks renderer_before_unload_start,
base::TimeTicks renderer_before_unload_end) {
if (!frame_->WillStartNavigation(*info))
return;
for (auto& observer : observers_)
observer.DidStartNavigation(info->url_request.Url(), info->navigation_type);
browser_side_navigation_pending_ = true;
WebDocument frame_document = frame_->GetDocument();
if (info->frame_type == blink::mojom::RequestContextFrameType::kTopLevel) {
info->url_request.SetSiteForCookies(
net::SiteForCookies::FromUrl(info->url_request.Url()));
} else {
info->url_request.SetSiteForCookies(frame_document.SiteForCookies());
}
ui::PageTransition transition_type = GetTransitionType(
ui::PAGE_TRANSITION_LINK,
info->frame_load_type == WebFrameLoadType::kReplaceCurrentItem,
IsMainFrame(), GetWebView()->IsFencedFrameRoot(), info->navigation_type);
if (info->is_client_redirect) {
transition_type = ui::PageTransitionFromInt(
transition_type | ui::PAGE_TRANSITION_CLIENT_REDIRECT);
}
bool for_outermost_main_frame = frame_->IsOutermostMainFrame();
WillSendRequestInternal(info->url_request, for_outermost_main_frame,
transition_type, ForRedirect(false));
DCHECK(info->url_request.GetURLRequestExtraData());
DCHECK_EQ(network::mojom::RequestMode::kNavigate,
info->url_request.GetMode());
DCHECK_EQ(network::mojom::CredentialsMode::kInclude,
info->url_request.GetCredentialsMode());
DCHECK_EQ(network::mojom::RedirectMode::kManual,
info->url_request.GetRedirectMode());
DCHECK(frame_->Parent() ||
info->frame_type == blink::mojom::RequestContextFrameType::kTopLevel);
DCHECK(!frame_->Parent() ||
info->frame_type == blink::mojom::RequestContextFrameType::kNested);
bool is_form_submission =
(info->navigation_type == blink::kWebNavigationTypeFormSubmitted ||
info->navigation_type ==
blink::kWebNavigationTypeFormResubmittedBackForward ||
info->navigation_type == blink::kWebNavigationTypeFormResubmittedReload);
bool was_initiated_by_link_click =
info->navigation_type == blink::kWebNavigationTypeLinkClicked;
GURL searchable_form_url;
std::string searchable_form_encoding;
if (!info->form.IsNull()) {
WebSearchableFormData web_searchable_form_data(info->form);
searchable_form_url = web_searchable_form_data.Url();
searchable_form_encoding = web_searchable_form_data.Encoding().Utf8();
}
GURL client_side_redirect_url;
if (info->is_client_redirect)
client_side_redirect_url = frame_->GetDocument().Url();
mojo::PendingRemote<blink::mojom::BlobURLToken> blob_url_token(
CloneBlobURLToken(info->blob_url_token));
int load_flags = info->url_request.GetLoadFlagsForWebUrlRequest();
absl::optional<base::Value::Dict> devtools_initiator;
if (!info->devtools_initiator_info.IsNull()) {
absl::optional<base::Value> devtools_initiator_value =
base::JSONReader::Read(info->devtools_initiator_info.Utf8());
if (devtools_initiator_value && devtools_initiator_value->is_dict()) {
devtools_initiator = std::move(*devtools_initiator_value).TakeDict();
}
}
absl::optional<network::ResourceRequest::WebBundleTokenParams>
web_bundle_token_params;
if (info->url_request.WebBundleToken()) {
web_bundle_token_params =
absl::make_optional(network::ResourceRequest::WebBundleTokenParams(
*info->url_request.WebBundleUrl(),
*info->url_request.WebBundleToken(),
-1 ));
}
blink::mojom::NavigationInitiatorActivationAndAdStatus
initiator_activation_and_ad_status =
blink::GetNavigationInitiatorActivationAndAdStatus(
info->url_request.HasUserGesture(), info->is_ad_script_in_stack);
blink::mojom::BeginNavigationParamsPtr begin_navigation_params =
blink::mojom::BeginNavigationParams::New(
info->initiator_frame_token,
blink::GetWebURLRequestHeadersAsString(info->url_request).Latin1(),
load_flags, info->url_request.GetSkipServiceWorker(),
blink::GetRequestContextTypeForWebURLRequest(info->url_request),
blink::GetMixedContentContextTypeForWebURLRequest(info->url_request),
is_form_submission, was_initiated_by_link_click,
info->force_history_push, searchable_form_url,
searchable_form_encoding, client_side_redirect_url,
std::move(devtools_initiator),
info->url_request.TrustTokenParams()
? info->url_request.TrustTokenParams()->Clone()
: nullptr,
info->impression, renderer_before_unload_start,
renderer_before_unload_end, web_bundle_token_params,
initiator_activation_and_ad_status, info->is_container_initiated,
info->is_fullscreen_requested, info->has_storage_access);
mojo::PendingAssociatedRemote<mojom::NavigationClient>
navigation_client_remote;
BindNavigationClient(
navigation_client_remote.InitWithNewEndpointAndPassReceiver());
mojo::PendingReceiver<mojom::NavigationRendererCancellationListener>
renderer_cancellation_listener_receiver;
navigation_client_impl_->SetUpRendererInitiatedNavigation(
renderer_cancellation_listener_receiver.InitWithNewPipeAndPassRemote());
bool current_frame_has_download_sandbox_flag = !frame_->IsAllowedToDownload();
bool has_download_sandbox_flag =
info->initiator_frame_has_download_sandbox_flag ||
current_frame_has_download_sandbox_flag;
bool from_ad = info->initiator_frame_is_ad || frame_->IsAdFrame();
mojo::PendingRemote<blink::mojom::PolicyContainerHostKeepAliveHandle>
initiator_policy_container_keep_alive_handle =
std::move(info->initiator_policy_container_keep_alive_handle);
network::mojom::RequestDestination request_destination =
blink::GetRequestDestinationForWebURLRequest(info->url_request);
GetFrameHost()->BeginNavigation(
MakeCommonNavigationParams(frame_->GetSecurityOrigin(), std::move(info),
load_flags, has_download_sandbox_flag, from_ad,
is_history_navigation_in_new_child_frame,
request_destination),
std::move(begin_navigation_params), std::move(blob_url_token),
std::move(navigation_client_remote),
std::move(initiator_policy_container_keep_alive_handle),
std::move(renderer_cancellation_listener_receiver));
}
void RenderFrameImpl::DecodeDataURL(
const blink::mojom::CommonNavigationParams& common_params,
const blink::mojom::CommitNavigationParams& commit_params,
std::string* mime_type,
std::string* charset,
std::string* data,
GURL* base_url) {
GURL data_url = common_params.url;
#if BUILDFLAG(IS_ANDROID)
if (!commit_params.data_url_as_string.empty()) {
#if DCHECK_IS_ON()
{
std::string mime_type_tmp, charset_tmp, data_tmp;
DCHECK(net::DataURL::Parse(data_url, &mime_type_tmp, &charset_tmp,
&data_tmp));
DCHECK(data_tmp.empty());
}
#endif
data_url = GURL(commit_params.data_url_as_string);
if (!data_url.is_valid() || !data_url.SchemeIs(url::kDataScheme)) {
data_url = common_params.url;
}
}
#endif
if (net::DataURL::Parse(data_url, mime_type, charset, data)) {
*base_url = common_params.base_url_for_data_url.is_empty()
? common_params.url
: common_params.base_url_for_data_url;
} else {
CHECK(false) << "Invalid URL passed: "
<< common_params.url.possibly_invalid_spec();
}
}
void RenderFrameImpl::SendUpdateState() {
delayed_state_sync_timer_.Stop();
if (GetWebFrame()->GetCurrentHistoryItem().IsNull())
return;
GetFrameHost()->UpdateState(GetWebFrame()->CurrentHistoryItemToPageState());
}
blink::WebURL RenderFrameImpl::LastCommittedUrlForUKM() {
return GetLoadingUrl();
}
GURL RenderFrameImpl::GetLoadingUrl() const {
WebDocumentLoader* document_loader = frame_->GetDocumentLoader();
GURL overriden_url;
if (MaybeGetOverriddenURL(document_loader, &overriden_url))
return overriden_url;
return document_loader->GetUrl();
}
media::MediaPermission* RenderFrameImpl::GetMediaPermission() {
if (!media_permission_dispatcher_) {
media_permission_dispatcher_ =
std::make_unique<MediaPermissionDispatcher>(this);
}
return media_permission_dispatcher_.get();
}
void RenderFrameImpl::RegisterMojoInterfaces() {
GetAssociatedInterfaceRegistry()
->AddInterface<blink::mojom::AutoplayConfigurationClient>(
base::BindRepeating(&RenderFrameImpl::BindAutoplayConfiguration,
weak_factory_.GetWeakPtr()));
GetAssociatedInterfaceRegistry()->AddInterface<mojom::FrameBindingsControl>(
base::BindRepeating(&RenderFrameImpl::BindFrameBindingsControl,
weak_factory_.GetWeakPtr()));
GetAssociatedInterfaceRegistry()->AddInterface<mojom::NavigationClient>(
base::BindRepeating(&RenderFrameImpl::BindNavigationClient,
weak_factory_.GetWeakPtr()));
GetAssociatedInterfaceRegistry()->AddInterface<mojom::MhtmlFileWriter>(
base::BindRepeating(&RenderFrameImpl::BindMhtmlFileWriter,
base::Unretained(this)));
GetAssociatedInterfaceRegistry()
->AddInterface<blink::mojom::RenderAccessibility>(base::BindRepeating(
&RenderAccessibilityManager::BindReceiver,
base::Unretained(render_accessibility_manager_.get())));
}
void RenderFrameImpl::BindMhtmlFileWriter(
mojo::PendingAssociatedReceiver<mojom::MhtmlFileWriter> receiver) {
mhtml_file_writer_receiver_.reset();
mhtml_file_writer_receiver_.Bind(
std::move(receiver), GetTaskRunner(blink::TaskType::kInternalDefault));
}
void RenderFrameImpl::CheckIfAudioSinkExistsAndIsAuthorized(
const blink::WebString& sink_id,
blink::WebSetSinkIdCompleteCallback completion_callback) {
std::move(
blink::ConvertToOutputDeviceStatusCB(std::move(completion_callback)))
.Run(blink::AudioDeviceFactory::GetInstance()
->GetOutputDeviceInfo(GetWebFrame()->GetLocalFrameToken(),
sink_id.Utf8())
.device_status());
}
scoped_refptr<network::SharedURLLoaderFactory>
RenderFrameImpl::GetURLLoaderFactory() {
if (!RenderThreadImpl::current()) {
if (url_loader_factory_override_for_test_) {
return url_loader_factory_override_for_test_;
}
for (auto* ancestor = GetWebFrame()->Parent(); ancestor;
ancestor = ancestor->Parent()) {
RenderFrameImpl* ancestor_frame = RenderFrameImpl::FromWebFrame(ancestor);
if (ancestor_frame &&
ancestor_frame->url_loader_factory_override_for_test_) {
return ancestor_frame->url_loader_factory_override_for_test_;
}
}
CHECK(false);
return nullptr;
}
return GetLoaderFactoryBundle();
}
void RenderFrameImpl::OnStopLoading() {
for (auto& observer : observers_)
observer.OnStop();
}
void RenderFrameImpl::DraggableRegionsChanged() {
for (auto& observer : observers_)
observer.DraggableRegionsChanged();
}
bool RenderFrameImpl::IsBrowserSideNavigationPending() {
return browser_side_navigation_pending_;
}
void RenderFrameImpl::LoadHTMLStringForTesting(const std::string& html,
const GURL& base_url,
const std::string& text_encoding,
const GURL& unreachable_url,
bool replace_current_item) {
AssertNavigationCommits assert_navigation_commits(
this, kMayReplaceInitialEmptyDocument);
pending_loader_factories_ = CreateLoaderFactoryBundle(
blink::ChildPendingURLLoaderFactoryBundle::CreateFromDefaultFactoryImpl(
network::NotImplementedURLLoaderFactory::Create()),
absl::nullopt,
{},
{},
{});
auto navigation_params = std::make_unique<WebNavigationParams>();
navigation_params->url = base_url;
WebNavigationParams::FillStaticResponse(navigation_params.get(), "text/html",
WebString::FromUTF8(text_encoding),
html);
navigation_params->unreachable_url = unreachable_url;
navigation_params->frame_load_type =
replace_current_item ? blink::WebFrameLoadType::kReplaceCurrentItem
: blink::WebFrameLoadType::kStandard;
navigation_params->service_worker_network_provider =
ServiceWorkerNetworkProviderForFrame::CreateInvalidInstance();
frame_->CommitNavigation(std::move(navigation_params), BuildDocumentState());
}
scoped_refptr<base::SingleThreadTaskRunner> RenderFrameImpl::GetTaskRunner(
blink::TaskType task_type) {
return GetWebFrame()->GetTaskRunner(task_type);
}
int RenderFrameImpl::GetEnabledBindings() {
return enabled_bindings_;
}
void RenderFrameImpl::SetAccessibilityModeForTest(ui::AXMode new_mode) {
render_accessibility_manager_->SetMode(new_mode);
}
const RenderFrameMediaPlaybackOptions&
RenderFrameImpl::GetRenderFrameMediaPlaybackOptions() {
return renderer_media_playback_options_;
}
void RenderFrameImpl::SetRenderFrameMediaPlaybackOptions(
const RenderFrameMediaPlaybackOptions& opts) {
renderer_media_playback_options_ = opts;
}
void RenderFrameImpl::SetAllowsCrossBrowsingInstanceFrameLookup() {
GetWebFrame()->SetAllowsCrossBrowsingInstanceFrameLookup();
}
bool RenderFrameImpl::IsAccessibilityEnabled() const {
return render_accessibility_manager_->GetAccessibilityMode().has_mode(
ui::AXMode::kWebContents);
}
#if BUILDFLAG(ENABLE_PPAPI)
mojom::PepperHost* RenderFrameImpl::GetPepperHost() {
if (!pepper_host_remote_.is_bound())
GetRemoteAssociatedInterfaces()->GetInterface(&pepper_host_remote_);
return pepper_host_remote_.get();
}
void RenderFrameImpl::PepperInstanceCreated(
PepperPluginInstanceImpl* instance,
mojo::PendingAssociatedRemote<mojom::PepperPluginInstance> mojo_instance,
mojo::PendingAssociatedReceiver<mojom::PepperPluginInstanceHost>
mojo_host) {
active_pepper_instances_.insert(instance);
GetPepperHost()->InstanceCreated(
instance->pp_instance(), std::move(mojo_instance), std::move(mojo_host));
}
void RenderFrameImpl::PepperInstanceDeleted(
PepperPluginInstanceImpl* instance) {
active_pepper_instances_.erase(instance);
if (focused_pepper_plugin_ == instance)
PepperFocusChanged(instance, false);
}
void RenderFrameImpl::PepperFocusChanged(PepperPluginInstanceImpl* instance,
bool focused) {
if (focused)
focused_pepper_plugin_ = instance;
else if (focused_pepper_plugin_ == instance)
focused_pepper_plugin_ = nullptr;
GetLocalRootWebFrameWidget()->UpdateTextInputState();
GetLocalRootWebFrameWidget()->UpdateSelectionBounds();
}
#endif
blink::WebComputedAXTree* RenderFrameImpl::GetOrCreateWebComputedAXTree() {
if (!computed_ax_tree_)
computed_ax_tree_ = std::make_unique<AomContentAxTree>(this);
return computed_ax_tree_.get();
}
std::unique_ptr<blink::WebSocketHandshakeThrottle>
RenderFrameImpl::CreateWebSocketHandshakeThrottle() {
WebLocalFrame* web_local_frame = GetWebFrame();
if (!web_local_frame)
return nullptr;
auto* render_frame = content::RenderFrame::FromWebFrame(web_local_frame);
if (!render_frame)
return nullptr;
int render_frame_id = render_frame->GetRoutingID();
if (!websocket_handshake_throttle_provider_) {
websocket_handshake_throttle_provider_ =
GetContentClient()
->renderer()
->CreateWebSocketHandshakeThrottleProvider();
if (!websocket_handshake_throttle_provider_)
return nullptr;
}
return websocket_handshake_throttle_provider_->CreateThrottle(
render_frame_id,
render_frame->GetTaskRunner(blink::TaskType::kInternalDefault));
}
bool RenderFrameImpl::GetCaretBoundsFromFocusedPlugin(gfx::Rect& rect) {
#if BUILDFLAG(ENABLE_PPAPI)
if (focused_pepper_plugin_) {
rect = focused_pepper_plugin_->GetCaretBounds();
return true;
}
#endif
return false;
}
void RenderFrameImpl::AddMessageToConsoleImpl(
blink::mojom::ConsoleMessageLevel level,
const std::string& message,
bool discard_duplicates) {
blink::WebConsoleMessage wcm(level, WebString::FromUTF8(message));
frame_->AddMessageToConsole(wcm, discard_duplicates);
}
void RenderFrameImpl::SetURLLoaderFactoryOverrideForTest(
scoped_refptr<network::SharedURLLoaderFactory> factory) {
url_loader_factory_override_for_test_ = std::move(factory);
}
scoped_refptr<blink::ChildURLLoaderFactoryBundle>
RenderFrameImpl::CloneLoaderFactories() {
auto pending_bundle = base::WrapUnique(
static_cast<blink::TrackedChildPendingURLLoaderFactoryBundle*>(
GetLoaderFactoryBundle()->Clone().release()));
return base::MakeRefCounted<blink::TrackedChildURLLoaderFactoryBundle>(
std::move(pending_bundle));
}
blink::scheduler::WebAgentGroupScheduler&
RenderFrameImpl::GetAgentGroupScheduler() {
return agent_scheduling_group_.agent_group_scheduler();
}
url::Origin RenderFrameImpl::GetSecurityOriginOfTopFrame() {
return frame_->Top()->GetSecurityOrigin();
}
base::WeakPtr<media::DecoderFactory> RenderFrameImpl::GetMediaDecoderFactory() {
return media_factory_.GetDecoderFactory();
}
gfx::RectF RenderFrameImpl::ElementBoundsInWindow(
const blink::WebElement& element) {
return gfx::RectF(GetLocalRootWebFrameWidget()->BlinkSpaceToEnclosedDIPs(
element.BoundsInWidget()));
}
void RenderFrameImpl::ConvertViewportToWindow(gfx::Rect* rect) {
*rect = GetLocalRootWebFrameWidget()->BlinkSpaceToEnclosedDIPs(*rect);
}
float RenderFrameImpl::GetDeviceScaleFactor() {
return GetLocalRootWebFrameWidget()->GetScreenInfo().device_scale_factor;
}
bool RenderFrameImpl::DeferMediaLoad(bool has_played_media_before,
base::OnceClosure closure) {
if (frame_->GetDocument().IsPrerendering()) {
frame_->GetDocument().AddPostPrerenderingActivationStep(
base::BindOnce(CallClientDeferMediaLoad, weak_factory_.GetWeakPtr(),
has_played_media_before, std::move(closure)));
return true;
}
return GetContentClient()->renderer()->DeferMediaLoad(
this, has_played_media_before, std::move(closure));
}
#if BUILDFLAG(IS_OHOS)
bool RenderFrameImpl::GetNewWindowWebView(const GURL& target_url,
blink::WebNavigationPolicy policy,
bool allow_popup) {
mojom::CreateNewWindowStatus status = mojom::CreateNewWindowStatus::kBlocked;
auto* frame_host = GetFrameHost();
if (!frame_host) {
return false;
}
if (!frame_host->GetCreateNewWindow(target_url,
NavigationPolicyToDisposition(policy),
allow_popup, &status) ||
status != mojom::CreateNewWindowStatus::kSuccess) {
return false;
}
return true;
}
#endif
WebView* RenderFrameImpl::CreateNewWindow(
const WebURLRequest& request,
const blink::WebWindowFeatures& features,
const WebString& frame_name,
WebNavigationPolicy policy,
network::mojom::WebSandboxFlags sandbox_flags,
const blink::SessionStorageNamespaceId& session_storage_namespace_id,
bool& consumed_user_gesture,
const absl::optional<blink::Impression>& impression,
const absl::optional<blink::WebPictureInPictureWindowOptions>& pip_options,
const blink::WebURL& base_url) {
consumed_user_gesture = false;
mojom::CreateNewWindowParamsPtr params = mojom::CreateNewWindowParams::New();
params->allow_popup = false;
if (GetContentClient()->renderer()->AllowPopup())
params->allow_popup = true;
#if BUILDFLAG(IS_OHOS)
GetNewWindowWebView(request.Url(), policy, params->allow_popup);
#endif
params->window_container_type = WindowFeaturesToContainerType(features);
params->session_storage_namespace_id = session_storage_namespace_id;
if (!features.noopener) {
params->clone_from_session_storage_namespace_id =
GetWebView()->GetSessionStorageNamespaceId();
}
const std::string& frame_name_utf8 = frame_name.Utf8(
WebString::UTF8ConversionMode::kStrictReplacingErrorsWithFFFD);
params->frame_name = frame_name_utf8;
params->opener_suppressed = features.noopener;
params->disposition = NavigationPolicyToDisposition(policy);
if (!request.IsNull()) {
params->target_url = request.Url();
params->referrer = blink::mojom::Referrer::New(
blink::WebStringToGURL(request.ReferrerString()),
request.GetReferrerPolicy());
}
params->features = ConvertWebWindowFeaturesToMojoWindowFeatures(features);
params->is_form_submission = request.IsFormSubmission();
params->form_submission_post_data =
blink::GetRequestBodyForWebURLRequest(request);
params->form_submission_post_content_type = request.HttpContentType().Utf8();
params->impression = impression;
if (pip_options) {
CHECK_EQ(policy, blink::kWebNavigationPolicyPictureInPicture);
auto pip_mojom_opts = blink::mojom::PictureInPictureWindowOptions::New();
pip_mojom_opts->width = pip_options->width;
pip_mojom_opts->height = pip_options->height;
pip_mojom_opts->initial_aspect_ratio = pip_options->initial_aspect_ratio;
pip_mojom_opts->lock_aspect_ratio = false;
params->pip_options = std::move(pip_mojom_opts);
}
params->download_policy.ApplyDownloadFramePolicy(
false, request.HasUserGesture(),
true,
!GetWebFrame()->IsAllowedToDownload(), GetWebFrame()->IsAdFrame());
params->initiator_activation_and_ad_status =
blink::GetNavigationInitiatorActivationAndAdStatus(
request.HasUserGesture(), GetWebFrame()->IsAdScriptInStack());
bool is_background_tab =
params->disposition == WindowOpenDisposition::NEW_BACKGROUND_TAB;
mojom::CreateNewWindowStatus status;
mojom::CreateNewWindowReplyPtr reply;
auto* frame_host = GetFrameHost();
if (!frame_host->CreateNewWindow(std::move(params), &status, &reply)) {
return nullptr;
}
if (status == mojom::CreateNewWindowStatus::kBlocked)
return nullptr;
if (status == mojom::CreateNewWindowStatus::kReuse)
return GetWebView();
consumed_user_gesture = GetWebFrame()->ConsumeTransientUserActivation(
blink::UserActivationUpdateSource::kBrowser);
if (status == mojom::CreateNewWindowStatus::kIgnore)
return nullptr;
DCHECK(reply);
DCHECK_NE(MSG_ROUTING_NONE, reply->main_frame_route_id);
DCHECK_NE(MSG_ROUTING_NONE, reply->widget_params->routing_id);
bool never_composited = false;
mojom::CreateViewParamsPtr view_params = mojom::CreateViewParams::New();
view_params->opener_frame_token = GetWebFrame()->GetFrameToken();
view_params->window_was_opened_by_another_window = true;
view_params->renderer_preferences = GetWebView()->GetRendererPreferences();
view_params->web_preferences = GetWebView()->GetWebPreferences();
view_params->replication_state = blink::mojom::FrameReplicationState::New();
view_params->replication_state->frame_policy.sandbox_flags = sandbox_flags;
view_params->replication_state->name = frame_name_utf8;
view_params->devtools_main_frame_token = reply->devtools_main_frame_token;
auto main_frame_params = mojom::CreateLocalMainFrameParams::New();
main_frame_params->frame_token = reply->main_frame_token;
main_frame_params->routing_id = reply->main_frame_route_id;
main_frame_params->frame = std::move(reply->frame);
main_frame_params->interface_broker =
std::move(reply->main_frame_interface_broker);
main_frame_params->document_token = reply->document_token;
main_frame_params->policy_container = std::move(reply->policy_container);
main_frame_params->associated_interface_provider_remote =
std::move(reply->associated_interface_provider);
main_frame_params->widget_params = std::move(reply->widget_params);
main_frame_params->subresource_loader_factories =
base::WrapUnique(static_cast<blink::PendingURLLoaderFactoryBundle*>(
CloneLoaderFactories()->Clone().release()));
view_params->main_frame =
mojom::CreateMainFrameUnion::NewLocalParams(std::move(main_frame_params));
view_params->blink_page_broadcast = std::move(reply->page_broadcast);
view_params->session_storage_namespace_id =
reply->cloned_session_storage_namespace_id;
DCHECK(!view_params->session_storage_namespace_id.empty())
<< "Session storage namespace must be populated.";
view_params->hidden = is_background_tab;
view_params->never_composited = never_composited;
WebView* web_view = agent_scheduling_group_.CreateWebView(
std::move(view_params),
true, base_url);
if (reply->wait_for_debugger) {
blink::WebFrameWidget* frame_widget =
web_view->MainFrame()->ToWebLocalFrame()->LocalRoot()->FrameWidget();
frame_widget->WaitForDebuggerWhenShown();
}
return web_view;
}
void RenderFrameImpl::ResetMembersUsedForDurationOfCommit() {
pending_loader_factories_ = nullptr;
pending_code_cache_host_.reset();
pending_cookie_manager_info_.reset();
pending_storage_info_.reset();
browser_side_navigation_pending_ = false;
}
#ifdef OHOS_DRAG_DROP
void RenderFrameImpl::ClearContextMenu() {
GetFrameHost()->OnClearContextMenu();
}
#endif
#if defined(OHOS_INPUT_EVENTS)
void RenderFrameImpl::SetZoomLevel(float magnify_delta,
const gfx::Point& anchor) {
auto web_frame_widget = GetLocalRootWebFrameWidget();
if (!web_frame_widget) {
return;
}
web_frame_widget->SetZoomLevel(magnify_delta, anchor);
}
void RenderFrameImpl::SetOverscrollMode(int mode) {
auto web_frame_widget = GetLocalRootWebFrameWidget();
if (!web_frame_widget) {
return;
}
web_frame_widget->SetOverscrollMode(mode);
}
#if defined(OHOS_GET_SCROLL_OFFSET)
gfx::Vector2dF RenderFrameImpl::GetOverScrollOffset() {
gfx::Vector2dF overscroll_offset;
overscroll_offset.set_x(0.0f);
overscroll_offset.set_y(0.0f);
auto web_frame_widget = GetLocalRootWebFrameWidget();
if (!web_frame_widget) {
return overscroll_offset;
}
return web_frame_widget->GetOverScrollOffset();
}
#endif
#endif
}