#include "chrome/browser/devtools/devtools_window.h"
#include <memory>
#include <set>
#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/json/json_reader.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/not_fatal_until.h"
#include "base/ranges/algorithm.h"
#include "base/strings/escape.h"
#include "base/task/sequenced_task_runner.h"
#include "base/time/time.h"
#include "base/values.h"
#include "chrome/browser/browser_features.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/certificate_viewer.h"
#include "chrome/browser/devtools/chrome_devtools_manager_delegate.h"
#include "chrome/browser/devtools/devtools_eye_dropper.h"
#include "chrome/browser/devtools/process_sharing_infobar_delegate.h"
#include "chrome/browser/file_select_helper.h"
#include "chrome/browser/infobars/confirm_infobar_creator.h"
#include "chrome/browser/profiles/keep_alive/profile_keep_alive_types.h"
#include "chrome/browser/profiles/keep_alive/scoped_profile_keep_alive.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/search_engines/template_url_service_factory.h"
#include "chrome/browser/task_manager/web_contents_tags.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_list.h"
#include "chrome/browser/ui/browser_tabstrip.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/prefs/prefs_tab_helper.h"
#include "chrome/browser/ui/scoped_tabbed_browser_displayer.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/browser/ui/tabs/tab_strip_user_gesture_details.h"
#include "chrome/browser/ui/webui/devtools/devtools_ui.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/url_constants.h"
#include "components/infobars/content/content_infobar_manager.h"
#include "components/infobars/core/infobar.h"
#include "components/input/native_web_keyboard_event.h"
#include "components/javascript_dialogs/app_modal_dialog_manager.h"
#include "components/keep_alive_registry/keep_alive_types.h"
#include "components/keep_alive_registry/scoped_keep_alive.h"
#include "components/language/core/browser/pref_names.h"
#include "components/pref_registry/pref_registry_syncable.h"
#include "components/prefs/scoped_user_pref_update.h"
#include "components/search_engines/util.h"
#include "components/sessions/content/session_tab_helper.h"
#include "components/sync_preferences/pref_service_syncable.h"
#include "components/web_modal/web_contents_modal_dialog_manager.h"
#include "components/zoom/page_zoom.h"
#include "components/zoom/zoom_controller.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/child_process_security_policy.h"
#include "content/public/browser/color_chooser.h"
#include "content/public/browser/devtools_agent_host.h"
#include "content/public/browser/file_select_listener.h"
#include "content/public/browser/keyboard_event_processing_result.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/navigation_throttle.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/render_widget_host_view.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/content_client.h"
#include "content/public/common/content_features.h"
#include "content/public/common/url_constants.h"
#include "extensions/browser/view_type_utils.h"
#include "extensions/common/constants.h"
#include "net/cert/x509_certificate.h"
#include "services/metrics/public/cpp/ukm_builders.h"
#include "services/metrics/public/cpp/ukm_recorder.h"
#include "services/metrics/public/cpp/ukm_source_id.h"
#include "third_party/blink/public/common/input/web_gesture_event.h"
#include "third_party/blink/public/common/input/web_input_event.h"
#include "third_party/blink/public/common/renderer_preferences/renderer_preferences.h"
#include "third_party/blink/public/public_buildflags.h"
#include "ui/base/page_transition_types.h"
#include "ui/events/keycodes/dom/keycode_converter.h"
#include "ui/events/keycodes/keyboard_code_conversion.h"
#include "ui/events/keycodes/keyboard_codes.h"
#if defined(_WINDOWS_)
#include "base/win/windows_h_disallowed.h"
#endif
WebInputEvent;
BrowserThread;
DevToolsAgentHost;
WebContents;
namespace {
DevToolsWindows;
base::LazyInstance<DevToolsWindows>::Leaky g_devtools_window_instances = …;
base::LazyInstance<
std::vector<base::RepeatingCallback<void(DevToolsWindow*)>>>::Leaky
g_creation_callbacks = …;
static const char kKeyUpEventName[] = …;
static const char kKeyDownEventName[] = …;
static const char kDefaultFrontendURL[] = …;
static const char kNodeFrontendURL[] = …;
static const char kWorkerFrontendURL[] = …;
static const char kJSFrontendURL[] = …;
static const char kFallbackFrontendURL[] = …;
bool FindInspectedBrowserAndTabIndex(
WebContents* inspected_web_contents, Browser** browser, int* tab) { … }
void SetPreferencesFromJson(Profile* profile, const std::string& json) { … }
class DevToolsToolboxDelegate
: public content::WebContentsObserver,
public content::WebContentsDelegate { … };
DevToolsToolboxDelegate::DevToolsToolboxDelegate(WebContents* toolbox_contents,
WebContents* web_contents)
: … { … }
DevToolsToolboxDelegate::~DevToolsToolboxDelegate() { … }
content::WebContents* DevToolsToolboxDelegate::OpenURLFromTab(
content::WebContents* source,
const content::OpenURLParams& params,
base::OnceCallback<void(content::NavigationHandle&)>
navigation_handle_callback) { … }
content::KeyboardEventProcessingResult
DevToolsToolboxDelegate::PreHandleKeyboardEvent(
content::WebContents* source,
const input::NativeWebKeyboardEvent& event) { … }
bool DevToolsToolboxDelegate::HandleKeyboardEvent(
content::WebContents* source,
const input::NativeWebKeyboardEvent& event) { … }
void DevToolsToolboxDelegate::WebContentsDestroyed() { … }
BrowserWindow* DevToolsToolboxDelegate::GetInspectedBrowserWindow() { … }
GURL DecorateFrontendURL(const GURL& base_url) { … }
}
class DevToolsEventForwarder { … };
void DevToolsEventForwarder::SetWhitelistedShortcuts(
const std::string& message) { … }
bool DevToolsEventForwarder::ForwardEvent(
const input::NativeWebKeyboardEvent& event) { … }
int DevToolsEventForwarder::CombineKeyCodeAndModifiers(int key_code,
int modifiers) { … }
bool DevToolsEventForwarder::KeyWhitelistingAllowed(int key_code,
int modifiers) { … }
void DevToolsWindow::OpenNodeFrontend() { … }
class DevToolsWindow::Throttle : public content::NavigationThrottle { … };
class DevToolsWindow::OwnedMainWebContents { … };
const char DevToolsWindow::kDevToolsApp[] = …;
void DevToolsWindow::AddCreationCallbackForTest(
const CreationCallback& callback) { … }
void DevToolsWindow::RemoveCreationCallbackForTest(
const CreationCallback& callback) { … }
DevToolsWindow::~DevToolsWindow() { … }
void DevToolsWindow::RegisterProfilePrefs(
user_prefs::PrefRegistrySyncable* registry) { … }
content::WebContents* DevToolsWindow::GetInTabWebContents(
WebContents* inspected_web_contents,
DevToolsContentsResizingStrategy* out_strategy) { … }
DevToolsWindow* DevToolsWindow::GetInstanceForInspectedWebContents(
WebContents* inspected_web_contents) { … }
bool DevToolsWindow::IsDevToolsWindow(content::WebContents* web_contents) { … }
void DevToolsWindow::OpenDevToolsWindowForWorker(
Profile* profile,
const scoped_refptr<DevToolsAgentHost>& worker_agent,
DevToolsOpenedByAction opened_by) { … }
void DevToolsWindow::OpenDevToolsWindow(
content::WebContents* inspected_web_contents,
DevToolsOpenedByAction opened_by) { … }
void DevToolsWindow::OpenDevToolsWindow(
content::WebContents* inspected_web_contents,
Profile* profile,
DevToolsOpenedByAction opened_by) { … }
void DevToolsWindow::OpenDevToolsWindow(
scoped_refptr<content::DevToolsAgentHost> agent_host,
Profile* profile,
DevToolsOpenedByAction opened_by) { … }
void DevToolsWindow::OpenDevToolsWindowWithBundledFrontend(
scoped_refptr<content::DevToolsAgentHost> agent_host,
Profile* profile,
DevToolsOpenedByAction opened_by) { … }
void DevToolsWindow::OpenDevToolsWindow(
scoped_refptr<content::DevToolsAgentHost> agent_host,
Profile* profile,
bool use_bundled_frontend,
DevToolsOpenedByAction opened_by) { … }
void DevToolsWindow::OpenDevToolsWindow(
content::WebContents* inspected_web_contents,
const DevToolsToggleAction& action,
DevToolsOpenedByAction opened_by) { … }
void DevToolsWindow::OpenDevToolsWindowForFrame(
Profile* profile,
const scoped_refptr<content::DevToolsAgentHost>& agent_host,
DevToolsOpenedByAction opened_by) { … }
void DevToolsWindow::ToggleDevToolsWindow(Browser* browser,
const DevToolsToggleAction& action,
DevToolsOpenedByAction opened_by) { … }
void DevToolsWindow::OpenExternalFrontend(
Profile* profile,
const std::string& frontend_url,
const scoped_refptr<content::DevToolsAgentHost>& agent_host,
bool use_bundled_frontend,
DevToolsOpenedByAction opened_by) { … }
DevToolsWindow* DevToolsWindow::OpenNodeFrontendWindow(
Profile* profile,
DevToolsOpenedByAction opened_by) { … }
Profile* DevToolsWindow::GetProfileForDevToolsWindow(
content::WebContents* web_contents) { … }
namespace {
scoped_refptr<DevToolsAgentHost> GetOrCreateDevToolsHostForWebContents(
WebContents* wc) { … }
}
void DevToolsWindow::ToggleDevToolsWindow(
content::WebContents* inspected_web_contents,
Profile* profile,
bool force_open,
const DevToolsToggleAction& action,
const std::string& settings,
DevToolsOpenedByAction toggled_by) { … }
void DevToolsWindow::InspectElement(
content::RenderFrameHost* inspected_frame_host,
int x,
int y) { … }
void DevToolsWindow::LogDevToolsOpenedByAction(
DevToolsOpenedByAction opened_by) { … }
void DevToolsWindow::LogDevToolsOpenedUKM(content::WebContents* web_contents) { … }
std::unique_ptr<content::NavigationThrottle>
DevToolsWindow::MaybeCreateNavigationThrottle(
content::NavigationHandle* handle) { … }
void DevToolsWindow::ScheduleShow(const DevToolsToggleAction& action) { … }
void DevToolsWindow::Show(const DevToolsToggleAction& action) { … }
bool DevToolsWindow::HandleBeforeUnload(WebContents* frontend_contents,
bool proceed, bool* proceed_to_fire_unload) { … }
bool DevToolsWindow::InterceptPageBeforeUnload(WebContents* contents) { … }
bool DevToolsWindow::NeedsToInterceptBeforeUnload(
WebContents* contents) { … }
bool DevToolsWindow::HasFiredBeforeUnloadEventForDevToolsBrowser(
Browser* browser) { … }
void DevToolsWindow::OnPageCloseCanceled(WebContents* contents) { … }
DevToolsWindow::DevToolsWindow(FrontendType frontend_type,
Profile* profile,
std::unique_ptr<WebContents> main_web_contents,
DevToolsUIBindings* bindings,
WebContents* inspected_web_contents,
bool can_dock,
DevToolsOpenedByAction opened_by)
: … { … }
bool DevToolsWindow::AllowDevToolsFor(Profile* profile,
content::WebContents* web_contents) { … }
DevToolsWindow* DevToolsWindow::Create(
Profile* profile,
content::WebContents* inspected_web_contents,
FrontendType frontend_type,
const std::string& frontend_url,
bool can_dock,
const std::string& settings,
const std::string& panel,
bool has_other_clients,
bool browser_connection,
DevToolsOpenedByAction opened_by) { … }
GURL DevToolsWindow::GetDevToolsURL(Profile* profile,
FrontendType frontend_type,
const std::string& frontend_url,
bool can_dock,
const std::string& panel,
bool has_other_clients,
bool browser_connection) { … }
DevToolsWindow* DevToolsWindow::FindDevToolsWindow(
DevToolsAgentHost* agent_host) { … }
DevToolsWindow* DevToolsWindow::AsDevToolsWindow(
content::WebContents* web_contents) { … }
DevToolsWindow* DevToolsWindow::AsDevToolsWindow(Browser* browser) { … }
WebContents* DevToolsWindow::OpenURLFromTab(
WebContents* source,
const content::OpenURLParams& params,
base::OnceCallback<void(content::NavigationHandle&)>
navigation_handle_callback) { … }
WebContents* DevToolsWindow::OpenURLFromInspectedTab(
const content::OpenURLParams& params) { … }
void DevToolsWindow::ActivateContents(WebContents* contents) { … }
WebContents* DevToolsWindow::AddNewContents(
WebContents* source,
std::unique_ptr<WebContents> new_contents,
const GURL& target_url,
WindowOpenDisposition disposition,
const blink::mojom::WindowFeatures& window_features,
bool user_gesture,
bool* was_blocked) { … }
void DevToolsWindow::WebContentsCreated(WebContents* source_contents,
int opener_render_process_id,
int opener_render_frame_id,
const std::string& frame_name,
const GURL& target_url,
WebContents* new_contents) { … }
void DevToolsWindow::CloseContents(WebContents* source) { … }
void DevToolsWindow::ContentsZoomChange(bool zoom_in) { … }
void DevToolsWindow::BeforeUnloadFired(WebContents* tab,
bool proceed,
bool* proceed_to_fire_unload) { … }
content::KeyboardEventProcessingResult DevToolsWindow::PreHandleKeyboardEvent(
WebContents* source,
const input::NativeWebKeyboardEvent& event) { … }
bool DevToolsWindow::HandleKeyboardEvent(
WebContents* source,
const input::NativeWebKeyboardEvent& event) { … }
content::JavaScriptDialogManager* DevToolsWindow::GetJavaScriptDialogManager(
WebContents* source) { … }
std::unique_ptr<content::EyeDropper> DevToolsWindow::OpenEyeDropper(
content::RenderFrameHost* render_frame_host,
content::EyeDropperListener* listener) { … }
void DevToolsWindow::RunFileChooser(
content::RenderFrameHost* render_frame_host,
scoped_refptr<content::FileSelectListener> listener,
const blink::mojom::FileChooserParams& params) { … }
bool DevToolsWindow::PreHandleGestureEvent(
WebContents* source,
const blink::WebGestureEvent& event) { … }
void DevToolsWindow::ActivateWindow() { … }
void DevToolsWindow::CloseWindow() { … }
void DevToolsWindow::Close(DevToolsClosedByAction closed_by) { … }
void DevToolsWindow::Inspect(scoped_refptr<content::DevToolsAgentHost> host) { … }
void DevToolsWindow::SetInspectedPageBounds(const gfx::Rect& rect) { … }
void DevToolsWindow::InspectElementCompleted() { … }
void DevToolsWindow::SetIsDocked(bool dock_requested) { … }
int DevToolsWindow::GetDockStateForLogging() { … }
int DevToolsWindow::GetOpenedByForLogging() { … }
int DevToolsWindow::GetClosedByForLogging() { … }
void DevToolsWindow::OpenInNewTab(const GURL& url) { … }
void DevToolsWindow::OpenInNewTab(const std::string& url) { … }
void DevToolsWindow::OpenSearchResultsInNewTab(const std::string& query) { … }
void DevToolsWindow::SetWhitelistedShortcuts(
const std::string& message) { … }
void DevToolsWindow::SetEyeDropperActive(bool active) { … }
void DevToolsWindow::ColorPickedInEyeDropper(int r, int g, int b, int a) { … }
void DevToolsWindow::InspectedContentsClosing() { … }
infobars::ContentInfoBarManager* DevToolsWindow::GetInfoBarManager() { … }
void DevToolsWindow::RenderProcessGone(bool crashed) { … }
void DevToolsWindow::ShowCertificateViewer(const std::string& cert_chain) { … }
void DevToolsWindow::OnLoadCompleted() { … }
void DevToolsWindow::ReadyForTest() { … }
void DevToolsWindow::ConnectionReady() { … }
void DevToolsWindow::SetOpenNewWindowForPopups(bool value) { … }
void DevToolsWindow::CreateDevToolsBrowser() { … }
BrowserWindow* DevToolsWindow::GetInspectedBrowserWindow() { … }
void DevToolsWindow::DoAction(const DevToolsToggleAction& action) { … }
void DevToolsWindow::UpdateBrowserToolbar() { … }
void DevToolsWindow::UpdateBrowserWindow() { … }
WebContents* DevToolsWindow::GetInspectedWebContents() { … }
void DevToolsWindow::LoadCompleted() { … }
void DevToolsWindow::SetLoadCompletedCallback(base::OnceClosure closure) { … }
bool DevToolsWindow::ForwardKeyboardEvent(
const input::NativeWebKeyboardEvent& event) { … }
bool DevToolsWindow::ReloadInspectedWebContents(bool bypass_cache) { … }
void DevToolsWindow::RegisterModalDialogManager(Browser* browser) { … }
void DevToolsWindow::OnLocaleChanged() { … }
void DevToolsWindow::OverrideAndSyncDevToolsRendererPrefs() { … }
void DevToolsWindow::MaybeShowSharedProcessInfobar() { … }
void DevToolsWindow::OnInfoBarRemoved(infobars::InfoBar* infobar,
bool animate) { … }
void DevToolsWindow::PrimaryPageChanged(content::Page& page) { … }