chromium/third_party/blink/renderer/core/frame/local_frame_mojo_handler.cc

// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifdef UNSAFE_BUFFERS_BUILD
// TODO(crbug.com/351564777): Remove this and convert code to safer constructs.
#pragma allow_unsafe_buffers
#endif

#include "third_party/blink/renderer/core/frame/local_frame_mojo_handler.h"

#include "base/metrics/histogram_functions.h"
#include "base/numerics/safe_conversions.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "cc/input/browser_controls_offset_tags_info.h"
#include "services/network/public/cpp/url_loader_completion_status.h"
#include "services/network/public/mojom/url_response_head.mojom.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/features.h"
#include "third_party/blink/public/common/frame/frame_owner_element_type.h"
#include "third_party/blink/public/common/page_state/page_state.h"
#include "third_party/blink/public/mojom/devtools/console_message.mojom-blink-forward.h"
#include "third_party/blink/public/mojom/devtools/inspector_issue.mojom-blink.h"
#include "third_party/blink/public/mojom/frame/frame_owner_properties.mojom-blink.h"
#include "third_party/blink/public/mojom/frame/media_player_action.mojom-blink.h"
#include "third_party/blink/public/mojom/opengraph/metadata.mojom-blink.h"
#include "third_party/blink/public/mojom/timing/resource_timing.mojom-blink-forward.h"
#include "third_party/blink/public/platform/browser_interface_broker_proxy.h"
#include "third_party/blink/public/platform/interface_registry.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/web/web_local_frame.h"
#include "third_party/blink/public/web/web_local_frame_client.h"
#include "third_party/blink/public/web/web_plugin.h"
#include "third_party/blink/renderer/bindings/core/v8/script_controller.h"
#include "third_party/blink/renderer/bindings/core/v8/script_evaluation_result.h"
#include "third_party/blink/renderer/bindings/core/v8/script_function.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_fullscreen_options.h"
#include "third_party/blink/renderer/core/dom/element_traversal.h"
#include "third_party/blink/renderer/core/dom/focus_params.h"
#include "third_party/blink/renderer/core/dom/ignore_opens_during_unload_count_incrementer.h"
#include "third_party/blink/renderer/core/editing/editing_utilities.h"
#include "third_party/blink/renderer/core/editing/frame_selection.h"
#include "third_party/blink/renderer/core/editing/surrounding_text.h"
#include "third_party/blink/renderer/core/exported/web_plugin_container_impl.h"
#include "third_party/blink/renderer/core/frame/csp/content_security_policy.h"
#include "third_party/blink/renderer/core/frame/frame_console.h"
#include "third_party/blink/renderer/core/frame/intervention.h"
#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/frame/local_frame_client.h"
#include "third_party/blink/renderer/core/frame/pausable_script_executor.h"
#include "third_party/blink/renderer/core/frame/remote_frame_owner.h"
#include "third_party/blink/renderer/core/frame/reporting_context.h"
#include "third_party/blink/renderer/core/frame/savable_resources.h"
#include "third_party/blink/renderer/core/frame/web_local_frame_impl.h"
#include "third_party/blink/renderer/core/fullscreen/fullscreen.h"
#include "third_party/blink/renderer/core/html/html_element.h"
#include "third_party/blink/renderer/core/html/html_embed_element.h"
#include "third_party/blink/renderer/core/html/html_link_element.h"
#include "third_party/blink/renderer/core/html/html_meta_element.h"
#include "third_party/blink/renderer/core/html/html_object_element.h"
#include "third_party/blink/renderer/core/html/media/html_video_element.h"
#include "third_party/blink/renderer/core/input/event_handler.h"
#include "third_party/blink/renderer/core/inspector/console_message.h"
#include "third_party/blink/renderer/core/inspector/main_thread_debugger.h"
#include "third_party/blink/renderer/core/layout/layout_embedded_content.h"
#include "third_party/blink/renderer/core/loader/mixed_content_checker.h"
#include "third_party/blink/renderer/core/messaging/message_port.h"
#include "third_party/blink/renderer/core/navigation_api/navigation_api.h"
#include "third_party/blink/renderer/core/page/chrome_client.h"
#include "third_party/blink/renderer/core/page/focus_controller.h"
#include "third_party/blink/renderer/core/page/page.h"
#include "third_party/blink/renderer/core/paint/timing/paint_timing.h"
#include "third_party/blink/renderer/core/script/classic_script.h"
#include "third_party/blink/renderer/core/timing/dom_window_performance.h"
#include "third_party/blink/renderer/core/view_transition/page_swap_event.h"
#include "third_party/blink/renderer/core/view_transition/view_transition_supplement.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_timing_utils.h"
#include "third_party/blink/renderer/platform/widget/frame_widget.h"

