diff --git a/base/base_paths_fuchsia.cc b/base/base_paths_fuchsia.cc
deleted file mode 100644
index afe449f..0000000
--- a/base/base_paths_fuchsia.cc
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/base_paths.h"
-
-#include <stdlib.h>
-
-#include "base/base_paths_fuchsia.h"
-#include "base/command_line.h"
-#include "base/files/file_util.h"
-#include "base/path_service.h"
-#include "base/process/process.h"
-
-namespace base {
-namespace {
-
-constexpr char kPackageRoot[] = "/pkg";
-
-}  // namespace
-
-base::FilePath GetPackageRoot() {
-  base::FilePath path_obj(kPackageRoot);
-
-  // Fuchsia's appmgr will set argv[0] to a fully qualified executable path
-  // under /pkg for packaged binaries.
-  if (path_obj.IsParent(base::CommandLine::ForCurrentProcess()->GetProgram())) {
-    return path_obj;
-  } else {
-    return base::FilePath();
-  }
-}
-
-bool PathProviderFuchsia(int key, FilePath* result) {
-  switch (key) {
-    case FILE_MODULE:
-      NOTIMPLEMENTED();
-      return false;
-    case FILE_EXE:
-      *result = CommandLine::ForCurrentProcess()->GetProgram();
-      return true;
-    case DIR_SOURCE_ROOT:
-      *result = GetPackageRoot();
-      return true;
-    case DIR_APP_DATA:
-      // TODO(https://crbug.com/840598): Switch to /data when minfs supports
-      // mmap().
-      DLOG(WARNING) << "Using /tmp as app data dir, changes will NOT be "
-                       "persisted! (crbug.com/840598)";
-      *result = FilePath("/tmp");
-      return true;
-    case DIR_CACHE:
-      *result = FilePath("/data");
-      return true;
-    case DIR_ASSETS:
-      *result = GetPackageRoot();
-      return true;
-  }
-  return false;
-}
-
-}  // namespace base
diff --git a/base/base_paths_fuchsia.h b/base/base_paths_fuchsia.h
deleted file mode 100644
index a2d4194..0000000
--- a/base/base_paths_fuchsia.h
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef BASE_BASE_PATHS_FUCHSIA_H_
-#define BASE_BASE_PATHS_FUCHSIA_H_
-
-#include "base/base_export.h"
-#include "base/files/file_path.h"
-
-namespace base {
-
-// These can be used with the PathService to access various special
-// directories and files.
-enum {
-  PATH_FUCHSIA_START = 1200,
-
-  // Path to the directory which contains application libraries and resources.
-  DIR_FUCHSIA_RESOURCES,
-
-  // Path to the directory which contains application user data.
-  DIR_APP_DATA,
-
-  PATH_FUCHSIA_END,
-};
-
-// If running inside a package, returns a FilePath of the root path
-// of the currently deployed package.
-// Otherwise returns an empty FilePath.
-BASE_EXPORT base::FilePath GetPackageRoot();
-
-}  // namespace base
-
-#endif  // BASE_BASE_PATHS_FUCHSIA_H_
diff --git a/base/debug/stack_trace_fuchsia.cc b/base/debug/stack_trace_fuchsia.cc
deleted file mode 100644
index f996933..0000000
--- a/base/debug/stack_trace_fuchsia.cc
+++ /dev/null
@@ -1,213 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/debug/stack_trace.h"
-
-#include <link.h>
-#include <stddef.h>
-#include <string.h>
-#include <threads.h>
-#include <unwind.h>
-#include <zircon/crashlogger.h>
-#include <zircon/process.h>
-#include <zircon/syscalls.h>
-#include <zircon/syscalls/definitions.h>
-#include <zircon/syscalls/port.h>
-#include <zircon/types.h>
-
-#include <algorithm>
-#include <iomanip>
-#include <iostream>
-
-#include "base/logging.h"
-
-namespace base {
-namespace debug {
-
-namespace {
-
-const char kProcessNamePrefix[] = "app:";
-const size_t kProcessNamePrefixLen = arraysize(kProcessNamePrefix) - 1;
-
-struct BacktraceData {
-  void** trace_array;
-  size_t* count;
-  size_t max;
-};
-
-_Unwind_Reason_Code UnwindStore(struct _Unwind_Context* context,
-                                void* user_data) {
-  BacktraceData* data = reinterpret_cast<BacktraceData*>(user_data);
-  uintptr_t pc = _Unwind_GetIP(context);
-  data->trace_array[*data->count] = reinterpret_cast<void*>(pc);
-  *data->count += 1;
-  if (*data->count == data->max)
-    return _URC_END_OF_STACK;
-  return _URC_NO_REASON;
-}
-
-// Stores and queries debugging symbol map info for the current process.
-class SymbolMap {
- public:
-  struct Entry {
-    void* addr;
-    char name[ZX_MAX_NAME_LEN + kProcessNamePrefixLen];
-  };
-
-  SymbolMap();
-  ~SymbolMap() = default;
-
-  // Gets the symbol map entry for |address|. Returns null if no entry could be
-  // found for the address, or if the symbol map could not be queried.
-  Entry* GetForAddress(void* address);
-
- private:
-  // Component builds of Chrome pull about 250 shared libraries (on Linux), so
-  // 512 entries should be enough in most cases.
-  static const size_t kMaxMapEntries = 512;
-
-  void Populate();
-
-  // Sorted in descending order by address, for lookup purposes.
-  Entry entries_[kMaxMapEntries];
-
-  size_t count_ = 0;
-  bool valid_ = false;
-
-  DISALLOW_COPY_AND_ASSIGN(SymbolMap);
-};
-
-SymbolMap::SymbolMap() {
-  Populate();
-}
-
-SymbolMap::Entry* SymbolMap::GetForAddress(void* address) {
-  if (!valid_) {
-    return nullptr;
-  }
-
-  // Working backwards in the address space, return the first map entry whose
-  // address comes before |address| (thereby enclosing it.)
-  for (size_t i = 0; i < count_; ++i) {
-    if (address >= entries_[i].addr) {
-      return &entries_[i];
-    }
-  }
-  return nullptr;
-}
-
-void SymbolMap::Populate() {
-  zx_handle_t process = zx_process_self();
-
-  // Try to fetch the name of the process' main executable, which was set as the
-  // name of the |process| kernel object.
-  // TODO(wez): Object names can only have up to ZX_MAX_NAME_LEN characters, so
-  // if we keep hitting problems with truncation, find a way to plumb argv[0]
-  // through to here instead, e.g. using CommandLine::GetProgramName().
-  char app_name[arraysize(SymbolMap::Entry::name)];
-  strcpy(app_name, kProcessNamePrefix);
-  zx_status_t status = zx_object_get_property(
-      process, ZX_PROP_NAME, app_name + kProcessNamePrefixLen,
-      sizeof(app_name) - kProcessNamePrefixLen);
-  if (status != ZX_OK) {
-    DPLOG(WARNING)
-        << "Couldn't get name, falling back to 'app' for program name: "
-        << status;
-    strlcat(app_name, "app", sizeof(app_name));
-  }
-
-  // Retrieve the debug info struct.
-  uintptr_t debug_addr;
-  status = zx_object_get_property(process, ZX_PROP_PROCESS_DEBUG_ADDR,
-                                  &debug_addr, sizeof(debug_addr));
-  if (status != ZX_OK) {
-    DPLOG(ERROR) << "Couldn't get symbol map for process: " << status;
-    return;
-  }
-  r_debug* debug_info = reinterpret_cast<r_debug*>(debug_addr);
-
-  // Get the link map from the debug info struct.
-  link_map* lmap = reinterpret_cast<link_map*>(debug_info->r_map);
-  if (!lmap) {
-    DPLOG(ERROR) << "Null link_map for process.";
-    return;
-  }
-
-  // Copy the contents of the link map linked list to |entries_|.
-  while (lmap != nullptr) {
-    if (count_ >= arraysize(entries_)) {
-      break;
-    }
-    SymbolMap::Entry* next_entry = &entries_[count_];
-    count_++;
-
-    next_entry->addr = reinterpret_cast<void*>(lmap->l_addr);
-    char* name_to_use = lmap->l_name[0] ? lmap->l_name : app_name;
-    strlcpy(next_entry->name, name_to_use, sizeof(next_entry->name));
-    lmap = lmap->l_next;
-  }
-
-  std::sort(
-      &entries_[0], &entries_[count_ - 1],
-      [](const Entry& a, const Entry& b) -> bool { return a.addr >= b.addr; });
-
-  valid_ = true;
-}
-
-}  // namespace
-
-// static
-bool EnableInProcessStackDumping() {
-  // StackTrace works to capture the current stack (e.g. for diagnostics added
-  // to code), but for local capture and print of backtraces, we just let the
-  // system crashlogger take over. It handles printing out a nicely formatted
-  // backtrace with dso information, relative offsets, etc. that we can then
-  // filter with addr2line in the run script to get file/line info.
-  return true;
-}
-
-StackTrace::StackTrace(size_t count) : count_(0) {
-  BacktraceData data = {&trace_[0], &count_,
-                        std::min(count, static_cast<size_t>(kMaxTraces))};
-  _Unwind_Backtrace(&UnwindStore, &data);
-}
-
-void StackTrace::Print() const {
-  OutputToStream(&std::cerr);
-}
-
-// Sample stack trace output is designed to be similar to Fuchsia's crashlogger:
-// bt#00: pc 0x1527a058aa00 (app:/system/base_unittests,0x18bda00)
-// bt#01: pc 0x1527a0254b5c (app:/system/base_unittests,0x1587b5c)
-// bt#02: pc 0x15279f446ece (app:/system/base_unittests,0x779ece)
-// ...
-// bt#21: pc 0x1527a05b51b4 (app:/system/base_unittests,0x18e81b4)
-// bt#22: pc 0x54fdbf3593de (libc.so,0x1c3de)
-// bt#23: end
-void StackTrace::OutputToStream(std::ostream* os) const {
-  SymbolMap map;
-
-  size_t i = 0;
-  for (; (i < count_) && os->good(); ++i) {
-    SymbolMap::Entry* entry = map.GetForAddress(trace_[i]);
-    if (entry) {
-      size_t offset = reinterpret_cast<uintptr_t>(trace_[i]) -
-                      reinterpret_cast<uintptr_t>(entry->addr);
-      *os << "bt#" << std::setw(2) << std::setfill('0') << i << std::setw(0)
-          << ": pc " << trace_[i] << " (" << entry->name << ",0x" << std::hex
-          << offset << std::dec << std::setw(0) << ")\n";
-    } else {
-      // Fallback if the DSO map isn't available.
-      // Logged PC values are absolute memory addresses, and the shared object
-      // name is not emitted.
-      *os << "bt#" << std::setw(2) << std::setfill('0') << i << std::setw(0)
-          << ": pc " << trace_[i] << "\n";
-    }
-  }
-
-  (*os) << "bt#" << std::setw(2) << i << ": end\n";
-}
-
-}  // namespace debug
-}  // namespace base
diff --git a/base/files/file_path_watcher_fuchsia.cc b/base/files/file_path_watcher_fuchsia.cc
deleted file mode 100644
index 53c927e..0000000
--- a/base/files/file_path_watcher_fuchsia.cc
+++ /dev/null
@@ -1,55 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/files/file_path_watcher.h"
-
-#include "base/macros.h"
-#include "base/memory/ptr_util.h"
-#include "base/threading/sequenced_task_runner_handle.h"
-
-namespace base {
-
-namespace {
-
-class FilePathWatcherImpl : public FilePathWatcher::PlatformDelegate {
- public:
-  FilePathWatcherImpl() {}
-  ~FilePathWatcherImpl() override {}
-
-  bool Watch(const FilePath& path,
-             bool recursive,
-             const FilePathWatcher::Callback& callback) override;
-
-  void Cancel() override;
-
- private:
-  FilePathWatcher::Callback callback_;
-  FilePath target_;
-
-  DISALLOW_COPY_AND_ASSIGN(FilePathWatcherImpl);
-};
-
-bool FilePathWatcherImpl::Watch(const FilePath& path,
-                                bool recursive,
-                                const FilePathWatcher::Callback& callback) {
-  DCHECK(!callback.is_null());
-  DCHECK(callback_.is_null());
-
-  callback_ = callback;
-  NOTIMPLEMENTED();
-  return false;
-}
-
-void FilePathWatcherImpl::Cancel() {
-  NOTIMPLEMENTED();
-}
-
-}  // namespace
-
-FilePathWatcher::FilePathWatcher() {
-  sequence_checker_.DetachFromSequence();
-  impl_ = std::make_unique<FilePathWatcherImpl>();
-}
-
-}  // namespace base
diff --git a/base/message_loop/message_pump_fuchsia.cc b/base/message_loop/message_pump_fuchsia.cc
deleted file mode 100644
index b9af643..0000000
--- a/base/message_loop/message_pump_fuchsia.cc
+++ /dev/null
@@ -1,304 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/message_loop/message_pump_fuchsia.h"
-
-#include <fdio/io.h>
-#include <fdio/private.h>
-#include <zircon/status.h>
-#include <zircon/syscalls.h>
-
-#include "base/auto_reset.h"
-#include "base/fuchsia/fuchsia_logging.h"
-#include "base/logging.h"
-
-namespace base {
-
-MessagePumpFuchsia::ZxHandleWatchController::ZxHandleWatchController(
-    const Location& from_here)
-    : async_wait_t({}), created_from_location_(from_here) {}
-
-MessagePumpFuchsia::ZxHandleWatchController::~ZxHandleWatchController() {
-  if (!StopWatchingZxHandle())
-    NOTREACHED();
-}
-
-bool MessagePumpFuchsia::ZxHandleWatchController::WaitBegin() {
-  DCHECK(!handler);
-  async_wait_t::handler = &HandleSignal;
-
-  zx_status_t status = async_begin_wait(&weak_pump_->async_dispatcher_, this);
-  if (status != ZX_OK) {
-    ZX_DLOG(ERROR, status) << "async_begin_wait() failed";
-    async_wait_t::handler = nullptr;
-    return false;
-  }
-
-  return true;
-}
-
-bool MessagePumpFuchsia::ZxHandleWatchController::StopWatchingZxHandle() {
-  if (was_stopped_) {
-    DCHECK(!*was_stopped_);
-    *was_stopped_ = true;
-
-    // |was_stopped_| points at a value stored on the stack, which will go out
-    // of scope. MessagePumpFuchsia::Run() will reset it only if the value is
-    // false. So we need to reset this pointer here as well, to make sure it's
-    // not used again.
-    was_stopped_ = nullptr;
-  }
-
-  // If the pump is gone then there is nothing to cancel.
-  if (!weak_pump_)
-    return true;
-
-  // |handler| is set when waiting for a signal.
-  if (!handler)
-    return true;
-
-  async_wait_t::handler = nullptr;
-
-  zx_status_t result = async_cancel_wait(&weak_pump_->async_dispatcher_, this);
-  ZX_DLOG_IF(ERROR, result != ZX_OK, result) << "async_cancel_wait failed";
-  return result == ZX_OK;
-}
-
-// static
-void MessagePumpFuchsia::ZxHandleWatchController::HandleSignal(
-    async_t* async,
-    async_wait_t* wait,
-    zx_status_t status,
-    const zx_packet_signal_t* signal) {
-  if (status != ZX_OK) {
-    ZX_LOG(WARNING, status) << "async wait failed";
-    return;
-  }
-
-  ZxHandleWatchController* controller =
-      static_cast<ZxHandleWatchController*>(wait);
-  DCHECK_EQ(controller->handler, &HandleSignal);
-  controller->handler = nullptr;
-
-  // |signal| can include other spurious things, in particular, that an fd
-  // is writable, when we only asked to know when it was readable. In that
-  // case, we don't want to call both the CanWrite and CanRead callback,
-  // when the caller asked for only, for example, readable callbacks. So,
-  // mask with the events that we actually wanted to know about.
-  zx_signals_t signals = signal->trigger & signal->observed;
-  DCHECK_NE(0u, signals);
-
-  // In the case of a persistent Watch, the Watch may be stopped and
-  // potentially deleted by the caller within the callback, in which case
-  // |controller| should not be accessed again, and we mustn't continue the
-  // watch. We check for this with a bool on the stack, which the Watch
-  // receives a pointer to.
-  bool was_stopped = false;
-  controller->was_stopped_ = &was_stopped;
-
-  controller->watcher_->OnZxHandleSignalled(wait->object, signals);
-
-  if (was_stopped)
-    return;
-
-  controller->was_stopped_ = nullptr;
-
-  if (controller->persistent_)
-    controller->WaitBegin();
-}
-
-void MessagePumpFuchsia::FdWatchController::OnZxHandleSignalled(
-    zx_handle_t handle,
-    zx_signals_t signals) {
-  uint32_t events;
-  __fdio_wait_end(io_, signals, &events);
-
-  // Each |watcher_| callback we invoke may stop or delete |this|. The pump has
-  // set |was_stopped_| to point to a safe location on the calling stack, so we
-  // can use that to detect being stopped mid-callback and avoid doing further
-  // work that would touch |this|.
-  bool* was_stopped = was_stopped_;
-  if (events & FDIO_EVT_WRITABLE)
-    watcher_->OnFileCanWriteWithoutBlocking(fd_);
-  if (!*was_stopped && (events & FDIO_EVT_READABLE))
-    watcher_->OnFileCanReadWithoutBlocking(fd_);
-
-  // Don't add additional work here without checking |*was_stopped_| again.
-}
-
-MessagePumpFuchsia::FdWatchController::FdWatchController(
-    const Location& from_here)
-    : FdWatchControllerInterface(from_here),
-      ZxHandleWatchController(from_here) {}
-
-MessagePumpFuchsia::FdWatchController::~FdWatchController() {
-  if (!StopWatchingFileDescriptor())
-    NOTREACHED();
-}
-
-bool MessagePumpFuchsia::FdWatchController::WaitBegin() {
-  // Refresh the |handle_| and |desired_signals_| from the mxio for the fd.
-  // Some types of fdio map read/write events to different signals depending on
-  // their current state, so we must do this every time we begin to wait.
-  __fdio_wait_begin(io_, desired_events_, &object, &trigger);
-  if (async_wait_t::object == ZX_HANDLE_INVALID) {
-    DLOG(ERROR) << "fdio_wait_begin failed";
-    return false;
-  }
-
-  return MessagePumpFuchsia::ZxHandleWatchController::WaitBegin();
-}
-
-bool MessagePumpFuchsia::FdWatchController::StopWatchingFileDescriptor() {
-  bool success = StopWatchingZxHandle();
-  if (io_) {
-    __fdio_release(io_);
-    io_ = nullptr;
-  }
-  return success;
-}
-
-MessagePumpFuchsia::MessagePumpFuchsia() : weak_factory_(this) {}
-
-MessagePumpFuchsia::~MessagePumpFuchsia() = default;
-
-bool MessagePumpFuchsia::WatchFileDescriptor(int fd,
-                                             bool persistent,
-                                             int mode,
-                                             FdWatchController* controller,
-                                             FdWatcher* delegate) {
-  DCHECK_GE(fd, 0);
-  DCHECK(controller);
-  DCHECK(delegate);
-
-  if (!controller->StopWatchingFileDescriptor())
-    NOTREACHED();
-
-  controller->fd_ = fd;
-  controller->watcher_ = delegate;
-
-  DCHECK(!controller->io_);
-  controller->io_ = __fdio_fd_to_io(fd);
-  if (!controller->io_) {
-    DLOG(ERROR) << "Failed to get IO for FD";
-    return false;
-  }
-
-  switch (mode) {
-    case WATCH_READ:
-      controller->desired_events_ = FDIO_EVT_READABLE;
-      break;
-    case WATCH_WRITE:
-      controller->desired_events_ = FDIO_EVT_WRITABLE;
-      break;
-    case WATCH_READ_WRITE:
-      controller->desired_events_ = FDIO_EVT_READABLE | FDIO_EVT_WRITABLE;
-      break;
-    default:
-      NOTREACHED() << "unexpected mode: " << mode;
-      return false;
-  }
-
-  // Pass dummy |handle| and |signals| values to WatchZxHandle(). The real
-  // values will be populated by FdWatchController::WaitBegin(), before actually
-  // starting the wait operation.
-  return WatchZxHandle(ZX_HANDLE_INVALID, persistent, 1, controller,
-                       controller);
-}
-
-bool MessagePumpFuchsia::WatchZxHandle(zx_handle_t handle,
-                                       bool persistent,
-                                       zx_signals_t signals,
-                                       ZxHandleWatchController* controller,
-                                       ZxHandleWatcher* delegate) {
-  DCHECK_NE(0u, signals);
-  DCHECK(controller);
-  DCHECK(delegate);
-  DCHECK(handle == ZX_HANDLE_INVALID ||
-         controller->async_wait_t::object == ZX_HANDLE_INVALID ||
-         handle == controller->async_wait_t::object);
-
-  if (!controller->StopWatchingZxHandle())
-    NOTREACHED();
-
-  controller->async_wait_t::object = handle;
-  controller->persistent_ = persistent;
-  controller->async_wait_t::trigger = signals;
-  controller->watcher_ = delegate;
-
-  controller->weak_pump_ = weak_factory_.GetWeakPtr();
-
-  return controller->WaitBegin();
-}
-
-bool MessagePumpFuchsia::HandleEvents(zx_time_t deadline) {
-  zx_status_t status = async_dispatcher_.DispatchOrWaitUntil(deadline);
-  switch (status) {
-    // Return true if some tasks or events were dispatched or if the dispatcher
-    // was stopped by ScheduleWork().
-    case ZX_OK:
-    case ZX_ERR_CANCELED:
-      return true;
-
-    case ZX_ERR_TIMED_OUT:
-      return false;
-
-    default:
-      ZX_DLOG(DCHECK, status) << "unexpected wait status";
-      return false;
-  }
-}
-
-void MessagePumpFuchsia::Run(Delegate* delegate) {
-  AutoReset<bool> auto_reset_keep_running(&keep_running_, true);
-
-  for (;;) {
-    bool did_work = delegate->DoWork();
-    if (!keep_running_)
-      break;
-
-    did_work |= delegate->DoDelayedWork(&delayed_work_time_);
-    if (!keep_running_)
-      break;
-
-    did_work |= HandleEvents(/*deadline=*/0);
-    if (!keep_running_)
-      break;
-
-    if (did_work)
-      continue;
-
-    did_work = delegate->DoIdleWork();
-    if (!keep_running_)
-      break;
-
-    if (did_work)
-      continue;
-
-    zx_time_t deadline = delayed_work_time_.is_null()
-                             ? ZX_TIME_INFINITE
-                             : delayed_work_time_.ToZxTime();
-    HandleEvents(deadline);
-  }
-}
-
-void MessagePumpFuchsia::Quit() {
-  keep_running_ = false;
-}
-
-void MessagePumpFuchsia::ScheduleWork() {
-  // Stop AsyncDispatcher to let MessagePumpFuchsia::Run() handle message loop
-  // tasks.
-  async_dispatcher_.Stop();
-}
-
-void MessagePumpFuchsia::ScheduleDelayedWork(
-    const TimeTicks& delayed_work_time) {
-  // We know that we can't be blocked right now since this method can only be
-  // called on the same thread as Run, so we only need to update our record of
-  // how long to sleep when we do sleep.
-  delayed_work_time_ = delayed_work_time;
-}
-
-}  // namespace base
diff --git a/base/message_loop/message_pump_fuchsia.h b/base/message_loop/message_pump_fuchsia.h
deleted file mode 100644
index 514e23f..0000000
--- a/base/message_loop/message_pump_fuchsia.h
+++ /dev/null
@@ -1,157 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef BASE_MESSAGE_LOOP_MESSAGE_PUMP_FUCHSIA_H_
-#define BASE_MESSAGE_LOOP_MESSAGE_PUMP_FUCHSIA_H_
-
-#include <lib/async/wait.h>
-
-#include "base/base_export.h"
-#include "base/fuchsia/async_dispatcher.h"
-#include "base/location.h"
-#include "base/macros.h"
-#include "base/memory/weak_ptr.h"
-#include "base/message_loop/message_pump.h"
-#include "base/message_loop/watchable_io_message_pump_posix.h"
-
-typedef struct fdio fdio_t;
-
-namespace base {
-
-class BASE_EXPORT MessagePumpFuchsia : public MessagePump,
-                                       public WatchableIOMessagePumpPosix {
- public:
-  // Implemented by callers to receive notifications of handle & fd events.
-  class ZxHandleWatcher {
-   public:
-    virtual void OnZxHandleSignalled(zx_handle_t handle,
-                                     zx_signals_t signals) = 0;
-
-   protected:
-    virtual ~ZxHandleWatcher() {}
-  };
-
-  // Manages an active watch on an zx_handle_t.
-  class ZxHandleWatchController : public async_wait_t {
-   public:
-    explicit ZxHandleWatchController(const Location& from_here);
-    // Deleting the Controller implicitly calls StopWatchingZxHandle.
-    virtual ~ZxHandleWatchController();
-
-    // Stop watching the handle, always safe to call.  No-op if there's nothing
-    // to do.
-    bool StopWatchingZxHandle();
-
-    const Location& created_from_location() { return created_from_location_; }
-
-   protected:
-    friend class MessagePumpFuchsia;
-
-    virtual bool WaitBegin();
-
-    static void HandleSignal(async_t* async,
-                             async_wait_t* wait,
-                             zx_status_t status,
-                             const zx_packet_signal_t* signal);
-
-    const Location created_from_location_;
-
-    // This bool is used by the pump when invoking the ZxHandleWatcher callback,
-    // and by the FdHandleWatchController when invoking read & write callbacks,
-    // to cope with the possibility of the caller deleting the *Watcher within
-    // the callback. The pump sets |was_stopped_| to a location on the stack,
-    // and the Watcher writes to it, if set, when deleted, allowing the pump
-    // to check the value on the stack to short-cut any post-callback work.
-    bool* was_stopped_ = nullptr;
-
-    // Set directly from the inputs to WatchFileDescriptor.
-    ZxHandleWatcher* watcher_ = nullptr;
-
-    // Used to safely access resources owned by the associated message pump.
-    WeakPtr<MessagePumpFuchsia> weak_pump_;
-
-    // A watch may be marked as persistent, which means it remains active even
-    // after triggering.
-    bool persistent_ = false;
-
-    DISALLOW_COPY_AND_ASSIGN(ZxHandleWatchController);
-  };
-
-  class FdWatchController : public FdWatchControllerInterface,
-                            public ZxHandleWatchController,
-                            public ZxHandleWatcher {
-   public:
-    explicit FdWatchController(const Location& from_here);
-    ~FdWatchController() override;
-
-    // FdWatchControllerInterface:
-    bool StopWatchingFileDescriptor() override;
-
-   private:
-    friend class MessagePumpFuchsia;
-
-    // Determines the desires signals, and begins waiting on the handle.
-    bool WaitBegin() override;
-
-    // ZxHandleWatcher interface.
-    void OnZxHandleSignalled(zx_handle_t handle, zx_signals_t signals) override;
-
-    // Set directly from the inputs to WatchFileDescriptor.
-    FdWatcher* watcher_ = nullptr;
-    int fd_ = -1;
-    uint32_t desired_events_ = 0;
-
-    // Set by WatchFileDescriptor to hold a reference to the descriptor's mxio.
-    fdio_t* io_ = nullptr;
-
-    DISALLOW_COPY_AND_ASSIGN(FdWatchController);
-  };
-
-  enum Mode {
-    WATCH_READ = 1 << 0,
-    WATCH_WRITE = 1 << 1,
-    WATCH_READ_WRITE = WATCH_READ | WATCH_WRITE
-  };
-
-  MessagePumpFuchsia();
-  ~MessagePumpFuchsia() override;
-
-  bool WatchZxHandle(zx_handle_t handle,
-                     bool persistent,
-                     zx_signals_t signals,
-                     ZxHandleWatchController* controller,
-                     ZxHandleWatcher* delegate);
-  bool WatchFileDescriptor(int fd,
-                           bool persistent,
-                           int mode,
-                           FdWatchController* controller,
-                           FdWatcher* delegate);
-
-  // MessagePump implementation:
-  void Run(Delegate* delegate) override;
-  void Quit() override;
-  void ScheduleWork() override;
-  void ScheduleDelayedWork(const TimeTicks& delayed_work_time) override;
-
- private:
-  // Handles IO events by running |async_dispatcher_|. Returns true if any
-  // events were received or if ScheduleWork() was called.
-  bool HandleEvents(zx_time_t deadline);
-
-  // This flag is set to false when Run should return.
-  bool keep_running_ = true;
-
-  AsyncDispatcher async_dispatcher_;
-
-  // The time at which we should call DoDelayedWork.
-  TimeTicks delayed_work_time_;
-
-  base::WeakPtrFactory<MessagePumpFuchsia> weak_factory_;
-
-  DISALLOW_COPY_AND_ASSIGN(MessagePumpFuchsia);
-};
-
-}  // namespace base
-
-#endif  // BASE_MESSAGE_LOOP_MESSAGE_PUMP_FUCHSIA_H_
diff --git a/base/native_library_fuchsia.cc b/base/native_library_fuchsia.cc
deleted file mode 100644
index 1d74273..0000000
--- a/base/native_library_fuchsia.cc
+++ /dev/null
@@ -1,87 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/native_library.h"
-
-#include <fcntl.h>
-#include <fdio/io.h>
-#include <stdio.h>
-#include <zircon/dlfcn.h>
-#include <zircon/status.h>
-#include <zircon/syscalls.h>
-
-#include "base/base_paths_fuchsia.h"
-#include "base/files/file.h"
-#include "base/files/file_path.h"
-#include "base/fuchsia/fuchsia_logging.h"
-#include "base/fuchsia/scoped_zx_handle.h"
-#include "base/logging.h"
-#include "base/path_service.h"
-#include "base/posix/safe_strerror.h"
-#include "base/strings/stringprintf.h"
-#include "base/strings/utf_string_conversions.h"
-#include "base/threading/thread_restrictions.h"
-
-namespace base {
-
-std::string NativeLibraryLoadError::ToString() const {
-  return message;
-}
-
-NativeLibrary LoadNativeLibraryWithOptions(const FilePath& library_path,
-                                           const NativeLibraryOptions& options,
-                                           NativeLibraryLoadError* error) {
-  std::vector<base::FilePath::StringType> components;
-  library_path.GetComponents(&components);
-  if (components.size() != 1u) {
-    NOTREACHED() << "library_path is a path, should be a filename: "
-                 << library_path.MaybeAsASCII();
-    return nullptr;
-  }
-
-  FilePath computed_path = base::GetPackageRoot();
-  computed_path = computed_path.AppendASCII("lib").Append(components[0]);
-  base::File library(computed_path,
-                     base::File::FLAG_OPEN | base::File::FLAG_READ);
-  if (!library.IsValid()) {
-    if (error) {
-      error->message = base::StringPrintf(
-          "open library: %s",
-          base::File::ErrorToString(library.error_details()).c_str());
-    }
-    return nullptr;
-  }
-
-  base::ScopedZxHandle vmo;
-  zx_status_t status =
-      fdio_get_vmo_clone(library.GetPlatformFile(), vmo.receive());
-  if (status != ZX_OK) {
-    if (error) {
-      error->message = base::StringPrintf("fdio_get_vmo_clone: %s",
-                                          zx_status_get_string(status));
-    }
-    return nullptr;
-  }
-  NativeLibrary result = dlopen_vmo(vmo.get(), RTLD_LAZY | RTLD_LOCAL);
-  return result;
-}
-
-void UnloadNativeLibrary(NativeLibrary library) {
-  // dlclose() is a no-op on Fuchsia, so do nothing here.
-}
-
-void* GetFunctionPointerFromNativeLibrary(NativeLibrary library,
-                                          StringPiece name) {
-  return dlsym(library, name.data());
-}
-
-std::string GetNativeLibraryName(StringPiece name) {
-  return base::StringPrintf("lib%s.so", name.as_string().c_str());
-}
-
-std::string GetLoadableModuleName(StringPiece name) {
-  return GetNativeLibraryName(name);
-}
-
-}  // namespace base
diff --git a/base/process/kill_fuchsia.cc b/base/process/kill_fuchsia.cc
deleted file mode 100644
index a862fc3..0000000
--- a/base/process/kill_fuchsia.cc
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/process/kill.h"
-
-#include <zircon/syscalls.h>
-
-#include "base/process/process_iterator.h"
-#include "base/task_scheduler/post_task.h"
-#include "base/threading/platform_thread.h"
-
-namespace base {
-
-bool KillProcessGroup(ProcessHandle process_group_id) {
-  // |process_group_id| is really a job on Fuchsia.
-  zx_status_t status = zx_task_kill(process_group_id);
-  DLOG_IF(ERROR, status != ZX_OK)
-      << "unable to terminate job " << process_group_id;
-  return status == ZX_OK;
-}
-
-TerminationStatus GetTerminationStatus(ProcessHandle handle, int* exit_code) {
-  DCHECK(exit_code);
-
-  zx_info_process_t process_info;
-  zx_status_t status =
-      zx_object_get_info(handle, ZX_INFO_PROCESS, &process_info,
-                         sizeof(process_info), nullptr, nullptr);
-  if (status != ZX_OK) {
-    DLOG(ERROR) << "unable to get termination status for " << handle;
-    *exit_code = 0;
-    return TERMINATION_STATUS_NORMAL_TERMINATION;
-  }
-  if (!process_info.started) {
-    *exit_code = 0;
-    return TERMINATION_STATUS_LAUNCH_FAILED;
-  }
-  if (!process_info.exited) {
-    *exit_code = 0;
-    return TERMINATION_STATUS_STILL_RUNNING;
-  }
-
-  // TODO(fuchsia): Is there more information about types of crashes, OOM, etc.
-  // available? https://crbug.com/706592.
-
-  *exit_code = process_info.return_code;
-  return process_info.return_code == 0
-             ? TERMINATION_STATUS_NORMAL_TERMINATION
-             : TERMINATION_STATUS_ABNORMAL_TERMINATION;
-}
-
-}  // namespace base
diff --git a/base/process/launch_fuchsia.cc b/base/process/launch_fuchsia.cc
deleted file mode 100644
index 3bc7580..0000000
--- a/base/process/launch_fuchsia.cc
+++ /dev/null
@@ -1,307 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/process/launch.h"
-
-#include <fdio/limits.h>
-#include <fdio/namespace.h>
-#include <fdio/util.h>
-#include <launchpad/launchpad.h>
-#include <stdint.h>
-#include <unistd.h>
-#include <zircon/process.h>
-#include <zircon/processargs.h>
-
-#include "base/command_line.h"
-#include "base/files/file_util.h"
-#include "base/fuchsia/default_job.h"
-#include "base/fuchsia/fuchsia_logging.h"
-#include "base/logging.h"
-#include "base/memory/ptr_util.h"
-#include "base/scoped_generic.h"
-
-namespace base {
-
-namespace {
-
-bool GetAppOutputInternal(const CommandLine& cmd_line,
-                          bool include_stderr,
-                          std::string* output,
-                          int* exit_code) {
-  DCHECK(exit_code);
-
-  LaunchOptions options;
-
-  // LaunchProcess will automatically clone any stdio fd we do not explicitly
-  // map.
-  int pipe_fd[2];
-  if (pipe(pipe_fd) < 0)
-    return false;
-  options.fds_to_remap.emplace_back(pipe_fd[1], STDOUT_FILENO);
-  if (include_stderr)
-    options.fds_to_remap.emplace_back(pipe_fd[1], STDERR_FILENO);
-
-  Process process = LaunchProcess(cmd_line, options);
-  close(pipe_fd[1]);
-  if (!process.IsValid()) {
-    close(pipe_fd[0]);
-    return false;
-  }
-
-  output->clear();
-  for (;;) {
-    char buffer[256];
-    ssize_t bytes_read = read(pipe_fd[0], buffer, sizeof(buffer));
-    if (bytes_read <= 0)
-      break;
-    output->append(buffer, bytes_read);
-  }
-  close(pipe_fd[0]);
-
-  return process.WaitForExit(exit_code);
-}
-
-bool MapPathsToLaunchpad(const std::vector<FilePath>& paths_to_map,
-                         launchpad_t* lp) {
-  zx_status_t status;
-
-  // Build a array of null terminated strings, which which will be used as an
-  // argument for launchpad_set_nametable().
-  std::vector<const char*> paths_c_str;
-  paths_c_str.reserve(paths_to_map.size());
-
-  for (size_t paths_idx = 0; paths_idx < paths_to_map.size(); ++paths_idx) {
-    const FilePath& next_path = paths_to_map[paths_idx];
-    if (!PathExists(next_path)) {
-      DLOG(ERROR) << "Path does not exist: " << next_path;
-      return false;
-    }
-
-    File dir(next_path, File::FLAG_OPEN | File::FLAG_READ);
-    ScopedPlatformFile scoped_fd(dir.TakePlatformFile());
-    zx_handle_t handles[FDIO_MAX_HANDLES] = {};
-    uint32_t types[FDIO_MAX_HANDLES] = {};
-    zx_status_t num_handles =
-        fdio_transfer_fd(scoped_fd.get(), 0, handles, types);
-    // fdio_transfer_fd() returns number of transferred handles, or negative
-    // error.
-    if (num_handles <= 0) {
-      DCHECK_LT(num_handles, 0);
-      ZX_LOG(ERROR, num_handles) << "fdio_transfer_fd";
-      return false;
-    }
-    ScopedZxHandle scoped_handle(handles[0]);
-    ignore_result(scoped_fd.release());
-
-    // Close the handles that we won't use.
-    for (int i = 1; i < num_handles; ++i) {
-      zx_handle_close(handles[i]);
-    }
-
-    if (types[0] != PA_FDIO_REMOTE) {
-      LOG(ERROR) << "Handle type for " << next_path.AsUTF8Unsafe()
-                 << " is not PA_FDIO_REMOTE: " << types[0];
-      return false;
-    }
-
-    // Add the handle to the child's nametable.
-    // We use the macro PA_HND(..., <index>) to relate the handle to its
-    // position in the nametable, which is stored as an array of path strings
-    // |paths_str|.
-    status = launchpad_add_handle(lp, scoped_handle.release(),
-                                  PA_HND(PA_NS_DIR, paths_idx));
-    if (status != ZX_OK) {
-      ZX_LOG(ERROR, status) << "launchpad_add_handle";
-      return false;
-    }
-    paths_c_str.push_back(next_path.value().c_str());
-  }
-
-  if (!paths_c_str.empty()) {
-    status =
-        launchpad_set_nametable(lp, paths_c_str.size(), paths_c_str.data());
-    if (status != ZX_OK) {
-      ZX_LOG(ERROR, status) << "launchpad_set_nametable";
-      return false;
-    }
-  }
-
-  return true;
-}
-
-struct LaunchpadScopedTraits {
-  static launchpad_t* InvalidValue() { return nullptr; }
-
-  static void Free(launchpad_t* lp) { launchpad_destroy(lp); }
-};
-
-using ScopedLaunchpad = ScopedGeneric<launchpad_t*, LaunchpadScopedTraits>;
-
-}  // namespace
-
-Process LaunchProcess(const CommandLine& cmdline,
-                      const LaunchOptions& options) {
-  return LaunchProcess(cmdline.argv(), options);
-}
-
-// TODO(768416): Investigate whether we can make LaunchProcess() create
-// unprivileged processes by default (no implicit capabilities are granted).
-Process LaunchProcess(const std::vector<std::string>& argv,
-                      const LaunchOptions& options) {
-  std::vector<const char*> argv_cstr;
-  argv_cstr.reserve(argv.size() + 1);
-  for (const auto& arg : argv)
-    argv_cstr.push_back(arg.c_str());
-  argv_cstr.push_back(nullptr);
-
-  // Note that per launchpad.h, the intention is that launchpad_ functions are
-  // used in a "builder" style. From launchpad_create() to launchpad_go() the
-  // status is tracked in the launchpad_t object, and launchpad_go() reports on
-  // the final status, and cleans up |lp| (assuming it was even created).
-  zx_handle_t job = options.job_handle != ZX_HANDLE_INVALID ? options.job_handle
-                                                            : GetDefaultJob();
-  DCHECK_NE(ZX_HANDLE_INVALID, job);
-  ScopedLaunchpad lp;
-  zx_status_t status;
-  if ((status = launchpad_create(job, argv_cstr[0], lp.receive())) != ZX_OK) {
-    ZX_LOG(ERROR, status) << "launchpad_create(job)";
-    return Process();
-  }
-
-  if ((status = launchpad_load_from_file(lp.get(), argv_cstr[0])) != ZX_OK) {
-    ZX_LOG(ERROR, status) << "launchpad_load_from_file(" << argv_cstr[0] << ")";
-    return Process();
-  }
-
-  if ((status = launchpad_set_args(lp.get(), argv.size(), argv_cstr.data())) !=
-      ZX_OK) {
-    ZX_LOG(ERROR, status) << "launchpad_set_args";
-    return Process();
-  }
-
-  uint32_t to_clone = options.clone_flags;
-
-  std::unique_ptr<char* []> new_environ;
-  char* const empty_environ = nullptr;
-  char* const* old_environ = environ;
-  if (options.clear_environ)
-    old_environ = &empty_environ;
-
-  EnvironmentMap environ_modifications = options.environ;
-  if (!options.current_directory.empty()) {
-    environ_modifications["PWD"] = options.current_directory.value();
-  } else {
-    FilePath cwd;
-    GetCurrentDirectory(&cwd);
-    environ_modifications["PWD"] = cwd.value();
-  }
-
-  if (to_clone & LP_CLONE_DEFAULT_JOB) {
-    // Override Fuchsia's built in default job cloning behavior with our own
-    // logic which uses |job| instead of zx_job_default().
-    // This logic is based on the launchpad implementation.
-    zx_handle_t job_duplicate = ZX_HANDLE_INVALID;
-    if ((status = zx_handle_duplicate(job, ZX_RIGHT_SAME_RIGHTS,
-                                      &job_duplicate)) != ZX_OK) {
-      ZX_LOG(ERROR, status) << "zx_handle_duplicate";
-      return Process();
-    }
-    launchpad_add_handle(lp.get(), job_duplicate, PA_HND(PA_JOB_DEFAULT, 0));
-    to_clone &= ~LP_CLONE_DEFAULT_JOB;
-  }
-
-  if (!environ_modifications.empty())
-    new_environ = AlterEnvironment(old_environ, environ_modifications);
-
-  if (!environ_modifications.empty() || options.clear_environ)
-    launchpad_set_environ(lp.get(), new_environ.get());
-  else
-    to_clone |= LP_CLONE_ENVIRON;
-
-  if (!options.paths_to_map.empty()) {
-    DCHECK(!(to_clone & LP_CLONE_FDIO_NAMESPACE));
-    if (!MapPathsToLaunchpad(options.paths_to_map, lp.get())) {
-      return Process();
-    }
-  }
-
-  launchpad_clone(lp.get(), to_clone);
-
-  // Clone the mapped file-descriptors, plus any of the stdio descriptors
-  // which were not explicitly specified.
-  bool stdio_already_mapped[3] = {false};
-  for (const auto& src_target : options.fds_to_remap) {
-    if (static_cast<size_t>(src_target.second) <
-        arraysize(stdio_already_mapped)) {
-      stdio_already_mapped[src_target.second] = true;
-    }
-    launchpad_clone_fd(lp.get(), src_target.first, src_target.second);
-  }
-  if (to_clone & LP_CLONE_FDIO_STDIO) {
-    for (size_t stdio_fd = 0; stdio_fd < arraysize(stdio_already_mapped);
-         ++stdio_fd) {
-      if (!stdio_already_mapped[stdio_fd])
-        launchpad_clone_fd(lp.get(), stdio_fd, stdio_fd);
-    }
-    to_clone &= ~LP_CLONE_FDIO_STDIO;
-  }
-
-  for (const auto& id_and_handle : options.handles_to_transfer) {
-    launchpad_add_handle(lp.get(), id_and_handle.handle, id_and_handle.id);
-  }
-
-  zx_handle_t process_handle;
-  const char* errmsg;
-  if ((status = launchpad_go(lp.get(), &process_handle, &errmsg)) != ZX_OK) {
-    ZX_LOG(ERROR, status) << "launchpad_go failed: " << errmsg;
-    return Process();
-  }
-  ignore_result(lp.release());  // launchpad_go() took ownership.
-
-  Process process(process_handle);
-  if (options.wait) {
-    status = zx_object_wait_one(process.Handle(), ZX_TASK_TERMINATED,
-                                ZX_TIME_INFINITE, nullptr);
-    DCHECK(status == ZX_OK)
-        << "zx_object_wait_one: " << zx_status_get_string(status);
-  }
-
-  return process;
-}
-
-bool GetAppOutput(const CommandLine& cl, std::string* output) {
-  int exit_code;
-  bool result = GetAppOutputInternal(cl, false, output, &exit_code);
-  return result && exit_code == EXIT_SUCCESS;
-}
-
-bool GetAppOutput(const std::vector<std::string>& argv, std::string* output) {
-  return GetAppOutput(CommandLine(argv), output);
-}
-
-bool GetAppOutputAndError(const CommandLine& cl, std::string* output) {
-  int exit_code;
-  bool result = GetAppOutputInternal(cl, true, output, &exit_code);
-  return result && exit_code == EXIT_SUCCESS;
-}
-
-bool GetAppOutputAndError(const std::vector<std::string>& argv,
-                          std::string* output) {
-  return GetAppOutputAndError(CommandLine(argv), output);
-}
-
-bool GetAppOutputWithExitCode(const CommandLine& cl,
-                              std::string* output,
-                              int* exit_code) {
-  // Contrary to GetAppOutput(), |true| return here means that the process was
-  // launched and the exit code was waited upon successfully, but not
-  // necessarily that the exit code was EXIT_SUCCESS.
-  return GetAppOutputInternal(cl, false, output, exit_code);
-}
-
-void RaiseProcessToHighPriority() {
-  // Fuchsia doesn't provide an API to change process priority.
-}
-
-}  // namespace base
diff --git a/base/process/memory_fuchsia.cc b/base/process/memory_fuchsia.cc
deleted file mode 100644
index 6f559a4..0000000
--- a/base/process/memory_fuchsia.cc
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/process/memory.h"
-
-#include <stdlib.h>
-
-namespace base {
-
-void EnableTerminationOnOutOfMemory() {
-  // Nothing to be done here.
-}
-
-void EnableTerminationOnHeapCorruption() {
-  // Nothing to be done here.
-}
-
-bool UncheckedMalloc(size_t size, void** result) {
-  *result = malloc(size);
-  return *result != nullptr;
-}
-
-}  // namespace base
diff --git a/base/process/process_fuchsia.cc b/base/process/process_fuchsia.cc
deleted file mode 100644
index 94bce34..0000000
--- a/base/process/process_fuchsia.cc
+++ /dev/null
@@ -1,226 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/process/process.h"
-
-#include <zircon/process.h>
-#include <zircon/syscalls.h>
-
-#include "base/debug/activity_tracker.h"
-#include "base/fuchsia/default_job.h"
-#include "base/strings/stringprintf.h"
-
-namespace base {
-
-Process::Process(ProcessHandle handle)
-    : process_(handle), is_current_process_(false) {
-  CHECK_NE(handle, zx_process_self());
-}
-
-Process::~Process() {
-  Close();
-}
-
-Process::Process(Process&& other)
-    : process_(std::move(other.process_)),
-      is_current_process_(other.is_current_process_) {
-  other.is_current_process_ = false;
-}
-
-Process& Process::operator=(Process&& other) {
-  process_ = std::move(other.process_);
-  is_current_process_ = other.is_current_process_;
-  other.is_current_process_ = false;
-  return *this;
-}
-
-// static
-Process Process::Current() {
-  Process process;
-  process.is_current_process_ = true;
-  return process;
-}
-
-// static
-Process Process::Open(ProcessId pid) {
-  if (pid == GetCurrentProcId())
-    return Current();
-
-  // While a process with object id |pid| might exist, the job returned by
-  // zx_job_default() might not contain it, so this call can fail.
-  ScopedZxHandle handle;
-  zx_status_t status = zx_object_get_child(
-      GetDefaultJob(), pid, ZX_RIGHT_SAME_RIGHTS, handle.receive());
-  if (status != ZX_OK) {
-    DLOG(ERROR) << "zx_object_get_child failed: " << status;
-    return Process();
-  }
-  return Process(handle.release());
-}
-
-// static
-Process Process::OpenWithExtraPrivileges(ProcessId pid) {
-  // No privileges to set.
-  return Open(pid);
-}
-
-// static
-Process Process::DeprecatedGetProcessFromHandle(ProcessHandle handle) {
-  DCHECK_NE(handle, GetCurrentProcessHandle());
-  ScopedZxHandle out;
-  if (zx_handle_duplicate(handle, ZX_RIGHT_SAME_RIGHTS, out.receive()) !=
-      ZX_OK) {
-    DLOG(ERROR) << "zx_handle_duplicate failed: " << handle;
-    return Process();
-  }
-
-  return Process(out.release());
-}
-
-// static
-bool Process::CanBackgroundProcesses() {
-  return false;
-}
-
-// static
-void Process::TerminateCurrentProcessImmediately(int exit_code) {
-  _exit(exit_code);
-}
-
-bool Process::IsValid() const {
-  return process_.is_valid() || is_current();
-}
-
-ProcessHandle Process::Handle() const {
-  return is_current_process_ ? zx_process_self() : process_.get();
-}
-
-Process Process::Duplicate() const {
-  if (is_current())
-    return Current();
-
-  if (!IsValid())
-    return Process();
-
-  ScopedZxHandle out;
-  if (zx_handle_duplicate(process_.get(), ZX_RIGHT_SAME_RIGHTS,
-                          out.receive()) != ZX_OK) {
-    DLOG(ERROR) << "zx_handle_duplicate failed: " << process_.get();
-    return Process();
-  }
-
-  return Process(out.release());
-}
-
-ProcessId Process::Pid() const {
-  DCHECK(IsValid());
-  return GetProcId(Handle());
-}
-
-bool Process::is_current() const {
-  return is_current_process_;
-}
-
-void Process::Close() {
-  is_current_process_ = false;
-  process_.reset();
-}
-
-bool Process::Terminate(int exit_code, bool wait) const {
-  // exit_code isn't supportable. https://crbug.com/753490.
-  zx_status_t status = zx_task_kill(Handle());
-  // TODO(scottmg): Put these LOG/CHECK back to DLOG/DCHECK after
-  // https://crbug.com/750756 is diagnosed.
-  if (status == ZX_OK && wait) {
-    zx_signals_t signals;
-    status = zx_object_wait_one(Handle(), ZX_TASK_TERMINATED,
-                                zx_deadline_after(ZX_SEC(60)), &signals);
-    if (status != ZX_OK) {
-      LOG(ERROR) << "Error waiting for process exit: " << status;
-    } else {
-      CHECK(signals & ZX_TASK_TERMINATED);
-    }
-  } else if (status != ZX_OK) {
-    LOG(ERROR) << "Unable to terminate process: " << status;
-  }
-
-  return status >= 0;
-}
-
-bool Process::WaitForExit(int* exit_code) const {
-  return WaitForExitWithTimeout(TimeDelta::Max(), exit_code);
-}
-
-bool Process::WaitForExitWithTimeout(TimeDelta timeout, int* exit_code) const {
-  if (is_current_process_)
-    return false;
-
-  // Record the event that this thread is blocking upon (for hang diagnosis).
-  base::debug::ScopedProcessWaitActivity process_activity(this);
-
-  zx_time_t deadline = timeout == TimeDelta::Max()
-                           ? ZX_TIME_INFINITE
-                           : (TimeTicks::Now() + timeout).ToZxTime();
-  // TODO(scottmg): https://crbug.com/755282
-  const bool kOnBot = getenv("CHROME_HEADLESS") != nullptr;
-  if (kOnBot) {
-    LOG(ERROR) << base::StringPrintf(
-        "going to wait for process %x (deadline=%zu, now=%zu)", process_.get(),
-        deadline, TimeTicks::Now().ToZxTime());
-  }
-  zx_signals_t signals_observed = 0;
-  zx_status_t status = zx_object_wait_one(process_.get(), ZX_TASK_TERMINATED,
-                                          deadline, &signals_observed);
-
-  // TODO(scottmg): Make these LOGs into DLOGs after https://crbug.com/750756 is
-  // fixed.
-  if (status != ZX_OK && status != ZX_ERR_TIMED_OUT) {
-    LOG(ERROR) << "zx_object_wait_one failed, status=" << status;
-    return false;
-  }
-  if (status == ZX_ERR_TIMED_OUT) {
-    zx_time_t now = TimeTicks::Now().ToZxTime();
-    LOG(ERROR) << "zx_object_wait_one timed out, signals=" << signals_observed
-               << ", deadline=" << deadline << ", now=" << now
-               << ", delta=" << (now - deadline);
-    return false;
-  }
-
-  zx_info_process_t proc_info;
-  status = zx_object_get_info(process_.get(), ZX_INFO_PROCESS, &proc_info,
-                              sizeof(proc_info), nullptr, nullptr);
-  if (status != ZX_OK) {
-    LOG(ERROR) << "zx_object_get_info failed, status=" << status;
-    if (exit_code)
-      *exit_code = -1;
-    return false;
-  }
-
-  if (exit_code)
-    *exit_code = proc_info.return_code;
-
-  return true;
-}
-
-void Process::Exited(int exit_code) const {}
-
-bool Process::IsProcessBackgrounded() const {
-  // See SetProcessBackgrounded().
-  DCHECK(IsValid());
-  return false;
-}
-
-bool Process::SetProcessBackgrounded(bool value) {
-  // No process priorities on Fuchsia. TODO(fuchsia): See MG-783, and update
-  // this later if priorities are implemented.
-  return false;
-}
-
-int Process::GetPriority() const {
-  DCHECK(IsValid());
-  // No process priorities on Fuchsia.
-  return 0;
-}
-
-}  // namespace base
diff --git a/base/process/process_handle_fuchsia.cc b/base/process/process_handle_fuchsia.cc
deleted file mode 100644
index c9d2a8e..0000000
--- a/base/process/process_handle_fuchsia.cc
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/process/process_handle.h"
-
-#include <zircon/process.h>
-#include <zircon/status.h>
-#include <zircon/syscalls.h>
-
-#include "base/logging.h"
-
-namespace base {
-
-ProcessId GetCurrentProcId() {
-  return GetProcId(GetCurrentProcessHandle());
-}
-
-ProcessHandle GetCurrentProcessHandle() {
-  // Note that zx_process_self() returns a real handle, and ownership is not
-  // transferred to the caller (i.e. this should never be closed).
-  return zx_process_self();
-}
-
-ProcessId GetProcId(ProcessHandle process) {
-  zx_info_handle_basic_t basic;
-  zx_status_t status = zx_object_get_info(process, ZX_INFO_HANDLE_BASIC, &basic,
-                                          sizeof(basic), nullptr, nullptr);
-  if (status != ZX_OK) {
-    DLOG(ERROR) << "zx_object_get_info failed: "
-                << zx_status_get_string(status);
-    return ZX_KOID_INVALID;
-  }
-  return basic.koid;
-}
-
-}  // namespace base
diff --git a/base/process/process_iterator_fuchsia.cc b/base/process/process_iterator_fuchsia.cc
deleted file mode 100644
index 6d411ba..0000000
--- a/base/process/process_iterator_fuchsia.cc
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/process/process_iterator.h"
-
-namespace base {
-
-ProcessIterator::ProcessIterator(const ProcessFilter* filter) {
-  // TODO(fuchsia): There's no Fuchsia API to iterate processes currently.
-  NOTREACHED();
-}
-
-ProcessIterator::~ProcessIterator() {}
-
-bool ProcessIterator::CheckForNextProcess() {
-  // TODO(fuchsia): There's no Fuchsia API to iterate processes currently.
-  return false;
-}
-
-bool NamedProcessIterator::IncludeEntry() {
-  // TODO(fuchsia): There's no Fuchsia API to iterate processes currently.
-  return false;
-}
-
-}  // namespace base
diff --git a/base/process/process_metrics_fuchsia.cc b/base/process/process_metrics_fuchsia.cc
deleted file mode 100644
index a34dff7..0000000
--- a/base/process/process_metrics_fuchsia.cc
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/process/process_metrics.h"
-
-#include <fdio/limits.h>
-
-namespace base {
-
-size_t GetMaxFds() {
-  return FDIO_MAX_FD;
-}
-
-size_t GetSystemCommitCharge() {
-  // Not available, doesn't seem likely that it will be (for the whole system).
-  NOTIMPLEMENTED();
-  return 0;
-}
-
-// static
-std::unique_ptr<ProcessMetrics> ProcessMetrics::CreateProcessMetrics(
-    ProcessHandle process) {
-  NOTIMPLEMENTED();  // TODO(fuchsia): https://crbug.com/706592.
-  return nullptr;
-}
-
-TimeDelta ProcessMetrics::GetCumulativeCPUUsage() {
-  NOTIMPLEMENTED();  // TODO(fuchsia): https://crbug.com/706592.
-  return TimeDelta();
-}
-
-bool GetSystemMemoryInfo(SystemMemoryInfoKB* meminfo) {
-  NOTIMPLEMENTED();  // TODO(fuchsia): https://crbug.com/706592.
-  return false;
-}
-
-}  // namespace base
diff --git a/base/rand_util_fuchsia.cc b/base/rand_util_fuchsia.cc
deleted file mode 100644
index 5f991d5..0000000
--- a/base/rand_util_fuchsia.cc
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/rand_util.h"
-
-#include <zircon/syscalls.h>
-
-#include <algorithm>
-
-#include "base/logging.h"
-
-namespace base {
-
-void RandBytes(void* output, size_t output_length) {
-  size_t remaining = output_length;
-  unsigned char* cur = reinterpret_cast<unsigned char*>(output);
-  while (remaining > 0) {
-    // The syscall has a maximum number of bytes that can be read at once.
-    size_t read_len =
-        std::min(remaining, static_cast<size_t>(ZX_CPRNG_DRAW_MAX_LEN));
-
-    size_t actual;
-    zx_status_t status = zx_cprng_draw(cur, read_len, &actual);
-    CHECK(status == ZX_OK && read_len == actual);
-
-    CHECK(remaining >= actual);
-    remaining -= actual;
-    cur += actual;
-  }
-}
-
-}  // namespace base
diff --git a/base/sys_info_fuchsia.cc b/base/sys_info_fuchsia.cc
deleted file mode 100644
index 081a55d..0000000
--- a/base/sys_info_fuchsia.cc
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/sys_info.h"
-
-#include <zircon/syscalls.h>
-
-#include "base/logging.h"
-
-namespace base {
-
-// static
-int64_t SysInfo::AmountOfPhysicalMemoryImpl() {
-  return zx_system_get_physmem();
-}
-
-// static
-int64_t SysInfo::AmountOfAvailablePhysicalMemoryImpl() {
-  // TODO(fuchsia): https://crbug.com/706592 This is not exposed.
-  NOTREACHED();
-  return 0;
-}
-
-// static
-int SysInfo::NumberOfProcessors() {
-  return zx_system_get_num_cpus();
-}
-
-// static
-int64_t SysInfo::AmountOfVirtualMemory() {
-  return 0;
-}
-
-}  // namespace base
diff --git a/base/threading/platform_thread_fuchsia.cc b/base/threading/platform_thread_fuchsia.cc
deleted file mode 100644
index eb06795..0000000
--- a/base/threading/platform_thread_fuchsia.cc
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/threading/platform_thread.h"
-
-#include <pthread.h>
-#include <sched.h>
-#include <zircon/syscalls.h>
-
-#include "base/threading/platform_thread_internal_posix.h"
-#include "base/threading/thread_id_name_manager.h"
-
-namespace base {
-
-void InitThreading() {}
-
-void TerminateOnThread() {}
-
-size_t GetDefaultThreadStackSize(const pthread_attr_t& attributes) {
-  return 0;
-}
-
-// static
-void PlatformThread::SetName(const std::string& name) {
-  zx_status_t status = zx_object_set_property(CurrentId(), ZX_PROP_NAME,
-                                              name.data(), name.size());
-  DCHECK_EQ(status, ZX_OK);
-
-  ThreadIdNameManager::GetInstance()->SetName(name);
-}
-
-// static
-bool PlatformThread::CanIncreaseCurrentThreadPriority() {
-  return false;
-}
-
-// static
-void PlatformThread::SetCurrentThreadPriority(ThreadPriority priority) {
-  if (priority != ThreadPriority::NORMAL) {
-    NOTIMPLEMENTED() << "setting ThreadPriority " << static_cast<int>(priority);
-  }
-}
-
-// static
-ThreadPriority PlatformThread::GetCurrentThreadPriority() {
-  return ThreadPriority::NORMAL;
-}
-
-}  // namespace base
diff --git a/base/time/time_fuchsia.cc b/base/time/time_fuchsia.cc
deleted file mode 100644
index 8b658b4..0000000
--- a/base/time/time_fuchsia.cc
+++ /dev/null
@@ -1,93 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/time/time.h"
-
-#include <zircon/syscalls.h>
-
-#include "base/compiler_specific.h"
-#include "base/numerics/checked_math.h"
-#include "base/time/time_override.h"
-
-namespace base {
-
-namespace {
-
-// Helper function to map an unsigned integer with nanosecond timebase to a
-// signed integer with microsecond timebase.
-ALWAYS_INLINE int64_t ZxTimeToMicroseconds(zx_time_t nanos) {
-  const zx_time_t micros =
-      nanos / static_cast<zx_time_t>(base::Time::kNanosecondsPerMicrosecond);
-  return static_cast<int64_t>(micros);
-}
-
-}  // namespace
-
-// Time -----------------------------------------------------------------------
-
-namespace subtle {
-Time TimeNowIgnoringOverride() {
-  const zx_time_t nanos_since_unix_epoch = zx_clock_get(ZX_CLOCK_UTC);
-  CHECK(nanos_since_unix_epoch != 0);
-  // The following expression will overflow in the year 289938 A.D.:
-  return Time() + TimeDelta::FromMicroseconds(
-                      ZxTimeToMicroseconds(nanos_since_unix_epoch) +
-                      Time::kTimeTToMicrosecondsOffset);
-}
-
-Time TimeNowFromSystemTimeIgnoringOverride() {
-  // Just use TimeNowIgnoringOverride() because it returns the system time.
-  return TimeNowIgnoringOverride();
-}
-}  // namespace subtle
-
-// TimeTicks ------------------------------------------------------------------
-
-namespace subtle {
-TimeTicks TimeTicksNowIgnoringOverride() {
-  const zx_time_t nanos_since_boot = zx_clock_get(ZX_CLOCK_MONOTONIC);
-  CHECK(nanos_since_boot != 0);
-  return TimeTicks() +
-         TimeDelta::FromMicroseconds(ZxTimeToMicroseconds(nanos_since_boot));
-}
-}  // namespace subtle
-
-// static
-TimeTicks::Clock TimeTicks::GetClock() {
-  return Clock::FUCHSIA_ZX_CLOCK_MONOTONIC;
-}
-
-// static
-bool TimeTicks::IsHighResolution() {
-  return true;
-}
-
-// static
-bool TimeTicks::IsConsistentAcrossProcesses() {
-  return true;
-}
-
-// static
-TimeTicks TimeTicks::FromZxTime(zx_time_t nanos_since_boot) {
-  return TimeTicks(ZxTimeToMicroseconds(nanos_since_boot));
-}
-
-zx_time_t TimeTicks::ToZxTime() const {
-  CheckedNumeric<zx_time_t> result(base::Time::kNanosecondsPerMicrosecond);
-  result *= us_;
-  return result.ValueOrDie();
-}
-
-// ThreadTicks ----------------------------------------------------------------
-
-namespace subtle {
-ThreadTicks ThreadTicksNowIgnoringOverride() {
-  const zx_time_t nanos_since_thread_started = zx_clock_get(ZX_CLOCK_THREAD);
-  CHECK(nanos_since_thread_started != 0);
-  return ThreadTicks() + TimeDelta::FromMicroseconds(
-                             ZxTimeToMicroseconds(nanos_since_thread_started));
-}
-}  // namespace subtle
-
-}  // namespace base
