blob: 73cdfe2252a033446dad942b4020e8458ea854c5 [file] [log] [blame]
Avi Drissman8ba1bad2022-09-13 19:22:361// Copyright 2016 The Chromium Authors
mhashmi1ec338a2016-10-25 22:13:342// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef COMPONENTS_UI_DEVTOOLS_DEVTOOLS_SERVER_H_
6#define COMPONENTS_UI_DEVTOOLS_DEVTOOLS_SERVER_H_
7
Helmut Januschka58a4b28c2024-05-01 23:41:028#include <string_view>
mhashmi1ec338a2016-10-25 22:13:349#include <vector>
10
mhashmi6d1b1cb22016-11-22 16:04:2411#include "base/compiler_specific.h"
Tomasz Wiszkowski31f736a2025-05-16 23:34:1912#include "base/files/file_path.h"
Avi Drissman12be0312023-01-11 09:16:0913#include "base/functional/callback_forward.h"
Bartek Nowierskifc9563f2024-04-06 19:11:4714#include "base/memory/raw_ptr.h"
Lily Houghton7f7b2fb2018-05-01 21:40:4615#include "base/memory/weak_ptr.h"
Patrick Monette643cdf62021-10-15 19:13:4216#include "base/task/single_thread_task_runner.h"
Matt Menkecde68ab2024-08-20 16:05:2817#include "base/thread_annotations.h"
mhashmi1ec338a2016-10-25 22:13:3418#include "components/ui_devtools/devtools_client.h"
thanhph3f3968512017-06-21 00:37:2319#include "components/ui_devtools/devtools_export.h"
Andrey Kosyakov103b8f2a2021-11-16 08:06:2620#include "components/ui_devtools/dom.h"
21#include "components/ui_devtools/forward.h"
22#include "components/ui_devtools/protocol.h"
Miyoung Shin5ea055b2019-10-15 02:53:3223#include "mojo/public/cpp/bindings/pending_receiver.h"
24#include "mojo/public/cpp/bindings/pending_remote.h"
Matt Menkecde68ab2024-08-20 16:05:2825#include "net/server/http_server_request_info.h"
26#include "net/traffic_annotation/network_traffic_annotation.h"
mhashmi1ec338a2016-10-25 22:13:3427
thanhph3f3968512017-06-21 00:37:2328namespace ui_devtools {
mhashmi1ec338a2016-10-25 22:13:3429
Mitsuru Oshima4de59ac2019-09-03 20:49:0930class TracingAgent;
31
Matt Menkecde68ab2024-08-20 16:05:2832class UI_DEVTOOLS_EXPORT UiDevToolsServer {
mhashmi1ec338a2016-10-25 22:13:3433 public:
Sadrul Habib Chowdhury729f2502021-07-16 21:40:1534 // Network tags to be used for the UI devtools servers.
Sean Gilhuly13fc02ff32018-11-01 14:05:3035 static const net::NetworkTrafficAnnotationTag kUIDevtoolsServerTag;
Sean Gilhuly13fc02ff32018-11-01 14:05:3036
Peter Boström09c01822021-09-20 22:43:2737 UiDevToolsServer(const UiDevToolsServer&) = delete;
38 UiDevToolsServer& operator=(const UiDevToolsServer&) = delete;
39
Matt Menkecde68ab2024-08-20 16:05:2840 ~UiDevToolsServer();
mhashmi1ec338a2016-10-25 22:13:3441
mhashmi6d1b1cb22016-11-22 16:04:2442 // Returns an empty unique_ptr if ui devtools flag isn't enabled or if a
Matt Menkecde68ab2024-08-20 16:05:2843 // server instance has already been created. All network activity is performed
44 // on `io_thread_task_runner`, which must run tasks on a thread with an IO
45 // message pump. All other work is done on the thread the UiDevToolsServer is
46 // created on. If `port` is 0, the server will choose an available port. If
47 // `port` is 0 and `active_port_output_directory` is present, the server will
48 // write the chosen port to `kUIDevToolsActivePortFileName` on
49 // `active_port_output_directory`.
Sean Gilhuly13fc02ff32018-11-01 14:05:3050 static std::unique_ptr<UiDevToolsServer> CreateForViews(
Matt Menkecde68ab2024-08-20 16:05:2851 scoped_refptr<base::SingleThreadTaskRunner> io_thread_task_runner,
Yuheng Huang55e929512021-06-04 16:33:1452 int port,
Tomasz Wiszkowski7de1eaa2025-05-16 22:47:4253 const base::FilePath& active_port_output_directory = base::FilePath());
mhashmi1ec338a2016-10-25 22:13:3454
Tomasz Wiszkowski31f736a2025-05-16 23:34:1955
mhashmi6d1b1cb22016-11-22 16:04:2456 // Returns a list of attached UiDevToolsClient name + URL
57 using NameUrlPair = std::pair<std::string, std::string>;
leon.han030d74f42016-12-13 02:52:1658 static std::vector<NameUrlPair> GetClientNamesAndUrls();
mhashmi6d1b1cb22016-11-22 16:04:2459
Mike Wasserman8f8b0852018-12-03 22:08:1060 // Returns true if UI Devtools is enabled by the given commandline switch.
61 static bool IsUiDevToolsEnabled(const char* enable_devtools_flag);
62
Ahmed Fakhryf6c1bcd2018-11-13 19:08:2563 // Returns the port number specified by a command line flag. If a number is
64 // not specified as a command line argument, returns the |default_port|.
65 static int GetUiDevToolsPort(const char* enable_devtools_flag,
66 int default_port);
Sean Gilhuly13fc02ff32018-11-01 14:05:3067
mhashmi1ec338a2016-10-25 22:13:3468 void AttachClient(std::unique_ptr<UiDevToolsClient> client);
Helmut Januschka58a4b28c2024-05-01 23:41:0269 void SendOverWebSocket(int connection_id, std::string_view message);
mhashmi1ec338a2016-10-25 22:13:3470
Matt Menkecde68ab2024-08-20 16:05:2871 int port() const {
72 DCHECK_CALLED_ON_VALID_SEQUENCE(main_sequence_);
73 return port_;
74 }
Illia Martyniukbd1e44852018-03-13 22:02:5975
Matt Menkecde68ab2024-08-20 16:05:2876 TracingAgent* tracing_agent() {
77 DCHECK_CALLED_ON_VALID_SEQUENCE(main_sequence_);
78 return tracing_agent_;
79 }
80
81 void set_tracing_agent(TracingAgent* agent) {
82 DCHECK_CALLED_ON_VALID_SEQUENCE(main_sequence_);
83 tracing_agent_ = agent;
84 }
Mitsuru Oshima4de59ac2019-09-03 20:49:0985
Wei Lie5915072021-03-09 18:42:4586 // Sets the callback which will be invoked when the session is closed.
87 // Marks as a const function so it can be called after the server is set up
88 // and used as a constant instance.
89 void SetOnSessionEnded(base::OnceClosure callback) const;
Leonard Grey2039b722022-04-11 22:52:5090 // Sets a callback that tests can use to wait for the server to be ready to
91 // accept connections.
92 void SetOnSocketConnectedForTesting(base::OnceClosure on_socket_connected);
Matt Menkecde68ab2024-08-20 16:05:2893 // Allows calling OnWebSocketRequest() with unexpected connection IDs for
94 // tests, bypassing the HttpServer.
95 void OnWebSocketRequestForTesting(int connection_id,
96 net::HttpServerRequestInfo info);
Wei Lie5915072021-03-09 18:42:4597
mhashmi1ec338a2016-10-25 22:13:3498 private:
Matt Menkecde68ab2024-08-20 16:05:2899 // Class that owns the ServerSocket and, after creation on the main thread,
100 // may only subsequently be used on the IO thread. The class is needed because
101 // HttpServers must live on an IO thread. This class contains all state that's
102 // read or written on the IO thread, to avoid UAF's on teardown. When the
103 // UiDevToolsServer server is destroyed, a task is posted to destroy the
104 // IOThreadData, but that task could still be run after the UiDevToolsServer
105 // is fully torn down.
106 //
107 // Because of this pattern, it's always safe to post messages to the IO thread
108 // to dereference the IOThreadData from the UiDevToolsServer assuming this
109 // class will still be valid, but tasks it posts back to the main thread to
110 // dereference the UiDevToolsServer must use weak pointers.
111 class IOThreadData;
mhashmi6011c1bd2016-10-31 15:24:29112
Matt Menkecde68ab2024-08-20 16:05:28113 UiDevToolsServer(
114 scoped_refptr<base::SingleThreadTaskRunner> io_thread_task_runner,
115 int port,
116 const net::NetworkTrafficAnnotationTag tag,
117 const base::FilePath& active_port_output_directory);
mhashmi1ec338a2016-10-25 22:13:34118
Matt Menkecde68ab2024-08-20 16:05:28119 // Invoked on the IO thread, initializes `server_` and starts listening for
120 // connections on `port`.
121 void MakeServer(int port);
122
123 // Invoked on the main thread. Called by MakeServer via a post task.
124 void ServerCreated(int port);
125
126 // These mirror the corresponding HttpServer methods.
127 void OnWebSocketRequest(int connection_id, net::HttpServerRequestInfo info);
128 void OnWebSocketMessage(int connection_id, std::string data);
129 void OnClose(int connection_id);
mhashmi1ec338a2016-10-25 22:13:34130
131 using ClientsList = std::vector<std::unique_ptr<UiDevToolsClient>>;
Ali Hijazi60a72b0a2024-09-30 17:58:53132 using ConnectionsMap =
133 std::map<uint32_t, raw_ptr<UiDevToolsClient, CtnExperimental>>;
Matt Menkecde68ab2024-08-20 16:05:28134 ClientsList clients_ GUARDED_BY_CONTEXT(main_sequence_);
135 ConnectionsMap connections_ GUARDED_BY_CONTEXT(main_sequence_);
mhashmi1ec338a2016-10-25 22:13:34136
Matt Menkecde68ab2024-08-20 16:05:28137 const scoped_refptr<base::SingleThreadTaskRunner> io_thread_task_runner_;
mhashmi1ec338a2016-10-25 22:13:34138
Matt Menkecde68ab2024-08-20 16:05:28139 // The port the devtools server listens on.
140 int port_ GUARDED_BY_CONTEXT(main_sequence_);
Yuheng Huang55e929512021-06-04 16:33:14141
Matt Menkecde68ab2024-08-20 16:05:28142 raw_ptr<TracingAgent> tracing_agent_ GUARDED_BY_CONTEXT(main_sequence_) =
143 nullptr;
Illia Martyniukbd1e44852018-03-13 22:02:59144
Matt Menkecde68ab2024-08-20 16:05:28145 // Invoked when the server doesn't have any live connections.
146 mutable base::OnceClosure on_session_ended_
147 GUARDED_BY_CONTEXT(main_sequence_);
Sean Gilhuly13fc02ff32018-11-01 14:05:30148
Matt Menkecde68ab2024-08-20 16:05:28149 // Set once the server has been started.
150 bool connected_ GUARDED_BY_CONTEXT(main_sequence_) = false;
Mitsuru Oshima4de59ac2019-09-03 20:49:09151
Matt Menkecde68ab2024-08-20 16:05:28152 // Invoked once the server has been started.
153 base::OnceClosure on_socket_connected_ GUARDED_BY_CONTEXT(main_sequence_);
Wei Lie5915072021-03-09 18:42:45154
Mike Wasserman8f8b0852018-12-03 22:08:10155 // The server (owned by Chrome for now)
mhashmi6d1b1cb22016-11-22 16:04:24156 static UiDevToolsServer* devtools_server_;
157
Matt Menkecde68ab2024-08-20 16:05:28158 std::unique_ptr<IOThreadData> io_thread_data_;
159
160 SEQUENCE_CHECKER(main_sequence_);
Jeremy Roman5c341f6d2019-07-15 15:56:10161 base::WeakPtrFactory<UiDevToolsServer> weak_ptr_factory_{this};
mhashmi1ec338a2016-10-25 22:13:34162};
163
thanhph3f3968512017-06-21 00:37:23164} // namespace ui_devtools
mhashmi1ec338a2016-10-25 22:13:34165
166#endif // COMPONENTS_UI_DEVTOOLS_DEVTOOLS_SERVER_H_