shill: Load values from the global profile into the manager

We persist parts of the manager's state to the global profile.
This CL allows it to load that state back in.

BUG=chromium-os:24991
TEST=New unit tests + manual (stop shill, change profile, restart shill,
make sure newly written out profile retains the change even if new
device entries have been written out)

Change-Id: I375d978be023d62d2a36d7239bc794be44dda593
Reviewed-on: https://gerrit.chromium.org/gerrit/14042
Reviewed-by: Thieu Le <thieule@chromium.org>
Reviewed-by: Gaurav Shah <gauravsh@chromium.org>
Commit-Ready: Paul Stewart <pstew@chromium.org>
Tested-by: Paul Stewart <pstew@chromium.org>
diff --git a/default_profile.cc b/default_profile.cc
index 15c7fea..04d105f 100644
--- a/default_profile.cc
+++ b/default_profile.cc
@@ -49,6 +49,15 @@
 
 DefaultProfile::~DefaultProfile() {}
 
+bool DefaultProfile::LoadManagerProperties(Manager::Properties *manager_props) {
+  storage()->GetBool(kStorageId, kStorageOfflineMode,
+                     &manager_props->offline_mode);
+  storage()->GetString(kStorageId,
+                       kStorageCheckPortalList,
+                       &manager_props->check_portal_list);
+  return true;
+}
+
 bool DefaultProfile::Save() {
   storage()->SetString(kStorageId, kStorageName, GetFriendlyName());
   storage()->SetBool(kStorageId, kStorageOfflineMode, props_.offline_mode);
diff --git a/default_profile.h b/default_profile.h
index 04b1ae6..35fb5e4 100644
--- a/default_profile.h
+++ b/default_profile.h
@@ -30,6 +30,9 @@
                  const Manager::Properties &manager_props);
   virtual ~DefaultProfile();
 
+  // Loads global configuration into manager properties.
+  virtual bool LoadManagerProperties(Manager::Properties *manager_props);
+
   // Persists profile information, as well as that of discovered devices
   // and bound services, to disk.
   // Returns true on success, false on failure.
@@ -44,8 +47,10 @@
   virtual bool GetStoragePath(FilePath *path);
 
  private:
-  FRIEND_TEST(DefaultProfileTest, Save);
+  friend class DefaultProfileTest;
   FRIEND_TEST(DefaultProfileTest, GetStoragePath);
+  FRIEND_TEST(DefaultProfileTest, LoadManagerProperties);
+  FRIEND_TEST(DefaultProfileTest, Save);
 
   static const char kDefaultId[];
   static const char kStorageId[];
diff --git a/default_profile_unittest.cc b/default_profile_unittest.cc
index 0fcebb5..6b77c17 100644
--- a/default_profile_unittest.cc
+++ b/default_profile_unittest.cc
@@ -25,7 +25,9 @@
 using std::string;
 using std::vector;
 using ::testing::_;
+using ::testing::DoAll;
 using ::testing::Return;
+using ::testing::SetArgumentPointee;
 
 namespace shill {
 
@@ -60,7 +62,7 @@
   static const char kTestStoragePath[];
 
   GLib real_glib_;
-  ProfileRefPtr profile_;
+  scoped_refptr<DefaultProfile> profile_;
   scoped_refptr<MockDevice> device_;
   Manager::Properties properties_;
 };
@@ -118,6 +120,25 @@
   manager()->DeregisterDevice(device_);
 }
 
+TEST_F(DefaultProfileTest, LoadManagerProperties) {
+  scoped_ptr<MockStore> storage(new MockStore);
+  EXPECT_CALL(*storage.get(), GetBool(DefaultProfile::kStorageId,
+                                      DefaultProfile::kStorageOfflineMode,
+                                      _))
+      .WillOnce(DoAll(SetArgumentPointee<2>(true), Return(true)));
+  const string portal_list("technology1,technology2");
+  EXPECT_CALL(*storage.get(), GetString(DefaultProfile::kStorageId,
+                                        DefaultProfile::kStorageCheckPortalList,
+                                        _))
+      .WillOnce(DoAll(SetArgumentPointee<2>(portal_list), Return(true)));
+  profile_->set_storage(storage.release());
+
+  Manager::Properties manager_props;
+  ASSERT_TRUE(profile_->LoadManagerProperties(&manager_props));
+  EXPECT_TRUE(manager_props.offline_mode);
+  EXPECT_EQ(portal_list, manager_props.check_portal_list);
+}
+
 TEST_F(DefaultProfileTest, GetStoragePath) {
   FilePath path;
   EXPECT_TRUE(profile_->GetStoragePath(&path));
diff --git a/manager.cc b/manager.cc
index 5511376..f3f33e8 100644
--- a/manager.cc
+++ b/manager.cc
@@ -151,11 +151,15 @@
   DCHECK(profiles_.empty());
   // The default profile must go first on the stack.
   CHECK(file_util::CreateDirectory(storage_path_)) << storage_path_.value();
-  profiles_.push_back(new DefaultProfile(control_interface_,
+  scoped_refptr<DefaultProfile>
+      default_profile(new DefaultProfile(control_interface_,
                                          this,
                                          storage_path_,
                                          props_));
-  CHECK(profiles_[0]->InitStorage(glib_, Profile::kCreateOrOpenExisting, NULL));
+  CHECK(default_profile->InitStorage(glib_, Profile::kCreateOrOpenExisting,
+                                     NULL));
+  CHECK(default_profile->LoadManagerProperties(&props_));
+  profiles_.push_back(default_profile.release());
   Error error;
   string path;
   for (vector<string>::iterator it = startup_profiles_.begin();
diff --git a/profile.h b/profile.h
index 5a5f966..cf0b199 100644
--- a/profile.h
+++ b/profile.h
@@ -124,9 +124,7 @@
   virtual bool GetStoragePath(FilePath *path);
 
  private:
-  friend class DefaultProfileTest;
   friend class ProfileAdaptorInterface;
-  FRIEND_TEST(DefaultProfileTest, GetStoragePath);
   FRIEND_TEST(ProfileTest, GetStoragePath);
   FRIEND_TEST(ProfileTest, IsValidIdentifierToken);