libweave: Remove loading/saving of config and state from libweave

External code should provide this functionality.

BUG=brillo:1257,brillo:1253
TEST=`FEATURES=test emerge-gizmo libweave buffet`

Change-Id: I95dcaf90cfd49dfb307fef4e9df12f12e3403d55
Reviewed-on: https://chromium-review.googlesource.com/293916
Tested-by: Vitaly Buka <vitalybuka@chromium.org>
Reviewed-by: Alex Vakulenko <avakulenko@chromium.org>
Commit-Queue: Vitaly Buka <vitalybuka@chromium.org>
diff --git a/libweave/include/weave/config.h b/libweave/include/weave/config_store.h
similarity index 68%
rename from libweave/include/weave/config.h
rename to libweave/include/weave/config_store.h
index e2512cb..f13ec8f 100644
--- a/libweave/include/weave/config.h
+++ b/libweave/include/weave/config_store.h
@@ -2,13 +2,14 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef LIBWEAVE_INCLUDE_WEAVE_CONFIG_H_
-#define LIBWEAVE_INCLUDE_WEAVE_CONFIG_H_
+#ifndef LIBWEAVE_INCLUDE_WEAVE_CONFIG_STORE_H_
+#define LIBWEAVE_INCLUDE_WEAVE_CONFIG_STORE_H_
 
 #include <set>
 #include <string>
 
 #include <base/callback.h>
+#include <base/time/time.h>
 #include <weave/enum_to_string.h>
 #include <weave/privet.h>
 
@@ -43,20 +44,17 @@
   std::string last_configured_ssid;
 };
 
-class Config {
+class ConfigStore {
  public:
-  // TODO(vitalybuka): Add information to identify changed values.
-  using OnChangedCallback = base::Callback<void(const Settings& settings)>;
-
-  // Sets callback which is called when config is changed.
-  virtual void AddOnChangedCallback(const OnChangedCallback& callback) = 0;
-
-  virtual const Settings& GetSettings() const = 0;
+  virtual bool LoadDefaults(Settings* settings) = 0;
+  virtual std::string LoadSettings() = 0;
+  virtual void SaveSettings(const std::string& settings) = 0;
+  virtual void OnSettingsChanged(const Settings& settings) = 0;
 
  protected:
-  virtual ~Config() = default;
+  virtual ~ConfigStore() = default;
 };
 
 }  // namespace weave
 
-#endif  // LIBWEAVE_INCLUDE_WEAVE_CONFIG_H_
+#endif  // LIBWEAVE_INCLUDE_WEAVE_CONFIG_STORE_H_
diff --git a/libweave/include/weave/device.h b/libweave/include/weave/device.h
index 585adba..25f18c0 100644
--- a/libweave/include/weave/device.h
+++ b/libweave/include/weave/device.h
@@ -12,7 +12,7 @@
 #include <base/files/file_path.h>
 #include <weave/cloud.h>
 #include <weave/commands.h>
-#include <weave/config.h>
+#include <weave/config_store.h>
 #include <weave/export.h>
 #include <weave/http_client.h>
 #include <weave/http_server.h>
@@ -42,6 +42,7 @@
   virtual ~Device() = default;
 
   virtual void Start(const Options& options,
+                     ConfigStore* config_store,
                      TaskRunner* task_runner,
                      HttpClient* http_client,
                      Network* network,
@@ -50,7 +51,6 @@
 
   virtual Commands* GetCommands() = 0;
   virtual State* GetState() = 0;
-  virtual Config* GetConfig() = 0;
   virtual Cloud* GetCloud() = 0;
   virtual Privet* GetPrivet() = 0;
 
diff --git a/libweave/include/weave/mock_config_store.h b/libweave/include/weave/mock_config_store.h
new file mode 100644
index 0000000..de44877
--- /dev/null
+++ b/libweave/include/weave/mock_config_store.h
@@ -0,0 +1,36 @@
+// Copyright 2015 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 LIBWEAVE_INCLUDE_WEAVE_MOCK_CONFIG_STORE_H_
+#define LIBWEAVE_INCLUDE_WEAVE_MOCK_CONFIG_STORE_H_
+
+#include <string>
+
+#include <gmock/gmock.h>
+#include <weave/config_store.h>
+
+using testing::_;
+using testing::Return;
+
+namespace weave {
+namespace unittests {
+
+class MockConfigStore : public ConfigStore {
+ public:
+  MockConfigStore() {
+    EXPECT_CALL(*this, LoadDefaults(_)).WillRepeatedly(Return(true));
+    EXPECT_CALL(*this, LoadSettings()).WillRepeatedly(Return(""));
+    EXPECT_CALL(*this, SaveSettings(_)).WillRepeatedly(Return());
+    EXPECT_CALL(*this, OnSettingsChanged(_)).WillRepeatedly(Return());
+  }
+  MOCK_METHOD1(LoadDefaults, bool(Settings*));
+  MOCK_METHOD0(LoadSettings, std::string());
+  MOCK_METHOD1(SaveSettings, void(const std::string&));
+  MOCK_METHOD1(OnSettingsChanged, void(const Settings&));
+};
+
+}  // namespace unittests
+}  // namespace weave
+
+#endif  // LIBWEAVE_INCLUDE_WEAVE_MOCK_CONFIG_STORE_H_
diff --git a/libweave/libweave.gyp b/libweave/libweave.gyp
index 649d9f4..d5f48b2 100644
--- a/libweave/libweave.gyp
+++ b/libweave/libweave.gyp
@@ -4,7 +4,6 @@
       'deps': [
         'expat',
         'libchrome-<(libbase_ver)',
-        'libchromeos-<(libbase_ver)',
         'libcrypto',
       ],
     },
@@ -35,7 +34,6 @@
       'sources': [
         'src/backoff_entry.cc',
         'src/base_api_handler.cc',
-        'src/buffet_config.cc',
         'src/commands/cloud_command_proxy.cc',
         'src/commands/command_definition.cc',
         'src/commands/command_dictionary.cc',
@@ -49,6 +47,7 @@
         'src/commands/schema_constants.cc',
         'src/commands/schema_utils.cc',
         'src/commands/user_role.cc',
+        'src/config.cc',
         'src/data_encoding.cc',
         'src/device_manager.cc',
         'src/device_registration_info.cc',
@@ -77,7 +76,6 @@
         'src/states/state_change_queue.cc',
         'src/states/state_manager.cc',
         'src/states/state_package.cc',
-        'src/storage_impls.cc',
         'src/string_utils.cc',
         'src/utils.cc',
       ],
