blob: eb4fe7729efa1e8f054f66ac16e363f5467147e3 [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"
Avi Drissman12be0312023-01-11 09:16:0912#include "base/functional/callback_forward.h"
Bartek Nowierskifc9563f2024-04-06 19:11:4713#include "base/memory/raw_ptr.h"
Lily Houghton7f7b2fb2018-05-01 21:40:4614#include "base/memory/weak_ptr.h"
Patrick Monette643cdf62021-10-15 19:13:4215#include "base/task/single_thread_task_runner.h"
Matt Menkecde68ab2024-08-20 16:05:2816#include "base/thread_annotations.h"
mhashmi1ec338a2016-10-25 22:13:3417#include "components/ui_devtools/devtools_client.h"
thanhph3f3968512017-06-21 00:37:2318#include "components/ui_devtools/devtools_export.h"
Andrey Kosyakov103b8f2a2021-11-16 08:06:2619#include "components/ui_devtools/dom.h"
20#include "components/ui_devtools/forward.h"
21#include "components/ui_devtools/protocol.h"
Miyoung Shin5ea055b2019-10-15 02:53:3222#include "mojo/public/cpp/bindings/pending_receiver.h"
23#include "mojo/public/cpp/bindings/pending_remote.h"
Matt Menkecde68ab2024-08-20 16:05:2824#include "net/server/http_server_request_info.h"
25#include "net/traffic_annotation/network_traffic_annotation.h"
mhashmi1ec338a2016-10-25 22:13:3426
thanhph3f3968512017-06-21 00:37:2327namespace ui_devtools {
mhashmi1ec338a2016-10-25 22:13:3428
Mitsuru Oshima4de59ac2019-09-03 20:49:0929class TracingAgent;
30
Matt Menkecde68ab2024-08-20 16:05:2831class UI_DEVTOOLS_EXPORT UiDevToolsServer {
mhashmi1ec338a2016-10-25 22:13:3432 public:
Sadrul Habib Chowdhury729f2502021-07-16 21:40:1533 // Network tags to be used for the UI devtools servers.
Sean Gilhuly13fc02ff32018-11-01 14:05:3034 static const net::NetworkTrafficAnnotationTag kUIDevtoolsServerTag;
Sean Gilhuly13fc02ff32018-11-01 14:05:3035
Peter Boström09c01822021-09-20 22:43:2736 UiDevToolsServer(const UiDevToolsServer&) = delete;
37 UiDevToolsServer& operator=(const UiDevToolsServer&) = delete;
38
Matt Menkecde68ab2024-08-20 16:05:2839 ~UiDevToolsServer();
mhashmi1ec338a2016-10-25 22:13:3440
mhashmi6d1b1cb22016-11-22 16:04:2441 // Returns an empty unique_ptr if ui devtools flag isn't enabled or if a
Matt Menkecde68ab2024-08-20 16:05:2842 // server instance has already been created. All network activity is performed
43 // on `io_thread_task_runner`, which must run tasks on a thread with an IO
44 // message pump. All other work is done on the thread the UiDevToolsServer is
45 // created on. If `port` is 0, the server will choose an available port. If
46 // `port` is 0 and `active_port_output_directory` is present, the server will
47 // write the chosen port to `kUIDevToolsActivePortFileName` on
48 // `active_port_output_directory`.
Sean Gilhuly13fc02ff32018-11-01 14:05:3049 static std::unique_ptr<UiDevToolsServer> CreateForViews(
Matt Menkecde68ab2024-08-20 16:05:2850 scoped_refptr<base::SingleThreadTaskRunner> io_thread_task_runner,
Yuheng Huang55e929512021-06-04 16:33:1451 int port,
52 const base::FilePath& active_port_output_directory = base::FilePath());
mhashmi1ec338a2016-10-25 22:13:3453
mhashmi6d1b1cb22016-11-22 16:04:2454 // Returns a list of attached UiDevToolsClient name + URL
55 using NameUrlPair = std::pair<std::string, std::string>;
leon.han030d74f2016-12-13 02:52:1656 static std::vector<NameUrlPair> GetClientNamesAndUrls();
mhashmi6d1b1cb22016-11-22 16:04:2457
Mike Wasserman8f8b0852018-12-03 22:08:1058 // Returns true if UI Devtools is enabled by the given commandline switch.
59 static bool IsUiDevToolsEnabled(const char* enable_devtools_flag);
60
Ahmed Fakhryf6c1bcd2018-11-13 19:08:2561 // Returns the port number specified by a command line flag. If a number is
62 // not specified as a command line argument, returns the |default_port|.
63 static int GetUiDevToolsPort(const char* enable_devtools_flag,
64 int default_port);
Sean Gilhuly13fc02ff32018-11-01 14:05:3065
mhashmi1ec338a2016-10-25 22:13:3466 void AttachClient(std::unique_ptr<UiDevToolsClient> client);
Helmut Januschka58a4b28c2024-05-01 23:41:0267 void SendOverWebSocket(int connection_id, std::string_view message);
mhashmi1ec338a2016-10-25 22:13:3468
Matt Menkecde68ab2024-08-20 16:05:2869 int port() const {
70 DCHECK_CALLED_ON_VALID_SEQUENCE(main_sequence_);
71 return port_;
72 }
Illia Martyniukbd1e44852018-03-13 22:02:5973
Matt Menkecde68ab2024-08-20 16:05:2874 TracingAgent* tracing_agent() {
75 DCHECK_CALLED_ON_VALID_SEQUENCE(main_sequence_);
76 return tracing_agent_;
77 }
78
79 void set_tracing_agent(TracingAgent* agent) {
80 DCHECK_CALLED_ON_VALID_SEQUENCE(main_sequence_);
81 tracing_agent_ = agent;
82 }
Mitsuru Oshima4de59ac2019-09-03 20:49:0983
Wei Lie5915072021-03-09 18:42:4584 // Sets the callback which will be invoked when the session is closed.
85 // Marks as a const function so it can be called after the server is set up
86 // and used as a constant instance.
87 void SetOnSessionEnded(base::OnceClosure callback) const;
Leonard Grey2039b722022-04-11 22:52:5088 // Sets a callback that tests can use to wait for the server to be ready to
89 // accept connections.
90 void SetOnSocketConnectedForTesting(base::OnceClosure on_socket_connected);
Matt Menkecde68ab2024-08-20 16:05:2891 // Allows calling OnWebSocketRequest() with unexpected connection IDs for
92 // tests, bypassing the HttpServer.
93 void OnWebSocketRequestForTesting(int connection_id,
94 net::HttpServerRequestInfo info);
Wei Lie5915072021-03-09 18:42:4595
mhashmi1ec338a2016-10-25 22:13:3496 private:
Matt Menkecde68ab2024-08-20 16:05:2897 // Class that owns the ServerSocket and, after creation on the main thread,
98 // may only subsequently be used on the IO thread. The class is needed because
99 // HttpServers must live on an IO thread. This class contains all state that's
100 // read or written on the IO thread, to avoid UAF's on teardown. When the
101 // UiDevToolsServer server is destroyed, a task is posted to destroy the
102 // IOThreadData, but that task could still be run after the UiDevToolsServer
103 // is fully torn down.
104 //
105 // Because of this pattern, it's always safe to post messages to the IO thread
106 // to dereference the IOThreadData from the UiDevToolsServer assuming this
107 // class will still be valid, but tasks it posts back to the main thread to
108 // dereference the UiDevToolsServer must use weak pointers.
109 class IOThreadData;
mhashmi6011c1bd2016-10-31 15:24:29110
Matt Menkecde68ab2024-08-20 16:05:28111 UiDevToolsServer(
112 scoped_refptr<base::SingleThreadTaskRunner> io_thread_task_runner,
113 int port,
114 const net::NetworkTrafficAnnotationTag tag,
115 const base::FilePath& active_port_output_directory);
mhashmi1ec338a2016-10-25 22:13:34116
Matt Menkecde68ab2024-08-20 16:05:28117 // Invoked on the IO thread, initializes `server_` and starts listening for
118 // connections on `port`.
119 void MakeServer(int port);
120
121 // Invoked on the main thread. Called by MakeServer via a post task.
122 void ServerCreated(int port);
123
124 // These mirror the corresponding HttpServer methods.
125 void OnWebSocketRequest(int connection_id, net::HttpServerRequestInfo info);
126 void OnWebSocketMessage(int connection_id, std::string data);
127 void OnClose(int connection_id);
mhashmi1ec338a2016-10-25 22:13:34128
129 using ClientsList = std::vector<std::unique_ptr<UiDevToolsClient>>;
Ali Hijazi60a72b0a2024-09-30 17:58:53130 using ConnectionsMap =
131 std::map<uint32_t, raw_ptr<UiDevToolsClient, CtnExperimental>>;
Matt Menkecde68ab2024-08-20 16:05:28132 ClientsList clients_ GUARDED_BY_CONTEXT(main_sequence_);
133 ConnectionsMap connections_ GUARDED_BY_CONTEXT(main_sequence_);
mhashmi1ec338a2016-10-25 22:13:34134
Matt Menkecde68ab2024-08-20 16:05:28135 const scoped_refptr<base::SingleThreadTaskRunner> io_thread_task_runner_;
mhashmi1ec338a2016-10-25 22:13:34136
Matt Menkecde68ab2024-08-20 16:05:28137 // The port the devtools server listens on.
138 int port_ GUARDED_BY_CONTEXT(main_sequence_);
Yuheng Huang55e929512021-06-04 16:33:14139
Matt Menkecde68ab2024-08-20 16:05:28140 raw_ptr<TracingAgent> tracing_agent_ GUARDED_BY_CONTEXT(main_sequence_) =
141 nullptr;
Illia Martyniukbd1e44852018-03-13 22:02:59142
Matt Menkecde68ab2024-08-20 16:05:28143 // Invoked when the server doesn't have any live connections.
144 mutable base::OnceClosure on_session_ended_
145 GUARDED_BY_CONTEXT(main_sequence_);
Sean Gilhuly13fc02ff32018-11-01 14:05:30146
Matt Menkecde68ab2024-08-20 16:05:28147 // Set once the server has been started.
148 bool connected_ GUARDED_BY_CONTEXT(main_sequence_) = false;
Mitsuru Oshima4de59ac2019-09-03 20:49:09149
Matt Menkecde68ab2024-08-20 16:05:28150 // Invoked once the server has been started.
151 base::OnceClosure on_socket_connected_ GUARDED_BY_CONTEXT(main_sequence_);
Wei Lie5915072021-03-09 18:42:45152
Mike Wasserman8f8b0852018-12-03 22:08:10153 // The server (owned by Chrome for now)
mhashmi6d1b1cb22016-11-22 16:04:24154 static UiDevToolsServer* devtools_server_;
155
Matt Menkecde68ab2024-08-20 16:05:28156 std::unique_ptr<IOThreadData> io_thread_data_;
157
158 SEQUENCE_CHECKER(main_sequence_);
Jeremy Roman5c341f6d2019-07-15 15:56:10159 base::WeakPtrFactory<UiDevToolsServer> weak_ptr_factory_{this};
mhashmi1ec338a2016-10-25 22:13:34160};
161
thanhph3f3968512017-06-21 00:37:23162} // namespace ui_devtools
mhashmi1ec338a2016-10-25 22:13:34163
164#endif // COMPONENTS_UI_DEVTOOLS_DEVTOOLS_SERVER_H_