media_galleries_preferences.cc revision d0247b1b59f9c528cb6df88b4f2b9afaf80d181e
12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/media_galleries/media_galleries_preferences.h"
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/i18n/time_formatting.h"
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/path_service.h"
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/prefs/pref_service.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/stl_util.h"
11868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string16.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_number_conversions.h"
13868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/values.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/browser_process.h"
16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/extensions/api/media_galleries_private/media_galleries_private_api.h"
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/extensions/extension_service.h"
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/extensions/extension_system.h"
19c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/media_galleries/fileapi/itunes_finder.h"
2058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "chrome/browser/media_galleries/fileapi/picasa_finder.h"
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/media_galleries/media_file_system_registry.h"
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/prefs/scoped_user_pref_update.h"
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/profiles/profile.h"
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/storage_monitor/media_storage_util.h"
25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/storage_monitor/storage_monitor.h"
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/common/chrome_paths.h"
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/common/extensions/extension.h"
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/common/extensions/permissions/api_permission.h"
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/common/extensions/permissions/media_galleries_permission.h"
3090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/common/extensions/permissions/permissions_data.h"
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/common/pref_names.h"
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "components/user_prefs/pref_registry_syncable.h"
33eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "grit/generated_resources.h"
34eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "ui/base/l10n/l10n_util.h"
35eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "ui/base/text/bytes_formatting.h"
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
37868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)using base::DictionaryValue;
38868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)using base::ListValue;
39868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)using extensions::ExtensionPrefs;
40868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace {
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
43868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Pref key for the list of media gallery permissions.
44868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)const char kMediaGalleriesPermissions[] = "media_galleries_permissions";
45868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Pref key for Media Gallery ID.
46868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)const char kMediaGalleryIdKey[] = "id";
47868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Pref key for Media Gallery Permission Value.
48868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)const char kMediaGalleryHasPermissionKey[] = "has_permission";
49868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kMediaGalleriesDeviceIdKey[] = "deviceId";
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kMediaGalleriesDisplayNameKey[] = "displayName";
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kMediaGalleriesPathKey[] = "path";
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kMediaGalleriesPrefIdKey[] = "prefId";
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kMediaGalleriesTypeKey[] = "type";
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kMediaGalleriesVolumeLabelKey[] = "volumeLabel";
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kMediaGalleriesVendorNameKey[] = "vendorName";
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kMediaGalleriesModelNameKey[] = "modelName";
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kMediaGalleriesSizeKey[] = "totalSize";
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kMediaGalleriesLastAttachTimeKey[] = "lastAttachTime";
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kMediaGalleriesPrefsVersionKey[] = "preferencesVersion";
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kMediaGalleriesTypeAutoDetectedValue[] = "autoDetected";
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kMediaGalleriesTypeUserAddedValue[] = "userAdded";
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kMediaGalleriesTypeBlackListedValue[] = "blackListed";
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const char kITunesGalleryName[] = "iTunes";
6790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)const char kPicasaGalleryName[] = "Picasa";
68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool GetPrefId(const DictionaryValue& dict, MediaGalleryPrefId* value) {
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string string_id;
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!dict.GetString(kMediaGalleriesPrefIdKey, &string_id) ||
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      !base::StringToUint64(string_id, value)) {
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool GetType(const DictionaryValue& dict, MediaGalleryPrefInfo::Type* type) {
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string string_type;
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!dict.GetString(kMediaGalleriesTypeKey, &string_type))
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (string_type == kMediaGalleriesTypeAutoDetectedValue) {
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    *type = MediaGalleryPrefInfo::kAutoDetected;
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return true;
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (string_type == kMediaGalleriesTypeUserAddedValue) {
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    *type = MediaGalleryPrefInfo::kUserAdded;
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return true;
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (string_type == kMediaGalleriesTypeBlackListedValue) {
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    *type = MediaGalleryPrefInfo::kBlackListed;
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return true;
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return false;
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool PopulateGalleryPrefInfoFromDictionary(
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const DictionaryValue& dict, MediaGalleryPrefInfo* out_gallery_info) {
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MediaGalleryPrefId pref_id;
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  string16 display_name;
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string device_id;
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath::StringType path;
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MediaGalleryPrefInfo::Type type = MediaGalleryPrefInfo::kAutoDetected;
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  string16 volume_label;
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  string16 vendor_name;
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  string16 model_name;
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  double total_size_in_bytes = 0.0;
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  double last_attach_time = 0.0;
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool volume_metadata_valid = false;
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int prefs_version = 0;
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!GetPrefId(dict, &pref_id) ||
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      !dict.GetString(kMediaGalleriesDeviceIdKey, &device_id) ||
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      !dict.GetString(kMediaGalleriesPathKey, &path) ||
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      !GetType(dict, &type)) {
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  dict.GetString(kMediaGalleriesDisplayNameKey, &display_name);
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  dict.GetInteger(kMediaGalleriesPrefsVersionKey, &prefs_version);
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (dict.GetString(kMediaGalleriesVolumeLabelKey, &volume_label) &&
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      dict.GetString(kMediaGalleriesVendorNameKey, &vendor_name) &&
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      dict.GetString(kMediaGalleriesModelNameKey, &model_name) &&
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      dict.GetDouble(kMediaGalleriesSizeKey, &total_size_in_bytes) &&
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      dict.GetDouble(kMediaGalleriesLastAttachTimeKey, &last_attach_time)) {
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    volume_metadata_valid = true;
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  out_gallery_info->pref_id = pref_id;
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  out_gallery_info->display_name = display_name;
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  out_gallery_info->device_id = device_id;
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  out_gallery_info->path = base::FilePath(path);
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  out_gallery_info->type = type;
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  out_gallery_info->volume_label = volume_label;
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  out_gallery_info->vendor_name = vendor_name;
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  out_gallery_info->model_name = model_name;
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  out_gallery_info->total_size_in_bytes = total_size_in_bytes;
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  out_gallery_info->last_attach_time =
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Time::FromInternalValue(last_attach_time);
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  out_gallery_info->volume_metadata_valid = volume_metadata_valid;
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  out_gallery_info->prefs_version = prefs_version;
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DictionaryValue* CreateGalleryPrefInfoDictionary(
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const MediaGalleryPrefInfo& gallery) {
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DictionaryValue* dict = new DictionaryValue();
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  dict->SetString(kMediaGalleriesPrefIdKey,
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                  base::Uint64ToString(gallery.pref_id));
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!gallery.volume_metadata_valid)
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    dict->SetString(kMediaGalleriesDisplayNameKey, gallery.display_name);
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  dict->SetString(kMediaGalleriesDeviceIdKey, gallery.device_id);
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  dict->SetString(kMediaGalleriesPathKey, gallery.path.value());
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const char* type = NULL;
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  switch (gallery.type) {
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case MediaGalleryPrefInfo::kAutoDetected:
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      type = kMediaGalleriesTypeAutoDetectedValue;
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case MediaGalleryPrefInfo::kUserAdded:
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      type = kMediaGalleriesTypeUserAddedValue;
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case MediaGalleryPrefInfo::kBlackListed:
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      type = kMediaGalleriesTypeBlackListedValue;
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    default:
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      NOTREACHED();
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  dict->SetString(kMediaGalleriesTypeKey, type);
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (gallery.volume_metadata_valid) {
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    dict->SetString(kMediaGalleriesVolumeLabelKey, gallery.volume_label);
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    dict->SetString(kMediaGalleriesVendorNameKey, gallery.vendor_name);
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    dict->SetString(kMediaGalleriesModelNameKey, gallery.model_name);
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    dict->SetDouble(kMediaGalleriesSizeKey, gallery.total_size_in_bytes);
1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    dict->SetDouble(kMediaGalleriesLastAttachTimeKey,
1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    gallery.last_attach_time.ToInternalValue());
1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Version 0 of the prefs format was that the display_name was always
1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // used to show the user-visible name of the gallery. Version 1 means
1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // that there is an optional display_name, and when it is present, it
1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // overrides the name that would be built from the volume metadata, path,
1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // or whatever other data. So if we see a display_name with version 0, it
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // means it may be overwritten simply by getting new volume metadata.
1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // A display_name with version 1 should not be overwritten.
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  dict->SetInteger(kMediaGalleriesPrefsVersionKey, gallery.prefs_version);
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return dict;
1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool HasAutoDetectedGalleryPermission(const extensions::Extension& extension) {
1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  extensions::MediaGalleriesPermission::CheckParam param(
2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      extensions::MediaGalleriesPermission::kAllAutoDetectedPermission);
20190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  return extensions::PermissionsData::CheckAPIPermissionWithParam(
20290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      &extension, extensions::APIPermission::kMediaGalleries, &param);
2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
205868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Retrieves the MediaGalleryPermission from the given dictionary; DCHECKs on
206868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// failure.
207868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)bool GetMediaGalleryPermissionFromDictionary(
208868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const DictionaryValue* dict,
209868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    MediaGalleryPermission* out_permission) {
210868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  std::string string_id;
211868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (dict->GetString(kMediaGalleryIdKey, &string_id) &&
212868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      base::StringToUint64(string_id, &out_permission->pref_id) &&
213868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      dict->GetBoolean(kMediaGalleryHasPermissionKey,
214868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                       &out_permission->has_permission)) {
215868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return true;
216868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
217868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  NOTREACHED();
218868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return false;
219868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
220868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
221eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochstring16 GetDisplayNameForDevice(uint64 storage_size_in_bytes,
222eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                 const string16& name) {
223eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  DCHECK(!name.empty());
224eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return (storage_size_in_bytes == 0) ?
225eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      name : ui::FormatBytes(storage_size_in_bytes) + ASCIIToUTF16(" ") + name;
226eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
227eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
228eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// For a device with |device_name| and a relative path |sub_folder|, construct
229eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// a display name. If |sub_folder| is empty, then just return |device_name|.
230eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochstring16 GetDisplayNameForSubFolder(const string16& device_name,
231eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                    const base::FilePath& sub_folder) {
232eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (sub_folder.empty())
233eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return device_name;
234eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return (sub_folder.BaseName().LossyDisplayName() +
235eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          ASCIIToUTF16(" - ") +
236eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          device_name);
237eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
238eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
239eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochstring16 GetFullProductName(const string16& vendor_name,
240eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                            const string16& model_name) {
241eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (vendor_name.empty() && model_name.empty())
242eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return string16();
243eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
244eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  string16 product_name;
245eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (vendor_name.empty())
246eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    product_name = model_name;
247eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  else if (model_name.empty())
248eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    product_name = vendor_name;
249eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  else if (!vendor_name.empty() && !model_name.empty())
250eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    product_name = vendor_name + UTF8ToUTF16(", ") + model_name;
251eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
252eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return product_name;
253eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
254eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace
2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)MediaGalleryPrefInfo::MediaGalleryPrefInfo()
2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : pref_id(kInvalidMediaGalleryPrefId),
2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      type(kInvalidType),
2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      total_size_in_bytes(0),
2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      volume_metadata_valid(false),
2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      prefs_version(0) {
2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)MediaGalleryPrefInfo::~MediaGalleryPrefInfo() {}
2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::FilePath MediaGalleryPrefInfo::AbsolutePath() const {
2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath base_path = MediaStorageUtil::FindDevicePathById(device_id);
269c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(!path.IsAbsolute());
2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return base_path.empty() ? base_path : base_path.Append(path);
2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
273eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochstring16 MediaGalleryPrefInfo::GetGalleryDisplayName() const {
274eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (!StorageInfo::IsRemovableDevice(device_id)) {
275eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    // For fixed storage, the name is the directory name, or, in the case
276eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    // of a root directory, the root directory name.
277eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    // TODO(gbillock): Using only the BaseName can lead to ambiguity. The
278eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    // tooltip resolves it. Is that enough?
279eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    base::FilePath path = AbsolutePath();
280eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    if (!display_name.empty())
281eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      return display_name;
282eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    if (path == path.DirName())
283eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      return path.LossyDisplayName();
284eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return path.BaseName().LossyDisplayName();
285eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
286eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
287eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  string16 name = display_name;
288eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (name.empty())
289eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    name = volume_label;
290eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (name.empty())
291eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    name = GetFullProductName(vendor_name, model_name);
292eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (name.empty())
293eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    name = l10n_util::GetStringUTF16(IDS_MEDIA_GALLERIES_UNLABELED_DEVICE);
294eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
295eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  name = GetDisplayNameForDevice(total_size_in_bytes, name);
296eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
297eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (!path.empty())
298eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    name = GetDisplayNameForSubFolder(name, path);
299eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
300eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return name;
301eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
302eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
303eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochstring16 MediaGalleryPrefInfo::GetGalleryTooltip() const {
304eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return AbsolutePath().LossyDisplayName();
305eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
306eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
307eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochstring16 MediaGalleryPrefInfo::GetGalleryAdditionalDetails() const {
308eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  string16 attached;
309eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (StorageInfo::IsRemovableDevice(device_id)) {
310eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    if (MediaStorageUtil::IsRemovableStorageAttached(device_id)) {
311eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      attached = l10n_util::GetStringUTF16(
312eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          IDS_MEDIA_GALLERIES_DIALOG_DEVICE_ATTACHED);
313eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    } else if (!last_attach_time.is_null()) {
314eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      attached = l10n_util::GetStringFUTF16(
315eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          IDS_MEDIA_GALLERIES_LAST_ATTACHED,
316eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          base::TimeFormatShortDateNumeric(last_attach_time));
317eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    } else {
318eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      attached = l10n_util::GetStringUTF16(
319eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          IDS_MEDIA_GALLERIES_DIALOG_DEVICE_NOT_ATTACHED);
320eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    }
321eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
322eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
323eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return attached;
324eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
325eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
326eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochbool MediaGalleryPrefInfo::IsGalleryAvailable() const {
327eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return !StorageInfo::IsRemovableDevice(device_id) ||
328eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch         MediaStorageUtil::IsRemovableStorageAttached(device_id);
329eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
330eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)MediaGalleriesPreferences::GalleryChangeObserver::~GalleryChangeObserver() {}
3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)MediaGalleriesPreferences::MediaGalleriesPreferences(Profile* profile)
334c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : weak_factory_(this),
335868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      profile_(profile),
336868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      extension_prefs_for_testing_(NULL) {
3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  AddDefaultGalleriesIfFreshProfile();
338c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
339c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Look for optional default galleries every time.
340c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  itunes::ITunesFinder::FindITunesLibrary(
341c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      base::Bind(&MediaGalleriesPreferences::OnITunesDeviceID,
342c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 weak_factory_.GetWeakPtr()));
34390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
34490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // TODO(tommycli): Turn on when Picasa code is ready.
34590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#if 0
34690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  picasa::PicasaFinder::FindPicasaDatabaseOnUIThread(
34790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      base::Bind(&MediaGalleriesPreferences::OnPicasaDeviceID,
34890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                 weak_factory_.GetWeakPtr()));
34990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#endif
350c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
351d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  InitFromPrefs();
352c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
353868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  StorageMonitor::GetInstance()->AddObserver(this);
3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
356c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)MediaGalleriesPreferences::~MediaGalleriesPreferences() {
3577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (StorageMonitor::GetInstance())
3587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    StorageMonitor::GetInstance()->RemoveObserver(this);
359c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
361d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)Profile* MediaGalleriesPreferences::profile() {
362d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  return profile_;
363d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
364d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void MediaGalleriesPreferences::AddDefaultGalleriesIfFreshProfile() {
3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Only add defaults the first time.
3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (APIHasBeenUsed(profile_))
3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Fresh profile case.
3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const int kDirectoryKeys[] = {
372d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    chrome::DIR_USER_MUSIC,
373d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    chrome::DIR_USER_PICTURES,
374d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    chrome::DIR_USER_VIDEOS,
3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (size_t i = 0; i < arraysize(kDirectoryKeys); ++i) {
3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::FilePath path;
3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!PathService::Get(kDirectoryKeys[i], &path))
3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      continue;
3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::FilePath relative_path;
3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    StorageInfo info;
3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (MediaStorageUtil::GetDeviceInfoFromPath(path, &info, &relative_path)) {
3857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      AddGalleryInternal(info.device_id(), info.name(), relative_path, false,
3867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                         info.storage_label(), info.vendor_name(),
3877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                         info.model_name(), info.total_size_in_bytes(),
3887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                         base::Time(), true, 2);
3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)bool MediaGalleriesPreferences::UpdateDeviceIDForSingletonType(
3947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    const std::string& device_id) {
3957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  StorageInfo::Type singleton_type;
3967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (!StorageInfo::CrackDeviceId(device_id, &singleton_type, NULL))
3977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return false;
3987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  PrefService* prefs = profile_->GetPrefs();
4007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<ListPrefUpdate> update(new ListPrefUpdate(
4017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      prefs, prefs::kMediaGalleriesRememberedGalleries));
4027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ListValue* list = update->Get();
4037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  for (ListValue::iterator iter = list->begin(); iter != list->end(); ++iter) {
4047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // All of these calls should succeed, but preferences file can be corrupt.
4057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    DictionaryValue* dict;
4067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    if (!(*iter)->GetAsDictionary(&dict))
4077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      continue;
4087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    std::string this_device_id;
4097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    if (!dict->GetString(kMediaGalleriesDeviceIdKey, &this_device_id))
4107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      continue;
4117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    if (this_device_id == device_id)
4127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      return true;  // No update is necessary.
4137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    StorageInfo::Type device_type;
4147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    if (!StorageInfo::CrackDeviceId(this_device_id, &device_type, NULL))
4157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      continue;
4167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    if (device_type == singleton_type) {
4187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      dict->SetString(kMediaGalleriesDeviceIdKey, device_id);
4197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      update.reset();  // commits the update.
420d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      InitFromPrefs();
421d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      MediaGalleryPrefId pref_id;
422d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      if (GetPrefId(*dict, &pref_id)) {
423d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        FOR_EACH_OBSERVER(GalleryChangeObserver,
424d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                          gallery_change_observers_,
425d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                          OnGalleryInfoUpdated(this, pref_id));
426d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      }
4277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      return true;
4287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    }
4297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
4307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return false;
4317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
4327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
433c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void MediaGalleriesPreferences::OnITunesDeviceID(const std::string& device_id) {
4347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (device_id.empty())
4357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return;
4367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (!UpdateDeviceIDForSingletonType(device_id)) {
4377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    AddGalleryInternal(device_id, ASCIIToUTF16(kITunesGalleryName),
4387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                       base::FilePath(), false /*not user added*/,
4397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                       string16(), string16(), string16(), 0,
4407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                       base::Time(), false, 2);
4417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
442c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
443c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
44490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void MediaGalleriesPreferences::OnPicasaDeviceID(const std::string& device_id) {
44590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  DCHECK(!device_id.empty());
4467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (!UpdateDeviceIDForSingletonType(device_id)) {
4477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    AddGalleryInternal(device_id, ASCIIToUTF16(kPicasaGalleryName),
4487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                       base::FilePath(), false /*not user added*/,
4497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                       string16(), string16(), string16(), 0,
4507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                       base::Time(), false, 2);
4517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
45290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
45390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
454d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void MediaGalleriesPreferences::InitFromPrefs() {
4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  known_galleries_.clear();
4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  device_map_.clear();
4572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PrefService* prefs = profile_->GetPrefs();
4592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const ListValue* list = prefs->GetList(
4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      prefs::kMediaGalleriesRememberedGalleries);
4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (list) {
4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (ListValue::const_iterator it = list->begin();
4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)         it != list->end(); ++it) {
4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const DictionaryValue* dict = NULL;
4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (!(*it)->GetAsDictionary(&dict))
4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        continue;
4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      MediaGalleryPrefInfo gallery_info;
4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (!PopulateGalleryPrefInfoFromDictionary(*dict, &gallery_info))
4702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        continue;
4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      known_galleries_[gallery_info.pref_id] = gallery_info;
4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      device_map_[gallery_info.device_id].insert(gallery_info.pref_id);
4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void MediaGalleriesPreferences::AddGalleryChangeObserver(
4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    GalleryChangeObserver* observer) {
4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gallery_change_observers_.AddObserver(observer);
4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void MediaGalleriesPreferences::RemoveGalleryChangeObserver(
4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    GalleryChangeObserver* observer) {
4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gallery_change_observers_.RemoveObserver(observer);
4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void MediaGalleriesPreferences::OnRemovableStorageAttached(
4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const StorageInfo& info) {
49090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (!StorageInfo::IsMediaDevice(info.device_id()))
4912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
4922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  AddGallery(info.device_id(), base::FilePath(),
4947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)             false /*not user added*/,
4957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)             info.storage_label(),
4967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)             info.vendor_name(),
4977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)             info.model_name(),
4987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)             info.total_size_in_bytes(),
4997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)             base::Time::Now());
5002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool MediaGalleriesPreferences::LookUpGalleryByPath(
5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::FilePath& path,
5042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MediaGalleryPrefInfo* gallery_info) const {
5052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  StorageInfo info;
5062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath relative_path;
5072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!MediaStorageUtil::GetDeviceInfoFromPath(path, &info, &relative_path)) {
5082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (gallery_info)
5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      *gallery_info = MediaGalleryPrefInfo();
5102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  relative_path = relative_path.NormalizePathSeparators();
5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MediaGalleryPrefIdSet galleries_on_device =
51590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      LookUpGalleriesByDeviceId(info.device_id());
5162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (MediaGalleryPrefIdSet::const_iterator it = galleries_on_device.begin();
5172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       it != galleries_on_device.end();
5182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       ++it) {
5192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const MediaGalleryPrefInfo& gallery = known_galleries_.find(*it)->second;
5202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (gallery.path != relative_path)
5212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      continue;
5222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (gallery_info)
5242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      *gallery_info = gallery;
5252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return true;
5262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // This method is called by controller::FilesSelected when the user
5292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // adds a new gallery. Control reaches here when the selected gallery is
5302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // on a volume we know about, but have no gallery already for. Returns
5312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // hypothetical data to the caller about what the prefs will look like
5322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // if the gallery is added.
5332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // TODO(gbillock): split this out into another function so it doesn't
5342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // conflate LookUp.
5352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (gallery_info) {
5362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gallery_info->pref_id = kInvalidMediaGalleryPrefId;
53790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    gallery_info->device_id = info.device_id();
5382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gallery_info->path = relative_path;
5392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gallery_info->type = MediaGalleryPrefInfo::kUserAdded;
5407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    gallery_info->volume_label = info.storage_label();
5417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    gallery_info->vendor_name = info.vendor_name();
5427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    gallery_info->model_name = info.model_name();
5437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    gallery_info->total_size_in_bytes = info.total_size_in_bytes();
5447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    gallery_info->last_attach_time = base::Time::Now();
5457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    gallery_info->volume_metadata_valid = true;
5467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    gallery_info->prefs_version = 2;
5472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return false;
5492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)MediaGalleryPrefIdSet MediaGalleriesPreferences::LookUpGalleriesByDeviceId(
5522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& device_id) const {
5532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DeviceIdPrefIdsMap::const_iterator found = device_map_.find(device_id);
5542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (found == device_map_.end())
5552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return MediaGalleryPrefIdSet();
5562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return found->second;
5572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::FilePath MediaGalleriesPreferences::LookUpGalleryPathForExtension(
5602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MediaGalleryPrefId gallery_id,
5612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const extensions::Extension* extension,
5622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool include_unpermitted_galleries) {
5632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(extension);
5642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!include_unpermitted_galleries &&
5652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      !ContainsKey(GalleriesForExtension(*extension), gallery_id))
5662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return base::FilePath();
5672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MediaGalleriesPrefInfoMap::const_iterator it =
5692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      known_galleries_.find(gallery_id);
5702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (it == known_galleries_.end())
5712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return base::FilePath();
5722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return MediaStorageUtil::FindDevicePathById(it->second.device_id);
5732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)MediaGalleryPrefId MediaGalleriesPreferences::AddGallery(
5762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& device_id,
5772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::FilePath& relative_path, bool user_added,
5782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const string16& volume_label, const string16& vendor_name,
5792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const string16& model_name, uint64 total_size_in_bytes,
5802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::Time last_attach_time) {
5812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return AddGalleryInternal(device_id, string16(), relative_path, user_added,
5822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            volume_label, vendor_name, model_name,
5837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                            total_size_in_bytes, last_attach_time, true, 2);
5842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)MediaGalleryPrefId MediaGalleriesPreferences::AddGalleryInternal(
5872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& device_id, const string16& display_name,
5882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::FilePath& relative_path, bool user_added,
5892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const string16& volume_label, const string16& vendor_name,
5902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const string16& model_name, uint64 total_size_in_bytes,
5912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::Time last_attach_time,
5922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool volume_metadata_valid,
5932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int prefs_version) {
5942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath normalized_relative_path =
5952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      relative_path.NormalizePathSeparators();
5962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MediaGalleryPrefIdSet galleries_on_device =
5972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LookUpGalleriesByDeviceId(device_id);
598d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  for (MediaGalleryPrefIdSet::const_iterator pref_id_it =
599d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)           galleries_on_device.begin();
600d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)       pref_id_it != galleries_on_device.end();
601d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)       ++pref_id_it) {
602d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    const MediaGalleryPrefInfo& existing =
603d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        known_galleries_.find(*pref_id_it)->second;
6042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (existing.path != normalized_relative_path)
6052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      continue;
6062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool update_gallery_type =
6082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        user_added && (existing.type == MediaGalleryPrefInfo::kBlackListed);
60990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // Status quo: In M27 and M28, galleries added manually use version 0,
61090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // and galleries added automatically (including default galleries) use
61190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // version 1. The name override is used by default galleries as well
61290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // as all device attach events.
6137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // We want to upgrade the name if the existing version is < 2. Leave it
6147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // alone if the existing display name is set with version == 2 and the
6157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // proposed new name is empty.
6162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool update_gallery_name = existing.display_name != display_name;
6177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    if (existing.prefs_version == 2 && !existing.display_name.empty() &&
6187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        display_name.empty()) {
6197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      update_gallery_name = false;
6207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    }
6212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool update_gallery_metadata = volume_metadata_valid &&
6222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        ((existing.volume_label != volume_label) ||
6232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)         (existing.vendor_name != vendor_name) ||
6242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)         (existing.model_name != model_name) ||
6252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)         (existing.total_size_in_bytes != total_size_in_bytes) ||
6262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)         (existing.last_attach_time != last_attach_time));
6272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!update_gallery_name && !update_gallery_type &&
6292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        !update_gallery_metadata)
630d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      return *pref_id_it;
6312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    PrefService* prefs = profile_->GetPrefs();
6332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<ListPrefUpdate> update(
6342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        new ListPrefUpdate(prefs, prefs::kMediaGalleriesRememberedGalleries));
6352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ListValue* list = update->Get();
6362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (ListValue::const_iterator list_iter = list->begin();
6382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)         list_iter != list->end();
6392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)         ++list_iter) {
6402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      DictionaryValue* dict;
6412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      MediaGalleryPrefId iter_id;
6422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if ((*list_iter)->GetAsDictionary(&dict) &&
6432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          GetPrefId(*dict, &iter_id) &&
644d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)          *pref_id_it == iter_id) {
6452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        if (update_gallery_type) {
6462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          dict->SetString(kMediaGalleriesTypeKey,
6472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          kMediaGalleriesTypeAutoDetectedValue);
6482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        }
6492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        if (update_gallery_name)
6502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          dict->SetString(kMediaGalleriesDisplayNameKey, display_name);
6512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        if (update_gallery_metadata) {
6522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          dict->SetString(kMediaGalleriesVolumeLabelKey, volume_label);
6532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          dict->SetString(kMediaGalleriesVendorNameKey, vendor_name);
6542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          dict->SetString(kMediaGalleriesModelNameKey, model_name);
6552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          dict->SetDouble(kMediaGalleriesSizeKey, total_size_in_bytes);
6562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          dict->SetDouble(kMediaGalleriesLastAttachTimeKey,
6572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          last_attach_time.ToInternalValue());
6582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        }
6592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        dict->SetInteger(kMediaGalleriesPrefsVersionKey, prefs_version);
6602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        break;
6612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }
6622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
6632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Commits the prefs update.
6652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    update.reset();
6662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
667d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    if (update_gallery_name || update_gallery_metadata ||
668d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        update_gallery_type) {
669d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      InitFromPrefs();
670d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      FOR_EACH_OBSERVER(GalleryChangeObserver,
671d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                        gallery_change_observers_,
672d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                        OnGalleryInfoUpdated(this, *pref_id_it));
673d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    }
674d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    return *pref_id_it;
6752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PrefService* prefs = profile_->GetPrefs();
6782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MediaGalleryPrefInfo gallery_info;
6802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gallery_info.pref_id = prefs->GetUint64(prefs::kMediaGalleriesUniqueId);
6812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  prefs->SetUint64(prefs::kMediaGalleriesUniqueId, gallery_info.pref_id + 1);
6822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gallery_info.display_name = display_name;
6832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gallery_info.device_id = device_id;
6842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gallery_info.path = normalized_relative_path;
6852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gallery_info.type = MediaGalleryPrefInfo::kAutoDetected;
6862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (user_added)
6872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gallery_info.type = MediaGalleryPrefInfo::kUserAdded;
6882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (volume_metadata_valid) {
6892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gallery_info.volume_label = volume_label;
6902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gallery_info.vendor_name = vendor_name;
6912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gallery_info.model_name = model_name;
6922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gallery_info.total_size_in_bytes = total_size_in_bytes;
6932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gallery_info.last_attach_time = last_attach_time;
6942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gallery_info.volume_metadata_valid = volume_metadata_valid;
6962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gallery_info.prefs_version = prefs_version;
6972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
6992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ListPrefUpdate update(prefs, prefs::kMediaGalleriesRememberedGalleries);
7002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ListValue* list = update.Get();
7012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    list->Append(CreateGalleryPrefInfoDictionary(gallery_info));
7022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
703d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  InitFromPrefs();
704d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  FOR_EACH_OBSERVER(GalleryChangeObserver,
705d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                    gallery_change_observers_,
706d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                    OnGalleryAdded(this, gallery_info.pref_id));
7072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return gallery_info.pref_id;
7092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)MediaGalleryPrefId MediaGalleriesPreferences::AddGalleryByPath(
7122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::FilePath& path) {
7132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MediaGalleryPrefInfo gallery_info;
7142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (LookUpGalleryByPath(path, &gallery_info) &&
7152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gallery_info.type != MediaGalleryPrefInfo::kBlackListed) {
7162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return gallery_info.pref_id;
7172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
7182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return AddGalleryInternal(gallery_info.device_id,
7192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            gallery_info.display_name,
7202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            gallery_info.path,
7212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            true /*user added*/,
7222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            gallery_info.volume_label,
7232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            gallery_info.vendor_name,
7242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            gallery_info.model_name,
7252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            gallery_info.total_size_in_bytes,
7262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            gallery_info.last_attach_time,
7272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            gallery_info.volume_metadata_valid,
7282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            gallery_info.prefs_version);
7292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void MediaGalleriesPreferences::ForgetGalleryById(MediaGalleryPrefId pref_id) {
7322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PrefService* prefs = profile_->GetPrefs();
733c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<ListPrefUpdate> update(new ListPrefUpdate(
734c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      prefs, prefs::kMediaGalleriesRememberedGalleries));
735c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ListValue* list = update->Get();
7362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!ContainsKey(known_galleries_, pref_id))
7382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
7392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (ListValue::iterator iter = list->begin(); iter != list->end(); ++iter) {
7412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DictionaryValue* dict;
7422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MediaGalleryPrefId iter_id;
7432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if ((*iter)->GetAsDictionary(&dict) && GetPrefId(*dict, &iter_id) &&
7442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        pref_id == iter_id) {
745868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      RemoveGalleryPermissionsFromPrefs(pref_id);
7462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      MediaGalleryPrefInfo::Type type;
7472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (GetType(*dict, &type) &&
7482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          type == MediaGalleryPrefInfo::kAutoDetected) {
7492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        dict->SetString(kMediaGalleriesTypeKey,
7502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                        kMediaGalleriesTypeBlackListedValue);
7512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      } else {
7522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        list->Erase(iter, NULL);
7532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }
754c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      update.reset(NULL);  // commits the update.
755c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
756d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      InitFromPrefs();
757d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      FOR_EACH_OBSERVER(GalleryChangeObserver,
758d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                        gallery_change_observers_,
759d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                        OnGalleryRemoved(this, pref_id));
7602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return;
7612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
7622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
7632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)MediaGalleryPrefIdSet MediaGalleriesPreferences::GalleriesForExtension(
7662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const extensions::Extension& extension) const {
7672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MediaGalleryPrefIdSet result;
7682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (HasAutoDetectedGalleryPermission(extension)) {
7702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (MediaGalleriesPrefInfoMap::const_iterator it =
7712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)             known_galleries_.begin(); it != known_galleries_.end(); ++it) {
7722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (it->second.type == MediaGalleryPrefInfo::kAutoDetected)
7732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        result.insert(it->second.pref_id);
7742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
7752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
7762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<MediaGalleryPermission> stored_permissions =
778868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      GetGalleryPermissionsFromPrefs(extension.id());
7792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (std::vector<MediaGalleryPermission>::const_iterator it =
7802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)           stored_permissions.begin(); it != stored_permissions.end(); ++it) {
7812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!it->has_permission) {
7822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      result.erase(it->pref_id);
7832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
7842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      MediaGalleriesPrefInfoMap::const_iterator gallery =
7852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          known_galleries_.find(it->pref_id);
7862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      DCHECK(gallery != known_galleries_.end());
7872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (gallery->second.type != MediaGalleryPrefInfo::kBlackListed) {
7882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        result.insert(it->pref_id);
7892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      } else {
7902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        NOTREACHED() << gallery->second.device_id;
7912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }
7922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
7932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
7942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return result;
7952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void MediaGalleriesPreferences::SetGalleryPermissionForExtension(
7982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const extensions::Extension& extension,
7992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MediaGalleryPrefId pref_id,
8002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool has_permission) {
8012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The gallery may not exist anymore if the user opened a second config
8022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // surface concurrently and removed it. Drop the permission update if so.
8032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MediaGalleriesPrefInfoMap::const_iterator gallery_info =
8042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      known_galleries_.find(pref_id);
8052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (gallery_info == known_galleries_.end())
8062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
8072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
808d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  bool default_permission = false;
809d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (gallery_info->second.type == MediaGalleryPrefInfo::kAutoDetected)
810d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    default_permission = HasAutoDetectedGalleryPermission(extension);
811d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // When the permission matches the default, we don't need to remember it.
812d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (has_permission == default_permission) {
813d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    if (!UnsetGalleryPermissionInPrefs(extension.id(), pref_id))
814d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      // If permission wasn't set, assume nothing has changed.
8152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return;
8162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
817d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    if (!SetGalleryPermissionInPrefs(extension.id(), pref_id, has_permission))
818d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      return;
8192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
820d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (has_permission)
821d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    FOR_EACH_OBSERVER(GalleryChangeObserver,
822d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                      gallery_change_observers_,
823d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                      OnPermissionAdded(this, extension.id(), pref_id));
824d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  else
825d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    FOR_EACH_OBSERVER(GalleryChangeObserver,
826d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                      gallery_change_observers_,
827d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                      OnPermissionRemoved(this, extension.id(), pref_id));
8282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
8292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void MediaGalleriesPreferences::Shutdown() {
831c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  weak_factory_.InvalidateWeakPtrs();
8322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  profile_ = NULL;
8332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
8342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
8362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool MediaGalleriesPreferences::APIHasBeenUsed(Profile* profile) {
8372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MediaGalleryPrefId current_id =
8382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      profile->GetPrefs()->GetUint64(prefs::kMediaGalleriesUniqueId);
8392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return current_id != kInvalidMediaGalleryPrefId + 1;
8402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
8412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
8437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid MediaGalleriesPreferences::RegisterProfilePrefs(
844c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    user_prefs::PrefRegistrySyncable* registry) {
8452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  registry->RegisterListPref(prefs::kMediaGalleriesRememberedGalleries,
846c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                             user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
847c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  registry->RegisterUint64Pref(
848c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      prefs::kMediaGalleriesUniqueId,
849c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      kInvalidMediaGalleryPrefId + 1,
850c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
8512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
8522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
853d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)bool MediaGalleriesPreferences::SetGalleryPermissionInPrefs(
854868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const std::string& extension_id,
855868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    MediaGalleryPrefId gallery_id,
856868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    bool has_access) {
857868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ExtensionPrefs::ScopedListUpdate update(GetExtensionPrefs(),
858868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                          extension_id,
859868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                          kMediaGalleriesPermissions);
860868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ListValue* permissions = update.Get();
861868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!permissions) {
862868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    permissions = update.Create();
863868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  } else {
864868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    // If the gallery is already in the list, update the permission...
865868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    for (ListValue::iterator iter = permissions->begin();
866868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)         iter != permissions->end(); ++iter) {
867868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      DictionaryValue* dict = NULL;
868868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      if (!(*iter)->GetAsDictionary(&dict))
869868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        continue;
870868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      MediaGalleryPermission perm;
871868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      if (!GetMediaGalleryPermissionFromDictionary(dict, &perm))
872868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        continue;
873868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      if (perm.pref_id == gallery_id) {
874d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        if (has_access != perm.has_permission) {
875d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)          dict->SetBoolean(kMediaGalleryHasPermissionKey, has_access);
876d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)          return true;
877d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        } else {
878d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)          return false;
879d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        }
880868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      }
881868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    }
882868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
883868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // ...Otherwise, add a new entry for the gallery.
884868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DictionaryValue* dict = new DictionaryValue;
885868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  dict->SetString(kMediaGalleryIdKey, base::Uint64ToString(gallery_id));
886868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  dict->SetBoolean(kMediaGalleryHasPermissionKey, has_access);
887868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  permissions->Append(dict);
888d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  return true;
889868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
890868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
891d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)bool MediaGalleriesPreferences::UnsetGalleryPermissionInPrefs(
892868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const std::string& extension_id,
893868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    MediaGalleryPrefId gallery_id) {
894868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ExtensionPrefs::ScopedListUpdate update(GetExtensionPrefs(),
895868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                          extension_id,
896868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                          kMediaGalleriesPermissions);
897868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ListValue* permissions = update.Get();
898868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!permissions)
899d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    return false;
900868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
901868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  for (ListValue::iterator iter = permissions->begin();
902868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)       iter != permissions->end(); ++iter) {
903868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const DictionaryValue* dict = NULL;
904868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (!(*iter)->GetAsDictionary(&dict))
905868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      continue;
906868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    MediaGalleryPermission perm;
907868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (!GetMediaGalleryPermissionFromDictionary(dict, &perm))
908868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      continue;
909868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (perm.pref_id == gallery_id) {
910868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      permissions->Erase(iter, NULL);
911d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      return true;
912868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    }
913868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
914d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  return false;
915868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
916868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
917868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)std::vector<MediaGalleryPermission>
918868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)MediaGalleriesPreferences::GetGalleryPermissionsFromPrefs(
919868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const std::string& extension_id) const {
920868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  std::vector<MediaGalleryPermission> result;
921868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const ListValue* permissions;
922868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!GetExtensionPrefs()->ReadPrefAsList(extension_id,
923868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                           kMediaGalleriesPermissions,
924868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                           &permissions)) {
925868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return result;
926868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
927868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
928868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  for (ListValue::const_iterator iter = permissions->begin();
929868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)       iter != permissions->end(); ++iter) {
930868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    DictionaryValue* dict = NULL;
931868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (!(*iter)->GetAsDictionary(&dict))
932868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      continue;
933868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    MediaGalleryPermission perm;
934868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (!GetMediaGalleryPermissionFromDictionary(dict, &perm))
935868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      continue;
936868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    result.push_back(perm);
937868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
938868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
939868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return result;
940868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
941868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
942868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void MediaGalleriesPreferences::RemoveGalleryPermissionsFromPrefs(
943868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    MediaGalleryPrefId gallery_id) {
944868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ExtensionPrefs* prefs = GetExtensionPrefs();
945868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const DictionaryValue* extensions =
9463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      prefs->pref_service()->GetDictionary(prefs::kExtensionsPref);
947868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!extensions)
948868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return;
949868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
950868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  for (DictionaryValue::Iterator iter(*extensions); !iter.IsAtEnd();
951868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)       iter.Advance()) {
952868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (!extensions::Extension::IdIsValid(iter.key())) {
953868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      NOTREACHED();
954868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      continue;
955868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    }
956868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    UnsetGalleryPermissionInPrefs(iter.key(), gallery_id);
957868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
958868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
959868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
960868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)ExtensionPrefs* MediaGalleriesPreferences::GetExtensionPrefs() const {
961868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (extension_prefs_for_testing_)
962868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return extension_prefs_for_testing_;
963868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return extensions::ExtensionPrefs::Get(profile_);
964868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
965868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
966868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void MediaGalleriesPreferences::SetExtensionPrefsForTesting(
967868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    extensions::ExtensionPrefs* extension_prefs) {
968868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  extension_prefs_for_testing_ = extension_prefs;
9692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
970