@@ -117,7 +115,6 @@
           'variables': {
             'deps': [
               'libchrome-test-<(libbase_ver)',
-              'libchromeos-test-<(libbase_ver)',
             ],
           },
           'dependencies': [
@@ -132,7 +129,6 @@
             'external/crypto/sha2_unittest.cc',
             'src/backoff_entry_unittest.cc',
             'src/base_api_handler_unittest.cc',
-            'src/buffet_config_unittest.cc',
             'src/commands/cloud_command_proxy_unittest.cc',
             'src/commands/command_definition_unittest.cc',
             'src/commands/command_dictionary_unittest.cc',
@@ -141,6 +137,7 @@
             'src/commands/command_queue_unittest.cc',
             'src/commands/object_schema_unittest.cc',
             'src/commands/schema_utils_unittest.cc',
+            'src/config_unittest.cc',
             'src/data_encoding_unittest.cc',
             'src/device_registration_info_unittest.cc',
             'src/error_unittest.cc',
diff --git a/libweave/src/base_api_handler.cc b/libweave/src/base_api_handler.cc
index d09e512..655983b 100644
--- a/libweave/src/base_api_handler.cc
+++ b/libweave/src/base_api_handler.cc
@@ -50,7 +50,7 @@
 void BaseApiHandler::UpdateBaseConfiguration(Command* command) {
   command->SetProgress(base::DictionaryValue{}, nullptr);
 
-  const BuffetConfig& config{device_info_->GetConfig()};
+  const Config& config{device_info_->GetConfig()};
   std::string anonymous_access_role{config.local_anonymous_access_role()};
   bool discovery_enabled{config.local_discovery_enabled()};
   bool pairing_enabled{config.local_pairing_enabled()};
@@ -82,7 +82,7 @@
 void BaseApiHandler::UpdateDeviceInfo(Command* command) {
   command->SetProgress(base::DictionaryValue{}, nullptr);
 
-  const BuffetConfig& config{device_info_->GetConfig()};
+  const Config& config{device_info_->GetConfig()};
   std::string name{config.name()};
   std::string description{config.description()};
   std::string location{config.location()};
diff --git a/libweave/src/base_api_handler_unittest.cc b/libweave/src/base_api_handler_unittest.cc
index 735ddd9..9b22ef8 100644
--- a/libweave/src/base_api_handler_unittest.cc
+++ b/libweave/src/base_api_handler_unittest.cc
@@ -7,15 +7,15 @@
 #include <base/strings/string_number_conversions.h>
 #include <base/values.h>
 #include <gtest/gtest.h>
+#include <weave/mock_config_store.h>
 #include <weave/mock_http_client.h>
 
-#include "libweave/src/buffet_config.h"
 #include "libweave/src/commands/command_manager.h"
 #include "libweave/src/commands/unittest_utils.h"
+#include "libweave/src/config.h"
 #include "libweave/src/device_registration_info.h"
 #include "libweave/src/states/mock_state_change_queue_interface.h"
 #include "libweave/src/states/state_manager.h"
-#include "libweave/src/storage_impls.h"
 
 using testing::_;
 using testing::StrictMock;
@@ -57,9 +57,8 @@
     ASSERT_TRUE(state_manager_->LoadStateDefaults(*state_defaults, nullptr));
     dev_reg_.reset(new DeviceRegistrationInfo(
         command_manager_, state_manager_,
-        std::unique_ptr<BuffetConfig>{new BuffetConfig{
-            std::unique_ptr<StorageInterface>{new MemStorage}}},
-        nullptr, &http_client_, true, nullptr));
+        std::unique_ptr<Config>{new Config{&config_store_}}, nullptr,
+        &http_client_, true, nullptr));
     handler_.reset(new BaseApiHandler{dev_reg_.get(), "123123", state_manager_,
                                       command_manager_});
   }
@@ -84,6 +83,7 @@
               command_manager_->FindCommand(id)->GetStatus());
   }
 
+  unittests::MockConfigStore config_store_;
   StrictMock<unittests::MockHttpClient> http_client_;
   std::unique_ptr<DeviceRegistrationInfo> dev_reg_;
   std::shared_ptr<CommandManager> command_manager_;
@@ -107,7 +107,7 @@
     }
   })");
 
-  BuffetConfig& config{*dev_reg_->GetMutableConfig()};
+  Config& config{*dev_reg_->GetMutableConfig()};
 
   AddCommand(R"({
     'name' : 'base.updateBaseConfiguration',
@@ -155,7 +155,7 @@
   EXPECT_JSON_EQ(expected, *state_manager_->GetStateValuesAsJson());
 
   {
-    BuffetConfig::Transaction change{&config};
+    Config::Transaction change{&config};
     change.set_local_anonymous_access_role("viewer");
   }
   expected = R"({
@@ -196,7 +196,7 @@
     }
   })");
 
-  const BuffetConfig& config{dev_reg_->GetConfig()};
+  const Config& config{dev_reg_->GetConfig()};
   EXPECT_EQ("testName", config.name());
   EXPECT_EQ("testDescription", config.description());
   EXPECT_EQ("testLocation", config.location());
diff --git a/libweave/src/config.cc b/libweave/src/config.cc
index 85c75fe..5783486 100644
--- a/libweave/src/config.cc
+++ b/libweave/src/config.cc
@@ -6,31 +6,17 @@
 
 #include <set>
 
-#include <base/files/file_util.h>
+#include <base/bind.h>
+#include <base/json/json_reader.h>
+#include <base/json/json_writer.h>
 #include <base/logging.h>
 #include <base/strings/string_number_conversions.h>
+#include <base/values.h>
 #include <weave/enum_to_string.h>
 
-#include "libweave/src/storage_impls.h"
-#include "libweave/src/storage_interface.h"
+#include "libweave/src/privet/privet_types.h"
 #include "libweave/src/string_utils.h"
 
