OLD | NEW |
| (Empty) |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "base/bind.h" | |
6 #include "base/command_line.h" | |
7 #include "content/browser/loader/cross_site_resource_handler.h" | |
8 #include "content/browser/loader/resource_dispatcher_host_impl.h" | |
9 #include "content/browser/loader/resource_request_info_impl.h" | |
10 #include "content/browser/transition_request_manager.h" | |
11 #include "content/browser/web_contents/web_contents_impl.h" | |
12 #include "content/public/browser/web_contents_observer.h" | |
13 #include "content/public/common/content_switches.h" | |
14 #include "content/public/test/browser_test_utils.h" | |
15 #include "content/public/test/content_browser_test.h" | |
16 #include "content/public/test/content_browser_test_utils.h" | |
17 #include "content/public/test/test_utils.h" | |
18 #include "content/shell/browser/shell.h" | |
19 #include "content/shell/browser/shell_resource_dispatcher_host_delegate.h" | |
20 #include "net/test/embedded_test_server/embedded_test_server.h" | |
21 #include "net/url_request/url_request.h" | |
22 | |
23 namespace content { | |
24 | |
25 class TransitionBrowserTest : public ContentBrowserTest { | |
26 public: | |
27 TransitionBrowserTest() {} | |
28 | |
29 void SetUpCommandLine(base::CommandLine* command_line) override { | |
30 command_line->AppendSwitch( | |
31 switches::kEnableExperimentalWebPlatformFeatures); | |
32 } | |
33 | |
34 private: | |
35 DISALLOW_COPY_AND_ASSIGN(TransitionBrowserTest); | |
36 }; | |
37 | |
38 class TransitionBrowserTestObserver | |
39 : public WebContentsObserver, | |
40 public ShellResourceDispatcherHostDelegate { | |
41 public: | |
42 TransitionBrowserTestObserver(WebContents* web_contents) | |
43 : WebContentsObserver(web_contents), | |
44 request_(NULL), | |
45 did_defer_response_(false), | |
46 is_transition_request_(false), | |
47 did_clear_data_(false) { | |
48 } | |
49 | |
50 void RequestBeginning(net::URLRequest* request, | |
51 ResourceContext* resource_context, | |
52 AppCacheService* appcache_service, | |
53 ResourceType resource_type, | |
54 ScopedVector<ResourceThrottle>* throttles) override { | |
55 CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
56 ShellResourceDispatcherHostDelegate::RequestBeginning(request, | |
57 resource_context, | |
58 appcache_service, | |
59 resource_type, | |
60 throttles); | |
61 request_ = request; | |
62 | |
63 ResourceRequestInfoImpl* info = | |
64 ResourceRequestInfoImpl::ForRequest(request_); | |
65 | |
66 if (is_transition_request_) { | |
67 TransitionRequestManager::GetInstance( | |
68 )->AddPendingTransitionRequestDataForTesting( | |
69 info->GetChildID(), info->GetRenderFrameID()); | |
70 } | |
71 } | |
72 | |
73 void OnResponseStarted(net::URLRequest* request, | |
74 ResourceContext* resource_context, | |
75 ResourceResponse* response, | |
76 IPC::Sender* sender) override { | |
77 ResourceRequestInfoImpl* info = | |
78 ResourceRequestInfoImpl::ForRequest(request_); | |
79 | |
80 did_defer_response_ = info->cross_site_handler()->did_defer_for_testing(); | |
81 } | |
82 | |
83 void RequestComplete(net::URLRequest* url_request) override { | |
84 if (is_transition_request_) { | |
85 ResourceRequestInfoImpl* info = | |
86 ResourceRequestInfoImpl::ForRequest(request_); | |
87 TransitionLayerData transition_data; | |
88 did_clear_data_ = !TransitionRequestManager::GetInstance( | |
89 )->GetPendingTransitionRequest(info->GetChildID(), | |
90 info->GetRenderFrameID(), | |
91 request_->url(), | |
92 &transition_data); | |
93 } | |
94 } | |
95 | |
96 void set_pending_transition_request(bool is_transition_request) { | |
97 is_transition_request_ = is_transition_request; | |
98 } | |
99 | |
100 bool did_defer_response() const { return did_defer_response_; } | |
101 bool did_clear_data() const { return did_clear_data_; } | |
102 | |
103 private: | |
104 net::URLRequest* request_; | |
105 bool did_defer_response_; | |
106 bool is_transition_request_; | |
107 bool did_clear_data_; | |
108 }; | |
109 | |
110 // This tests that normal navigations don't defer at first response. | |
111 IN_PROC_BROWSER_TEST_F(TransitionBrowserTest, | |
112 NormalNavigationNotDeferred) { | |
113 // This test shouldn't run in --site-per-process mode, where normal | |
114 // navigations are also deferred. | |
115 if (base::CommandLine::ForCurrentProcess()->HasSwitch( | |
116 switches::kSitePerProcess)) | |
117 return; | |
118 | |
119 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); | |
120 scoped_ptr<TransitionBrowserTestObserver> observer( | |
121 new TransitionBrowserTestObserver(shell()->web_contents())); | |
122 | |
123 ResourceDispatcherHost::Get()->SetDelegate(observer.get()); | |
124 | |
125 NavigateToURL(shell(), embedded_test_server()->GetURL("/title1.html")); | |
126 | |
127 EXPECT_FALSE(observer->did_defer_response()); | |
128 } | |
129 | |
130 // This tests that when a navigation transition is detected, the response is | |
131 // deferred. | |
132 IN_PROC_BROWSER_TEST_F(TransitionBrowserTest, | |
133 TransitionNavigationIsDeferred) { | |
134 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); | |
135 scoped_ptr<TransitionBrowserTestObserver> observer( | |
136 new TransitionBrowserTestObserver(shell()->web_contents())); | |
137 | |
138 ResourceDispatcherHost::Get()->SetDelegate(observer.get()); | |
139 observer->set_pending_transition_request(true); | |
140 | |
141 NavigateToURL(shell(), embedded_test_server()->GetURL("/title1.html")); | |
142 | |
143 EXPECT_TRUE(observer->did_defer_response()); | |
144 } | |
145 | |
146 // This tests that the renderer is reused between the outgoing and transition. | |
147 IN_PROC_BROWSER_TEST_F(TransitionBrowserTest, | |
148 TransitionNavigationSharesRenderer) { | |
149 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); | |
150 | |
151 NavigateToURL(shell(), embedded_test_server()->GetURL("/title1.html")); | |
152 | |
153 int outgoing_process_id = | |
154 shell()->web_contents()->GetRenderProcessHost()->GetID(); | |
155 | |
156 WebContents::CreateParams create_params( | |
157 shell()->web_contents()->GetBrowserContext(), | |
158 shell()->web_contents()->GetSiteInstance()); | |
159 scoped_ptr<WebContents> transition_web_contents( | |
160 WebContents::Create(create_params)); | |
161 | |
162 GURL about_blank(url::kAboutBlankURL); | |
163 NavigationController::LoadURLParams params(about_blank); | |
164 transition_web_contents->GetController().LoadURLWithParams(params); | |
165 transition_web_contents->Focus(); | |
166 | |
167 WaitForLoadStop(transition_web_contents.get()); | |
168 | |
169 int transition_process_id = | |
170 transition_web_contents->GetRenderProcessHost()->GetID(); | |
171 | |
172 EXPECT_EQ(outgoing_process_id, transition_process_id); | |
173 } | |
174 | |
175 // This tests that the transition data is cleared after the transition. | |
176 IN_PROC_BROWSER_TEST_F(TransitionBrowserTest, | |
177 TransitionNavigationDataIsCleared) { | |
178 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); | |
179 scoped_ptr<TransitionBrowserTestObserver> observer( | |
180 new TransitionBrowserTestObserver(shell()->web_contents())); | |
181 | |
182 ResourceDispatcherHost::Get()->SetDelegate(observer.get()); | |
183 observer->set_pending_transition_request(true); | |
184 | |
185 NavigateToURL(shell(), embedded_test_server()->GetURL("/title1.html")); | |
186 WaitForLoadStop(shell()->web_contents()); | |
187 | |
188 EXPECT_TRUE(observer->did_clear_data()); | |
189 } | |
190 | |
191 } // namespace content | |
OLD | NEW |