Revert of Add button to add new FSP services to Files app. (patchset #8 id:140001...
[chromium-blink-merge.git] / chrome / browser / media_galleries / media_file_system_registry_unittest.cc
blob5b218760927888abb5020a7f0a5a57b59b20b745
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/files/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/common/chrome_paths.h"
32 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
33 #include "chrome/test/base/testing_browser_process.h"
34 #include "chrome/test/base/testing_profile.h"
35 #include "components/storage_monitor/removable_device_constants.h"
36 #include "components/storage_monitor/storage_info.h"
37 #include "components/storage_monitor/storage_monitor.h"
38 #include "components/storage_monitor/test_storage_monitor.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/users/scoped_test_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;
58 using storage_monitor::StorageInfo;
59 using storage_monitor::StorageMonitor;
60 using storage_monitor::TestStorageMonitor;
62 // Not anonymous so it can be friends with MediaFileSystemRegistry.
63 class TestMediaFileSystemContext : public MediaFileSystemContext {
64 public:
65 struct FSInfo {
66 FSInfo() {}
67 FSInfo(const std::string& device_id, const base::FilePath& path,
68 const std::string& fs_name);
70 bool operator<(const FSInfo& other) const;
72 std::string device_id;
73 base::FilePath path;
74 std::string fs_name;
77 explicit TestMediaFileSystemContext(MediaFileSystemRegistry* registry);
78 ~TestMediaFileSystemContext() override {}
80 // MediaFileSystemContext implementation.
81 bool RegisterFileSystem(const std::string& device_id,
82 const std::string& fs_name,
83 const base::FilePath& path) override;
85 void RevokeFileSystem(const std::string& fs_name) override;
87 base::FilePath GetRegisteredPath(const std::string& fs_name) const override;
89 MediaFileSystemRegistry* registry() { return registry_; }
91 private:
92 void AddFSEntry(const std::string& device_id,
93 const base::FilePath& path,
94 const std::string& fs_name);
96 MediaFileSystemRegistry* registry_;
98 // The currently allocated mock file systems.
99 std::map<std::string /*fs_name*/, FSInfo> file_systems_by_name_;
102 TestMediaFileSystemContext::FSInfo::FSInfo(const std::string& device_id,
103 const base::FilePath& path,
104 const std::string& fs_name)
105 : device_id(device_id),
106 path(path),
107 fs_name(fs_name) {
110 bool TestMediaFileSystemContext::FSInfo::operator<(const FSInfo& other) const {
111 if (device_id != other.device_id)
112 return device_id < other.device_id;
113 if (path.value() != other.path.value())
114 return path.value() < other.path.value();
115 return fs_name < other.fs_name;
118 TestMediaFileSystemContext::TestMediaFileSystemContext(
119 MediaFileSystemRegistry* registry)
120 : registry_(registry) {
121 registry_->file_system_context_.reset(this);
124 bool TestMediaFileSystemContext::RegisterFileSystem(
125 const std::string& device_id,
126 const std::string& fs_name,
127 const base::FilePath& path) {
128 AddFSEntry(device_id, path, fs_name);
129 return true;
132 void TestMediaFileSystemContext::RevokeFileSystem(const std::string& fs_name) {
133 if (!ContainsKey(file_systems_by_name_, fs_name))
134 return;
135 EXPECT_EQ(1U, file_systems_by_name_.erase(fs_name));
138 base::FilePath TestMediaFileSystemContext::GetRegisteredPath(
139 const std::string& fs_name) const {
140 std::map<std::string /*fs_name*/, FSInfo>::const_iterator it =
141 file_systems_by_name_.find(fs_name);
142 if (it == file_systems_by_name_.end())
143 return base::FilePath();
144 return it->second.path;
147 void TestMediaFileSystemContext::AddFSEntry(const std::string& device_id,
148 const base::FilePath& path,
149 const std::string& fs_name) {
150 DCHECK_CURRENTLY_ON(BrowserThread::UI);
151 DCHECK(path.IsAbsolute());
152 DCHECK(!path.ReferencesParent());
154 FSInfo info(device_id, path, fs_name);
155 file_systems_by_name_[fs_name] = info;
158 namespace {
160 typedef std::map<MediaGalleryPrefId, MediaFileSystemInfo> FSInfoMap;
162 void GetGalleryInfoCallback(
163 FSInfoMap* results,
164 const std::vector<MediaFileSystemInfo>& file_systems) {
165 for (size_t i = 0; i < file_systems.size(); ++i) {
166 ASSERT_FALSE(ContainsKey(*results, file_systems[i].pref_id));
167 (*results)[file_systems[i].pref_id] = file_systems[i];
171 void CheckGalleryInfo(const MediaFileSystemInfo& info,
172 TestMediaFileSystemContext* fs_context,
173 const base::FilePath& path,
174 bool removable,
175 bool media_device) {
176 EXPECT_EQ(path, info.path);
177 EXPECT_EQ(removable, info.removable);
178 EXPECT_EQ(media_device, info.media_device);
179 EXPECT_NE(0UL, info.pref_id);
181 if (removable)
182 EXPECT_NE(0UL, info.transient_device_id.size());
183 else
184 EXPECT_EQ(0UL, info.transient_device_id.size());
186 base::FilePath fsid_path = fs_context->GetRegisteredPath(info.fsid);
187 EXPECT_EQ(path, fsid_path);
190 class MockProfileSharedRenderProcessHostFactory
191 : public content::RenderProcessHostFactory {
192 public:
193 MockProfileSharedRenderProcessHostFactory() {}
194 ~MockProfileSharedRenderProcessHostFactory() override;
196 // RPH created with this factory are owned by it. If the RPH is destroyed
197 // for testing purposes, it must be removed from the factory first.
198 content::MockRenderProcessHost* ReleaseRPH(
199 content::BrowserContext* browser_context);
201 content::RenderProcessHost* CreateRenderProcessHost(
202 content::BrowserContext* browser_context,
203 content::SiteInstance* site_instance) const override;
205 private:
206 typedef std::map<content::BrowserContext*, content::MockRenderProcessHost*>
207 ProfileRPHMap;
208 mutable ProfileRPHMap rph_map_;
210 DISALLOW_COPY_AND_ASSIGN(MockProfileSharedRenderProcessHostFactory);
213 class ProfileState {
214 public:
215 explicit ProfileState(
216 MockProfileSharedRenderProcessHostFactory* rph_factory);
217 ~ProfileState();
219 MediaGalleriesPreferences* GetMediaGalleriesPrefs();
221 void CheckGalleries(
222 const std::string& test,
223 const std::vector<MediaFileSystemInfo>& regular_extension_galleries,
224 const std::vector<MediaFileSystemInfo>& all_extension_galleries);
226 FSInfoMap GetGalleriesInfo(extensions::Extension* extension);
228 extensions::Extension* all_permission_extension();
229 extensions::Extension* regular_permission_extension();
230 Profile* profile();
232 void AddNameForReadCompare(const base::string16& name);
233 void AddNameForAllCompare(const base::string16& name);
235 private:
236 void CompareResults(const std::string& test,
237 const std::vector<base::string16>& names,
238 const std::vector<MediaFileSystemInfo>& expected,
239 const std::vector<MediaFileSystemInfo>& actual);
240 bool ContainsEntry(const MediaFileSystemInfo& info,
241 const std::vector<MediaFileSystemInfo>& container);
243 int GetAndClearComparisonCount();
245 int num_comparisons_;
247 scoped_ptr<TestingProfile> profile_;
249 scoped_refptr<extensions::Extension> all_permission_extension_;
250 scoped_refptr<extensions::Extension> regular_permission_extension_;
251 scoped_refptr<extensions::Extension> no_permissions_extension_;
253 scoped_ptr<content::WebContents> single_web_contents_;
254 scoped_ptr<content::WebContents> shared_web_contents1_;
255 scoped_ptr<content::WebContents> shared_web_contents2_;
257 // The RenderProcessHosts are freed when their respective WebContents /
258 // RenderViewHosts go away.
259 content::MockRenderProcessHost* single_rph_;
260 content::MockRenderProcessHost* shared_rph_;
262 std::vector<base::string16> compare_names_read_;
263 std::vector<base::string16> compare_names_all_;
265 DISALLOW_COPY_AND_ASSIGN(ProfileState);
268 base::string16 GetExpectedFolderName(const base::FilePath& path) {
269 #if defined(OS_CHROMEOS)
270 return path.BaseName().LossyDisplayName();
271 #else
272 return path.LossyDisplayName();
273 #endif
276 } // namespace
278 class MediaFileSystemRegistryTest : public ChromeRenderViewHostTestHarness {
279 public:
280 void CreateProfileState(size_t profile_count);
282 ProfileState* GetProfileState(size_t i);
284 MediaGalleriesPreferences* GetPreferences(Profile* profile);
286 base::FilePath empty_dir() {
287 return empty_dir_;
290 base::FilePath dcim_dir() {
291 return dcim_dir_;
294 TestMediaFileSystemContext* test_file_system_context() {
295 return test_file_system_context_;
298 // Create a user added gallery based on the information passed and add it to
299 // |profiles|. Returns the device id.
300 std::string AddUserGallery(StorageInfo::Type type,
301 const std::string& unique_id,
302 const base::FilePath& path);
304 // Returns the device id.
305 std::string AttachDevice(StorageInfo::Type type,
306 const std::string& unique_id,
307 const base::FilePath& location);
309 void DetachDevice(const std::string& device_id);
311 void SetGalleryPermission(ProfileState* profile_state,
312 extensions::Extension* extension,
313 const std::string& device_id,
314 bool has_access);
316 void AssertAllAutoAddedGalleries();
318 void InitForGalleriesInfoTest(FSInfoMap* galleries_info);
320 void CheckNewGalleryInfo(ProfileState* profile_state,
321 const FSInfoMap& galleries_info,
322 const base::FilePath& location,
323 bool removable,
324 bool media_device);
326 std::vector<MediaFileSystemInfo> GetAutoAddedGalleries(
327 ProfileState* profile_state);
329 void ProcessAttach(const std::string& id,
330 const base::string16& name,
331 const base::FilePath::StringType& location) {
332 StorageInfo info(id, location, name, base::string16(), base::string16(), 0);
333 StorageMonitor::GetInstance()->receiver()->ProcessAttach(info);
336 void ProcessDetach(const std::string& id) {
337 StorageMonitor::GetInstance()->receiver()->ProcessDetach(id);
340 MediaFileSystemRegistry* registry() {
341 return test_file_system_context_->registry();
344 size_t GetExtensionGalleriesHostCount(
345 const MediaFileSystemRegistry* registry) const;
347 int num_auto_galleries() {
348 return media_directories_.num_galleries();
351 protected:
352 void SetUp() override;
353 void TearDown() override;
355 private:
356 // This makes sure that at least one default gallery exists on the file
357 // system.
358 EnsureMediaDirectoriesExists media_directories_;
360 // Some test gallery directories.
361 base::ScopedTempDir galleries_dir_;
362 // An empty directory in |galleries_dir_|
363 base::FilePath empty_dir_;
364 // A directory in |galleries_dir_| with a DCIM directory in it.
365 base::FilePath dcim_dir_;
367 // MediaFileSystemRegistry owns this.
368 TestMediaFileSystemContext* test_file_system_context_;
370 // Needed for extension service & friends to work.
372 #if defined(OS_CHROMEOS)
373 chromeos::ScopedTestDeviceSettingsService test_device_settings_service_;
374 chromeos::ScopedTestCrosSettings test_cros_settings_;
375 scoped_ptr<chromeos::ScopedTestUserManager> test_user_manager_;
376 #endif
378 MockProfileSharedRenderProcessHostFactory rph_factory_;
380 ScopedVector<ProfileState> profile_states_;
383 namespace {
385 bool MediaFileSystemInfoComparator(const MediaFileSystemInfo& a,
386 const MediaFileSystemInfo& b) {
387 CHECK_NE(a.name, b.name); // Name must be unique.
388 return a.name < b.name;
391 ///////////////////////////////////////////////
392 // MockProfileSharedRenderProcessHostFactory //
393 ///////////////////////////////////////////////
395 MockProfileSharedRenderProcessHostFactory::
396 ~MockProfileSharedRenderProcessHostFactory() {
397 STLDeleteValues(&rph_map_);
400 content::MockRenderProcessHost*
401 MockProfileSharedRenderProcessHostFactory::ReleaseRPH(
402 content::BrowserContext* browser_context) {
403 ProfileRPHMap::iterator existing = rph_map_.find(browser_context);
404 if (existing == rph_map_.end())
405 return NULL;
406 content::MockRenderProcessHost* result = existing->second;
407 rph_map_.erase(existing);
408 return result;
411 content::RenderProcessHost*
412 MockProfileSharedRenderProcessHostFactory::CreateRenderProcessHost(
413 content::BrowserContext* browser_context,
414 content::SiteInstance* site_instance) const {
415 ProfileRPHMap::const_iterator existing = rph_map_.find(browser_context);
416 if (existing != rph_map_.end())
417 return existing->second;
418 rph_map_[browser_context] =
419 new content::MockRenderProcessHost(browser_context);
420 return rph_map_[browser_context];
423 //////////////////
424 // ProfileState //
425 //////////////////
427 ProfileState::ProfileState(
428 MockProfileSharedRenderProcessHostFactory* rph_factory)
429 : num_comparisons_(0),
430 profile_(new TestingProfile()) {
431 extensions::TestExtensionSystem* extension_system(
432 static_cast<extensions::TestExtensionSystem*>(
433 extensions::ExtensionSystem::Get(profile_.get())));
434 extension_system->CreateExtensionService(
435 base::CommandLine::ForCurrentProcess(), base::FilePath(), false);
437 std::vector<std::string> all_permissions;
438 all_permissions.push_back("allAutoDetected");
439 all_permissions.push_back("read");
440 std::vector<std::string> read_permissions;
441 read_permissions.push_back("read");
443 all_permission_extension_ =
444 AddMediaGalleriesApp("all", all_permissions, profile_.get());
445 regular_permission_extension_ =
446 AddMediaGalleriesApp("regular", read_permissions, profile_.get());
447 no_permissions_extension_ =
448 AddMediaGalleriesApp("no", read_permissions, profile_.get());
450 single_web_contents_.reset(
451 content::WebContentsTester::CreateTestWebContents(profile_.get(), NULL));
452 single_rph_ = rph_factory->ReleaseRPH(profile_.get());
454 shared_web_contents1_.reset(
455 content::WebContentsTester::CreateTestWebContents(profile_.get(), NULL));
456 shared_web_contents2_.reset(
457 content::WebContentsTester::CreateTestWebContents(profile_.get(), NULL));
458 shared_rph_ = rph_factory->ReleaseRPH(profile_.get());
461 ProfileState::~ProfileState() {
462 // TestExtensionSystem uses DeleteSoon, so we need to delete the profiles
463 // and then run the message queue to clean up. But first we have to
464 // delete everything that references the profile.
465 single_web_contents_.reset();
466 shared_web_contents1_.reset();
467 shared_web_contents2_.reset();
468 profile_.reset();
470 base::MessageLoop::current()->RunUntilIdle();
473 MediaGalleriesPreferences* ProfileState::GetMediaGalleriesPrefs() {
474 MediaGalleriesPreferences* prefs =
475 MediaGalleriesPreferencesFactory::GetForProfile(profile_.get());
476 base::RunLoop loop;
477 prefs->EnsureInitialized(loop.QuitClosure());
478 loop.Run();
479 return prefs;
482 void ProfileState::CheckGalleries(
483 const std::string& test,
484 const std::vector<MediaFileSystemInfo>& regular_extension_galleries,
485 const std::vector<MediaFileSystemInfo>& all_extension_galleries) {
486 content::RenderViewHost* rvh = single_web_contents_->GetRenderViewHost();
487 MediaFileSystemRegistry* registry =
488 g_browser_process->media_file_system_registry();
490 // No Media Galleries permissions.
491 std::vector<MediaFileSystemInfo> empty_expectation;
492 std::vector<base::string16> empty_names;
493 registry->GetMediaFileSystemsForExtension(
494 rvh, no_permissions_extension_.get(),
495 base::Bind(&ProfileState::CompareResults, base::Unretained(this),
496 base::StringPrintf("%s (no permission)", test.c_str()),
497 base::ConstRef(empty_names),
498 base::ConstRef(empty_expectation)));
499 base::MessageLoop::current()->RunUntilIdle();
500 EXPECT_EQ(1, GetAndClearComparisonCount());
502 // Read permission only.
503 registry->GetMediaFileSystemsForExtension(
504 rvh, regular_permission_extension_.get(),
505 base::Bind(&ProfileState::CompareResults, base::Unretained(this),
506 base::StringPrintf("%s (regular permission)", test.c_str()),
507 base::ConstRef(compare_names_read_),
508 base::ConstRef(regular_extension_galleries)));
509 base::MessageLoop::current()->RunUntilIdle();
510 EXPECT_EQ(1, GetAndClearComparisonCount());
512 // All galleries permission.
513 registry->GetMediaFileSystemsForExtension(
514 rvh, all_permission_extension_.get(),
515 base::Bind(&ProfileState::CompareResults, base::Unretained(this),
516 base::StringPrintf("%s (all permission)", test.c_str()),
517 base::ConstRef(compare_names_all_),
518 base::ConstRef(all_extension_galleries)));
519 base::MessageLoop::current()->RunUntilIdle();
520 EXPECT_EQ(1, GetAndClearComparisonCount());
523 FSInfoMap ProfileState::GetGalleriesInfo(extensions::Extension* extension) {
524 content::RenderViewHost* rvh = single_web_contents_->GetRenderViewHost();
525 FSInfoMap results;
526 MediaFileSystemRegistry* registry =
527 g_browser_process->media_file_system_registry();
528 registry->GetMediaFileSystemsForExtension(
529 rvh, extension,
530 base::Bind(&GetGalleryInfoCallback, base::Unretained(&results)));
531 base::MessageLoop::current()->RunUntilIdle();
532 return results;
535 extensions::Extension* ProfileState::all_permission_extension() {
536 return all_permission_extension_.get();
539 extensions::Extension* ProfileState::regular_permission_extension() {
540 return regular_permission_extension_.get();
543 Profile* ProfileState::profile() {
544 return profile_.get();
547 void ProfileState::AddNameForReadCompare(const base::string16& name) {
548 compare_names_read_.push_back(name);
551 void ProfileState::AddNameForAllCompare(const base::string16& name) {
552 compare_names_all_.push_back(name);
555 bool ProfileState::ContainsEntry(
556 const MediaFileSystemInfo& info,
557 const std::vector<MediaFileSystemInfo>& container) {
558 for (size_t i = 0; i < container.size(); ++i) {
559 if (info.path.value() == container[i].path.value()) {
560 EXPECT_FALSE(container[i].fsid.empty());
561 if (!info.fsid.empty())
562 EXPECT_EQ(info.fsid, container[i].fsid);
563 return true;
566 return false;
569 void ProfileState::CompareResults(
570 const std::string& test,
571 const std::vector<base::string16>& names,
572 const std::vector<MediaFileSystemInfo>& expected,
573 const std::vector<MediaFileSystemInfo>& actual) {
574 num_comparisons_++;
575 EXPECT_EQ(expected.size(), actual.size()) << test;
577 // Order isn't important, so sort the results.
578 std::vector<MediaFileSystemInfo> sorted(actual);
579 std::sort(sorted.begin(), sorted.end(), MediaFileSystemInfoComparator);
580 std::vector<MediaFileSystemInfo> expect(expected);
581 std::sort(expect.begin(), expect.end(), MediaFileSystemInfoComparator);
582 std::vector<base::string16> expect_names(names);
583 std::sort(expect_names.begin(), expect_names.end());
585 for (size_t i = 0; i < expect.size() && i < sorted.size(); ++i) {
586 if (expect_names.size() > i)
587 EXPECT_EQ(expect_names[i], sorted[i].name) << test;
588 EXPECT_TRUE(ContainsEntry(expect[i], sorted)) << test;
592 int ProfileState::GetAndClearComparisonCount() {
593 int result = num_comparisons_;
594 num_comparisons_ = 0;
595 return result;
598 } // namespace
600 /////////////////////////////////
601 // MediaFileSystemRegistryTest //
602 /////////////////////////////////
604 void MediaFileSystemRegistryTest::CreateProfileState(size_t profile_count) {
605 for (size_t i = 0; i < profile_count; ++i) {
606 ProfileState* state = new ProfileState(&rph_factory_);
607 profile_states_.push_back(state);
611 ProfileState* MediaFileSystemRegistryTest::GetProfileState(size_t i) {
612 return profile_states_[i];
615 MediaGalleriesPreferences* MediaFileSystemRegistryTest::GetPreferences(
616 Profile* profile) {
617 MediaGalleriesPreferences* prefs = registry()->GetPreferences(profile);
618 base::RunLoop loop;
619 prefs->EnsureInitialized(loop.QuitClosure());
620 loop.Run();
621 return prefs;
624 std::string MediaFileSystemRegistryTest::AddUserGallery(
625 StorageInfo::Type type,
626 const std::string& unique_id,
627 const base::FilePath& path) {
628 std::string device_id = StorageInfo::MakeDeviceId(type, unique_id);
629 DCHECK(!StorageInfo::IsMediaDevice(device_id));
631 for (size_t i = 0; i < profile_states_.size(); ++i) {
632 profile_states_[i]->GetMediaGalleriesPrefs()->AddGallery(
633 device_id, base::FilePath(), MediaGalleryPrefInfo::kUserAdded,
634 base::string16(), base::string16(), base::string16(), 0,
635 base::Time::Now(), 0, 0, 0);
637 return device_id;
640 std::string MediaFileSystemRegistryTest::AttachDevice(
641 StorageInfo::Type type,
642 const std::string& unique_id,
643 const base::FilePath& location) {
644 std::string device_id = StorageInfo::MakeDeviceId(type, unique_id);
645 DCHECK(StorageInfo::IsRemovableDevice(device_id));
646 base::string16 label = location.BaseName().LossyDisplayName();
647 ProcessAttach(device_id, label, location.value());
648 base::MessageLoop::current()->RunUntilIdle();
649 return device_id;
652 void MediaFileSystemRegistryTest::DetachDevice(const std::string& device_id) {
653 DCHECK(StorageInfo::IsRemovableDevice(device_id));
654 ProcessDetach(device_id);
655 base::MessageLoop::current()->RunUntilIdle();
658 void MediaFileSystemRegistryTest::SetGalleryPermission(
659 ProfileState* profile_state, extensions::Extension* extension,
660 const std::string& device_id, bool has_access) {
661 MediaGalleriesPreferences* preferences =
662 profile_state->GetMediaGalleriesPrefs();
663 MediaGalleryPrefIdSet pref_id =
664 preferences->LookUpGalleriesByDeviceId(device_id);
665 ASSERT_EQ(1U, pref_id.size());
666 preferences->SetGalleryPermissionForExtension(*extension, *pref_id.begin(),
667 has_access);
670 void MediaFileSystemRegistryTest::AssertAllAutoAddedGalleries() {
671 for (size_t i = 0; i < profile_states_.size(); ++i) {
672 MediaGalleriesPreferences* prefs =
673 profile_states_[0]->GetMediaGalleriesPrefs();
675 // Make sure that we have at least one gallery and that they are all
676 // auto added galleries.
677 const MediaGalleriesPrefInfoMap& galleries = prefs->known_galleries();
678 #if !defined(OS_CHROMEOS) && !defined(OS_ANDROID)
679 ASSERT_GT(galleries.size(), 0U);
680 #endif
681 for (MediaGalleriesPrefInfoMap::const_iterator it = galleries.begin();
682 it != galleries.end();
683 ++it) {
684 ASSERT_EQ(MediaGalleryPrefInfo::kAutoDetected, it->second.type);
689 void MediaFileSystemRegistryTest::InitForGalleriesInfoTest(
690 FSInfoMap* galleries_info) {
691 CreateProfileState(1);
692 AssertAllAutoAddedGalleries();
694 // Get all existing gallery names.
695 ProfileState* profile_state = GetProfileState(0U);
696 *galleries_info = profile_state->GetGalleriesInfo(
697 profile_state->all_permission_extension());
698 #if !defined(OS_CHROMEOS) && !defined(OS_ANDROID)
699 ASSERT_EQ(3U, galleries_info->size());
700 #else
701 ASSERT_EQ(0U, galleries_info->size());
702 #endif
705 void MediaFileSystemRegistryTest::CheckNewGalleryInfo(
706 ProfileState* profile_state,
707 const FSInfoMap& galleries_info,
708 const base::FilePath& location,
709 bool removable,
710 bool media_device) {
711 // Get new galleries.
712 FSInfoMap new_galleries_info = profile_state->GetGalleriesInfo(
713 profile_state->all_permission_extension());
714 ASSERT_EQ(galleries_info.size() + 1U, new_galleries_info.size());
716 bool found_new = false;
717 for (FSInfoMap::const_iterator it = new_galleries_info.begin();
718 it != new_galleries_info.end();
719 ++it) {
720 if (ContainsKey(galleries_info, it->first))
721 continue;
723 ASSERT_FALSE(found_new);
724 CheckGalleryInfo(it->second, test_file_system_context_, location,
725 removable, media_device);
726 found_new = true;
728 ASSERT_TRUE(found_new);
731 std::vector<MediaFileSystemInfo>
732 MediaFileSystemRegistryTest::GetAutoAddedGalleries(
733 ProfileState* profile_state) {
734 const MediaGalleriesPrefInfoMap& galleries =
735 profile_state->GetMediaGalleriesPrefs()->known_galleries();
736 std::vector<MediaFileSystemInfo> result;
737 for (MediaGalleriesPrefInfoMap::const_iterator it = galleries.begin();
738 it != galleries.end();
739 ++it) {
740 if (it->second.type == MediaGalleryPrefInfo::kAutoDetected) {
741 base::FilePath path = it->second.AbsolutePath();
742 MediaFileSystemInfo info(path.BaseName().LossyDisplayName(), path,
743 std::string(), 0, std::string(), false, false);
744 result.push_back(info);
747 std::sort(result.begin(), result.end(), MediaFileSystemInfoComparator);
748 return result;
751 size_t MediaFileSystemRegistryTest::GetExtensionGalleriesHostCount(
752 const MediaFileSystemRegistry* registry) const {
753 size_t extension_galleries_host_count = 0;
754 for (MediaFileSystemRegistry::ExtensionGalleriesHostMap::const_iterator it =
755 registry->extension_hosts_map_.begin();
756 it != registry->extension_hosts_map_.end();
757 ++it) {
758 extension_galleries_host_count += it->second.size();
760 return extension_galleries_host_count;
764 void MediaFileSystemRegistryTest::SetUp() {
765 ChromeRenderViewHostTestHarness::SetUp();
766 ASSERT_TRUE(TestStorageMonitor::CreateAndInstall());
768 DeleteContents();
769 SetRenderProcessHostFactory(&rph_factory_);
771 test_file_system_context_ = new TestMediaFileSystemContext(
772 g_browser_process->media_file_system_registry());
774 #if defined(OS_CHROMEOS)
775 test_user_manager_.reset(new chromeos::ScopedTestUserManager());
776 #endif
778 ASSERT_TRUE(galleries_dir_.CreateUniqueTempDir());
779 empty_dir_ = galleries_dir_.path().AppendASCII("empty");
780 ASSERT_TRUE(base::CreateDirectory(empty_dir_));
781 dcim_dir_ = galleries_dir_.path().AppendASCII("with_dcim");
782 ASSERT_TRUE(base::CreateDirectory(dcim_dir_));
783 ASSERT_TRUE(base::CreateDirectory(
784 dcim_dir_.Append(storage_monitor::kDCIMDirectoryName)));
787 void MediaFileSystemRegistryTest::TearDown() {
788 profile_states_.clear();
789 MediaFileSystemRegistry* registry =
790 g_browser_process->media_file_system_registry();
791 EXPECT_EQ(0U, GetExtensionGalleriesHostCount(registry));
792 TestStorageMonitor::Destroy();
793 #if defined(OS_CHROMEOS)
794 test_user_manager_.reset();
795 #endif
797 ChromeRenderViewHostTestHarness::TearDown();
800 ///////////
801 // Tests //
802 ///////////
804 TEST_F(MediaFileSystemRegistryTest, Basic) {
805 CreateProfileState(1);
806 AssertAllAutoAddedGalleries();
808 ProfileState* profile_state = GetProfileState(0);
809 std::vector<MediaFileSystemInfo> auto_galleries =
810 GetAutoAddedGalleries(profile_state);
811 std::vector<MediaFileSystemInfo> empty_expectation;
812 profile_state->CheckGalleries("basic", empty_expectation, auto_galleries);
815 TEST_F(MediaFileSystemRegistryTest, UserAddedGallery) {
816 CreateProfileState(1);
817 AssertAllAutoAddedGalleries();
818 ProfileState* profile_state = GetProfileState(0);
819 std::vector<MediaFileSystemInfo> auto_galleries =
820 GetAutoAddedGalleries(profile_state);
821 std::vector<MediaFileSystemInfo> added_galleries;
822 profile_state->CheckGalleries("user added init", added_galleries,
823 auto_galleries);
825 // Add a user gallery to the regular permission extension.
826 std::string device_id = AddUserGallery(StorageInfo::FIXED_MASS_STORAGE,
827 empty_dir().AsUTF8Unsafe(),
828 empty_dir());
829 SetGalleryPermission(profile_state,
830 profile_state->regular_permission_extension(),
831 device_id,
832 true /*has access*/);
833 MediaFileSystemInfo added_info(empty_dir().LossyDisplayName(), empty_dir(),
834 std::string(), 0, std::string(), false, false);
835 added_galleries.push_back(added_info);
836 profile_state->CheckGalleries("user added regular", added_galleries,
837 auto_galleries);
839 // Add it to the all galleries extension.
840 SetGalleryPermission(profile_state,
841 profile_state->all_permission_extension(),
842 device_id,
843 true /*has access*/);
844 auto_galleries.push_back(added_info);
845 profile_state->CheckGalleries("user added all", added_galleries,
846 auto_galleries);
849 // Regression test to make sure erasing galleries does not result a crash.
850 TEST_F(MediaFileSystemRegistryTest, EraseGalleries) {
851 CreateProfileState(1);
852 AssertAllAutoAddedGalleries();
854 ProfileState* profile_state = GetProfileState(0);
855 std::vector<MediaFileSystemInfo> auto_galleries =
856 GetAutoAddedGalleries(profile_state);
857 std::vector<MediaFileSystemInfo> empty_expectation;
858 profile_state->CheckGalleries("erase", empty_expectation, auto_galleries);
860 MediaGalleriesPreferences* prefs = profile_state->GetMediaGalleriesPrefs();
861 MediaGalleriesPrefInfoMap galleries = prefs->known_galleries();
862 for (MediaGalleriesPrefInfoMap::const_iterator it = galleries.begin();
863 it != galleries.end(); ++it) {
864 prefs->ForgetGalleryById(it->first);
868 // Regression test to make sure calling GetPreferences() does not re-insert
869 // galleries on auto-detected removable devices that were blacklisted.
870 TEST_F(MediaFileSystemRegistryTest,
871 GetPreferencesDoesNotReinsertBlacklistedGalleries) {
872 CreateProfileState(1);
873 AssertAllAutoAddedGalleries();
875 ProfileState* profile_state = GetProfileState(0);
876 const size_t gallery_count = GetAutoAddedGalleries(profile_state).size();
878 // Attach a device.
879 const std::string device_id = AttachDevice(
880 StorageInfo::REMOVABLE_MASS_STORAGE_WITH_DCIM,
881 "removable_dcim_fake_id",
882 dcim_dir());
883 EXPECT_EQ(gallery_count + 1, GetAutoAddedGalleries(profile_state).size());
885 // Forget the device.
886 bool forget_gallery = false;
887 MediaGalleriesPreferences* prefs = GetPreferences(profile_state->profile());
888 const MediaGalleriesPrefInfoMap& galleries = prefs->known_galleries();
889 for (MediaGalleriesPrefInfoMap::const_iterator it = galleries.begin();
890 it != galleries.end(); ++it) {
891 if (it->second.device_id == device_id) {
892 prefs->ForgetGalleryById(it->first);
893 forget_gallery = true;
894 break;
897 base::MessageLoop::current()->RunUntilIdle();
898 EXPECT_TRUE(forget_gallery);
899 EXPECT_EQ(gallery_count, GetAutoAddedGalleries(profile_state).size());
901 // Call GetPreferences() and the gallery count should not change.
902 prefs = GetPreferences(profile_state->profile());
903 EXPECT_EQ(gallery_count, GetAutoAddedGalleries(profile_state).size());
906 TEST_F(MediaFileSystemRegistryTest, GalleryNameDefault) {
907 FSInfoMap galleries_info;
908 InitForGalleriesInfoTest(&galleries_info);
910 for (FSInfoMap::const_iterator it = galleries_info.begin();
911 it != galleries_info.end();
912 ++it) {
913 CheckGalleryInfo(it->second, test_file_system_context(),
914 it->second.path, false, false);
918 // TODO(gbillock): Move the remaining test into the linux directory.
919 #if !defined(OS_MACOSX) && !defined(OS_WIN)
920 TEST_F(MediaFileSystemRegistryTest, GalleryMTP) {
921 FSInfoMap galleries_info;
922 InitForGalleriesInfoTest(&galleries_info);
924 base::FilePath location(FILE_PATH_LITERAL("/mtp_bogus"));
925 AttachDevice(StorageInfo::MTP_OR_PTP, "mtp_fake_id", location);
926 CheckNewGalleryInfo(GetProfileState(0U), galleries_info, location,
927 true /*removable*/, true /* media device */);
929 #endif
931 TEST_F(MediaFileSystemRegistryTest, GalleryDCIM) {
932 FSInfoMap galleries_info;
933 InitForGalleriesInfoTest(&galleries_info);
935 AttachDevice(StorageInfo::REMOVABLE_MASS_STORAGE_WITH_DCIM,
936 "removable_dcim_fake_id",
937 dcim_dir());
938 CheckNewGalleryInfo(GetProfileState(0U), galleries_info, dcim_dir(),
939 true /*removable*/, true /* media device */);
942 TEST_F(MediaFileSystemRegistryTest, GalleryNoDCIM) {
943 FSInfoMap galleries_info;
944 InitForGalleriesInfoTest(&galleries_info);
946 std::string device_id =
947 AttachDevice(StorageInfo::REMOVABLE_MASS_STORAGE_NO_DCIM,
948 empty_dir().AsUTF8Unsafe(),
949 empty_dir());
950 std::string device_id2 =
951 AddUserGallery(StorageInfo::REMOVABLE_MASS_STORAGE_NO_DCIM,
952 empty_dir().AsUTF8Unsafe(),
953 empty_dir());
954 ASSERT_EQ(device_id, device_id2);
955 // Add permission for new non-default gallery.
956 ProfileState* profile_state = GetProfileState(0U);
957 SetGalleryPermission(profile_state,
958 profile_state->all_permission_extension(),
959 device_id,
960 true /*has access*/);
961 CheckNewGalleryInfo(profile_state, galleries_info, empty_dir(),
962 true /*removable*/, false /* media device */);
965 TEST_F(MediaFileSystemRegistryTest, GalleryUserAddedPath) {
966 FSInfoMap galleries_info;
967 InitForGalleriesInfoTest(&galleries_info);
969 std::string device_id = AddUserGallery(StorageInfo::FIXED_MASS_STORAGE,
970 empty_dir().AsUTF8Unsafe(),
971 empty_dir());
972 // Add permission for new non-default gallery.
973 ProfileState* profile_state = GetProfileState(0U);
974 SetGalleryPermission(profile_state,
975 profile_state->all_permission_extension(),
976 device_id,
977 true /*has access*/);
978 CheckNewGalleryInfo(profile_state, galleries_info, empty_dir(),
979 false /*removable*/, false /* media device */);
982 TEST_F(MediaFileSystemRegistryTest, DetachedDeviceGalleryPath) {
983 const std::string device_id = AttachDevice(
984 StorageInfo::REMOVABLE_MASS_STORAGE_WITH_DCIM,
985 "removable_dcim_fake_id",
986 dcim_dir());
988 MediaGalleryPrefInfo pref_info;
989 pref_info.device_id = device_id;
990 EXPECT_EQ(dcim_dir().value(), pref_info.AbsolutePath().value());
992 MediaGalleryPrefInfo pref_info_with_relpath;
993 pref_info_with_relpath.path =
994 base::FilePath(FILE_PATH_LITERAL("test_relpath"));
995 pref_info_with_relpath.device_id = device_id;
996 EXPECT_EQ(dcim_dir().Append(pref_info_with_relpath.path).value(),
997 pref_info_with_relpath.AbsolutePath().value());
999 DetachDevice(device_id);
1000 EXPECT_TRUE(pref_info.AbsolutePath().empty());
1001 EXPECT_TRUE(pref_info_with_relpath.AbsolutePath().empty());
1004 TEST_F(MediaFileSystemRegistryTest, TestNameConstruction) {
1005 CreateProfileState(1);
1006 AssertAllAutoAddedGalleries();
1008 ProfileState* profile_state = GetProfileState(0);
1010 std::string user_gallery = AddUserGallery(StorageInfo::FIXED_MASS_STORAGE,
1011 empty_dir().AsUTF8Unsafe(),
1012 empty_dir());
1013 SetGalleryPermission(profile_state,
1014 profile_state->regular_permission_extension(),
1015 user_gallery,
1016 true /*has access*/);
1017 SetGalleryPermission(profile_state,
1018 profile_state->all_permission_extension(),
1019 user_gallery,
1020 true /*has access*/);
1022 std::vector<MediaFileSystemInfo> auto_galleries =
1023 GetAutoAddedGalleries(profile_state);
1024 MediaFileSystemInfo added_info(empty_dir().BaseName().LossyDisplayName(),
1025 empty_dir(), std::string(), 0, std::string(),
1026 false, false);
1027 auto_galleries.push_back(added_info);
1028 std::vector<MediaFileSystemInfo> one_expectation;
1029 one_expectation.push_back(added_info);
1031 base::string16 empty_dir_name = GetExpectedFolderName(empty_dir());
1032 profile_state->AddNameForReadCompare(empty_dir_name);
1033 profile_state->AddNameForAllCompare(empty_dir_name);
1035 // This part of the test is conditional on default directories existing
1036 // on the test platform. In ChromeOS, these directories do not exist.
1037 base::FilePath path;
1038 if (num_auto_galleries() > 0) {
1039 ASSERT_TRUE(PathService::Get(chrome::DIR_USER_MUSIC, &path));
1040 profile_state->AddNameForAllCompare(GetExpectedFolderName(path));
1041 ASSERT_TRUE(PathService::Get(chrome::DIR_USER_PICTURES, &path));
1042 profile_state->AddNameForAllCompare(GetExpectedFolderName(path));
1043 ASSERT_TRUE(PathService::Get(chrome::DIR_USER_VIDEOS, &path));
1044 profile_state->AddNameForAllCompare(GetExpectedFolderName(path));
1046 profile_state->CheckGalleries("names-dir", one_expectation, auto_galleries);
1047 } else {
1048 profile_state->CheckGalleries("names", one_expectation, one_expectation);
1052 TEST_F(MediaFileSystemRegistryTest, PreferenceListener) {
1053 CreateProfileState(1);
1054 AssertAllAutoAddedGalleries();
1056 // Add a user gallery to the regular permission extension.
1057 std::string device_id = AddUserGallery(StorageInfo::FIXED_MASS_STORAGE,
1058 empty_dir().AsUTF8Unsafe(),
1059 empty_dir());
1060 ProfileState* profile_state = GetProfileState(0);
1061 SetGalleryPermission(profile_state,
1062 profile_state->regular_permission_extension(),
1063 device_id,
1064 true /*has access*/);
1066 FSInfoMap fs_info = profile_state->GetGalleriesInfo(
1067 profile_state->regular_permission_extension());
1068 ASSERT_EQ(1U, fs_info.size());
1069 EXPECT_FALSE(test_file_system_context()->GetRegisteredPath(
1070 fs_info.begin()->second.fsid).empty());
1072 // Revoke permission and ensure that the file system is revoked.
1073 SetGalleryPermission(profile_state,
1074 profile_state->regular_permission_extension(),
1075 device_id,
1076 false /*has access*/);
1077 EXPECT_TRUE(test_file_system_context()->GetRegisteredPath(
1078 fs_info.begin()->second.fsid).empty());