1 // Copyright 2014 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.
6 #include "base/command_line.h"
7 #include "base/files/file_path.h"
8 #include "base/files/file_util.h"
9 #include "base/files/scoped_temp_dir.h"
10 #include "base/memory/scoped_ptr.h"
11 #include "base/run_loop.h"
12 #include "base/test/scoped_path_override.h"
13 #include "chrome/browser/extensions/test_extension_system.h"
14 #include "chrome/browser/media_galleries/gallery_watch_manager.h"
15 #include "chrome/browser/media_galleries/gallery_watch_manager_observer.h"
16 #include "chrome/browser/media_galleries/media_galleries_preferences.h"
17 #include "chrome/browser/media_galleries/media_galleries_preferences_factory.h"
18 #include "chrome/browser/media_galleries/media_galleries_test_util.h"
19 #include "chrome/test/base/testing_profile.h"
20 #include "components/storage_monitor/test_storage_monitor.h"
21 #include "content/public/test/test_browser_thread_bundle.h"
22 #include "extensions/browser/extension_system.h"
23 #include "extensions/common/extension.h"
24 #include "extensions/common/permissions/media_galleries_permission.h"
25 #include "testing/gtest/include/gtest/gtest.h"
27 #if defined(OS_CHROMEOS)
28 #include "chrome/browser/chromeos/login/users/scoped_test_user_manager.h"
29 #include "chrome/browser/chromeos/settings/cros_settings.h"
30 #include "chrome/browser/chromeos/settings/device_settings_service.h"
33 namespace component_updater
{
37 void ConfirmWatch(base::RunLoop
* loop
, const std::string
& error
) {
38 EXPECT_TRUE(error
.empty());
42 void ExpectWatchError(base::RunLoop
* loop
,
43 const std::string
& expected_error
,
44 const std::string
& error
) {
45 EXPECT_EQ(expected_error
, error
);
51 class GalleryWatchManagerTest
: public GalleryWatchManagerObserver
,
52 public testing::Test
{
54 GalleryWatchManagerTest()
55 : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP
),
56 profile_(new TestingProfile()),
58 expect_gallery_changed_(false),
59 expect_gallery_watch_dropped_(false),
60 pending_loop_(NULL
) {}
62 ~GalleryWatchManagerTest() override
{}
64 void SetUp() override
{
65 monitor_
= storage_monitor::TestStorageMonitor::CreateAndInstall();
66 ASSERT_TRUE(monitor_
);
68 extensions::TestExtensionSystem
* extension_system(
69 static_cast<extensions::TestExtensionSystem
*>(
70 extensions::ExtensionSystem::Get(profile_
.get())));
71 extension_system
->CreateExtensionService(
72 base::CommandLine::ForCurrentProcess(), base::FilePath(), false);
75 MediaGalleriesPreferencesFactory::GetForProfile(profile_
.get());
77 gallery_prefs_
->EnsureInitialized(loop
.QuitClosure());
80 std::vector
<std::string
> read_permissions
;
81 read_permissions
.push_back(
82 extensions::MediaGalleriesPermission::kReadPermission
);
83 extension_
= AddMediaGalleriesApp("read", read_permissions
, profile_
.get());
85 manager_
.reset(new GalleryWatchManager
);
86 manager_
->AddObserver(profile_
.get(), this);
89 void TearDown() override
{
90 manager_
->RemoveObserver(profile_
.get());
92 storage_monitor::TestStorageMonitor::Destroy();
96 // Create the specified path, and add it to preferences as a gallery.
97 MediaGalleryPrefId
AddGallery(const base::FilePath
& path
) {
98 MediaGalleryPrefInfo gallery_info
;
99 EXPECT_FALSE(gallery_prefs_
->LookUpGalleryByPath(path
, &gallery_info
));
100 MediaGalleryPrefId id
=
101 gallery_prefs_
->AddGallery(gallery_info
.device_id
,
103 MediaGalleryPrefInfo::kUserAdded
,
104 gallery_info
.volume_label
,
105 gallery_info
.vendor_name
,
106 gallery_info
.model_name
,
107 gallery_info
.total_size_in_bytes
,
108 gallery_info
.last_attach_time
,
112 EXPECT_NE(kInvalidMediaGalleryPrefId
, id
);
114 EXPECT_TRUE(gallery_prefs_
->SetGalleryPermissionForExtension(
115 *extension_
, id
, true));
119 TestingProfile
* profile() { return profile_
.get(); }
121 GalleryWatchManager
* manager() { return manager_
.get(); }
123 extensions::Extension
* extension() { return extension_
.get(); }
125 MediaGalleriesPreferences
* gallery_prefs() { return gallery_prefs_
; }
127 storage_monitor::TestStorageMonitor
* storage_monitor() { return monitor_
; }
129 bool GalleryWatchesSupported() {
130 return base::FilePathWatcher::RecursiveWatchAvailable();
133 void AddAndConfirmWatch(MediaGalleryPrefId gallery_id
) {
135 manager()->AddWatch(profile(),
138 base::Bind(&ConfirmWatch
, base::Unretained(&loop
)));
142 void ExpectGalleryChanged(base::RunLoop
* loop
) {
143 expect_gallery_changed_
= true;
144 pending_loop_
= loop
;
147 void ExpectGalleryWatchDropped(base::RunLoop
* loop
) {
148 expect_gallery_watch_dropped_
= true;
149 pending_loop_
= loop
;
153 // GalleryWatchManagerObserver implementation.
154 void OnGalleryChanged(const std::string
& extension_id
,
155 MediaGalleryPrefId gallery_id
) override
{
156 EXPECT_TRUE(expect_gallery_changed_
);
157 pending_loop_
->Quit();
160 void OnGalleryWatchDropped(const std::string
& extension_id
,
161 MediaGalleryPrefId gallery_id
) override
{
162 EXPECT_TRUE(expect_gallery_watch_dropped_
);
163 pending_loop_
->Quit();
166 scoped_ptr
<GalleryWatchManager
> manager_
;
168 // Needed for extension service & friends to work.
169 content::TestBrowserThreadBundle thread_bundle_
;
171 scoped_refptr
<extensions::Extension
> extension_
;
173 EnsureMediaDirectoriesExists mock_gallery_locations_
;
175 #if defined(OS_CHROMEOS)
176 chromeos::ScopedTestDeviceSettingsService test_device_settings_service_
;
177 chromeos::ScopedTestCrosSettings test_cros_settings_
;
178 chromeos::ScopedTestUserManager test_user_manager_
;
181 storage_monitor::TestStorageMonitor
* monitor_
;
182 scoped_ptr
<TestingProfile
> profile_
;
183 MediaGalleriesPreferences
* gallery_prefs_
;
185 bool expect_gallery_changed_
;
186 bool expect_gallery_watch_dropped_
;
187 base::RunLoop
* pending_loop_
;
189 DISALLOW_COPY_AND_ASSIGN(GalleryWatchManagerTest
);
192 TEST_F(GalleryWatchManagerTest
, Basic
) {
193 base::ScopedTempDir temp_dir
;
194 ASSERT_TRUE(temp_dir
.CreateUniqueTempDir());
195 MediaGalleryPrefId id
= AddGallery(temp_dir
.path());
198 if (GalleryWatchesSupported()) {
199 manager()->AddWatch(profile(),
202 base::Bind(&ConfirmWatch
, base::Unretained(&loop
)));
208 base::Bind(&ExpectWatchError
,
209 base::Unretained(&loop
),
210 GalleryWatchManager::kCouldNotWatchGalleryError
));
215 TEST_F(GalleryWatchManagerTest
, AddAndRemoveTwoWatches
) {
216 if (!GalleryWatchesSupported())
219 EXPECT_TRUE(manager()->GetWatchSet(profile(), extension()->id()).empty());
221 base::ScopedTempDir temp1
;
222 ASSERT_TRUE(temp1
.CreateUniqueTempDir());
223 MediaGalleryPrefId id1
= AddGallery(temp1
.path());
225 base::ScopedTempDir temp2
;
226 ASSERT_TRUE(temp2
.CreateUniqueTempDir());
227 MediaGalleryPrefId id2
= AddGallery(temp2
.path());
229 // Add first watch and test it was added correctly.
230 AddAndConfirmWatch(id1
);
231 MediaGalleryPrefIdSet set1
=
232 manager()->GetWatchSet(profile(), extension()->id());
233 EXPECT_EQ(1u, set1
.size());
234 EXPECT_TRUE(ContainsKey(set1
, id1
));
236 // Test that the second watch was added correctly too.
237 AddAndConfirmWatch(id2
);
238 MediaGalleryPrefIdSet set2
=
239 manager()->GetWatchSet(profile(), extension()->id());
240 EXPECT_EQ(2u, set2
.size());
241 EXPECT_TRUE(ContainsKey(set2
, id1
));
242 EXPECT_TRUE(ContainsKey(set2
, id2
));
244 // Remove first watch and test that the second is still in there.
245 manager()->RemoveWatch(profile(), extension()->id(), id1
);
246 MediaGalleryPrefIdSet set3
=
247 manager()->GetWatchSet(profile(), extension()->id());
248 EXPECT_EQ(1u, set3
.size());
249 EXPECT_TRUE(ContainsKey(set3
, id2
));
251 // Try removing the first watch again and test that it has no effect.
252 manager()->RemoveWatch(profile(), extension()->id(), id1
);
253 EXPECT_EQ(1u, manager()->GetWatchSet(profile(), extension()->id()).size());
255 // Remove the second watch and test that the new watch set is empty.
256 manager()->RemoveWatch(profile(), extension()->id(), id2
);
257 EXPECT_TRUE(manager()->GetWatchSet(profile(), extension()->id()).empty());
260 TEST_F(GalleryWatchManagerTest
, RemoveAllWatches
) {
261 if (!GalleryWatchesSupported())
264 base::ScopedTempDir temp1
;
265 ASSERT_TRUE(temp1
.CreateUniqueTempDir());
266 MediaGalleryPrefId id1
= AddGallery(temp1
.path());
268 base::ScopedTempDir temp2
;
269 ASSERT_TRUE(temp2
.CreateUniqueTempDir());
270 MediaGalleryPrefId id2
= AddGallery(temp2
.path());
273 AddAndConfirmWatch(id1
);
274 AddAndConfirmWatch(id2
);
276 EXPECT_EQ(2u, manager()->GetWatchSet(profile(), extension()->id()).size());
278 // RemoveAllWatches using a different extension ID and verify watches remain.
279 manager()->RemoveAllWatches(profile(), "OtherExtensionId");
280 EXPECT_EQ(2u, manager()->GetWatchSet(profile(), extension()->id()).size());
282 // RemoveAllWatches using the correct extension ID and verify watches gone.
284 manager()->RemoveAllWatches(profile(), extension()->id());
285 EXPECT_TRUE(manager()->GetWatchSet(profile(), extension()->id()).empty());
288 TEST_F(GalleryWatchManagerTest
, DropWatchOnGalleryRemoved
) {
289 if (!GalleryWatchesSupported())
292 base::ScopedTempDir temp_dir
;
293 ASSERT_TRUE(temp_dir
.CreateUniqueTempDir());
294 MediaGalleryPrefId id
= AddGallery(temp_dir
.path());
295 AddAndConfirmWatch(id
);
297 base::RunLoop success_loop
;
298 ExpectGalleryWatchDropped(&success_loop
);
299 gallery_prefs()->EraseGalleryById(id
);
303 TEST_F(GalleryWatchManagerTest
, DropWatchOnGalleryPermissionRevoked
) {
304 if (!GalleryWatchesSupported())
307 base::ScopedTempDir temp_dir
;
308 ASSERT_TRUE(temp_dir
.CreateUniqueTempDir());
309 MediaGalleryPrefId id
= AddGallery(temp_dir
.path());
310 AddAndConfirmWatch(id
);
312 base::RunLoop success_loop
;
313 ExpectGalleryWatchDropped(&success_loop
);
314 gallery_prefs()->SetGalleryPermissionForExtension(*extension(), id
, false);
318 TEST_F(GalleryWatchManagerTest
, DropWatchOnStorageRemoved
) {
319 if (!GalleryWatchesSupported())
322 // Create a temporary directory and treat is as a removable storage device.
323 base::ScopedTempDir temp_dir
;
324 ASSERT_TRUE(temp_dir
.CreateUniqueTempDir());
325 storage_monitor()->AddRemovablePath(temp_dir
.path());
326 storage_monitor::StorageInfo storage_info
;
328 storage_monitor()->GetStorageInfoForPath(temp_dir
.path(), &storage_info
));
329 storage_monitor()->receiver()->ProcessAttach(storage_info
);
331 MediaGalleryPrefId id
= AddGallery(temp_dir
.path());
332 AddAndConfirmWatch(id
);
334 base::RunLoop success_loop
;
335 ExpectGalleryWatchDropped(&success_loop
);
336 storage_monitor()->receiver()->ProcessDetach(storage_info
.device_id());
340 TEST_F(GalleryWatchManagerTest
, TestWatchOperation
) {
341 if (!GalleryWatchesSupported())
344 base::ScopedTempDir temp_dir
;
345 ASSERT_TRUE(temp_dir
.CreateUniqueTempDir());
346 MediaGalleryPrefId id
= AddGallery(temp_dir
.path());
347 AddAndConfirmWatch(id
);
349 base::RunLoop success_loop
;
350 ExpectGalleryChanged(&success_loop
);
352 4, base::WriteFile(temp_dir
.path().AppendASCII("fake file"), "blah", 4));
356 } // namespace component_updater