chromium/chrome/browser/devtools/devtools_ui_bindings.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 "chrome/browser/devtools/devtools_ui_bindings.h"

#include <stddef.h>

#include <memory>
#include <string_view>
#include <utility>

#include "aida_client.h"
#include "base/base64.h"
#include "base/command_line.h"
#include "base/functional/bind.h"
#include "base/functional/callback_helpers.h"
#include "base/json/json_reader.h"
#include "base/json/string_escape.h"
#include "base/memory/raw_ptr.h"
#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
#include "base/metrics/user_metrics.h"
#include "base/no_destructor.h"
#include "base/not_fatal_until.h"
#include "base/ranges/algorithm.h"
#include "base/strings/escape.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/time/time.h"
#include "base/uuid.h"
#include "base/values.h"
#include "build/build_config.h"
#include "chrome/browser/browser_features.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/devtools/devtools_file_watcher.h"
#include "chrome/browser/devtools/devtools_window.h"
#include "chrome/browser/devtools/url_constants.h"
#include "chrome/browser/extensions/extension_management.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_avatar_icon_util.h"
#include "chrome/browser/search/search.h"
#include "chrome/browser/search_engines/template_url_service_factory.h"
#include "chrome/browser/signin/identity_manager_factory.h"
#include "chrome/browser/sync/sync_service_factory.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_finder.h"
#include "chrome/browser/ui/hats/hats_service.h"
#include "chrome/browser/ui/hats/hats_service_factory.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/extensions/chrome_manifest_url_handlers.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/url_constants.h"
#include "components/infobars/content/content_infobar_manager.h"
#include "components/metrics/structured/structured_events.h"
#include "components/metrics/structured/structured_metrics_client.h"
#include "components/prefs/scoped_user_pref_update.h"
#include "components/search_engines/util.h"
#include "components/signin/public/identity_manager/account_info.h"
#include "components/signin/public/identity_manager/identity_manager.h"
#include "components/sync/service/sync_service.h"
#include "components/sync_preferences/pref_service_syncable.h"
#include "components/zoom/page_zoom.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/child_process_security_policy.h"
#include "content/public/browser/devtools_external_agent_proxy.h"
#include "content/public/browser/devtools_external_agent_proxy_delegate.h"
#include "content/public/browser/file_url_loader.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/reload_type.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/shared_cors_origin_access_list.h"
#include "content/public/browser/storage_partition.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_observer.h"
#include "content/public/browser/web_ui_url_loader_factory.h"
#include "content/public/common/url_constants.h"
#include "content/public/common/url_utils.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/browser/extension_system.h"
#include "extensions/browser/extension_util.h"
#include "extensions/common/constants.h"
#include "extensions/common/permissions/permissions_data.h"
#include "google_apis/google_api_keys.h"
#include "ipc/ipc_channel.h"
#include "net/base/load_flags.h"
#include "net/base/net_errors.h"
#include "net/base/url_util.h"
#include "net/http/http_response_headers.h"
#include "net/http/http_status_code.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
#include "services/network/public/cpp/resource_request.h"
#include "services/network/public/cpp/simple_url_loader.h"
#include "services/network/public/cpp/simple_url_loader_stream_consumer.h"
#include "services/network/public/cpp/wrapper_shared_url_loader_factory.h"
#include "services/network/public/mojom/url_response_head.mojom.h"
#include "third_party/blink/public/public_buildflags.h"
#include "ui/base/page_transition_types.h"
#include "ui/base/resource/resource_bundle.h"

BrowserThread;

namespace content {
struct LoadCommittedDetails;
struct FrameNavigateParams;
}  // namespace content

