media_galleries_preferences.cc revision 90dce4d38c5ff5333bea97d859d4e484e27edf0c
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)
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/path_service.h"
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/prefs/pref_service.h"
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/stl_util.h"
10c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/string16.h"
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_number_conversions.h"
12c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/utf_string_conversions.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/values.h"
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/browser_process.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/extensions/api/media_galleries_private/gallery_watch_state_tracker.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_prefs.h"
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/extensions/extension_service.h"
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/extensions/extension_system.h"
20c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/media_galleries/fileapi/itunes_finder.h"
2190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/browser/media_galleries/fileapi/picasa/picasa_finder.h"
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/media_galleries/media_file_system_registry.h"
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/prefs/scoped_user_pref_update.h"
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/profiles/profile.h"
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/storage_monitor/media_storage_util.h"
26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/storage_monitor/storage_monitor.h"
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/common/chrome_paths.h"
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/common/extensions/extension.h"
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/common/extensions/permissions/api_permission.h"
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/common/extensions/permissions/media_galleries_permission.h"
3190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/common/extensions/permissions/permissions_data.h"
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/common/pref_names.h"
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "components/user_prefs/pref_registry_syncable.h"
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace chrome {
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace {
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kMediaGalleriesDeviceIdKey[] = "deviceId";
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kMediaGalleriesDisplayNameKey[] = "displayName";
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kMediaGalleriesPathKey[] = "path";
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kMediaGalleriesPrefIdKey[] = "prefId";
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kMediaGalleriesTypeKey[] = "type";
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kMediaGalleriesVolumeLabelKey[] = "volumeLabel";
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kMediaGalleriesVendorNameKey[] = "vendorName";
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kMediaGalleriesModelNameKey[] = "modelName";
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kMediaGalleriesSizeKey[] = "totalSize";
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kMediaGalleriesLastAttachTimeKey[] = "lastAttachTime";
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kMediaGalleriesPrefsVersionKey[] = "preferencesVersion";
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kMediaGalleriesTypeAutoDetectedValue[] = "autoDetected";
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kMediaGalleriesTypeUserAddedValue[] = "userAdded";
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kMediaGalleriesTypeBlackListedValue[] = "blackListed";
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const char kITunesGalleryName[] = "iTunes";
5690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)const char kPicasaGalleryName[] = "Picasa";
57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool GetPrefId(const DictionaryValue& dict, MediaGalleryPrefId* value) {
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string string_id;
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!dict.GetString(kMediaGalleriesPrefIdKey, &string_id) ||
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      !base::StringToUint64(string_id, value)) {
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool GetType(const DictionaryValue& dict, MediaGalleryPrefInfo::Type* type) {
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string string_type;
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!dict.GetString(kMediaGalleriesTypeKey, &string_type))
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (string_type == kMediaGalleriesTypeAutoDetectedValue) {
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    *type = MediaGalleryPrefInfo::kAutoDetected;
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return true;
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (string_type == kMediaGalleriesTypeUserAddedValue) {
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    *type = MediaGalleryPrefInfo::kUserAdded;
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return true;
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (string_type == kMediaGalleriesTypeBlackListedValue) {
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    *type = MediaGalleryPrefInfo::kBlackListed;
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return true;
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return false;
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool PopulateGalleryPrefInfoFromDictionary(
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const DictionaryValue& dict, MediaGalleryPrefInfo* out_gallery_info) {
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MediaGalleryPrefId pref_id;
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  string16 display_name;
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string device_id;
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath::StringType path;
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MediaGalleryPrefInfo::Type type = MediaGalleryPrefInfo::kAutoDetected;
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  string16 volume_label;
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  string16 vendor_name;
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  string16 model_name;
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  double total_size_in_bytes = 0.0;
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  double last_attach_time = 0.0;
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool volume_metadata_valid = false;
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int prefs_version = 0;
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!GetPrefId(dict, &pref_id) ||
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      !dict.GetString(kMediaGalleriesDeviceIdKey, &device_id) ||
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      !dict.GetString(kMediaGalleriesPathKey, &path) ||
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      !GetType(dict, &type)) {
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  dict.GetString(kMediaGalleriesDisplayNameKey, &display_name);
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  dict.GetInteger(kMediaGalleriesPrefsVersionKey, &prefs_version);
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (dict.GetString(kMediaGalleriesVolumeLabelKey, &volume_label) &&
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      dict.GetString(kMediaGalleriesVendorNameKey, &vendor_name) &&
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      dict.GetString(kMediaGalleriesModelNameKey, &model_name) &&
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      dict.GetDouble(kMediaGalleriesSizeKey, &total_size_in_bytes) &&
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      dict.GetDouble(kMediaGalleriesLastAttachTimeKey, &last_attach_time)) {
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    volume_metadata_valid = true;
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  out_gallery_info->pref_id = pref_id;
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  out_gallery_info->display_name = display_name;
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  out_gallery_info->device_id = device_id;
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  out_gallery_info->path = base::FilePath(path);
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  out_gallery_info->type = type;
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  out_gallery_info->volume_label = volume_label;
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  out_gallery_info->vendor_name = vendor_name;
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  out_gallery_info->model_name = model_name;
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  out_gallery_info->total_size_in_bytes = total_size_in_bytes;
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  out_gallery_info->last_attach_time =
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Time::FromInternalValue(last_attach_time);
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  out_gallery_info->volume_metadata_valid = volume_metadata_valid;
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  out_gallery_info->prefs_version = prefs_version;
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DictionaryValue* CreateGalleryPrefInfoDictionary(
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const MediaGalleryPrefInfo& gallery) {
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DictionaryValue* dict = new DictionaryValue();
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  dict->SetString(kMediaGalleriesPrefIdKey,
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                  base::Uint64ToString(gallery.pref_id));
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!gallery.volume_metadata_valid)
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    dict->SetString(kMediaGalleriesDisplayNameKey, gallery.display_name);
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  dict->SetString(kMediaGalleriesDeviceIdKey, gallery.device_id);
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  dict->SetString(kMediaGalleriesPathKey, gallery.path.value());
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const char* type = NULL;
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  switch (gallery.type) {
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case MediaGalleryPrefInfo::kAutoDetected:
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      type = kMediaGalleriesTypeAutoDetectedValue;
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case MediaGalleryPrefInfo::kUserAdded:
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      type = kMediaGalleriesTypeUserAddedValue;
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case MediaGalleryPrefInfo::kBlackListed:
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      type = kMediaGalleriesTypeBlackListedValue;
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    default:
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      NOTREACHED();
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  dict->SetString(kMediaGalleriesTypeKey, type);
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (gallery.volume_metadata_valid) {
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    dict->SetString(kMediaGalleriesVolumeLabelKey, gallery.volume_label);
1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    dict->SetString(kMediaGalleriesVendorNameKey, gallery.vendor_name);
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    dict->SetString(kMediaGalleriesModelNameKey, gallery.model_name);
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    dict->SetDouble(kMediaGalleriesSizeKey, gallery.total_size_in_bytes);
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    dict->SetDouble(kMediaGalleriesLastAttachTimeKey,
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    gallery.last_attach_time.ToInternalValue());
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Version 0 of the prefs format was that the display_name was always
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // used to show the user-visible name of the gallery. Version 1 means
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // that there is an optional display_name, and when it is present, it
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // overrides the name that would be built from the volume metadata, path,
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // or whatever other data. So if we see a display_name with version 0, it
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // means it may be overwritten simply by getting new volume metadata.
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // A display_name with version 1 should not be overwritten.
1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  dict->SetInteger(kMediaGalleriesPrefsVersionKey, gallery.prefs_version);
1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return dict;
1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool HasAutoDetectedGalleryPermission(const extensions::Extension& extension) {
1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  extensions::MediaGalleriesPermission::CheckParam param(
1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      extensions::MediaGalleriesPermission::kAllAutoDetectedPermission);
19090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  return extensions::PermissionsData::CheckAPIPermissionWithParam(
19190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      &extension, extensions::APIPermission::kMediaGalleries, &param);
1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)MediaGalleryPrefInfo::MediaGalleryPrefInfo()
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : pref_id(kInvalidMediaGalleryPrefId),
1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      type(kInvalidType),
1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      total_size_in_bytes(0),
2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      volume_metadata_valid(false),
2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      prefs_version(0) {
2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)MediaGalleryPrefInfo::~MediaGalleryPrefInfo() {}
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::FilePath MediaGalleryPrefInfo::AbsolutePath() const {
2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath base_path = MediaStorageUtil::FindDevicePathById(device_id);
208c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(!path.IsAbsolute());
2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return base_path.empty() ? base_path : base_path.Append(path);
2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)MediaGalleriesPreferences::GalleryChangeObserver::~GalleryChangeObserver() {}
2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)MediaGalleriesPreferences::MediaGalleriesPreferences(Profile* profile)
215c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : weak_factory_(this),
216c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      profile_(profile) {
2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  AddDefaultGalleriesIfFreshProfile();
218c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
21990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // TODO(vandebo) Turn this back on when the iTunes code is ready.
22090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Temporarily turned off because it adds an extra user-visible entry to the
22190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // preferences that does not quite work.
22290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#if 0
223c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Look for optional default galleries every time.
224c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  itunes::ITunesFinder::FindITunesLibrary(
225c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      base::Bind(&MediaGalleriesPreferences::OnITunesDeviceID,
226c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 weak_factory_.GetWeakPtr()));
22790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#endif
22890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
22990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // TODO(tommycli): Turn on when Picasa code is ready.
23090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#if 0
23190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  picasa::PicasaFinder::FindPicasaDatabaseOnUIThread(
23290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      base::Bind(&MediaGalleriesPreferences::OnPicasaDeviceID,
23390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                 weak_factory_.GetWeakPtr()));
23490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#endif
235c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  InitFromPrefs(false /*no notification*/);
237c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
238c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  StorageMonitor* monitor = StorageMonitor::GetInstance();
239c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (monitor)
240c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    monitor->AddObserver(this);
2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
243c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)MediaGalleriesPreferences::~MediaGalleriesPreferences() {
244c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  StorageMonitor* monitor = StorageMonitor::GetInstance();
245c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (monitor)
246c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    monitor->RemoveObserver(this);
247c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void MediaGalleriesPreferences::AddDefaultGalleriesIfFreshProfile() {
2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Only add defaults the first time.
2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (APIHasBeenUsed(profile_))
2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Fresh profile case.
2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const int kDirectoryKeys[] = {
2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DIR_USER_MUSIC,
2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DIR_USER_PICTURES,
2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DIR_USER_VIDEOS,
2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (size_t i = 0; i < arraysize(kDirectoryKeys); ++i) {
2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::FilePath path;
2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!PathService::Get(kDirectoryKeys[i], &path))
2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      continue;
2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::FilePath relative_path;
2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    StorageInfo info;
2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (MediaStorageUtil::GetDeviceInfoFromPath(path, &info, &relative_path)) {
2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // TODO(gbillock): Add in the volume metadata here when available.
27090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      AddGalleryWithName(info.device_id(), info.name(), relative_path,
2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         false /*user added*/);
2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
276c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void MediaGalleriesPreferences::OnITunesDeviceID(const std::string& device_id) {
277c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(!device_id.empty());
278c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  AddGalleryWithName(device_id, ASCIIToUTF16(kITunesGalleryName),
279c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                     base::FilePath(), false /*not user added*/);
280c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
281c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
28290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void MediaGalleriesPreferences::OnPicasaDeviceID(const std::string& device_id) {
28390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // TODO(tommycli): Implement support for location moves.
28490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  DCHECK(!device_id.empty());
28590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  AddGalleryWithName(device_id, ASCIIToUTF16(kPicasaGalleryName),
28690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                     base::FilePath(), false /*not user added*/);
28790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
28890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void MediaGalleriesPreferences::InitFromPrefs(bool notify_observers) {
2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  known_galleries_.clear();
2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  device_map_.clear();
2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PrefService* prefs = profile_->GetPrefs();
2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const ListValue* list = prefs->GetList(
2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      prefs::kMediaGalleriesRememberedGalleries);
2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (list) {
2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (ListValue::const_iterator it = list->begin();
2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)         it != list->end(); ++it) {
2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const DictionaryValue* dict = NULL;
3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (!(*it)->GetAsDictionary(&dict))
3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        continue;
3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      MediaGalleryPrefInfo gallery_info;
3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (!PopulateGalleryPrefInfoFromDictionary(*dict, &gallery_info))
3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        continue;
3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      known_galleries_[gallery_info.pref_id] = gallery_info;
3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      device_map_[gallery_info.device_id].insert(gallery_info.pref_id);
3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (notify_observers)
312c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    NotifyChangeObservers(std::string());
3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void MediaGalleriesPreferences::NotifyChangeObservers(
3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& extension_id) {
3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FOR_EACH_OBSERVER(GalleryChangeObserver,
3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    gallery_change_observers_,
3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    OnGalleryChanged(this, extension_id));
3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void MediaGalleriesPreferences::AddGalleryChangeObserver(
3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    GalleryChangeObserver* observer) {
3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gallery_change_observers_.AddObserver(observer);
3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void MediaGalleriesPreferences::RemoveGalleryChangeObserver(
3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    GalleryChangeObserver* observer) {
3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gallery_change_observers_.RemoveObserver(observer);
3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void MediaGalleriesPreferences::OnRemovableStorageAttached(
3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const StorageInfo& info) {
33490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (!StorageInfo::IsMediaDevice(info.device_id()))
3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
33790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (info.name().empty()) {
33890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    AddGallery(info.device_id(),
33990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)               base::FilePath(),
3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)               false /*not user added*/,
34190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)               info.storage_label(),
34290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)               info.vendor_name(),
34390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)               info.model_name(),
34490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)               info.total_size_in_bytes(),
3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)               base::Time::Now());
3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
347b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    // TODO(gbillock): get rid of this code path.
34890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    AddGalleryWithName(info.device_id(), info.name(), base::FilePath(), false);
3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool MediaGalleriesPreferences::LookUpGalleryByPath(
3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::FilePath& path,
3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MediaGalleryPrefInfo* gallery_info) const {
3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  StorageInfo info;
3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath relative_path;
3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!MediaStorageUtil::GetDeviceInfoFromPath(path, &info, &relative_path)) {
3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (gallery_info)
3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      *gallery_info = MediaGalleryPrefInfo();
3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  relative_path = relative_path.NormalizePathSeparators();
3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MediaGalleryPrefIdSet galleries_on_device =
36590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      LookUpGalleriesByDeviceId(info.device_id());
3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (MediaGalleryPrefIdSet::const_iterator it = galleries_on_device.begin();
3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       it != galleries_on_device.end();
3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       ++it) {
3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const MediaGalleryPrefInfo& gallery = known_galleries_.find(*it)->second;
3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (gallery.path != relative_path)
3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      continue;
3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (gallery_info)
3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      *gallery_info = gallery;
3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return true;
3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // This method is called by controller::FilesSelected when the user
3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // adds a new gallery. Control reaches here when the selected gallery is
3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // on a volume we know about, but have no gallery already for. Returns
3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // hypothetical data to the caller about what the prefs will look like
3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // if the gallery is added.
3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // TODO(gbillock): split this out into another function so it doesn't
3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // conflate LookUp.
3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (gallery_info) {
3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gallery_info->pref_id = kInvalidMediaGalleryPrefId;
38790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    gallery_info->display_name = info.name();
38890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    gallery_info->device_id = info.device_id();
3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gallery_info->path = relative_path;
3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gallery_info->type = MediaGalleryPrefInfo::kUserAdded;
3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // TODO(gbillock): Need to add volume metadata here from |info|.
3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return false;
3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)MediaGalleryPrefIdSet MediaGalleriesPreferences::LookUpGalleriesByDeviceId(
3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& device_id) const {
3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DeviceIdPrefIdsMap::const_iterator found = device_map_.find(device_id);
3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (found == device_map_.end())
4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return MediaGalleryPrefIdSet();
4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return found->second;
4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::FilePath MediaGalleriesPreferences::LookUpGalleryPathForExtension(
4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MediaGalleryPrefId gallery_id,
4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const extensions::Extension* extension,
4072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool include_unpermitted_galleries) {
4082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(extension);
4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!include_unpermitted_galleries &&
4102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      !ContainsKey(GalleriesForExtension(*extension), gallery_id))
4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return base::FilePath();
4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MediaGalleriesPrefInfoMap::const_iterator it =
4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      known_galleries_.find(gallery_id);
4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (it == known_galleries_.end())
4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return base::FilePath();
4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return MediaStorageUtil::FindDevicePathById(it->second.device_id);
4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)MediaGalleryPrefId MediaGalleriesPreferences::AddGallery(
4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& device_id,
4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::FilePath& relative_path, bool user_added,
4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const string16& volume_label, const string16& vendor_name,
4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const string16& model_name, uint64 total_size_in_bytes,
4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::Time last_attach_time) {
4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return AddGalleryInternal(device_id, string16(), relative_path, user_added,
4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            volume_label, vendor_name, model_name,
4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            total_size_in_bytes, last_attach_time, true, 1);
4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)MediaGalleryPrefId MediaGalleriesPreferences::AddGalleryWithName(
4322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& device_id, const string16& display_name,
4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::FilePath& relative_path, bool user_added) {
4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return AddGalleryInternal(device_id, display_name, relative_path, user_added,
4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            string16(), string16(), string16(),
4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            0, base::Time(), false, 1);
4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)MediaGalleryPrefId MediaGalleriesPreferences::AddGalleryInternal(
4402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& device_id, const string16& display_name,
4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::FilePath& relative_path, bool user_added,
4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const string16& volume_label, const string16& vendor_name,
4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const string16& model_name, uint64 total_size_in_bytes,
4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::Time last_attach_time,
4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool volume_metadata_valid,
4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int prefs_version) {
4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath normalized_relative_path =
4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      relative_path.NormalizePathSeparators();
4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MediaGalleryPrefIdSet galleries_on_device =
4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LookUpGalleriesByDeviceId(device_id);
4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (MediaGalleryPrefIdSet::const_iterator it = galleries_on_device.begin();
4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       it != galleries_on_device.end();
4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       ++it) {
4542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const MediaGalleryPrefInfo& existing = known_galleries_.find(*it)->second;
4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (existing.path != normalized_relative_path)
4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      continue;
4572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool update_gallery_type =
4592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        user_added && (existing.type == MediaGalleryPrefInfo::kBlackListed);
46090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // TODO(gbillock): Once we have all updates adding the device metadata,
46190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // we'll change this to always update the gallery name if we have device
46290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // metadata.
46390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // Status quo: In M27 and M28, galleries added manually use version 0,
46490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // and galleries added automatically (including default galleries) use
46590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // version 1. The name override is used by default galleries as well
46690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // as all device attach events.
4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool update_gallery_name = existing.display_name != display_name;
4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool update_gallery_metadata = volume_metadata_valid &&
4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        ((existing.volume_label != volume_label) ||
4702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)         (existing.vendor_name != vendor_name) ||
4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)         (existing.model_name != model_name) ||
4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)         (existing.total_size_in_bytes != total_size_in_bytes) ||
4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)         (existing.last_attach_time != last_attach_time));
4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!update_gallery_name && !update_gallery_type &&
4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        !update_gallery_metadata)
4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return *it;
4782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    PrefService* prefs = profile_->GetPrefs();
4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<ListPrefUpdate> update(
4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        new ListPrefUpdate(prefs, prefs::kMediaGalleriesRememberedGalleries));
4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ListValue* list = update->Get();
4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (ListValue::const_iterator list_iter = list->begin();
4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)         list_iter != list->end();
4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)         ++list_iter) {
4872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      DictionaryValue* dict;
4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      MediaGalleryPrefId iter_id;
4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if ((*list_iter)->GetAsDictionary(&dict) &&
4902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          GetPrefId(*dict, &iter_id) &&
4912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          *it == iter_id) {
4922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        if (update_gallery_type) {
4932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          dict->SetString(kMediaGalleriesTypeKey,
4942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          kMediaGalleriesTypeAutoDetectedValue);
4952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        }
4962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        if (update_gallery_name)
4972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          dict->SetString(kMediaGalleriesDisplayNameKey, display_name);
4982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        if (update_gallery_metadata) {
4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          dict->SetString(kMediaGalleriesVolumeLabelKey, volume_label);
5002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          dict->SetString(kMediaGalleriesVendorNameKey, vendor_name);
5012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          dict->SetString(kMediaGalleriesModelNameKey, model_name);
5022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          dict->SetDouble(kMediaGalleriesSizeKey, total_size_in_bytes);
5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          dict->SetDouble(kMediaGalleriesLastAttachTimeKey,
5042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          last_attach_time.ToInternalValue());
5052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        }
5062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        dict->SetInteger(kMediaGalleriesPrefsVersionKey, prefs_version);
5072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        break;
5082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }
5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
5102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Commits the prefs update.
5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    update.reset();
5132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (update_gallery_name || update_gallery_metadata || update_gallery_type)
5152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      InitFromPrefs(true /* notify observers */);
5162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return *it;
5172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PrefService* prefs = profile_->GetPrefs();
5202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MediaGalleryPrefInfo gallery_info;
5222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gallery_info.pref_id = prefs->GetUint64(prefs::kMediaGalleriesUniqueId);
5232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  prefs->SetUint64(prefs::kMediaGalleriesUniqueId, gallery_info.pref_id + 1);
5242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gallery_info.display_name = display_name;
5252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gallery_info.device_id = device_id;
5262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gallery_info.path = normalized_relative_path;
5272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gallery_info.type = MediaGalleryPrefInfo::kAutoDetected;
5282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (user_added)
5292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gallery_info.type = MediaGalleryPrefInfo::kUserAdded;
5302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (volume_metadata_valid) {
5312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gallery_info.volume_label = volume_label;
5322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gallery_info.vendor_name = vendor_name;
5332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gallery_info.model_name = model_name;
5342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gallery_info.total_size_in_bytes = total_size_in_bytes;
5352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gallery_info.last_attach_time = last_attach_time;
5362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gallery_info.volume_metadata_valid = volume_metadata_valid;
5382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gallery_info.prefs_version = prefs_version;
5392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
5412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ListPrefUpdate update(prefs, prefs::kMediaGalleriesRememberedGalleries);
5422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ListValue* list = update.Get();
5432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    list->Append(CreateGalleryPrefInfoDictionary(gallery_info));
5442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  InitFromPrefs(true /* notify observers */);
5462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return gallery_info.pref_id;
5482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)MediaGalleryPrefId MediaGalleriesPreferences::AddGalleryByPath(
5512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::FilePath& path) {
5522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MediaGalleryPrefInfo gallery_info;
5532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (LookUpGalleryByPath(path, &gallery_info) &&
5542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gallery_info.type != MediaGalleryPrefInfo::kBlackListed) {
5552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return gallery_info.pref_id;
5562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return AddGalleryInternal(gallery_info.device_id,
5582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            gallery_info.display_name,
5592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            gallery_info.path,
5602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            true /*user added*/,
5612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            gallery_info.volume_label,
5622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            gallery_info.vendor_name,
5632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            gallery_info.model_name,
5642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            gallery_info.total_size_in_bytes,
5652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            gallery_info.last_attach_time,
5662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            gallery_info.volume_metadata_valid,
5672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            gallery_info.prefs_version);
5682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void MediaGalleriesPreferences::ForgetGalleryById(MediaGalleryPrefId pref_id) {
5712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PrefService* prefs = profile_->GetPrefs();
572c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<ListPrefUpdate> update(new ListPrefUpdate(
573c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      prefs, prefs::kMediaGalleriesRememberedGalleries));
574c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ListValue* list = update->Get();
5752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!ContainsKey(known_galleries_, pref_id))
5772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
5782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (ListValue::iterator iter = list->begin(); iter != list->end(); ++iter) {
5802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DictionaryValue* dict;
5812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MediaGalleryPrefId iter_id;
5822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if ((*iter)->GetAsDictionary(&dict) && GetPrefId(*dict, &iter_id) &&
5832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        pref_id == iter_id) {
584c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      extensions::MediaGalleriesPrivateAPI::RemoveMediaGalleryPermissions(
585c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          GetExtensionPrefs(), pref_id);
5862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      MediaGalleryPrefInfo::Type type;
5872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (GetType(*dict, &type) &&
5882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          type == MediaGalleryPrefInfo::kAutoDetected) {
5892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        dict->SetString(kMediaGalleriesTypeKey,
5902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                        kMediaGalleriesTypeBlackListedValue);
5912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      } else {
5922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        list->Erase(iter, NULL);
5932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }
594c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      update.reset(NULL);  // commits the update.
595c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
5962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      InitFromPrefs(true /* notify observers */);
5972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return;
5982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
5992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)MediaGalleryPrefIdSet MediaGalleriesPreferences::GalleriesForExtension(
6032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const extensions::Extension& extension) const {
6042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MediaGalleryPrefIdSet result;
6052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (HasAutoDetectedGalleryPermission(extension)) {
6072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (MediaGalleriesPrefInfoMap::const_iterator it =
6082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)             known_galleries_.begin(); it != known_galleries_.end(); ++it) {
6092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (it->second.type == MediaGalleryPrefInfo::kAutoDetected)
6102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        result.insert(it->second.pref_id);
6112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
6122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<MediaGalleryPermission> stored_permissions =
615c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      extensions::MediaGalleriesPrivateAPI::GetMediaGalleryPermissions(
616c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          GetExtensionPrefs(), extension.id());
6172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (std::vector<MediaGalleryPermission>::const_iterator it =
6182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)           stored_permissions.begin(); it != stored_permissions.end(); ++it) {
6192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!it->has_permission) {
6202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      result.erase(it->pref_id);
6212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
6222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      MediaGalleriesPrefInfoMap::const_iterator gallery =
6232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          known_galleries_.find(it->pref_id);
6242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      DCHECK(gallery != known_galleries_.end());
6252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (gallery->second.type != MediaGalleryPrefInfo::kBlackListed) {
6262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        result.insert(it->pref_id);
6272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      } else {
6282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        NOTREACHED() << gallery->second.device_id;
6292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }
6302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
6312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return result;
6332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void MediaGalleriesPreferences::SetGalleryPermissionForExtension(
6362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const extensions::Extension& extension,
6372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MediaGalleryPrefId pref_id,
6382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool has_permission) {
6392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The gallery may not exist anymore if the user opened a second config
6402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // surface concurrently and removed it. Drop the permission update if so.
6412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MediaGalleriesPrefInfoMap::const_iterator gallery_info =
6422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      known_galleries_.find(pref_id);
6432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (gallery_info == known_galleries_.end())
6442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
6452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(ENABLE_EXTENSIONS)
6472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  extensions::GalleryWatchStateTracker* state_tracker =
6482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      extensions::GalleryWatchStateTracker::GetForProfile(profile_);
6492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
6502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool all_permission = HasAutoDetectedGalleryPermission(extension);
6512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (has_permission && all_permission) {
6522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (gallery_info->second.type == MediaGalleryPrefInfo::kAutoDetected) {
653c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      extensions::MediaGalleriesPrivateAPI::UnsetMediaGalleryPermission(
654c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          GetExtensionPrefs(), extension.id(), pref_id);
6552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      NotifyChangeObservers(extension.id());
6562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(ENABLE_EXTENSIONS)
6572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (state_tracker) {
6582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        state_tracker->OnGalleryPermissionChanged(extension.id(), pref_id,
6592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                  true);
6602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }
6612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
6622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return;
6632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
6642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!has_permission && !all_permission) {
667c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    extensions::MediaGalleriesPrivateAPI::UnsetMediaGalleryPermission(
668c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        GetExtensionPrefs(), extension.id(), pref_id);
6692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
670c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    extensions::MediaGalleriesPrivateAPI::SetMediaGalleryPermission(
671c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        GetExtensionPrefs(), extension.id(), pref_id, has_permission);
6722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  NotifyChangeObservers(extension.id());
6742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(ENABLE_EXTENSIONS)
6752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (state_tracker) {
6762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    state_tracker->OnGalleryPermissionChanged(extension.id(), pref_id,
6772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                              has_permission);
6782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
6802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void MediaGalleriesPreferences::Shutdown() {
683c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  weak_factory_.InvalidateWeakPtrs();
6842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  profile_ = NULL;
6852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
6882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool MediaGalleriesPreferences::APIHasBeenUsed(Profile* profile) {
6892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MediaGalleryPrefId current_id =
6902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      profile->GetPrefs()->GetUint64(prefs::kMediaGalleriesUniqueId);
6912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return current_id != kInvalidMediaGalleryPrefId + 1;
6922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
6952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void MediaGalleriesPreferences::RegisterUserPrefs(
696c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    user_prefs::PrefRegistrySyncable* registry) {
6972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  registry->RegisterListPref(prefs::kMediaGalleriesRememberedGalleries,
698c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                             user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
699c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  registry->RegisterUint64Pref(
700c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      prefs::kMediaGalleriesUniqueId,
701c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      kInvalidMediaGalleryPrefId + 1,
702c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
7032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)extensions::ExtensionPrefs*
7062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)MediaGalleriesPreferences::GetExtensionPrefs() const {
7072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ExtensionService* extension_service =
7082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      extensions::ExtensionSystem::Get(profile_)->extension_service();
7092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return extension_service->extension_prefs();
7102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace chrome
713