chromium/content/browser/devtools/protocol/page_handler.cc

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

#include "content/browser/devtools/protocol/page_handler.h"

#include <algorithm>
#include <memory>
#include <optional>
#include <sstream>
#include <string>
#include <utility>
#include <vector>

#include "base/functional/bind.h"
#include "base/location.h"
#include "base/memory/ref_counted.h"
#include "base/memory/ref_counted_memory.h"
#include "base/numerics/safe_conversions.h"
#include "base/process/process_handle.h"
#include "base/ranges/algorithm.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/strings/to_string.h"
#include "base/strings/utf_string_conversions.h"
#include "base/task/single_thread_task_runner.h"
#include "base/task/thread_pool.h"
#include "base/trace_event/trace_event.h"
#include "build/build_config.h"
#include "components/back_forward_cache/disabled_reason_id.h"
#include "content/browser/child_process_security_policy_impl.h"
#include "content/browser/devtools/devtools_agent_host_impl.h"
#include "content/browser/devtools/protocol/browser_handler.h"
#include "content/browser/devtools/protocol/devtools_mhtml_helper.h"
#include "content/browser/devtools/protocol/emulation_handler.h"
#include "content/browser/devtools/protocol/handler_helpers.h"
#include "content/browser/manifest/manifest_manager_host.h"
#include "content/browser/preloading/prerender/prerender_final_status.h"
#include "content/browser/renderer_host/back_forward_cache_can_store_document_result.h"
#include "content/browser/renderer_host/back_forward_cache_disable.h"
#include "content/browser/renderer_host/back_forward_cache_metrics.h"
#include "content/browser/renderer_host/frame_tree.h"
#include "content/browser/renderer_host/navigation_entry_impl.h"
#include "content/browser/renderer_host/navigation_request.h"
#include "content/browser/renderer_host/navigator.h"
#include "content/browser/renderer_host/render_frame_host_impl.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
#include "content/browser/renderer_host/render_widget_host_view_base.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/browser/web_contents/web_contents_view.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/download_manager.h"
#include "content/public/browser/file_select_listener.h"
#include "content/public/browser/javascript_dialog_manager.h"
#include "content/public/browser/navigation_controller.h"
#include "content/public/browser/navigation_entry.h"
#include "content/public/browser/navigation_handle.h"
#include "content/public/browser/storage_partition.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_delegate.h"
#include "content/public/common/referrer.h"
#include "content/public/common/result_codes.h"
#include "content/public/common/url_constants.h"
#include "content/public/common/url_utils.h"
#include "net/base/filename_util.h"
#include "third_party/blink/public/common/manifest/manifest_util.h"
#include "third_party/blink/public/mojom/back_forward_cache_not_restored_reasons.mojom.h"
#include "third_party/blink/public/mojom/frame/back_forward_cache_controller.mojom.h"
#include "third_party/blink/public/mojom/manifest/manifest.mojom.h"
#include "third_party/blink/public/mojom/script_source_location.mojom.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "third_party/skia/include/core/SkColor.h"
#include "ui/base/page_transition_types.h"
#include "ui/gfx/codec/jpeg_codec.h"
#include "ui/gfx/codec/png_codec.h"
#include "ui/gfx/codec/webp_codec.h"
#include "ui/gfx/color_utils.h"
#include "ui/gfx/geometry/size.h"
#include "ui/gfx/geometry/size_conversions.h"
#include "ui/gfx/image/image.h"
#include "ui/gfx/skbitmap_operations.h"
#include "ui/snapshot/snapshot.h"
#include "url/gurl.h"

#if BUILDFLAG(IS_ANDROID)
#include "content/browser/renderer_host/compositor_impl_android.h"
#endif

