Move unix socket to base.

Change-Id: Ic84986efb90ee95a45abc4558fa472f890acd885
diff --git a/Android.bp b/Android.bp
index 8edd08a..e7f0d6c 100644
--- a/Android.bp
+++ b/Android.bp
@@ -35,12 +35,12 @@
     "src/base/file_utils.cc",
     "src/base/metatrace.cc",
     "src/base/page_allocator.cc",
-    "src/base/sock_utils.cc",
     "src/base/string_splitter.cc",
     "src/base/string_utils.cc",
     "src/base/temp_file.cc",
     "src/base/thread_checker.cc",
     "src/base/time.cc",
+    "src/base/unix_socket.cc",
     "src/base/unix_task_runner.cc",
     "src/base/virtual_destructors.cc",
     "src/base/watchdog_posix.cc",
@@ -49,7 +49,6 @@
     "src/ipc/deferred.cc",
     "src/ipc/host_impl.cc",
     "src/ipc/service_proxy.cc",
-    "src/ipc/unix_socket.cc",
     "src/ipc/virtual_destructors.cc",
     "src/protozero/message.cc",
     "src/protozero/message_handle.cc",
@@ -161,12 +160,12 @@
     "src/base/file_utils.cc",
     "src/base/metatrace.cc",
     "src/base/page_allocator.cc",
-    "src/base/sock_utils.cc",
     "src/base/string_splitter.cc",
     "src/base/string_utils.cc",
     "src/base/temp_file.cc",
     "src/base/thread_checker.cc",
     "src/base/time.cc",
+    "src/base/unix_socket.cc",
     "src/base/unix_task_runner.cc",
     "src/base/virtual_destructors.cc",
     "src/base/watchdog_posix.cc",
@@ -175,7 +174,6 @@
     "src/ipc/deferred.cc",
     "src/ipc/host_impl.cc",
     "src/ipc/service_proxy.cc",
-    "src/ipc/unix_socket.cc",
     "src/ipc/virtual_destructors.cc",
     "src/perfetto_cmd/main.cc",
     "src/perfetto_cmd/perfetto_cmd.cc",
@@ -302,7 +300,6 @@
     "src/base/file_utils.cc",
     "src/base/metatrace.cc",
     "src/base/page_allocator.cc",
-    "src/base/sock_utils.cc",
     "src/base/string_splitter.cc",
     "src/base/string_utils.cc",
     "src/base/temp_file.cc",
@@ -311,6 +308,7 @@
     "src/base/test/vm_test_utils.cc",
     "src/base/thread_checker.cc",
     "src/base/time.cc",
+    "src/base/unix_socket.cc",
     "src/base/unix_task_runner.cc",
     "src/base/virtual_destructors.cc",
     "src/base/watchdog_posix.cc",
@@ -319,7 +317,6 @@
     "src/ipc/deferred.cc",
     "src/ipc/host_impl.cc",
     "src/ipc/service_proxy.cc",
-    "src/ipc/unix_socket.cc",
     "src/ipc/virtual_destructors.cc",
     "src/protozero/message.cc",
     "src/protozero/message_handle.cc",
@@ -3618,12 +3615,12 @@
     "src/base/file_utils.cc",
     "src/base/metatrace.cc",
     "src/base/page_allocator.cc",
-    "src/base/sock_utils.cc",
     "src/base/string_splitter.cc",
     "src/base/string_utils.cc",
     "src/base/temp_file.cc",
     "src/base/thread_checker.cc",
     "src/base/time.cc",
+    "src/base/unix_socket.cc",
     "src/base/unix_task_runner.cc",
     "src/base/virtual_destructors.cc",
     "src/base/watchdog_posix.cc",
@@ -3632,7 +3629,6 @@
     "src/ipc/deferred.cc",
     "src/ipc/host_impl.cc",
     "src/ipc/service_proxy.cc",
-    "src/ipc/unix_socket.cc",
     "src/ipc/virtual_destructors.cc",
     "src/protozero/message.cc",
     "src/protozero/message_handle.cc",
@@ -3809,7 +3805,6 @@
     "src/base/page_allocator.cc",
     "src/base/page_allocator_unittest.cc",
     "src/base/scoped_file_unittest.cc",
-    "src/base/sock_utils.cc",
     "src/base/string_splitter.cc",
     "src/base/string_splitter_unittest.cc",
     "src/base/string_utils.cc",
@@ -3825,6 +3820,8 @@
     "src/base/thread_checker_unittest.cc",
     "src/base/time.cc",
     "src/base/time_unittest.cc",
+    "src/base/unix_socket.cc",
+    "src/base/unix_socket_unittest.cc",
     "src/base/unix_task_runner.cc",
     "src/base/utils_unittest.cc",
     "src/base/virtual_destructors.cc",
@@ -3841,8 +3838,6 @@
     "src/ipc/host_impl_unittest.cc",
     "src/ipc/service_proxy.cc",
     "src/ipc/test/ipc_integrationtest.cc",
-    "src/ipc/unix_socket.cc",
-    "src/ipc/unix_socket_unittest.cc",
     "src/ipc/virtual_destructors.cc",
     "src/perfetto_cmd/perfetto_cmd.cc",
     "src/perfetto_cmd/rate_limiter.cc",
