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.
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"
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
{
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
;
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_
; }
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
),
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
);
133 void TestMediaFileSystemContext::RevokeFileSystem(const std::string
& fs_name
) {
134 if (!ContainsKey(file_systems_by_name_
, fs_name
))
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
;
161 typedef std::map
<MediaGalleryPrefId
, MediaFileSystemInfo
> FSInfoMap
;
163 void GetGalleryInfoCallback(
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
,
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
);
183 EXPECT_NE(0UL, info
.transient_device_id
.size());
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
{
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
;
207 typedef std::map
<content::BrowserContext
*, content::MockRenderProcessHost
*>
209 mutable ProfileRPHMap rph_map_
;
211 DISALLOW_COPY_AND_ASSIGN(MockProfileSharedRenderProcessHostFactory
);
216 explicit ProfileState(
217 MockProfileSharedRenderProcessHostFactory
* rph_factory
);
220 MediaGalleriesPreferences
* GetMediaGalleriesPrefs();
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();
233 void AddNameForReadCompare(const base::string16
& name
);
234 void AddNameForAllCompare(const base::string16
& name
);
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();
273 return path
.LossyDisplayName();
279 class MediaFileSystemRegistryTest
: public ChromeRenderViewHostTestHarness
{
281 void CreateProfileState(size_t profile_count
);
283 ProfileState
* GetProfileState(size_t i
);
285 MediaGalleriesPreferences
* GetPreferences(Profile
* profile
);
287 base::FilePath
empty_dir() {
291 base::FilePath
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
,
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
,
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();
353 virtual void SetUp() OVERRIDE
;
354 virtual void TearDown() OVERRIDE
;
357 // This makes sure that at least one default gallery exists on the file
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_
;
379 MockProfileSharedRenderProcessHostFactory rph_factory_
;
381 ScopedVector
<ProfileState
> profile_states_
;
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())
407 content::MockRenderProcessHost
* result
= existing
->second
;
408 rph_map_
.erase(existing
);
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
];
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();
471 base::MessageLoop::current()->RunUntilIdle();
474 MediaGalleriesPreferences
* ProfileState::GetMediaGalleriesPrefs() {
475 MediaGalleriesPreferences
* prefs
=
476 MediaGalleriesPreferencesFactory::GetForProfile(profile_
.get());
478 prefs
->EnsureInitialized(loop
.QuitClosure());
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();
527 MediaFileSystemRegistry
* registry
=
528 g_browser_process
->media_file_system_registry();
529 registry
->GetMediaFileSystemsForExtension(
531 base::Bind(&GetGalleryInfoCallback
, base::Unretained(&results
)));
532 base::MessageLoop::current()->RunUntilIdle();
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
);
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
) {
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;
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(
618 MediaGalleriesPreferences
* prefs
= registry()->GetPreferences(profile
);
620 prefs
->EnsureInitialized(loop
.QuitClosure());
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);
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();
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(),
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);
682 for (MediaGalleriesPrefInfoMap::const_iterator it
= galleries
.begin();
683 it
!= galleries
.end();
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());
702 ASSERT_EQ(0U, galleries_info
->size());
706 void MediaFileSystemRegistryTest::CheckNewGalleryInfo(
707 ProfileState
* profile_state
,
708 const FSInfoMap
& galleries_info
,
709 const base::FilePath
& location
,
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();
721 if (ContainsKey(galleries_info
, it
->first
))
724 ASSERT_FALSE(found_new
);
725 CheckGalleryInfo(it
->second
, test_file_system_context_
, location
,
726 removable
, media_device
);
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();
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
);
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();
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());
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());
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();
798 ChromeRenderViewHostTestHarness::TearDown();
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
,
826 // Add a user gallery to the regular permission extension.
827 std::string device_id
= AddUserGallery(StorageInfo::FIXED_MASS_STORAGE
,
828 empty_dir().AsUTF8Unsafe(),
830 SetGalleryPermission(profile_state
,
831 profile_state
->regular_permission_extension(),
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
,
840 // Add it to the all galleries extension.
841 SetGalleryPermission(profile_state
,
842 profile_state
->all_permission_extension(),
844 true /*has access*/);
845 auto_galleries
.push_back(added_info
);
846 profile_state
->CheckGalleries("user added all", added_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();
880 const std::string device_id
= AttachDevice(
881 StorageInfo::REMOVABLE_MASS_STORAGE_WITH_DCIM
,
882 "removable_dcim_fake_id",
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;
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();
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 */);
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",
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(),
951 std::string device_id2
=
952 AddUserGallery(StorageInfo::REMOVABLE_MASS_STORAGE_NO_DCIM
,
953 empty_dir().AsUTF8Unsafe(),
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(),
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(),
973 // Add permission for new non-default gallery.
974 ProfileState
* profile_state
= GetProfileState(0U);
975 SetGalleryPermission(profile_state
,
976 profile_state
->all_permission_extension(),
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",
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(),
1014 SetGalleryPermission(profile_state
,
1015 profile_state
->regular_permission_extension(),
1017 true /*has access*/);
1018 SetGalleryPermission(profile_state
,
1019 profile_state
->all_permission_extension(),
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(),
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
);
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(),
1061 ProfileState
* profile_state
= GetProfileState(0);
1062 SetGalleryPermission(profile_state
,
1063 profile_state
->regular_permission_extension(),
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(),
1077 false /*has access*/);
1078 EXPECT_TRUE(test_file_system_context()->GetRegisteredPath(
1079 fs_info
.begin()->second
.fsid
).empty());