| // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "content/test/test_navigation_observer.h" |
| |
| #include "content/public/browser/notification_service.h" |
| #include "content/public/browser/notification_types.h" |
| #include "content/public/browser/render_view_host_observer.h" |
| #include "content/test/js_injection_ready_observer.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| |
| // This class observes |render_view_host| and calls OnJsInjectionReady() of |
| // |js_injection_ready_observer| when the time is right to inject JavaScript |
| // into the page. |
| class TestNavigationObserver::RVHOSendJS |
| : public content::RenderViewHostObserver { |
| public: |
| RVHOSendJS(RenderViewHost* render_view_host, |
| JsInjectionReadyObserver* js_injection_ready_observer) |
| : content::RenderViewHostObserver(render_view_host), |
| js_injection_ready_observer_(js_injection_ready_observer) { |
| } |
| |
| private: |
| // content::RenderViewHostObserver implementation. |
| virtual void RenderViewHostInitialized() OVERRIDE { |
| if (js_injection_ready_observer_) |
| js_injection_ready_observer_->OnJsInjectionReady(render_view_host()); |
| } |
| |
| JsInjectionReadyObserver* js_injection_ready_observer_; |
| |
| DISALLOW_COPY_AND_ASSIGN(RVHOSendJS); |
| }; |
| |
| TestNavigationObserver::TestNavigationObserver( |
| const content::NotificationSource& source, |
| JsInjectionReadyObserver* js_injection_ready_observer, |
| int number_of_navigations) |
| : navigation_started_(false), |
| navigations_completed_(0), |
| number_of_navigations_(number_of_navigations), |
| js_injection_ready_observer_(js_injection_ready_observer), |
| done_(false), |
| running_(false) { |
| // When javascript injection is requested, register for RenderViewHost |
| // creation. |
| if (js_injection_ready_observer_) { |
| registrar_.Add(this, content::NOTIFICATION_RENDER_VIEW_HOST_CREATED, |
| content::NotificationService::AllSources()); |
| } |
| RegisterAsObserver(source); |
| } |
| |
| TestNavigationObserver::~TestNavigationObserver() { |
| } |
| |
| void TestNavigationObserver::WaitForObservation( |
| const base::Closure& wait_loop_callback, |
| const base::Closure& done_callback) { |
| if (!done_) { |
| EXPECT_FALSE(running_); |
| running_ = true; |
| done_callback_ = done_callback; |
| wait_loop_callback.Run(); |
| } |
| } |
| |
| TestNavigationObserver::TestNavigationObserver( |
| JsInjectionReadyObserver* js_injection_ready_observer, |
| int number_of_navigations) |
| : navigation_started_(false), |
| navigations_completed_(0), |
| number_of_navigations_(number_of_navigations), |
| js_injection_ready_observer_(js_injection_ready_observer), |
| done_(false), |
| running_(false) { |
| // When javascript injection is requested, register for RenderViewHost |
| // creation. |
| if (js_injection_ready_observer_) { |
| registrar_.Add(this, content::NOTIFICATION_RENDER_VIEW_HOST_CREATED, |
| content::NotificationService::AllSources()); |
| } |
| } |
| |
| void TestNavigationObserver::RegisterAsObserver( |
| const content::NotificationSource& source) { |
| // Register for events to know when we've finished loading the page and are |
| // ready to quit the current message loop to return control back to the |
| // waiting test. |
| registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED, source); |
| registrar_.Add(this, content::NOTIFICATION_LOAD_START, source); |
| registrar_.Add(this, content::NOTIFICATION_LOAD_STOP, source); |
| } |
| |
| void TestNavigationObserver::Observe( |
| int type, const content::NotificationSource& source, |
| const content::NotificationDetails& details) { |
| switch (type) { |
| case content::NOTIFICATION_NAV_ENTRY_COMMITTED: |
| case content::NOTIFICATION_LOAD_START: |
| navigation_started_ = true; |
| break; |
| case content::NOTIFICATION_LOAD_STOP: |
| if (navigation_started_ && |
| ++navigations_completed_ == number_of_navigations_) { |
| navigation_started_ = false; |
| done_ = true; |
| if (running_) |
| done_callback_.Run(); |
| } |
| break; |
| case content::NOTIFICATION_RENDER_VIEW_HOST_CREATED: |
| rvho_send_js_.reset(new RVHOSendJS( |
| content::Source<RenderViewHost>(source).ptr(), |
| js_injection_ready_observer_)); |
| break; |
| default: |
| NOTREACHED(); |
| } |
| } |