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)
768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "base/base_paths_posix.h"
84e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/callback.h"
9eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/i18n/time_formatting.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/path_service.h"
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/prefs/pref_service.h"
121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "base/prefs/scoped_user_pref_update.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/stl_util.h"
14868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string16.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_number_conversions.h"
16868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/values.h"
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/browser_process.h"
19c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/extensions/api/media_galleries_private/media_galleries_private_api.h"
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/extensions/extension_service.h"
214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/browser/media_galleries/fileapi/iapps_finder.h"
2258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "chrome/browser/media_galleries/fileapi/picasa_finder.h"
23effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "chrome/browser/media_galleries/imported_media_gallery_registry.h"
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/media_galleries/media_file_system_registry.h"
254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/browser/media_galleries/media_galleries_histograms.h"
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/profiles/profile.h"
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/common/chrome_paths.h"
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/common/pref_names.h"
2903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "chrome/grit/generated_resources.h"
3003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "components/crx_file/id_util.h"
31cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "components/pref_registry/pref_registry_syncable.h"
325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "components/storage_monitor/media_storage_util.h"
335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "components/storage_monitor/storage_monitor.h"
344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "content/public/browser/browser_thread.h"
35cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "extensions/browser/extension_prefs.h"
365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/browser/extension_system.h"
375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/browser/pref_names.h"
385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/common/extension_set.h"
394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "extensions/common/permissions/api_permission.h"
40effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "extensions/common/permissions/media_galleries_permission.h"
41f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/permissions/permissions_data.h"
42eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "ui/base/l10n/l10n_util.h"
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
44868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)using base::DictionaryValue;
45868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)using base::ListValue;
46868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)using extensions::ExtensionPrefs;
47a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)using storage_monitor::MediaStorageUtil;
48a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)using storage_monitor::StorageInfo;
49a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)using storage_monitor::StorageMonitor;
50868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace {
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
53868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Pref key for the list of media gallery permissions.
54868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)const char kMediaGalleriesPermissions[] = "media_galleries_permissions";
55868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Pref key for Media Gallery ID.
56868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)const char kMediaGalleryIdKey[] = "id";
57868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Pref key for Media Gallery Permission Value.
58868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)const char kMediaGalleryHasPermissionKey[] = "has_permission";
59868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kMediaGalleriesDeviceIdKey[] = "deviceId";
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kMediaGalleriesDisplayNameKey[] = "displayName";
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kMediaGalleriesPathKey[] = "path";
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kMediaGalleriesPrefIdKey[] = "prefId";
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kMediaGalleriesTypeKey[] = "type";
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kMediaGalleriesVolumeLabelKey[] = "volumeLabel";
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kMediaGalleriesVendorNameKey[] = "vendorName";
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kMediaGalleriesModelNameKey[] = "modelName";
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kMediaGalleriesSizeKey[] = "totalSize";
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kMediaGalleriesLastAttachTimeKey[] = "lastAttachTime";
705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const char kMediaGalleriesScanAudioCountKey[] = "audioCount";
715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const char kMediaGalleriesScanImageCountKey[] = "imageCount";
725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const char kMediaGalleriesScanVideoCountKey[] = "videoCount";
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kMediaGalleriesTypeAutoDetectedValue[] = "autoDetected";
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kMediaGalleriesTypeBlackListedValue[] = "blackListed";
765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const char kMediaGalleriesTypeRemovedScanValue[] = "removedScan";
775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const char kMediaGalleriesTypeScanResultValue[] = "scanResult";
785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const char kMediaGalleriesTypeUserAddedValue[] = "userAdded";
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)const char kMediaGalleriesDefaultGalleryTypeNotDefaultValue[] = "notDefault";
815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)const char kMediaGalleriesDefaultGalleryTypeMusicDefaultValue[] = "music";
825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)const char kMediaGalleriesDefaultGalleryTypePicturesDefaultValue[] = "pictures";
835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)const char kMediaGalleriesDefaultGalleryTypeVideosDefaultValue[] = "videos";
845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)const char kIPhotoGalleryName[] = "iPhoto";
86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const char kITunesGalleryName[] = "iTunes";
8790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)const char kPicasaGalleryName[] = "Picasa";
88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)const int kCurrentPrefsVersion = 3;
905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)int NumberExtensionsUsingMediaGalleries(Profile* profile) {
924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  int count = 0;
934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (!profile)
944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return count;
954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ExtensionService* extension_service =
964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      extensions::ExtensionSystem::Get(profile)->extension_service();
974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (!extension_service)
984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return count;
994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const extensions::ExtensionSet* extensions = extension_service->extensions();
1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  for (extensions::ExtensionSet::const_iterator i = extensions->begin();
1024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)       i != extensions->end(); ++i) {
10346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    const extensions::PermissionsData* permissions_data =
10446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        (*i)->permissions_data();
10546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    if (permissions_data->HasAPIPermission(
10646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)            extensions::APIPermission::kMediaGalleries) ||
10746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        permissions_data->HasAPIPermission(
10846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)            extensions::APIPermission::kMediaGalleriesPrivate)) {
1094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      count++;
1104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    }
1114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
1124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return count;
1134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
1144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool GetPrefId(const base::DictionaryValue& dict, MediaGalleryPrefId* value) {
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string string_id;
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!dict.GetString(kMediaGalleriesPrefIdKey, &string_id) ||
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      !base::StringToUint64(string_id, value)) {
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool GetType(const base::DictionaryValue& dict,
1265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)             MediaGalleryPrefInfo::Type* type) {
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string string_type;
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!dict.GetString(kMediaGalleriesTypeKey, &string_type))
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (string_type == kMediaGalleriesTypeUserAddedValue) {
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    *type = MediaGalleryPrefInfo::kUserAdded;
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return true;
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (string_type == kMediaGalleriesTypeAutoDetectedValue) {
1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    *type = MediaGalleryPrefInfo::kAutoDetected;
1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return true;
1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (string_type == kMediaGalleriesTypeBlackListedValue) {
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    *type = MediaGalleryPrefInfo::kBlackListed;
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return true;
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (string_type == kMediaGalleriesTypeScanResultValue) {
1445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    *type = MediaGalleryPrefInfo::kScanResult;
1455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return true;
1465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (string_type == kMediaGalleriesTypeRemovedScanValue) {
1485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    *type = MediaGalleryPrefInfo::kRemovedScan;
1495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return true;
1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return false;
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const char* TypeToStringValue(MediaGalleryPrefInfo::Type type) {
1565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const char* result = NULL;
1575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  switch (type) {
1585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    case MediaGalleryPrefInfo::kUserAdded:
1595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      result = kMediaGalleriesTypeUserAddedValue;
1605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      break;
1615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    case MediaGalleryPrefInfo::kAutoDetected:
1625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      result = kMediaGalleriesTypeAutoDetectedValue;
1635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      break;
1645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    case MediaGalleryPrefInfo::kBlackListed:
1655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      result = kMediaGalleriesTypeBlackListedValue;
1665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      break;
1675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    case MediaGalleryPrefInfo::kScanResult:
1685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      result = kMediaGalleriesTypeScanResultValue;
1695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      break;
1705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    case MediaGalleryPrefInfo::kRemovedScan:
1715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      result = kMediaGalleriesTypeRemovedScanValue;
1725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      break;
1735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    default:
1745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      NOTREACHED();
1755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      break;
1765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return result;
1785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)MediaGalleryPrefInfo::DefaultGalleryType GetDefaultGalleryType(
1815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const base::DictionaryValue& dict) {
1825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  std::string default_gallery_type_string;
1835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (!dict.GetString(
1845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          kMediaGalleriesDefaultGalleryTypeKey, &default_gallery_type_string))
1855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return MediaGalleryPrefInfo::kNotDefault;
1865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (default_gallery_type_string ==
1885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      kMediaGalleriesDefaultGalleryTypeMusicDefaultValue) {
1895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return MediaGalleryPrefInfo::kMusicDefault;
1905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
1915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (default_gallery_type_string ==
1925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      kMediaGalleriesDefaultGalleryTypePicturesDefaultValue) {
1935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return MediaGalleryPrefInfo::kPicturesDefault;
1945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
1955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (default_gallery_type_string ==
1965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      kMediaGalleriesDefaultGalleryTypeVideosDefaultValue) {
1975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return MediaGalleryPrefInfo::kVideosDefault;
1985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
1995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return MediaGalleryPrefInfo::kNotDefault;
2005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
2015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)const char* DefaultGalleryTypeToStringValue(
2035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    MediaGalleryPrefInfo::DefaultGalleryType default_gallery_type) {
2045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  const char* result = NULL;
2055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  switch (default_gallery_type) {
2065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    case MediaGalleryPrefInfo::kNotDefault:
2075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      result = kMediaGalleriesDefaultGalleryTypeNotDefaultValue;
2085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      break;
2095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    case MediaGalleryPrefInfo::kMusicDefault:
2105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      result = kMediaGalleriesDefaultGalleryTypeMusicDefaultValue;
2115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      break;
2125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    case MediaGalleryPrefInfo::kPicturesDefault:
2135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      result = kMediaGalleriesDefaultGalleryTypePicturesDefaultValue;
2145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      break;
2155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    case MediaGalleryPrefInfo::kVideosDefault:
2165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      result = kMediaGalleriesDefaultGalleryTypeVideosDefaultValue;
2175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      break;
2185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    default:
2195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      NOTREACHED();
2205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      break;
2215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
2225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return result;
2235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
2245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool PopulateGalleryPrefInfoFromDictionary(
2265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const base::DictionaryValue& dict, MediaGalleryPrefInfo* out_gallery_info) {
2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MediaGalleryPrefId pref_id;
228a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::string16 display_name;
2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string device_id;
2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath::StringType path;
2315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  MediaGalleryPrefInfo::Type type = MediaGalleryPrefInfo::kInvalidType;
232a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::string16 volume_label;
233a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::string16 vendor_name;
234a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::string16 model_name;
2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  double total_size_in_bytes = 0.0;
2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  double last_attach_time = 0.0;
2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool volume_metadata_valid = false;
2385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int audio_count = 0;
2395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int image_count = 0;
2405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int video_count = 0;
2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int prefs_version = 0;
2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!GetPrefId(dict, &pref_id) ||
2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      !dict.GetString(kMediaGalleriesDeviceIdKey, &device_id) ||
2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      !dict.GetString(kMediaGalleriesPathKey, &path) ||
2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      !GetType(dict, &type)) {
2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  dict.GetString(kMediaGalleriesDisplayNameKey, &display_name);
2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  dict.GetInteger(kMediaGalleriesPrefsVersionKey, &prefs_version);
2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (dict.GetString(kMediaGalleriesVolumeLabelKey, &volume_label) &&
2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      dict.GetString(kMediaGalleriesVendorNameKey, &vendor_name) &&
2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      dict.GetString(kMediaGalleriesModelNameKey, &model_name) &&
2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      dict.GetDouble(kMediaGalleriesSizeKey, &total_size_in_bytes) &&
2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      dict.GetDouble(kMediaGalleriesLastAttachTimeKey, &last_attach_time)) {
2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    volume_metadata_valid = true;
2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (dict.GetInteger(kMediaGalleriesScanAudioCountKey, &audio_count) &&
2625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      dict.GetInteger(kMediaGalleriesScanImageCountKey, &image_count) &&
2635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      dict.GetInteger(kMediaGalleriesScanVideoCountKey, &video_count)) {
2645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    out_gallery_info->audio_count = audio_count;
2655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    out_gallery_info->image_count = image_count;
2665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    out_gallery_info->video_count = video_count;
2675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  } else {
2685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    out_gallery_info->audio_count = 0;
2695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    out_gallery_info->image_count = 0;
2705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    out_gallery_info->video_count = 0;
2715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
2725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  out_gallery_info->pref_id = pref_id;
2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  out_gallery_info->display_name = display_name;
2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  out_gallery_info->device_id = device_id;
2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  out_gallery_info->path = base::FilePath(path);
2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  out_gallery_info->type = type;
2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  out_gallery_info->volume_label = volume_label;
2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  out_gallery_info->vendor_name = vendor_name;
2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  out_gallery_info->model_name = model_name;
2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  out_gallery_info->total_size_in_bytes = total_size_in_bytes;
2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  out_gallery_info->last_attach_time =
2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Time::FromInternalValue(last_attach_time);
2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  out_gallery_info->volume_metadata_valid = volume_metadata_valid;
2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  out_gallery_info->prefs_version = prefs_version;
2865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  out_gallery_info->default_gallery_type = GetDefaultGalleryType(dict);
2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::DictionaryValue* CreateGalleryPrefInfoDictionary(
2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const MediaGalleryPrefInfo& gallery) {
2925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::DictionaryValue* dict = new base::DictionaryValue();
2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  dict->SetString(kMediaGalleriesPrefIdKey,
2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                  base::Uint64ToString(gallery.pref_id));
2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  dict->SetString(kMediaGalleriesDeviceIdKey, gallery.device_id);
2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  dict->SetString(kMediaGalleriesPathKey, gallery.path.value());
2975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  dict->SetString(kMediaGalleriesTypeKey, TypeToStringValue(gallery.type));
2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (gallery.default_gallery_type != MediaGalleryPrefInfo::kNotDefault) {
3005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    dict->SetString(kMediaGalleriesDefaultGalleryTypeKey,
3015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                    DefaultGalleryTypeToStringValue(
3025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                        gallery.default_gallery_type));
3035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
3045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (gallery.volume_metadata_valid) {
3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    dict->SetString(kMediaGalleriesVolumeLabelKey, gallery.volume_label);
3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    dict->SetString(kMediaGalleriesVendorNameKey, gallery.vendor_name);
3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    dict->SetString(kMediaGalleriesModelNameKey, gallery.model_name);
3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    dict->SetDouble(kMediaGalleriesSizeKey, gallery.total_size_in_bytes);
3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    dict->SetDouble(kMediaGalleriesLastAttachTimeKey,
3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    gallery.last_attach_time.ToInternalValue());
3125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  } else {
3135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    dict->SetString(kMediaGalleriesDisplayNameKey, gallery.display_name);
3145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
3155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (gallery.audio_count || gallery.image_count || gallery.video_count) {
3175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    dict->SetInteger(kMediaGalleriesScanAudioCountKey, gallery.audio_count);
3185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    dict->SetInteger(kMediaGalleriesScanImageCountKey, gallery.image_count);
3195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    dict->SetInteger(kMediaGalleriesScanVideoCountKey, gallery.video_count);
3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Version 0 of the prefs format was that the display_name was always
3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // used to show the user-visible name of the gallery. Version 1 means
3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // that there is an optional display_name, and when it is present, it
3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // overrides the name that would be built from the volume metadata, path,
3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // or whatever other data. So if we see a display_name with version 0, it
3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // means it may be overwritten simply by getting new volume metadata.
3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // A display_name with version 1 should not be overwritten.
3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  dict->SetInteger(kMediaGalleriesPrefsVersionKey, gallery.prefs_version);
3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return dict;
3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool HasAutoDetectedGalleryPermission(const extensions::Extension& extension) {
3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  extensions::MediaGalleriesPermission::CheckParam param(
3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      extensions::MediaGalleriesPermission::kAllAutoDetectedPermission);
33746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  return extension.permissions_data()->CheckAPIPermissionWithParam(
33846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      extensions::APIPermission::kMediaGalleries, &param);
3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
341868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Retrieves the MediaGalleryPermission from the given dictionary; DCHECKs on
342868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// failure.
343868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)bool GetMediaGalleryPermissionFromDictionary(
3445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const base::DictionaryValue* dict,
345868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    MediaGalleryPermission* out_permission) {
346868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  std::string string_id;
347868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (dict->GetString(kMediaGalleryIdKey, &string_id) &&
348868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      base::StringToUint64(string_id, &out_permission->pref_id) &&
349868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      dict->GetBoolean(kMediaGalleryHasPermissionKey,
350868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                       &out_permission->has_permission)) {
351868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return true;
352868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
353868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  NOTREACHED();
354868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return false;
355868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
356868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
357eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// For a device with |device_name| and a relative path |sub_folder|, construct
358eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// a display name. If |sub_folder| is empty, then just return |device_name|.
359a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)base::string16 GetDisplayNameForSubFolder(const base::string16& device_name,
360a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                          const base::FilePath& sub_folder) {
361eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (sub_folder.empty())
362eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return device_name;
363eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return (sub_folder.BaseName().LossyDisplayName() +
3645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          base::ASCIIToUTF16(" - ") +
365eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          device_name);
366eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
367eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
368effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid InitializeImportedMediaGalleryRegistryOnFileThread() {
369e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  DCHECK_CURRENTLY_ON(content::BrowserThread::FILE);
370effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  ImportedMediaGalleryRegistry::GetInstance()->Initialize();
371effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
372effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace
3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)MediaGalleryPrefInfo::MediaGalleryPrefInfo()
3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : pref_id(kInvalidMediaGalleryPrefId),
3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      type(kInvalidType),
3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      total_size_in_bytes(0),
3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      volume_metadata_valid(false),
3805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      audio_count(0),
3815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      image_count(0),
3825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      video_count(0),
3835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      default_gallery_type(kNotDefault),
3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      prefs_version(0) {
3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)MediaGalleryPrefInfo::~MediaGalleryPrefInfo() {}
3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::FilePath MediaGalleryPrefInfo::AbsolutePath() const {
3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath base_path = MediaStorageUtil::FindDevicePathById(device_id);
391c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(!path.IsAbsolute());
3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return base_path.empty() ? base_path : base_path.Append(path);
3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool MediaGalleryPrefInfo::IsBlackListedType() const {
3965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return type == kBlackListed || type == kRemovedScan;
3975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
399a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)base::string16 MediaGalleryPrefInfo::GetGalleryDisplayName() const {
400eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (!StorageInfo::IsRemovableDevice(device_id)) {
40168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    // For fixed storage, the default name is the fully qualified directory
40268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    // name, or in the case of a root directory, the root directory name.
40368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    // Exception: ChromeOS -- the full pathname isn't visible there, so only
40468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    // the directory name is used.
405eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    base::FilePath path = AbsolutePath();
406eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    if (!display_name.empty())
407eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      return display_name;
40868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
40968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#if defined(OS_CHROMEOS)
41068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    // See chrome/browser/chromeos/fileapi/file_system_backend.cc
4115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::FilePath download_path;
4125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (PathService::Get(chrome::DIR_DEFAULT_DOWNLOADS_SAFE, &download_path)) {
41368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      base::FilePath relative;
4145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      if (download_path.AppendRelativePath(path, &relative))
41568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        return relative.LossyDisplayName();
41668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    }
417eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return path.BaseName().LossyDisplayName();
41868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#else
41968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    return path.LossyDisplayName();
42068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#endif
421eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
422eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
423a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  StorageInfo info(device_id,
424a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                   MediaStorageUtil::FindDevicePathById(device_id).value(),
425a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                   volume_label, vendor_name, model_name, total_size_in_bytes);
426a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  base::string16 name = info.GetDisplayNameWithOverride(display_name, true);
427eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (!path.empty())
428eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    name = GetDisplayNameForSubFolder(name, path);
429eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return name;
430eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
431eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
432a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)base::string16 MediaGalleryPrefInfo::GetGalleryTooltip() const {
433eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return AbsolutePath().LossyDisplayName();
434eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
435eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
436a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)base::string16 MediaGalleryPrefInfo::GetGalleryAdditionalDetails() const {
437a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::string16 attached;
438eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (StorageInfo::IsRemovableDevice(device_id)) {
439eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    if (MediaStorageUtil::IsRemovableStorageAttached(device_id)) {
440eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      attached = l10n_util::GetStringUTF16(
441eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          IDS_MEDIA_GALLERIES_DIALOG_DEVICE_ATTACHED);
442eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    } else if (!last_attach_time.is_null()) {
443eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      attached = l10n_util::GetStringFUTF16(
444eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          IDS_MEDIA_GALLERIES_LAST_ATTACHED,
445eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          base::TimeFormatShortDateNumeric(last_attach_time));
446eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    } else {
447eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      attached = l10n_util::GetStringUTF16(
448eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          IDS_MEDIA_GALLERIES_DIALOG_DEVICE_NOT_ATTACHED);
449eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    }
450eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
451eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
452eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return attached;
453eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
454eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
455eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochbool MediaGalleryPrefInfo::IsGalleryAvailable() const {
456eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return !StorageInfo::IsRemovableDevice(device_id) ||
457eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch         MediaStorageUtil::IsRemovableStorageAttached(device_id);
458eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
459eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)MediaGalleriesPreferences::GalleryChangeObserver::~GalleryChangeObserver() {}
4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)MediaGalleriesPreferences::MediaGalleriesPreferences(Profile* profile)
4634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    : initialized_(false),
4644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      pre_initialization_callbacks_waiting_(0),
465868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      profile_(profile),
4664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      extension_prefs_for_testing_(NULL),
4674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      weak_factory_(this) {
4684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
4694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
4704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)MediaGalleriesPreferences::~MediaGalleriesPreferences() {
4714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (StorageMonitor::GetInstance())
4724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    StorageMonitor::GetInstance()->RemoveObserver(this);
4734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
4744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
4754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void MediaGalleriesPreferences::EnsureInitialized(base::Closure callback) {
476e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
4774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
4784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (IsInitialized()) {
4794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    if (!callback.is_null())
4804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      callback.Run();
4814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return;
4824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
4834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
4844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  on_initialize_callbacks_.push_back(callback);
4854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (on_initialize_callbacks_.size() > 1)
4864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return;
4874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
4884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // This counter must match the number of async methods dispatched below.
4894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // It cannot be incremented inline with each callback, as some may return
4904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // synchronously, decrement the counter to 0, and prematurely trigger
4914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // FinishInitialization.
4925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  pre_initialization_callbacks_waiting_ = 4;
4934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
4944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Check whether we should be initializing -- are there any extensions that
4954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // are using media galleries?
4964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  media_galleries::UsageCount(media_galleries::PREFS_INITIALIZED);
4974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (NumberExtensionsUsingMediaGalleries(profile_) == 0) {
4984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    media_galleries::UsageCount(media_galleries::PREFS_INITIALIZED_ERROR);
4994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
5004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
5014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // We determine the freshness of the profile here, before any of the finders
5025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // return and add media galleries to it (hence why the APIHasBeenUsed check
5035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // needs to happen here rather than inside OnStorageMonitorInit itself).
5044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  StorageMonitor::GetInstance()->EnsureInitialized(
5054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      base::Bind(&MediaGalleriesPreferences::OnStorageMonitorInit,
5064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                 weak_factory_.GetWeakPtr(),
5075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                 APIHasBeenUsed(profile_)));
508c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
509c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Look for optional default galleries every time.
5104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  iapps::FindITunesLibrary(
5114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      base::Bind(&MediaGalleriesPreferences::OnFinderDeviceID,
5124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                 weak_factory_.GetWeakPtr()));
5134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
5144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  picasa::FindPicasaDatabase(
5154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      base::Bind(&MediaGalleriesPreferences::OnFinderDeviceID,
516c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 weak_factory_.GetWeakPtr()));
51790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
5184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  iapps::FindIPhotoLibrary(
5194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      base::Bind(&MediaGalleriesPreferences::OnFinderDeviceID,
52090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                 weak_factory_.GetWeakPtr()));
5214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
5224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
5234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)bool MediaGalleriesPreferences::IsInitialized() const { return initialized_; }
5244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
5254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)Profile* MediaGalleriesPreferences::profile() { return profile_; }
5264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
5274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void MediaGalleriesPreferences::OnInitializationCallbackReturned() {
5284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(!IsInitialized());
5295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK_GT(pre_initialization_callbacks_waiting_, 0);
5304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (--pre_initialization_callbacks_waiting_ == 0)
5314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    FinishInitialization();
5324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
5334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
5344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void MediaGalleriesPreferences::FinishInitialization() {
5354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(!IsInitialized());
5364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
5374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  initialized_ = true;
5384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
5394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  StorageMonitor* monitor = StorageMonitor::GetInstance();
5404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(monitor->IsInitialized());
541c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
542d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  InitFromPrefs();
543c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
544868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  StorageMonitor::GetInstance()->AddObserver(this);
5452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::vector<StorageInfo> existing_devices =
5474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      monitor->GetAllAvailableStorages();
5484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  for (size_t i = 0; i < existing_devices.size(); i++) {
5494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    if (!(StorageInfo::IsMediaDevice(existing_devices[i].device_id()) &&
5504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)          StorageInfo::IsRemovableDevice(existing_devices[i].device_id())))
5514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      continue;
5524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    AddGallery(existing_devices[i].device_id(),
5534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)               base::FilePath(),
5545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)               MediaGalleryPrefInfo::kAutoDetected,
5554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)               existing_devices[i].storage_label(),
5564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)               existing_devices[i].vendor_name(),
5574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)               existing_devices[i].model_name(),
5584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)               existing_devices[i].total_size_in_bytes(),
5595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)               base::Time::Now(), 0, 0, 0);
5604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
5612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  for (std::vector<base::Closure>::iterator iter =
5634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)           on_initialize_callbacks_.begin();
5644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)       iter != on_initialize_callbacks_.end();
5654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)       ++iter) {
5664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    iter->Run();
5674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
5684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  on_initialize_callbacks_.clear();
569d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
570d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
5714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void MediaGalleriesPreferences::AddDefaultGalleries() {
5725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  const struct DefaultTypes {
5735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    int directory_key;
5745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    MediaGalleryPrefInfo::DefaultGalleryType default_gallery_type;
5755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  } kDirectories[] = {
5765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    {chrome::DIR_USER_MUSIC, MediaGalleryPrefInfo::kMusicDefault},
5775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    {chrome::DIR_USER_PICTURES, MediaGalleryPrefInfo::kPicturesDefault},
5785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    {chrome::DIR_USER_VIDEOS, MediaGalleryPrefInfo::kVideosDefault},
5792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
5802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  for (size_t i = 0; i < arraysize(kDirectories); ++i) {
5822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::FilePath path;
5835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (!PathService::Get(kDirectories[i].directory_key, &path))
5842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      continue;
5852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::FilePath relative_path;
5872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    StorageInfo info;
5882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (MediaStorageUtil::GetDeviceInfoFromPath(path, &info, &relative_path)) {
5895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      MediaGalleryPrefInfo::DefaultGalleryType default_gallery_type =
5905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          kDirectories[i].default_gallery_type;
5915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      DCHECK_NE(default_gallery_type, MediaGalleryPrefInfo::kNotDefault);
5925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
5935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      AddOrUpdateGalleryInternal(
5945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          info.device_id(),
5955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          base::string16(),
5965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          relative_path,
5975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          MediaGalleryPrefInfo::kAutoDetected,
5985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          info.storage_label(),
5995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          info.vendor_name(),
6005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          info.model_name(),
6015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          info.total_size_in_bytes(),
6025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          base::Time(),
6035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          true,
6045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          0,
6055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          0,
6065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          0,
6075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          kCurrentPrefsVersion,
6085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          default_gallery_type);
6092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
6102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)bool MediaGalleriesPreferences::UpdateDeviceIDForSingletonType(
6147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    const std::string& device_id) {
6157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  StorageInfo::Type singleton_type;
6167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (!StorageInfo::CrackDeviceId(device_id, &singleton_type, NULL))
6177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return false;
6187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
6197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  PrefService* prefs = profile_->GetPrefs();
6207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<ListPrefUpdate> update(new ListPrefUpdate(
6217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      prefs, prefs::kMediaGalleriesRememberedGalleries));
6225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::ListValue* list = update->Get();
6235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  for (base::ListValue::iterator iter = list->begin();
6245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)       iter != list->end(); ++iter) {
6257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // All of these calls should succeed, but preferences file can be corrupt.
6265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::DictionaryValue* dict;
6277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    if (!(*iter)->GetAsDictionary(&dict))
6287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      continue;
6297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    std::string this_device_id;
6307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    if (!dict->GetString(kMediaGalleriesDeviceIdKey, &this_device_id))
6317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      continue;
6327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    if (this_device_id == device_id)
6337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      return true;  // No update is necessary.
6347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    StorageInfo::Type device_type;
6357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    if (!StorageInfo::CrackDeviceId(this_device_id, &device_type, NULL))
6367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      continue;
6377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
6387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    if (device_type == singleton_type) {
6397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      dict->SetString(kMediaGalleriesDeviceIdKey, device_id);
6407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      update.reset();  // commits the update.
641d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      InitFromPrefs();
642d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      MediaGalleryPrefId pref_id;
643d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      if (GetPrefId(*dict, &pref_id)) {
644d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        FOR_EACH_OBSERVER(GalleryChangeObserver,
645d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                          gallery_change_observers_,
646d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                          OnGalleryInfoUpdated(this, pref_id));
647d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      }
6487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      return true;
6497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    }
6507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
6517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return false;
6527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
6537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
6544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void MediaGalleriesPreferences::OnStorageMonitorInit(
6555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    bool api_has_been_used) {
6565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (api_has_been_used)
6575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    UpdateDefaultGalleriesPaths();
6585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
6595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Invoke this method even if the API has been used before, in order to ensure
6605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // we upgrade (migrate) prefs for galleries with prefs version prior to 3.
6615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  AddDefaultGalleries();
6625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
6634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  OnInitializationCallbackReturned();
664c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
665c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
6664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void MediaGalleriesPreferences::OnFinderDeviceID(const std::string& device_id) {
667effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  if (!device_id.empty()) {
6684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    std::string gallery_name;
6694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    if (StorageInfo::IsIPhotoDevice(device_id))
6704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      gallery_name = kIPhotoGalleryName;
6714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    else if (StorageInfo::IsITunesDevice(device_id))
6724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      gallery_name = kITunesGalleryName;
6734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    else if (StorageInfo::IsPicasaDevice(device_id))
6744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      gallery_name = kPicasaGalleryName;
6754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
676effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    if (!gallery_name.empty()) {
677effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      pre_initialization_callbacks_waiting_++;
678effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      content::BrowserThread::PostTaskAndReply(
679effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch          content::BrowserThread::FILE,
680effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch          FROM_HERE,
681effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch          base::Bind(&InitializeImportedMediaGalleryRegistryOnFileThread),
682effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch          base::Bind(
683effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch              &MediaGalleriesPreferences::OnInitializationCallbackReturned,
684effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch              weak_factory_.GetWeakPtr()));
685effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    }
686effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
687effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    if (!UpdateDeviceIDForSingletonType(device_id)) {
688effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      DCHECK(!gallery_name.empty());
6895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      AddOrUpdateGalleryInternal(
6905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          device_id,
6915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          base::ASCIIToUTF16(gallery_name),
6925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          base::FilePath(),
6935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          MediaGalleryPrefInfo::kAutoDetected,
6945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          base::string16(),
6955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          base::string16(),
6965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          base::string16(),
6975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          0,
6985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          base::Time(),
6995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          false,
7005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          0,
7015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          0,
7025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          0,
7035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          kCurrentPrefsVersion,
7045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          MediaGalleryPrefInfo::kNotDefault);
705effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    }
7067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
7074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
7084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  OnInitializationCallbackReturned();
70990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
71090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
711d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void MediaGalleriesPreferences::InitFromPrefs() {
7122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  known_galleries_.clear();
7132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  device_map_.clear();
7142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PrefService* prefs = profile_->GetPrefs();
7165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const base::ListValue* list = prefs->GetList(
7172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      prefs::kMediaGalleriesRememberedGalleries);
7182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (list) {
7195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    for (base::ListValue::const_iterator it = list->begin();
7202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)         it != list->end(); ++it) {
7215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      const base::DictionaryValue* dict = NULL;
7222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (!(*it)->GetAsDictionary(&dict))
7232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        continue;
7242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      MediaGalleryPrefInfo gallery_info;
7262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (!PopulateGalleryPrefInfoFromDictionary(*dict, &gallery_info))
7272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        continue;
7282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      known_galleries_[gallery_info.pref_id] = gallery_info;
7302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      device_map_[gallery_info.device_id].insert(gallery_info.pref_id);
7312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
7322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
7332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void MediaGalleriesPreferences::AddGalleryChangeObserver(
7362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    GalleryChangeObserver* observer) {
7374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(IsInitialized());
7382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gallery_change_observers_.AddObserver(observer);
7392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void MediaGalleriesPreferences::RemoveGalleryChangeObserver(
7422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    GalleryChangeObserver* observer) {
7434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(IsInitialized());
7442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gallery_change_observers_.RemoveObserver(observer);
7452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void MediaGalleriesPreferences::OnRemovableStorageAttached(
7482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const StorageInfo& info) {
7494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(IsInitialized());
75090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (!StorageInfo::IsMediaDevice(info.device_id()))
7512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
7522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  AddGallery(info.device_id(), base::FilePath(),
7545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)             MediaGalleryPrefInfo::kAutoDetected, info.storage_label(),
7555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)             info.vendor_name(), info.model_name(), info.total_size_in_bytes(),
7565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)             base::Time::Now(), 0, 0, 0);
7572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool MediaGalleriesPreferences::LookUpGalleryByPath(
7602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::FilePath& path,
7612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MediaGalleryPrefInfo* gallery_info) const {
7624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(IsInitialized());
763f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
764f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // First check if the path matches an imported gallery.
765f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  for (MediaGalleriesPrefInfoMap::const_iterator it =
766f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)           known_galleries_.begin(); it != known_galleries_.end(); ++it) {
767f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    const std::string& device_id = it->second.device_id;
768f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    if (iapps::PathIndicatesIPhotoLibrary(device_id, path) ||
769f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        iapps::PathIndicatesITunesLibrary(device_id, path)) {
770f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      *gallery_info = it->second;
771f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      return true;
772f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    }
773f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
774f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
7752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  StorageInfo info;
7762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath relative_path;
7772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!MediaStorageUtil::GetDeviceInfoFromPath(path, &info, &relative_path)) {
7782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (gallery_info)
7792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      *gallery_info = MediaGalleryPrefInfo();
7802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
7812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
7822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  relative_path = relative_path.NormalizePathSeparators();
7842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MediaGalleryPrefIdSet galleries_on_device =
78590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      LookUpGalleriesByDeviceId(info.device_id());
7862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (MediaGalleryPrefIdSet::const_iterator it = galleries_on_device.begin();
7872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       it != galleries_on_device.end();
7882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       ++it) {
7892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const MediaGalleryPrefInfo& gallery = known_galleries_.find(*it)->second;
7902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (gallery.path != relative_path)
7912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      continue;
7922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (gallery_info)
7942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      *gallery_info = gallery;
7952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return true;
7962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
7972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // This method is called by controller::FilesSelected when the user
7992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // adds a new gallery. Control reaches here when the selected gallery is
8002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // on a volume we know about, but have no gallery already for. Returns
8012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // hypothetical data to the caller about what the prefs will look like
8022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // if the gallery is added.
8032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // TODO(gbillock): split this out into another function so it doesn't
8042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // conflate LookUp.
8052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (gallery_info) {
8062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gallery_info->pref_id = kInvalidMediaGalleryPrefId;
80790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    gallery_info->device_id = info.device_id();
8082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gallery_info->path = relative_path;
8095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    gallery_info->type = MediaGalleryPrefInfo::kInvalidType;
8107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    gallery_info->volume_label = info.storage_label();
8117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    gallery_info->vendor_name = info.vendor_name();
8127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    gallery_info->model_name = info.model_name();
8137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    gallery_info->total_size_in_bytes = info.total_size_in_bytes();
8147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    gallery_info->last_attach_time = base::Time::Now();
8157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    gallery_info->volume_metadata_valid = true;
8165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    gallery_info->prefs_version = kCurrentPrefsVersion;
8172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
8182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return false;
8192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
8202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)MediaGalleryPrefIdSet MediaGalleriesPreferences::LookUpGalleriesByDeviceId(
8222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& device_id) const {
8232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DeviceIdPrefIdsMap::const_iterator found = device_map_.find(device_id);
8242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (found == device_map_.end())
8252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return MediaGalleryPrefIdSet();
8262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return found->second;
8272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
8282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::FilePath MediaGalleriesPreferences::LookUpGalleryPathForExtension(
8302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MediaGalleryPrefId gallery_id,
8312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const extensions::Extension* extension,
8322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool include_unpermitted_galleries) {
8334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(IsInitialized());
8342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(extension);
8352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!include_unpermitted_galleries &&
8362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      !ContainsKey(GalleriesForExtension(*extension), gallery_id))
8372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return base::FilePath();
8382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MediaGalleriesPrefInfoMap::const_iterator it =
8402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      known_galleries_.find(gallery_id);
8412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (it == known_galleries_.end())
8422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return base::FilePath();
8432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return MediaStorageUtil::FindDevicePathById(it->second.device_id);
8442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
8452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)MediaGalleryPrefId MediaGalleriesPreferences::AddGallery(
8472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& device_id,
8485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const base::FilePath& relative_path,
8495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    MediaGalleryPrefInfo::Type type,
8505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const base::string16& volume_label,
8515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const base::string16& vendor_name,
8525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const base::string16& model_name,
8535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    uint64 total_size_in_bytes,
8545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::Time last_attach_time,
8555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    int audio_count,
8565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    int image_count,
8575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    int video_count) {
8584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(IsInitialized());
8595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return AddOrUpdateGalleryInternal(
8605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      device_id,
8615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      base::string16(),
8625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      relative_path,
8635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      type,
8645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      volume_label,
8655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      vendor_name,
8665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      model_name,
8675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      total_size_in_bytes,
8685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      last_attach_time,
8695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      true,
8705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      audio_count,
8715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      image_count,
8725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      video_count,
8735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      kCurrentPrefsVersion,
8745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      MediaGalleryPrefInfo::kNotDefault);
8752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
8762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)MediaGalleryPrefId MediaGalleriesPreferences::AddOrUpdateGalleryInternal(
878a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const std::string& device_id, const base::string16& display_name,
8795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const base::FilePath& relative_path, MediaGalleryPrefInfo::Type type,
880a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const base::string16& volume_label, const base::string16& vendor_name,
881a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const base::string16& model_name, uint64 total_size_in_bytes,
8825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::Time last_attach_time, bool volume_metadata_valid,
8835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    int audio_count, int image_count, int video_count, int prefs_version,
8845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    MediaGalleryPrefInfo::DefaultGalleryType default_gallery_type) {
8855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(type == MediaGalleryPrefInfo::kUserAdded ||
8865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)         type == MediaGalleryPrefInfo::kAutoDetected ||
8875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)         type == MediaGalleryPrefInfo::kScanResult);
8882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath normalized_relative_path =
8892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      relative_path.NormalizePathSeparators();
8902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MediaGalleryPrefIdSet galleries_on_device =
8912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LookUpGalleriesByDeviceId(device_id);
8925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
893d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  for (MediaGalleryPrefIdSet::const_iterator pref_id_it =
894d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)           galleries_on_device.begin();
895d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)       pref_id_it != galleries_on_device.end();
896d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)       ++pref_id_it) {
897d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    const MediaGalleryPrefInfo& existing =
898d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        known_galleries_.find(*pref_id_it)->second;
8992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (existing.path != normalized_relative_path)
9002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      continue;
9012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    bool update_gallery_type = false;
9035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    MediaGalleryPrefInfo::Type new_type = existing.type;
9045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (type == MediaGalleryPrefInfo::kUserAdded) {
9055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      if (existing.type == MediaGalleryPrefInfo::kBlackListed) {
9065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        new_type = MediaGalleryPrefInfo::kAutoDetected;
9075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        update_gallery_type = true;
9085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      }
9095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      if (existing.type == MediaGalleryPrefInfo::kRemovedScan) {
9105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        new_type = MediaGalleryPrefInfo::kUserAdded;
9115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        update_gallery_type = true;
9125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      }
9135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
9145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
91590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // Status quo: In M27 and M28, galleries added manually use version 0,
91690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // and galleries added automatically (including default galleries) use
91790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // version 1. The name override is used by default galleries as well
91890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // as all device attach events.
9197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // We want to upgrade the name if the existing version is < 2. Leave it
9205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // alone if the existing display name is set with version >= 2 and the
9217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // proposed new name is empty.
9222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool update_gallery_name = existing.display_name != display_name;
9235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (existing.prefs_version >= 2 && !existing.display_name.empty() &&
9247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        display_name.empty()) {
9257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      update_gallery_name = false;
9267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    }
9275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
9285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // Version 3 adds the default_gallery_type field.
9295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    bool update_default_gallery_type =
9305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)         existing.prefs_version <= 2 &&
9315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)         default_gallery_type != existing.default_gallery_type;
9325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
9332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool update_gallery_metadata = volume_metadata_valid &&
9342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        ((existing.volume_label != volume_label) ||
9352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)         (existing.vendor_name != vendor_name) ||
9362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)         (existing.model_name != model_name) ||
9372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)         (existing.total_size_in_bytes != total_size_in_bytes) ||
9382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)         (existing.last_attach_time != last_attach_time));
9392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    bool update_scan_counts =
9415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      new_type != MediaGalleryPrefInfo::kRemovedScan &&
9425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      new_type != MediaGalleryPrefInfo::kBlackListed &&
9435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      (audio_count > 0 || image_count > 0 || video_count > 0 ||
9445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)       existing.audio_count || existing.image_count || existing.video_count);
9455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
9462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!update_gallery_name && !update_gallery_type &&
9475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        !update_gallery_metadata && !update_scan_counts &&
9485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        !update_default_gallery_type)
949d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      return *pref_id_it;
9502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    PrefService* prefs = profile_->GetPrefs();
9522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<ListPrefUpdate> update(
9532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        new ListPrefUpdate(prefs, prefs::kMediaGalleriesRememberedGalleries));
9545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::ListValue* list = update->Get();
955