// 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(source).ptr(), js_injection_ready_observer_)); break; default: NOTREACHED(); } }