summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsail@chromium.org <sail@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-06-27 19:43:39 +0000
committersail@chromium.org <sail@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-06-27 19:43:39 +0000
commitdee810ea1b9b58410399bbc42637ffba79fde1c6 (patch)
treeaaeccd263306f734357cf557aba40f3113c5e4cd
parentc8f5778ea91dc9c5c21e1007661237c6e26399ad (diff)
downloadchromium_src-dee810ea1b9b58410399bbc42637ffba79fde1c6.zip
chromium_src-dee810ea1b9b58410399bbc42637ffba79fde1c6.tar.gz
chromium_src-dee810ea1b9b58410399bbc42637ffba79fde1c6.tar.bz2
Store profile avatar to preferences
This change adds a preference to store avatar icons. For this change I extended the idea of kProfileAvatarIconMap pref into a full blown class. The class is responsible for mantaining a list of sorted profiles that can be displayed without having to load profiles from disk. Once this is chcked in there are several TODOs: - remove the ProfileManager::GetNumberOfProfiles(), etc... functions that I added earlier - add UI to customize the avatar icon - create a single instance of the new ProfileInfoCache object some where. Maybe from ProfileManager? BUG= TEST= Review URL: http://codereview.chromium.org/7155015 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@90622 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/app/theme/theme_resources.grd5
-rw-r--r--chrome/browser/prefs/browser_prefs.cc2
-rw-r--r--chrome/browser/profiles/profile_info_cache.cc209
-rw-r--r--chrome/browser/profiles/profile_info_cache.h71
-rw-r--r--chrome/browser/profiles/profile_info_cache_unittest.cc99
-rw-r--r--chrome/chrome_browser.gypi2
-rw-r--r--chrome/chrome_tests.gypi1
-rw-r--r--chrome/common/pref_names.cc5
-rw-r--r--chrome/common/pref_names.h1
9 files changed, 394 insertions, 1 deletions
diff --git a/chrome/app/theme/theme_resources.grd b/chrome/app/theme/theme_resources.grd
index 83dd3b3..df9c012 100644
--- a/chrome/app/theme/theme_resources.grd
+++ b/chrome/app/theme/theme_resources.grd
@@ -217,7 +217,10 @@
<!-- NOTE: product_logo_*.* files beyond what's listed above are
referenced by installer code; don't remove them unless you know what
you're doing! -->
- <include name="IDR_PROFILE_AVATAR_1" file="avatar_cupcake.png" type="BINDATA" />
+ <include name="IDR_PROFILE_AVATAR_0" file="avatar_cupcake.png" type="BINDATA" />
+ <include name="IDR_PROFILE_AVATAR_1" file="avatar_beaker.png" type="BINDATA" />
+ <include name="IDR_PROFILE_AVATAR_2" file="avatar_bee.png" type="BINDATA" />
+ <include name="IDR_PROFILE_AVATAR_3" file="avatar_briefcase.png" type="BINDATA" />
<include name="IDR_RESTORE_BUTTON_MASK" file="restore_button_mask.png" type="BINDATA" />
<include name="IDR_SAD_FAVICON" file="sadfavicon.png" type="BINDATA" />
<include name="IDR_SAD_TAB" file="sadtab.png" type="BINDATA" />
diff --git a/chrome/browser/prefs/browser_prefs.cc b/chrome/browser/prefs/browser_prefs.cc
index 1d9f0ed..4bc2f817 100644
--- a/chrome/browser/prefs/browser_prefs.cc
+++ b/chrome/browser/prefs/browser_prefs.cc
@@ -38,6 +38,7 @@
#include "chrome/browser/prefs/session_startup_pref.h"
#include "chrome/browser/printing/print_job_manager.h"
#include "chrome/browser/profiles/profile_impl.h"
+#include "chrome/browser/profiles/profile_info_cache.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/renderer_host/web_cache_manager.h"
#include "chrome/browser/safe_browsing/safe_browsing_service.h"
@@ -110,6 +111,7 @@ void RegisterLocalState(PrefService* local_state) {
NotificationUIManager::RegisterPrefs(local_state);
PrefProxyConfigService::RegisterPrefs(local_state);
policy::CloudPolicySubsystem::RegisterPrefs(local_state);
+ ProfileInfoCache::RegisterPrefs(local_state);
ProfileManager::RegisterPrefs(local_state);
#if defined(OS_CHROMEOS)
chromeos::AudioMixerAlsa::RegisterPrefs(local_state);
diff --git a/chrome/browser/profiles/profile_info_cache.cc b/chrome/browser/profiles/profile_info_cache.cc
new file mode 100644
index 0000000..4a71e02
--- /dev/null
+++ b/chrome/browser/profiles/profile_info_cache.cc
@@ -0,0 +1,209 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/profiles/profile_info_cache.h"
+
+#include "base/logging.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/string_number_conversions.h"
+#include "base/stringprintf.h"
+#include "base/utf_string_conversions.h"
+#include "base/values.h"
+#include "chrome/browser/prefs/pref_service.h"
+#include "chrome/browser/prefs/scoped_user_pref_update.h"
+#include "chrome/common/pref_names.h"
+#include "grit/theme_resources.h"
+#include "ui/base/resource/resource_bundle.h"
+
+namespace {
+
+const char kNameKey[] = "name";
+const char kAvatarIconKey[] = "avatar_icon";
+const char kDefaultUrlPrefix[] = "chrome://theme/IDR_PROFILE_AVATAR_";
+
+const int kDefaultAvatarIconResources[] = {
+ IDR_PROFILE_AVATAR_0,
+ IDR_PROFILE_AVATAR_1,
+ IDR_PROFILE_AVATAR_2,
+ IDR_PROFILE_AVATAR_3,
+};
+
+const int kDefaultAvatarIconsCount = arraysize(kDefaultAvatarIconResources);
+
+// Checks if the given URL points to one of the default avatar icons. if it is,
+// returns true and its index through |icon_index|. If not, returns false.
+bool IsDefaultAvatarIconUrl(const std::string& url, size_t* icon_index) {
+ DCHECK(icon_index);
+ if (url.find(kDefaultUrlPrefix) != 0)
+ return false;
+
+ int int_value = -1;
+ if (base::StringToInt(url.begin() + strlen(kDefaultUrlPrefix),
+ url.end(),
+ &int_value)) {
+ if (int_value < 0 || int_value >= kDefaultAvatarIconsCount)
+ return false;
+ *icon_index = int_value;
+ return true;
+ }
+
+ return false;
+}
+
+// Returns a URL for the default avatar icon with specified index.
+std::string GetDefaultAvatarIconUrl(int icon_index) {
+ DCHECK_LT(icon_index, kDefaultAvatarIconsCount);
+ return StringPrintf("%s%d", kDefaultUrlPrefix, icon_index);
+}
+
+} // namespace
+
+ProfileInfoCache::ProfileInfoCache(PrefService* prefs,
+ const FilePath& user_data_dir)
+ : prefs_(prefs),
+ user_data_dir_(user_data_dir) {
+ // Populate the cache
+ const DictionaryValue* cache =
+ prefs_->GetDictionary(prefs::kProfileInfoCache);
+ for (DictionaryValue::key_iterator it = cache->begin_keys();
+ it != cache->end_keys(); ++it) {
+ std::string key = *it;
+ DictionaryValue* info = NULL;
+ cache->GetDictionary(key, &info);
+ string16 name;
+ info->GetString(kNameKey, &name);
+ sorted_keys_.insert(FindPositionForProfile(key, name), key);
+ }
+}
+
+ProfileInfoCache::~ProfileInfoCache() {
+}
+
+void ProfileInfoCache::AddProfileToCache(const FilePath& profile_path,
+ const string16& name,
+ size_t icon_index) {
+ std::string key = CacheKeyFromProfilePath(profile_path);
+ DictionaryPrefUpdate update(prefs_, prefs::kProfileInfoCache);
+ DictionaryValue* cache = update.Get();
+
+ scoped_ptr<DictionaryValue> info(new DictionaryValue);
+ info->SetString(kNameKey, name);
+ info->SetString(kAvatarIconKey, GetDefaultAvatarIconUrl(icon_index));
+ cache->Set(key, info.release());
+
+ sorted_keys_.insert(FindPositionForProfile(key, name), key);
+}
+
+void ProfileInfoCache::DeleteProfileFromCache(const FilePath& profile_path) {
+ DictionaryPrefUpdate update(prefs_, prefs::kProfileInfoCache);
+ DictionaryValue* cache = update.Get();
+
+ std::string key = CacheKeyFromProfilePath(profile_path);
+ cache->Remove(key, NULL);
+ sorted_keys_.erase(std::find(sorted_keys_.begin(), sorted_keys_.end(), key));
+}
+
+size_t ProfileInfoCache::GetNumberOfProfiles() const {
+ return sorted_keys_.size();
+}
+
+string16 ProfileInfoCache::GetNameOfProfileAtIndex(size_t index) const {
+ string16 name;
+ GetInfoForProfileAtIndex(index)->GetString(kNameKey, &name);
+ return name;
+}
+
+FilePath ProfileInfoCache::GetPathOfProfileAtIndex(size_t index) const {
+ FilePath::StringType base_name;
+#if defined(OS_POSIX)
+ base_name = sorted_keys_[index];
+#elif defined(OS_WIN)
+ base_name = ASCIIToWide(sorted_keys_[index]);
+#endif
+ return user_data_dir_.Append(base_name);
+}
+
+const gfx::Image& ProfileInfoCache::GetAvatarIconOfProfileAtIndex(
+ size_t index) const {
+ std::string icon_url;
+ GetInfoForProfileAtIndex(index)->GetString(kAvatarIconKey, &icon_url);
+ size_t icon_index = 0;
+ if (IsDefaultAvatarIconUrl(icon_url, &icon_index)) {
+ int resource_id = GetDefaultAvatarIconResourceIDAtIndex(icon_index);
+ return ResourceBundle::GetSharedInstance().GetImageNamed(resource_id);
+ }
+
+ DLOG(WARNING) << "Unknown avatar icon: " << icon_url;
+ return ResourceBundle::GetSharedInstance().GetImageNamed(
+ GetDefaultAvatarIconResourceIDAtIndex(0));
+}
+
+void ProfileInfoCache::SetNameOfProfileAtIndex(size_t index,
+ const string16& name) {
+ scoped_ptr<DictionaryValue> info(GetInfoForProfileAtIndex(index)->DeepCopy());
+ info->SetString(kNameKey, name);
+ // This takes ownership of |info|.
+ SetInfoForProfileAtIndex(index, info.release());
+}
+
+void ProfileInfoCache::SetAvatarIconOfProfileAtIndex(size_t index,
+ size_t icon_index) {
+ scoped_ptr<DictionaryValue> info(GetInfoForProfileAtIndex(index)->DeepCopy());
+ info->SetString(kAvatarIconKey, GetDefaultAvatarIconUrl(icon_index));
+ // This takes ownership of |info|.
+ SetInfoForProfileAtIndex(index, info.release());
+}
+
+size_t ProfileInfoCache::GetDefaultAvatarIconCount() {
+ return kDefaultAvatarIconsCount;
+}
+
+int ProfileInfoCache::GetDefaultAvatarIconResourceIDAtIndex(size_t index) {
+ DCHECK_LT(index, GetDefaultAvatarIconCount());
+ return kDefaultAvatarIconResources[index];
+}
+
+const DictionaryValue* ProfileInfoCache::GetInfoForProfileAtIndex(
+ size_t index) const {
+ DCHECK_LT(index, GetNumberOfProfiles());
+ const DictionaryValue* cache =
+ prefs_->GetDictionary(prefs::kProfileInfoCache);
+ DictionaryValue* info = NULL;
+ cache->GetDictionary(sorted_keys_[index], &info);
+ return info;
+}
+
+void ProfileInfoCache::SetInfoForProfileAtIndex(size_t index,
+ DictionaryValue* info) {
+ DictionaryPrefUpdate update(prefs_, prefs::kProfileInfoCache);
+ DictionaryValue* cache = update.Get();
+ cache->Set(sorted_keys_[index], info);
+}
+
+std::string ProfileInfoCache::CacheKeyFromProfilePath(
+ const FilePath& profile_path) const {
+ DCHECK(user_data_dir_ == profile_path.DirName());
+ FilePath base_name = profile_path.BaseName();
+ return base_name.MaybeAsASCII();
+}
+
+std::vector<std::string>::iterator ProfileInfoCache::FindPositionForProfile(
+ std::string search_key,
+ const string16& search_name) {
+ for (size_t i = 0; i < GetNumberOfProfiles(); ++i) {
+ int name_compare = search_name.compare(GetNameOfProfileAtIndex(i));
+ if (name_compare < 0)
+ return sorted_keys_.begin() + i;
+ if (name_compare == 0) {
+ int key_compare = search_key.compare(sorted_keys_[i]);
+ if (key_compare < 0)
+ return sorted_keys_.begin() + i;
+ }
+ }
+ return sorted_keys_.end();
+}
+
+void ProfileInfoCache::RegisterPrefs(PrefService* prefs) {
+ prefs->RegisterDictionaryPref(prefs::kProfileInfoCache);
+}
diff --git a/chrome/browser/profiles/profile_info_cache.h b/chrome/browser/profiles/profile_info_cache.h
new file mode 100644
index 0000000..e6ca12a
--- /dev/null
+++ b/chrome/browser/profiles/profile_info_cache.h
@@ -0,0 +1,71 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_PROFILES_PROFILE_INFO_CACHE_H_
+#define CHROME_BROWSER_PROFILES_PROFILE_INFO_CACHE_H_
+#pragma once
+
+#include <string>
+#include <vector>
+
+#include "base/basictypes.h"
+#include "base/file_path.h"
+#include "base/string16.h"
+
+namespace gfx {
+class Image;
+}
+
+class DictionaryValue;
+class PrefService;
+
+
+// This class saves various information about profiles to local preferences.
+// This cache can be used to display a list of profiles without having to
+// actually load the profiles from disk.
+class ProfileInfoCache {
+ public:
+ ProfileInfoCache(PrefService* prefs, const FilePath& user_data_dir);
+ ~ProfileInfoCache();
+
+ void AddProfileToCache(const FilePath& profile_path,
+ const string16& name,
+ size_t icon_index);
+ void DeleteProfileFromCache(const FilePath& profile_path);
+
+ size_t GetNumberOfProfiles() const;
+ string16 GetNameOfProfileAtIndex(size_t index) const;
+ FilePath GetPathOfProfileAtIndex(size_t index) const;
+ const gfx::Image& GetAvatarIconOfProfileAtIndex(size_t index) const;
+
+ void SetNameOfProfileAtIndex(size_t index, const string16& name);
+ void SetAvatarIconOfProfileAtIndex(size_t index, size_t icon_index);
+
+ // Gets the number of default avatar icons that exist.
+ static size_t GetDefaultAvatarIconCount();
+ // Gets the resource ID of the default avatar icon at |index|.
+ static int GetDefaultAvatarIconResourceIDAtIndex(size_t index);
+
+ // Register cache related preferences in Local State.
+ static void RegisterPrefs(PrefService* prefs);
+
+ private:
+ const DictionaryValue* GetInfoForProfileAtIndex(size_t index) const;
+ // Saves the profile info to a cache and takes ownership of |info|.
+ // Currently the only information that is cached is the profiles name and
+ // avatar icon.
+ void SetInfoForProfileAtIndex(size_t index, DictionaryValue* info);
+ std::string CacheKeyFromProfilePath(const FilePath& profile_path) const;
+ std::vector<std::string>::iterator FindPositionForProfile(
+ std::string search_key,
+ const string16& search_name);
+
+ PrefService* prefs_;
+ std::vector<std::string> sorted_keys_;
+ FilePath user_data_dir_;
+
+ DISALLOW_COPY_AND_ASSIGN(ProfileInfoCache);
+};
+
+#endif // CHROME_BROWSER_PROFILES_PROFILE_INFO_CACHE_H_
diff --git a/chrome/browser/profiles/profile_info_cache_unittest.cc b/chrome/browser/profiles/profile_info_cache_unittest.cc
new file mode 100644
index 0000000..b270566
--- /dev/null
+++ b/chrome/browser/profiles/profile_info_cache_unittest.cc
@@ -0,0 +1,99 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/profiles/profile_info_cache.h"
+
+#include "base/stringprintf.h"
+#include "base/utf_string_conversions.h"
+#include "chrome/test/testing_browser_process_test.h"
+#include "chrome/test/testing_pref_service.h"
+#include "third_party/skia/include/core/SkBitmap.h"
+#include "ui/base/resource/resource_bundle.h"
+#include "ui/gfx/image/image.h"
+
+namespace {
+
+class ProfileInfoCacheUnittests : public TestingBrowserProcessTest {
+ protected:
+ ProfileInfoCacheUnittests() : local_state_(testing_browser_process_.get()) {
+ cache_.reset(new ProfileInfoCache(local_state_.Get(), GetUserDataDir()));
+ }
+
+ FilePath GetUserDataDir() {
+ return StringToFilePath("usr").Append(StringToFilePath("profile"));
+ }
+
+ FilePath StringToFilePath(std::string string_path) {
+#if defined(OS_POSIX)
+ return FilePath(string_path);
+#elif defined(OS_WIN)
+ return FilePath(ASCIIToWide(string_path));
+#endif
+ }
+
+ scoped_ptr<ProfileInfoCache> cache_;
+ ScopedTestingLocalState local_state_;
+};
+
+TEST_F(ProfileInfoCacheUnittests, AddProfiles) {
+ EXPECT_EQ(0u, cache_->GetNumberOfProfiles());
+
+ for (uint32 i = 0; i < 4; ++i) {
+ std::string base_name = StringPrintf("path_%ud", i);
+ FilePath profile_path =
+ GetUserDataDir().Append(StringToFilePath(base_name));
+ string16 profile_name = ASCIIToUTF16(StringPrintf("name_%ud", i));
+ const SkBitmap& icon = ResourceBundle::GetSharedInstance().GetImageNamed(
+ ProfileInfoCache::GetDefaultAvatarIconResourceIDAtIndex(i));
+
+ cache_->AddProfileToCache(profile_path, profile_name, 0);
+
+ EXPECT_EQ(i + 1, cache_->GetNumberOfProfiles());
+ EXPECT_EQ(profile_name, cache_->GetNameOfProfileAtIndex(i));
+ EXPECT_EQ(profile_path, cache_->GetPathOfProfileAtIndex(i));
+ const SkBitmap& actual_icon = cache_->GetAvatarIconOfProfileAtIndex(i);
+ EXPECT_EQ(icon.width(), actual_icon.width());
+ EXPECT_EQ(icon.height(), actual_icon.height());
+ }
+}
+
+TEST_F(ProfileInfoCacheUnittests, DeleteProfile) {
+ EXPECT_EQ(0u, cache_->GetNumberOfProfiles());
+
+ FilePath path_1 = GetUserDataDir().Append(StringToFilePath("path_1"));
+ cache_->AddProfileToCache(path_1, ASCIIToUTF16("name_1"),
+ 0);
+ EXPECT_EQ(1u, cache_->GetNumberOfProfiles());
+
+ FilePath path_2 = GetUserDataDir().Append(StringToFilePath("path_2"));
+ string16 name_2 = ASCIIToUTF16("name_2");
+ cache_->AddProfileToCache(path_2, name_2, 0);
+ EXPECT_EQ(2u, cache_->GetNumberOfProfiles());
+
+ cache_->DeleteProfileFromCache(path_1);
+ EXPECT_EQ(1u, cache_->GetNumberOfProfiles());
+ EXPECT_EQ(name_2, cache_->GetNameOfProfileAtIndex(0));
+
+ cache_->DeleteProfileFromCache(path_2);
+ EXPECT_EQ(0u, cache_->GetNumberOfProfiles());
+}
+
+TEST_F(ProfileInfoCacheUnittests, MutateProfile) {
+ cache_->AddProfileToCache(GetUserDataDir().Append(StringToFilePath("path_1")),
+ ASCIIToUTF16("name_1"), 0);
+ cache_->AddProfileToCache(GetUserDataDir().Append(StringToFilePath("path_2")),
+ ASCIIToUTF16("name_2"), 0);
+
+ string16 new_name = ASCIIToUTF16("new_name");
+ cache_->SetNameOfProfileAtIndex(1, new_name);
+ EXPECT_EQ(new_name, cache_->GetNameOfProfileAtIndex(1));
+ EXPECT_NE(new_name, cache_->GetNameOfProfileAtIndex(0));
+
+ size_t new_icon_index = 3;
+ cache_->SetAvatarIconOfProfileAtIndex(1, new_icon_index);
+ // Not much to test.
+ cache_->GetAvatarIconOfProfileAtIndex(1);
+}
+
+} // namespace
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index 1499e75..5e62e81 100644
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -1751,6 +1751,8 @@
'browser/profiles/profile_impl.h',
'browser/profiles/profile_impl_io_data.cc',
'browser/profiles/profile_impl_io_data.h',
+ 'browser/profiles/profile_info_cache.cc',
+ 'browser/profiles/profile_info_cache.h',
'browser/profiles/profile_io_data.cc',
'browser/profiles/profile_io_data.h',
'browser/profiles/profile_keyed_service_factory.cc',
diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi
index 1214adb..39d2122 100644
--- a/chrome/chrome_tests.gypi
+++ b/chrome/chrome_tests.gypi
@@ -1555,6 +1555,7 @@
'browser/process_info_snapshot_mac_unittest.cc',
'browser/process_singleton_mac_unittest.cc',
'browser/profiles/profile_dependency_manager_unittest.cc',
+ 'browser/profiles/profile_info_cache_unittest.cc',
'browser/profiles/profile_manager_unittest.cc',
'browser/renderer_host/accelerated_plugin_view_mac_unittest.mm',
'browser/renderer_host/gtk_key_bindings_handler_unittest.cc',
diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc
index 6020631..3c762bc 100644
--- a/chrome/common/pref_names.cc
+++ b/chrome/common/pref_names.cc
@@ -729,6 +729,11 @@ const char kProfileDirectoryMap[] = "profile.directory_map";
// directories.
const char kProfilesNumCreated[] = "profile.profiles_created";
+// A map of profile data directory to cached information. This cache can be
+// used to display information about profiles without actually having to load
+// them.
+const char kProfileInfoCache[] = "profile.info_cache";
+
// Prefs for SSLConfigServicePref.
const char kCertRevocationCheckingEnabled[] = "ssl.rev_checking.enabled";
const char kSSL3Enabled[] = "ssl.ssl3.enabled";
diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h
index d49d346..9140483 100644
--- a/chrome/common/pref_names.h
+++ b/chrome/common/pref_names.h
@@ -265,6 +265,7 @@ extern const char kMetricsOngoingLogs[];
extern const char kProfileLastUsed[];
extern const char kProfileDirectoryMap[];
extern const char kProfilesNumCreated[];
+extern const char kProfileInfoCache[];
extern const char kProfileMetrics[];
extern const char kProfilePrefix[];