Expose CefLoadHandler in the render process (issue #1077).

git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@1442 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
This commit is contained in:
Marshall Greenblatt 2013-09-12 23:36:54 +00:00
parent c577293d96
commit 71125f76d8
12 changed files with 527 additions and 78 deletions

View File

@ -47,7 +47,8 @@ extern "C" {
///
// Implement this structure to handle events related to browser load status. The
// functions of this structure will be called on the UI thread.
// functions of this structure will be called on the browser process UI thread
// or render process main thread (TID_RENDERER).
///
typedef struct _cef_load_handler_t {
///

View File

@ -88,6 +88,12 @@ typedef struct _cef_render_process_handler_t {
struct _cef_render_process_handler_t* self,
struct _cef_browser_t* browser);
///
// Return the handler for browser load status events.
///
struct _cef_load_handler_t* (CEF_CALLBACK *get_load_handler)(
struct _cef_render_process_handler_t* self);
///
// Called before browser navigation. Return true (1) to cancel the navigation
// or false (0) to allow the navigation to proceed. The |request| object

View File

@ -44,7 +44,8 @@
///
// Implement this interface to handle events related to browser load status. The
// methods of this class will be called on the UI thread.
// methods of this class will be called on the browser process UI thread or
// render process main thread (TID_RENDERER).
///
/*--cef(source=client)--*/
class CefLoadHandler : public virtual CefBase {

View File

@ -42,6 +42,7 @@
#include "include/cef_browser.h"
#include "include/cef_dom.h"
#include "include/cef_frame.h"
#include "include/cef_load_handler.h"
#include "include/cef_process_message.h"
#include "include/cef_v8.h"
#include "include/cef_values.h"
@ -85,6 +86,14 @@ class CefRenderProcessHandler : public virtual CefBase {
/*--cef()--*/
virtual void OnBrowserDestroyed(CefRefPtr<CefBrowser> browser) {}
///
// Return the handler for browser load status events.
///
/*--cef()--*/
virtual CefRefPtr<CefLoadHandler> GetLoadHandler() {
return NULL;
}
///
// Called before browser navigation. Return true to cancel the navigation or
// false to allow the navigation to proceed. The |request| object cannot be

View File

@ -24,9 +24,11 @@
#include "content/public/renderer/document_state.h"
#include "content/public/renderer/navigation_state.h"
#include "content/public/renderer/render_view.h"
#include "content/renderer/render_view_impl.h"
#include "net/http/http_util.h"
#include "third_party/WebKit/public/platform/WebString.h"
#include "third_party/WebKit/public/platform/WebURL.h"
#include "third_party/WebKit/public/platform/WebURLError.h"
#include "third_party/WebKit/public/platform/WebURLResponse.h"
#include "third_party/WebKit/public/web/WebDataSource.h"
#include "third_party/WebKit/public/web/WebDocument.h"
@ -443,6 +445,12 @@ void CefBrowserImpl::AddFrameObject(int64 frame_id,
manager->Add(tracked_object);
}
bool CefBrowserImpl::is_swapped_out() const {
content::RenderViewImpl* render_view_impl =
static_cast<content::RenderViewImpl*>(render_view());
return (!render_view_impl || render_view_impl->is_swapped_out());
}
// RenderViewObserver methods.
// -----------------------------------------------------------------------------
@ -462,6 +470,21 @@ void CefBrowserImpl::OnDestruct() {
CefContentRendererClient::Get()->OnBrowserDestroyed(this);
}
void CefBrowserImpl::DidStartLoading() {
OnLoadingStateChange(true);
}
void CefBrowserImpl::DidStopLoading() {
OnLoadingStateChange(false);
}
void CefBrowserImpl::DidFailLoad(
WebKit::WebFrame* frame,
const WebKit::WebURLError& error) {
OnLoadError(frame, error);
OnLoadEnd(frame);
}
void CefBrowserImpl::DidFinishLoad(WebKit::WebFrame* frame) {
WebKit::WebDataSource* ds = frame->dataSource();
Send(new CefHostMsg_DidFinishLoad(routing_id(),
@ -469,6 +492,7 @@ void CefBrowserImpl::DidFinishLoad(WebKit::WebFrame* frame) {
ds->request().url(),
!frame->parent(),
ds->response().httpStatusCode()));
OnLoadEnd(frame);
}
void CefBrowserImpl::DidStartProvisionalLoad(WebKit::WebFrame* frame) {
@ -476,6 +500,17 @@ void CefBrowserImpl::DidStartProvisionalLoad(WebKit::WebFrame* frame) {
GetWebFrameImpl(frame);
}
void CefBrowserImpl::DidFailProvisionalLoad(
WebKit::WebFrame* frame,
const WebKit::WebURLError& error) {
OnLoadError(frame, error);
}
void CefBrowserImpl::DidCommitProvisionalLoad(WebKit::WebFrame* frame,
bool is_new_navigation) {
OnLoadStart(frame);
}
void CefBrowserImpl::FrameDetached(WebFrame* frame) {
int64 frame_id = frame->identifier();
@ -713,3 +748,92 @@ void CefBrowserImpl::OnResponse(const Cef_Response_Params& params) {
void CefBrowserImpl::OnResponseAck(int request_id) {
response_manager_->RunAckHandler(request_id);
}
void CefBrowserImpl::OnLoadingStateChange(bool isLoading) {
content::RenderViewImpl* render_view_impl =
static_cast<content::RenderViewImpl*>(render_view());
if (is_swapped_out())
return;
CefRefPtr<CefApp> app = CefContentClient::Get()->application();
if (app.get()) {
CefRefPtr<CefRenderProcessHandler> handler =
app->GetRenderProcessHandler();
if (handler.get()) {
CefRefPtr<CefLoadHandler> load_handler = handler->GetLoadHandler();
if (load_handler.get()) {
WebView* web_view = render_view()->GetWebView();
const bool canGoBack = webkit_glue::CanGoBack(web_view);
const bool canGoForward = webkit_glue::CanGoForward(web_view);
load_handler->OnLoadingStateChange(this, isLoading, canGoBack,
canGoForward);
}
}
}
}
void CefBrowserImpl::OnLoadStart(WebKit::WebFrame* frame) {
content::RenderViewImpl* render_view_impl =
static_cast<content::RenderViewImpl*>(render_view());
if (is_swapped_out())
return;
CefRefPtr<CefApp> app = CefContentClient::Get()->application();
if (app.get()) {
CefRefPtr<CefRenderProcessHandler> handler =
app->GetRenderProcessHandler();
if (handler.get()) {
CefRefPtr<CefLoadHandler> load_handler = handler->GetLoadHandler();
if (load_handler.get()) {
CefRefPtr<CefFrameImpl> cef_frame = GetWebFrameImpl(frame);
load_handler->OnLoadStart(this, cef_frame.get());
}
}
}
}
void CefBrowserImpl::OnLoadEnd(WebKit::WebFrame* frame) {
content::RenderViewImpl* render_view_impl =
static_cast<content::RenderViewImpl*>(render_view());
if (is_swapped_out())
return;
CefRefPtr<CefApp> app = CefContentClient::Get()->application();
if (app.get()) {
CefRefPtr<CefRenderProcessHandler> handler =
app->GetRenderProcessHandler();
if (handler.get()) {
CefRefPtr<CefLoadHandler> load_handler = handler->GetLoadHandler();
if (load_handler.get()) {
CefRefPtr<CefFrameImpl> cef_frame = GetWebFrameImpl(frame);
int httpStatusCode = frame->dataSource()->response().httpStatusCode();
load_handler->OnLoadEnd(this, cef_frame.get(), httpStatusCode);
}
}
}
}
void CefBrowserImpl::OnLoadError(WebKit::WebFrame* frame,
const WebKit::WebURLError& error) {
if (is_swapped_out())
return;
CefRefPtr<CefApp> app = CefContentClient::Get()->application();
if (app.get()) {
CefRefPtr<CefRenderProcessHandler> handler =
app->GetRenderProcessHandler();
if (handler.get()) {
CefRefPtr<CefLoadHandler> load_handler = handler->GetLoadHandler();
if (load_handler.get()) {
CefRefPtr<CefFrameImpl> cef_frame = GetWebFrameImpl(frame);
const cef_errorcode_t errorCode =
static_cast<cef_errorcode_t>(error.reason);
const std::string& errorText = error.localizedDescription.utf8();
const GURL& failedUrl = error.unreachableURL;
load_handler->OnLoadError(this, cef_frame.get(), errorCode, errorText,
failedUrl.spec());
}
}
}
}

View File

@ -103,15 +103,26 @@ class CefBrowserImpl : public CefBrowser,
bool is_window_rendering_disabled() const {
return is_window_rendering_disabled_;
}
content::RenderView* render_view() {
content::RenderView* render_view() const {
return content::RenderViewObserver::render_view();
}
bool is_swapped_out() const;
private:
// RenderViewObserver methods.
virtual void OnDestruct() OVERRIDE;
virtual void DidStartLoading() OVERRIDE;
virtual void DidStopLoading() OVERRIDE;
virtual void DidFailLoad(WebKit::WebFrame* frame,
const WebKit::WebURLError& error) OVERRIDE;
virtual void DidFinishLoad(WebKit::WebFrame* frame) OVERRIDE;
virtual void DidStartProvisionalLoad(WebKit::WebFrame* frame) OVERRIDE;
virtual void DidFailProvisionalLoad(
WebKit::WebFrame* frame,
const WebKit::WebURLError& error) OVERRIDE;
virtual void DidCommitProvisionalLoad(WebKit::WebFrame* frame,
bool is_new_navigation) OVERRIDE;
virtual void FrameDetached(WebKit::WebFrame* frame) OVERRIDE;
virtual void FocusedNodeChanged(const WebKit::WebNode& node) OVERRIDE;
virtual void DidCreateDataSource(WebKit::WebFrame* frame,
@ -123,6 +134,11 @@ class CefBrowserImpl : public CefBrowser,
void OnResponse(const Cef_Response_Params& params);
void OnResponseAck(int request_id);
void OnLoadingStateChange(bool isLoading);
void OnLoadStart(WebKit::WebFrame* frame);
void OnLoadEnd(WebKit::WebFrame* frame);
void OnLoadError(WebKit::WebFrame* frame, const WebKit::WebURLError& error);
// ID of the browser that this RenderView is associated with. During loading
// of cross-origin requests multiple RenderViews may be associated with the
// same browser ID.

View File

@ -10,6 +10,7 @@
// for more information.
//
#include "libcef_dll/cpptoc/load_handler_cpptoc.h"
#include "libcef_dll/cpptoc/render_process_handler_cpptoc.h"
#include "libcef_dll/ctocpp/browser_ctocpp.h"
#include "libcef_dll/ctocpp/domnode_ctocpp.h"
@ -88,6 +89,22 @@ void CEF_CALLBACK render_process_handler_on_browser_destroyed(
CefBrowserCToCpp::Wrap(browser));
}
cef_load_handler_t* CEF_CALLBACK render_process_handler_get_load_handler(
struct _cef_render_process_handler_t* self) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return NULL;
// Execute
CefRefPtr<CefLoadHandler> _retval = CefRenderProcessHandlerCppToC::Get(
self)->GetLoadHandler();
// Return type: refptr_same
return CefLoadHandlerCppToC::Wrap(_retval);
}
int CEF_CALLBACK render_process_handler_on_before_navigation(
struct _cef_render_process_handler_t* self, cef_browser_t* browser,
cef_frame_t* frame, struct _cef_request_t* request,
@ -282,6 +299,7 @@ CefRenderProcessHandlerCppToC::CefRenderProcessHandlerCppToC(
render_process_handler_on_browser_created;
struct_.struct_.on_browser_destroyed =
render_process_handler_on_browser_destroyed;
struct_.struct_.get_load_handler = render_process_handler_get_load_handler;
struct_.struct_.on_before_navigation =
render_process_handler_on_before_navigation;
struct_.struct_.on_context_created =

View File

@ -19,6 +19,7 @@
#include "libcef_dll/cpptoc/v8context_cpptoc.h"
#include "libcef_dll/cpptoc/v8exception_cpptoc.h"
#include "libcef_dll/cpptoc/v8stack_trace_cpptoc.h"
#include "libcef_dll/ctocpp/load_handler_ctocpp.h"
#include "libcef_dll/ctocpp/render_process_handler_ctocpp.h"
@ -85,6 +86,19 @@ void CefRenderProcessHandlerCToCpp::OnBrowserDestroyed(
CefBrowserCppToC::Wrap(browser));
}
CefRefPtr<CefLoadHandler> CefRenderProcessHandlerCToCpp::GetLoadHandler() {
if (CEF_MEMBER_MISSING(struct_, get_load_handler))
return NULL;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Execute
cef_load_handler_t* _retval = struct_->get_load_handler(struct_);
// Return type: refptr_same
return CefLoadHandlerCToCpp::Wrap(_retval);
}
bool CefRenderProcessHandlerCToCpp::OnBeforeNavigation(
CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame,
CefRefPtr<CefRequest> request, NavigationType navigation_type,

View File

@ -39,6 +39,7 @@ class CefRenderProcessHandlerCToCpp
virtual void OnWebKitInitialized() OVERRIDE;
virtual void OnBrowserCreated(CefRefPtr<CefBrowser> browser) OVERRIDE;
virtual void OnBrowserDestroyed(CefRefPtr<CefBrowser> browser) OVERRIDE;
virtual CefRefPtr<CefLoadHandler> GetLoadHandler() OVERRIDE;
virtual bool OnBeforeNavigation(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame, CefRefPtr<CefRequest> request,
NavigationType navigation_type, bool is_redirect) OVERRIDE;

View File

@ -279,6 +279,16 @@ void ClientApp::OnBrowserDestroyed(CefRefPtr<CefBrowser> browser) {
(*it)->OnBrowserDestroyed(this, browser);
}
CefRefPtr<CefLoadHandler> ClientApp::GetLoadHandler() {
CefRefPtr<CefLoadHandler> load_handler;
RenderDelegateSet::iterator it = render_delegates_.begin();
for (; it != render_delegates_.end() && !load_handler.get(); ++it)
load_handler = (*it)->GetLoadHandler(this);
return load_handler;
}
bool ClientApp::OnBeforeNavigation(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefRequest> request,

View File

@ -51,6 +51,10 @@ class ClientApp : public CefApp,
virtual void OnBrowserDestroyed(CefRefPtr<ClientApp> app,
CefRefPtr<CefBrowser> browser) {}
virtual CefRefPtr<CefLoadHandler> GetLoadHandler(CefRefPtr<ClientApp> app) {
return NULL;
}
virtual bool OnBeforeNavigation(CefRefPtr<ClientApp> app,
CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
@ -151,6 +155,7 @@ class ClientApp : public CefApp,
virtual void OnWebKitInitialized() OVERRIDE;
virtual void OnBrowserCreated(CefRefPtr<CefBrowser> browser) OVERRIDE;
virtual void OnBrowserDestroyed(CefRefPtr<CefBrowser> browser) OVERRIDE;
virtual CefRefPtr<CefLoadHandler> GetLoadHandler() OVERRIDE;
virtual bool OnBeforeNavigation(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefRequest> request,

View File

@ -69,7 +69,8 @@ class HistoryNavBrowserTest : public ClientApp::BrowserDelegate {
};
// Renderer side.
class HistoryNavRendererTest : public ClientApp::RenderDelegate {
class HistoryNavRendererTest : public ClientApp::RenderDelegate,
public CefLoadHandler {
public:
HistoryNavRendererTest()
: run_test_(false),
@ -90,6 +91,81 @@ class HistoryNavRendererTest : public ClientApp::RenderDelegate {
run_test_ = true;
}
virtual CefRefPtr<CefLoadHandler> GetLoadHandler(
CefRefPtr<ClientApp> app) OVERRIDE {
if (!run_test_)
return NULL;
return this;
}
virtual void OnLoadingStateChange(CefRefPtr<CefBrowser> browser,
bool isLoading,
bool canGoBack,
bool canGoForward) OVERRIDE {
const NavListItem& item = kHNavList[nav_];
const std::string& url = browser->GetMainFrame()->GetURL();
if (isLoading) {
got_loading_state_start_.yes();
EXPECT_STRNE(item.target, url.c_str());
if (nav_ > 0) {
const NavListItem& last_item = kHNavList[nav_ - 1];
EXPECT_EQ(last_item.can_go_back, browser->CanGoBack());
EXPECT_EQ(last_item.can_go_back, canGoBack);
EXPECT_EQ(last_item.can_go_forward, browser->CanGoForward());
EXPECT_EQ(last_item.can_go_forward, canGoForward);
} else {
EXPECT_FALSE(browser->CanGoBack());
EXPECT_FALSE(canGoBack);
EXPECT_FALSE(browser->CanGoForward());
EXPECT_FALSE(canGoForward);
}
} else {
got_loading_state_end_.yes();
EXPECT_STREQ(item.target, url.c_str());
EXPECT_EQ(item.can_go_back, browser->CanGoBack());
EXPECT_EQ(item.can_go_back, canGoBack);
EXPECT_EQ(item.can_go_forward, browser->CanGoForward());
EXPECT_EQ(item.can_go_forward, canGoForward);
SendTestResultsIfDone(browser);
}
}
virtual void OnLoadStart(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame) OVERRIDE {
const NavListItem& item = kHNavList[nav_];
got_load_start_.yes();
const std::string& url = frame->GetURL();
EXPECT_STREQ(item.target, url.c_str());
EXPECT_EQ(item.can_go_back, browser->CanGoBack());
EXPECT_EQ(item.can_go_forward, browser->CanGoForward());
}
virtual void OnLoadEnd(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
int httpStatusCode) OVERRIDE {
const NavListItem& item = kHNavList[nav_];
got_load_end_.yes();
const std::string& url = frame->GetURL();
EXPECT_STREQ(item.target, url.c_str());
EXPECT_EQ(item.can_go_back, browser->CanGoBack());
EXPECT_EQ(item.can_go_forward, browser->CanGoForward());
SendTestResultsIfDone(browser);
}
virtual bool OnBeforeNavigation(CefRefPtr<ClientApp> app,
CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
@ -121,15 +197,22 @@ class HistoryNavRendererTest : public ClientApp::RenderDelegate {
EXPECT_FALSE(browser->CanGoForward());
}
SendTestResults(browser);
nav_++;
return false;
}
protected:
void SendTestResultsIfDone(CefRefPtr<CefBrowser> browser) {
if (got_load_end_ && got_loading_state_end_)
SendTestResults(browser);
}
// Send the test results.
void SendTestResults(CefRefPtr<CefBrowser> browser) {
EXPECT_TRUE(got_loading_state_start_);
EXPECT_TRUE(got_loading_state_end_);
EXPECT_TRUE(got_load_start_);
EXPECT_TRUE(got_load_end_);
// Check if the test has failed.
bool result = !TestFailed();
@ -141,11 +224,24 @@ class HistoryNavRendererTest : public ClientApp::RenderDelegate {
EXPECT_TRUE(args->SetInt(0, nav_));
EXPECT_TRUE(args->SetBool(1, result));
EXPECT_TRUE(browser->SendProcessMessage(PID_BROWSER, return_msg));
// Reset the test results for the next navigation.
got_loading_state_start_.reset();
got_loading_state_end_.reset();
got_load_start_.reset();
got_load_end_.reset();
nav_++;
}
bool run_test_;
int nav_;
TrackCallback got_loading_state_start_;
TrackCallback got_loading_state_end_;
TrackCallback got_load_start_;
TrackCallback got_load_end_;
IMPLEMENT_REFCOUNTING(HistoryNavRendererTest);
};
@ -859,13 +955,99 @@ class OrderNavBrowserTest : public ClientApp::BrowserDelegate {
IMPLEMENT_REFCOUNTING(OrderNavBrowserTest);
};
class OrderNavLoadState {
public:
OrderNavLoadState(bool is_popup, bool browser_side)
: is_popup_(is_popup),
browser_side_(browser_side) {}
void OnLoadingStateChange(CefRefPtr<CefBrowser> browser,
bool isLoading,
bool canGoBack,
bool canGoForward) {
if (isLoading) {
EXPECT_TRUE(Verify(false, false, false, false));
got_loading_state_start_.yes();
} else {
EXPECT_TRUE(Verify(true, false, true, false));
got_loading_state_end_.yes();
}
}
void OnLoadStart(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame) {
EXPECT_TRUE(Verify(true, false, false, false));
got_load_start_.yes();
}
void OnLoadEnd(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
int httpStatusCode) {
EXPECT_TRUE(Verify(true, true, true, false));
got_load_end_.yes();
}
bool IsStarted() {
return got_loading_state_start_ ||
got_loading_state_end_ ||
got_load_start_ ||
got_load_end_;
}
bool IsDone() {
return got_loading_state_start_ &&
got_loading_state_end_ &&
got_load_start_ &&
got_load_end_;
}
private:
bool Verify(bool got_loading_state_start,
bool got_loading_state_end,
bool got_load_start,
bool got_load_end) {
EXPECT_EQ(got_loading_state_start, got_loading_state_start_)
<< "Popup: " << is_popup_
<< "; Browser Side: " << browser_side_;
EXPECT_EQ(got_loading_state_end, got_loading_state_end_)
<< "Popup: " << is_popup_
<< "; Browser Side: " << browser_side_;
EXPECT_EQ(got_load_start, got_load_start_)
<< "Popup: " << is_popup_
<< "; Browser Side: " << browser_side_;
EXPECT_EQ(got_load_end, got_load_end_)
<< "Popup: " << is_popup_
<< "; Browser Side: " << browser_side_;
return got_loading_state_start == got_loading_state_start_ &&
got_loading_state_end == got_loading_state_end_ &&
got_load_start == got_load_start_ &&
got_load_end == got_load_end_;
}
bool is_popup_;
bool browser_side_;
TrackCallback got_loading_state_start_;
TrackCallback got_loading_state_end_;
TrackCallback got_load_start_;
TrackCallback got_load_end_;
};
// Renderer side.
class OrderNavRendererTest : public ClientApp::RenderDelegate {
class OrderNavRendererTest : public ClientApp::RenderDelegate,
public CefLoadHandler {
public:
OrderNavRendererTest()
: run_test_(false),
browser_id_main_(0),
browser_id_popup_(0) {}
browser_id_popup_(0),
state_main_(false, false),
state_popup_(true, false) {}
virtual void OnRenderThreadCreated(
CefRefPtr<ClientApp> app,
@ -910,16 +1092,16 @@ class OrderNavRendererTest : public ClientApp::RenderDelegate {
if (browser->IsPopup()) {
EXPECT_FALSE(got_browser_created_popup_);
EXPECT_FALSE(got_before_navigation_popup_);
EXPECT_FALSE(got_browser_destroyed_popup_);
EXPECT_FALSE(state_popup_.IsStarted());
got_browser_created_popup_.yes();
browser_id_popup_ = browser->GetIdentifier();
EXPECT_GT(browser->GetIdentifier(), 0);
} else {
EXPECT_FALSE(got_browser_created_main_);
EXPECT_FALSE(got_before_navigation_main_);
EXPECT_FALSE(got_browser_destroyed_main_);
EXPECT_FALSE(state_main_.IsStarted());
got_browser_created_main_.yes();
browser_id_main_ = browser->GetIdentifier();
@ -939,8 +1121,8 @@ class OrderNavRendererTest : public ClientApp::RenderDelegate {
if (browser->IsPopup()) {
EXPECT_TRUE(got_browser_created_popup_);
EXPECT_TRUE(got_before_navigation_popup_);
EXPECT_FALSE(got_browser_destroyed_popup_);
EXPECT_TRUE(state_popup_.IsDone());
got_browser_destroyed_popup_.yes();
EXPECT_EQ(browser_id_popup_, browser->GetIdentifier());
@ -950,8 +1132,8 @@ class OrderNavRendererTest : public ClientApp::RenderDelegate {
SendTestResults(browser_main_, kOrderNavClosedMsg);
} else {
EXPECT_TRUE(got_browser_created_main_);
EXPECT_TRUE(got_before_navigation_main_);
EXPECT_FALSE(got_browser_destroyed_main_);
EXPECT_TRUE(state_main_.IsDone());
got_browser_destroyed_main_.yes();
EXPECT_EQ(browser_id_main_, browser->GetIdentifier());
@ -961,52 +1143,90 @@ class OrderNavRendererTest : public ClientApp::RenderDelegate {
}
}
virtual bool OnBeforeNavigation(CefRefPtr<ClientApp> app,
CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefRequest> request,
cef_navigation_type_t navigation_type,
bool is_redirect) OVERRIDE {
virtual CefRefPtr<CefLoadHandler> GetLoadHandler(
CefRefPtr<ClientApp> app) OVERRIDE {
if (!run_test_)
return false;
return NULL;
return this;
}
virtual void OnLoadingStateChange(CefRefPtr<CefBrowser> browser,
bool isLoading,
bool canGoBack,
bool canGoForward) OVERRIDE {
EXPECT_TRUE(got_render_thread_created_);
EXPECT_TRUE(got_webkit_initialized_);
EXPECT_EQ(RT_SUB_RESOURCE, request->GetResourceType());
EXPECT_EQ(TT_EXPLICIT, request->GetTransitionType());
if (browser->IsPopup()) {
EXPECT_TRUE(got_browser_created_popup_);
EXPECT_FALSE(got_browser_destroyed_popup_);
state_popup_.OnLoadingStateChange(browser, isLoading, canGoBack,
canGoForward);
} else {
EXPECT_TRUE(got_browser_created_main_);
EXPECT_FALSE(got_browser_destroyed_main_);
state_main_.OnLoadingStateChange(browser, isLoading, canGoBack,
canGoForward);
}
if (!isLoading)
SendTestResultsIfDone(browser);
}
virtual void OnLoadStart(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame) OVERRIDE {
EXPECT_TRUE(got_render_thread_created_);
EXPECT_TRUE(got_webkit_initialized_);
if (browser->IsPopup()) {
EXPECT_TRUE(got_browser_created_popup_);
EXPECT_FALSE(got_before_navigation_popup_);
EXPECT_FALSE(got_browser_destroyed_popup_);
got_before_navigation_popup_.yes();
EXPECT_EQ(browser_id_popup_, browser->GetIdentifier());
EXPECT_GT(browser->GetIdentifier(), 0);
state_popup_.OnLoadStart(browser, frame);
} else {
EXPECT_TRUE(got_browser_created_main_);
EXPECT_FALSE(got_before_navigation_main_);
EXPECT_FALSE(got_browser_destroyed_main_);
got_before_navigation_main_.yes();
EXPECT_EQ(browser_id_main_, browser->GetIdentifier());
EXPECT_GT(browser->GetIdentifier(), 0);
state_main_.OnLoadStart(browser, frame);
}
}
virtual void OnLoadEnd(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
int httpStatusCode) OVERRIDE {
EXPECT_TRUE(got_render_thread_created_);
EXPECT_TRUE(got_webkit_initialized_);
if (browser->IsPopup()) {
EXPECT_TRUE(got_browser_created_popup_);
EXPECT_FALSE(got_browser_destroyed_popup_);
state_popup_.OnLoadEnd(browser, frame, httpStatusCode);
} else {
EXPECT_TRUE(got_browser_created_main_);
EXPECT_FALSE(got_browser_destroyed_main_);
state_main_.OnLoadEnd(browser, frame, httpStatusCode);
}
std::string url = request->GetURL();
if (url == KONav1)
EXPECT_FALSE(browser->IsPopup());
else if (url == KONav2)
EXPECT_TRUE(browser->IsPopup());
else
EXPECT_TRUE(false); // not reached
SendTestResults(browser, kOrderNavMsg);
return false;
SendTestResultsIfDone(browser);
}
protected:
void SendTestResultsIfDone(CefRefPtr<CefBrowser> browser) {
bool done = false;
if (browser->IsPopup())
done = state_popup_.IsDone();
else
done = state_main_.IsDone();
if (done)
SendTestResults(browser, kOrderNavMsg);
}
// Send the test results.
void SendTestResults(CefRefPtr<CefBrowser> browser, const char* msg_name) {
// Check if the test has failed.
@ -1034,10 +1254,11 @@ class OrderNavRendererTest : public ClientApp::RenderDelegate {
TrackCallback got_webkit_initialized_;
TrackCallback got_browser_created_main_;
TrackCallback got_browser_destroyed_main_;
TrackCallback got_before_navigation_main_;
TrackCallback got_browser_created_popup_;
TrackCallback got_browser_destroyed_popup_;
TrackCallback got_before_navigation_popup_;
OrderNavLoadState state_main_;
OrderNavLoadState state_popup_;
IMPLEMENT_REFCOUNTING(OrderNavRendererTest);
};
@ -1048,8 +1269,9 @@ class OrderNavTestHandler : public TestHandler {
OrderNavTestHandler()
: browser_id_main_(0),
browser_id_popup_(0),
got_message_(false),
got_load_end_(false) {}
state_main_(false, true),
state_popup_(true, true),
got_message_(false) {}
virtual void RunTest() OVERRIDE {
// Add the resources that we will navigate to/from.
@ -1061,11 +1283,18 @@ class OrderNavTestHandler : public TestHandler {
}
void ContinueIfReady(CefRefPtr<CefBrowser> browser) {
if (!got_message_ || !got_load_end_)
if (!got_message_)
return;
bool done = false;
if (browser->IsPopup())
done = state_popup_.IsDone();
else
done = state_main_.IsDone();
if (!done)
return;
got_message_ = false;
got_load_end_ = false;
if (!browser->IsPopup()) {
// Create the popup window.
@ -1137,14 +1366,28 @@ class OrderNavTestHandler : public TestHandler {
return false;
}
virtual void OnLoadingStateChange(CefRefPtr<CefBrowser> browser,
bool isLoading,
bool canGoBack,
bool canGoForward) OVERRIDE {
if (browser->IsPopup()) {
state_popup_.OnLoadingStateChange(browser, isLoading, canGoBack,
canGoForward);
} else {
state_main_.OnLoadingStateChange(browser, isLoading, canGoBack,
canGoForward);
}
if (!isLoading)
ContinueIfReady(browser);
}
virtual void OnLoadStart(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame) OVERRIDE {
if (browser->IsPopup()) {
EXPECT_GT(browser->GetIdentifier(), 0);
EXPECT_EQ(browser_id_popup_, browser->GetIdentifier());
state_popup_.OnLoadStart(browser, frame);
} else {
EXPECT_GT(browser->GetIdentifier(), 0);
EXPECT_EQ(browser_id_main_, browser->GetIdentifier());
state_main_.OnLoadStart(browser, frame);
}
}
@ -1152,14 +1395,11 @@ class OrderNavTestHandler : public TestHandler {
CefRefPtr<CefFrame> frame,
int httpStatusCode) OVERRIDE {
if (browser->IsPopup()) {
EXPECT_GT(browser->GetIdentifier(), 0);
EXPECT_EQ(browser_id_popup_, browser->GetIdentifier());
state_popup_.OnLoadEnd(browser, frame, httpStatusCode);
} else {
EXPECT_GT(browser->GetIdentifier(), 0);
EXPECT_EQ(browser_id_main_, browser->GetIdentifier());
state_main_.OnLoadEnd(browser, frame, httpStatusCode);
}
got_load_end_ = true;
ContinueIfReady(browser);
}
@ -1221,8 +1461,10 @@ class OrderNavTestHandler : public TestHandler {
TrackCallback got_before_browse_main_;
TrackCallback got_before_browse_popup_;
OrderNavLoadState state_main_;
OrderNavLoadState state_popup_;
bool got_message_;
bool got_load_end_;
};
} // namespace
@ -1265,7 +1507,8 @@ class CrossOriginNavBrowserTest : public ClientApp::BrowserDelegate {
};
// Renderer side.
class CrossOriginNavRendererTest : public ClientApp::RenderDelegate {
class CrossOriginNavRendererTest : public ClientApp::RenderDelegate,
public CefLoadHandler {
public:
CrossOriginNavRendererTest()
: run_test_(false) {}
@ -1326,40 +1569,41 @@ class CrossOriginNavRendererTest : public ClientApp::RenderDelegate {
EXPECT_TRUE(status);
EXPECT_TRUE(status->got_browser_created);
EXPECT_TRUE(status->got_before_navigation);
EXPECT_TRUE(status->got_loading_state_end);
EXPECT_EQ(status->browser_id, browser->GetIdentifier());
EXPECT_TRUE(RemoveStatus(browser));
}
virtual bool OnBeforeNavigation(CefRefPtr<ClientApp> app,
CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefRequest> request,
cef_navigation_type_t navigation_type,
bool is_redirect) OVERRIDE {
virtual CefRefPtr<CefLoadHandler> GetLoadHandler(
CefRefPtr<ClientApp> app) OVERRIDE {
if (!run_test_)
return false;
return NULL;
EXPECT_TRUE(got_render_thread_created_);
EXPECT_TRUE(got_webkit_initialized_);
return this;
}
EXPECT_EQ(RT_SUB_RESOURCE, request->GetResourceType());
EXPECT_EQ(TT_EXPLICIT, request->GetTransitionType());
virtual void OnLoadingStateChange(CefRefPtr<CefBrowser> browser,
bool isLoading,
bool canGoBack,
bool canGoForward) OVERRIDE {
if (!isLoading) {
EXPECT_TRUE(got_render_thread_created_);
EXPECT_TRUE(got_webkit_initialized_);
Status* status = GetStatus(browser);
EXPECT_TRUE(status);
Status* status = GetStatus(browser);
EXPECT_TRUE(status);
EXPECT_TRUE(status->got_browser_created);
EXPECT_FALSE(status->got_before_navigation);
EXPECT_TRUE(status->got_browser_created);
EXPECT_FALSE(status->got_loading_state_end);
status->got_before_navigation.yes();
status->got_loading_state_end.yes();
EXPECT_EQ(status->browser_id, browser->GetIdentifier());
EXPECT_EQ(status->browser_id, browser->GetIdentifier());
SendTestResults(browser);
return false;
SendTestResults(browser);
}
}
protected:
@ -1389,7 +1633,7 @@ class CrossOriginNavRendererTest : public ClientApp::RenderDelegate {
CefRefPtr<CefBrowser> browser;
int browser_id;
TrackCallback got_browser_created;
TrackCallback got_before_navigation;
TrackCallback got_loading_state_end;
};
typedef std::list<Status> StatusList;
StatusList status_list_;