Pivot source files into top-level src,include and unify test target

See discussion in go/perfetto-build-files .
This is to disambiguate things like
  #include "base/logging.h"
when in the chrome tree.

Also this CL unifies the test targets into two monolithic targets:
perfetto_tests and perfetto_benchmarks. This is to avoid ending
up with confusing binary names in the chrome tree (e.g.,
ipc_unittests)

Bug: 68710794
Change-Id: I1768e15b661406052b2be060d7aab0f1e7443a98
diff --git a/src/ipc/unix_socket.cc b/src/ipc/unix_socket.cc
new file mode 100644
index 0000000..e28f3dc
--- /dev/null
+++ b/src/ipc/unix_socket.cc
@@ -0,0 +1,450 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "src/ipc/unix_socket.h"
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/un.h>
+#include <unistd.h>
+
+#include <algorithm>
+#include <memory>
+
+#include "perfetto/base/build_config.h"
+#include "perfetto/base/logging.h"
+#include "perfetto/base/task_runner.h"
+#include "perfetto/base/utils.h"
+
+#if BUILDFLAG(OS_MACOSX)
+#include <sys/ucred.h>
+#endif
+
+namespace perfetto {
+namespace ipc {
+
+// TODO(primiano): Add ThreadChecker to methods of this class.
+
+namespace {
+
+// MSG_NOSIGNAL is not supported on Mac OS X, but in that case the socket is
+// created with SO_NOSIGPIPE (See InitializeSocket()).
+#if BUILDFLAG(OS_MACOSX)
+constexpr int kNoSigPipe = 0;
+#else
+constexpr int kNoSigPipe = MSG_NOSIGNAL;
+#endif
+
+// Android takes an int instead of socklen_t for the control buffer size.
+#if BUILDFLAG(OS_ANDROID)
+using CBufLenType = size_t;
+#else
+using CBufLenType = socklen_t;
+#endif
+
+bool MakeSockAddr(const std::string& socket_name,
+                  sockaddr_un* addr,
+                  socklen_t* addr_size) {
+  memset(addr, 0, sizeof(*addr));
+  const size_t name_len = socket_name.size();
+  if (name_len >= sizeof(addr->sun_path)) {
+    errno = ENAMETOOLONG;
+    return false;
+  }
+  memcpy(addr->sun_path, socket_name.data(), name_len);
+  if (addr->sun_path[0] == '@')
+    addr->sun_path[0] = '\0';
+  addr->sun_family = AF_UNIX;
+  *addr_size = static_cast<socklen_t>(
+      __builtin_offsetof(sockaddr_un, sun_path) + name_len + 1);
+  return true;
+}
+
+}  // namespace
+
+// static
+std::unique_ptr<UnixSocket> UnixSocket::Listen(const std::string& socket_name,
+                                               EventListener* event_listener,
+                                               base::TaskRunner* task_runner) {
+  std::unique_ptr<UnixSocket> sock(new UnixSocket(event_listener, task_runner));
+  sock->DoListen(socket_name);
+  return sock;
+}
+
+// static
+std::unique_ptr<UnixSocket> UnixSocket::Connect(const std::string& socket_name,
+                                                EventListener* event_listener,
+                                                base::TaskRunner* task_runner) {
+  std::unique_ptr<UnixSocket> sock(new UnixSocket(event_listener, task_runner));
+  sock->DoConnect(socket_name);
+  return sock;
+}
+
+UnixSocket::UnixSocket(EventListener* event_listener,
+                       base::TaskRunner* task_runner)
+    : UnixSocket(event_listener, task_runner, base::ScopedFile()) {}
+
+UnixSocket::UnixSocket(EventListener* event_listener,
+                       base::TaskRunner* task_runner,
+                       base::ScopedFile adopt_fd)
+    : event_listener_(event_listener),
+      task_runner_(task_runner),
+      weak_ptr_factory_(this) {
+  if (adopt_fd) {
+    // Only in the case of OnNewIncomingConnection().
+    fd_ = std::move(adopt_fd);
+    state_ = State::kConnected;
+    ReadPeerCredentials();
+  } else {
+    fd_.reset(socket(AF_UNIX, SOCK_STREAM, 0));
+  }
+  if (!fd_) {
+    last_error_ = errno;
+    return;
+  }
+
+#if BUILDFLAG(OS_MACOSX)
+  const int no_sigpipe = 1;
+  setsockopt(*fd_, SOL_SOCKET, SO_NOSIGPIPE, &no_sigpipe, sizeof(no_sigpipe));
+#endif
+  // There is no reason why a socket should outlive the process in case of
+  // exec() by default, this is just working around a broken unix design.
+  int fcntl_res = fcntl(*fd_, F_SETFD, FD_CLOEXEC);
+  PERFETTO_CHECK(fcntl_res == 0);
+
+  // Set non-blocking mode.
+  int flags = fcntl(*fd_, F_GETFL, 0);
+  flags |= O_NONBLOCK;
+  fcntl_res = fcntl(fd(), F_SETFL, flags);
+  PERFETTO_CHECK(fcntl_res == 0);
+
+  base::WeakPtr<UnixSocket> weak_ptr = weak_ptr_factory_.GetWeakPtr();
+  task_runner_->AddFileDescriptorWatch(*fd_, [weak_ptr]() {
+    if (weak_ptr)
+      weak_ptr->OnEvent();
+  });
+}
+
+UnixSocket::~UnixSocket() {
+  // The implicit dtor of |weak_ptr_factory_| will no-op pending callbacks.
+  Shutdown();
+}
+
+// Called only by the Listen() static constructor.
+void UnixSocket::DoListen(const std::string& socket_name) {
+  PERFETTO_DCHECK(state_ == State::kDisconnected);
+  if (!fd_)
+    return;  // This is the only thing that can gracefully fail in the ctor.
+
+  sockaddr_un addr;
+  socklen_t addr_size;
+  if (!MakeSockAddr(socket_name, &addr, &addr_size)) {
+    last_error_ = errno;
+    return;
+  }
+
+// Android takes an int as 3rd argument of bind() instead of socklen_t.
+#if BUILDFLAG(OS_ANDROID)
+  const int bind_size = static_cast<int>(addr_size);
+#else
+  const socklen_t bind_size = addr_size;
+#endif
+
+  if (bind(*fd_, reinterpret_cast<sockaddr*>(&addr), bind_size)) {
+    last_error_ = errno;
+    PERFETTO_DPLOG("bind()");
+    return;
+  }
+  if (listen(*fd_, SOMAXCONN)) {
+    last_error_ = errno;
+    PERFETTO_DPLOG("listen()");
+    return;
+  }
+
+  last_error_ = 0;
+  state_ = State::kListening;
+}
+
+// Called only by the Connect() static constructor.
+void UnixSocket::DoConnect(const std::string& socket_name) {
+  PERFETTO_DCHECK(state_ == State::kDisconnected);
+
+  // This is the only thing that can gracefully fail in the ctor.
+  if (!fd_)
+    return NotifyConnectionState(false);
+
+  sockaddr_un addr;
+  socklen_t addr_size;
+  if (!MakeSockAddr(socket_name, &addr, &addr_size)) {
+    last_error_ = errno;
+    return NotifyConnectionState(false);
+  }
+
+  int res = PERFETTO_EINTR(
+      connect(*fd_, reinterpret_cast<sockaddr*>(&addr), addr_size));
+  if (res && errno != EINPROGRESS) {
+    last_error_ = errno;
+    return NotifyConnectionState(false);
+  }
+
+  // At this point either |res| == 0 (the connect() succeeded) or started
+  // asynchronously (EINPROGRESS).
+  last_error_ = 0;
+  state_ = State::kConnecting;
+
+  // Even if the socket is non-blocking, connecting to a UNIX socket can be
+  // acknowledged straight away rather than returning EINPROGRESS. In this case
+  // just trigger an OnEvent without waiting for the FD watch. That will poll
+  // the SO_ERROR and evolve the state into either kConnected or kDisconnected.
+  if (res == 0) {
+    base::WeakPtr<UnixSocket> weak_ptr = weak_ptr_factory_.GetWeakPtr();
+    task_runner_->PostTask([weak_ptr]() {
+      if (weak_ptr)
+        weak_ptr->OnEvent();
+    });
+  }
+}
+
+void UnixSocket::ReadPeerCredentials() {
+#if BUILDFLAG(OS_LINUX) || BUILDFLAG(OS_ANDROID)
+  struct ucred user_cred;
+  socklen_t len = sizeof(user_cred);
+  int res = getsockopt(*fd_, SOL_SOCKET, SO_PEERCRED, &user_cred, &len);
+  PERFETTO_CHECK(res == 0);
+  peer_uid_ = user_cred.uid;
+#else
+  struct xucred user_cred;
+  socklen_t len = sizeof(user_cred);
+  int res = getsockopt(*fd_, 0, LOCAL_PEERCRED, &user_cred, &len);
+  PERFETTO_CHECK(res == 0 && user_cred.cr_version == XUCRED_VERSION);
+  peer_uid_ = user_cred.cr_uid;
+#endif
+}
+
+void UnixSocket::OnEvent() {
+  if (state_ == State::kDisconnected)
+    return;  // Some spurious event, typically queued just before Shutdown().
+
+  if (state_ == State::kConnected)
+    return event_listener_->OnDataAvailable(this);
+
+  if (state_ == State::kConnecting) {
+    PERFETTO_DCHECK(fd_);
+    int sock_err = EINVAL;
+    socklen_t err_len = sizeof(sock_err);
+    int res = getsockopt(*fd_, SOL_SOCKET, SO_ERROR, &sock_err, &err_len);
+    if (res == 0 && sock_err == EINPROGRESS)
+      return;  // Not connected yet, just a spurious FD watch wakeup.
+    if (res == 0 && sock_err == 0) {
+      ReadPeerCredentials();
+      state_ = State::kConnected;
+      return event_listener_->OnConnect(this, true /* connected */);
+    }
+    last_error_ = sock_err;
+    return event_listener_->OnConnect(this, false /* connected */);
+  }
+
+  // New incoming connection.
+  if (state_ == State::kListening) {
+    // There could be more than one incoming connection behind each FD watch
+    // notification. Drain'em all.
+    for (;;) {
+      sockaddr_un cli_addr = {};
+      socklen_t size = sizeof(cli_addr);
+      base::ScopedFile new_fd(PERFETTO_EINTR(
+          accept(*fd_, reinterpret_cast<sockaddr*>(&cli_addr), &size)));
+      if (!new_fd)
+        return;
+      std::unique_ptr<UnixSocket> new_sock(
+          new UnixSocket(event_listener_, task_runner_, std::move(new_fd)));
+      event_listener_->OnNewIncomingConnection(this, std::move(new_sock));
+    }
+  }
+}
+
+bool UnixSocket::Send(const std::string& msg) {
+  return Send(msg.c_str(), msg.size() + 1);
+}
+
+bool UnixSocket::Send(const void* msg, size_t len, int send_fd) {
+  if (state_ != State::kConnected) {
+    errno = last_error_ = ENOTCONN;
+    return false;
+  }
+
+  msghdr msg_hdr = {};
+  iovec iov = {const_cast<void*>(msg), len};
+  msg_hdr.msg_iov = &iov;
+  msg_hdr.msg_iovlen = 1;
+  alignas(cmsghdr) char control_buf[256];
+
+  if (send_fd > -1) {
+    const CBufLenType control_buf_len =
+        static_cast<CBufLenType>(CMSG_SPACE(sizeof(int)));
+    PERFETTO_CHECK(control_buf_len <= sizeof(control_buf));
+    memset(control_buf, 0, sizeof(control_buf));
+    msg_hdr.msg_control = control_buf;
+    msg_hdr.msg_controllen = control_buf_len;
+    struct cmsghdr* cmsg = CMSG_FIRSTHDR(&msg_hdr);
+    cmsg->cmsg_level = SOL_SOCKET;
+    cmsg->cmsg_type = SCM_RIGHTS;
+    cmsg->cmsg_len = CMSG_LEN(sizeof(int));
+    memcpy(CMSG_DATA(cmsg), &send_fd, sizeof(int));
+    msg_hdr.msg_controllen = cmsg->cmsg_len;
+  }
+
+  const ssize_t sz = PERFETTO_EINTR(sendmsg(*fd_, &msg_hdr, kNoSigPipe));
+  if (sz >= 0) {
+    // There should be no way a non-blocking socket returns < |len|.
+    // If the queueing fails, sendmsg() must return -1 + errno = EWOULDBLOCK.
+    PERFETTO_CHECK(static_cast<size_t>(sz) == len);
+    last_error_ = 0;
+    return true;
+  }
+
+  if (errno == EAGAIN || errno == EWOULDBLOCK) {
+    // A genuine out-of-buffer. The client should retry or give up.
+    // Man pages specify that EAGAIN and EWOULDBLOCK have the same semantic here
+    // and clients should check for both.
+    last_error_ = EAGAIN;
+    return false;
+  }
+
+  // Either the the other endpoint disconnect (ECONNRESET) or some other error
+  // happened.
+  last_error_ = errno;
+  PERFETTO_DPLOG("sendmsg() failed");
+  Shutdown();
+  return false;
+}
+
+void UnixSocket::Shutdown() {
+  base::WeakPtr<UnixSocket> weak_ptr = weak_ptr_factory_.GetWeakPtr();
+  if (state_ == State::kConnected) {
+    task_runner_->PostTask([weak_ptr]() {
+      if (weak_ptr)
+        weak_ptr->event_listener_->OnDisconnect(weak_ptr.get());
+    });
+  } else if (state_ == State::kConnecting) {
+    task_runner_->PostTask([weak_ptr]() {
+      if (weak_ptr)
+        weak_ptr->event_listener_->OnConnect(weak_ptr.get(), false);
+    });
+  }
+  if (fd_) {
+    shutdown(*fd_, SHUT_RDWR);
+    task_runner_->RemoveFileDescriptorWatch(*fd_);
+    fd_.reset();
+  }
+  state_ = State::kDisconnected;
+}
+
+size_t UnixSocket::Receive(void* msg, size_t len, base::ScopedFile* recv_fd) {
+  if (state_ != State::kConnected) {
+    last_error_ = ENOTCONN;
+    return 0;
+  }
+
+  msghdr msg_hdr = {};
+  iovec iov = {msg, len};
+  msg_hdr.msg_iov = &iov;
+  msg_hdr.msg_iovlen = 1;
+  alignas(cmsghdr) char control_buf[256];
+
+  if (recv_fd) {
+    msg_hdr.msg_control = control_buf;
+    msg_hdr.msg_controllen = static_cast<CBufLenType>(CMSG_SPACE(sizeof(int)));
+    PERFETTO_CHECK(msg_hdr.msg_controllen <= sizeof(control_buf));
+  }
+  const ssize_t sz = PERFETTO_EINTR(recvmsg(*fd_, &msg_hdr, kNoSigPipe));
+  if (sz < 0 && (errno == EAGAIN || errno == EWOULDBLOCK)) {
+    last_error_ = EAGAIN;
+    return 0;
+  }
+  if (sz <= 0) {
+    last_error_ = errno;
+    Shutdown();
+    return 0;
+  }
+  PERFETTO_CHECK(static_cast<size_t>(sz) <= len);
+
+  int* fds = nullptr;
+  uint32_t fds_len = 0;
+
+  if (msg_hdr.msg_controllen > 0) {
+    for (cmsghdr* cmsg = CMSG_FIRSTHDR(&msg_hdr); cmsg;
+         cmsg = CMSG_NXTHDR(&msg_hdr, cmsg)) {
+      const size_t payload_len = cmsg->cmsg_len - CMSG_LEN(0);
+      if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS) {
+        PERFETTO_DCHECK(payload_len % sizeof(int) == 0u);
+        PERFETTO_DCHECK(fds == nullptr);
+        fds = reinterpret_cast<int*>(CMSG_DATA(cmsg));
+        fds_len = static_cast<uint32_t>(payload_len / sizeof(int));
+      }
+    }
+  }
+
+  if (msg_hdr.msg_flags & MSG_TRUNC || msg_hdr.msg_flags & MSG_CTRUNC) {
+    for (size_t i = 0; fds && i < fds_len; ++i)
+      close(fds[i]);
+    last_error_ = EMSGSIZE;
+    Shutdown();
+    return 0;
+  }
+
+  for (size_t i = 0; fds && i < fds_len; ++i) {
+    if (recv_fd && i == 0) {
+      recv_fd->reset(fds[i]);
+    } else {
+      close(fds[i]);
+    }
+  }
+
+  last_error_ = 0;
+  return static_cast<size_t>(sz);
+}
+
+std::string UnixSocket::ReceiveString(size_t max_length) {
+  std::unique_ptr<char[]> buf(new char[max_length + 1]);
+  size_t rsize = Receive(buf.get(), max_length);
+  PERFETTO_CHECK(static_cast<size_t>(rsize) <= max_length);
+  buf[static_cast<size_t>(rsize)] = '\0';
+  return std::string(buf.get());
+}
+
+void UnixSocket::NotifyConnectionState(bool success) {
+  base::WeakPtr<UnixSocket> weak_ptr = weak_ptr_factory_.GetWeakPtr();
+  task_runner_->PostTask([weak_ptr, success]() {
+    if (weak_ptr)
+      weak_ptr->event_listener_->OnConnect(weak_ptr.get(), success);
+  });
+}
+
+UnixSocket::EventListener::~EventListener() {}
+void UnixSocket::EventListener::OnNewIncomingConnection(
+    UnixSocket*,
+    std::unique_ptr<UnixSocket>) {}
+void UnixSocket::EventListener::OnConnect(UnixSocket*, bool) {}
+void UnixSocket::EventListener::OnDisconnect(UnixSocket*) {}
+void UnixSocket::EventListener::OnDataAvailable(UnixSocket*) {}
+
+}  // namespace ipc
+}  // namespace perfetto