namespace {

const char kFrontendHostId[] =;
const char kFrontendHostMethod[] =;
const char kFrontendHostParams[] =;
const char kTitleFormat[] =;

const char kConfigDiscoverUsbDevices[] =;
const char kConfigPortForwardingEnabled[] =;
const char kConfigPortForwardingConfig[] =;
const char kConfigNetworkDiscoveryEnabled[] =;
const char kConfigNetworkDiscoveryConfig[] =;

// This constant should be in sync with
// the constant
// kShellMaxMessageChunkSize in content/shell/browser/shell_devtools_bindings.cc
// and
// kLayoutTestMaxMessageChunkSize in
// content/shell/browser/layout_test/devtools_protocol_test_bindings.cc.
const size_t kMaxMessageChunkSize =;

base::Value::Dict CreateFileSystemValue(
    DevToolsFileHelper::FileSystem file_system) {}

// DevToolsUIDefaultDelegate --------------------------------------------------

class DefaultBindingsDelegate : public DevToolsUIBindings::Delegate {};

void DefaultBindingsDelegate::ActivateWindow() {}

void DefaultBindingsDelegate::OpenInNewTab(const std::string& url) {}

void DefaultBindingsDelegate::OpenSearchResultsInNewTab(
    const std::string& query) {}

void DefaultBindingsDelegate::InspectedContentsClosing() {}

infobars::ContentInfoBarManager* DefaultBindingsDelegate::GetInfoBarManager() {}

base::Value::Dict BuildObjectForResponse(const net::HttpResponseHeaders* rh,
                                         bool success,
                                         int net_error) {}

GURL SanitizeFrontendURL(const GURL& url,
                         const std::string& scheme,
                         const std::string& host,
                         const std::string& path,
                         bool allow_query_and_fragment);

std::string SanitizeRevision(const std::string& revision) {}

std::string SanitizeRemoteVersion(const std::string& remoteVersion) {}

std::string SanitizeFrontendPath(const std::string& path) {}

std::string SanitizeEndpoint(const std::string& value) {}

std::string SanitizeRemoteBase(const std::string& value) {}

std::string SanitizeRemoteFrontendURL(const std::string& value) {}

std::string SanitizeEnabledExperiments(const std::string& value) {}

std::string SanitizeFrontendQueryParam(const std::string& key,
                                       const std::string& value) {}

GURL SanitizeFrontendURL(const GURL& url,
                         const std::string& scheme,
                         const std::string& host,
                         const std::string& path,
                         bool allow_query_and_fragment) {}

constexpr base::TimeDelta kInitialBackoffDelay =;
constexpr base::TimeDelta kMaxBackoffDelay =;

}  // namespace

class DevToolsUIBindings::NetworkResourceLoader
    : public network::SimpleURLLoaderStreamConsumer {};

// DevToolsUIBindings::FrontendWebContentsObserver ----------------------------

class DevToolsUIBindings::FrontendWebContentsObserver
    : public content::WebContentsObserver {};

DevToolsUIBindings::FrontendWebContentsObserver::FrontendWebContentsObserver(
    DevToolsUIBindings* devtools_ui_bindings)
    :{}

DevToolsUIBindings::FrontendWebContentsObserver::
    ~FrontendWebContentsObserver() {}

// static
GURL DevToolsUIBindings::SanitizeFrontendURL(const GURL& url) {}

// static
bool DevToolsUIBindings::IsValidFrontendURL(const GURL& url) {}

bool DevToolsUIBindings::IsValidRemoteFrontendURL(const GURL& url) {}

void DevToolsUIBindings::FrontendWebContentsObserver::
    PrimaryMainFrameRenderProcessGone(base::TerminationStatus status) {}

void DevToolsUIBindings::FrontendWebContentsObserver::ReadyToCommitNavigation(
    content::NavigationHandle* navigation_handle) {}

void DevToolsUIBindings::FrontendWebContentsObserver::
    DocumentOnLoadCompletedInPrimaryMainFrame() {}

void DevToolsUIBindings::FrontendWebContentsObserver::PrimaryPageChanged(
    content::Page&) {}

// DevToolsUIBindings ---------------------------------------------------------

DevToolsUIBindings* DevToolsUIBindings::ForWebContents(
    content::WebContents* web_contents) {}

std::string DevToolsUIBindings::GetTypeForMetrics() {}

DevToolsUIBindings::DevToolsUIBindings(content::WebContents* web_contents)
    :{}