namespace content {
namespace protocol {

namespace {

constexpr const char* kMhtml =;
constexpr int kDefaultScreenshotQuality =;
constexpr int kMaxScreencastFramesInFlight =;
constexpr char kCommandIsOnlyAvailableAtTopTarget[] =;
constexpr char kErrorNotAttached[] =;
constexpr char kErrorInactivePage[] =;

BitmapEncoder;

bool EncodeBitmapAsPngSlow(const SkBitmap& bitmap,
                           std::vector<uint8_t>& output) {}

bool EncodeBitmapAsPngFast(const SkBitmap& bitmap,
                           std::vector<uint8_t>& output) {}

bool EncodeBitmapAsJpeg(int quality,
                        const SkBitmap& bitmap,
                        std::vector<uint8_t>& output) {}

bool EncodeBitmapAsWebp(int quality,
                        const SkBitmap& bitmap,
                        std::vector<uint8_t>& output) {}

absl::variant<protocol::Response, BitmapEncoder>
GetEncoder(const std::string& format, int quality, bool optimize_for_speed) {}

std::unique_ptr<Page::ScreencastFrameMetadata> BuildScreencastFrameMetadata(
    const gfx::Size& surface_size,
    float device_scale_factor,
    float page_scale_factor,
    const gfx::PointF& root_scroll_offset,
    float top_controls_visible_height) {}

// Determines the snapshot size that best-fits the Surface's content to the
// remote's requested image size.
gfx::Size DetermineSnapshotSize(const gfx::Size& surface_size,
                                int screencast_max_width,
                                int screencast_max_height) {}

void GetMetadataFromFrame(const media::VideoFrame& frame,
                          double* device_scale_factor,
                          double* page_scale_factor,
                          gfx::PointF* root_scroll_offset,
                          double* top_controls_visible_height) {}

template <typename ProtocolCallback>
bool CanExecuteGlobalCommands(
    PageHandler* page_handler,
    const std::unique_ptr<ProtocolCallback>& callback) {}

void GotManifest(protocol::Maybe<std::string> manifest_id,
                 std::unique_ptr<PageHandler::GetAppManifestCallback> callback,
                 const GURL& manifest_url,
                 ::blink::mojom::ManifestPtr input_manifest,
                 blink::mojom::ManifestDebugInfoPtr debug_info) {}

}  // namespace

PageHandler::PageHandler(EmulationHandler* emulation_handler,
                         BrowserHandler* browser_handler,
                         bool allow_unsafe_operations,
                         bool is_trusted,
                         std::optional<url::Origin> navigation_initiator_origin,
                         bool may_read_local_files)
    :{}

PageHandler::~PageHandler() = default;

// static
std::vector<PageHandler*> PageHandler::EnabledForWebContents(
    WebContentsImpl* contents) {}

// static
std::vector<PageHandler*> PageHandler::ForAgentHost(
    DevToolsAgentHostImpl* host) {}

void PageHandler::SetRenderer(int process_host_id,
                              RenderFrameHostImpl* frame_host) {}

void PageHandler::Wire(UberDispatcher* dispatcher) {}

void PageHandler::RenderWidgetHostVisibilityChanged(
    RenderWidgetHost* widget_host,
    bool became_visible) {}

void PageHandler::RenderWidgetHostDestroyed(RenderWidgetHost* widget_host) {}

void PageHandler::DidAttachInterstitialPage() {}

void PageHandler::DidDetachInterstitialPage() {}

void PageHandler::DidRunJavaScriptDialog(const GURL& url,
                                         const std::u16string& message,
                                         const std::u16string& default_prompt,
                                         JavaScriptDialogType dialog_type,
                                         bool has_non_devtools_handlers,
                                         JavaScriptDialogCallback callback) {}

void PageHandler::DidRunBeforeUnloadConfirm(const GURL& url,
                                            bool has_non_devtools_handlers,
                                            JavaScriptDialogCallback callback) {}

void PageHandler::DidCloseJavaScriptDialog(bool success,
                                           const std::u16string& user_input) {}

Response PageHandler::Enable() {}

Response PageHandler::Disable() {}

Response PageHandler::Crash() {}

Response PageHandler::Close() {}

void PageHandler::Reload(Maybe<bool> bypassCache,
                         Maybe<std::string> script_to_evaluate_on_load,
                         Maybe<std::string> loader_id,
                         std::unique_ptr<ReloadCallback> callback) {}

static network::mojom::ReferrerPolicy ParsePolicyFromString(
    const std::string& policy) {}

namespace {

void DispatchNavigateCallback(
    NavigationRequest* request,
    std::unique_ptr<PageHandler::NavigateCallback> callback) {}

}  // namespace

void PageHandler::Navigate(const std::string& url,
                           Maybe<std::string> referrer,
                           Maybe<std::string> maybe_transition_type,
                           Maybe<std::string> frame_id,
                           Maybe<std::string> referrer_policy,
                           std::unique_ptr<NavigateCallback> callback) {}

void PageHandler::NavigationReset(NavigationRequest* navigation_request) {}

void PageHandler::DownloadWillBegin(FrameTreeNode* ftn,
                                    download::DownloadItem* item) {}

void PageHandler::OnFrameDetached(const base::UnguessableToken& frame_id) {}

void PageHandler::DidChangeFrameLoadingState(const FrameTreeNode& ftn) {}

void PageHandler::OnDownloadDestroyed(download::DownloadItem* item) {}

void PageHandler::OnDownloadUpdated(download::DownloadItem* item) {}

static const char* TransitionTypeName(ui::PageTransition type) {}

Response PageHandler::GetNavigationHistory(
    int* current_index,
    std::unique_ptr<NavigationEntries>* entries) {}

Response PageHandler::NavigateToHistoryEntry(int entry_id) {}

static bool ReturnTrue(NavigationEntry* entry) {}

Response PageHandler::ResetNavigationHistory() {}

void PageHandler::CaptureSnapshot(
    Maybe<std::string> format,
    std::unique_ptr<CaptureSnapshotCallback> callback) {}

// Sets a clip with full page dimensions. Calls CaptureScreenshot with updated
// value to proceed with capturing the full page screenshot.
// TODO(crbug.com/40238745): at the point this method is called, the page could
// have changed its size.
void PageHandler::CaptureFullPageScreenshot(
    Maybe<std::string> format,
    Maybe<int> quality,
    Maybe<bool> optimize_for_speed,
    std::unique_ptr<CaptureScreenshotCallback> callback,
    const gfx::Size& full_page_size) {}

void PageHandler::CaptureScreenshot(
    Maybe<std::string> format,
    Maybe<int> quality,
    Maybe<Page::Viewport> clip,
    Maybe<bool> from_surface,
    Maybe<bool> capture_beyond_viewport,
    Maybe<bool> optimize_for_speed,
    std::unique_ptr<CaptureScreenshotCallback> callback) {}

Response PageHandler::StartScreencast(Maybe<std::string> format,
                                      Maybe<int> quality,
                                      Maybe<int> max_width,
                                      Maybe<int> max_height,
                                      Maybe<int> every_nth_frame) {}

Response PageHandler::StopScreencast() {}

Response PageHandler::ScreencastFrameAck(int session_id) {}

Response PageHandler::HandleJavaScriptDialog(bool accept,
                                             Maybe<std::string> prompt_text) {}

Response PageHandler::BringToFront() {}

Response PageHandler::SetDownloadBehavior(const std::string& behavior,
                                          Maybe<std::string> download_path) {}

void PageHandler::GetAppManifest(
    protocol::Maybe<std::string> manifest_id,
    std::unique_ptr<GetAppManifestCallback> callback) {}

PageHandler::ResponseOrWebContents
PageHandler::GetWebContentsForTopLevelActiveFrame() {}

void PageHandler::NotifyScreencastVisibility(bool visible) {}

bool PageHandler::ShouldCaptureNextScreencastFrame() {}

void PageHandler::OnFrameFromVideoConsumer(
    scoped_refptr<media::VideoFrame> frame) {}

void PageHandler::ScreencastFrameCaptured(
    std::unique_ptr<Page::ScreencastFrameMetadata> page_metadata,
    const SkBitmap& bitmap) {}

void PageHandler::ScreencastFrameEncoded(
    std::unique_ptr<Page::ScreencastFrameMetadata> page_metadata,
    std::vector<uint8_t> data) {}

void PageHandler::ScreenshotCaptured(
    std::unique_ptr<CaptureScreenshotCallback> callback,
    BitmapEncoder encoder,
    const gfx::Size& original_view_size,
    const gfx::Size& requested_image_size,
    const blink::DeviceEmulationParams& original_emulation_params,
    const std::optional<blink::web_pref::WebPreferences>&
        maybe_original_web_prefs,
    const gfx::Image& image) {}

Response PageHandler::StopLoading() {}

Response PageHandler::SetWebLifecycleState(const std::string& state) {}

void PageHandler::GetInstallabilityErrors(
    std::unique_ptr<GetInstallabilityErrorsCallback> callback) {}

void PageHandler::GetManifestIcons(
    std::unique_ptr<GetManifestIconsCallback> callback) {}

void PageHandler::GetAppId(std::unique_ptr<GetAppIdCallback> callback) {}

Response PageHandler::SetBypassCSP(bool enabled) {}

Page::BackForwardCacheNotRestoredReason NotRestoredReasonToProtocol(
    BackForwardCacheMetrics::NotRestoredReason reason) {}

WebSchedulerTrackedFeature;
Page::BackForwardCacheNotRestoredReason BlocklistedFeatureToProtocol(
    WebSchedulerTrackedFeature feature) {}

std::unique_ptr<Page::BackForwardCacheBlockingDetails> SourceLocationToProtocol(
    const blink::mojom::ScriptSourceLocationPtr& source) {}

Page::BackForwardCacheNotRestoredReason
DisableForRenderFrameHostReasonToProtocol(
    BackForwardCache::DisabledReason reason) {}

Page::BackForwardCacheNotRestoredReasonType MapNotRestoredReasonToType(
    BackForwardCacheMetrics::NotRestoredReason reason) {}

Page::BackForwardCacheNotRestoredReasonType MapBlocklistedFeatureToType(
    WebSchedulerTrackedFeature feature) {}

Page::BackForwardCacheNotRestoredReasonType
MapDisableForRenderFrameHostReasonToType(
    BackForwardCache::DisabledReason reason) {}

BlockingDetailsMap;

std::unique_ptr<protocol::Array<Page::BackForwardCacheNotRestoredExplanation>>
CreateNotRestoredExplanation(
    const BackForwardCacheCanStoreDocumentResult::NotRestoredReasons
        not_restored_reasons,
    const blink::scheduler::WebSchedulerTrackedFeatures blocklisted_features,
    const BackForwardCacheCanStoreDocumentResult::DisabledReasonsMap&
        disabled_reasons,
    const BlockingDetailsMap& details) {}

std::unique_ptr<Page::BackForwardCacheNotRestoredExplanationTree>
CreateNotRestoredExplanationTree(
    const BackForwardCacheCanStoreTreeResult& tree_result) {}

Response PageHandler::AddCompilationCache(const std::string& url,
                                          const Binary& data) {}

void PageHandler::IsPrerenderingAllowed(bool& is_allowed) {}

Response PageHandler::SetPrerenderingAllowed(bool is_allowed) {}

Response PageHandler::AssureTopLevelActiveFrame() {}

void PageHandler::BackForwardCacheNotUsed(
    const NavigationRequest* navigation,
    const BackForwardCacheCanStoreDocumentResult* result,
    const BackForwardCacheCanStoreTreeResult* tree_result) {}

bool PageHandler::ShouldBypassCSP() {}

}  // namespace protocol
}  // namespace content