OLD | NEW |
---|---|
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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 "chrome/browser/data_use_measurement/chrome_data_use_ascriber.h" | 5 #include "chrome/browser/data_use_measurement/chrome_data_use_ascriber.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 | 8 |
9 #include "base/memory/ptr_util.h" | 9 #include "base/memory/ptr_util.h" |
10 #include "chrome/browser/data_use_measurement/chrome_data_use_recorder.h" | 10 #include "chrome/browser/data_use_measurement/chrome_data_use_recorder.h" |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
51 ChromeDataUseRecorder* ChromeDataUseAscriber::GetOrCreateDataUseRecorder( | 51 ChromeDataUseRecorder* ChromeDataUseAscriber::GetOrCreateDataUseRecorder( |
52 net::URLRequest* request) { | 52 net::URLRequest* request) { |
53 DataUseRecorderEntry entry = GetOrCreateDataUseRecorderEntry(request); | 53 DataUseRecorderEntry entry = GetOrCreateDataUseRecorderEntry(request); |
54 return entry == data_use_recorders_.end() ? nullptr : &(*entry); | 54 return entry == data_use_recorders_.end() ? nullptr : &(*entry); |
55 } | 55 } |
56 | 56 |
57 ChromeDataUseRecorder* ChromeDataUseAscriber::GetDataUseRecorder( | 57 ChromeDataUseRecorder* ChromeDataUseAscriber::GetDataUseRecorder( |
58 const net::URLRequest& request) { | 58 const net::URLRequest& request) { |
59 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); | 59 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); |
60 | 60 |
61 // TODO(ryansturm): Handle PlzNavigate (http://crbug/664233). | |
62 if (content::IsBrowserSideNavigationEnabled()) | |
63 return nullptr; | |
64 | |
65 // If a DataUseRecorder has already been set as user data, then return that. | 61 // If a DataUseRecorder has already been set as user data, then return that. |
66 auto* user_data = static_cast<DataUseRecorderEntryAsUserData*>( | 62 auto* user_data = static_cast<DataUseRecorderEntryAsUserData*>( |
67 request.GetUserData(DataUseRecorderEntryAsUserData::kUserDataKey)); | 63 request.GetUserData(DataUseRecorderEntryAsUserData::kUserDataKey)); |
68 return user_data ? &(*user_data->recorder_entry()) : nullptr; | 64 return user_data ? &(*user_data->recorder_entry()) : nullptr; |
69 } | 65 } |
70 | 66 |
71 ChromeDataUseAscriber::DataUseRecorderEntry | 67 ChromeDataUseAscriber::DataUseRecorderEntry |
72 ChromeDataUseAscriber::GetOrCreateDataUseRecorderEntry( | 68 ChromeDataUseAscriber::GetOrCreateDataUseRecorderEntry( |
73 net::URLRequest* request) { | 69 net::URLRequest* request) { |
74 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); | 70 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); |
75 | 71 |
76 // TODO(ryansturm): Handle PlzNavigate (http://crbug/664233). | |
77 if (content::IsBrowserSideNavigationEnabled()) | |
78 return data_use_recorders_.end(); | |
79 | |
80 // If a DataUseRecorder has already been set as user data, then return that. | 72 // If a DataUseRecorder has already been set as user data, then return that. |
81 auto* user_data = static_cast<DataUseRecorderEntryAsUserData*>( | 73 auto* user_data = static_cast<DataUseRecorderEntryAsUserData*>( |
82 request->GetUserData(DataUseRecorderEntryAsUserData::kUserDataKey)); | 74 request->GetUserData(DataUseRecorderEntryAsUserData::kUserDataKey)); |
83 if (user_data) | 75 if (user_data) |
84 return user_data->recorder_entry(); | 76 return user_data->recorder_entry(); |
85 | 77 |
86 // If request is associated with a ChromeService, create a new | 78 // If request is associated with a ChromeService, create a new |
87 // DataUseRecorder for it. There is no reason to aggregate URLRequests | 79 // DataUseRecorder for it. There is no reason to aggregate URLRequests |
88 // from ChromeServices into the same DataUseRecorder instance. | 80 // from ChromeServices into the same DataUseRecorder instance. |
89 DataUseUserData* service = static_cast<DataUseUserData*>( | 81 DataUseUserData* service = static_cast<DataUseUserData*>( |
90 request->GetUserData(DataUseUserData::kUserDataKey)); | 82 request->GetUserData(DataUseUserData::kUserDataKey)); |
91 if (service) { | 83 if (service) { |
92 DataUseRecorderEntry entry = | 84 DataUseRecorderEntry entry = |
93 CreateNewDataUseRecorder(request, DataUse::TrafficType::SERVICES); | 85 CreateNewDataUseRecorder(request, DataUse::TrafficType::SERVICES); |
94 entry->data_use().set_description( | 86 entry->data_use().set_description( |
95 DataUseUserData::GetServiceNameAsString(service->service_name())); | 87 DataUseUserData::GetServiceNameAsString(service->service_name())); |
96 return entry; | 88 return entry; |
97 } | 89 } |
98 | 90 |
91 const content::ResourceRequestInfo* request_info = | |
92 content::ResourceRequestInfo::ForRequest(request); | |
93 if (!request_info || | |
94 request_info->GetGlobalRequestID() == content::GlobalRequestID()) { | |
95 // Create a new DataUseRecorder for all other requests. | |
96 DataUseRecorderEntry entry = | |
97 CreateNewDataUseRecorder(request, DataUse::TrafficType::UNKNOWN); | |
98 DataUse& data_use = entry->data_use(); | |
99 data_use.set_url(request->url()); | |
100 return entry; | |
101 } | |
102 | |
103 if (request_info->GetResourceType() == content::RESOURCE_TYPE_MAIN_FRAME) { | |
104 DataUseRecorderEntry new_entry = | |
105 CreateNewDataUseRecorder(request, DataUse::TrafficType::USER_TRAFFIC); | |
106 new_entry->set_main_frame_request_id(request_info->GetGlobalRequestID()); | |
107 pending_navigation_data_use_map_.insert( | |
108 std::make_pair(request_info->GetGlobalRequestID(), new_entry)); | |
109 return new_entry; | |
110 } | |
111 | |
99 int render_process_id = -1; | 112 int render_process_id = -1; |
100 int render_frame_id = -1; | 113 int render_frame_id = -1; |
101 bool has_valid_frame = content::ResourceRequestInfo::GetRenderFrameForRequest( | 114 bool has_valid_frame = content::ResourceRequestInfo::GetRenderFrameForRequest( |
102 request, &render_process_id, &render_frame_id); | 115 request, &render_process_id, &render_frame_id); |
103 if (has_valid_frame && | 116 if (has_valid_frame && |
104 render_frame_id != SpecialRoutingIDs::MSG_ROUTING_NONE) { | 117 render_frame_id != SpecialRoutingIDs::MSG_ROUTING_NONE) { |
105 DCHECK(render_process_id >= 0 || render_frame_id >= 0); | 118 DCHECK(render_process_id >= 0 || render_frame_id >= 0); |
106 | 119 |
107 // Browser tests may not set up DataUseWebContentsObservers in which case | 120 // Browser tests may not set up DataUseWebContentsObservers in which case |
108 // this class never sees navigation and frame events so DataUseRecorders | 121 // this class never sees navigation and frame events so DataUseRecorders |
109 // will never be destroyed. To avoid this, we ignore requests whose | 122 // will never be destroyed. To avoid this, we ignore requests whose |
110 // render frames don't have a record. However, this can also be caused by | 123 // render frames don't have a record. However, this can also be caused by |
111 // URLRequests racing the frame create events. | 124 // URLRequests racing the frame create events. |
112 // TODO(kundaji): Add UMA. | 125 // TODO(kundaji): Add UMA. |
113 RenderFrameHostID frame_key(render_process_id, render_frame_id); | 126 RenderFrameHostID frame_key(render_process_id, render_frame_id); |
114 auto main_frame_key_iter = subframe_to_mainframe_map_.find(frame_key); | 127 auto main_frame_key_iter = subframe_to_mainframe_map_.find(frame_key); |
115 if (main_frame_key_iter == subframe_to_mainframe_map_.end()) { | 128 if (main_frame_key_iter == subframe_to_mainframe_map_.end()) { |
116 return data_use_recorders_.end(); | 129 return data_use_recorders_.end(); |
117 } | 130 } |
118 auto frame_iter = | 131 auto frame_iter = |
119 main_render_frame_data_use_map_.find(main_frame_key_iter->second); | 132 main_render_frame_data_use_map_.find(main_frame_key_iter->second); |
120 if (frame_iter == main_render_frame_data_use_map_.end()) { | 133 if (frame_iter == main_render_frame_data_use_map_.end()) { |
121 return data_use_recorders_.end(); | 134 return data_use_recorders_.end(); |
122 } | 135 } |
123 | 136 |
124 const content::ResourceRequestInfo* request_info = | |
125 content::ResourceRequestInfo::ForRequest(request); | |
126 content::ResourceType resource_type = | |
127 request_info ? request_info->GetResourceType() | |
128 : content::RESOURCE_TYPE_LAST_TYPE; | |
129 | |
130 if (resource_type == content::RESOURCE_TYPE_MAIN_FRAME) { | |
131 content::GlobalRequestID navigation_key = | |
132 request_info->GetGlobalRequestID(); | |
133 | |
134 DataUseRecorderEntry new_entry = | |
135 CreateNewDataUseRecorder(request, DataUse::TrafficType::USER_TRAFFIC); | |
136 new_entry->set_main_frame_request_id(navigation_key); | |
137 pending_navigation_data_use_map_.insert( | |
138 std::make_pair(navigation_key, new_entry)); | |
139 | |
140 return new_entry; | |
141 } | |
142 | |
143 DCHECK(frame_iter != main_render_frame_data_use_map_.end()); | |
144 auto entry = frame_iter->second; | 137 auto entry = frame_iter->second; |
145 request->SetUserData( | 138 request->SetUserData( |
146 DataUseRecorderEntryAsUserData::kUserDataKey, | 139 DataUseRecorderEntryAsUserData::kUserDataKey, |
147 base::MakeUnique<DataUseRecorderEntryAsUserData>(entry)); | 140 base::MakeUnique<DataUseRecorderEntryAsUserData>(entry)); |
148 entry->AddPendingURLRequest(request); | 141 entry->AddPendingURLRequest(request); |
149 return entry; | 142 return entry; |
150 } | 143 } |
151 | 144 |
152 // Create a new DataUseRecorder for all other requests. | 145 // Create a new DataUseRecorder for all other requests. |
153 DataUseRecorderEntry entry = CreateNewDataUseRecorder( | 146 DataUseRecorderEntry entry = CreateNewDataUseRecorder( |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
191 // GetOrCreateDataUseRecorderEntry is not needed. The entry gets created in | 184 // GetOrCreateDataUseRecorderEntry is not needed. The entry gets created in |
192 // DataUseAscriber::OnBeforeUrlRequest(). | 185 // DataUseAscriber::OnBeforeUrlRequest(). |
193 DataUseRecorderEntry entry = GetOrCreateDataUseRecorderEntry(request); | 186 DataUseRecorderEntry entry = GetOrCreateDataUseRecorderEntry(request); |
194 | 187 |
195 if (entry == data_use_recorders_.end()) | 188 if (entry == data_use_recorders_.end()) |
196 return; | 189 return; |
197 | 190 |
198 for (auto& observer : observers_) | 191 for (auto& observer : observers_) |
199 observer.OnPageResourceLoad(*request, &entry->data_use()); | 192 observer.OnPageResourceLoad(*request, &entry->data_use()); |
200 | 193 |
201 RenderFrameHostID frame_key = entry->main_frame_id(); | 194 bool will_datause_complete = false; |
202 auto frame_iter = main_render_frame_data_use_map_.find(frame_key); | |
203 bool is_in_render_frame_map = | |
204 frame_iter != main_render_frame_data_use_map_.end() && | |
205 frame_iter->second->HasPendingURLRequest(request); | |
206 | |
207 const content::ResourceRequestInfo* request_info = | 195 const content::ResourceRequestInfo* request_info = |
208 content::ResourceRequestInfo::ForRequest(request); | 196 content::ResourceRequestInfo::ForRequest(request); |
209 bool is_in_pending_navigation_map = | 197 |
210 request_info && | 198 if (request_info && |
211 request_info->GetResourceType() == content::RESOURCE_TYPE_MAIN_FRAME && | 199 request_info->GetResourceType() == content::RESOURCE_TYPE_MAIN_FRAME) { |
212 pending_navigation_data_use_map_.find(entry->main_frame_request_id()) != | 200 will_datause_complete = |
213 pending_navigation_data_use_map_.end(); | 201 pending_navigation_data_use_map_.find(entry->main_frame_request_id()) == |
202 pending_navigation_data_use_map_.end(); | |
203 } else { | |
204 // Non-mainframe, Services, and other requests. | |
205 auto frame_iter = | |
206 main_render_frame_data_use_map_.find(entry->main_frame_id()); | |
207 will_datause_complete = | |
208 frame_iter == main_render_frame_data_use_map_.end() || | |
209 !frame_iter->second->HasPendingURLRequest(request); | |
210 } | |
214 | 211 |
215 DataUseAscriber::OnUrlRequestDestroyed(request); | 212 DataUseAscriber::OnUrlRequestDestroyed(request); |
216 request->RemoveUserData(DataUseRecorderEntryAsUserData::kUserDataKey); | 213 request->RemoveUserData(DataUseRecorderEntryAsUserData::kUserDataKey); |
217 | 214 |
218 if (entry->IsDataUseComplete() && !is_in_render_frame_map && | 215 if (entry->IsDataUseComplete() && will_datause_complete) { |
219 !is_in_pending_navigation_map) { | |
220 NotifyDataUseCompleted(entry); | 216 NotifyDataUseCompleted(entry); |
221 data_use_recorders_.erase(entry); | 217 data_use_recorders_.erase(entry); |
222 } | 218 } |
223 } | 219 } |
224 | 220 |
225 void ChromeDataUseAscriber::RenderFrameCreated(int render_process_id, | 221 void ChromeDataUseAscriber::RenderFrameCreated(int render_process_id, |
226 int render_frame_id, | 222 int render_frame_id, |
227 int main_render_process_id, | 223 int main_render_process_id, |
228 int main_render_frame_id) { | 224 int main_render_frame_id) { |
229 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); | 225 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); |
230 | 226 |
231 if (content::IsBrowserSideNavigationEnabled()) | |
232 return; | |
233 | |
234 if (main_render_process_id != -1 && main_render_frame_id != -1) { | 227 if (main_render_process_id != -1 && main_render_frame_id != -1) { |
235 // Create an entry in |subframe_to_mainframe_map_| for this frame mapped to | 228 // Create an entry in |subframe_to_mainframe_map_| for this frame mapped to |
236 // it's parent frame. | 229 // it's parent frame. |
237 subframe_to_mainframe_map_.insert(std::make_pair( | 230 subframe_to_mainframe_map_.insert(std::make_pair( |
238 RenderFrameHostID(render_process_id, render_frame_id), | 231 RenderFrameHostID(render_process_id, render_frame_id), |
239 RenderFrameHostID(main_render_process_id, main_render_frame_id))); | 232 RenderFrameHostID(main_render_process_id, main_render_frame_id))); |
240 } else { | 233 } else { |
241 subframe_to_mainframe_map_.insert( | 234 subframe_to_mainframe_map_.insert( |
242 std::make_pair(RenderFrameHostID(render_process_id, render_frame_id), | 235 std::make_pair(RenderFrameHostID(render_process_id, render_frame_id), |
243 RenderFrameHostID(render_process_id, render_frame_id))); | 236 RenderFrameHostID(render_process_id, render_frame_id))); |
244 auto frame_iter = main_render_frame_data_use_map_.find( | 237 auto frame_iter = main_render_frame_data_use_map_.find( |
245 RenderFrameHostID(render_process_id, render_frame_id)); | 238 RenderFrameHostID(render_process_id, render_frame_id)); |
246 DCHECK(frame_iter == main_render_frame_data_use_map_.end()); | 239 DCHECK(frame_iter == main_render_frame_data_use_map_.end()); |
247 DataUseRecorderEntry entry = | 240 DataUseRecorderEntry entry = |
248 CreateNewDataUseRecorder(nullptr, DataUse::TrafficType::UNKNOWN); | 241 CreateNewDataUseRecorder(nullptr, DataUse::TrafficType::UNKNOWN); |
249 entry->set_main_frame_id( | 242 entry->set_main_frame_id( |
250 RenderFrameHostID(render_process_id, render_frame_id)); | 243 RenderFrameHostID(render_process_id, render_frame_id)); |
251 main_render_frame_data_use_map_.insert(std::make_pair( | 244 main_render_frame_data_use_map_.insert(std::make_pair( |
252 RenderFrameHostID(render_process_id, render_frame_id), entry)); | 245 RenderFrameHostID(render_process_id, render_frame_id), entry)); |
253 } | 246 } |
254 } | 247 } |
255 | 248 |
256 void ChromeDataUseAscriber::RenderFrameDeleted(int render_process_id, | 249 void ChromeDataUseAscriber::RenderFrameDeleted(int render_process_id, |
257 int render_frame_id, | 250 int render_frame_id, |
258 int main_render_process_id, | 251 int main_render_process_id, |
259 int main_render_frame_id) { | 252 int main_render_frame_id) { |
260 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); | 253 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); |
261 | 254 |
262 if (content::IsBrowserSideNavigationEnabled()) | |
263 return; | |
264 | |
265 RenderFrameHostID key(render_process_id, render_frame_id); | 255 RenderFrameHostID key(render_process_id, render_frame_id); |
266 | 256 |
267 if (main_render_process_id == -1 && main_render_frame_id == -1) { | 257 if (main_render_process_id == -1 && main_render_frame_id == -1) { |
268 auto frame_iter = main_render_frame_data_use_map_.find(key); | 258 auto frame_iter = main_render_frame_data_use_map_.find(key); |
269 DataUseRecorderEntry entry = frame_iter->second; | 259 DataUseRecorderEntry entry = frame_iter->second; |
270 if (entry->IsDataUseComplete()) { | 260 if (entry->IsDataUseComplete()) { |
271 NotifyDataUseCompleted(entry); | 261 NotifyDataUseCompleted(entry); |
272 data_use_recorders_.erase(entry); | 262 data_use_recorders_.erase(entry); |
273 } | 263 } |
274 main_render_frame_data_use_map_.erase(frame_iter); | 264 main_render_frame_data_use_map_.erase(frame_iter); |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
377 base::MakeUnique<DataUseRecorderEntryAsUserData>(old_frame_entry)); | 367 base::MakeUnique<DataUseRecorderEntryAsUserData>(old_frame_entry)); |
378 old_frame_entry->AddPendingURLRequest(request); | 368 old_frame_entry->AddPendingURLRequest(request); |
379 } | 369 } |
380 | 370 |
381 entry->RemoveAllPendingURLRequests(); | 371 entry->RemoveAllPendingURLRequests(); |
382 | 372 |
383 data_use_recorders_.erase(entry); | 373 data_use_recorders_.erase(entry); |
384 } else { | 374 } else { |
385 // Navigation is not same page, so remove old entry from | 375 // Navigation is not same page, so remove old entry from |
386 // |main_render_frame_data_use_map_|, possibly marking it complete. | 376 // |main_render_frame_data_use_map_|, possibly marking it complete. |
387 main_render_frame_data_use_map_.erase(frame_it); | |
388 if (old_frame_entry->IsDataUseComplete()) { | 377 if (old_frame_entry->IsDataUseComplete()) { |
389 NotifyDataUseCompleted(old_frame_entry); | 378 NotifyDataUseCompleted(old_frame_entry); |
390 data_use_recorders_.erase(old_frame_entry); | 379 data_use_recorders_.erase(old_frame_entry); |
391 | 380 |
392 if (visible_main_render_frames_.find(mainframe) != | 381 if (visible_main_render_frames_.find(mainframe) != |
393 visible_main_render_frames_.end()) { | 382 visible_main_render_frames_.end()) { |
394 entry->set_is_visible(true); | 383 entry->set_is_visible(true); |
395 } | 384 } |
396 } | 385 } |
397 | 386 |
398 DataUse& data_use = entry->data_use(); | 387 DataUse& data_use = entry->data_use(); |
399 | 388 |
400 DCHECK(!data_use.url().is_valid() || data_use.url() == gurl) | 389 DCHECK(!data_use.url().is_valid() || data_use.url() == gurl) |
401 << "is valid: " << data_use.url().is_valid() | 390 << "is valid: " << data_use.url().is_valid() |
402 << "; data_use.url(): " << data_use.url().spec() | 391 << "; data_use.url(): " << data_use.url().spec() |
403 << "; gurl: " << gurl.spec(); | 392 << "; gurl: " << gurl.spec(); |
404 if (!data_use.url().is_valid()) { | 393 if (!data_use.url().is_valid()) { |
405 data_use.set_url(gurl); | 394 data_use.set_url(gurl); |
406 } | 395 } |
407 | 396 |
397 main_render_frame_data_use_map_.erase(frame_it); | |
rajendrant
2017/05/24 07:14:09
Moving it down, since |old_frame_entry| is accesse
RyanSturm
2017/05/24 16:08:44
Acknowledged.
| |
408 main_render_frame_data_use_map_.insert(std::make_pair(mainframe, entry)); | 398 main_render_frame_data_use_map_.insert(std::make_pair(mainframe, entry)); |
409 } | 399 } |
410 } | 400 } |
411 | 401 |
412 void ChromeDataUseAscriber::NotifyPageLoadCommit(DataUseRecorderEntry entry) { | 402 void ChromeDataUseAscriber::NotifyPageLoadCommit(DataUseRecorderEntry entry) { |
413 for (auto& observer : observers_) | 403 for (auto& observer : observers_) |
414 observer.OnPageLoadCommit(&entry->data_use()); | 404 observer.OnPageLoadCommit(&entry->data_use()); |
415 } | 405 } |
416 | 406 |
417 void ChromeDataUseAscriber::NotifyDataUseCompleted(DataUseRecorderEntry entry) { | 407 void ChromeDataUseAscriber::NotifyDataUseCompleted(DataUseRecorderEntry entry) { |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
470 pending_navigation_global_request_id_.find(old_frame); | 460 pending_navigation_global_request_id_.find(old_frame); |
471 if (pending_navigation_iter != pending_navigation_global_request_id_.end()) { | 461 if (pending_navigation_iter != pending_navigation_global_request_id_.end()) { |
472 pending_navigation_global_request_id_.insert(std::make_pair( | 462 pending_navigation_global_request_id_.insert(std::make_pair( |
473 RenderFrameHostID(new_render_process_id, new_render_frame_id), | 463 RenderFrameHostID(new_render_process_id, new_render_frame_id), |
474 pending_navigation_iter->second)); | 464 pending_navigation_iter->second)); |
475 pending_navigation_global_request_id_.erase(pending_navigation_iter); | 465 pending_navigation_global_request_id_.erase(pending_navigation_iter); |
476 } | 466 } |
477 } | 467 } |
478 | 468 |
479 } // namespace data_use_measurement | 469 } // namespace data_use_measurement |
OLD | NEW |