DevToolsUIBindings::~DevToolsUIBindings() {}

// content::DevToolsFrontendHost::Delegate implementation ---------------------
void DevToolsUIBindings::HandleMessageFromDevToolsFrontend(
    base::Value::Dict message) {}

// content::DevToolsAgentHostClient implementation --------------------------
// There is a sibling implementation of DevToolsAgentHostClient in
//   content/shell/browser/shell_devtools_bindings.cc
// that is used in layout tests, which only use content_shell.
// The two implementations needs to be kept in sync wrt. the interface they
// provide to the DevTools front-end.

void DevToolsUIBindings::DispatchProtocolMessage(
    content::DevToolsAgentHost* agent_host,
    base::span<const uint8_t> message) {}

void DevToolsUIBindings::AgentHostClosed(
    content::DevToolsAgentHost* agent_host) {}

bool DevToolsUIBindings::MayWriteLocalFiles() {}

void DevToolsUIBindings::SendMessageAck(int request_id,
                                        const base::Value* arg) {}

void DevToolsUIBindings::InnerAttach() {}

// DevToolsEmbedderMessageDispatcher::Delegate implementation -----------------

void DevToolsUIBindings::ActivateWindow() {}

void DevToolsUIBindings::CloseWindow() {}

void DevToolsUIBindings::LoadCompleted() {}

void DevToolsUIBindings::SetInspectedPageBounds(const gfx::Rect& rect) {}

void DevToolsUIBindings::SetIsDocked(DispatchCallback callback,
                                     bool dock_requested) {}

namespace {
constexpr net::NetworkTrafficAnnotationTag kAidaTrafficAnnotation =;
}  // namespace

void DevToolsUIBindings::OnAidaConversationRequest(
    DevToolsEmbedderMessageDispatcher::Delegate::DispatchCallback callback,
    int stream_id,
    const std::string& request,
    base::TimeDelta delay,
    absl::variant<network::ResourceRequest, std::string>
        resource_request_or_error) {}

void DevToolsUIBindings::OnRegisterAidaClientEventRequest(
    DevToolsEmbedderMessageDispatcher::Delegate::DispatchCallback callback,
    const std::string& request,
    absl::variant<network::ResourceRequest, std::string>
        resource_request_or_error) {}

void DevToolsUIBindings::OnAidaConversationResponse(
    DevToolsEmbedderMessageDispatcher::Delegate::DispatchCallback callback,
    int stream_id,
    const std::string& request,
    base::TimeDelta delay,
    absl::variant<network::ResourceRequest, std::string>
        resource_request_or_error,
    base::TimeTicks start_time,
    const base::Value* response) {}

void DevToolsUIBindings::OnAidaClientResponse(
    DevToolsEmbedderMessageDispatcher::Delegate::DispatchCallback callback,
    std::unique_ptr<network::SimpleURLLoader> simple_url_loader,
    std::optional<std::string> response_body) {}

void DevToolsUIBindings::InspectElementCompleted() {}

void DevToolsUIBindings::InspectedURLChanged(const std::string& url) {}

void DevToolsUIBindings::LoadNetworkResource(DispatchCallback callback,
                                             const std::string& url,
                                             const std::string& headers,
                                             int stream_id) {}

void DevToolsUIBindings::OpenInNewTab(const std::string& url) {}

void DevToolsUIBindings::OpenSearchResultsInNewTab(const std::string& query) {}

void DevToolsUIBindings::ShowItemInFolder(const std::string& file_system_path) {}

void DevToolsUIBindings::SaveToFile(const std::string& url,
                                    const std::string& content,
                                    bool save_as,
                                    bool is_base64) {}

void DevToolsUIBindings::AppendToFile(const std::string& url,
                                      const std::string& content) {}

void DevToolsUIBindings::RequestFileSystems() {}

void DevToolsUIBindings::AddFileSystem(const std::string& type) {}

void DevToolsUIBindings::RemoveFileSystem(const std::string& file_system_path) {}

