From e6cf7fb1960f544357925fed03e6c738e678f89b Mon Sep 17 00:00:00 2001
From: Vaibhav Rustagi <vaibhavrustagi@google.com>
Date: Tue, 21 Sep 2021 09:57:31 -0700
Subject: [PATCH] libbrillo: remove glib usage

We're ugprading glib to latest 2.68 which causes an API
breakage and considering it is not used anymore in favor
of libchrome, we drop glib support instead of fixing it.

ChromeOS Reference: https://chromium-review.googlesource.com/c/chromiumos/platform2/+/3103795/

Change-Id: I357b04beb1a4042e3d369189c56e4ddcb536ec08
---
 BUILD.gn                            |  42 --
 brillo/glib/README.md               |   5 -
 brillo/glib/abstract_dbus_service.cc      |  33 --
 brillo/glib/abstract_dbus_service.h |  50 --
 brillo/glib/dbus.cc                 | 331 ------------
 brillo/glib/dbus.h                  | 450 -----------------
 brillo/glib/object.h                | 469 ------------------
 brillo/glib/object_test.cc          | 132 -----
 8 files changed, 1512 deletions(-)
 delete mode 100644 brillo/glib/README.md
 delete mode 100644 brillo/glib/abstract_dbus_service.cc
 delete mode 100644 brillo/glib/abstract_dbus_service.h
 delete mode 100644 brillo/glib/dbus.cc
 delete mode 100644 brillo/glib/dbus.h
 delete mode 100644 brillo/glib/object.h
 delete mode 100644 brillo/glib/object_test.cc

