NaCl: Update revision in DEPS, r12770 -> r12773
[chromium-blink-merge.git] / chrome / browser / media_galleries / media_file_system_registry_unittest.cc
blobdc65189a018d9444eb26683fc3abf9bea75c4ebf
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.
5 // MediaFileSystemRegistry unit tests.
7 #include <algorithm>
8 #include <set>
10 #include "base/bind_helpers.h"
11 #include "base/command_line.h"
12 #include "base/file_util.h"
13 #include "base/files/scoped_temp_dir.h"
14 #include "base/memory/ref_counted.h"
15 #include "base/memory/scoped_ptr.h"
16 #include "base/memory/scoped_vector.h"
17 #include "base/message_loop/message_loop.h"
18 #include "base/path_service.h"
19 #include "base/run_loop.h"
20 #include "base/stl_util.h"
21 #include "base/strings/stringprintf.h"
22 #include "base/strings/utf_string_conversions.h"
23 #include "base/threading/sequenced_worker_pool.h"
24 #include "base/values.h"
25 #include "chrome/browser/extensions/extension_service.h"
26 #include "chrome/browser/extensions/test_extension_system.h"
27 #include "chrome/browser/media_galleries/media_file_system_context.h"
28 #include "chrome/browser/media_galleries/media_file_system_registry.h"
29 #include "chrome/browser/media_galleries/media_galleries_preferences_factory.h"
30 #include "chrome/browser/media_galleries/media_galleries_test_util.h"
31 #include "chrome/browser/storage_monitor/removable_device_constants.h"
32 #include "chrome/browser/storage_monitor/storage_info.h"
33 #include "chrome/browser/storage_monitor/storage_monitor.h"
34 #include "chrome/browser/storage_monitor/test_storage_monitor.h"
35 #include "chrome/common/chrome_paths.h"
36 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
37 #include "chrome/test/base/testing_browser_process.h"
38 #include "chrome/test/base/testing_profile.h"
39 #include "content/public/browser/render_process_host.h"
40 #include "content/public/browser/render_process_host_factory.h"
41 #include "content/public/browser/render_view_host.h"
42 #include "content/public/browser/web_contents.h"
43 #include "content/public/test/mock_render_process_host.h"
44 #include "content/public/test/test_browser_thread.h"
45 #include "content/public/test/web_contents_tester.h"
46 #include "extensions/browser/extension_system.h"
47 #include "extensions/common/extension.h"
48 #include "sync/api/string_ordinal.h"
49 #include "testing/gtest/include/gtest/gtest.h"
51 #if defined(OS_CHROMEOS)
52 #include "chrome/browser/chromeos/login/user_manager.h"
53 #include "chrome/browser/chromeos/settings/cros_settings.h"
54 #include "chrome/browser/chromeos/settings/device_settings_service.h"
55 #endif
57 using content::BrowserThread;
59 // Not anonymous so it can be friends with MediaFileSystemRegistry.
60 class TestMediaFileSystemContext : public MediaFileSystemContext {
61 public:
62 struct FSInfo {
63 FSInfo() {}
64 FSInfo(const std::string& device_id, const base::FilePath& path,
65 const std::string& fsid);
67 bool operator<(const FSInfo& other) const;
69 std::string device_id;
70 base::FilePath path;
71 std::string fsid;
74 explicit TestMediaFileSystemContext(MediaFileSystemRegistry* registry);
75 virtual ~TestMediaFileSystemContext() {}
77 // MediaFileSystemContext implementation.
78 virtual std::string RegisterFileSystem(
79 const std::string& device_id, const base::FilePath& path) OVERRIDE;
81 virtual void RevokeFileSystem(const std::string& fsid) OVERRIDE;
83 base::FilePath GetPathForId(const std::string& fsid) const;
85 MediaFileSystemRegistry* registry() { return registry_; }
87 private:
88 std::string AddFSEntry(const std::string& device_id,
89 const base::FilePath& path);
91 MediaFileSystemRegistry* registry_;
93 // A counter used to construct mock FSIDs.
94 int fsid_;
96 // The currently allocated mock file systems.
97 std::map<std::string /*fsid*/, FSInfo> file_systems_by_id_;
100 TestMediaFileSystemContext::FSInfo::FSInfo(const std::string& device_id,
101 const base::FilePath& path,
102 const std::string& fsid)
103 : device_id(device_id),
104 path(path),
105 fsid(fsid) {
108 bool TestMediaFileSystemContext::FSInfo::operator<(const FSInfo& other) const {
109 if (device_id != other.device_id)
110 return device_id < other.device_id;
111 if (path.value() != other.path.value())
112 return path.value() < other.path.value();
113 return fsid < other.fsid;
116 TestMediaFileSystemContext::TestMediaFileSystemContext(
117 MediaFileSystemRegistry* registry)
118 : registry_(registry),
119 fsid_(0) {
120 registry_->file_system_context_.reset(this);
123 std::string TestMediaFileSystemContext::RegisterFileSystem(
124 const std::string& device_id, const base::FilePath& path) {
125 std::string fsid = AddFSEntry(device_id, path);
126 return fsid;
129 void TestMediaFileSystemContext::RevokeFileSystem(const std::string& fsid) {
130 if (!ContainsKey(file_systems_by_id_, fsid))
131 return;
132 EXPECT_EQ(1U, file_systems_by_id_.erase(fsid));
135 base::FilePath TestMediaFileSystemContext::GetPathForId(
136 const std::string& fsid) const {
137 std::map<std::string /*fsid*/, FSInfo>::const_iterator it =
138 file_systems_by_id_.find(fsid);
139 if (it == file_systems_by_id_.end())
140 return base::FilePath();
141 return it->second.path;
144 std::string TestMediaFileSystemContext::AddFSEntry(const std::string& device_id,
145 const base::FilePath& path) {
146 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
147 DCHECK(path.IsAbsolute());
148 DCHECK(!path.ReferencesParent());
150 std::string fsid = base::StringPrintf("FSID:%d", ++fsid_);
151 FSInfo info(device_id, path, fsid);
152 file_systems_by_id_[fsid] = info;
153 return fsid;
156 namespace {
158 typedef std::map<MediaGalleryPrefId, MediaFileSystemInfo> FSInfoMap;
160 void GetGalleryInfoCallback(
161 FSInfoMap* results,
162 const std::vector<MediaFileSystemInfo>& file_systems) {
163 for (size_t i = 0; i < file_systems.size(); ++i) {
164 ASSERT_FALSE(ContainsKey(*results, file_systems[i].pref_id));
165 (*results)[file_systems[i].pref_id] = file_systems[i];
169 void CheckGalleryInfo(const MediaFileSystemInfo& info,
170 TestMediaFileSystemContext* fs_context,
171 const base::FilePath& path,
172 bool removable,
173 bool media_device) {
174 EXPECT_EQ(path, info.path);
175 EXPECT_EQ(removable, info.removable);
176 EXPECT_EQ(media_device, info.media_device);
177 EXPECT_NE(0UL, info.pref_id);
179 if (removable)
180 EXPECT_NE(0UL, info.transient_device_id.size());
181 else
182 EXPECT_EQ(0UL, info.transient_device_id.size());
184 base::FilePath fsid_path = fs_context->GetPathForId(info.fsid);
185 EXPECT_EQ(path, fsid_path);
188 class MockProfileSharedRenderProcessHostFactory
189 : public content::RenderProcessHostFactory {
190 public:
191 MockProfileSharedRenderProcessHostFactory() {}
192 virtual ~MockProfileSharedRenderProcessHostFactory();
194 // RPH created with this factory are owned by it. If the RPH is destroyed
195 // for testing purposes, it must be removed from the factory first.
196 content::MockRenderProcessHost* ReleaseRPH(
197 content::BrowserContext* browser_context);
199 virtual content::RenderProcessHost* CreateRenderProcessHost(
200 content::BrowserContext* browser_context,
201 content::SiteInstance* site_instance) const OVERRIDE;
203 private:
204 typedef std::map<content::BrowserContext*, content::MockRenderProcessHost*>
205 ProfileRPHMap;
206 mutable ProfileRPHMap rph_map_;
208 DISALLOW_COPY_AND_ASSIGN(MockProfileSharedRenderProcessHostFactory);
211 class ProfileState {
212 public:
213 explicit ProfileState(
214 MockProfileSharedRenderProcessHostFactory* rph_factory);
215 ~ProfileState();
217 MediaGalleriesPreferences* GetMediaGalleriesPrefs();
219 void CheckGalleries(
220 const std::string& test,
221 const std::vector<MediaFileSystemInfo>& regular_extension_galleries,
222 const std::vector<MediaFileSystemInfo>& all_extension_galleries);
224 FSInfoMap GetGalleriesInfo(extensions::Extension* extension);
226 extensions::Extension* all_permission_extension();
227 extensions::Extension* regular_permission_extension();
228 Profile* profile();
230 void AddNameForReadCompare(const base::string16& name);
231 void AddNameForAllCompare(const base::string16& name);
233 private:
234 void CompareResults(const std::string& test,
235 const std::vector<base::string16>& names,
236 const std::vector<MediaFileSystemInfo>& expected,
237 const std::vector<MediaFileSystemInfo>& actual);
238 bool ContainsEntry(const MediaFileSystemInfo& info,
239 const std::vector<MediaFileSystemInfo>& container);
241 int GetAndClearComparisonCount();
243 int num_comparisons_;
245 scoped_ptr<TestingProfile> profile_;
247 scoped_refptr<extensions::Extension> all_permission_extension_;
248 scoped_refptr<extensions::Extension> regular_permission_extension_;
249 scoped_refptr<extensions::Extension> no_permissions_extension_;
251 scoped_ptr<content::WebContents> single_web_contents_;
252 scoped_ptr<content::WebContents> shared_web_contents1_;
253 scoped_ptr<content::WebContents> shared_web_contents2_;
255 // The RenderProcessHosts are freed when their respective WebContents /
256 // RenderViewHosts go away.
257 content::MockRenderProcessHost* single_rph_;
258 content::MockRenderProcessHost* shared_rph_;
260 std::vector<base::string16> compare_names_read_;
261 std::vector<base::string16> compare_names_all_;
263 DISALLOW_COPY_AND_ASSIGN(ProfileState);
266 base::string16 GetExpectedFolderName(const base::FilePath& path) {
267 #if defined(OS_CHROMEOS)
268 return path.BaseName().LossyDisplayName();
269 #else
270 return path.LossyDisplayName();
271 #endif
274 } // namespace
276 class MediaFileSystemRegistryTest : public ChromeRenderViewHostTestHarness {
277 public:
278 void CreateProfileState(size_t profile_count);
280 ProfileState* GetProfileState(size_t i);
282 MediaGalleriesPreferences* GetPreferences(Profile* profile);
284 base::FilePath empty_dir() {
285 return empty_dir_;
288 base::FilePath dcim_dir() {
289 return dcim_dir_;
292 TestMediaFileSystemContext* test_file_system_context() {
293 return test_file_system_context_;
296 // Create a user added gallery based on the information passed and add it to
297 // |profiles|. Returns the device id.
298 std::string AddUserGallery(StorageInfo::Type type,
299 const std::string& unique_id,
300 const base::FilePath& path);
302 // Returns the device id.
303 std::string AttachDevice(StorageInfo::Type type,
304 const std::string& unique_id,
305 const base::FilePath& location);
307 void DetachDevice(const std::string& device_id);
309 void SetGalleryPermission(ProfileState* profile_state,
310 extensions::Extension* extension,
311 const std::string& device_id,
312 bool has_access);
314 void AssertAllAutoAddedGalleries();
316 void InitForGalleriesInfoTest(FSInfoMap* galleries_info);
318 void CheckNewGalleryInfo(ProfileState* profile_state,
319 const FSInfoMap& galleries_info,
320 const base::FilePath& location,
321 bool removable,
322 bool media_device);
324 std::vector<MediaFileSystemInfo> GetAutoAddedGalleries(
325 ProfileState* profile_state);
327 void ProcessAttach(const std::string& id,
328 const base::string16& name,
329 const base::FilePath::StringType& location) {
330 StorageInfo info(id, base::string16(), location, name, base::string16(),
331 base::string16(), 0);
332 StorageMonitor::GetInstance()->receiver()->ProcessAttach(info);
335 void ProcessDetach(const std::string& id) {
336 StorageMonitor::GetInstance()->receiver()->ProcessDetach(id);
339 MediaFileSystemRegistry* registry() {
340 return test_file_system_context_->registry();
343 size_t GetExtensionGalleriesHostCount(
344 const MediaFileSystemRegistry* registry) const;
346 int num_auto_galleries() {
347 return media_directories_.num_galleries();
350 protected:
351 virtual void SetUp() OVERRIDE;
352 virtual void TearDown() OVERRIDE;
354 private:
355 // This makes sure that at least one default gallery exists on the file
356 // system.
357 EnsureMediaDirectoriesExists media_directories_;
359 // Some test gallery directories.
360 base::ScopedTempDir galleries_dir_;
361 // An empty directory in |galleries_dir_|
362 base::FilePath empty_dir_;
363 // A directory in |galleries_dir_| with a DCIM directory in it.
364 base::FilePath dcim_dir_;
366 // MediaFileSystemRegistry owns this.
367 TestMediaFileSystemContext* test_file_system_context_;
369 // Needed for extension service & friends to work.
371 #if defined(OS_CHROMEOS)
372 chromeos::ScopedTestDeviceSettingsService test_device_settings_service_;
373 chromeos::ScopedTestCrosSettings test_cros_settings_;
374 scoped_ptr<chromeos::ScopedTestUserManager> test_user_manager_;
375 #endif
377 MockProfileSharedRenderProcessHostFactory rph_factory_;
379 ScopedVector<ProfileState> profile_states_;
382 namespace {
384 bool MediaFileSystemInfoComparator(const MediaFileSystemInfo& a,
385 const MediaFileSystemInfo& b) {
386 CHECK_NE(a.name, b.name); // Name must be unique.
387 return a.name < b.name;
390 ///////////////////////////////////////////////
391 // MockProfileSharedRenderProcessHostFactory //
392 ///////////////////////////////////////////////
394 MockProfileSharedRenderProcessHostFactory::
395 ~MockProfileSharedRenderProcessHostFactory() {
396 STLDeleteValues(&rph_map_);
399 content::MockRenderProcessHost*
400 MockProfileSharedRenderProcessHostFactory::ReleaseRPH(
401 content::BrowserContext* browser_context) {
402 ProfileRPHMap::iterator existing = rph_map_.find(browser_context);
403 if (existing == rph_map_.end())
404 return NULL;
405 content::MockRenderProcessHost* result = existing->second;
406 rph_map_.erase(existing);
407 return result;
410 content::RenderProcessHost*
411 MockProfileSharedRenderProcessHostFactory::CreateRenderProcessHost(
412 content::BrowserContext* browser_context,
413 content::SiteInstance* site_instance) const {
414 ProfileRPHMap::const_iterator existing = rph_map_.find(browser_context);
415 if (existing != rph_map_.end())
416 return existing->second;
417 rph_map_[browser_context] =
418 new content::MockRenderProcessHost(browser_context);
419 return rph_map_[browser_context];
422 //////////////////
423 // ProfileState //
424 //////////////////
426 ProfileState::ProfileState(
427 MockProfileSharedRenderProcessHostFactory* rph_factory)
428 : num_comparisons_(0),
429 profile_(new TestingProfile()) {
430 extensions::TestExtensionSystem* extension_system(
431 static_cast<extensions::TestExtensionSystem*>(
432 extensions::ExtensionSystem::Get(profile_.get())));
433 extension_system->CreateExtensionService(
434 CommandLine::ForCurrentProcess(), base::FilePath(), false);
436 std::vector<std::string> all_permissions;
437 all_permissions.push_back("allAutoDetected");
438 all_permissions.push_back("read");
439 std::vector<std::string> read_permissions;
440 read_permissions.push_back("read");
442 all_permission_extension_ =
443 AddMediaGalleriesApp("all", all_permissions, profile_.get());
444 regular_permission_extension_ =
445 AddMediaGalleriesApp("regular", read_permissions, profile_.get());
446 no_permissions_extension_ =
447 AddMediaGalleriesApp("no", read_permissions, profile_.get());
449 single_web_contents_.reset(
450 content::WebContentsTester::CreateTestWebContents(profile_.get(), NULL));
451 single_rph_ = rph_factory->ReleaseRPH(profile_.get());
453 shared_web_contents1_.reset(
454 content::WebContentsTester::CreateTestWebContents(profile_.get(), NULL));
455 shared_web_contents2_.reset(
456 content::WebContentsTester::CreateTestWebContents(profile_.get(), NULL));
457 shared_rph_ = rph_factory->ReleaseRPH(profile_.get());
460 ProfileState::~ProfileState() {
461 // TestExtensionSystem uses DeleteSoon, so we need to delete the profiles
462 // and then run the message queue to clean up. But first we have to
463 // delete everything that references the profile.
464 single_web_contents_.reset();
465 shared_web_contents1_.reset();
466 shared_web_contents2_.reset();
467 profile_.reset();
469 base::MessageLoop::current()->RunUntilIdle();
472 MediaGalleriesPreferences* ProfileState::GetMediaGalleriesPrefs() {
473 MediaGalleriesPreferences* prefs =
474 MediaGalleriesPreferencesFactory::GetForProfile(profile_.get());
475 base::RunLoop loop;
476 prefs->EnsureInitialized(loop.QuitClosure());
477 loop.Run();
478 return prefs;
481 void ProfileState::CheckGalleries(
482 const std::string& test,
483 const std::vector<MediaFileSystemInfo>& regular_extension_galleries,
484 const std::vector<MediaFileSystemInfo>& all_extension_galleries) {
485 content::RenderViewHost* rvh = single_web_contents_->GetRenderViewHost();
486 MediaFileSystemRegistry* registry =
487 g_browser_process->media_file_system_registry();
489 // No Media Galleries permissions.
490 std::vector<MediaFileSystemInfo> empty_expectation;
491 std::vector<base::string16> empty_names;
492 registry->GetMediaFileSystemsForExtension(
493 rvh, no_permissions_extension_.get(),
494 base::Bind(&ProfileState::CompareResults, base::Unretained(this),
495 base::StringPrintf("%s (no permission)", test.c_str()),
496 base::ConstRef(empty_names),
497 base::ConstRef(empty_expectation)));
498 base::MessageLoop::current()->RunUntilIdle();
499 EXPECT_EQ(1, GetAndClearComparisonCount());
501 // Read permission only.
502 registry->GetMediaFileSystemsForExtension(
503 rvh, regular_permission_extension_.get(),
504 base::Bind(&ProfileState::CompareResults, base::Unretained(this),
505 base::StringPrintf("%s (regular permission)", test.c_str()),
506 base::ConstRef(compare_names_read_),
507 base::ConstRef(regular_extension_galleries)));
508 base::MessageLoop::current()->RunUntilIdle();
509 EXPECT_EQ(1, GetAndClearComparisonCount());
511 // All galleries permission.
512 registry->GetMediaFileSystemsForExtension(
513 rvh, all_permission_extension_.get(),
514 base::Bind(&ProfileState::CompareResults, base::Unretained(this),
515 base::StringPrintf("%s (all permission)", test.c_str()),
516 base::ConstRef(compare_names_all_),
517 base::ConstRef(all_extension_galleries)));
518 base::MessageLoop::current()->RunUntilIdle();
519 EXPECT_EQ(1, GetAndClearComparisonCount());
522 FSInfoMap ProfileState::GetGalleriesInfo(extensions::Extension* extension) {
523 content::RenderViewHost* rvh = single_web_contents_->GetRenderViewHost();
524 FSInfoMap results;
525 MediaFileSystemRegistry* registry =
526 g_browser_process->media_file_system_registry();
527 registry->GetMediaFileSystemsForExtension(
528 rvh, extension,
529 base::Bind(&GetGalleryInfoCallback, base::Unretained(&results)));
530 base::MessageLoop::current()->RunUntilIdle();
531 return results;
534 extensions::Extension* ProfileState::all_permission_extension() {
535 return all_permission_extension_.get();
538 extensions::Extension* ProfileState::regular_permission_extension() {
539 return regular_permission_extension_.get();
542 Profile* ProfileState::profile() {
543 return profile_.get();
546 void ProfileState::AddNameForReadCompare(const base::string16& name) {
547 compare_names_read_.push_back(name);
550 void ProfileState::AddNameForAllCompare(const base::string16& name) {
551 compare_names_all_.push_back(name);
554 bool ProfileState::ContainsEntry(
555 const MediaFileSystemInfo& info,
556 const std::vector<MediaFileSystemInfo>& container) {
557 for (size_t i = 0; i < container.size(); ++i) {
558 if (info.path.value() == container[i].path.value()) {
559 EXPECT_FALSE(container[i].fsid.empty());
560 if (!info.fsid.empty())
561 EXPECT_EQ(info.fsid, container[i].fsid);
562 return true;
565 return false;
568 void ProfileState::CompareResults(
569 const std::string& test,
570 const std::vector<base::string16>& names,
571 const std::vector<MediaFileSystemInfo>& expected,
572 const std::vector<MediaFileSystemInfo>& actual) {
573 num_comparisons_++;
574 EXPECT_EQ(expected.size(), actual.size()) << test;
576 // Order isn't important, so sort the results.
577 std::vector<MediaFileSystemInfo> sorted(actual);
578 std::sort(sorted.begin(), sorted.end(), MediaFileSystemInfoComparator);
579 std::vector<MediaFileSystemInfo> expect(expected);
580 std::sort(expect.begin(), expect.end(), MediaFileSystemInfoComparator);
581 std::vector<base::string16> expect_names(names);
582 std::sort(expect_names.begin(), expect_names.end());
584 for (size_t i = 0; i < expect.size() && i < sorted.size(); ++i) {
585 if (expect_names.size() > i)
586 EXPECT_EQ(expect_names[i], sorted[i].name) << test;
587 EXPECT_TRUE(ContainsEntry(expect[i], sorted)) << test;
591 int ProfileState::GetAndClearComparisonCount() {
592 int result = num_comparisons_;
593 num_comparisons_ = 0;
594 return result;
597 } // namespace
599 /////////////////////////////////
600 // MediaFileSystemRegistryTest //
601 /////////////////////////////////
603 void MediaFileSystemRegistryTest::CreateProfileState(size_t profile_count) {
604 for (size_t i = 0; i < profile_count; ++i) {
605 ProfileState* state = new ProfileState(&rph_factory_);
606 profile_states_.push_back(state);
610 ProfileState* MediaFileSystemRegistryTest::GetProfileState(size_t i) {
611 return profile_states_[i];
614 MediaGalleriesPreferences* MediaFileSystemRegistryTest::GetPreferences(
615 Profile* profile) {
616 MediaGalleriesPreferences* prefs = registry()->GetPreferences(profile);
617 base::RunLoop loop;
618 prefs->EnsureInitialized(loop.QuitClosure());
619 loop.Run();
620 return prefs;
623 std::string MediaFileSystemRegistryTest::AddUserGallery(
624 StorageInfo::Type type,
625 const std::string& unique_id,
626 const base::FilePath& path) {
627 std::string device_id = StorageInfo::MakeDeviceId(type, unique_id);
628 DCHECK(!StorageInfo::IsMediaDevice(device_id));
630 for (size_t i = 0; i < profile_states_.size(); ++i) {
631 profile_states_[i]->GetMediaGalleriesPrefs()->AddGallery(
632 device_id, base::FilePath(), MediaGalleryPrefInfo::kUserAdded,
633 base::string16(), base::string16(), base::string16(), 0,
634 base::Time::Now(), 0, 0, 0);
636 return device_id;
639 std::string MediaFileSystemRegistryTest::AttachDevice(
640 StorageInfo::Type type,
641 const std::string& unique_id,
642 const base::FilePath& location) {
643 std::string device_id = StorageInfo::MakeDeviceId(type, unique_id);
644 DCHECK(StorageInfo::IsRemovableDevice(device_id));
645 base::string16 label = location.BaseName().LossyDisplayName();
646 ProcessAttach(device_id, label, location.value());
647 base::MessageLoop::current()->RunUntilIdle();
648 return device_id;
651 void MediaFileSystemRegistryTest::DetachDevice(const std::string& device_id) {
652 DCHECK(StorageInfo::IsRemovableDevice(device_id));
653 ProcessDetach(device_id);
654 base::MessageLoop::current()->RunUntilIdle();
657 void MediaFileSystemRegistryTest::SetGalleryPermission(
658 ProfileState* profile_state, extensions::Extension* extension,
659 const std::string& device_id, bool has_access) {
660 MediaGalleriesPreferences* preferences =
661 profile_state->GetMediaGalleriesPrefs();
662 MediaGalleryPrefIdSet pref_id =
663 preferences->LookUpGalleriesByDeviceId(device_id);
664 ASSERT_EQ(1U, pref_id.size());
665 preferences->SetGalleryPermissionForExtension(*extension, *pref_id.begin(),
666 has_access);
669 void MediaFileSystemRegistryTest::AssertAllAutoAddedGalleries() {
670 for (size_t i = 0; i < profile_states_.size(); ++i) {
671 MediaGalleriesPreferences* prefs =
672 profile_states_[0]->GetMediaGalleriesPrefs();
674 // Make sure that we have at least one gallery and that they are all
675 // auto added galleries.
676 const MediaGalleriesPrefInfoMap& galleries = prefs->known_galleries();
677 #if !defined(OS_CHROMEOS) && !defined(OS_ANDROID)
678 ASSERT_GT(galleries.size(), 0U);
679 #endif
680 for (MediaGalleriesPrefInfoMap::const_iterator it = galleries.begin();
681 it != galleries.end();
682 ++it) {
683 ASSERT_EQ(MediaGalleryPrefInfo::kAutoDetected, it->second.type);
688 void MediaFileSystemRegistryTest::InitForGalleriesInfoTest(
689 FSInfoMap* galleries_info) {
690 CreateProfileState(1);
691 AssertAllAutoAddedGalleries();
693 // Get all existing gallery names.
694 ProfileState* profile_state = GetProfileState(0U);
695 *galleries_info = profile_state->GetGalleriesInfo(
696 profile_state->all_permission_extension());
697 #if !defined(OS_CHROMEOS) && !defined(OS_ANDROID)
698 ASSERT_EQ(3U, galleries_info->size());
699 #else
700 ASSERT_EQ(0U, galleries_info->size());
701 #endif
704 void MediaFileSystemRegistryTest::CheckNewGalleryInfo(
705 ProfileState* profile_state,
706 const FSInfoMap& galleries_info,
707 const base::FilePath& location,
708 bool removable,
709 bool media_device) {
710 // Get new galleries.
711 FSInfoMap new_galleries_info = profile_state->GetGalleriesInfo(
712 profile_state->all_permission_extension());
713 ASSERT_EQ(galleries_info.size() + 1U, new_galleries_info.size());
715 bool found_new = false;
716 for (FSInfoMap::const_iterator it = new_galleries_info.begin();
717 it != new_galleries_info.end();
718 ++it) {
719 if (ContainsKey(galleries_info, it->first))
720 continue;
722 ASSERT_FALSE(found_new);
723 CheckGalleryInfo(it->second, test_file_system_context_, location,
724 removable, media_device);
725 found_new = true;
727 ASSERT_TRUE(found_new);
730 std::vector<MediaFileSystemInfo>
731 MediaFileSystemRegistryTest::GetAutoAddedGalleries(
732 ProfileState* profile_state) {
733 const MediaGalleriesPrefInfoMap& galleries =
734 profile_state->GetMediaGalleriesPrefs()->known_galleries();
735 std::vector<MediaFileSystemInfo> result;
736 for (MediaGalleriesPrefInfoMap::const_iterator it = galleries.begin();
737 it != galleries.end();
738 ++it) {
739 if (it->second.type == MediaGalleryPrefInfo::kAutoDetected) {
740 base::FilePath path = it->second.AbsolutePath();
741 MediaFileSystemInfo info(path.BaseName().LossyDisplayName(), path,
742 std::string(), 0, std::string(), false, false);
743 result.push_back(info);
746 std::sort(result.begin(), result.end(), MediaFileSystemInfoComparator);
747 return result;
750 size_t MediaFileSystemRegistryTest::GetExtensionGalleriesHostCount(
751 const MediaFileSystemRegistry* registry) const {
752 size_t extension_galleries_host_count = 0;
753 for (MediaFileSystemRegistry::ExtensionGalleriesHostMap::const_iterator it =
754 registry->extension_hosts_map_.begin();
755 it != registry->extension_hosts_map_.end();
756 ++it) {
757 extension_galleries_host_count += it->second.size();
759 return extension_galleries_host_count;
763 void MediaFileSystemRegistryTest::SetUp() {
764 ChromeRenderViewHostTestHarness::SetUp();
765 ASSERT_TRUE(TestStorageMonitor::CreateAndInstall());
767 DeleteContents();
768 SetRenderProcessHostFactory(&rph_factory_);
770 test_file_system_context_ = new TestMediaFileSystemContext(
771 g_browser_process->media_file_system_registry());
773 #if defined(OS_CHROMEOS)
774 test_user_manager_.reset(new chromeos::ScopedTestUserManager());
775 #endif
777 ASSERT_TRUE(galleries_dir_.CreateUniqueTempDir());
778 empty_dir_ = galleries_dir_.path().AppendASCII("empty");
779 ASSERT_TRUE(base::CreateDirectory(empty_dir_));
780 dcim_dir_ = galleries_dir_.path().AppendASCII("with_dcim");
781 ASSERT_TRUE(base::CreateDirectory(dcim_dir_));
782 ASSERT_TRUE(base::CreateDirectory(dcim_dir_.Append(kDCIMDirectoryName)));
785 void MediaFileSystemRegistryTest::TearDown() {
786 profile_states_.clear();
787 MediaFileSystemRegistry* registry =
788 g_browser_process->media_file_system_registry();
789 EXPECT_EQ(0U, GetExtensionGalleriesHostCount(registry));
790 TestStorageMonitor::RemoveSingleton();
791 #if defined(OS_CHROMEOS)
792 test_user_manager_.reset();
793 #endif
795 ChromeRenderViewHostTestHarness::TearDown();
798 ///////////
799 // Tests //
800 ///////////
802 TEST_F(MediaFileSystemRegistryTest, Basic) {
803 CreateProfileState(1);
804 AssertAllAutoAddedGalleries();
806 ProfileState* profile_state = GetProfileState(0);
807 std::vector<MediaFileSystemInfo> auto_galleries =
808 GetAutoAddedGalleries(profile_state);
809 std::vector<MediaFileSystemInfo> empty_expectation;
810 profile_state->CheckGalleries("basic", empty_expectation, auto_galleries);
813 TEST_F(MediaFileSystemRegistryTest, UserAddedGallery) {
814 CreateProfileState(1);
815 AssertAllAutoAddedGalleries();
816 ProfileState* profile_state = GetProfileState(0);
817 std::vector<MediaFileSystemInfo> auto_galleries =
818 GetAutoAddedGalleries(profile_state);
819 std::vector<MediaFileSystemInfo> added_galleries;
820 profile_state->CheckGalleries("user added init", added_galleries,
821 auto_galleries);
823 // Add a user gallery to the regular permission extension.
824 std::string device_id = AddUserGallery(StorageInfo::FIXED_MASS_STORAGE,
825 empty_dir().AsUTF8Unsafe(),
826 empty_dir());
827 SetGalleryPermission(profile_state,
828 profile_state->regular_permission_extension(),
829 device_id,
830 true /*has access*/);
831 MediaFileSystemInfo added_info(empty_dir().LossyDisplayName(), empty_dir(),
832 std::string(), 0, std::string(), false, false);
833 added_galleries.push_back(added_info);
834 profile_state->CheckGalleries("user added regular", added_galleries,
835 auto_galleries);
837 // Add it to the all galleries extension.
838 SetGalleryPermission(profile_state,
839 profile_state->all_permission_extension(),
840 device_id,
841 true /*has access*/);
842 auto_galleries.push_back(added_info);
843 profile_state->CheckGalleries("user added all", added_galleries,
844 auto_galleries);
847 // Regression test to make sure erasing galleries does not result a crash.
848 TEST_F(MediaFileSystemRegistryTest, EraseGalleries) {
849 CreateProfileState(1);
850 AssertAllAutoAddedGalleries();
852 ProfileState* profile_state = GetProfileState(0);
853 std::vector<MediaFileSystemInfo> auto_galleries =
854 GetAutoAddedGalleries(profile_state);
855 std::vector<MediaFileSystemInfo> empty_expectation;
856 profile_state->CheckGalleries("erase", empty_expectation, auto_galleries);
858 MediaGalleriesPreferences* prefs = profile_state->GetMediaGalleriesPrefs();
859 MediaGalleriesPrefInfoMap galleries = prefs->known_galleries();
860 for (MediaGalleriesPrefInfoMap::const_iterator it = galleries.begin();
861 it != galleries.end(); ++it) {
862 prefs->ForgetGalleryById(it->first);
866 // Regression test to make sure calling GetPreferences() does not re-insert
867 // galleries on auto-detected removable devices that were blacklisted.
868 TEST_F(MediaFileSystemRegistryTest,
869 GetPreferencesDoesNotReinsertBlacklistedGalleries) {
870 CreateProfileState(1);
871 AssertAllAutoAddedGalleries();
873 ProfileState* profile_state = GetProfileState(0);
874 const size_t gallery_count = GetAutoAddedGalleries(profile_state).size();
876 // Attach a device.
877 const std::string device_id = AttachDevice(
878 StorageInfo::REMOVABLE_MASS_STORAGE_WITH_DCIM,
879 "removable_dcim_fake_id",
880 dcim_dir());
881 EXPECT_EQ(gallery_count + 1, GetAutoAddedGalleries(profile_state).size());
883 // Forget the device.
884 bool forget_gallery = false;
885 MediaGalleriesPreferences* prefs = GetPreferences(profile_state->profile());
886 const MediaGalleriesPrefInfoMap& galleries = prefs->known_galleries();
887 for (MediaGalleriesPrefInfoMap::const_iterator it = galleries.begin();
888 it != galleries.end(); ++it) {
889 if (it->second.device_id == device_id) {
890 prefs->ForgetGalleryById(it->first);
891 forget_gallery = true;
892 break;
895 base::MessageLoop::current()->RunUntilIdle();
896 EXPECT_TRUE(forget_gallery);
897 EXPECT_EQ(gallery_count, GetAutoAddedGalleries(profile_state).size());
899 // Call GetPreferences() and the gallery count should not change.
900 prefs = GetPreferences(profile_state->profile());
901 EXPECT_EQ(gallery_count, GetAutoAddedGalleries(profile_state).size());
904 TEST_F(MediaFileSystemRegistryTest, GalleryNameDefault) {
905 FSInfoMap galleries_info;
906 InitForGalleriesInfoTest(&galleries_info);
908 for (FSInfoMap::const_iterator it = galleries_info.begin();
909 it != galleries_info.end();
910 ++it) {
911 CheckGalleryInfo(it->second, test_file_system_context(),
912 it->second.path, false, false);
916 // TODO(gbillock): Move the remaining test into the linux directory.
917 #if !defined(OS_MACOSX) && !defined(OS_WIN)
918 TEST_F(MediaFileSystemRegistryTest, GalleryMTP) {
919 FSInfoMap galleries_info;
920 InitForGalleriesInfoTest(&galleries_info);
922 base::FilePath location(FILE_PATH_LITERAL("/mtp_bogus"));
923 AttachDevice(StorageInfo::MTP_OR_PTP, "mtp_fake_id", location);
924 CheckNewGalleryInfo(GetProfileState(0U), galleries_info, location,
925 true /*removable*/, true /* media device */);
927 #endif
929 TEST_F(MediaFileSystemRegistryTest, GalleryDCIM) {
930 FSInfoMap galleries_info;
931 InitForGalleriesInfoTest(&galleries_info);
933 AttachDevice(StorageInfo::REMOVABLE_MASS_STORAGE_WITH_DCIM,
934 "removable_dcim_fake_id",
935 dcim_dir());
936 CheckNewGalleryInfo(GetProfileState(0U), galleries_info, dcim_dir(),
937 true /*removable*/, true /* media device */);
940 TEST_F(MediaFileSystemRegistryTest, GalleryNoDCIM) {
941 FSInfoMap galleries_info;
942 InitForGalleriesInfoTest(&galleries_info);
944 std::string device_id =
945 AttachDevice(StorageInfo::REMOVABLE_MASS_STORAGE_NO_DCIM,
946 empty_dir().AsUTF8Unsafe(),
947 empty_dir());
948 std::string device_id2 =
949 AddUserGallery(StorageInfo::REMOVABLE_MASS_STORAGE_NO_DCIM,
950 empty_dir().AsUTF8Unsafe(),
951 empty_dir());
952 ASSERT_EQ(device_id, device_id2);
953 // Add permission for new non-default gallery.
954 ProfileState* profile_state = GetProfileState(0U);
955 SetGalleryPermission(profile_state,
956 profile_state->all_permission_extension(),
957 device_id,
958 true /*has access*/);
959 CheckNewGalleryInfo(profile_state, galleries_info, empty_dir(),
960 true /*removable*/, false /* media device */);
963 TEST_F(MediaFileSystemRegistryTest, GalleryUserAddedPath) {
964 FSInfoMap galleries_info;
965 InitForGalleriesInfoTest(&galleries_info);
967 std::string device_id = AddUserGallery(StorageInfo::FIXED_MASS_STORAGE,
968 empty_dir().AsUTF8Unsafe(),
969 empty_dir());
970 // Add permission for new non-default gallery.
971 ProfileState* profile_state = GetProfileState(0U);
972 SetGalleryPermission(profile_state,
973 profile_state->all_permission_extension(),
974 device_id,
975 true /*has access*/);
976 CheckNewGalleryInfo(profile_state, galleries_info, empty_dir(),
977 false /*removable*/, false /* media device */);
980 TEST_F(MediaFileSystemRegistryTest, DetachedDeviceGalleryPath) {
981 const std::string device_id = AttachDevice(
982 StorageInfo::REMOVABLE_MASS_STORAGE_WITH_DCIM,
983 "removable_dcim_fake_id",
984 dcim_dir());
986 MediaGalleryPrefInfo pref_info;
987 pref_info.device_id = device_id;
988 EXPECT_EQ(dcim_dir().value(), pref_info.AbsolutePath().value());
990 MediaGalleryPrefInfo pref_info_with_relpath;
991 pref_info_with_relpath.path =
992 base::FilePath(FILE_PATH_LITERAL("test_relpath"));
993 pref_info_with_relpath.device_id = device_id;
994 EXPECT_EQ(dcim_dir().Append(pref_info_with_relpath.path).value(),
995 pref_info_with_relpath.AbsolutePath().value());
997 DetachDevice(device_id);
998 EXPECT_TRUE(pref_info.AbsolutePath().empty());
999 EXPECT_TRUE(pref_info_with_relpath.AbsolutePath().empty());
1002 TEST_F(MediaFileSystemRegistryTest, TestNameConstruction) {
1003 CreateProfileState(1);
1004 AssertAllAutoAddedGalleries();
1006 ProfileState* profile_state = GetProfileState(0);
1008 std::string user_gallery = AddUserGallery(StorageInfo::FIXED_MASS_STORAGE,
1009 empty_dir().AsUTF8Unsafe(),
1010 empty_dir());
1011 SetGalleryPermission(profile_state,
1012 profile_state->regular_permission_extension(),
1013 user_gallery,
1014 true /*has access*/);
1015 SetGalleryPermission(profile_state,
1016 profile_state->all_permission_extension(),
1017 user_gallery,
1018 true /*has access*/);
1020 std::vector<MediaFileSystemInfo> auto_galleries =
1021 GetAutoAddedGalleries(profile_state);
1022 MediaFileSystemInfo added_info(empty_dir().BaseName().LossyDisplayName(),
1023 empty_dir(), std::string(), 0, std::string(),
1024 false, false);
1025 auto_galleries.push_back(added_info);
1026 std::vector<MediaFileSystemInfo> one_expectation;
1027 one_expectation.push_back(added_info);
1029 base::string16 empty_dir_name = GetExpectedFolderName(empty_dir());
1030 profile_state->AddNameForReadCompare(empty_dir_name);
1031 profile_state->AddNameForAllCompare(empty_dir_name);
1033 // This part of the test is conditional on default directories existing
1034 // on the test platform. In ChromeOS, these directories do not exist.
1035 base::FilePath path;
1036 if (num_auto_galleries() > 0) {
1037 ASSERT_TRUE(PathService::Get(chrome::DIR_USER_MUSIC, &path));
1038 profile_state->AddNameForAllCompare(GetExpectedFolderName(path));
1039 ASSERT_TRUE(PathService::Get(chrome::DIR_USER_PICTURES, &path));
1040 profile_state->AddNameForAllCompare(GetExpectedFolderName(path));
1041 ASSERT_TRUE(PathService::Get(chrome::DIR_USER_VIDEOS, &path));
1042 profile_state->AddNameForAllCompare(GetExpectedFolderName(path));
1044 profile_state->CheckGalleries("names-dir", one_expectation, auto_galleries);
1045 } else {
1046 profile_state->CheckGalleries("names", one_expectation, one_expectation);
1050 TEST_F(MediaFileSystemRegistryTest, PreferenceListener) {
1051 CreateProfileState(1);
1052 AssertAllAutoAddedGalleries();
1054 // Add a user gallery to the regular permission extension.
1055 std::string device_id = AddUserGallery(StorageInfo::FIXED_MASS_STORAGE,
1056 empty_dir().AsUTF8Unsafe(),
1057 empty_dir());
1058 ProfileState* profile_state = GetProfileState(0);
1059 SetGalleryPermission(profile_state,
1060 profile_state->regular_permission_extension(),
1061 device_id,
1062 true /*has access*/);
1064 FSInfoMap fs_info = profile_state->GetGalleriesInfo(
1065 profile_state->regular_permission_extension());
1066 ASSERT_EQ(1U, fs_info.size());
1067 EXPECT_FALSE(test_file_system_context()->GetPathForId(
1068 fs_info.begin()->second.fsid).empty());
1070 // Revoke permission and ensure that the file system is revoked.
1071 SetGalleryPermission(profile_state,
1072 profile_state->regular_permission_extension(),
1073 device_id,
1074 false /*has access*/);
1075 EXPECT_TRUE(test_file_system_context()->GetPathForId(
1076 fs_info.begin()->second.fsid).empty());