void DevToolsUIBindings::UpgradeDraggedFileSystemPermissions(
    const std::string& file_system_url) {}

void DevToolsUIBindings::IndexPath(
    int index_request_id,
    const std::string& file_system_path,
    const std::string& excluded_folders_message) {}

void DevToolsUIBindings::StopIndexing(int index_request_id) {}

void DevToolsUIBindings::SearchInPath(int search_request_id,
                                      const std::string& file_system_path,
                                      const std::string& query) {}

void DevToolsUIBindings::SetWhitelistedShortcuts(const std::string& message) {}

void DevToolsUIBindings::SetEyeDropperActive(bool active) {}

void DevToolsUIBindings::ShowCertificateViewer(const std::string& cert_chain) {}

void DevToolsUIBindings::ZoomIn() {}

void DevToolsUIBindings::ZoomOut() {}

void DevToolsUIBindings::ResetZoom() {}

void DevToolsUIBindings::SetDevicesDiscoveryConfig(
    bool discover_usb_devices,
    bool port_forwarding_enabled,
    const std::string& port_forwarding_config,
    bool network_discovery_enabled,
    const std::string& network_discovery_config) {}

void DevToolsUIBindings::DevicesDiscoveryConfigUpdated() {}

void DevToolsUIBindings::SendPortForwardingStatus(base::Value status) {}

void DevToolsUIBindings::SetDevicesUpdatesEnabled(bool enabled) {}

void DevToolsUIBindings::OpenRemotePage(const std::string& browser_id,
                                        const std::string& url) {}

void DevToolsUIBindings::OpenNodeFrontend() {}

void DevToolsUIBindings::RegisterPreference(const std::string& name,
                                            const RegisterOptions& options) {}

void DevToolsUIBindings::GetPreferences(DispatchCallback callback) {}

void DevToolsUIBindings::GetPreference(DispatchCallback callback,
                                       const std::string& name) {}

void DevToolsUIBindings::SetPreference(const std::string& name,
                                       const std::string& value) {}

void DevToolsUIBindings::RemovePreference(const std::string& name) {}

void DevToolsUIBindings::ClearPreferences() {}

void DevToolsUIBindings::GetSyncInformation(DispatchCallback callback) {}

base::Value::Dict DevToolsUIBindings::GetSyncInformationForProfile(
    Profile* profile) {}

void DevToolsUIBindings::GetHostConfig(DispatchCallback callback) {}

void DevToolsUIBindings::Reattach(DispatchCallback callback) {}

void DevToolsUIBindings::ReadyForTest() {}

void DevToolsUIBindings::ConnectionReady() {}

void DevToolsUIBindings::SetOpenNewWindowForPopups(bool value) {}

void DevToolsUIBindings::DispatchProtocolMessageFromDevToolsFrontend(
    const std::string& message) {}

void DevToolsUIBindings::RecordCountHistogram(const std::string& name,
                                              int sample,
                                              int min,
                                              int exclusive_max,
                                              int buckets) {}

void DevToolsUIBindings::RecordEnumeratedHistogram(const std::string& name,
                                                   int sample,
                                                   int boundary_value) {}

void DevToolsUIBindings::RecordPerformanceHistogram(const std::string& name,
                                                    double duration) {}

void DevToolsUIBindings::RecordUserMetricsAction(const std::string& name) {}

bool DevToolsUIBindings::MaybeStartLogging() {}

base::TimeDelta DevToolsUIBindings::GetTimeSinceSessionStart() {}

void DevToolsUIBindings::RecordImpression(const ImpressionEvent& event) {}

void DevToolsUIBindings::RecordResize(const ResizeEvent& event) {}

void DevToolsUIBindings::RecordClick(const ClickEvent& event) {}

void DevToolsUIBindings::RecordHover(const HoverEvent& event) {}

void DevToolsUIBindings::RecordDrag(const DragEvent& event) {}

void DevToolsUIBindings::RecordChange(const ChangeEvent& event) {}

void DevToolsUIBindings::RecordKeyDown(const KeyDownEvent& event) {}