diff --git a/include/perfetto/base/BUILD.gn b/include/perfetto/base/BUILD.gn
index ea5fa38..10da3d0 100644
--- a/include/perfetto/base/BUILD.gn
+++ b/include/perfetto/base/BUILD.gn
@@ -12,6 +12,8 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+import("../../../gn/perfetto.gni")
+
 source_set("base") {
   sources = [
     "build_config.h",
@@ -39,4 +41,7 @@
   if (is_android) {
     sources += [ "android_task_runner.h" ]
   }
+  if (!build_with_chromium) {
+    sources += [ "unix_socket.h" ]
+  }
 }
diff --git a/include/perfetto/base/sock_utils.h b/include/perfetto/base/sock_utils.h
deleted file mode 100644
index 8f3a8b3..0000000
--- a/include/perfetto/base/sock_utils.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2018 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.
- */
-
-#ifndef INCLUDE_PERFETTO_BASE_SOCK_UTILS_H_
-#define INCLUDE_PERFETTO_BASE_SOCK_UTILS_H_
-
-#include "perfetto/base/scoped_file.h"
-
-#include <sys/socket.h>
-#include <sys/un.h>
-
-namespace perfetto {
-namespace base {
-
-ssize_t Send(int fd,
-             const void* msg,
-             size_t len,
-             const int* send_fds,
-             size_t num_fds);
-
-ssize_t Receive(int fd,
-                void* msg,
-                size_t len,
-                base::ScopedFile* fd_vec,
-                size_t max_files);
-
-bool MakeSockAddr(const std::string& socket_name,
-                  sockaddr_un* addr,
-                  socklen_t* addr_size);
-
-base::ScopedFile CreateSocket();
-
-}  // namespace base
-}  // namespace perfetto
-
-#endif  // INCLUDE_PERFETTO_BASE_SOCK_UTILS_H_
diff --git a/src/ipc/unix_socket.h b/include/perfetto/base/unix_socket.h
similarity index 92%
rename from src/ipc/unix_socket.h
rename to include/perfetto/base/unix_socket.h
index 32839d3..7daf5a2 100644
--- a/src/ipc/unix_socket.h
+++ b/include/perfetto/base/unix_socket.h
@@ -14,8 +14,8 @@
  * limitations under the License.
  */
 
-#ifndef SRC_IPC_UNIX_SOCKET_H_
-#define SRC_IPC_UNIX_SOCKET_H_
+#ifndef INCLUDE_PERFETTO_BASE_UNIX_SOCKET_H_
+#define INCLUDE_PERFETTO_BASE_UNIX_SOCKET_H_
 
 #include <stdint.h>
 #include <sys/types.h>
@@ -25,16 +25,34 @@
 
 #include "perfetto/base/logging.h"
 #include "perfetto/base/scoped_file.h"
+#include "perfetto/base/utils.h"
 #include "perfetto/base/weak_ptr.h"
-#include "perfetto/ipc/basic_types.h"
+
+#include <sys/socket.h>
+#include <sys/un.h>
 
 namespace perfetto {
-
 namespace base {
-class TaskRunner;
-}  // namespace base.
 
-namespace ipc {
+class TaskRunner;
+
+ssize_t SockSend(int fd,
+                 const void* msg,
+                 size_t len,
+                 const int* send_fds,
+                 size_t num_fds);
+
+ssize_t SockReceive(int fd,
+                    void* msg,
+                    size_t len,
+                    base::ScopedFile* fd_vec,
+                    size_t max_files);
+
+bool MakeSockAddr(const std::string& socket_name,
+                  sockaddr_un* addr,
+                  socklen_t* addr_size);
+
+base::ScopedFile CreateSocket();
 
 // A non-blocking UNIX domain socket in SOCK_STREAM mode. Allows also to
 // transfer file descriptors. None of the methods in this class are blocking.
@@ -234,7 +252,7 @@
   base::WeakPtrFactory<UnixSocket> weak_ptr_factory_;
 };
 
-}  // namespace ipc
+}  // namespace base
 }  // namespace perfetto
 
-#endif  // SRC_IPC_UNIX_SOCKET_H_
+#endif  // INCLUDE_PERFETTO_BASE_UNIX_SOCKET_H_
diff --git a/include/perfetto/base/utils.h b/include/perfetto/base/utils.h
index 9b18214..4d2f439 100644
--- a/include/perfetto/base/utils.h
+++ b/include/perfetto/base/utils.h
@@ -22,6 +22,9 @@
 #include <errno.h>
 #include <stddef.h>
 #include <stdlib.h>
