xref: /aosp_15_r20/external/perfetto/src/traced_relay/relay_service.h (revision 6dbdd20afdafa5e3ca9b8809fa73465d530080dc)
1*6dbdd20aSAndroid Build Coastguard Worker /*
2*6dbdd20aSAndroid Build Coastguard Worker  * Copyright (C) 2023 The Android Open Source Project
3*6dbdd20aSAndroid Build Coastguard Worker  *
4*6dbdd20aSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*6dbdd20aSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*6dbdd20aSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*6dbdd20aSAndroid Build Coastguard Worker  *
8*6dbdd20aSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*6dbdd20aSAndroid Build Coastguard Worker  *
10*6dbdd20aSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*6dbdd20aSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*6dbdd20aSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*6dbdd20aSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*6dbdd20aSAndroid Build Coastguard Worker  * limitations under the License.
15*6dbdd20aSAndroid Build Coastguard Worker  */
16*6dbdd20aSAndroid Build Coastguard Worker 
17*6dbdd20aSAndroid Build Coastguard Worker #ifndef SRC_TRACED_RELAY_RELAY_SERVICE_H_
18*6dbdd20aSAndroid Build Coastguard Worker #define SRC_TRACED_RELAY_RELAY_SERVICE_H_
19*6dbdd20aSAndroid Build Coastguard Worker 
20*6dbdd20aSAndroid Build Coastguard Worker #include <memory>
21*6dbdd20aSAndroid Build Coastguard Worker #include <vector>
22*6dbdd20aSAndroid Build Coastguard Worker 
23*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/ext/base/unix_socket.h"
24*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/ext/tracing/core/tracing_service.h"
25*6dbdd20aSAndroid Build Coastguard Worker #include "src/traced_relay/socket_relay_handler.h"
26*6dbdd20aSAndroid Build Coastguard Worker #include "src/tracing/ipc/producer/relay_ipc_client.h"
27*6dbdd20aSAndroid Build Coastguard Worker 
28*6dbdd20aSAndroid Build Coastguard Worker namespace perfetto {
29*6dbdd20aSAndroid Build Coastguard Worker 
30*6dbdd20aSAndroid Build Coastguard Worker namespace base {
31*6dbdd20aSAndroid Build Coastguard Worker class TaskRunner;
32*6dbdd20aSAndroid Build Coastguard Worker }  // namespace base.
33*6dbdd20aSAndroid Build Coastguard Worker 
34*6dbdd20aSAndroid Build Coastguard Worker // RelayClient provides a service that is independent of the relayed producers
35*6dbdd20aSAndroid Build Coastguard Worker // and is global in the machine. This class implements time synchronization with
36*6dbdd20aSAndroid Build Coastguard Worker // the host machine:
37*6dbdd20aSAndroid Build Coastguard Worker // 1. Connects to the host machine using the client socket name (e.g.
38*6dbdd20aSAndroid Build Coastguard Worker // vsock://2:10001) to port 10001 of VMADDR_CID_HOST.
39*6dbdd20aSAndroid Build Coastguard Worker // 2. After the socket is connected, send the SetPeerIdentity message to let the
40*6dbdd20aSAndroid Build Coastguard Worker // tracing service know the identity (machine ID) of this RelayClient.
41*6dbdd20aSAndroid Build Coastguard Worker // 3. Then hand over the socket to RelayIPCClient, which is the client
42*6dbdd20aSAndroid Build Coastguard Worker // implementation of the RelayPort RPC service.
43*6dbdd20aSAndroid Build Coastguard Worker // 4. On any socket error, the RelayClient notifies its user using
44*6dbdd20aSAndroid Build Coastguard Worker // OnErrorCallback so the user (class RelayService) may retry the connection.
45*6dbdd20aSAndroid Build Coastguard Worker class RelayClient : private base::UnixSocket::EventListener,
46*6dbdd20aSAndroid Build Coastguard Worker                     private RelayIPCClient::EventListener {
47*6dbdd20aSAndroid Build Coastguard Worker  public:
48*6dbdd20aSAndroid Build Coastguard Worker   using OnErrorCallback = std::function<void()>;
49*6dbdd20aSAndroid Build Coastguard Worker   RelayClient(const std::string& client_sock_name,
50*6dbdd20aSAndroid Build Coastguard Worker               const std::string& machine_id_hint,
51*6dbdd20aSAndroid Build Coastguard Worker               base::TaskRunner* task_runner,
52*6dbdd20aSAndroid Build Coastguard Worker               OnErrorCallback on_destroy_callback);
53*6dbdd20aSAndroid Build Coastguard Worker   ~RelayClient() override;
54*6dbdd20aSAndroid Build Coastguard Worker 
ipc_client_connected()55*6dbdd20aSAndroid Build Coastguard Worker   bool ipc_client_connected() const { return phase_ != Phase::CONNECTING; }
clock_synced_with_service_for_testing()56*6dbdd20aSAndroid Build Coastguard Worker   bool clock_synced_with_service_for_testing() const {
57*6dbdd20aSAndroid Build Coastguard Worker     return clock_synced_with_service_for_testing_;
58*6dbdd20aSAndroid Build Coastguard Worker   }
59*6dbdd20aSAndroid Build Coastguard Worker 
60*6dbdd20aSAndroid Build Coastguard Worker  private:
61*6dbdd20aSAndroid Build Coastguard Worker   // UnixSocket::EventListener implementation for connecting to the client
62*6dbdd20aSAndroid Build Coastguard Worker   // socket.
OnNewIncomingConnection(base::UnixSocket *,std::unique_ptr<base::UnixSocket>)63*6dbdd20aSAndroid Build Coastguard Worker   void OnNewIncomingConnection(base::UnixSocket*,
64*6dbdd20aSAndroid Build Coastguard Worker                                std::unique_ptr<base::UnixSocket>) override {
65*6dbdd20aSAndroid Build Coastguard Worker     // This class doesn't open a socket in listening mode.
66*6dbdd20aSAndroid Build Coastguard Worker     PERFETTO_DFATAL("Should be unreachable.");
67*6dbdd20aSAndroid Build Coastguard Worker   }
68*6dbdd20aSAndroid Build Coastguard Worker   void OnConnect(base::UnixSocket* self, bool connected) override;
OnDisconnect(base::UnixSocket *)69*6dbdd20aSAndroid Build Coastguard Worker   void OnDisconnect(base::UnixSocket*) override { NotifyError(); }
OnDataAvailable(base::UnixSocket *)70*6dbdd20aSAndroid Build Coastguard Worker   void OnDataAvailable(base::UnixSocket*) override {
71*6dbdd20aSAndroid Build Coastguard Worker     // Should be handled in the IPC client.
72*6dbdd20aSAndroid Build Coastguard Worker     PERFETTO_DFATAL("Should be unreachable.");
73*6dbdd20aSAndroid Build Coastguard Worker   }
74*6dbdd20aSAndroid Build Coastguard Worker 
75*6dbdd20aSAndroid Build Coastguard Worker   void NotifyError();
76*6dbdd20aSAndroid Build Coastguard Worker   void Connect();
77*6dbdd20aSAndroid Build Coastguard Worker   void SendSyncClockRequest();
78*6dbdd20aSAndroid Build Coastguard Worker 
79*6dbdd20aSAndroid Build Coastguard Worker   // RelayIPCClient::EventListener implementation.
80*6dbdd20aSAndroid Build Coastguard Worker   void OnServiceConnected() override;
81*6dbdd20aSAndroid Build Coastguard Worker   void OnServiceDisconnected() override;
82*6dbdd20aSAndroid Build Coastguard Worker   void OnSyncClockResponse(const protos::gen::SyncClockResponse& resp) override;
83*6dbdd20aSAndroid Build Coastguard Worker 
84*6dbdd20aSAndroid Build Coastguard Worker   enum class Phase : uint32_t { CONNECTING = 1, PING, UPDATE };
85*6dbdd20aSAndroid Build Coastguard Worker   Phase phase_ = Phase::CONNECTING;
86*6dbdd20aSAndroid Build Coastguard Worker   bool clock_synced_with_service_for_testing_ = false;
87*6dbdd20aSAndroid Build Coastguard Worker 
88*6dbdd20aSAndroid Build Coastguard Worker   base::TaskRunner* task_runner_;
89*6dbdd20aSAndroid Build Coastguard Worker   OnErrorCallback on_error_callback_;
90*6dbdd20aSAndroid Build Coastguard Worker 
91*6dbdd20aSAndroid Build Coastguard Worker   std::string client_sock_name_;
92*6dbdd20aSAndroid Build Coastguard Worker   // A hint to the host traced for inferring the identifier of this machine.
93*6dbdd20aSAndroid Build Coastguard Worker   std::string machine_id_hint_;
94*6dbdd20aSAndroid Build Coastguard Worker   std::unique_ptr<base::UnixSocket> client_sock_;
95*6dbdd20aSAndroid Build Coastguard Worker   std::unique_ptr<RelayIPCClient> relay_ipc_client_;
96*6dbdd20aSAndroid Build Coastguard Worker 
97*6dbdd20aSAndroid Build Coastguard Worker   base::WeakPtrFactory<RelayIPCClient::EventListener>
98*6dbdd20aSAndroid Build Coastguard Worker       weak_factory_for_ipc_client{this};
99*6dbdd20aSAndroid Build Coastguard Worker   base::WeakPtrFactory<RelayClient> weak_factory_{this};
100*6dbdd20aSAndroid Build Coastguard Worker };
101*6dbdd20aSAndroid Build Coastguard Worker 
102*6dbdd20aSAndroid Build Coastguard Worker // A class for relaying the producer data between the local producers and the
103*6dbdd20aSAndroid Build Coastguard Worker // remote tracing service.
104*6dbdd20aSAndroid Build Coastguard Worker class RelayService : public base::UnixSocket::EventListener {
105*6dbdd20aSAndroid Build Coastguard Worker  public:
106*6dbdd20aSAndroid Build Coastguard Worker   explicit RelayService(base::TaskRunner* task_runner);
107*6dbdd20aSAndroid Build Coastguard Worker   ~RelayService() override = default;
108*6dbdd20aSAndroid Build Coastguard Worker 
109*6dbdd20aSAndroid Build Coastguard Worker   // Starts the service relay that forwards messages between the
110*6dbdd20aSAndroid Build Coastguard Worker   // |server_socket_name| and |client_socket_name| ports.
111*6dbdd20aSAndroid Build Coastguard Worker   void Start(const char* server_socket_name, const char* client_socket_name);
112*6dbdd20aSAndroid Build Coastguard Worker 
113*6dbdd20aSAndroid Build Coastguard Worker   // Starts the service relay that forwards messages between the
114*6dbdd20aSAndroid Build Coastguard Worker   // |server_socket_handle| and |client_socket_name| ports. Called when the
115*6dbdd20aSAndroid Build Coastguard Worker   // service is started by Android init.
116*6dbdd20aSAndroid Build Coastguard Worker   void Start(base::ScopedSocketHandle server_socket_handle,
117*6dbdd20aSAndroid Build Coastguard Worker              const char* client_socket_name);
118*6dbdd20aSAndroid Build Coastguard Worker 
119*6dbdd20aSAndroid Build Coastguard Worker   static std::string GetMachineIdHint(
120*6dbdd20aSAndroid Build Coastguard Worker       bool use_pseudo_boot_id_for_testing = false);
121*6dbdd20aSAndroid Build Coastguard Worker 
SetRelayClientDisabledForTesting(bool disabled)122*6dbdd20aSAndroid Build Coastguard Worker   void SetRelayClientDisabledForTesting(bool disabled) {
123*6dbdd20aSAndroid Build Coastguard Worker     relay_client_disabled_for_testing_ = disabled;
124*6dbdd20aSAndroid Build Coastguard Worker   }
SetMachineIdHintForTesting(std::string machine_id_hint)125*6dbdd20aSAndroid Build Coastguard Worker   void SetMachineIdHintForTesting(std::string machine_id_hint) {
126*6dbdd20aSAndroid Build Coastguard Worker     machine_id_hint_ = machine_id_hint;
127*6dbdd20aSAndroid Build Coastguard Worker   }
relay_client_for_testing()128*6dbdd20aSAndroid Build Coastguard Worker   RelayClient* relay_client_for_testing() { return relay_client_.get(); }
129*6dbdd20aSAndroid Build Coastguard Worker 
130*6dbdd20aSAndroid Build Coastguard Worker  private:
131*6dbdd20aSAndroid Build Coastguard Worker   struct PendingConnection {
132*6dbdd20aSAndroid Build Coastguard Worker     // This keeps a connected UnixSocketRaw server socket in its first element.
133*6dbdd20aSAndroid Build Coastguard Worker     std::unique_ptr<SocketPair> socket_pair;
134*6dbdd20aSAndroid Build Coastguard Worker     // This keeps the connecting client connection.
135*6dbdd20aSAndroid Build Coastguard Worker     std::unique_ptr<base::UnixSocket> connecting_client_conn;
136*6dbdd20aSAndroid Build Coastguard Worker   };
137*6dbdd20aSAndroid Build Coastguard Worker 
138*6dbdd20aSAndroid Build Coastguard Worker   RelayService(const RelayService&) = delete;
139*6dbdd20aSAndroid Build Coastguard Worker   RelayService& operator=(const RelayService&) = delete;
140*6dbdd20aSAndroid Build Coastguard Worker 
141*6dbdd20aSAndroid Build Coastguard Worker   // UnixSocket::EventListener implementation.
142*6dbdd20aSAndroid Build Coastguard Worker   void OnNewIncomingConnection(base::UnixSocket*,
143*6dbdd20aSAndroid Build Coastguard Worker                                std::unique_ptr<base::UnixSocket>) override;
144*6dbdd20aSAndroid Build Coastguard Worker   void OnConnect(base::UnixSocket* self, bool connected) override;
145*6dbdd20aSAndroid Build Coastguard Worker   void OnDisconnect(base::UnixSocket* self) override;
146*6dbdd20aSAndroid Build Coastguard Worker   void OnDataAvailable(base::UnixSocket* self) override;
147*6dbdd20aSAndroid Build Coastguard Worker 
148*6dbdd20aSAndroid Build Coastguard Worker   void ReconnectRelayClient();
149*6dbdd20aSAndroid Build Coastguard Worker   void ConnectRelayClient();
150*6dbdd20aSAndroid Build Coastguard Worker 
151*6dbdd20aSAndroid Build Coastguard Worker   base::TaskRunner* const task_runner_ = nullptr;
152*6dbdd20aSAndroid Build Coastguard Worker 
153*6dbdd20aSAndroid Build Coastguard Worker   // A hint to the host traced for inferring the identifier of this machine.
154*6dbdd20aSAndroid Build Coastguard Worker   std::string machine_id_hint_;
155*6dbdd20aSAndroid Build Coastguard Worker 
156*6dbdd20aSAndroid Build Coastguard Worker   std::unique_ptr<base::UnixSocket> listening_socket_;
157*6dbdd20aSAndroid Build Coastguard Worker   std::string client_socket_name_;
158*6dbdd20aSAndroid Build Coastguard Worker 
159*6dbdd20aSAndroid Build Coastguard Worker   // Keeps the socket pairs while waiting for relay connections to be
160*6dbdd20aSAndroid Build Coastguard Worker   // established.
161*6dbdd20aSAndroid Build Coastguard Worker   std::vector<PendingConnection> pending_connections_;
162*6dbdd20aSAndroid Build Coastguard Worker 
163*6dbdd20aSAndroid Build Coastguard Worker   SocketRelayHandler socket_relay_handler_;
164*6dbdd20aSAndroid Build Coastguard Worker 
165*6dbdd20aSAndroid Build Coastguard Worker   std::unique_ptr<RelayClient> relay_client_;
166*6dbdd20aSAndroid Build Coastguard Worker   // On RelayClient connection error, how long should we wait before retrying.
167*6dbdd20aSAndroid Build Coastguard Worker   static constexpr uint32_t kDefaultRelayClientRetryDelayMs = 1000;
168*6dbdd20aSAndroid Build Coastguard Worker   uint32_t relay_client_retry_delay_ms_ = kDefaultRelayClientRetryDelayMs;
169*6dbdd20aSAndroid Build Coastguard Worker   bool relay_client_disabled_for_testing_ = false;
170*6dbdd20aSAndroid Build Coastguard Worker };
171*6dbdd20aSAndroid Build Coastguard Worker 
172*6dbdd20aSAndroid Build Coastguard Worker }  // namespace perfetto
173*6dbdd20aSAndroid Build Coastguard Worker 
174*6dbdd20aSAndroid Build Coastguard Worker #endif  // SRC_TRACED_RELAY_RELAY_SERVICE_H_
175