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/browser/storage_monitor/removable_device_constants.h"
32 #include "chrome/browser/storage_monitor/storage_info.h"
33 #include "chrome/browser/storage_monitor/storage_monitor.h"
34 #include "chrome/browser/storage_monitor/test_storage_monitor.h"
35 #include "chrome/common/chrome_paths.h"
36 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
37 #include "chrome/test/base/testing_browser_process.h"
38 #include "chrome/test/base/testing_profile.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
;
59 // Not anonymous so it can be friends with MediaFileSystemRegistry.
60 class TestMediaFileSystemContext
: public MediaFileSystemContext
{
64 FSInfo(const std::string
& device_id
, const base::FilePath
& path
,
65 const std::string
& fsid
);
67 bool operator<(const FSInfo
& other
) const;
69 std::string device_id
;
74 explicit TestMediaFileSystemContext(MediaFileSystemRegistry
* registry
);
75 virtual ~TestMediaFileSystemContext() {}
77 // MediaFileSystemContext implementation.
78 virtual std::string
RegisterFileSystem(
79 const std::string
& device_id
, const base::FilePath
& path
) OVERRIDE
;
81 virtual void RevokeFileSystem(const std::string
& fsid
) OVERRIDE
;
83 base::FilePath
GetPathForId(const std::string
& fsid
) const;
85 MediaFileSystemRegistry
* registry() { return registry_
; }
88 std::string
AddFSEntry(const std::string
& device_id
,
89 const base::FilePath
& path
);
91 MediaFileSystemRegistry
* registry_
;
93 // A counter used to construct mock FSIDs.
96 // The currently allocated mock file systems.
97 std::map
<std::string
/*fsid*/, FSInfo
> file_systems_by_id_
;
100 TestMediaFileSystemContext::FSInfo::FSInfo(const std::string
& device_id
,
101 const base::FilePath
& path
,
102 const std::string
& fsid
)
103 : device_id(device_id
),
108 bool TestMediaFileSystemContext::FSInfo::operator<(const FSInfo
& other
) const {
109 if (device_id
!= other
.device_id
)
110 return device_id
< other
.device_id
;
111 if (path
.value() != other
.path
.value())
112 return path
.value() < other
.path
.value();
113 return fsid
< other
.fsid
;
116 TestMediaFileSystemContext::TestMediaFileSystemContext(
117 MediaFileSystemRegistry
* registry
)
118 : registry_(registry
),
120 registry_
->file_system_context_
.reset(this);
123 std::string
TestMediaFileSystemContext::RegisterFileSystem(
124 const std::string
& device_id
, const base::FilePath
& path
) {
125 std::string fsid
= AddFSEntry(device_id
, path
);
129 void TestMediaFileSystemContext::RevokeFileSystem(const std::string
& fsid
) {
130 if (!ContainsKey(file_systems_by_id_
, fsid
))
132 EXPECT_EQ(1U, file_systems_by_id_
.erase(fsid
));
135 base::FilePath
TestMediaFileSystemContext::GetPathForId(
136 const std::string
& fsid
) const {
137 std::map
<std::string
/*fsid*/, FSInfo
>::const_iterator it
=
138 file_systems_by_id_
.find(fsid
);
139 if (it
== file_systems_by_id_
.end())
140 return base::FilePath();
141 return it
->second
.path
;
144 std::string
TestMediaFileSystemContext::AddFSEntry(const std::string
& device_id
,
145 const base::FilePath
& path
) {
146 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
147 DCHECK(path
.IsAbsolute());
148 DCHECK(!path
.ReferencesParent());
150 std::string fsid
= base::StringPrintf("FSID:%d", ++fsid_
);
151 FSInfo
info(device_id
, path
, fsid
);
152 file_systems_by_id_
[fsid
] = info
;
158 typedef std::map
<MediaGalleryPrefId
, MediaFileSystemInfo
> FSInfoMap
;
160 void GetGalleryInfoCallback(
162 const std::vector
<MediaFileSystemInfo
>& file_systems
) {
163 for (size_t i
= 0; i
< file_systems
.size(); ++i
) {
164 ASSERT_FALSE(ContainsKey(*results
, file_systems
[i
].pref_id
));
165 (*results
)[file_systems
[i
].pref_id
] = file_systems
[i
];
169 void CheckGalleryInfo(const MediaFileSystemInfo
& info
,
170 TestMediaFileSystemContext
* fs_context
,
171 const base::FilePath
& path
,
174 EXPECT_EQ(path
, info
.path
);
175 EXPECT_EQ(removable
, info
.removable
);
176 EXPECT_EQ(media_device
, info
.media_device
);
177 EXPECT_NE(0UL, info
.pref_id
);
180 EXPECT_NE(0UL, info
.transient_device_id
.size());
182 EXPECT_EQ(0UL, info
.transient_device_id
.size());
184 base::FilePath fsid_path
= fs_context
->GetPathForId(info
.fsid
);
185 EXPECT_EQ(path
, fsid_path
);
188 class MockProfileSharedRenderProcessHostFactory
189 : public content::RenderProcessHostFactory
{
191 MockProfileSharedRenderProcessHostFactory() {}
192 virtual ~MockProfileSharedRenderProcessHostFactory();
194 // RPH created with this factory are owned by it. If the RPH is destroyed
195 // for testing purposes, it must be removed from the factory first.
196 content::MockRenderProcessHost
* ReleaseRPH(
197 content::BrowserContext
* browser_context
);
199 virtual content::RenderProcessHost
* CreateRenderProcessHost(
200 content::BrowserContext
* browser_context
,
201 content::SiteInstance
* site_instance
) const OVERRIDE
;
204 typedef std::map
<content::BrowserContext
*, content::MockRenderProcessHost
*>
206 mutable ProfileRPHMap rph_map_
;
208 DISALLOW_COPY_AND_ASSIGN(MockProfileSharedRenderProcessHostFactory
);
213 explicit ProfileState(
214 MockProfileSharedRenderProcessHostFactory
* rph_factory
);
217 MediaGalleriesPreferences
* GetMediaGalleriesPrefs();
220 const std::string
& test
,
221 const std::vector
<MediaFileSystemInfo
>& regular_extension_galleries
,
222 const std::vector
<MediaFileSystemInfo
>& all_extension_galleries
);
224 FSInfoMap
GetGalleriesInfo(extensions::Extension
* extension
);
226 extensions::Extension
* all_permission_extension();
227 extensions::Extension
* regular_permission_extension();
230 void AddNameForReadCompare(const base::string16
& name
);
231 void AddNameForAllCompare(const base::string16
& name
);
234 void CompareResults(const std::string
& test
,
235 const std::vector
<base::string16
>& names
,
236 const std::vector
<MediaFileSystemInfo
>& expected
,
237 const std::vector
<MediaFileSystemInfo
>& actual
);
238 bool ContainsEntry(const MediaFileSystemInfo
& info
,
239 const std::vector
<MediaFileSystemInfo
>& container
);
241 int GetAndClearComparisonCount();
243 int num_comparisons_
;
245 scoped_ptr
<TestingProfile
> profile_
;
247 scoped_refptr
<extensions::Extension
> all_permission_extension_
;
248 scoped_refptr
<extensions::Extension
> regular_permission_extension_
;
249 scoped_refptr
<extensions::Extension
> no_permissions_extension_
;
251 scoped_ptr
<content::WebContents
> single_web_contents_
;
252 scoped_ptr
<content::WebContents
> shared_web_contents1_
;
253 scoped_ptr
<content::WebContents
> shared_web_contents2_
;
255 // The RenderProcessHosts are freed when their respective WebContents /
256 // RenderViewHosts go away.
257 content::MockRenderProcessHost
* single_rph_
;
258 content::MockRenderProcessHost
* shared_rph_
;
260 std::vector
<base::string16
> compare_names_read_
;
261 std::vector
<base::string16
> compare_names_all_
;
263 DISALLOW_COPY_AND_ASSIGN(ProfileState
);
266 base::string16
GetExpectedFolderName(const base::FilePath
& path
) {
267 #if defined(OS_CHROMEOS)
268 return path
.BaseName().LossyDisplayName();
270 return path
.LossyDisplayName();
276 class MediaFileSystemRegistryTest
: public ChromeRenderViewHostTestHarness
{
278 void CreateProfileState(size_t profile_count
);
280 ProfileState
* GetProfileState(size_t i
);
282 MediaGalleriesPreferences
* GetPreferences(Profile
* profile
);
284 base::FilePath
empty_dir() {
288 base::FilePath
dcim_dir() {
292 TestMediaFileSystemContext
* test_file_system_context() {
293 return test_file_system_context_
;
296 // Create a user added gallery based on the information passed and add it to
297 // |profiles|. Returns the device id.
298 std::string
AddUserGallery(StorageInfo::Type type
,
299 const std::string
& unique_id
,
300 const base::FilePath
& path
);
302 // Returns the device id.
303 std::string
AttachDevice(StorageInfo::Type type
,
304 const std::string
& unique_id
,
305 const base::FilePath
& location
);
307 void DetachDevice(const std::string
& device_id
);
309 void SetGalleryPermission(ProfileState
* profile_state
,
310 extensions::Extension
* extension
,
311 const std::string
& device_id
,
314 void AssertAllAutoAddedGalleries();
316 void InitForGalleriesInfoTest(FSInfoMap
* galleries_info
);
318 void CheckNewGalleryInfo(ProfileState
* profile_state
,
319 const FSInfoMap
& galleries_info
,
320 const base::FilePath
& location
,
324 std::vector
<MediaFileSystemInfo
> GetAutoAddedGalleries(
325 ProfileState
* profile_state
);
327 void ProcessAttach(const std::string
& id
,
328 const base::string16
& name
,
329 const base::FilePath::StringType
& location
) {
330 StorageInfo
info(id
, base::string16(), location
, name
, base::string16(),
331 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 virtual void SetUp() OVERRIDE
;
352 virtual 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 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 content::RenderViewHost
* rvh
= single_web_contents_
->GetRenderViewHost();
486 MediaFileSystemRegistry
* registry
=
487 g_browser_process
->media_file_system_registry();
489 // No Media Galleries permissions.
490 std::vector
<MediaFileSystemInfo
> empty_expectation
;
491 std::vector
<base::string16
> empty_names
;
492 registry
->GetMediaFileSystemsForExtension(
493 rvh
, no_permissions_extension_
.get(),
494 base::Bind(&ProfileState::CompareResults
, base::Unretained(this),
495 base::StringPrintf("%s (no permission)", test
.c_str()),
496 base::ConstRef(empty_names
),
497 base::ConstRef(empty_expectation
)));
498 base::MessageLoop::current()->RunUntilIdle();
499 EXPECT_EQ(1, GetAndClearComparisonCount());
501 // Read permission only.
502 registry
->GetMediaFileSystemsForExtension(
503 rvh
, regular_permission_extension_
.get(),
504 base::Bind(&ProfileState::CompareResults
, base::Unretained(this),
505 base::StringPrintf("%s (regular permission)", test
.c_str()),
506 base::ConstRef(compare_names_read_
),
507 base::ConstRef(regular_extension_galleries
)));
508 base::MessageLoop::current()->RunUntilIdle();
509 EXPECT_EQ(1, GetAndClearComparisonCount());
511 // All galleries permission.
512 registry
->GetMediaFileSystemsForExtension(
513 rvh
, all_permission_extension_
.get(),
514 base::Bind(&ProfileState::CompareResults
, base::Unretained(this),
515 base::StringPrintf("%s (all permission)", test
.c_str()),
516 base::ConstRef(compare_names_all_
),
517 base::ConstRef(all_extension_galleries
)));
518 base::MessageLoop::current()->RunUntilIdle();
519 EXPECT_EQ(1, GetAndClearComparisonCount());
522 FSInfoMap
ProfileState::GetGalleriesInfo(extensions::Extension
* extension
) {
523 content::RenderViewHost
* rvh
= single_web_contents_
->GetRenderViewHost();
525 MediaFileSystemRegistry
* registry
=
526 g_browser_process
->media_file_system_registry();
527 registry
->GetMediaFileSystemsForExtension(
529 base::Bind(&GetGalleryInfoCallback
, base::Unretained(&results
)));
530 base::MessageLoop::current()->RunUntilIdle();
534 extensions::Extension
* ProfileState::all_permission_extension() {
535 return all_permission_extension_
.get();
538 extensions::Extension
* ProfileState::regular_permission_extension() {
539 return regular_permission_extension_
.get();
542 Profile
* ProfileState::profile() {
543 return profile_
.get();
546 void ProfileState::AddNameForReadCompare(const base::string16
& name
) {
547 compare_names_read_
.push_back(name
);
550 void ProfileState::AddNameForAllCompare(const base::string16
& name
) {
551 compare_names_all_
.push_back(name
);
554 bool ProfileState::ContainsEntry(
555 const MediaFileSystemInfo
& info
,
556 const std::vector
<MediaFileSystemInfo
>& container
) {
557 for (size_t i
= 0; i
< container
.size(); ++i
) {
558 if (info
.path
.value() == container
[i
].path
.value()) {
559 EXPECT_FALSE(container
[i
].fsid
.empty());
560 if (!info
.fsid
.empty())
561 EXPECT_EQ(info
.fsid
, container
[i
].fsid
);
568 void ProfileState::CompareResults(
569 const std::string
& test
,
570 const std::vector
<base::string16
>& names
,
571 const std::vector
<MediaFileSystemInfo
>& expected
,
572 const std::vector
<MediaFileSystemInfo
>& actual
) {
574 EXPECT_EQ(expected
.size(), actual
.size()) << test
;
576 // Order isn't important, so sort the results.
577 std::vector
<MediaFileSystemInfo
> sorted(actual
);
578 std::sort(sorted
.begin(), sorted
.end(), MediaFileSystemInfoComparator
);
579 std::vector
<MediaFileSystemInfo
> expect(expected
);
580 std::sort(expect
.begin(), expect
.end(), MediaFileSystemInfoComparator
);
581 std::vector
<base::string16
> expect_names(names
);
582 std::sort(expect_names
.begin(), expect_names
.end());
584 for (size_t i
= 0; i
< expect
.size() && i
< sorted
.size(); ++i
) {
585 if (expect_names
.size() > i
)
586 EXPECT_EQ(expect_names
[i
], sorted
[i
].name
) << test
;
587 EXPECT_TRUE(ContainsEntry(expect
[i
], sorted
)) << test
;
591 int ProfileState::GetAndClearComparisonCount() {
592 int result
= num_comparisons_
;
593 num_comparisons_
= 0;
599 /////////////////////////////////
600 // MediaFileSystemRegistryTest //
601 /////////////////////////////////
603 void MediaFileSystemRegistryTest::CreateProfileState(size_t profile_count
) {
604 for (size_t i
= 0; i
< profile_count
; ++i
) {
605 ProfileState
* state
= new ProfileState(&rph_factory_
);
606 profile_states_
.push_back(state
);
610 ProfileState
* MediaFileSystemRegistryTest::GetProfileState(size_t i
) {
611 return profile_states_
[i
];
614 MediaGalleriesPreferences
* MediaFileSystemRegistryTest::GetPreferences(
616 MediaGalleriesPreferences
* prefs
= registry()->GetPreferences(profile
);
618 prefs
->EnsureInitialized(loop
.QuitClosure());
623 std::string
MediaFileSystemRegistryTest::AddUserGallery(
624 StorageInfo::Type type
,
625 const std::string
& unique_id
,
626 const base::FilePath
& path
) {
627 std::string device_id
= StorageInfo::MakeDeviceId(type
, unique_id
);
628 DCHECK(!StorageInfo::IsMediaDevice(device_id
));
630 for (size_t i
= 0; i
< profile_states_
.size(); ++i
) {
631 profile_states_
[i
]->GetMediaGalleriesPrefs()->AddGallery(
632 device_id
, base::FilePath(), MediaGalleryPrefInfo::kUserAdded
,
633 base::string16(), base::string16(), base::string16(), 0,
634 base::Time::Now(), 0, 0, 0);
639 std::string
MediaFileSystemRegistryTest::AttachDevice(
640 StorageInfo::Type type
,
641 const std::string
& unique_id
,
642 const base::FilePath
& location
) {
643 std::string device_id
= StorageInfo::MakeDeviceId(type
, unique_id
);
644 DCHECK(StorageInfo::IsRemovableDevice(device_id
));
645 base::string16 label
= location
.BaseName().LossyDisplayName();
646 ProcessAttach(device_id
, label
, location
.value());
647 base::MessageLoop::current()->RunUntilIdle();
651 void MediaFileSystemRegistryTest::DetachDevice(const std::string
& device_id
) {
652 DCHECK(StorageInfo::IsRemovableDevice(device_id
));
653 ProcessDetach(device_id
);
654 base::MessageLoop::current()->RunUntilIdle();
657 void MediaFileSystemRegistryTest::SetGalleryPermission(
658 ProfileState
* profile_state
, extensions::Extension
* extension
,
659 const std::string
& device_id
, bool has_access
) {
660 MediaGalleriesPreferences
* preferences
=
661 profile_state
->GetMediaGalleriesPrefs();
662 MediaGalleryPrefIdSet pref_id
=
663 preferences
->LookUpGalleriesByDeviceId(device_id
);
664 ASSERT_EQ(1U, pref_id
.size());
665 preferences
->SetGalleryPermissionForExtension(*extension
, *pref_id
.begin(),
669 void MediaFileSystemRegistryTest::AssertAllAutoAddedGalleries() {
670 for (size_t i
= 0; i
< profile_states_
.size(); ++i
) {
671 MediaGalleriesPreferences
* prefs
=
672 profile_states_
[0]->GetMediaGalleriesPrefs();
674 // Make sure that we have at least one gallery and that they are all
675 // auto added galleries.
676 const MediaGalleriesPrefInfoMap
& galleries
= prefs
->known_galleries();
677 #if !defined(OS_CHROMEOS) && !defined(OS_ANDROID)
678 ASSERT_GT(galleries
.size(), 0U);
680 for (MediaGalleriesPrefInfoMap::const_iterator it
= galleries
.begin();
681 it
!= galleries
.end();
683 ASSERT_EQ(MediaGalleryPrefInfo::kAutoDetected
, it
->second
.type
);
688 void MediaFileSystemRegistryTest::InitForGalleriesInfoTest(
689 FSInfoMap
* galleries_info
) {
690 CreateProfileState(1);
691 AssertAllAutoAddedGalleries();
693 // Get all existing gallery names.
694 ProfileState
* profile_state
= GetProfileState(0U);
695 *galleries_info
= profile_state
->GetGalleriesInfo(
696 profile_state
->all_permission_extension());
697 #if !defined(OS_CHROMEOS) && !defined(OS_ANDROID)
698 ASSERT_EQ(3U, galleries_info
->size());
700 ASSERT_EQ(0U, galleries_info
->size());
704 void MediaFileSystemRegistryTest::CheckNewGalleryInfo(
705 ProfileState
* profile_state
,
706 const FSInfoMap
& galleries_info
,
707 const base::FilePath
& location
,
710 // Get new galleries.
711 FSInfoMap new_galleries_info
= profile_state
->GetGalleriesInfo(
712 profile_state
->all_permission_extension());
713 ASSERT_EQ(galleries_info
.size() + 1U, new_galleries_info
.size());
715 bool found_new
= false;
716 for (FSInfoMap::const_iterator it
= new_galleries_info
.begin();
717 it
!= new_galleries_info
.end();
719 if (ContainsKey(galleries_info
, it
->first
))
722 ASSERT_FALSE(found_new
);
723 CheckGalleryInfo(it
->second
, test_file_system_context_
, location
,
724 removable
, media_device
);
727 ASSERT_TRUE(found_new
);
730 std::vector
<MediaFileSystemInfo
>
731 MediaFileSystemRegistryTest::GetAutoAddedGalleries(
732 ProfileState
* profile_state
) {
733 const MediaGalleriesPrefInfoMap
& galleries
=
734 profile_state
->GetMediaGalleriesPrefs()->known_galleries();
735 std::vector
<MediaFileSystemInfo
> result
;
736 for (MediaGalleriesPrefInfoMap::const_iterator it
= galleries
.begin();
737 it
!= galleries
.end();
739 if (it
->second
.type
== MediaGalleryPrefInfo::kAutoDetected
) {
740 base::FilePath path
= it
->second
.AbsolutePath();
741 MediaFileSystemInfo
info(path
.BaseName().LossyDisplayName(), path
,
742 std::string(), 0, std::string(), false, false);
743 result
.push_back(info
);
746 std::sort(result
.begin(), result
.end(), MediaFileSystemInfoComparator
);
750 size_t MediaFileSystemRegistryTest::GetExtensionGalleriesHostCount(
751 const MediaFileSystemRegistry
* registry
) const {
752 size_t extension_galleries_host_count
= 0;
753 for (MediaFileSystemRegistry::ExtensionGalleriesHostMap::const_iterator it
=
754 registry
->extension_hosts_map_
.begin();
755 it
!= registry
->extension_hosts_map_
.end();
757 extension_galleries_host_count
+= it
->second
.size();
759 return extension_galleries_host_count
;
763 void MediaFileSystemRegistryTest::SetUp() {
764 ChromeRenderViewHostTestHarness::SetUp();
765 ASSERT_TRUE(TestStorageMonitor::CreateAndInstall());
768 SetRenderProcessHostFactory(&rph_factory_
);
770 test_file_system_context_
= new TestMediaFileSystemContext(
771 g_browser_process
->media_file_system_registry());
773 #if defined(OS_CHROMEOS)
774 test_user_manager_
.reset(new chromeos::ScopedTestUserManager());
777 ASSERT_TRUE(galleries_dir_
.CreateUniqueTempDir());
778 empty_dir_
= galleries_dir_
.path().AppendASCII("empty");
779 ASSERT_TRUE(base::CreateDirectory(empty_dir_
));
780 dcim_dir_
= galleries_dir_
.path().AppendASCII("with_dcim");
781 ASSERT_TRUE(base::CreateDirectory(dcim_dir_
));
782 ASSERT_TRUE(base::CreateDirectory(dcim_dir_
.Append(kDCIMDirectoryName
)));
785 void MediaFileSystemRegistryTest::TearDown() {
786 profile_states_
.clear();
787 MediaFileSystemRegistry
* registry
=
788 g_browser_process
->media_file_system_registry();
789 EXPECT_EQ(0U, GetExtensionGalleriesHostCount(registry
));
790 TestStorageMonitor::RemoveSingleton();
791 #if defined(OS_CHROMEOS)
792 test_user_manager_
.reset();
795 ChromeRenderViewHostTestHarness::TearDown();
802 TEST_F(MediaFileSystemRegistryTest
, Basic
) {
803 CreateProfileState(1);
804 AssertAllAutoAddedGalleries();
806 ProfileState
* profile_state
= GetProfileState(0);
807 std::vector
<MediaFileSystemInfo
> auto_galleries
=
808 GetAutoAddedGalleries(profile_state
);
809 std::vector
<MediaFileSystemInfo
> empty_expectation
;
810 profile_state
->CheckGalleries("basic", empty_expectation
, auto_galleries
);
813 TEST_F(MediaFileSystemRegistryTest
, UserAddedGallery
) {
814 CreateProfileState(1);
815 AssertAllAutoAddedGalleries();
816 ProfileState
* profile_state
= GetProfileState(0);
817 std::vector
<MediaFileSystemInfo
> auto_galleries
=
818 GetAutoAddedGalleries(profile_state
);
819 std::vector
<MediaFileSystemInfo
> added_galleries
;
820 profile_state
->CheckGalleries("user added init", added_galleries
,
823 // Add a user gallery to the regular permission extension.
824 std::string device_id
= AddUserGallery(StorageInfo::FIXED_MASS_STORAGE
,
825 empty_dir().AsUTF8Unsafe(),
827 SetGalleryPermission(profile_state
,
828 profile_state
->regular_permission_extension(),
830 true /*has access*/);
831 MediaFileSystemInfo
added_info(empty_dir().LossyDisplayName(), empty_dir(),
832 std::string(), 0, std::string(), false, false);
833 added_galleries
.push_back(added_info
);
834 profile_state
->CheckGalleries("user added regular", added_galleries
,
837 // Add it to the all galleries extension.
838 SetGalleryPermission(profile_state
,
839 profile_state
->all_permission_extension(),
841 true /*has access*/);
842 auto_galleries
.push_back(added_info
);
843 profile_state
->CheckGalleries("user added all", added_galleries
,
847 // Regression test to make sure erasing galleries does not result a crash.
848 TEST_F(MediaFileSystemRegistryTest
, EraseGalleries
) {
849 CreateProfileState(1);
850 AssertAllAutoAddedGalleries();
852 ProfileState
* profile_state
= GetProfileState(0);
853 std::vector
<MediaFileSystemInfo
> auto_galleries
=
854 GetAutoAddedGalleries(profile_state
);
855 std::vector
<MediaFileSystemInfo
> empty_expectation
;
856 profile_state
->CheckGalleries("erase", empty_expectation
, auto_galleries
);
858 MediaGalleriesPreferences
* prefs
= profile_state
->GetMediaGalleriesPrefs();
859 MediaGalleriesPrefInfoMap galleries
= prefs
->known_galleries();
860 for (MediaGalleriesPrefInfoMap::const_iterator it
= galleries
.begin();
861 it
!= galleries
.end(); ++it
) {
862 prefs
->ForgetGalleryById(it
->first
);
866 // Regression test to make sure calling GetPreferences() does not re-insert
867 // galleries on auto-detected removable devices that were blacklisted.
868 TEST_F(MediaFileSystemRegistryTest
,
869 GetPreferencesDoesNotReinsertBlacklistedGalleries
) {
870 CreateProfileState(1);
871 AssertAllAutoAddedGalleries();
873 ProfileState
* profile_state
= GetProfileState(0);
874 const size_t gallery_count
= GetAutoAddedGalleries(profile_state
).size();
877 const std::string device_id
= AttachDevice(
878 StorageInfo::REMOVABLE_MASS_STORAGE_WITH_DCIM
,
879 "removable_dcim_fake_id",
881 EXPECT_EQ(gallery_count
+ 1, GetAutoAddedGalleries(profile_state
).size());
883 // Forget the device.
884 bool forget_gallery
= false;
885 MediaGalleriesPreferences
* prefs
= GetPreferences(profile_state
->profile());
886 const MediaGalleriesPrefInfoMap
& galleries
= prefs
->known_galleries();
887 for (MediaGalleriesPrefInfoMap::const_iterator it
= galleries
.begin();
888 it
!= galleries
.end(); ++it
) {
889 if (it
->second
.device_id
== device_id
) {
890 prefs
->ForgetGalleryById(it
->first
);
891 forget_gallery
= true;
895 base::MessageLoop::current()->RunUntilIdle();
896 EXPECT_TRUE(forget_gallery
);
897 EXPECT_EQ(gallery_count
, GetAutoAddedGalleries(profile_state
).size());
899 // Call GetPreferences() and the gallery count should not change.
900 prefs
= GetPreferences(profile_state
->profile());
901 EXPECT_EQ(gallery_count
, GetAutoAddedGalleries(profile_state
).size());
904 TEST_F(MediaFileSystemRegistryTest
, GalleryNameDefault
) {
905 FSInfoMap galleries_info
;
906 InitForGalleriesInfoTest(&galleries_info
);
908 for (FSInfoMap::const_iterator it
= galleries_info
.begin();
909 it
!= galleries_info
.end();
911 CheckGalleryInfo(it
->second
, test_file_system_context(),
912 it
->second
.path
, false, false);
916 // TODO(gbillock): Move the remaining test into the linux directory.
917 #if !defined(OS_MACOSX) && !defined(OS_WIN)
918 TEST_F(MediaFileSystemRegistryTest
, GalleryMTP
) {
919 FSInfoMap galleries_info
;
920 InitForGalleriesInfoTest(&galleries_info
);
922 base::FilePath
location(FILE_PATH_LITERAL("/mtp_bogus"));
923 AttachDevice(StorageInfo::MTP_OR_PTP
, "mtp_fake_id", location
);
924 CheckNewGalleryInfo(GetProfileState(0U), galleries_info
, location
,
925 true /*removable*/, true /* media device */);
929 TEST_F(MediaFileSystemRegistryTest
, GalleryDCIM
) {
930 FSInfoMap galleries_info
;
931 InitForGalleriesInfoTest(&galleries_info
);
933 AttachDevice(StorageInfo::REMOVABLE_MASS_STORAGE_WITH_DCIM
,
934 "removable_dcim_fake_id",
936 CheckNewGalleryInfo(GetProfileState(0U), galleries_info
, dcim_dir(),
937 true /*removable*/, true /* media device */);
940 TEST_F(MediaFileSystemRegistryTest
, GalleryNoDCIM
) {
941 FSInfoMap galleries_info
;
942 InitForGalleriesInfoTest(&galleries_info
);
944 std::string device_id
=
945 AttachDevice(StorageInfo::REMOVABLE_MASS_STORAGE_NO_DCIM
,
946 empty_dir().AsUTF8Unsafe(),
948 std::string device_id2
=
949 AddUserGallery(StorageInfo::REMOVABLE_MASS_STORAGE_NO_DCIM
,
950 empty_dir().AsUTF8Unsafe(),
952 ASSERT_EQ(device_id
, device_id2
);
953 // Add permission for new non-default gallery.
954 ProfileState
* profile_state
= GetProfileState(0U);
955 SetGalleryPermission(profile_state
,
956 profile_state
->all_permission_extension(),
958 true /*has access*/);
959 CheckNewGalleryInfo(profile_state
, galleries_info
, empty_dir(),
960 true /*removable*/, false /* media device */);
963 TEST_F(MediaFileSystemRegistryTest
, GalleryUserAddedPath
) {
964 FSInfoMap galleries_info
;
965 InitForGalleriesInfoTest(&galleries_info
);
967 std::string device_id
= AddUserGallery(StorageInfo::FIXED_MASS_STORAGE
,
968 empty_dir().AsUTF8Unsafe(),
970 // Add permission for new non-default gallery.
971 ProfileState
* profile_state
= GetProfileState(0U);
972 SetGalleryPermission(profile_state
,
973 profile_state
->all_permission_extension(),
975 true /*has access*/);
976 CheckNewGalleryInfo(profile_state
, galleries_info
, empty_dir(),
977 false /*removable*/, false /* media device */);
980 TEST_F(MediaFileSystemRegistryTest
, DetachedDeviceGalleryPath
) {
981 const std::string device_id
= AttachDevice(
982 StorageInfo::REMOVABLE_MASS_STORAGE_WITH_DCIM
,
983 "removable_dcim_fake_id",
986 MediaGalleryPrefInfo pref_info
;
987 pref_info
.device_id
= device_id
;
988 EXPECT_EQ(dcim_dir().value(), pref_info
.AbsolutePath().value());
990 MediaGalleryPrefInfo pref_info_with_relpath
;
991 pref_info_with_relpath
.path
=
992 base::FilePath(FILE_PATH_LITERAL("test_relpath"));
993 pref_info_with_relpath
.device_id
= device_id
;
994 EXPECT_EQ(dcim_dir().Append(pref_info_with_relpath
.path
).value(),
995 pref_info_with_relpath
.AbsolutePath().value());
997 DetachDevice(device_id
);
998 EXPECT_TRUE(pref_info
.AbsolutePath().empty());
999 EXPECT_TRUE(pref_info_with_relpath
.AbsolutePath().empty());
1002 TEST_F(MediaFileSystemRegistryTest
, TestNameConstruction
) {
1003 CreateProfileState(1);
1004 AssertAllAutoAddedGalleries();
1006 ProfileState
* profile_state
= GetProfileState(0);
1008 std::string user_gallery
= AddUserGallery(StorageInfo::FIXED_MASS_STORAGE
,
1009 empty_dir().AsUTF8Unsafe(),
1011 SetGalleryPermission(profile_state
,
1012 profile_state
->regular_permission_extension(),
1014 true /*has access*/);
1015 SetGalleryPermission(profile_state
,
1016 profile_state
->all_permission_extension(),
1018 true /*has access*/);
1020 std::vector
<MediaFileSystemInfo
> auto_galleries
=
1021 GetAutoAddedGalleries(profile_state
);
1022 MediaFileSystemInfo
added_info(empty_dir().BaseName().LossyDisplayName(),
1023 empty_dir(), std::string(), 0, std::string(),
1025 auto_galleries
.push_back(added_info
);
1026 std::vector
<MediaFileSystemInfo
> one_expectation
;
1027 one_expectation
.push_back(added_info
);
1029 base::string16 empty_dir_name
= GetExpectedFolderName(empty_dir());
1030 profile_state
->AddNameForReadCompare(empty_dir_name
);
1031 profile_state
->AddNameForAllCompare(empty_dir_name
);
1033 // This part of the test is conditional on default directories existing
1034 // on the test platform. In ChromeOS, these directories do not exist.
1035 base::FilePath path
;
1036 if (num_auto_galleries() > 0) {
1037 ASSERT_TRUE(PathService::Get(chrome::DIR_USER_MUSIC
, &path
));
1038 profile_state
->AddNameForAllCompare(GetExpectedFolderName(path
));
1039 ASSERT_TRUE(PathService::Get(chrome::DIR_USER_PICTURES
, &path
));
1040 profile_state
->AddNameForAllCompare(GetExpectedFolderName(path
));
1041 ASSERT_TRUE(PathService::Get(chrome::DIR_USER_VIDEOS
, &path
));
1042 profile_state
->AddNameForAllCompare(GetExpectedFolderName(path
));
1044 profile_state
->CheckGalleries("names-dir", one_expectation
, auto_galleries
);
1046 profile_state
->CheckGalleries("names", one_expectation
, one_expectation
);
1050 TEST_F(MediaFileSystemRegistryTest
, PreferenceListener
) {
1051 CreateProfileState(1);
1052 AssertAllAutoAddedGalleries();
1054 // Add a user gallery to the regular permission extension.
1055 std::string device_id
= AddUserGallery(StorageInfo::FIXED_MASS_STORAGE
,
1056 empty_dir().AsUTF8Unsafe(),
1058 ProfileState
* profile_state
= GetProfileState(0);
1059 SetGalleryPermission(profile_state
,
1060 profile_state
->regular_permission_extension(),
1062 true /*has access*/);
1064 FSInfoMap fs_info
= profile_state
->GetGalleriesInfo(
1065 profile_state
->regular_permission_extension());
1066 ASSERT_EQ(1U, fs_info
.size());
1067 EXPECT_FALSE(test_file_system_context()->GetPathForId(
1068 fs_info
.begin()->second
.fsid
).empty());
1070 // Revoke permission and ensure that the file system is revoked.
1071 SetGalleryPermission(profile_state
,
1072 profile_state
->regular_permission_extension(),
1074 false /*has access*/);
1075 EXPECT_TRUE(test_file_system_context()->GetPathForId(
1076 fs_info
.begin()->second
.fsid
).empty());