media_galleries_preferences.cc revision 2a99a7e74a7f215066514fe81d2bfa6639d9eddd
1// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "chrome/browser/media_galleries/media_galleries_preferences.h" 6 7#include "base/path_service.h" 8#include "base/prefs/pref_service.h" 9#include "base/stl_util.h" 10#include "base/strings/string_number_conversions.h" 11#include "base/values.h" 12#include "chrome/browser/browser_process.h" 13#include "chrome/browser/extensions/api/media_galleries_private/gallery_watch_state_tracker.h" 14#include "chrome/browser/extensions/extension_prefs.h" 15#include "chrome/browser/extensions/extension_service.h" 16#include "chrome/browser/extensions/extension_system.h" 17#include "chrome/browser/media_galleries/media_file_system_registry.h" 18#include "chrome/browser/prefs/scoped_user_pref_update.h" 19#include "chrome/browser/profiles/profile.h" 20#include "chrome/browser/storage_monitor/media_storage_util.h" 21#include "chrome/common/chrome_paths.h" 22#include "chrome/common/extensions/extension.h" 23#include "chrome/common/extensions/permissions/api_permission.h" 24#include "chrome/common/extensions/permissions/media_galleries_permission.h" 25#include "chrome/common/pref_names.h" 26#include "components/user_prefs/pref_registry_syncable.h" 27 28namespace chrome { 29 30namespace { 31 32const char kMediaGalleriesDeviceIdKey[] = "deviceId"; 33const char kMediaGalleriesDisplayNameKey[] = "displayName"; 34const char kMediaGalleriesPathKey[] = "path"; 35const char kMediaGalleriesPrefIdKey[] = "prefId"; 36const char kMediaGalleriesTypeKey[] = "type"; 37const char kMediaGalleriesVolumeLabelKey[] = "volumeLabel"; 38const char kMediaGalleriesVendorNameKey[] = "vendorName"; 39const char kMediaGalleriesModelNameKey[] = "modelName"; 40const char kMediaGalleriesSizeKey[] = "totalSize"; 41const char kMediaGalleriesLastAttachTimeKey[] = "lastAttachTime"; 42const char kMediaGalleriesPrefsVersionKey[] = "preferencesVersion"; 43 44const char kMediaGalleriesTypeAutoDetectedValue[] = "autoDetected"; 45const char kMediaGalleriesTypeUserAddedValue[] = "userAdded"; 46const char kMediaGalleriesTypeBlackListedValue[] = "blackListed"; 47 48bool GetPrefId(const DictionaryValue& dict, MediaGalleryPrefId* value) { 49 std::string string_id; 50 if (!dict.GetString(kMediaGalleriesPrefIdKey, &string_id) || 51 !base::StringToUint64(string_id, value)) { 52 return false; 53 } 54 55 return true; 56} 57 58bool GetType(const DictionaryValue& dict, MediaGalleryPrefInfo::Type* type) { 59 std::string string_type; 60 if (!dict.GetString(kMediaGalleriesTypeKey, &string_type)) 61 return false; 62 63 if (string_type == kMediaGalleriesTypeAutoDetectedValue) { 64 *type = MediaGalleryPrefInfo::kAutoDetected; 65 return true; 66 } 67 if (string_type == kMediaGalleriesTypeUserAddedValue) { 68 *type = MediaGalleryPrefInfo::kUserAdded; 69 return true; 70 } 71 if (string_type == kMediaGalleriesTypeBlackListedValue) { 72 *type = MediaGalleryPrefInfo::kBlackListed; 73 return true; 74 } 75 76 return false; 77} 78 79bool PopulateGalleryPrefInfoFromDictionary( 80 const DictionaryValue& dict, MediaGalleryPrefInfo* out_gallery_info) { 81 MediaGalleryPrefId pref_id; 82 string16 display_name; 83 std::string device_id; 84 base::FilePath::StringType path; 85 MediaGalleryPrefInfo::Type type = MediaGalleryPrefInfo::kAutoDetected; 86 string16 volume_label; 87 string16 vendor_name; 88 string16 model_name; 89 double total_size_in_bytes = 0.0; 90 double last_attach_time = 0.0; 91 bool volume_metadata_valid = false; 92 int prefs_version = 0; 93 94 if (!GetPrefId(dict, &pref_id) || 95 !dict.GetString(kMediaGalleriesDeviceIdKey, &device_id) || 96 !dict.GetString(kMediaGalleriesPathKey, &path) || 97 !GetType(dict, &type)) { 98 return false; 99 } 100 101 dict.GetString(kMediaGalleriesDisplayNameKey, &display_name); 102 dict.GetInteger(kMediaGalleriesPrefsVersionKey, &prefs_version); 103 104 if (dict.GetString(kMediaGalleriesVolumeLabelKey, &volume_label) && 105 dict.GetString(kMediaGalleriesVendorNameKey, &vendor_name) && 106 dict.GetString(kMediaGalleriesModelNameKey, &model_name) && 107 dict.GetDouble(kMediaGalleriesSizeKey, &total_size_in_bytes) && 108 dict.GetDouble(kMediaGalleriesLastAttachTimeKey, &last_attach_time)) { 109 volume_metadata_valid = true; 110 } 111 112 out_gallery_info->pref_id = pref_id; 113 out_gallery_info->display_name = display_name; 114 out_gallery_info->device_id = device_id; 115 out_gallery_info->path = base::FilePath(path); 116 out_gallery_info->type = type; 117 out_gallery_info->volume_label = volume_label; 118 out_gallery_info->vendor_name = vendor_name; 119 out_gallery_info->model_name = model_name; 120 out_gallery_info->total_size_in_bytes = total_size_in_bytes; 121 out_gallery_info->last_attach_time = 122 base::Time::FromInternalValue(last_attach_time); 123 out_gallery_info->volume_metadata_valid = volume_metadata_valid; 124 out_gallery_info->prefs_version = prefs_version; 125 126 return true; 127} 128 129DictionaryValue* CreateGalleryPrefInfoDictionary( 130 const MediaGalleryPrefInfo& gallery) { 131 DictionaryValue* dict = new DictionaryValue(); 132 dict->SetString(kMediaGalleriesPrefIdKey, 133 base::Uint64ToString(gallery.pref_id)); 134 if (!gallery.volume_metadata_valid) 135 dict->SetString(kMediaGalleriesDisplayNameKey, gallery.display_name); 136 dict->SetString(kMediaGalleriesDeviceIdKey, gallery.device_id); 137 dict->SetString(kMediaGalleriesPathKey, gallery.path.value()); 138 139 const char* type = NULL; 140 switch (gallery.type) { 141 case MediaGalleryPrefInfo::kAutoDetected: 142 type = kMediaGalleriesTypeAutoDetectedValue; 143 break; 144 case MediaGalleryPrefInfo::kUserAdded: 145 type = kMediaGalleriesTypeUserAddedValue; 146 break; 147 case MediaGalleryPrefInfo::kBlackListed: 148 type = kMediaGalleriesTypeBlackListedValue; 149 break; 150 default: 151 NOTREACHED(); 152 break; 153 } 154 dict->SetString(kMediaGalleriesTypeKey, type); 155 156 if (gallery.volume_metadata_valid) { 157 dict->SetString(kMediaGalleriesVolumeLabelKey, gallery.volume_label); 158 dict->SetString(kMediaGalleriesVendorNameKey, gallery.vendor_name); 159 dict->SetString(kMediaGalleriesModelNameKey, gallery.model_name); 160 dict->SetDouble(kMediaGalleriesSizeKey, gallery.total_size_in_bytes); 161 dict->SetDouble(kMediaGalleriesLastAttachTimeKey, 162 gallery.last_attach_time.ToInternalValue()); 163 } 164 165 // Version 0 of the prefs format was that the display_name was always 166 // used to show the user-visible name of the gallery. Version 1 means 167 // that there is an optional display_name, and when it is present, it 168 // overrides the name that would be built from the volume metadata, path, 169 // or whatever other data. So if we see a display_name with version 0, it 170 // means it may be overwritten simply by getting new volume metadata. 171 // A display_name with version 1 should not be overwritten. 172 dict->SetInteger(kMediaGalleriesPrefsVersionKey, gallery.prefs_version); 173 174 return dict; 175} 176 177bool HasAutoDetectedGalleryPermission(const extensions::Extension& extension) { 178 extensions::MediaGalleriesPermission::CheckParam param( 179 extensions::MediaGalleriesPermission::kAllAutoDetectedPermission); 180 return extension.CheckAPIPermissionWithParam( 181 extensions::APIPermission::kMediaGalleries, ¶m); 182} 183 184} // namespace 185 186MediaGalleryPrefInfo::MediaGalleryPrefInfo() 187 : pref_id(kInvalidMediaGalleryPrefId), 188 type(kInvalidType), 189 total_size_in_bytes(0), 190 volume_metadata_valid(false), 191 prefs_version(0) { 192} 193 194MediaGalleryPrefInfo::~MediaGalleryPrefInfo() {} 195 196base::FilePath MediaGalleryPrefInfo::AbsolutePath() const { 197 base::FilePath base_path = MediaStorageUtil::FindDevicePathById(device_id); 198 return base_path.empty() ? base_path : base_path.Append(path); 199} 200 201MediaGalleriesPreferences::GalleryChangeObserver::~GalleryChangeObserver() {} 202 203MediaGalleriesPreferences::MediaGalleriesPreferences(Profile* profile) 204 : profile_(profile) { 205 AddDefaultGalleriesIfFreshProfile(); 206 InitFromPrefs(false /*no notification*/); 207} 208 209MediaGalleriesPreferences::~MediaGalleriesPreferences() {} 210 211void MediaGalleriesPreferences::AddDefaultGalleriesIfFreshProfile() { 212 // Only add defaults the first time. 213 if (APIHasBeenUsed(profile_)) 214 return; 215 216 // Fresh profile case. 217 const int kDirectoryKeys[] = { 218 DIR_USER_MUSIC, 219 DIR_USER_PICTURES, 220 DIR_USER_VIDEOS, 221 }; 222 223 for (size_t i = 0; i < arraysize(kDirectoryKeys); ++i) { 224 base::FilePath path; 225 if (!PathService::Get(kDirectoryKeys[i], &path)) 226 continue; 227 228 base::FilePath relative_path; 229 StorageInfo info; 230 if (MediaStorageUtil::GetDeviceInfoFromPath(path, &info, &relative_path)) { 231 // TODO(gbillock): Add in the volume metadata here when available. 232 AddGalleryWithName(info.device_id, info.name, relative_path, 233 false /*user added*/); 234 } 235 } 236} 237 238void MediaGalleriesPreferences::InitFromPrefs(bool notify_observers) { 239 known_galleries_.clear(); 240 device_map_.clear(); 241 242 PrefService* prefs = profile_->GetPrefs(); 243 const ListValue* list = prefs->GetList( 244 prefs::kMediaGalleriesRememberedGalleries); 245 if (list) { 246 for (ListValue::const_iterator it = list->begin(); 247 it != list->end(); ++it) { 248 const DictionaryValue* dict = NULL; 249 if (!(*it)->GetAsDictionary(&dict)) 250 continue; 251 252 MediaGalleryPrefInfo gallery_info; 253 if (!PopulateGalleryPrefInfoFromDictionary(*dict, &gallery_info)) 254 continue; 255 256 known_galleries_[gallery_info.pref_id] = gallery_info; 257 device_map_[gallery_info.device_id].insert(gallery_info.pref_id); 258 } 259 } 260 if (notify_observers) 261 NotifyChangeObservers(""); 262} 263 264void MediaGalleriesPreferences::NotifyChangeObservers( 265 const std::string& extension_id) { 266 FOR_EACH_OBSERVER(GalleryChangeObserver, 267 gallery_change_observers_, 268 OnGalleryChanged(this, extension_id)); 269} 270 271void MediaGalleriesPreferences::AddGalleryChangeObserver( 272 GalleryChangeObserver* observer) { 273 gallery_change_observers_.AddObserver(observer); 274} 275 276void MediaGalleriesPreferences::RemoveGalleryChangeObserver( 277 GalleryChangeObserver* observer) { 278 gallery_change_observers_.RemoveObserver(observer); 279} 280 281void MediaGalleriesPreferences::OnRemovableStorageAttached( 282 const StorageInfo& info) { 283 if (!MediaStorageUtil::IsMediaDevice(info.device_id)) 284 return; 285 286 if (info.name.empty()) { 287 AddGallery(info.device_id, base::FilePath(info.location), 288 false /*not user added*/, 289 info.storage_label, 290 info.vendor_name, 291 info.model_name, 292 info.total_size_in_bytes, 293 base::Time::Now()); 294 } else { 295 AddGalleryWithName(info.device_id, info.name, 296 base::FilePath(info.location), false); 297 } 298} 299 300bool MediaGalleriesPreferences::LookUpGalleryByPath( 301 const base::FilePath& path, 302 MediaGalleryPrefInfo* gallery_info) const { 303 StorageInfo info; 304 base::FilePath relative_path; 305 if (!MediaStorageUtil::GetDeviceInfoFromPath(path, &info, &relative_path)) { 306 if (gallery_info) 307 *gallery_info = MediaGalleryPrefInfo(); 308 return false; 309 } 310 311 relative_path = relative_path.NormalizePathSeparators(); 312 MediaGalleryPrefIdSet galleries_on_device = 313 LookUpGalleriesByDeviceId(info.device_id); 314 for (MediaGalleryPrefIdSet::const_iterator it = galleries_on_device.begin(); 315 it != galleries_on_device.end(); 316 ++it) { 317 const MediaGalleryPrefInfo& gallery = known_galleries_.find(*it)->second; 318 if (gallery.path != relative_path) 319 continue; 320 321 if (gallery_info) 322 *gallery_info = gallery; 323 return true; 324 } 325 326 // This method is called by controller::FilesSelected when the user 327 // adds a new gallery. Control reaches here when the selected gallery is 328 // on a volume we know about, but have no gallery already for. Returns 329 // hypothetical data to the caller about what the prefs will look like 330 // if the gallery is added. 331 // TODO(gbillock): split this out into another function so it doesn't 332 // conflate LookUp. 333 if (gallery_info) { 334 gallery_info->pref_id = kInvalidMediaGalleryPrefId; 335 gallery_info->display_name = info.name; 336 gallery_info->device_id = info.device_id; 337 gallery_info->path = relative_path; 338 gallery_info->type = MediaGalleryPrefInfo::kUserAdded; 339 // TODO(gbillock): Need to add volume metadata here from |info|. 340 } 341 return false; 342} 343 344MediaGalleryPrefIdSet MediaGalleriesPreferences::LookUpGalleriesByDeviceId( 345 const std::string& device_id) const { 346 DeviceIdPrefIdsMap::const_iterator found = device_map_.find(device_id); 347 if (found == device_map_.end()) 348 return MediaGalleryPrefIdSet(); 349 return found->second; 350} 351 352base::FilePath MediaGalleriesPreferences::LookUpGalleryPathForExtension( 353 MediaGalleryPrefId gallery_id, 354 const extensions::Extension* extension, 355 bool include_unpermitted_galleries) { 356 DCHECK(extension); 357 if (!include_unpermitted_galleries && 358 !ContainsKey(GalleriesForExtension(*extension), gallery_id)) 359 return base::FilePath(); 360 361 MediaGalleriesPrefInfoMap::const_iterator it = 362 known_galleries_.find(gallery_id); 363 if (it == known_galleries_.end()) 364 return base::FilePath(); 365 return MediaStorageUtil::FindDevicePathById(it->second.device_id); 366} 367 368MediaGalleryPrefId MediaGalleriesPreferences::AddGallery( 369 const std::string& device_id, 370 const base::FilePath& relative_path, bool user_added, 371 const string16& volume_label, const string16& vendor_name, 372 const string16& model_name, uint64 total_size_in_bytes, 373 base::Time last_attach_time) { 374 return AddGalleryInternal(device_id, string16(), relative_path, user_added, 375 volume_label, vendor_name, model_name, 376 total_size_in_bytes, last_attach_time, true, 1); 377} 378 379MediaGalleryPrefId MediaGalleriesPreferences::AddGalleryWithName( 380 const std::string& device_id, const string16& display_name, 381 const base::FilePath& relative_path, bool user_added) { 382 return AddGalleryInternal(device_id, display_name, relative_path, user_added, 383 string16(), string16(), string16(), 384 0, base::Time(), false, 1); 385} 386 387MediaGalleryPrefId MediaGalleriesPreferences::AddGalleryInternal( 388 const std::string& device_id, const string16& display_name, 389 const base::FilePath& relative_path, bool user_added, 390 const string16& volume_label, const string16& vendor_name, 391 const string16& model_name, uint64 total_size_in_bytes, 392 base::Time last_attach_time, 393 bool volume_metadata_valid, 394 int prefs_version) { 395 base::FilePath normalized_relative_path = 396 relative_path.NormalizePathSeparators(); 397 MediaGalleryPrefIdSet galleries_on_device = 398 LookUpGalleriesByDeviceId(device_id); 399 for (MediaGalleryPrefIdSet::const_iterator it = galleries_on_device.begin(); 400 it != galleries_on_device.end(); 401 ++it) { 402 const MediaGalleryPrefInfo& existing = known_galleries_.find(*it)->second; 403 if (existing.path != normalized_relative_path) 404 continue; 405 406 bool update_gallery_type = 407 user_added && (existing.type == MediaGalleryPrefInfo::kBlackListed); 408 bool update_gallery_name = existing.display_name != display_name; 409 bool update_gallery_metadata = volume_metadata_valid && 410 ((existing.volume_label != volume_label) || 411 (existing.vendor_name != vendor_name) || 412 (existing.model_name != model_name) || 413 (existing.total_size_in_bytes != total_size_in_bytes) || 414 (existing.last_attach_time != last_attach_time)); 415 416 if (!update_gallery_name && !update_gallery_type && 417 !update_gallery_metadata) 418 return *it; 419 420 PrefService* prefs = profile_->GetPrefs(); 421 scoped_ptr<ListPrefUpdate> update( 422 new ListPrefUpdate(prefs, prefs::kMediaGalleriesRememberedGalleries)); 423 ListValue* list = update->Get(); 424 425 for (ListValue::const_iterator list_iter = list->begin(); 426 list_iter != list->end(); 427 ++list_iter) { 428 DictionaryValue* dict; 429 MediaGalleryPrefId iter_id; 430 if ((*list_iter)->GetAsDictionary(&dict) && 431 GetPrefId(*dict, &iter_id) && 432 *it == iter_id) { 433 if (update_gallery_type) { 434 dict->SetString(kMediaGalleriesTypeKey, 435 kMediaGalleriesTypeAutoDetectedValue); 436 } 437 if (update_gallery_name) 438 dict->SetString(kMediaGalleriesDisplayNameKey, display_name); 439 if (update_gallery_metadata) { 440 dict->SetString(kMediaGalleriesVolumeLabelKey, volume_label); 441 dict->SetString(kMediaGalleriesVendorNameKey, vendor_name); 442 dict->SetString(kMediaGalleriesModelNameKey, model_name); 443 dict->SetDouble(kMediaGalleriesSizeKey, total_size_in_bytes); 444 dict->SetDouble(kMediaGalleriesLastAttachTimeKey, 445 last_attach_time.ToInternalValue()); 446 } 447 dict->SetInteger(kMediaGalleriesPrefsVersionKey, prefs_version); 448 break; 449 } 450 } 451 452 // Commits the prefs update. 453 update.reset(); 454 455 if (update_gallery_name || update_gallery_metadata || update_gallery_type) 456 InitFromPrefs(true /* notify observers */); 457 return *it; 458 } 459 460 PrefService* prefs = profile_->GetPrefs(); 461 462 MediaGalleryPrefInfo gallery_info; 463 gallery_info.pref_id = prefs->GetUint64(prefs::kMediaGalleriesUniqueId); 464 prefs->SetUint64(prefs::kMediaGalleriesUniqueId, gallery_info.pref_id + 1); 465 gallery_info.display_name = display_name; 466 gallery_info.device_id = device_id; 467 gallery_info.path = normalized_relative_path; 468 gallery_info.type = MediaGalleryPrefInfo::kAutoDetected; 469 if (user_added) 470 gallery_info.type = MediaGalleryPrefInfo::kUserAdded; 471 if (volume_metadata_valid) { 472 gallery_info.volume_label = volume_label; 473 gallery_info.vendor_name = vendor_name; 474 gallery_info.model_name = model_name; 475 gallery_info.total_size_in_bytes = total_size_in_bytes; 476 gallery_info.last_attach_time = last_attach_time; 477 } 478 gallery_info.volume_metadata_valid = volume_metadata_valid; 479 gallery_info.prefs_version = prefs_version; 480 481 { 482 ListPrefUpdate update(prefs, prefs::kMediaGalleriesRememberedGalleries); 483 ListValue* list = update.Get(); 484 list->Append(CreateGalleryPrefInfoDictionary(gallery_info)); 485 } 486 InitFromPrefs(true /* notify observers */); 487 488 return gallery_info.pref_id; 489} 490 491MediaGalleryPrefId MediaGalleriesPreferences::AddGalleryByPath( 492 const base::FilePath& path) { 493 MediaGalleryPrefInfo gallery_info; 494 if (LookUpGalleryByPath(path, &gallery_info) && 495 gallery_info.type != MediaGalleryPrefInfo::kBlackListed) { 496 return gallery_info.pref_id; 497 } 498 return AddGalleryInternal(gallery_info.device_id, 499 gallery_info.display_name, 500 gallery_info.path, 501 true /*user added*/, 502 gallery_info.volume_label, 503 gallery_info.vendor_name, 504 gallery_info.model_name, 505 gallery_info.total_size_in_bytes, 506 gallery_info.last_attach_time, 507 gallery_info.volume_metadata_valid, 508 gallery_info.prefs_version); 509} 510 511void MediaGalleriesPreferences::ForgetGalleryById(MediaGalleryPrefId pref_id) { 512 PrefService* prefs = profile_->GetPrefs(); 513 ListPrefUpdate update(prefs, prefs::kMediaGalleriesRememberedGalleries); 514 ListValue* list = update.Get(); 515 516 if (!ContainsKey(known_galleries_, pref_id)) 517 return; 518 519 for (ListValue::iterator iter = list->begin(); iter != list->end(); ++iter) { 520 DictionaryValue* dict; 521 MediaGalleryPrefId iter_id; 522 if ((*iter)->GetAsDictionary(&dict) && GetPrefId(*dict, &iter_id) && 523 pref_id == iter_id) { 524 GetExtensionPrefs()->RemoveMediaGalleryPermissions(pref_id); 525 MediaGalleryPrefInfo::Type type; 526 if (GetType(*dict, &type) && 527 type == MediaGalleryPrefInfo::kAutoDetected) { 528 dict->SetString(kMediaGalleriesTypeKey, 529 kMediaGalleriesTypeBlackListedValue); 530 } else { 531 list->Erase(iter, NULL); 532 } 533 InitFromPrefs(true /* notify observers */); 534 return; 535 } 536 } 537} 538 539MediaGalleryPrefIdSet MediaGalleriesPreferences::GalleriesForExtension( 540 const extensions::Extension& extension) const { 541 MediaGalleryPrefIdSet result; 542 543 if (HasAutoDetectedGalleryPermission(extension)) { 544 for (MediaGalleriesPrefInfoMap::const_iterator it = 545 known_galleries_.begin(); it != known_galleries_.end(); ++it) { 546 if (it->second.type == MediaGalleryPrefInfo::kAutoDetected) 547 result.insert(it->second.pref_id); 548 } 549 } 550 551 std::vector<MediaGalleryPermission> stored_permissions = 552 GetExtensionPrefs()->GetMediaGalleryPermissions(extension.id()); 553 554 for (std::vector<MediaGalleryPermission>::const_iterator it = 555 stored_permissions.begin(); it != stored_permissions.end(); ++it) { 556 if (!it->has_permission) { 557 result.erase(it->pref_id); 558 } else { 559 MediaGalleriesPrefInfoMap::const_iterator gallery = 560 known_galleries_.find(it->pref_id); 561 DCHECK(gallery != known_galleries_.end()); 562 if (gallery->second.type != MediaGalleryPrefInfo::kBlackListed) { 563 result.insert(it->pref_id); 564 } else { 565 NOTREACHED() << gallery->second.device_id; 566 } 567 } 568 } 569 return result; 570} 571 572void MediaGalleriesPreferences::SetGalleryPermissionForExtension( 573 const extensions::Extension& extension, 574 MediaGalleryPrefId pref_id, 575 bool has_permission) { 576 // The gallery may not exist anymore if the user opened a second config 577 // surface concurrently and removed it. Drop the permission update if so. 578 MediaGalleriesPrefInfoMap::const_iterator gallery_info = 579 known_galleries_.find(pref_id); 580 if (gallery_info == known_galleries_.end()) 581 return; 582 583#if defined(ENABLE_EXTENSIONS) 584 extensions::GalleryWatchStateTracker* state_tracker = 585 extensions::GalleryWatchStateTracker::GetForProfile(profile_); 586#endif 587 bool all_permission = HasAutoDetectedGalleryPermission(extension); 588 if (has_permission && all_permission) { 589 if (gallery_info->second.type == MediaGalleryPrefInfo::kAutoDetected) { 590 GetExtensionPrefs()->UnsetMediaGalleryPermission(extension.id(), pref_id); 591 NotifyChangeObservers(extension.id()); 592#if defined(ENABLE_EXTENSIONS) 593 if (state_tracker) { 594 state_tracker->OnGalleryPermissionChanged(extension.id(), pref_id, 595 true); 596 } 597#endif 598 return; 599 } 600 } 601 602 if (!has_permission && !all_permission) { 603 GetExtensionPrefs()->UnsetMediaGalleryPermission(extension.id(), pref_id); 604 } else { 605 GetExtensionPrefs()->SetMediaGalleryPermission(extension.id(), pref_id, 606 has_permission); 607 } 608 NotifyChangeObservers(extension.id()); 609#if defined(ENABLE_EXTENSIONS) 610 if (state_tracker) { 611 state_tracker->OnGalleryPermissionChanged(extension.id(), pref_id, 612 has_permission); 613 } 614#endif 615} 616 617void MediaGalleriesPreferences::Shutdown() { 618 profile_ = NULL; 619} 620 621// static 622bool MediaGalleriesPreferences::APIHasBeenUsed(Profile* profile) { 623 MediaGalleryPrefId current_id = 624 profile->GetPrefs()->GetUint64(prefs::kMediaGalleriesUniqueId); 625 return current_id != kInvalidMediaGalleryPrefId + 1; 626} 627 628// static 629void MediaGalleriesPreferences::RegisterUserPrefs( 630 PrefRegistrySyncable* registry) { 631 registry->RegisterListPref(prefs::kMediaGalleriesRememberedGalleries, 632 PrefRegistrySyncable::UNSYNCABLE_PREF); 633 registry->RegisterUint64Pref(prefs::kMediaGalleriesUniqueId, 634 kInvalidMediaGalleryPrefId + 1, 635 PrefRegistrySyncable::UNSYNCABLE_PREF); 636} 637 638extensions::ExtensionPrefs* 639MediaGalleriesPreferences::GetExtensionPrefs() const { 640 ExtensionService* extension_service = 641 extensions::ExtensionSystem::Get(profile_)->extension_service(); 642 return extension_service->extension_prefs(); 643} 644 645} // namespace chrome 646