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

Side by Side Diff: extensions/browser/extension_api_frame_id_map.cc

Issue 2002763003: webRequest: reliably determine tabId (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@webRequest-testing-unload
Patch Set: Last nits Created 4 years, 7 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
« no previous file with comments | « extensions/browser/extension_api_frame_id_map.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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 "extensions/browser/extension_api_frame_id_map.h" 5 #include "extensions/browser/extension_api_frame_id_map.h"
6 6
7 #include <tuple> 7 #include <tuple>
8 8
9 #include "base/metrics/histogram_macros.h" 9 #include "base/metrics/histogram_macros.h"
10 #include "content/public/browser/browser_thread.h" 10 #include "content/public/browser/browser_thread.h"
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
103 return kInvalidFrameId; 103 return kInvalidFrameId;
104 if (rfh->GetParent()) 104 if (rfh->GetParent())
105 return rfh->GetFrameTreeNodeId(); 105 return rfh->GetFrameTreeNodeId();
106 return kTopFrameId; 106 return kTopFrameId;
107 } 107 }
108 108
109 // static 109 // static
110 int ExtensionApiFrameIdMap::GetFrameId( 110 int ExtensionApiFrameIdMap::GetFrameId(
111 content::NavigationHandle* navigation_handle) { 111 content::NavigationHandle* navigation_handle) {
112 return navigation_handle->IsInMainFrame() 112 return navigation_handle->IsInMainFrame()
113 ? 0 113 ? kTopFrameId
114 : navigation_handle->GetFrameTreeNodeId(); 114 : navigation_handle->GetFrameTreeNodeId();
115 } 115 }
116 116
117 // static 117 // static
118 int ExtensionApiFrameIdMap::GetParentFrameId(content::RenderFrameHost* rfh) { 118 int ExtensionApiFrameIdMap::GetParentFrameId(content::RenderFrameHost* rfh) {
119 return rfh ? GetFrameId(rfh->GetParent()) : kInvalidFrameId; 119 return rfh ? GetFrameId(rfh->GetParent()) : kInvalidFrameId;
120 } 120 }
121 121
122 // static 122 // static
123 int ExtensionApiFrameIdMap::GetParentFrameId( 123 int ExtensionApiFrameIdMap::GetParentFrameId(
124 content::NavigationHandle* navigation_handle) { 124 content::NavigationHandle* navigation_handle) {
125 if (navigation_handle->IsInMainFrame()) 125 if (navigation_handle->IsInMainFrame())
126 return -1; 126 return kInvalidFrameId;
127 127
128 if (navigation_handle->IsParentMainFrame()) 128 if (navigation_handle->IsParentMainFrame())
129 return 0; 129 return kTopFrameId;
130 130
131 return navigation_handle->GetParentFrameTreeNodeId(); 131 return navigation_handle->GetParentFrameTreeNodeId();
132 } 132 }
133 133
134 // static 134 // static
135 content::RenderFrameHost* ExtensionApiFrameIdMap::GetRenderFrameHostById( 135 content::RenderFrameHost* ExtensionApiFrameIdMap::GetRenderFrameHostById(
136 content::WebContents* web_contents, 136 content::WebContents* web_contents,
137 int frame_id) { 137 int frame_id) {
138 // Although it is technically possible to map |frame_id| to a RenderFrameHost 138 // Although it is technically possible to map |frame_id| to a RenderFrameHost
139 // without WebContents, we choose to not do that because in the extension API 139 // without WebContents, we choose to not do that because in the extension API
(...skipping 17 matching lines...) Expand all
157 key.render_process_id, key.frame_routing_id); 157 key.render_process_id, key.frame_routing_id);
158 int tab_id = -1; 158 int tab_id = -1;
159 int window_id = -1; 159 int window_id = -1;
160 if (helper_) 160 if (helper_)
161 helper_->GetTabAndWindowId(rfh, &tab_id, &window_id); 161 helper_->GetTabAndWindowId(rfh, &tab_id, &window_id);
162 return FrameData(GetFrameId(rfh), GetParentFrameId(rfh), tab_id, window_id); 162 return FrameData(GetFrameId(rfh), GetParentFrameId(rfh), tab_id, window_id);
163 } 163 }
164 164
165 ExtensionApiFrameIdMap::FrameData ExtensionApiFrameIdMap::LookupFrameDataOnUI( 165 ExtensionApiFrameIdMap::FrameData ExtensionApiFrameIdMap::LookupFrameDataOnUI(
166 const RenderFrameIdKey& key, 166 const RenderFrameIdKey& key,
167 bool for_lookup) { 167 bool is_from_io) {
168 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 168 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
169 169
170 bool lookup_successful = false; 170 bool lookup_successful = false;
171 FrameData data; 171 FrameData data;
172 FrameDataMap::const_iterator frame_id_iter = frame_data_map_.find(key); 172 FrameDataMap::const_iterator frame_id_iter = frame_data_map_.find(key);
173 if (frame_id_iter != frame_data_map_.end()) { 173 if (frame_id_iter != frame_data_map_.end()) {
174 lookup_successful = true; 174 lookup_successful = true;
175 data = frame_id_iter->second; 175 data = frame_id_iter->second;
176 } else { 176 } else {
177 data = KeyToValue(key); 177 data = KeyToValue(key);
178 // Don't save invalid values in the map. 178 // Don't save invalid values in the map.
179 if (data.frame_id != kInvalidFrameId) { 179 if (data.frame_id != kInvalidFrameId) {
180 lookup_successful = true; 180 lookup_successful = true;
181 auto kvpair = FrameDataMap::value_type(key, data); 181 auto kvpair = FrameDataMap::value_type(key, data);
182 base::AutoLock lock(frame_data_map_lock_); 182 base::AutoLock lock(frame_data_map_lock_);
183 frame_data_map_.insert(kvpair); 183 frame_data_map_.insert(kvpair);
184 } 184 }
185 } 185 }
186 186
187 // TODO(devlin): Depending on how the data looks, this may be removable after 187 // TODO(devlin): Depending on how the data looks, this may be removable after
188 // a few cycles. Check back in M52 to see if it's still needed. 188 // a few cycles. Check back in M52 to see if it's still needed.
189 if (for_lookup) { 189 if (is_from_io) {
190 UMA_HISTOGRAM_BOOLEAN("Extensions.ExtensionFrameMapLookupSuccessful", 190 UMA_HISTOGRAM_BOOLEAN("Extensions.ExtensionFrameMapLookupSuccessful",
191 lookup_successful); 191 lookup_successful);
192 } 192 }
193 193
194 return data; 194 return data;
195 } 195 }
196 196
197 void ExtensionApiFrameIdMap::ReceivedFrameDataOnIO( 197 void ExtensionApiFrameIdMap::ReceivedFrameDataOnIO(
198 const RenderFrameIdKey& key, 198 const RenderFrameIdKey& key,
199 const FrameData& cached_frame_data) { 199 const FrameData& cached_frame_data) {
200 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 200 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
201 201
202 FrameDataCallbacksMap::iterator map_iter = callbacks_map_.find(key); 202 FrameDataCallbacksMap::iterator map_iter = callbacks_map_.find(key);
203 if (map_iter == callbacks_map_.end()) { 203 if (map_iter == callbacks_map_.end()) {
204 // Can happen if ReceivedFrameIdOnIO was called after the frame ID was 204 // Can happen if ReceivedFrameDataOnIO was called after the frame ID was
205 // resolved (e.g. via GetFrameDataOnIO), but before PostTaskAndReply 205 // resolved (e.g. via GetFrameDataOnIO), but before PostTaskAndReply
206 // replied. 206 // replied.
207 return; 207 return;
208 } 208 }
209 209
210 FrameDataCallbacks& callbacks = map_iter->second; 210 FrameDataCallbacks& callbacks = map_iter->second;
211 211
212 if (callbacks.is_iterating) 212 if (callbacks.is_iterating)
213 return; 213 return;
214 callbacks.is_iterating = true; 214 callbacks.is_iterating = true;
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
262 } 262 }
263 return; 263 return;
264 } 264 }
265 265
266 // The key was seen for the first time (or the frame has been removed). 266 // The key was seen for the first time (or the frame has been removed).
267 // Hop to the UI thread to look up the extension API frame ID. 267 // Hop to the UI thread to look up the extension API frame ID.
268 callbacks_map_[key].callbacks.push_back(callback); 268 callbacks_map_[key].callbacks.push_back(callback);
269 content::BrowserThread::PostTaskAndReplyWithResult( 269 content::BrowserThread::PostTaskAndReplyWithResult(
270 content::BrowserThread::UI, FROM_HERE, 270 content::BrowserThread::UI, FROM_HERE,
271 base::Bind(&ExtensionApiFrameIdMap::LookupFrameDataOnUI, 271 base::Bind(&ExtensionApiFrameIdMap::LookupFrameDataOnUI,
272 base::Unretained(this), key, true /* for lookup */), 272 base::Unretained(this), key, true /* is_from_io */),
273 base::Bind(&ExtensionApiFrameIdMap::ReceivedFrameDataOnIO, 273 base::Bind(&ExtensionApiFrameIdMap::ReceivedFrameDataOnIO,
274 base::Unretained(this), key)); 274 base::Unretained(this), key));
275 } 275 }
276 276
277 bool ExtensionApiFrameIdMap::GetCachedFrameDataOnIO(int render_process_id, 277 bool ExtensionApiFrameIdMap::GetCachedFrameDataOnIO(int render_process_id,
278 int frame_routing_id, 278 int frame_routing_id,
279 FrameData* frame_data_out) { 279 FrameData* frame_data_out) {
280 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 280 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
281 281
282 // TODO(robwu): Enable assertion when all callers have been fixed. 282 // TODO(robwu): Enable assertion when all callers have been fixed.
283 // DCHECK_EQ(MSG_ROUTING_NONE, -1); 283 // DCHECK_EQ(MSG_ROUTING_NONE, -1);
284 if (!IsFrameRoutingIdValid(frame_routing_id)) 284 if (!IsFrameRoutingIdValid(frame_routing_id))
285 return false; 285 return false;
286 286
287 // A valid routing ID is only meaningful with a valid process ID. 287 // A valid routing ID is only meaningful with a valid process ID.
288 DCHECK_GE(render_process_id, 0); 288 DCHECK_GE(render_process_id, 0);
289 289
290 bool found = false; 290 bool found = false;
291 { 291 {
292 base::AutoLock lock(frame_data_map_lock_); 292 base::AutoLock lock(frame_data_map_lock_);
293 FrameDataMap::const_iterator frame_id_iter = frame_data_map_.find( 293 FrameDataMap::const_iterator frame_id_iter = frame_data_map_.find(
294 RenderFrameIdKey(render_process_id, frame_routing_id)); 294 RenderFrameIdKey(render_process_id, frame_routing_id));
295 if (frame_id_iter != frame_data_map_.end()) { 295 if (frame_id_iter != frame_data_map_.end()) {
296 // This is very likely to happen because CacheFrameId() is called as soon 296 // This is very likely to happen because CacheFrameData() is called as
297 // as the frame is created. 297 // soon as the frame is created.
298 *frame_data_out = frame_id_iter->second; 298 *frame_data_out = frame_id_iter->second;
299 found = true; 299 found = true;
300 } 300 }
301 } 301 }
302 302
303 // TODO(devlin): Depending on how the data looks, this may be removable after 303 // TODO(devlin): Depending on how the data looks, this may be removable after
304 // a few cycles. Check back in M52 to see if it's still needed. 304 // a few cycles. Check back in M52 to see if it's still needed.
305 UMA_HISTOGRAM_BOOLEAN("Extensions.ExtensionFrameMapCacheHit", found); 305 UMA_HISTOGRAM_BOOLEAN("Extensions.ExtensionFrameMapCacheHit", found);
306 return found; 306 return found;
307 } 307 }
308 308
309 ExtensionApiFrameIdMap::FrameData ExtensionApiFrameIdMap::GetFrameData(
310 content::RenderFrameHost* rfh) {
311 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
312
313 const RenderFrameIdKey key(rfh->GetProcess()->GetID(), rfh->GetRoutingID());
314 return LookupFrameDataOnUI(key, false /* is_from_io */);
315 }
316
309 void ExtensionApiFrameIdMap::CacheFrameData(content::RenderFrameHost* rfh) { 317 void ExtensionApiFrameIdMap::CacheFrameData(content::RenderFrameHost* rfh) {
310 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 318 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
311 319
312 const RenderFrameIdKey key(rfh->GetProcess()->GetID(), rfh->GetRoutingID()); 320 const RenderFrameIdKey key(rfh->GetProcess()->GetID(), rfh->GetRoutingID());
313 CacheFrameData(key); 321 CacheFrameData(key);
314 DCHECK(frame_data_map_.find(key) != frame_data_map_.end()); 322 DCHECK(frame_data_map_.find(key) != frame_data_map_.end());
315 } 323 }
316 324
317 void ExtensionApiFrameIdMap::CacheFrameData(const RenderFrameIdKey& key) { 325 void ExtensionApiFrameIdMap::CacheFrameData(const RenderFrameIdKey& key) {
318 LookupFrameDataOnUI(key, false /* not for lookup */); 326 LookupFrameDataOnUI(key, false /* is_from_io */);
319 } 327 }
320 328
321 void ExtensionApiFrameIdMap::RemoveFrameData(content::RenderFrameHost* rfh) { 329 void ExtensionApiFrameIdMap::RemoveFrameData(content::RenderFrameHost* rfh) {
322 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 330 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
323 DCHECK(rfh); 331 DCHECK(rfh);
324 332
325 const RenderFrameIdKey key(rfh->GetProcess()->GetID(), rfh->GetRoutingID()); 333 const RenderFrameIdKey key(rfh->GetProcess()->GetID(), rfh->GetRoutingID());
326 RemoveFrameData(key); 334 RemoveFrameData(key);
327 } 335 }
328 336
(...skipping 16 matching lines...) Expand all
345 } 353 }
346 354
347 void ExtensionApiFrameIdMap::RemoveFrameData(const RenderFrameIdKey& key) { 355 void ExtensionApiFrameIdMap::RemoveFrameData(const RenderFrameIdKey& key) {
348 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 356 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
349 357
350 base::AutoLock lock(frame_data_map_lock_); 358 base::AutoLock lock(frame_data_map_lock_);
351 frame_data_map_.erase(key); 359 frame_data_map_.erase(key);
352 } 360 }
353 361
354 } // namespace extensions 362 } // namespace extensions
OLDNEW
« no previous file with comments | « extensions/browser/extension_api_frame_id_map.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698