-namespace {
-
-bool IsValidAccessRole(const std::string& role) {
-  return role == "none" || role == "viewer" || role == "user";
-}
-
-bool StringToTimeDelta(const std::string& value, base::TimeDelta* delta) {
-  uint64_t ms{0};
-  if (!base::StringToUint64(value, &ms))
-    return false;
-  *delta = base::TimeDelta::FromMilliseconds(ms);
-  return true;
-}
-
-}  // namespace
-
 namespace weave {
 
 namespace config_keys {
@@ -46,23 +32,21 @@
 const char kLocalAnonymousAccessRole[] = "local_anonymous_access_role";
 const char kLocalDiscoveryEnabled[] = "local_discovery_enabled";
 const char kLocalPairingEnabled[] = "local_pairing_enabled";
-const char kOemName[] = "oem_name";
-const char kModelName[] = "model_name";
-const char kModelId[] = "model_id";
-const char kPollingPeriodMs[] = "polling_period_ms";
-const char kBackupPollingPeriodMs[] = "backup_polling_period_ms";
 const char kRefreshToken[] = "refresh_token";
 const char kDeviceId[] = "device_id";
 const char kRobotAccount[] = "robot_account";
-const char kWifiAutoSetupEnabled[] = "wifi_auto_setup_enabled";
-const char kBleSetupEnabled[] = "ble_setup_enabled";
-const char kEmbeddedCode[] = "embedded_code";
-const char kPairingModes[] = "pairing_modes";
 const char kLastConfiguredSsid[] = "last_configured_ssid";
 
 }  // namespace config_keys
 
-Settings Config::CreateDefaultSettings() {
+namespace {
+
+bool IsValidAccessRole(const std::string& role) {
+  privet::AuthScope scope;
+  return StringToEnum(role, &scope);
+}
+
+Settings CreateDefaultSettings() {
   Settings result;
   result.client_id = "58855907228.apps.googleusercontent.com";
   result.client_secret = "eHSAREAHrIqPsHBxCE9zPPBi";
@@ -84,11 +68,15 @@
   return result;
 }
 
-Config::Config(std::unique_ptr<StorageInterface> storage)
-    : storage_{std::move(storage)} {}
+}  // namespace
 
-Config::Config(const base::FilePath& state_path)
-    : Config{std::unique_ptr<StorageInterface>{new FileStorage{state_path}}} {}
+Config::Config(ConfigStore* config_store)
+    : settings_{CreateDefaultSettings()}, config_store_{config_store} {
+  if (config_store_) {
+    AddOnChangedCallback(base::Bind(&ConfigStore::OnSettingsChanged,
+                                    base::Unretained(config_store_)));
+  }
+}
 
 void Config::AddOnChangedCallback(const OnChangedCallback& callback) {
   on_changed_.push_back(callback);
@@ -100,97 +88,50 @@
   return settings_;
 }
 
-void Config::Load(const base::FilePath& config_path) {
-  chromeos::KeyValueStore store;
-  if (base::PathExists(config_path)) {
-    CHECK(store.Load(config_path)) << "Unable to read or parse config file at"
-                                   << config_path.value();
-  }
-  Load(store);
-}
-
-void Config::Load(const chromeos::KeyValueStore& store) {
+void Config::Load() {
   Transaction change{this};
   change.save_ = false;
 
-  store.GetString(config_keys::kClientId, &settings_.client_id);
+  settings_ = CreateDefaultSettings();
+
+  if (!config_store_)
+    return;
+
+  // Crash on any mistakes in defaults.
+  CHECK(config_store_->LoadDefaults(&settings_));
+
   CHECK(!settings_.client_id.empty());
-
-  store.GetString(config_keys::kClientSecret, &settings_.client_secret);
   CHECK(!settings_.client_secret.empty());
-
-  store.GetString(config_keys::kApiKey, &settings_.api_key);
   CHECK(!settings_.api_key.empty());
-
-  store.GetString(config_keys::kOAuthURL, &settings_.oauth_url);
   CHECK(!settings_.oauth_url.empty());
-
-  store.GetString(config_keys::kServiceURL, &settings_.service_url);
   CHECK(!settings_.service_url.empty());
-
-  store.GetString(config_keys::kOemName, &settings_.oem_name);
   CHECK(!settings_.oem_name.empty());
-
-  store.GetString(config_keys::kModelName, &settings_.model_name);
   CHECK(!settings_.model_name.empty());
-
-  store.GetString(config_keys::kModelId, &settings_.model_id);
   CHECK(!settings_.model_id.empty());
-
-  std::string polling_period_str;
-  if (store.GetString(config_keys::kPollingPeriodMs, &polling_period_str))
-    CHECK(StringToTimeDelta(polling_period_str, &settings_.polling_period));
-
-  if (store.GetString(config_keys::kBackupPollingPeriodMs, &polling_period_str))
-    CHECK(StringToTimeDelta(polling_period_str,
-                            &settings_.backup_polling_period));
-
-  store.GetBoolean(config_keys::kWifiAutoSetupEnabled,
-                   &settings_.wifi_auto_setup_enabled);
-
-  store.GetBoolean(config_keys::kBleSetupEnabled, &settings_.ble_setup_enabled);
-
-  store.GetString(config_keys::kEmbeddedCode, &settings_.embedded_code);
-
-  std::string modes_str;
-  if (store.GetString(config_keys::kPairingModes, &modes_str)) {
-    std::set<PairingType> pairing_modes;
-    for (const std::string& mode : Split(modes_str, ",", true, true)) {
-      PairingType pairing_mode;
-      CHECK(StringToEnum(mode, &pairing_mode));
-      pairing_modes.insert(pairing_mode);
-    }
-    settings_.pairing_modes = std::move(pairing_modes);
-  }
-
-  // Empty name set by user or server is allowed, still we expect some
-  // meaningfull config value.
-  store.GetString(config_keys::kName, &settings_.name);
   CHECK(!settings_.name.empty());
-
-  store.GetString(config_keys::kDescription, &settings_.description);
-  store.GetString(config_keys::kLocation, &settings_.location);
-
-  store.GetString(config_keys::kLocalAnonymousAccessRole,
-                  &settings_.local_anonymous_access_role);
   CHECK(IsValidAccessRole(settings_.local_anonymous_access_role))
       << "Invalid role: " << settings_.local_anonymous_access_role;
-
-  store.GetBoolean(config_keys::kLocalDiscoveryEnabled,
-                   &settings_.local_discovery_enabled);
-  store.GetBoolean(config_keys::kLocalPairingEnabled,
-                   &settings_.local_pairing_enabled);
+  CHECK_EQ(
+      settings_.embedded_code.empty(),
+      std::find(settings_.pairing_modes.begin(), settings_.pairing_modes.end(),
+                PairingType::kEmbeddedCode) == settings_.pairing_modes.end());
 
   change.LoadState();
 }
 
 void Config::Transaction::LoadState() {
-  if (!config_->storage_)
+  if (!config_->config_store_)
     return;
-  auto value = config_->storage_->Load();
+  std::string json_string = config_->config_store_->LoadSettings();
+  if (json_string.empty())
+    return;
+
+  auto value = base::JSONReader::Read(json_string);
   const base::DictionaryValue* dict = nullptr;
-  if (!value || !value->GetAsDictionary(&dict))
+  if (!value || !value->GetAsDictionary(&dict)) {
+    LOG(ERROR) << "Failed to parse settings.";
     return;
+  }
 
   std::string tmp;
   bool tmp_bool{false};
@@ -241,9 +182,10 @@
     set_device_id(tmp);
 }
 
-bool Config::Save() {
-  if (!storage_)
-    return false;
+void Config::Save() {
+  if (!config_store_)
+    return;
+
   base::DictionaryValue dict;
   dict.SetString(config_keys::kClientId, settings_.client_id);
   dict.SetString(config_keys::kClientSecret, settings_.client_secret);
@@ -265,7 +207,11 @@
   dict.SetBoolean(config_keys::kLocalPairingEnabled,
                   settings_.local_pairing_enabled);
 
-  return storage_->Save(dict);
+  std::string json_string;
+  base::JSONWriter::WriteWithOptions(
+      dict, base::JSONWriter::OPTIONS_PRETTY_PRINT, &json_string);
+
+  config_store_->SaveSettings(json_string);
 }
 
 Config::Transaction::~Transaction() {
diff --git a/libweave/src/config.h b/libweave/src/config.h
index 5871629..55d7d09 100644
--- a/libweave/src/config.h
+++ b/libweave/src/config.h
@@ -10,10 +10,8 @@
 #include <vector>
 
 #include <base/callback.h>
-#include <base/files/file_path.h>
+#include <weave/config_store.h>
 #include <weave/error.h>
-#include <chromeos/key_value_store.h>
-#include <weave/config.h>
 
 #include "libweave/src/privet/security_delegate.h"
 
@@ -22,21 +20,17 @@
 class StorageInterface;
 
 // Handles reading buffet config and state files.
-class Config final : public Config {
+class Config final {
  public:
   using OnChangedCallback = base::Callback<void(const Settings&)>;
-  ~Config() override = default;
+  ~Config() = default;
 
-  explicit Config(std::unique_ptr<StorageInterface> storage);
+  explicit Config(ConfigStore* config_store);
 
-  explicit Config(const base::FilePath& state_path);
+  void AddOnChangedCallback(const OnChangedCallback& callback);
+  const Settings& GetSettings() const;
 
-  // Config overrides.
-  void AddOnChangedCallback(const OnChangedCallback& callback) override;
-  const Settings& GetSettings() const override;
-
-  void Load(const base::FilePath& config_path);
-  void Load(const chromeos::KeyValueStore& store);
+  void Load();
 
   // Allows editing of config. Makes sure that callbacks were called and changes
   // were saved.
@@ -136,14 +130,10 @@
   }
 
  private:
-  bool Save();
-  static Settings CreateDefaultSettings();
+  void Save();
 
-  Settings settings_ = CreateDefaultSettings();
-
-  // Serialization interface to save and load buffet state.
-  std::unique_ptr<StorageInterface> storage_;
-
+  Settings settings_;
+  ConfigStore* config_store_{nullptr};
   std::vector<OnChangedCallback> on_changed_;
 
   DISALLOW_COPY_AND_ASSIGN(Config);
diff --git a/libweave/src/config_unittest.cc b/libweave/src/config_unittest.cc
index 0ffad43..be24e00 100644
--- a/libweave/src/config_unittest.cc
+++ b/libweave/src/config_unittest.cc
@@ -9,11 +9,12 @@
 #include <base/bind.h>
 #include <gmock/gmock.h>
 #include <gtest/gtest.h>
+#include <weave/mock_config_store.h>
 
 #include "libweave/src/commands/unittest_utils.h"
-#include "libweave/src/storage_impls.h"
 
 using testing::_;
+using testing::Invoke;
 
 namespace weave {
 
@@ -22,18 +23,14 @@
   void SetUp() override {
     EXPECT_CALL(*this, OnConfigChanged(_))
         .Times(1);  // Called from AddOnChangedCallback
-
-    std::unique_ptr<StorageInterface> storage{new MemStorage};
-    storage_ = storage.get();
-    config_.reset(new Config{std::move(storage)});
-
+    config_.reset(new Config{&config_store_});
     config_->AddOnChangedCallback(
         base::Bind(&ConfigTest::OnConfigChanged, base::Unretained(this)));
   }
 
   MOCK_METHOD1(OnConfigChanged, void(const Settings&));
 
-  StorageInterface* storage_{nullptr};
+  unittests::MockConfigStore config_store_;
   std::unique_ptr<Config> config_;
   const Config default_{nullptr};
 };
@@ -73,125 +70,28 @@
   EXPECT_EQ("", config_->last_configured_ssid());
 }
 
-TEST_F(ConfigTest, LoadConfig) {
-  chromeos::KeyValueStore config_store;
-  config_store.SetString("client_id", "conf_client_id");
-  config_store.SetString("client_secret", "conf_client_secret");
-  config_store.SetString("api_key", "conf_api_key");
-  config_store.SetString("oauth_url", "conf_oauth_url");
-  config_store.SetString("service_url", "conf_service_url");
-  config_store.SetString("oem_name", "conf_oem_name");
-  config_store.SetString("model_name", "conf_model_name");
-  config_store.SetString("model_id", "ABCDE");
-  config_store.SetString("polling_period_ms", "12345");
-  config_store.SetString("backup_polling_period_ms", "6589");
-  config_store.SetBoolean("wifi_auto_setup_enabled", false);
-  config_store.SetBoolean("ble_setup_enabled", true);
-  config_store.SetString("pairing_modes",
-                         "pinCode,embeddedCode,ultrasound32,audible32");
-  config_store.SetString("embedded_code", "1234");
-  config_store.SetString("name", "conf_name");
-  config_store.SetString("description", "conf_description");
-  config_store.SetString("location", "conf_location");
-  config_store.SetString("local_anonymous_access_role", "user");
-  config_store.SetBoolean("local_pairing_enabled", false);
-  config_store.SetBoolean("local_discovery_enabled", false);
-
-  // Following will be ignored.
-  config_store.SetString("device_kind", "conf_device_kind");
-  config_store.SetString("device_id", "conf_device_id");
-  config_store.SetString("refresh_token", "conf_refresh_token");
-  config_store.SetString("robot_account", "conf_robot_account");
-  config_store.SetString("last_configured_ssid", "conf_last_configured_ssid");
-
-  EXPECT_CALL(*this, OnConfigChanged(_)).Times(1);
-  config_->Load(config_store);
-
-  EXPECT_EQ("conf_client_id", config_->client_id());
-  EXPECT_EQ("conf_client_secret", config_->client_secret());
-  EXPECT_EQ("conf_api_key", config_->api_key());
-  EXPECT_EQ("conf_oauth_url", config_->oauth_url());
-  EXPECT_EQ("conf_service_url", config_->service_url());
-  EXPECT_EQ("conf_oem_name", config_->oem_name());
-  EXPECT_EQ("conf_model_name", config_->model_name());
-  EXPECT_EQ("ABCDE", config_->model_id());
-  EXPECT_EQ(base::TimeDelta::FromMilliseconds(12345),
-            config_->polling_period());
-  EXPECT_EQ(base::TimeDelta::FromMilliseconds(6589),
-            config_->backup_polling_period());
-  EXPECT_FALSE(config_->wifi_auto_setup_enabled());
-  EXPECT_TRUE(config_->ble_setup_enabled());
-  std::set<PairingType> pairing_types{
-      PairingType::kPinCode, PairingType::kEmbeddedCode,
-      PairingType::kUltrasound32, PairingType::kAudible32};
-  EXPECT_EQ(pairing_types, config_->pairing_modes());
-  EXPECT_EQ("1234", config_->embedded_code());
-  EXPECT_EQ("conf_name", config_->name());
-  EXPECT_EQ("conf_description", config_->description());
-  EXPECT_EQ("conf_location", config_->location());
-  EXPECT_EQ("user", config_->local_anonymous_access_role());
-  EXPECT_FALSE(config_->local_pairing_enabled());
-  EXPECT_FALSE(config_->local_discovery_enabled());
-
-  // Not from config.
-  EXPECT_EQ(default_.device_id(), config_->device_id());
-  EXPECT_EQ(default_.refresh_token(), config_->refresh_token());
-  EXPECT_EQ(default_.robot_account(), config_->robot_account());
-  EXPECT_EQ(default_.last_configured_ssid(), config_->last_configured_ssid());
-
-  // Nothing should be saved yet.
-  EXPECT_JSON_EQ("{}", *storage_->Load());
-
-  Config::Transaction change{config_.get()};
-  EXPECT_CALL(*this, OnConfigChanged(_)).Times(1);
-  change.Commit();
-
-  auto expected = R"({
-    'api_key': 'conf_api_key',
-    'client_id': 'conf_client_id',
-    'client_secret': 'conf_client_secret',
-    'description': 'conf_description',
-    'device_id': '',
-    'local_anonymous_access_role': 'user',
-    'local_discovery_enabled': false,
-    'local_pairing_enabled': false,
-    'location': 'conf_location',
-    'name': 'conf_name',
-    'oauth_url': 'conf_oauth_url',
-    'refresh_token': '',
-    'robot_account': '',
-    'last_configured_ssid': '',
-    'service_url': 'conf_service_url'
-  })";
-  EXPECT_JSON_EQ(expected, *storage_->Load());
-}
-
 TEST_F(ConfigTest, LoadState) {
   auto state = R"({
-    'api_key': 'state_api_key',
-    'client_id': 'state_client_id',
-    'client_secret': 'state_client_secret',
-    'description': 'state_description',
-    'device_id': 'state_device_id',
-    'local_anonymous_access_role': 'user',
-    'local_discovery_enabled': false,
-    'local_pairing_enabled': false,
-    'location': 'state_location',
-    'name': 'state_name',
-    'oauth_url': 'state_oauth_url',
-    'refresh_token': 'state_refresh_token',
-    'robot_account': 'state_robot_account',
-    'last_configured_ssid': 'state_last_configured_ssid',
-    'service_url': 'state_service_url'
+    "api_key": "state_api_key",
+    "client_id": "state_client_id",
+    "client_secret": "state_client_secret",
+    "description": "state_description",
+    "device_id": "state_device_id",
+    "local_anonymous_access_role": "user",
+    "local_discovery_enabled": false,
+    "local_pairing_enabled": false,
+    "location": "state_location",
+    "name": "state_name",
+    "oauth_url": "state_oauth_url",
+    "refresh_token": "state_refresh_token",
+    "robot_account": "state_robot_account",
+    "last_configured_ssid": "state_last_configured_ssid",
+    "service_url": "state_service_url"
   })";
-  storage_->Save(*unittests::CreateDictionaryValue(state));
+  EXPECT_CALL(config_store_, LoadSettings()).WillOnce(Return(state));
 
-  chromeos::KeyValueStore config_store;
   EXPECT_CALL(*this, OnConfigChanged(_)).Times(1);
-  config_->Load(config_store);
-
-  // Clear storage.
-  storage_->Save(base::DictionaryValue());
+  config_->Load();
 
   EXPECT_EQ("state_client_id", config_->client_id());
   EXPECT_EQ("state_client_secret", config_->client_secret());
@@ -218,15 +118,6 @@
   EXPECT_EQ("state_refresh_token", config_->refresh_token());
   EXPECT_EQ("state_robot_account", config_->robot_account());
   EXPECT_EQ("state_last_configured_ssid", config_->last_configured_ssid());
-
-  // Nothing should be saved yet.
-  EXPECT_JSON_EQ("{}", *storage_->Load());
-
-  Config::Transaction change{config_.get()};
-  EXPECT_CALL(*this, OnConfigChanged(_)).Times(1);
-  change.Commit();
-
-  EXPECT_JSON_EQ(state, *storage_->Load());
 }
 
 TEST_F(ConfigTest, Setters) {
@@ -290,25 +181,31 @@
   EXPECT_EQ("set_last_configured_ssid", config_->last_configured_ssid());
 
   EXPECT_CALL(*this, OnConfigChanged(_)).Times(1);
-  change.Commit();
 
-  auto expected = R"({
-    'api_key': 'set_api_key',
-    'client_id': 'set_client_id',
-    'client_secret': 'set_client_secret',
-    'description': 'set_description',
-    'device_id': 'set_id',
-    'local_anonymous_access_role': 'user',
-    'local_discovery_enabled': true,
-    'local_pairing_enabled': true,
-    'location': 'set_location',
-    'name': 'set_name',
-    'oauth_url': 'set_oauth_url',
-    'refresh_token': 'set_token',
-    'robot_account': 'set_account',
-    'last_configured_ssid': 'set_last_configured_ssid',
-    'service_url': 'set_service_url'
-  })";
-  EXPECT_JSON_EQ(expected, *storage_->Load());
+  EXPECT_CALL(config_store_, SaveSettings(_))
+      .WillOnce(Invoke([](const std::string& json) {
+        auto expected = R"({
+          'api_key': 'set_api_key',
+          'client_id': 'set_client_id',
+          'client_secret': 'set_client_secret',
+          'description': 'set_description',
+          'device_id': 'set_id',
+          'local_anonymous_access_role': 'user',
+          'local_discovery_enabled': true,
+          'local_pairing_enabled': true,
+          'location': 'set_location',
+          'name': 'set_name',
+          'oauth_url': 'set_oauth_url',
+          'refresh_token': 'set_token',
+          'robot_account': 'set_account',
+          'last_configured_ssid': 'set_last_configured_ssid',
+          'service_url': 'set_service_url'
+        })";
+        EXPECT_JSON_EQ(expected, *unittests::CreateValue(json));
+      }));
+  EXPECT_CALL(config_store_, OnSettingsChanged(_)).Times(1);
+
+  change.Commit();
 }
