diff --git a/SConstruct.chromiumos b/SConstruct.chromiumos
index fd413d1..0acac05 100644
--- a/SConstruct.chromiumos
+++ b/SConstruct.chromiumos
@@ -65,7 +65,6 @@
 base_env.Append(LINKFLAGS=Split('-fPIC'))
 
 SOURCES = Split('''\
-  chromeos_cryptohome.cc
   chromeos_network.cc
   marshal.glibmarshal.c
   version_check.cc
diff --git a/chromeos_cros_api.h b/chromeos_cros_api.h
index 97b5978..ca6a749 100644
--- a/chromeos_cros_api.h
+++ b/chromeos_cros_api.h
@@ -364,12 +364,29 @@
 //      CryptohomeInstallAttributesIsInvalid,
 //      CryptohomeInstallAttributesIsFirstInstall, CryptohomeFreeString
 //      CryptohomeMonitorSession.
+// 197: Removed CryptohomeAsyncCheckKey, CryptohomeAsyncMigrateKey,
+//      CryptohomeAsyncMountGuest, CryptohomeAsyncMountSafe,
+//      CryptohomeAsyncRemove, CryptohomeAsyncSetOwnerUser,
+//      CryptohomeFreeString, CryptohomeGetStatusString,
+//      CryptohomeGetStatusStringSafe, CryptohomeGetSystemSaltSafe,
+//      CryptohomeInstallAttributesFinalize, CryptohomeInstallAttributesGet,
+//      CryptohomeInstallAttributesIsFirstInstall,
+//      CryptohomeInstallAttributesIsInvalid,
+//      CryptohomeInstallAttributesIsReady, CryptohomeInstallAttributesSet,
+//      CryptohomeIsMounted, CryptohomeMonitorSession,
+//      CryptohomePkcs11GetTpmTokenInfo,
+//      CryptohomePkcs11GetTmpTokenReadyForUser,
+//      CryptohomePkcs11IsTpmTokenReady,
+//      CryptohomePkcs11IsTmpTokenReadyForUser,
+//      CryptohomeTpmCanAttemptOwnership, CryptohomeTpmClearStoredPassword,
+//      CryptohomeTpmGetPasswordSafe, CryptohomeTpmIsBeingOwned,
+//      CryptohomeTpmIsEnabled, CryptohomeTpmIsOwned, CryptohomeTpmIsReady.
 
 namespace chromeos {  // NOLINT
 
 enum CrosAPIVersion {
-  kCrosAPIMinVersion = 191,
-  kCrosAPIVersion = 196
+  kCrosAPIMinVersion = 196,
+  kCrosAPIVersion = 197
 };
 
 // Default path to pass to LoadCros: "/opt/google/chrome/chromeos/libcros.so"
diff --git a/chromeos_cryptohome.cc b/chromeos_cryptohome.cc
deleted file mode 100644
index 52e10e4..0000000
--- a/chromeos_cryptohome.cc
+++ /dev/null
@@ -1,838 +0,0 @@
-// Copyright (c) 2012 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 <string>
-#include <vector>
-
-#include <base/basictypes.h>
-#include <base/string_util.h>
-#include <dbus/dbus-glib-lowlevel.h>
-#include <chromeos/dbus/dbus.h>
-#include <chromeos/dbus/service_constants.h>
-#include <chromeos/glib/object.h>
-
-namespace chromeos {  // NOLINT
-
-struct CryptohomeAsyncCallStatus {
-  int async_id;
-  bool return_status;
-  int return_code;
-};
-
-typedef void(*CryptohomeSignalCallback)(
-    const CryptohomeAsyncCallStatus& call_status, void* callback_context);
-
-extern "C"
-int ChromeOSCryptohomeAsyncCheckKey(const char* user_email, const char* key) {
-  dbus::BusConnection bus = dbus::GetSystemBusConnection();
-  dbus::Proxy proxy(bus,
-                    cryptohome::kCryptohomeServiceName,
-                    cryptohome::kCryptohomeServicePath,
-                    cryptohome::kCryptohomeInterface);
-  gint async_call_id = 0;
-  glib::ScopedError error;
-
-  if (!::dbus_g_proxy_call(proxy.gproxy(),
-                           cryptohome::kCryptohomeAsyncCheckKey,
-                           &Resetter(&error).lvalue(),
-                           G_TYPE_STRING,
-                           user_email,
-                           G_TYPE_STRING,
-                           key,
-                           G_TYPE_INVALID,
-                           G_TYPE_INT,
-                           &async_call_id,
-                           G_TYPE_INVALID)) {
-    LOG(WARNING) << cryptohome::kCryptohomeAsyncCheckKey << " failed: "
-                 << (error->message ? error->message : "Unknown Error.");
-  }
-  return async_call_id;
-}
-
-extern "C"
-int ChromeOSCryptohomeAsyncMigrateKey(const char* user_email,
-                                      const char* from_key,
-                                      const char* to_key) {
-  dbus::BusConnection bus = dbus::GetSystemBusConnection();
-  dbus::Proxy proxy(bus,
-                    cryptohome::kCryptohomeServiceName,
-                    cryptohome::kCryptohomeServicePath,
-                    cryptohome::kCryptohomeInterface);
-  gint async_call_id = 0;
-  glib::ScopedError error;
-
-  if (!::dbus_g_proxy_call(proxy.gproxy(),
-                           cryptohome::kCryptohomeAsyncMigrateKey,
-                           &Resetter(&error).lvalue(),
-                           G_TYPE_STRING,
-                           user_email,
-                           G_TYPE_STRING,
-                           from_key,
-                           G_TYPE_STRING,
-                           to_key,
-                           G_TYPE_INVALID,
-                           G_TYPE_INT,
-                           &async_call_id,
-                           G_TYPE_INVALID)) {
-    LOG(WARNING) << cryptohome::kCryptohomeAsyncMigrateKey << " failed: "
-                 << (error->message ? error->message : "Unknown Error.");
-  }
-  return async_call_id;
-}
-
-extern "C"
-int ChromeOSCryptohomeAsyncRemove(const char* user_email) {
-  dbus::BusConnection bus = dbus::GetSystemBusConnection();
-  dbus::Proxy proxy(bus,
-                    cryptohome::kCryptohomeServiceName,
-                    cryptohome::kCryptohomeServicePath,
-                    cryptohome::kCryptohomeInterface);
-  gint async_call_id = 0;
-  glib::ScopedError error;
-
-  if (!::dbus_g_proxy_call(proxy.gproxy(),
-                           cryptohome::kCryptohomeAsyncRemove,
-                           &Resetter(&error).lvalue(),
-                           G_TYPE_STRING,
-                           user_email,
-                           G_TYPE_INVALID,
-                           G_TYPE_INT,
-                           &async_call_id,
-                           G_TYPE_INVALID)) {
-    LOG(WARNING) << cryptohome::kCryptohomeAsyncRemove << " failed: "
-                 << (error->message ? error->message : "Unknown Error.");
-  }
-  return async_call_id;
-}
-
-extern "C"
-bool ChromeOSCryptohomeGetSystemSaltSafe(char** salt, int* length) {
-  dbus::BusConnection bus = dbus::GetSystemBusConnection();
-  dbus::Proxy proxy(bus,
-                    cryptohome::kCryptohomeServiceName,
-                    cryptohome::kCryptohomeServicePath,
-                    cryptohome::kCryptohomeInterface);
-  GArray* dbus_salt;
-  glib::ScopedError error;
-
-  if (!::dbus_g_proxy_call(proxy.gproxy(),
-                           cryptohome::kCryptohomeGetSystemSalt,
-                           &Resetter(&error).lvalue(),
-                           G_TYPE_INVALID,
-                           DBUS_TYPE_G_UCHAR_ARRAY,
-                           &dbus_salt,
-                           G_TYPE_INVALID)) {
-    LOG(WARNING) << cryptohome::kCryptohomeGetSystemSalt << " failed: "
-                 << (error->message ? error->message : "Unknown Error.");
-    return false;
-  }
-  char* local_salt = static_cast<char*>(g_malloc(dbus_salt->len));
-  if (local_salt) {
-    memcpy(local_salt, static_cast<const void*>(dbus_salt->data),
-           dbus_salt->len);
-    *salt = local_salt;
-    *length = dbus_salt->len;
-    g_array_free(dbus_salt, false);
-    return true;
-  }
-  g_array_free(dbus_salt, false);
-  return false;
-}
-
-extern "C"
-bool ChromeOSCryptohomeIsMounted() {
-  dbus::BusConnection bus = dbus::GetSystemBusConnection();
-  dbus::Proxy proxy(bus,
-                    cryptohome::kCryptohomeServiceName,
-                    cryptohome::kCryptohomeServicePath,
-                    cryptohome::kCryptohomeInterface);
-  gboolean done = false;
-  glib::ScopedError error;
-
-  if (!::dbus_g_proxy_call(proxy.gproxy(),
-                           cryptohome::kCryptohomeIsMounted,
-                           &Resetter(&error).lvalue(),
-                           G_TYPE_INVALID,
-                           G_TYPE_BOOLEAN,
-                           &done,
-                           G_TYPE_INVALID)) {
-
-    LOG(FATAL) << cryptohome::kCryptohomeIsMounted << " failed: "
-               << (error->message ? error->message : "Unknown Error.");
-
-  }
-  return done;
-}
-
-gchar** ChromeOSCryptohomeCopyStringArray(
-    const std::vector<std::string>& input_array) {
-  gchar** return_array = g_new(gchar*, input_array.size() + 1);
-  if (!return_array) {
-    return NULL;
-  }
-  int i = 0;
-  for (std::vector<std::string>::const_iterator itr = input_array.begin();
-       itr != input_array.end();
-       itr++, i++) {
-    return_array[i] = g_strdup((*itr).c_str());
-    if (!return_array[i]) {
-      // return_array is automatically NULL-terminated in this case
-      g_strfreev(return_array);
-      return NULL;
-    }
-  }
-  return_array[i] = NULL;
-  return return_array;
-}
-
-extern "C"
-int ChromeOSCryptohomeAsyncMountSafe(
-    const char* user_email,
-    const char* key,
-    bool create_if_missing,
-    bool replace_tracked_subdirectories,
-    const char** tracked_subdirectories) {
-  dbus::BusConnection bus = dbus::GetSystemBusConnection();
-  dbus::Proxy proxy(bus,
-                    cryptohome::kCryptohomeServiceName,
-                    cryptohome::kCryptohomeServicePath,
-                    cryptohome::kCryptohomeInterface);
-  gint async_call_id = 0;
-  glib::ScopedError error;
-
-  if (!::dbus_g_proxy_call(proxy.gproxy(),
-                           cryptohome::kCryptohomeAsyncMount,
-                           &Resetter(&error).lvalue(),
-                           G_TYPE_STRING,
-                           user_email,
-                           G_TYPE_STRING,
-                           key,
-                           G_TYPE_BOOLEAN,
-                           create_if_missing,
-                           G_TYPE_BOOLEAN,
-                           replace_tracked_subdirectories,
-                           G_TYPE_STRV,
-                           tracked_subdirectories,
-                           G_TYPE_INVALID,
-                           G_TYPE_INT,
-                           &async_call_id,
-                           G_TYPE_INVALID)) {
-    LOG(WARNING) << cryptohome::kCryptohomeAsyncMount << " failed: "
-                 << (error->message ? error->message : "Unknown Error.");
-  }
-
-  return async_call_id;
-}
-
-extern "C"
-int ChromeOSCryptohomeAsyncMountGuest() {
-  dbus::BusConnection bus = dbus::GetSystemBusConnection();
-  dbus::Proxy proxy(bus,
-                    cryptohome::kCryptohomeServiceName,
-                    cryptohome::kCryptohomeServicePath,
-                    cryptohome::kCryptohomeInterface);
-  gint async_call_id = 0;
-  glib::ScopedError error;
-
-  if (!::dbus_g_proxy_call(proxy.gproxy(),
-                           cryptohome::kCryptohomeAsyncMountGuest,
-                           &Resetter(&error).lvalue(),
-                           G_TYPE_INVALID,
-                           G_TYPE_INT,
-                           &async_call_id,
-                           G_TYPE_INVALID)) {
-    LOG(WARNING) << cryptohome::kCryptohomeAsyncMountGuest << " failed: "
-                 << (error->message ? error->message : "Unknown Error.");
-  }
-  return async_call_id;
-}
-
-extern "C"
-int ChromeOSCryptohomeAsyncSetOwnerUser(const char* username) {
-  return 0;
-}
-
-extern "C"
-bool ChromeOSCryptohomeTpmIsReady() {
-  dbus::BusConnection bus = dbus::GetSystemBusConnection();
-  dbus::Proxy proxy(bus,
-                    cryptohome::kCryptohomeServiceName,
-                    cryptohome::kCryptohomeServicePath,
-                    cryptohome::kCryptohomeInterface);
-  gboolean ready = false;
-  glib::ScopedError error;
-
-  if (!::dbus_g_proxy_call(proxy.gproxy(),
-                           cryptohome::kCryptohomeTpmIsReady,
-                           &Resetter(&error).lvalue(),
-                           G_TYPE_INVALID,
-                           G_TYPE_BOOLEAN,
-                           &ready,
-                           G_TYPE_INVALID)) {
-
-    LOG(WARNING) << cryptohome::kCryptohomeTpmIsReady << " failed: "
-                 << (error->message ? error->message : "Unknown Error.");
-
-  }
-  return ready;
-}
-
-extern "C"
-bool ChromeOSCryptohomeTpmIsEnabled() {
-  dbus::BusConnection bus = dbus::GetSystemBusConnection();
-  dbus::Proxy proxy(bus,
-                    cryptohome::kCryptohomeServiceName,
-                    cryptohome::kCryptohomeServicePath,
-                    cryptohome::kCryptohomeInterface);
-  gboolean done = false;
-  glib::ScopedError error;
-
-  if (!::dbus_g_proxy_call(proxy.gproxy(),
-                           cryptohome::kCryptohomeTpmIsEnabled,
-                           &Resetter(&error).lvalue(),
-                           G_TYPE_INVALID,
-                           G_TYPE_BOOLEAN,
-                           &done,
-                           G_TYPE_INVALID)) {
-
-    LOG(WARNING) << cryptohome::kCryptohomeTpmIsEnabled << " failed: "
-                 << (error->message ? error->message : "Unknown Error.");
-
-  }
-  return done;
-}
-
-extern "C"
-bool ChromeOSCryptohomeTpmIsOwned() {
-  dbus::BusConnection bus = dbus::GetSystemBusConnection();
-  dbus::Proxy proxy(bus,
-                    cryptohome::kCryptohomeServiceName,
-                    cryptohome::kCryptohomeServicePath,
-                    cryptohome::kCryptohomeInterface);
-  gboolean done = false;
-  glib::ScopedError error;
-
-  if (!::dbus_g_proxy_call(proxy.gproxy(),
-                           cryptohome::kCryptohomeTpmIsOwned,
-                           &Resetter(&error).lvalue(),
-                           G_TYPE_INVALID,
-                           G_TYPE_BOOLEAN,
-                           &done,
-                           G_TYPE_INVALID)) {
-
-    LOG(WARNING) << cryptohome::kCryptohomeTpmIsOwned << " failed: "
-                 << (error->message ? error->message : "Unknown Error.");
-
-  }
-  return done;
-}
-
-extern "C"
-bool ChromeOSCryptohomeTpmIsBeingOwned() {
-  dbus::BusConnection bus = dbus::GetSystemBusConnection();
-  dbus::Proxy proxy(bus,
-                    cryptohome::kCryptohomeServiceName,
-                    cryptohome::kCryptohomeServicePath,
-                    cryptohome::kCryptohomeInterface);
-  gboolean done = false;
-  glib::ScopedError error;
-
-  if (!::dbus_g_proxy_call(proxy.gproxy(),
-                           cryptohome::kCryptohomeTpmIsBeingOwned,
-                           &Resetter(&error).lvalue(),
-                           G_TYPE_INVALID,
-                           G_TYPE_BOOLEAN,
-                           &done,
-                           G_TYPE_INVALID)) {
-
-    LOG(WARNING) << cryptohome::kCryptohomeTpmIsBeingOwned << " failed: "
-                 << (error->message ? error->message : "Unknown Error.");
-
-  }
-  return done;
-}
-
-extern "C"
-bool ChromeOSCryptohomeTpmGetPasswordSafe(char** password) {
-  dbus::BusConnection bus = dbus::GetSystemBusConnection();
-  dbus::Proxy proxy(bus,
-                    cryptohome::kCryptohomeServiceName,
-                    cryptohome::kCryptohomeServicePath,
-                    cryptohome::kCryptohomeInterface);
-  gchar* local_password = NULL;
-  glib::ScopedError error;
-
-  if (!::dbus_g_proxy_call(proxy.gproxy(),
-                           cryptohome::kCryptohomeTpmGetPassword,
-                           &Resetter(&error).lvalue(),
-                           G_TYPE_INVALID,
-                           G_TYPE_STRING,
-                           &local_password,
-                           G_TYPE_INVALID)) {
-
-    LOG(WARNING) << cryptohome::kCryptohomeTpmGetPassword << " failed: "
-                 << (error->message ? error->message : "Unknown Error.");
-
-  }
-
-  if (local_password) {
-    *password = local_password;
-    return true;
-  }
-  *password = NULL;
-  return false;
-}
-
-extern "C"
-void ChromeOSCryptohomeTpmCanAttemptOwnership() {
-  dbus::BusConnection bus = dbus::GetSystemBusConnection();
-  dbus::Proxy proxy(bus,
-                    cryptohome::kCryptohomeServiceName,
-                    cryptohome::kCryptohomeServicePath,
-                    cryptohome::kCryptohomeInterface);
-  glib::ScopedError error;
-
-  if (!::dbus_g_proxy_call(proxy.gproxy(),
-                           cryptohome::kCryptohomeTpmCanAttemptOwnership,
-                           &Resetter(&error).lvalue(),
-                           G_TYPE_INVALID,
-                           G_TYPE_INVALID)) {
-
-    LOG(WARNING) << cryptohome::kCryptohomeTpmCanAttemptOwnership << " failed: "
-                 << (error->message ? error->message : "Unknown Error.");
-
-  }
-}
-
-extern "C"
-void ChromeOSCryptohomeTpmClearStoredPassword() {
-  dbus::BusConnection bus = dbus::GetSystemBusConnection();
-  dbus::Proxy proxy(bus,
-                    cryptohome::kCryptohomeServiceName,
-                    cryptohome::kCryptohomeServicePath,
-                    cryptohome::kCryptohomeInterface);
-  glib::ScopedError error;
-
-  if (!::dbus_g_proxy_call(proxy.gproxy(),
-                           cryptohome::kCryptohomeTpmClearStoredPassword,
-                           &Resetter(&error).lvalue(),
-                           G_TYPE_INVALID,
-                           G_TYPE_INVALID)) {
-
-    LOG(WARNING) << cryptohome::kCryptohomeTpmClearStoredPassword << " failed: "
-                 << (error->message ? error->message : "Unknown Error.");
-
-  }
-}
-
-// TODO(ellyjones): Remove this. crosbug.com/22120
-extern "C"
-bool ChromeOSCryptohomePkcs11IsTpmTokenReady() {
-  dbus::BusConnection bus = dbus::GetSystemBusConnection();
-  dbus::Proxy proxy(bus,
-                    cryptohome::kCryptohomeServiceName,
-                    cryptohome::kCryptohomeServicePath,
-                    cryptohome::kCryptohomeInterface);
-  gboolean ready = FALSE;
-  glib::ScopedError error;
-
-  if (!::dbus_g_proxy_call(proxy.gproxy(),
-                           cryptohome::kCryptohomePkcs11IsTpmTokenReady,
-                           &Resetter(&error).lvalue(),
-                           G_TYPE_INVALID,
-                           G_TYPE_BOOLEAN,
-                           &ready,
-                           G_TYPE_INVALID)) {
-
-    LOG(WARNING) << cryptohome::kCryptohomePkcs11IsTpmTokenReady << " failed: "
-                 << (error->message ? error->message : "Unknown Error.");
-
-  }
-  return ready;
-}
-
-extern "C"
-bool ChromeOSCryptohomePkcs11IsTpmTokenReadyForUser(const std::string& user) {
-  dbus::BusConnection bus = dbus::GetSystemBusConnection();
-  dbus::Proxy proxy(bus,
-                    cryptohome::kCryptohomeServiceName,
-                    cryptohome::kCryptohomeServicePath,
-                    cryptohome::kCryptohomeInterface);
-  gboolean ready = FALSE;
-  glib::ScopedError error;
-
-  if (!::dbus_g_proxy_call(proxy.gproxy(),
-                           cryptohome::kCryptohomePkcs11IsTpmTokenReadyForUser,
-                           &Resetter(&error).lvalue(),
-                           G_TYPE_STRING,
-                           user.c_str(),
-                           G_TYPE_INVALID,
-                           G_TYPE_BOOLEAN,
-                           &ready,
-                           G_TYPE_INVALID)) {
-
-    LOG(WARNING) << cryptohome::kCryptohomePkcs11IsTpmTokenReadyForUser
-                 << " failed: "
-                 << (error->message ? error->message : "Unknown Error.");
-
-  }
-  return ready;
-}
-
-// TODO(ellyjones): Remove this. crosbug.com/22120
-extern "C"
-void ChromeOSCryptohomePkcs11GetTpmTokenInfo(std::string* label,
-                                             std::string* user_pin) {
-  dbus::BusConnection bus = dbus::GetSystemBusConnection();
-  dbus::Proxy proxy(bus,
-                    cryptohome::kCryptohomeServiceName,
-                    cryptohome::kCryptohomeServicePath,
-                    cryptohome::kCryptohomeInterface);
-  gchar* local_label = NULL;
-  gchar* local_user_pin = NULL;
-  glib::ScopedError error;
-
-  if (!::dbus_g_proxy_call(proxy.gproxy(),
-                           cryptohome::kCryptohomePkcs11GetTpmTokenInfo,
-                           &Resetter(&error).lvalue(),
-                           G_TYPE_INVALID,
-                           G_TYPE_STRING,
-                           &local_label,
-                           G_TYPE_STRING,
-                           &local_user_pin,
-                           G_TYPE_INVALID)) {
-
-    LOG(WARNING) << cryptohome::kCryptohomePkcs11GetTpmTokenInfo << " failed: "
-                 << (error->message ? error->message : "Unknown Error.");
-
-  }
-
-  if (local_label) {
-    *label = local_label;
-    g_free(local_label);
-  }
-  if (local_user_pin) {
-    *user_pin = local_user_pin;
-    g_free(local_user_pin);
-  }
-}
-
-extern "C"
-void ChromeOSCryptohomePkcs11GetTpmTokenInfoForUser(const std::string& user,
-                                                    std::string* label,
-                                                    std::string* user_pin) {
-  dbus::BusConnection bus = dbus::GetSystemBusConnection();
-  dbus::Proxy proxy(bus,
-                    cryptohome::kCryptohomeServiceName,
-                    cryptohome::kCryptohomeServicePath,
-                    cryptohome::kCryptohomeInterface);
-  gchar* local_label = NULL;
-  gchar* local_user_pin = NULL;
-  glib::ScopedError error;
-
-  if (!::dbus_g_proxy_call(proxy.gproxy(),
-                           cryptohome::kCryptohomePkcs11GetTpmTokenInfoForUser,
-                           &Resetter(&error).lvalue(),
-                           G_TYPE_STRING,
-                           user.c_str(),
-                           G_TYPE_INVALID,
-                           G_TYPE_STRING,
-                           &local_label,
-                           G_TYPE_STRING,
-                           &local_user_pin,
-                           G_TYPE_INVALID)) {
-
-    LOG(WARNING) << cryptohome::kCryptohomePkcs11GetTpmTokenInfo << " failed: "
-                 << (error->message ? error->message : "Unknown Error.");
-
-  }
-
-  if (local_label) {
-    *label = local_label;
-    g_free(local_label);
-  }
-  if (local_user_pin) {
-    *user_pin = local_user_pin;
-    g_free(local_user_pin);
-  }
-}
-
-extern "C"
-bool ChromeOSCryptohomeGetStatusStringSafe(char** status) {
-  dbus::BusConnection bus = dbus::GetSystemBusConnection();
-  dbus::Proxy proxy(bus,
-                    cryptohome::kCryptohomeServiceName,
-                    cryptohome::kCryptohomeServicePath,
-                    cryptohome::kCryptohomeInterface);
-  gchar* local_status = NULL;
-  glib::ScopedError error;
-
-  if (!::dbus_g_proxy_call(proxy.gproxy(),
-                           cryptohome::kCryptohomeGetStatusString,
-                           &Resetter(&error).lvalue(),
-                           G_TYPE_INVALID,
-                           G_TYPE_STRING,
-                           &local_status,
-                           G_TYPE_INVALID)) {
-
-    LOG(WARNING) << cryptohome::kCryptohomeGetStatusString << " failed: "
-                 << (error->message ? error->message : "Unknown Error.");
-
-  }
-
-  if (local_status) {
-    *status = local_status;
-    return true;
-  }
-  *status = NULL;
-  return false;
-}
-
-extern "C"
-bool ChromeOSCryptohomeGetStatusString(std::string* status) {
-  gchar* local_status = NULL;
-  if (!ChromeOSCryptohomeGetStatusStringSafe(&local_status)) {
-    return false;
-  }
-
-  status->assign(local_status);
-  g_free(local_status);
-  return true;
-}
-
-extern "C"
-bool ChromeOSCryptohomeInstallAttributesGet(const char* name, char** value) {
-  dbus::BusConnection bus = dbus::GetSystemBusConnection();
-  dbus::Proxy proxy(bus,
-                    cryptohome::kCryptohomeServiceName,
-                    cryptohome::kCryptohomeServicePath,
-                    cryptohome::kCryptohomeInterface);
-  gboolean done = false;
-  GArray* dbus_value = NULL;
-  glib::ScopedError error;
-
-  if (!::dbus_g_proxy_call(proxy.gproxy(),
-                           cryptohome::kCryptohomeInstallAttributesGet,
-                           &Resetter(&error).lvalue(),
-                           G_TYPE_STRING,
-                           name,
-                           G_TYPE_INVALID,
-                           DBUS_TYPE_G_UCHAR_ARRAY,
-                           &dbus_value,
-                           G_TYPE_BOOLEAN,
-                           &done,
-                           G_TYPE_INVALID)) {
-    LOG(WARNING) << cryptohome::kCryptohomeInstallAttributesGet << " failed: "
-                 << (error->message ? error->message : "Unknown Error.");
-  }
-
-  if (!dbus_value || !done)
-    return false;
-
-  char* local_value = static_cast<char*>(g_malloc(dbus_value->len));
-  if (local_value) {
-    memcpy(local_value, static_cast<const void*>(dbus_value->data),
-           dbus_value->len);
-    *value = local_value;
-    g_array_free(dbus_value, false);
-    return done;
-  }
-  g_array_free(dbus_value, false);
-  return false;
-}
-
-extern "C"
-bool ChromeOSCryptohomeInstallAttributesSet(const char* name,
-                                            const char* value) {
-  dbus::BusConnection bus = dbus::GetSystemBusConnection();
-  dbus::Proxy proxy(bus,
-                    cryptohome::kCryptohomeServiceName,
-                    cryptohome::kCryptohomeServicePath,
-                    cryptohome::kCryptohomeInterface);
-  gboolean done = false;
-  // TODO(pastarmovj): Change this to a bin data compatible impl. when needed.
-  int value_len = strlen(value)+1;
-  gchar* local_value = static_cast<char*>(g_malloc(value_len));
-  if (!local_value)
-    return false;
-
-  memcpy(local_value, static_cast<const gchar*>(value), value_len);
-  GArray *dbus_value = g_array_new(FALSE, FALSE, 1);
-  if (!dbus_value)
-    return false;
-
-  dbus_value->data = local_value;
-  dbus_value->len = value_len;
-  glib::ScopedError error;
-
-  if (!::dbus_g_proxy_call(proxy.gproxy(),
-                           cryptohome::kCryptohomeInstallAttributesSet,
-                           &Resetter(&error).lvalue(),
-                           G_TYPE_STRING,
-                           name,
-                           DBUS_TYPE_G_UCHAR_ARRAY,
-                           dbus_value,
-                           G_TYPE_INVALID,
-                           G_TYPE_BOOLEAN,
-                           &done,
-                           G_TYPE_INVALID)) {
-    LOG(WARNING) << cryptohome::kCryptohomeInstallAttributesSet << " failed: "
-                 << (error->message ? error->message : "Unknown Error.");
-  }
-
-  g_array_free(dbus_value, FALSE);
-  g_free(local_value);
-
-  return done;
-}
-
-bool CallCryptohomeBoolFunction(const char* function) {
-  dbus::BusConnection bus = dbus::GetSystemBusConnection();
-  dbus::Proxy proxy(bus,
-                    cryptohome::kCryptohomeServiceName,
-                    cryptohome::kCryptohomeServicePath,
-                    cryptohome::kCryptohomeInterface);
-  gboolean done = false;
-  glib::ScopedError error;
-
-  if (!::dbus_g_proxy_call(proxy.gproxy(),
-                           function,
-                           &Resetter(&error).lvalue(),
-                           G_TYPE_INVALID,
-                           G_TYPE_BOOLEAN,
-                           &done,
-                           G_TYPE_INVALID)) {
-    LOG(WARNING) << function << " failed: "
-                 << (error->message ? error->message : "Unknown Error.");
-  }
-  return done;
-}
-
-
-extern "C"
-bool ChromeOSCryptohomeInstallAttributesFinalize() {
-  return CallCryptohomeBoolFunction(
-      cryptohome::kCryptohomeInstallAttributesFinalize);
-}
-
-extern "C"
-bool ChromeOSCryptohomeInstallAttributesIsReady() {
-  return CallCryptohomeBoolFunction(
-      cryptohome::kCryptohomeInstallAttributesIsReady);
-}
-
-extern "C"
-bool ChromeOSCryptohomeInstallAttributesIsInvalid() {
-  return CallCryptohomeBoolFunction(
-      cryptohome::kCryptohomeInstallAttributesIsInvalid);
-}
-
-extern "C"
-bool ChromeOSCryptohomeInstallAttributesIsFirstInstall() {
-  return CallCryptohomeBoolFunction(
-      cryptohome::kCryptohomeInstallAttributesIsFirstInstall);
-}
-
-extern "C"
-void ChromeOSCryptohomeFreeString(char* value) {
-  if (value) {
-    g_free(value);
-  }
-}
-
-class CryptohomeSessionConnection {
- public:
-  CryptohomeSessionConnection(const CryptohomeSignalCallback& monitor,
-                              void* monitor_context)
-      : monitor_(monitor),
-        monitor_context_(monitor_context) {
-  }
-
-  virtual ~CryptohomeSessionConnection() {}
-
-  void Notify(const CryptohomeAsyncCallStatus& call_status) {
-    monitor_(call_status, monitor_context_);
-  }
-
- private:
-  CryptohomeSignalCallback monitor_;
-  void* monitor_context_;
-
-  DISALLOW_COPY_AND_ASSIGN(CryptohomeSessionConnection);
-};
-
-
-#ifndef SAFE_MESSAGE
-#define SAFE_MESSAGE(e) (e.message ? e.message : "unknown error")
-#endif  // SAFE_MESSAGE
-
-bool CryptohomeExtractAsyncStatus(DBusMessage* message,
-                                  CryptohomeAsyncCallStatus* call_status) {
-  DBusError error;
-  dbus_error_init (&error);
-  bool unpack = dbus_message_get_args(message,
-                                      &error,
-                                      DBUS_TYPE_INT32,
-                                      &(call_status->async_id),
-                                      DBUS_TYPE_BOOLEAN,
-                                      &(call_status->return_status),
-                                      DBUS_TYPE_INT32,
-                                      &(call_status->return_code),
-                                      DBUS_TYPE_INVALID);
-  if (!unpack) {
-    LOG(INFO) << "Couldn't get arg: " << SAFE_MESSAGE(error);
-    return false;
-  }
-  return true;
-}
-
-// A message filter to receive signals.
-DBusHandlerResult CryptohomeSignalFilter(DBusConnection* dbus_connection,
-                         DBusMessage* message,
-                         void* connection) {
-  CryptohomeSessionConnection* self =
-      static_cast<CryptohomeSessionConnection*>(connection);
-  if (dbus_message_is_signal(message, cryptohome::kCryptohomeInterface,
-                             cryptohome::kSignalAsyncCallStatus)) {
-    LOG(INFO) << "Filter:: AsyncCallStatus signal received";
-    CryptohomeAsyncCallStatus call_status;
-    if (CryptohomeExtractAsyncStatus(message, &call_status)) {
-      self->Notify(call_status);
-      return DBUS_HANDLER_RESULT_HANDLED;
-    }
-  }
-  return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
-}
-
-extern "C"
-void* ChromeOSCryptohomeMonitorSession(CryptohomeSignalCallback monitor,
-                                       void* monitor_context) {
-  const std::string filter = StringPrintf("type='signal', interface='%s'",
-                                          cryptohome::kCryptohomeInterface);
-
-  DBusError error;
-  ::dbus_error_init(&error);
-  DBusConnection* dbus_connection = ::dbus_g_connection_get_connection(
-      dbus::GetSystemBusConnection().g_connection());
-  CHECK(dbus_connection);
-  ::dbus_bus_add_match(dbus_connection, filter.c_str(), &error);
-  if (::dbus_error_is_set(&error)) {
-    LOG(WARNING) << "Failed to add a filter:" << error.name << ", message="
-                 << SAFE_MESSAGE(error);
-    return NULL;
-  }
-
-  CryptohomeSessionConnection* connection = new CryptohomeSessionConnection(
-      monitor,
-      monitor_context);
-  CHECK(dbus_connection_add_filter(dbus_connection,
-                                   &CryptohomeSignalFilter,
-                                   connection,
-                                   NULL));
-
-  LOG(INFO) << "Cryptohome API event monitoring started";
-  return connection;
-}
-
-}  // namespace chromeos
