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/web_contents.h"
42 #include "content/public/test/mock_render_process_host.h"
43 #include "content/public/test/test_browser_thread.h"
44 #include "content/public/test/web_contents_tester.h"
45 #include "extensions/browser/extension_system.h"
46 #include "extensions/common/extension.h"
47 #include "sync/api/string_ordinal.h"
48 #include "testing/gtest/include/gtest/gtest.h"
50 #if defined(OS_CHROMEOS)
51 #include "chrome/browser/chromeos/login/users/scoped_test_user_manager.h"
52 #include "chrome/browser/chromeos/settings/cros_settings.h"
53 #include "chrome/browser/chromeos/settings/device_settings_service.h"
56 using content::BrowserThread
;
57 using storage_monitor::StorageInfo
;
58 using storage_monitor::StorageMonitor
;
59 using storage_monitor::TestStorageMonitor
;
61 // Not anonymous so it can be friends with MediaFileSystemRegistry.
62 class TestMediaFileSystemContext
: public MediaFileSystemContext
{
66 FSInfo(const std::string
& device_id
, const base::FilePath
& path
,
67 const std::string
& fs_name
);
69 bool operator<(const FSInfo
& other
) const;
71 std::string device_id
;
76 explicit TestMediaFileSystemContext(MediaFileSystemRegistry
* registry
);
77 ~TestMediaFileSystemContext() override
{}
79 // MediaFileSystemContext implementation.
80 bool RegisterFileSystem(const std::string
& device_id
,
81 const std::string
& fs_name
,
82 const base::FilePath
& path
) override
;
84 void RevokeFileSystem(const std::string
& fs_name
) override
;
86 base::FilePath
GetRegisteredPath(const std::string
& fs_name
) const override
;
88 MediaFileSystemRegistry
* registry() { return registry_
; }
91 void AddFSEntry(const std::string
& device_id
,
92 const base::FilePath
& path
,
93 const std::string
& fs_name
);
95 MediaFileSystemRegistry
* registry_
;
97 // The currently allocated mock file systems.
98 std::map
<std::string
/*fs_name*/, FSInfo
> file_systems_by_name_
;
101 TestMediaFileSystemContext::FSInfo::FSInfo(const std::string
& device_id
,
102 const base::FilePath
& path
,
103 const std::string
& fs_name
)
104 : device_id(device_id
),
109 bool TestMediaFileSystemContext::FSInfo::operator<(const FSInfo
& other
) const {
110 if (device_id
!= other
.device_id
)
111 return device_id
< other
.device_id
;
112 if (path
.value() != other
.path
.value())
113 return path
.value() < other
.path
.value();
114 return fs_name
< other
.fs_name
;
117 TestMediaFileSystemContext::TestMediaFileSystemContext(
118 MediaFileSystemRegistry
* registry
)
119 : registry_(registry
) {
120 registry_
->file_system_context_
.reset(this);
123 bool TestMediaFileSystemContext::RegisterFileSystem(
124 const std::string
& device_id
,
125 const std::string
& fs_name
,
126 const base::FilePath
& path
) {
127 AddFSEntry(device_id
, path
, fs_name
);
131 void TestMediaFileSystemContext::RevokeFileSystem(const std::string
& fs_name
) {
132 if (!ContainsKey(file_systems_by_name_
, fs_name
))
134 EXPECT_EQ(1U, file_systems_by_name_
.erase(fs_name
));
137 base::FilePath
TestMediaFileSystemContext::GetRegisteredPath(
138 const std::string
& fs_name
) const {
139 std::map
<std::string
/*fs_name*/, FSInfo
>::const_iterator it
=
140 file_systems_by_name_
.find(fs_name
);
141 if (it
== file_systems_by_name_
.end())
142 return base::FilePath();
143 return it
->second
.path
;
146 void TestMediaFileSystemContext::AddFSEntry(const std::string
& device_id
,
147 const base::FilePath
& path
,
148 const std::string
& fs_name
) {
149 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
150 DCHECK(path
.IsAbsolute());
151 DCHECK(!path
.ReferencesParent());
153 FSInfo
info(device_id
, path
, fs_name
);
154 file_systems_by_name_
[fs_name
] = info
;
159 typedef std::map
<MediaGalleryPrefId
, MediaFileSystemInfo
> FSInfoMap
;
161 void GetGalleryInfoCallback(
163 const std::vector
<MediaFileSystemInfo
>& file_systems
) {
164 for (size_t i
= 0; i
< file_systems
.size(); ++i
) {
165 ASSERT_FALSE(ContainsKey(*results
, file_systems
[i
].pref_id
));
166 (*results
)[file_systems
[i
].pref_id
] = file_systems
[i
];
170 void CheckGalleryInfo(const MediaFileSystemInfo
& info
,
171 TestMediaFileSystemContext
* fs_context
,
172 const base::FilePath
& path
,
175 EXPECT_EQ(path
, info
.path
);
176 EXPECT_EQ(removable
, info
.removable
);
177 EXPECT_EQ(media_device
, info
.media_device
);
178 EXPECT_NE(0UL, info
.pref_id
);
181 EXPECT_NE(0UL, info
.transient_device_id
.size());
183 EXPECT_EQ(0UL, info
.transient_device_id
.size());
185 base::FilePath fsid_path
= fs_context
->GetRegisteredPath(info
.fsid
);
186 EXPECT_EQ(path
, fsid_path
);
189 class MockProfileSharedRenderProcessHostFactory
190 : public content::RenderProcessHostFactory
{
192 MockProfileSharedRenderProcessHostFactory() {}
193 ~MockProfileSharedRenderProcessHostFactory() override
;
195 // RPH created with this factory are owned by it. If the RPH is destroyed
196 // for testing purposes, it must be removed from the factory first.
197 content::MockRenderProcessHost
* ReleaseRPH(
198 content::BrowserContext
* browser_context
);
200 content::RenderProcessHost
* CreateRenderProcessHost(
201 content::BrowserContext
* browser_context
,
202 content::SiteInstance
* site_instance
) const override
;
205 typedef std::map
<content::BrowserContext
*, content::MockRenderProcessHost
*>
207 mutable ProfileRPHMap rph_map_
;
209 DISALLOW_COPY_AND_ASSIGN(MockProfileSharedRenderProcessHostFactory
);
214 explicit ProfileState(
215 MockProfileSharedRenderProcessHostFactory
* rph_factory
);
218 MediaGalleriesPreferences
* GetMediaGalleriesPrefs();
221 const std::string
& test
,
222 const std::vector
<MediaFileSystemInfo
>& regular_extension_galleries
,
223 const std::vector
<MediaFileSystemInfo
>& all_extension_galleries
);
225 FSInfoMap
GetGalleriesInfo(extensions::Extension
* extension
);
227 extensions::Extension
* all_permission_extension();
228 extensions::Extension
* regular_permission_extension();
231 void AddNameForReadCompare(const base::string16
& name
);
232 void AddNameForAllCompare(const base::string16
& name
);
235 void CompareResults(const std::string
& test
,
236 const std::vector
<base::string16
>& names
,
237 const std::vector
<MediaFileSystemInfo
>& expected
,
238 const std::vector
<MediaFileSystemInfo
>& actual
);
239 bool ContainsEntry(const MediaFileSystemInfo
& info
,
240 const std::vector
<MediaFileSystemInfo
>& container
);
242 int GetAndClearComparisonCount();
244 int num_comparisons_
;
246 scoped_ptr
<TestingProfile
> profile_
;
248 scoped_refptr
<extensions::Extension
> all_permission_extension_
;
249 scoped_refptr
<extensions::Extension
> regular_permission_extension_
;
250 scoped_refptr
<extensions::Extension
> no_permissions_extension_
;
252 scoped_ptr
<content::WebContents
> single_web_contents_
;
253 scoped_ptr
<content::WebContents
> shared_web_contents1_
;
254 scoped_ptr
<content::WebContents
> shared_web_contents2_
;
256 // The RenderProcessHosts are freed when their respective WebContents /
257 // RenderViewHosts go away.
258 content::MockRenderProcessHost
* single_rph_
;
259 content::MockRenderProcessHost
* shared_rph_
;
261 std::vector
<base::string16
> compare_names_read_
;
262 std::vector
<base::string16
> compare_names_all_
;
264 DISALLOW_COPY_AND_ASSIGN(ProfileState
);
267 base::string16
GetExpectedFolderName(const base::FilePath
& path
) {
268 #if defined(OS_CHROMEOS)
269 return path
.BaseName().LossyDisplayName();
271 return path
.LossyDisplayName();
277 class MediaFileSystemRegistryTest
: public ChromeRenderViewHostTestHarness
{
279 void CreateProfileState(size_t profile_count
);
281 ProfileState
* GetProfileState(size_t i
);
283 MediaGalleriesPreferences
* GetPreferences(Profile
* profile
);
285 base::FilePath
empty_dir() {
289 base::FilePath
dcim_dir() {
293 TestMediaFileSystemContext
* test_file_system_context() {
294 return test_file_system_context_
;
297 // Create a user added gallery based on the information passed and add it to
298 // |profiles|. Returns the device id.
299 std::string
AddUserGallery(StorageInfo::Type type
,
300 const std::string
& unique_id
,
301 const base::FilePath
& path
);
303 // Returns the device id.
304 std::string
AttachDevice(StorageInfo::Type type
,
305 const std::string
& unique_id
,
306 const base::FilePath
& location
);
308 void DetachDevice(const std::string
& device_id
);
310 void SetGalleryPermission(ProfileState
* profile_state
,
311 extensions::Extension
* extension
,
312 const std::string
& device_id
,
315 void AssertAllAutoAddedGalleries();
317 void InitForGalleriesInfoTest(FSInfoMap
* galleries_info
);
319 void CheckNewGalleryInfo(ProfileState
* profile_state
,
320 const FSInfoMap
& galleries_info
,
321 const base::FilePath
& location
,
325 std::vector
<MediaFileSystemInfo
> GetAutoAddedGalleries(
326 ProfileState
* profile_state
);
328 void ProcessAttach(const std::string
& id
,
329 const base::string16
& name
,
330 const base::FilePath::StringType
& location
) {
331 StorageInfo
info(id
, location
, name
, base::string16(), base::string16(), 0);
332 StorageMonitor::GetInstance()->receiver()->ProcessAttach(info
);
335 void ProcessDetach(const std::string
& id
) {
336 StorageMonitor::GetInstance()->receiver()->ProcessDetach(id
);
339 MediaFileSystemRegistry
* registry() {
340 return test_file_system_context_
->registry();
343 size_t GetExtensionGalleriesHostCount(
344 const MediaFileSystemRegistry
* registry
) const;
346 int num_auto_galleries() {
347 return media_directories_
.num_galleries();
351 void SetUp() override
;
352 void TearDown() override
;
355 // This makes sure that at least one default gallery exists on the file
357 EnsureMediaDirectoriesExists media_directories_
;
359 // Some test gallery directories.
360 base::ScopedTempDir galleries_dir_
;
361 // An empty directory in |galleries_dir_|
362 base::FilePath empty_dir_
;
363 // A directory in |galleries_dir_| with a DCIM directory in it.
364 base::FilePath dcim_dir_
;
366 // MediaFileSystemRegistry owns this.
367 TestMediaFileSystemContext
* test_file_system_context_
;
369 // Needed for extension service & friends to work.
371 #if defined(OS_CHROMEOS)
372 chromeos::ScopedTestDeviceSettingsService test_device_settings_service_
;
373 chromeos::ScopedTestCrosSettings test_cros_settings_
;
374 scoped_ptr
<chromeos::ScopedTestUserManager
> test_user_manager_
;
377 MockProfileSharedRenderProcessHostFactory rph_factory_
;
379 ScopedVector
<ProfileState
> profile_states_
;
384 bool MediaFileSystemInfoComparator(const MediaFileSystemInfo
& a
,
385 const MediaFileSystemInfo
& b
) {
386 CHECK_NE(a
.name
, b
.name
); // Name must be unique.
387 return a
.name
< b
.name
;
390 ///////////////////////////////////////////////
391 // MockProfileSharedRenderProcessHostFactory //
392 ///////////////////////////////////////////////
394 MockProfileSharedRenderProcessHostFactory::
395 ~MockProfileSharedRenderProcessHostFactory() {
396 STLDeleteValues(&rph_map_
);
399 content::MockRenderProcessHost
*
400 MockProfileSharedRenderProcessHostFactory::ReleaseRPH(
401 content::BrowserContext
* browser_context
) {
402 ProfileRPHMap::iterator existing
= rph_map_
.find(browser_context
);
403 if (existing
== rph_map_
.end())
405 content::MockRenderProcessHost
* result
= existing
->second
;
406 rph_map_
.erase(existing
);
410 content::RenderProcessHost
*
411 MockProfileSharedRenderProcessHostFactory::CreateRenderProcessHost(
412 content::BrowserContext
* browser_context
,
413 content::SiteInstance
* site_instance
) const {
414 ProfileRPHMap::const_iterator existing
= rph_map_
.find(browser_context
);
415 if (existing
!= rph_map_
.end())
416 return existing
->second
;
417 rph_map_
[browser_context
] =
418 new content::MockRenderProcessHost(browser_context
);
419 return rph_map_
[browser_context
];
426 ProfileState::ProfileState(
427 MockProfileSharedRenderProcessHostFactory
* rph_factory
)
428 : num_comparisons_(0),
429 profile_(new TestingProfile()) {
430 extensions::TestExtensionSystem
* extension_system(
431 static_cast<extensions::TestExtensionSystem
*>(
432 extensions::ExtensionSystem::Get(profile_
.get())));
433 extension_system
->CreateExtensionService(
434 base::CommandLine::ForCurrentProcess(), base::FilePath(), false);
436 std::vector
<std::string
> all_permissions
;
437 all_permissions
.push_back("allAutoDetected");
438 all_permissions
.push_back("read");
439 std::vector
<std::string
> read_permissions
;
440 read_permissions
.push_back("read");
442 all_permission_extension_
=
443 AddMediaGalleriesApp("all", all_permissions
, profile_
.get());
444 regular_permission_extension_
=
445 AddMediaGalleriesApp("regular", read_permissions
, profile_
.get());
446 no_permissions_extension_
=
447 AddMediaGalleriesApp("no", read_permissions
, profile_
.get());
449 single_web_contents_
.reset(
450 content::WebContentsTester::CreateTestWebContents(profile_
.get(), NULL
));
451 single_rph_
= rph_factory
->ReleaseRPH(profile_
.get());
453 shared_web_contents1_
.reset(
454 content::WebContentsTester::CreateTestWebContents(profile_
.get(), NULL
));
455 shared_web_contents2_
.reset(
456 content::WebContentsTester::CreateTestWebContents(profile_
.get(), NULL
));
457 shared_rph_
= rph_factory
->ReleaseRPH(profile_
.get());
460 ProfileState::~ProfileState() {
461 // TestExtensionSystem uses DeleteSoon, so we need to delete the profiles
462 // and then run the message queue to clean up. But first we have to
463 // delete everything that references the profile.
464 single_web_contents_
.reset();
465 shared_web_contents1_
.reset();
466 shared_web_contents2_
.reset();
469 base::MessageLoop::current()->RunUntilIdle();
472 MediaGalleriesPreferences
* ProfileState::GetMediaGalleriesPrefs() {
473 MediaGalleriesPreferences
* prefs
=
474 MediaGalleriesPreferencesFactory::GetForProfile(profile_
.get());
476 prefs
->EnsureInitialized(loop
.QuitClosure());
481 void ProfileState::CheckGalleries(
482 const std::string
& test
,
483 const std::vector
<MediaFileSystemInfo
>& regular_extension_galleries
,
484 const std::vector
<MediaFileSystemInfo
>& all_extension_galleries
) {
485 MediaFileSystemRegistry
* registry
=
486 g_browser_process
->media_file_system_registry();
488 // No Media Galleries permissions.
489 std::vector
<MediaFileSystemInfo
> empty_expectation
;
490 std::vector
<base::string16
> empty_names
;
491 registry
->GetMediaFileSystemsForExtension(
492 single_web_contents_
.get(), no_permissions_extension_
.get(),
493 base::Bind(&ProfileState::CompareResults
, base::Unretained(this),
494 base::StringPrintf("%s (no permission)", test
.c_str()),
495 base::ConstRef(empty_names
),
496 base::ConstRef(empty_expectation
)));
497 base::MessageLoop::current()->RunUntilIdle();
498 EXPECT_EQ(1, GetAndClearComparisonCount());
500 // Read permission only.
501 registry
->GetMediaFileSystemsForExtension(
502 single_web_contents_
.get(), regular_permission_extension_
.get(),
503 base::Bind(&ProfileState::CompareResults
, base::Unretained(this),
504 base::StringPrintf("%s (regular permission)", test
.c_str()),
505 base::ConstRef(compare_names_read_
),
506 base::ConstRef(regular_extension_galleries
)));
507 base::MessageLoop::current()->RunUntilIdle();
508 EXPECT_EQ(1, GetAndClearComparisonCount());
510 // All galleries permission.
511 registry
->GetMediaFileSystemsForExtension(
512 single_web_contents_
.get(), all_permission_extension_
.get(),
513 base::Bind(&ProfileState::CompareResults
, base::Unretained(this),
514 base::StringPrintf("%s (all permission)", test
.c_str()),
515 base::ConstRef(compare_names_all_
),
516 base::ConstRef(all_extension_galleries
)));
517 base::MessageLoop::current()->RunUntilIdle();
518 EXPECT_EQ(1, GetAndClearComparisonCount());
521 FSInfoMap
ProfileState::GetGalleriesInfo(extensions::Extension
* extension
) {
523 MediaFileSystemRegistry
* registry
=
524 g_browser_process
->media_file_system_registry();
525 registry
->GetMediaFileSystemsForExtension(
526 single_web_contents_
.get(), extension
,
527 base::Bind(&GetGalleryInfoCallback
, base::Unretained(&results
)));
528 base::MessageLoop::current()->RunUntilIdle();
532 extensions::Extension
* ProfileState::all_permission_extension() {
533 return all_permission_extension_
.get();
536 extensions::Extension
* ProfileState::regular_permission_extension() {
537 return regular_permission_extension_
.get();
540 Profile
* ProfileState::profile() {
541 return profile_
.get();
544 void ProfileState::AddNameForReadCompare(const base::string16
& name
) {
545 compare_names_read_
.push_back(name
);
548 void ProfileState::AddNameForAllCompare(const base::string16
& name
) {
549 compare_names_all_
.push_back(name
);
552 bool ProfileState::ContainsEntry(
553 const MediaFileSystemInfo
& info
,
554 const std::vector
<MediaFileSystemInfo
>& container
) {
555 for (size_t i
= 0; i
< container
.size(); ++i
) {
556 if (info
.path
.value() == container
[i
].path
.value()) {
557 EXPECT_FALSE(container
[i
].fsid
.empty());
558 if (!info
.fsid
.empty())
559 EXPECT_EQ(info
.fsid
, container
[i
].fsid
);
566 void ProfileState::CompareResults(
567 const std::string
& test
,
568 const std::vector
<base::string16
>& names
,
569 const std::vector
<MediaFileSystemInfo
>& expected
,
570 const std::vector
<MediaFileSystemInfo
>& actual
) {
572 EXPECT_EQ(expected
.size(), actual
.size()) << test
;
574 // Order isn't important, so sort the results.
575 std::vector
<MediaFileSystemInfo
> sorted(actual
);
576 std::sort(sorted
.begin(), sorted
.end(), MediaFileSystemInfoComparator
);
577 std::vector
<MediaFileSystemInfo
> expect(expected
);
578 std::sort(expect
.begin(), expect
.end(), MediaFileSystemInfoComparator
);
579 std::vector
<base::string16
> expect_names(names
);
580 std::sort(expect_names
.begin(), expect_names
.end());
582 for (size_t i
= 0; i
< expect
.size() && i
< sorted
.size(); ++i
) {
583 if (expect_names
.size() > i
)
584 EXPECT_EQ(expect_names
[i
], sorted
[i
].name
) << test
;
585 EXPECT_TRUE(ContainsEntry(expect
[i
], sorted
)) << test
;
589 int ProfileState::GetAndClearComparisonCount() {
590 int result
= num_comparisons_
;
591 num_comparisons_
= 0;
597 /////////////////////////////////
598 // MediaFileSystemRegistryTest //
599 /////////////////////////////////
601 void MediaFileSystemRegistryTest::CreateProfileState(size_t profile_count
) {
602 for (size_t i
= 0; i
< profile_count
; ++i
) {
603 ProfileState
* state
= new ProfileState(&rph_factory_
);
604 profile_states_
.push_back(state
);
608 ProfileState
* MediaFileSystemRegistryTest::GetProfileState(size_t i
) {
609 return profile_states_
[i
];
612 MediaGalleriesPreferences
* MediaFileSystemRegistryTest::GetPreferences(
614 MediaGalleriesPreferences
* prefs
= registry()->GetPreferences(profile
);
616 prefs
->EnsureInitialized(loop
.QuitClosure());
621 std::string
MediaFileSystemRegistryTest::AddUserGallery(
622 StorageInfo::Type type
,
623 const std::string
& unique_id
,
624 const base::FilePath
& path
) {
625 std::string device_id
= StorageInfo::MakeDeviceId(type
, unique_id
);
626 DCHECK(!StorageInfo::IsMediaDevice(device_id
));
628 for (size_t i
= 0; i
< profile_states_
.size(); ++i
) {
629 profile_states_
[i
]->GetMediaGalleriesPrefs()->AddGallery(
630 device_id
, base::FilePath(), MediaGalleryPrefInfo::kUserAdded
,
631 base::string16(), base::string16(), base::string16(), 0,
632 base::Time::Now(), 0, 0, 0);
637 std::string
MediaFileSystemRegistryTest::AttachDevice(
638 StorageInfo::Type type
,
639 const std::string
& unique_id
,
640 const base::FilePath
& location
) {
641 std::string device_id
= StorageInfo::MakeDeviceId(type
, unique_id
);
642 DCHECK(StorageInfo::IsRemovableDevice(device_id
));
643 base::string16 label
= location
.BaseName().LossyDisplayName();
644 ProcessAttach(device_id
, label
, location
.value());
645 base::MessageLoop::current()->RunUntilIdle();
649 void MediaFileSystemRegistryTest::DetachDevice(const std::string
& device_id
) {
650 DCHECK(StorageInfo::IsRemovableDevice(device_id
));
651 ProcessDetach(device_id
);
652 base::MessageLoop::current()->RunUntilIdle();
655 void MediaFileSystemRegistryTest::SetGalleryPermission(
656 ProfileState
* profile_state
, extensions::Extension
* extension
,
657 const std::string
& device_id
, bool has_access
) {
658 MediaGalleriesPreferences
* preferences
=
659 profile_state
->GetMediaGalleriesPrefs();
660 MediaGalleryPrefIdSet pref_id
=
661 preferences
->LookUpGalleriesByDeviceId(device_id
);
662 ASSERT_EQ(1U, pref_id
.size());
663 preferences
->SetGalleryPermissionForExtension(*extension
, *pref_id
.begin(),
667 void MediaFileSystemRegistryTest::AssertAllAutoAddedGalleries() {
668 for (size_t i
= 0; i
< profile_states_
.size(); ++i
) {
669 MediaGalleriesPreferences
* prefs
=
670 profile_states_
[0]->GetMediaGalleriesPrefs();
672 // Make sure that we have at least one gallery and that they are all
673 // auto added galleries.
674 const MediaGalleriesPrefInfoMap
& galleries
= prefs
->known_galleries();
675 #if !defined(OS_CHROMEOS) && !defined(OS_ANDROID)
676 ASSERT_GT(galleries
.size(), 0U);
678 for (MediaGalleriesPrefInfoMap::const_iterator it
= galleries
.begin();
679 it
!= galleries
.end();
681 ASSERT_EQ(MediaGalleryPrefInfo::kAutoDetected
, it
->second
.type
);
686 void MediaFileSystemRegistryTest::InitForGalleriesInfoTest(
687 FSInfoMap
* galleries_info
) {
688 CreateProfileState(1);
689 AssertAllAutoAddedGalleries();
691 // Get all existing gallery names.
692 ProfileState
* profile_state
= GetProfileState(0U);
693 *galleries_info
= profile_state
->GetGalleriesInfo(
694 profile_state
->all_permission_extension());
695 #if !defined(OS_CHROMEOS) && !defined(OS_ANDROID)
696 ASSERT_EQ(3U, galleries_info
->size());
698 ASSERT_EQ(0U, galleries_info
->size());
702 void MediaFileSystemRegistryTest::CheckNewGalleryInfo(
703 ProfileState
* profile_state
,
704 const FSInfoMap
& galleries_info
,
705 const base::FilePath
& location
,
708 // Get new galleries.
709 FSInfoMap new_galleries_info
= profile_state
->GetGalleriesInfo(
710 profile_state
->all_permission_extension());
711 ASSERT_EQ(galleries_info
.size() + 1U, new_galleries_info
.size());
713 bool found_new
= false;
714 for (FSInfoMap::const_iterator it
= new_galleries_info
.begin();
715 it
!= new_galleries_info
.end();
717 if (ContainsKey(galleries_info
, it
->first
))
720 ASSERT_FALSE(found_new
);
721 CheckGalleryInfo(it
->second
, test_file_system_context_
, location
,
722 removable
, media_device
);
725 ASSERT_TRUE(found_new
);
728 std::vector
<MediaFileSystemInfo
>
729 MediaFileSystemRegistryTest::GetAutoAddedGalleries(
730 ProfileState
* profile_state
) {
731 const MediaGalleriesPrefInfoMap
& galleries
=
732 profile_state
->GetMediaGalleriesPrefs()->known_galleries();
733 std::vector
<MediaFileSystemInfo
> result
;
734 for (MediaGalleriesPrefInfoMap::const_iterator it
= galleries
.begin();
735 it
!= galleries
.end();
737 if (it
->second
.type
== MediaGalleryPrefInfo::kAutoDetected
) {
738 base::FilePath path
= it
->second
.AbsolutePath();
739 MediaFileSystemInfo
info(path
.BaseName().LossyDisplayName(), path
,
740 std::string(), 0, std::string(), false, false);
741 result
.push_back(info
);
744 std::sort(result
.begin(), result
.end(), MediaFileSystemInfoComparator
);
748 size_t MediaFileSystemRegistryTest::GetExtensionGalleriesHostCount(
749 const MediaFileSystemRegistry
* registry
) const {
750 size_t extension_galleries_host_count
= 0;
751 for (MediaFileSystemRegistry::ExtensionGalleriesHostMap::const_iterator it
=
752 registry
->extension_hosts_map_
.begin();
753 it
!= registry
->extension_hosts_map_
.end();
755 extension_galleries_host_count
+= it
->second
.size();
757 return extension_galleries_host_count
;
761 void MediaFileSystemRegistryTest::SetUp() {
762 ChromeRenderViewHostTestHarness::SetUp();
763 ASSERT_TRUE(TestStorageMonitor::CreateAndInstall());
766 SetRenderProcessHostFactory(&rph_factory_
);
768 test_file_system_context_
= new TestMediaFileSystemContext(
769 g_browser_process
->media_file_system_registry());
771 #if defined(OS_CHROMEOS)
772 test_user_manager_
.reset(new chromeos::ScopedTestUserManager());
775 ASSERT_TRUE(galleries_dir_
.CreateUniqueTempDir());
776 empty_dir_
= galleries_dir_
.path().AppendASCII("empty");
777 ASSERT_TRUE(base::CreateDirectory(empty_dir_
));
778 dcim_dir_
= galleries_dir_
.path().AppendASCII("with_dcim");
779 ASSERT_TRUE(base::CreateDirectory(dcim_dir_
));
780 ASSERT_TRUE(base::CreateDirectory(
781 dcim_dir_
.Append(storage_monitor::kDCIMDirectoryName
)));
784 void MediaFileSystemRegistryTest::TearDown() {
785 profile_states_
.clear();
786 MediaFileSystemRegistry
* registry
=
787 g_browser_process
->media_file_system_registry();
788 EXPECT_EQ(0U, GetExtensionGalleriesHostCount(registry
));
789 TestStorageMonitor::Destroy();
790 #if defined(OS_CHROMEOS)
791 test_user_manager_
.reset();
794 ChromeRenderViewHostTestHarness::TearDown();
801 TEST_F(MediaFileSystemRegistryTest
, Basic
) {
802 CreateProfileState(1);
803 AssertAllAutoAddedGalleries();
805 ProfileState
* profile_state
= GetProfileState(0);
806 std::vector
<MediaFileSystemInfo
> auto_galleries
=
807 GetAutoAddedGalleries(profile_state
);
808 std::vector
<MediaFileSystemInfo
> empty_expectation
;
809 profile_state
->CheckGalleries("basic", empty_expectation
, auto_galleries
);
812 TEST_F(MediaFileSystemRegistryTest
, UserAddedGallery
) {
813 CreateProfileState(1);
814 AssertAllAutoAddedGalleries();
815 ProfileState
* profile_state
= GetProfileState(0);
816 std::vector
<MediaFileSystemInfo
> auto_galleries
=
817 GetAutoAddedGalleries(profile_state
);
818 std::vector
<MediaFileSystemInfo
> added_galleries
;
819 profile_state
->CheckGalleries("user added init", added_galleries
,
822 // Add a user gallery to the regular permission extension.
823 std::string device_id
= AddUserGallery(StorageInfo::FIXED_MASS_STORAGE
,
824 empty_dir().AsUTF8Unsafe(),
826 SetGalleryPermission(profile_state
,
827 profile_state
->regular_permission_extension(),
829 true /*has access*/);
830 MediaFileSystemInfo
added_info(empty_dir().LossyDisplayName(), empty_dir(),
831 std::string(), 0, std::string(), false, false);
832 added_galleries
.push_back(added_info
);
833 profile_state
->CheckGalleries("user added regular", added_galleries
,
836 // Add it to the all galleries extension.
837 SetGalleryPermission(profile_state
,
838 profile_state
->all_permission_extension(),
840 true /*has access*/);
841 auto_galleries
.push_back(added_info
);
842 profile_state
->CheckGalleries("user added all", added_galleries
,
846 // Regression test to make sure erasing galleries does not result a crash.
847 TEST_F(MediaFileSystemRegistryTest
, EraseGalleries
) {
848 CreateProfileState(1);
849 AssertAllAutoAddedGalleries();
851 ProfileState
* profile_state
= GetProfileState(0);
852 std::vector
<MediaFileSystemInfo
> auto_galleries
=
853 GetAutoAddedGalleries(profile_state
);
854 std::vector
<MediaFileSystemInfo
> empty_expectation
;
855 profile_state
->CheckGalleries("erase", empty_expectation
, auto_galleries
);
857 MediaGalleriesPreferences
* prefs
= profile_state
->GetMediaGalleriesPrefs();
858 MediaGalleriesPrefInfoMap galleries
= prefs
->known_galleries();
859 for (MediaGalleriesPrefInfoMap::const_iterator it
= galleries
.begin();
860 it
!= galleries
.end(); ++it
) {
861 prefs
->ForgetGalleryById(it
->first
);
865 // Regression test to make sure calling GetPreferences() does not re-insert
866 // galleries on auto-detected removable devices that were blacklisted.
867 TEST_F(MediaFileSystemRegistryTest
,
868 GetPreferencesDoesNotReinsertBlacklistedGalleries
) {
869 CreateProfileState(1);
870 AssertAllAutoAddedGalleries();
872 ProfileState
* profile_state
= GetProfileState(0);
873 const size_t gallery_count
= GetAutoAddedGalleries(profile_state
).size();
876 const std::string device_id
= AttachDevice(
877 StorageInfo::REMOVABLE_MASS_STORAGE_WITH_DCIM
,
878 "removable_dcim_fake_id",
880 EXPECT_EQ(gallery_count
+ 1, GetAutoAddedGalleries(profile_state
).size());
882 // Forget the device.
883 bool forget_gallery
= false;
884 MediaGalleriesPreferences
* prefs
= GetPreferences(profile_state
->profile());
885 const MediaGalleriesPrefInfoMap
& galleries
= prefs
->known_galleries();
886 for (MediaGalleriesPrefInfoMap::const_iterator it
= galleries
.begin();
887 it
!= galleries
.end(); ++it
) {
888 if (it
->second
.device_id
== device_id
) {
889 prefs
->ForgetGalleryById(it
->first
);
890 forget_gallery
= true;
894 base::MessageLoop::current()->RunUntilIdle();
895 EXPECT_TRUE(forget_gallery
);
896 EXPECT_EQ(gallery_count
, GetAutoAddedGalleries(profile_state
).size());
898 // Call GetPreferences() and the gallery count should not change.
899 prefs
= GetPreferences(profile_state
->profile());
900 EXPECT_EQ(gallery_count
, GetAutoAddedGalleries(profile_state
).size());
903 TEST_F(MediaFileSystemRegistryTest
, GalleryNameDefault
) {
904 FSInfoMap galleries_info
;
905 InitForGalleriesInfoTest(&galleries_info
);
907 for (FSInfoMap::const_iterator it
= galleries_info
.begin();
908 it
!= galleries_info
.end();
910 CheckGalleryInfo(it
->second
, test_file_system_context(),
911 it
->second
.path
, false, false);
915 // TODO(gbillock): Move the remaining test into the linux directory.
916 #if !defined(OS_MACOSX) && !defined(OS_WIN)
917 TEST_F(MediaFileSystemRegistryTest
, GalleryMTP
) {
918 FSInfoMap galleries_info
;
919 InitForGalleriesInfoTest(&galleries_info
);
921 base::FilePath
location(FILE_PATH_LITERAL("/mtp_bogus"));
922 AttachDevice(StorageInfo::MTP_OR_PTP
, "mtp_fake_id", location
);
923 CheckNewGalleryInfo(GetProfileState(0U), galleries_info
, location
,
924 true /*removable*/, true /* media device */);
928 TEST_F(MediaFileSystemRegistryTest
, GalleryDCIM
) {
929 FSInfoMap galleries_info
;
930 InitForGalleriesInfoTest(&galleries_info
);
932 AttachDevice(StorageInfo::REMOVABLE_MASS_STORAGE_WITH_DCIM
,
933 "removable_dcim_fake_id",
935 CheckNewGalleryInfo(GetProfileState(0U), galleries_info
, dcim_dir(),
936 true /*removable*/, true /* media device */);
939 TEST_F(MediaFileSystemRegistryTest
, GalleryNoDCIM
) {
940 FSInfoMap galleries_info
;
941 InitForGalleriesInfoTest(&galleries_info
);
943 std::string device_id
=
944 AttachDevice(StorageInfo::REMOVABLE_MASS_STORAGE_NO_DCIM
,
945 empty_dir().AsUTF8Unsafe(),
947 std::string device_id2
=
948 AddUserGallery(StorageInfo::REMOVABLE_MASS_STORAGE_NO_DCIM
,
949 empty_dir().AsUTF8Unsafe(),
951 ASSERT_EQ(device_id
, device_id2
);
952 // Add permission for new non-default gallery.
953 ProfileState
* profile_state
= GetProfileState(0U);
954 SetGalleryPermission(profile_state
,
955 profile_state
->all_permission_extension(),
957 true /*has access*/);
958 CheckNewGalleryInfo(profile_state
, galleries_info
, empty_dir(),
959 true /*removable*/, false /* media device */);
962 TEST_F(MediaFileSystemRegistryTest
, GalleryUserAddedPath
) {
963 FSInfoMap galleries_info
;
964 InitForGalleriesInfoTest(&galleries_info
);
966 std::string device_id
= AddUserGallery(StorageInfo::FIXED_MASS_STORAGE
,
967 empty_dir().AsUTF8Unsafe(),
969 // Add permission for new non-default gallery.
970 ProfileState
* profile_state
= GetProfileState(0U);
971 SetGalleryPermission(profile_state
,
972 profile_state
->all_permission_extension(),
974 true /*has access*/);
975 CheckNewGalleryInfo(profile_state
, galleries_info
, empty_dir(),
976 false /*removable*/, false /* media device */);
979 TEST_F(MediaFileSystemRegistryTest
, DetachedDeviceGalleryPath
) {
980 const std::string device_id
= AttachDevice(
981 StorageInfo::REMOVABLE_MASS_STORAGE_WITH_DCIM
,
982 "removable_dcim_fake_id",
985 MediaGalleryPrefInfo pref_info
;
986 pref_info
.device_id
= device_id
;
987 EXPECT_EQ(dcim_dir().value(), pref_info
.AbsolutePath().value());
989 MediaGalleryPrefInfo pref_info_with_relpath
;
990 pref_info_with_relpath
.path
=
991 base::FilePath(FILE_PATH_LITERAL("test_relpath"));
992 pref_info_with_relpath
.device_id
= device_id
;
993 EXPECT_EQ(dcim_dir().Append(pref_info_with_relpath
.path
).value(),
994 pref_info_with_relpath
.AbsolutePath().value());
996 DetachDevice(device_id
);
997 EXPECT_TRUE(pref_info
.AbsolutePath().empty());
998 EXPECT_TRUE(pref_info_with_relpath
.AbsolutePath().empty());
1001 TEST_F(MediaFileSystemRegistryTest
, TestNameConstruction
) {
1002 CreateProfileState(1);
1003 AssertAllAutoAddedGalleries();
1005 ProfileState
* profile_state
= GetProfileState(0);
1007 std::string user_gallery
= AddUserGallery(StorageInfo::FIXED_MASS_STORAGE
,
1008 empty_dir().AsUTF8Unsafe(),
1010 SetGalleryPermission(profile_state
,
1011 profile_state
->regular_permission_extension(),
1013 true /*has access*/);
1014 SetGalleryPermission(profile_state
,
1015 profile_state
->all_permission_extension(),
1017 true /*has access*/);
1019 std::vector
<MediaFileSystemInfo
> auto_galleries
=
1020 GetAutoAddedGalleries(profile_state
);
1021 MediaFileSystemInfo
added_info(empty_dir().BaseName().LossyDisplayName(),
1022 empty_dir(), std::string(), 0, std::string(),
1024 auto_galleries
.push_back(added_info
);
1025 std::vector
<MediaFileSystemInfo
> one_expectation
;
1026 one_expectation
.push_back(added_info
);
1028 base::string16 empty_dir_name
= GetExpectedFolderName(empty_dir());
1029 profile_state
->AddNameForReadCompare(empty_dir_name
);
1030 profile_state
->AddNameForAllCompare(empty_dir_name
);
1032 // This part of the test is conditional on default directories existing
1033 // on the test platform. In ChromeOS, these directories do not exist.
1034 base::FilePath path
;
1035 if (num_auto_galleries() > 0) {
1036 ASSERT_TRUE(PathService::Get(chrome::DIR_USER_MUSIC
, &path
));
1037 profile_state
->AddNameForAllCompare(GetExpectedFolderName(path
));
1038 ASSERT_TRUE(PathService::Get(chrome::DIR_USER_PICTURES
, &path
));
1039 profile_state
->AddNameForAllCompare(GetExpectedFolderName(path
));
1040 ASSERT_TRUE(PathService::Get(chrome::DIR_USER_VIDEOS
, &path
));
1041 profile_state
->AddNameForAllCompare(GetExpectedFolderName(path
));
1043 profile_state
->CheckGalleries("names-dir", one_expectation
, auto_galleries
);
1045 profile_state
->CheckGalleries("names", one_expectation
, one_expectation
);
1049 TEST_F(MediaFileSystemRegistryTest
, PreferenceListener
) {
1050 CreateProfileState(1);
1051 AssertAllAutoAddedGalleries();
1053 // Add a user gallery to the regular permission extension.
1054 std::string device_id
= AddUserGallery(StorageInfo::FIXED_MASS_STORAGE
,
1055 empty_dir().AsUTF8Unsafe(),
1057 ProfileState
* profile_state
= GetProfileState(0);
1058 SetGalleryPermission(profile_state
,
1059 profile_state
->regular_permission_extension(),
1061 true /*has access*/);
1063 FSInfoMap fs_info
= profile_state
->GetGalleriesInfo(
1064 profile_state
->regular_permission_extension());
1065 ASSERT_EQ(1U, fs_info
.size());
1066 EXPECT_FALSE(test_file_system_context()->GetRegisteredPath(
1067 fs_info
.begin()->second
.fsid
).empty());
1069 // Revoke permission and ensure that the file system is revoked.
1070 SetGalleryPermission(profile_state
,
1071 profile_state
->regular_permission_extension(),
1073 false /*has access*/);
1074 EXPECT_TRUE(test_file_system_context()->GetRegisteredPath(
1075 fs_info
.begin()->second
.fsid
).empty());