void DevToolsUIBindings::SendJsonRequest(DispatchCallback callback,
                                         const std::string& browser_id,
                                         const std::string& url) {}

void DevToolsUIBindings::JsonReceived(DispatchCallback callback,
                                      int result,
                                      const std::string& message) {}

void DevToolsUIBindings::DeviceCountChanged(int count) {}

void DevToolsUIBindings::DevicesUpdated(const std::string& source,
                                        const base::Value& targets) {}

void DevToolsUIBindings::FileSavedAs(const std::string& url,
                                     const std::string& file_system_path) {}

void DevToolsUIBindings::CanceledFileSaveAs(const std::string& url) {}

void DevToolsUIBindings::AppendedTo(const std::string& url) {}

void DevToolsUIBindings::FileSystemAdded(
    const std::string& error,
    const DevToolsFileHelper::FileSystem* file_system) {}

void DevToolsUIBindings::FileSystemRemoved(
    const std::string& file_system_path) {}

void DevToolsUIBindings::FilePathsChanged(
    const std::vector<std::string>& changed_paths,
    const std::vector<std::string>& added_paths,
    const std::vector<std::string>& removed_paths) {}

void DevToolsUIBindings::IndexingTotalWorkCalculated(
    int request_id,
    const std::string& file_system_path,
    int total_work) {}

void DevToolsUIBindings::IndexingWorked(int request_id,
                                        const std::string& file_system_path,
                                        int worked) {}

void DevToolsUIBindings::IndexingDone(int request_id,
                                      const std::string& file_system_path) {}

void DevToolsUIBindings::SearchCompleted(
    int request_id,
    const std::string& file_system_path,
    const std::vector<std::string>& file_paths) {}

void DevToolsUIBindings::ShowDevToolsInfoBar(
    const std::u16string& message,
    DevToolsInfoBarDelegate::Callback callback) {}

void DevToolsUIBindings::AddDevToolsExtensionsToClient() {}

void DevToolsUIBindings::RegisterExtensionsAPI(const std::string& origin,
                                               const std::string& script) {}

namespace {

void ShowSurveyCallback(DevToolsUIBindings::DispatchCallback callback,
                        bool survey_shown) {}

}  // namespace

void DevToolsUIBindings::ShowSurvey(DispatchCallback callback,
                                    const std::string& trigger) {}

void DevToolsUIBindings::CanShowSurvey(DispatchCallback callback,
                                       const std::string& trigger) {}

void DevToolsUIBindings::DoAidaConversation(DispatchCallback callback,
                                            const std::string& request,
                                            int stream_id) {}

void DevToolsUIBindings::RegisterAidaClientEvent(DispatchCallback callback,
                                                 const std::string& request) {}

void DevToolsUIBindings::SetDelegate(Delegate* delegate) {}

void DevToolsUIBindings::AttachTo(
    const scoped_refptr<content::DevToolsAgentHost>& agent_host) {}

void DevToolsUIBindings::AttachViaBrowserTarget(
    const scoped_refptr<content::DevToolsAgentHost>& agent_host) {}

void DevToolsUIBindings::Detach() {}

bool DevToolsUIBindings::IsAttachedTo(content::DevToolsAgentHost* agent_host) {}

void DevToolsUIBindings::OnThemeChanged() {}

void DevToolsUIBindings::CallClientMethod(
    const std::string& object_name,
    const std::string& method_name,
    base::Value arg1,
    base::Value arg2,
    base::Value arg3,
    base::OnceCallback<void(base::Value)> completion_callback) {}

void DevToolsUIBindings::ReadyToCommitNavigation(
    content::NavigationHandle* navigation_handle) {}

void DevToolsUIBindings::DocumentOnLoadCompletedInPrimaryMainFrame() {}

void DevToolsUIBindings::PrimaryPageChanged() {}

void DevToolsUIBindings::FrontendLoaded() {}

DevToolsUIBindings::DevToolsUIBindingsList&
DevToolsUIBindings::GetDevToolsUIBindings() {}