15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile_info_cache.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/file_util.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/format_macros.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/i18n/case_conversion.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/prefs/pref_registry_simple.h"
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/prefs/pref_service.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/rand_util.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/stl_util.h"
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_number_conversions.h"
18c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/strings/string_piece.h"
19868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/stringprintf.h"
20868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/browser_process.h"
237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/chrome_notification_types.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/prefs/scoped_user_pref_update.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/pref_names.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_thread.h"
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_service.h"
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/generated_resources.h"
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/theme_resources.h"
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/skia/include/core/SkBitmap.h"
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/l10n/l10n_util.h"
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/resource/resource_bundle.h"
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/image/image.h"
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/image/image_util.h"
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserThread;
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kNameKey[] = "name";
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kShortcutNameKey[] = "shortcut_name";
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kGAIANameKey[] = "gaia_name";
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kUseGAIANameKey[] = "use_gaia_name";
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kUserNameKey[] = "user_name";
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kAvatarIconKey[] = "avatar_icon";
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kUseGAIAPictureKey[] = "use_gaia_picture";
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kBackgroundAppsKey[] = "background_apps";
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kHasMigratedToGAIAInfoKey[] = "has_migrated_to_gaia_info";
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kGAIAPictureFileNameKey[] = "gaia_picture_file_name";
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kIsManagedKey[] = "is_managed";
51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const char kSigninRequiredKey[] = "signin_required";
522385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochconst char kManagedUserId[] = "managed_user_id";
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kDefaultUrlPrefix[] = "chrome://theme/IDR_PROFILE_AVATAR_";
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kGAIAPictureFileName[] = "Google Profile Picture.png";
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kDefaultAvatarIconResources[] = {
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IDR_PROFILE_AVATAR_0,
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IDR_PROFILE_AVATAR_1,
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IDR_PROFILE_AVATAR_2,
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IDR_PROFILE_AVATAR_3,
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IDR_PROFILE_AVATAR_4,
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IDR_PROFILE_AVATAR_5,
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IDR_PROFILE_AVATAR_6,
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IDR_PROFILE_AVATAR_7,
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IDR_PROFILE_AVATAR_8,
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IDR_PROFILE_AVATAR_9,
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IDR_PROFILE_AVATAR_10,
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IDR_PROFILE_AVATAR_11,
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IDR_PROFILE_AVATAR_12,
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IDR_PROFILE_AVATAR_13,
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IDR_PROFILE_AVATAR_14,
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IDR_PROFILE_AVATAR_15,
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IDR_PROFILE_AVATAR_16,
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IDR_PROFILE_AVATAR_17,
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IDR_PROFILE_AVATAR_18,
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IDR_PROFILE_AVATAR_19,
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IDR_PROFILE_AVATAR_20,
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IDR_PROFILE_AVATAR_21,
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IDR_PROFILE_AVATAR_22,
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IDR_PROFILE_AVATAR_23,
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IDR_PROFILE_AVATAR_24,
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IDR_PROFILE_AVATAR_25,
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const size_t kDefaultAvatarIconsCount = arraysize(kDefaultAvatarIconResources);
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The first 8 icons are generic.
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const size_t kGenericIconCount = 8;
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// First eight are generic icons, which use IDS_NUMBERED_PROFILE_NAME.
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kDefaultNames[] = {
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IDS_DEFAULT_AVATAR_NAME_8,
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IDS_DEFAULT_AVATAR_NAME_9,
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IDS_DEFAULT_AVATAR_NAME_10,
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IDS_DEFAULT_AVATAR_NAME_11,
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IDS_DEFAULT_AVATAR_NAME_12,
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IDS_DEFAULT_AVATAR_NAME_13,
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IDS_DEFAULT_AVATAR_NAME_14,
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IDS_DEFAULT_AVATAR_NAME_15,
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IDS_DEFAULT_AVATAR_NAME_16,
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IDS_DEFAULT_AVATAR_NAME_17,
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IDS_DEFAULT_AVATAR_NAME_18,
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IDS_DEFAULT_AVATAR_NAME_19,
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IDS_DEFAULT_AVATAR_NAME_20,
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IDS_DEFAULT_AVATAR_NAME_21,
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IDS_DEFAULT_AVATAR_NAME_22,
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IDS_DEFAULT_AVATAR_NAME_23,
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IDS_DEFAULT_AVATAR_NAME_24,
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IDS_DEFAULT_AVATAR_NAME_25
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef std::vector<unsigned char> ImageData;
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Writes |data| to disk and takes ownership of the pointer. On completion
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// |success| is set to true on success and false on failure.
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SaveBitmap(ImageData* data,
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                const base::FilePath& image_path,
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                bool* success) {
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<ImageData> data_owner(data);
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *success = false;
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure the destination directory exists.
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath dir = image_path.DirName();
1267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (!base::DirectoryExists(dir) && !file_util::CreateDirectory(dir)) {
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(ERROR) << "Failed to create parent directory.";
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (file_util::WriteFile(image_path,
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           reinterpret_cast<char*>(&(*data)[0]),
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           data->size()) == -1) {
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(ERROR) << "Failed to save image to file.";
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *success = true;
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Reads a PNG from disk and decodes it. If the bitmap was successfully read
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// from disk the then |out_image| will contain the bitmap image, otherwise it
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// will be NULL.
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ReadBitmap(const base::FilePath& image_path,
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                gfx::Image** out_image) {
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *out_image = NULL;
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string image_data;
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!file_util::ReadFileToString(image_path, &image_data)) {
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(ERROR) << "Failed to read PNG file from disk.";
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const unsigned char* data =
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      reinterpret_cast<const unsigned char*>(image_data.data());
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Image image =
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Image::CreateFrom1xPNGBytes(data, image_data.length());
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (image.IsEmpty()) {
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(ERROR) << "Failed to decode PNG file.";
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  *out_image = new gfx::Image(image);
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DeleteBitmap(const base::FilePath& image_path) {
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
1697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  base::DeleteFile(image_path, false);
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ProfileInfoCache::ProfileInfoCache(PrefService* prefs,
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                   const base::FilePath& user_data_dir)
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : prefs_(prefs),
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      user_data_dir_(user_data_dir) {
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Populate the cache
1792385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  DictionaryPrefUpdate update(prefs_, prefs::kProfileInfoCache);
1802385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  DictionaryValue* cache = update.Get();
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (DictionaryValue::Iterator it(*cache); !it.IsAtEnd(); it.Advance()) {
1822385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    DictionaryValue* info = NULL;
1832385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    cache->GetDictionaryWithoutPathExpansion(it.key(), &info);
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    string16 name;
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    info->GetString(kNameKey, &name);
1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    sorted_keys_.insert(FindPositionForProfile(it.key(), name), it.key());
1872385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    // TODO(ibraaaa): delete this when we fully migrate to
1882385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    // |prefs::kManagedUserId|.
1892385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    bool is_managed = false;
1902385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    info->GetBoolean(kIsManagedKey, &is_managed);
1912385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    if (is_managed) {
1922385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      info->SetString(kManagedUserId, "DUMMY_ID");
1932385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      info->Remove(kIsManagedKey, NULL);
1942385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    }
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ProfileInfoCache::~ProfileInfoCache() {
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  STLDeleteContainerPairSecondPointers(
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gaia_pictures_.begin(), gaia_pictures_.end());
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ProfileInfoCache::AddProfileToCache(const base::FilePath& profile_path,
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         const string16& name,
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         const string16& username,
2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                         size_t icon_index,
2072385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                                         const std::string& managed_user_id) {
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string key = CacheKeyFromProfilePath(profile_path);
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DictionaryPrefUpdate update(prefs_, prefs::kProfileInfoCache);
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DictionaryValue* cache = update.Get();
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<DictionaryValue> info(new DictionaryValue);
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  info->SetString(kNameKey, name);
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  info->SetString(kUserNameKey, username);
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  info->SetString(kAvatarIconKey, GetDefaultAvatarIconUrl(icon_index));
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Default value for whether background apps are running is false.
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  info->SetBoolean(kBackgroundAppsKey, false);
2182385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  info->SetString(kManagedUserId, managed_user_id);
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cache->Set(key, info.release());
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sorted_keys_.insert(FindPositionForProfile(key, name), key);
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FOR_EACH_OBSERVER(ProfileInfoCacheObserver,
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    observer_list_,
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    OnProfileAdded(profile_path));
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::NotificationService::current()->Notify(
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      chrome::NOTIFICATION_PROFILE_CACHED_INFO_CHANGED,
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::NotificationService::AllSources(),
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::NotificationService::NoDetails());
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ProfileInfoCache::AddObserver(ProfileInfoCacheObserver* obs) {
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  observer_list_.AddObserver(obs);
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ProfileInfoCache::RemoveObserver(ProfileInfoCacheObserver* obs) {
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  observer_list_.RemoveObserver(obs);
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ProfileInfoCache::DeleteProfileFromCache(
2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::FilePath& profile_path) {
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t profile_index = GetIndexOfProfileWithPath(profile_path);
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (profile_index == std::string::npos) {
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NOTREACHED();
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string16 name = GetNameOfProfileAtIndex(profile_index);
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FOR_EACH_OBSERVER(ProfileInfoCacheObserver,
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    observer_list_,
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    OnProfileWillBeRemoved(profile_path));
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DictionaryPrefUpdate update(prefs_, prefs::kProfileInfoCache);
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DictionaryValue* cache = update.Get();
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string key = CacheKeyFromProfilePath(profile_path);
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cache->Remove(key, NULL);
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sorted_keys_.erase(std::find(sorted_keys_.begin(), sorted_keys_.end(), key));
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FOR_EACH_OBSERVER(ProfileInfoCacheObserver,
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    observer_list_,
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    OnProfileWasRemoved(profile_path, name));
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::NotificationService::current()->Notify(
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      chrome::NOTIFICATION_PROFILE_CACHED_INFO_CHANGED,
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::NotificationService::AllSources(),
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::NotificationService::NoDetails());
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)size_t ProfileInfoCache::GetNumberOfProfiles() const {
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return sorted_keys_.size();
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)size_t ProfileInfoCache::GetIndexOfProfileWithPath(
2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::FilePath& profile_path) const {
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (profile_path.DirName() != user_data_dir_)
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return std::string::npos;
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string search_key = CacheKeyFromProfilePath(profile_path);
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < sorted_keys_.size(); ++i) {
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (sorted_keys_[i] == search_key)
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return i;
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return std::string::npos;
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string16 ProfileInfoCache::GetNameOfProfileAtIndex(size_t index) const {
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string16 name;
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (IsUsingGAIANameOfProfileAtIndex(index))
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    name = GetGAIANameOfProfileAtIndex(index);
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (name.empty())
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GetInfoForProfileAtIndex(index)->GetString(kNameKey, &name);
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return name;
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string16 ProfileInfoCache::GetShortcutNameOfProfileAtIndex(size_t index)
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const {
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string16 shortcut_name;
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetInfoForProfileAtIndex(index)->GetString(
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kShortcutNameKey, &shortcut_name);
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return shortcut_name;
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::FilePath ProfileInfoCache::GetPathOfProfileAtIndex(size_t index) const {
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return user_data_dir_.AppendASCII(sorted_keys_[index]);
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string16 ProfileInfoCache::GetUserNameOfProfileAtIndex(size_t index) const {
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string16 user_name;
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetInfoForProfileAtIndex(index)->GetString(kUserNameKey, &user_name);
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return user_name;
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const gfx::Image& ProfileInfoCache::GetAvatarIconOfProfileAtIndex(
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    size_t index) const {
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (IsUsingGAIAPictureOfProfileAtIndex(index)) {
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const gfx::Image* image = GetGAIAPictureOfProfileAtIndex(index);
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (image)
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return *image;
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int resource_id = GetDefaultAvatarIconResourceIDAtIndex(
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GetAvatarIconIndexOfProfileAtIndex(index));
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return ResourceBundle::GetSharedInstance().GetNativeImageNamed(resource_id);
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ProfileInfoCache::GetBackgroundStatusOfProfileAtIndex(
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    size_t index) const {
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool background_app_status;
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!GetInfoForProfileAtIndex(index)->GetBoolean(kBackgroundAppsKey,
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                   &background_app_status)) {
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return background_app_status;
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string16 ProfileInfoCache::GetGAIANameOfProfileAtIndex(size_t index) const {
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string16 name;
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetInfoForProfileAtIndex(index)->GetString(kGAIANameKey, &name);
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return name;
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ProfileInfoCache::IsUsingGAIANameOfProfileAtIndex(size_t index) const {
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool value = false;
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetInfoForProfileAtIndex(index)->GetBoolean(kUseGAIANameKey, &value);
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return value;
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const gfx::Image* ProfileInfoCache::GetGAIAPictureOfProfileAtIndex(
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    size_t index) const {
3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath path = GetPathOfProfileAtIndex(index);
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string key = CacheKeyFromProfilePath(path);
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If the picture is already loaded then use it.
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (gaia_pictures_.count(key)) {
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (gaia_pictures_[key]->IsEmpty())
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return NULL;
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return gaia_pictures_[key];
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string file_name;
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetInfoForProfileAtIndex(index)->GetString(
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kGAIAPictureFileNameKey, &file_name);
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If the picture is not on disk or it is already being loaded then return
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // NULL.
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (file_name.empty() || gaia_pictures_loading_[key])
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gaia_pictures_loading_[key] = true;
3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath image_path = path.AppendASCII(file_name);
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Image** image = new gfx::Image*;
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BrowserThread::PostTaskAndReply(BrowserThread::FILE, FROM_HERE,
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&ReadBitmap, image_path, image),
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&ProfileInfoCache::OnGAIAPictureLoaded,
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          const_cast<ProfileInfoCache*>(this)->AsWeakPtr(), path, image));
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return NULL;
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool ProfileInfoCache::ProfileIsManagedAtIndex(size_t index) const {
3812385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  return !GetManagedUserIdOfProfileAtIndex(index).empty();
3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
384c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool ProfileInfoCache::ProfileIsSigninRequiredAtIndex(size_t index) const {
385c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool value = false;
386c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GetInfoForProfileAtIndex(index)->GetBoolean(kSigninRequiredKey, &value);
387c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return value;
388c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
389c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3902385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochstd::string ProfileInfoCache::GetManagedUserIdOfProfileAtIndex(
3912385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    size_t index) const {
3922385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  std::string managed_user_id;
3932385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  GetInfoForProfileAtIndex(index)->GetString(kManagedUserId, &managed_user_id);
3942385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  return managed_user_id;
3952385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch}
3962385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ProfileInfoCache::OnGAIAPictureLoaded(const base::FilePath& path,
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           gfx::Image** image) const {
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string key = CacheKeyFromProfilePath(path);
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gaia_pictures_loading_[key] = false;
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (*image) {
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delete gaia_pictures_[key];
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gaia_pictures_[key] = *image;
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Place an empty image in the cache to avoid reloading it again.
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gaia_pictures_[key] = new gfx::Image();
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delete image;
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::NotificationService::current()->Notify(
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      chrome::NOTIFICATION_PROFILE_CACHED_INFO_CHANGED,
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::NotificationService::AllSources(),
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::NotificationService::NoDetails());
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ProfileInfoCache::OnGAIAPictureSaved(const base::FilePath& path,
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                          bool* success) const  {
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (*success) {
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    content::NotificationService::current()->Notify(
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        chrome::NOTIFICATION_PROFILE_CACHE_PICTURE_SAVED,
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        content::NotificationService::AllSources(),
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        content::NotificationService::NoDetails());
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delete success;
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ProfileInfoCache::IsUsingGAIAPictureOfProfileAtIndex(
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    size_t index) const {
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool value = false;
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetInfoForProfileAtIndex(index)->GetBoolean(kUseGAIAPictureKey, &value);
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return value;
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)size_t ProfileInfoCache::GetAvatarIconIndexOfProfileAtIndex(size_t index)
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const {
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string icon_url;
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetInfoForProfileAtIndex(index)->GetString(kAvatarIconKey, &icon_url);
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t icon_index = 0;
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (IsDefaultAvatarIconUrl(icon_url, &icon_index))
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return icon_index;
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DLOG(WARNING) << "Unknown avatar icon: " << icon_url;
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return GetDefaultAvatarIconResourceIDAtIndex(0);
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ProfileInfoCache::SetNameOfProfileAtIndex(size_t index,
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                               const string16& name) {
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<DictionaryValue> info(GetInfoForProfileAtIndex(index)->DeepCopy());
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string16 current_name;
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  info->GetString(kNameKey, &current_name);
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (name == current_name)
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string16 old_display_name = GetNameOfProfileAtIndex(index);
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  info->SetString(kNameKey, name);
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This takes ownership of |info|.
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetInfoForProfileAtIndex(index, info.release());
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string16 new_display_name = GetNameOfProfileAtIndex(index);
4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath profile_path = GetPathOfProfileAtIndex(index);
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UpdateSortForProfileIndex(index);
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (old_display_name != new_display_name) {
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FOR_EACH_OBSERVER(ProfileInfoCacheObserver,
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      observer_list_,
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      OnProfileNameChanged(profile_path, old_display_name));
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ProfileInfoCache::SetShortcutNameOfProfileAtIndex(
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    size_t index,
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const string16& shortcut_name) {
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (shortcut_name == GetShortcutNameOfProfileAtIndex(index))
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<DictionaryValue> info(GetInfoForProfileAtIndex(index)->DeepCopy());
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  info->SetString(kShortcutNameKey, shortcut_name);
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This takes ownership of |info|.
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetInfoForProfileAtIndex(index, info.release());
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ProfileInfoCache::SetUserNameOfProfileAtIndex(size_t index,
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                   const string16& user_name) {
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (user_name == GetUserNameOfProfileAtIndex(index))
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<DictionaryValue> info(GetInfoForProfileAtIndex(index)->DeepCopy());
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  info->SetString(kUserNameKey, user_name);
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This takes ownership of |info|.
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetInfoForProfileAtIndex(index, info.release());
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ProfileInfoCache::SetAvatarIconOfProfileAtIndex(size_t index,
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                     size_t icon_index) {
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<DictionaryValue> info(GetInfoForProfileAtIndex(index)->DeepCopy());
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  info->SetString(kAvatarIconKey, GetDefaultAvatarIconUrl(icon_index));
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This takes ownership of |info|.
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetInfoForProfileAtIndex(index, info.release());
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath profile_path = GetPathOfProfileAtIndex(index);
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FOR_EACH_OBSERVER(ProfileInfoCacheObserver,
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    observer_list_,
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    OnProfileAvatarChanged(profile_path));
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5092385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochvoid ProfileInfoCache::SetManagedUserIdOfProfileAtIndex(size_t index,
5102385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                                                        const std::string& id) {
5112385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  scoped_ptr<DictionaryValue> info(GetInfoForProfileAtIndex(index)->DeepCopy());
5122385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  info->SetString(kManagedUserId, id);
5132385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  // This takes ownership of |info|.
5142385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  SetInfoForProfileAtIndex(index, info.release());
5152385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch}
5162385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ProfileInfoCache::SetBackgroundStatusOfProfileAtIndex(
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    size_t index,
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool running_background_apps) {
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (GetBackgroundStatusOfProfileAtIndex(index) == running_background_apps)
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<DictionaryValue> info(GetInfoForProfileAtIndex(index)->DeepCopy());
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  info->SetBoolean(kBackgroundAppsKey, running_background_apps);
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This takes ownership of |info|.
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetInfoForProfileAtIndex(index, info.release());
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ProfileInfoCache::SetGAIANameOfProfileAtIndex(size_t index,
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                   const string16& name) {
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (name == GetGAIANameOfProfileAtIndex(index))
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string16 old_display_name = GetNameOfProfileAtIndex(index);
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<DictionaryValue> info(GetInfoForProfileAtIndex(index)->DeepCopy());
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  info->SetString(kGAIANameKey, name);
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This takes ownership of |info|.
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetInfoForProfileAtIndex(index, info.release());
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string16 new_display_name = GetNameOfProfileAtIndex(index);
5392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath profile_path = GetPathOfProfileAtIndex(index);
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UpdateSortForProfileIndex(index);
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (old_display_name != new_display_name) {
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FOR_EACH_OBSERVER(ProfileInfoCacheObserver,
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      observer_list_,
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      OnProfileNameChanged(profile_path, old_display_name));
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ProfileInfoCache::SetIsUsingGAIANameOfProfileAtIndex(size_t index,
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                          bool value) {
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (value == IsUsingGAIANameOfProfileAtIndex(index))
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string16 old_display_name = GetNameOfProfileAtIndex(index);
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<DictionaryValue> info(GetInfoForProfileAtIndex(index)->DeepCopy());
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  info->SetBoolean(kUseGAIANameKey, value);
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This takes ownership of |info|.
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetInfoForProfileAtIndex(index, info.release());
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string16 new_display_name = GetNameOfProfileAtIndex(index);
5602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath profile_path = GetPathOfProfileAtIndex(index);
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UpdateSortForProfileIndex(index);
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (old_display_name != new_display_name) {
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FOR_EACH_OBSERVER(ProfileInfoCacheObserver,
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      observer_list_,
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      OnProfileNameChanged(profile_path, old_display_name));
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ProfileInfoCache::SetGAIAPictureOfProfileAtIndex(size_t index,
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                      const gfx::Image* image) {
5722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath path = GetPathOfProfileAtIndex(index);
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string key = CacheKeyFromProfilePath(path);
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Delete the old bitmap from cache.
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::map<std::string, gfx::Image*>::iterator it = gaia_pictures_.find(key);
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (it != gaia_pictures_.end()) {
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delete it->second;
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gaia_pictures_.erase(it);
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string old_file_name;
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetInfoForProfileAtIndex(index)->GetString(
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kGAIAPictureFileNameKey, &old_file_name);
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string new_file_name;
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!image) {
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Delete the old bitmap from disk.
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!old_file_name.empty()) {
5902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::FilePath image_path = path.AppendASCII(old_file_name);
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              base::Bind(&DeleteBitmap, image_path));
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Save the new bitmap to disk.
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gaia_pictures_[key] = new gfx::Image(*image);
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_ptr<ImageData> data(new ImageData);
5982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_refptr<base::RefCountedMemory> png_data = image->As1xPNGBytes();
5992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    data->assign(png_data->front(), png_data->front() + png_data->size());
6002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!data->size()) {
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LOG(ERROR) << "Failed to PNG encode the image.";
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new_file_name =
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          old_file_name.empty() ? kGAIAPictureFileName : old_file_name;
6052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::FilePath image_path = path.AppendASCII(new_file_name);
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      bool* success = new bool;
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BrowserThread::PostTaskAndReply(BrowserThread::FILE, FROM_HERE,
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          base::Bind(&SaveBitmap, data.release(), image_path, success),
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          base::Bind(&ProfileInfoCache::OnGAIAPictureSaved, AsWeakPtr(),
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     path, success));
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<DictionaryValue> info(GetInfoForProfileAtIndex(index)->DeepCopy());
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  info->SetString(kGAIAPictureFileNameKey, new_file_name);
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This takes ownership of |info|.
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetInfoForProfileAtIndex(index, info.release());
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FOR_EACH_OBSERVER(ProfileInfoCacheObserver,
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    observer_list_,
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    OnProfileAvatarChanged(path));
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ProfileInfoCache::SetIsUsingGAIAPictureOfProfileAtIndex(size_t index,
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                             bool value) {
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<DictionaryValue> info(GetInfoForProfileAtIndex(index)->DeepCopy());
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  info->SetBoolean(kUseGAIAPictureKey, value);
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This takes ownership of |info|.
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetInfoForProfileAtIndex(index, info.release());
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Retrieve some info to update observers who care about avatar changes.
6322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath profile_path = GetPathOfProfileAtIndex(index);
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FOR_EACH_OBSERVER(ProfileInfoCacheObserver,
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    observer_list_,
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    OnProfileAvatarChanged(profile_path));
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
638c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ProfileInfoCache::SetProfileSigninRequiredAtIndex(size_t index,
639c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                                       bool value) {
640c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (value == ProfileIsSigninRequiredAtIndex(index))
641c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return;
642c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
643c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<DictionaryValue> info(GetInfoForProfileAtIndex(index)->DeepCopy());
644c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  info->SetBoolean(kSigninRequiredKey, value);
645c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // This takes ownership of |info|.
646c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  SetInfoForProfileAtIndex(index, info.release());
647c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
648c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
6492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)string16 ProfileInfoCache::ChooseNameForNewProfile(size_t icon_index) const {
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string16 name;
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int name_index = 1; ; ++name_index) {
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (icon_index < kGenericIconCount) {
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      name = l10n_util::GetStringFUTF16Int(IDS_NUMBERED_PROFILE_NAME,
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           name_index);
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      name = l10n_util::GetStringUTF16(
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          kDefaultNames[icon_index - kGenericIconCount]);
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (name_index > 1)
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        name.append(UTF8ToUTF16(base::IntToString(name_index)));
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Loop through previously named profiles to ensure we're not duplicating.
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool name_found = false;
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (size_t i = 0; i < GetNumberOfProfiles(); ++i) {
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (GetNameOfProfileAtIndex(i) == name) {
6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        name_found = true;
6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!name_found)
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return name;
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ProfileInfoCache::GetHasMigratedToGAIAInfoOfProfileAtIndex(
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      size_t index) const {
6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool value = false;
6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetInfoForProfileAtIndex(index)->GetBoolean(
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kHasMigratedToGAIAInfoKey, &value);
6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return value;
6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ProfileInfoCache::SetHasMigratedToGAIAInfoOfProfileAtIndex(
6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    size_t index, bool value) {
6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<DictionaryValue> info(GetInfoForProfileAtIndex(index)->DeepCopy());
6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  info->SetBoolean(kHasMigratedToGAIAInfoKey, value);
6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This takes ownership of |info|.
6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetInfoForProfileAtIndex(index, info.release());
6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ProfileInfoCache::IconIndexIsUnique(size_t icon_index) const {
6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < GetNumberOfProfiles(); ++i) {
6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (GetAvatarIconIndexOfProfileAtIndex(i) == icon_index)
6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ProfileInfoCache::ChooseAvatarIconIndexForNewProfile(
7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool allow_generic_icon,
7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool must_be_unique,
7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    size_t* out_icon_index) const {
7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t start = allow_generic_icon ? 0 : kGenericIconCount;
7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t end = GetDefaultAvatarIconCount();
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t count = end - start;
7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rand = base::RandInt(0, count);
7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < count; ++i) {
7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    size_t icon_index = start + (rand + i) %  count;
7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!must_be_unique || IconIndexIsUnique(icon_index)) {
7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *out_icon_index = icon_index;
7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return true;
7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)size_t ProfileInfoCache::ChooseAvatarIconIndexForNewProfile() const {
7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t icon_index = 0;
7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Try to find a unique, non-generic icon.
7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (ChooseAvatarIconIndexForNewProfile(false, true, &icon_index))
7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return icon_index;
7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Try to find any unique icon.
7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (ChooseAvatarIconIndexForNewProfile(true, true, &icon_index))
7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return icon_index;
7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Settle for any random icon, even if it's not unique.
7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (ChooseAvatarIconIndexForNewProfile(true, false, &icon_index))
7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return icon_index;
7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NOTREACHED();
7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return 0;
7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const base::FilePath& ProfileInfoCache::GetUserDataDir() const {
7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return user_data_dir_;
7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)size_t ProfileInfoCache::GetDefaultAvatarIconCount() {
7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return kDefaultAvatarIconsCount;
7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int ProfileInfoCache::GetDefaultAvatarIconResourceIDAtIndex(size_t index) {
7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(IsDefaultAvatarIconIndex(index));
7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return kDefaultAvatarIconResources[index];
7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string ProfileInfoCache::GetDefaultAvatarIconUrl(size_t index) {
7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(IsDefaultAvatarIconIndex(index));
7532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return base::StringPrintf("%s%" PRIuS, kDefaultUrlPrefix, index);
7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ProfileInfoCache::IsDefaultAvatarIconIndex(size_t index) {
7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return index < kDefaultAvatarIconsCount;
7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ProfileInfoCache::IsDefaultAvatarIconUrl(const std::string& url,
7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              size_t* icon_index) {
7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(icon_index);
7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (url.find(kDefaultUrlPrefix) != 0)
7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int int_value = -1;
7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (base::StringToInt(base::StringPiece(url.begin() +
7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                          strlen(kDefaultUrlPrefix),
7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                          url.end()),
7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        &int_value)) {
7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (int_value < 0 ||
7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        int_value >= static_cast<int>(kDefaultAvatarIconsCount))
7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *icon_index = int_value;
7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const DictionaryValue* ProfileInfoCache::GetInfoForProfileAtIndex(
7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    size_t index) const {
7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_LT(index, GetNumberOfProfiles());
7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const DictionaryValue* cache =
7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      prefs_->GetDictionary(prefs::kProfileInfoCache);
7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const DictionaryValue* info = NULL;
7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cache->GetDictionary(sorted_keys_[index], &info);
7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return info;
7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ProfileInfoCache::SetInfoForProfileAtIndex(size_t index,
7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                DictionaryValue* info) {
7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DictionaryPrefUpdate update(prefs_, prefs::kProfileInfoCache);
7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DictionaryValue* cache = update.Get();
7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cache->Set(sorted_keys_[index], info);
7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::NotificationService::current()->Notify(
8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      chrome::NOTIFICATION_PROFILE_CACHED_INFO_CHANGED,
8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::NotificationService::AllSources(),
8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::NotificationService::NoDetails());
8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string ProfileInfoCache::CacheKeyFromProfilePath(
8062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::FilePath& profile_path) const {
8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(user_data_dir_ == profile_path.DirName());
8082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath base_name = profile_path.BaseName();
8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return base_name.MaybeAsASCII();
8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::vector<std::string>::iterator ProfileInfoCache::FindPositionForProfile(
8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& search_key,
8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const string16& search_name) {
8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string16 search_name_l = base::i18n::ToLower(search_name);
8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < GetNumberOfProfiles(); ++i) {
8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    string16 name_l = base::i18n::ToLower(GetNameOfProfileAtIndex(i));
8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int name_compare = search_name_l.compare(name_l);
8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (name_compare < 0)
8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return sorted_keys_.begin() + i;
8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (name_compare == 0) {
8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      int key_compare = search_key.compare(sorted_keys_[i]);
8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (key_compare < 0)
8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return sorted_keys_.begin() + i;
8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return sorted_keys_.end();
8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ProfileInfoCache::UpdateSortForProfileIndex(size_t index) {
8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string16 name = GetNameOfProfileAtIndex(index);
8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Remove and reinsert key in |sorted_keys_| to alphasort.
8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string key = CacheKeyFromProfilePath(GetPathOfProfileAtIndex(index));
8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<std::string>::iterator key_it =
8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      std::find(sorted_keys_.begin(), sorted_keys_.end(), key);
8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(key_it != sorted_keys_.end());
8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sorted_keys_.erase(key_it);
8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sorted_keys_.insert(FindPositionForProfile(key, name), key);
8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::NotificationService::current()->Notify(
8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      chrome::NOTIFICATION_PROFILE_CACHED_INFO_CHANGED,
8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::NotificationService::AllSources(),
8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::NotificationService::NoDetails());
8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::vector<string16> ProfileInfoCache::GetProfileNames() {
8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<string16> names;
8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PrefService* local_state = g_browser_process->local_state();
8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const DictionaryValue* cache = local_state->GetDictionary(
8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      prefs::kProfileInfoCache);
8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string16 name;
8542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (base::DictionaryValue::Iterator it(*cache); !it.IsAtEnd();
8552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       it.Advance()) {
8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const base::DictionaryValue* info = NULL;
8572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    it.value().GetAsDictionary(&info);
8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    info->GetString(kNameKey, &name);
8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    names.push_back(name);
8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return names;
8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
8652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ProfileInfoCache::RegisterPrefs(PrefRegistrySimple* registry) {
8662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  registry->RegisterDictionaryPref(prefs::kProfileInfoCache);
8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
868