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/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"
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 ~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_
; }
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
),
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
);
132 void TestMediaFileSystemContext::RevokeFileSystem(const std::string
& fs_name
) {
133 if (!ContainsKey(file_systems_by_name_
, fs_name
))
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
;
160 typedef std::map
<MediaGalleryPrefId
, MediaFileSystemInfo
> FSInfoMap
;
162 void GetGalleryInfoCallback(
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
,
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
);
182 EXPECT_NE(0UL, info
.transient_device_id
.size());
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
{
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
;
206 typedef std::map
<content::BrowserContext
*, content::MockRenderProcessHost
*>
208 mutable ProfileRPHMap rph_map_
;
210 DISALLOW_COPY_AND_ASSIGN(MockProfileSharedRenderProcessHostFactory
);
215 explicit ProfileState(
216 MockProfileSharedRenderProcessHostFactory
* rph_factory
);
219 MediaGalleriesPreferences
* GetMediaGalleriesPrefs();
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();
232 void AddNameForReadCompare(const base::string16
& name
);
233 void AddNameForAllCompare(const base::string16
& name
);
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();
272 return path
.LossyDisplayName();
278 class MediaFileSystemRegistryTest
: public ChromeRenderViewHostTestHarness
{
280 void CreateProfileState(size_t profile_count
);
282 ProfileState
* GetProfileState(size_t i
);
284 MediaGalleriesPreferences
* GetPreferences(Profile
* profile
);
286 base::FilePath
empty_dir() {
290 base::FilePath
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
,
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
,
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();
352 void SetUp() override
;
353 void TearDown() override
;
356 // This makes sure that at least one default gallery exists on the file
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_
;
378 MockProfileSharedRenderProcessHostFactory rph_factory_
;
380 ScopedVector
<ProfileState
> profile_states_
;
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())
406 content::MockRenderProcessHost
* result
= existing
->second
;
407 rph_map_
.erase(existing
);
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
];
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();
470 base::MessageLoop::current()->RunUntilIdle();
473 MediaGalleriesPreferences
* ProfileState::GetMediaGalleriesPrefs() {
474 MediaGalleriesPreferences
* prefs
=
475 MediaGalleriesPreferencesFactory::GetForProfile(profile_
.get());
477 prefs
->EnsureInitialized(loop
.QuitClosure());
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();
526 MediaFileSystemRegistry
* registry
=
527 g_browser_process
->media_file_system_registry();
528 registry
->GetMediaFileSystemsForExtension(
530 base::Bind(&GetGalleryInfoCallback
, base::Unretained(&results
)));
531 base::MessageLoop::current()->RunUntilIdle();
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
);
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
) {
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;
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(
617 MediaGalleriesPreferences
* prefs
= registry()->GetPreferences(profile
);
619 prefs
->EnsureInitialized(loop
.QuitClosure());
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);
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();
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(),
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);
681 for (MediaGalleriesPrefInfoMap::const_iterator it
= galleries
.begin();
682 it
!= galleries
.end();
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());
701 ASSERT_EQ(0U, galleries_info
->size());
705 void MediaFileSystemRegistryTest::CheckNewGalleryInfo(
706 ProfileState
* profile_state
,
707 const FSInfoMap
& galleries_info
,
708 const base::FilePath
& location
,
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();
720 if (ContainsKey(galleries_info
, it
->first
))
723 ASSERT_FALSE(found_new
);
724 CheckGalleryInfo(it
->second
, test_file_system_context_
, location
,
725 removable
, media_device
);
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();
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
);
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();
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());
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());
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();
797 ChromeRenderViewHostTestHarness::TearDown();
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
,
825 // Add a user gallery to the regular permission extension.
826 std::string device_id
= AddUserGallery(StorageInfo::FIXED_MASS_STORAGE
,
827 empty_dir().AsUTF8Unsafe(),
829 SetGalleryPermission(profile_state
,
830 profile_state
->regular_permission_extension(),
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
,
839 // Add it to the all galleries extension.
840 SetGalleryPermission(profile_state
,
841 profile_state
->all_permission_extension(),
843 true /*has access*/);
844 auto_galleries
.push_back(added_info
);
845 profile_state
->CheckGalleries("user added all", added_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();
879 const std::string device_id
= AttachDevice(
880 StorageInfo::REMOVABLE_MASS_STORAGE_WITH_DCIM
,
881 "removable_dcim_fake_id",
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;
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();
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 */);
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",
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(),
950 std::string device_id2
=
951 AddUserGallery(StorageInfo::REMOVABLE_MASS_STORAGE_NO_DCIM
,
952 empty_dir().AsUTF8Unsafe(),
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(),
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(),
972 // Add permission for new non-default gallery.
973 ProfileState
* profile_state
= GetProfileState(0U);
974 SetGalleryPermission(profile_state
,
975 profile_state
->all_permission_extension(),
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",
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(),
1013 SetGalleryPermission(profile_state
,
1014 profile_state
->regular_permission_extension(),
1016 true /*has access*/);
1017 SetGalleryPermission(profile_state
,
1018 profile_state
->all_permission_extension(),
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(),
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
);
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(),
1060 ProfileState
* profile_state
= GetProfileState(0);
1061 SetGalleryPermission(profile_state
,
1062 profile_state
->regular_permission_extension(),
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(),
1076 false /*has access*/);
1077 EXPECT_TRUE(test_file_system_context()->GetRegisteredPath(
1078 fs_info
.begin()->second
.fsid
).empty());