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. 4 // 5 // MediaGalleriesPrivate gallery watch API browser tests. 6 7 #include "base/files/file_path.h" 8 #include "base/files/file_path_watcher.h" 9 #include "base/files/file_util.h" 10 #include "base/path_service.h" 11 #include "base/run_loop.h" 12 #include "base/strings/utf_string_conversions.h" 13 #include "build/build_config.h" 14 #include "chrome/browser/browser_process.h" 15 #include "chrome/browser/extensions/extension_apitest.h" 16 #include "chrome/browser/extensions/extension_service.h" 17 #include "chrome/browser/media_galleries/media_file_system_registry.h" 18 #include "chrome/browser/media_galleries/media_galleries_preferences.h" 19 #include "chrome/browser/media_galleries/media_galleries_test_util.h" 20 #include "chrome/common/chrome_paths.h" 21 #include "content/public/browser/render_frame_host.h" 22 #include "content/public/browser/render_view_host.h" 23 #include "extensions/browser/extension_system.h" 24 #include "extensions/common/extension.h" 25 #include "extensions/common/switches.h" 26 #include "extensions/test/extension_test_message_listener.h" 27 28 namespace { 29 30 // Id of test extension from 31 // chrome/test/data/extensions/api_test/|kTestExtensionPath| 32 const char kTestExtensionId[] = "gceegfkgibmgpfopknlcgleimclbknie"; 33 const char kTestExtensionPath[] = "media_galleries_private/gallerywatch"; 34 35 // JS commands. 36 const char kGetAllWatchedGalleryIdsCmd[] = "getAllWatchedGalleryIds()"; 37 const char kGetMediaFileSystemsCmd[] = "getMediaFileSystems()"; 38 const char kSetupWatchOnValidGalleriesCmd[] = "setupWatchOnValidGalleries()"; 39 const char kAddGalleryChangedListenerCmd[] = "addGalleryChangedListener()"; 40 const char kRemoveAllGalleryWatchCmd[] = "removeAllGalleryWatch()"; 41 const char kRemoveGalleryChangedListenerCmd[] = 42 "removeGalleryChangedListener()"; 43 const char kRemoveGalleryWatchCmd[] = "removeGalleryWatch()"; 44 const char kSetupWatchOnInvalidGalleryCmd[] = "setupWatchOnInvalidGallery()"; 45 46 // And JS reply messages. 47 const char kAddGalleryWatchOK[] = "add_gallery_watch_ok"; 48 const char kGetAllGalleryWatchOK[] = "get_all_gallery_watch_ok"; 49 const char kGetMediaFileSystemsCallbackOK[] = 50 "get_media_file_systems_callback_ok"; 51 const char kGetMediaFileSystemsOK[] = "get_media_file_systems_ok"; 52 const char kAddGalleryChangedListenerOK[] = "add_gallery_changed_listener_ok"; 53 const char kRemoveAllGalleryWatchOK[] = "remove_all_gallery_watch_ok"; 54 const char kRemoveGalleryChangedListenerOK[] = 55 "remove_gallery_changed_listener_ok"; 56 const char kRemoveGalleryWatchOK[] = "remove_gallery_watch_ok"; 57 58 // Test reply messages. 59 const char kNoGalleryWatchesInstalled[] = "gallery_watchers_does_not_exists"; 60 const char kAddGalleryWatchRequestFailed[] = "add_watch_request_failed"; 61 const char kAddGalleryWatchRequestSucceeded[] = "add_watch_request_succeeded"; 62 const char kGalleryChangedEventReceived[] = "gallery_changed_event_received"; 63 const char kGalleryWatchesCheck[] = "gallery_watcher_checks"; 64 65 } // namespace 66 67 68 /////////////////////////////////////////////////////////////////////////////// 69 // MediaGalleriesPrivateGalleryWatchApiTest // 70 /////////////////////////////////////////////////////////////////////////////// 71 72 class MediaGalleriesPrivateGalleryWatchApiTest : public ExtensionApiTest { 73 public: 74 MediaGalleriesPrivateGalleryWatchApiTest() 75 : extension_(NULL), 76 background_host_(NULL) { 77 } 78 virtual ~MediaGalleriesPrivateGalleryWatchApiTest() {} 79 80 protected: 81 // ExtensionApiTest overrides. 82 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { 83 ExtensionApiTest::SetUpCommandLine(command_line); 84 command_line->AppendSwitchASCII( 85 extensions::switches::kWhitelistedExtensionID, 86 kTestExtensionId); 87 } 88 virtual void SetUpOnMainThread() OVERRIDE { 89 ExtensionApiTest::SetUpOnMainThread(); 90 ensure_media_directories_exists_.reset(new EnsureMediaDirectoriesExists); 91 extension_ = LoadExtension(test_data_dir_.AppendASCII(kTestExtensionPath)); 92 GetBackgroundHostForTestExtension(); 93 CreateTestGallery(); 94 FetchMediaGalleriesList(); 95 } 96 virtual void TearDownOnMainThread() OVERRIDE { 97 extension_ = NULL; 98 background_host_ = NULL; 99 ensure_media_directories_exists_.reset(); 100 ExtensionApiTest::TearDownOnMainThread(); 101 } 102 103 bool GalleryWatchesSupported() { 104 return base::FilePathWatcher::RecursiveWatchAvailable(); 105 } 106 107 void ExecuteCmdAndCheckReply(const std::string& js_command, 108 const std::string& ok_message) { 109 ExtensionTestMessageListener listener(ok_message, false); 110 background_host_->GetMainFrame()->ExecuteJavaScript( 111 base::ASCIIToUTF16(js_command)); 112 EXPECT_TRUE(listener.WaitUntilSatisfied()); 113 } 114 115 bool AddNewFileInTestGallery() { 116 base::FilePath gallery_file = 117 test_gallery_.path().Append(FILE_PATH_LITERAL("test1.txt")); 118 std::string content("new content"); 119 int write_size = base::WriteFile(gallery_file, content.c_str(), 120 content.length()); 121 return (write_size == static_cast<int>(content.length())); 122 } 123 124 void SetupGalleryWatches() { 125 std::string expected_result = GalleryWatchesSupported() ? 126 kAddGalleryWatchRequestSucceeded : kAddGalleryWatchRequestFailed; 127 128 ExtensionTestMessageListener add_gallery_watch_finished( 129 expected_result, false /* no reply */); 130 ExecuteCmdAndCheckReply(kSetupWatchOnValidGalleriesCmd, kAddGalleryWatchOK); 131 EXPECT_TRUE(add_gallery_watch_finished.WaitUntilSatisfied()); 132 } 133 134 private: 135 void GetBackgroundHostForTestExtension() { 136 ASSERT_TRUE(extension_); 137 extensions::ExtensionSystem* extension_system = 138 extensions::ExtensionSystem::Get(browser()->profile()); 139 background_host_ = 140 extension_system->process_manager()->GetBackgroundHostForExtension( 141 extension_->id())->render_view_host(); 142 ASSERT_TRUE(background_host_); 143 } 144 145 void CreateTestGallery() { 146 MediaGalleriesPreferences* preferences = 147 g_browser_process->media_file_system_registry()->GetPreferences( 148 browser()->profile()); 149 base::RunLoop runloop; 150 preferences->EnsureInitialized(runloop.QuitClosure()); 151 runloop.Run(); 152 153 ASSERT_TRUE(test_gallery_.CreateUniqueTempDir()); 154 MediaGalleryPrefInfo gallery_info; 155 ASSERT_FALSE(preferences->LookUpGalleryByPath(test_gallery_.path(), 156 &gallery_info)); 157 MediaGalleryPrefId id = preferences->AddGallery( 158 gallery_info.device_id, 159 gallery_info.path, 160 MediaGalleryPrefInfo::kAutoDetected, 161 gallery_info.volume_label, 162 gallery_info.vendor_name, 163 gallery_info.model_name, 164 gallery_info.total_size_in_bytes, 165 gallery_info.last_attach_time, 166 0, 0, 0); 167 168 preferences->SetGalleryPermissionForExtension(*extension_, id, true); 169 } 170 171 void FetchMediaGalleriesList() { 172 ExtensionTestMessageListener get_media_systems_finished( 173 kGetMediaFileSystemsCallbackOK, false /* no reply */); 174 ExecuteCmdAndCheckReply(kGetMediaFileSystemsCmd, kGetMediaFileSystemsOK); 175 EXPECT_TRUE(get_media_systems_finished.WaitUntilSatisfied()); 176 } 177 178 scoped_ptr<EnsureMediaDirectoriesExists> ensure_media_directories_exists_; 179 180 base::ScopedTempDir test_gallery_; 181 182 const extensions::Extension* extension_; 183 184 content::RenderViewHost* background_host_; 185 186 DISALLOW_COPY_AND_ASSIGN(MediaGalleriesPrivateGalleryWatchApiTest); 187 }; 188 189 // Crashing on OSX. 190 #if defined(OS_MACOSX) 191 #define MAYBE_BasicGalleryWatch DISABLED_BasicGalleryWatch 192 #else 193 #define MAYBE_BasicGalleryWatch BasicGalleryWatch 194 #endif 195 IN_PROC_BROWSER_TEST_F(MediaGalleriesPrivateGalleryWatchApiTest, 196 MAYBE_BasicGalleryWatch) { 197 SetupGalleryWatches(); 198 199 // Add gallery watch listener. 200 ExecuteCmdAndCheckReply(kAddGalleryChangedListenerCmd, 201 kAddGalleryChangedListenerOK); 202 203 // Modify gallery contents. 204 ExtensionTestMessageListener gallery_change_event_received( 205 kGalleryChangedEventReceived, false /* no reply */); 206 ASSERT_TRUE(AddNewFileInTestGallery()); 207 if (GalleryWatchesSupported()) 208 EXPECT_TRUE(gallery_change_event_received.WaitUntilSatisfied()); 209 210 // Remove gallery watch listener. 211 ExecuteCmdAndCheckReply(kRemoveGalleryChangedListenerCmd, 212 kRemoveGalleryChangedListenerOK); 213 214 // Remove gallery watch request. 215 if (GalleryWatchesSupported()) 216 ExecuteCmdAndCheckReply(kRemoveGalleryWatchCmd, kRemoveGalleryWatchOK); 217 } 218 219 // http://crbug.com/390979 220 IN_PROC_BROWSER_TEST_F(MediaGalleriesPrivateGalleryWatchApiTest, 221 DISABLED_RemoveListenerAndModifyGallery) { 222 if (!GalleryWatchesSupported()) 223 return; 224 225 SetupGalleryWatches(); 226 227 // Add a gallery watch listener. 228 ExecuteCmdAndCheckReply(kAddGalleryChangedListenerCmd, 229 kAddGalleryChangedListenerOK); 230 // Modify gallery contents. 231 ExtensionTestMessageListener gallery_change_event_received( 232 kGalleryChangedEventReceived, false /* no reply */); 233 ASSERT_TRUE(AddNewFileInTestGallery()); 234 EXPECT_TRUE(gallery_change_event_received.WaitUntilSatisfied()); 235 236 // Remove gallery watch listener. 237 ExecuteCmdAndCheckReply(kRemoveGalleryChangedListenerCmd, 238 kRemoveGalleryChangedListenerOK); 239 240 // No listener, modify gallery contents. 241 ASSERT_TRUE(AddNewFileInTestGallery()); 242 243 // Remove gallery watch. 244 ExecuteCmdAndCheckReply(kRemoveGalleryWatchCmd, kRemoveGalleryWatchOK); 245 } 246 247 IN_PROC_BROWSER_TEST_F(MediaGalleriesPrivateGalleryWatchApiTest, 248 SetupGalleryWatchWithoutListeners) { 249 if (!GalleryWatchesSupported()) 250 return; 251 252 SetupGalleryWatches(); 253 254 // No listeners, modify gallery contents. 255 ExtensionTestMessageListener gallery_change_event_received( 256 kGalleryChangedEventReceived, false /* no reply */); 257 ASSERT_TRUE(AddNewFileInTestGallery()); 258 259 // Remove gallery watch. 260 ExecuteCmdAndCheckReply(kRemoveGalleryWatchCmd, kRemoveGalleryWatchOK); 261 } 262 263 IN_PROC_BROWSER_TEST_F(MediaGalleriesPrivateGalleryWatchApiTest, 264 SetupGalleryChangedListenerWithoutWatchers) { 265 // Add gallery watch listener. 266 ExecuteCmdAndCheckReply(kAddGalleryChangedListenerCmd, 267 kAddGalleryChangedListenerOK); 268 269 // Modify gallery contents. Listener should not get called because add watch 270 // request was not called. 271 ExtensionTestMessageListener gallery_change_event_received( 272 kGalleryChangedEventReceived, false /* no reply */); 273 ASSERT_TRUE(AddNewFileInTestGallery()); 274 275 // Remove gallery watch listener. 276 ExecuteCmdAndCheckReply(kRemoveGalleryChangedListenerCmd, 277 kRemoveGalleryChangedListenerOK); 278 } 279 280 IN_PROC_BROWSER_TEST_F(MediaGalleriesPrivateGalleryWatchApiTest, 281 SetupWatchOnInvalidGallery) { 282 // Set up a invalid gallery watch. 283 ExtensionTestMessageListener invalid_gallery_watch_request_finished( 284 kAddGalleryWatchRequestFailed, false /* no reply */); 285 ExecuteCmdAndCheckReply(kSetupWatchOnInvalidGalleryCmd, kAddGalleryWatchOK); 286 EXPECT_TRUE(invalid_gallery_watch_request_finished.WaitUntilSatisfied()); 287 } 288 289 IN_PROC_BROWSER_TEST_F(MediaGalleriesPrivateGalleryWatchApiTest, 290 GetAllGalleryWatch) { 291 // Gallery watchers are not yet added. 292 // chrome.mediaGalleriesPrivate.getAllGalleryWatch should return an empty 293 // list. 294 ExtensionTestMessageListener initial_get_all_check_finished( 295 kNoGalleryWatchesInstalled, false /* no reply */); 296 ExecuteCmdAndCheckReply(kGetAllWatchedGalleryIdsCmd, kGetAllGalleryWatchOK); 297 EXPECT_TRUE(initial_get_all_check_finished.WaitUntilSatisfied()); 298 299 if (!GalleryWatchesSupported()) 300 return; 301 302 SetupGalleryWatches(); 303 304 // chrome.mediaGalleriesPrivate.getAllGalleryWatch should return the 305 // gallery identifiers. 306 ExtensionTestMessageListener get_all_watched_galleries_finished( 307 kGalleryWatchesCheck, false /* no reply */); 308 ExecuteCmdAndCheckReply(kGetAllWatchedGalleryIdsCmd, kGetAllGalleryWatchOK); 309 EXPECT_TRUE(get_all_watched_galleries_finished.WaitUntilSatisfied()); 310 311 // Remove gallery watch request. 312 ExecuteCmdAndCheckReply(kRemoveGalleryWatchCmd, kRemoveGalleryWatchOK); 313 314 // Gallery watchers removed. 315 // chrome.mediaGalleriesPrivate.getAllGalleryWatch() should return an empty 316 // list. 317 ExtensionTestMessageListener final_get_all_check_finished( 318 kNoGalleryWatchesInstalled, false /* no reply */); 319 ExecuteCmdAndCheckReply(kGetAllWatchedGalleryIdsCmd, kGetAllGalleryWatchOK); 320 EXPECT_TRUE(final_get_all_check_finished.WaitUntilSatisfied()); 321 } 322 323 IN_PROC_BROWSER_TEST_F(MediaGalleriesPrivateGalleryWatchApiTest, 324 RemoveAllGalleryWatch) { 325 if (!GalleryWatchesSupported()) 326 return; 327 328 SetupGalleryWatches(); 329 330 // chrome.mediaGalleriesPrivate.getAllGalleryWatch should return the watched 331 // gallery identifiers. 332 ExtensionTestMessageListener get_all_watched_galleries_finished( 333 kGalleryWatchesCheck, false /* no reply */); 334 ExecuteCmdAndCheckReply(kGetAllWatchedGalleryIdsCmd, kGetAllGalleryWatchOK); 335 EXPECT_TRUE(get_all_watched_galleries_finished.WaitUntilSatisfied()); 336 337 // Remove all gallery watchers. 338 ExecuteCmdAndCheckReply(kRemoveAllGalleryWatchCmd, kRemoveAllGalleryWatchOK); 339 340 // Gallery watchers removed. chrome.mediaGalleriesPrivate.getAllGalleryWatch 341 // should return an empty list. 342 ExtensionTestMessageListener final_get_all_check_finished( 343 kNoGalleryWatchesInstalled, false /* no reply */); 344 ExecuteCmdAndCheckReply(kGetAllWatchedGalleryIdsCmd, kGetAllGalleryWatchOK); 345 EXPECT_TRUE(final_get_all_check_finished.WaitUntilSatisfied()); 346 } 347