Cast: Stop logging kVideoFrameSentToEncoder and rename a couple events.
[chromium-blink-merge.git] / chrome / browser / media_galleries / media_file_system_registry_unittest.cc
blob5d180b7010f5477bc6644f9ed883867f456c97c3
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/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/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 virtual ~TestMediaFileSystemContext() {}
80 // MediaFileSystemContext implementation.
81 virtual bool RegisterFileSystem(const std::string& device_id,
82 const std::string& fs_name,
83 const base::FilePath& path) OVERRIDE;
85 virtual void RevokeFileSystem(const std::string& fs_name) OVERRIDE;
87 virtual base::FilePath GetRegisteredPath(
88 const std::string& fs_name) const OVERRIDE;
90 MediaFileSystemRegistry* registry() { return registry_; }
92 private:
93 void AddFSEntry(const std::string& device_id,
94 const base::FilePath& path,
95 const std::string& fs_name);
97 MediaFileSystemRegistry* registry_;
99 // The currently allocated mock file systems.
100 std::map<std::string /*fs_name*/, FSInfo> file_systems_by_name_;
103 TestMediaFileSystemContext::FSInfo::FSInfo(const std::string& device_id,
104 const base::FilePath& path,
105 const std::string& fs_name)
106 : device_id(device_id),
107 path(path),
108 fs_name(fs_name) {
111 bool TestMediaFileSystemContext::FSInfo::operator<(const FSInfo& other) const {
112 if (device_id != other.device_id)
113 return device_id < other.device_id;
114 if (path.value() != other.path.value())
115 return path.value() < other.path.value();
116 return fs_name < other.fs_name;
119 TestMediaFileSystemContext::TestMediaFileSystemContext(
120 MediaFileSystemRegistry* registry)
121 : registry_(registry) {
122 registry_->file_system_context_.reset(this);
125 bool TestMediaFileSystemContext::RegisterFileSystem(
126 const std::string& device_id,
127 const std::string& fs_name,
128 const base::FilePath& path) {
129 AddFSEntry(device_id, path, fs_name);
130 return true;
133 void TestMediaFileSystemContext::RevokeFileSystem(const std::string& fs_name) {
134 if (!ContainsKey(file_systems_by_name_, fs_name))
135 return;
136 EXPECT_EQ(1U, file_systems_by_name_.erase(fs_name));
139 base::FilePath TestMediaFileSystemContext::GetRegisteredPath(
140 const std::string& fs_name) const {
141 std::map<std::string /*fs_name*/, FSInfo>::const_iterator it =
142 file_systems_by_name_.find(fs_name);
143 if (it == file_systems_by_name_.end())
144 return base::FilePath();
145 return it->second.path;
148 void TestMediaFileSystemContext::AddFSEntry(const std::string& device_id,
149 const base::FilePath& path,
150 const std::string& fs_name) {
151 DCHECK_CURRENTLY_ON(BrowserThread::UI);
152 DCHECK(path.IsAbsolute());
153 DCHECK(!path.ReferencesParent());
155 FSInfo info(device_id, path, fs_name);
156 file_systems_by_name_[fs_name] = info;
159 namespace {
161 typedef std::map<MediaGalleryPrefId, MediaFileSystemInfo> FSInfoMap;
163 void GetGalleryInfoCallback(
164 FSInfoMap* results,
165 const std::vector<MediaFileSystemInfo>& file_systems) {
166 for (size_t i = 0; i < file_systems.size(); ++i) {
167 ASSERT_FALSE(ContainsKey(*results, file_systems[i].pref_id));
168 (*results)[file_systems[i].pref_id] = file_systems[i];
172 void CheckGalleryInfo(const MediaFileSystemInfo& info,
173 TestMediaFileSystemContext* fs_context,
174 const base::FilePath& path,
175 bool removable,
176 bool media_device) {
177 EXPECT_EQ(path, info.path);
178 EXPECT_EQ(removable, info.removable);
179 EXPECT_EQ(media_device, info.media_device);
180 EXPECT_NE(0UL, info.pref_id);
182 if (removable)
183 EXPECT_NE(0UL, info.transient_device_id.size());
184 else
185 EXPECT_EQ(0UL, info.transient_device_id.size());
187 base::FilePath fsid_path = fs_context->GetRegisteredPath(info.fsid);
188 EXPECT_EQ(path, fsid_path);
191 class MockProfileSharedRenderProcessHostFactory
192 : public content::RenderProcessHostFactory {
193 public:
194 MockProfileSharedRenderProcessHostFactory() {}
195 virtual ~MockProfileSharedRenderProcessHostFactory();
197 // RPH created with this factory are owned by it. If the RPH is destroyed
198 // for testing purposes, it must be removed from the factory first.
199 content::MockRenderProcessHost* ReleaseRPH(
200 content::BrowserContext* browser_context);
202 virtual content::RenderProcessHost* CreateRenderProcessHost(
203 content::BrowserContext* browser_context,
204 content::SiteInstance* site_instance) const OVERRIDE;
206 private:
207 typedef std::map<content::BrowserContext*, content::MockRenderProcessHost*>
208 ProfileRPHMap;
209 mutable ProfileRPHMap rph_map_;
211 DISALLOW_COPY_AND_ASSIGN(MockProfileSharedRenderProcessHostFactory);
214 class ProfileState {
215 public:
216 explicit ProfileState(
217 MockProfileSharedRenderProcessHostFactory* rph_factory);
218 ~ProfileState();
220 MediaGalleriesPreferences* GetMediaGalleriesPrefs();
222 void CheckGalleries(
223 const std::string& test,
224 const std::vector<MediaFileSystemInfo>& regular_extension_galleries,
225 const std::vector<MediaFileSystemInfo>& all_extension_galleries);
227 FSInfoMap GetGalleriesInfo(extensions::Extension* extension);
229 extensions::Extension* all_permission_extension();
230 extensions::Extension* regular_permission_extension();
231 Profile* profile();
233 void AddNameForReadCompare(const base::string16& name);
234 void AddNameForAllCompare(const base::string16& name);
236 private:
237 void CompareResults(const std::string& test,
238 const std::vector<base::string16>& names,
239 const std::vector<MediaFileSystemInfo>& expected,
240 const std::vector<MediaFileSystemInfo>& actual);
241 bool ContainsEntry(const MediaFileSystemInfo& info,
242 const std::vector<MediaFileSystemInfo>& container);
244 int GetAndClearComparisonCount();
246 int num_comparisons_;
248 scoped_ptr<TestingProfile> profile_;
250 scoped_refptr<extensions::Extension> all_permission_extension_;
251 scoped_refptr<extensions::Extension> regular_permission_extension_;
252 scoped_refptr<extensions::Extension> no_permissions_extension_;
254 scoped_ptr<content::WebContents> single_web_contents_;
255 scoped_ptr<content::WebContents> shared_web_contents1_;
256 scoped_ptr<content::WebContents> shared_web_contents2_;
258 // The RenderProcessHosts are freed when their respective WebContents /
259 // RenderViewHosts go away.
260 content::MockRenderProcessHost* single_rph_;
261 content::MockRenderProcessHost* shared_rph_;
263 std::vector<base::string16> compare_names_read_;
264 std::vector<base::string16> compare_names_all_;
266 DISALLOW_COPY_AND_ASSIGN(ProfileState);
269 base::string16 GetExpectedFolderName(const base::FilePath& path) {
270 #if defined(OS_CHROMEOS)
271 return path.BaseName().LossyDisplayName();
272 #else
273 return path.LossyDisplayName();
274 #endif
277 } // namespace
279 class MediaFileSystemRegistryTest : public ChromeRenderViewHostTestHarness {
280 public:
281 void CreateProfileState(size_t profile_count);
283 ProfileState* GetProfileState(size_t i);
285 MediaGalleriesPreferences* GetPreferences(Profile* profile);
287 base::FilePath empty_dir() {
288 return empty_dir_;
291 base::FilePath dcim_dir() {
292 return dcim_dir_;
295 TestMediaFileSystemContext* test_file_system_context() {
296 return test_file_system_context_;
299 // Create a user added gallery based on the information passed and add it to
300 // |profiles|. Returns the device id.
301 std::string AddUserGallery(StorageInfo::Type type,
302 const std::string& unique_id,
303 const base::FilePath& path);
305 // Returns the device id.
306 std::string AttachDevice(StorageInfo::Type type,
307 const std::string& unique_id,
308 const base::FilePath& location);
310 void DetachDevice(const std::string& device_id);
312 void SetGalleryPermission(ProfileState* profile_state,
313 extensions::Extension* extension,
314 const std::string& device_id,
315 bool has_access);
317 void AssertAllAutoAddedGalleries();
319 void InitForGalleriesInfoTest(FSInfoMap* galleries_info);
321 void CheckNewGalleryInfo(ProfileState* profile_state,
322 const FSInfoMap& galleries_info,
323 const base::FilePath& location,
324 bool removable,
325 bool media_device);
327 std::vector<MediaFileSystemInfo> GetAutoAddedGalleries(
328 ProfileState* profile_state);
330 void ProcessAttach(const std::string& id,
331 const base::string16& name,
332 const base::FilePath::StringType& location) {
333 StorageInfo info(id, location, name, base::string16(), base::string16(), 0);
334 StorageMonitor::GetInstance()->receiver()->ProcessAttach(info);
337 void ProcessDetach(const std::string& id) {
338 StorageMonitor::GetInstance()->receiver()->ProcessDetach(id);
341 MediaFileSystemRegistry* registry() {
342 return test_file_system_context_->registry();
345 size_t GetExtensionGalleriesHostCount(
346 const MediaFileSystemRegistry* registry) const;
348 int num_auto_galleries() {
349 return media_directories_.num_galleries();
352 protected:
353 virtual void SetUp() OVERRIDE;
354 virtual void TearDown() OVERRIDE;
356 private:
357 // This makes sure that at least one default gallery exists on the file
358 // system.
359 EnsureMediaDirectoriesExists media_directories_;
361 // Some test gallery directories.
362 base::ScopedTempDir galleries_dir_;
363 // An empty directory in |galleries_dir_|
364 base::FilePath empty_dir_;
365 // A directory in |galleries_dir_| with a DCIM directory in it.
366 base::FilePath dcim_dir_;
368 // MediaFileSystemRegistry owns this.
369 TestMediaFileSystemContext* test_file_system_context_;
371 // Needed for extension service & friends to work.
373 #if defined(OS_CHROMEOS)
374 chromeos::ScopedTestDeviceSettingsService test_device_settings_service_;
375 chromeos::ScopedTestCrosSettings test_cros_settings_;
376 scoped_ptr<chromeos::ScopedTestUserManager> test_user_manager_;
377 #endif
379 MockProfileSharedRenderProcessHostFactory rph_factory_;
381 ScopedVector<ProfileState> profile_states_;
384 namespace {
386 bool MediaFileSystemInfoComparator(const MediaFileSystemInfo& a,
387 const MediaFileSystemInfo& b) {
388 CHECK_NE(a.name, b.name); // Name must be unique.
389 return a.name < b.name;
392 ///////////////////////////////////////////////
393 // MockProfileSharedRenderProcessHostFactory //
394 ///////////////////////////////////////////////
396 MockProfileSharedRenderProcessHostFactory::
397 ~MockProfileSharedRenderProcessHostFactory() {
398 STLDeleteValues(&rph_map_);
401 content::MockRenderProcessHost*
402 MockProfileSharedRenderProcessHostFactory::ReleaseRPH(
403 content::BrowserContext* browser_context) {
404 ProfileRPHMap::iterator existing = rph_map_.find(browser_context);
405 if (existing == rph_map_.end())
406 return NULL;
407 content::MockRenderProcessHost* result = existing->second;
408 rph_map_.erase(existing);
409 return result;
412 content::RenderProcessHost*
413 MockProfileSharedRenderProcessHostFactory::CreateRenderProcessHost(
414 content::BrowserContext* browser_context,
415 content::SiteInstance* site_instance) const {
416 ProfileRPHMap::const_iterator existing = rph_map_.find(browser_context);
417 if (existing != rph_map_.end())
418 return existing->second;
419 rph_map_[browser_context] =
420 new content::MockRenderProcessHost(browser_context);
421 return rph_map_[browser_context];
424 //////////////////
425 // ProfileState //
426 //////////////////
428 ProfileState::ProfileState(
429 MockProfileSharedRenderProcessHostFactory* rph_factory)
430 : num_comparisons_(0),
431 profile_(new TestingProfile()) {
432 extensions::TestExtensionSystem* extension_system(
433 static_cast<extensions::TestExtensionSystem*>(
434 extensions::ExtensionSystem::Get(profile_.get())));
435 extension_system->CreateExtensionService(
436 CommandLine::ForCurrentProcess(), base::FilePath(), false);
438 std::vector<std::string> all_permissions;
439 all_permissions.push_back("allAutoDetected");
440 all_permissions.push_back("read");
441 std::vector<std::string> read_permissions;
442 read_permissions.push_back("read");
444 all_permission_extension_ =
445 AddMediaGalleriesApp("all", all_permissions, profile_.get());
446 regular_permission_extension_ =
447 AddMediaGalleriesApp("regular", read_permissions, profile_.get());
448 no_permissions_extension_ =
449 AddMediaGalleriesApp("no", read_permissions, profile_.get());
451 single_web_contents_.reset(
452 content::WebContentsTester::CreateTestWebContents(profile_.get(), NULL));
453 single_rph_ = rph_factory->ReleaseRPH(profile_.get());
455 shared_web_contents1_.reset(
456 content::WebContentsTester::CreateTestWebContents(profile_.get(), NULL));
457 shared_web_contents2_.reset(
458 content::WebContentsTester::CreateTestWebContents(profile_.get(), NULL));
459 shared_rph_ = rph_factory->ReleaseRPH(profile_.get());
462 ProfileState::~ProfileState() {
463 // TestExtensionSystem uses DeleteSoon, so we need to delete the profiles
464 // and then run the message queue to clean up. But first we have to
465 // delete everything that references the profile.
466 single_web_contents_.reset();
467 shared_web_contents1_.reset();
468 shared_web_contents2_.reset();
469 profile_.reset();
471 base::MessageLoop::current()->RunUntilIdle();
474 MediaGalleriesPreferences* ProfileState::GetMediaGalleriesPrefs() {
475 MediaGalleriesPreferences* prefs =
476 MediaGalleriesPreferencesFactory::GetForProfile(profile_.get());
477 base::RunLoop loop;
478 prefs->EnsureInitialized(loop.QuitClosure());
479 loop.Run();
480 return prefs;
483 void ProfileState::CheckGalleries(
484 const std::string& test,
485 const std::vector<MediaFileSystemInfo>& regular_extension_galleries,
486 const std::vector<MediaFileSystemInfo>& all_extension_galleries) {
487 content::RenderViewHost* rvh = single_web_contents_->GetRenderViewHost();
488 MediaFileSystemRegistry* registry =
489 g_browser_process->media_file_system_registry();
491 // No Media Galleries permissions.
492 std::vector<MediaFileSystemInfo> empty_expectation;
493 std::vector<base::string16> empty_names;
494 registry->GetMediaFileSystemsForExtension(
495 rvh, no_permissions_extension_.get(),
496 base::Bind(&ProfileState::CompareResults, base::Unretained(this),
497 base::StringPrintf("%s (no permission)", test.c_str()),
498 base::ConstRef(empty_names),
499 base::ConstRef(empty_expectation)));
500 base::MessageLoop::current()->RunUntilIdle();
501 EXPECT_EQ(1, GetAndClearComparisonCount());
503 // Read permission only.
504 registry->GetMediaFileSystemsForExtension(
505 rvh, regular_permission_extension_.get(),
506 base::Bind(&ProfileState::CompareResults, base::Unretained(this),
507 base::StringPrintf("%s (regular permission)", test.c_str()),
508 base::ConstRef(compare_names_read_),
509 base::ConstRef(regular_extension_galleries)));
510 base::MessageLoop::current()->RunUntilIdle();
511 EXPECT_EQ(1, GetAndClearComparisonCount());
513 // All galleries permission.
514 registry->GetMediaFileSystemsForExtension(
515 rvh, all_permission_extension_.get(),
516 base::Bind(&ProfileState::CompareResults, base::Unretained(this),
517 base::StringPrintf("%s (all permission)", test.c_str()),
518 base::ConstRef(compare_names_all_),
519 base::ConstRef(all_extension_galleries)));
520 base::MessageLoop::current()->RunUntilIdle();
521 EXPECT_EQ(1, GetAndClearComparisonCount());
524 FSInfoMap ProfileState::GetGalleriesInfo(extensions::Extension* extension) {
525 content::RenderViewHost* rvh = single_web_contents_->GetRenderViewHost();
526 FSInfoMap results;
527 MediaFileSystemRegistry* registry =
528 g_browser_process->media_file_system_registry();
529 registry->GetMediaFileSystemsForExtension(
530 rvh, extension,
531 base::Bind(&GetGalleryInfoCallback, base::Unretained(&results)));
532 base::MessageLoop::current()->RunUntilIdle();
533 return results;
536 extensions::Extension* ProfileState::all_permission_extension() {
537 return all_permission_extension_.get();
540 extensions::Extension* ProfileState::regular_permission_extension() {
541 return regular_permission_extension_.get();
544 Profile* ProfileState::profile() {
545 return profile_.get();
548 void ProfileState::AddNameForReadCompare(const base::string16& name) {
549 compare_names_read_.push_back(name);
552 void ProfileState::AddNameForAllCompare(const base::string16& name) {
553 compare_names_all_.push_back(name);
556 bool ProfileState::ContainsEntry(
557 const MediaFileSystemInfo& info,
558 const std::vector<MediaFileSystemInfo>& container) {
559 for (size_t i = 0; i < container.size(); ++i) {
560 if (info.path.value() == container[i].path.value()) {
561 EXPECT_FALSE(container[i].fsid.empty());
562 if (!info.fsid.empty())
563 EXPECT_EQ(info.fsid, container[i].fsid);
564 return true;
567 return false;
570 void ProfileState::CompareResults(
571 const std::string& test,
572 const std::vector<base::string16>& names,
573 const std::vector<MediaFileSystemInfo>& expected,
574 const std::vector<MediaFileSystemInfo>& actual) {
575 num_comparisons_++;
576 EXPECT_EQ(expected.size(), actual.size()) << test;
578 // Order isn't important, so sort the results.
579 std::vector<MediaFileSystemInfo> sorted(actual);
580 std::sort(sorted.begin(), sorted.end(), MediaFileSystemInfoComparator);
581 std::vector<MediaFileSystemInfo> expect(expected);
582 std::sort(expect.begin(), expect.end(), MediaFileSystemInfoComparator);
583 std::vector<base::string16> expect_names(names);
584 std::sort(expect_names.begin(), expect_names.end());
586 for (size_t i = 0; i < expect.size() && i < sorted.size(); ++i) {
587 if (expect_names.size() > i)
588 EXPECT_EQ(expect_names[i], sorted[i].name) << test;
589 EXPECT_TRUE(ContainsEntry(expect[i], sorted)) << test;
593 int ProfileState::GetAndClearComparisonCount() {
594 int result = num_comparisons_;
595 num_comparisons_ = 0;
596 return result;
599 } // namespace
601 /////////////////////////////////
602 // MediaFileSystemRegistryTest //
603 /////////////////////////////////
605 void MediaFileSystemRegistryTest::CreateProfileState(size_t profile_count) {
606 for (size_t i = 0; i < profile_count; ++i) {
607 ProfileState* state = new ProfileState(&rph_factory_);
608 profile_states_.push_back(state);
612 ProfileState* MediaFileSystemRegistryTest::GetProfileState(size_t i) {
613 return profile_states_[i];
616 MediaGalleriesPreferences* MediaFileSystemRegistryTest::GetPreferences(
617 Profile* profile) {
618 MediaGalleriesPreferences* prefs = registry()->GetPreferences(profile);
619 base::RunLoop loop;
620 prefs->EnsureInitialized(loop.QuitClosure());
621 loop.Run();
622 return prefs;
625 std::string MediaFileSystemRegistryTest::AddUserGallery(
626 StorageInfo::Type type,
627 const std::string& unique_id,
628 const base::FilePath& path) {
629 std::string device_id = StorageInfo::MakeDeviceId(type, unique_id);
630 DCHECK(!StorageInfo::IsMediaDevice(device_id));
632 for (size_t i = 0; i < profile_states_.size(); ++i) {
633 profile_states_[i]->GetMediaGalleriesPrefs()->AddGallery(
634 device_id, base::FilePath(), MediaGalleryPrefInfo::kUserAdded,
635 base::string16(), base::string16(), base::string16(), 0,
636 base::Time::Now(), 0, 0, 0);
638 return device_id;
641 std::string MediaFileSystemRegistryTest::AttachDevice(
642 StorageInfo::Type type,
643 const std::string& unique_id,
644 const base::FilePath& location) {
645 std::string device_id = StorageInfo::MakeDeviceId(type, unique_id);
646 DCHECK(StorageInfo::IsRemovableDevice(device_id));
647 base::string16 label = location.BaseName().LossyDisplayName();
648 ProcessAttach(device_id, label, location.value());
649 base::MessageLoop::current()->RunUntilIdle();
650 return device_id;
653 void MediaFileSystemRegistryTest::DetachDevice(const std::string& device_id) {
654 DCHECK(StorageInfo::IsRemovableDevice(device_id));
655 ProcessDetach(device_id);
656 base::MessageLoop::current()->RunUntilIdle();
659 void MediaFileSystemRegistryTest::SetGalleryPermission(
660 ProfileState* profile_state, extensions::Extension* extension,
661 const std::string& device_id, bool has_access) {
662 MediaGalleriesPreferences* preferences =
663 profile_state->GetMediaGalleriesPrefs();
664 MediaGalleryPrefIdSet pref_id =
665 preferences->LookUpGalleriesByDeviceId(device_id);
666 ASSERT_EQ(1U, pref_id.size());
667 preferences->SetGalleryPermissionForExtension(*extension, *pref_id.begin(),
668 has_access);
671 void MediaFileSystemRegistryTest::AssertAllAutoAddedGalleries() {
672 for (size_t i = 0; i < profile_states_.size(); ++i) {
673 MediaGalleriesPreferences* prefs =
674 profile_states_[0]->GetMediaGalleriesPrefs();
676 // Make sure that we have at least one gallery and that they are all
677 // auto added galleries.
678 const MediaGalleriesPrefInfoMap& galleries = prefs->known_galleries();
679 #if !defined(OS_CHROMEOS) && !defined(OS_ANDROID)
680 ASSERT_GT(galleries.size(), 0U);
681 #endif
682 for (MediaGalleriesPrefInfoMap::const_iterator it = galleries.begin();
683 it != galleries.end();
684 ++it) {
685 ASSERT_EQ(MediaGalleryPrefInfo::kAutoDetected, it->second.type);
690 void MediaFileSystemRegistryTest::InitForGalleriesInfoTest(
691 FSInfoMap* galleries_info) {
692 CreateProfileState(1);
693 AssertAllAutoAddedGalleries();
695 // Get all existing gallery names.
696 ProfileState* profile_state = GetProfileState(0U);
697 *galleries_info = profile_state->GetGalleriesInfo(
698 profile_state->all_permission_extension());
699 #if !defined(OS_CHROMEOS) && !defined(OS_ANDROID)
700 ASSERT_EQ(3U, galleries_info->size());
701 #else
702 ASSERT_EQ(0U, galleries_info->size());
703 #endif
706 void MediaFileSystemRegistryTest::CheckNewGalleryInfo(
707 ProfileState* profile_state,
708 const FSInfoMap& galleries_info,
709 const base::FilePath& location,
710 bool removable,
711 bool media_device) {
712 // Get new galleries.
713 FSInfoMap new_galleries_info = profile_state->GetGalleriesInfo(
714 profile_state->all_permission_extension());
715 ASSERT_EQ(galleries_info.size() + 1U, new_galleries_info.size());
717 bool found_new = false;
718 for (FSInfoMap::const_iterator it = new_galleries_info.begin();
719 it != new_galleries_info.end();
720 ++it) {
721 if (ContainsKey(galleries_info, it->first))
722 continue;
724 ASSERT_FALSE(found_new);
725 CheckGalleryInfo(it->second, test_file_system_context_, location,
726 removable, media_device);
727 found_new = true;
729 ASSERT_TRUE(found_new);
732 std::vector<MediaFileSystemInfo>
733 MediaFileSystemRegistryTest::GetAutoAddedGalleries(
734 ProfileState* profile_state) {
735 const MediaGalleriesPrefInfoMap& galleries =
736 profile_state->GetMediaGalleriesPrefs()->known_galleries();
737 std::vector<MediaFileSystemInfo> result;
738 for (MediaGalleriesPrefInfoMap::const_iterator it = galleries.begin();
739 it != galleries.end();
740 ++it) {
741 if (it->second.type == MediaGalleryPrefInfo::kAutoDetected) {
742 base::FilePath path = it->second.AbsolutePath();
743 MediaFileSystemInfo info(path.BaseName().LossyDisplayName(), path,
744 std::string(), 0, std::string(), false, false);
745 result.push_back(info);
748 std::sort(result.begin(), result.end(), MediaFileSystemInfoComparator);
749 return result;
752 size_t MediaFileSystemRegistryTest::GetExtensionGalleriesHostCount(
753 const MediaFileSystemRegistry* registry) const {
754 size_t extension_galleries_host_count = 0;
755 for (MediaFileSystemRegistry::ExtensionGalleriesHostMap::const_iterator it =
756 registry->extension_hosts_map_.begin();
757 it != registry->extension_hosts_map_.end();
758 ++it) {
759 extension_galleries_host_count += it->second.size();
761 return extension_galleries_host_count;
765 void MediaFileSystemRegistryTest::SetUp() {
766 ChromeRenderViewHostTestHarness::SetUp();
767 ASSERT_TRUE(TestStorageMonitor::CreateAndInstall());
769 DeleteContents();
770 SetRenderProcessHostFactory(&rph_factory_);
772 test_file_system_context_ = new TestMediaFileSystemContext(
773 g_browser_process->media_file_system_registry());
775 #if defined(OS_CHROMEOS)
776 test_user_manager_.reset(new chromeos::ScopedTestUserManager());
777 #endif
779 ASSERT_TRUE(galleries_dir_.CreateUniqueTempDir());
780 empty_dir_ = galleries_dir_.path().AppendASCII("empty");
781 ASSERT_TRUE(base::CreateDirectory(empty_dir_));
782 dcim_dir_ = galleries_dir_.path().AppendASCII("with_dcim");
783 ASSERT_TRUE(base::CreateDirectory(dcim_dir_));
784 ASSERT_TRUE(base::CreateDirectory(
785 dcim_dir_.Append(storage_monitor::kDCIMDirectoryName)));
788 void MediaFileSystemRegistryTest::TearDown() {
789 profile_states_.clear();
790 MediaFileSystemRegistry* registry =
791 g_browser_process->media_file_system_registry();
792 EXPECT_EQ(0U, GetExtensionGalleriesHostCount(registry));
793 TestStorageMonitor::Destroy();
794 #if defined(OS_CHROMEOS)
795 test_user_manager_.reset();
796 #endif
798 ChromeRenderViewHostTestHarness::TearDown();
801 ///////////
802 // Tests //
803 ///////////
805 TEST_F(MediaFileSystemRegistryTest, Basic) {
806 CreateProfileState(1);
807 AssertAllAutoAddedGalleries();
809 ProfileState* profile_state = GetProfileState(0);
810 std::vector<MediaFileSystemInfo> auto_galleries =
811 GetAutoAddedGalleries(profile_state);
812 std::vector<MediaFileSystemInfo> empty_expectation;
813 profile_state->CheckGalleries("basic", empty_expectation, auto_galleries);
816 TEST_F(MediaFileSystemRegistryTest, UserAddedGallery) {
817 CreateProfileState(1);
818 AssertAllAutoAddedGalleries();
819 ProfileState* profile_state = GetProfileState(0);
820 std::vector<MediaFileSystemInfo> auto_galleries =
821 GetAutoAddedGalleries(profile_state);
822 std::vector<MediaFileSystemInfo> added_galleries;
823 profile_state->CheckGalleries("user added init", added_galleries,
824 auto_galleries);
826 // Add a user gallery to the regular permission extension.
827 std::string device_id = AddUserGallery(StorageInfo::FIXED_MASS_STORAGE,
828 empty_dir().AsUTF8Unsafe(),
829 empty_dir());
830 SetGalleryPermission(profile_state,
831 profile_state->regular_permission_extension(),
832 device_id,
833 true /*has access*/);
834 MediaFileSystemInfo added_info(empty_dir().LossyDisplayName(), empty_dir(),
835 std::string(), 0, std::string(), false, false);
836 added_galleries.push_back(added_info);
837 profile_state->CheckGalleries("user added regular", added_galleries,
838 auto_galleries);
840 // Add it to the all galleries extension.
841 SetGalleryPermission(profile_state,
842 profile_state->all_permission_extension(),
843 device_id,
844 true /*has access*/);
845 auto_galleries.push_back(added_info);
846 profile_state->CheckGalleries("user added all", added_galleries,
847 auto_galleries);
850 // Regression test to make sure erasing galleries does not result a crash.
851 TEST_F(MediaFileSystemRegistryTest, EraseGalleries) {
852 CreateProfileState(1);
853 AssertAllAutoAddedGalleries();
855 ProfileState* profile_state = GetProfileState(0);
856 std::vector<MediaFileSystemInfo> auto_galleries =
857 GetAutoAddedGalleries(profile_state);
858 std::vector<MediaFileSystemInfo> empty_expectation;
859 profile_state->CheckGalleries("erase", empty_expectation, auto_galleries);
861 MediaGalleriesPreferences* prefs = profile_state->GetMediaGalleriesPrefs();
862 MediaGalleriesPrefInfoMap galleries = prefs->known_galleries();
863 for (MediaGalleriesPrefInfoMap::const_iterator it = galleries.begin();
864 it != galleries.end(); ++it) {
865 prefs->ForgetGalleryById(it->first);
869 // Regression test to make sure calling GetPreferences() does not re-insert
870 // galleries on auto-detected removable devices that were blacklisted.
871 TEST_F(MediaFileSystemRegistryTest,
872 GetPreferencesDoesNotReinsertBlacklistedGalleries) {
873 CreateProfileState(1);
874 AssertAllAutoAddedGalleries();
876 ProfileState* profile_state = GetProfileState(0);
877 const size_t gallery_count = GetAutoAddedGalleries(profile_state).size();
879 // Attach a device.
880 const std::string device_id = AttachDevice(
881 StorageInfo::REMOVABLE_MASS_STORAGE_WITH_DCIM,
882 "removable_dcim_fake_id",
883 dcim_dir());
884 EXPECT_EQ(gallery_count + 1, GetAutoAddedGalleries(profile_state).size());
886 // Forget the device.
887 bool forget_gallery = false;
888 MediaGalleriesPreferences* prefs = GetPreferences(profile_state->profile());
889 const MediaGalleriesPrefInfoMap& galleries = prefs->known_galleries();
890 for (MediaGalleriesPrefInfoMap::const_iterator it = galleries.begin();
891 it != galleries.end(); ++it) {
892 if (it->second.device_id == device_id) {
893 prefs->ForgetGalleryById(it->first);
894 forget_gallery = true;
895 break;
898 base::MessageLoop::current()->RunUntilIdle();
899 EXPECT_TRUE(forget_gallery);
900 EXPECT_EQ(gallery_count, GetAutoAddedGalleries(profile_state).size());
902 // Call GetPreferences() and the gallery count should not change.
903 prefs = GetPreferences(profile_state->profile());
904 EXPECT_EQ(gallery_count, GetAutoAddedGalleries(profile_state).size());
907 TEST_F(MediaFileSystemRegistryTest, GalleryNameDefault) {
908 FSInfoMap galleries_info;
909 InitForGalleriesInfoTest(&galleries_info);
911 for (FSInfoMap::const_iterator it = galleries_info.begin();
912 it != galleries_info.end();
913 ++it) {
914 CheckGalleryInfo(it->second, test_file_system_context(),
915 it->second.path, false, false);
919 // TODO(gbillock): Move the remaining test into the linux directory.
920 #if !defined(OS_MACOSX) && !defined(OS_WIN)
921 TEST_F(MediaFileSystemRegistryTest, GalleryMTP) {
922 FSInfoMap galleries_info;
923 InitForGalleriesInfoTest(&galleries_info);
925 base::FilePath location(FILE_PATH_LITERAL("/mtp_bogus"));
926 AttachDevice(StorageInfo::MTP_OR_PTP, "mtp_fake_id", location);
927 CheckNewGalleryInfo(GetProfileState(0U), galleries_info, location,
928 true /*removable*/, true /* media device */);
930 #endif
932 TEST_F(MediaFileSystemRegistryTest, GalleryDCIM) {
933 FSInfoMap galleries_info;
934 InitForGalleriesInfoTest(&galleries_info);
936 AttachDevice(StorageInfo::REMOVABLE_MASS_STORAGE_WITH_DCIM,
937 "removable_dcim_fake_id",
938 dcim_dir());
939 CheckNewGalleryInfo(GetProfileState(0U), galleries_info, dcim_dir(),
940 true /*removable*/, true /* media device */);
943 TEST_F(MediaFileSystemRegistryTest, GalleryNoDCIM) {
944 FSInfoMap galleries_info;
945 InitForGalleriesInfoTest(&galleries_info);
947 std::string device_id =
948 AttachDevice(StorageInfo::REMOVABLE_MASS_STORAGE_NO_DCIM,
949 empty_dir().AsUTF8Unsafe(),
950 empty_dir());
951 std::string device_id2 =
952 AddUserGallery(StorageInfo::REMOVABLE_MASS_STORAGE_NO_DCIM,
953 empty_dir().AsUTF8Unsafe(),
954 empty_dir());
955 ASSERT_EQ(device_id, device_id2);
956 // Add permission for new non-default gallery.
957 ProfileState* profile_state = GetProfileState(0U);
958 SetGalleryPermission(profile_state,
959 profile_state->all_permission_extension(),
960 device_id,
961 true /*has access*/);
962 CheckNewGalleryInfo(profile_state, galleries_info, empty_dir(),
963 true /*removable*/, false /* media device */);
966 TEST_F(MediaFileSystemRegistryTest, GalleryUserAddedPath) {
967 FSInfoMap galleries_info;
968 InitForGalleriesInfoTest(&galleries_info);
970 std::string device_id = AddUserGallery(StorageInfo::FIXED_MASS_STORAGE,
971 empty_dir().AsUTF8Unsafe(),
972 empty_dir());
973 // Add permission for new non-default gallery.
974 ProfileState* profile_state = GetProfileState(0U);
975 SetGalleryPermission(profile_state,
976 profile_state->all_permission_extension(),
977 device_id,
978 true /*has access*/);
979 CheckNewGalleryInfo(profile_state, galleries_info, empty_dir(),
980 false /*removable*/, false /* media device */);
983 TEST_F(MediaFileSystemRegistryTest, DetachedDeviceGalleryPath) {
984 const std::string device_id = AttachDevice(
985 StorageInfo::REMOVABLE_MASS_STORAGE_WITH_DCIM,
986 "removable_dcim_fake_id",
987 dcim_dir());
989 MediaGalleryPrefInfo pref_info;
990 pref_info.device_id = device_id;
991 EXPECT_EQ(dcim_dir().value(), pref_info.AbsolutePath().value());
993 MediaGalleryPrefInfo pref_info_with_relpath;
994 pref_info_with_relpath.path =
995 base::FilePath(FILE_PATH_LITERAL("test_relpath"));
996 pref_info_with_relpath.device_id = device_id;
997 EXPECT_EQ(dcim_dir().Append(pref_info_with_relpath.path).value(),
998 pref_info_with_relpath.AbsolutePath().value());
1000 DetachDevice(device_id);
1001 EXPECT_TRUE(pref_info.AbsolutePath().empty());
1002 EXPECT_TRUE(pref_info_with_relpath.AbsolutePath().empty());
1005 TEST_F(MediaFileSystemRegistryTest, TestNameConstruction) {
1006 CreateProfileState(1);
1007 AssertAllAutoAddedGalleries();
1009 ProfileState* profile_state = GetProfileState(0);
1011 std::string user_gallery = AddUserGallery(StorageInfo::FIXED_MASS_STORAGE,
1012 empty_dir().AsUTF8Unsafe(),
1013 empty_dir());
1014 SetGalleryPermission(profile_state,
1015 profile_state->regular_permission_extension(),
1016 user_gallery,
1017 true /*has access*/);
1018 SetGalleryPermission(profile_state,
1019 profile_state->all_permission_extension(),
1020 user_gallery,
1021 true /*has access*/);
1023 std::vector<MediaFileSystemInfo> auto_galleries =
1024 GetAutoAddedGalleries(profile_state);
1025 MediaFileSystemInfo added_info(empty_dir().BaseName().LossyDisplayName(),
1026 empty_dir(), std::string(), 0, std::string(),
1027 false, false);
1028 auto_galleries.push_back(added_info);
1029 std::vector<MediaFileSystemInfo> one_expectation;
1030 one_expectation.push_back(added_info);
1032 base::string16 empty_dir_name = GetExpectedFolderName(empty_dir());
1033 profile_state->AddNameForReadCompare(empty_dir_name);
1034 profile_state->AddNameForAllCompare(empty_dir_name);
1036 // This part of the test is conditional on default directories existing
1037 // on the test platform. In ChromeOS, these directories do not exist.
1038 base::FilePath path;
1039 if (num_auto_galleries() > 0) {
1040 ASSERT_TRUE(PathService::Get(chrome::DIR_USER_MUSIC, &path));
1041 profile_state->AddNameForAllCompare(GetExpectedFolderName(path));
1042 ASSERT_TRUE(PathService::Get(chrome::DIR_USER_PICTURES, &path));
1043 profile_state->AddNameForAllCompare(GetExpectedFolderName(path));
1044 ASSERT_TRUE(PathService::Get(chrome::DIR_USER_VIDEOS, &path));
1045 profile_state->AddNameForAllCompare(GetExpectedFolderName(path));
1047 profile_state->CheckGalleries("names-dir", one_expectation, auto_galleries);
1048 } else {
1049 profile_state->CheckGalleries("names", one_expectation, one_expectation);
1053 TEST_F(MediaFileSystemRegistryTest, PreferenceListener) {
1054 CreateProfileState(1);
1055 AssertAllAutoAddedGalleries();
1057 // Add a user gallery to the regular permission extension.
1058 std::string device_id = AddUserGallery(StorageInfo::FIXED_MASS_STORAGE,
1059 empty_dir().AsUTF8Unsafe(),
1060 empty_dir());
1061 ProfileState* profile_state = GetProfileState(0);
1062 SetGalleryPermission(profile_state,
1063 profile_state->regular_permission_extension(),
1064 device_id,
1065 true /*has access*/);
1067 FSInfoMap fs_info = profile_state->GetGalleriesInfo(
1068 profile_state->regular_permission_extension());
1069 ASSERT_EQ(1U, fs_info.size());
1070 EXPECT_FALSE(test_file_system_context()->GetRegisteredPath(
1071 fs_info.begin()->second.fsid).empty());
1073 // Revoke permission and ensure that the file system is revoked.
1074 SetGalleryPermission(profile_state,
1075 profile_state->regular_permission_extension(),
1076 device_id,
1077 false /*has access*/);
1078 EXPECT_TRUE(test_file_system_context()->GetRegisteredPath(
1079 fs_info.begin()->second.fsid).empty());