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 "chrome/browser/extensions/event_router_forwarder.h" 6 7 #include "base/bind.h" 8 #include "base/message_loop/message_loop.h" 9 #include "base/power_monitor/power_monitor.h" 10 #include "base/power_monitor/power_monitor_device_source.h" 11 #include "base/test/thread_test_helper.h" 12 #include "chrome/browser/profiles/profile_manager.h" 13 #include "chrome/test/base/testing_browser_process.h" 14 #include "chrome/test/base/testing_profile.h" 15 #include "chrome/test/base/testing_profile_manager.h" 16 #include "content/public/test/test_browser_thread.h" 17 #include "testing/gmock/include/gmock/gmock.h" 18 #include "testing/gtest/include/gtest/gtest.h" 19 #include "url/gurl.h" 20 21 using content::BrowserThread; 22 23 namespace extensions { 24 25 namespace { 26 27 const char kEventName[] = "event_name"; 28 const char kExt[] = "extension"; 29 30 class MockEventRouterForwarder : public EventRouterForwarder { 31 public: 32 MOCK_METHOD5(CallEventRouter, 33 void(Profile*, const std::string&, const std::string&, Profile*, 34 const GURL&)); 35 36 virtual void CallEventRouter( 37 Profile* profile, const std::string& extension_id, 38 const std::string& event_name, scoped_ptr<base::ListValue> event_args, 39 Profile* restrict_to_profile, const GURL& event_url) { 40 CallEventRouter(profile, extension_id, event_name, 41 restrict_to_profile, event_url); 42 } 43 44 protected: 45 virtual ~MockEventRouterForwarder() {} 46 }; 47 48 static void BroadcastEventToRenderers(EventRouterForwarder* event_router, 49 const std::string& event_name, 50 const GURL& url) { 51 scoped_ptr<base::ListValue> args(new base::ListValue()); 52 event_router->BroadcastEventToRenderers(event_name, args.Pass(), url); 53 } 54 55 static void DispatchEventToRenderers(EventRouterForwarder* event_router, 56 const std::string& event_name, 57 void* profile, 58 bool use_profile_to_restrict_events, 59 const GURL& url) { 60 scoped_ptr<base::ListValue> args(new base::ListValue()); 61 event_router->DispatchEventToRenderers(event_name, args.Pass(), profile, 62 use_profile_to_restrict_events, url); 63 } 64 65 static void BroadcastEventToExtension(EventRouterForwarder* event_router, 66 const std::string& extension, 67 const std::string& event_name, 68 const GURL& url) { 69 scoped_ptr<base::ListValue> args(new base::ListValue()); 70 event_router->BroadcastEventToExtension(extension, event_name, args.Pass(), 71 url); 72 } 73 74 static void DispatchEventToExtension(EventRouterForwarder* event_router, 75 const std::string& extension, 76 const std::string& event_name, 77 void* profile, 78 bool use_profile_to_restrict_events, 79 const GURL& url) { 80 scoped_ptr<base::ListValue> args(new base::ListValue()); 81 event_router->DispatchEventToExtension( 82 extension, event_name, args.Pass(), profile, 83 use_profile_to_restrict_events, url); 84 } 85 86 } // namespace 87 88 class EventRouterForwarderTest : public testing::Test { 89 protected: 90 EventRouterForwarderTest() 91 : ui_thread_(BrowserThread::UI, &message_loop_), 92 io_thread_(BrowserThread::IO), 93 profile_manager_( 94 TestingBrowserProcess::GetGlobal()) { 95 #if defined(OS_MACOSX) 96 base::PowerMonitorDeviceSource::AllocateSystemIOPorts(); 97 #endif 98 scoped_ptr<base::PowerMonitorSource> power_monitor_source( 99 new base::PowerMonitorDeviceSource()); 100 dummy.reset(new base::PowerMonitor(power_monitor_source.Pass())); 101 } 102 103 virtual void SetUp() { 104 ASSERT_TRUE(profile_manager_.SetUp()); 105 106 // Inject a BrowserProcess with a ProfileManager. 107 ASSERT_TRUE(io_thread_.Start()); 108 109 profile1_ = profile_manager_.CreateTestingProfile("one"); 110 profile2_ = profile_manager_.CreateTestingProfile("two"); 111 } 112 113 base::MessageLoopForUI message_loop_; 114 content::TestBrowserThread ui_thread_; 115 content::TestBrowserThread io_thread_; 116 TestingProfileManager profile_manager_; 117 scoped_ptr<base::PowerMonitor> dummy; 118 // Profiles are weak pointers, owned by ProfileManager in |browser_process_|. 119 TestingProfile* profile1_; 120 TestingProfile* profile2_; 121 }; 122 123 TEST_F(EventRouterForwarderTest, BroadcastRendererUI) { 124 scoped_refptr<MockEventRouterForwarder> event_router( 125 new MockEventRouterForwarder); 126 GURL url; 127 EXPECT_CALL(*event_router.get(), 128 CallEventRouter(profile1_, "", kEventName, profile1_, url)); 129 EXPECT_CALL(*event_router.get(), 130 CallEventRouter(profile2_, "", kEventName, profile2_, url)); 131 BroadcastEventToRenderers(event_router.get(), kEventName, url); 132 } 133 134 TEST_F(EventRouterForwarderTest, BroadcastRendererUIIncognito) { 135 scoped_refptr<MockEventRouterForwarder> event_router( 136 new MockEventRouterForwarder); 137 using ::testing::_; 138 GURL url; 139 Profile* incognito = profile1_->GetOffTheRecordProfile(); 140 EXPECT_CALL(*event_router.get(), 141 CallEventRouter(profile1_, "", kEventName, profile1_, url)); 142 EXPECT_CALL(*event_router.get(), CallEventRouter(incognito, _, _, _, _)) 143 .Times(0); 144 EXPECT_CALL(*event_router.get(), 145 CallEventRouter(profile2_, "", kEventName, profile2_, url)); 146 BroadcastEventToRenderers(event_router.get(), kEventName, url); 147 } 148 149 // This is the canonical test for passing control flow from the IO thread 150 // to the UI thread. Repeating this for all public functions of 151 // EventRouterForwarder would not increase coverage. 152 TEST_F(EventRouterForwarderTest, BroadcastRendererIO) { 153 scoped_refptr<MockEventRouterForwarder> event_router( 154 new MockEventRouterForwarder); 155 GURL url; 156 EXPECT_CALL(*event_router.get(), 157 CallEventRouter(profile1_, "", kEventName, profile1_, url)); 158 EXPECT_CALL(*event_router.get(), 159 CallEventRouter(profile2_, "", kEventName, profile2_, url)); 160 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, 161 base::Bind( 162 &BroadcastEventToRenderers, base::Unretained(event_router.get()), 163 kEventName, url)); 164 165 // Wait for IO thread's message loop to be processed 166 scoped_refptr<base::ThreadTestHelper> helper(new base::ThreadTestHelper( 167 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO).get())); 168 ASSERT_TRUE(helper->Run()); 169 170 base::MessageLoop::current()->RunUntilIdle(); 171 } 172 173 TEST_F(EventRouterForwarderTest, UnicastRendererUIRestricted) { 174 scoped_refptr<MockEventRouterForwarder> event_router( 175 new MockEventRouterForwarder); 176 using ::testing::_; 177 GURL url; 178 EXPECT_CALL(*event_router.get(), 179 CallEventRouter(profile1_, "", kEventName, profile1_, url)); 180 EXPECT_CALL(*event_router.get(), CallEventRouter(profile2_, _, _, _, _)) 181 .Times(0); 182 DispatchEventToRenderers(event_router.get(), kEventName, profile1_, true, 183 url); 184 } 185 186 TEST_F(EventRouterForwarderTest, UnicastRendererUIRestrictedIncognito1) { 187 scoped_refptr<MockEventRouterForwarder> event_router( 188 new MockEventRouterForwarder); 189 Profile* incognito = profile1_->GetOffTheRecordProfile(); 190 using ::testing::_; 191 GURL url; 192 EXPECT_CALL(*event_router.get(), 193 CallEventRouter(profile1_, "", kEventName, profile1_, url)); 194 EXPECT_CALL(*event_router.get(), CallEventRouter(incognito, _, _, _, _)) 195 .Times(0); 196 EXPECT_CALL(*event_router.get(), CallEventRouter(profile2_, _, _, _, _)) 197 .Times(0); 198 DispatchEventToRenderers(event_router.get(), kEventName, profile1_, true, 199 url); 200 } 201 202 TEST_F(EventRouterForwarderTest, UnicastRendererUIRestrictedIncognito2) { 203 scoped_refptr<MockEventRouterForwarder> event_router( 204 new MockEventRouterForwarder); 205 Profile* incognito = profile1_->GetOffTheRecordProfile(); 206 using ::testing::_; 207 GURL url; 208 EXPECT_CALL(*event_router.get(), CallEventRouter(profile1_, _, _, _, _)) 209 .Times(0); 210 EXPECT_CALL(*event_router.get(), 211 CallEventRouter(incognito, "", kEventName, incognito, url)); 212 EXPECT_CALL(*event_router.get(), CallEventRouter(profile2_, _, _, _, _)) 213 .Times(0); 214 DispatchEventToRenderers(event_router.get(), kEventName, incognito, true, 215 url); 216 } 217 218 TEST_F(EventRouterForwarderTest, UnicastRendererUIUnrestricted) { 219 scoped_refptr<MockEventRouterForwarder> event_router( 220 new MockEventRouterForwarder); 221 using ::testing::_; 222 GURL url; 223 EXPECT_CALL(*event_router.get(), 224 CallEventRouter(profile1_, "", kEventName, NULL, url)); 225 EXPECT_CALL(*event_router.get(), CallEventRouter(profile2_, _, _, _, _)) 226 .Times(0); 227 DispatchEventToRenderers(event_router.get(), kEventName, profile1_, false, 228 url); 229 } 230 231 TEST_F(EventRouterForwarderTest, UnicastRendererUIUnrestrictedIncognito) { 232 scoped_refptr<MockEventRouterForwarder> event_router( 233 new MockEventRouterForwarder); 234 Profile* incognito = profile1_->GetOffTheRecordProfile(); 235 using ::testing::_; 236 GURL url; 237 EXPECT_CALL(*event_router.get(), 238 CallEventRouter(profile1_, "", kEventName, NULL, url)); 239 EXPECT_CALL(*event_router.get(), CallEventRouter(incognito, _, _, _, _)) 240 .Times(0); 241 EXPECT_CALL(*event_router.get(), CallEventRouter(profile2_, _, _, _, _)) 242 .Times(0); 243 DispatchEventToRenderers(event_router.get(), kEventName, profile1_, false, 244 url); 245 } 246 247 TEST_F(EventRouterForwarderTest, BroadcastExtensionUI) { 248 scoped_refptr<MockEventRouterForwarder> event_router( 249 new MockEventRouterForwarder); 250 GURL url; 251 EXPECT_CALL(*event_router.get(), 252 CallEventRouter(profile1_, kExt, kEventName, profile1_, url)); 253 EXPECT_CALL(*event_router.get(), 254 CallEventRouter(profile2_, kExt, kEventName, profile2_, url)); 255 BroadcastEventToExtension(event_router.get(), kExt, kEventName, url); 256 } 257 258 TEST_F(EventRouterForwarderTest, UnicastExtensionUIRestricted) { 259 scoped_refptr<MockEventRouterForwarder> event_router( 260 new MockEventRouterForwarder); 261 using ::testing::_; 262 GURL url; 263 EXPECT_CALL(*event_router.get(), 264 CallEventRouter(profile1_, kExt, kEventName, profile1_, url)); 265 EXPECT_CALL(*event_router.get(), CallEventRouter(profile2_, _, _, _, _)) 266 .Times(0); 267 DispatchEventToExtension(event_router.get(), kExt, kEventName, profile1_, 268 true, url); 269 } 270 271 TEST_F(EventRouterForwarderTest, UnicastExtensionUIUnrestricted) { 272 scoped_refptr<MockEventRouterForwarder> event_router( 273 new MockEventRouterForwarder); 274 using ::testing::_; 275 GURL url; 276 EXPECT_CALL(*event_router.get(), 277 CallEventRouter(profile1_, kExt, kEventName, NULL, url)); 278 EXPECT_CALL(*event_router.get(), CallEventRouter(profile2_, _, _, _, _)) 279 .Times(0); 280 DispatchEventToExtension(event_router.get(), kExt, kEventName, profile1_, 281 false, url); 282 } 283 284 } // namespace extensions 285