+
 }  // namespace weave
diff --git a/libweave/src/device_manager.cc b/libweave/src/device_manager.cc
index 4d3c251..846298a 100644
--- a/libweave/src/device_manager.cc
+++ b/libweave/src/device_manager.cc
@@ -7,8 +7,8 @@
 #include <string>
 
 #include "libweave/src/base_api_handler.h"
-#include "libweave/src/buffet_config.h"
 #include "libweave/src/commands/command_manager.h"
+#include "libweave/src/config.h"
 #include "libweave/src/device_registration_info.h"
 #include "libweave/src/privet/privet_manager.h"
 #include "libweave/src/states/state_change_queue.h"
@@ -28,6 +28,7 @@
 DeviceManager::~DeviceManager() {}
 
 void DeviceManager::Start(const Options& options,
+                          ConfigStore* config_store,
                           TaskRunner* task_runner,
                           HttpClient* http_client,
                           Network* network,
@@ -40,8 +41,8 @@
   state_manager_ = std::make_shared<StateManager>(state_change_queue_.get());
   state_manager_->Startup();
 
-  std::unique_ptr<BuffetConfig> config{new BuffetConfig{options.state_path}};
-  config->Load(options.config_path);
+  std::unique_ptr<Config> config{new Config{config_store}};
+  config->Load();
 
   // TODO(avakulenko): Figure out security implications of storing
   // device info state data unencrypted.
@@ -101,7 +102,7 @@
     weave::privet::WifiBootstrapManager::State state) {
   const std::string& ssid = privet_->GetCurrentlyConnectedSsid();
   if (ssid != device_info_->GetConfig().last_configured_ssid()) {
-    weave::BuffetConfig::Transaction change{device_info_->GetMutableConfig()};
+    weave::Config::Transaction change{device_info_->GetMutableConfig()};
     change.set_last_configured_ssid(ssid);
   }
 }
