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