1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef INCLUDE_PERFETTO_EXT_IPC_CLIENT_H_
18 #define INCLUDE_PERFETTO_EXT_IPC_CLIENT_H_
19 
20 #include <functional>
21 #include <memory>
22 
23 #include "perfetto/ext/base/scoped_file.h"
24 #include "perfetto/ext/base/unix_socket.h"
25 #include "perfetto/ext/base/weak_ptr.h"
26 #include "perfetto/ext/ipc/basic_types.h"
27 
28 namespace perfetto {
29 
30 namespace base {
31 class TaskRunner;
32 }  // namespace base
33 
34 namespace ipc {
35 class ServiceProxy;
36 
37 // The client-side class that talks to the host over the socket and multiplexes
38 // requests coming from the various autogenerated ServiceProxy stubs.
39 // This is meant to be used by the user code as follows:
40 // auto client = Client::CreateInstance("socket_name", task_runner);
41 // std::unique_ptr<GreeterService> svc(new GreeterService());
42 // client.BindService(svc);
43 // svc.OnConnect([] () {
44 //    svc.SayHello(..., ...);
45 // });
46 class Client {
47  public:
48   // struct ConnArgs is used for creating a client in 2 connection modes:
49   // 1. Connect using a socket name with the option to retry the connection on
50   //    connection failure.
51   // 2. Adopt a connected socket.
52   struct ConnArgs {
ConnArgsConnArgs53     ConnArgs(const char* sock_name, bool sock_retry)
54         : socket_name(sock_name), retry(sock_retry) {}
ConnArgsConnArgs55     explicit ConnArgs(base::ScopedSocketHandle sock_fd)
56         : socket_fd(std::move(sock_fd)) {}
57 
58     // Disallow copy. Only supports move.
59     ConnArgs(const ConnArgs& other) = delete;
60     ConnArgs(ConnArgs&& other) = default;
61 
62     base::ScopedSocketHandle socket_fd;
63     const char* socket_name = nullptr;
64     bool retry = false;  // Only for connecting with |socket_name|.
65   };
66 
67   static std::unique_ptr<Client> CreateInstance(ConnArgs, base::TaskRunner*);
68   virtual ~Client();
69 
70   virtual void BindService(base::WeakPtr<ServiceProxy>) = 0;
71 
72   // There is no need to call this method explicitly. Destroying the
73   // ServiceProxy instance is sufficient and will automatically unbind it. This
74   // method is exposed only for the ServiceProxy destructor.
75   virtual void UnbindService(ServiceID) = 0;
76 
77   // Returns (with move semantics) the last file descriptor received on the IPC
78   // channel. No buffering is performed: if a service sends two file descriptors
79   // and the caller doesn't read them immediately, the first one will be
80   // automatically closed when the second is received (and will hit a DCHECK in
81   // debug builds).
82   virtual base::ScopedFile TakeReceivedFD() = 0;
83 };
84 
85 }  // namespace ipc
86 }  // namespace perfetto
87 
88 #endif  // INCLUDE_PERFETTO_EXT_IPC_CLIENT_H_
89