diff --git a/libweave/src/device_manager.h b/libweave/src/device_manager.h
index cfa9ce0..951cbf2 100644
--- a/libweave/src/device_manager.h
+++ b/libweave/src/device_manager.h
@@ -11,7 +11,7 @@
 namespace weave {
 
 class BaseApiHandler;
-class BuffetConfig;
+class Config;
 class CommandManager;
 class DeviceRegistrationInfo;
 class StateChangeQueue;
@@ -27,6 +27,7 @@
   ~DeviceManager() override;
 
   void Start(const Options& options,
+             ConfigStore* config_store,
              TaskRunner* task_runner,
              HttpClient* http_client,
              Network* network,
@@ -35,10 +36,11 @@
 
   Commands* GetCommands() override;
   State* GetState() override;
-  Config* GetConfig() override;
   Cloud* GetCloud() override;
   Privet* GetPrivet() override;
 
+  Config* GetConfig();
+
  private:
   void StartPrivet(const Options& options,
                    TaskRunner* task_runner,
diff --git a/libweave/src/device_registration_info.cc b/libweave/src/device_registration_info.cc
index 0f150e1..26e47ed 100644
--- a/libweave/src/device_registration_info.cc
+++ b/libweave/src/device_registration_info.cc
@@ -15,7 +15,6 @@
 #include <base/json/json_writer.h>
 #include <base/strings/string_number_conversions.h>
 #include <base/values.h>
-#include <chromeos/key_value_store.h>
 #include <weave/http_client.h>
 #include <weave/network.h>
 #include <weave/task_runner.h>
@@ -215,7 +214,7 @@
 DeviceRegistrationInfo::DeviceRegistrationInfo(
     const std::shared_ptr<CommandManager>& command_manager,
     const std::shared_ptr<StateManager>& state_manager,
-    std::unique_ptr<BuffetConfig> config,
+    std::unique_ptr<Config> config,
     TaskRunner* task_runner,
     HttpClient* http_client,
     bool notifications_enabled,
@@ -480,7 +479,7 @@
 }
 
 void DeviceRegistrationInfo::AddOnConfigChangedCallback(
-    const BuffetConfig::OnChangedCallback& callback) {
+    const Config::OnChangedCallback& callback) {
   config_->AddOnChangedCallback(callback);
 }
 
@@ -614,7 +613,7 @@
   access_token_expiration_ =
       base::Time::Now() + base::TimeDelta::FromSeconds(expires_in);
 
-  BuffetConfig::Transaction change{config_.get()};
+  Config::Transaction change{config_.get()};
   change.set_device_id(device_id);
   change.set_robot_account(robot_account);
   change.set_refresh_token(refresh_token);
@@ -807,7 +806,7 @@
                                               const std::string& description,
                                               const std::string& location,
                                               ErrorPtr* error) {
-  BuffetConfig::Transaction change{config_.get()};
+  Config::Transaction change{config_.get()};
   change.set_name(name);
   change.set_description(description);
   change.set_location(location);
@@ -826,7 +825,7 @@
     bool local_discovery_enabled,
     bool local_pairing_enabled,
     ErrorPtr* error) {
-  BuffetConfig::Transaction change(config_.get());
+  Config::Transaction change(config_.get());
   if (!change.set_local_anonymous_access_role(anonymous_access_role)) {
     Error::AddToPrintf(error, FROM_HERE, kErrorDomain, "invalid_parameter",
                        "Invalid role: %s", anonymous_access_role.c_str());
@@ -851,7 +850,7 @@
                  "Unable to change config for registered device");
     return false;
   }
-  BuffetConfig::Transaction change{config_.get()};
+  Config::Transaction change{config_.get()};
   change.set_client_id(client_id);
   change.set_client_secret(client_secret);
   change.set_api_key(api_key);
@@ -1273,7 +1272,7 @@
   connected_to_cloud_ = false;
 
   LOG(INFO) << "Device is unregistered from the cloud. Deleting credentials";
-  BuffetConfig::Transaction change{config_.get()};
+  Config::Transaction change{config_.get()};
   change.set_device_id("");
   change.set_robot_account("");
   change.set_refresh_token("");
diff --git a/libweave/src/device_registration_info.h b/libweave/src/device_registration_info.h
index 1dcc41b..45f2257 100644
--- a/libweave/src/device_registration_info.h
+++ b/libweave/src/device_registration_info.h
@@ -20,19 +20,17 @@
 #include <base/timer/timer.h>
 #include <weave/error.h>
 #include <weave/cloud.h>
-#include <weave/config.h>
 #include <weave/http_client.h>
 
 #include "libweave/src/backoff_entry.h"
-#include "libweave/src/buffet_config.h"
 #include "libweave/src/commands/cloud_command_update_interface.h"
 #include "libweave/src/commands/command_manager.h"
+#include "libweave/src/config.h"
 #include "libweave/src/data_encoding.h"
 #include "libweave/src/notification/notification_channel.h"
 #include "libweave/src/notification/notification_delegate.h"
 #include "libweave/src/notification/pull_channel.h"
 #include "libweave/src/states/state_change_queue_interface.h"
-#include "libweave/src/storage_interface.h"
 
 namespace base {
 class DictionaryValue;
@@ -63,7 +61,7 @@
 
   DeviceRegistrationInfo(const std::shared_ptr<CommandManager>& command_manager,
                          const std::shared_ptr<StateManager>& state_manager,
-                         std::unique_ptr<BuffetConfig> config,
+                         std::unique_ptr<Config> config,
                          TaskRunner* task_runner,
                          HttpClient* http_client,
                          bool notifications_enabled,
@@ -137,8 +135,8 @@
                      const base::Closure& on_error) override;
 
   // TODO(vitalybuka): remove getters and pass config to dependent code.
-  const BuffetConfig& GetConfig() const { return *config_; }
-  BuffetConfig* GetMutableConfig() { return config_.get(); }
+  const Config& GetConfig() const { return *config_; }
+  Config* GetMutableConfig() { return config_.get(); }
 
  private:
   friend class DeviceRegistrationInfoTest;
@@ -301,7 +299,7 @@
   // Device state manager.
   std::shared_ptr<StateManager> state_manager_;
 
-  std::unique_ptr<BuffetConfig> config_;
+  std::unique_ptr<Config> config_;
 
   // Backoff manager for DoCloudRequest() method.
   std::unique_ptr<BackoffEntry::Policy> cloud_backoff_policy_;
diff --git a/libweave/src/device_registration_info_unittest.cc b/libweave/src/device_registration_info_unittest.cc
index 9c70207..ec79c5d 100644
--- a/libweave/src/device_registration_info_unittest.cc
+++ b/libweave/src/device_registration_info_unittest.cc
@@ -7,8 +7,8 @@
 #include <base/json/json_reader.h>
 #include <base/json/json_writer.h>
 #include <base/values.h>
-#include <chromeos/key_value_store.h>
 #include <gtest/gtest.h>
+#include <weave/mock_config_store.h>
 #include <weave/mock_http_client.h>
 
 #include "libweave/src/bind_lambda.h"
@@ -17,7 +17,6 @@
 #include "libweave/src/http_constants.h"
 #include "libweave/src/states/mock_state_change_queue_interface.h"
 #include "libweave/src/states/state_manager.h"
-#include "libweave/src/storage_impls.h"
 
 using testing::_;
 using testing::AtLeast;
@@ -27,6 +26,7 @@
 using testing::Return;
 using testing::ReturnRef;
 using testing::ReturnRefOfCopy;
+using testing::SaveArg;
 using testing::StrictMock;
 using testing::WithArgs;
 
@@ -66,13 +66,6 @@
 
 }  // namespace test_data
 
-// Add the test device registration information.
-void SetDefaultDeviceRegistration(base::DictionaryValue* data) {
-  data->SetString("refresh_token", test_data::kRefreshToken);
-  data->SetString("device_id", test_data::kDeviceId);
-  data->SetString("robot_account", test_data::kRobotAccountEmail);
-}
-
 std::string GetFormField(const std::string& data, const std::string& name) {
   EXPECT_FALSE(data.empty());
   for (const auto& i : WebParamsDecode(data)) {
@@ -123,38 +116,49 @@
     EXPECT_CALL(mock_state_change_queue_, MockAddOnStateUpdatedCallback(_))
         .WillRepeatedly(Return(nullptr));
 
-    std::unique_ptr<StorageInterface> storage{new MemStorage};
-    storage_ = storage.get();
-    storage->Save(data_);
     command_manager_ = std::make_shared<CommandManager>();
     state_manager_ = std::make_shared<StateManager>(&mock_state_change_queue_);
 
-    std::unique_ptr<BuffetConfig> config{new BuffetConfig{std::move(storage)}};
+    std::unique_ptr<Config> config{new Config{&config_store_}};
     config_ = config.get();
     dev_reg_.reset(new DeviceRegistrationInfo{command_manager_, state_manager_,
                                               std::move(config), nullptr,
                                               &http_client_, true, nullptr});
 
-    ReloadConfig();
+    ReloadDefaults();
   }
 
-  void ReloadConfig() {
-    chromeos::KeyValueStore config_store;
-    config_store.SetString("client_id", test_data::kClientId);
-    config_store.SetString("client_secret", test_data::kClientSecret);
-    config_store.SetString("api_key", test_data::kApiKey);
-    config_store.SetString("device_kind", "vendor");
-    config_store.SetString("name", "Coffee Pot");
-    config_store.SetString("description", "Easy to clean");
-    config_store.SetString("location", "Kitchen");
-    config_store.SetString("local_anonymous_access_role", "viewer");
-    config_store.SetString("model_id", "AAAAA");
-    config_store.SetString("oauth_url", test_data::kOAuthURL);
-    config_store.SetString("service_url", test_data::kServiceURL);
-    config_->Load(config_store);
+  void ReloadDefaults() {
+    EXPECT_CALL(config_store_, LoadDefaults(_))
+        .WillOnce(Invoke([](Settings* settings) {
+          settings->client_id = test_data::kClientId;
+          settings->client_secret = test_data::kClientSecret;
+          settings->api_key = test_data::kApiKey;
+          settings->name = "Coffee Pot";
+          settings->description = "Easy to clean";
+          settings->location = "Kitchen";
+          settings->local_anonymous_access_role = "viewer";
+          settings->model_id = "AAAAA";
+          settings->oauth_url = test_data::kOAuthURL;
+          settings->service_url = test_data::kServiceURL;
+          return true;
+        }));
+    config_->Load();
     dev_reg_->Start();
   }
 
+  void ReloadSettings() {
+    base::DictionaryValue dict;
+    dict.SetString("refresh_token", test_data::kRefreshToken);
+    dict.SetString("device_id", test_data::kDeviceId);
+    dict.SetString("robot_account", test_data::kRobotAccountEmail);
+    std::string json_string;
+    base::JSONWriter::WriteWithOptions(
+        dict, base::JSONWriter::OPTIONS_PRETTY_PRINT, &json_string);
+    EXPECT_CALL(config_store_, LoadSettings()).WillOnce(Return(json_string));
+    ReloadDefaults();
+  }
+
   void PublishCommands(const base::ListValue& commands) {
     return dev_reg_->PublishCommands(commands);
   }
@@ -177,10 +181,10 @@
     return dev_reg_->registration_status_;
   }
 
+  unittests::MockConfigStore config_store_;
   StrictMock<MockHttpClient> http_client_;
   base::DictionaryValue data_;
-  StorageInterface* storage_{nullptr};
-  BuffetConfig* config_{nullptr};
+  Config* config_{nullptr};
   std::unique_ptr<DeviceRegistrationInfo> dev_reg_;
   std::shared_ptr<CommandManager> command_manager_;
   StrictMock<MockStateChangeQueueInterface> mock_state_change_queue_;
@@ -223,9 +227,7 @@
 
 TEST_F(DeviceRegistrationInfoTest, HaveRegistrationCredentials) {
   EXPECT_FALSE(dev_reg_->HaveRegistrationCredentials());
-  SetDefaultDeviceRegistration(&data_);
-  storage_->Save(data_);
-  ReloadConfig();
+  ReloadSettings();
 
   EXPECT_CALL(http_client_,
               MockSendRequest(http::kPost, dev_reg_->GetOAuthURL("token"),
@@ -250,9 +252,7 @@
 }
 
 TEST_F(DeviceRegistrationInfoTest, CheckAuthenticationFailure) {
-  SetDefaultDeviceRegistration(&data_);
-  storage_->Save(data_);
-  ReloadConfig();
+  ReloadSettings();
   EXPECT_EQ(RegistrationStatus::kConnecting, GetRegistrationStatus());
 
   EXPECT_CALL(http_client_,
@@ -278,9 +278,7 @@
 }
 
 TEST_F(DeviceRegistrationInfoTest, CheckDeregistration) {
-  SetDefaultDeviceRegistration(&data_);
-  storage_->Save(data_);
-  ReloadConfig();
+  ReloadSettings();
   EXPECT_EQ(RegistrationStatus::kConnecting, GetRegistrationStatus());
 
   EXPECT_CALL(http_client_,
@@ -306,9 +304,7 @@
 }
 
 TEST_F(DeviceRegistrationInfoTest, GetDeviceInfo) {
-  SetDefaultDeviceRegistration(&data_);
-  storage_->Save(data_);
-  ReloadConfig();
+  ReloadSettings();
   SetAccessToken();
 
   EXPECT_CALL(http_client_,
@@ -483,6 +479,11 @@
         return ReplyWithJson(200, json);
       })));
 
+  Settings saved_settings;
+  EXPECT_CALL(config_store_, OnSettingsChanged(_))
+      .Times(AtLeast(1))
+      .WillRepeatedly(SaveArg<0>(&saved_settings));
+
   std::string device_id =
       dev_reg_->RegisterDevice(test_data::kClaimTicketId, nullptr);
 
@@ -490,16 +491,9 @@
   EXPECT_EQ(RegistrationStatus::kConnecting, GetRegistrationStatus());
 
   // Validate the device info saved to storage...
-  auto storage_data = storage_->Load();
-  base::DictionaryValue* dict = nullptr;
-  EXPECT_TRUE(storage_data->GetAsDictionary(&dict));
-  std::string value;
-  EXPECT_TRUE(dict->GetString("device_id", &value));
-  EXPECT_EQ(test_data::kDeviceId, value);
-  EXPECT_TRUE(dict->GetString("refresh_token", &value));
-  EXPECT_EQ(test_data::kRefreshToken, value);
-  EXPECT_TRUE(dict->GetString("robot_account", &value));
-  EXPECT_EQ(test_data::kRobotAccountEmail, value);
+  EXPECT_EQ(test_data::kDeviceId, saved_settings.device_id);
+  EXPECT_EQ(test_data::kRefreshToken, saved_settings.refresh_token);
+  EXPECT_EQ(test_data::kRobotAccountEmail, saved_settings.robot_account);
 }
 
 TEST_F(DeviceRegistrationInfoTest, OOBRegistrationStatus) {
@@ -507,16 +501,12 @@
   // unregistered, depending on whether or not we've found credentials.
   EXPECT_EQ(RegistrationStatus::kUnconfigured, GetRegistrationStatus());
   // Put some credentials into our state, make sure we call that offline.
-  SetDefaultDeviceRegistration(&data_);
-  storage_->Save(data_);
-  ReloadConfig();
+  ReloadSettings();
   EXPECT_EQ(RegistrationStatus::kConnecting, GetRegistrationStatus());
 }
 
 TEST_F(DeviceRegistrationInfoTest, UpdateCommand) {
-  SetDefaultDeviceRegistration(&data_);
-  storage_->Save(data_);
-  ReloadConfig();
+  ReloadSettings();
   SetAccessToken();
 
   auto json_cmds = CreateDictionaryValue(R"({
diff --git a/libweave/src/privet/cloud_delegate.cc b/libweave/src/privet/cloud_delegate.cc
index 3a2a249..f761b67 100644
--- a/libweave/src/privet/cloud_delegate.cc
+++ b/libweave/src/privet/cloud_delegate.cc
@@ -14,8 +14,8 @@
 #include <weave/error.h>
 #include <weave/task_runner.h>
 
-#include "libweave/src/buffet_config.h"
 #include "libweave/src/commands/command_manager.h"
+#include "libweave/src/config.h"
 #include "libweave/src/device_registration_info.h"
 #include "libweave/src/privet/constants.h"
 #include "libweave/src/states/state_manager.h"
diff --git a/libweave/src/states/state_manager.cc b/libweave/src/states/state_manager.cc
index 48dbc74..455b563 100644
--- a/libweave/src/states/state_manager.cc
+++ b/libweave/src/states/state_manager.cc
@@ -8,7 +8,6 @@
 #include <base/files/file_path.h>
 #include <base/logging.h>
 #include <base/values.h>
-#include <chromeos/key_value_store.h>
 
 #include "libweave/src/json_error_codes.h"
 #include "libweave/src/states/error_codes.h"
diff --git a/libweave/src/storage_impls.cc b/libweave/src/storage_impls.cc
deleted file mode 100644
index 025af39..0000000
--- a/libweave/src/storage_impls.cc
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright 2014 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 "libweave/src/storage_impls.h"
-
-#include <string>
-
-#include <base/files/important_file_writer.h>
-#include <base/json/json_writer.h>
-
-#include "libweave/src/utils.h"
-
-namespace weave {
-
-FileStorage::FileStorage(const base::FilePath& file_path)
-    : file_path_(file_path) {
-}
-
-std::unique_ptr<base::DictionaryValue> FileStorage::Load() {
-  return LoadJsonDict(file_path_, nullptr);
-}
-
-bool FileStorage::Save(const base::DictionaryValue& config) {
-  std::string json;
-  base::JSONWriter::WriteWithOptions(
-      config, base::JSONWriter::OPTIONS_PRETTY_PRINT, &json);
-  return base::ImportantFileWriter::WriteFileAtomically(file_path_, json);
-}
-
-std::unique_ptr<base::DictionaryValue> MemStorage::Load() {
-  return std::unique_ptr<base::DictionaryValue>(cache_.DeepCopy());
-}
-
-bool MemStorage::Save(const base::DictionaryValue& config) {
-  cache_.Clear();
-  cache_.MergeDictionary(&config);
-  return true;
-}
-
-}  // namespace weave
diff --git a/libweave/src/storage_impls.h b/libweave/src/storage_impls.h
deleted file mode 100644
index 760b2a9..0000000
--- a/libweave/src/storage_impls.h
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright 2014 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 LIBWEAVE_SRC_STORAGE_IMPLS_H_
-#define LIBWEAVE_SRC_STORAGE_IMPLS_H_
-
-#include <base/files/file_util.h>
-#include <base/macros.h>
-#include <base/values.h>
-
-#include "libweave/src/storage_interface.h"
-
-namespace weave {
-
-// Persists the given Value to an atomically written file.
-class FileStorage : public StorageInterface {
- public:
-  explicit FileStorage(const base::FilePath& file_path);
-  ~FileStorage() override = default;
-  std::unique_ptr<base::DictionaryValue> Load() override;
-  bool Save(const base::DictionaryValue& config) override;
-
- private:
-  base::FilePath file_path_;
-  DISALLOW_COPY_AND_ASSIGN(FileStorage);
-};
-
-// StorageInterface for testing. Just stores the values in memory.
-class MemStorage : public StorageInterface {
- public:
-  MemStorage() = default;
-  ~MemStorage() override = default;
-  std::unique_ptr<base::DictionaryValue> Load() override;
-  bool Save(const base::DictionaryValue& config) override;
-
- private:
-  base::DictionaryValue cache_;
-  DISALLOW_COPY_AND_ASSIGN(MemStorage);
-};
-
-}  // namespace weave
-
-#endif  // LIBWEAVE_SRC_STORAGE_IMPLS_H_
diff --git a/libweave/src/storage_interface.h b/libweave/src/storage_interface.h
deleted file mode 100644
index 5a2834f..0000000
--- a/libweave/src/storage_interface.h
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright 2014 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 LIBWEAVE_SRC_STORAGE_INTERFACE_H_
-#define LIBWEAVE_SRC_STORAGE_INTERFACE_H_
-
-#include <memory>
-
-#include <base/values.h>
-
-namespace weave {
-
-// We need to persist data in a couple places, and it is convenient to hide
-// the details of this storage behind an interface for test purposes.
-class StorageInterface {
- public:
-  virtual ~StorageInterface() = default;
-
-  // Load the dictionary from storage. If it fails (e.g. the storage container
-  // [file?] doesn't exist), then it returns empty unique_ptr (aka nullptr).
-  virtual std::unique_ptr<base::DictionaryValue> Load() = 0;
-
-  // Save the dictionary to storage. If saved successfully, returns true. Could
-  // fail when writing to physical storage like file system for various reasons
-  // (out of disk space,access permissions, etc).
-  virtual bool Save(const base::DictionaryValue& config) = 0;
-};
-
-}  // namespace weave
-
-#endif  // LIBWEAVE_SRC_STORAGE_INTERFACE_H_