| // Copyright 2016 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef CONTENT_BROWSER_DEVTOOLS_PROTOCOL_TARGET_HANDLER_H_ |
| #define CONTENT_BROWSER_DEVTOOLS_PROTOCOL_TARGET_HANDLER_H_ |
| |
| #include <map> |
| #include <set> |
| |
| #include "base/containers/flat_map.h" |
| #include "base/containers/flat_set.h" |
| #include "base/memory/raw_ptr.h" |
| #include "base/memory/weak_ptr.h" |
| #include "content/browser/devtools/devtools_session.h" |
| #include "content/browser/devtools/devtools_throttle_handle.h" |
| #include "content/browser/devtools/protocol/devtools_domain_handler.h" |
| #include "content/browser/devtools/protocol/hidden_target_manager.h" |
| #include "content/browser/devtools/protocol/target.h" |
| #include "content/browser/devtools/protocol/target_auto_attacher.h" |
| #include "content/public/browser/devtools_agent_host_observer.h" |
| #include "net/proxy_resolution/proxy_config.h" |
| #include "services/network/public/mojom/network_context.mojom.h" |
| |
| namespace content { |
| |
| class DevToolsAgentHostImpl; |
| class DevToolsSession; |
| |
| namespace protocol { |
| |
| class TargetHandler : public DevToolsDomainHandler, |
| public Target::Backend, |
| public DevToolsAgentHostObserver, |
| public TargetAutoAttacher::Client { |
| public: |
| enum class AccessMode { |
| // Only setAutoAttach is supported. Any non-related target are not |
| // accessible. |
| kAutoAttachOnly, |
| // Standard mode of operation: both auto-attach and discovery. |
| kRegular, |
| // This mode also allows advanced method like Target.exposeDevToolsProtocol, |
| // which should not be exposed on a non-browser-wide connection. |
| kBrowser |
| }; |
| TargetHandler(AccessMode access_mode, |
| const std::string& owner_target_id, |
| TargetAutoAttacher* auto_attacher, |
| DevToolsSession* session); |
| |
| TargetHandler(const TargetHandler&) = delete; |
| TargetHandler& operator=(const TargetHandler&) = delete; |
| |
| ~TargetHandler() override; |
| |
| static std::vector<TargetHandler*> ForAgentHost(DevToolsAgentHostImpl* host); |
| |
| void Wire(UberDispatcher* dispatcher) override; |
| Response Disable() override; |
| |
| bool ShouldThrottlePopups() const; |
| |
| // This is to support legacy protocol, where an autoattacher on service worker |
| // targets would not auto-attach service workers. |
| // TODO(caseq): update front-end logic and get rid of this. |
| void DisableAutoAttachOfServiceWorkers(); |
| |
| // Domain implementation. |
| Response SetDiscoverTargets( |
| bool discover, |
| std::unique_ptr<protocol::Array<protocol::Target::FilterEntry>> filter) |
| override; |
| void SetAutoAttach( |
| bool auto_attach, |
| bool wait_for_debugger_on_start, |
| std::optional<bool> flatten, |
| std::unique_ptr<protocol::Array<protocol::Target::FilterEntry>> filter, |
| std::unique_ptr<SetAutoAttachCallback> callback) override; |
| void AutoAttachRelated( |
| const std::string& targetId, |
| bool wait_for_debugger_on_start, |
| std::unique_ptr<protocol::Array<protocol::Target::FilterEntry>> filter, |
| std::unique_ptr<AutoAttachRelatedCallback> callback) override; |
| Response SetRemoteLocations( |
| std::unique_ptr<protocol::Array<Target::RemoteLocation>>) override; |
| Response AttachToTarget(const std::string& target_id, |
| std::optional<bool> flatten, |
| std::string* out_session_id) override; |
| Response AttachToBrowserTarget(std::string* out_session_id) override; |
| Response DetachFromTarget(std::optional<std::string> session_id, |
| std::optional<std::string> target_id) override; |
| Response SendMessageToTarget(const std::string& message, |
| std::optional<std::string> session_id, |
| std::optional<std::string> target_id) override; |
| Response GetTargetInfo( |
| std::optional<std::string> target_id, |
| std::unique_ptr<Target::TargetInfo>* target_info) override; |
| Response ActivateTarget(const std::string& target_id) override; |
| Response CloseTarget(const std::string& target_id, |
| bool* out_success) override; |
| void ExposeDevToolsProtocol( |
| const std::string& target_id, |
| std::optional<std::string> binding_name, |
| std::optional<bool> inherit_permissions, |
| std::unique_ptr<ExposeDevToolsProtocolCallback> callback) override; |
| void CreateBrowserContext( |
| std::optional<bool> in_disposeOnDetach, |
| std::optional<String> in_proxyServer, |
| std::optional<String> in_proxyBypassList, |
| std::unique_ptr<protocol::Array<String>> |
| in_originsToGrantUniversalNetworkAccess, |
| std::unique_ptr<CreateBrowserContextCallback> callback) override; |
| void DisposeBrowserContext( |
| const std::string& context_id, |
| std::unique_ptr<DisposeBrowserContextCallback> callback) override; |
| Response GetBrowserContexts( |
| std::unique_ptr<protocol::Array<String>>* browser_context_ids) override; |
| Response CreateTarget(const std::string& url, |
| std::optional<int> left, |
| std::optional<int> top, |
| std::optional<int> width, |
| std::optional<int> height, |
| std::optional<std::string> window_state, |
| std::optional<std::string> browser_context_id, |
| std::optional<bool> enable_begin_frame_control, |
| std::optional<bool> new_window, |
| std::optional<bool> background, |
| std::optional<bool> for_tab, |
| std::optional<bool> hidden, |
| std::string* out_target_id) override; |
| Response GetTargets( |
| std::unique_ptr<protocol::Array<protocol::Target::FilterEntry>> filter, |
| std::unique_ptr<protocol::Array<Target::TargetInfo>>* target_infos) |
| override; |
| |
| Response OpenDevTools(const std::string& target_id, |
| std::string* out_target_id) override; |
| |
| void ApplyNetworkContextParamsOverrides( |
| BrowserContext* browser_context, |
| network::mojom::NetworkContextParams* network_context_params); |
| |
| // Adds a ServiceWorker or DedicatedWorker throttle for an auto attaching |
| // session. If none is known for this `agent_host`, is a no-op. |
| // TODO(crbug.com/40154954): support SharedWorker. |
| void AddWorkerThrottle(DevToolsAgentHost* agent_host, |
| scoped_refptr<DevToolsThrottleHandle> throttle_handle); |
| |
| private: |
| class Session; |
| class Throttle; |
| class RequestThrottle; |
| class ResponseThrottle; |
| class TargetFilter; |
| |
| // TargetAutoAttacher::Delegate implementation. |
| bool AutoAttach(TargetAutoAttacher* source, |
| DevToolsAgentHost* host, |
| bool waiting_for_debugger) override; |
| void AutoDetach(TargetAutoAttacher* source, DevToolsAgentHost* host) override; |
| void SetAttachedTargetsOfType( |
| TargetAutoAttacher* source, |
| const base::flat_set<scoped_refptr<DevToolsAgentHost>>& new_hosts, |
| const std::string& type) override; |
| void MaybeCreateAndAddNavigationThrottle( |
| TargetAutoAttacher* auto_attacher, |
| NavigationThrottleRegistry& registry) override; |
| void TargetInfoChanged(DevToolsAgentHost* host) override; |
| void AutoAttacherDestroyed(TargetAutoAttacher* auto_attacher) override; |
| |
| bool ShouldWaitForDebuggerOnStart( |
| NavigationRequest* navigation_request) const; |
| |
| Response FindSession(std::optional<std::string> session_id, |
| std::optional<std::string> target_id, |
| Session** session); |
| void ClearThrottles(); |
| void SetAutoAttachInternal(bool auto_attach, |
| bool wait_for_debugger_on_start, |
| bool flatten, |
| base::OnceClosure callback); |
| void UpdateAgentHostObserver(); |
| |
| // DevToolsAgentHostObserver implementation. |
| bool ShouldForceDevToolsAgentHostCreation() override; |
| void DevToolsAgentHostCreated(DevToolsAgentHost* agent_host) override; |
| void DevToolsAgentHostNavigated(DevToolsAgentHost* agent_host) override; |
| void DevToolsAgentHostDestroyed(DevToolsAgentHost* agent_host) override; |
| void DevToolsAgentHostAttached(DevToolsAgentHost* agent_host) override; |
| void DevToolsAgentHostDetached(DevToolsAgentHost* agent_host) override; |
| void DevToolsAgentHostCrashed(DevToolsAgentHost* agent_host, |
| base::TerminationStatus status) override; |
| bool discover() const { return !!discover_target_filter_; } |
| Session* FindWaitingSession(DevToolsAgentHost* host); |
| |
| const AccessMode access_mode_; |
| const std::string owner_target_id_; |
| const DevToolsSession::Mode session_mode_; |
| const raw_ptr<DevToolsSession> root_session_; |
| const raw_ptr<TargetAutoAttacher> auto_attacher_; |
| std::unique_ptr<Target::Frontend> frontend_; |
| |
| bool flatten_auto_attach_ = false; |
| bool auto_attach_ = false; |
| // The below is set iff (auto_attach_ || |
| // !auto_attach_related_targets_.empty()) |
| std::unique_ptr<TargetFilter> auto_attach_target_filter_; |
| bool wait_for_debugger_on_start_ = false; |
| std::map<DevToolsAgentHost*, raw_ptr<Session, CtnExperimental>> |
| auto_attached_sessions_; |
| base::flat_map<TargetAutoAttacher*, bool /* wait_for_debugger_on_start */> |
| auto_attach_related_targets_; |
| bool auto_attach_service_workers_ = true; |
| |
| std::unique_ptr<TargetFilter> discover_target_filter_; |
| bool observing_agent_hosts_ = false; |
| std::map<std::string, std::unique_ptr<Session>> attached_sessions_; |
| std::set<raw_ptr<DevToolsAgentHost, SetExperimental>> reported_hosts_; |
| base::flat_set<std::string> dispose_on_detach_context_ids_; |
| base::flat_map<std::string, net::ProxyConfig> contexts_with_overridden_proxy_; |
| base::flat_set<raw_ptr<Throttle, CtnExperimental>> throttles_; |
| std::optional<net::ProxyConfig> pending_proxy_config_; |
| HiddenTargetManager hidden_target_manager_; |
| |
| base::WeakPtrFactory<TargetHandler> weak_factory_{this}; |
| }; |
| |
| } // namespace protocol |
| } // namespace content |
| |
| #endif // CONTENT_BROWSER_DEVTOOLS_PROTOCOL_TARGET_HANDLER_H_ |