Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(190)

Side by Side Diff: content/public/test/web_contents_observer_sanity_checker.cc

Issue 869533004: Fix WCO::RenderFrameCreated and WCO::RenderFrameDeleted notifications. Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fixes for RenderFrameHostChanged. Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/public/test/web_contents_observer_sanity_checker.h" 5 #include "content/public/test/web_contents_observer_sanity_checker.h"
6 6
7 #include "base/debug/stack_trace.h"
7 #include "base/strings/stringprintf.h" 8 #include "base/strings/stringprintf.h"
8 #include "content/public/browser/render_frame_host.h" 9 #include "content/public/browser/render_frame_host.h"
9 #include "content/public/browser/render_process_host.h" 10 #include "content/public/browser/render_process_host.h"
10 #include "content/public/browser/site_instance.h" 11 #include "content/public/browser/site_instance.h"
11 #include "content/public/browser/web_contents.h" 12 #include "content/public/browser/web_contents.h"
12 #include "content/public/browser/web_contents_observer.h" 13 #include "content/public/browser/web_contents_observer.h"
13 14
14 namespace content { 15 namespace content {
15 16
16 namespace { 17 namespace {
17 18
18 const char kWebContentsObserverSanityCheckerKey[] = 19 const char kWebContentsObserverSanityCheckerKey[] =
19 "WebContentsObserverSanityChecker"; 20 "WebContentsObserverSanityChecker";
20 21
22 // Set this variable to true to collect stack traces on each RenderFrameCreated
23 // and RenderFrameDeleted call, so duplicate calls can be easily debugged.
24 static bool g_collect_stack_traces = true;
25
21 } // namespace 26 } // namespace
22 27
23 // static 28 // static
24 void WebContentsObserverSanityChecker::Enable(WebContents* web_contents) { 29 void WebContentsObserverSanityChecker::Enable(WebContents* web_contents) {
25 if (web_contents->GetUserData(&kWebContentsObserverSanityCheckerKey)) 30 if (web_contents->GetUserData(&kWebContentsObserverSanityCheckerKey))
26 return; 31 return;
27 web_contents->SetUserData(&kWebContentsObserverSanityCheckerKey, 32 web_contents->SetUserData(&kWebContentsObserverSanityCheckerKey,
28 new WebContentsObserverSanityChecker(web_contents)); 33 new WebContentsObserverSanityChecker(web_contents));
29 } 34 }
30 35
31 void WebContentsObserverSanityChecker::RenderFrameCreated( 36 void WebContentsObserverSanityChecker::RenderFrameCreated(
32 RenderFrameHost* render_frame_host) { 37 RenderFrameHost* render_frame_host) {
38 LOG(ERROR) << "Checker[" << this << "]::RenderFrameCreated: " << Format(render _frame_host);
39
33 CHECK(!web_contents_destroyed_); 40 CHECK(!web_contents_destroyed_);
34 std::pair<int, int> routing_pair = 41 std::pair<int, int> routing_pair =
35 std::make_pair(render_frame_host->GetProcess()->GetID(), 42 std::make_pair(render_frame_host->GetProcess()->GetID(),
36 render_frame_host->GetRoutingID()); 43 render_frame_host->GetRoutingID());
37 bool frame_exists = !live_routes_.insert(routing_pair).second; 44 bool frame_exists = !live_routes_.insert(routing_pair).second;
38 bool dead_already = deleted_routes_.count(routing_pair) != 0; 45 deleted_routes_.erase(routing_pair);
39 46
40 if (frame_exists) { 47 if (frame_exists) {
41 // TODO(nick): Disabled because of http://crbug.com/425397 48 std::string trace;
42 #if 0 49 if (g_collect_stack_traces) {
50 trace = "\nPrevious creation stack trace:\n" +
51 render_frame_created_stacks_[routing_pair];
52 }
43 CHECK(false) << "RenderFrameCreated called more than once for routing pair:" 53 CHECK(false) << "RenderFrameCreated called more than once for routing pair:"
44 << Format(render_frame_host); 54 << Format(render_frame_host) << trace;
45 #endif 55 }
46 } else if (dead_already) { 56
47 CHECK(false) << "RenderFrameCreated called for routing pair that was " 57 if (g_collect_stack_traces) {
48 << "previously deleted: " << Format(render_frame_host); 58 base::debug::StackTrace stack;
59 render_frame_created_stacks_.insert(
60 std::make_pair(routing_pair, stack.ToString()));
61 render_frame_deleted_stacks_.erase(routing_pair);
49 } 62 }
50 } 63 }
51 64
52 void WebContentsObserverSanityChecker::RenderFrameDeleted( 65 void WebContentsObserverSanityChecker::RenderFrameDeleted(
53 RenderFrameHost* render_frame_host) { 66 RenderFrameHost* render_frame_host) {
67 LOG(ERROR) << "Checker[" << this << "]::RenderFrameDeleted: " << Format(render _frame_host);
68
54 CHECK(!web_contents_destroyed_); 69 CHECK(!web_contents_destroyed_);
55 std::pair<int, int> routing_pair = 70 std::pair<int, int> routing_pair =
56 std::make_pair(render_frame_host->GetProcess()->GetID(), 71 std::make_pair(render_frame_host->GetProcess()->GetID(),
57 render_frame_host->GetRoutingID()); 72 render_frame_host->GetRoutingID());
58 bool was_live = !!live_routes_.erase(routing_pair); 73 bool was_live = !!live_routes_.erase(routing_pair);
59 bool was_dead_already = !deleted_routes_.insert(routing_pair).second; 74 bool was_dead_already = !deleted_routes_.insert(routing_pair).second;
60 75
61 if (was_dead_already) { 76 if (was_dead_already) {
77 std::string trace;
78 if (g_collect_stack_traces) {
79 trace = "\nPrevious deletion stack trace:\n" +
80 render_frame_deleted_stacks_[routing_pair];
81 }
62 CHECK(false) << "RenderFrameDeleted called more than once for routing pair " 82 CHECK(false) << "RenderFrameDeleted called more than once for routing pair "
63 << Format(render_frame_host); 83 << Format(render_frame_host) << trace;
64 } else if (!was_live) { 84 } else if (!was_live) {
65 // TODO(nick): Clients can easily ignore an unrecognized object, but it 85 // TODO(nick): Clients can easily ignore an unrecognized object, but it
66 // would be useful from a finding-bugs perspective if we could enable this 86 // would be useful from a finding-bugs perspective if we could enable this
67 // check. 87 // check.
68 #if 0 88 #if 0
69 CHECK(false) << "RenderFrameDeleted called for routing pair " 89 CHECK(false) << "RenderFrameDeleted called for routing pair "
70 << Format(render_frame_host) 90 << Format(render_frame_host)
71 << " for which RenderFrameCreated was never called"; 91 << " for which RenderFrameCreated was never called";
72 #endif 92 #endif
73 } 93 }
94
95 if (g_collect_stack_traces) {
96 base::debug::StackTrace stack;
97 render_frame_deleted_stacks_.insert(
98 std::make_pair(routing_pair, stack.ToString()));
99 render_frame_created_stacks_.erase(routing_pair);
100 }
74 } 101 }
75 102
76 void WebContentsObserverSanityChecker::RenderFrameForInterstitialPageCreated( 103 void WebContentsObserverSanityChecker::RenderFrameForInterstitialPageCreated(
77 RenderFrameHost* render_frame_host) { 104 RenderFrameHost* render_frame_host) {
78 // TODO(nick): Record this. 105 // TODO(nick): Record this.
79 } 106 }
80 107
81 void WebContentsObserverSanityChecker::RenderFrameHostChanged( 108 void WebContentsObserverSanityChecker::RenderFrameHostChanged(
82 RenderFrameHost* old_host, 109 RenderFrameHost* old_host,
83 RenderFrameHost* new_host) { 110 RenderFrameHost* new_host) {
84 CHECK(new_host); 111 CHECK(new_host);
85 if (old_host) 112 CHECK_NE(new_host, old_host);
86 AssertFrameExists(old_host); 113
87 AssertFrameExists(new_host); 114 if (old_host) {
115 LOG(ERROR) << "Checker[" << this << "]::RenderFrameHostChanged: old:" << For mat(old_host);
116
117 AssertRenderFrameHostExists(old_host);
118 std::pair<int, int> routing_pair =
119 std::make_pair(old_host->GetProcess()->GetID(),
120 old_host->GetRoutingID());
121 bool old_did_exist = !!current_hosts_.erase(routing_pair);
122 if (!old_did_exist) {
123 CHECK(false)
124 << "RenderFrameHostChanged called with old host that did not exist:"
125 << Format(old_host);
126 }
127 } else {
128 LOG(ERROR) << "Checker[" << this << "]::RenderFrameHostChanged: old: null";
129 }
130
131 LOG(ERROR) << "Checker[" << this << "]::RenderFrameHostChanged: new:" << Forma t(new_host);
132
133 std::pair<int, int> routing_pair =
134 std::make_pair(new_host->GetProcess()->GetID(),
135 new_host->GetRoutingID());
136 bool host_exists = !current_hosts_.insert(routing_pair).second;
137 if (host_exists) {
138 CHECK(false)
139 << "RenderFrameHostChanged called more than once for routing pair:"
140 << Format(new_host);
141 }
88 } 142 }
89 143
90 void WebContentsObserverSanityChecker::FrameDeleted( 144 void WebContentsObserverSanityChecker::FrameDeleted(
91 RenderFrameHost* render_frame_host) { 145 RenderFrameHost* render_frame_host) {
92 AssertFrameExists(render_frame_host); 146 LOG(ERROR) << "Checker[" << this << "]::FrameDeleted: " << Format(render_frame _host);
147 AssertRenderFrameExists(render_frame_host);
93 } 148 }
94 149
95 void WebContentsObserverSanityChecker::DidStartProvisionalLoadForFrame( 150 void WebContentsObserverSanityChecker::DidStartProvisionalLoadForFrame(
96 RenderFrameHost* render_frame_host, 151 RenderFrameHost* render_frame_host,
97 const GURL& validated_url, 152 const GURL& validated_url,
98 bool is_error_page, 153 bool is_error_page,
99 bool is_iframe_srcdoc) { 154 bool is_iframe_srcdoc) {
100 AssertFrameExists(render_frame_host); 155 AssertRenderFrameExists(render_frame_host);
101 } 156 }
102 157
103 void WebContentsObserverSanityChecker::DidCommitProvisionalLoadForFrame( 158 void WebContentsObserverSanityChecker::DidCommitProvisionalLoadForFrame(
104 RenderFrameHost* render_frame_host, 159 RenderFrameHost* render_frame_host,
105 const GURL& url, 160 const GURL& url,
106 ui::PageTransition transition_type) { 161 ui::PageTransition transition_type) {
107 AssertFrameExists(render_frame_host); 162 AssertRenderFrameExists(render_frame_host);
108 } 163 }
109 164
110 void WebContentsObserverSanityChecker::DidFailProvisionalLoad( 165 void WebContentsObserverSanityChecker::DidFailProvisionalLoad(
111 RenderFrameHost* render_frame_host, 166 RenderFrameHost* render_frame_host,
112 const GURL& validated_url, 167 const GURL& validated_url,
113 int error_code, 168 int error_code,
114 const base::string16& error_description) { 169 const base::string16& error_description) {
115 AssertFrameExists(render_frame_host); 170 AssertRenderFrameExists(render_frame_host);
116 } 171 }
117 172
118 void WebContentsObserverSanityChecker::DidNavigateMainFrame( 173 void WebContentsObserverSanityChecker::DidNavigateMainFrame(
119 const LoadCommittedDetails& details, 174 const LoadCommittedDetails& details,
120 const FrameNavigateParams& params) { 175 const FrameNavigateParams& params) {
121 AssertMainFrameExists(); 176 AssertMainFrameExists();
122 } 177 }
123 178
124 void WebContentsObserverSanityChecker::DidNavigateAnyFrame( 179 void WebContentsObserverSanityChecker::DidNavigateAnyFrame(
125 RenderFrameHost* render_frame_host, 180 RenderFrameHost* render_frame_host,
126 const LoadCommittedDetails& details, 181 const LoadCommittedDetails& details,
127 const FrameNavigateParams& params) { 182 const FrameNavigateParams& params) {
128 AssertFrameExists(render_frame_host); 183 AssertRenderFrameExists(render_frame_host);
129 } 184 }
130 185
131 void WebContentsObserverSanityChecker::DocumentAvailableInMainFrame() { 186 void WebContentsObserverSanityChecker::DocumentAvailableInMainFrame() {
132 AssertMainFrameExists(); 187 AssertMainFrameExists();
133 } 188 }
134 189
135 void WebContentsObserverSanityChecker::DocumentOnLoadCompletedInMainFrame() { 190 void WebContentsObserverSanityChecker::DocumentOnLoadCompletedInMainFrame() {
136 AssertMainFrameExists(); 191 AssertMainFrameExists();
137 } 192 }
138 193
139 void WebContentsObserverSanityChecker::DocumentLoadedInFrame( 194 void WebContentsObserverSanityChecker::DocumentLoadedInFrame(
140 RenderFrameHost* render_frame_host) { 195 RenderFrameHost* render_frame_host) {
141 AssertFrameExists(render_frame_host); 196 AssertRenderFrameExists(render_frame_host);
142 } 197 }
143 198
144 void WebContentsObserverSanityChecker::DidFinishLoad( 199 void WebContentsObserverSanityChecker::DidFinishLoad(
145 RenderFrameHost* render_frame_host, 200 RenderFrameHost* render_frame_host,
146 const GURL& validated_url) { 201 const GURL& validated_url) {
147 AssertFrameExists(render_frame_host); 202 AssertRenderFrameExists(render_frame_host);
148 } 203 }
149 204
150 void WebContentsObserverSanityChecker::DidFailLoad( 205 void WebContentsObserverSanityChecker::DidFailLoad(
151 RenderFrameHost* render_frame_host, 206 RenderFrameHost* render_frame_host,
152 const GURL& validated_url, 207 const GURL& validated_url,
153 int error_code, 208 int error_code,
154 const base::string16& error_description) { 209 const base::string16& error_description) {
155 AssertFrameExists(render_frame_host); 210 AssertRenderFrameExists(render_frame_host);
156 } 211 }
157 212
158 void WebContentsObserverSanityChecker::DidGetRedirectForResourceRequest( 213 void WebContentsObserverSanityChecker::DidGetRedirectForResourceRequest(
159 RenderFrameHost* render_frame_host, 214 RenderFrameHost* render_frame_host,
160 const ResourceRedirectDetails& details) { 215 const ResourceRedirectDetails& details) {
161 AssertFrameExists(render_frame_host); 216 AssertRenderFrameExists(render_frame_host);
162 } 217 }
163 218
164 void WebContentsObserverSanityChecker::DidOpenRequestedURL( 219 void WebContentsObserverSanityChecker::DidOpenRequestedURL(
165 WebContents* new_contents, 220 WebContents* new_contents,
166 RenderFrameHost* source_render_frame_host, 221 RenderFrameHost* source_render_frame_host,
167 const GURL& url, 222 const GURL& url,
168 const Referrer& referrer, 223 const Referrer& referrer,
169 WindowOpenDisposition disposition, 224 WindowOpenDisposition disposition,
170 ui::PageTransition transition) { 225 ui::PageTransition transition) {
171 AssertFrameExists(source_render_frame_host); 226 AssertRenderFrameExists(source_render_frame_host);
172 } 227 }
173 228
174 bool WebContentsObserverSanityChecker::OnMessageReceived( 229 bool WebContentsObserverSanityChecker::OnMessageReceived(
175 const IPC::Message& message, 230 const IPC::Message& message,
176 RenderFrameHost* render_frame_host) { 231 RenderFrameHost* render_frame_host) {
177 #if !defined(OS_MACOSX) 232 #if !defined(OS_MACOSX)
178 // TODO(avi): Disabled because of http://crbug.com/445054 233 // TODO(avi): Disabled because of http://crbug.com/445054
179 AssertFrameExists(render_frame_host); 234 AssertRenderFrameExists(render_frame_host);
180 #endif 235 #endif
181 return false; 236 return false;
182 } 237 }
183 238
184 void WebContentsObserverSanityChecker::WebContentsDestroyed() { 239 void WebContentsObserverSanityChecker::WebContentsDestroyed() {
185 CHECK(!web_contents_destroyed_); 240 CHECK(!web_contents_destroyed_);
186 web_contents_destroyed_ = true; 241 web_contents_destroyed_ = true;
187 } 242 }
188 243
189 WebContentsObserverSanityChecker::WebContentsObserverSanityChecker( 244 WebContentsObserverSanityChecker::WebContentsObserverSanityChecker(
190 WebContents* web_contents) 245 WebContents* web_contents)
191 : WebContentsObserver(web_contents), web_contents_destroyed_(false) { 246 : WebContentsObserver(web_contents), web_contents_destroyed_(false) {
247 LOG(ERROR) << "SanityChecker[" << this << "]::ctor";
248
192 // Prime the pump with the initial objects. 249 // Prime the pump with the initial objects.
193 RenderViewCreated(web_contents->GetRenderViewHost()); 250 RenderViewCreated(web_contents->GetRenderViewHost());
194 RenderFrameCreated(web_contents->GetMainFrame());
195 } 251 }
196 252
197 WebContentsObserverSanityChecker::~WebContentsObserverSanityChecker() { 253 WebContentsObserverSanityChecker::~WebContentsObserverSanityChecker() {
254 LOG(ERROR) << "SanityChecker[" << this << "]::dtor";
198 CHECK(web_contents_destroyed_); 255 CHECK(web_contents_destroyed_);
199 } 256 }
200 257
201 void WebContentsObserverSanityChecker::AssertFrameExists( 258 void WebContentsObserverSanityChecker::AssertRenderFrameHostExists(
202 RenderFrameHost* render_frame_host) { 259 RenderFrameHost* render_frame_host) {
203 CHECK(!web_contents_destroyed_); 260 CHECK(!web_contents_destroyed_);
204 std::pair<int, int> routing_pair = 261 std::pair<int, int> routing_pair =
205 std::make_pair(render_frame_host->GetProcess()->GetID(), 262 std::make_pair(render_frame_host->GetProcess()->GetID(),
206 render_frame_host->GetRoutingID()); 263 render_frame_host->GetRoutingID());
264
265 bool host_changed_happened = current_hosts_.count(routing_pair) != 0;
266 bool host_deleted_happened = deleted_hosts_.count(routing_pair) != 0;
267
268 CHECK(host_changed_happened)
269 << "A RenderFrameHost pointer was passed to a WebContentsObserver "
270 << "method, but WebContentsObserver::RenderFrameHostChanged was never "
271 << "called for that RenderFrameHost: " << Format(render_frame_host);
272 CHECK(!host_deleted_happened)
273 << "A RenderFrameHost pointer was passed to a WebContentsObserver "
274 << "method, but WebContentsObserver::FrameDeleted was never "
275 << "called for that RenderFrameHost: " << Format(render_frame_host);
276 }
277
278 void WebContentsObserverSanityChecker::AssertRenderFrameExists(
279 RenderFrameHost* render_frame_host) {
280 CHECK(!web_contents_destroyed_);
281 std::pair<int, int> routing_pair =
282 std::make_pair(render_frame_host->GetProcess()->GetID(),
283 render_frame_host->GetRoutingID());
284
207 bool render_frame_created_happened = live_routes_.count(routing_pair) != 0; 285 bool render_frame_created_happened = live_routes_.count(routing_pair) != 0;
208 bool render_frame_deleted_happened = deleted_routes_.count(routing_pair) != 0; 286 bool render_frame_deleted_happened = deleted_routes_.count(routing_pair) != 0;
209 287
210 CHECK(render_frame_created_happened) 288 CHECK(render_frame_created_happened)
211 << "A RenderFrameHost pointer was passed to a WebContentsObserver " 289 << "A RenderFrameHost pointer was passed to a WebContentsObserver "
212 << "method, but WebContentsObserver::RenderFrameCreated was never called " 290 << "method, but WebContentsObserver::RenderFrameCreated was never called "
213 << "for that RenderFrameHost: " << Format(render_frame_host); 291 << "for that RenderFrameHost: " << Format(render_frame_host);
214 CHECK(!render_frame_deleted_happened) 292 CHECK(!render_frame_deleted_happened)
215 << "A RenderFrameHost pointer was passed to a WebContentsObserver " 293 << "A RenderFrameHost pointer was passed to a WebContentsObserver "
216 << "method, but WebContentsObserver::RenderFrameDeleted had already been " 294 << "method, but WebContentsObserver::RenderFrameDeleted had already been "
217 << "called on that frame:" << Format(render_frame_host); 295 << "called on that frame:" << Format(render_frame_host);
218 } 296 }
219 297
220 void WebContentsObserverSanityChecker::AssertMainFrameExists() { 298 void WebContentsObserverSanityChecker::AssertMainFrameExists() {
221 AssertFrameExists(web_contents()->GetMainFrame()); 299 AssertRenderFrameExists(web_contents()->GetMainFrame());
222 } 300 }
223 301
224 std::string WebContentsObserverSanityChecker::Format( 302 std::string WebContentsObserverSanityChecker::Format(
225 RenderFrameHost* render_frame_host) { 303 RenderFrameHost* render_frame_host) {
226 return base::StringPrintf( 304 return base::StringPrintf(
227 "(%d, %d -> %s )", render_frame_host->GetProcess()->GetID(), 305 "(%d, %d -> %s)", render_frame_host->GetProcess()->GetID(),
228 render_frame_host->GetRoutingID(), 306 render_frame_host->GetRoutingID(),
229 render_frame_host->GetSiteInstance()->GetSiteURL().spec().c_str()); 307 render_frame_host->GetSiteInstance()->GetSiteURL().spec().c_str());
230 } 308 }
231 309
232 } // namespace content 310 } // namespace content
OLDNEW
« no previous file with comments | « content/public/test/web_contents_observer_sanity_checker.h ('k') | content/renderer/render_thread_impl.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698