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