#if BUILDFLAG(IS_MAC)
#include "base/apple/foundation_util.h"
#include "third_party/blink/renderer/core/editing/substring_util.h"
#include "third_party/blink/renderer/platform/fonts/mac/attributed_string_type_converter.h"
#include "ui/base/mojom/attributed_string.mojom-blink.h"
#endif

namespace blink {

namespace {

constexpr char kInvalidWorldID[] =;

#if BUILDFLAG(IS_MAC)
size_t GetCurrentCursorPositionInFrame(LocalFrame* local_frame) {
  blink::WebRange range =
      WebLocalFrameImpl::FromFrame(local_frame)->SelectionRange();
  return range.IsNull() ? size_t{0} : static_cast<size_t>(range.StartOffset());
}
#endif

RemoteFrame* SourceFrameForOptionalToken(
    const std::optional<RemoteFrameToken>& source_frame_token) {}

v8::Local<v8::Context> MainWorldScriptContext(LocalFrame* local_frame) {}

base::Value GetJavaScriptExecutionResult(v8::Local<v8::Value> result,
                                         v8::Local<v8::Context> context,
                                         WebV8ValueConverter* converter) {}

v8::MaybeLocal<v8::Value> GetProperty(v8::Local<v8::Context> context,
                                      v8::Local<v8::Value> object,
                                      const String& name) {}

v8::MaybeLocal<v8::Value> CallMethodOnFrame(LocalFrame* local_frame,
                                            const String& object_name,
                                            const String& method_name,
                                            base::Value::List arguments,
                                            WebV8ValueConverter* converter) {}

HitTestResult HitTestResultForRootFramePos(
    LocalFrame* frame,
    const PhysicalOffset& pos_in_root_frame) {}

void ParseOpenGraphProperty(const HTMLMetaElement& element,
                            const Document& document,
                            mojom::blink::OpenGraphMetadata* metadata) {}

// Convert the error to a string so it can be sent back to the test.
//
// We try to use .stack property so that the error message contains a stack
// trace, but otherwise fallback to .toString().
v8::Local<v8::String> ErrorToString(ScriptState* script_state,
                                    v8::Local<v8::Value> error) {}

class JavaScriptExecuteRequestForTestsHandler
    : public GarbageCollected<JavaScriptExecuteRequestForTestsHandler> {};

}  // namespace

ActiveURLMessageFilter::~ActiveURLMessageFilter() {}

bool ActiveURLMessageFilter::WillDispatch(mojo::Message* message) {}

void ActiveURLMessageFilter::DidDispatchOrReject(mojo::Message* message,
                                                 bool accepted) {}

LocalFrameMojoHandler::LocalFrameMojoHandler(blink::LocalFrame& frame)
    :{}

void LocalFrameMojoHandler::Trace(Visitor* visitor) const {}

void LocalFrameMojoHandler::WasAttachedAsLocalMainFrame() {}

void LocalFrameMojoHandler::DidDetachFrame() {}

void LocalFrameMojoHandler::ClosePageForTesting() {}

mojom::blink::BackForwardCacheControllerHost&
LocalFrameMojoHandler::BackForwardCacheControllerHostRemote() {}

#if BUILDFLAG(IS_MAC)
mojom::blink::TextInputHost& LocalFrameMojoHandler::TextInputHost() {
  DCHECK(text_input_host_.is_bound());
  return *text_input_host_.get();
}

void LocalFrameMojoHandler::ResetTextInputHostForTesting() {
  text_input_host_.reset();
}

void LocalFrameMojoHandler::RebindTextInputHostForTesting() {
  frame_->GetBrowserInterfaceBroker().GetInterface(
      text_input_host_.BindNewPipeAndPassReceiver(
          frame_->GetTaskRunner(TaskType::kInternalDefault)));
}
#endif

mojom::blink::ReportingServiceProxy* LocalFrameMojoHandler::ReportingService() {}

mojom::blink::DevicePostureProvider*
LocalFrameMojoHandler::DevicePostureProvider() {}

mojom::blink::DevicePostureType LocalFrameMojoHandler::GetDevicePosture() {}

void LocalFrameMojoHandler::OverrideDevicePostureForEmulation(
    mojom::blink::DevicePostureType device_posture_param) {}

void LocalFrameMojoHandler::DisableDevicePostureOverrideForEmulation() {}

Page* LocalFrameMojoHandler::GetPage() const {}

LocalDOMWindow* LocalFrameMojoHandler::DomWindow() const {}

Document* LocalFrameMojoHandler::GetDocument() const {}

void LocalFrameMojoHandler::BindToLocalFrameReceiver(
    mojo::PendingAssociatedReceiver<mojom::blink::LocalFrame> receiver) {}

void LocalFrameMojoHandler::BindToMainFrameReceiver(
    mojo::PendingAssociatedReceiver<mojom::blink::LocalMainFrame> receiver) {}

void LocalFrameMojoHandler::BindFullscreenVideoElementReceiver(
    mojo::PendingAssociatedReceiver<mojom::blink::FullscreenVideoElementHandler>
        receiver) {}

void LocalFrameMojoHandler::GetTextSurroundingSelection(
    uint32_t max_length,
    GetTextSurroundingSelectionCallback callback) {}

void LocalFrameMojoHandler::SendInterventionReport(const String& id,
                                                   const String& message) {}

void LocalFrameMojoHandler::SetFrameOwnerProperties(
    mojom::blink::FrameOwnerPropertiesPtr properties) {}

void LocalFrameMojoHandler::NotifyUserActivation(
    mojom::blink::UserActivationNotificationType notification_type) {}

void LocalFrameMojoHandler::NotifyVirtualKeyboardOverlayRect(
    const gfx::Rect& keyboard_rect) {}

void LocalFrameMojoHandler::AddMessageToConsole(
    mojom::blink::ConsoleMessageLevel level,
    const WTF::String& message,
    bool discard_duplicates) {}

void LocalFrameMojoHandler::SwapInImmediately() {}

void LocalFrameMojoHandler::CheckCompleted() {}

void LocalFrameMojoHandler::StopLoading() {}

void LocalFrameMojoHandler::Collapse(bool collapsed) {}

void LocalFrameMojoHandler::EnableViewSourceMode() {}

void LocalFrameMojoHandler::Focus() {}

void LocalFrameMojoHandler::ClearFocusedElement() {}

void LocalFrameMojoHandler::CopyImageAt(const gfx::Point& window_point) {}

void LocalFrameMojoHandler::SaveImageAt(const gfx::Point& window_point) {}

void LocalFrameMojoHandler::ReportBlinkFeatureUsage(
    const Vector<mojom::blink::WebFeature>& features) {}

void LocalFrameMojoHandler::RenderFallbackContent() {}

void LocalFrameMojoHandler::BeforeUnload(bool is_reload,
                                         BeforeUnloadCallback callback) {}

void LocalFrameMojoHandler::MediaPlayerActionAt(
    const gfx::Point& window_point,
    blink::mojom::blink::MediaPlayerActionPtr action) {}

void LocalFrameMojoHandler::RequestVideoFrameAtWithBoundsHint(
    const gfx::Point& window_point,
    const gfx::Size& max_size,
    int max_area,
    RequestVideoFrameAtWithBoundsHintCallback callback) {}

void LocalFrameMojoHandler::AdvanceFocusInFrame(
    mojom::blink::FocusType focus_type,
    const std::optional<RemoteFrameToken>& source_frame_token) {}

void LocalFrameMojoHandler::AdvanceFocusForIME(
    mojom::blink::FocusType focus_type) {}

void LocalFrameMojoHandler::ReportContentSecurityPolicyViolation(
    network::mojom::blink::CSPViolationPtr violation) {}

void LocalFrameMojoHandler::DidUpdateFramePolicy(
    const FramePolicy& frame_policy) {}

void LocalFrameMojoHandler::OnFrameVisibilityChanged(
    mojom::blink::FrameVisibility visibility) {}

void LocalFrameMojoHandler::OnPostureChanged(
    mojom::blink::DevicePostureType posture) {}

void LocalFrameMojoHandler::PostMessageEvent(
    const std::optional<RemoteFrameToken>& source_frame_token,
    const String& source_origin,
    const String& target_origin,
    BlinkTransferableMessage message) {}

void LocalFrameMojoHandler::JavaScriptMethodExecuteRequest(
    const String& object_name,
    const String& method_name,
    base::Value::List arguments,
    bool wants_result,
    JavaScriptMethodExecuteRequestCallback callback) {}

void LocalFrameMojoHandler::JavaScriptExecuteRequest(
    const String& javascript,
    bool wants_result,
    JavaScriptExecuteRequestCallback callback) {}

void LocalFrameMojoHandler::JavaScriptExecuteRequestForTests(
    const String& javascript,
    bool has_user_gesture,
    bool resolve_promises,
    bool honor_js_content_settings,
    int32_t world_id,
    JavaScriptExecuteRequestForTestsCallback callback) {}

void LocalFrameMojoHandler::JavaScriptExecuteRequestInIsolatedWorld(
    const String& javascript,
    bool wants_result,
    int32_t world_id,
    JavaScriptExecuteRequestInIsolatedWorldCallback callback) {}

#if BUILDFLAG(IS_MAC)
void LocalFrameMojoHandler::GetCharacterIndexAtPoint(const gfx::Point& point) {
  frame_->GetCharacterIndexAtPoint(point);
}

void LocalFrameMojoHandler::GetFirstRectForRange(const gfx::Range& range) {
  gfx::Rect rect;
  WebLocalFrameClient* client = WebLocalFrameImpl::FromFrame(frame_)->Client();
  if (!client)
    return;

  WebPluginContainerImpl* plugin_container = frame_->GetWebPluginContainer();
  if (plugin_container) {
    // Pepper-free PDF will reach here.
    rect = plugin_container->Plugin()->GetPluginCaretBounds();
  } else {
    // TODO(crbug.com/40511450): Remove `pepper_has_caret` once PPAPI is gone.
    bool pepper_has_caret = client->GetCaretBoundsFromFocusedPlugin(rect);
    if (!pepper_has_caret) {
      // When request range is invalid we will try to obtain it from current
      // frame selection. The fallback value will be 0.
      size_t start = range.IsValid()
                           ? range.start()
                           : GetCurrentCursorPositionInFrame(frame_);

      WebLocalFrameImpl::FromFrame(frame_)->FirstRectForCharacterRange(
          base::checked_cast<uint32_t>(start),
          base::checked_cast<uint32_t>(range.length()), rect);
    }
  }

  TextInputHost().GotFirstRectForRange(rect);
}

void LocalFrameMojoHandler::GetStringForRange(
    const gfx::Range& range,
    GetStringForRangeCallback callback) {
  gfx::Point baseline_point;
  ui::mojom::blink::AttributedStringPtr attributed_string = nullptr;
  base::apple::ScopedCFTypeRef<CFAttributedStringRef> string =
      SubstringUtil::AttributedSubstringInRange(
          frame_, base::checked_cast<WTF::wtf_size_t>(range.start()),
          base::checked_cast<WTF::wtf_size_t>(range.length()), baseline_point);
  if (string) {
    attributed_string = ui::mojom::blink::AttributedString::From(string.get());
  }

  std::move(callback).Run(std::move(attributed_string), baseline_point);
}
#endif

void LocalFrameMojoHandler::BindReportingObserver(
    mojo::PendingReceiver<mojom::blink::ReportingObserver> receiver) {}

void LocalFrameMojoHandler::UpdateOpener(
    const std::optional<blink::FrameToken>& opener_frame_token) {}

void LocalFrameMojoHandler::GetSavableResourceLinks(
    GetSavableResourceLinksCallback callback) {}

void LocalFrameMojoHandler::MixedContentFound(
    const KURL& main_resource_url,
    const KURL& mixed_content_url,
    mojom::blink::RequestContextType request_context,
    bool was_allowed,
    const KURL& url_before_redirects,
    bool had_redirect,
    network::mojom::blink::SourceLocationPtr source_location) {}

void LocalFrameMojoHandler::BindDevToolsAgent(
    mojo::PendingAssociatedRemote<mojom::blink::DevToolsAgentHost> host,
    mojo::PendingAssociatedReceiver<mojom::blink::DevToolsAgent> receiver) {}

#if BUILDFLAG(IS_ANDROID)
void LocalFrameMojoHandler::ExtractSmartClipData(
    const gfx::Rect& rect,
    ExtractSmartClipDataCallback callback) {
  String clip_text;
  String clip_html;
  gfx::Rect clip_rect;
  frame_->ExtractSmartClipDataInternal(rect, clip_text, clip_html, clip_rect);
  std::move(callback).Run(clip_text.IsNull() ? g_empty_string : clip_text,
                          clip_html.IsNull() ? g_empty_string : clip_html,
                          clip_rect);
}
#endif  // BUILDFLAG(IS_ANDROID)

void LocalFrameMojoHandler::HandleRendererDebugURL(const KURL& url) {}

void LocalFrameMojoHandler::GetCanonicalUrlForSharing(
    GetCanonicalUrlForSharingCallback callback) {}

void LocalFrameMojoHandler::GetOpenGraphMetadata(
    GetOpenGraphMetadataCallback callback) {}

void LocalFrameMojoHandler::SetNavigationApiHistoryEntriesForRestore(
    mojom::blink::NavigationApiHistoryEntryArraysPtr entry_arrays,
    mojom::blink::NavigationApiEntryRestoreReason restore_reason) {}

void LocalFrameMojoHandler::NotifyNavigationApiOfDisposedEntries(
    const WTF::Vector<WTF::String>& keys) {}

void LocalFrameMojoHandler::DispatchNavigateEventForCrossDocumentTraversal(
    const KURL& url,
    const std::string& page_state,
    bool is_browser_initiated) {}

void LocalFrameMojoHandler::TraverseCancelled(
    const String& navigation_api_key,
    mojom::blink::TraverseCancelledReason reason) {}

void LocalFrameMojoHandler::AnimateDoubleTapZoom(const gfx::Point& point,
                                                 const gfx::Rect& rect) {}

void LocalFrameMojoHandler::SetScaleFactor(float scale_factor) {}

void LocalFrameMojoHandler::ClosePage(
    mojom::blink::LocalMainFrame::ClosePageCallback completion_callback) {}

void LocalFrameMojoHandler::GetFullPageSize(
    mojom::blink::LocalMainFrame::GetFullPageSizeCallback callback) {}

void LocalFrameMojoHandler::PluginActionAt(
    const gfx::Point& location,
    mojom::blink::PluginActionType action) {}

void LocalFrameMojoHandler::SetInitialFocus(bool reverse) {}

void LocalFrameMojoHandler::EnablePreferredSizeChangedMode() {}

void LocalFrameMojoHandler::ZoomToFindInPageRect(
    const gfx::Rect& rect_in_root_frame) {}

void LocalFrameMojoHandler::InstallCoopAccessMonitor(
    const FrameToken& accessed_window,
    network::mojom::blink::CrossOriginOpenerPolicyReporterParamsPtr
        coop_reporter_params,
    bool is_in_same_virtual_coop_related_group) {}

void LocalFrameMojoHandler::UpdateBrowserControlsState(
    cc::BrowserControlsState constraints,
    cc::BrowserControlsState current,
    bool animate,
    const std::optional<cc::BrowserControlsOffsetTagsInfo>& offset_tags_info) {}

void LocalFrameMojoHandler::Discard() {}

void LocalFrameMojoHandler::SetV8CompileHints(
    base::ReadOnlySharedMemoryRegion data) {}

void LocalFrameMojoHandler::SnapshotDocumentForViewTransition(
    const blink::ViewTransitionToken& transition_token,
    mojom::blink::PageSwapEventParamsPtr params,
    SnapshotDocumentForViewTransitionCallback callback) {}

void LocalFrameMojoHandler::NotifyViewTransitionAbortedToOldDocument() {}

void LocalFrameMojoHandler::DispatchPageSwap(
    mojom::blink::PageSwapEventParamsPtr params) {}

void LocalFrameMojoHandler::AddResourceTimingEntryForFailedSubframeNavigation(
    const FrameToken& subframe_token,
    const KURL& initial_url,
    base::TimeTicks start_time,
    base::TimeTicks redirect_time,
    base::TimeTicks request_start,
    base::TimeTicks response_start,
    uint32_t response_code,
    const WTF::String& mime_type,
    network::mojom::blink::LoadTimingInfoPtr load_timing_info,
    net::HttpConnectionInfo connection_info,
    const WTF::String& alpn_negotiated_protocol,
    bool is_secure_transport,
    bool is_validated,
    const WTF::String& normalized_server_timing,
    const network::URLLoaderCompletionStatus& completion_status) {}

void LocalFrameMojoHandler::RequestFullscreenVideoElement() {}

void LocalFrameMojoHandler::UpdatePrerenderURL(
    const KURL& matched_url,
    UpdatePrerenderURLCallback callback) {}

}  // namespace blink