| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "extensions/browser/event_router.h" | 5 #include "extensions/browser/event_router.h" |
| 6 | 6 |
| 7 #include <memory> | 7 #include <memory> |
| 8 #include <string> | 8 #include <string> |
| 9 #include <utility> | 9 #include <utility> |
| 10 | 10 |
| (...skipping 19 matching lines...) Expand all Loading... |
| 30 namespace extensions { | 30 namespace extensions { |
| 31 | 31 |
| 32 namespace { | 32 namespace { |
| 33 | 33 |
| 34 // A simple mock to keep track of listener additions and removals. | 34 // A simple mock to keep track of listener additions and removals. |
| 35 class MockEventRouterObserver : public EventRouter::Observer { | 35 class MockEventRouterObserver : public EventRouter::Observer { |
| 36 public: | 36 public: |
| 37 MockEventRouterObserver() | 37 MockEventRouterObserver() |
| 38 : listener_added_count_(0), | 38 : listener_added_count_(0), |
| 39 listener_removed_count_(0) {} | 39 listener_removed_count_(0) {} |
| 40 virtual ~MockEventRouterObserver() {} | 40 ~MockEventRouterObserver() override {} |
| 41 | 41 |
| 42 int listener_added_count() const { return listener_added_count_; } | 42 int listener_added_count() const { return listener_added_count_; } |
| 43 int listener_removed_count() const { return listener_removed_count_; } | 43 int listener_removed_count() const { return listener_removed_count_; } |
| 44 const std::string& last_event_name() const { return last_event_name_; } | 44 const std::string& last_event_name() const { return last_event_name_; } |
| 45 | 45 |
| 46 void Reset() { | 46 void Reset() { |
| 47 listener_added_count_ = 0; | 47 listener_added_count_ = 0; |
| 48 listener_removed_count_ = 0; | 48 listener_removed_count_ = 0; |
| 49 last_event_name_.clear(); | 49 last_event_name_.clear(); |
| 50 } | 50 } |
| (...skipping 10 matching lines...) Expand all Loading... |
| 61 } | 61 } |
| 62 | 62 |
| 63 private: | 63 private: |
| 64 int listener_added_count_; | 64 int listener_added_count_; |
| 65 int listener_removed_count_; | 65 int listener_removed_count_; |
| 66 std::string last_event_name_; | 66 std::string last_event_name_; |
| 67 | 67 |
| 68 DISALLOW_COPY_AND_ASSIGN(MockEventRouterObserver); | 68 DISALLOW_COPY_AND_ASSIGN(MockEventRouterObserver); |
| 69 }; | 69 }; |
| 70 | 70 |
| 71 typedef base::Callback<std::unique_ptr<EventListener>( | 71 using EventListenerConstructor = base::Callback<std::unique_ptr<EventListener>( |
| 72 const std::string&, // event_name | 72 const std::string& /* event_name */, |
| 73 content::RenderProcessHost*, // process | 73 content::RenderProcessHost* /* process */, |
| 74 base::DictionaryValue* // filter (takes ownership) | 74 std::unique_ptr<base::DictionaryValue> /* filter */)>; |
| 75 )> | |
| 76 EventListenerConstructor; | |
| 77 | 75 |
| 78 std::unique_ptr<EventListener> CreateEventListenerForExtension( | 76 std::unique_ptr<EventListener> CreateEventListenerForExtension( |
| 79 const std::string& extension_id, | 77 const std::string& extension_id, |
| 80 const std::string& event_name, | 78 const std::string& event_name, |
| 81 content::RenderProcessHost* process, | 79 content::RenderProcessHost* process, |
| 82 base::DictionaryValue* filter) { | 80 std::unique_ptr<base::DictionaryValue> filter) { |
| 83 return EventListener::ForExtension(event_name, extension_id, process, | 81 return EventListener::ForExtension(event_name, extension_id, process, |
| 84 base::WrapUnique(filter)); | 82 std::move(filter)); |
| 85 } | 83 } |
| 86 | 84 |
| 87 std::unique_ptr<EventListener> CreateEventListenerForURL( | 85 std::unique_ptr<EventListener> CreateEventListenerForURL( |
| 88 const GURL& listener_url, | 86 const GURL& listener_url, |
| 89 const std::string& event_name, | 87 const std::string& event_name, |
| 90 content::RenderProcessHost* process, | 88 content::RenderProcessHost* process, |
| 91 base::DictionaryValue* filter) { | 89 std::unique_ptr<base::DictionaryValue> filter) { |
| 92 return EventListener::ForURL(event_name, listener_url, process, | 90 return EventListener::ForURL(event_name, listener_url, process, |
| 93 base::WrapUnique(filter)); | 91 std::move(filter)); |
| 94 } | 92 } |
| 95 | 93 |
| 96 // Creates an extension. If |component| is true, it is created as a component | 94 // Creates an extension. If |component| is true, it is created as a component |
| 97 // extension. If |persistent| is true, it is created with a persistent | 95 // extension. If |persistent| is true, it is created with a persistent |
| 98 // background page; otherwise it is created with an event page. | 96 // background page; otherwise it is created with an event page. |
| 99 scoped_refptr<Extension> CreateExtension(bool component, bool persistent) { | 97 scoped_refptr<Extension> CreateExtension(bool component, bool persistent) { |
| 100 ExtensionBuilder builder; | 98 ExtensionBuilder builder; |
| 101 std::unique_ptr<base::DictionaryValue> manifest = | 99 std::unique_ptr<base::DictionaryValue> manifest = |
| 102 base::MakeUnique<base::DictionaryValue>(); | 100 base::MakeUnique<base::DictionaryValue>(); |
| 103 manifest->SetString("name", "foo"); | 101 manifest->SetString("name", "foo"); |
| 104 manifest->SetString("version", "1.0.0"); | 102 manifest->SetString("version", "1.0.0"); |
| 105 manifest->SetInteger("manifest_version", 2); | 103 manifest->SetInteger("manifest_version", 2); |
| 106 manifest->SetString("background.page", "background.html"); | 104 manifest->SetString("background.page", "background.html"); |
| 107 manifest->SetBoolean("background.persistent", persistent); | 105 manifest->SetBoolean("background.persistent", persistent); |
| 108 builder.SetManifest(std::move(manifest)); | 106 builder.SetManifest(std::move(manifest)); |
| 109 if (component) | 107 if (component) |
| 110 builder.SetLocation(Manifest::Location::COMPONENT); | 108 builder.SetLocation(Manifest::Location::COMPONENT); |
| 111 | 109 |
| 112 return builder.Build(); | 110 return builder.Build(); |
| 113 } | 111 } |
| 114 | 112 |
| 115 std::unique_ptr<DictionaryValue> CreateHostSuffixFilter( | 113 std::unique_ptr<DictionaryValue> CreateHostSuffixFilter( |
| 116 const std::string& suffix) { | 114 const std::string& suffix) { |
| 117 std::unique_ptr<DictionaryValue> filter(new DictionaryValue()); | 115 auto filter_dict = base::MakeUnique<DictionaryValue>(); |
| 118 std::unique_ptr<ListValue> filter_list(new ListValue()); | 116 filter_dict->Set("hostSuffix", base::MakeUnique<Value>(suffix)); |
| 119 std::unique_ptr<DictionaryValue> filter_dict(new DictionaryValue()); | |
| 120 | 117 |
| 121 filter_dict->Set("hostSuffix", base::MakeUnique<Value>(suffix)); | 118 auto filter_list = base::MakeUnique<ListValue>(); |
| 122 filter_list->Append(std::move(filter_dict)); | 119 filter_list->Append(std::move(filter_dict)); |
| 120 |
| 121 auto filter = base::MakeUnique<DictionaryValue>(); |
| 123 filter->Set("url", std::move(filter_list)); | 122 filter->Set("url", std::move(filter_list)); |
| 124 | |
| 125 return filter; | 123 return filter; |
| 126 } | 124 } |
| 127 | 125 |
| 128 } // namespace | 126 } // namespace |
| 129 | 127 |
| 130 class EventRouterTest : public ExtensionsTest { | 128 class EventRouterTest : public ExtensionsTest { |
| 131 public: | 129 public: |
| 132 EventRouterTest() {} | 130 EventRouterTest() {} |
| 133 | 131 |
| 134 protected: | 132 protected: |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 181 | 179 |
| 182 DISALLOW_COPY_AND_ASSIGN(EventRouterTest); | 180 DISALLOW_COPY_AND_ASSIGN(EventRouterTest); |
| 183 }; | 181 }; |
| 184 | 182 |
| 185 class EventRouterFilterTest : public ExtensionsTest { | 183 class EventRouterFilterTest : public ExtensionsTest { |
| 186 public: | 184 public: |
| 187 EventRouterFilterTest() {} | 185 EventRouterFilterTest() {} |
| 188 | 186 |
| 189 void SetUp() override { | 187 void SetUp() override { |
| 190 ExtensionsTest::SetUp(); | 188 ExtensionsTest::SetUp(); |
| 191 render_process_host_.reset( | 189 render_process_host_ = |
| 192 new content::MockRenderProcessHost(browser_context())); | 190 base::MakeUnique<content::MockRenderProcessHost>(browser_context()); |
| 193 ASSERT_TRUE(EventRouter::Get(browser_context())); // constructs EventRouter | 191 ASSERT_TRUE(event_router()); // constructs EventRouter |
| 194 } | 192 } |
| 195 | 193 |
| 196 void TearDown() override { | 194 void TearDown() override { |
| 197 render_process_host_.reset(); | 195 render_process_host_.reset(); |
| 198 ExtensionsTest::TearDown(); | 196 ExtensionsTest::TearDown(); |
| 199 } | 197 } |
| 200 | 198 |
| 201 content::RenderProcessHost* render_process_host() const { | 199 content::RenderProcessHost* render_process_host() const { |
| 202 return render_process_host_.get(); | 200 return render_process_host_.get(); |
| 203 } | 201 } |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 252 // Normal event names are passed through unchanged. | 250 // Normal event names are passed through unchanged. |
| 253 EXPECT_EQ("foo.onBar", EventRouter::GetBaseEventName("foo.onBar")); | 251 EXPECT_EQ("foo.onBar", EventRouter::GetBaseEventName("foo.onBar")); |
| 254 | 252 |
| 255 // Sub-events are converted to the part before the slash. | 253 // Sub-events are converted to the part before the slash. |
| 256 EXPECT_EQ("foo.onBar", EventRouter::GetBaseEventName("foo.onBar/123")); | 254 EXPECT_EQ("foo.onBar", EventRouter::GetBaseEventName("foo.onBar/123")); |
| 257 } | 255 } |
| 258 | 256 |
| 259 // Tests adding and removing observers from EventRouter. | 257 // Tests adding and removing observers from EventRouter. |
| 260 void EventRouterTest::RunEventRouterObserverTest( | 258 void EventRouterTest::RunEventRouterObserverTest( |
| 261 const EventListenerConstructor& constructor) { | 259 const EventListenerConstructor& constructor) { |
| 262 EventRouter router(NULL, NULL); | 260 EventRouter router(nullptr, nullptr); |
| 263 std::unique_ptr<EventListener> listener = | 261 std::unique_ptr<EventListener> listener = constructor.Run( |
| 264 constructor.Run("event_name", NULL, new base::DictionaryValue()); | 262 "event_name", nullptr, base::MakeUnique<base::DictionaryValue>()); |
| 265 | 263 |
| 266 // Add/remove works without any observers. | 264 // Add/remove works without any observers. |
| 267 router.OnListenerAdded(listener.get()); | 265 router.OnListenerAdded(listener.get()); |
| 268 router.OnListenerRemoved(listener.get()); | 266 router.OnListenerRemoved(listener.get()); |
| 269 | 267 |
| 270 // Register observers that both match and don't match the event above. | 268 // Register observers that both match and don't match the event above. |
| 271 MockEventRouterObserver matching_observer; | 269 MockEventRouterObserver matching_observer; |
| 272 router.RegisterObserver(&matching_observer, "event_name"); | 270 router.RegisterObserver(&matching_observer, "event_name"); |
| 273 MockEventRouterObserver non_matching_observer; | 271 MockEventRouterObserver non_matching_observer; |
| 274 router.RegisterObserver(&non_matching_observer, "other"); | 272 router.RegisterObserver(&non_matching_observer, "other"); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 289 EXPECT_EQ(0, non_matching_observer.listener_added_count()); | 287 EXPECT_EQ(0, non_matching_observer.listener_added_count()); |
| 290 | 288 |
| 291 // Removing the listener again notifies again. | 289 // Removing the listener again notifies again. |
| 292 router.OnListenerRemoved(listener.get()); | 290 router.OnListenerRemoved(listener.get()); |
| 293 EXPECT_EQ(2, matching_observer.listener_removed_count()); | 291 EXPECT_EQ(2, matching_observer.listener_removed_count()); |
| 294 EXPECT_EQ(0, non_matching_observer.listener_removed_count()); | 292 EXPECT_EQ(0, non_matching_observer.listener_removed_count()); |
| 295 | 293 |
| 296 // Adding a listener with a sub-event notifies the main observer with | 294 // Adding a listener with a sub-event notifies the main observer with |
| 297 // proper details. | 295 // proper details. |
| 298 matching_observer.Reset(); | 296 matching_observer.Reset(); |
| 299 std::unique_ptr<EventListener> sub_event_listener = | 297 std::unique_ptr<EventListener> sub_event_listener = constructor.Run( |
| 300 constructor.Run("event_name/1", NULL, new base::DictionaryValue()); | 298 "event_name/1", nullptr, base::MakeUnique<base::DictionaryValue>()); |
| 301 router.OnListenerAdded(sub_event_listener.get()); | 299 router.OnListenerAdded(sub_event_listener.get()); |
| 302 EXPECT_EQ(1, matching_observer.listener_added_count()); | 300 EXPECT_EQ(1, matching_observer.listener_added_count()); |
| 303 EXPECT_EQ(0, matching_observer.listener_removed_count()); | 301 EXPECT_EQ(0, matching_observer.listener_removed_count()); |
| 304 EXPECT_EQ("event_name/1", matching_observer.last_event_name()); | 302 EXPECT_EQ("event_name/1", matching_observer.last_event_name()); |
| 305 | 303 |
| 306 // Ditto for removing the listener. | 304 // Ditto for removing the listener. |
| 307 matching_observer.Reset(); | 305 matching_observer.Reset(); |
| 308 router.OnListenerRemoved(sub_event_listener.get()); | 306 router.OnListenerRemoved(sub_event_listener.get()); |
| 309 EXPECT_EQ(0, matching_observer.listener_added_count()); | 307 EXPECT_EQ(0, matching_observer.listener_added_count()); |
| 310 EXPECT_EQ(1, matching_observer.listener_removed_count()); | 308 EXPECT_EQ(1, matching_observer.listener_removed_count()); |
| 311 EXPECT_EQ("event_name/1", matching_observer.last_event_name()); | 309 EXPECT_EQ("event_name/1", matching_observer.last_event_name()); |
| 312 } | 310 } |
| 313 | 311 |
| 314 TEST_F(EventRouterTest, EventRouterObserverForExtensions) { | 312 TEST_F(EventRouterTest, EventRouterObserverForExtensions) { |
| 315 RunEventRouterObserverTest( | 313 RunEventRouterObserverTest( |
| 316 base::Bind(&CreateEventListenerForExtension, "extension_id")); | 314 base::Bind(&CreateEventListenerForExtension, "extension_id")); |
| 317 } | 315 } |
| 318 | 316 |
| 319 TEST_F(EventRouterTest, EventRouterObserverForURLs) { | 317 TEST_F(EventRouterTest, EventRouterObserverForURLs) { |
| 320 RunEventRouterObserverTest( | 318 RunEventRouterObserverTest( |
| 321 base::Bind(&CreateEventListenerForURL, GURL("http://google.com/path"))); | 319 base::Bind(&CreateEventListenerForURL, GURL("http://google.com/path"))); |
| 322 } | 320 } |
| 323 | 321 |
| 324 TEST_F(EventRouterTest, TestReportEvent) { | 322 TEST_F(EventRouterTest, TestReportEvent) { |
| 325 EventRouter router(browser_context(), NULL); | 323 EventRouter router(browser_context(), nullptr); |
| 326 scoped_refptr<Extension> normal = test_util::CreateEmptyExtension("id1"); | 324 scoped_refptr<Extension> normal = test_util::CreateEmptyExtension("id1"); |
| 327 router.ReportEvent(events::HistogramValue::FOR_TEST, normal.get(), | 325 router.ReportEvent(events::HistogramValue::FOR_TEST, normal.get(), |
| 328 false /** did_enqueue */); | 326 false /** did_enqueue */); |
| 329 ExpectHistogramCounts(1 /** Dispatch */, 0 /** DispatchToComponent */, | 327 ExpectHistogramCounts(1 /** Dispatch */, 0 /** DispatchToComponent */, |
| 330 0 /** DispatchWithPersistentBackgroundPage */, | 328 0 /** DispatchWithPersistentBackgroundPage */, |
| 331 0 /** DispatchWithSuspendedEventPage */, | 329 0 /** DispatchWithSuspendedEventPage */, |
| 332 0 /** DispatchToComponentWithSuspendedEventPage */, | 330 0 /** DispatchToComponentWithSuspendedEventPage */, |
| 333 0 /** DispatchWithRunningEventPage */); | 331 0 /** DispatchWithRunningEventPage */); |
| 334 | 332 |
| 335 scoped_refptr<Extension> component = | 333 scoped_refptr<Extension> component = |
| (...skipping 29 matching lines...) Expand all Loading... |
| 365 // For the purpose of this test, "." is important in |event_name| as it | 363 // For the purpose of this test, "." is important in |event_name| as it |
| 366 // exercises the code path that uses |event_name| as a key in DictionaryValue. | 364 // exercises the code path that uses |event_name| as a key in DictionaryValue. |
| 367 const std::string kEventName = "webNavigation.onBeforeNavigate"; | 365 const std::string kEventName = "webNavigation.onBeforeNavigate"; |
| 368 | 366 |
| 369 const std::string kExtensionId = "mbflcebpggnecokmikipoihdbecnjfoj"; | 367 const std::string kExtensionId = "mbflcebpggnecokmikipoihdbecnjfoj"; |
| 370 const std::string kHostSuffixes[] = {"foo.com", "bar.com", "baz.com"}; | 368 const std::string kHostSuffixes[] = {"foo.com", "bar.com", "baz.com"}; |
| 371 std::vector<std::unique_ptr<DictionaryValue>> filters; | 369 std::vector<std::unique_ptr<DictionaryValue>> filters; |
| 372 for (size_t i = 0; i < arraysize(kHostSuffixes); ++i) { | 370 for (size_t i = 0; i < arraysize(kHostSuffixes); ++i) { |
| 373 std::unique_ptr<base::DictionaryValue> filter = | 371 std::unique_ptr<base::DictionaryValue> filter = |
| 374 CreateHostSuffixFilter(kHostSuffixes[i]); | 372 CreateHostSuffixFilter(kHostSuffixes[i]); |
| 375 EventRouter::Get(browser_context()) | 373 event_router()->AddFilteredEventListener(kEventName, render_process_host(), |
| 376 ->AddFilteredEventListener(kEventName, render_process_host(), | 374 kExtensionId, *filter, true); |
| 377 kExtensionId, *filter, true); | |
| 378 filters.push_back(std::move(filter)); | 375 filters.push_back(std::move(filter)); |
| 379 } | 376 } |
| 380 | 377 |
| 381 const base::DictionaryValue* filtered_events = | 378 const base::DictionaryValue* filtered_events = |
| 382 GetFilteredEvents(kExtensionId); | 379 GetFilteredEvents(kExtensionId); |
| 383 ASSERT_TRUE(filtered_events); | 380 ASSERT_TRUE(filtered_events); |
| 384 ASSERT_EQ(1u, filtered_events->size()); | 381 ASSERT_EQ(1u, filtered_events->size()); |
| 385 | 382 |
| 386 DictionaryValue::Iterator iter(*filtered_events); | 383 DictionaryValue::Iterator iter(*filtered_events); |
| 387 ASSERT_EQ(kEventName, iter.key()); | 384 ASSERT_EQ(kEventName, iter.key()); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 410 | 407 |
| 411 // Remove the third filter. | 408 // Remove the third filter. |
| 412 event_router()->RemoveFilteredEventListener(kEventName, render_process_host(), | 409 event_router()->RemoveFilteredEventListener(kEventName, render_process_host(), |
| 413 kExtensionId, *filters[2], true); | 410 kExtensionId, *filters[2], true); |
| 414 ASSERT_FALSE(ContainsFilter(kExtensionId, kEventName, *filters[0])); | 411 ASSERT_FALSE(ContainsFilter(kExtensionId, kEventName, *filters[0])); |
| 415 ASSERT_FALSE(ContainsFilter(kExtensionId, kEventName, *filters[1])); | 412 ASSERT_FALSE(ContainsFilter(kExtensionId, kEventName, *filters[1])); |
| 416 ASSERT_FALSE(ContainsFilter(kExtensionId, kEventName, *filters[2])); | 413 ASSERT_FALSE(ContainsFilter(kExtensionId, kEventName, *filters[2])); |
| 417 } | 414 } |
| 418 | 415 |
| 419 } // namespace extensions | 416 } // namespace extensions |
| OLD | NEW |