diff --git a/BUILD.gn b/BUILD.gn
index 7b2073b451..b263e02074 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -9,7 +9,6 @@ import("//common-mk/proto_library.gni")
 group("all") {
   deps = [
     ":libbrillo",
-    ":libbrillo-glib",
     ":libbrillo-test",
     ":libinstallattributes",
     ":libpolicy",
@@ -392,45 +391,6 @@ shared_library("libpolicy") {
   ]
 }
 
-libbrillo_glib_pkg_deps = [
-  "glib-2.0",
-  "gobject-2.0",
-]
-if (use.dbus) {
-  libbrillo_glib_pkg_deps += [
-    "dbus-1",
-    "dbus-glib-1",
-  ]
-}
-
-generate_pkg_config("libbrillo-glib_pc") {
-  name = "libbrillo-glib"
-  output_name = "libbrillo-glib"
-  description = "brillo glib wrapper library"
-  version = libbase_ver
-  requires_private = libbrillo_glib_pkg_deps
-  libs = [ "-lbrillo-glib" ]
-}
-
-shared_library("libbrillo-glib") {
-  configs += [ ":target_defaults" ]
-  cflags = [
-    # glib uses the deprecated "register" attribute in some header files.
-    "-Wno-deprecated-register",
-  ]
-  deps = [
-    ":libbrillo",
-    ":libbrillo-glib_pc",
-  ]
-  all_dependent_pkg_deps = libbrillo_glib_pkg_deps
-  if (use.dbus) {
-    sources = [
-      "brillo/glib/abstract_dbus_service.cc",
-      "brillo/glib/dbus.cc",
-    ]
-  }
-}
-
 if (use.test) {
   static_library("libbrillo_static") {
     configs += [ ":target_defaults" ]
@@ -469,7 +429,6 @@ if (use.test) {
       "brillo/files/file_util_test.cc",
       "brillo/files/safe_fd_test.cc",
       "brillo/flag_helper_test.cc",
-      "brillo/glib/object_test.cc",
       "brillo/http/http_connection_curl_test.cc",
       "brillo/http/http_form_data_test.cc",
       "brillo/http/http_request_test.cc",
@@ -537,7 +496,6 @@ if (use.test) {
     cflags = [ "-Wno-format-zero-length" ]
     pkg_deps = [ "libchrome-test" ]
     deps = [
-      ":libbrillo-glib",
       ":libbrillo-test",
       ":libbrillo_static",
       ":libbrillo_tests_proto",
diff --git a/brillo/glib/README.md b/brillo/glib/README.md
deleted file mode 100644
index ef9ec9ee85..0000000000
--- a/brillo/glib/README.md
+++ /dev/null
@@ -1,5 +0,0 @@
-# libbrillo GLib support
-
-GLib is deprecated in Chrome OS. Use [libchrome] instead.
-
-[libchrome]: ../../../libchrome
diff --git a/brillo/glib/abstract_dbus_service.cc b/brillo/glib/abstract_dbus_service.cc
deleted file mode 100644
index 4f3869715e..0000000000
--- a/brillo/glib/abstract_dbus_service.cc
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright (c) 2010 The Chromium OS 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/logging.h>
-
-#include "brillo/glib/abstract_dbus_service.h"
-
-namespace brillo {
-namespace dbus {
-
-bool AbstractDbusService::Register(const brillo::dbus::BusConnection& conn) {
-  return RegisterExclusiveService(conn, service_interface(), service_name(),
-                                  service_path(), service_object());
-}
-
-bool AbstractDbusService::Run() {
-  if (!main_loop()) {
-    LOG(ERROR) << "No run loop. Call Initialize before use.";
-    return false;
-  }
-  ::g_main_loop_run(main_loop());
-  DLOG(INFO) << "Run() completed";
-  return true;
-}
-
-bool AbstractDbusService::Shutdown() {
-  ::g_main_loop_quit(main_loop());
-  return true;
-}
-
-}  // namespace dbus
-}  // namespace brillo
diff --git a/brillo/glib/abstract_dbus_service.h b/brillo/glib/abstract_dbus_service.h
deleted file mode 100644
index 32725c71bf..0000000000
--- a/brillo/glib/abstract_dbus_service.h
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright (c) 2010 The Chromium OS 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 LIBBRILLO_BRILLO_GLIB_ABSTRACT_DBUS_SERVICE_H_
-#define LIBBRILLO_BRILLO_GLIB_ABSTRACT_DBUS_SERVICE_H_
-
-// IMPORTANT: Do not use this in new code. Instead, use
-// <brillo/daemons/dbus_daemon.h>. See https://goo.gl/EH3MmR for more details.
-
-#include <brillo/brillo_export.h>
-#include <brillo/glib/dbus.h>
-
-namespace brillo {
-
-namespace dbus {
-class BRILLO_EXPORT AbstractDbusService {
- public:
-  virtual ~AbstractDbusService() {}
-
-  // Setup the wrapped GObject and the GMainLoop
-  virtual bool Initialize() = 0;
-  virtual bool Reset() = 0;
-
-  // Registers the GObject as a service with the system DBus
-  // TODO(wad) make this testable by making BusConn and Proxy
-  //           subclassing friendly.
-  virtual bool Register(const brillo::dbus::BusConnection& conn);
-
-  // Starts the run loop
-  virtual bool Run();
-
-  // Stops the run loop
-  virtual bool Shutdown();
-
-  // Used internally during registration to set the
-  // proper service information.
-  virtual const char* service_name() const = 0;
-  virtual const char* service_path() const = 0;
-  virtual const char* service_interface() const = 0;
-  virtual GObject* service_object() const = 0;
-
- protected:
-  virtual GMainLoop* main_loop() = 0;
-};
-
-}  // namespace dbus
-}  // namespace brillo
-
-#endif  // LIBBRILLO_BRILLO_GLIB_ABSTRACT_DBUS_SERVICE_H_
diff --git a/brillo/glib/dbus.cc b/brillo/glib/dbus.cc
deleted file mode 100644
index 7525adfdfa..0000000000
--- a/brillo/glib/dbus.cc
+++ /dev/null
@@ -1,331 +0,0 @@
-// Copyright (c) 2009 The Chromium OS 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 "brillo/glib/dbus.h"
-
-#include <base/check.h>
-#include <dbus/dbus.h>
-#include <dbus/dbus-glib-bindings.h>
-#include <dbus/dbus-glib-lowlevel.h>
-
-#include <base/logging.h>
-#include <base/strings/stringprintf.h>
-
-namespace brillo {
-namespace dbus {
-
-bool CallPtrArray(const Proxy& proxy,
-                  const char* method,
-                  glib::ScopedPtrArray<const char*>* result) {
-  glib::ScopedError error;
-
-  ::GType g_type_array =
-      ::dbus_g_type_get_collection("GPtrArray", DBUS_TYPE_G_OBJECT_PATH);
-
-  if (!::dbus_g_proxy_call(proxy.gproxy(), method, &Resetter(&error).lvalue(),
-                           G_TYPE_INVALID, g_type_array,
-                           &Resetter(result).lvalue(), G_TYPE_INVALID)) {
-    LOG(WARNING) << "CallPtrArray failed: "
-                 << (error->message ? error->message : "Unknown Error.");
-    return false;
-  }
-
-  return true;
-}
-
-BusConnection GetSystemBusConnection() {
-  glib::ScopedError error;
-  ::DBusGConnection* result =
-      ::dbus_g_bus_get(DBUS_BUS_SYSTEM, &Resetter(&error).lvalue());
-  if (!result) {
-    LOG(ERROR) << "dbus_g_bus_get(DBUS_BUS_SYSTEM) failed: "
-               << ((error.get() && error->message) ? error->message
-                                                   : "Unknown Error");
-    return BusConnection(nullptr);
-  }
-  // Set to not exit when system bus is disconnected.
-  // This fixes the problem where when the dbus daemon is stopped, exit is
-  // called which kills Chrome.
-  ::dbus_connection_set_exit_on_disconnect(
-      ::dbus_g_connection_get_connection(result), FALSE);
-  return BusConnection(result);
-}
-
-BusConnection GetPrivateBusConnection(const char* address) {
-  // Since dbus-glib does not have an API like dbus_g_connection_open_private(),
-  // we have to implement our own.
-
-  // We have to call _dbus_g_value_types_init() to register standard marshalers
-  // just like as dbus_g_bus_get() and dbus_g_connection_open() do, but the
-  // function is not exported. So we call GetPrivateBusConnection() which calls
-  // dbus_g_bus_get() here instead. Note that if we don't call
-  // _dbus_g_value_types_init(), we might get "WARNING **: No demarshaller
-  // registered for type xxxxx" error and might not be able to handle incoming
-  // signals nor method calls.
-  {
-    BusConnection system_bus_connection = GetSystemBusConnection();
-    if (!system_bus_connection.HasConnection()) {
-      return system_bus_connection;  // returns NULL connection.
-    }
-  }
-
-  ::DBusError error;
-  ::dbus_error_init(&error);
-
-  ::DBusGConnection* result = nullptr;
-  ::DBusConnection* raw_connection =
-      ::dbus_connection_open_private(address, &error);
-  if (!raw_connection) {
-    LOG(WARNING) << "dbus_connection_open_private failed: " << address;
-    return BusConnection(nullptr);
-  }
-
-  if (!::dbus_bus_register(raw_connection, &error)) {
-    LOG(ERROR) << "dbus_bus_register failed: "
-               << (error.message ? error.message : "Unknown Error.");
-    ::dbus_error_free(&error);
-    // TODO(yusukes): We don't call dbus_connection_close() nor g_object_unref()
-    // here for now since these calls might interfere with IBusBus connections
-    // in libcros and Chrome. See the comment in ~InputMethodStatusConnection()
-    // function in platform/cros/chromeos_input_method.cc for details.
-    return BusConnection(nullptr);
-  }
-
-  ::dbus_connection_setup_with_g_main(raw_connection,
-                                      nullptr /* default context */);
-
-  // A reference count of |raw_connection| is transferred to |result|. You don't
-  // have to (and should not) unref the |raw_connection|.
-  result = ::dbus_connection_get_g_connection(raw_connection);
-  CHECK(result);
-
-  ::dbus_connection_set_exit_on_disconnect(
-      ::dbus_g_connection_get_connection(result), FALSE);
-
-  return BusConnection(result);
-}
-
-bool RetrieveProperties(const Proxy& proxy,
-                        const char* interface,
-                        glib::ScopedHashTable* result) {
-  glib::ScopedError error;
-
-  if (!::dbus_g_proxy_call(
-          proxy.gproxy(), "GetAll", &Resetter(&error).lvalue(), G_TYPE_STRING,
-          interface, G_TYPE_INVALID,
-          ::dbus_g_type_get_map("GHashTable", G_TYPE_STRING, G_TYPE_VALUE),
-          &Resetter(result).lvalue(), G_TYPE_INVALID)) {
-    LOG(WARNING) << "RetrieveProperties failed: "
-                 << (error->message ? error->message : "Unknown Error.");
-    return false;
-  }
-  return true;
-}
-
-Proxy::Proxy() : object_(nullptr) {}
-
-// Set |connect_to_name_owner| true if you'd like to use
-// dbus_g_proxy_new_for_name_owner() rather than dbus_g_proxy_new_for_name().
-Proxy::Proxy(const BusConnection& connection,
-             const char* name,
-             const char* path,
-             const char* interface,
-             bool connect_to_name_owner)
-    : object_(GetGProxy(
-          connection, name, path, interface, connect_to_name_owner)) {}
-
-// Equivalent to Proxy(connection, name, path, interface, false).
-Proxy::Proxy(const BusConnection& connection,
-             const char* name,
-             const char* path,
-             const char* interface)
-    : object_(GetGProxy(connection, name, path, interface, false)) {}
-
-// Creates a peer proxy using dbus_g_proxy_new_for_peer.
-Proxy::Proxy(const BusConnection& connection,
-             const char* path,
-             const char* interface)
-    : object_(GetGPeerProxy(connection, path, interface)) {}
-
-Proxy::Proxy(const Proxy& x) : object_(x.object_) {
-  if (object_)
-    ::g_object_ref(object_);
-}
-
-Proxy::~Proxy() {
-  if (object_)
-    ::g_object_unref(object_);
-}
-
-/* static */
-Proxy::value_type Proxy::GetGProxy(const BusConnection& connection,
-                                   const char* name,
-                                   const char* path,
-                                   const char* interface,
-                                   bool connect_to_name_owner) {
-  value_type result = nullptr;
-  if (connect_to_name_owner) {
-    glib::ScopedError error;
-    result = ::dbus_g_proxy_new_for_name_owner(
-        connection.object_, name, path, interface, &Resetter(&error).lvalue());
-    if (!result) {
-      DLOG(ERROR) << "Failed to construct proxy: "
-                  << (error->message ? error->message : "Unknown Error") << ": "
-                  << path;
-    }
-  } else {
-    result =
-        ::dbus_g_proxy_new_for_name(connection.object_, name, path, interface);
-    if (!result) {
-      LOG(ERROR) << "Failed to construct proxy: " << path;
-    }
-  }
-  return result;
-}
-
-/* static */
-Proxy::value_type Proxy::GetGPeerProxy(const BusConnection& connection,
-                                       const char* path,
-                                       const char* interface) {
-  value_type result =
-      ::dbus_g_proxy_new_for_peer(connection.object_, path, interface);
-  if (!result)
-    LOG(ERROR) << "Failed to construct peer proxy: " << path;
-
-  return result;
-}
-
-bool RegisterExclusiveService(const BusConnection& connection,
-                              const char* interface_name,
-                              const char* service_name,
-                              const char* service_path,
-                              GObject* object) {
-  CHECK(object);
-  CHECK(interface_name);
-  CHECK(service_name);
-  // Create a proxy to DBus itself so that we can request to become a
-  // service name owner and then register an object at the related service path.
-  Proxy proxy = brillo::dbus::Proxy(connection, DBUS_SERVICE_DBUS,
-                                    DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS);
-  // Exclusivity is determined by replacing any existing
-  // service, not queuing, and ensuring we are the primary
-  // owner after the name is ours.
-  glib::ScopedError err;
-  guint result = 0;
-  // TODO(wad) determine if we are moving away from using generated functions
-  if (!org_freedesktop_DBus_request_name(proxy.gproxy(), service_name, 0,
-                                         &result, &Resetter(&err).lvalue())) {
-    LOG(ERROR) << "Unable to request service name: "
-               << (err->message ? err->message : "Unknown Error.");
-    return false;
-  }
-
-  // Handle the error codes, releasing the name if exclusivity conditions
-  // are not met.
-  bool needs_release = false;
-  if (result != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
-    LOG(ERROR) << "Failed to become the primary owner. Releasing . . .";
-    needs_release = true;
-  }
-  if (result == DBUS_REQUEST_NAME_REPLY_EXISTS) {
-    LOG(ERROR) << "Service name exists: " << service_name;
-    return false;
-  } else if (result == DBUS_REQUEST_NAME_REPLY_IN_QUEUE) {
-    LOG(ERROR) << "Service name request enqueued despite our flags. Releasing";
-    needs_release = true;
-  }
-  LOG_IF(WARNING, result == DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER)
-      << "Service name already owned by this process";
-  if (needs_release) {
-    if (!org_freedesktop_DBus_release_name(proxy.gproxy(), service_name,
-                                           &result, &Resetter(&err).lvalue())) {
-      LOG(ERROR) << "Unabled to release service name: "
-                 << (err->message ? err->message : "Unknown Error.");
-    }
-    DLOG(INFO) << "ReleaseName returned code " << result;
-    return false;
-  }
-
-  // Determine a path from the service name and register the object.
-  dbus_g_connection_register_g_object(connection.g_connection(), service_path,
-                                      object);
-  return true;
-}
-
-void CallMethodWithNoArguments(const char* service_name,
-                               const char* path,
-                               const char* interface_name,
-                               const char* method_name) {
-  Proxy proxy(dbus::GetSystemBusConnection(), service_name, path,
-              interface_name);
-  ::dbus_g_proxy_call_no_reply(proxy.gproxy(), method_name, G_TYPE_INVALID);
-}
-
-void SignalWatcher::StartMonitoring(const std::string& interface,
-                                    const std::string& signal) {
-  DCHECK(interface_.empty()) << "StartMonitoring() must be called only once";
-  interface_ = interface;
-  signal_ = signal;
-
-  // Snoop on D-Bus messages so we can get notified about signals.
-  DBusConnection* dbus_conn =
-      dbus_g_connection_get_connection(GetSystemBusConnection().g_connection());
-  DCHECK(dbus_conn);
-
-  DBusError error;
-  dbus_error_init(&error);
-  dbus_bus_add_match(dbus_conn, GetDBusMatchString().c_str(), &error);
-  if (dbus_error_is_set(&error)) {
-    LOG(DFATAL) << "Got error while adding D-Bus match rule: " << error.name
-                << " (" << error.message << ")";
-  }
-
-  if (!dbus_connection_add_filter(dbus_conn, &SignalWatcher::FilterDBusMessage,
-                                  this,        // user_data
-                                  nullptr)) {  // free_data_function
-    LOG(DFATAL) << "Unable to add D-Bus filter";
-  }
-}
-
-SignalWatcher::~SignalWatcher() {
-  if (interface_.empty())
-    return;
-
-  DBusConnection* dbus_conn = dbus_g_connection_get_connection(
-      dbus::GetSystemBusConnection().g_connection());
-  DCHECK(dbus_conn);
-
-  dbus_connection_remove_filter(dbus_conn, &SignalWatcher::FilterDBusMessage,
-                                this);
-
-  DBusError error;
-  dbus_error_init(&error);
-  dbus_bus_remove_match(dbus_conn, GetDBusMatchString().c_str(), &error);
-  if (dbus_error_is_set(&error)) {
-    LOG(DFATAL) << "Got error while removing D-Bus match rule: " << error.name
-                << " (" << error.message << ")";
-  }
-}
-
-std::string SignalWatcher::GetDBusMatchString() const {
-  return base::StringPrintf("type='signal', interface='%s', member='%s'",
-                            interface_.c_str(), signal_.c_str());
-}
-
-/* static */
-DBusHandlerResult SignalWatcher::FilterDBusMessage(DBusConnection* dbus_conn,
-                                                   DBusMessage* message,
-                                                   void* data) {
-  SignalWatcher* self = static_cast<SignalWatcher*>(data);
-  if (dbus_message_is_signal(message, self->interface_.c_str(),
-                             self->signal_.c_str())) {
-    self->OnSignal(message);
-    return DBUS_HANDLER_RESULT_HANDLED;
-  } else {
-    return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
-  }
-}
-
-}  // namespace dbus
-}  // namespace brillo
diff --git a/brillo/glib/dbus.h b/brillo/glib/dbus.h
deleted file mode 100644
index 299d65159e..0000000000
--- a/brillo/glib/dbus.h
+++ /dev/null
@@ -1,450 +0,0 @@
-// Copyright (c) 2009 The Chromium OS 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 LIBBRILLO_BRILLO_GLIB_DBUS_H_
-#define LIBBRILLO_BRILLO_GLIB_DBUS_H_
-
-// IMPORTANT: Do not use this in new code. Instead, use libchrome's D-Bus
-// bindings. See https://goo.gl/EH3MmR for more details.
-
-#include <base/check.h>
-#include <dbus/dbus-glib.h>
-#include <glib-object.h>
-
-#include <algorithm>
-#include <string>
-#include <utility>
-
-#include "base/logging.h"
-#include <brillo/brillo_export.h>
-#include <brillo/glib/object.h>
-
-struct DBusMessage;
-struct DBusConnection;
-
-namespace brillo {
-
-namespace dbus {
-
-// \brief   BusConnection manages the ref-count for a ::DBusGConnection*.
-//
-// A BusConnection has reference semantics bound to a particular communication
-// bus.
-//
-// \models Copyable, Assignable
-// \related GetSystemBusConnection()
-
-class BRILLO_EXPORT BusConnection {
- public:
-  typedef ::DBusGConnection* value_type;
-
-  BusConnection(const BusConnection& x) : object_(x.object_) {
-    if (object_)
-      ::dbus_g_connection_ref(object_);
-  }
-
-  ~BusConnection() {
-    if (object_)
-      ::dbus_g_connection_unref(object_);
-  }
-
-  BusConnection& operator=(BusConnection x) {
-    swap(*this, x);
-    return *this;
-  }
-
-  const value_type& g_connection() const {
-    DCHECK(object_) << "referencing an empty connection";
-    return object_;
-  }
-
-  operator bool() const { return object_; }
-
-  bool HasConnection() const { return object_; }
-
- private:
-  friend void swap(BusConnection& x, BusConnection& y);
-
-  friend class Proxy;
-  friend BusConnection GetSystemBusConnection();
-  friend BusConnection GetPrivateBusConnection(const char* address);
-
-  // Constructor takes ownership
-  BRILLO_PRIVATE explicit BusConnection(::DBusGConnection* x) : object_(x) {}
-
-  value_type object_;
-};
-
-inline void swap(BusConnection& x, BusConnection& y) {
-  std::swap(x.object_, y.object_);
-}
-
-// \brief Proxy manages the ref-count for a ::DBusGProxy*.
-//
-// Proxy has reference semantics and represents a connection to on object on
-// the bus. A proxy object is constructed with a connection to a bus, a name
-// to an entity on the bus, a path to an object owned by the entity, and an
-// interface protocol name used to communicate with the object.
-
-class BRILLO_EXPORT Proxy {
- public:
-  typedef ::DBusGProxy* value_type;
-
-  Proxy();
-
-  // Set |connect_to_name_owner| true if you'd like to use
-  // dbus_g_proxy_new_for_name_owner() rather than dbus_g_proxy_new_for_name().
-  Proxy(const BusConnection& connection,
-        const char* name,
-        const char* path,
-        const char* interface,
-        bool connect_to_name_owner);
-
-  // Equivalent to Proxy(connection, name, path, interface, false).
-  Proxy(const BusConnection& connection,
-        const char* name,
-        const char* path,
-        const char* interface);
-
-  // Creates a peer proxy using dbus_g_proxy_new_for_peer.
-  Proxy(const BusConnection& connection,
-        const char* path,
-        const char* interface);
-
-  Proxy(const Proxy& x);
-
-  ~Proxy();
-
-  Proxy& operator=(Proxy x) {
-    swap(*this, x);
-    return *this;
-  }
-
-  const char* path() const {
-    DCHECK(object_) << "referencing an empty proxy";
-    return ::dbus_g_proxy_get_path(object_);
-  }
-
-  // gproxy() returns a reference to the underlying ::DBusGProxy*. As this
-  // library evolves, the gproxy() will be moved to be private.
-
-  const value_type& gproxy() const {
-    DCHECK(object_) << "referencing an empty proxy";
-    return object_;
-  }
-
-  operator bool() const { return object_; }
-
- private:
-  BRILLO_PRIVATE static value_type GetGProxy(const BusConnection& connection,
-                                             const char* name,
-                                             const char* path,
-                                             const char* interface,
-                                             bool connect_to_name_owner);
-
-  BRILLO_PRIVATE static value_type GetGPeerProxy(
-      const BusConnection& connection, const char* path, const char* interface);
-
-  BRILLO_PRIVATE operator int() const;  // for safe bool cast
-  friend void swap(Proxy& x, Proxy& y);
-
-  value_type object_;
-};
-
-inline void swap(Proxy& x, Proxy& y) {
-  std::swap(x.object_, y.object_);
-}
-
-// \brief RegisterExclusiveService configures a GObject to run as a service on
-//  a supplied ::BusConnection.
-//
-//  RegisterExclusiveService encapsulates the process of configuring the
-//  supplied \param object at \param service_path on the \param connection.
-//  Exclusivity is ensured by replacing any existing services at that named
-//  location and confirming that the connection is the primary owner.
-//
-//  Type information for the \param object must be installed with
-//  dbus_g_object_type_install_info prior to use.
-
-BRILLO_EXPORT bool RegisterExclusiveService(const BusConnection& connection,
-                                            const char* interface_name,
-                                            const char* service_name,
-                                            const char* service_path,
-                                            GObject* object);
-
-template <typename F>  // F is a function signature
-class MonitorConnection;
-
-template <typename A1>
-class MonitorConnection<void(A1)> {
- public:
-  MonitorConnection(const Proxy& proxy,
-                    const char* name,
-                    void (*monitor)(void*, A1),
-                    void* object)
-      : proxy_(proxy), name_(name), monitor_(monitor), object_(object) {}
-
-  static void Run(::DBusGProxy*, A1 x, MonitorConnection* self) {
-    self->monitor_(self->object_, x);
-  }
-  const Proxy& proxy() const { return proxy_; }
-  const std::string& name() const { return name_; }
-
- private:
-  Proxy proxy_;
-  std::string name_;
-  void (*monitor_)(void*, A1);
-  void* object_;
-};
-
-template <typename A1, typename A2>
-class MonitorConnection<void(A1, A2)> {
- public:
-  MonitorConnection(const Proxy& proxy,
-                    const char* name,
-                    void (*monitor)(void*, A1, A2),
-                    void* object)
-      : proxy_(proxy), name_(name), monitor_(monitor), object_(object) {}
-
-  static void Run(::DBusGProxy*, A1 x, A2 y, MonitorConnection* self) {
-    self->monitor_(self->object_, x, y);
-  }
-  const Proxy& proxy() const { return proxy_; }
-  const std::string& name() const { return name_; }
-
- private:
-  Proxy proxy_;
-  std::string name_;
-  void (*monitor_)(void*, A1, A2);
-  void* object_;
-};
-
-template <typename A1, typename A2, typename A3>
-class MonitorConnection<void(A1, A2, A3)> {
- public:
-  MonitorConnection(const Proxy& proxy,
-                    const char* name,
-                    void (*monitor)(void*, A1, A2, A3),
-                    void* object)
-      : proxy_(proxy), name_(name), monitor_(monitor), object_(object) {}
-
-  static void Run(::DBusGProxy*, A1 x, A2 y, A3 z, MonitorConnection* self) {
-    self->monitor_(self->object_, x, y, z);
-  }
-  const Proxy& proxy() const { return proxy_; }
-  const std::string& name() const { return name_; }
-
- private:
-  Proxy proxy_;
-  std::string name_;
-  void (*monitor_)(void*, A1, A2, A3);
-  void* object_;
-};
-
-template <typename A1, typename A2, typename A3, typename A4>
-class MonitorConnection<void(A1, A2, A3, A4)> {
- public:
-  MonitorConnection(const Proxy& proxy,
-                    const char* name,
-                    void (*monitor)(void*, A1, A2, A3, A4),
-                    void* object)
-      : proxy_(proxy), name_(name), monitor_(monitor), object_(object) {}
-
-  static void Run(
-      ::DBusGProxy*, A1 x, A2 y, A3 z, A4 w, MonitorConnection* self) {
-    self->monitor_(self->object_, x, y, z, w);
-  }
-  const Proxy& proxy() const { return proxy_; }
-  const std::string& name() const { return name_; }
-
- private:
-  Proxy proxy_;
-  std::string name_;
-  void (*monitor_)(void*, A1, A2, A3, A4);
-  void* object_;
-};
-
-template <typename A1>
-MonitorConnection<void(A1)>* Monitor(const Proxy& proxy,
-                                     const char* name,
-                                     void (*monitor)(void*, A1),
-                                     void* object) {
-  typedef MonitorConnection<void(A1)> ConnectionType;
-
-  ConnectionType* result = new ConnectionType(proxy, name, monitor, object);
-
-  ::dbus_g_proxy_add_signal(proxy.gproxy(), name, glib::type_to_gtypeid<A1>(),
-                            G_TYPE_INVALID);
-  ::dbus_g_proxy_connect_signal(
-      proxy.gproxy(), name, G_CALLBACK(&ConnectionType::Run), result, nullptr);
-  return result;
-}
-
-template <typename A1, typename A2>
-MonitorConnection<void(A1, A2)>* Monitor(const Proxy& proxy,
-                                         const char* name,
-                                         void (*monitor)(void*, A1, A2),
-                                         void* object) {
-  typedef MonitorConnection<void(A1, A2)> ConnectionType;
-
-  ConnectionType* result = new ConnectionType(proxy, name, monitor, object);
-
-  ::dbus_g_proxy_add_signal(proxy.gproxy(), name, glib::type_to_gtypeid<A1>(),
-                            glib::type_to_gtypeid<A2>(), G_TYPE_INVALID);
-  ::dbus_g_proxy_connect_signal(
-      proxy.gproxy(), name, G_CALLBACK(&ConnectionType::Run), result, nullptr);
-  return result;
-}
-
-template <typename A1, typename A2, typename A3>
-MonitorConnection<void(A1, A2, A3)>* Monitor(const Proxy& proxy,
-                                             const char* name,
-                                             void (*monitor)(void*, A1, A2, A3),
-                                             void* object) {
-  typedef MonitorConnection<void(A1, A2, A3)> ConnectionType;
-
-  ConnectionType* result = new ConnectionType(proxy, name, monitor, object);
-
-  ::dbus_g_proxy_add_signal(proxy.gproxy(), name, glib::type_to_gtypeid<A1>(),
-                            glib::type_to_gtypeid<A2>(),
-                            glib::type_to_gtypeid<A3>(), G_TYPE_INVALID);
-  ::dbus_g_proxy_connect_signal(
-      proxy.gproxy(), name, G_CALLBACK(&ConnectionType::Run), result, nullptr);
-  return result;
-}
-
-template <typename A1, typename A2, typename A3, typename A4>
-MonitorConnection<void(A1, A2, A3, A4)>* Monitor(
-    const Proxy& proxy,
-    const char* name,
-    void (*monitor)(void*, A1, A2, A3, A4),
-    void* object) {
-  typedef MonitorConnection<void(A1, A2, A3, A4)> ConnectionType;
-
-  ConnectionType* result = new ConnectionType(proxy, name, monitor, object);
-
-  ::dbus_g_proxy_add_signal(proxy.gproxy(), name, glib::type_to_gtypeid<A1>(),
-                            glib::type_to_gtypeid<A2>(),
-                            glib::type_to_gtypeid<A3>(),
-                            glib::type_to_gtypeid<A4>(), G_TYPE_INVALID);
-  ::dbus_g_proxy_connect_signal(
-      proxy.gproxy(), name, G_CALLBACK(&ConnectionType::Run), result, nullptr);
-  return result;
-}
-
-template <typename F>
-void Disconnect(MonitorConnection<F>* connection) {
-  typedef MonitorConnection<F> ConnectionType;
-
-  ::dbus_g_proxy_disconnect_signal(
-      connection->proxy().gproxy(), connection->name().c_str(),
-      G_CALLBACK(&ConnectionType::Run), connection);
-  delete connection;
-}
-
-// \brief call_PtrArray() invokes a method on a proxy returning a
-//  glib::PtrArray.
-//
-// CallPtrArray is the first instance of what is likely to be a general
-// way to make method calls to a proxy. It will likely be replaced with
-// something like Call(proxy, method, arg1, arg2, ..., ResultType*) in the
-// future. However, I don't yet have enough cases to generalize from.
-
-BRILLO_EXPORT bool CallPtrArray(const Proxy& proxy,
-                                const char* method,
-                                glib::ScopedPtrArray<const char*>* result);
-
-// \brief RetrieveProperty() retrieves a property of an object associated with a
-//  proxy.
-//
-// Given a proxy to an object supporting the org.freedesktop.DBus.Properties
-// interface, the RetrieveProperty() call will retrieve a property of the
-// specified interface on the object storing it in \param result and returning
-// \true. If the dbus call fails or the object returned is not of type \param T,
-// then \false is returned and \param result is unchanged.
-//
-// \example
-// Proxy proxy(GetSystemBusConnection(),
-//             "org.freedesktop.DeviceKit.Power", // A named entity on the bus
-//             battery_name,  // Path to a battery on the bus
-//             "org.freedesktop.DBus.Properties") // Properties interface
-//
-// double x;
-// if (RetrieveProperty(proxy,
-//                      "org.freedesktop.DeviceKit.Power.Device",
-//                      "percentage")
-//   std::cout << "Battery charge is " << x << "% of capacity.";
-// \end_example
-
-template <typename T>
-inline bool RetrieveProperty(const Proxy& proxy,
-                             const char* interface,
-                             const char* property,
-                             T* result) {
-  glib::ScopedError error;
-  glib::Value value;
-
-  if (!::dbus_g_proxy_call(proxy.gproxy(), "Get", &Resetter(&error).lvalue(),
-                           G_TYPE_STRING, interface, G_TYPE_STRING, property,
-                           G_TYPE_INVALID, G_TYPE_VALUE, &value,
-                           G_TYPE_INVALID)) {
-    LOG(ERROR) << "Getting property failed: "
-               << (error->message ? error->message : "Unknown Error.");
-    return false;
-  }
-  return glib::Retrieve(value, result);
-}
-
-// \brief RetrieveProperties returns a HashTable of all properties for the
-// specified interface.
-
-BRILLO_EXPORT bool RetrieveProperties(const Proxy& proxy,
-                                      const char* interface,
-                                      glib::ScopedHashTable* result);
-
-// \brief Returns a connection to the system bus.
-
-BRILLO_EXPORT BusConnection GetSystemBusConnection();
-
-// \brief Returns a private connection to a bus at |address|.
-
-BRILLO_EXPORT BusConnection GetPrivateBusConnection(const char* address);
-
-// \brief Calls a method |method_name| with no arguments per the given |path|
-// and |interface_name|.  Ignores return value.
-
-BRILLO_EXPORT void CallMethodWithNoArguments(const char* service_name,
-                                             const char* path,
-                                             const char* interface_name,
-                                             const char* method_name);
-
-// \brief Low-level signal monitor base class.
-//
-// Used when there is no definite named signal sender (that Proxy
-// could be used for).
-
-class BRILLO_EXPORT SignalWatcher {
- public:
-  SignalWatcher() {}
-  ~SignalWatcher();
-  void StartMonitoring(const std::string& interface, const std::string& signal);
-
- private:
-  // Callback invoked on the given signal arrival.
-  virtual void OnSignal(DBusMessage* message) = 0;
-
-  // Returns a string matching the D-Bus messages that we want to listen for.
-  BRILLO_PRIVATE std::string GetDBusMatchString() const;
-
-  // A D-Bus message filter to receive signals.
-  BRILLO_PRIVATE static DBusHandlerResult FilterDBusMessage(
-      DBusConnection* dbus_conn, DBusMessage* message, void* data);
-  std::string interface_;
-  std::string signal_;
-};
-
-}  // namespace dbus
-}  // namespace brillo
-
-#endif  // LIBBRILLO_BRILLO_GLIB_DBUS_H_
diff --git a/brillo/glib/object.h b/brillo/glib/object.h
deleted file mode 100644
index 87e5601648..0000000000
--- a/brillo/glib/object.h
+++ /dev/null
@@ -1,469 +0,0 @@
-// Copyright (c) 2009 The Chromium OS 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 LIBBRILLO_BRILLO_GLIB_OBJECT_H_
-#define LIBBRILLO_BRILLO_GLIB_OBJECT_H_
-
-#include <glib-object.h>
-#include <stdint.h>
-
-#include <algorithm>
-#include <cstddef>
-#include <memory>
-#include <string>
-#include <utility>
-
-#include <base/check.h>
-#include <base/logging.h>
-#include <base/macros.h>
-
-namespace brillo {
-
-namespace details {  // NOLINT
-
-// \brief ResetHelper is a private class for use with Resetter().
-//
-// ResetHelper passes ownership of a pointer to a scoped pointer type with reset
-// on destruction.
-
-template <typename T>  // T models ScopedPtr
-class ResetHelper {
- public:
-  typedef typename T::element_type element_type;
-
-  explicit ResetHelper(T* x) : ptr_(nullptr), scoped_(x) {}
-  ~ResetHelper() { scoped_->reset(ptr_); }
-  element_type*& lvalue() { return ptr_; }
-
- private:
-  element_type* ptr_;
-  T* scoped_;
-};
-
-}  // namespace details
-
-// \brief Resetter() is a utility function for passing pointers to
-//  scoped pointers.
-//
-// The Resetter() function return a temporary object containing an lvalue of
-// \code T::element_type which can be assigned to. When the temporary object
-// destructs, the associated scoped pointer is reset with the lvalue. It is of
-// general use when a pointer is returned as an out-argument.
-//
-// \example
-// void function(int** x) {
-//   *x = new int(10);
-// }
-// ...
-// std::unique_ptr<int> x;
-// function(Resetter(x).lvalue());
-//
-// \end_example
-
-template <typename T>  // T models ScopedPtr
-details::ResetHelper<T> Resetter(T* x) {
-  return details::ResetHelper<T>(x);
-}
-
-namespace glib {
-
-// \brief type_to_gtypeid is a type function mapping from a canonical type to
-// the GType typeid for the associated GType (see type_to_gtype).
-
-template <typename T>
-::GType type_to_gtypeid();
-
-template <>
-inline ::GType type_to_gtypeid<const char*>() {
-  return G_TYPE_STRING;
-}
-template <>
-inline ::GType type_to_gtypeid<char*>() {
-  return G_TYPE_STRING;
-}
-template <>
-inline ::GType type_to_gtypeid< ::uint8_t>() {
-  return G_TYPE_UCHAR;
-}
-template <>
-inline ::GType type_to_gtypeid<double>() {
-  return G_TYPE_DOUBLE;
-}
-template <>
-inline ::GType type_to_gtypeid<bool>() {
-  return G_TYPE_BOOLEAN;
-}
-class Value;
-template <>
-inline ::GType type_to_gtypeid<const Value*>() {
-  return G_TYPE_VALUE;
-}
-
-template <>
-inline ::GType type_to_gtypeid< ::uint32_t>() {
-  // REVISIT (seanparent) : There currently isn't any G_TYPE_UINT32, this code
-  // assumes sizeof(guint) == sizeof(guint32). Need a static_assert to assert
-  // that.
-  return G_TYPE_UINT;
-}
-
-template <>
-inline ::GType type_to_gtypeid< ::int64_t>() {
-  return G_TYPE_INT64;
-}
-
-template <>
-inline ::GType type_to_gtypeid< ::int32_t>() {
-  return G_TYPE_INT;
-}
-
-// \brief Value (and Retrieve) support using std::string as well as const char*
-// by promoting from const char* to the string. promote_from provides a mapping
-// for this promotion (and possibly others in the future).
-
-template <typename T>
-struct promotes_from {
-  typedef T type;
-};
-template <>
-struct promotes_from<std::string> {
-  typedef const char* type;
-};
-
-// \brief RawCast converts from a GValue to a value of a canonical type.
-//
-// RawCast is a low level function. Generally, use Cast() instead.
-//
-// \precondition \param x contains a value of type \param T.
-
-template <typename T>
-inline T RawCast(const ::GValue& x) {
-  // Use static_assert() to issue a meaningful compile-time error.
-  // To prevent this from happening for all references to RawCast, use sizeof(T)
-  // to make static_assert depend on type T and therefore prevent binding it
-  // unconditionally until the actual RawCast<T> instantiation happens.
-  static_assert(sizeof(T) == 0, "Using RawCast on unsupported type");
-  return T();
-}
-
-template <>
-inline const char* RawCast<const char*>(const ::GValue& x) {
-  return static_cast<const char*>(::g_value_get_string(&x));
-}
-template <>
-inline double RawCast<double>(const ::GValue& x) {
-  return static_cast<double>(::g_value_get_double(&x));
-}
-template <>
-inline bool RawCast<bool>(const ::GValue& x) {
-  return static_cast<bool>(::g_value_get_boolean(&x));
-}
-template <>
-inline ::uint32_t RawCast< ::uint32_t>(const ::GValue& x) {
-  return static_cast< ::uint32_t>(::g_value_get_uint(&x));
-}
-template <>
-inline ::uint8_t RawCast< ::uint8_t>(const ::GValue& x) {
-  return static_cast< ::uint8_t>(::g_value_get_uchar(&x));
-}
-template <>
-inline ::int64_t RawCast< ::int64_t>(const ::GValue& x) {
-  return static_cast< ::int64_t>(::g_value_get_int64(&x));
-}
-template <>
-inline ::int32_t RawCast< ::int32_t>(const ::GValue& x) {
-  return static_cast< ::int32_t>(::g_value_get_int(&x));
-}
-
-inline void RawSet(GValue* x, const std::string& v) {
-  ::g_value_set_string(x, v.c_str());
-}
-inline void RawSet(GValue* x, const char* v) {
-  ::g_value_set_string(x, v);
-}
-inline void RawSet(GValue* x, double v) {
-  ::g_value_set_double(x, v);
-}
-inline void RawSet(GValue* x, bool v) {
-  ::g_value_set_boolean(x, v);
-}
-inline void RawSet(GValue* x, ::uint32_t v) {
-  ::g_value_set_uint(x, v);
-}
-inline void RawSet(GValue* x, ::uint8_t v) {
-  ::g_value_set_uchar(x, v);
-}
-inline void RawSet(GValue* x, ::int64_t v) {
-  ::g_value_set_int64(x, v);
-}
-inline void RawSet(GValue* x, ::int32_t v) {
-  ::g_value_set_int(x, v);
-}
-
-// \brief Value is a data type for managing GValues.
-//
-// A Value is a polymorphic container holding at most a single value.
-//
-// The Value wrapper ensures proper initialization, copies, and assignment of
-// GValues.
-//
-// \note GValues are equationally incomplete and so can't support proper
-// equality. The semantics of copy are verified with equality of retrieved
-// values.
-
-class Value : public ::GValue {
- public:
-  Value() : GValue() {}
-  explicit Value(const ::GValue& x) : GValue() {
-    *this = *static_cast<const Value*>(&x);
-  }
-  template <typename T>
-  explicit Value(T x) : GValue() {
-    ::g_value_init(this, type_to_gtypeid<typename promotes_from<T>::type>());
-    RawSet(this, x);
-  }
-  Value(const Value& x) : GValue() {
-    if (x.empty())
-      return;
-    ::g_value_init(this, G_VALUE_TYPE(&x));
-    ::g_value_copy(&x, this);
-  }
-  ~Value() { clear(); }
-  Value& operator=(const Value& x) {
-    if (this == &x)
-      return *this;
-    clear();
-    if (x.empty())
-      return *this;
-    ::g_value_init(this, G_VALUE_TYPE(&x));
-    ::g_value_copy(&x, this);
-    return *this;
-  }
-  template <typename T>
-  Value& operator=(const T& x) {
-    clear();
-    ::g_value_init(this, type_to_gtypeid<typename promotes_from<T>::type>());
-    RawSet(this, x);
-    return *this;
-  }
-
-  // Lower-case names to follow STL container conventions.
-
-  void clear() {
-    if (!empty())
-      ::g_value_unset(this);
-  }
-
-  bool empty() const { return G_VALUE_TYPE(this) == G_TYPE_INVALID; }
-};
-
-template <>
-inline const Value* RawCast<const Value*>(const ::GValue& x) {
-  return static_cast<const Value*>(&x);
-}
-
-// \brief Retrieve gets a value from a GValue.
-//
-// \postcondition If \param x contains a value of type \param T, then the
-//  value is copied to \param result and \true is returned. Otherwise, \param
-//  result is unchanged and \false is returned.
-//
-// \precondition \param result is not \nullptr.
-
-template <typename T>
-bool Retrieve(const ::GValue& x, T* result) {
-  if (!G_VALUE_HOLDS(&x, type_to_gtypeid<typename promotes_from<T>::type>())) {
-    LOG(WARNING) << "GValue retrieve failed. Expected: "
-                 << g_type_name(
-                        type_to_gtypeid<typename promotes_from<T>::type>())
-                 << ", Found: " << g_type_name(G_VALUE_TYPE(&x));
-    return false;
-  }
-
-  *result = RawCast<typename promotes_from<T>::type>(x);
-  return true;
-}
-
-inline bool Retrieve(const ::GValue& x, Value* result) {
-  *result = Value(x);
-  return true;
-}
-
-// \brief ScopedError holds a ::GError* and deletes it on destruction.
-
-struct FreeError {
-  void operator()(::GError* x) const {
-    if (x)
-      ::g_error_free(x);
-  }
-};
-
-typedef std::unique_ptr< ::GError, FreeError> ScopedError;
-
-// \brief ScopedArray holds a ::GArray* and deletes both the container and the
-// segment containing the elements on destruction.
-
-struct FreeArray {
-  void operator()(::GArray* x) const {
-    if (x)
-      ::g_array_free(x, TRUE);
-  }
-};
-
-typedef std::unique_ptr< ::GArray, FreeArray> ScopedArray;
-
-// \brief ScopedPtrArray adapts ::GPtrArray* to conform to the standard
-//  container requirements.
-//
-// \note ScopedPtrArray is only partially implemented and is being fleshed out
-//  as needed.
-//
-// \models Random Access Container, Back Insertion Sequence, ScopedPtrArray is
-//  not copyable and equationally incomplete.
-
-template <typename T>  // T models pointer
-class ScopedPtrArray {
- public:
-  typedef ::GPtrArray element_type;
-
-  typedef T value_type;
-  typedef const value_type& const_reference;
-  typedef value_type* iterator;
-  typedef const value_type* const_iterator;
-
-  ScopedPtrArray() : object_(0) {}
-
-  explicit ScopedPtrArray(::GPtrArray* x) : object_(x) {}
-  ScopedPtrArray(const ScopedPtrArray&) = delete;
-  ScopedPtrArray& operator=(const ScopedPtrArray&) = delete;
-
-  ~ScopedPtrArray() { clear(); }
-
-  iterator begin() { return iterator(object_ ? object_->pdata : nullptr); }
-  iterator end() { return begin() + size(); }
-  const_iterator begin() const {
-    return const_iterator(object_ ? object_->pdata : nullptr);
-  }
-  const_iterator end() const { return begin() + size(); }
-
-  // \precondition x is a pointer to an object allocated with g_new().
-
-  void push_back(T x) {
-    if (!object_)
-      object_ = ::g_ptr_array_sized_new(1);
-    ::g_ptr_array_add(object_, ::gpointer(x));
-  }
-
-  T& operator[](std::size_t n) {
-    DCHECK(!(size() < n)) << "ScopedPtrArray index out-of-bound.";
-    return *(begin() + n);
-  }
-
-  std::size_t size() const { return object_ ? object_->len : 0; }
-
-  void clear() {
-    if (object_) {
-      std::for_each(begin(), end(), FreeHelper());
-      ::g_ptr_array_free(object_, true);
-      object_ = nullptr;
-    }
-  }
-
-  void reset(::GPtrArray* p = nullptr) {
-    if (p != object_) {
-      clear();
-      object_ = p;
-    }
-  }
-
- private:
-  struct FreeHelper {
-    void operator()(T x) const { ::g_free(::gpointer(x)); }
-  };
-
-  template <typename U>
-  friend void swap(ScopedPtrArray<U>& x, ScopedPtrArray<U>& y);
-
-  ::GPtrArray* object_;
-};
-
-template <typename U>
-inline void swap(ScopedPtrArray<U>& x, ScopedPtrArray<U>& y) {
-  std::swap(x.object_, y.object_);
-}
-
-// \brief ScopedHashTable manages the lifetime of a ::GHashTable* with an
-// interface compatibitle with a scoped ptr.
-//
-// The ScopedHashTable is also the start of an adaptor to model a standard
-// Container. The standard for an associative container would have an iterator
-// returning a key value pair. However, that isn't possible with
-// ::GHashTable because there is no interface returning a reference to the
-// key value pair, only to retrieve the keys and values and individual elements.
-//
-// So the standard interface of find() wouldn't work. I considered implementing
-// operator[] and count() - operator []. So retrieving a value would look like:
-//
-// if (table.count(key))
-//   success = Retrieve(table[key], &value);
-//
-// But that requires hashing the key twice.
-// For now I implemented a Retrieve member function to follow the pattern
-// developed elsewhere in the code.
-//
-// bool success = Retrieve(key, &x);
-//
-// This is also a template to retrieve the corect type from the stored GValue
-// type.
-//
-// I may revisit this and use scoped_ptr_malloc and a non-member function
-// Retrieve() in the future. The Retrieve pattern is becoming common enough
-// that I want to give some thought as to how to generalize it further.
-
-class ScopedHashTable {
- public:
-  typedef ::GHashTable element_type;
-
-  ScopedHashTable() : object_(nullptr) {}
-
-  explicit ScopedHashTable(::GHashTable* p) : object_(p) {}
-
-  ~ScopedHashTable() { clear(); }
-
-  template <typename T>
-  bool Retrieve(const char* key, T* result) const {
-    DCHECK(object_) << "Retrieve on empty ScopedHashTable.";
-    if (!object_)
-      return false;
-
-    ::gpointer ptr = ::g_hash_table_lookup(object_, key);
-    if (!ptr)
-      return false;
-    return glib::Retrieve(*static_cast< ::GValue*>(ptr), result);
-  }
-
-  void clear() {
-    if (object_) {
-      ::g_hash_table_unref(object_);
-      object_ = nullptr;
-    }
-  }
-
-  GHashTable* get() { return object_; }
-
-  void reset(::GHashTable* p = nullptr) {
-    if (p != object_) {
-      clear();
-      object_ = p;
-    }
-  }
-
- private:
-  ::GHashTable* object_;
-};
-
-}  // namespace glib
-}  // namespace brillo
-
-#endif  // LIBBRILLO_BRILLO_GLIB_OBJECT_H_
diff --git a/brillo/glib/object_test.cc b/brillo/glib/object_test.cc
deleted file mode 100644
index 9381866b9f..0000000000
--- a/brillo/glib/object_test.cc
+++ /dev/null
@@ -1,132 +0,0 @@
-// Copyright (c) 2009 The Chromium OS 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 "brillo/glib/object.h"
-
-#include <gtest/gtest.h>
-
-#include <algorithm>
-#include <cstring>
-#include <iterator>
-#include <string>
-
-using brillo::Resetter;
-using brillo::glib::Retrieve;
-using brillo::glib::ScopedError;
-using brillo::glib::ScopedPtrArray;
-using brillo::glib::Value;
-
-namespace {  // NOLINT
-
-template <typename T>
-void SetRetrieveTest(const T& x) {
-  Value tmp(x);
-  T result;
-  EXPECT_TRUE(Retrieve(tmp, &result));
-  EXPECT_EQ(result, x);
-}
-
-void ModifyValue(Value* x) {
-  *x = 1.0 / 1231415926.0;  // An unlikely value
-}
-
-template <typename T, typename O>
-void MutableRegularTestValue(const T& x, O modify) {
-  Value tmp(x);
-  Value y = tmp;  // copy-construction
-  T result;
-  EXPECT_TRUE(Retrieve(y, &result));
-  EXPECT_EQ(result, x);
-  modify(&y);
-  LOG(INFO) << "Warning Expected.";
-  EXPECT_TRUE(!(Retrieve(y, &result) && result == x));
-  y = tmp;  // assignment
-  EXPECT_TRUE(Retrieve(y, &result));
-  EXPECT_EQ(result, x);
-  modify(&y);
-  LOG(INFO) << "Warning Expected.";
-  EXPECT_TRUE(!(Retrieve(y, &result) && result == x));
-}
-
-void OutArgument(int** x) {
-  *x = new int(10);  // NOLINT
-}
-
-}  // namespace
-
-TEST(ResetterTest, All) {
-  std::unique_ptr<int> x;
-  OutArgument(&Resetter(&x).lvalue());
-  EXPECT_EQ(*x, 10);
-}
-
-TEST(RetrieveTest, Types) {
-  SetRetrieveTest(std::string("Hello!"));
-  SetRetrieveTest(static_cast<uint32_t>(10));
-  SetRetrieveTest(10.5);
-  SetRetrieveTest(true);
-}
-
-TEST(ValueTest, All) {
-  Value x;      // default construction
-  Value y = x;  // copy with default value
-  x = y;        // assignment with default value
-  Value z(1.5);
-  x = z;  // assignment to default value
-  MutableRegularTestValue(std::string("Hello!"), &ModifyValue);
-}
-
-TEST(ScopedErrorTest, All) {
-  ScopedError a;  // default construction
-  ScopedError b(::g_error_new(::g_quark_from_static_string("error"), -1,
-                              ""));  // constructor
-  ::GError* c = ::g_error_new(::g_quark_from_static_string("error"), -1, "");
-  ::GError* d = ::g_error_new(::g_quark_from_static_string("error"), -1, "");
-  a.reset(c);  // reset form 1
-  (void)d;
-}
-
-TEST(ScopedPtrArrayTest, Construction) {
-  const char item[] = "a string";
-  char* a = static_cast<char*>(::g_malloc(sizeof(item)));
-  std::strcpy(a, &item[0]);  // NOLINT
-
-  ::GPtrArray* array = ::g_ptr_array_new();
-  ::g_ptr_array_add(array, ::gpointer(a));
-
-  ScopedPtrArray<const char*> x(array);
-  EXPECT_EQ(x.size(), 1);
-  EXPECT_EQ(x[0], a);  // indexing
-}
-
-TEST(ScopedPtrArrayTest, Reset) {
-  const char item[] = "a string";
-  char* a = static_cast<char*>(::g_malloc(sizeof(item)));
-  std::strcpy(a, &item[0]);  // NOLINT
-
-  ScopedPtrArray<const char*> x;  // default construction
-  x.push_back(a);
-  EXPECT_EQ(x.size(), 1);
-  x.reset();
-  EXPECT_EQ(x.size(), 0);
-
-  char* b = static_cast<char*>(::g_malloc(sizeof(item)));
-  std::strcpy(b, &item[0]);  // NOLINT
-
-  ::GPtrArray* array = ::g_ptr_array_new();
-  ::g_ptr_array_add(array, ::gpointer(b));
-
-  x.reset(array);
-  EXPECT_EQ(x.size(), 1);
-}
-
-TEST(ScopedPtrArrayTest, Iteration) {
-  char* a[] = {static_cast<char*>(::g_malloc(1)),
-               static_cast<char*>(::g_malloc(1)),
-               static_cast<char*>(::g_malloc(1))};
-
-  ScopedPtrArray<const char*> x;
-  std::copy(&a[0], &a[3], std::back_inserter(x));
-  EXPECT_TRUE(std::equal(x.begin(), x.end(), &a[0]));
-}
-- 
2.33.0.464.g1972c5931b-goog

