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 21using content::BrowserThread; 22 23namespace extensions { 24 25namespace { 26 27const char kEventName[] = "event_name"; 28const char kExt[] = "extension"; 29 30class 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 48static 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 55static 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 65static 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 74static 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 88class 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 TestingProfile* CreateIncognitoProfile(TestingProfile* base) { 114 TestingProfile::Builder builder; 115 builder.SetIncognito(); 116 scoped_ptr<TestingProfile> incognito = builder.Build(); 117 TestingProfile* incognito_ptr = incognito.get(); 118 // Incognito profile now owned by |base| 119 base->SetOffTheRecordProfile(incognito.PassAs<Profile>()); 120 return incognito_ptr; 121 } 122 123 base::MessageLoopForUI message_loop_; 124 content::TestBrowserThread ui_thread_; 125 content::TestBrowserThread io_thread_; 126 TestingProfileManager profile_manager_; 127 scoped_ptr<base::PowerMonitor> dummy; 128 // Profiles are weak pointers, owned by ProfileManager in |browser_process_|. 129 TestingProfile* profile1_; 130 TestingProfile* profile2_; 131}; 132 133TEST_F(EventRouterForwarderTest, BroadcastRendererUI) { 134 scoped_refptr<MockEventRouterForwarder> event_router( 135 new MockEventRouterForwarder); 136 GURL url; 137 EXPECT_CALL(*event_router.get(), 138 CallEventRouter(profile1_, "", kEventName, profile1_, url)); 139 EXPECT_CALL(*event_router.get(), 140 CallEventRouter(profile2_, "", kEventName, profile2_, url)); 141 BroadcastEventToRenderers(event_router.get(), kEventName, url); 142} 143 144TEST_F(EventRouterForwarderTest, BroadcastRendererUIIncognito) { 145 scoped_refptr<MockEventRouterForwarder> event_router( 146 new MockEventRouterForwarder); 147 using ::testing::_; 148 GURL url; 149 Profile* incognito = CreateIncognitoProfile(profile1_); 150 EXPECT_CALL(*event_router.get(), 151 CallEventRouter(profile1_, "", kEventName, profile1_, url)); 152 EXPECT_CALL(*event_router.get(), CallEventRouter(incognito, _, _, _, _)) 153 .Times(0); 154 EXPECT_CALL(*event_router.get(), 155 CallEventRouter(profile2_, "", kEventName, profile2_, url)); 156 BroadcastEventToRenderers(event_router.get(), kEventName, url); 157} 158 159// This is the canonical test for passing control flow from the IO thread 160// to the UI thread. Repeating this for all public functions of 161// EventRouterForwarder would not increase coverage. 162TEST_F(EventRouterForwarderTest, BroadcastRendererIO) { 163 scoped_refptr<MockEventRouterForwarder> event_router( 164 new MockEventRouterForwarder); 165 GURL url; 166 EXPECT_CALL(*event_router.get(), 167 CallEventRouter(profile1_, "", kEventName, profile1_, url)); 168 EXPECT_CALL(*event_router.get(), 169 CallEventRouter(profile2_, "", kEventName, profile2_, url)); 170 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, 171 base::Bind( 172 &BroadcastEventToRenderers, base::Unretained(event_router.get()), 173 kEventName, url)); 174 175 // Wait for IO thread's message loop to be processed 176 scoped_refptr<base::ThreadTestHelper> helper(new base::ThreadTestHelper( 177 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO).get())); 178 ASSERT_TRUE(helper->Run()); 179 180 base::MessageLoop::current()->RunUntilIdle(); 181} 182 183TEST_F(EventRouterForwarderTest, UnicastRendererUIRestricted) { 184 scoped_refptr<MockEventRouterForwarder> event_router( 185 new MockEventRouterForwarder); 186 using ::testing::_; 187 GURL url; 188 EXPECT_CALL(*event_router.get(), 189 CallEventRouter(profile1_, "", kEventName, profile1_, url)); 190 EXPECT_CALL(*event_router.get(), CallEventRouter(profile2_, _, _, _, _)) 191 .Times(0); 192 DispatchEventToRenderers(event_router.get(), kEventName, profile1_, true, 193 url); 194} 195 196TEST_F(EventRouterForwarderTest, UnicastRendererUIRestrictedIncognito1) { 197 scoped_refptr<MockEventRouterForwarder> event_router( 198 new MockEventRouterForwarder); 199 Profile* incognito = CreateIncognitoProfile(profile1_); 200 using ::testing::_; 201 GURL url; 202 EXPECT_CALL(*event_router.get(), 203 CallEventRouter(profile1_, "", kEventName, profile1_, url)); 204 EXPECT_CALL(*event_router.get(), CallEventRouter(incognito, _, _, _, _)) 205 .Times(0); 206 EXPECT_CALL(*event_router.get(), CallEventRouter(profile2_, _, _, _, _)) 207 .Times(0); 208 DispatchEventToRenderers(event_router.get(), kEventName, profile1_, true, 209 url); 210} 211 212TEST_F(EventRouterForwarderTest, UnicastRendererUIRestrictedIncognito2) { 213 scoped_refptr<MockEventRouterForwarder> event_router( 214 new MockEventRouterForwarder); 215 Profile* incognito = CreateIncognitoProfile(profile1_); 216 using ::testing::_; 217 GURL url; 218 EXPECT_CALL(*event_router.get(), CallEventRouter(profile1_, _, _, _, _)) 219 .Times(0); 220 EXPECT_CALL(*event_router.get(), 221 CallEventRouter(incognito, "", kEventName, incognito, url)); 222 EXPECT_CALL(*event_router.get(), CallEventRouter(profile2_, _, _, _, _)) 223 .Times(0); 224 DispatchEventToRenderers(event_router.get(), kEventName, incognito, true, 225 url); 226} 227 228TEST_F(EventRouterForwarderTest, UnicastRendererUIUnrestricted) { 229 scoped_refptr<MockEventRouterForwarder> event_router( 230 new MockEventRouterForwarder); 231 using ::testing::_; 232 GURL url; 233 EXPECT_CALL(*event_router.get(), 234 CallEventRouter(profile1_, "", kEventName, NULL, url)); 235 EXPECT_CALL(*event_router.get(), CallEventRouter(profile2_, _, _, _, _)) 236 .Times(0); 237 DispatchEventToRenderers(event_router.get(), kEventName, profile1_, false, 238 url); 239} 240 241TEST_F(EventRouterForwarderTest, UnicastRendererUIUnrestrictedIncognito) { 242 scoped_refptr<MockEventRouterForwarder> event_router( 243 new MockEventRouterForwarder); 244 Profile* incognito = CreateIncognitoProfile(profile1_); 245 using ::testing::_; 246 GURL url; 247 EXPECT_CALL(*event_router.get(), 248 CallEventRouter(profile1_, "", kEventName, NULL, url)); 249 EXPECT_CALL(*event_router.get(), CallEventRouter(incognito, _, _, _, _)) 250 .Times(0); 251 EXPECT_CALL(*event_router.get(), CallEventRouter(profile2_, _, _, _, _)) 252 .Times(0); 253 DispatchEventToRenderers(event_router.get(), kEventName, profile1_, false, 254 url); 255} 256 257TEST_F(EventRouterForwarderTest, BroadcastExtensionUI) { 258 scoped_refptr<MockEventRouterForwarder> event_router( 259 new MockEventRouterForwarder); 260 GURL url; 261 EXPECT_CALL(*event_router.get(), 262 CallEventRouter(profile1_, kExt, kEventName, profile1_, url)); 263 EXPECT_CALL(*event_router.get(), 264 CallEventRouter(profile2_, kExt, kEventName, profile2_, url)); 265 BroadcastEventToExtension(event_router.get(), kExt, kEventName, url); 266} 267 268TEST_F(EventRouterForwarderTest, UnicastExtensionUIRestricted) { 269 scoped_refptr<MockEventRouterForwarder> event_router( 270 new MockEventRouterForwarder); 271 using ::testing::_; 272 GURL url; 273 EXPECT_CALL(*event_router.get(), 274 CallEventRouter(profile1_, kExt, kEventName, profile1_, url)); 275 EXPECT_CALL(*event_router.get(), CallEventRouter(profile2_, _, _, _, _)) 276 .Times(0); 277 DispatchEventToExtension(event_router.get(), kExt, kEventName, profile1_, 278 true, url); 279} 280 281TEST_F(EventRouterForwarderTest, UnicastExtensionUIUnrestricted) { 282 scoped_refptr<MockEventRouterForwarder> event_router( 283 new MockEventRouterForwarder); 284 using ::testing::_; 285 GURL url; 286 EXPECT_CALL(*event_router.get(), 287 CallEventRouter(profile1_, kExt, kEventName, NULL, url)); 288 EXPECT_CALL(*event_router.get(), CallEventRouter(profile2_, _, _, _, _)) 289 .Times(0); 290 DispatchEventToExtension(event_router.get(), kExt, kEventName, profile1_, 291 false, url); 292} 293 294} // namespace extensions 295