1420e47e26ce8a988601a12bc47ba6acb31e97d6dPrimiano Tucci/*
2420e47e26ce8a988601a12bc47ba6acb31e97d6dPrimiano Tucci * Copyright (C) 2017 The Android Open Source Project
3420e47e26ce8a988601a12bc47ba6acb31e97d6dPrimiano Tucci *
4420e47e26ce8a988601a12bc47ba6acb31e97d6dPrimiano Tucci * Licensed under the Apache License, Version 2.0 (the "License");
5420e47e26ce8a988601a12bc47ba6acb31e97d6dPrimiano Tucci * you may not use this file except in compliance with the License.
6420e47e26ce8a988601a12bc47ba6acb31e97d6dPrimiano Tucci * You may obtain a copy of the License at
7420e47e26ce8a988601a12bc47ba6acb31e97d6dPrimiano Tucci *
8420e47e26ce8a988601a12bc47ba6acb31e97d6dPrimiano Tucci *      http://www.apache.org/licenses/LICENSE-2.0
9420e47e26ce8a988601a12bc47ba6acb31e97d6dPrimiano Tucci *
10420e47e26ce8a988601a12bc47ba6acb31e97d6dPrimiano Tucci * Unless required by applicable law or agreed to in writing, software
11420e47e26ce8a988601a12bc47ba6acb31e97d6dPrimiano Tucci * distributed under the License is distributed on an "AS IS" BASIS,
12420e47e26ce8a988601a12bc47ba6acb31e97d6dPrimiano Tucci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13420e47e26ce8a988601a12bc47ba6acb31e97d6dPrimiano Tucci * See the License for the specific language governing permissions and
14420e47e26ce8a988601a12bc47ba6acb31e97d6dPrimiano Tucci * limitations under the License.
15420e47e26ce8a988601a12bc47ba6acb31e97d6dPrimiano Tucci */
16420e47e26ce8a988601a12bc47ba6acb31e97d6dPrimiano Tucci
174f9b6d7b7b2ad7b86e1577a18dc6e2df91b98164Primiano Tucci#ifndef SRC_IPC_HOST_IMPL_H_
184f9b6d7b7b2ad7b86e1577a18dc6e2df91b98164Primiano Tucci#define SRC_IPC_HOST_IMPL_H_
19420e47e26ce8a988601a12bc47ba6acb31e97d6dPrimiano Tucci
20420e47e26ce8a988601a12bc47ba6acb31e97d6dPrimiano Tucci#include <map>
21420e47e26ce8a988601a12bc47ba6acb31e97d6dPrimiano Tucci#include <set>
22420e47e26ce8a988601a12bc47ba6acb31e97d6dPrimiano Tucci#include <string>
23420e47e26ce8a988601a12bc47ba6acb31e97d6dPrimiano Tucci#include <vector>
24420e47e26ce8a988601a12bc47ba6acb31e97d6dPrimiano Tucci
254f9b6d7b7b2ad7b86e1577a18dc6e2df91b98164Primiano Tucci#include "perfetto/base/task_runner.h"
264f9b6d7b7b2ad7b86e1577a18dc6e2df91b98164Primiano Tucci#include "perfetto/base/thread_checker.h"
274f9b6d7b7b2ad7b86e1577a18dc6e2df91b98164Primiano Tucci#include "perfetto/ipc/deferred.h"
284f9b6d7b7b2ad7b86e1577a18dc6e2df91b98164Primiano Tucci#include "perfetto/ipc/host.h"
294f9b6d7b7b2ad7b86e1577a18dc6e2df91b98164Primiano Tucci#include "src/ipc/buffered_frame_deserializer.h"
304f9b6d7b7b2ad7b86e1577a18dc6e2df91b98164Primiano Tucci#include "src/ipc/unix_socket.h"
31420e47e26ce8a988601a12bc47ba6acb31e97d6dPrimiano Tucci
32420e47e26ce8a988601a12bc47ba6acb31e97d6dPrimiano Tuccinamespace perfetto {
33420e47e26ce8a988601a12bc47ba6acb31e97d6dPrimiano Tuccinamespace ipc {
34420e47e26ce8a988601a12bc47ba6acb31e97d6dPrimiano Tucci
35420e47e26ce8a988601a12bc47ba6acb31e97d6dPrimiano Tucciclass Frame;
36420e47e26ce8a988601a12bc47ba6acb31e97d6dPrimiano Tucci
37420e47e26ce8a988601a12bc47ba6acb31e97d6dPrimiano Tucciclass HostImpl : public Host, public UnixSocket::EventListener {
38420e47e26ce8a988601a12bc47ba6acb31e97d6dPrimiano Tucci public:
39420e47e26ce8a988601a12bc47ba6acb31e97d6dPrimiano Tucci  HostImpl(const char* socket_name, base::TaskRunner*);
409b5d3368acca7d1388ac82efb416d82179db3f71Primiano Tucci  HostImpl(base::ScopedFile socket_fd, base::TaskRunner*);
41420e47e26ce8a988601a12bc47ba6acb31e97d6dPrimiano Tucci  ~HostImpl() override;
42420e47e26ce8a988601a12bc47ba6acb31e97d6dPrimiano Tucci
43420e47e26ce8a988601a12bc47ba6acb31e97d6dPrimiano Tucci  // Host implementation.
44420e47e26ce8a988601a12bc47ba6acb31e97d6dPrimiano Tucci  bool ExposeService(std::unique_ptr<Service>) override;
45420e47e26ce8a988601a12bc47ba6acb31e97d6dPrimiano Tucci
46420e47e26ce8a988601a12bc47ba6acb31e97d6dPrimiano Tucci  // UnixSocket::EventListener implementation.
47420e47e26ce8a988601a12bc47ba6acb31e97d6dPrimiano Tucci  void OnNewIncomingConnection(UnixSocket*,
48420e47e26ce8a988601a12bc47ba6acb31e97d6dPrimiano Tucci                               std::unique_ptr<UnixSocket>) override;
49420e47e26ce8a988601a12bc47ba6acb31e97d6dPrimiano Tucci  void OnDisconnect(UnixSocket*) override;
50420e47e26ce8a988601a12bc47ba6acb31e97d6dPrimiano Tucci  void OnDataAvailable(UnixSocket*) override;
51420e47e26ce8a988601a12bc47ba6acb31e97d6dPrimiano Tucci
52420e47e26ce8a988601a12bc47ba6acb31e97d6dPrimiano Tucci  const UnixSocket* sock() const { return sock_.get(); }
53420e47e26ce8a988601a12bc47ba6acb31e97d6dPrimiano Tucci
54420e47e26ce8a988601a12bc47ba6acb31e97d6dPrimiano Tucci private:
55420e47e26ce8a988601a12bc47ba6acb31e97d6dPrimiano Tucci  // Owns the per-client receive buffer (BufferedFrameDeserializer).
56420e47e26ce8a988601a12bc47ba6acb31e97d6dPrimiano Tucci  struct ClientConnection {
57420e47e26ce8a988601a12bc47ba6acb31e97d6dPrimiano Tucci    ~ClientConnection();
58420e47e26ce8a988601a12bc47ba6acb31e97d6dPrimiano Tucci    ClientID id;
59420e47e26ce8a988601a12bc47ba6acb31e97d6dPrimiano Tucci    std::unique_ptr<UnixSocket> sock;
60420e47e26ce8a988601a12bc47ba6acb31e97d6dPrimiano Tucci    BufferedFrameDeserializer frame_deserializer;
61d16508e288431f2b5fc02e5f45ba1e3cb1801487Florian Mayer    base::ScopedFile received_fd;
62420e47e26ce8a988601a12bc47ba6acb31e97d6dPrimiano Tucci  };
63420e47e26ce8a988601a12bc47ba6acb31e97d6dPrimiano Tucci  struct ExposedService {
64420e47e26ce8a988601a12bc47ba6acb31e97d6dPrimiano Tucci    ExposedService(ServiceID, const std::string&, std::unique_ptr<Service>);
65420e47e26ce8a988601a12bc47ba6acb31e97d6dPrimiano Tucci    ~ExposedService();
66420e47e26ce8a988601a12bc47ba6acb31e97d6dPrimiano Tucci    ExposedService(ExposedService&&) noexcept;
67420e47e26ce8a988601a12bc47ba6acb31e97d6dPrimiano Tucci    ExposedService& operator=(ExposedService&&);
68420e47e26ce8a988601a12bc47ba6acb31e97d6dPrimiano Tucci
69420e47e26ce8a988601a12bc47ba6acb31e97d6dPrimiano Tucci    ServiceID id;
70420e47e26ce8a988601a12bc47ba6acb31e97d6dPrimiano Tucci    std::string name;
71420e47e26ce8a988601a12bc47ba6acb31e97d6dPrimiano Tucci    std::unique_ptr<Service> instance;
72420e47e26ce8a988601a12bc47ba6acb31e97d6dPrimiano Tucci  };
73420e47e26ce8a988601a12bc47ba6acb31e97d6dPrimiano Tucci
74420e47e26ce8a988601a12bc47ba6acb31e97d6dPrimiano Tucci  HostImpl(const HostImpl&) = delete;
75420e47e26ce8a988601a12bc47ba6acb31e97d6dPrimiano Tucci  HostImpl& operator=(const HostImpl&) = delete;
76420e47e26ce8a988601a12bc47ba6acb31e97d6dPrimiano Tucci
77420e47e26ce8a988601a12bc47ba6acb31e97d6dPrimiano Tucci  bool Initialize(const char* socket_name);
78420e47e26ce8a988601a12bc47ba6acb31e97d6dPrimiano Tucci  void OnReceivedFrame(ClientConnection*, const Frame&);
79420e47e26ce8a988601a12bc47ba6acb31e97d6dPrimiano Tucci  void OnBindService(ClientConnection*, const Frame&);
80420e47e26ce8a988601a12bc47ba6acb31e97d6dPrimiano Tucci  void OnInvokeMethod(ClientConnection*, const Frame&);
81420e47e26ce8a988601a12bc47ba6acb31e97d6dPrimiano Tucci  void ReplyToMethodInvocation(ClientID, RequestID, AsyncResult<ProtoMessage>);
82420e47e26ce8a988601a12bc47ba6acb31e97d6dPrimiano Tucci  const ExposedService* GetServiceByName(const std::string&);
83420e47e26ce8a988601a12bc47ba6acb31e97d6dPrimiano Tucci
84f54cae46abc4c9e8b7d9120dbeba813b7c066561Primiano Tucci  static void SendFrame(ClientConnection*, const Frame&, int fd = -1);
85420e47e26ce8a988601a12bc47ba6acb31e97d6dPrimiano Tucci
86420e47e26ce8a988601a12bc47ba6acb31e97d6dPrimiano Tucci  base::TaskRunner* const task_runner_;
87420e47e26ce8a988601a12bc47ba6acb31e97d6dPrimiano Tucci  std::map<ServiceID, ExposedService> services_;
88420e47e26ce8a988601a12bc47ba6acb31e97d6dPrimiano Tucci  std::unique_ptr<UnixSocket> sock_;  // The listening socket.
89420e47e26ce8a988601a12bc47ba6acb31e97d6dPrimiano Tucci  std::map<ClientID, std::unique_ptr<ClientConnection>> clients_;
90420e47e26ce8a988601a12bc47ba6acb31e97d6dPrimiano Tucci  std::map<UnixSocket*, ClientConnection*> clients_by_socket_;
91420e47e26ce8a988601a12bc47ba6acb31e97d6dPrimiano Tucci  ServiceID last_service_id_ = 0;
92420e47e26ce8a988601a12bc47ba6acb31e97d6dPrimiano Tucci  ClientID last_client_id_ = 0;
9368323b084eac9a8cc53ff0c9354839be0a5c4dd8Primiano Tucci  base::WeakPtrFactory<HostImpl> weak_ptr_factory_;
94420e47e26ce8a988601a12bc47ba6acb31e97d6dPrimiano Tucci  PERFETTO_THREAD_CHECKER(thread_checker_)
95420e47e26ce8a988601a12bc47ba6acb31e97d6dPrimiano Tucci};
96420e47e26ce8a988601a12bc47ba6acb31e97d6dPrimiano Tucci
97420e47e26ce8a988601a12bc47ba6acb31e97d6dPrimiano Tucci}  // namespace ipc
98420e47e26ce8a988601a12bc47ba6acb31e97d6dPrimiano Tucci}  // namespace perfetto
99420e47e26ce8a988601a12bc47ba6acb31e97d6dPrimiano Tucci
1004f9b6d7b7b2ad7b86e1577a18dc6e2df91b98164Primiano Tucci#endif  // SRC_IPC_HOST_IMPL_H_
101