1116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Copyright 2014 The Chromium Authors. All rights reserved.
2116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Use of this source code is governed by a BSD-style license that can be
3116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// found in the LICENSE file.
4116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
5116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/bind.h"
66e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "base/command_line.h"
7116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "content/browser/loader/cross_site_resource_handler.h"
8116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "content/browser/loader/resource_dispatcher_host_impl.h"
9116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "content/browser/loader/resource_request_info_impl.h"
10116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "content/browser/transition_request_manager.h"
11116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "content/browser/web_contents/web_contents_impl.h"
12116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "content/public/browser/web_contents_observer.h"
136e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "content/public/common/content_switches.h"
145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/public/test/browser_test_utils.h"
15116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "content/public/test/content_browser_test.h"
16116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "content/public/test/content_browser_test_utils.h"
17116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "content/public/test/test_utils.h"
18116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "content/shell/browser/shell.h"
19116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "content/shell/browser/shell_resource_dispatcher_host_delegate.h"
20116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "net/test/embedded_test_server/embedded_test_server.h"
21116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "net/url_request/url_request.h"
22116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
23116680a4aac90f2aa7413d9095a592090648e557Ben Murdochnamespace content {
24116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
25116680a4aac90f2aa7413d9095a592090648e557Ben Murdochclass TransitionBrowserTest : public ContentBrowserTest {
26116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch public:
27116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  TransitionBrowserTest() {}
28116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
296e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
306e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    command_line->AppendSwitch(
316e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        switches::kEnableExperimentalWebPlatformFeatures);
326e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  }
336e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
34116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch private:
35116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DISALLOW_COPY_AND_ASSIGN(TransitionBrowserTest);
36116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch};
37116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
38116680a4aac90f2aa7413d9095a592090648e557Ben Murdochclass TransitionBrowserTestObserver
39116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    : public WebContentsObserver,
40116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      public ShellResourceDispatcherHostDelegate {
41116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch public:
42116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  TransitionBrowserTestObserver(WebContents* web_contents)
43116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      : WebContentsObserver(web_contents),
44116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        request_(NULL),
45116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        did_defer_response_(false),
46116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        is_transition_request_(false) {
47116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
48116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
49116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  virtual void RequestBeginning(
50116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      net::URLRequest* request,
51116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      ResourceContext* resource_context,
52116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      AppCacheService* appcache_service,
535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      ResourceType resource_type,
54116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      ScopedVector<ResourceThrottle>* throttles) OVERRIDE {
55116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
56116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    ShellResourceDispatcherHostDelegate::RequestBeginning(request,
57116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                                          resource_context,
58116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                                          appcache_service,
59116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                                          resource_type,
60116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                                          throttles);
61116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    request_ = request;
62116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
63116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    ResourceRequestInfoImpl* info =
64116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        ResourceRequestInfoImpl::ForRequest(request_);
65116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
666e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    if (is_transition_request_) {
676e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      TransitionRequestManager::GetInstance()->AddPendingTransitionRequestData(
6803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)          info->GetChildID(), info->GetRenderFrameID(), "*", "", "");
696e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    }
70116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
71116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
72116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  virtual void OnResponseStarted(
73116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      net::URLRequest* request,
74116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      ResourceContext* resource_context,
75116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      ResourceResponse* response,
76116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      IPC::Sender* sender) OVERRIDE {
77116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    ResourceRequestInfoImpl* info =
78116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        ResourceRequestInfoImpl::ForRequest(request_);
79116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
80116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    did_defer_response_ = info->cross_site_handler()->did_defer_for_testing();
81116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
82116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
83116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  void set_pending_transition_request(bool is_transition_request) {
84116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    is_transition_request_ = is_transition_request;
85116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
86116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
87116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  bool did_defer_response() const { return did_defer_response_; }
88116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
89116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch private:
90116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  net::URLRequest* request_;
91116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  bool did_defer_response_;
92116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  bool is_transition_request_;
93116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch};
94116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
95116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// This tests that normal navigations don't defer at first response.
96116680a4aac90f2aa7413d9095a592090648e557Ben MurdochIN_PROC_BROWSER_TEST_F(TransitionBrowserTest,
97116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                       NormalNavigationNotDeferred) {
98116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
99116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  scoped_ptr<TransitionBrowserTestObserver> observer(
100116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      new TransitionBrowserTestObserver(shell()->web_contents()));
101116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
102116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ResourceDispatcherHost::Get()->SetDelegate(observer.get());
103116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
104116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  NavigateToURL(shell(), embedded_test_server()->GetURL("/title1.html"));
105116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
1065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_FALSE(observer->did_defer_response());
107116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
108116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
109116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// This tests that when a navigation transition is detected, the response is
110116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// deferred.
111116680a4aac90f2aa7413d9095a592090648e557Ben MurdochIN_PROC_BROWSER_TEST_F(TransitionBrowserTest,
112116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                       TransitionNavigationIsDeferred) {
113116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
114116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  scoped_ptr<TransitionBrowserTestObserver> observer(
115116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      new TransitionBrowserTestObserver(shell()->web_contents()));
116116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
117116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ResourceDispatcherHost::Get()->SetDelegate(observer.get());
118116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  observer->set_pending_transition_request(true);
119116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
120116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  NavigateToURL(shell(), embedded_test_server()->GetURL("/title1.html"));
121116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
1225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_TRUE(observer->did_defer_response());
1235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
1245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// This tests that the renderer is reused between the outgoing and transition.
1265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(TransitionBrowserTest,
1275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                       TransitionNavigationSharesRenderer) {
1285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
1295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  NavigateToURL(shell(), embedded_test_server()->GetURL("/title1.html"));
1315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  int outgoing_process_id =
1335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      shell()->web_contents()->GetRenderProcessHost()->GetID();
1345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  WebContents::CreateParams create_params(
1365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      shell()->web_contents()->GetBrowserContext(),
1375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      shell()->web_contents()->GetSiteInstance());
1385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  scoped_ptr<WebContents> transition_web_contents(
1395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      WebContents::Create(create_params));
1405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  GURL about_blank(url::kAboutBlankURL);
1425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  NavigationController::LoadURLParams params(about_blank);
1435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  transition_web_contents->GetController().LoadURLWithParams(params);
1445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  transition_web_contents->Focus();
1455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  WaitForLoadStop(transition_web_contents.get());
1475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  int transition_process_id =
1495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      transition_web_contents->GetRenderProcessHost()->GetID();
1505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_EQ(outgoing_process_id, transition_process_id);
152116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
153116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
154116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}  // namespace content
155