+#if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+#include <sys/types.h>
+#endif
 
 #define PERFETTO_EINTR(x)                                   \
   ({                                                        \
@@ -61,6 +64,11 @@
 namespace perfetto {
 namespace base {
 
+#if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+constexpr uid_t kInvalidUid = static_cast<uid_t>(-1);
+constexpr pid_t kInvalidPid = static_cast<pid_t>(-1);
+#endif
+
 constexpr size_t kPageSize = 4096;
 constexpr size_t kMaxCpus = 128;
 
diff --git a/src/base/BUILD.gn b/src/base/BUILD.gn
index 68939a9..019cd7b 100644
--- a/src/base/BUILD.gn
+++ b/src/base/BUILD.gn
@@ -88,13 +88,13 @@
 
 if (!build_with_chromium) {
   # This cannot be in :base as it does not build on WASM.
-  source_set("sock_utils") {
+  source_set("unix_socket") {
     deps = [
       "../../gn:default_deps",
       "../../include/perfetto/base",
     ]
     sources = [
-      "sock_utils.cc",
+      "unix_socket.cc",
     ]
   }
 }
@@ -153,7 +153,10 @@
       "utils_unittest.cc",
     ]
   }
-  if (!build_with_chromium && (is_linux || is_android)) {
-    sources += [ "watchdog_unittest.cc" ]
+  if (!build_with_chromium) {
+    sources += [ "unix_socket_unittest.cc" ]
+    if (is_linux || is_android) {
+      sources += [ "watchdog_unittest.cc" ]
+    }
   }
 }
diff --git a/src/base/sock_utils.cc b/src/base/sock_utils.cc
deleted file mode 100644
index bbe00fd..0000000
--- a/src/base/sock_utils.cc
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * Copyright (C) 2018 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 "perfetto/base/sock_utils.h"
-
-#include <sys/socket.h>
-#include <sys/un.h>
-
-namespace perfetto {
-namespace base {
-namespace {
-// MSG_NOSIGNAL is not supported on Mac OS X, but in that case the socket is
-// created with SO_NOSIGPIPE (See InitializeSocket()).
-#if PERFETTO_BUILDFLAG(PERFETTO_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 PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
-using CBufLenType = size_t;
-#else
-using CBufLenType = socklen_t;
-#endif
-}
-
-// The CMSG_* macros use NULL instead of nullptr.
-#pragma GCC diagnostic push
-#if !PERFETTO_BUILDFLAG(PERFETTO_OS_MACOSX)
-#pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant"
-#endif
-
-ssize_t Send(int fd,
-             const void* msg,
-             size_t len,
-             const int* send_fds,
-             size_t num_fds) {
-  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 (num_fds > 0) {
-    const CBufLenType control_buf_len =
-        static_cast<CBufLenType>(CMSG_SPACE(num_fds * 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 = static_cast<CBufLenType>(CMSG_LEN(num_fds * sizeof(int)));
-    memcpy(CMSG_DATA(cmsg), send_fds, num_fds * sizeof(int));
-    msg_hdr.msg_controllen = cmsg->cmsg_len;
-  }
-
-  return PERFETTO_EINTR(sendmsg(fd, &msg_hdr, kNoSigPipe));
-}
-
-ssize_t Receive(int fd,
-                void* msg,
-                size_t len,
-                base::ScopedFile* fd_vec,
-                size_t max_files) {
-  msghdr msg_hdr = {};
-  iovec iov = {msg, len};
-  msg_hdr.msg_iov = &iov;
-  msg_hdr.msg_iovlen = 1;
-  alignas(cmsghdr) char control_buf[256];
-
-  if (max_files > 0) {
-    msg_hdr.msg_control = control_buf;
-    msg_hdr.msg_controllen =
-        static_cast<CBufLenType>(CMSG_SPACE(max_files * 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) {
-    return sz;
-  }
-  PERFETTO_CHECK(static_cast<size_t>(sz) <= len);
-
-  int* fds = nullptr;
-  uint32_t fds_len = 0;
-
-  if (max_files > 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_CHECK(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]);
-    errno = EMSGSIZE;
-    return -1;
-  }
-
-  for (size_t i = 0; fds && i < fds_len; ++i) {
-    if (i < max_files)
-      fd_vec[i].reset(fds[i]);
-    else
-      close(fds[i]);
-  }
-
-  return sz;
-}
-
-#pragma GCC diagnostic pop
-
-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;
-}
-
-base::ScopedFile CreateSocket() {
-  return base::ScopedFile(socket(AF_UNIX, SOCK_STREAM, 0));
-}
-
-}  // namespace base
-}  // namespace perfetto
diff --git a/src/ipc/unix_socket.cc b/src/base/unix_socket.cc
similarity index 68%
rename from src/ipc/unix_socket.cc
rename to src/base/unix_socket.cc
index 3f49b8d..e3ed5f2 100644
--- a/src/ipc/unix_socket.cc
+++ b/src/base/unix_socket.cc
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#include "src/ipc/unix_socket.h"
+#include "perfetto/base/unix_socket.h"
 
 #include <errno.h>
 #include <fcntl.h>
@@ -31,7 +31,6 @@
 
 #include "perfetto/base/build_config.h"
 #include "perfetto/base/logging.h"
-#include "perfetto/base/sock_utils.h"
 #include "perfetto/base/task_runner.h"
 #include "perfetto/base/utils.h"
 
@@ -40,25 +39,157 @@
 #endif
 
 namespace perfetto {
-namespace ipc {
+namespace base {
+
+namespace {
+// MSG_NOSIGNAL is not supported on Mac OS X, but in that case the socket is
+// created with SO_NOSIGPIPE (See InitializeSocket()).
+#if PERFETTO_BUILDFLAG(PERFETTO_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 PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+using CBufLenType = size_t;
+#else
+using CBufLenType = socklen_t;
+#endif
+}
+
+// The CMSG_* macros use NULL instead of nullptr.
+#pragma GCC diagnostic push
+#if !PERFETTO_BUILDFLAG(PERFETTO_OS_MACOSX)
+#pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant"
+#endif
+
+ssize_t SockSend(int fd,
+                 const void* msg,
+                 size_t len,
+                 const int* send_fds,
+                 size_t num_fds) {
+  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 (num_fds > 0) {
+    const CBufLenType control_buf_len =
+        static_cast<CBufLenType>(CMSG_SPACE(num_fds * 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 = static_cast<CBufLenType>(CMSG_LEN(num_fds * sizeof(int)));
+    memcpy(CMSG_DATA(cmsg), send_fds, num_fds * sizeof(int));
+    msg_hdr.msg_controllen = cmsg->cmsg_len;
+  }
+
+  return PERFETTO_EINTR(sendmsg(fd, &msg_hdr, kNoSigPipe));
+}
+
+ssize_t SockReceive(int fd,
+                    void* msg,
+                    size_t len,
+                    ScopedFile* fd_vec,
+                    size_t max_files) {
+  msghdr msg_hdr = {};
+  iovec iov = {msg, len};
+  msg_hdr.msg_iov = &iov;
+  msg_hdr.msg_iovlen = 1;
+  alignas(cmsghdr) char control_buf[256];
+
+  if (max_files > 0) {
+    msg_hdr.msg_control = control_buf;
+    msg_hdr.msg_controllen =
+        static_cast<CBufLenType>(CMSG_SPACE(max_files * 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) {
+    return sz;
+  }
+  PERFETTO_CHECK(static_cast<size_t>(sz) <= len);
+
+  int* fds = nullptr;
+  uint32_t fds_len = 0;
+
+  if (max_files > 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_CHECK(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]);
+    errno = EMSGSIZE;
+    return -1;
+  }
+
+  for (size_t i = 0; fds && i < fds_len; ++i) {
+    if (i < max_files)
+      fd_vec[i].reset(fds[i]);
+    else
+      close(fds[i]);
+  }
+
+  return sz;
+}
+
+#pragma GCC diagnostic pop
+
+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;
+}
+
+ScopedFile CreateSocket() {
+  return ScopedFile(socket(AF_UNIX, SOCK_STREAM, 0));
+}
 
 // TODO(primiano): Add ThreadChecker to methods of this class.
 
 // static
-base::ScopedFile UnixSocket::CreateAndBind(const std::string& socket_name) {
-  base::ScopedFile fd = base::CreateSocket();
+ScopedFile UnixSocket::CreateAndBind(const std::string& socket_name) {
+  ScopedFile fd = CreateSocket();
   if (!fd)
     return fd;
 
   sockaddr_un addr;
   socklen_t addr_size;
-  if (!base::MakeSockAddr(socket_name, &addr, &addr_size)) {
-    return base::ScopedFile();
+  if (!MakeSockAddr(socket_name, &addr, &addr_size)) {
+    return ScopedFile();
   }
 
   if (bind(*fd, reinterpret_cast<sockaddr*>(&addr), addr_size)) {
     PERFETTO_DPLOG("bind()");
-    return base::ScopedFile();
+    return ScopedFile();
   }
 
   return fd;
@@ -67,15 +198,15 @@
 // static
 std::unique_ptr<UnixSocket> UnixSocket::Listen(const std::string& socket_name,
                                                EventListener* event_listener,
-                                               base::TaskRunner* task_runner) {
+                                               TaskRunner* task_runner) {
   // Forward the call to the Listen() overload below.
   return Listen(CreateAndBind(socket_name), event_listener, task_runner);
 }
 
 // static
-std::unique_ptr<UnixSocket> UnixSocket::Listen(base::ScopedFile socket_fd,
+std::unique_ptr<UnixSocket> UnixSocket::Listen(ScopedFile socket_fd,
                                                EventListener* event_listener,
-                                               base::TaskRunner* task_runner) {
+                                               TaskRunner* task_runner) {
   std::unique_ptr<UnixSocket> sock(new UnixSocket(
       event_listener, task_runner, std::move(socket_fd), State::kListening));
   return sock;
@@ -84,22 +215,21 @@
 // static
 std::unique_ptr<UnixSocket> UnixSocket::Connect(const std::string& socket_name,
                                                 EventListener* event_listener,
-                                                base::TaskRunner* task_runner) {
+                                                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::UnixSocket(EventListener* event_listener, TaskRunner* task_runner)
     : UnixSocket(event_listener,
                  task_runner,
-                 base::ScopedFile(),
+                 ScopedFile(),
                  State::kDisconnected) {}
 
 UnixSocket::UnixSocket(EventListener* event_listener,
-                       base::TaskRunner* task_runner,
-                       base::ScopedFile adopt_fd,
+                       TaskRunner* task_runner,
+                       ScopedFile adopt_fd,
                        State adopt_state)
     : event_listener_(event_listener),
       task_runner_(task_runner),
@@ -108,7 +238,7 @@
   if (adopt_state == State::kDisconnected) {
     // We get here from the default ctor().
     PERFETTO_DCHECK(!adopt_fd);
-    fd_ = base::CreateSocket();
+    fd_ = CreateSocket();
     if (!fd_) {
       last_error_ = errno;
       return;
@@ -153,7 +283,7 @@
 
   SetBlockingIO(false);
 
-  base::WeakPtr<UnixSocket> weak_ptr = weak_ptr_factory_.GetWeakPtr();
+  WeakPtr<UnixSocket> weak_ptr = weak_ptr_factory_.GetWeakPtr();
   task_runner_->AddFileDescriptorWatch(*fd_, [weak_ptr]() {
     if (weak_ptr)
       weak_ptr->OnEvent();
@@ -175,7 +305,7 @@
 
   sockaddr_un addr;
   socklen_t addr_size;
-  if (!base::MakeSockAddr(socket_name, &addr, &addr_size)) {
+  if (!MakeSockAddr(socket_name, &addr, &addr_size)) {
     last_error_ = errno;
     return NotifyConnectionState(false);
   }
@@ -197,7 +327,7 @@
   // 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();
+    WeakPtr<UnixSocket> weak_ptr = weak_ptr_factory_.GetWeakPtr();
     task_runner_->PostTask([weak_ptr]() {
       if (weak_ptr)
         weak_ptr->OnEvent();
@@ -255,7 +385,7 @@
     for (;;) {
       sockaddr_un cli_addr = {};
       socklen_t size = sizeof(cli_addr);
-      base::ScopedFile new_fd(PERFETTO_EINTR(
+      ScopedFile new_fd(PERFETTO_EINTR(
           accept(*fd_, reinterpret_cast<sockaddr*>(&cli_addr), &size)));
       if (!new_fd)
         return;
@@ -291,7 +421,7 @@
 
   if (blocking_mode == BlockingMode::kBlocking)
     SetBlockingIO(true);
-  const ssize_t sz = base::Send(*fd_, msg, len, send_fds, num_fds);
+  const ssize_t sz = SockSend(*fd_, msg, len, send_fds, num_fds);
   if (blocking_mode == BlockingMode::kBlocking)
     SetBlockingIO(false);
 
@@ -321,7 +451,7 @@
 }
 
 void UnixSocket::Shutdown(bool notify) {
-  base::WeakPtr<UnixSocket> weak_ptr = weak_ptr_factory_.GetWeakPtr();
+  WeakPtr<UnixSocket> weak_ptr = weak_ptr_factory_.GetWeakPtr();
   if (notify) {
     if (state_ == State::kConnected) {
       task_runner_->PostTask([weak_ptr]() {
@@ -350,14 +480,14 @@
 
 size_t UnixSocket::Receive(void* msg,
                            size_t len,
-                           base::ScopedFile* fd_vec,
+                           ScopedFile* fd_vec,
                            size_t max_files) {
   if (state_ != State::kConnected) {
     last_error_ = ENOTCONN;
     return 0;
   }
 
-  const ssize_t sz = base::Receive(*fd_, msg, len, fd_vec, max_files);
+  const ssize_t sz = SockReceive(*fd_, msg, len, fd_vec, max_files);
   if (sz < 0 && (errno == EAGAIN || errno == EWOULDBLOCK)) {
     last_error_ = EAGAIN;
     return 0;
@@ -383,7 +513,7 @@
   if (!success)
     Shutdown(false);
 
-  base::WeakPtr<UnixSocket> weak_ptr = weak_ptr_factory_.GetWeakPtr();
+  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);
@@ -409,5 +539,5 @@
 void UnixSocket::EventListener::OnDisconnect(UnixSocket*) {}
 void UnixSocket::EventListener::OnDataAvailable(UnixSocket*) {}
 
-}  // namespace ipc
+}  // namespace base
 }  // namespace perfetto
diff --git a/src/ipc/unix_socket_unittest.cc b/src/base/unix_socket_unittest.cc
similarity index 97%
rename from src/ipc/unix_socket_unittest.cc
rename to src/base/unix_socket_unittest.cc
index 024072f..5cdd6ab 100644
--- a/src/ipc/unix_socket_unittest.cc
+++ b/src/base/unix_socket_unittest.cc
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#include "src/ipc/unix_socket.h"
+#include "perfetto/base/unix_socket.h"
 
 #include <sys/mman.h>
 
@@ -31,7 +31,7 @@
 #include "src/ipc/test/test_socket.h"
 
 namespace perfetto {
-namespace ipc {
+namespace base {
 namespace {
 
 using ::testing::_;
@@ -74,7 +74,7 @@
   void SetUp() override { DESTROY_TEST_SOCK(kSocketName); }
   void TearDown() override { DESTROY_TEST_SOCK(kSocketName); }
 
-  base::TestTaskRunner task_runner_;
+  TestTaskRunner task_runner_;
   MockEventListener event_listener_;
 };
 
@@ -199,15 +199,15 @@
   ASSERT_TRUE(srv_conn);
   ASSERT_TRUE(cli->is_connected());
 
-  base::ScopedFile null_fd(open("/dev/null", O_RDONLY));
-  base::ScopedFile zero_fd(open("/dev/zero", O_RDONLY));
+  ScopedFile null_fd(open("/dev/null", O_RDONLY));
+  ScopedFile zero_fd(open("/dev/zero", O_RDONLY));
 
   auto cli_did_recv = task_runner_.CreateCheckpoint("cli_did_recv");
   EXPECT_CALL(event_listener_, OnDataAvailable(cli.get()))
       .WillRepeatedly(Invoke([cli_did_recv](UnixSocket* s) {
-        base::ScopedFile fd_buf[3];
+        ScopedFile fd_buf[3];
         char buf[sizeof(cli_str)];
-        if (!s->Receive(buf, sizeof(buf), fd_buf, base::ArraySize(fd_buf)))
+        if (!s->Receive(buf, sizeof(buf), fd_buf, ArraySize(fd_buf)))
           return;
         ASSERT_STREQ(srv_str, buf);
         ASSERT_NE(*fd_buf[0], -1);
@@ -225,9 +225,9 @@
   auto srv_did_recv = task_runner_.CreateCheckpoint("srv_did_recv");
   EXPECT_CALL(event_listener_, OnDataAvailable(srv_conn.get()))
       .WillRepeatedly(Invoke([srv_did_recv](UnixSocket* s) {
-        base::ScopedFile fd_buf[3];
+        ScopedFile fd_buf[3];
         char buf[sizeof(srv_str)];
-        if (!s->Receive(buf, sizeof(buf), fd_buf, base::ArraySize(fd_buf)))
+        if (!s->Receive(buf, sizeof(buf), fd_buf, ArraySize(fd_buf)))
           return;
         ASSERT_STREQ(cli_str, buf);
         ASSERT_NE(*fd_buf[0], -1);
@@ -339,7 +339,7 @@
 
   if (pid == 0) {
     // Child process.
-    base::TempFile scoped_tmp = base::TempFile::CreateUnlinked();
+    TempFile scoped_tmp = TempFile::CreateUnlinked();
     int tmp_fd = scoped_tmp.fd();
     ASSERT_FALSE(ftruncate(tmp_fd, kTmpSize));
     char* mem = reinterpret_cast<char*>(
@@ -379,7 +379,7 @@
     EXPECT_CALL(event_listener_, OnDataAvailable(cli.get()))
         .WillOnce(Invoke([checkpoint](UnixSocket* s) {
           char msg[32];
-          base::ScopedFile fd;
+          ScopedFile fd;
           ASSERT_EQ(5u, s->Receive(msg, sizeof(msg), &fd));
           ASSERT_STREQ("txfd", msg);
           ASSERT_TRUE(fd);
@@ -405,7 +405,7 @@
 
 constexpr size_t kAtomicWrites_FrameSize = 1123;
 bool AtomicWrites_SendAttempt(UnixSocket* s,
-                              base::TaskRunner* task_runner,
+                              TaskRunner* task_runner,
                               int num_frame) {
   char buf[kAtomicWrites_FrameSize];
   memset(buf, static_cast<char>(num_frame), sizeof(buf));
@@ -547,7 +547,7 @@
 
   // Perform the blocking send form another thread.
   std::thread tx_thread([] {
-    base::TestTaskRunner tx_task_runner;
+    TestTaskRunner tx_task_runner;
     MockEventListener tx_events;
     auto cli = UnixSocket::Connect(kSocketName, &tx_events, &tx_task_runner);
 
@@ -594,7 +594,7 @@
 
   // Perform the blocking send form another thread.
   std::thread tx_thread([] {
-    base::TestTaskRunner tx_task_runner;
+    TestTaskRunner tx_task_runner;
     MockEventListener tx_events;
     auto cli = UnixSocket::Connect(kSocketName, &tx_events, &tx_task_runner);
 
@@ -634,5 +634,5 @@
 // verify that no spurious EventListener callback is received.
 
 }  // namespace
-}  // namespace ipc
+}  // namespace base
 }  // namespace perfetto
diff --git a/src/ipc/BUILD.gn b/src/ipc/BUILD.gn
index 4dffcf7..8a7e4e1 100644
--- a/src/ipc/BUILD.gn
+++ b/src/ipc/BUILD.gn
@@ -30,12 +30,12 @@
   public_configs = [ "../../gn:default_config" ]
   public_deps = [
     "../../include/perfetto/ipc",
+    "../base:unix_socket",
   ]
   deps = [
     ":wire_protocol",
     "../../gn:default_deps",
     "../base",
-    "../base:sock_utils",
   ]
   sources = [
     "buffered_frame_deserializer.cc",
@@ -44,8 +44,6 @@
     "host_impl.cc",
     "host_impl.h",
     "service_proxy.cc",
-    "unix_socket.cc",
-    "unix_socket.h",
     "virtual_destructors.cc",
   ]
 }
@@ -78,7 +76,6 @@
     "deferred_unittest.cc",
     "host_impl_unittest.cc",
     "test/ipc_integrationtest.cc",
-    "unix_socket_unittest.cc",
   ]
 }
 
diff --git a/src/ipc/client_impl.cc b/src/ipc/client_impl.cc
index cc58bf5..d648df5 100644
--- a/src/ipc/client_impl.cc
+++ b/src/ipc/client_impl.cc
@@ -44,13 +44,14 @@
 ClientImpl::ClientImpl(const char* socket_name, base::TaskRunner* task_runner)
     : task_runner_(task_runner), weak_ptr_factory_(this) {
   GOOGLE_PROTOBUF_VERIFY_VERSION;
-  sock_ = UnixSocket::Connect(socket_name, this, task_runner);
+  sock_ = base::UnixSocket::Connect(socket_name, this, task_runner);
 }
 
 ClientImpl::~ClientImpl() {
   // Ensure we are not destroyed in the middle of invoking a reply.
   PERFETTO_DCHECK(!invoking_method_reply_);
-  OnDisconnect(nullptr);  // The UnixSocket* ptr is not used in OnDisconnect().
+  OnDisconnect(
+      nullptr);  // The base::UnixSocket* ptr is not used in OnDisconnect().
 }
 
 void ClientImpl::BindService(base::WeakPtr<ServiceProxy> service_proxy) {
@@ -122,12 +123,12 @@
   // the send and PostTask the reply later? Right now we are making Send()
   // blocking as a workaround. Propagate bakpressure to the caller instead.
   bool res = sock_->Send(buf.data(), buf.size(), fd,
-                         UnixSocket::BlockingMode::kBlocking);
+                         base::UnixSocket::BlockingMode::kBlocking);
   PERFETTO_CHECK(res || !sock_->is_connected());
   return res;
 }
 
-void ClientImpl::OnConnect(UnixSocket*, bool connected) {
+void ClientImpl::OnConnect(base::UnixSocket*, bool connected) {
   // Drain the BindService() calls that were queued before establishig the
   // connection with the host.
   for (base::WeakPtr<ServiceProxy>& service_proxy : queued_bindings_) {
@@ -140,7 +141,7 @@
   queued_bindings_.clear();
 }
 
-void ClientImpl::OnDisconnect(UnixSocket*) {
+void ClientImpl::OnDisconnect(base::UnixSocket*) {
   for (auto it : service_bindings_) {
     base::WeakPtr<ServiceProxy>& service_proxy = it.second;
     task_runner_->PostTask([service_proxy] {
@@ -152,7 +153,7 @@
   queued_bindings_.clear();
 }
 
-void ClientImpl::OnDataAvailable(UnixSocket*) {
+void ClientImpl::OnDataAvailable(base::UnixSocket*) {
   size_t rsize;
   do {
     auto buf = frame_deserializer_.BeginReceive();
diff --git a/src/ipc/client_impl.h b/src/ipc/client_impl.h
index 2402d17..d53c05b 100644
--- a/src/ipc/client_impl.h
+++ b/src/ipc/client_impl.h
@@ -19,9 +19,9 @@
 
 #include "perfetto/base/scoped_file.h"
 #include "perfetto/base/task_runner.h"
+#include "perfetto/base/unix_socket.h"
 #include "perfetto/ipc/client.h"
 #include "src/ipc/buffered_frame_deserializer.h"
-#include "src/ipc/unix_socket.h"
 
 #include "src/ipc/wire_protocol.pb.h"
 
@@ -39,7 +39,7 @@
 
 class ServiceDescriptor;
 
-class ClientImpl : public Client, public UnixSocket::EventListener {
+class ClientImpl : public Client, public base::UnixSocket::EventListener {
  public:
   ClientImpl(const char* socket_name, base::TaskRunner*);
   ~ClientImpl() override;
@@ -49,10 +49,10 @@
   void UnbindService(ServiceID) override;
   base::ScopedFile TakeReceivedFD() override;
 
-  // UnixSocket::EventListener implementation.
-  void OnConnect(UnixSocket*, bool connected) override;
-  void OnDisconnect(UnixSocket*) override;
-  void OnDataAvailable(UnixSocket*) override;
+  // base::UnixSocket::EventListener implementation.
+  void OnConnect(base::UnixSocket*, bool connected) override;
+  void OnDisconnect(base::UnixSocket*) override;
+  void OnDataAvailable(base::UnixSocket*) override;
 
   RequestID BeginInvoke(ServiceID,
                         const std::string& method_name,
@@ -82,7 +82,7 @@
   void OnInvokeMethodReply(QueuedRequest, const Frame::InvokeMethodReply&);
 
   bool invoking_method_reply_ = false;
-  std::unique_ptr<UnixSocket> sock_;
+  std::unique_ptr<base::UnixSocket> sock_;
   base::TaskRunner* const task_runner_;
   RequestID last_request_id_ = 0;
   BufferedFrameDeserializer frame_deserializer_;
diff --git a/src/ipc/client_impl_unittest.cc b/src/ipc/client_impl_unittest.cc
index 9922cb8..445e3d0 100644
--- a/src/ipc/client_impl_unittest.cc
+++ b/src/ipc/client_impl_unittest.cc
@@ -24,13 +24,13 @@
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
 #include "perfetto/base/temp_file.h"
+#include "perfetto/base/unix_socket.h"
 #include "perfetto/base/utils.h"
 #include "perfetto/ipc/service_descriptor.h"
 #include "perfetto/ipc/service_proxy.h"
 #include "src/base/test/test_task_runner.h"
 #include "src/ipc/buffered_frame_deserializer.h"
 #include "src/ipc/test/test_socket.h"
-#include "src/ipc/unix_socket.h"
 
 #include "src/ipc/test/client_unittest_messages.pb.h"
 
@@ -78,7 +78,7 @@
 
 // A fake host implementation. Listens on |kSockName| and replies to IPC
 // metohds like a real one.
-class FakeHost : public UnixSocket::EventListener {
+class FakeHost : public base::UnixSocket::EventListener {
  public:
   struct FakeMethod {
     MethodID id;
@@ -103,7 +103,7 @@
 
   explicit FakeHost(base::TaskRunner* task_runner) {
     DESTROY_TEST_SOCK(kSockName);
-    listening_sock = UnixSocket::Listen(kSockName, this, task_runner);
+    listening_sock = base::UnixSocket::Listen(kSockName, this, task_runner);
     EXPECT_TRUE(listening_sock->is_listening());
   }
   ~FakeHost() override { DESTROY_TEST_SOCK(kSockName); }
@@ -117,15 +117,15 @@
     return svc;
   }
 
-  // UnixSocket::EventListener implementation.
+  // base::UnixSocket::EventListener implementation.
   void OnNewIncomingConnection(
-      UnixSocket*,
-      std::unique_ptr<UnixSocket> new_connection) override {
+      base::UnixSocket*,
+      std::unique_ptr<base::UnixSocket> new_connection) override {
     ASSERT_FALSE(client_sock);
     client_sock = std::move(new_connection);
   }
 
-  void OnDataAvailable(UnixSocket* sock) override {
+  void OnDataAvailable(base::UnixSocket* sock) override {
     if (sock != client_sock.get())
       return;
     auto buf = frame_deserializer.BeginReceive();
@@ -187,8 +187,8 @@
   }
 
   BufferedFrameDeserializer frame_deserializer;
-  std::unique_ptr<UnixSocket> listening_sock;
-  std::unique_ptr<UnixSocket> client_sock;
+  std::unique_ptr<base::UnixSocket> listening_sock;
+  std::unique_ptr<base::UnixSocket> client_sock;
   std::map<std::string, std::unique_ptr<FakeService>> services;
   ServiceID last_service_id = 0;
   int next_reply_fd = -1;
diff --git a/src/ipc/host_impl.cc b/src/ipc/host_impl.cc
index 2e9fe79..02d0a68 100644
--- a/src/ipc/host_impl.cc
+++ b/src/ipc/host_impl.cc
@@ -56,14 +56,14 @@
     : task_runner_(task_runner), weak_ptr_factory_(this) {
   GOOGLE_PROTOBUF_VERIFY_VERSION;
   PERFETTO_DCHECK_THREAD(thread_checker_);
-  sock_ = UnixSocket::Listen(std::move(socket_fd), this, task_runner_);
+  sock_ = base::UnixSocket::Listen(std::move(socket_fd), this, task_runner_);
 }
 
 HostImpl::HostImpl(const char* socket_name, base::TaskRunner* task_runner)
     : task_runner_(task_runner), weak_ptr_factory_(this) {
   GOOGLE_PROTOBUF_VERIFY_VERSION;
   PERFETTO_DCHECK_THREAD(thread_checker_);
-  sock_ = UnixSocket::Listen(socket_name, this, task_runner_);
+  sock_ = base::UnixSocket::Listen(socket_name, this, task_runner_);
 }
 
 HostImpl::~HostImpl() = default;
@@ -81,8 +81,9 @@
   return true;
 }
 
-void HostImpl::OnNewIncomingConnection(UnixSocket*,
-                                       std::unique_ptr<UnixSocket> new_conn) {
+void HostImpl::OnNewIncomingConnection(
+    base::UnixSocket*,
+    std::unique_ptr<base::UnixSocket> new_conn) {
   PERFETTO_DCHECK_THREAD(thread_checker_);
   std::unique_ptr<ClientConnection> client(new ClientConnection());
   ClientID client_id = ++last_client_id_;
@@ -92,7 +93,7 @@
   clients_[client_id] = std::move(client);
 }
 
-void HostImpl::OnDataAvailable(UnixSocket* sock) {
+void HostImpl::OnDataAvailable(base::UnixSocket* sock) {
   PERFETTO_DCHECK_THREAD(thread_checker_);
   auto it = clients_by_socket_.find(sock);
   if (it == clients_by_socket_.end())
@@ -237,11 +238,11 @@
   // the send and PostTask the reply later? Right now we are making Send()
   // blocking as a workaround. Propagate bakpressure to the caller instead.
   bool res = client->sock->Send(buf.data(), buf.size(), fd,
-                                UnixSocket::BlockingMode::kBlocking);
+                                base::UnixSocket::BlockingMode::kBlocking);
   PERFETTO_CHECK(res || !client->sock->is_connected());
 }
 
-void HostImpl::OnDisconnect(UnixSocket* sock) {
+void HostImpl::OnDisconnect(base::UnixSocket* sock) {
   PERFETTO_DCHECK_THREAD(thread_checker_);
   auto it = clients_by_socket_.find(sock);
   if (it == clients_by_socket_.end())
diff --git a/src/ipc/host_impl.h b/src/ipc/host_impl.h
index bef1d9e..5a062d4 100644
--- a/src/ipc/host_impl.h
+++ b/src/ipc/host_impl.h
@@ -24,17 +24,17 @@
 
 #include "perfetto/base/task_runner.h"
 #include "perfetto/base/thread_checker.h"
+#include "perfetto/base/unix_socket.h"
 #include "perfetto/ipc/deferred.h"
 #include "perfetto/ipc/host.h"
 #include "src/ipc/buffered_frame_deserializer.h"
-#include "src/ipc/unix_socket.h"
 
 namespace perfetto {
 namespace ipc {
 
 class Frame;
 
-class HostImpl : public Host, public UnixSocket::EventListener {
+class HostImpl : public Host, public base::UnixSocket::EventListener {
  public:
   HostImpl(const char* socket_name, base::TaskRunner*);
   HostImpl(base::ScopedFile socket_fd, base::TaskRunner*);
@@ -43,20 +43,20 @@
   // Host implementation.
   bool ExposeService(std::unique_ptr<Service>) override;
 
-  // UnixSocket::EventListener implementation.
-  void OnNewIncomingConnection(UnixSocket*,
-                               std::unique_ptr<UnixSocket>) override;
-  void OnDisconnect(UnixSocket*) override;
-  void OnDataAvailable(UnixSocket*) override;
+  // base::UnixSocket::EventListener implementation.
+  void OnNewIncomingConnection(base::UnixSocket*,
+                               std::unique_ptr<base::UnixSocket>) override;
+  void OnDisconnect(base::UnixSocket*) override;
+  void OnDataAvailable(base::UnixSocket*) override;
 
-  const UnixSocket* sock() const { return sock_.get(); }
+  const base::UnixSocket* sock() const { return sock_.get(); }
 
  private:
   // Owns the per-client receive buffer (BufferedFrameDeserializer).
   struct ClientConnection {
     ~ClientConnection();
     ClientID id;
-    std::unique_ptr<UnixSocket> sock;
+    std::unique_ptr<base::UnixSocket> sock;
     BufferedFrameDeserializer frame_deserializer;
     base::ScopedFile received_fd;
   };
@@ -85,9 +85,9 @@
 
   base::TaskRunner* const task_runner_;
   std::map<ServiceID, ExposedService> services_;
-  std::unique_ptr<UnixSocket> sock_;  // The listening socket.
+  std::unique_ptr<base::UnixSocket> sock_;  // The listening socket.
   std::map<ClientID, std::unique_ptr<ClientConnection>> clients_;
-  std::map<UnixSocket*, ClientConnection*> clients_by_socket_;
+  std::map<base::UnixSocket*, ClientConnection*> clients_by_socket_;
   ServiceID last_service_id_ = 0;
   ClientID last_client_id_ = 0;
   base::WeakPtrFactory<HostImpl> weak_ptr_factory_;
diff --git a/src/ipc/host_impl_unittest.cc b/src/ipc/host_impl_unittest.cc
index f48775d..3ff1f99 100644
--- a/src/ipc/host_impl_unittest.cc
+++ b/src/ipc/host_impl_unittest.cc
@@ -22,13 +22,13 @@
 #include "gtest/gtest.h"
 #include "perfetto/base/scoped_file.h"
 #include "perfetto/base/temp_file.h"
+#include "perfetto/base/unix_socket.h"
 #include "perfetto/base/utils.h"
 #include "perfetto/ipc/service.h"
 #include "perfetto/ipc/service_descriptor.h"
 #include "src/base/test/test_task_runner.h"
 #include "src/ipc/buffered_frame_deserializer.h"
 #include "src/ipc/test/test_socket.h"
-#include "src/ipc/unix_socket.h"
 
 #include "src/ipc/test/client_unittest_messages.pb.h"
 #include "src/ipc/wire_protocol.pb.h"
@@ -78,7 +78,7 @@
   ServiceDescriptor descriptor_;
 };
 
-class FakeClient : public UnixSocket::EventListener {
+class FakeClient : public base::UnixSocket::EventListener {
  public:
   MOCK_METHOD0(OnConnect, void());
   MOCK_METHOD0(OnDisconnect, void());
@@ -88,7 +88,7 @@
   MOCK_METHOD0(OnRequestError, void());
 
   explicit FakeClient(base::TaskRunner* task_runner) {
-    sock_ = UnixSocket::Connect(kSockName, this, task_runner);
+    sock_ = base::UnixSocket::Connect(kSockName, this, task_runner);
   }
 
   ~FakeClient() override = default;
@@ -118,15 +118,15 @@
     SendFrame(frame, fd);
   }
 
-  // UnixSocket::EventListener implementation.
-  void OnConnect(UnixSocket*, bool success) override {
+  // base::UnixSocket::EventListener implementation.
+  void OnConnect(base::UnixSocket*, bool success) override {
     ASSERT_TRUE(success);
     OnConnect();
   }
 
-  void OnDisconnect(UnixSocket*) override { OnDisconnect(); }
+  void OnDisconnect(base::UnixSocket*) override { OnDisconnect(); }
 
-  void OnDataAvailable(UnixSocket* sock) override {
+  void OnDataAvailable(base::UnixSocket* sock) override {
     ASSERT_EQ(sock_.get(), sock);
     auto buf = frame_deserializer_.BeginReceive();
     base::ScopedFile fd;
@@ -156,7 +156,7 @@
   }
 
   BufferedFrameDeserializer frame_deserializer_;
-  std::unique_ptr<UnixSocket> sock_;
+  std::unique_ptr<base::UnixSocket> sock_;
   std::map<uint64_t /* request_id */, int /* num_replies_received */> requests_;
   ServiceID last_bound_service_id_;
 };
diff --git a/src/profiling/memory/client.cc b/src/profiling/memory/client.cc
index 86f2063..d00f451 100644
--- a/src/profiling/memory/client.cc
+++ b/src/profiling/memory/client.cc
@@ -35,7 +35,7 @@
 #include <unwindstack/RegsGetLocal.h>
 
 #include "perfetto/base/logging.h"
-#include "perfetto/base/sock_utils.h"
+#include "perfetto/base/unix_socket.h"
 #include "perfetto/base/utils.h"
 #include "src/profiling/memory/wire_protocol.h"
 
@@ -146,7 +146,7 @@
   int fds[2];
   fds[0] = open("/proc/self/maps", O_RDONLY | O_CLOEXEC);
   fds[1] = open("/proc/self/mem", O_RDONLY | O_CLOEXEC);
-  base::Send(*socket_pool_.Borrow(), &size, sizeof(size), fds, 2);
+  base::SockSend(*socket_pool_.Borrow(), &size, sizeof(size), fds, 2);
 }
 
 Client::Client(const std::string& sock_name, size_t conns)
diff --git a/src/profiling/memory/heapprofd_integrationtest.cc b/src/profiling/memory/heapprofd_integrationtest.cc
index c9b6219..1dc10aa 100644
--- a/src/profiling/memory/heapprofd_integrationtest.cc
+++ b/src/profiling/memory/heapprofd_integrationtest.cc
@@ -64,7 +64,7 @@
       },
       &callsites);
 
-  auto sock = ipc::UnixSocket::Listen(kSocketName, &listener, &task_runner);
+  auto sock = base::UnixSocket::Listen(kSocketName, &listener, &task_runner);
   if (!sock->is_listening()) {
     PERFETTO_ELOG("Socket not listening.");
     PERFETTO_CHECK(false);
diff --git a/src/profiling/memory/socket_listener.cc b/src/profiling/memory/socket_listener.cc
index f857a42..1a26e01 100644
--- a/src/profiling/memory/socket_listener.cc
+++ b/src/profiling/memory/socket_listener.cc
@@ -19,18 +19,18 @@
 
 namespace perfetto {
 
-void SocketListener::OnDisconnect(ipc::UnixSocket* self) {
+void SocketListener::OnDisconnect(base::UnixSocket* self) {
   sockets_.erase(self);
 }
 
 void SocketListener::OnNewIncomingConnection(
-    ipc::UnixSocket*,
-    std::unique_ptr<ipc::UnixSocket> new_connection) {
-  ipc::UnixSocket* new_connection_raw = new_connection.get();
+    base::UnixSocket*,
+    std::unique_ptr<base::UnixSocket> new_connection) {
+  base::UnixSocket* new_connection_raw = new_connection.get();
   sockets_.emplace(new_connection_raw, std::move(new_connection));
 }
 
-void SocketListener::OnDataAvailable(ipc::UnixSocket* self) {
+void SocketListener::OnDataAvailable(base::UnixSocket* self) {
   auto it = sockets_.find(self);
   if (it == sockets_.end())
     return;
@@ -92,7 +92,7 @@
   }
 }
 
-void SocketListener::RecordReceived(ipc::UnixSocket* self,
+void SocketListener::RecordReceived(base::UnixSocket* self,
                                     size_t size,
                                     std::unique_ptr<uint8_t[]> buf) {
   auto it = sockets_.find(self);
diff --git a/src/profiling/memory/socket_listener.h b/src/profiling/memory/socket_listener.h
index 8b1609d..6d83d9e 100644
--- a/src/profiling/memory/socket_listener.h
+++ b/src/profiling/memory/socket_listener.h
@@ -17,7 +17,7 @@
 #ifndef SRC_PROFILING_MEMORY_SOCKET_LISTENER_H_
 #define SRC_PROFILING_MEMORY_SOCKET_LISTENER_H_
 
-#include "src/ipc/unix_socket.h"
+#include "perfetto/base/unix_socket.h"
 #include "src/profiling/memory/bookkeeping.h"
 #include "src/profiling/memory/record_reader.h"
 #include "src/profiling/memory/unwinding.h"
@@ -27,22 +27,22 @@
 
 namespace perfetto {
 
-class SocketListener : public ipc::UnixSocket::EventListener {
+class SocketListener : public base::UnixSocket::EventListener {
  public:
   SocketListener(std::function<void(UnwindingRecord)> fn,
                  GlobalCallstackTrie* callsites)
       : callback_function_(std::move(fn)), callsites_(callsites) {}
-  void OnDisconnect(ipc::UnixSocket* self) override;
+  void OnDisconnect(base::UnixSocket* self) override;
   void OnNewIncomingConnection(
-      ipc::UnixSocket* self,
-      std::unique_ptr<ipc::UnixSocket> new_connection) override;
-  void OnDataAvailable(ipc::UnixSocket* self) override;
+      base::UnixSocket* self,
+      std::unique_ptr<base::UnixSocket> new_connection) override;
+  void OnDataAvailable(base::UnixSocket* self) override;
 
  private:
   struct Entry {
-    Entry(std::unique_ptr<ipc::UnixSocket> s) : sock(std::move(s)) {}
+    Entry(std::unique_ptr<base::UnixSocket> s) : sock(std::move(s)) {}
     // Only here for ownership of the object.
-    const std::unique_ptr<ipc::UnixSocket> sock;
+    const std::unique_ptr<base::UnixSocket> sock;
     RecordReader record_reader;
     bool recv_fds = false;
     // The sockets own the metadata for a particular PID. When the last socket
@@ -55,13 +55,13 @@
     std::shared_ptr<ProcessMetadata> process_metadata;
   };
 
-  void RecordReceived(ipc::UnixSocket*, size_t, std::unique_ptr<uint8_t[]>);
+  void RecordReceived(base::UnixSocket*, size_t, std::unique_ptr<uint8_t[]>);
   void InitProcess(Entry* entry,
                    pid_t peer_pid,
                    base::ScopedFile maps_fd,
                    base::ScopedFile mem_fd);
 
-  std::map<ipc::UnixSocket*, Entry> sockets_;
+  std::map<base::UnixSocket*, Entry> sockets_;
   std::map<pid_t, std::weak_ptr<ProcessMetadata>> process_metadata_;
   std::function<void(UnwindingRecord)> callback_function_;
   GlobalCallstackTrie* callsites_;
diff --git a/src/profiling/memory/socket_listener_unittest.cc b/src/profiling/memory/socket_listener_unittest.cc
index 2dd6310..58d5e8f 100644
--- a/src/profiling/memory/socket_listener_unittest.cc
+++ b/src/profiling/memory/socket_listener_unittest.cc
@@ -37,9 +37,9 @@
   void TearDown() override { DESTROY_TEST_SOCK(kSocketName); }
 };
 
-class MockEventListener : public ipc::UnixSocket::EventListener {
+class MockEventListener : public base::UnixSocket::EventListener {
  public:
-  MOCK_METHOD2(OnConnect, void(ipc::UnixSocket*, bool));
+  MOCK_METHOD2(OnConnect, void(base::UnixSocket*, bool));
 };
 
 TEST_F(SocketListenerTest, ReceiveRecord) {
@@ -59,11 +59,11 @@
   EXPECT_CALL(client_listener, OnConnect(_, _))
       .WillOnce(InvokeWithoutArgs(connected));
 
-  std::unique_ptr<ipc::UnixSocket> recv_socket =
-      ipc::UnixSocket::Listen(kSocketName, &listener, &task_runner);
+  std::unique_ptr<base::UnixSocket> recv_socket =
+      base::UnixSocket::Listen(kSocketName, &listener, &task_runner);
 
-  std::unique_ptr<ipc::UnixSocket> client_socket =
-      ipc::UnixSocket::Connect(kSocketName, &client_listener, &task_runner);
+  std::unique_ptr<base::UnixSocket> client_socket =
+      base::UnixSocket::Connect(kSocketName, &client_listener, &task_runner);
 
   task_runner.RunUntilCheckpoint("connected");
   uint64_t size = 1;