media_galleries_preferences.cc revision 46d4c2bc3267f3f028f39e7e311b0f89aba2e4fd
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"
29cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "components/pref_registry/pref_registry_syncable.h"
305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "components/storage_monitor/media_storage_util.h"
315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "components/storage_monitor/storage_monitor.h"
324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "content/public/browser/browser_thread.h"
33cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "extensions/browser/extension_prefs.h"
345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/browser/extension_system.h"
355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/browser/pref_names.h"
36f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/extension.h"
375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/common/extension_set.h"
384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "extensions/common/permissions/api_permission.h"
39effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "extensions/common/permissions/media_galleries_permission.h"
40f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/permissions/permissions_data.h"
41eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "grit/generated_resources.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)const char kMediaGalleriesPrefsVersionKey[] = "preferencesVersion";
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kMediaGalleriesTypeAutoDetectedValue[] = "autoDetected";
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kMediaGalleriesTypeBlackListedValue[] = "blackListed";
775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const char kMediaGalleriesTypeRemovedScanValue[] = "removedScan";
785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const char kMediaGalleriesTypeScanResultValue[] = "scanResult";
795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const char kMediaGalleriesTypeUserAddedValue[] = "userAdded";
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)const char kIPhotoGalleryName[] = "iPhoto";
82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const char kITunesGalleryName[] = "iTunes";
8390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)const char kPicasaGalleryName[] = "Picasa";
84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const int kCurrentPrefsVersion = 2;
865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)int NumberExtensionsUsingMediaGalleries(Profile* profile) {
884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  int count = 0;
894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (!profile)
904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return count;
914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ExtensionService* extension_service =
924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      extensions::ExtensionSystem::Get(profile)->extension_service();
934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (!extension_service)
944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return count;
954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const extensions::ExtensionSet* extensions = extension_service->extensions();
975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  for (extensions::ExtensionSet::const_iterator i = extensions->begin();
984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)       i != extensions->end(); ++i) {
9946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    const extensions::PermissionsData* permissions_data =
10046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        (*i)->permissions_data();
10146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    if (permissions_data->HasAPIPermission(
10246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)            extensions::APIPermission::kMediaGalleries) ||
10346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        permissions_data->HasAPIPermission(
10446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)            extensions::APIPermission::kMediaGalleriesPrivate)) {
1054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      count++;
1064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    }
1074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
1084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return count;
1094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
1104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool GetPrefId(const base::DictionaryValue& dict, MediaGalleryPrefId* value) {
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string string_id;
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!dict.GetString(kMediaGalleriesPrefIdKey, &string_id) ||
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      !base::StringToUint64(string_id, value)) {
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool GetType(const base::DictionaryValue& dict,
1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)             MediaGalleryPrefInfo::Type* type) {
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string string_type;
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!dict.GetString(kMediaGalleriesTypeKey, &string_type))
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (string_type == kMediaGalleriesTypeUserAddedValue) {
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    *type = MediaGalleryPrefInfo::kUserAdded;
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return true;
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (string_type == kMediaGalleriesTypeAutoDetectedValue) {
1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    *type = MediaGalleryPrefInfo::kAutoDetected;
1335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return true;
1345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (string_type == kMediaGalleriesTypeBlackListedValue) {
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    *type = MediaGalleryPrefInfo::kBlackListed;
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return true;
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (string_type == kMediaGalleriesTypeScanResultValue) {
1405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    *type = MediaGalleryPrefInfo::kScanResult;
1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return true;
1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (string_type == kMediaGalleriesTypeRemovedScanValue) {
1445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    *type = MediaGalleryPrefInfo::kRemovedScan;
1455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return true;
1465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return false;
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const char* TypeToStringValue(MediaGalleryPrefInfo::Type type) {
1525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const char* result = NULL;
1535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  switch (type) {
1545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    case MediaGalleryPrefInfo::kUserAdded:
1555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      result = kMediaGalleriesTypeUserAddedValue;
1565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      break;
1575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    case MediaGalleryPrefInfo::kAutoDetected:
1585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      result = kMediaGalleriesTypeAutoDetectedValue;
1595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      break;
1605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    case MediaGalleryPrefInfo::kBlackListed:
1615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      result = kMediaGalleriesTypeBlackListedValue;
1625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      break;
1635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    case MediaGalleryPrefInfo::kScanResult:
1645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      result = kMediaGalleriesTypeScanResultValue;
1655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      break;
1665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    case MediaGalleryPrefInfo::kRemovedScan:
1675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      result = kMediaGalleriesTypeRemovedScanValue;
1685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      break;
1695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    default:
1705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      NOTREACHED();
1715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      break;
1725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return result;
1745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool PopulateGalleryPrefInfoFromDictionary(
1775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const base::DictionaryValue& dict, MediaGalleryPrefInfo* out_gallery_info) {
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MediaGalleryPrefId pref_id;
179a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::string16 display_name;
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string device_id;
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath::StringType path;
1825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  MediaGalleryPrefInfo::Type type = MediaGalleryPrefInfo::kInvalidType;
183a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::string16 volume_label;
184a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::string16 vendor_name;
185a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::string16 model_name;
1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  double total_size_in_bytes = 0.0;
1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  double last_attach_time = 0.0;
1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool volume_metadata_valid = false;
1895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int audio_count = 0;
1905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int image_count = 0;
1915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int video_count = 0;
1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int prefs_version = 0;
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!GetPrefId(dict, &pref_id) ||
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      !dict.GetString(kMediaGalleriesDeviceIdKey, &device_id) ||
1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      !dict.GetString(kMediaGalleriesPathKey, &path) ||
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      !GetType(dict, &type)) {
1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  dict.GetString(kMediaGalleriesDisplayNameKey, &display_name);
2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  dict.GetInteger(kMediaGalleriesPrefsVersionKey, &prefs_version);
2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (dict.GetString(kMediaGalleriesVolumeLabelKey, &volume_label) &&
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      dict.GetString(kMediaGalleriesVendorNameKey, &vendor_name) &&
2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      dict.GetString(kMediaGalleriesModelNameKey, &model_name) &&
2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      dict.GetDouble(kMediaGalleriesSizeKey, &total_size_in_bytes) &&
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      dict.GetDouble(kMediaGalleriesLastAttachTimeKey, &last_attach_time)) {
2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    volume_metadata_valid = true;
2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (dict.GetInteger(kMediaGalleriesScanAudioCountKey, &audio_count) &&
2135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      dict.GetInteger(kMediaGalleriesScanImageCountKey, &image_count) &&
2145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      dict.GetInteger(kMediaGalleriesScanVideoCountKey, &video_count)) {
2155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    out_gallery_info->audio_count = audio_count;
2165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    out_gallery_info->image_count = image_count;
2175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    out_gallery_info->video_count = video_count;
2185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  } else {
2195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    out_gallery_info->audio_count = 0;
2205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    out_gallery_info->image_count = 0;
2215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    out_gallery_info->video_count = 0;
2225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
2235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  out_gallery_info->pref_id = pref_id;
2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  out_gallery_info->display_name = display_name;
2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  out_gallery_info->device_id = device_id;
2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  out_gallery_info->path = base::FilePath(path);
2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  out_gallery_info->type = type;
2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  out_gallery_info->volume_label = volume_label;
2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  out_gallery_info->vendor_name = vendor_name;
2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  out_gallery_info->model_name = model_name;
2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  out_gallery_info->total_size_in_bytes = total_size_in_bytes;
2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  out_gallery_info->last_attach_time =
2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Time::FromInternalValue(last_attach_time);
2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  out_gallery_info->volume_metadata_valid = volume_metadata_valid;
2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  out_gallery_info->prefs_version = prefs_version;
2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::DictionaryValue* CreateGalleryPrefInfoDictionary(
2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const MediaGalleryPrefInfo& gallery) {
2435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::DictionaryValue* dict = new base::DictionaryValue();
2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  dict->SetString(kMediaGalleriesPrefIdKey,
2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                  base::Uint64ToString(gallery.pref_id));
2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  dict->SetString(kMediaGalleriesDeviceIdKey, gallery.device_id);
2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  dict->SetString(kMediaGalleriesPathKey, gallery.path.value());
2485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  dict->SetString(kMediaGalleriesTypeKey, TypeToStringValue(gallery.type));
2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (gallery.volume_metadata_valid) {
2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    dict->SetString(kMediaGalleriesVolumeLabelKey, gallery.volume_label);
2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    dict->SetString(kMediaGalleriesVendorNameKey, gallery.vendor_name);
2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    dict->SetString(kMediaGalleriesModelNameKey, gallery.model_name);
2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    dict->SetDouble(kMediaGalleriesSizeKey, gallery.total_size_in_bytes);
2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    dict->SetDouble(kMediaGalleriesLastAttachTimeKey,
2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    gallery.last_attach_time.ToInternalValue());
2575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  } else {
2585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    dict->SetString(kMediaGalleriesDisplayNameKey, gallery.display_name);
2595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
2605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (gallery.audio_count || gallery.image_count || gallery.video_count) {
2625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    dict->SetInteger(kMediaGalleriesScanAudioCountKey, gallery.audio_count);
2635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    dict->SetInteger(kMediaGalleriesScanImageCountKey, gallery.image_count);
2645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    dict->SetInteger(kMediaGalleriesScanVideoCountKey, gallery.video_count);
2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Version 0 of the prefs format was that the display_name was always
2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // used to show the user-visible name of the gallery. Version 1 means
2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // that there is an optional display_name, and when it is present, it
2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // overrides the name that would be built from the volume metadata, path,
2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // or whatever other data. So if we see a display_name with version 0, it
2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // means it may be overwritten simply by getting new volume metadata.
2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // A display_name with version 1 should not be overwritten.
2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  dict->SetInteger(kMediaGalleriesPrefsVersionKey, gallery.prefs_version);
2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return dict;
2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool HasAutoDetectedGalleryPermission(const extensions::Extension& extension) {
2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  extensions::MediaGalleriesPermission::CheckParam param(
2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      extensions::MediaGalleriesPermission::kAllAutoDetectedPermission);
28246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  return extension.permissions_data()->CheckAPIPermissionWithParam(
28346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      extensions::APIPermission::kMediaGalleries, &param);
2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
286868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Retrieves the MediaGalleryPermission from the given dictionary; DCHECKs on
287868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// failure.
288868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)bool GetMediaGalleryPermissionFromDictionary(
2895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const base::DictionaryValue* dict,
290868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    MediaGalleryPermission* out_permission) {
291868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  std::string string_id;
292868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (dict->GetString(kMediaGalleryIdKey, &string_id) &&
293868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      base::StringToUint64(string_id, &out_permission->pref_id) &&
294868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      dict->GetBoolean(kMediaGalleryHasPermissionKey,
295868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                       &out_permission->has_permission)) {
296868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return true;
297868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
298868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  NOTREACHED();
299868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return false;
300868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
301868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
302eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// For a device with |device_name| and a relative path |sub_folder|, construct
303eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// a display name. If |sub_folder| is empty, then just return |device_name|.
304a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)base::string16 GetDisplayNameForSubFolder(const base::string16& device_name,
305a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                          const base::FilePath& sub_folder) {
306eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (sub_folder.empty())
307eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return device_name;
308eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return (sub_folder.BaseName().LossyDisplayName() +
3095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          base::ASCIIToUTF16(" - ") +
310eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          device_name);
311eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
312eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
313effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid InitializeImportedMediaGalleryRegistryOnFileThread() {
314e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  DCHECK_CURRENTLY_ON(content::BrowserThread::FILE);
315effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  ImportedMediaGalleryRegistry::GetInstance()->Initialize();
316effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
317effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace
3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)MediaGalleryPrefInfo::MediaGalleryPrefInfo()
3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : pref_id(kInvalidMediaGalleryPrefId),
3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      type(kInvalidType),
3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      total_size_in_bytes(0),
3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      volume_metadata_valid(false),
3255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      audio_count(0),
3265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      image_count(0),
3275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      video_count(0),
3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      prefs_version(0) {
3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)MediaGalleryPrefInfo::~MediaGalleryPrefInfo() {}
3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::FilePath MediaGalleryPrefInfo::AbsolutePath() const {
3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath base_path = MediaStorageUtil::FindDevicePathById(device_id);
335c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(!path.IsAbsolute());
3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return base_path.empty() ? base_path : base_path.Append(path);
3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool MediaGalleryPrefInfo::IsBlackListedType() const {
3405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return type == kBlackListed || type == kRemovedScan;
3415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
343a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)base::string16 MediaGalleryPrefInfo::GetGalleryDisplayName() const {
344eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (!StorageInfo::IsRemovableDevice(device_id)) {
34568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    // For fixed storage, the default name is the fully qualified directory
34668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    // name, or in the case of a root directory, the root directory name.
34768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    // Exception: ChromeOS -- the full pathname isn't visible there, so only
34868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    // the directory name is used.
349eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    base::FilePath path = AbsolutePath();
350eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    if (!display_name.empty())
351eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      return display_name;
35268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
35368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#if defined(OS_CHROMEOS)
35468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    // See chrome/browser/chromeos/fileapi/file_system_backend.cc
3555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::FilePath download_path;
3565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (PathService::Get(chrome::DIR_DEFAULT_DOWNLOADS_SAFE, &download_path)) {
35768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      base::FilePath relative;
3585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      if (download_path.AppendRelativePath(path, &relative))
35968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        return relative.LossyDisplayName();
36068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    }
361eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return path.BaseName().LossyDisplayName();
36268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#else
36368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    return path.LossyDisplayName();
36468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#endif
365eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
366eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
367a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  StorageInfo info(device_id,
368a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                   MediaStorageUtil::FindDevicePathById(device_id).value(),
369a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                   volume_label, vendor_name, model_name, total_size_in_bytes);
370a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  base::string16 name = info.GetDisplayNameWithOverride(display_name, true);
371eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (!path.empty())
372eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    name = GetDisplayNameForSubFolder(name, path);
373eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return name;
374eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
375eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
376a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)base::string16 MediaGalleryPrefInfo::GetGalleryTooltip() const {
377eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return AbsolutePath().LossyDisplayName();
378eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
379eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
380a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)base::string16 MediaGalleryPrefInfo::GetGalleryAdditionalDetails() const {
381a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::string16 attached;
382eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (StorageInfo::IsRemovableDevice(device_id)) {
383eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    if (MediaStorageUtil::IsRemovableStorageAttached(device_id)) {
384eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      attached = l10n_util::GetStringUTF16(
385eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          IDS_MEDIA_GALLERIES_DIALOG_DEVICE_ATTACHED);
386eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    } else if (!last_attach_time.is_null()) {
387eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      attached = l10n_util::GetStringFUTF16(
388eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          IDS_MEDIA_GALLERIES_LAST_ATTACHED,
389eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          base::TimeFormatShortDateNumeric(last_attach_time));
390eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    } else {
391eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      attached = l10n_util::GetStringUTF16(
392eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          IDS_MEDIA_GALLERIES_DIALOG_DEVICE_NOT_ATTACHED);
393eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    }
394eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
395eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
396eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return attached;
397eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
398eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
399eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochbool MediaGalleryPrefInfo::IsGalleryAvailable() const {
400eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return !StorageInfo::IsRemovableDevice(device_id) ||
401eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch         MediaStorageUtil::IsRemovableStorageAttached(device_id);
402eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
403eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)MediaGalleriesPreferences::GalleryChangeObserver::~GalleryChangeObserver() {}
4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)MediaGalleriesPreferences::MediaGalleriesPreferences(Profile* profile)
4074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    : initialized_(false),
4084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      pre_initialization_callbacks_waiting_(0),
409868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      profile_(profile),
4104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      extension_prefs_for_testing_(NULL),
4114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      weak_factory_(this) {
4124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
4134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
4144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)MediaGalleriesPreferences::~MediaGalleriesPreferences() {
4154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (StorageMonitor::GetInstance())
4164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    StorageMonitor::GetInstance()->RemoveObserver(this);
4174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
4184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
4194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void MediaGalleriesPreferences::EnsureInitialized(base::Closure callback) {
420e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
4214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
4224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (IsInitialized()) {
4234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    if (!callback.is_null())
4244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      callback.Run();
4254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return;
4264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
4274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
4284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  on_initialize_callbacks_.push_back(callback);
4294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (on_initialize_callbacks_.size() > 1)
4304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return;
4314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
4324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // This counter must match the number of async methods dispatched below.
4334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // It cannot be incremented inline with each callback, as some may return
4344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // synchronously, decrement the counter to 0, and prematurely trigger
4354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // FinishInitialization.
4365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  pre_initialization_callbacks_waiting_ = 4;
4374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
4384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Check whether we should be initializing -- are there any extensions that
4394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // are using media galleries?
4404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  media_galleries::UsageCount(media_galleries::PREFS_INITIALIZED);
4414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (NumberExtensionsUsingMediaGalleries(profile_) == 0) {
4424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    media_galleries::UsageCount(media_galleries::PREFS_INITIALIZED_ERROR);
4434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
4444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
4454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // We determine the freshness of the profile here, before any of the finders
4464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // return and add media galleries to it.
4474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  StorageMonitor::GetInstance()->EnsureInitialized(
4484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      base::Bind(&MediaGalleriesPreferences::OnStorageMonitorInit,
4494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                 weak_factory_.GetWeakPtr(),
4504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                 !APIHasBeenUsed(profile_) /* add_default_galleries */));
451c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
452c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Look for optional default galleries every time.
4534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  iapps::FindITunesLibrary(
4544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      base::Bind(&MediaGalleriesPreferences::OnFinderDeviceID,
4554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                 weak_factory_.GetWeakPtr()));
4564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
4574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  picasa::FindPicasaDatabase(
4584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      base::Bind(&MediaGalleriesPreferences::OnFinderDeviceID,
459c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 weak_factory_.GetWeakPtr()));
46090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
4614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  iapps::FindIPhotoLibrary(
4624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      base::Bind(&MediaGalleriesPreferences::OnFinderDeviceID,
46390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                 weak_factory_.GetWeakPtr()));
4644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
4654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
4664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)bool MediaGalleriesPreferences::IsInitialized() const { return initialized_; }
4674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
4684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)Profile* MediaGalleriesPreferences::profile() { return profile_; }
4694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
4704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void MediaGalleriesPreferences::OnInitializationCallbackReturned() {
4714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(!IsInitialized());
4725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK_GT(pre_initialization_callbacks_waiting_, 0);
4734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (--pre_initialization_callbacks_waiting_ == 0)
4744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    FinishInitialization();
4754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
4764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
4774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void MediaGalleriesPreferences::FinishInitialization() {
4784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(!IsInitialized());
4794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
4804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  initialized_ = true;
4814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
4824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  StorageMonitor* monitor = StorageMonitor::GetInstance();
4834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(monitor->IsInitialized());
484c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
485d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  InitFromPrefs();
486c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
487868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  StorageMonitor::GetInstance()->AddObserver(this);
4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::vector<StorageInfo> existing_devices =
4904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      monitor->GetAllAvailableStorages();
4914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  for (size_t i = 0; i < existing_devices.size(); i++) {
4924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    if (!(StorageInfo::IsMediaDevice(existing_devices[i].device_id()) &&
4934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)          StorageInfo::IsRemovableDevice(existing_devices[i].device_id())))
4944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      continue;
4954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    AddGallery(existing_devices[i].device_id(),
4964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)               base::FilePath(),
4975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)               MediaGalleryPrefInfo::kAutoDetected,
4984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)               existing_devices[i].storage_label(),
4994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)               existing_devices[i].vendor_name(),
5004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)               existing_devices[i].model_name(),
5014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)               existing_devices[i].total_size_in_bytes(),
5025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)               base::Time::Now(), 0, 0, 0);
5034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
5042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  for (std::vector<base::Closure>::iterator iter =
5064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)           on_initialize_callbacks_.begin();
5074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)       iter != on_initialize_callbacks_.end();
5084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)       ++iter) {
5094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    iter->Run();
5104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
5114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  on_initialize_callbacks_.clear();
512d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
513d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
5144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void MediaGalleriesPreferences::AddDefaultGalleries() {
5152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const int kDirectoryKeys[] = {
516d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    chrome::DIR_USER_MUSIC,
517d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    chrome::DIR_USER_PICTURES,
518d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    chrome::DIR_USER_VIDEOS,
5192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
5202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (size_t i = 0; i < arraysize(kDirectoryKeys); ++i) {
5222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::FilePath path;
5232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!PathService::Get(kDirectoryKeys[i], &path))
5242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      continue;
5252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::FilePath relative_path;
5272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    StorageInfo info;
5282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (MediaStorageUtil::GetDeviceInfoFromPath(path, &info, &relative_path)) {
529a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      AddGalleryInternal(info.device_id(), base::string16(), relative_path,
5305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                         MediaGalleryPrefInfo::kAutoDetected,
5317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                         info.storage_label(), info.vendor_name(),
5327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                         info.model_name(), info.total_size_in_bytes(),
5335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                         base::Time(), true, 0, 0, 0, kCurrentPrefsVersion);
5342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
5352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)bool MediaGalleriesPreferences::UpdateDeviceIDForSingletonType(
5397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    const std::string& device_id) {
5407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  StorageInfo::Type singleton_type;
5417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (!StorageInfo::CrackDeviceId(device_id, &singleton_type, NULL))
5427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return false;
5437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
5447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  PrefService* prefs = profile_->GetPrefs();
5457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<ListPrefUpdate> update(new ListPrefUpdate(
5467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      prefs, prefs::kMediaGalleriesRememberedGalleries));
5475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::ListValue* list = update->Get();
5485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  for (base::ListValue::iterator iter = list->begin();
5495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)       iter != list->end(); ++iter) {
5507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // All of these calls should succeed, but preferences file can be corrupt.
5515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::DictionaryValue* dict;
5527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    if (!(*iter)->GetAsDictionary(&dict))
5537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      continue;
5547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    std::string this_device_id;
5557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    if (!dict->GetString(kMediaGalleriesDeviceIdKey, &this_device_id))
5567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      continue;
5577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    if (this_device_id == device_id)
5587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      return true;  // No update is necessary.
5597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    StorageInfo::Type device_type;
5607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    if (!StorageInfo::CrackDeviceId(this_device_id, &device_type, NULL))
5617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      continue;
5627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
5637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    if (device_type == singleton_type) {
5647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      dict->SetString(kMediaGalleriesDeviceIdKey, device_id);
5657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      update.reset();  // commits the update.
566d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      InitFromPrefs();
567d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      MediaGalleryPrefId pref_id;
568d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      if (GetPrefId(*dict, &pref_id)) {
569d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        FOR_EACH_OBSERVER(GalleryChangeObserver,
570d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                          gallery_change_observers_,
571d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                          OnGalleryInfoUpdated(this, pref_id));
572d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      }
5737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      return true;
5747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    }
5757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
5767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return false;
5777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
5787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
5794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void MediaGalleriesPreferences::OnStorageMonitorInit(
5804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    bool add_default_galleries) {
5814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (add_default_galleries)
5824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    AddDefaultGalleries();
5834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  OnInitializationCallbackReturned();
584c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
585c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
5864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void MediaGalleriesPreferences::OnFinderDeviceID(const std::string& device_id) {
587effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  if (!device_id.empty()) {
5884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    std::string gallery_name;
5894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    if (StorageInfo::IsIPhotoDevice(device_id))
5904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      gallery_name = kIPhotoGalleryName;
5914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    else if (StorageInfo::IsITunesDevice(device_id))
5924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      gallery_name = kITunesGalleryName;
5934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    else if (StorageInfo::IsPicasaDevice(device_id))
5944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      gallery_name = kPicasaGalleryName;
5954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
596effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    if (!gallery_name.empty()) {
597effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      pre_initialization_callbacks_waiting_++;
598effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      content::BrowserThread::PostTaskAndReply(
599effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch          content::BrowserThread::FILE,
600effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch          FROM_HERE,
601effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch          base::Bind(&InitializeImportedMediaGalleryRegistryOnFileThread),
602effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch          base::Bind(
603effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch              &MediaGalleriesPreferences::OnInitializationCallbackReturned,
604effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch              weak_factory_.GetWeakPtr()));
605effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    }
606effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
607effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    if (!UpdateDeviceIDForSingletonType(device_id)) {
608effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      DCHECK(!gallery_name.empty());
609effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      AddGalleryInternal(device_id, base::ASCIIToUTF16(gallery_name),
610effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                         base::FilePath(), MediaGalleryPrefInfo::kAutoDetected,
611effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                         base::string16(), base::string16(), base::string16(),
612effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                         0, base::Time(), false, 0, 0, 0, kCurrentPrefsVersion);
613effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    }
6147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
6154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
6164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  OnInitializationCallbackReturned();
61790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
61890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
619d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void MediaGalleriesPreferences::InitFromPrefs() {
6202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  known_galleries_.clear();
6212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  device_map_.clear();
6222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PrefService* prefs = profile_->GetPrefs();
6245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const base::ListValue* list = prefs->GetList(
6252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      prefs::kMediaGalleriesRememberedGalleries);
6262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (list) {
6275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    for (base::ListValue::const_iterator it = list->begin();
6282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)         it != list->end(); ++it) {
6295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      const base::DictionaryValue* dict = NULL;
6302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (!(*it)->GetAsDictionary(&dict))
6312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        continue;
6322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      MediaGalleryPrefInfo gallery_info;
6342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (!PopulateGalleryPrefInfoFromDictionary(*dict, &gallery_info))
6352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        continue;
6362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      known_galleries_[gallery_info.pref_id] = gallery_info;
6382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      device_map_[gallery_info.device_id].insert(gallery_info.pref_id);
6392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
6402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void MediaGalleriesPreferences::AddGalleryChangeObserver(
6442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    GalleryChangeObserver* observer) {
6454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(IsInitialized());
6462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gallery_change_observers_.AddObserver(observer);
6472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void MediaGalleriesPreferences::RemoveGalleryChangeObserver(
6502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    GalleryChangeObserver* observer) {
6514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(IsInitialized());
6522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gallery_change_observers_.RemoveObserver(observer);
6532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void MediaGalleriesPreferences::OnRemovableStorageAttached(
6562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const StorageInfo& info) {
6574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(IsInitialized());
65890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (!StorageInfo::IsMediaDevice(info.device_id()))
6592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
6602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  AddGallery(info.device_id(), base::FilePath(),
6625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)             MediaGalleryPrefInfo::kAutoDetected, info.storage_label(),
6635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)             info.vendor_name(), info.model_name(), info.total_size_in_bytes(),
6645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)             base::Time::Now(), 0, 0, 0);
6652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool MediaGalleriesPreferences::LookUpGalleryByPath(
6682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::FilePath& path,
6692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MediaGalleryPrefInfo* gallery_info) const {
6704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(IsInitialized());
6712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  StorageInfo info;
6722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath relative_path;
6732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!MediaStorageUtil::GetDeviceInfoFromPath(path, &info, &relative_path)) {
6742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (gallery_info)
6752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      *gallery_info = MediaGalleryPrefInfo();
6762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
6772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  relative_path = relative_path.NormalizePathSeparators();
6802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MediaGalleryPrefIdSet galleries_on_device =
68190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      LookUpGalleriesByDeviceId(info.device_id());
6822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (MediaGalleryPrefIdSet::const_iterator it = galleries_on_device.begin();
6832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       it != galleries_on_device.end();
6842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       ++it) {
6852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const MediaGalleryPrefInfo& gallery = known_galleries_.find(*it)->second;
6862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (gallery.path != relative_path)
6872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      continue;
6882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (gallery_info)
6902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      *gallery_info = gallery;
6912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return true;
6922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // This method is called by controller::FilesSelected when the user
6952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // adds a new gallery. Control reaches here when the selected gallery is
6962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // on a volume we know about, but have no gallery already for. Returns
6972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // hypothetical data to the caller about what the prefs will look like
6982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // if the gallery is added.
6992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // TODO(gbillock): split this out into another function so it doesn't
7002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // conflate LookUp.
7012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (gallery_info) {
7022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gallery_info->pref_id = kInvalidMediaGalleryPrefId;
70390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    gallery_info->device_id = info.device_id();
7042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gallery_info->path = relative_path;
7055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    gallery_info->type = MediaGalleryPrefInfo::kInvalidType;
7067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    gallery_info->volume_label = info.storage_label();
7077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    gallery_info->vendor_name = info.vendor_name();
7087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    gallery_info->model_name = info.model_name();
7097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    gallery_info->total_size_in_bytes = info.total_size_in_bytes();
7107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    gallery_info->last_attach_time = base::Time::Now();
7117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    gallery_info->volume_metadata_valid = true;
7125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    gallery_info->prefs_version = kCurrentPrefsVersion;
7132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
7142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return false;
7152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)MediaGalleryPrefIdSet MediaGalleriesPreferences::LookUpGalleriesByDeviceId(
7182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& device_id) const {
7192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DeviceIdPrefIdsMap::const_iterator found = device_map_.find(device_id);
7202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (found == device_map_.end())
7212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return MediaGalleryPrefIdSet();
7222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return found->second;
7232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::FilePath MediaGalleriesPreferences::LookUpGalleryPathForExtension(
7262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MediaGalleryPrefId gallery_id,
7272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const extensions::Extension* extension,
7282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool include_unpermitted_galleries) {
7294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(IsInitialized());
7302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(extension);
7312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!include_unpermitted_galleries &&
7322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      !ContainsKey(GalleriesForExtension(*extension), gallery_id))
7332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return base::FilePath();
7342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MediaGalleriesPrefInfoMap::const_iterator it =
7362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      known_galleries_.find(gallery_id);
7372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (it == known_galleries_.end())
7382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return base::FilePath();
7392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return MediaStorageUtil::FindDevicePathById(it->second.device_id);
7402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)MediaGalleryPrefId MediaGalleriesPreferences::AddGallery(
7432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& device_id,
7445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const base::FilePath& relative_path,
7455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    MediaGalleryPrefInfo::Type type,
7465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const base::string16& volume_label,
7475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const base::string16& vendor_name,
7485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const base::string16& model_name,
7495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    uint64 total_size_in_bytes,
7505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::Time last_attach_time,
7515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    int audio_count,
7525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    int image_count,
7535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    int video_count) {
7544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(IsInitialized());
755a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  return AddGalleryInternal(device_id, base::string16(), relative_path,
7565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                            type, volume_label, vendor_name, model_name,
7575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                            total_size_in_bytes, last_attach_time, true,
7585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                            audio_count, image_count, video_count,
7595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                            kCurrentPrefsVersion);
7602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)MediaGalleryPrefId MediaGalleriesPreferences::AddGalleryInternal(
763a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const std::string& device_id, const base::string16& display_name,
7645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const base::FilePath& relative_path, MediaGalleryPrefInfo::Type type,
765a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const base::string16& volume_label, const base::string16& vendor_name,
766a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const base::string16& model_name, uint64 total_size_in_bytes,
7675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::Time last_attach_time, bool volume_metadata_valid,
7685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    int audio_count, int image_count, int video_count, int prefs_version) {
7695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(type == MediaGalleryPrefInfo::kUserAdded ||
7705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)         type == MediaGalleryPrefInfo::kAutoDetected ||
7715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)         type == MediaGalleryPrefInfo::kScanResult);
7722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath normalized_relative_path =
7732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      relative_path.NormalizePathSeparators();
7742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MediaGalleryPrefIdSet galleries_on_device =
7752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LookUpGalleriesByDeviceId(device_id);
776d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  for (MediaGalleryPrefIdSet::const_iterator pref_id_it =
777d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)           galleries_on_device.begin();
778d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)       pref_id_it != galleries_on_device.end();
779d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)       ++pref_id_it) {
780d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    const MediaGalleryPrefInfo& existing =
781d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        known_galleries_.find(*pref_id_it)->second;
7822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (existing.path != normalized_relative_path)
7832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      continue;
7842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    bool update_gallery_type = false;
7865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    MediaGalleryPrefInfo::Type new_type = existing.type;
7875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (type == MediaGalleryPrefInfo::kUserAdded) {
7885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      if (existing.type == MediaGalleryPrefInfo::kBlackListed) {
7895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        new_type = MediaGalleryPrefInfo::kAutoDetected;
7905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        update_gallery_type = true;
7915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      }
7925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      if (existing.type == MediaGalleryPrefInfo::kRemovedScan) {
7935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        new_type = MediaGalleryPrefInfo::kUserAdded;
7945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        update_gallery_type = true;
7955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      }
7965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
7975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
79890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // Status quo: In M27 and M28, galleries added manually use version 0,
79990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // and galleries added automatically (including default galleries) use
80090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // version 1. The name override is used by default galleries as well
80190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // as all device attach events.
8027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // We want to upgrade the name if the existing version is < 2. Leave it
8037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // alone if the existing display name is set with version == 2 and the
8047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // proposed new name is empty.
8052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool update_gallery_name = existing.display_name != display_name;
8067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    if (existing.prefs_version == 2 && !existing.display_name.empty() &&
8077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        display_name.empty()) {
8087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      update_gallery_name = false;
8097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    }
8102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool update_gallery_metadata = volume_metadata_valid &&
8112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        ((existing.volume_label != volume_label) ||
8122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)         (existing.vendor_name != vendor_name) ||
8132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)         (existing.model_name != model_name) ||
8142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)         (existing.total_size_in_bytes != total_size_in_bytes) ||
8152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)         (existing.last_attach_time != last_attach_time));
8162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    bool update_scan_counts =
8185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      new_type != MediaGalleryPrefInfo::kRemovedScan &&
8195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      new_type != MediaGalleryPrefInfo::kBlackListed &&
8205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      (audio_count > 0 || image_count > 0 || video_count > 0 ||
8215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)       existing.audio_count || existing.image_count || existing.video_count);
8225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
8232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!update_gallery_name && !update_gallery_type &&
8245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        !update_gallery_metadata && !update_scan_counts)
825d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      return *pref_id_it;
8262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    PrefService* prefs = profile_->GetPrefs();
8282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<ListPrefUpdate> update(
8292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        new ListPrefUpdate(prefs, prefs::kMediaGalleriesRememberedGalleries));
8305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::ListValue* list = update->Get();
8312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    for (base::ListValue::const_iterator list_iter = list->begin();
8332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)         list_iter != list->end();
8342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)         ++list_iter) {
8355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::DictionaryValue* dict;
8362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      MediaGalleryPrefId iter_id;
8372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if ((*list_iter)->GetAsDictionary(&dict) &&
8382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          GetPrefId(*dict, &iter_id) &&
839d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)          *pref_id_it == iter_id) {
8405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        if (update_gallery_type)
8415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          dict->SetString(kMediaGalleriesTypeKey, TypeToStringValue(new_type));
8422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        if (update_gallery_name)
8432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          dict->SetString(kMediaGalleriesDisplayNameKey, display_name);
8442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        if (update_gallery_metadata) {
8452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          dict->SetString(kMediaGalleriesVolumeLabelKey, volume_label);
8462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          dict->SetString(kMediaGalleriesVendorNameKey, vendor_name);
8472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          dict->SetString(kMediaGalleriesModelNameKey, model_name);
8482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          dict->SetDouble(kMediaGalleriesSizeKey, total_size_in_bytes);
8492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          dict->SetDouble(kMediaGalleriesLastAttachTimeKey,
8502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          last_attach_time.ToInternalValue());
8512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        }
8525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        if (update_scan_counts) {
8535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          dict->SetInteger(kMediaGalleriesScanAudioCountKey, audio_count);
8545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          dict->SetInteger(kMediaGalleriesScanImageCountKey, image_count);
8555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          dict->SetInteger(kMediaGalleriesScanVideoCountKey, video_count);
8565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        }
8572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        dict->SetInteger(kMediaGalleriesPrefsVersionKey, prefs_version);
8582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        break;
8592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }
8602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
8612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Commits the prefs update.
8632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    update.reset();
8642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    InitFromPrefs();
8665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    FOR_EACH_OBSERVER(GalleryChangeObserver, gallery_change_observers_,
8675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                      OnGalleryInfoUpdated(this, *pref_id_it));
868d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    return *pref_id_it;
8692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
8702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PrefService* prefs = profile_->GetPrefs();
8722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MediaGalleryPrefInfo gallery_info;
8742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gallery_info.pref_id = prefs->GetUint64(prefs::kMediaGalleriesUniqueId);
8752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  prefs->SetUint64(prefs::kMediaGalleriesUniqueId, gallery_info.pref_id + 1);
8762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gallery_info.display_name = display_name;
8772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gallery_info.device_id = device_id;
8782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gallery_info.path = normalized_relative_path;
8795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  gallery_info.type = type;
8805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  gallery_info.volume_label = volume_label;
8815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  gallery_info.vendor_name = vendor_name;
8825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  gallery_info.model_name = model_name;
8835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  gallery_info.total_size_in_bytes = total_size_in_bytes;
8845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  gallery_info.last_attach_time = last_attach_time;
8852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gallery_info.volume_metadata_valid = volume_metadata_valid;
8865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  gallery_info.audio_count = audio_count;
8875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  gallery_info.image_count = image_count;
8885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  gallery_info.video_count = video_count;
8892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gallery_info.prefs_version = prefs_version;
8902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
8922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ListPrefUpdate update(prefs, prefs::kMediaGalleriesRememberedGalleries);
8935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::ListValue* list = update.Get();
8942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    list->Append(CreateGalleryPrefInfoDictionary(gallery_info));
8952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
896d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  InitFromPrefs();
897d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  FOR_EACH_OBSERVER(GalleryChangeObserver,
898d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                    gallery_change_observers_,
899d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                    OnGalleryAdded(this, gallery_info.pref_id));
9002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return gallery_info.pref_id;
9022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
9032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)MediaGalleryPrefId MediaGalleriesPreferences::AddGalleryByPath(
9055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const base::FilePath& path, MediaGalleryPrefInfo::Type type) {
9064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(IsInitialized());
9072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MediaGalleryPrefInfo gallery_info;
9082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (LookUpGalleryByPath(path, &gallery_info) &&
9095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      !gallery_info.IsBlackListedType()) {
9102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return gallery_info.pref_id;
9112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
9122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return AddGalleryInternal(gallery_info.device_id,
9132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            gallery_info.display_name,
9142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            gallery_info.path,
9155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                            type,
9162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            gallery_info.volume_label,
9172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            gallery_info.vendor_name,
9182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            gallery_info.model_name,
9192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            gallery_info.total_size_in_bytes,
9202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            gallery_info.last_attach_time,
9212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            gallery_info.volume_metadata_valid,
9225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                            0, 0, 0,
9235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                            kCurrentPrefsVersion);
9242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
9252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void MediaGalleriesPreferences::ForgetGalleryById(MediaGalleryPrefId id) {
9275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EraseOrBlacklistGalleryById(id, false);
9285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
9295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
9305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void MediaGalleriesPreferences::EraseGalleryById(MediaGalleryPrefId id) {
9315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EraseOrBlacklistGalleryById(id, true);
9325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
9335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
9345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void MediaGalleriesPreferences::EraseOrBlacklistGalleryById(
9355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    MediaGalleryPrefId id, bool erase) {
9364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(IsInitialized());
9372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PrefService* prefs = profile_->GetPrefs();
938c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<ListPrefUpdate> update(new ListPrefUpdate(
939c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      prefs, prefs::kMediaGalleriesRememberedGalleries));
9405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::ListValue* list = update->Get();
9412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!ContainsKey(known_galleries_, id))
9432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
9442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  for (base::ListValue::iterator iter = list->begin();
9465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)       iter != list->end(); ++iter) {
9475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::DictionaryValue* dict;
9482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MediaGalleryPrefId iter_id;
9492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if ((*iter)->GetAsDictionary(&dict) && GetPrefId(*dict, &iter_id) &&
9505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        id == iter_id) {
9515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      RemoveGalleryPermissionsFromPrefs(id);
9522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      MediaGalleryPrefInfo::Type type;
9535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      if (!erase && GetType(*dict, &type) &&
9545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          (type == MediaGalleryPrefInfo::kAutoDetected ||
9555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)           type == MediaGalleryPrefInfo::kScanResult)) {
9565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        if (type == MediaGalleryPrefInfo::kAutoDetected) {
9575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          dict->SetString(kMediaGalleriesTypeKey,
9585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                          kMediaGalleriesTypeBlackListedValue);
9595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        } else {
9605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          dict->SetString(kMediaGalleriesTypeKey,
9615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                          kMediaGalleriesTypeRemovedScanValue);
9625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          dict->SetInteger(kMediaGalleriesScanAudioCountKey, 0);
9635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          dict->SetInteger(kMediaGalleriesScanImageCountKey, 0);
9645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          dict->SetInteger(kMediaGalleriesScanVideoCountKey, 0);
9655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        }
9662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      } else {
9672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        list->Erase(iter, NULL);
9682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }
969c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      update.reset(NULL);  // commits the update.
970c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
971d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      InitFromPrefs();
972d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      FOR_EACH_OBSERVER(GalleryChangeObserver,
973d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                        gallery_change_observers_,
9745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                        OnGalleryRemoved(this, id));
9752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return;
9762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
9772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
9782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
9792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool MediaGalleriesPreferences::NonAutoGalleryHasPermission(
9815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    MediaGalleryPrefId id) const {
9825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(IsInitialized());
9835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(!ContainsKey(known_galleries_, id) ||
9845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)         known_galleries_.find(id)->second.type !=
9855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)             MediaGalleryPrefInfo::kAutoDetected);
9865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ExtensionPrefs* prefs = GetExtensionPrefs();
9875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const base::DictionaryValue* extensions =
9885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      prefs->pref_service()->GetDictionary(extensions::pref_names::kExtensions);
9895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!extensions)
9905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return true;
9915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
9925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  for (base::DictionaryValue::Iterator iter(*extensions); !iter.IsAtEnd();
9935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)       iter.Advance()) {
9945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (!extensions::Extension::IdIsValid(iter.key())) {
9955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      NOTREACHED();
9965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      continue;
9975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
9985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    std::vector<MediaGalleryPermission> permissions =
9995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        GetGalleryPermissionsFromPrefs(iter.key());
10005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    for (std::vector<MediaGalleryPermission>::const_iterator it =
10015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)             permissions.begin(); it != permissions.end(); ++it) {
10025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      if (it->pref_id == id) {
10035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        if (it->has_permission)
10045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          return true;
10055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        break;
10065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      }
10075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
10085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
10095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return false;
10105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
10115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
10122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)MediaGalleryPrefIdSet MediaGalleriesPreferences::GalleriesForExtension(
10132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const extensions::Extension& extension) const {
10144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(IsInitialized());
10152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MediaGalleryPrefIdSet result;
10162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (HasAutoDetectedGalleryPermission(extension)) {
10182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (MediaGalleriesPrefInfoMap::const_iterator it =
10192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)             known_galleries_.begin(); it != known_galleries_.end(); ++it) {
10202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (it->second.type == MediaGalleryPrefInfo::kAutoDetected)
10212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        result.insert(it->second.pref_id);
10222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
10232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
10242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<MediaGalleryPermission> stored_permissions =
1026868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      GetGalleryPermissionsFromPrefs(extension.id());
10272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (std::vector<MediaGalleryPermission>::const_iterator it =
10282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)           stored_permissions.begin(); it != stored_permissions.end(); ++it) {
10292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!it->has_permission) {
10302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      result.erase(it->pref_id);
10312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
10322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      MediaGalleriesPrefInfoMap::const_iterator gallery =
10332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          known_galleries_.find(it->pref_id);
10342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      DCHECK(gallery != known_galleries_.end());
10355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      if (!gallery->second.IsBlackListedType()) {
10362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        result.insert(it->pref_id);
10372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      } else {
10382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        NOTREACHED() << gallery->second.device_id;
10392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }
10402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
10412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
10422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return result;
10432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
10442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
104568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)bool MediaGalleriesPreferences::SetGalleryPermissionForExtension(
10462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const extensions::Extension& extension,
10472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MediaGalleryPrefId pref_id,
10482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool has_permission) {
10494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(IsInitialized());
10502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The gallery may not exist anymore if the user opened a second config
10512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // surface concurrently and removed it. Drop the permission update if so.
10522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MediaGalleriesPrefInfoMap::const_iterator gallery_info =
10532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      known_galleries_.find(pref_id);
10542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (gallery_info == known_galleries_.end())
105568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    return false;
10562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1057d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  bool default_permission = false;
1058d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (gallery_info->second.type == MediaGalleryPrefInfo::kAutoDetected)
1059d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    default_permission = HasAutoDetectedGalleryPermission(extension);
1060d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // When the permission matches the default, we don't need to remember it.
1061d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (has_permission == default_permission) {
1062d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    if (!UnsetGalleryPermissionInPrefs(extension.id(), pref_id))
1063d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      // If permission wasn't set, assume nothing has changed.
106468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      return false;
10652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
1066d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    if (!SetGalleryPermissionInPrefs(extension.id(), pref_id, has_permission))
106768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      return false;
10682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1069d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (has_permission)
1070d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    FOR_EACH_OBSERVER(GalleryChangeObserver,
1071d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                      gallery_change_observers_,
1072d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                      OnPermissionAdded(this, extension.id(), pref_id));
1073d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  else
1074d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    FOR_EACH_OBSERVER(GalleryChangeObserver,
1075d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                      gallery_change_observers_,
1076d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                      OnPermissionRemoved(this, extension.id(), pref_id));
107768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  return true;
10782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
10792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)const MediaGalleriesPrefInfoMap& MediaGalleriesPreferences::known_galleries()
10814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    const {
10824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(IsInitialized());
10834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return known_galleries_;
10844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
10854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
10865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::Time MediaGalleriesPreferences::GetLastScanCompletionTime() const {
10875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int64 last_scan_time_internal =
10885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      profile_->GetPrefs()->GetInt64(prefs::kMediaGalleriesLastScanTime);
10895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return base::Time::FromInternalValue(last_scan_time_internal);
10905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
10915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
10925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void MediaGalleriesPreferences::SetLastScanCompletionTime(
10935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const base::Time& time) {
10945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  profile_->GetPrefs()->SetInt64(prefs::kMediaGalleriesLastScanTime,
10955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                 time.ToInternalValue());
10965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
10975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
10982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void MediaGalleriesPreferences::Shutdown() {
1099c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  weak_factory_.InvalidateWeakPtrs();
11002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  profile_ = NULL;
11012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
11022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
11042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool MediaGalleriesPreferences::APIHasBeenUsed(Profile* profile) {
11052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MediaGalleryPrefId current_id =
11062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      profile->GetPrefs()->GetUint64(prefs::kMediaGalleriesUniqueId);
11072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return current_id != kInvalidMediaGalleryPrefId + 1;
11082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
11092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
11117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid MediaGalleriesPreferences::RegisterProfilePrefs(
1112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    user_prefs::PrefRegistrySyncable* registry) {
11132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  registry->RegisterListPref(prefs::kMediaGalleriesRememberedGalleries,
1114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                             user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
1115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  registry->RegisterUint64Pref(
1116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      prefs::kMediaGalleriesUniqueId,
1117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      kInvalidMediaGalleryPrefId + 1,
1118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
11195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  registry->RegisterInt64Pref(
11205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      prefs::kMediaGalleriesLastScanTime,
11215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::Time().ToInternalValue(),
11225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
11232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
11242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1125d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)bool MediaGalleriesPreferences::SetGalleryPermissionInPrefs(
1126868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const std::string& extension_id,
1127868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    MediaGalleryPrefId gallery_id,
1128868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    bool has_access) {
11294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(IsInitialized());
1130868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ExtensionPrefs::ScopedListUpdate update(GetExtensionPrefs(),
1131868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                          extension_id,
1132868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                          kMediaGalleriesPermissions);
11335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::ListValue* permissions = update.Get();
1134868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!permissions) {
1135868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    permissions = update.Create();
1136868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  } else {
1137868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    // If the gallery is already in the list, update the permission...
11385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    for (base::ListValue::iterator iter = permissions->begin();
1139868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)         iter != permissions->end(); ++iter) {
11405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::DictionaryValue* dict = NULL;
1141868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      if (!(*iter)->GetAsDictionary(&dict))
1142868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        continue;
1143868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      MediaGalleryPermission perm;
1144868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      if (!GetMediaGalleryPermissionFromDictionary(dict, &perm))
1145868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        continue;
1146868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      if (perm.pref_id == gallery_id) {
1147d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        if (has_access != perm.has_permission) {
1148d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)          dict->SetBoolean(kMediaGalleryHasPermissionKey, has_access);
1149d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)          return true;
1150d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        } else {
1151d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)          return false;
1152d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        }
1153868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      }
1154868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    }
1155868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
1156868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // ...Otherwise, add a new entry for the gallery.
11575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::DictionaryValue* dict = new base::DictionaryValue;
1158868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  dict->SetString(kMediaGalleryIdKey, base::Uint64ToString(gallery_id));
1159868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  dict->SetBoolean(kMediaGalleryHasPermissionKey, has_access);
1160868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  permissions->Append(dict);
1161d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  return true;
1162868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1163868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1164d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)bool MediaGalleriesPreferences::UnsetGalleryPermissionInPrefs(
1165868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const std::string& extension_id,
1166868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    MediaGalleryPrefId gallery_id) {
11674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(IsInitialized());
1168868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ExtensionPrefs::ScopedListUpdate update(GetExtensionPrefs(),
1169868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                          extension_id,
1170868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                          kMediaGalleriesPermissions);
11715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::ListValue* permissions = update.Get();
1172868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!permissions)
1173d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    return false;
1174868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
11755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  for (base::ListValue::iterator iter = permissions->begin();
1176868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)       iter != permissions->end(); ++iter) {
11775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const base::DictionaryValue* dict = NULL;
1178868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (!(*iter)->GetAsDictionary(&dict))
1179868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      continue;
1180868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    MediaGalleryPermission perm;
1181868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (!GetMediaGalleryPermissionFromDictionary(dict, &perm))
1182868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      continue;
1183868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (perm.pref_id == gallery_id) {
1184868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      permissions->Erase(iter, NULL);
1185d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      return true;
1186868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    }
1187868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
1188d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  return false;
1189868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1190868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1191868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)std::vector<MediaGalleryPermission>
1192868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)MediaGalleriesPreferences::GetGalleryPermissionsFromPrefs(
1193868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const std::string& extension_id) const {
11944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(IsInitialized());
1195868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  std::vector<MediaGalleryPermission> result;
11965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const base::ListValue* permissions;
1197868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!GetExtensionPrefs()->ReadPrefAsList(extension_id,
1198868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                           kMediaGalleriesPermissions,
1199868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                           &permissions)) {
1200868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return result;
1201868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
1202868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
12035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  for (base::ListValue::const_iterator iter = permissions->begin();
1204868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)       iter != permissions->end(); ++iter) {
12055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::DictionaryValue* dict = NULL;
1206868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (!(*iter)->GetAsDictionary(&dict))
1207868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      continue;
1208868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    MediaGalleryPermission perm;
1209868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (!GetMediaGalleryPermissionFromDictionary(dict, &perm))
1210868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      continue;
1211868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    result.push_back(perm);
1212868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
1213868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1214868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return result;
1215868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1216868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1217868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void MediaGalleriesPreferences::RemoveGalleryPermissionsFromPrefs(
1218868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    MediaGalleryPrefId gallery_id) {
12194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(IsInitialized());
1220868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ExtensionPrefs* prefs = GetExtensionPrefs();
12215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const base::DictionaryValue* extensions =
12225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      prefs->pref_service()->GetDictionary(extensions::pref_names::kExtensions);
1223868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!extensions)
1224868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return;
1225868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
12265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  for (base::DictionaryValue::Iterator iter(*extensions); !iter.IsAtEnd();
1227868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)       iter.Advance()) {
1228868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (!extensions::Extension::IdIsValid(iter.key())) {
1229868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      NOTREACHED();
1230868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      continue;
1231868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    }
1232868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    UnsetGalleryPermissionInPrefs(iter.key(), gallery_id);
1233868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
1234868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1235868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1236868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)ExtensionPrefs* MediaGalleriesPreferences::GetExtensionPrefs() const {
12374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(IsInitialized());
1238868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (extension_prefs_for_testing_)
1239868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return extension_prefs_for_testing_;
1240868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return extensions::ExtensionPrefs::Get(profile_);
1241868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1242868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1243868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void MediaGalleriesPreferences::SetExtensionPrefsForTesting(
1244868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    extensions::ExtensionPrefs* extension_prefs) {
12454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(IsInitialized());
1246868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  extension_prefs_for_testing_ = extension_prefs;
12472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1248