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 #include "base/strings/stringprintf.h" 6 #include "base/strings/utf_string_conversions.h" 7 #include "chrome/browser/extensions/api/media_galleries_private/media_galleries_private_api.h" 8 #include "chrome/browser/extensions/extension_apitest.h" 9 #include "chrome/browser/extensions/extension_service.h" 10 #include "chrome/browser/extensions/extension_system.h" 11 #include "chrome/browser/extensions/extension_test_message_listener.h" 12 #include "chrome/browser/storage_monitor/storage_info.h" 13 #include "chrome/browser/storage_monitor/storage_monitor.h" 14 #include "chrome/browser/storage_monitor/test_storage_monitor.h" 15 #include "chrome/browser/ui/browser.h" 16 #include "chrome/common/chrome_switches.h" 17 #include "chrome/test/base/ui_test_utils.h" 18 #include "content/public/browser/render_view_host.h" 19 #include "content/public/browser/web_contents.h" 20 #include "content/public/test/browser_test_utils.h" 21 #include "extensions/common/extension.h" 22 #include "url/gurl.h" 23 24 namespace { 25 26 // Id of test extension from 27 // chrome/test/data/extensions/api_test/|kTestExtensionPath| 28 const char kTestExtensionId[] = "lkegdcleigedmkiikoijjgfchobofdbe"; 29 const char kTestExtensionPath[] = "media_galleries_private/attachdetach"; 30 31 // JS commands. 32 const char kAddAttachListenerCmd[] = "addAttachListener()"; 33 const char kAddDetachListenerCmd[] = "addDetachListener()"; 34 const char kAddDummyDetachListenerCmd[] = "addDummyDetachListener()"; 35 const char kRemoveAttachListenerCmd[] = "removeAttachListener()"; 36 const char kRemoveDummyDetachListenerCmd[] = "removeDummyDetachListener()"; 37 38 // And JS reply messages. 39 const char kAddAttachListenerOk[] = "add_attach_ok"; 40 const char kAddDetachListenerOk[] = "add_detach_ok"; 41 const char kAddDummyDetachListenerOk[] = "add_dummy_detach_ok"; 42 const char kRemoveAttachListenerOk[] = "remove_attach_ok"; 43 const char kRemoveDummyDetachListenerOk[] = "remove_dummy_detach_ok"; 44 45 // Test reply messages. 46 const char kAttachTestOk[] = "attach_test_ok"; 47 const char kDetachTestOk[] = "detach_test_ok"; 48 49 // Dummy device properties. 50 const char kDeviceId[] = "testDeviceId"; 51 const char kDeviceName[] = "foobar"; 52 base::FilePath::CharType kDevicePath[] = FILE_PATH_LITERAL("/qux"); 53 54 } // namespace 55 56 class MediaGalleriesPrivateApiTest : public ExtensionApiTest { 57 public: 58 MediaGalleriesPrivateApiTest() {} 59 virtual ~MediaGalleriesPrivateApiTest() {} 60 61 // ExtensionApiTest overrides. 62 virtual void SetUp() OVERRIDE { 63 device_id_ = StorageInfo::MakeDeviceId( 64 StorageInfo::REMOVABLE_MASS_STORAGE_WITH_DCIM, kDeviceId); 65 ExtensionApiTest::SetUp(); 66 } 67 68 protected: 69 // ExtensionApiTest overrides. 70 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { 71 ExtensionApiTest::SetUpCommandLine(command_line); 72 command_line->AppendSwitchASCII(switches::kWhitelistedExtensionID, 73 kTestExtensionId); 74 } 75 76 void ChangeListener(content::RenderViewHost* host, 77 const std::string& js_command, 78 const std::string& ok_message) { 79 ExtensionTestMessageListener listener(ok_message, false /* no reply */); 80 host->ExecuteJavascriptInWebFrame(base::string16(), 81 ASCIIToUTF16(js_command)); 82 EXPECT_TRUE(listener.WaitUntilSatisfied()); 83 } 84 85 void AttachDetach() { 86 Attach(); 87 Detach(); 88 } 89 90 void Attach() { 91 DCHECK(StorageMonitor::GetInstance()->IsInitialized()); 92 StorageInfo info(device_id_, ASCIIToUTF16(kDeviceName), kDevicePath, 93 base::string16(), base::string16(), base::string16(), 0); 94 StorageMonitor::GetInstance()->receiver()->ProcessAttach(info); 95 content::RunAllPendingInMessageLoop(); 96 } 97 98 void Detach() { 99 DCHECK(StorageMonitor::GetInstance()->IsInitialized()); 100 StorageMonitor::GetInstance()->receiver()->ProcessDetach(device_id_); 101 content::RunAllPendingInMessageLoop(); 102 } 103 104 private: 105 std::string device_id_; 106 107 DISALLOW_COPY_AND_ASSIGN(MediaGalleriesPrivateApiTest); 108 }; 109 110 // Fails on official Linux bot. See http://crbug.com/315276 111 // Flaky on Mac trybots. See http://crbug.com/326324 112 #if (defined(GOOGLE_CHROME_BUILD) && defined(OS_LINUX)) || defined(OS_MACOSX) 113 #define MAYBE_DeviceAttachDetachEvents DISABLED_DeviceAttachDetachEvents 114 #else 115 #define MAYBE_DeviceAttachDetachEvents DeviceAttachDetachEvents 116 #endif 117 IN_PROC_BROWSER_TEST_F(MediaGalleriesPrivateApiTest, 118 MAYBE_DeviceAttachDetachEvents) { 119 // Setup. 120 TestStorageMonitor::SyncInitialize(); 121 const extensions::Extension* extension = 122 LoadExtension(test_data_dir_.AppendASCII(kTestExtensionPath)); 123 ASSERT_TRUE(extension); 124 125 content::RenderViewHost* host = 126 extensions::ExtensionSystem::Get(browser()->profile())-> 127 process_manager()->GetBackgroundHostForExtension(extension->id())-> 128 render_view_host(); 129 ASSERT_TRUE(host); 130 131 // No listeners, attach and detach a couple times. 132 AttachDetach(); 133 AttachDetach(); 134 135 // Add attach listener. 136 ChangeListener(host, kAddAttachListenerCmd, kAddAttachListenerOk); 137 138 // Attach / detach 139 const std::string expect_attach_msg = 140 base::StringPrintf("%s,%s", kAttachTestOk, kDeviceName); 141 ExtensionTestMessageListener attach_finished_listener(expect_attach_msg, 142 false /* no reply */); 143 Attach(); 144 EXPECT_TRUE(attach_finished_listener.WaitUntilSatisfied()); 145 Detach(); 146 147 // Attach / detach 148 Attach(); 149 EXPECT_TRUE(attach_finished_listener.WaitUntilSatisfied()); 150 // Detach 151 Detach(); 152 153 // Remove attach listener. 154 ChangeListener(host, kRemoveAttachListenerCmd, kRemoveAttachListenerOk); 155 156 // No listeners, attach and detach a couple times. 157 AttachDetach(); 158 AttachDetach(); 159 160 // Add detach listener. 161 ChangeListener(host, kAddDummyDetachListenerCmd, kAddDummyDetachListenerOk); 162 163 // Attach / detach 164 Attach(); 165 166 ExtensionTestMessageListener detach_finished_listener(kDetachTestOk, 167 false /* no reply */); 168 Detach(); 169 EXPECT_TRUE(detach_finished_listener.WaitUntilSatisfied()); 170 171 // Attach / detach 172 Attach(); 173 Detach(); 174 EXPECT_TRUE(detach_finished_listener.WaitUntilSatisfied()); 175 176 // Switch ok dummy detach listener for the regular one. 177 ChangeListener(host, kRemoveDummyDetachListenerCmd, 178 kRemoveDummyDetachListenerOk); 179 ChangeListener(host, kAddDetachListenerCmd, kAddDetachListenerOk); 180 181 // Add attach listener. 182 ChangeListener(host, kAddAttachListenerCmd, kAddAttachListenerOk); 183 184 Attach(); 185 EXPECT_TRUE(attach_finished_listener.WaitUntilSatisfied()); 186 Detach(); 187 EXPECT_TRUE(detach_finished_listener.WaitUntilSatisfied()); 188 189 Attach(); 190 EXPECT_TRUE(attach_finished_listener.WaitUntilSatisfied()); 191 Detach(); 192 EXPECT_TRUE(detach_finished_listener.WaitUntilSatisfied()); 193 } 194