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// MediaGalleriesPreferences unit tests.
6
7#include "chrome/browser/media_galleries/media_galleries_preferences.h"
8
9#include <string>
10#include <vector>
11
12#include "base/command_line.h"
13#include "base/memory/ref_counted.h"
14#include "base/memory/scoped_ptr.h"
15#include "base/path_service.h"
16#include "base/prefs/scoped_user_pref_update.h"
17#include "base/run_loop.h"
18#include "base/strings/utf_string_conversions.h"
19#include "base/values.h"
20#include "chrome/browser/extensions/test_extension_system.h"
21#include "chrome/browser/media_galleries/media_file_system_registry.h"
22#include "chrome/browser/media_galleries/media_galleries_test_util.h"
23#include "chrome/common/chrome_paths.h"
24#include "chrome/common/pref_names.h"
25#include "chrome/grit/generated_resources.h"
26#include "chrome/test/base/testing_profile.h"
27#include "components/storage_monitor/media_storage_util.h"
28#include "components/storage_monitor/storage_monitor.h"
29#include "components/storage_monitor/test_storage_monitor.h"
30#include "content/public/test/test_browser_thread_bundle.h"
31#include "extensions/browser/extension_system.h"
32#include "extensions/common/extension.h"
33#include "extensions/common/manifest_handlers/background_info.h"
34#include "extensions/common/permissions/media_galleries_permission.h"
35#include "sync/api/string_ordinal.h"
36#include "testing/gtest/include/gtest/gtest.h"
37#include "ui/base/l10n/l10n_util.h"
38
39#if defined(OS_CHROMEOS)
40#include "chrome/browser/chromeos/login/users/scoped_test_user_manager.h"
41#include "chrome/browser/chromeos/settings/cros_settings.h"
42#include "chrome/browser/chromeos/settings/device_settings_service.h"
43#endif
44
45using base::ASCIIToUTF16;
46using storage_monitor::MediaStorageUtil;
47using storage_monitor::StorageInfo;
48using storage_monitor::TestStorageMonitor;
49
50namespace {
51
52class MockGalleryChangeObserver
53    : public MediaGalleriesPreferences::GalleryChangeObserver {
54 public:
55  explicit MockGalleryChangeObserver(MediaGalleriesPreferences* pref)
56      : pref_(pref),
57        notifications_(0) {}
58  virtual ~MockGalleryChangeObserver() {}
59
60  int notifications() const { return notifications_;}
61
62 private:
63  // MediaGalleriesPreferences::GalleryChangeObserver implementation.
64  virtual void OnPermissionAdded(MediaGalleriesPreferences* pref,
65                                 const std::string& extension_id,
66                                 MediaGalleryPrefId pref_id) OVERRIDE {
67    EXPECT_EQ(pref_, pref);
68    ++notifications_;
69  }
70
71  virtual void OnPermissionRemoved(MediaGalleriesPreferences* pref,
72                                   const std::string& extension_id,
73                                   MediaGalleryPrefId pref_id) OVERRIDE {
74    EXPECT_EQ(pref_, pref);
75    ++notifications_;
76  }
77
78  virtual void OnGalleryAdded(MediaGalleriesPreferences* pref,
79                              MediaGalleryPrefId pref_id) OVERRIDE {
80    EXPECT_EQ(pref_, pref);
81    ++notifications_;
82  }
83
84  virtual void OnGalleryRemoved(MediaGalleriesPreferences* pref,
85                                MediaGalleryPrefId pref_id) OVERRIDE {
86    EXPECT_EQ(pref_, pref);
87    ++notifications_;
88  }
89
90  virtual void OnGalleryInfoUpdated(MediaGalleriesPreferences* pref,
91                                    MediaGalleryPrefId pref_id) OVERRIDE {
92    EXPECT_EQ(pref_, pref);
93    ++notifications_;
94  }
95
96  MediaGalleriesPreferences* pref_;
97  int notifications_;
98
99  DISALLOW_COPY_AND_ASSIGN(MockGalleryChangeObserver);
100};
101
102}  // namespace
103
104class MediaGalleriesPreferencesTest : public testing::Test {
105 public:
106  typedef std::map<std::string /*device id*/, MediaGalleryPrefIdSet>
107      DeviceIdPrefIdsMap;
108
109  MediaGalleriesPreferencesTest()
110      : profile_(new TestingProfile()),
111        default_galleries_count_(0) {
112  }
113
114  virtual ~MediaGalleriesPreferencesTest() {
115  }
116
117  virtual void SetUp() OVERRIDE {
118    ASSERT_TRUE(TestStorageMonitor::CreateAndInstall());
119
120    extensions::TestExtensionSystem* extension_system(
121        static_cast<extensions::TestExtensionSystem*>(
122            extensions::ExtensionSystem::Get(profile_.get())));
123    extension_system->CreateExtensionService(
124        CommandLine::ForCurrentProcess(), base::FilePath(), false);
125
126    ReinitPrefsAndExpectations();
127
128    const MediaGalleriesPrefInfoMap& known_galleries =
129        gallery_prefs_->known_galleries();
130    if (!known_galleries.empty()) {
131      ASSERT_EQ(3U, known_galleries.size());
132    }
133
134    std::vector<std::string> all_permissions;
135    all_permissions.push_back(
136        extensions::MediaGalleriesPermission::kReadPermission);
137    all_permissions.push_back(
138        extensions::MediaGalleriesPermission::kAllAutoDetectedPermission);
139    std::vector<std::string> read_permissions;
140    read_permissions.push_back(
141        extensions::MediaGalleriesPermission::kReadPermission);
142
143    all_permission_extension =
144        AddMediaGalleriesApp("all", all_permissions, profile_.get());
145    regular_permission_extension =
146        AddMediaGalleriesApp("regular", read_permissions, profile_.get());
147    no_permissions_extension =
148        AddMediaGalleriesApp("no", read_permissions, profile_.get());
149  }
150
151  virtual void TearDown() OVERRIDE {
152    Verify();
153    TestStorageMonitor::Destroy();
154  }
155
156  void ChangeMediaPathOverrides() {
157    mock_gallery_locations_.ChangeMediaPathOverrides();
158  }
159
160  void ReinitPrefsAndExpectations() {
161    gallery_prefs_.reset(new MediaGalleriesPreferences(profile_.get()));
162    base::RunLoop loop;
163    gallery_prefs_->EnsureInitialized(loop.QuitClosure());
164    loop.Run();
165
166    // Load the default galleries into the expectations.
167    const MediaGalleriesPrefInfoMap& known_galleries =
168        gallery_prefs_->known_galleries();
169    if (!known_galleries.empty()) {
170      default_galleries_count_ = 3;
171      MediaGalleriesPrefInfoMap::const_iterator it;
172      for (it = known_galleries.begin(); it != known_galleries.end(); ++it) {
173        expected_galleries_[it->first] = it->second;
174        if (it->second.type == MediaGalleryPrefInfo::kAutoDetected)
175          expected_galleries_for_all.insert(it->first);
176      }
177    }
178  }
179
180  void RemovePersistedDefaultGalleryValues() {
181    PrefService* prefs = profile_->GetPrefs();
182    scoped_ptr<ListPrefUpdate> update(new ListPrefUpdate(
183        prefs, prefs::kMediaGalleriesRememberedGalleries));
184    base::ListValue* list = update->Get();
185
186    for (base::ListValue::iterator iter = list->begin();
187         iter != list->end();
188         ++iter) {
189      base::DictionaryValue* dict;
190
191      if ((*iter)->GetAsDictionary(&dict)) {
192        // Setting the prefs version to 2 which is the version before
193        // default_gallery_type was added.
194        dict->SetInteger(kMediaGalleriesPrefsVersionKey, 2);
195        dict->Remove(kMediaGalleriesDefaultGalleryTypeKey, NULL);
196      }
197    }
198    update.reset();
199  }
200
201  void Verify() {
202    const MediaGalleriesPrefInfoMap& known_galleries =
203        gallery_prefs_->known_galleries();
204    EXPECT_EQ(expected_galleries_.size(), known_galleries.size());
205    for (MediaGalleriesPrefInfoMap::const_iterator it = known_galleries.begin();
206         it != known_galleries.end();
207         ++it) {
208      VerifyGalleryInfo(it->second, it->first);
209      if (it->second.type != MediaGalleryPrefInfo::kAutoDetected &&
210          it->second.type != MediaGalleryPrefInfo::kBlackListed) {
211        if (!ContainsKey(expected_galleries_for_all, it->first) &&
212            !ContainsKey(expected_galleries_for_regular, it->first)) {
213          EXPECT_FALSE(gallery_prefs_->NonAutoGalleryHasPermission(it->first));
214        } else {
215          EXPECT_TRUE(gallery_prefs_->NonAutoGalleryHasPermission(it->first));
216        }
217      }
218    }
219
220    for (DeviceIdPrefIdsMap::const_iterator it = expected_device_map.begin();
221         it != expected_device_map.end();
222         ++it) {
223      MediaGalleryPrefIdSet actual_id_set =
224          gallery_prefs_->LookUpGalleriesByDeviceId(it->first);
225      EXPECT_EQ(it->second, actual_id_set);
226    }
227
228    std::set<MediaGalleryPrefId> galleries_for_all =
229        gallery_prefs_->GalleriesForExtension(*all_permission_extension.get());
230    EXPECT_EQ(expected_galleries_for_all, galleries_for_all);
231
232    std::set<MediaGalleryPrefId> galleries_for_regular =
233        gallery_prefs_->GalleriesForExtension(
234            *regular_permission_extension.get());
235    EXPECT_EQ(expected_galleries_for_regular, galleries_for_regular);
236
237    std::set<MediaGalleryPrefId> galleries_for_no =
238        gallery_prefs_->GalleriesForExtension(*no_permissions_extension.get());
239    EXPECT_EQ(0U, galleries_for_no.size());
240  }
241
242  void VerifyGalleryInfo(const MediaGalleryPrefInfo& actual,
243                         MediaGalleryPrefId expected_id) const {
244    MediaGalleriesPrefInfoMap::const_iterator in_expectation =
245      expected_galleries_.find(expected_id);
246    ASSERT_FALSE(in_expectation == expected_galleries_.end())  << expected_id;
247    EXPECT_EQ(in_expectation->second.pref_id, actual.pref_id);
248    EXPECT_EQ(in_expectation->second.display_name, actual.display_name);
249    EXPECT_EQ(in_expectation->second.device_id, actual.device_id);
250    EXPECT_EQ(in_expectation->second.path.value(), actual.path.value());
251    EXPECT_EQ(in_expectation->second.type, actual.type);
252    EXPECT_EQ(in_expectation->second.audio_count, actual.audio_count);
253    EXPECT_EQ(in_expectation->second.image_count, actual.image_count);
254    EXPECT_EQ(in_expectation->second.video_count, actual.video_count);
255    EXPECT_EQ(
256        in_expectation->second.default_gallery_type,
257        actual.default_gallery_type);
258  }
259
260  MediaGalleriesPreferences* gallery_prefs() {
261    return gallery_prefs_.get();
262  }
263
264  uint64 default_galleries_count() {
265    return default_galleries_count_;
266  }
267
268  void AddGalleryExpectation(MediaGalleryPrefId id, base::string16 display_name,
269                             std::string device_id,
270                             base::FilePath relative_path,
271                             MediaGalleryPrefInfo::Type type) {
272    expected_galleries_[id].pref_id = id;
273    expected_galleries_[id].display_name = display_name;
274    expected_galleries_[id].device_id = device_id;
275    expected_galleries_[id].path = relative_path.NormalizePathSeparators();
276    expected_galleries_[id].type = type;
277
278    if (type == MediaGalleryPrefInfo::kAutoDetected)
279      expected_galleries_for_all.insert(id);
280
281    expected_device_map[device_id].insert(id);
282  }
283
284  void AddScanResultExpectation(MediaGalleryPrefId id,
285                                base::string16 display_name,
286                                std::string device_id,
287                                base::FilePath relative_path,
288                                int audio_count,
289                                int image_count,
290                                int video_count) {
291    AddGalleryExpectation(id, display_name, device_id, relative_path,
292                          MediaGalleryPrefInfo::kScanResult);
293    expected_galleries_[id].audio_count = audio_count;
294    expected_galleries_[id].image_count = image_count;
295    expected_galleries_[id].video_count = video_count;
296  }
297
298  MediaGalleryPrefId AddGalleryWithNameV0(const std::string& device_id,
299                                          const base::string16& display_name,
300                                          const base::FilePath& relative_path,
301                                          bool user_added) {
302    MediaGalleryPrefInfo::Type type =
303        user_added ? MediaGalleryPrefInfo::kUserAdded
304                   : MediaGalleryPrefInfo::kAutoDetected;
305    return gallery_prefs()->AddOrUpdateGalleryInternal(
306        device_id, display_name, relative_path, type,
307        base::string16(), base::string16(), base::string16(), 0, base::Time(),
308        false, 0, 0, 0, 0, MediaGalleryPrefInfo::kNotDefault);
309  }
310
311  MediaGalleryPrefId AddGalleryWithNameV1(const std::string& device_id,
312                                          const base::string16& display_name,
313                                          const base::FilePath& relative_path,
314                                          bool user_added) {
315    MediaGalleryPrefInfo::Type type =
316        user_added ? MediaGalleryPrefInfo::kUserAdded
317                   : MediaGalleryPrefInfo::kAutoDetected;
318    return gallery_prefs()->AddOrUpdateGalleryInternal(
319        device_id, display_name, relative_path, type,
320        base::string16(), base::string16(), base::string16(), 0, base::Time(),
321        false, 0, 0, 0, 1, MediaGalleryPrefInfo::kNotDefault);
322  }
323
324  MediaGalleryPrefId AddGalleryWithNameV2(const std::string& device_id,
325                                          const base::string16& display_name,
326                                          const base::FilePath& relative_path,
327                                          MediaGalleryPrefInfo::Type type) {
328    return gallery_prefs()->AddOrUpdateGalleryInternal(
329        device_id, display_name, relative_path, type,
330        base::string16(), base::string16(), base::string16(), 0, base::Time(),
331        false, 0, 0, 0, 2, MediaGalleryPrefInfo::kNotDefault);
332  }
333
334  MediaGalleryPrefId AddFixedGalleryWithExepectation(
335      const std::string& path_name, const std::string& name,
336      MediaGalleryPrefInfo::Type type) {
337    base::FilePath path = MakeMediaGalleriesTestingPath(path_name);
338    StorageInfo info;
339    base::FilePath relative_path;
340    MediaStorageUtil::GetDeviceInfoFromPath(path, &info, &relative_path);
341    base::string16 gallery_name = base::ASCIIToUTF16(name);
342    MediaGalleryPrefId id = AddGalleryWithNameV2(info.device_id(), gallery_name,
343                                                relative_path, type);
344    AddGalleryExpectation(id, gallery_name, info.device_id(), relative_path,
345                          type);
346    Verify();
347    return id;
348  }
349
350  bool UpdateDeviceIDForSingletonType(const std::string& device_id) {
351    return gallery_prefs()->UpdateDeviceIDForSingletonType(device_id);
352  }
353
354  scoped_refptr<extensions::Extension> all_permission_extension;
355  scoped_refptr<extensions::Extension> regular_permission_extension;
356  scoped_refptr<extensions::Extension> no_permissions_extension;
357
358  std::set<MediaGalleryPrefId> expected_galleries_for_all;
359  std::set<MediaGalleryPrefId> expected_galleries_for_regular;
360
361  DeviceIdPrefIdsMap expected_device_map;
362
363  MediaGalleriesPrefInfoMap expected_galleries_;
364
365 private:
366  // Needed for extension service & friends to work.
367  content::TestBrowserThreadBundle thread_bundle_;
368
369  EnsureMediaDirectoriesExists mock_gallery_locations_;
370
371#if defined(OS_CHROMEOS)
372  chromeos::ScopedTestDeviceSettingsService test_device_settings_service_;
373  chromeos::ScopedTestCrosSettings test_cros_settings_;
374  chromeos::ScopedTestUserManager test_user_manager_;
375#endif
376
377  TestStorageMonitor monitor_;
378  scoped_ptr<TestingProfile> profile_;
379  scoped_ptr<MediaGalleriesPreferences> gallery_prefs_;
380
381  uint64 default_galleries_count_;
382
383  DISALLOW_COPY_AND_ASSIGN(MediaGalleriesPreferencesTest);
384};
385
386TEST_F(MediaGalleriesPreferencesTest, GalleryManagement) {
387  MediaGalleryPrefId auto_id, user_added_id, scan_id, id;
388  base::FilePath path;
389  base::FilePath relative_path;
390  Verify();
391
392  // Add a new auto detected gallery.
393  path = MakeMediaGalleriesTestingPath("new_auto");
394  StorageInfo info;
395  MediaStorageUtil::GetDeviceInfoFromPath(path, &info, &relative_path);
396  base::string16 gallery_name = base::ASCIIToUTF16("NewAutoGallery");
397  id = AddGalleryWithNameV2(info.device_id(), gallery_name, relative_path,
398                            MediaGalleryPrefInfo::kAutoDetected);
399  EXPECT_EQ(default_galleries_count() + 1UL, id);
400  auto_id = id;
401  AddGalleryExpectation(id, gallery_name, info.device_id(), relative_path,
402                        MediaGalleryPrefInfo::kAutoDetected);
403  Verify();
404
405  // Add it as other types, nothing should happen.
406  id = AddGalleryWithNameV2(info.device_id(), gallery_name, relative_path,
407                            MediaGalleryPrefInfo::kUserAdded);
408  EXPECT_EQ(auto_id, id);
409  Verify();
410  id = AddGalleryWithNameV2(info.device_id(), gallery_name, relative_path,
411                            MediaGalleryPrefInfo::kAutoDetected);
412  EXPECT_EQ(auto_id, id);
413  Verify();
414  id = AddGalleryWithNameV2(info.device_id(), gallery_name, relative_path,
415                            MediaGalleryPrefInfo::kScanResult);
416  EXPECT_EQ(auto_id, id);
417
418  // Add a new user added gallery.
419  path = MakeMediaGalleriesTestingPath("new_user");
420  MediaStorageUtil::GetDeviceInfoFromPath(path, &info, &relative_path);
421  gallery_name = base::ASCIIToUTF16("NewUserGallery");
422  id = AddGalleryWithNameV2(info.device_id(), gallery_name, relative_path,
423                            MediaGalleryPrefInfo::kUserAdded);
424  EXPECT_EQ(default_galleries_count() + 2UL, id);
425  user_added_id = id;
426  const std::string user_added_device_id = info.device_id();
427  AddGalleryExpectation(id, gallery_name, info.device_id(), relative_path,
428                        MediaGalleryPrefInfo::kUserAdded);
429  Verify();
430
431  // Add it as other types, nothing should happen.
432  id = AddGalleryWithNameV2(info.device_id(), gallery_name, relative_path,
433                            MediaGalleryPrefInfo::kUserAdded);
434  EXPECT_EQ(user_added_id, id);
435  Verify();
436  id = AddGalleryWithNameV2(info.device_id(), gallery_name, relative_path,
437                            MediaGalleryPrefInfo::kAutoDetected);
438  EXPECT_EQ(user_added_id, id);
439  Verify();
440  id = AddGalleryWithNameV2(info.device_id(), gallery_name, relative_path,
441                            MediaGalleryPrefInfo::kScanResult);
442  EXPECT_EQ(user_added_id, id);
443  Verify();
444
445  // Add a new scan result gallery.
446  path = MakeMediaGalleriesTestingPath("new_scan");
447  MediaStorageUtil::GetDeviceInfoFromPath(path, &info, &relative_path);
448  gallery_name = base::ASCIIToUTF16("NewScanGallery");
449  id = AddGalleryWithNameV2(info.device_id(), gallery_name, relative_path,
450                            MediaGalleryPrefInfo::kScanResult);
451  EXPECT_EQ(default_galleries_count() + 3UL, id);
452  scan_id = id;
453  AddGalleryExpectation(id, gallery_name, info.device_id(), relative_path,
454                        MediaGalleryPrefInfo::kScanResult);
455  Verify();
456
457  // Add it as other types, nothing should happen.
458  id = AddGalleryWithNameV2(info.device_id(), gallery_name, relative_path,
459                            MediaGalleryPrefInfo::kUserAdded);
460  EXPECT_EQ(scan_id, id);
461  Verify();
462  id = AddGalleryWithNameV2(info.device_id(), gallery_name, relative_path,
463                            MediaGalleryPrefInfo::kAutoDetected);
464  EXPECT_EQ(scan_id, id);
465  Verify();
466  id = AddGalleryWithNameV2(info.device_id(), gallery_name, relative_path,
467                            MediaGalleryPrefInfo::kScanResult);
468  EXPECT_EQ(scan_id, id);
469  Verify();
470
471  // Lookup some galleries.
472  EXPECT_TRUE(gallery_prefs()->LookUpGalleryByPath(
473      MakeMediaGalleriesTestingPath("new_auto"), NULL));
474  EXPECT_TRUE(gallery_prefs()->LookUpGalleryByPath(
475      MakeMediaGalleriesTestingPath("new_user"), NULL));
476  EXPECT_TRUE(gallery_prefs()->LookUpGalleryByPath(
477      MakeMediaGalleriesTestingPath("new_scan"), NULL));
478  EXPECT_FALSE(gallery_prefs()->LookUpGalleryByPath(
479      MakeMediaGalleriesTestingPath("other"), NULL));
480
481  // Check that we always get the gallery info.
482  MediaGalleryPrefInfo gallery_info;
483  EXPECT_TRUE(gallery_prefs()->LookUpGalleryByPath(
484      MakeMediaGalleriesTestingPath("new_auto"), &gallery_info));
485  VerifyGalleryInfo(gallery_info, auto_id);
486  EXPECT_FALSE(gallery_info.volume_metadata_valid);
487  EXPECT_TRUE(gallery_prefs()->LookUpGalleryByPath(
488      MakeMediaGalleriesTestingPath("new_user"), &gallery_info));
489  VerifyGalleryInfo(gallery_info, user_added_id);
490  EXPECT_FALSE(gallery_info.volume_metadata_valid);
491  EXPECT_TRUE(gallery_prefs()->LookUpGalleryByPath(
492      MakeMediaGalleriesTestingPath("new_scan"), &gallery_info));
493  VerifyGalleryInfo(gallery_info, scan_id);
494  EXPECT_FALSE(gallery_info.volume_metadata_valid);
495
496  path = MakeMediaGalleriesTestingPath("other");
497  EXPECT_FALSE(gallery_prefs()->LookUpGalleryByPath(path, &gallery_info));
498  EXPECT_EQ(kInvalidMediaGalleryPrefId, gallery_info.pref_id);
499
500  StorageInfo other_info;
501  MediaStorageUtil::GetDeviceInfoFromPath(path, &other_info, &relative_path);
502  EXPECT_EQ(other_info.device_id(), gallery_info.device_id);
503  EXPECT_EQ(relative_path.value(), gallery_info.path.value());
504
505  // Remove an auto added gallery (i.e. make it blacklisted).
506  gallery_prefs()->ForgetGalleryById(auto_id);
507  expected_galleries_[auto_id].type = MediaGalleryPrefInfo::kBlackListed;
508  expected_galleries_for_all.erase(auto_id);
509  Verify();
510
511  // Remove a scan result (i.e. make it blacklisted).
512  gallery_prefs()->ForgetGalleryById(scan_id);
513  expected_galleries_[scan_id].type = MediaGalleryPrefInfo::kRemovedScan;
514  Verify();
515
516  // Remove a user added gallery and it should go away.
517  gallery_prefs()->ForgetGalleryById(user_added_id);
518  expected_galleries_.erase(user_added_id);
519  expected_device_map[user_added_device_id].erase(user_added_id);
520  Verify();
521}
522
523TEST_F(MediaGalleriesPreferencesTest, ForgetAndErase) {
524  MediaGalleryPrefId user_erase =
525      AddFixedGalleryWithExepectation("user_erase", "UserErase",
526                                      MediaGalleryPrefInfo::kUserAdded);
527  EXPECT_EQ(default_galleries_count() + 1UL, user_erase);
528  MediaGalleryPrefId user_forget =
529      AddFixedGalleryWithExepectation("user_forget", "UserForget",
530                                      MediaGalleryPrefInfo::kUserAdded);
531  EXPECT_EQ(default_galleries_count() + 2UL, user_forget);
532
533  MediaGalleryPrefId auto_erase =
534      AddFixedGalleryWithExepectation("auto_erase", "AutoErase",
535                                      MediaGalleryPrefInfo::kAutoDetected);
536  EXPECT_EQ(default_galleries_count() + 3UL, auto_erase);
537  MediaGalleryPrefId auto_forget =
538      AddFixedGalleryWithExepectation("auto_forget", "AutoForget",
539                                      MediaGalleryPrefInfo::kAutoDetected);
540  EXPECT_EQ(default_galleries_count() + 4UL, auto_forget);
541
542  MediaGalleryPrefId scan_erase =
543      AddFixedGalleryWithExepectation("scan_erase", "ScanErase",
544                                      MediaGalleryPrefInfo::kScanResult);
545  EXPECT_EQ(default_galleries_count() + 5UL, scan_erase);
546  MediaGalleryPrefId scan_forget =
547      AddFixedGalleryWithExepectation("scan_forget", "ScanForget",
548                                      MediaGalleryPrefInfo::kScanResult);
549  EXPECT_EQ(default_galleries_count() + 6UL, scan_forget);
550
551  Verify();
552  std::string device_id;
553
554  gallery_prefs()->ForgetGalleryById(user_forget);
555  device_id = expected_galleries_[user_forget].device_id;
556  expected_galleries_.erase(user_forget);
557  expected_device_map[device_id].erase(user_forget);
558  Verify();
559
560  gallery_prefs()->ForgetGalleryById(auto_forget);
561  expected_galleries_[auto_forget].type = MediaGalleryPrefInfo::kBlackListed;
562  expected_galleries_for_all.erase(auto_forget);
563  Verify();
564
565  gallery_prefs()->ForgetGalleryById(scan_forget);
566  expected_galleries_[scan_forget].type = MediaGalleryPrefInfo::kRemovedScan;
567  Verify();
568
569  gallery_prefs()->EraseGalleryById(user_erase);
570  device_id = expected_galleries_[user_erase].device_id;
571  expected_galleries_.erase(user_erase);
572  expected_device_map[device_id].erase(user_erase);
573  Verify();
574
575  gallery_prefs()->EraseGalleryById(auto_erase);
576  device_id = expected_galleries_[auto_erase].device_id;
577  expected_galleries_.erase(auto_erase);
578  expected_device_map[device_id].erase(auto_erase);
579  expected_galleries_for_all.erase(auto_erase);
580  Verify();
581
582  gallery_prefs()->EraseGalleryById(scan_erase);
583  device_id = expected_galleries_[scan_erase].device_id;
584  expected_galleries_.erase(scan_erase);
585  expected_device_map[device_id].erase(scan_erase);
586  Verify();
587
588  // Also erase the previously forgetten ones to check erasing blacklisted ones.
589  gallery_prefs()->EraseGalleryById(auto_forget);
590  device_id = expected_galleries_[auto_forget].device_id;
591  expected_galleries_.erase(auto_forget);
592  expected_device_map[device_id].erase(auto_forget);
593  Verify();
594
595  gallery_prefs()->EraseGalleryById(scan_forget);
596  device_id = expected_galleries_[scan_forget].device_id;
597  expected_galleries_.erase(scan_forget);
598  expected_device_map[device_id].erase(scan_forget);
599  Verify();
600}
601
602TEST_F(MediaGalleriesPreferencesTest, AddGalleryWithVolumeMetadata) {
603  MediaGalleryPrefId id;
604  StorageInfo info;
605  base::FilePath path;
606  base::FilePath relative_path;
607  base::Time now = base::Time::Now();
608  Verify();
609
610  // Add a new auto detected gallery.
611  path = MakeMediaGalleriesTestingPath("new_auto");
612  MediaStorageUtil::GetDeviceInfoFromPath(path, &info, &relative_path);
613  id = gallery_prefs()->AddGallery(info.device_id(), relative_path,
614                                   MediaGalleryPrefInfo::kAutoDetected,
615                                   ASCIIToUTF16("volume label"),
616                                   ASCIIToUTF16("vendor name"),
617                                   ASCIIToUTF16("model name"),
618                                   1000000ULL, now, 0, 0, 0);
619  EXPECT_EQ(default_galleries_count() + 1UL, id);
620  AddGalleryExpectation(id, base::string16(), info.device_id(), relative_path,
621                        MediaGalleryPrefInfo::kAutoDetected);
622  Verify();
623
624  MediaGalleryPrefInfo gallery_info;
625  EXPECT_TRUE(gallery_prefs()->LookUpGalleryByPath(
626      MakeMediaGalleriesTestingPath("new_auto"), &gallery_info));
627  EXPECT_TRUE(gallery_info.volume_metadata_valid);
628  EXPECT_EQ(ASCIIToUTF16("volume label"), gallery_info.volume_label);
629  EXPECT_EQ(ASCIIToUTF16("vendor name"), gallery_info.vendor_name);
630  EXPECT_EQ(ASCIIToUTF16("model name"), gallery_info.model_name);
631  EXPECT_EQ(1000000ULL, gallery_info.total_size_in_bytes);
632  // Note: we put the microseconds time into a double, so there'll
633  // be some possible rounding errors. If it's less than 100, we don't
634  // care.
635  EXPECT_LE(std::abs(now.ToInternalValue() -
636                     gallery_info.last_attach_time.ToInternalValue()),
637            100);
638}
639
640TEST_F(MediaGalleriesPreferencesTest, ReplaceGalleryWithVolumeMetadata) {
641  MediaGalleryPrefId id, metadata_id;
642  base::FilePath path;
643  StorageInfo info;
644  base::FilePath relative_path;
645  base::Time now = base::Time::Now();
646  Verify();
647
648  // Add an auto detected gallery in the prefs version 0 format.
649  path = MakeMediaGalleriesTestingPath("new_auto");
650  MediaStorageUtil::GetDeviceInfoFromPath(path, &info, &relative_path);
651  base::string16 gallery_name = base::ASCIIToUTF16("NewAutoGallery");
652  id = AddGalleryWithNameV0(info.device_id(), gallery_name, relative_path,
653                            false /*auto*/);
654  EXPECT_EQ(default_galleries_count() + 1UL, id);
655  AddGalleryExpectation(id, gallery_name, info.device_id(), relative_path,
656                        MediaGalleryPrefInfo::kAutoDetected);
657  Verify();
658
659  metadata_id = gallery_prefs()->AddGallery(info.device_id(),
660                                            relative_path,
661                                            MediaGalleryPrefInfo::kAutoDetected,
662                                            ASCIIToUTF16("volume label"),
663                                            ASCIIToUTF16("vendor name"),
664                                            ASCIIToUTF16("model name"),
665                                            1000000ULL, now, 0, 0, 0);
666  EXPECT_EQ(id, metadata_id);
667  AddGalleryExpectation(id, base::string16(), info.device_id(), relative_path,
668                        MediaGalleryPrefInfo::kAutoDetected);
669
670  // Make sure the display_name is set to empty now, as the metadata
671  // upgrade should set the manual override name empty.
672  Verify();
673}
674
675// Whenever an "AutoDetected" gallery is removed, it is moved to a black listed
676// state.  When the gallery is added again, the black listed state is updated
677// back to the "AutoDetected" type.
678TEST_F(MediaGalleriesPreferencesTest, AutoAddedBlackListing) {
679  MediaGalleryPrefId auto_id, id;
680  base::FilePath path;
681  StorageInfo info;
682  base::FilePath relative_path;
683  Verify();
684
685  // Add a new auto detect gallery to test with.
686  path = MakeMediaGalleriesTestingPath("new_auto");
687  MediaStorageUtil::GetDeviceInfoFromPath(path, &info, &relative_path);
688  base::string16 gallery_name = base::ASCIIToUTF16("NewAutoGallery");
689  id = AddGalleryWithNameV1(info.device_id(), gallery_name,
690                            relative_path, false /*auto*/);
691  EXPECT_EQ(default_galleries_count() + 1UL, id);
692  auto_id = id;
693  AddGalleryExpectation(id, gallery_name, info.device_id(), relative_path,
694                        MediaGalleryPrefInfo::kAutoDetected);
695  Verify();
696
697  // Remove an auto added gallery (i.e. make it blacklisted).
698  gallery_prefs()->ForgetGalleryById(auto_id);
699  expected_galleries_[auto_id].type = MediaGalleryPrefInfo::kBlackListed;
700  expected_galleries_for_all.erase(auto_id);
701  Verify();
702
703  // Try adding the gallery again automatically and it should be a no-op.
704  id = AddGalleryWithNameV1(info.device_id(), gallery_name, relative_path,
705                            false /*auto*/);
706  EXPECT_EQ(auto_id, id);
707  Verify();
708
709  // Add the gallery again as a user action.
710  id = gallery_prefs()->AddGalleryByPath(path,
711                                         MediaGalleryPrefInfo::kUserAdded);
712  EXPECT_EQ(auto_id, id);
713  AddGalleryExpectation(id, gallery_name, info.device_id(), relative_path,
714                        MediaGalleryPrefInfo::kAutoDetected);
715  Verify();
716}
717
718// Whenever a "ScanResult" gallery is removed, it is moved to a black listed
719// state.  When the gallery is added again, the black listed state is updated
720// back to the "ScanResult" type.
721TEST_F(MediaGalleriesPreferencesTest, ScanResultBlackListing) {
722  MediaGalleryPrefId scan_id, id;
723  base::FilePath path;
724  StorageInfo info;
725  base::FilePath relative_path;
726  Verify();
727
728  // Add a new scan result gallery to test with.
729  path = MakeMediaGalleriesTestingPath("new_scan");
730  MediaStorageUtil::GetDeviceInfoFromPath(path, &info, &relative_path);
731  base::string16 gallery_name = base::ASCIIToUTF16("NewScanGallery");
732  id = AddGalleryWithNameV2(info.device_id(), gallery_name, relative_path,
733                            MediaGalleryPrefInfo::kScanResult);
734  EXPECT_EQ(default_galleries_count() + 1UL, id);
735  scan_id = id;
736  AddGalleryExpectation(id, gallery_name, info.device_id(), relative_path,
737                        MediaGalleryPrefInfo::kScanResult);
738  Verify();
739
740  // Remove a scan result gallery (i.e. make it blacklisted).
741  gallery_prefs()->ForgetGalleryById(scan_id);
742  expected_galleries_[scan_id].type = MediaGalleryPrefInfo::kRemovedScan;
743  expected_galleries_for_all.erase(scan_id);
744  Verify();
745
746  // Try adding the gallery again as a scan result it should be a no-op.
747  id = AddGalleryWithNameV2(info.device_id(), gallery_name, relative_path,
748                            MediaGalleryPrefInfo::kScanResult);
749  EXPECT_EQ(scan_id, id);
750  Verify();
751
752  // Add the gallery again as a user action.
753  id = gallery_prefs()->AddGalleryByPath(path,
754                                         MediaGalleryPrefInfo::kUserAdded);
755  EXPECT_EQ(scan_id, id);
756  AddGalleryExpectation(id, gallery_name, info.device_id(), relative_path,
757                        MediaGalleryPrefInfo::kUserAdded);
758  Verify();
759}
760
761TEST_F(MediaGalleriesPreferencesTest, UpdateGalleryNameV2) {
762  // Add a new auto detect gallery to test with.
763  base::FilePath path = MakeMediaGalleriesTestingPath("new_auto");
764  StorageInfo info;
765  base::FilePath relative_path;
766  MediaStorageUtil::GetDeviceInfoFromPath(path, &info, &relative_path);
767  base::string16 gallery_name = base::ASCIIToUTF16("NewAutoGallery");
768  MediaGalleryPrefId id =
769      AddGalleryWithNameV2(info.device_id(), gallery_name, relative_path,
770                           MediaGalleryPrefInfo::kAutoDetected);
771  AddGalleryExpectation(id, gallery_name, info.device_id(), relative_path,
772                        MediaGalleryPrefInfo::kAutoDetected);
773  Verify();
774
775  // Won't override the name -- don't change any expectation.
776  gallery_name = base::string16();
777  AddGalleryWithNameV2(info.device_id(), gallery_name, relative_path,
778                       MediaGalleryPrefInfo::kAutoDetected);
779  Verify();
780
781  gallery_name = base::ASCIIToUTF16("NewName");
782  id = AddGalleryWithNameV2(info.device_id(), gallery_name, relative_path,
783                            MediaGalleryPrefInfo::kAutoDetected);
784  // Note: will really just update the existing expectation.
785  AddGalleryExpectation(id, gallery_name, info.device_id(), relative_path,
786                        MediaGalleryPrefInfo::kAutoDetected);
787  Verify();
788}
789
790TEST_F(MediaGalleriesPreferencesTest, GalleryPermissions) {
791  MediaGalleryPrefId auto_id, user_added_id, to_blacklist_id, scan_id,
792                     to_scan_remove_id, id;
793  base::FilePath path;
794  StorageInfo info;
795  base::FilePath relative_path;
796  Verify();
797
798  // Add some galleries to test with.
799  path = MakeMediaGalleriesTestingPath("new_user");
800  MediaStorageUtil::GetDeviceInfoFromPath(path, &info, &relative_path);
801  base::string16 gallery_name = base::ASCIIToUTF16("NewUserGallery");
802  id = AddGalleryWithNameV1(info.device_id(), gallery_name, relative_path,
803                            true /*user*/);
804  EXPECT_EQ(default_galleries_count() + 1UL, id);
805  user_added_id = id;
806  AddGalleryExpectation(id, gallery_name, info.device_id(), relative_path,
807                        MediaGalleryPrefInfo::kUserAdded);
808  Verify();
809
810  path = MakeMediaGalleriesTestingPath("new_auto");
811  MediaStorageUtil::GetDeviceInfoFromPath(path, &info, &relative_path);
812  gallery_name = base::ASCIIToUTF16("NewAutoGallery");
813  id = AddGalleryWithNameV1(info.device_id(), gallery_name, relative_path,
814                            false /*auto*/);
815  EXPECT_EQ(default_galleries_count() + 2UL, id);
816  auto_id = id;
817  AddGalleryExpectation(id, gallery_name, info.device_id(), relative_path,
818                        MediaGalleryPrefInfo::kAutoDetected);
819  Verify();
820
821  path = MakeMediaGalleriesTestingPath("to_blacklist");
822  MediaStorageUtil::GetDeviceInfoFromPath(path, &info, &relative_path);
823  gallery_name = base::ASCIIToUTF16("ToBlacklistGallery");
824  id = AddGalleryWithNameV1(info.device_id(), gallery_name, relative_path,
825                            false /*auto*/);
826  EXPECT_EQ(default_galleries_count() + 3UL, id);
827  to_blacklist_id = id;
828  AddGalleryExpectation(id, gallery_name, info.device_id(), relative_path,
829                        MediaGalleryPrefInfo::kAutoDetected);
830  Verify();
831
832  path = MakeMediaGalleriesTestingPath("new_scan");
833  MediaStorageUtil::GetDeviceInfoFromPath(path, &info, &relative_path);
834  gallery_name = base::ASCIIToUTF16("NewScanGallery");
835  id = AddGalleryWithNameV2(info.device_id(), gallery_name, relative_path,
836                            MediaGalleryPrefInfo::kScanResult);
837  EXPECT_EQ(default_galleries_count() + 4UL, id);
838  scan_id = id;
839  AddGalleryExpectation(id, gallery_name, info.device_id(), relative_path,
840                        MediaGalleryPrefInfo::kScanResult);
841  Verify();
842
843  path = MakeMediaGalleriesTestingPath("to_scan_remove");
844  MediaStorageUtil::GetDeviceInfoFromPath(path, &info, &relative_path);
845  gallery_name = base::ASCIIToUTF16("ToScanRemoveGallery");
846  id = AddGalleryWithNameV2(info.device_id(), gallery_name, relative_path,
847                            MediaGalleryPrefInfo::kScanResult);
848  EXPECT_EQ(default_galleries_count() + 5UL, id);
849  to_scan_remove_id = id;
850  AddGalleryExpectation(id, gallery_name, info.device_id(), relative_path,
851                        MediaGalleryPrefInfo::kScanResult);
852  Verify();
853
854  // Remove permission for all galleries from the all-permission extension.
855  gallery_prefs()->SetGalleryPermissionForExtension(
856      *all_permission_extension.get(), auto_id, false);
857  expected_galleries_for_all.erase(auto_id);
858  Verify();
859
860  gallery_prefs()->SetGalleryPermissionForExtension(
861      *all_permission_extension.get(), user_added_id, false);
862  expected_galleries_for_all.erase(user_added_id);
863  Verify();
864
865  gallery_prefs()->SetGalleryPermissionForExtension(
866      *all_permission_extension.get(), to_blacklist_id, false);
867  expected_galleries_for_all.erase(to_blacklist_id);
868  Verify();
869
870  gallery_prefs()->SetGalleryPermissionForExtension(
871      *all_permission_extension.get(), scan_id, false);
872  expected_galleries_for_all.erase(scan_id);
873  Verify();
874
875  gallery_prefs()->SetGalleryPermissionForExtension(
876      *all_permission_extension.get(), to_scan_remove_id, false);
877  expected_galleries_for_all.erase(to_scan_remove_id);
878  Verify();
879
880  // Add permission back for all galleries to the all-permission extension.
881  gallery_prefs()->SetGalleryPermissionForExtension(
882      *all_permission_extension.get(), auto_id, true);
883  expected_galleries_for_all.insert(auto_id);
884  Verify();
885
886  gallery_prefs()->SetGalleryPermissionForExtension(
887      *all_permission_extension.get(), user_added_id, true);
888  expected_galleries_for_all.insert(user_added_id);
889  Verify();
890
891  gallery_prefs()->SetGalleryPermissionForExtension(
892      *all_permission_extension.get(), to_blacklist_id, true);
893  expected_galleries_for_all.insert(to_blacklist_id);
894  Verify();
895
896  gallery_prefs()->SetGalleryPermissionForExtension(
897      *all_permission_extension.get(), scan_id, true);
898  expected_galleries_for_all.insert(scan_id);
899  Verify();
900
901  gallery_prefs()->SetGalleryPermissionForExtension(
902      *all_permission_extension.get(), to_scan_remove_id, true);
903  expected_galleries_for_all.insert(to_scan_remove_id);
904  Verify();
905
906  // Add permission for all galleries to the regular permission extension.
907  gallery_prefs()->SetGalleryPermissionForExtension(
908      *regular_permission_extension.get(), auto_id, true);
909  expected_galleries_for_regular.insert(auto_id);
910  Verify();
911
912  gallery_prefs()->SetGalleryPermissionForExtension(
913      *regular_permission_extension.get(), user_added_id, true);
914  expected_galleries_for_regular.insert(user_added_id);
915  Verify();
916
917  gallery_prefs()->SetGalleryPermissionForExtension(
918      *regular_permission_extension.get(), to_blacklist_id, true);
919  expected_galleries_for_regular.insert(to_blacklist_id);
920  Verify();
921
922  gallery_prefs()->SetGalleryPermissionForExtension(
923      *regular_permission_extension.get(), scan_id, true);
924  expected_galleries_for_regular.insert(scan_id);
925  Verify();
926
927  gallery_prefs()->SetGalleryPermissionForExtension(
928      *regular_permission_extension.get(), to_scan_remove_id, true);
929  expected_galleries_for_regular.insert(to_scan_remove_id);
930  Verify();
931
932  // Blacklist the to be black listed gallery
933  gallery_prefs()->ForgetGalleryById(to_blacklist_id);
934  expected_galleries_[to_blacklist_id].type =
935      MediaGalleryPrefInfo::kBlackListed;
936  expected_galleries_for_all.erase(to_blacklist_id);
937  expected_galleries_for_regular.erase(to_blacklist_id);
938  Verify();
939
940  gallery_prefs()->ForgetGalleryById(to_scan_remove_id);
941  expected_galleries_[to_scan_remove_id].type =
942      MediaGalleryPrefInfo::kRemovedScan;
943  expected_galleries_for_all.erase(to_scan_remove_id);
944  expected_galleries_for_regular.erase(to_scan_remove_id);
945  Verify();
946
947  // Remove permission for all galleries to the regular permission extension.
948  gallery_prefs()->SetGalleryPermissionForExtension(
949      *regular_permission_extension.get(), auto_id, false);
950  expected_galleries_for_regular.erase(auto_id);
951  Verify();
952
953  gallery_prefs()->SetGalleryPermissionForExtension(
954      *regular_permission_extension.get(), user_added_id, false);
955  expected_galleries_for_regular.erase(user_added_id);
956  Verify();
957
958  gallery_prefs()->SetGalleryPermissionForExtension(
959      *regular_permission_extension.get(), scan_id, false);
960  expected_galleries_for_regular.erase(scan_id);
961  Verify();
962
963  // Add permission for an invalid gallery id.
964  gallery_prefs()->SetGalleryPermissionForExtension(
965      *regular_permission_extension.get(), 9999L, true);
966  Verify();
967}
968
969// What an existing gallery is added again, update the gallery information if
970// needed.
971TEST_F(MediaGalleriesPreferencesTest, UpdateGalleryDetails) {
972  MediaGalleryPrefId auto_id, id;
973  base::FilePath path;
974  StorageInfo info;
975  base::FilePath relative_path;
976  Verify();
977
978  // Add a new auto detect gallery to test with.
979  path = MakeMediaGalleriesTestingPath("new_auto");
980  MediaStorageUtil::GetDeviceInfoFromPath(path, &info, &relative_path);
981  base::string16 gallery_name = base::ASCIIToUTF16("NewAutoGallery");
982  id = AddGalleryWithNameV1(info.device_id(), gallery_name,
983                            relative_path, false /*auto*/);
984  EXPECT_EQ(default_galleries_count() + 1UL, id);
985  auto_id = id;
986  AddGalleryExpectation(id, gallery_name, info.device_id(), relative_path,
987                        MediaGalleryPrefInfo::kAutoDetected);
988  Verify();
989
990  // Update the device name and add the gallery again.
991  gallery_name = base::ASCIIToUTF16("AutoGallery2");
992  id = AddGalleryWithNameV1(info.device_id(), gallery_name, relative_path,
993                            false /*auto*/);
994  EXPECT_EQ(auto_id, id);
995  AddGalleryExpectation(id, gallery_name, info.device_id(), relative_path,
996                        MediaGalleryPrefInfo::kAutoDetected);
997  Verify();
998}
999
1000TEST_F(MediaGalleriesPreferencesTest, MultipleGalleriesPerDevices) {
1001  base::FilePath path;
1002  StorageInfo info;
1003  base::FilePath relative_path;
1004  Verify();
1005
1006  // Add a regular gallery
1007  path = MakeMediaGalleriesTestingPath("new_user");
1008  MediaStorageUtil::GetDeviceInfoFromPath(path, &info, &relative_path);
1009  base::string16 gallery_name = base::ASCIIToUTF16("NewUserGallery");
1010  MediaGalleryPrefId user_added_id =
1011      AddGalleryWithNameV1(info.device_id(), gallery_name, relative_path,
1012                           true /*user*/);
1013  EXPECT_EQ(default_galleries_count() + 1UL, user_added_id);
1014  AddGalleryExpectation(user_added_id, gallery_name, info.device_id(),
1015                        relative_path, MediaGalleryPrefInfo::kUserAdded);
1016  Verify();
1017
1018  // Find it by device id and fail to find something related.
1019  MediaGalleryPrefIdSet pref_id_set;
1020  pref_id_set = gallery_prefs()->LookUpGalleriesByDeviceId(info.device_id());
1021  EXPECT_EQ(1U, pref_id_set.size());
1022  EXPECT_TRUE(pref_id_set.find(user_added_id) != pref_id_set.end());
1023
1024  MediaStorageUtil::GetDeviceInfoFromPath(
1025      MakeMediaGalleriesTestingPath("new_user/foo"), &info, &relative_path);
1026  pref_id_set = gallery_prefs()->LookUpGalleriesByDeviceId(info.device_id());
1027  EXPECT_EQ(0U, pref_id_set.size());
1028
1029  // Add some galleries on the same device.
1030  relative_path = base::FilePath(FILE_PATH_LITERAL("path1/on/device1"));
1031  gallery_name = base::ASCIIToUTF16("Device1Path1");
1032  std::string device_id = "path:device1";
1033  MediaGalleryPrefId dev1_path1_id = AddGalleryWithNameV1(
1034      device_id, gallery_name, relative_path, true /*user*/);
1035  EXPECT_EQ(default_galleries_count() + 2UL, dev1_path1_id);
1036  AddGalleryExpectation(dev1_path1_id, gallery_name, device_id, relative_path,
1037                        MediaGalleryPrefInfo::kUserAdded);
1038  Verify();
1039
1040  relative_path = base::FilePath(FILE_PATH_LITERAL("path2/on/device1"));
1041  gallery_name = base::ASCIIToUTF16("Device1Path2");
1042  MediaGalleryPrefId dev1_path2_id = AddGalleryWithNameV1(
1043      device_id, gallery_name, relative_path, true /*user*/);
1044  EXPECT_EQ(default_galleries_count() + 3UL, dev1_path2_id);
1045  AddGalleryExpectation(dev1_path2_id, gallery_name, device_id, relative_path,
1046                        MediaGalleryPrefInfo::kUserAdded);
1047  Verify();
1048
1049  relative_path = base::FilePath(FILE_PATH_LITERAL("path1/on/device2"));
1050  gallery_name = base::ASCIIToUTF16("Device2Path1");
1051  device_id = "path:device2";
1052  MediaGalleryPrefId dev2_path1_id = AddGalleryWithNameV1(
1053      device_id, gallery_name, relative_path, true /*user*/);
1054  EXPECT_EQ(default_galleries_count() + 4UL, dev2_path1_id);
1055  AddGalleryExpectation(dev2_path1_id, gallery_name, device_id, relative_path,
1056                        MediaGalleryPrefInfo::kUserAdded);
1057  Verify();
1058
1059  relative_path = base::FilePath(FILE_PATH_LITERAL("path2/on/device2"));
1060  gallery_name = base::ASCIIToUTF16("Device2Path2");
1061  MediaGalleryPrefId dev2_path2_id = AddGalleryWithNameV1(
1062      device_id, gallery_name, relative_path, true /*user*/);
1063  EXPECT_EQ(default_galleries_count() + 5UL, dev2_path2_id);
1064  AddGalleryExpectation(dev2_path2_id, gallery_name, device_id, relative_path,
1065                        MediaGalleryPrefInfo::kUserAdded);
1066  Verify();
1067
1068  // Check that adding one of them again works as expected.
1069  MediaGalleryPrefId id = AddGalleryWithNameV1(
1070      device_id, gallery_name, relative_path, true /*user*/);
1071  EXPECT_EQ(dev2_path2_id, id);
1072  Verify();
1073}
1074
1075TEST_F(MediaGalleriesPreferencesTest, GalleryChangeObserver) {
1076  // Start with one observer.
1077  MockGalleryChangeObserver observer1(gallery_prefs());
1078  gallery_prefs()->AddGalleryChangeObserver(&observer1);
1079
1080  // Add a new auto detected gallery.
1081  base::FilePath path = MakeMediaGalleriesTestingPath("new_auto");
1082  StorageInfo info;
1083  base::FilePath relative_path;
1084  MediaStorageUtil::GetDeviceInfoFromPath(path, &info, &relative_path);
1085  base::string16 gallery_name = base::ASCIIToUTF16("NewAutoGallery");
1086  MediaGalleryPrefId auto_id = AddGalleryWithNameV1(
1087      info.device_id(), gallery_name, relative_path, false /*auto*/);
1088  EXPECT_EQ(default_galleries_count() + 1UL, auto_id);
1089  AddGalleryExpectation(auto_id, gallery_name, info.device_id(),
1090                        relative_path, MediaGalleryPrefInfo::kAutoDetected);
1091  EXPECT_EQ(1, observer1.notifications());
1092
1093  // Add a second observer.
1094  MockGalleryChangeObserver observer2(gallery_prefs());
1095  gallery_prefs()->AddGalleryChangeObserver(&observer2);
1096
1097  // Add a new user added gallery.
1098  path = MakeMediaGalleriesTestingPath("new_user");
1099  MediaStorageUtil::GetDeviceInfoFromPath(path, &info, &relative_path);
1100  gallery_name = base::ASCIIToUTF16("NewUserGallery");
1101  MediaGalleryPrefId user_added_id =
1102      AddGalleryWithNameV1(info.device_id(), gallery_name, relative_path,
1103                           true /*user*/);
1104  AddGalleryExpectation(user_added_id, gallery_name, info.device_id(),
1105                        relative_path, MediaGalleryPrefInfo::kUserAdded);
1106  EXPECT_EQ(default_galleries_count() + 2UL, user_added_id);
1107  EXPECT_EQ(2, observer1.notifications());
1108  EXPECT_EQ(1, observer2.notifications());
1109
1110  // Remove the first observer.
1111  gallery_prefs()->RemoveGalleryChangeObserver(&observer1);
1112
1113  // Remove an auto added gallery (i.e. make it blacklisted).
1114  gallery_prefs()->ForgetGalleryById(auto_id);
1115  expected_galleries_[auto_id].type = MediaGalleryPrefInfo::kBlackListed;
1116  expected_galleries_for_all.erase(auto_id);
1117
1118  EXPECT_EQ(2, observer1.notifications());
1119  EXPECT_EQ(2, observer2.notifications());
1120
1121  // Remove a user added gallery and it should go away.
1122  gallery_prefs()->ForgetGalleryById(user_added_id);
1123  expected_galleries_.erase(user_added_id);
1124  expected_device_map[info.device_id()].erase(user_added_id);
1125
1126  EXPECT_EQ(2, observer1.notifications());
1127  EXPECT_EQ(3, observer2.notifications());
1128}
1129
1130TEST_F(MediaGalleriesPreferencesTest, UpdateSingletonDeviceIdType) {
1131  MediaGalleryPrefId id;
1132  base::FilePath path;
1133  Verify();
1134
1135  // Add a new auto detect gallery to test with.
1136  path = MakeMediaGalleriesTestingPath("new_auto");
1137  base::string16 gallery_name = base::ASCIIToUTF16("NewAutoGallery");
1138  std::string device_id = StorageInfo::MakeDeviceId(StorageInfo::ITUNES,
1139                                                    path.AsUTF8Unsafe());
1140  id = AddGalleryWithNameV2(device_id, gallery_name, base::FilePath(),
1141                            MediaGalleryPrefInfo::kAutoDetected);
1142  EXPECT_EQ(default_galleries_count() + 1UL, id);
1143  AddGalleryExpectation(id, gallery_name, device_id, base::FilePath(),
1144                        MediaGalleryPrefInfo::kAutoDetected);
1145  Verify();
1146
1147  // Update the device id.
1148  MockGalleryChangeObserver observer(gallery_prefs());
1149  gallery_prefs()->AddGalleryChangeObserver(&observer);
1150
1151  path = MakeMediaGalleriesTestingPath("updated_path");
1152  std::string updated_device_id =
1153      StorageInfo::MakeDeviceId(StorageInfo::ITUNES, path.AsUTF8Unsafe());
1154  EXPECT_TRUE(UpdateDeviceIDForSingletonType(updated_device_id));
1155  AddGalleryExpectation(id, gallery_name, updated_device_id, base::FilePath(),
1156                        MediaGalleryPrefInfo::kAutoDetected);
1157  expected_device_map[device_id].erase(id);
1158  expected_device_map[updated_device_id].insert(id);
1159  Verify();
1160  EXPECT_EQ(1, observer.notifications());
1161
1162  // No gallery for type.
1163  std::string new_device_id =
1164      StorageInfo::MakeDeviceId(StorageInfo::PICASA, path.AsUTF8Unsafe());
1165  EXPECT_FALSE(UpdateDeviceIDForSingletonType(new_device_id));
1166}
1167
1168TEST_F(MediaGalleriesPreferencesTest, LookupImportedGalleryByPath) {
1169  MediaGalleryPrefId id;
1170  base::FilePath path;
1171  Verify();
1172
1173  // iTunes device path points to an XML file in the library directory.
1174  path = MakeMediaGalleriesTestingPath("new_auto").AppendASCII("library.xml");
1175  base::string16 gallery_name = base::ASCIIToUTF16("NewAutoGallery");
1176  std::string device_id = StorageInfo::MakeDeviceId(StorageInfo::ITUNES,
1177                                                    path.AsUTF8Unsafe());
1178  id = AddGalleryWithNameV2(device_id, gallery_name, base::FilePath(),
1179                            MediaGalleryPrefInfo::kAutoDetected);
1180  EXPECT_EQ(default_galleries_count() + 1UL, id);
1181  AddGalleryExpectation(id, gallery_name, device_id, base::FilePath(),
1182                        MediaGalleryPrefInfo::kAutoDetected);
1183  Verify();
1184
1185  // Verify we can look up the imported gallery by its path.
1186  MediaGalleryPrefInfo gallery_info;
1187  EXPECT_TRUE(gallery_prefs()->LookUpGalleryByPath(path.DirName(),
1188                                                   &gallery_info));
1189  EXPECT_EQ(id, gallery_info.pref_id);
1190}
1191
1192TEST_F(MediaGalleriesPreferencesTest, ScanResults) {
1193  MediaGalleryPrefId id;
1194  base::FilePath path;
1195  StorageInfo info;
1196  base::FilePath relative_path;
1197  base::Time now = base::Time::Now();
1198  Verify();
1199
1200  // Add a new scan result gallery to test with.
1201  path = MakeMediaGalleriesTestingPath("new_scan");
1202  MediaStorageUtil::GetDeviceInfoFromPath(path, &info, &relative_path);
1203  id = gallery_prefs()->AddGallery(info.device_id(), relative_path,
1204                                   MediaGalleryPrefInfo::kScanResult,
1205                                   ASCIIToUTF16("volume label"),
1206                                   ASCIIToUTF16("vendor name"),
1207                                   ASCIIToUTF16("model name"),
1208                                   1000000ULL, now, 1, 2, 3);
1209  EXPECT_EQ(default_galleries_count() + 1UL, id);
1210  AddScanResultExpectation(id, base::string16(), info.device_id(),
1211                           relative_path, 1, 2, 3);
1212  Verify();
1213
1214  // Update the found media count.
1215  id = gallery_prefs()->AddGallery(info.device_id(), relative_path,
1216                                   MediaGalleryPrefInfo::kScanResult,
1217                                   ASCIIToUTF16("volume label"),
1218                                   ASCIIToUTF16("vendor name"),
1219                                   ASCIIToUTF16("model name"),
1220                                   1000000ULL, now, 4, 5, 6);
1221  EXPECT_EQ(default_galleries_count() + 1UL, id);
1222  AddScanResultExpectation(id, base::string16(), info.device_id(),
1223                           relative_path, 4, 5, 6);
1224  Verify();
1225
1226  // Remove a scan result (i.e. make it blacklisted).
1227  gallery_prefs()->ForgetGalleryById(id);
1228  expected_galleries_[id].type = MediaGalleryPrefInfo::kRemovedScan;
1229  expected_galleries_[id].audio_count = 0;
1230  expected_galleries_[id].image_count = 0;
1231  expected_galleries_[id].video_count = 0;
1232  Verify();
1233
1234  // Try adding the gallery again as a scan result it should be a no-op.
1235  id = gallery_prefs()->AddGallery(info.device_id(), relative_path,
1236                                   MediaGalleryPrefInfo::kScanResult,
1237                                   ASCIIToUTF16("volume label"),
1238                                   ASCIIToUTF16("vendor name"),
1239                                   ASCIIToUTF16("model name"),
1240                                   1000000ULL, now, 7, 8, 9);
1241  EXPECT_EQ(default_galleries_count() + 1UL, id);
1242  Verify();
1243
1244  // Add the gallery again as a user action.
1245  id = gallery_prefs()->AddGalleryByPath(path,
1246                                         MediaGalleryPrefInfo::kUserAdded);
1247  EXPECT_EQ(default_galleries_count() + 1UL, id);
1248  AddGalleryExpectation(id, base::string16(), info.device_id(), relative_path,
1249                        MediaGalleryPrefInfo::kUserAdded);
1250  Verify();
1251}
1252
1253TEST(MediaGalleriesPrefInfoTest, NameGeneration) {
1254  ASSERT_TRUE(TestStorageMonitor::CreateAndInstall());
1255
1256  MediaGalleryPrefInfo info;
1257  info.pref_id = 1;
1258  info.display_name = ASCIIToUTF16("override");
1259  info.device_id = StorageInfo::MakeDeviceId(
1260      StorageInfo::REMOVABLE_MASS_STORAGE_WITH_DCIM, "unique");
1261
1262  EXPECT_EQ(ASCIIToUTF16("override"), info.GetGalleryDisplayName());
1263
1264  info.display_name = ASCIIToUTF16("o2");
1265  EXPECT_EQ(ASCIIToUTF16("o2"), info.GetGalleryDisplayName());
1266
1267  EXPECT_EQ(l10n_util::GetStringUTF16(
1268                IDS_MEDIA_GALLERIES_DIALOG_DEVICE_NOT_ATTACHED),
1269            info.GetGalleryAdditionalDetails());
1270
1271  info.last_attach_time = base::Time::Now();
1272  EXPECT_NE(l10n_util::GetStringUTF16(
1273                IDS_MEDIA_GALLERIES_DIALOG_DEVICE_NOT_ATTACHED),
1274            info.GetGalleryAdditionalDetails());
1275  EXPECT_NE(l10n_util::GetStringUTF16(
1276                IDS_MEDIA_GALLERIES_DIALOG_DEVICE_ATTACHED),
1277            info.GetGalleryAdditionalDetails());
1278
1279  info.volume_label = ASCIIToUTF16("vol");
1280  info.vendor_name = ASCIIToUTF16("vendor");
1281  info.model_name = ASCIIToUTF16("model");
1282  EXPECT_EQ(ASCIIToUTF16("o2"), info.GetGalleryDisplayName());
1283
1284  info.display_name = base::string16();
1285  EXPECT_EQ(ASCIIToUTF16("vol"), info.GetGalleryDisplayName());
1286  info.volume_label = base::string16();
1287  EXPECT_EQ(ASCIIToUTF16("vendor, model"), info.GetGalleryDisplayName());
1288
1289  info.device_id = StorageInfo::MakeDeviceId(
1290      StorageInfo::FIXED_MASS_STORAGE, "unique");
1291  EXPECT_EQ(base::FilePath(FILE_PATH_LITERAL("unique")).AsUTF8Unsafe(),
1292            base::UTF16ToUTF8(info.GetGalleryTooltip()));
1293
1294  TestStorageMonitor::Destroy();
1295}
1296
1297TEST_F(MediaGalleriesPreferencesTest, SetsDefaultGalleryTypeField) {
1298  // Tests that default galleries (Music, Pictures, Video) have the correct
1299  // default_gallery field set.
1300
1301  // No default galleries exist on CrOS so this test isn't relevant there.
1302#if defined(OS_CHROMEOS)
1303  return;
1304#endif
1305
1306  base::FilePath music_path;
1307  base::FilePath pictures_path;
1308  base::FilePath videos_path;
1309  bool got_music_path = PathService::Get(chrome::DIR_USER_MUSIC, &music_path);
1310  bool got_pictures_path =
1311      PathService::Get(chrome::DIR_USER_PICTURES, &pictures_path);
1312  bool got_videos_path =
1313      PathService::Get(chrome::DIR_USER_VIDEOS, &videos_path);
1314
1315  int num_default_galleries = 0;
1316
1317  const MediaGalleriesPrefInfoMap& known_galleries =
1318      gallery_prefs()->known_galleries();
1319  for (MediaGalleriesPrefInfoMap::const_iterator it =
1320           known_galleries.begin();
1321       it != known_galleries.end();
1322       ++it) {
1323    if (it->second.type != MediaGalleryPrefInfo::kAutoDetected)
1324      continue;
1325
1326    std::string unique_id;
1327    if (!StorageInfo::CrackDeviceId(it->second.device_id, NULL, &unique_id))
1328      continue;
1329
1330    if (got_music_path && unique_id == music_path.AsUTF8Unsafe()) {
1331      EXPECT_EQ(MediaGalleryPrefInfo::DefaultGalleryType::kMusicDefault,
1332                it->second.default_gallery_type);
1333      num_default_galleries++;
1334    } else if (got_pictures_path && unique_id == pictures_path.AsUTF8Unsafe()) {
1335      EXPECT_EQ(MediaGalleryPrefInfo::DefaultGalleryType::kPicturesDefault,
1336                it->second.default_gallery_type);
1337      num_default_galleries++;
1338    } else if (got_videos_path && unique_id == videos_path.AsUTF8Unsafe()) {
1339      EXPECT_EQ(MediaGalleryPrefInfo::DefaultGalleryType::kVideosDefault,
1340                it->second.default_gallery_type);
1341      num_default_galleries++;
1342    } else {
1343      EXPECT_EQ(MediaGalleryPrefInfo::DefaultGalleryType::kNotDefault,
1344                it->second.default_gallery_type);
1345    }
1346  }
1347
1348  EXPECT_EQ(3, num_default_galleries);
1349}
1350
1351TEST_F(MediaGalleriesPreferencesTest, UpdatesDefaultGalleryType) {
1352  // Tests that if the path of a default gallery changed since last init,
1353  // then when the MediaGalleriesPreferences is initialized, it will
1354  // rewrite the device ID in prefs to include the new path.
1355
1356  // No default galleries exist on CrOS so this test isn't relevant there.
1357#if defined(OS_CHROMEOS)
1358  return;
1359#endif
1360
1361  base::FilePath old_music_path;
1362  base::FilePath old_pictures_path;
1363  base::FilePath old_videos_path;
1364  bool got_old_music_path =
1365      PathService::Get(chrome::DIR_USER_MUSIC, &old_music_path);
1366  bool got_old_pictures_path =
1367      PathService::Get(chrome::DIR_USER_PICTURES, &old_pictures_path);
1368  bool got_old_videos_path =
1369      PathService::Get(chrome::DIR_USER_VIDEOS, &old_videos_path);
1370
1371  bool found_music = false;
1372  bool found_pictures = false;
1373  bool found_videos = false;
1374
1375  const MediaGalleriesPrefInfoMap& old_known_galleries =
1376      gallery_prefs()->known_galleries();
1377  for (MediaGalleriesPrefInfoMap::const_iterator it =
1378           old_known_galleries.begin();
1379       it != old_known_galleries.end();
1380       ++it) {
1381    if (it->second.type == MediaGalleryPrefInfo::kAutoDetected) {
1382      std::string unique_id;
1383      if (!StorageInfo::CrackDeviceId(it->second.device_id, NULL, &unique_id))
1384        continue;
1385
1386      if (got_old_music_path &&
1387          it->second.default_gallery_type ==
1388          MediaGalleryPrefInfo::DefaultGalleryType::kMusicDefault) {
1389        EXPECT_EQ(old_music_path.AsUTF8Unsafe(), unique_id);
1390        found_music = true;
1391      } else if (got_old_pictures_path &&
1392                 it->second.default_gallery_type ==
1393                 MediaGalleryPrefInfo::DefaultGalleryType::kPicturesDefault) {
1394        EXPECT_EQ(old_pictures_path.AsUTF8Unsafe(), unique_id);
1395        found_pictures = true;
1396      } else if (got_old_videos_path &&
1397                 it->second.default_gallery_type ==
1398                 MediaGalleryPrefInfo::DefaultGalleryType::kVideosDefault) {
1399        EXPECT_EQ(old_videos_path.AsUTF8Unsafe(), unique_id);
1400        found_videos = true;
1401      }
1402    }
1403  }
1404
1405  EXPECT_TRUE(found_music);
1406  EXPECT_TRUE(found_pictures);
1407  EXPECT_TRUE(found_videos);
1408
1409  ChangeMediaPathOverrides();
1410  ReinitPrefsAndExpectations();
1411
1412  base::FilePath new_music_path;
1413  base::FilePath new_pictures_path;
1414  base::FilePath new_videos_path;
1415  bool got_new_music_path =
1416      PathService::Get(chrome::DIR_USER_MUSIC, &new_music_path);
1417  bool got_new_pictures_path =
1418      PathService::Get(chrome::DIR_USER_PICTURES, &new_pictures_path);
1419  bool got_new_videos_path =
1420      PathService::Get(chrome::DIR_USER_VIDEOS, &new_videos_path);
1421
1422  EXPECT_NE(new_music_path, old_music_path);
1423  EXPECT_NE(new_pictures_path, old_pictures_path);
1424  EXPECT_NE(new_videos_path, old_videos_path);
1425
1426  found_music = false;
1427  found_pictures = false;
1428  found_videos = false;
1429
1430  const MediaGalleriesPrefInfoMap& known_galleries =
1431      gallery_prefs()->known_galleries();
1432  for (MediaGalleriesPrefInfoMap::const_iterator it = known_galleries.begin();
1433       it != known_galleries.end();
1434       ++it) {
1435    if (it->second.type == MediaGalleryPrefInfo::kAutoDetected) {
1436      std::string unique_id;
1437      if (!StorageInfo::CrackDeviceId(it->second.device_id, NULL, &unique_id))
1438        continue;
1439
1440      if (got_new_music_path &&
1441          it->second.default_gallery_type ==
1442          MediaGalleryPrefInfo::DefaultGalleryType::kMusicDefault) {
1443        EXPECT_EQ(new_music_path.AsUTF8Unsafe(), unique_id);
1444        found_music = true;
1445      } else if (got_new_pictures_path &&
1446                 it->second.default_gallery_type ==
1447                 MediaGalleryPrefInfo::DefaultGalleryType::kPicturesDefault) {
1448        EXPECT_EQ(new_pictures_path.AsUTF8Unsafe(), unique_id);
1449        found_pictures = true;
1450      } else if (got_new_videos_path &&
1451                 it->second.default_gallery_type ==
1452                 MediaGalleryPrefInfo::DefaultGalleryType::kVideosDefault) {
1453        EXPECT_EQ(new_videos_path.AsUTF8Unsafe(), unique_id);
1454        found_videos = true;
1455      }
1456    }
1457  }
1458
1459  EXPECT_TRUE(found_music);
1460  EXPECT_TRUE(found_pictures);
1461  EXPECT_TRUE(found_videos);
1462}
1463
1464TEST_F(MediaGalleriesPreferencesTest, UpdateAddsDefaultGalleryTypeIfMissing) {
1465  // Tests that if no default_gallery_type was specified for an existing prefs
1466  // info object corresponding to a particular gallery, then when the
1467  // MediaGalleriesPreferences is initialized, it assigns the proper one.
1468
1469  // No default galleries exist on CrOS so this test isn't relevant there.
1470#if defined(OS_CHROMEOS)
1471  return;
1472#endif
1473
1474  // Add a new user added gallery.
1475  AddFixedGalleryWithExepectation("user_added", "UserAdded",
1476                                  MediaGalleryPrefInfo::kUserAdded);
1477
1478  // Remove the "default_gallery_type" field completely from the persisted data
1479  // for the prefs info object. This simulates the case where a user updated
1480  // Chrome from a version without that field to one with it.
1481  RemovePersistedDefaultGalleryValues();
1482
1483  // Reinitializing the MediaGalleriesPreferences should populate the
1484  // default_gallery_type field with the correct value for each gallery.
1485  ReinitPrefsAndExpectations();
1486
1487  base::FilePath music_path;
1488  base::FilePath pictures_path;
1489  base::FilePath videos_path;
1490  bool got_music_path = PathService::Get(chrome::DIR_USER_MUSIC, &music_path);
1491  bool got_pictures_path =
1492      PathService::Get(chrome::DIR_USER_PICTURES, &pictures_path);
1493  bool got_videos_path =
1494      PathService::Get(chrome::DIR_USER_VIDEOS, &videos_path);
1495
1496  bool found_music = false;
1497  bool found_pictures = false;
1498  bool found_videos = false;
1499  bool found_user_added = false;
1500
1501  const MediaGalleriesPrefInfoMap& known_galleries =
1502      gallery_prefs()->known_galleries();
1503  for (MediaGalleriesPrefInfoMap::const_iterator it = known_galleries.begin();
1504       it != known_galleries.end();
1505       ++it) {
1506    std::string unique_id;
1507    if (!StorageInfo::CrackDeviceId(it->second.device_id, NULL, &unique_id))
1508      continue;
1509
1510    if (got_music_path &&
1511        it->second.default_gallery_type ==
1512        MediaGalleryPrefInfo::DefaultGalleryType::kMusicDefault) {
1513      EXPECT_EQ(music_path.AsUTF8Unsafe(), unique_id);
1514      found_music = true;
1515    } else if (got_pictures_path &&
1516               it->second.default_gallery_type ==
1517               MediaGalleryPrefInfo::DefaultGalleryType::kPicturesDefault) {
1518      EXPECT_EQ(pictures_path.AsUTF8Unsafe(), unique_id);
1519      found_pictures = true;
1520    } else if (got_videos_path &&
1521               it->second.default_gallery_type ==
1522               MediaGalleryPrefInfo::DefaultGalleryType::kVideosDefault) {
1523      EXPECT_EQ(videos_path.AsUTF8Unsafe(), unique_id);
1524      found_videos = true;
1525    } else if (it->second.default_gallery_type ==
1526               MediaGalleryPrefInfo::DefaultGalleryType::kNotDefault) {
1527      found_user_added = true;
1528    }
1529  }
1530
1531  EXPECT_TRUE(found_music);
1532  EXPECT_TRUE(found_pictures);
1533  EXPECT_TRUE(found_videos);
1534  EXPECT_TRUE(found_user_added);
1535}
1536